diff options
author | imp <imp@FreeBSD.org> | 1999-10-15 17:29:21 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 1999-10-15 17:29:21 +0000 |
commit | 9f89acc8ccb787d8e0e9e50b9489441a50c52ff4 (patch) | |
tree | 7a31d68bbb8d2f04dff22a0de848dfb580df4ff7 /sys/pccard | |
parent | 99455ff0f7319d665313ec3f969a1f2163778d7c (diff) | |
download | FreeBSD-src-9f89acc8ccb787d8e0e9e50b9489441a50c52ff4.zip FreeBSD-src-9f89acc8ccb787d8e0e9e50b9489441a50c52ff4.tar.gz |
Reorganize the attachement point for pcic (it was unattached and
floating before). Attach pccard devices to pcic, one per slot
(although this may change to one per pcic). pcic is now attached to
isa (to act as a bridge) and pccard is attached to pcic, cbb and
pc98ic (the last two are card bus bridge and the pc98ic version of
pcic, neither of which are in the tree yet). Move pccard compat code
into pccard/pccard_compat.c.
THIS REQUIRES A CONFIG FILE CHANGE. You must change your pcic/card
entries to be:
# PCCARD (PCMCIA) support
controller pcic0 at isa?
controller pcic1 at isa?
controller card0
The old system was upside down and this corrects that problem. It
will make it easier to add support for YENTA pccard/card bus bridges.
Much more cleanup needs to happen before newbus devices can have
pccard attachments. My previous commit's comments were premature.
Diffstat (limited to 'sys/pccard')
-rw-r--r-- | sys/pccard/driver.h | 1 | ||||
-rw-r--r-- | sys/pccard/pccard.c | 4 | ||||
-rw-r--r-- | sys/pccard/pccard_nbk.c | 173 | ||||
-rw-r--r-- | sys/pccard/pcic.c | 168 |
4 files changed, 50 insertions, 296 deletions
diff --git a/sys/pccard/driver.h b/sys/pccard/driver.h index 31711d5..4f1ae15 100644 --- a/sys/pccard/driver.h +++ b/sys/pccard/driver.h @@ -17,7 +17,6 @@ int pccard_alloc_intr __P((u_int imask, ointhand2_t *hand, int unit, u_int *maskp, u_int *pcic_imask)); #endif void pccard_remove_driver __P((struct pccard_device *)); -int pcic_probe __P((void)); /* XXX should be linker set */ enum beepstate { BEEP_ON, BEEP_OFF }; diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index e3ad114..0908594 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -504,8 +504,6 @@ pccard_alloc_slot(struct slot_ctrl *ctrl) ctrl->maxmem = NUM_MEM_WINDOWS; if (ctrl->maxio > NUM_IO_WINDOWS) ctrl->maxio = NUM_IO_WINDOWS; - printf("pcic: pccard bridge %s (%d mem & %d I/O windows)\n", - ctrl->name, ctrl->maxmem, ctrl->maxio); } callout_handle_init(&slt->insert_ch); callout_handle_init(&slt->poff_ch); @@ -573,7 +571,7 @@ allocate_driver(struct slot *slt, struct dev_desc *desc) struct pccard_device *drv; device_t pccarddev; char devnam[128]; - int err, irq = 0, s; + int err, irq = 0; pccarddev = devclass_get_device(pccard_devclass, 0); snprintf(devnam, sizeof(devnam), "pccard-%s", desc->name); diff --git a/sys/pccard/pccard_nbk.c b/sys/pccard/pccard_nbk.c index 6c0853a..a10f0e2 100644 --- a/sys/pccard/pccard_nbk.c +++ b/sys/pccard/pccard_nbk.c @@ -86,7 +86,7 @@ pccard_add_children(device_t dev, int busno) static int pccard_probe(device_t dev) { - device_set_desc(dev, "PC Card bus -- KLUDGE version"); + device_set_desc(dev, "PC Card bus -- kludge version"); return pccard_add_children(dev, device_get_unit(dev)); } @@ -162,171 +162,6 @@ static driver_t pccard_driver = { 1, /* no softc */ }; - -DRIVER_MODULE(pccard, nexus, pccard_driver, pccard_devclass, 0, 0); - -/* ============================================================ */ - -static int -pccnbk_probe(device_t dev) -{ - char devnam[128]; - const char *name; - struct pccard_devinfo *devi = device_get_ivars(dev); - - if (devi) { - name = device_get_name(dev); - snprintf(devnam, sizeof(devnam), "pccard-%s", - devi->drv->name); - if (!name || strcmp(name, devnam) != 0) - return ENXIO; - device_set_desc(dev, devi->drv->name); - return 0; - } - return ENXIO; -} - -static int -pccnbk_attach(device_t dev) -{ - struct pccard_devinfo *devi = device_get_ivars(dev); - struct pccard_device *drv; - struct slot *slt; - int err; - int s; - - slt = devi->slt; - drv = devi->drv; - devi->next = slt->devices; - slt->devices = devi; - s = splhigh(); - err = drv->enable(devi); - splx(s); - /* - * If the enable functions returns no error, then the - * device has been successfully installed. If so, then - * attach it to the slot, otherwise free it and return - * the error. We assume that when we free the device, - * it will also set 'running' to off. - */ - if (err) { - printf("pccard: %s%d Enable failed %d\n", devi->drv->name, - devi->isahd.id_unit, err); - pccard_remove_device(devi); - } - return(err); -} - -/* - * Allocate resources for this device in the rman system. - */ -int -pccnbk_alloc_resources(device_t dev) -{ - struct pccard_devinfo *devi = device_get_ivars(dev); - int rid; - u_long start; - u_long end; - u_long count; - - start = devi->isahd.id_iobase; - count = devi->isahd.id_iosize; - end = start + count - 1; - - rid = 0; - devi->iorv = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IOPORT, &rid, start, end, count, RF_ACTIVE); - if (!devi->iorv) { - printf("Cannot allocate ports 0x%lx-0x%lx\n", start, end); - return (ENOMEM); - } - rid = 0; - start = end = ffs(devi->isahd.id_irq) - 1; - count = 1; - devi->irqrv = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IRQ, &rid, start, end, count, RF_ACTIVE); - if (!devi->irqrv) { - return (ENOMEM); - } - return(0); -} - -void -pccnbk_release_resources(device_t dev) -{ - struct pccard_devinfo *devi = device_get_ivars(dev); - u_long start; - u_long end; - u_long count; - - start = devi->isahd.id_iobase; - count = devi->isahd.id_iosize; - end = start + count - 1; - - if (devi->iorv) { - BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, - SYS_RES_IOPORT, 0, devi->iorv); - devi->iorv = NULL; - } - if (devi->irqrv) { - BUS_RELEASE_RESOURCE(device_get_parent(dev), dev, SYS_RES_IRQ, - 0, devi->irqrv); - devi->irqrv = NULL; - } -} - -static device_method_t pccnbk_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, pccnbk_probe), - DEVMETHOD(device_attach, pccnbk_attach), - DEVMETHOD(device_shutdown, bus_generic_shutdown), - DEVMETHOD(device_suspend, bus_generic_suspend), - DEVMETHOD(device_resume, bus_generic_resume), - - /* Bus interface */ - DEVMETHOD(bus_print_child, bus_generic_print_child), - DEVMETHOD(bus_driver_added, bus_generic_driver_added), - DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), - DEVMETHOD(bus_release_resource, bus_generic_release_resource), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), - DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), - DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), - DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), - - { 0, 0 } -}; - -void -pccnbk_wrap_old_driver(struct pccard_device *drv) -{ - char devnam[128]; - char *nm; - driver_t *driver; - - snprintf(devnam, sizeof(devnam), "pccard-%s", drv->name); - driver = malloc(sizeof(driver_t), M_DEVBUF, M_NOWAIT); - if (!driver) - return; - bzero(driver, sizeof(driver_t)); - /* XXX May create a memory leak for load/unload :-( XXX */ - nm = malloc(strlen(devnam) + 1, M_DEVBUF, M_NOWAIT); - strcpy(nm, devnam); - driver->name = nm; - driver->methods = pccnbk_methods; - driver->softc = sizeof(struct pccard_device); - driver->priv = drv; - devclass_add_driver(pccard_devclass, driver); - drv->driver = driver; -} - -#if 0 -static devclass_t pccnbk_devclass; - -static driver_t pccnbk_driver = { - "pccnbk", - pccnbk_methods, - 1, /* no softc */ -}; - -DRIVER_MODULE(pccnbk, pccard, pccnbk_driver, pccnbk_devclass, 0, 0); -#endif +DRIVER_MODULE(pccard, pcic, pccard_driver, pccard_devclass, 0, 0); +DRIVER_MODULE(pccard, pc98pcic, pccard_driver, pccard_devclass, 0, 0); +DRIVER_MODULE(pccard, cbb, pccard_driver, pccard_devclass, 0, 0); diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index e4af972..18ef25b 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -75,11 +75,8 @@ static void pcic_mapirq __P((struct slot *, int)); static timeout_t pcictimeout; static struct callout_handle pcictimeout_ch = CALLOUT_HANDLE_INITIALIZER(&pcictimeout_ch); -static int pcic_modevent __P((module_t, int, void *)); -static int pcic_unload __P((void)); static int pcic_memory(struct slot *, int); static int pcic_io(struct slot *, int); -static u_int build_freelist(u_int); /* * Per-slot data table. @@ -206,84 +203,6 @@ int unregister_pcic_intr(int intr, ointhand2_t handler) #endif /* APIC_IO */ - -/* - * Loadable kernel module interface. - */ - -/* - * Module handler that processes loads and unloads. - * Once the module is loaded, the probe routine - * is called to install the slots (if any). - */ -static int -pcic_modevent(module_t mod, int what, void *arg) -{ - int err = 0; /* default = success*/ - static int pcic_started = 0; - - switch (what) { - case MOD_LOAD: - - /* - * Call the probe routine to find the slots. If - * no slots exist, then don't bother loading the module. - * XXX but this is not appropriate as a static module. - */ - if (pcic_probe()) - pcic_started = 1; - break; - - case MOD_UNLOAD: - /* - * Attempt to unload the slot driver. - */ - if (pcic_started) { - printf("Unloading PCIC driver\n"); - err = pcic_unload(); - pcic_started = 0; - } - break; /* Success*/ - - default: /* we only care about load/unload; ignore shutdown */ - break; - } - - return(err); -} - -static moduledata_t pcic_mod = { - "pcic", - pcic_modevent, - 0 -}; - -/* After configure() has run.. bring on the new bus system! */ -DECLARE_MODULE(pcic, pcic_mod, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE); - -/* - * pcic_unload - Called when unloading a kernel module. - * Disables interrupts and resets PCIC. - */ -static int -pcic_unload() -{ - int slot; - struct pcic_slot *sp = pcic_slots; - - untimeout(pcictimeout, 0, pcictimeout_ch); - if (pcic_irq) { - for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) { - if (sp->slt) - sp->putb(sp, PCIC_STAT_INT, 0); - } - unregister_pcic_intr(pcic_irq, pcicintr); - } - pccard_remove_controller(&cinfo); - return(0); -} - - #if 0 static void pcic_dump_attributes(unsigned char *scratch, int maxlen) @@ -308,43 +227,6 @@ pcic_dump_attributes(unsigned char *scratch, int maxlen) } #endif -static void -nullfunc(int arg) -{ - /* empty */ -} - -static u_int -build_freelist(u_int pcic_mask) -{ - int irq; - u_int mask, freemask; - - /* No free IRQs (yet). */ - freemask = 0; - - /* Walk through all of the IRQ's and find any that aren't allocated. */ - for (irq = 1; irq < ICU_LEN; irq++) { - /* - * If the PCIC controller can't generate it, don't - * bother checking to see if it it's free. - */ - mask = 1 << irq; - if (!(mask & pcic_mask)) continue; - - /* See if the IRQ is free. */ - if (register_pcic_intr(irq, 0, 0, nullfunc, NULL, irq) == 0) { - /* Give it back, but add it to the mask */ - INTRMASK(freemask, mask); - unregister_pcic_intr(irq, nullfunc); - } - } -#ifdef PCIC_DEBUG - printf("Freelist of IRQ's <0x%x>\n", freemask); -#endif - return freemask; -} - /* * entry point from main code to map/unmap memory context. */ @@ -571,18 +453,22 @@ printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win); * of slot 1. Assume it's the only PCIC whose vendor ID is 0x84, * contact Nate Williams <nate@FreeBSD.org> if incorrect. */ -int -pcic_probe(void) +static int +pcic_probe(device_t dev) { int slotnum, validslots = 0; u_int free_irqs, desired_irq; struct slot *slt; struct pcic_slot *sp; unsigned char c; + int i; static int maybe_vlsi = 0; + if (device_get_unit(dev) != 0) + return ENXIO; + /* Determine the list of free interrupts */ - free_irqs = build_freelist(PCIC_INT_MASK_ALLOWED); + free_irqs = PCIC_INT_MASK_ALLOWED; /* * Initialise controller information structure. @@ -749,6 +635,7 @@ pcic_probe(void) cinfo.name = "Unknown!"; break; } + device_set_desc(dev, cinfo.name); /* * OK it seems we have a PCIC or lookalike. * Allocate a slot and initialise the data structures. @@ -765,7 +652,6 @@ pcic_probe(void) * then attempt to get one. */ if (pcic_irq == 0) { - pcic_imask = soft_imask; /* See if the user has requested a specific IRQ */ @@ -851,7 +737,12 @@ pcic_probe(void) #endif /* PC98 */ if (validslots && pcic_irq <= 0) pcictimeout_ch = timeout(pcictimeout, 0, hz/2); - return(validslots); + if (validslots) { + for (i = 0; i < validslots; i++) { + device_add_child(dev, NULL, -1, NULL); + } + } + return(validslots ? 0 : ENXIO); } /* @@ -1181,3 +1072,34 @@ pcic_resume(struct slot *slt) setb(sp, PCIC_MISC2, PCIC_LPDM_EN); } } + +static device_method_t pcic_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, pcic_probe), + DEVMETHOD(device_attach, bus_generic_attach), + DEVMETHOD(device_detach, bus_generic_detach), + DEVMETHOD(device_shutdown, bus_generic_shutdown), + DEVMETHOD(device_suspend, bus_generic_suspend), + DEVMETHOD(device_resume, bus_generic_resume), + + /* Bus interface */ + DEVMETHOD(bus_print_child, bus_generic_print_child), + DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource), + DEVMETHOD(bus_release_resource, bus_generic_release_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), + DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), + DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), + DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), + + { 0, 0 } +}; + +devclass_t pcic_devclass; + +static driver_t pcic_driver = { + "pcic", + pcic_methods, + 1, /* no softc */ +}; + +DRIVER_MODULE(pcic, isa, pcic_driver, pcic_devclass, 0, 0); |