Date: Thu, 10 Feb 2000 10:27:07 -0800 (PST) From: Doug Ambrisko <ambrisko@whistle.com> To: imp@village.org, freebsd-mobile@freebsd.org Subject: Update to pccard ata changes (removal support) Message-ID: <200002101827.KAA90609@whistle.com>
next in thread | raw e-mail | index | archive | help
I have now added removal support to the ata driver for pccard. Caveats, the devices increment each time they are inserted and removed. Also I do not checks for mounted devices etc. yet. I'm not sure what the details are to deal with this (since as the card is being ripped out there won't be time to sync the device). So your machine might panic. I don't know and haven't tested this. I also need to look at the incrementing device issue. I thought it would be usefull to get this code out before I start to investigate that. I have tested it with my external hard disk, CD-Rom and Zip. They all seemed to handle it fine. Device accesses to old device names failed somewhat gracefully (ie. no panic but some error messages). Please let me know how it works. Again this is relative to -current. Doug A. Index: ata-all.c =================================================================== RCS file: /cvs/freebsd/src/sys/dev/ata/ata-all.c,v retrieving revision 1.47 diff -c -r1.47 ata-all.c *** ata-all.c 2000/02/04 10:20:20 1.47 --- ata-all.c 2000/02/10 18:17:34 *************** *** 30,35 **** --- 30,36 ---- #include "ata.h" #include "apm.h" + #include "card.h" #include "isa.h" #include "pci.h" #include "atadisk.h" *************** *** 88,93 **** --- 89,103 ---- static void btrim(int8_t *, int32_t); static void bpack(int8_t *, int8_t *, int32_t); + #if NCARD > 0 + static int ata_pccard_attach __P((device_t dev)); + static int ata_pccard_detach __P((device_t dev)); + static int ata_pccard_probe __P((device_t dev)); + /* XXX */ + extern void ad_drvinit(void); + extern void atapi_init(void); + #endif /* NCARD > 0 */ + /* local vars */ static int32_t atanlun = 2; static struct intr_config_hook *ata_attach_hook = NULL; *************** *** 187,192 **** --- 197,354 ---- DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0); #endif + #if NCARD > 0 + static int + ata_pccard_probe(dev) + device_t dev; + { + struct resource *port; + int rid; + int32_t res; + int32_t lun; + static struct intr_config_hook *tmp; + + /* Allocate the port range */ + rid = 0; + port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 16, RF_ACTIVE); + /* XXX 16 shouldn't be hard coded */ + + if (!port) + return (ENOMEM); + + /* don't worry about conflict since PCCard code should have checked + already */ + /* + * XXX ALTPORT not used in pccard XXX + * Here's the i/o map for isa vs pccard + * Offset isa pccard + * DATA 0 0 + * ERROR 1 1 R + * FEATURE 1 1 W + * COUNT 2 2 W + * IREASON 2 2 R + * SECTOR 3 3 + * CYL_LSB 4 4 + * CYL_MSB 5 5 + * DRIVE 6 6 + * CMD 7 7 + * STATUS 7 7 + * ALTSTATUS 206 8 R + * CTLR 206 8 W + * wd_digin 207 9 + */ + + /* trick ata_probe to not queue up interrupts since interupts + are active now */ + tmp=ata_attach_hook; + ata_attach_hook = 1; + + res = ata_probe(rman_get_start(port), + rman_get_start(port) + ATA_ALTPORT_ONE_WINDOW, 0, dev, &lun); + + /* restore hook */ + ata_attach_hook = tmp; + + bus_release_resource(dev, SYS_RES_IOPORT, rid, port); + + if (res) { + isa_set_portsize(dev, res); + *(int *)device_get_softc(dev) = lun; + atadevices[lun]->flags |= ATA_USE_16BIT; + return 0; + } + return ENXIO; + } + + static int + ata_pccard_attach(dev) + device_t dev; + { + struct ata_softc *sc = atadevices[*(int *)device_get_softc(dev)]; + int status; + + /* Allocate the port range and interrupt */ + sc->port_res = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->port_rid, + 0, ~0, 1, RF_ACTIVE); + if (!sc->port_res) { + /* XXX Need to free things ? */ + return (ENOMEM); + } + + sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid, + 0, ~0, 1, RF_ACTIVE); + if (!sc->irq_res) { + /* XXX Need to free things ? */ + bus_release_resource(dev, SYS_RES_IOPORT, sc->port_rid, sc->port_res); + return (ENOMEM); + } + status = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_BIO, ataintr, + atadevices[*(int *)device_get_softc(dev)], + &sc->irq_handle); + + /* XXX The following really should just scan *THIS* device XXX */ + /* XXX Also, we need to do more than just ad XXX */ + + if (status == 0) { + ata_attach(dev); + } + return status; + } + + + static int + ata_pccard_detach(dev) + device_t dev; + { + struct ata_softc *sc = atadevices[*(int *)device_get_softc(dev)]; + + if (sc->gone) { + device_printf(dev,"already unloaded\n"); + return(0); + } + + sc->gone = 1; + + bus_teardown_intr(dev, sc->irq_res, sc->irq_handle); + + if (sc->port_res) { + bus_release_resource(dev, SYS_RES_IOPORT, + sc->port_rid, sc->port_res); + sc->port_res = 0; + } + if (sc->irq_res) { + bus_release_resource(dev, SYS_RES_IRQ, + sc->irq_rid, sc->irq_res); + sc->irq_res = 0; + } + + atadevices[*(int *)device_get_softc(dev)]=NULL; + + free(sc, M_DEVBUF); + + device_printf(dev,"unloaded\n"); + return (0); + } + + + static device_method_t ata_pccard_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, ata_pccard_probe), + DEVMETHOD(device_attach, ata_pccard_attach), + DEVMETHOD(device_detach, ata_pccard_detach), + + { 0, 0 } + }; + + static driver_t ata_pccard_driver = { + "ata", + ata_pccard_methods, + sizeof(int), + }; + + DRIVER_MODULE(ata, pccard, ata_pccard_driver, ata_devclass, 0, 0); + #endif (NCARD > 0) + #if NPCI > 0 static const char * ata_pcimatch(device_t dev) *************** *** 655,661 **** * of non-exsistent devices and thereby long delays */ for (ctlr=0; ctlr<MAXATA; ctlr++) { ! if (!atadevices[ctlr]) continue; if (atadevices[ctlr]->devices & ATA_ATA_SLAVE) if (ata_getparam(atadevices[ctlr], ATA_SLAVE, ATA_C_ATA_IDENTIFY)) atadevices[ctlr]->devices &= ~ATA_ATA_SLAVE; --- 817,824 ---- * of non-exsistent devices and thereby long delays */ for (ctlr=0; ctlr<MAXATA; ctlr++) { ! if (!atadevices[ctlr] || ! (atadevices[ctlr]->devices & ATA_PROBED)) continue; if (atadevices[ctlr]->devices & ATA_ATA_SLAVE) if (ata_getparam(atadevices[ctlr], ATA_SLAVE, ATA_C_ATA_IDENTIFY)) atadevices[ctlr]->devices &= ~ATA_ATA_SLAVE; *************** *** 673,679 **** #if NATADISK > 0 /* now we know whats there, do the real attach, first the ATA disks */ for (ctlr=0; ctlr<MAXATA; ctlr++) { ! if (!atadevices[ctlr]) continue; if (atadevices[ctlr]->devices & ATA_ATA_MASTER) ad_attach(atadevices[ctlr], ATA_MASTER); if (atadevices[ctlr]->devices & ATA_ATA_SLAVE) --- 836,843 ---- #if NATADISK > 0 /* now we know whats there, do the real attach, first the ATA disks */ for (ctlr=0; ctlr<MAXATA; ctlr++) { ! if (!atadevices[ctlr] || ! (atadevices[ctlr]->devices & ATA_PROBED)) continue; if (atadevices[ctlr]->devices & ATA_ATA_MASTER) ad_attach(atadevices[ctlr], ATA_MASTER); if (atadevices[ctlr]->devices & ATA_ATA_SLAVE) *************** *** 683,695 **** #if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0 /* then the atapi devices */ for (ctlr=0; ctlr<MAXATA; ctlr++) { ! if (!atadevices[ctlr]) continue; if (atadevices[ctlr]->devices & ATA_ATAPI_MASTER) atapi_attach(atadevices[ctlr], ATA_MASTER); if (atadevices[ctlr]->devices & ATA_ATAPI_SLAVE) atapi_attach(atadevices[ctlr], ATA_SLAVE); } #endif if (ata_attach_hook) { config_intrhook_disestablish(ata_attach_hook); free(ata_attach_hook, M_ATA); --- 847,865 ---- #if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0 /* then the atapi devices */ for (ctlr=0; ctlr<MAXATA; ctlr++) { ! if (!atadevices[ctlr] || ! (atadevices[ctlr]->devices & ATA_PROBED)) continue; if (atadevices[ctlr]->devices & ATA_ATAPI_MASTER) atapi_attach(atadevices[ctlr], ATA_MASTER); if (atadevices[ctlr]->devices & ATA_ATAPI_SLAVE) atapi_attach(atadevices[ctlr], ATA_SLAVE); } #endif + /* mark all current controllers probed for devices */ + for (ctlr=0; ctlr<MAXATA; ctlr++) { + if (!atadevices[ctlr]) continue; + atadevices[ctlr]->devices |= ATA_PROBED; + } if (ata_attach_hook) { config_intrhook_disestablish(ata_attach_hook); free(ata_attach_hook, M_ATA); Index: ata-all.h =================================================================== RCS file: /cvs/freebsd/src/sys/dev/ata/ata-all.h,v retrieving revision 1.23 diff -c -r1.23 ata-all.h *** ata-all.h 2000/01/28 13:35:42 1.23 --- ata-all.h 2000/02/10 18:17:34 *************** *** 87,92 **** --- 87,93 ---- #define ATA_S_BUSY 0x80 /* busy */ #define ATA_ALTPORT 0x206 /* alternate Status register */ + #define ATA_ALTPORT_ONE_WINDOW 0x08 /* Alternate port for pccard */ #define ATA_A_IDS 0x02 /* disable interrupts */ #define ATA_A_RESET 0x04 /* RESET controller */ #define ATA_A_4BIT 0x08 /* 4 head bits */ *************** *** 281,286 **** --- 282,288 ---- #define ATA_ATA_SLAVE 0x02 #define ATA_ATAPI_MASTER 0x04 #define ATA_ATAPI_SLAVE 0x08 + #define ATA_PROBED 0x10 u_int8_t status; /* last controller status */ u_int8_t error; /* last controller error */ *************** *** 300,306 **** #if NAPM > 0 struct apmhook resume_hook; /* hook for apm */ #endif ! }; /* array to hold all ata softc's */ --- 302,313 ---- #if NAPM > 0 struct apmhook resume_hook; /* hook for apm */ #endif ! int port_rid; /* resource id for port range */ ! struct resource* port_res; /* resource for port range */ ! int irq_rid; /* resource id for irq */ ! struct resource* irq_res; /* resource for irq */ ! void* irq_handle; /* handle for irq handler */ ! int gone; }; /* array to hold all ata softc's */ To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-mobile" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200002101827.KAA90609>