diff options
Diffstat (limited to 'sys/pccard')
-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 |
9 files changed, 322 insertions, 1122 deletions
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 */ |