diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/eisa/eisaconf.c | 589 | ||||
-rw-r--r-- | sys/i386/eisa/aic7770.c | 8 | ||||
-rw-r--r-- | sys/i386/eisa/eisaconf.c | 589 |
3 files changed, 578 insertions, 608 deletions
diff --git a/sys/dev/eisa/eisaconf.c b/sys/dev/eisa/eisaconf.c index cddaa1b762d5..f10869388df9 100644 --- a/sys/dev/eisa/eisaconf.c +++ b/sys/dev/eisa/eisaconf.c @@ -18,22 +18,21 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: eisaconf.c,v 1.3 1995/11/05 04:42:49 gibbs Exp $ + * $Id: eisaconf.c,v 1.4 1995/11/06 05:20:59 gibbs Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/conf.h> #include <sys/malloc.h> +#include <sys/devconf.h> -#include "sys/types.h" #include "i386/isa/icu.h" /* Hmmm. Interrupt stuff? */ -#include <sys/devconf.h> #include "eisaconf.h" struct eisa_device_node{ - struct eisa_device dev; - struct eisa_device_node *next; + struct eisa_device dev; + struct eisa_device_node *next; }; extern struct kern_devconf kdc_cpu0; @@ -74,173 +73,144 @@ static struct eisa_driver mainboard_drv = { void eisa_configure() { - int i,slot; - char *id_string; - struct eisa_device_node *dev_node; - struct eisa_driver **e_drvp = (struct eisa_driver**)eisadriver_set.ls_items; - struct eisa_driver *e_drv; - struct eisa_device *e_dev; - int eisaBase = 0xC80; - int first_slot = 0; - eisa_id_t eisa_id; - - outb(eisaBase,0xFF); - eisa_id = inb(eisaBase); - if (eisa_id & 0x80) { - /* - * Not an EISA machine. We still want to find boards like the - * Adaptec 284x that respond to EISA probes, so we "fake" the - * system board entry which the rest of the code uses as the - * sentinal node in the eisa_dev_list. - */ - first_slot = 1; /* Start at slot 1 just to be safe */ - eisaBase+=0x1000; - dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), - M_DEVBUF, M_NOWAIT); - if (!dev_node) { - printf("eisa0: cannot malloc eisa_device_node"); - return; - } - bzero(dev_node, sizeof(*dev_node)); - e_dev = &(dev_node->dev); - e_dev->ioconf.slot = 0; - *eisa_dev_list_tail = dev_node; - eisa_dev_list_tail = &dev_node->next; - } - - for (slot = first_slot; slot < EISA_SLOTS; eisaBase+=0x1000, slot++) { - int id_size = sizeof(eisa_id); - eisa_id = 0; - for( i = 0; i < id_size; i++ ) { - outb(eisaBase,0xc80 + i); /* Some cards require priming */ - eisa_id |= inb(eisaBase + i) << ((id_size - i - 1) * CHAR_BIT); - } - if (eisa_id & 0x80000000) - continue; /* no EISA card in slot */ - - /* Prepare an eisa_device_node for this slot */ - dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), - M_DEVBUF, M_NOWAIT); - if (!dev_node) { - printf("eisa0: cannot malloc eisa_device_node"); - break; /* Try to attach what we have already */ - } - bzero(dev_node, sizeof(*dev_node)); - e_dev = &(dev_node->dev); - e_dev->id = eisa_id; - /* - * Add an EISA ID based descriptive name incase we don't - * have a driver for it. We do this now instead of after all - * probes because in the future, the eisa module will only - * be responsible for creating the list of devices in the system - * for the configuration manager to use. - */ - e_dev->full_name = (char *)malloc(14*sizeof(char), M_DEVBUF, M_NOWAIT); - if (!e_dev->full_name) { - panic("Eisa probe unable to malloc"); - } - sprintf(e_dev->full_name, "%c%c%c%x rev %x", - EISA_MFCTR_CHAR0(e_dev->id), - EISA_MFCTR_CHAR1(e_dev->id), - EISA_MFCTR_CHAR2(e_dev->id), - EISA_PRODUCT_ID(e_dev->id), - EISA_REVISION_ID(e_dev->id)); - e_dev->ioconf.slot = slot; - /* Is iobase defined in any EISA specs? */ - e_dev->ioconf.iobase = eisaBase & 0xff00; - *eisa_dev_list_tail = dev_node; - eisa_dev_list_tail = &dev_node->next; - } - - dev_node = eisa_dev_list; - - /* - * "Attach" the system board - */ - - /* The first entry had better be the motherboard */ - if (!dev_node || (dev_node->dev.ioconf.slot != 0)) - panic("EISA system board not in eisa_dev_list"); - - e_dev = &dev_node->dev; - e_dev->driver = &mainboard_drv; - e_dev->unit = (*e_dev->driver->unit)++; - - if (e_dev->full_name) { /* This is a real EISA system */ - id_string = e_dev->full_name; - e_dev->full_name = (char *)malloc(strlen(e_dev->full_name) - + sizeof(" (System Board)") - + 1, M_DEVBUF, M_NOWAIT); - if (!e_dev->full_name) { - panic("Eisa probe unable to malloc"); + int i,slot; + char *id_string; + struct eisa_device_node *dev_node; + struct eisa_driver **e_drvp; + struct eisa_driver *e_drv; + struct eisa_device *e_dev; + int eisaBase = 0xc80; + eisa_id_t eisa_id; + + e_drvp = (struct eisa_driver**)eisadriver_set.ls_items; + + for (slot = 0; slot < EISA_SLOTS; eisaBase+=0x1000, slot++) { + int id_size = sizeof(eisa_id); + eisa_id = 0; + for( i = 0; i < id_size; i++ ) { + outb(eisaBase,0xc80 + i); /*Some cards require priming*/ + eisa_id |= inb(eisaBase+i) << ((id_size-i-1)*CHAR_BIT); + } + if (eisa_id & 0x80000000) + continue; /* no EISA card in slot */ + + /* Prepare an eisa_device_node for this slot */ + dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), + M_DEVBUF, M_NOWAIT); + if (!dev_node) { + printf("eisa0: cannot malloc eisa_device_node"); + break; /* Try to attach what we have already */ + } + bzero(dev_node, sizeof(*dev_node)); + e_dev = &(dev_node->dev); + e_dev->id = eisa_id; + /* + * Add an EISA ID based descriptive name incase we don't + * have a driver for it. We do this now instead of after all + * probes because in the future, the eisa module will only + * be responsible for creating the list of devices in the system + * for the configuration manager to use. + */ + e_dev->full_name = (char *)malloc(14*sizeof(char), + M_DEVBUF, M_NOWAIT); + if (!e_dev->full_name) { + panic("Eisa probe unable to malloc"); + } + sprintf(e_dev->full_name, "%c%c%c%x rev %x", + EISA_MFCTR_CHAR0(e_dev->id), + EISA_MFCTR_CHAR1(e_dev->id), + EISA_MFCTR_CHAR2(e_dev->id), + EISA_PRODUCT_ID(e_dev->id), + EISA_REVISION_ID(e_dev->id)); + e_dev->ioconf.slot = slot; + /* Is iobase defined in any EISA specs? */ + e_dev->ioconf.iobase = eisaBase & 0xff00; + *eisa_dev_list_tail = dev_node; + eisa_dev_list_tail = &dev_node->next; } - sprintf(e_dev->full_name, "%s (System Board)", id_string); - free(id_string, M_DEVBUF); - printf("%s%ld: <%s>\n", - e_dev->driver->name, - e_dev->unit, - e_dev->full_name); + dev_node = eisa_dev_list; - /* Should set the iosize, but I don't have a spec handy */ + /* + * "Attach" the system board + */ - dev_attach(&kdc_eisa0); /* - * Hmm. Do I need to do this attach always - * in case I attach a 284x in an otherwise - * non-EISA machine? - */ - printf("Probing for devices on the EISA bus\n"); - } + /* The first will be the motherboard in a true EISA system */ + if (dev_node && (dev_node->dev.ioconf.slot == 0)) { + e_dev = &dev_node->dev; + e_dev->driver = &mainboard_drv; + e_dev->unit = (*e_dev->driver->unit)++; + id_string = e_dev->full_name; + e_dev->full_name = (char *)malloc(strlen(e_dev->full_name) + + sizeof(" (System Board)") + + 1, M_DEVBUF, M_NOWAIT); + if (!e_dev->full_name) { + panic("Eisa probe unable to malloc"); + } + sprintf(e_dev->full_name, "%s (System Board)", id_string); + free(id_string, M_DEVBUF); + + printf("%s%ld: <%s>\n", + e_dev->driver->name, + e_dev->unit, + e_dev->full_name); + + /* Should set the iosize, but I don't have a spec handy */ + kdc_eisa0.kdc_parentdata = e_dev; + dev_attach(&kdc_eisa0); + printf("Probing for devices on the EISA bus\n"); + dev_node = dev_node->next; + } - if (!eisa_dev_list->next) { + if (!eisa_dev_list) { + /* + * No devices. + */ + return; + } /* - * No devices. - * We may be able to remove the sentinal node in the non-EISA - * system case here depending on whether we had to do the - * dev_attach(&kdc_eisa0) up above. + * See what devices we recognize. */ - return; - } - /* - * See what devices we recognize. - */ - while((e_drv = *e_drvp++)) { - (*e_drv->probe)(); - } - - /* - * Attach the devices we found in slot order - */ - for (dev_node = eisa_dev_list->next; dev_node; dev_node = dev_node->next) { - e_dev = &dev_node->dev; - e_drv = e_dev->driver; - if (e_drv) { - /* - * Determine the proper unit number for this device. - * Here we should look in the device table generated - * by config to see if this type of device is enabled - * either generically or for this particular address - * as well as determine if a reserved unit number should - * be used. We should also ensure that the "next availible - * unit number" skips over "wired" unit numbers. This will - * be done after config is fixed or some other configuration - * method is chosen. - */ - e_dev->unit = (*e_drv->unit)++; - if ((*e_drv->attach)(e_dev) < 0) { - /* Clean up after the device?? */ - } - e_dev->kdc->kdc_unit = e_dev->unit; + while((e_drv = *e_drvp++)) { + (*e_drv->probe)(); } - else { - /* Announce unattached device */ - printf("%s%ld:%d <%s> unknown device\n", - eisa_dev_list->dev.driver->name, /* Mainboard */ - eisa_dev_list->dev.unit, - e_dev->ioconf.slot, - e_dev->full_name); + + /* + * Attach the devices we found in slot order + */ + for (; dev_node; dev_node=dev_node->next) { + e_dev = &dev_node->dev; + e_drv = e_dev->driver; + if (e_drv) { + /* + * Determine the proper unit number for this device. + * Here we should look in the device table generated + * by config to see if this type of device is enabled + * either generically or for this particular address + * as well as determine if a reserved unit number + * should be used. We should also ensure that the + * "next availible unit number" skips over "wired" unit + * numbers. This will be done after config is fixed or + * some other configuration method is chosen. + */ + e_dev->unit = (*e_drv->unit)++; + if ((*e_drv->attach)(e_dev) < 0) { + printf("%s0:%d <%s> attach failed\n", + mainboard_drv.name, + e_dev->ioconf.slot, + e_dev->full_name); + continue; + } + e_dev->kdc->kdc_unit = e_dev->unit; + } + else { + /* Announce unattached device */ + printf("%s0:%d <%s> unknown device\n", + mainboard_drv.name, + e_dev->ioconf.slot, + e_dev->full_name); + } } - } } struct eisa_device * @@ -248,32 +218,27 @@ eisa_match_dev(e_dev, match_func) struct eisa_device *e_dev; char* (*match_func)(eisa_id_t); { - struct eisa_device_node *e_node = eisa_dev_list; - - if(e_dev) { - /* Start our search from the last successful match */ - e_node = (struct eisa_device_node *)e_dev; - } - - /* - * The first node in the list is the motherboard, so don't bother - * to look at it. - */ - while (e_node->next != NULL) { - char *result; - e_node = e_node->next; - if (e_node->dev.driver) { - /* Already claimed */ - continue; + struct eisa_device_node *e_node = eisa_dev_list; + + if (e_dev) { + /* Start our search from the last successful match */ + e_node = ((struct eisa_device_node *)e_dev)->next; } - result = (*match_func)(e_node->dev.id); - if (result) { - free(e_node->dev.full_name, M_DEVBUF); - e_node->dev.full_name = result; - return (&(e_node->dev)); + + for(; e_node; e_node = e_node->next) { + char *result; + if (e_node->dev.driver) { + /* Already claimed */ + continue; + } + result = (*match_func)(e_node->dev.id); + if (result) { + free(e_node->dev.full_name, M_DEVBUF); + e_node->dev.full_name = result; + return (&(e_node->dev)); + } } - } - return NULL; + return NULL; } /* Interrupt and I/O space registration facitlities */ @@ -281,13 +246,13 @@ void eisa_reg_start(e_dev) struct eisa_device *e_dev; { - /* - * Announce the device. - */ - printf("%s%ld: <%s>", - e_dev->driver->name, - e_dev->unit, - e_dev->full_name); + /* + * Announce the device. + */ + printf("%s%ld: <%s>", + e_dev->driver->name, + e_dev->unit, + e_dev->full_name); } /* Interrupt and I/O space registration facitlities */ @@ -295,10 +260,19 @@ void eisa_reg_end(e_dev) struct eisa_device *e_dev; { - printf(" on %s%ld slot %d\n", - eisa_dev_list->dev.driver->name, /* Mainboard */ - eisa_dev_list->dev.unit, - e_dev->ioconf.slot); + /* + * The device should have called eisa_registerdev() + * during its probe. So hopefully we can use the kdc + * to weed out ISA/VL devices that use EISA id registers. + */ + if (e_dev->kdc && (e_dev->kdc->kdc_parent == &kdc_isa0)) { + printf(" on isa\n"); + } + else { + printf(" on %s0 slot %d\n", + mainboard_drv.name, + e_dev->ioconf.slot); + } } int @@ -306,8 +280,8 @@ eisa_add_intr(e_dev, irq) struct eisa_device *e_dev; int irq; { - e_dev->ioconf.irq |= 1ul << irq; - return 0; + e_dev->ioconf.irq |= 1ul << irq; + return 0; } int @@ -319,42 +293,42 @@ eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared) u_int *maskptr; int shared; { - int result; - int s; + int result; + int s; #if NOT_YET - /* - * Punt on conflict detection for the moment. - * I want to develop a generic routine to do - * this for all device types. - */ - int checkthese = CC_IRQ; - if(haveseen_dev(dev, checkthese)) - return 1; + /* + * Punt on conflict detection for the moment. + * I want to develop a generic routine to do + * this for all device types. + */ + int checkthese = CC_IRQ; + if (haveseen_dev(dev, checkthese)) + return 1; #endif - s = splhigh(); - /* - * This should really go to a routine that can optionally - * handle shared interrupts. - */ - result = register_intr(irq, /* isa irq */ - 0, /* deviced?? */ - 0, /* flags? */ - (inthand2_t*) func, /* handler */ - maskptr, /* mask pointer */ - (int)arg); /* handler arg */ - - if (result) { - printf ("eisa_reg_int: result=%d\n", result); + s = splhigh(); + /* + * This should really go to a routine that can optionally + * handle shared interrupts. + */ + result = register_intr(irq, /* isa irq */ + 0, /* deviced?? */ + 0, /* flags? */ + (inthand2_t*) func, /* handler */ + maskptr, /* mask pointer */ + (int)arg); /* handler arg */ + + if (result) { + printf ("eisa_reg_int: result=%d\n", result); + splx(s); + return (result); + }; + update_intr_masks(); splx(s); - return (result); - }; - update_intr_masks(); - splx(s); - - e_dev->ioconf.irq |= 1ul << irq; - printf(" irq %d", irq); - return (0); + + e_dev->ioconf.irq |= 1ul << irq; + printf(" irq %d", irq); + return (0); } int @@ -363,27 +337,28 @@ eisa_release_intr(e_dev, irq, func) int irq; void (*func)(void *); { - int result; - int s; - - if (!(e_dev->ioconf.irq & (1ul << irq))) { - printf("%s%ld: Attempted to release an interrupt (%d) it doesn't own\n", - e_dev->driver->name, e_dev->unit, irq); - return (-1); - } - - s = splhigh(); - INTRDIS ((1ul<<irq)); - - result = unregister_intr (irq, (inthand2_t*)func); + int result; + int s; + + if (!(e_dev->ioconf.irq & (1ul << irq))) { + printf("%s%ld: Attempted to release an interrupt (%d) " + "it doesn't own\n", e_dev->driver->name, + e_dev->unit, irq); + return (-1); + } + + s = splhigh(); + INTRDIS ((1ul<<irq)); + + result = unregister_intr (irq, (inthand2_t*)func); - if (result) - printf ("eisa_release_intr: result=%d\n", result); + if (result) + printf ("eisa_release_intr: result=%d\n", result); - update_intr_masks(); + update_intr_masks(); - splx(s); - return (result); + splx(s); + return (result); } int @@ -391,17 +366,18 @@ eisa_enable_intr(e_dev, irq) struct eisa_device *e_dev; int irq; { - int s; - - if (!(e_dev->ioconf.irq & (1ul << irq))) { - printf("%s%ld: Attempted to enable an interrupt (%d) it doesn't own\n", - e_dev->driver->name, e_dev->unit, irq); - return (-1); - } - s = splhigh(); - INTREN((1ul << irq)); - splx(s); - return 0; + int s; + + if (!(e_dev->ioconf.irq & (1ul << irq))) { + printf("%s%ld: Attempted to enable an interrupt (%d) " + "it doesn't own\n", e_dev->driver->name, + e_dev->unit, irq); + return (-1); + } + s = splhigh(); + INTREN((1ul << irq)); + splx(s); + return 0; } int @@ -410,13 +386,13 @@ eisa_add_iospace(e_dev, iobase, iosize) u_long iobase; int iosize; { - /* - * We should develop a scheme for storing the results of - * multiple calls to this function. - */ - e_dev->ioconf.iobase = iobase; - e_dev->ioconf.iosize = iosize; - return 0; + /* + * We should develop a scheme for storing the results of + * multiple calls to this function. + */ + e_dev->ioconf.iobase = iobase; + e_dev->ioconf.iosize = iosize; + return 0; } int @@ -425,25 +401,25 @@ eisa_reg_iospace(e_dev, iobase, iosize) u_long iobase; int iosize; { - /* - * We should develop a scheme for storing the results of - * multiple calls to this function. - */ + /* + * We should develop a scheme for storing the results of + * multiple calls to this function. + */ #ifdef NOT_YET - /* - * Punt on conflict detection for the moment. - * I want to develop a generic routine to do - * this for all device types. - */ - int checkthese = CC_IOADDR; - if(haveseen_dev(dev, checkthese)) - return -1; + /* + * Punt on conflict detection for the moment. + * I want to develop a generic routine to do + * this for all device types. + */ + int checkthese = CC_IOADDR; + if (haveseen_dev(dev, checkthese)) + return -1; #endif - e_dev->ioconf.iobase = iobase; - e_dev->ioconf.iosize = iosize; + e_dev->ioconf.iobase = iobase; + e_dev->ioconf.iosize = iosize; - printf(" at 0x%lx-0x%lx", iobase, iobase + iosize - 1); - return (0); + printf(" at 0x%lx-0x%lx", iobase, iobase + iosize - 1); + return (0); } int @@ -452,18 +428,19 @@ eisa_registerdev(e_dev, driver, kdc_template) struct eisa_driver *driver; struct kern_devconf *kdc_template; { - e_dev->driver = driver; /* Driver now owns this device */ - e_dev->kdc = (struct kern_devconf *)malloc(sizeof(struct kern_devconf), + e_dev->driver = driver; /* Driver now owns this device */ + e_dev->kdc = (struct kern_devconf *)malloc(sizeof(struct kern_devconf), M_DEVBUF, M_NOWAIT); - if (!e_dev->kdc) { - printf("WARNING: eisa_registerdev unable to malloc! " - "Device kdc will not be registerd\n"); - return 1; - } - bcopy(kdc_template, e_dev->kdc, sizeof(*kdc_template)); - e_dev->kdc->kdc_description = e_dev->full_name; - dev_attach(e_dev->kdc); - return (0); + if (!e_dev->kdc) { + printf("WARNING: eisa_registerdev unable to malloc! " + "Device kdc will not be registerd\n"); + return 1; + } + bcopy(kdc_template, e_dev->kdc, sizeof(*kdc_template)); + e_dev->kdc->kdc_description = e_dev->full_name; + e_dev->kdc->kdc_parentdata = e_dev; + dev_attach(e_dev->kdc); + return (0); } /* @@ -471,19 +448,25 @@ eisa_registerdev(e_dev, driver, kdc_template) * hw.devconf interface. */ int -eisa_externalize(struct eisa_device *id, void *userp, size_t *maxlen) +eisa_externalize(id, userp, maxlen) + struct eisa_device *id; + void *userp; + size_t *maxlen; { - if(*maxlen < (sizeof *id)) { - return ENOMEM; - } - *maxlen -= (sizeof *id); - return (copyout(id, userp, sizeof *id)); + if (*maxlen < (sizeof *id)) { + return ENOMEM; + } + *maxlen -= (sizeof *id); + return (copyout(id, userp, sizeof *id)); } int -eisa_generic_externalize(struct proc *p, struct kern_devconf *kdc, - void *userp, size_t l) +eisa_generic_externalize(p, kdc, userp, l) + struct proc *p; + struct kern_devconf *kdc; + void *userp; + size_t l; { return eisa_externalize(kdc->kdc_eisa, userp, &l); } diff --git a/sys/i386/eisa/aic7770.c b/sys/i386/eisa/aic7770.c index 49640987030b..5285d39041fd 100644 --- a/sys/i386/eisa/aic7770.c +++ b/sys/i386/eisa/aic7770.c @@ -19,7 +19,7 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: aic7770.c,v 1.16 1995/09/05 23:39:31 gibbs Exp $ + * $Id: aic7770.c,v 1.17 1995/11/05 04:42:47 gibbs Exp $ */ #include "eisa.h" @@ -128,11 +128,15 @@ aic7770probe(void) printf("aic7770 at slot %d: illegal " "irq setting %d\n", e_dev->ioconf.slot, intdef); - DELAY(10000000); continue; } eisa_add_intr(e_dev, irq); eisa_registerdev(e_dev, &ahc_eisa_driver, &kdc_aic7770); + if(e_dev->id == EISA_DEVICE_ID_ADAPTEC_284xB + || e_dev->id == EISA_DEVICE_ID_ADAPTEC_284x) { + /* Our real parent is the isa bus. Say so */ + e_dev->kdc->kdc_parent = &kdc_isa0; + } count++; } return count; diff --git a/sys/i386/eisa/eisaconf.c b/sys/i386/eisa/eisaconf.c index cddaa1b762d5..f10869388df9 100644 --- a/sys/i386/eisa/eisaconf.c +++ b/sys/i386/eisa/eisaconf.c @@ -18,22 +18,21 @@ * 4. Modifications may be freely made to this file if the above conditions * are met. * - * $Id: eisaconf.c,v 1.3 1995/11/05 04:42:49 gibbs Exp $ + * $Id: eisaconf.c,v 1.4 1995/11/06 05:20:59 gibbs Exp $ */ #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/conf.h> #include <sys/malloc.h> +#include <sys/devconf.h> -#include "sys/types.h" #include "i386/isa/icu.h" /* Hmmm. Interrupt stuff? */ -#include <sys/devconf.h> #include "eisaconf.h" struct eisa_device_node{ - struct eisa_device dev; - struct eisa_device_node *next; + struct eisa_device dev; + struct eisa_device_node *next; }; extern struct kern_devconf kdc_cpu0; @@ -74,173 +73,144 @@ static struct eisa_driver mainboard_drv = { void eisa_configure() { - int i,slot; - char *id_string; - struct eisa_device_node *dev_node; - struct eisa_driver **e_drvp = (struct eisa_driver**)eisadriver_set.ls_items; - struct eisa_driver *e_drv; - struct eisa_device *e_dev; - int eisaBase = 0xC80; - int first_slot = 0; - eisa_id_t eisa_id; - - outb(eisaBase,0xFF); - eisa_id = inb(eisaBase); - if (eisa_id & 0x80) { - /* - * Not an EISA machine. We still want to find boards like the - * Adaptec 284x that respond to EISA probes, so we "fake" the - * system board entry which the rest of the code uses as the - * sentinal node in the eisa_dev_list. - */ - first_slot = 1; /* Start at slot 1 just to be safe */ - eisaBase+=0x1000; - dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), - M_DEVBUF, M_NOWAIT); - if (!dev_node) { - printf("eisa0: cannot malloc eisa_device_node"); - return; - } - bzero(dev_node, sizeof(*dev_node)); - e_dev = &(dev_node->dev); - e_dev->ioconf.slot = 0; - *eisa_dev_list_tail = dev_node; - eisa_dev_list_tail = &dev_node->next; - } - - for (slot = first_slot; slot < EISA_SLOTS; eisaBase+=0x1000, slot++) { - int id_size = sizeof(eisa_id); - eisa_id = 0; - for( i = 0; i < id_size; i++ ) { - outb(eisaBase,0xc80 + i); /* Some cards require priming */ - eisa_id |= inb(eisaBase + i) << ((id_size - i - 1) * CHAR_BIT); - } - if (eisa_id & 0x80000000) - continue; /* no EISA card in slot */ - - /* Prepare an eisa_device_node for this slot */ - dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), - M_DEVBUF, M_NOWAIT); - if (!dev_node) { - printf("eisa0: cannot malloc eisa_device_node"); - break; /* Try to attach what we have already */ - } - bzero(dev_node, sizeof(*dev_node)); - e_dev = &(dev_node->dev); - e_dev->id = eisa_id; - /* - * Add an EISA ID based descriptive name incase we don't - * have a driver for it. We do this now instead of after all - * probes because in the future, the eisa module will only - * be responsible for creating the list of devices in the system - * for the configuration manager to use. - */ - e_dev->full_name = (char *)malloc(14*sizeof(char), M_DEVBUF, M_NOWAIT); - if (!e_dev->full_name) { - panic("Eisa probe unable to malloc"); - } - sprintf(e_dev->full_name, "%c%c%c%x rev %x", - EISA_MFCTR_CHAR0(e_dev->id), - EISA_MFCTR_CHAR1(e_dev->id), - EISA_MFCTR_CHAR2(e_dev->id), - EISA_PRODUCT_ID(e_dev->id), - EISA_REVISION_ID(e_dev->id)); - e_dev->ioconf.slot = slot; - /* Is iobase defined in any EISA specs? */ - e_dev->ioconf.iobase = eisaBase & 0xff00; - *eisa_dev_list_tail = dev_node; - eisa_dev_list_tail = &dev_node->next; - } - - dev_node = eisa_dev_list; - - /* - * "Attach" the system board - */ - - /* The first entry had better be the motherboard */ - if (!dev_node || (dev_node->dev.ioconf.slot != 0)) - panic("EISA system board not in eisa_dev_list"); - - e_dev = &dev_node->dev; - e_dev->driver = &mainboard_drv; - e_dev->unit = (*e_dev->driver->unit)++; - - if (e_dev->full_name) { /* This is a real EISA system */ - id_string = e_dev->full_name; - e_dev->full_name = (char *)malloc(strlen(e_dev->full_name) - + sizeof(" (System Board)") - + 1, M_DEVBUF, M_NOWAIT); - if (!e_dev->full_name) { - panic("Eisa probe unable to malloc"); + int i,slot; + char *id_string; + struct eisa_device_node *dev_node; + struct eisa_driver **e_drvp; + struct eisa_driver *e_drv; + struct eisa_device *e_dev; + int eisaBase = 0xc80; + eisa_id_t eisa_id; + + e_drvp = (struct eisa_driver**)eisadriver_set.ls_items; + + for (slot = 0; slot < EISA_SLOTS; eisaBase+=0x1000, slot++) { + int id_size = sizeof(eisa_id); + eisa_id = 0; + for( i = 0; i < id_size; i++ ) { + outb(eisaBase,0xc80 + i); /*Some cards require priming*/ + eisa_id |= inb(eisaBase+i) << ((id_size-i-1)*CHAR_BIT); + } + if (eisa_id & 0x80000000) + continue; /* no EISA card in slot */ + + /* Prepare an eisa_device_node for this slot */ + dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), + M_DEVBUF, M_NOWAIT); + if (!dev_node) { + printf("eisa0: cannot malloc eisa_device_node"); + break; /* Try to attach what we have already */ + } + bzero(dev_node, sizeof(*dev_node)); + e_dev = &(dev_node->dev); + e_dev->id = eisa_id; + /* + * Add an EISA ID based descriptive name incase we don't + * have a driver for it. We do this now instead of after all + * probes because in the future, the eisa module will only + * be responsible for creating the list of devices in the system + * for the configuration manager to use. + */ + e_dev->full_name = (char *)malloc(14*sizeof(char), + M_DEVBUF, M_NOWAIT); + if (!e_dev->full_name) { + panic("Eisa probe unable to malloc"); + } + sprintf(e_dev->full_name, "%c%c%c%x rev %x", + EISA_MFCTR_CHAR0(e_dev->id), + EISA_MFCTR_CHAR1(e_dev->id), + EISA_MFCTR_CHAR2(e_dev->id), + EISA_PRODUCT_ID(e_dev->id), + EISA_REVISION_ID(e_dev->id)); + e_dev->ioconf.slot = slot; + /* Is iobase defined in any EISA specs? */ + e_dev->ioconf.iobase = eisaBase & 0xff00; + *eisa_dev_list_tail = dev_node; + eisa_dev_list_tail = &dev_node->next; } - sprintf(e_dev->full_name, "%s (System Board)", id_string); - free(id_string, M_DEVBUF); - printf("%s%ld: <%s>\n", - e_dev->driver->name, - e_dev->unit, - e_dev->full_name); + dev_node = eisa_dev_list; - /* Should set the iosize, but I don't have a spec handy */ + /* + * "Attach" the system board + */ - dev_attach(&kdc_eisa0); /* - * Hmm. Do I need to do this attach always - * in case I attach a 284x in an otherwise - * non-EISA machine? - */ - printf("Probing for devices on the EISA bus\n"); - } + /* The first will be the motherboard in a true EISA system */ + if (dev_node && (dev_node->dev.ioconf.slot == 0)) { + e_dev = &dev_node->dev; + e_dev->driver = &mainboard_drv; + e_dev->unit = (*e_dev->driver->unit)++; + id_string = e_dev->full_name; + e_dev->full_name = (char *)malloc(strlen(e_dev->full_name) + + sizeof(" (System Board)") + + 1, M_DEVBUF, M_NOWAIT); + if (!e_dev->full_name) { + panic("Eisa probe unable to malloc"); + } + sprintf(e_dev->full_name, "%s (System Board)", id_string); + free(id_string, M_DEVBUF); + + printf("%s%ld: <%s>\n", + e_dev->driver->name, + e_dev->unit, + e_dev->full_name); + + /* Should set the iosize, but I don't have a spec handy */ + kdc_eisa0.kdc_parentdata = e_dev; + dev_attach(&kdc_eisa0); + printf("Probing for devices on the EISA bus\n"); + dev_node = dev_node->next; + } - if (!eisa_dev_list->next) { + if (!eisa_dev_list) { + /* + * No devices. + */ + return; + } /* - * No devices. - * We may be able to remove the sentinal node in the non-EISA - * system case here depending on whether we had to do the - * dev_attach(&kdc_eisa0) up above. + * See what devices we recognize. */ - return; - } - /* - * See what devices we recognize. - */ - while((e_drv = *e_drvp++)) { - (*e_drv->probe)(); - } - - /* - * Attach the devices we found in slot order - */ - for (dev_node = eisa_dev_list->next; dev_node; dev_node = dev_node->next) { - e_dev = &dev_node->dev; - e_drv = e_dev->driver; - if (e_drv) { - /* - * Determine the proper unit number for this device. - * Here we should look in the device table generated - * by config to see if this type of device is enabled - * either generically or for this particular address - * as well as determine if a reserved unit number should - * be used. We should also ensure that the "next availible - * unit number" skips over "wired" unit numbers. This will - * be done after config is fixed or some other configuration - * method is chosen. - */ - e_dev->unit = (*e_drv->unit)++; - if ((*e_drv->attach)(e_dev) < 0) { - /* Clean up after the device?? */ - } - e_dev->kdc->kdc_unit = e_dev->unit; + while((e_drv = *e_drvp++)) { + (*e_drv->probe)(); } - else { - /* Announce unattached device */ - printf("%s%ld:%d <%s> unknown device\n", - eisa_dev_list->dev.driver->name, /* Mainboard */ - eisa_dev_list->dev.unit, - e_dev->ioconf.slot, - e_dev->full_name); + + /* + * Attach the devices we found in slot order + */ + for (; dev_node; dev_node=dev_node->next) { + e_dev = &dev_node->dev; + e_drv = e_dev->driver; + if (e_drv) { + /* + * Determine the proper unit number for this device. + * Here we should look in the device table generated + * by config to see if this type of device is enabled + * either generically or for this particular address + * as well as determine if a reserved unit number + * should be used. We should also ensure that the + * "next availible unit number" skips over "wired" unit + * numbers. This will be done after config is fixed or + * some other configuration method is chosen. + */ + e_dev->unit = (*e_drv->unit)++; + if ((*e_drv->attach)(e_dev) < 0) { + printf("%s0:%d <%s> attach failed\n", + mainboard_drv.name, + e_dev->ioconf.slot, + e_dev->full_name); + continue; + } + e_dev->kdc->kdc_unit = e_dev->unit; + } + else { + /* Announce unattached device */ + printf("%s0:%d <%s> unknown device\n", + mainboard_drv.name, + e_dev->ioconf.slot, + e_dev->full_name); + } } - } } struct eisa_device * @@ -248,32 +218,27 @@ eisa_match_dev(e_dev, match_func) struct eisa_device *e_dev; char* (*match_func)(eisa_id_t); { - struct eisa_device_node *e_node = eisa_dev_list; - - if(e_dev) { - /* Start our search from the last successful match */ - e_node = (struct eisa_device_node *)e_dev; - } - - /* - * The first node in the list is the motherboard, so don't bother - * to look at it. - */ - while (e_node->next != NULL) { - char *result; - e_node = e_node->next; - if (e_node->dev.driver) { - /* Already claimed */ - continue; + struct eisa_device_node *e_node = eisa_dev_list; + + if (e_dev) { + /* Start our search from the last successful match */ + e_node = ((struct eisa_device_node *)e_dev)->next; } - result = (*match_func)(e_node->dev.id); - if (result) { - free(e_node->dev.full_name, M_DEVBUF); - e_node->dev.full_name = result; - return (&(e_node->dev)); + + for(; e_node; e_node = e_node->next) { + char *result; + if (e_node->dev.driver) { + /* Already claimed */ + continue; + } + result = (*match_func)(e_node->dev.id); + if (result) { + free(e_node->dev.full_name, M_DEVBUF); + e_node->dev.full_name = result; + return (&(e_node->dev)); + } } - } - return NULL; + return NULL; } /* Interrupt and I/O space registration facitlities */ @@ -281,13 +246,13 @@ void eisa_reg_start(e_dev) struct eisa_device *e_dev; { - /* - * Announce the device. - */ - printf("%s%ld: <%s>", - e_dev->driver->name, - e_dev->unit, - e_dev->full_name); + /* + * Announce the device. + */ + printf("%s%ld: <%s>", + e_dev->driver->name, + e_dev->unit, + e_dev->full_name); } /* Interrupt and I/O space registration facitlities */ @@ -295,10 +260,19 @@ void eisa_reg_end(e_dev) struct eisa_device *e_dev; { - printf(" on %s%ld slot %d\n", - eisa_dev_list->dev.driver->name, /* Mainboard */ - eisa_dev_list->dev.unit, - e_dev->ioconf.slot); + /* + * The device should have called eisa_registerdev() + * during its probe. So hopefully we can use the kdc + * to weed out ISA/VL devices that use EISA id registers. + */ + if (e_dev->kdc && (e_dev->kdc->kdc_parent == &kdc_isa0)) { + printf(" on isa\n"); + } + else { + printf(" on %s0 slot %d\n", + mainboard_drv.name, + e_dev->ioconf.slot); + } } int @@ -306,8 +280,8 @@ eisa_add_intr(e_dev, irq) struct eisa_device *e_dev; int irq; { - e_dev->ioconf.irq |= 1ul << irq; - return 0; + e_dev->ioconf.irq |= 1ul << irq; + return 0; } int @@ -319,42 +293,42 @@ eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared) u_int *maskptr; int shared; { - int result; - int s; + int result; + int s; #if NOT_YET - /* - * Punt on conflict detection for the moment. - * I want to develop a generic routine to do - * this for all device types. - */ - int checkthese = CC_IRQ; - if(haveseen_dev(dev, checkthese)) - return 1; + /* + * Punt on conflict detection for the moment. + * I want to develop a generic routine to do + * this for all device types. + */ + int checkthese = CC_IRQ; + if (haveseen_dev(dev, checkthese)) + return 1; #endif - s = splhigh(); - /* - * This should really go to a routine that can optionally - * handle shared interrupts. - */ - result = register_intr(irq, /* isa irq */ - 0, /* deviced?? */ - 0, /* flags? */ - (inthand2_t*) func, /* handler */ - maskptr, /* mask pointer */ - (int)arg); /* handler arg */ - - if (result) { - printf ("eisa_reg_int: result=%d\n", result); + s = splhigh(); + /* + * This should really go to a routine that can optionally + * handle shared interrupts. + */ + result = register_intr(irq, /* isa irq */ + 0, /* deviced?? */ + 0, /* flags? */ + (inthand2_t*) func, /* handler */ + maskptr, /* mask pointer */ + (int)arg); /* handler arg */ + + if (result) { + printf ("eisa_reg_int: result=%d\n", result); + splx(s); + return (result); + }; + update_intr_masks(); splx(s); - return (result); - }; - update_intr_masks(); - splx(s); - - e_dev->ioconf.irq |= 1ul << irq; - printf(" irq %d", irq); - return (0); + + e_dev->ioconf.irq |= 1ul << irq; + printf(" irq %d", irq); + return (0); } int @@ -363,27 +337,28 @@ eisa_release_intr(e_dev, irq, func) int irq; void (*func)(void *); { - int result; - int s; - - if (!(e_dev->ioconf.irq & (1ul << irq))) { - printf("%s%ld: Attempted to release an interrupt (%d) it doesn't own\n", - e_dev->driver->name, e_dev->unit, irq); - return (-1); - } - - s = splhigh(); - INTRDIS ((1ul<<irq)); - - result = unregister_intr (irq, (inthand2_t*)func); + int result; + int s; + + if (!(e_dev->ioconf.irq & (1ul << irq))) { + printf("%s%ld: Attempted to release an interrupt (%d) " + "it doesn't own\n", e_dev->driver->name, + e_dev->unit, irq); + return (-1); + } + + s = splhigh(); + INTRDIS ((1ul<<irq)); + + result = unregister_intr (irq, (inthand2_t*)func); - if (result) - printf ("eisa_release_intr: result=%d\n", result); + if (result) + printf ("eisa_release_intr: result=%d\n", result); - update_intr_masks(); + update_intr_masks(); - splx(s); - return (result); + splx(s); + return (result); } int @@ -391,17 +366,18 @@ eisa_enable_intr(e_dev, irq) struct eisa_device *e_dev; int irq; { - int s; - - if (!(e_dev->ioconf.irq & (1ul << irq))) { - printf("%s%ld: Attempted to enable an interrupt (%d) it doesn't own\n", - e_dev->driver->name, e_dev->unit, irq); - return (-1); - } - s = splhigh(); - INTREN((1ul << irq)); - splx(s); - return 0; + int s; + + if (!(e_dev->ioconf.irq & (1ul << irq))) { + printf("%s%ld: Attempted to enable an interrupt (%d) " + "it doesn't own\n", e_dev->driver->name, + e_dev->unit, irq); + return (-1); + } + s = splhigh(); + INTREN((1ul << irq)); + splx(s); + return 0; } int @@ -410,13 +386,13 @@ eisa_add_iospace(e_dev, iobase, iosize) u_long iobase; int iosize; { - /* - * We should develop a scheme for storing the results of - * multiple calls to this function. - */ - e_dev->ioconf.iobase = iobase; - e_dev->ioconf.iosize = iosize; - return 0; + /* + * We should develop a scheme for storing the results of + * multiple calls to this function. + */ + e_dev->ioconf.iobase = iobase; + e_dev->ioconf.iosize = iosize; + return 0; } int @@ -425,25 +401,25 @@ eisa_reg_iospace(e_dev, iobase, iosize) u_long iobase; int iosize; { - /* - * We should develop a scheme for storing the results of - * multiple calls to this function. - */ + /* + * We should develop a scheme for storing the results of + * multiple calls to this function. + */ #ifdef NOT_YET - /* - * Punt on conflict detection for the moment. - * I want to develop a generic routine to do - * this for all device types. - */ - int checkthese = CC_IOADDR; - if(haveseen_dev(dev, checkthese)) - return -1; + /* + * Punt on conflict detection for the moment. + * I want to develop a generic routine to do + * this for all device types. + */ + int checkthese = CC_IOADDR; + if (haveseen_dev(dev, checkthese)) + return -1; #endif - e_dev->ioconf.iobase = iobase; - e_dev->ioconf.iosize = iosize; + e_dev->ioconf.iobase = iobase; + e_dev->ioconf.iosize = iosize; - printf(" at 0x%lx-0x%lx", iobase, iobase + iosize - 1); - return (0); + printf(" at 0x%lx-0x%lx", iobase, iobase + iosize - 1); + return (0); } int @@ -452,18 +428,19 @@ eisa_registerdev(e_dev, driver, kdc_template) struct eisa_driver *driver; struct kern_devconf *kdc_template; { - e_dev->driver = driver; /* Driver now owns this device */ - e_dev->kdc = (struct kern_devconf *)malloc(sizeof(struct kern_devconf), + e_dev->driver = driver; /* Driver now owns this device */ + e_dev->kdc = (struct kern_devconf *)malloc(sizeof(struct kern_devconf), M_DEVBUF, M_NOWAIT); - if (!e_dev->kdc) { - printf("WARNING: eisa_registerdev unable to malloc! " - "Device kdc will not be registerd\n"); - return 1; - } - bcopy(kdc_template, e_dev->kdc, sizeof(*kdc_template)); - e_dev->kdc->kdc_description = e_dev->full_name; - dev_attach(e_dev->kdc); - return (0); + if (!e_dev->kdc) { + printf("WARNING: eisa_registerdev unable to malloc! " + "Device kdc will not be registerd\n"); + return 1; + } + bcopy(kdc_template, e_dev->kdc, sizeof(*kdc_template)); + e_dev->kdc->kdc_description = e_dev->full_name; + e_dev->kdc->kdc_parentdata = e_dev; + dev_attach(e_dev->kdc); + return (0); } /* @@ -471,19 +448,25 @@ eisa_registerdev(e_dev, driver, kdc_template) * hw.devconf interface. */ int -eisa_externalize(struct eisa_device *id, void *userp, size_t *maxlen) +eisa_externalize(id, userp, maxlen) + struct eisa_device *id; + void *userp; + size_t *maxlen; { - if(*maxlen < (sizeof *id)) { - return ENOMEM; - } - *maxlen -= (sizeof *id); - return (copyout(id, userp, sizeof *id)); + if (*maxlen < (sizeof *id)) { + return ENOMEM; + } + *maxlen -= (sizeof *id); + return (copyout(id, userp, sizeof *id)); } int -eisa_generic_externalize(struct proc *p, struct kern_devconf *kdc, - void *userp, size_t l) +eisa_generic_externalize(p, kdc, userp, l) + struct proc *p; + struct kern_devconf *kdc; + void *userp; + size_t l; { return eisa_externalize(kdc->kdc_eisa, userp, &l); } |