diff options
author | imp <imp@FreeBSD.org> | 1999-10-25 02:41:58 +0000 |
---|---|---|
committer | imp <imp@FreeBSD.org> | 1999-10-25 02:41:58 +0000 |
commit | b3ebae016a5c532ef50c367a058d394d04b05029 (patch) | |
tree | f08c2d0c060a6858fd722931d6a11acad72b8933 | |
parent | 5c654c474375626efab60ddf5d5bf9098b8f7337 (diff) | |
download | FreeBSD-src-b3ebae016a5c532ef50c367a058d394d04b05029.zip FreeBSD-src-b3ebae016a5c532ef50c367a058d394d04b05029.tar.gz |
Massive rewrite of pccard to convert it to newbus.
o Gut the compatibility interface, you now must attach with newbus.
o Unit numbers from pccardd are now ignored. This may change the units
assigned to a card. It now uses the first available unit.
o kill old skeleton code that is now obsolete.
o Use newbus attachment code.
o cleanup interfile dependencies some.
o kill list of devices per slot. we use the device tree for what we need.
o Remove now obsolete code.
o The ep driver (and maybe ed) may need some config file tweaks to
allow it to attach. See config files that were committed for examples
on how to do this.
Drivers to be commited shortly.
This is an interrum fix until the new pccard. ed, ep and sio will be
supported by me with this release, although others are welcome to try
to support other devices before new pccard is working.
I plan on doing minimal further work on this code base. Be careful
when upgrading, since this code is known to work on my laptop and
those of a couple others as well, but your milage may vary.
BUGS TO BE FIXED:
o system memory isn't allocated yet, it will be soon.
o No devices actually have a pccard newbus attach in the tree.
BUGS THAT MIGHT BE FIXED:
o card removal, including suspend, usually hangs the system.
Many thanks to Peter Wemm and Doug Rabson for helping me to fill in
the missing bits of New Bus understanding at FreeBSD Con '99.
-rw-r--r-- | sys/amd64/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/conf/NOTES | 1 | ||||
-rw-r--r-- | sys/conf/files | 1 | ||||
-rw-r--r-- | sys/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/i386/conf/GENERIC | 3 | ||||
-rw-r--r-- | sys/i386/conf/LINT | 1 | ||||
-rw-r--r-- | sys/i386/conf/NOTES | 1 | ||||
-rw-r--r-- | sys/i386/conf/PCCARD | 4 | ||||
-rw-r--r-- | sys/i386/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/pccard/driver.h | 5 | ||||
-rw-r--r-- | sys/pccard/pccard.c | 443 | ||||
-rw-r--r-- | sys/pccard/pccard_compat.c | 218 | ||||
-rw-r--r-- | sys/pccard/pccard_nbk.c | 176 | ||||
-rw-r--r-- | sys/pccard/pccard_nbk.h | 6 | ||||
-rw-r--r-- | sys/pccard/pcic.c | 427 | ||||
-rw-r--r-- | sys/pccard/pcic.h | 14 | ||||
-rw-r--r-- | sys/pccard/skel.c | 98 | ||||
-rw-r--r-- | sys/pccard/slot.h | 57 |
18 files changed, 338 insertions, 1126 deletions
diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 7d1c9db..356abb0 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -183,6 +183,9 @@ device xl0 # 3Com 3c90x (``Boomerang'', ``Cyclone'') # The probe order of these is presently determined by i386/isa/isa_compat.c. device ed0 at isa? port 0x280 irq 10 iomem 0xd8000 device ie0 at isa? port 0x300 irq 10 iomem 0xd0000 +# NOTE: if you configure ep0 for pccard, use +# device ep0 +# instead. device ep0 at isa? port 0x300 irq 10 device ex0 at isa? port? irq? device fe0 at isa? port 0x300 irq ? diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 4b0c075..765ee6f 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -1259,6 +1259,7 @@ device cs0 at isa? port 0x300 irq ? device cx0 at isa? port 0x240 irq 15 drq 7 device ed0 at isa? port 0x280 irq 5 iomem 0xd8000 device el0 at isa? port 0x300 irq 9 +# for pccard support of ep0, omit all after at in following line. device ep0 at isa? port 0x300 irq 10 device ex0 at isa? port? irq? device fe0 at isa? port 0x300 irq ? diff --git a/sys/conf/files b/sys/conf/files index 19cdb43..5d8ee41 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -658,7 +658,6 @@ nwfs/nwfs_vnops.c optional nwfs pccard/pccard.c optional card pccard/pccard_beep.c optional card pccard/pccard_nbk.c optional card -pccard/pccard_compat.c optional card pccard/pcic.c optional pcic pci/amd.c optional amd pci/pcic_p.c optional pcic pci diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 5c01331..bf5ec5d 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -59,7 +59,7 @@ dev/ata/atapi-fd.c optional atapifd dev/ata/atapi-tape.c optional atapist dev/ed/if_ed.c optional ed dev/ed/if_ed_isa.c optional ed isa -#dev/ed/if_ed_pccard.c optional ed card +dev/ed/if_ed_pccard.c optional ed card dev/fb/fb.c optional fb dev/fb/fb.c optional vga dev/fb/splash.c optional splash @@ -207,6 +207,7 @@ i386/isa/if_rdp.c optional rdp i386/isa/if_sr.c optional sr i386/isa/if_wi.c optional wi i386/isa/if_wl.c optional wl +i386/isa/if_wlp.c optional wlp i386/isa/if_ze.c optional ze i386/isa/if_zp.c optional zp i386/isa/intr_machdep.c standard diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index 7d1c9db..356abb0 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -183,6 +183,9 @@ device xl0 # 3Com 3c90x (``Boomerang'', ``Cyclone'') # The probe order of these is presently determined by i386/isa/isa_compat.c. device ed0 at isa? port 0x280 irq 10 iomem 0xd8000 device ie0 at isa? port 0x300 irq 10 iomem 0xd0000 +# NOTE: if you configure ep0 for pccard, use +# device ep0 +# instead. device ep0 at isa? port 0x300 irq 10 device ex0 at isa? port? irq? device fe0 at isa? port 0x300 irq ? diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT index 4b0c075..765ee6f 100644 --- a/sys/i386/conf/LINT +++ b/sys/i386/conf/LINT @@ -1259,6 +1259,7 @@ device cs0 at isa? port 0x300 irq ? device cx0 at isa? port 0x240 irq 15 drq 7 device ed0 at isa? port 0x280 irq 5 iomem 0xd8000 device el0 at isa? port 0x300 irq 9 +# for pccard support of ep0, omit all after at in following line. device ep0 at isa? port 0x300 irq 10 device ex0 at isa? port? irq? device fe0 at isa? port 0x300 irq ? diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index 4b0c075..765ee6f 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -1259,6 +1259,7 @@ device cs0 at isa? port 0x300 irq ? device cx0 at isa? port 0x240 irq 15 drq 7 device ed0 at isa? port 0x280 irq 5 iomem 0xd8000 device el0 at isa? port 0x300 irq 9 +# for pccard support of ep0, omit all after at in following line. device ep0 at isa? port 0x300 irq 10 device ex0 at isa? port? irq? device fe0 at isa? port 0x300 irq ? diff --git a/sys/i386/conf/PCCARD b/sys/i386/conf/PCCARD index 3e53aba..62cfcd9 100644 --- a/sys/i386/conf/PCCARD +++ b/sys/i386/conf/PCCARD @@ -182,7 +182,9 @@ device xl0 # 3Com 3c90x (``Boomerang'', ``Cyclone'') # The probe order of these is presently determined by i386/isa/isa_compat.c. device ed0 at isa? port 0x280 irq 10 iomem 0xd8000 device ie0 at isa? port 0x300 irq 10 iomem 0xd0000 -device ep0 at isa? port 0x300 irq 10 +# NOTE: This removes the isa attachment so that the pccard unit numbers +# come out right. +device ep0 device ex0 at isa? port? irq? device fe0 at isa? port 0x300 irq ? device le0 at isa? port 0x300 irq 5 iomem 0xd0000 diff --git a/sys/i386/conf/files.i386 b/sys/i386/conf/files.i386 index 5c01331..bf5ec5d 100644 --- a/sys/i386/conf/files.i386 +++ b/sys/i386/conf/files.i386 @@ -59,7 +59,7 @@ dev/ata/atapi-fd.c optional atapifd dev/ata/atapi-tape.c optional atapist dev/ed/if_ed.c optional ed dev/ed/if_ed_isa.c optional ed isa -#dev/ed/if_ed_pccard.c optional ed card +dev/ed/if_ed_pccard.c optional ed card dev/fb/fb.c optional fb dev/fb/fb.c optional vga dev/fb/splash.c optional splash @@ -207,6 +207,7 @@ i386/isa/if_rdp.c optional rdp i386/isa/if_sr.c optional sr i386/isa/if_wi.c optional wi i386/isa/if_wl.c optional wl +i386/isa/if_wlp.c optional wlp i386/isa/if_ze.c optional ze i386/isa/if_zp.c optional zp i386/isa/intr_machdep.c standard diff --git a/sys/pccard/driver.h b/sys/pccard/driver.h index 4f1ae15..1cd030b 100644 --- a/sys/pccard/driver.h +++ b/sys/pccard/driver.h @@ -12,11 +12,6 @@ struct pccard_device; void pccard_add_driver __P((struct pccard_device *)); -#ifdef _I386_ISA_ISA_DEVICE_H_ /* XXX actually if ointhand2_t is declared */ -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 *)); enum beepstate { BEEP_ON, BEEP_OFF }; diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index 44c6993..111ae3b 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -95,16 +95,10 @@ SYSCTL_INT(_machdep_pccard, OID_AUTO, pcic_resume_reset, CTLFLAG_RW, static int allocate_driver(struct slot *, struct dev_desc *); static void inserted(void *); -static void unregister_device_interrupt(struct pccard_devinfo *); static void disable_slot(struct slot *); static int invalid_io_memory(unsigned long, int); -static struct pccard_device *find_driver(char *); -static ointhand2_t slot_irq_handler; static void power_off_slot(void *); -static void pccard_configure(void *); -SYSINIT(pccard, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE + 1, pccard_configure, NULL); - #if NAPM > 0 /* * For the APM stuff, the apmhook structure is kept @@ -121,7 +115,6 @@ static struct apmhook r_hook[MAXSLOT]; /* APM resume */ static struct slot *pccard_slots[MAXSLOT]; /* slot entries */ static struct slot *slot_list; static struct slot_ctrl *cont_list; -static struct pccard_device *drivers; /* Card drivers */ /* * The driver interface for read/write uses a block @@ -156,173 +149,6 @@ static struct cdevsw crd_cdevsw = { /* bmaj */ -1 }; - -/* - * pccard_configure - called by autoconf code. - * Probes for various PC-CARD controllers, and - * initialises data structures to point to the - * various slots. - * - * Each controller indicates the number of slots - * that it sees, and these are mapped to a master - * slot number accessed via the character device entries. - * - * XXX this is a relic. Each controller has it's own probe - * configuration hook. Printing a list of configured devices - * with pccard support probably isn't all that useful. - */ -static void -pccard_configure(dummy) - void *dummy; -{ - struct pccard_device *drv; - - /* This isn't strictly correct, but works because of initialize order */ - printf("pccard: initalizing drivers:"); - for (drv = drivers; drv != NULL; drv = drv->next) { - pccnbk_wrap_old_driver(drv); - printf(" %s", drv->name); - } - cdevsw_add(&crd_cdevsw); - printf("\n"); -} - -int -pccard_module_handler(module_t mod, int what, void *arg) -{ - struct pccard_device *drv = (struct pccard_device *)arg; - - switch(what) { - case MOD_LOAD: - pccard_add_driver(drv); - break; - case MOD_UNLOAD: - pccard_remove_driver(drv); - break; - default: - break; - } - return 0; -} - -/* - * pccard_add_driver - Add a new driver to the list of - * drivers available for allocation. - */ -void -pccard_add_driver(struct pccard_device *drv) -{ - /* - * If already loaded, then reject the driver. - */ - if (find_driver(drv->name)) { - printf("pccard: driver %s already loaded\n", drv->name); - return; - } - drv->next = drivers; - drivers = drv; -} - -/* - * pccard_remove_driver - called to unlink driver - * from devices. Usually called when drivers are - * unloaded from kernel. - */ -void -pccard_remove_driver(struct pccard_device *drv) -{ - struct slot *slt; - struct pccard_devinfo *devi, *next; - struct pccard_device *drvlist; - - for (slt = slot_list; slt; slt = slt->next) - for (devi = slt->devices; devi; devi = next) { - next = devi->next; - if (devi->drv == drv) - pccard_remove_device(devi); - } - /* - * Once all the devices belonging to this driver have been - * freed, then remove the driver from the list - * of registered drivers. - */ - if (drivers == drv) - drivers = drv->next; - else - for (drvlist = drivers; drvlist->next; drvlist = drvlist->next) - if (drvlist->next == drv) { - drvlist->next = drv->next; - break; - } -} - -/* - * pccard_remove_controller - Called when the slot - * driver is unloaded. The plan is to unload - * drivers from the slots, and then remove the - * slots from the slot list, and then finally - * remove the controller structure. Messy... - */ -void -pccard_remove_controller(struct slot_ctrl *ctrl) -{ - struct slot *slt, *next, *last = 0; - struct slot_ctrl *cl; - struct pccard_devinfo *devi; - - for (slt = slot_list; slt; slt = next) { - next = slt->next; - /* - * If this slot belongs to this controller, - * remove this slot. - */ - if (slt->ctrl == ctrl) { - pccard_slots[slt->slotnum] = 0; - if (slt->insert_seq) - untimeout(inserted, (void *)slt, slt->insert_ch); - /* - * Unload the drivers attached to this slot. - */ - while ((devi = slt->devices) != NULL) - pccard_remove_device(devi); - /* - * Disable the slot and unlink the slot from the - * slot list. - */ - disable_slot(slt); - if (last) - last->next = next; - else - slot_list = next; -#if NAPM > 0 - apm_hook_disestablish(APM_HOOK_SUSPEND, - &s_hook[slt->slotnum]); - apm_hook_disestablish(APM_HOOK_RESUME, - &r_hook[slt->slotnum]); -#endif - if (ctrl->extra && slt->cdata) - FREE(slt->cdata, M_DEVBUF); - FREE(slt, M_DEVBUF); - /* - * Can't use slot after we have freed it. - */ - } else { - last = slt; - } - } - /* - * Unlink controller structure from controller list. - */ - if (cont_list == ctrl) - cont_list = ctrl->next; - else - for (cl = cont_list; cl->next; cl = cl->next) - if (cl->next == ctrl) { - cl->next = ctrl->next; - break; - } -} - /* * Power off the slot. * (doing it immediately makes the removal of some cards unstable) @@ -331,39 +157,19 @@ static void power_off_slot(void *arg) { struct slot *slt = (struct slot *)arg; + int s; + /* + * The following will generate an interrupt. So, to hold off + * the interrupt unitl after disable runs so that we can get rid + * rid of the interrupt before it becomes unsafe to touch the + * device. + */ + s = splhigh(); /* Power off the slot. */ slt->pwr_off_pending = 0; slt->ctrl->disable(slt); -} - -/* - * unregister_device_interrupt - Disable the interrupt generation to - * the device driver which is handling it, so we can remove it. - */ -static void -unregister_device_interrupt(struct pccard_devinfo *devi) -{ - struct slot *slt = devi->slt; - int s; - - if (devi->running) { - s = splhigh(); - devi->drv->disable(devi); - devi->running = 0; - if (devi->isahd.id_irq && --slt->irqref <= 0) { - slt->ctrl->mapirq(slt, 0); - INTRDIS(1<<slt->irq); - unregister_pcic_intr(slt->irq, slot_irq_handler); - if (devi->drv->imask) - INTRUNMASK(*devi->drv->imask,(1<<slt->irq)); - /* Remove from the PCIC controller imask */ - if (slt->ctrl->imask) - INTRUNMASK(*(slt->ctrl->imask), (1<<slt->irq)); - slt->irq = 0; - } - splx(s); - } + splx(s); } /* @@ -390,9 +196,7 @@ disable_slot(struct slot *slt) */ pccarddev = devclass_get_device(pccard_devclass, 0); for (devi = slt->devices; devi; devi = devi->next) { - unregister_device_interrupt(devi); if (devi->isahd.id_device != 0) { - pccnbk_release_resources(devi->isahd.id_device); device_delete_child(pccarddev, devi->isahd.id_device); devi->isahd.id_device = 0; } @@ -408,11 +212,6 @@ disable_slot(struct slot *slt) slt->mem[i].flags = 0; (void)slt->ctrl->mapmem(slt, i); } - for (i = 0; i < slt->ctrl->maxio; i++) - if (slt->io[i].flags & IODF_ACTIVE) { - slt->io[i].flags = 0; - (void)slt->ctrl->mapio(slt, i); - } } /* @@ -427,6 +226,7 @@ slot_suspend(void *arg) /* This code stolen from pccard_event:card_removed */ if (slt->state == filled) { int s = splhigh(); +printf("splhigh -- slot_suspend\n"); disable_slot(slt); slt->laststate = filled; slt->state = suspend; @@ -529,35 +329,36 @@ pccard_alloc_slot(struct slot_ctrl *ctrl) } /* - * pccard_alloc_intr - allocate an interrupt from the - * free interrupts and return its number. The interrupts - * allowed are passed as a mask. + * Allocate resources for this device in the rman system. */ -int -pccard_alloc_intr(u_int imask, ointhand2_t *hand, int unit, - u_int *maskp, u_int *pcic_imask) +static int +pccard_alloc_resources(device_t dev) { - int irq; - unsigned int mask; - - for (irq = 1; irq < ICU_LEN; irq++) { - mask = 1ul << irq; - if (!(mask & imask)) - continue; - INTRMASK(*maskp, mask); - if (register_pcic_intr(irq, unit, 0, hand, maskp, unit) == 0) { - /* add this to the PCIC controller's mask */ - if (pcic_imask) - INTRMASK(*pcic_imask, (1 << irq)); - update_intr_masks(); - INTREN(mask); - return(irq); - } - /* No luck, remove from mask again... */ - INTRUNMASK(*maskp, mask); - update_intr_masks(); + /* XXX NEED TO DO MEMORY TOO XXX */ + struct pccard_devinfo *devi = device_get_ivars(dev); + int rid; + u_long start; + u_long count; + int e; + + start = devi->isahd.id_iobase; + count = devi->isahd.id_iosize; + + rid = 0; + e = bus_set_resource(dev, SYS_RES_IOPORT, rid, start, count); + if (e) { + printf("ioport error %d\n", e); + return e; + } + rid = 0; + start = ffs(devi->isahd.id_irq) - 1; + count = 1; + e = bus_set_resource(dev, SYS_RES_IRQ, rid, start, count); + if (e) { + printf("irq error %d\n", e); + return e; } - return(-1); + return(0); } /* @@ -568,80 +369,20 @@ static int allocate_driver(struct slot *slt, struct dev_desc *desc) { struct pccard_devinfo *devi; - struct pccard_device *drv; device_t pccarddev; - char devnam[128]; int err, irq = 0; + device_t child; pccarddev = devclass_get_device(pccard_devclass, 0); - snprintf(devnam, sizeof(devnam), "pccard-%s", desc->name); - drv = find_driver(desc->name); - if (drv == 0) - return(ENXIO); - /* - * If an instance of this driver is already installed, - * but not running, then remove it. If it is running, - * then reject the request. - */ - for (devi = slt->devices; devi; devi = devi->next) { - if (devi->drv == drv && devi->isahd.id_unit == desc->unit) { - if (devi->running) { - printf("pccard: %s%d still running\n", - devi->drv->name, desc->unit); - return(EBUSY); - } - pccard_remove_device(devi); - break; - } - } - /* - * If an interrupt mask has been given, then check it - * against the slot interrupt (if one has been allocated). - */ - if (desc->irqmask && drv->imask) { - if ((slt->ctrl->irqs & desc->irqmask) == 0) { - printf("pccard: PIOCSDRV requested irq (mask 0x%x) is " - "not free (available mask 0x%x)\n", desc->irqmask, - slt->ctrl->irqs); - return(EINVAL); - } - if (slt->irq) { - if (((1 << slt->irq) & desc->irqmask) == 0) { - printf("pccard: PIOSCDRIV irq %d not in " - "available mask 0x%x\n", slt->irq, - desc->irqmask); - return(EINVAL); - } - slt->irqref++; - irq = slt->irq; - } else { - /* - * Attempt to allocate an interrupt. - * XXX We lose at the moment if the second - * device relies on a different interrupt mask. - */ - irq = pccard_alloc_intr(desc->irqmask, - slot_irq_handler, (int)slt, - drv->imask, slt->ctrl->imask); - if (irq < 0) { - printf("pccard: alloc intr failed irq %d\n", - irq); - return(EINVAL); - } - slt->irq = irq; - slt->irqref = 1; - slt->ctrl->mapirq(slt, slt->irq); - } - } + irq = ffs(desc->irqmask) - 1; MALLOC(devi, struct pccard_devinfo *, sizeof(*devi), M_DEVBUF, M_WAITOK); bzero(devi, sizeof(*devi)); + strcpy(devi->name, desc->name); /* * Create an entry for the device under this slot. */ devi->running = 1; - devi->drv = drv; devi->slt = slt; - devi->isahd.id_irq = irq; devi->isahd.id_unit = desc->unit; devi->isahd.id_msize = desc->memsize; devi->isahd.id_iobase = desc->iobase; @@ -661,52 +402,18 @@ allocate_driver(struct slot *slt, struct dev_desc *desc) /* * XXX I think the following should be done in an attach * routine, but can't seem to slip the knot to get it working - * right. This is one reason I call this a kludge + * right. This is one reason I call this a kludge... */ - devi->isahd.id_device = device_add_child(pccarddev, devnam, + resource_list_init(&devi->resources); + child = devi->isahd.id_device = device_add_child(pccarddev, devi->name, devi->isahd.id_unit, devi); - if ((err = pccnbk_alloc_resources(devi->isahd.id_device)) != 0) { - device_delete_child(pccarddev, devi->isahd.id_device); - devi->isahd.id_device = 0; - free(devi, M_DEVBUF); - return(err); - } - err = device_probe_and_attach(devi->isahd.id_device); + pccard_alloc_resources(child); + err = device_probe_and_attach(child); + if (err) + device_delete_child(pccarddev, child); return err; } -void -pccard_remove_device(struct pccard_devinfo *devi) -{ - struct slot *slt = devi->slt; - struct pccard_devinfo *list; - - /* - * If an interrupt is enabled on this slot, - * then unregister it if no-one else is using it. - */ - unregister_device_interrupt(devi); - if (devi->isahd.id_device) - pccnbk_release_resources(devi->isahd.id_device); - devi->isahd.id_device = NULL; - - /* - * Remove from device list on this slot. - */ - if (slt->devices == devi) - slt->devices = devi->next; - else - for (list = slt->devices; list->next; list = list->next) - if (list->next == devi) { - list->next = devi->next; - break; - } - /* - * Finally, free the memory space. - */ - FREE(devi, M_DEVBUF); -} - /* * card insert routine - Called from a timeout to debounce * insertion events. @@ -758,6 +465,7 @@ pccard_event(struct slot *slt, enum card_event event) */ if (slt->state == filled) { int s = splhigh(); +printf("splhigh card_removed\n"); disable_slot(slt); slt->state = empty; splx(s); @@ -775,32 +483,6 @@ pccard_event(struct slot *slt, enum card_event event) } /* - * slot_irq_handler - Interrupt handler for shared irq devices. - */ -static void -slot_irq_handler(int arg) -{ - struct pccard_devinfo *devi; - struct slot *slt = (struct slot *)arg; - - /* - * For each device that has the shared interrupt, - * call the interrupt handler. If the interrupt was - * caught, the handler returns true. - */ - for (devi = slt->devices; devi; devi = devi->next) - if (devi->isahd.id_irq && devi->running && - devi->drv->handler(devi)) - return; - /* - * XXX - Should 'debounce' these for drivers that have recently - * been removed. - */ - printf("pccard: slot %d, unfielded interrupt (%d)\n", slt->slotnum, - slt->irq); -} - -/* * Device driver interface. */ static int @@ -853,10 +535,6 @@ crdread(dev_t dev, struct uio *uio, int ioflag) mp = &slt->mem[win]; oldmap = *mp; mp->flags = slt->rwmem|MDF_ACTIVE; -#if 0 - printf("Rd at offs %d, size %d\n", (int)uio->uio_offset, - uio->uio_resid); -#endif while (uio->uio_resid && error == 0) { mp->card = uio->uio_offset; mp->size = PCCARD_MEMSIZE; @@ -896,17 +574,13 @@ crdwrite(dev_t dev, struct uio *uio, int ioflag) if (pccard_mem == 0) return(ENOMEM); for (win = 0; win < slt->ctrl->maxmem; win++) - if ((slt->mem[win].flags & MDF_ACTIVE)==0) + if ((slt->mem[win].flags & MDF_ACTIVE) == 0) break; if (win >= slt->ctrl->maxmem) return(EBUSY); mp = &slt->mem[win]; oldmap = *mp; mp->flags = slt->rwmem|MDF_ACTIVE; -#if 0 - printf("Wr at offs %d, size %d\n", (int)uio->uio_offset, - uio->uio_resid); -#endif while (uio->uio_resid && error == 0) { mp->card = uio->uio_offset; mp->size = PCCARD_MEMSIZE; @@ -916,9 +590,6 @@ crdwrite(dev_t dev, struct uio *uio, int ioflag) offs = (unsigned int)uio->uio_offset & (PCCARD_MEMSIZE - 1); p = pccard_kmem + offs; count = MIN(PCCARD_MEMSIZE - offs, uio->uio_resid); -#if 0 - printf("Writing %d bytes to address 0x%x\n", count, p); -#endif error = uiomove(p, count, uio); } /* @@ -963,7 +634,7 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) splx(s); ((struct slotstate *)data)->maxmem = slt->ctrl->maxmem; ((struct slotstate *)data)->maxio = slt->ctrl->maxio; - ((struct slotstate *)data)->irqs = slt->ctrl->irqs; + ((struct slotstate *)data)->irqs = 0; break; /* * Get memory context. @@ -1017,7 +688,8 @@ crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, struct proc *p) if (s < 0 || s >= slt->ctrl->maxio) return(EINVAL); slt->io[s] = *((struct io_desc *)data); - return(slt->ctrl->mapio(slt, s)); + /* XXX Don't actually map */ + return 0; break; /* * Set memory window flags for read/write interface. @@ -1126,14 +798,3 @@ invalid_io_memory(unsigned long adr, int size) return(1); return(0); } - -static struct pccard_device * -find_driver(char *name) -{ - struct pccard_device *drv; - - for (drv = drivers; drv; drv = drv->next) - if (strcmp(drv->name, name)==0) - return(drv); - return(0); -} diff --git a/sys/pccard/pccard_compat.c b/sys/pccard/pccard_compat.c deleted file mode 100644 index 9bc435a..0000000 --- a/sys/pccard/pccard_compat.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 1999, M. Warner Losh. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include "opt_bus.h" - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/module.h> -#include <sys/fcntl.h> -#include <sys/conf.h> -#include <sys/kernel.h> -#include <sys/queue.h> -#include <sys/select.h> -#include <sys/types.h> - -#include <sys/bus.h> -#include <machine/bus.h> -#include <sys/rman.h> -#include <machine/resource.h> - -#include <i386/isa/isa_device.h> -#include <pccard/cardinfo.h> -#include <pccard/driver.h> -#include <pccard/pcic.h> -#include <pccard/slot.h> -#include <pccard/pccard_nbk.h> - -/* ============================================================ */ - -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 diff --git a/sys/pccard/pccard_nbk.c b/sys/pccard/pccard_nbk.c index a10f0e2..1fc9bee 100644 --- a/sys/pccard/pccard_nbk.c +++ b/sys/pccard/pccard_nbk.c @@ -76,6 +76,11 @@ devclass_t pccard_devclass; +#define PCCARD_NPORT 2 +#define PCCARD_NMEM 5 +#define PCCARD_NIRQ 1 +#define PCCARD_NDRQ 0 + static int pccard_add_children(device_t dev, int busno) { @@ -90,28 +95,54 @@ pccard_probe(device_t dev) return pccard_add_children(dev, device_get_unit(dev)); } +static void +pccard_print_resources(struct resource_list *rl, const char *name, int type, + int count, const char *format) +{ + struct resource_list_entry *rle; + int printed; + int i; + + printed = 0; + for (i = 0; i < count; i++) { + rle = resource_list_find(rl, type, i); + if (rle) { + if (printed == 0) + printf(" %s ", name); + else if (printed > 0) + printf(","); + printed++; + printf(format, rle->start); + if (rle->count > 1) { + printf("-"); + printf(format, rle->start + rle->count - 1); + } + } else if (i > 3) { + /* check the first few regardless */ + break; + } + } +} + static int pccard_print_child(device_t dev, device_t child) { struct pccard_devinfo *devi = device_get_ivars(child); + struct resource_list *rl = &devi->resources; int retval = 0; retval += bus_print_child_header(dev, child); retval += printf(" at"); if (devi) { - if (devi->iorv) { - retval += printf(" port 0x%lx", - rman_get_start(devi->iorv)); - if (rman_get_start(devi->iorv) != - rman_get_end(devi->iorv)) - retval += printf("-0x%lx", - rman_get_end(devi->iorv)); - } - if (devi->irqrv) { - retval += printf(" irq %ld", - rman_get_start(devi->irqrv)); - } + pccard_print_resources(rl, "port", SYS_RES_IOPORT, + PCCARD_NPORT, "%#lx"); + pccard_print_resources(rl, "iomem", SYS_RES_MEMORY, + PCCARD_NMEM, "%#lx"); + pccard_print_resources(rl, "irq", SYS_RES_IRQ, PCCARD_NIRQ, + "%ld"); + pccard_print_resources(rl, "drq", SYS_RES_DRQ, PCCARD_NDRQ, + "%ld"); retval += printf(" slot %d", devi->slt->slotnum); } @@ -120,22 +151,116 @@ pccard_print_child(device_t dev, device_t child) return (retval); } -/* - * Create "connection point" - */ +static int +pccard_set_resource(device_t dev, device_t child, int type, int rid, + u_long start, u_long count) +{ + struct pccard_devinfo *devi = device_get_ivars(child); + struct resource_list *rl = &devi->resources; + + if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY + && type != SYS_RES_IRQ && type != SYS_RES_DRQ) + return EINVAL; + if (rid < 0) + return EINVAL; + if (type == SYS_RES_IOPORT && rid >= PCCARD_NPORT) + return EINVAL; + if (type == SYS_RES_MEMORY && rid >= PCCARD_NMEM) + return EINVAL; + if (type == SYS_RES_IRQ && rid >= PCCARD_NIRQ) + return EINVAL; + if (type == SYS_RES_DRQ && rid >= PCCARD_NDRQ) + return EINVAL; + + resource_list_add(rl, type, rid, start, start + count - 1, count); + + return 0; +} + +static int +pccard_get_resource(device_t dev, device_t child, int type, int rid, + u_long *startp, u_long *countp) +{ + struct pccard_devinfo *devi = device_get_ivars(child); + struct resource_list *rl = &devi->resources; + struct resource_list_entry *rle; + + rle = resource_list_find(rl, type, rid); + if (!rle) + return ENOENT; + + *startp = rle->start; + *countp = rle->count; + + return 0; +} + static void -pccard_identify(driver_t *driver, device_t parent) +pccard_delete_resource(device_t dev, device_t child, int type, int rid) { - device_t child; + struct pccard_devinfo *devi = device_get_ivars(child); + struct resource_list *rl = &devi->resources; + resource_list_delete(rl, type, rid); +} - child = BUS_ADD_CHILD(parent, 0, "pccard", 0); - if (child == NULL) - panic("pccard_identify"); +static struct resource * +pccard_alloc_resource(device_t bus, device_t child, int type, int *rid, + u_long start, u_long end, u_long count, u_int flags) +{ + /* + * Consider adding a resource definition. We allow rid 0 for + * irq, 0-3 for memory and 0-1 for ports + */ + int passthrough = (device_get_parent(child) != bus); + int isdefault = (start == 0UL && end == ~0UL); + struct pccard_devinfo *devi = device_get_ivars(child); + struct resource_list *rl = &devi->resources; + struct resource_list_entry *rle; + + if (!passthrough && !isdefault) { + rle = resource_list_find(rl, type, *rid); + if (!rle) { + if (*rid < 0) + return 0; + switch (type) { + case SYS_RES_IRQ: + if (*rid >= PCCARD_NIRQ) + return 0; + break; + case SYS_RES_DRQ: + if (*rid >= PCCARD_NDRQ) + return 0; + break; + case SYS_RES_MEMORY: + if (*rid >= PCCARD_NMEM) + return 0; + break; + case SYS_RES_IOPORT: + if (*rid >= PCCARD_NPORT) + return 0; + break; + default: + return 0; + } + resource_list_add(rl, type, *rid, start, end, count); + } + } + + return resource_list_alloc(rl, bus, child, type, rid, + start, end, count, flags); +} + +static int +pccard_release_resource(device_t bus, device_t child, int type, int rid, + struct resource *r) +{ + struct pccard_devinfo *devi = device_get_ivars(child); + struct resource_list *rl = &devi->resources; + return resource_list_release(rl, bus, child, type, rid, r); } static device_method_t pccard_methods[] = { /* Device interface */ - DEVMETHOD(device_identify, pccard_identify), DEVMETHOD(device_probe, pccard_probe), DEVMETHOD(device_attach, bus_generic_attach), DEVMETHOD(device_shutdown, bus_generic_shutdown), @@ -144,14 +269,17 @@ static device_method_t pccard_methods[] = { /* Bus interface */ DEVMETHOD(bus_print_child, pccard_print_child), -/* DEVMETHOD(bus_probe_nomatch, pccard_probe_nomatch),*/ 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_alloc_resource, pccard_alloc_resource), + DEVMETHOD(bus_release_resource, pccard_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), + DEVMETHOD(bus_set_resource, pccard_set_resource), + DEVMETHOD(bus_get_resource, pccard_get_resource), + DEVMETHOD(bus_delete_resource, pccard_delete_resource), + { 0, 0 } }; diff --git a/sys/pccard/pccard_nbk.h b/sys/pccard/pccard_nbk.h index 971191e..bf0a20c 100644 --- a/sys/pccard/pccard_nbk.h +++ b/sys/pccard/pccard_nbk.h @@ -31,11 +31,5 @@ struct pccard_device; extern devclass_t pccard_devclass; -extern int pccnbk_alloc_resources(device_t); -extern void pccnbk_release_resources(device_t); -extern void pccnbk_wrap_old_driver(struct pccard_device *); - -/* kludges */ -extern void pccard_remove_device(struct pccard_devinfo *); #endif /* ! PCCARD_PCCARD_NBK_H */ diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index 1d8f39a..e186403 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -30,11 +30,6 @@ * $FreeBSD$ */ -/* - * pcic98 : PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L. - * by Noriyuki Hosobuchi <yj8n-hsbc@asahi-net.or.jp> - */ - #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> @@ -44,14 +39,13 @@ #include <machine/clock.h> +#if 0 #include <i386/isa/icu.h> #include <i386/isa/isa_device.h> #include <i386/isa/intr_machdep.h> +#endif #include <pccard/i82365.h> -#ifdef PC98 -#include <pccard/pcic98reg.h> -#endif #include <pccard/cardinfo.h> #include <pccard/driver.h> @@ -95,7 +89,6 @@ static struct pcic_slot { } pcic_slots[PCIC_MAX_SLOTS]; static int pcic_irq; -static unsigned pcic_imask; static struct slot_ctrl cinfo; @@ -112,12 +105,6 @@ getb1(struct pcic_slot *sp, int reg) return inb(sp->data); } -static __inline unsigned char -getb2(struct pcic_slot *sp, int reg) -{ - return (sp->regs[reg]); -} - /* * Write a register on the PCIC */ @@ -128,12 +115,6 @@ putb1(struct pcic_slot *sp, int reg, unsigned char val) outb(sp->data, val); } -static __inline void -putb2(struct pcic_slot *sp, int reg, unsigned char val) -{ - sp->regs[reg] = val; -} - /* * Clear bit(s) of a register. */ @@ -162,71 +143,6 @@ putw(struct pcic_slot *sp, int reg, unsigned short word) sp->putb(sp, reg + 1, (word >> 8) & 0xff); } - -/* - * Gerneral functions for registering and unregistering interrupts. - * isa_to_apic() is used to map the ISA IRQ onto the APIC IRQ to - * check if the APIC IRQ is used or free. - */ -#ifdef APIC_IO -int register_pcic_intr(int intr, int device_id, u_int flags, - ointhand2_t handler, u_int *maskptr, int unit) -{ - int apic_intr; - apic_intr = isa_apic_irq(intr); - if (apic_intr <0) - return -1; - else - return register_intr(apic_intr, device_id, flags, handler, - maskptr, unit); -} - -int unregister_pcic_intr(int intr, ointhand2_t handler) -{ - int apic_intr; - apic_intr = isa_apic_irq(intr); - return unregister_intr(apic_intr, handler); -} - -#else /* Not APIC_IO */ - -int register_pcic_intr(int intr, int device_id, u_int flags, - ointhand2_t handler, u_int *maskptr, int unit) -{ - return register_intr(intr, device_id, flags, handler, maskptr, unit); -} - -int unregister_pcic_intr(int intr, ointhand2_t handler) -{ - return unregister_intr(intr, handler); -} - -#endif /* APIC_IO */ - -#if 0 -static void -pcic_dump_attributes(unsigned char *scratch, int maxlen) -{ - int i,j,k; - - i = 0; - while (scratch[i] != 0xff && i < maxlen) { - unsigned char link = scratch[i+2]; - - /* - * Dump attribute memory - */ - if (scratch[i]) { - printf("[%02x] ", i); - for (j = 0; j < 2 * link + 4 && j < 128; j += 2) - printf("%02x ", scratch[j + i]); - printf("\n"); - } - i += 4 + 2 * link; - } -} -#endif - /* * entry point from main code to map/unmap memory context. */ @@ -237,49 +153,6 @@ pcic_memory(struct slot *slt, int win) struct mem_desc *mp = &slt->mem[win]; int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE; -#ifdef PC98 - if (sp->controller == PCIC_PC98) { - if (mp->flags & MDF_ACTIVE) { - /* slot = 0, window = 0, sys_addr = 0xda000, length = 8KB */ - unsigned char x; - - if ((unsigned long)mp->start != 0xda000) { - printf("sys_addr must be 0xda000. requested address = 0x%x\n", - mp->start); - return(EINVAL); - } - - /* omajinai ??? */ - outb(PCIC98_REG0, 0); - x = inb(PCIC98_REG1); - x &= 0xfc; - x |= 0x02; - outb(PCIC98_REG1, x); - - outw(PCIC98_REG_PAGOFS, 0); - - if (mp->flags & MDF_ATTR) { - outb(PCIC98_REG6, inb(PCIC98_REG6) | PCIC98_ATTRMEM); - }else{ - outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_ATTRMEM)); - } - - outb(PCIC98_REG_WINSEL, PCIC98_MAPWIN); - -#if 0 - if ((mp->flags & MDF_16BITS) == 1) { /* 16bit */ - outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_8BIT)); - }else{ /* 8bit */ - outb(PCIC98_REG2, inb(PCIC98_REG2) | PCIC98_8BIT); - } -#endif - }else{ - outb(PCIC98_REG_WINSEL, PCIC98_UNMAPWIN); - } - return 0; - } -#endif /* PC98 */ - if (mp->flags & MDF_ACTIVE) { unsigned long sys_addr = (uintptr_t)(void *)mp->start >> 12; /* @@ -290,11 +163,6 @@ pcic_memory(struct slot *slt, int win) putw(sp, reg, sys_addr & 0xFFF); putw(sp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF); putw(sp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF); -#if 0 - printf("card offs = card_adr = 0x%x 0x%x, sys_addr = 0x%x\n", - mp->card, ((mp->card >> 12) - sys_addr) & 0x3FFF, - sys_addr); -#endif /* * Each 16 bit register has some flags in the upper bits. */ @@ -310,26 +178,12 @@ pcic_memory(struct slot *slt, int win) setb(sp, reg+5, PCIC_REG); if (mp->flags & MDF_WP) setb(sp, reg+5, PCIC_WP); -#if 0 - printf("Slot number %d, reg 0x%x, offs 0x%x\n", - sp->slotnum, reg, sp->offset); - printf("Map window to sys addr 0x%x for %d bytes, card 0x%x\n", - mp->start, mp->size, mp->card); - printf("regs are: 0x%02x%02x 0x%02x%02x 0x%02x%02x flags 0x%x\n", - sp->getb(sp, reg), sp->getb(sp, reg+1), - sp->getb(sp, reg+2), sp->getb(sp, reg+3), - sp->getb(sp, reg+4), sp->getb(sp, reg+5), - mp->flags); -#endif /* * Enable the memory window. By experiment, we need a delay. */ setb(sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16); DELAY(50); } else { -#if 0 - printf("Unmapping window %d\n", win); -#endif clrb(sp, PCIC_ADDRWINE, 1<<win); putw(sp, reg, 0); putw(sp, reg+2, 0); @@ -347,46 +201,6 @@ pcic_io(struct slot *slt, int win) int mask, reg; struct pcic_slot *sp = slt->cdata; struct io_desc *ip = &slt->io[win]; -#ifdef PC98 - if (sp->controller == PCIC_PC98) { - unsigned char x; - -#if 0 - if (win =! 0) { - printf("pcic98:Illegal PCIC I/O window request(%d)!", win); - return(EINVAL); - } -#endif - - if (ip->flags & IODF_ACTIVE) { - unsigned short base; - - x = inb(PCIC98_REG2) & 0x0f; - if (! (ip->flags & IODF_16BIT)) - x |= PCIC98_8BIT; - - if (ip->size > 16) /* 128bytes mapping */ - x |= PCIC98_MAP128; - - x |= PCIC98_IOMEMORY; - outb(PCIC98_REG2, x); - - base = 0x80d0; - outw(PCIC98_REG4, base); /* 98side IO base */ - outw(PCIC98_REG5, ip->start); /* card side IO base */ - -#ifdef PCIC_DEBUG - printf("pcic98: IO mapped 0x%04x(98) -> 0x%04x(Card) and width %d bytes\n", - base, ip->start, ip->size); -#endif - ip->start = base; - - }else{ - outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY)); - } - return 0; - } -#endif switch (win) { case 0: mask = PCIC_IO0_EN; @@ -402,9 +216,6 @@ pcic_io(struct slot *slt, int win) if (ip->flags & IODF_ACTIVE) { unsigned char x, ioctlv; -#ifdef PCIC_DEBUG -printf("Map I/O 0x%x (size 0x%x) on Window %d\n", ip->start, ip->size, win); -#endif /* PCIC_DEBUG */ putw(sp, reg, ip->start); putw(sp, reg+2, ip->start+ip->size-1); x = 0; @@ -457,7 +268,6 @@ static int pcic_probe(device_t dev) { int slotnum, validslots = 0; - u_int free_irqs; struct slot *slt; struct pcic_slot *sp; unsigned char c; @@ -472,9 +282,6 @@ pcic_probe(device_t dev) if (device_get_unit(dev) != 0) return ENXIO; - /* Determine the list of free interrupts */ - free_irqs = PCIC_INT_MASK_ALLOWED; - /* * Initialise controller information structure. */ @@ -488,8 +295,6 @@ pcic_probe(device_t dev) cinfo.resume = pcic_resume; cinfo.maxmem = PCIC_MEM_WIN; cinfo.maxio = PCIC_IO_WIN; - cinfo.irqs = free_irqs; - cinfo.imask = &pcic_imask; sp = pcic_slots; for (slotnum = 0; slotnum < PCIC_MAX_SLOTS; slotnum++, sp++) { @@ -653,8 +458,8 @@ pcic_probe(device_t dev) slt->cdata = sp; sp->slt = slt; /* - * If we haven't allocated an interrupt for the controller, - * then attempt to get one. + * If we haven't allocated an interrupt for the controller, + * then attempt to get one. */ if (pcic_irq == 0) { /* See if the user has requested a specific IRQ */ @@ -704,42 +509,6 @@ pcic_probe(device_t dev) if (pcic_irq > 0) sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); } -#ifdef PC98 - if (validslots == 0) { - sp = pcic_slots; - slotnum = 0; - if (inb(PCIC98_REG0) != 0xff) { - sp->controller = PCIC_PC98; - sp->revision = 0; - name = "PC98 Original"; - device_set_desc(dev, name); - cinfo.maxmem = 1; - cinfo.maxio = 1; -/* cinfo.irqs = PCIC_INT_MASK_ALLOWED;*/ - cinfo.irqs = 0x1468; - validslots++; - sp->slotnum = slotnum; - - slt = pccard_alloc_slot(&cinfo); - if (slt == 0) { - printf("pcic98: slt == NULL\n"); - goto pcic98_probe_end; - } - slt->cdata = sp; - sp->slt = slt; - - /* Check for a card in this slot */ - if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) { - /* PCMCIA card exist */ - slt->laststate = slt->state = filled; - pccard_event(sp->slt, card_inserted); - } else { - slt->laststate = slt->state = empty; - } - } - pcic98_probe_end: - } -#endif /* PC98 */ if (validslots && pcic_irq <= 0) pcictimeout_ch = timeout(pcictimeout, 0, hz/2); if (validslots) { @@ -787,35 +556,6 @@ pcic_power(struct slot *slt) struct pcic_slot *sp = slt->cdata; switch(sp->controller) { -#ifdef PC98 - case PCIC_PC98: - reg = inb(PCIC98_REG6) & (~PCIC98_VPP12V); - switch(slt->pwr.vpp) { - default: - return(EINVAL); - case 50: - break; - case 120: - reg |= PCIC98_VPP12V; - break; - } - outb(PCIC98_REG6, reg); - DELAY(100*1000); - - reg = inb(PCIC98_REG2) & (~PCIC98_VCC3P3V); - switch(slt->pwr.vcc) { - default: - return(EINVAL); - case 33: - reg |= PCIC98_VCC3P3V; - break; - case 50: - break; - } - outb(PCIC98_REG2, reg); - DELAY(100*1000); - return (0); -#endif case PCIC_PD672X: case PCIC_PD6710: case PCIC_VG365: @@ -900,35 +640,6 @@ static void pcic_mapirq(struct slot *slt, int irq) { struct pcic_slot *sp = slt->cdata; -#ifdef PC98 - if (sp->controller == PCIC_PC98) { - unsigned char x; - switch (irq) { - case 3: - x = PCIC98_INT0; break; - case 5: - x = PCIC98_INT1; break; - case 6: - x = PCIC98_INT2; break; - case 10: - x = PCIC98_INT4; break; - case 12: - x = PCIC98_INT5; break; - case 0: /* disable */ - x = PCIC98_INTDISABLE; - break; - default: - printf("pcic98: illegal irq %d\n", irq); - return; - } -#ifdef PCIC_DEBUG - printf("pcic98: irq=%d mapped.\n", irq); -#endif - outb(PCIC98_REG3, x); - - return; - } -#endif if (irq == 0) clrb(sp, PCIC_INT_GEN, 0xF); else @@ -945,19 +656,6 @@ pcic_reset(void *chan) struct slot *slt = chan; struct pcic_slot *sp = slt->cdata; -#ifdef PC98 - if (sp->controller == PCIC_PC98) { - outb(PCIC98_REG0, 0); - outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_IOMEMORY)); - outb(PCIC98_REG3, PCIC98_INTDISABLE); - outb(PCIC98_REG2, inb(PCIC98_REG2) & (~PCIC98_VCC3P3V)); - outb(PCIC98_REG6, inb(PCIC98_REG6) & (~PCIC98_VPP12V)); - outb(PCIC98_REG1, 0); - - selwakeup(&slt->selp); - return; - } -#endif switch (slt->insert_seq) { case 0: /* Something funny happended on the way to the pub... */ return; @@ -997,11 +695,6 @@ pcic_disable(struct slot *slt) { struct pcic_slot *sp = slt->cdata; -#ifdef PC98 - if (sp->controller == PCIC_PC98) { - return; - } -#endif sp->putb(sp, PCIC_INT_GEN, 0); sp->putb(sp, PCIC_POWER, 0); } @@ -1030,26 +723,13 @@ pcicintr(void *arg) int slot, s; unsigned char chg; struct pcic_slot *sp = pcic_slots; + static int count = 0; + + if (count++ > 20) + Debugger("Trapdoor"); -#ifdef PC98 - if (sp->controller == PCIC_PC98) { - slot = 0; - s = splhigh(); - /* Check for a card in this slot */ - if (inb(PCIC98_REG1) & PCIC98_CARDEXIST) { - if (sp->slt->laststate != filled) { - pccard_event(sp->slt, card_inserted); - } - } else { - if (sp->slt->laststate != empty) { - pccard_event(sp->slt, card_removed); - } - } - splx(s); - return; - } -#endif /* PC98 */ s = splhigh(); +printf("splhigh for pcicintr\n"); for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) if (sp->slt && (chg = sp->getb(sp, PCIC_STAT_CHG)) != 0) if (chg & PCIC_CDTCH) { @@ -1060,6 +740,7 @@ pcicintr(void *arg) pccard_event(sp->slt, card_removed); } } +printf("splx\n"); splx(s); } @@ -1070,6 +751,7 @@ static void pcic_resume(struct slot *slt) { struct pcic_slot *sp = slt->cdata; + if (pcic_irq > 0) sp->putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); if (sp->controller == PCIC_PD672X) { @@ -1078,6 +760,85 @@ pcic_resume(struct slot *slt) } } +static int +pcic_activate_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + struct pccard_devinfo *devi = device_get_ivars(child); + struct io_desc *ip = &devi->slt->io[rid]; + int err; + + switch (type) { + case SYS_RES_IOPORT: +#if 0 + if (ip->flags & IODF_ACTIVE) + return EBUSY; +#endif + ip->flags |= IODF_ACTIVE; + ip->start = rman_get_start(r); + ip->size = rman_get_end(r) - rman_get_start(r) + 1; + err = pcic_io(devi->slt, rid); + if (err) { + return err; + } + break; + case SYS_RES_IRQ: + pcic_mapirq(devi->slt, rman_get_start(r)); + break; + case SYS_RES_MEMORY: + default: + break; + } + err = bus_generic_activate_resource(dev, child, type, rid, r); + return err; +} + +static int +pcic_deactivate_resource(device_t dev, device_t child, int type, int rid, + struct resource *r) +{ + struct pccard_devinfo *devi = device_get_ivars(child); + struct io_desc *ip = &devi->slt->io[rid]; + int err; + + switch (type) { + case SYS_RES_IOPORT: +#if 0 + if (ip->flags & IODF_ACTIVE) + return EBUSY; +#endif + ip->flags &= ~IODF_ACTIVE; + err = pcic_io(devi->slt, rid); + if (err) { + return err; + } + break; + case SYS_RES_IRQ: + pcic_mapirq(devi->slt, 0); + break; + case SYS_RES_MEMORY: + default: + break; + } + err = bus_generic_deactivate_resource(dev, child, type, rid, r); + return err; +} + +static int +pcic_setup_intr(device_t dev, device_t child, struct resource *irq, + int flags, driver_intr_t *intr, void *arg, void **cookiep) +{ + return (bus_generic_setup_intr(dev, child, irq, flags, intr, arg, + cookiep)); +} + +static int +pcic_teardown_intr(device_t dev, device_t child, struct resource *irq, + void *cookie) +{ + return (bus_generic_teardown_intr(dev, child, irq, cookie)); +} + static device_method_t pcic_methods[] = { /* Device interface */ DEVMETHOD(device_probe, pcic_probe), @@ -1091,10 +852,10 @@ static device_method_t pcic_methods[] = { 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), + DEVMETHOD(bus_activate_resource, pcic_activate_resource), + DEVMETHOD(bus_deactivate_resource, pcic_deactivate_resource), + DEVMETHOD(bus_setup_intr, pcic_setup_intr), + DEVMETHOD(bus_teardown_intr, pcic_teardown_intr), { 0, 0 } }; diff --git a/sys/pccard/pcic.h b/sys/pccard/pcic.h index 53839a3..3019e36 100644 --- a/sys/pccard/pcic.h +++ b/sys/pccard/pcic.h @@ -31,6 +31,14 @@ * $FreeBSD$ */ -int register_pcic_intr(int intr, int device_id, u_int flags, - ointhand2_t handler, u_int *maskptr, int unit); -int unregister_pcic_intr(int intr, ointhand2_t handler); +#define PCIC_RF_IODF_WS (0x01 << 16) +#define PCIC_RF_IODF_16BIT (0x02 << 16) +#define PCIC_RF_IODF_CS16 (0x04 << 16) +#define PCIC_RF_IODF_ZEROWS (0x08 << 16) + +#define PCIC_RF_MDF_16BITS (0x01 << 16) +#define PCIC_RF_MDF_ZEROWS (0x02 << 16) +#define PCIC_RF_MDF_WS0 (0x04 << 16) +#define PCIC_RF_MDF_WS1 (0x08 << 16) +#define PCIC_RF_MDF_ATTR (0x10 << 16) +#define PCIC_RF_MDF_WP (0x20 << 16) diff --git a/sys/pccard/skel.c b/sys/pccard/skel.c deleted file mode 100644 index 7c8c6a9..0000000 --- a/sys/pccard/skel.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Loadable kernel module skeleton driver - * 11 July 1995 Andrew McRae - * - *------------------------------------------------------------------------- - * - * Copyright (c) 1995 Andrew McRae. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/proc.h> -#include <sys/conf.h> -#include <sys/mount.h> -#include <sys/sysent.h> -#include <sys/exec.h> - -#include <i386/isa/isa_device.h> - -#include <sys/select.h> -#include <sys/kernel.h> -#include <sys/module.h> -#include <pccard/cardinfo.h> -#include <pccard/driver.h> -#include <pccard/slot.h> - -static int skelinit(struct pccard_devinfo *); /* init device */ -static void skelunload(struct pccard_devinfo *); /* Disable driver */ -static int skelintr(struct pccard_devinfo *); /* Interrupt handler */ - -PCCARD_MODULE(skel, skelinit, skelunload, skelintr, 0, net_imask); - -static int opened; /* Rather minimal device state... */ - -/* - * Skeleton driver entry points for PCCARD configuration. - */ -/* - * Initialize the device. - */ -static int -skelinit(struct pccard_devinfo *devi) -{ - int unit = devi->isahd.id_unit; - - if (opened & (1 << unit)) - return(EBUSY); - opened |= 1 << unit; - printf("%s%d: init\n", devi->drv->name, unit); - printf("%s%d: irq %d iobase 0x%x maddr 0x%x memlen %d\n", - devi->drv->name, unit, devi->isahd.id_irq, - devi->isahd.id_iobase, devi->isahd.id_maddr, - devi->isahd.id_msize); - return(0); -} -/* - * The device entry is being removed. Shut it down, - * and turn off interrupts etc. Not called unless - * the device was successfully installed. - */ -static void -skelunload(struct pccard_devinfo *devi) -{ - int unit = devi->isahd.id_unit; - - printf("%s%d: unload\n", devi->drv->name, unit); - opened &= ~(1 << unit); -} -/* - * Interrupt handler. - * Returns true if the interrupt is for us. - */ -static int -skelintr(struct pccard_devinfo *devi) -{ - return(0); -} diff --git a/sys/pccard/slot.h b/sys/pccard/slot.h index 07e4d0d..18ffc62 100644 --- a/sys/pccard/slot.h +++ b/sys/pccard/slot.h @@ -72,8 +72,6 @@ struct slot_ctrl { int extra; /* Controller specific size */ int maxmem; /* Number of allowed memory windows */ int maxio; /* Number of allowed I/O windows */ - int irqs; /* IRQ's that are allowed */ - u_int *imask; /* IRQ mask for the PCIC controller */ /* * The rest is maintained by the mainline PC-CARD code. @@ -83,43 +81,6 @@ struct slot_ctrl { }; /* - * Driver structure - each driver registers itself - * with the mainline PC-CARD code. These drivers are - * then available for linking to the devices. - */ -struct pccard_devinfo; - -struct pccard_device { - char *name; /* Driver name */ - int (*enable)(struct pccard_devinfo *); /* init/enable driver */ - void (*disable)(struct pccard_devinfo *); /* disable driver */ - int (*handler)(struct pccard_devinfo *); /* interrupt handler */ - int attr; /* driver attributes */ - unsigned int *imask; /* Interrupt mask ptr */ - driver_t *driver; /* Driver */ - - struct pccard_device *next; -}; - -int pccard_module_handler __P((module_t mod, int what, void *arg)); - -#define PCCARD_MODULE(name, enable, disable, handler, attr, imask) \ -static struct pccard_device name ## _info = { \ - #name, \ - enable, \ - disable, \ - handler, \ - attr, \ - &imask \ -}; \ -static moduledata_t name ## _mod = { \ - "pccard_" #name, \ - pccard_module_handler, \ - &name ## _info \ -}; \ -DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE) - -/* * Device structure for cards. Each card may have one * or more pccard drivers attached to it; each driver is assumed * to require at most one interrupt handler, one I/O block @@ -127,14 +88,13 @@ DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE) * devices together. */ struct pccard_devinfo { - struct pccard_device *drv; - struct isa_device isahd; /* Device details */ + u_char name[128]; + struct isa_device isahd; int running; /* Current state of driver */ u_char misc[128]; /* For any random info */ struct slot *slt; /* Back pointer to slot */ - struct resource *iorv; /* Kludge: keep track of io resource */ - struct resource *irqrv; /* Kludge: keep track of irq */ + struct resource_list resources; struct pccard_devinfo *next; /* List of drivers */ }; @@ -170,6 +130,15 @@ enum card_event { card_removed, card_inserted }; struct slot *pccard_alloc_slot(struct slot_ctrl *); void pccard_event(struct slot *, enum card_event); -void pccard_remove_controller(struct slot_ctrl *); + +static __inline__ const char * +pccard_get_name(device_t dev) +{ + struct pccard_devinfo *devi = (struct pccard_devinfo *) + device_get_ivars(dev); + if (!devi) + return ("anonymous"); + return (devi->name); +} #endif /* !_PCCARD_SLOT_H */ |