diff options
author | phk <phk@FreeBSD.org> | 1995-11-09 20:44:36 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1995-11-09 20:44:36 +0000 |
commit | f898a1f1fe89ceeb0be5f51f05d7a976f8a4c5d6 (patch) | |
tree | d5758a4e61336468edaa5ab91711b6d119bae69f /sys/pccard | |
parent | c1dbd5b37790b10eff4f18af33308b8a0b1caa8b (diff) | |
download | FreeBSD-src-f898a1f1fe89ceeb0be5f51f05d7a976f8a4c5d6.zip FreeBSD-src-f898a1f1fe89ceeb0be5f51f05d7a976f8a4c5d6.tar.gz |
Clean up the ident style.
Remove the APM stuff
Add support for VA469
Submitted by: Janic.Thaillandier@ratp.fr
Diffstat (limited to 'sys/pccard')
-rw-r--r-- | sys/pccard/card.h | 31 | ||||
-rw-r--r-- | sys/pccard/cardinfo.h | 31 | ||||
-rw-r--r-- | sys/pccard/i82365.h | 1 | ||||
-rw-r--r-- | sys/pccard/pccard.c | 740 | ||||
-rw-r--r-- | sys/pccard/pcic.c | 644 | ||||
-rw-r--r-- | sys/pccard/slot.h | 63 |
6 files changed, 725 insertions, 785 deletions
diff --git a/sys/pccard/card.h b/sys/pccard/card.h index a2e5642..575253f 100644 --- a/sys/pccard/card.h +++ b/sys/pccard/card.h @@ -51,14 +51,13 @@ enum cardstate { noslot, empty, filled }; /* * Descriptor structure for memory map. */ -struct mem_desc - { +struct mem_desc { int window; /* Memory map window number (0-4) */ int flags; /* Flags - see below */ caddr_t start; /* System memory start */ int size; /* Size of memory area */ unsigned long card; /* Card memory address */ - }; +}; #define MDF_16BITS 0x01 /* Memory is 16 bits wide */ #define MDF_ZEROWS 0x02 /* Set no wait states for memory */ @@ -71,13 +70,12 @@ struct mem_desc /* * Descriptor structure for I/O map */ -struct io_desc - { +struct io_desc { int window; /* I/O map number (0-1) */ int flags; /* Flags - see below */ int start; /* I/O port start */ int size; /* Number of port addresses */ - }; +}; #define IODF_WS 0x01 /* Set wait states for 16 bit I/O access */ #define IODF_16BIT 0x02 /* I/O access are 16 bit */ @@ -88,8 +86,7 @@ struct io_desc /* * Device descriptor for allocation of driver. */ -struct drv_desc - { +struct drv_desc { char name[16]; /* Driver name */ int unit; /* Driver unit number */ unsigned long mem; /* Memory address of driver */ @@ -98,33 +95,31 @@ struct drv_desc int irqmask; /* Interrupt number(s) to allocate */ int flags; /* Device flags */ u_char misc[128]; /* For any random info */ - }; +}; -struct pcic_reg - { +struct pcic_reg { unsigned char reg; unsigned char value; - }; +}; + /* * Slot information. Used to read current status of slot. */ -struct slotstate - { +struct slotstate { enum cardstate state; /* Current state of slot */ int maxmem; /* Max allowed memory windows */ int maxio; /* Max allowed I/O windows */ int irqs; /* Bitmap of IRQs allowed */ int flags; /* Capability flags */ - }; +}; /* * The power values are in volts * 10, e.g. 5V is 50, 3.3V is 33. */ -struct power - { +struct power { int vcc; int vpp; - }; +}; /* * Other system limits diff --git a/sys/pccard/cardinfo.h b/sys/pccard/cardinfo.h index a2e5642..575253f 100644 --- a/sys/pccard/cardinfo.h +++ b/sys/pccard/cardinfo.h @@ -51,14 +51,13 @@ enum cardstate { noslot, empty, filled }; /* * Descriptor structure for memory map. */ -struct mem_desc - { +struct mem_desc { int window; /* Memory map window number (0-4) */ int flags; /* Flags - see below */ caddr_t start; /* System memory start */ int size; /* Size of memory area */ unsigned long card; /* Card memory address */ - }; +}; #define MDF_16BITS 0x01 /* Memory is 16 bits wide */ #define MDF_ZEROWS 0x02 /* Set no wait states for memory */ @@ -71,13 +70,12 @@ struct mem_desc /* * Descriptor structure for I/O map */ -struct io_desc - { +struct io_desc { int window; /* I/O map number (0-1) */ int flags; /* Flags - see below */ int start; /* I/O port start */ int size; /* Number of port addresses */ - }; +}; #define IODF_WS 0x01 /* Set wait states for 16 bit I/O access */ #define IODF_16BIT 0x02 /* I/O access are 16 bit */ @@ -88,8 +86,7 @@ struct io_desc /* * Device descriptor for allocation of driver. */ -struct drv_desc - { +struct drv_desc { char name[16]; /* Driver name */ int unit; /* Driver unit number */ unsigned long mem; /* Memory address of driver */ @@ -98,33 +95,31 @@ struct drv_desc int irqmask; /* Interrupt number(s) to allocate */ int flags; /* Device flags */ u_char misc[128]; /* For any random info */ - }; +}; -struct pcic_reg - { +struct pcic_reg { unsigned char reg; unsigned char value; - }; +}; + /* * Slot information. Used to read current status of slot. */ -struct slotstate - { +struct slotstate { enum cardstate state; /* Current state of slot */ int maxmem; /* Max allowed memory windows */ int maxio; /* Max allowed I/O windows */ int irqs; /* Bitmap of IRQs allowed */ int flags; /* Capability flags */ - }; +}; /* * The power values are in volts * 10, e.g. 5V is 50, 3.3V is 33. */ -struct power - { +struct power { int vcc; int vpp; - }; +}; /* * Other system limits diff --git a/sys/pccard/i82365.h b/sys/pccard/i82365.h index 4c4d233..3ca9683 100644 --- a/sys/pccard/i82365.h +++ b/sys/pccard/i82365.h @@ -40,6 +40,7 @@ #define PCIC_PD6710 4 #define PCIC_CL6729 5 #define PCIC_VG468 6 +#define PCIC_VG469 7 /* * Address of the controllers. Each controller can manage * two PCMCIA slots. Up to 8 slots are supported in total. diff --git a/sys/pccard/pccard.c b/sys/pccard/pccard.c index ed86105..e4feaa5 100644 --- a/sys/pccard/pccard.c +++ b/sys/pccard/pccard.c @@ -30,7 +30,6 @@ */ #include "crd.h" -#if NCRD > 0 #include <sys/param.h> #include <sys/systm.h> @@ -42,63 +41,46 @@ #include <sys/syslog.h> #include <sys/devconf.h> #include <sys/malloc.h> +#include <sys/devconf.h> + +#include <pccard/card.h> +#include <pccard/slot.h> #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/icu.h> -#include <sys/devconf.h> + extern struct kern_devconf kdc_cpu0; struct kern_devconf kdc_pccard0 = { - 0, 0, 0, /* filled in by dev_attach */ + 0, 0, 0, /* filled in by dev_attach */ "pccard", 0, { MDDT_BUS, 0 }, 0, 0, 0, BUS_EXTERNALLEN, - &kdc_cpu0, /* parent is the CPU */ - 0, /* no parentdata */ - DC_UNCONFIGURED, /* until we see it */ + &kdc_cpu0, /* parent is the CPU */ + 0, /* no parentdata */ + DC_UNCONFIGURED, /* until we see it */ "PCCARD or PCMCIA bus", - DC_CLS_BUS /* class */ + DC_CLS_BUS /* class */ }; -#include "apm.h" -#if NAPM > 0 -#include <machine/apm_bios.h> -#endif /* NAPM > 0 */ - -#include <pccard/card.h> -#include <pccard/slot.h> - #define PCCARD_MEMSIZE (4*1024) #define MIN(a,b) ((a)<(b)?(a):(b)) -static int allocate_driver(struct slot *, struct drv_desc *); -static void inserted(void *); -static void disable_slot(struct slot *); -static int invalid_io_memory(unsigned long, int); +static int allocate_driver(struct slot *, struct drv_desc *); +static void inserted(void *); +static void disable_slot(struct slot *); +static int invalid_io_memory(unsigned long, int); static struct pccard_drv *find_driver(char *); -static void remove_device(struct pccard_dev *); -static void slot_irq_handler(int); -#if NAPM > 0 -/* - * For the APM stuff, the apmhook structure is kept - * separate from the slot structure so that the slot - * drivers do not need to know about the hooks (or the - * data structures). - */ -static int slot_suspend(void *vsp); -static int slot_resume(void *vsp); -static struct apmhook s_hook[MAXSLOT]; /* APM suspend */ -static struct apmhook r_hook[MAXSLOT]; /* APM resume */ -#endif /* NAPM > 0 */ +static void remove_device(struct pccard_dev *); +static void slot_irq_handler(int); -void pcic_probe(); - -static struct slot *pccard_slots[MAXSLOT]; /* slot entries */ -static struct slot *slot_list; -static struct slot_cont *cont_list; +static struct slot *pccard_slots[MAXSLOT]; /* slot entries */ +static struct slot *slot_list; +static struct slot_ctrl *cont_list; static struct pccard_drv *drivers; /* Card drivers */ + /* * The driver interface for read/write uses a block * of memory in the ISA I/O memory space allocated via @@ -106,6 +88,7 @@ static struct pccard_drv *drivers; /* Card drivers */ */ static unsigned long pccard_mem; /* Physical memory */ static unsigned char *pccard_kmem; /* Kernel virtual address */ + /* * pccard_configure - called by autoconf code. * Probes for various PC-CARD controllers, and @@ -119,16 +102,21 @@ static unsigned char *pccard_kmem; /* Kernel virtual address */ void pccard_configure() { -struct slot_cont *cp; -struct slot *sp; + struct slot_ctrl *cp; + struct slot *sp; + dev_attach(&kdc_pccard0); #include "pcic.h" #if NPCIC > 0 + { + extern void pcic_probe(); /* XXX Should be linker set */ pcic_probe(); + } #endif } + /* * pccard_add_driver - Add a new driver to the list of * drivers available for allocation. @@ -136,17 +124,17 @@ struct slot *sp; void pccard_add_driver(struct pccard_drv *dp) { -/* - * If already loaded, then reject the driver. - */ - if (find_driver(dp->name)) - { + /* + * If already loaded, then reject the driver. + */ + if (find_driver(dp->name)) { printf("Driver %s already loaded\n", dp->name); return; - } + } dp->next = drivers; drivers = dp; } + /* * pccard_remove_driver - called to unlink driver * from devices. Usually called when drivers are @@ -155,32 +143,31 @@ pccard_add_driver(struct pccard_drv *dp) void pccard_remove_driver(struct pccard_drv *dp) { -struct slot *sp; -struct pccard_dev *devp, *next; -struct pccard_drv *drvp; + struct slot *sp; + struct pccard_dev *devp, *next; + struct pccard_drv *drvp; for (sp = slot_list; sp; sp = sp->next) - for (devp = sp->devices; devp; devp = next) - { + for (devp = sp->devices; devp; devp = next) { next = devp->next; if (devp->drv == dp) remove_device(devp); - } -/* - * Once all the devices belonging to this driver have been - * freed, then remove the driver from the list - * of registered drivers. - */ + } + /* + * Once all the devices belonging to this driver have been + * freed, then remove the driver from the list + * of registered drivers. + */ if (drivers == dp) drivers = dp->next; else for (drvp = drivers; drvp->next; drvp = drvp->next) - if (drvp->next == dp) - { + if (drvp->next == dp) { drvp->next = dp->next; break; - } + } } + /* * pccard_remove_controller - Called when the slot * driver is unloaded. The plan is to unload @@ -189,65 +176,57 @@ struct pccard_drv *drvp; * remove the controller structure. Messy... */ void -pccard_remove_controller(struct slot_cont *cp) +pccard_remove_controller(struct slot_ctrl *cp) { -struct slot *sp, *next, *last = 0; -struct slot_cont *cl; -struct pccard_dev *dp; + struct slot *sp, *next, *last = 0; + struct slot_ctrl *cl; + struct pccard_dev *dp; - for (sp = slot_list; sp; sp = next) - { + for (sp = slot_list; sp; sp = next) { next = sp->next; -/* - * If this slot belongs to this controller, - * remove this slot. - */ - if (sp->cinfo == cp) - { + /* + * If this slot belongs to this controller, + * remove this slot. + */ + if (sp->ctrl == cp) { pccard_slots[sp->slot] = 0; - if (sp->insert_timeout) + if (sp->insert_seq) untimeout(inserted, (void *)sp); -/* - * Unload the drivers attached to this slot. - */ + /* + * Unload the drivers attached to this slot. + */ while (dp = sp->devices) remove_device(dp); -/* - * Disable the slot and unlink the slot from the slot list. - */ + /* + * Disable the slot and unlink the slot from the + * slot list. + */ disable_slot(sp); if (last) last->next = next; else slot_list = next; -#if NAPM > 0 - apm_hook_disestablish(APM_HOOK_SUSPEND, - &s_hook[sp->slot]); - apm_hook_disestablish(APM_HOOK_RESUME, - &r_hook[sp->slot]); -#endif if (cp->extra && sp->cdata) FREE(sp->cdata, M_DEVBUF); FREE(sp, M_DEVBUF); -/* - * xx Can't use sp after we have freed it. - */ - } - else + /* + * xx Can't use sp after we have freed it. + */ + } else { last = sp; } -/* - * Unlink controller structure from controller list. - */ + } + /* + * Unlink controller structure from controller list. + */ if (cont_list == cp) cont_list = cp->next; else for (cl = cont_list; cl->next; cl = cl->next) - if (cl->next == cp) - { + if (cl->next == cp) { cl->next = cp->next; break; - } + } } /* @@ -257,76 +236,53 @@ struct pccard_dev *dp; static void disable_slot(struct slot *sp) { -int i; -struct pccard_dev *devp; -/* - * Unload all the drivers on this slot. Note we can't - * call remove_device from here, because this may be called - * from the event routine, which is called from the slot - * controller's ISR, and this could remove the device - * structure out in the middle of some driver activity. - * - * Note that a race condition is possible here; if a - * driver is accessing the device and it is removed, then - * all bets are off... - */ + int i; + struct pccard_dev *devp; + /* + * Unload all the drivers on this slot. Note we can't + * call remove_device from here, because this may be called + * from the event routine, which is called from the slot + * controller's ISR, and this could remove the device + * structure out in the middle of some driver activity. + * + * Note that a race condition is possible here; if a + * driver is accessing the device and it is removed, then + * all bets are off... + */ for (devp = sp->devices; devp; devp = devp->next) { if (devp->running) { + int s = splhigh(); devp->drv->unload(devp); devp->running = 0; + if (devp->isahd.id_irq && --sp->irqref == 0) { + printf("Return IRQ=%d\n",sp->irq); + sp->ctrl->mapirq(sp, 0); + INTRDIS(1<<sp->irq); + unregister_intr(sp->irq, slot_irq_handler); + if (devp->drv->imask) + INTRUNMASK(*devp->drv->imask,(1<<sp->irq)); + sp->irq = 0; + } + splx(s); } } -/* - * Power off the slot. - */ - sp->cinfo->disable(sp); -/* - * De-activate all contexts. - */ - for (i = 0; i < sp->cinfo->maxmem; i++) - if (sp->mem[i].flags & MDF_ACTIVE) - { + /* Power off the slot. */ + sp->ctrl->disable(sp); + + /* De-activate all contexts. */ + for (i = 0; i < sp->ctrl->maxmem; i++) + if (sp->mem[i].flags & MDF_ACTIVE) { sp->mem[i].flags = 0; - (void)sp->cinfo->mapmem(sp, i); - } - for (i = 0; i < sp->cinfo->maxio; i++) - if (sp->io[i].flags & IODF_ACTIVE) - { + (void)sp->ctrl->mapmem(sp, i); + } + for (i = 0; i < sp->ctrl->maxio; i++) + if (sp->io[i].flags & IODF_ACTIVE) { sp->io[i].flags = 0; - (void)sp->cinfo->mapio(sp, i); - } + (void)sp->ctrl->mapio(sp, i); + } } /* - * APM hooks for suspending and resuming. - */ -#if NAPM > 0 -static int -slot_suspend(void *vsp) -{ -struct pccard_dev *dp; -struct slot *sp = vsp; - - for (dp = sp->devices; dp; dp = dp->next) - (void)dp->drv->suspend(dp); - sp->cinfo->disable(sp); - return(0); -} -static int -slot_resume(void *vsp) -{ -struct pccard_dev *dp; -struct slot *sp = vsp; - - sp->cinfo->power(sp); - if (sp->irq) - sp->cinfo->mapirq(sp, sp->irq); - for (dp = sp->devices; dp; dp = dp->next) - (void)dp->drv->init(dp, 0); - return(0); -} -#endif /* NAPM > 0 */ -/* * pccard_alloc_slot - Called from controller probe * routine, this function allocates a new PC-CARD slot * and initialises the data structures using the data provided. @@ -334,10 +290,10 @@ struct slot *sp = vsp; * to allow the controller specific data to be initialised. */ struct slot * -pccard_alloc_slot(struct slot_cont *cp) +pccard_alloc_slot(struct slot_ctrl *cp) { -struct slot *sp; -int slotno; + struct slot *sp; + int slotno; for (slotno = 0; slotno < MAXSLOT; slotno++) if (pccard_slots[slotno] == 0) @@ -347,22 +303,20 @@ int slotno; kdc_pccard0.kdc_state = DC_BUSY; MALLOC(sp, struct slot *, sizeof(*sp), M_DEVBUF, M_WAITOK); bzero(sp, sizeof(*sp)); - if (cp->extra) - { + if (cp->extra) { MALLOC(sp->cdata, void *, cp->extra, M_DEVBUF, M_WAITOK); bzero(sp->cdata, cp->extra); - } - sp->cinfo = cp; + } + sp->ctrl = cp; sp->slot = slotno; pccard_slots[slotno] = sp; sp->next = slot_list; slot_list = sp; -/* - * If this controller hasn't been seen before, then - * link it into the list of controllers. - */ - if (cp->slots++ == 0) - { + /* + * If this controller hasn't been seen before, then + * link it into the list of controllers. + */ + if (cp->slots++ == 0) { cp->next = cont_list; cont_list = cp; if (cp->maxmem > NUM_MEM_WINDOWS) @@ -371,27 +325,10 @@ int slotno; cp->maxio = NUM_IO_WINDOWS; printf("PC-Card %s (%d mem & %d I/O windows)\n", cp->name, cp->maxmem, cp->maxio); - } -#if NAPM > 0 - { - struct apmhook *ap; - - ap = &s_hook[sp->slot]; - ap->ah_fun = slot_suspend; - ap->ah_arg = (void *) sp; - ap->ah_name = cp->name; - ap->ah_order = APM_MID_ORDER; - apm_hook_establish(APM_HOOK_SUSPEND, ap); - ap = &r_hook[sp->slot]; - ap->ah_fun = slot_resume; - ap->ah_arg = (void *) sp; - ap->ah_name = cp->name; - ap->ah_order = APM_MID_ORDER; - apm_hook_establish(APM_HOOK_RESUME, ap); } -#endif /* NAPM > 0 */ return(sp); } + /* * pccard_alloc_intr - allocate an interrupt from the * free interrupts and return its number. The interrupts @@ -400,27 +337,33 @@ int slotno; int pccard_alloc_intr(int imask, inthand2_t *hand, int unit, int *maskp) { -int rv, irq; -unsigned int mask; + int rv, irq; + unsigned int mask; - for (irq = 1; irq < 16; irq++) - { + imask = 1<< 3; + imask |= 1<< 5; + imask |= 1<< 9; + imask |= 1<<11; + imask |= 1<<15; + + + for (irq = 1; irq < 16; irq++) { mask = 1ul << irq; if (!(mask & imask)) continue; -printf("IRQ=%d\n",irq); if (maskp) INTRMASK (*maskp, mask); - if (register_intr(irq, 0, 0, hand, maskp, unit)==0) - { -printf("IRQ=%d yes!\n",irq); - INTREN (1 << irq); - + if (register_intr(irq, 0, 0, hand, maskp, unit)==0) { + INTREN (mask); return(irq); - } } + /* Well no luck, remove from mask again... */ + if (maskp) + INTRUNMASK (*maskp, mask); + } return(-1); } + /* * allocate_driver - Create a new device entry for this * slot, and attach a driver to it. @@ -428,63 +371,60 @@ printf("IRQ=%d yes!\n",irq); static int allocate_driver(struct slot *sp, struct drv_desc *drvp) { -struct pccard_dev *devp; -struct pccard_drv *dp; -int err, irq = 0, s; + struct pccard_dev *devp; + struct pccard_drv *dp; + int err, irq = 0, s; dp = find_driver(drvp->name); if (dp == 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. - */ + /* + * If an instance of this driver is already installed, + * but not running, then remove it. If it is running, + * then reject the request. + */ for (devp = sp->devices; devp; devp = devp->next) - if (devp->drv == dp && devp->isahd.id_unit == drvp->unit) - { + if (devp->drv == dp && devp->isahd.id_unit == drvp->unit) { if (devp->running) return(EBUSY); remove_device(devp); break; - } -/* - * If an interrupt mask has been given, then check it - * against the slot interrupt (if one has been allocated). - */ - if (drvp->irqmask && dp->imask) - { - if ((sp->cinfo->irqs & drvp->irqmask)==0) + } + /* + * If an interrupt mask has been given, then check it + * against the slot interrupt (if one has been allocated). + */ + if (drvp->irqmask && dp->imask) { + if ((sp->ctrl->irqs & drvp->irqmask)==0) return(EINVAL); - if (sp->irq) - { + if (sp->irq) { if (((1 << sp->irq)&drvp->irqmask)==0) return(EINVAL); sp->irqref++; irq = sp->irq; - } -/* - * Attempt to allocate an interrupt. XXX We lose at the moment - * if the second device relies on a different interrupt mask. - */ - else - { + } 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(drvp->irqmask, slot_irq_handler, (int)sp, dp->imask); if (irq < 0) return(EINVAL); sp->irq = irq; sp->irqref = 1; - sp->cinfo->mapirq(sp, sp->irq); - } + sp->ctrl->mapirq(sp, sp->irq); } + } MALLOC(devp, struct pccard_dev *, sizeof(*devp), M_DEVBUF, M_WAITOK); bzero(devp, sizeof(*devp)); -/* - * Create an entry for the device under this slot. - */ + /* + * Create an entry for the device under this slot. + */ devp->drv = dp; devp->sp = sp; + devp->isahd.id_irq = irq; devp->isahd.id_unit = drvp->unit; devp->isahd.id_msize = drvp->memsize; devp->isahd.id_iobase = drvp->iobase; @@ -492,11 +432,12 @@ int err, irq = 0, s; if (irq) devp->isahd.id_irq = 1 << irq; devp->isahd.id_flags = drvp->flags; -/* - * Convert the memory to kernel space. - */ + /* + * Convert the memory to kernel space. + */ if (drvp->mem) - devp->isahd.id_maddr = (caddr_t)(drvp->mem + atdevbase - 0xA0000); + devp->isahd.id_maddr = + (caddr_t)(drvp->mem + atdevbase - 0xA0000); else devp->isahd.id_maddr = 0; devp->next = sp->devices; @@ -504,61 +445,62 @@ int err, irq = 0, s; s = splhigh(); err = dp->init(devp, 1); splx(s); -/* - * If the init 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. - */ + /* + * If the init 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. + */ if (err) remove_device(devp); else devp->running = 1; return(err); } + static void -remove_device(struct pccard_dev *dp) +remove_device(struct pccard_dev *devp) { -struct slot *sp = dp->sp; -struct pccard_dev *list; -int s; - -/* - * If an interrupt is enabled on this slot, - * then unregister it if no-one else is using it. - */ + struct slot *sp = devp->sp; + struct pccard_dev *list; + int s; + + /* + * If an interrupt is enabled on this slot, + * then unregister it if no-one else is using it. + */ s = splhigh(); - if (dp->running) { - dp->drv->unload(dp); - dp->running = 0; + if (devp->running) { + devp->drv->unload(devp); + devp->running = 0; } - if (dp->isahd.id_irq && --sp->irqref == 0) - { - sp->cinfo->mapirq(sp, 0); + if (devp->isahd.id_irq && --sp->irqref == 0) { + printf("Return IRQ=%d\n",sp->irq); + sp->ctrl->mapirq(sp, 0); INTRDIS(1<<sp->irq); unregister_intr(sp->irq, slot_irq_handler); - if (dp->drv->imask) - INTRUNMASK(*dp->drv->imask,(1<<sp->irq)); + if (devp->drv->imask) + INTRUNMASK(*devp->drv->imask,(1<<sp->irq)); sp->irq = 0; - } + } splx(s); -/* - * Remove from device list on this slot. - */ - if (sp->devices == dp) - sp->devices = dp->next; + /* + * Remove from device list on this slot. + */ + if (sp->devices == devp) + sp->devices = devp->next; else for (list = sp->devices; list->next; list = list->next) - if (list->next == dp) - { - list->next = dp->next; + if (list->next == devp) { + list->next = devp->next; break; - } -/* - * Finally, free the memory space. - */ - FREE(dp, M_DEVBUF); + } + /* + * Finally, free the memory space. + */ + FREE(devp, M_DEVBUF); } + /* * card insert routine - Called from a timeout to debounce * insertion events. @@ -566,23 +508,22 @@ int s; static void inserted(void *arg) { -struct slot *sp = arg; + struct slot *sp = arg; - sp->insert_timeout = 0; sp->state = filled; -/* - * Enable 5V to the card so that the CIS can be read. - */ + /* + * Enable 5V to the card so that the CIS can be read. + */ sp->pwr.vcc = 50; sp->pwr.vpp = 0; - sp->cinfo->power(sp); + sp->ctrl->power(sp); printf("Card inserted, slot %d\n", sp->slot); -/* - * Now reset the card. - */ - sp->cinfo->reset(sp); - selwakeup(&sp->selp); + /* + * Now start resetting the card. + */ + sp->ctrl->reset(sp); } + /* * Card event callback. Called at splhigh to prevent * device interrupts from interceding. @@ -592,56 +533,55 @@ pccard_event(struct slot *sp, enum card_event event) { int s; - if (sp->insert_timeout) - { - sp->insert_timeout = 0; + if (sp->insert_seq) { + sp->insert_seq = 0; untimeout(inserted, (void *)sp); - } - switch(event) - { -/* - * The slot and devices are disabled, but the - * data structures are not unlinked. - */ + } + switch(event) { case card_removed: - if (sp->state == filled) - { + /* + * The slot and devices are disabled, but the + * data structures are not unlinked. + */ + if (sp->state == filled) { s = splhigh(); disable_slot(sp); sp->state = empty; splx(s); printf("Card removed, slot %d\n", sp->slot); selwakeup(&sp->selp); - } + } break; case card_inserted: - sp->insert_timeout = 1; + sp->insert_seq = 1; timeout(inserted, (void *)sp, hz/4); break; - } + } } + /* * slot_irq_handler - Interrupt handler for shared irq devices. */ static void slot_irq_handler(int sp) { -struct pccard_dev *dp; + struct pccard_dev *dp; -/* - * For each device that has the shared interrupt, - * call the interrupt handler. If the interrupt was - * caught, the handler returns true. - */ + /* + * For each device that has the shared interrupt, + * call the interrupt handler. If the interrupt was + * caught, the handler returns true. + */ for (dp = ((struct slot *)sp)->devices; dp; dp = dp->next) if (dp->isahd.id_irq && dp->running && dp->drv->handler(dp)) return; printf("Slot %d, unfielded interrupt (%d)\n", ((struct slot *)sp)->slot, ((struct slot *)sp)->irq); } -/* - * Device driver interface. - */ + + /* + * Device driver interface. + */ int crdopen(dev_t dev, int oflags, int devtype, struct proc *p) { @@ -656,6 +596,7 @@ struct slot *sp; sp->rwmem = MDF_ATTR; return(0); } + /* * Close doesn't de-allocate any resources, since * slots may be assigned to drivers already. @@ -665,6 +606,7 @@ crdclose(dev_t dev, int fflag, int devtype, struct proc *p) { return(0); } + /* * read interface. Map memory at lseek offset, * then transfer to user space. @@ -672,20 +614,20 @@ crdclose(dev_t dev, int fflag, int devtype, struct proc *p) int crdread(dev_t dev, struct uio *uio, int ioflag) { -struct slot *sp = pccard_slots[minor(dev)]; -unsigned char *p; -int error = 0, win, count; -struct mem_desc *mp, oldmap; -unsigned int offs; + struct slot *sp = pccard_slots[minor(dev)]; + unsigned char *p; + int error = 0, win, count; + struct mem_desc *mp, oldmap; + unsigned int offs; if (sp == 0 || sp->state != filled) return(ENXIO); if (pccard_mem == 0) return(ENOMEM); - for (win = 0; win < sp->cinfo->maxmem; win++) + for (win = 0; win < sp->ctrl->maxmem; win++) if ((sp->mem[win].flags & MDF_ACTIVE)==0) break; - if (win >= sp->cinfo->maxmem) + if (win >= sp->ctrl->maxmem) return(EBUSY); mp = &sp->mem[win]; oldmap = *mp; @@ -694,26 +636,26 @@ unsigned int offs; printf("Rd at offs %d, size %d\n", (int)uio->uio_offset, uio->uio_resid); #endif - while (uio->uio_resid && error == 0) - { + while (uio->uio_resid && error == 0) { mp->card = uio->uio_offset; mp->size = PCCARD_MEMSIZE; mp->start = (caddr_t)pccard_mem; - if (error = sp->cinfo->mapmem(sp, win)) + if (error = sp->ctrl->mapmem(sp, win)) break; offs = (unsigned int)uio->uio_offset & (PCCARD_MEMSIZE - 1); p = pccard_kmem + offs; count = MIN(PCCARD_MEMSIZE - offs, uio->uio_resid); error = uiomove(p, count, uio); - } -/* - * Restore original map. - */ + } + /* + * Restore original map. + */ *mp = oldmap; - sp->cinfo->mapmem(sp, win); + sp->ctrl->mapmem(sp, win); return(error); } + /* * crdwrite - Write data to card memory. * Handles wrap around so that only one memory @@ -723,19 +665,19 @@ int crdwrite(dev_t dev, struct uio *uio, int ioflag) { struct slot *sp = pccard_slots[minor(dev)]; -unsigned char *p, c; -int error = 0, win, count; -struct mem_desc *mp, oldmap; -unsigned int offs; + unsigned char *p, c; + int error = 0, win, count; + struct mem_desc *mp, oldmap; + unsigned int offs; if (sp == 0 || sp->state != filled) return(ENXIO); if (pccard_mem == 0) return(ENOMEM); - for (win = 0; win < sp->cinfo->maxmem; win++) + for (win = 0; win < sp->ctrl->maxmem; win++) if ((sp->mem[win].flags & MDF_ACTIVE)==0) break; - if (win >= sp->cinfo->maxmem) + if (win >= sp->ctrl->maxmem) return(EBUSY); mp = &sp->mem[win]; oldmap = *mp; @@ -744,12 +686,11 @@ unsigned int offs; printf("Wr at offs %d, size %d\n", (int)uio->uio_offset, uio->uio_resid); #endif - while (uio->uio_resid && error == 0) - { + while (uio->uio_resid && error == 0) { mp->card = uio->uio_offset; mp->size = PCCARD_MEMSIZE; mp->start = (caddr_t)pccard_mem; - if (error = sp->cinfo->mapmem(sp, win)) + if (error = sp->ctrl->mapmem(sp, win)) break; offs = (unsigned int)uio->uio_offset & (PCCARD_MEMSIZE - 1); p = pccard_kmem + offs; @@ -758,15 +699,16 @@ unsigned int offs; printf("Writing %d bytes to address 0x%x\n", count, p); #endif error = uiomove(p, count, uio); - } -/* - * Restore original map. - */ + } + /* + * Restore original map. + */ *mp = oldmap; - sp->cinfo->mapmem(sp, win); + sp->ctrl->mapmem(sp, win); return(error); } + /* * ioctl calls - allows setting/getting of memory and I/O * descriptors, and assignment of drivers. @@ -774,34 +716,33 @@ unsigned int offs; int crdioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p) { -int s; -struct slot *sp = pccard_slots[minor(dev)]; -struct mem_desc *mp; -struct io_desc *ip; + int s; + struct slot *sp = pccard_slots[minor(dev)]; + struct mem_desc *mp; + struct io_desc *ip; if (sp == 0 && cmd != PIOCRWMEM) return(ENXIO); - switch(cmd) - { + switch(cmd) { default: - if (sp->cinfo->ioctl) - return(sp->cinfo->ioctl(sp, cmd, data)); + if (sp->ctrl->ioctl) + return(sp->ctrl->ioctl(sp, cmd, data)); return(EINVAL); case PIOCGSTATE: s = splhigh(); ((struct slotstate *)data)->state = sp->state; sp->laststate = sp->state; splx(s); - ((struct slotstate *)data)->maxmem = sp->cinfo->maxmem; - ((struct slotstate *)data)->maxio = sp->cinfo->maxio; - ((struct slotstate *)data)->irqs = sp->cinfo->irqs; + ((struct slotstate *)data)->maxmem = sp->ctrl->maxmem; + ((struct slotstate *)data)->maxio = sp->ctrl->maxio; + ((struct slotstate *)data)->irqs = sp->ctrl->irqs; break; -/* - * Get memory context. - */ + /* + * Get memory context. + */ case PIOCGMEM: s = ((struct mem_desc *)data)->window; - if (s < 0 || s >= sp->cinfo->maxmem) + if (s < 0 || s >= sp->ctrl->maxmem) return(EINVAL); mp = &sp->mem[s]; ((struct mem_desc *)data)->flags = mp->flags; @@ -809,90 +750,89 @@ struct io_desc *ip; ((struct mem_desc *)data)->size = mp->size; ((struct mem_desc *)data)->card = mp->card; break; -/* - * Set memory context. If context already active, then unmap it. - * It is hard to see how the parameters can be checked. - * At the very least, we only allow root to set the context. - */ + /* + * Set memory context. If context already active, then unmap it. + * It is hard to see how the parameters can be checked. + * At the very least, we only allow root to set the context. + */ case PIOCSMEM: if (suser(p->p_ucred, &p->p_acflag)) return(EPERM); if (sp->state != filled) return(ENXIO); s = ((struct mem_desc *)data)->window; - if (s < 0 || s >= sp->cinfo->maxmem) + if (s < 0 || s >= sp->ctrl->maxmem) return(EINVAL); sp->mem[s] = *((struct mem_desc *)data); - return(sp->cinfo->mapmem(sp, s)); -/* - * Get I/O port context. - */ + return(sp->ctrl->mapmem(sp, s)); + /* + * Get I/O port context. + */ case PIOCGIO: s = ((struct io_desc *)data)->window; - if (s < 0 || s >= sp->cinfo->maxio) + if (s < 0 || s >= sp->ctrl->maxio) return(EINVAL); ip = &sp->io[s]; ((struct io_desc *)data)->flags = ip->flags; ((struct io_desc *)data)->start = ip->start; ((struct io_desc *)data)->size = ip->size; break; -/* - * Set I/O port context. - */ + /* + * Set I/O port context. + */ case PIOCSIO: if (suser(p->p_ucred, &p->p_acflag)) return(EPERM); if (sp->state != filled) return(ENXIO); s = ((struct io_desc *)data)->window; - if (s < 0 || s >= sp->cinfo->maxio) + if (s < 0 || s >= sp->ctrl->maxio) return(EINVAL); sp->io[s] = *((struct io_desc *)data); - return(sp->cinfo->mapio(sp, s)); + return(sp->ctrl->mapio(sp, s)); break; -/* - * Set memory window flags for read/write interface. - */ + /* + * Set memory window flags for read/write interface. + */ case PIOCRWFLAG: sp->rwmem = *(int *)data; break; -/* - * Set the memory window to be used for the read/write - * interface. - */ + /* + * Set the memory window to be used for the read/write + * interface. + */ case PIOCRWMEM: - if (*(unsigned long *)data == 0) - { + if (*(unsigned long *)data == 0) { if (pccard_mem) *(unsigned long *)data = pccard_mem; break; - } + } if (suser(p->p_ucred, &p->p_acflag)) return(EPERM); -/* - * Validate the memory by checking it against the - * I/O memory range. It must also start on an aligned block size. - */ + /* + * Validate the memory by checking it against the I/O + * memory range. It must also start on an aligned block size. + */ if (invalid_io_memory(*(unsigned long *)data, PCCARD_MEMSIZE)) return(EINVAL); if (*(unsigned long *)data & (PCCARD_MEMSIZE-1)) return(EINVAL); -/* - * Map it to kernel VM. - */ + /* + * Map it to kernel VM. + */ pccard_mem = *(unsigned long *)data; pccard_kmem = (unsigned char *)(pccard_mem + atdevbase - 0xA0000); break; -/* - * Set power values - */ + /* + * Set power values + */ case PIOCSPOW: sp->pwr = *(struct power *)data; - return(sp->cinfo->power(sp)); -/* - * Allocate a driver to this slot. - */ + return(sp->ctrl->power(sp)); + /* + * Allocate a driver to this slot. + */ case PIOCSDRV: if (suser(p->p_ucred, &p->p_acflag)) return(EPERM); @@ -900,6 +840,7 @@ struct io_desc *ip; } return(0); } + /* * select - Selects on exceptions will return true * when a change in card status occurs. @@ -907,29 +848,29 @@ struct io_desc *ip; int crdselect(dev_t dev, int rw, struct proc *p) { -int s; -struct slot *sp = pccard_slots[minor(dev)]; + int s; + struct slot *sp = pccard_slots[minor(dev)]; switch (rw) { case FREAD: return 1; case FWRITE: return 1; -/* - * select for exception - card event. - */ + /* + * select for exception - card event. + */ case 0: s = splhigh(); - if (sp == 0 || sp->laststate != sp->state) - { + if (sp == 0 || sp->laststate != sp->state) { splx(s); return(1); - } + } selrecord(p, &sp->selp); splx(s); } return(0); } + /* * invalid_io_memory - verify that the ISA I/O memory block * is a valid and unallocated address. @@ -944,15 +885,14 @@ invalid_io_memory(unsigned long adr, int size) return(1); return(0); } + static struct pccard_drv * find_driver(char *name) { -struct pccard_drv *dp; + struct pccard_drv *dp; for (dp = drivers; dp; dp = dp->next) if (strcmp(dp->name, name)==0) return(dp); return(0); } - -#endif /* NCRD */ diff --git a/sys/pccard/pcic.c b/sys/pccard/pcic.c index 6b2854f..cfbb9b9 100644 --- a/sys/pccard/pcic.c +++ b/sys/pccard/pcic.c @@ -46,17 +46,18 @@ #include <sys/sysent.h> #include <sys/exec.h> #include <sys/lkm.h> +#include <sys/devconf.h> #include <machine/clock.h> +#include <pccard/i82365.h> +#include <pccard/card.h> +#include <pccard/slot.h> + #include <i386/isa/isa.h> #include <i386/isa/isa_device.h> #include <i386/isa/icu.h> -#include <pccard/i82365.h> -#include <pccard/card.h> -#include <pccard/slot.h> -#include <sys/devconf.h> extern struct kern_devconf kdc_pccard0; @@ -76,34 +77,34 @@ struct kern_devconf kdc_pcic[PCIC_MAX_SLOTS] = { /* * Prototypes for interrupt handler. */ -static void pcicintr __P((int unit)); -static int pcic_ioctl __P((struct slot *, int, caddr_t)); -static int pcic_power __P((struct slot *)); -static void pcic_reset __P((struct slot *)); -static void pcic_disable __P((struct slot *)); -static void pcic_mapirq __P((struct slot *, int)); -static timeout_t pcictimeout; +static void pcicintr __P((int unit)); +static int pcic_ioctl __P((struct slot *, int, caddr_t)); +static int pcic_power __P((struct slot *)); +static void pcic_reset __P((struct slot *)); +static void pcic_disable __P((struct slot *)); +static void pcic_mapirq __P((struct slot *, int)); +static timeout_t pcictimeout; +static int pcic_memory(struct slot *, int); +static int pcic_io(struct slot *, int); + int pcic_probe(); /* * Per-slot data table. */ -static struct pcic_slot - { +static struct pcic_slot { int slot; /* My slot number */ int index; /* Index register */ int data; /* Data register */ int offset; /* Offset value for index */ - char controller; /* Device type */ - char revision; /* Device Revision */ - struct slot *sp; /* Back ptr to slot */ - } pcic_slots[PCIC_MAX_SLOTS]; -static int pcic_irq; -static unsigned pcic_imask; -static struct slot_cont cinfo; - -static int pcic_memory(struct slot *, int); -static int pcic_io(struct slot *, int); -int pcic_probe(); + char controller; /* Device type */ + char revision; /* Device Revision */ + struct slot *slotp; /* Back ptr to slot */ +} pcic_slots[PCIC_MAX_SLOTS]; + +static int pcic_irq; +static unsigned pcic_imask; +static struct slot_ctrl cinfo; + /* * Internal inline functions for accessing the PCIC. @@ -174,11 +175,9 @@ static int pcic_unload(); */ static int -pcic_handle( lkmtp, cmd) -struct lkm_table *lkmtp; -int cmd; +pcic_handle(struct lkm_table *lkmtp, int cmd) { - int err = 0; /* default = success*/ + int err = 0; /* default = success*/ switch( cmd) { case LKM_E_LOAD: @@ -188,16 +187,16 @@ int cmd; */ if( lkmexists( lkmtp)) return( EEXIST); -/* - * Call the probe routine to find the slots. If - * no slots exist, then don't bother loading the module. - */ + /* + * Call the probe routine to find the slots. If + * no slots exist, then don't bother loading the module. + */ if (pcic_probe() == 0) return(ENODEV); break; /* Success*/ -/* - * Attempt to unload the slot driver. - */ + /* + * Attempt to unload the slot driver. + */ case LKM_E_UNLOAD: printf("Unloading PCIC driver\n"); err = pcic_unload(); @@ -231,13 +230,11 @@ int cmd; * case it should return an errno from errno.h). */ int -pcic_mod(lkmtp, cmd, ver) -struct lkm_table *lkmtp; -int cmd; -int ver; +pcic_mod(struct lkm_table *lkmtp, int cmd, int ver) { DISPATCH(lkmtp,cmd,ver,pcic_handle,pcic_handle,nosys) } + /* * pcic_unload - Called when unloading a LKM. * Disables interrupts and resets PCIC. @@ -245,23 +242,23 @@ int ver; static int pcic_unload() { -int slot; -struct pcic_slot *cp = pcic_slots; + int slot; + struct pcic_slot *sp = pcic_slots; untimeout(pcictimeout,0); - if (pcic_irq) - { - for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, cp++) { - if (cp->sp) - putb(cp, PCIC_STAT_INT, 0); + if (pcic_irq) { + for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) { + if (sp->slotp) + putb(sp, PCIC_STAT_INT, 0); kdc_pcic[slot].kdc_state = DC_UNCONFIGURED; } unregister_intr(pcic_irq, pcicintr); - } + } pccard_remove_controller(&cinfo); return(0); } -#endif LKM + +#endif /* LKM */ #if 0 static void @@ -271,19 +268,18 @@ pcic_dump_attributes (unsigned char *scratch, int maxlen) i = 0; while (scratch[i] != 0xff && i < maxlen) { - unsigned char link = scratch[i+2]; + 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"); + /* + * 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; + i += 4 + 2 * link; } } #endif @@ -292,58 +288,58 @@ pcic_dump_attributes (unsigned char *scratch, int maxlen) * entry point from main code to map/unmap memory context. */ static int -pcic_memory(struct slot *sp, int win) +pcic_memory(struct slot *slotp, int win) { -struct pcic_slot *cp = sp->cdata; -struct mem_desc *mp = &sp->mem[win]; -int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE; + struct pcic_slot *sp = slotp->cdata; + struct mem_desc *mp = &slotp->mem[win]; + int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE; if (mp->flags & MDF_ACTIVE) { unsigned long sys_addr = (unsigned long)mp->start >> 12; -/* - * Write the addresses, card offsets and length. - * The values are all stored as the upper 12 bits of the - * 24 bit address i.e everything is allocated as 4 Kb chunks. - */ - putw (cp, reg, sys_addr & 0xFFF); - putw (cp, reg+2, (sys_addr + (mp->size >> 12) - 1) & 0xFFF); - putw (cp, reg+4, ((mp->card >> 12) - sys_addr) & 0x3FFF); + /* + * Write the addresses, card offsets and length. + * The values are all stored as the upper 12 bits of the + * 24 bit address i.e everything is allocated as 4 Kb chunks. + */ + 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. - */ + /* + * Each 16 bit register has some flags in the upper bits. + */ if (mp->flags & MDF_16BITS) - setb(cp, reg+1, PCIC_DATA16); + setb(sp, reg+1, PCIC_DATA16); if (mp->flags & MDF_ZEROWS) - setb(cp, reg+1, PCIC_ZEROWS); + setb(sp, reg+1, PCIC_ZEROWS); if (mp->flags & MDF_WS0) - setb(cp, reg+3, PCIC_MW0); + setb(sp, reg+3, PCIC_MW0); if (mp->flags & MDF_WS1) - setb(cp, reg+3, PCIC_MW1); + setb(sp, reg+3, PCIC_MW1); if (mp->flags & MDF_ATTR) - setb(cp, reg+5, PCIC_REG); + setb(sp, reg+5, PCIC_REG); if (mp->flags & MDF_WP) - setb(cp, reg+5, PCIC_WP); + setb(sp, reg+5, PCIC_WP); #if 0 printf("Slot number %d, reg 0x%x, offs 0x%x\n", - cp->slot, reg, cp->offset); + sp->slot, 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", - getb(cp, reg), getb(cp, reg+1), - getb(cp, reg+2), getb(cp, reg+3), - getb(cp, reg+4), getb(cp, reg+5), + getb(sp, reg), getb(sp, reg+1), + getb(sp, reg+2), getb(sp, reg+3), + getb(sp, reg+4), getb(sp, reg+5), mp->flags); #endif -/* - * Enable the memory window. By experiment, we need a delay. - */ - setb (cp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16); + /* + * Enable the memory window. By experiment, we need a delay. + */ + setb (sp, PCIC_ADDRWINE, (1<<win) | PCIC_MEMCS16); DELAY(50); } else @@ -351,39 +347,36 @@ int reg = mp->window * PCIC_MEMSIZE + PCIC_MEMBASE; #if 0 printf("Unmapping window %d\n", win); #endif - clrb (cp, PCIC_ADDRWINE, 1<<win); - putw (cp, reg, 0); - putw (cp, reg+2, 0); - putw (cp, reg+4, 0); + clrb (sp, PCIC_ADDRWINE, 1<<win); + putw (sp, reg, 0); + putw (sp, reg+2, 0); + putw (sp, reg+4, 0); } return(0); } + /* * pcic_io - map or unmap I/O context */ static int -pcic_io(struct slot *sp, int win) +pcic_io(struct slot *slotp, int win) { -int mask, reg; -struct pcic_slot *cp = sp->cdata; -struct io_desc *ip = &sp->io[win]; + int mask, reg; + struct pcic_slot *sp = slotp->cdata; + struct io_desc *ip = &slotp->io[win]; - if (win) - { + if (win) { mask = PCIC_IO0_EN; reg = PCIC_IO0; - } - else - { + } else { mask = PCIC_IO1_EN; reg = PCIC_IO1; - } - if (ip->flags & IODF_ACTIVE) - { + } + if (ip->flags & IODF_ACTIVE) { unsigned char x = 0; - putw (cp, reg, ip->start); - putw (cp, reg+2, ip->start+ip->size-1); + putw (sp, reg, ip->start); + putw (sp, reg+2, ip->start+ip->size-1); if (ip->flags & IODF_ZEROWS) x = PCIC_IO_0WS; if (ip->flags & IODF_WS) @@ -392,27 +385,26 @@ struct io_desc *ip = &sp->io[win]; x |= PCIC_IO_CS16; else if (ip->flags & IODF_16BIT) x |= PCIC_IO_16BIT; -/* - * Extract the current flags and merge with new flags. - * Flags for window 0 in lower nybble, and in upper nybble - * for window 1. - */ + /* + * Extract the current flags and merge with new flags. + * Flags for window 0 in lower nybble, and in upper nybble + * for window 1. + */ if (win) - putb(cp, PCIC_IOCTL, (x << 4) | - (getb(cp, PCIC_IOCTL) & 0xF)); + putb(sp, PCIC_IOCTL, (x << 4) | + (getb(sp, PCIC_IOCTL) & 0xF)); else - putb(cp, PCIC_IOCTL, x | (getb(cp, PCIC_IOCTL) & 0xF0)); - setb (cp, PCIC_ADDRWINE, mask); + putb(sp, PCIC_IOCTL, x | (getb(sp, PCIC_IOCTL) & 0xF0)); + setb (sp, PCIC_ADDRWINE, mask); DELAY(100); - } - else - { - clrb (cp, PCIC_ADDRWINE, mask); - putw (cp, reg, 0); - putw (cp, reg + 2, 0); - } + } else { + clrb (sp, PCIC_ADDRWINE, mask); + putw (sp, reg, 0); + putw (sp, reg + 2, 0); + } return(0); } + /* * Look for an Intel PCIC (or compatible). * For each available slot, allocate a PC-CARD slot. @@ -421,14 +413,14 @@ struct io_desc *ip = &sp->io[win]; int pcic_probe () { -int slot, i, validslots = 0; -struct slot *sp; -struct pcic_slot *cp; -unsigned char c; + int slot, i, validslots = 0; + struct slot *slotp; + struct pcic_slot *sp; + unsigned char c; -/* - * Initialise controller information structure. - */ + /* + * Initialise controller information structure. + */ cinfo.mapmem = pcic_memory; cinfo.mapio = pcic_io; cinfo.ioctl = pcic_ioctl; @@ -443,187 +435,181 @@ unsigned char c; #ifdef LKM bzero(pcic_slots, sizeof(pcic_slots)); #endif - cp = pcic_slots; - for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, cp++) { -/* - * Initialise the PCIC slot table. - */ - if (slot < 4) - { - cp->index = PCIC_INDEX_0; - cp->data = PCIC_DATA_0; - cp->offset = slot * PCIC_SLOT_SIZE; - } - else - { - cp->index = PCIC_INDEX_1; - cp->data = PCIC_DATA_1; - cp->offset = (slot - 4) * PCIC_SLOT_SIZE; + sp = pcic_slots; + for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) { + /* + * Initialise the PCIC slot table. + */ + if (slot < 4) { + sp->index = PCIC_INDEX_0; + sp->data = PCIC_DATA_0; + sp->offset = slot * PCIC_SLOT_SIZE; + } else { + sp->index = PCIC_INDEX_1; + sp->data = PCIC_DATA_1; + sp->offset = (slot - 4) * PCIC_SLOT_SIZE; } - /* - * see if there's a PCMCIA controller here - * Intel PCMCIA controllers use 0x82 and 0x83 - * IBM clone chips use 0x88 and 0x89, apparently - */ - c = getb (cp, PCIC_ID_REV); - cp->revision = -1; - switch(c) - { -/* - * 82365 or clones. - */ - case 0x82: - case 0x83: - cp->controller = PCIC_I82365; - cp->revision = c & 1; -/* - * Now check for VADEM chips. - */ - outb(cp->index, 0x0E); - outb(cp->index, 0x37); - setb(cp, 0x3A, 0x40); - c = getb (cp, PCIC_ID_REV); - if (c & 0x08) - { - cp->controller = PCIC_VG468; - cp->revision = c & 7; - clrb(cp, 0x3A, 0x40); + /* + * see if there's a PCMCIA controller here + * Intel PCMCIA controllers use 0x82 and 0x83 + * IBM clone chips use 0x88 and 0x89, apparently + */ + c = getb (sp, PCIC_ID_REV); + sp->revision = -1; + switch(c) { + /* + * 82365 or clones. + */ + case 0x82: + case 0x83: + sp->controller = PCIC_I82365; + sp->revision = c & 1; + /* + * Now check for VADEM chips. + */ + outb(sp->index, 0x0E); + outb(sp->index, 0x37); + setb(sp, 0x3A, 0x40); + c = getb (sp, PCIC_ID_REV); + if (c & 0x08) { + sp->controller = ((sp->revision = c & 7) == 4) ? + PCIC_VG469 : PCIC_VG468 ; + clrb(sp, 0x3A, 0x40); } - break; -/* - * VLSI chips. - */ - case 0x84: - cp->controller = PCIC_VLSI; - break; - case 0x88: - case 0x89: - cp->controller = PCIC_IBM; - cp->revision = c & 1; - break; - default: - continue; + break; + /* + * VLSI chips. + */ + case 0x84: + sp->controller = PCIC_VLSI; + break; + case 0x88: + case 0x89: + sp->controller = PCIC_IBM; + sp->revision = c & 1; + break; + default: + continue; } -/* - * Check for Cirrus logic chips. - */ - putb(cp, 0x1F, 0); - c = getb(cp, 0x1F); - if ((c & 0xC0) == 0xC0) - { - c = getb(cp, 0x1F); - if ((c & 0xC0) == 0) - { - if (c & 0x20) - cp->controller = PCIC_PD672X; - else - cp->controller = PCIC_PD6710; - cp->revision = 8 - ((c & 0x1F) >> 2); + /* + * Check for Cirrus logic chips. + */ + putb(sp, 0x1F, 0); + c = getb(sp, 0x1F); + if ((c & 0xC0) == 0xC0) { + c = getb(sp, 0x1F); + if ((c & 0xC0) == 0) { + if (c & 0x20) + sp->controller = PCIC_PD672X; + else + sp->controller = PCIC_PD6710; + sp->revision = 8 - ((c & 0x1F) >> 2); } } - switch(cp->controller) - { - case PCIC_I82365: - cinfo.name = "Intel 82365"; - break; - case PCIC_IBM: - cinfo.name = "IBM PCIC"; - break; - case PCIC_PD672X: - cinfo.name = "Cirrus Logic PD672X"; - break; - case PCIC_PD6710: - cinfo.name = "Cirrus Logic PD6710"; - break; - case PCIC_VG468: - cinfo.name = "Vadem 468"; - break; - default: - cinfo.name = "Unknown!"; - break; + switch(sp->controller) { + case PCIC_I82365: + cinfo.name = "Intel 82365"; + break; + case PCIC_IBM: + cinfo.name = "IBM PCIC"; + break; + case PCIC_PD672X: + cinfo.name = "Cirrus Logic PD672X"; + break; + case PCIC_PD6710: + cinfo.name = "Cirrus Logic PD6710"; + break; + case PCIC_VG468: + cinfo.name = "Vadem 468"; + break; + case PCIC_VG469: + cinfo.name = "Vadem 469"; + break; + default: + cinfo.name = "Unknown!"; + break; } -/* - * clear out the registers. - */ - for (i = 2; i < 0x40; i++) - putb(cp, i, 0); -/* - * OK it seems we have a PCIC or lookalike. - * Allocate a slot and initialise the data structures. - */ - validslots++; - cp->slot = slot; - if (kdc_pcic[slot].kdc_state == DC_UNKNOWN) { - if (slot != 0) - kdc_pcic[slot] = kdc_pcic[0]; - kdc_pcic[slot].kdc_unit = slot; - kdc_pcic[slot].kdc_state = DC_UNCONFIGURED; - kdc_pcic[slot].kdc_description = cinfo.name; - dev_attach(kdc_pcic+slot); - } - sp = pccard_alloc_slot(&cinfo); - if (sp == 0) - continue; - kdc_pcic[slot].kdc_state = DC_IDLE; - sp->cdata = cp; - cp->sp = sp; -/* - * If we haven't allocated an interrupt for the controller, - * then attempt to get one. - */ - if (pcic_irq == 0) - { - pcic_irq = pccard_alloc_intr(PCIC_INT_MASK_ALLOWED, - pcicintr, 0, &pcic_imask); - if (pcic_irq < 0) - printf("pcic: failed to allocate IRQ\n"); + /* + * clear out the registers. + */ + for (i = 2; i < 0x40; i++) + putb(sp, i, 0); + /* + * OK it seems we have a PCIC or lookalike. + * Allocate a slot and initialise the data structures. + */ + validslots++; + sp->slot = slot; + if (kdc_pcic[slot].kdc_state == DC_UNKNOWN) { + if (slot != 0) + kdc_pcic[slot] = kdc_pcic[0]; + kdc_pcic[slot].kdc_unit = slot; + kdc_pcic[slot].kdc_state = DC_UNCONFIGURED; + kdc_pcic[slot].kdc_description = cinfo.name; + dev_attach(kdc_pcic+slot); } -/* - * Check for a card in this slot. - */ - setb (cp, PCIC_POWER, PCIC_APSENA | PCIC_DISRST); - if ((getb (cp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) - sp->laststate = sp->state = empty; - else - { - sp->laststate = sp->state = filled; - pccard_event(cp->sp, card_inserted); + slotp = pccard_alloc_slot(&cinfo); + if (slotp == 0) + continue; + kdc_pcic[slot].kdc_state = DC_IDLE; + slotp->cdata = sp; + sp->slotp = slotp; + /* + * If we haven't allocated an interrupt for the controller, + * then attempt to get one. + */ + if (pcic_irq == 0) { + pcic_irq = pccard_alloc_intr(PCIC_INT_MASK_ALLOWED, + pcicintr, 0, &pcic_imask); + if (pcic_irq < 0) + printf("pcic: failed to allocate IRQ\n"); } -/* - * Assign IRQ for slot changes - */ - if (pcic_irq > 0) - putb(cp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); + /* + * Check for a card in this slot. + */ + setb (sp, PCIC_POWER, PCIC_APSENA | PCIC_DISRST); + if ((getb (sp, PCIC_STATUS) & PCIC_CD) != PCIC_CD) { + slotp->laststate = slotp->state = empty; + } else { + slotp->laststate = slotp->state = filled; + pccard_event(sp->slotp, card_inserted); + } + /* + * Assign IRQ for slot changes + */ + if (pcic_irq > 0) + putb(sp, PCIC_STAT_INT, (pcic_irq << 4) | 0xF); } if (validslots) timeout(pcictimeout,0,hz/2); return(validslots); } + /* * ioctl calls - Controller specific ioctls */ static int -pcic_ioctl(struct slot *sp, int cmd, caddr_t data) +pcic_ioctl(struct slot *slotp, int cmd, caddr_t data) { - switch(cmd) - { + switch(cmd) { default: return(EINVAL); -/* - * Get/set PCIC registers - */ + /* + * Get/set PCIC registers + */ case PIOCGREG: ((struct pcic_reg *)data)->value = - getb(sp->cdata, ((struct pcic_reg *)data)->reg); + getb(slotp->cdata, ((struct pcic_reg *)data)->reg); break; case PIOCSREG: - putb(sp->cdata, ((struct pcic_reg *)data)->reg, + putb(slotp->cdata, ((struct pcic_reg *)data)->reg, ((struct pcic_reg *)data)->value); break; - } + } return(0); } + /* * pcic_power - Enable the power of the slot according to * the parameters in the power structure(s). @@ -631,15 +617,14 @@ pcic_ioctl(struct slot *sp, int cmd, caddr_t data) static int pcic_power(struct slot *slotp) { -unsigned char reg = PCIC_DISRST|PCIC_APSENA; -struct pcic_slot *sp = slotp->cdata; + unsigned char reg = PCIC_DISRST|PCIC_APSENA; + struct pcic_slot *sp = slotp->cdata; - switch(sp->controller) - { + switch(sp->controller) { case PCIC_PD672X: case PCIC_PD6710: - switch(slotp->pwr.vpp) - { + case PCIC_VG469: + switch(slotp->pwr.vpp) { default: return(EINVAL); case 0: @@ -651,31 +636,35 @@ struct pcic_slot *sp = slotp->cdata; case 120: reg |= PCIC_VPP_12V; break; - } - switch(slotp->pwr.vcc) - { + } + switch(slotp->pwr.vcc) { default: return(EINVAL); case 0: break; case 33: reg |= PCIC_VCC_5V; - setb(sp, 0x16, 0x02); + if (sp->controller == PCIC_VG469) + setb(sp, 0x2f, 0x03) ; + else + setb(sp, 0x16, 0x02); break; case 50: reg |= PCIC_VCC_5V; - clrb(sp, 0x16, 0x02); + if (sp->controller == PCIC_VG469) + clrb(sp, 0x2f, 0x03) ; + else + clrb(sp, 0x16, 0x02); break; - } } + } putb (sp, PCIC_POWER, reg); DELAY(300*1000); - if (slotp->pwr.vcc) - { + if (slotp->pwr.vcc) { reg |= PCIC_OUTENA; putb (sp, PCIC_POWER, reg); DELAY (100*1000); - } + } return(0); } @@ -686,44 +675,65 @@ struct pcic_slot *sp = slotp->cdata; static void pcic_mapirq (struct slot *slotp, int irq) { -struct pcic_slot *sp = slotp->cdata; + struct pcic_slot *sp = slotp->cdata; if (irq == 0) clrb(sp, PCIC_INT_GEN, 0xF); else putb (sp, PCIC_INT_GEN, (getb (sp, PCIC_INT_GEN) & 0xF0) | irq); } + /* * pcic_reset - Reset the card and enable initial power. - * Allow */ + static void pcic_reset(struct slot *slotp) { -struct pcic_slot *sp = slotp->cdata; - - clrb (sp, PCIC_INT_GEN, PCIC_CARDRESET); - DELAY (200*1000); - setb (sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD); - DELAY (200*1000); - if (sp->controller == PCIC_PD672X || - sp->controller == PCIC_PD6710) - { + struct pcic_slot *sp = slotp->cdata; + + switch (slotp->insert_seq) { + case 0: /* Something funny happended on the way to the pub... */ + return; + case 1: /* Assert reset */ + printf("R"); + clrb (sp, PCIC_INT_GEN, PCIC_CARDRESET); + slotp->insert_seq = 2; + timeout(pcic_reset, (void*) slotp, hz/4); + return; + case 2: /* Deassert it again */ + printf("r"); + setb (sp, PCIC_INT_GEN, PCIC_CARDRESET|PCIC_IOCARD); + slotp->insert_seq = 3; + timeout(pcic_reset, (void*) slotp, hz/4); + return; + case 3: /* Wait if card needs more time */ + if (!getb(sp, PCIC_STATUS) & PCIC_READY) { + printf("_"); + timeout(pcic_reset, (void*) slotp, hz/10); + return; + } + } + printf(".\n"); + slotp->insert_seq = 0; + if (sp->controller == PCIC_PD672X || sp->controller == PCIC_PD6710) { putb(sp, PCIC_TIME_SETUP0, 0x1); putb(sp, PCIC_TIME_CMD0, 0x6); putb(sp, PCIC_TIME_RECOV0, 0x0); putb(sp, PCIC_TIME_SETUP1, 1); putb(sp, PCIC_TIME_CMD1, 0x5F); putb(sp, PCIC_TIME_RECOV1, 0); - } + } + selwakeup(&slotp->selp); } + /* * pcic_disable - Disable the slot. */ static void pcic_disable(struct slot *slotp) { -struct pcic_slot *sp = slotp->cdata; + struct pcic_slot *sp = slotp->cdata; putb(sp, PCIC_INT_GEN, 0); putb(sp, PCIC_POWER, 0); @@ -750,21 +760,21 @@ pcictimeout(void *chan) static void pcicintr(int unit) { -int slot, s; -unsigned char chg; -struct pcic_slot *cp = pcic_slots; + int slot, s; + unsigned char chg; + struct pcic_slot *sp = pcic_slots; s = splhigh(); - for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, cp++) - if (cp->sp && (chg = getb(cp, PCIC_STAT_CHG)) != 0) + for (slot = 0; slot < PCIC_MAX_SLOTS; slot++, sp++) + if (sp->slotp && (chg = getb(sp, PCIC_STAT_CHG)) != 0) if (chg & PCIC_CDTCH) { - if ((getb(cp, PCIC_STATUS) & PCIC_CD) == + if ((getb(sp, PCIC_STATUS) & PCIC_CD) == PCIC_CD) { kdc_pcic[slot].kdc_state = DC_BUSY;; - pccard_event(cp->sp, + pccard_event(sp->slotp, card_inserted); } else { - pccard_event(cp->sp, + pccard_event(sp->slotp, card_removed); kdc_pcic[slot].kdc_state = DC_IDLE;; } diff --git a/sys/pccard/slot.h b/sys/pccard/slot.h index 4ee0602..51c7cb9 100644 --- a/sys/pccard/slot.h +++ b/sys/pccard/slot.h @@ -32,11 +32,11 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + /* * Controller data - Specific to each slot controller. */ -struct slot_cont - { +struct slot_ctrl { int (*mapmem)(); /* Map memory */ int (*mapio)(); /* Map io */ void (*reset)(); /* init */ @@ -49,13 +49,14 @@ struct slot_cont int maxio; /* Number of allowed I/O windows */ int irqs; /* IRQ's that are allowed */ char *name; /* controller name */ -/* - * The rest is maintained by the mainline PC-CARD code. - */ + /* + * The rest is maintained by the mainline PC-CARD code. + */ - struct slot_cont *next; /* Allows linked list of controllers */ + struct slot_ctrl *next; /* Allows linked list of controllers */ int slots; /* Slots available */ - }; +}; + /* * Driver structure - each driver registers itself * with the mainline PC-CARD code. These drivers are @@ -63,8 +64,7 @@ struct slot_cont */ struct pccard_dev; -struct pccard_drv - { +struct pccard_drv { char *name; /* Driver name */ int (*handler)(struct pccard_dev *); /* Interrupt handler */ void (*unload)(struct pccard_dev *); /* Disable driver */ @@ -74,7 +74,8 @@ struct pccard_drv unsigned int *imask; /* Interrupt mask ptr */ struct pccard_drv *next; - }; +}; + /* * Device structure for cards. Each card may have one * or more drivers attached to it; each driver is assumed @@ -82,8 +83,7 @@ struct pccard_drv * and one memory block. This structure is used to link the different * devices together. */ -struct pccard_dev - { +struct pccard_dev { struct pccard_dev *next; /* List of drivers */ struct isa_device isahd; /* Device details */ struct pccard_drv *drv; @@ -91,13 +91,12 @@ struct pccard_dev struct slot *sp; /* Back pointer to slot */ int running; /* Current state of driver */ u_char misc[128]; /* For any random info */ - }; +}; /* * Per-slot structure. */ -struct slot - { +struct slot { struct slot *next; /* Master list */ int slot; /* Slot number */ int flags; /* Slot flags (see below) */ @@ -106,24 +105,24 @@ struct slot int irq; /* IRQ allocated (0 = none) */ int irqref; /* Reference count of driver IRQs */ struct pccard_dev *devices; /* List of drivers attached */ -/* - * flags. - */ - unsigned int insert_timeout:1; /* Insert timeout active */ + /* + * flags. + */ + unsigned int insert_seq; /* Firing up under the card */ - enum cardstate state, laststate; /* Current/last card states */ - struct selinfo selp; /* Info for select */ - struct mem_desc mem[NUM_MEM_WINDOWS]; /* Memory windows */ - struct io_desc io[NUM_IO_WINDOWS]; /* I/O windows */ - struct power pwr; /* Power values */ - struct slot_cont *cinfo; /* Per-controller data */ - void *cdata; /* Controller specific data */ - }; + enum cardstate state, laststate; /* Current/last card states */ + struct selinfo selp; /* Info for select */ + struct mem_desc mem[NUM_MEM_WINDOWS]; /* Memory windows */ + struct io_desc io[NUM_IO_WINDOWS]; /* I/O windows */ + struct power pwr; /* Power values */ + struct slot_ctrl *ctrl; /* Per-controller data */ + void *cdata; /* Controller specific data */ +}; enum card_event { card_removed, card_inserted }; -struct slot *pccard_alloc_slot(struct slot_cont *); -void pccard_event(struct slot *, enum card_event); -void pccard_remove_controller(struct slot_cont *); -int pccard_alloc_intr(); -void pccard_add_driver(struct pccard_drv *); +struct slot *pccard_alloc_slot(struct slot_ctrl *); +void pccard_event(struct slot *, enum card_event); +void pccard_remove_controller(struct slot_ctrl *); +int pccard_alloc_intr(); +void pccard_add_driver(struct pccard_drv *); |