summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgibbs <gibbs@FreeBSD.org>1996-01-29 03:13:23 +0000
committergibbs <gibbs@FreeBSD.org>1996-01-29 03:13:23 +0000
commit0b627d75b7d924f59d3cc0c0ca10e754ba53854f (patch)
tree1b6101f6ee35060aacfbf2e0aae2d6e0d2e72010
parente94d9bd8af1b0fd9544212c02ae1125ec377a6c3 (diff)
downloadFreeBSD-src-0b627d75b7d924f59d3cc0c0ca10e754ba53854f.zip
FreeBSD-src-0b627d75b7d924f59d3cc0c0ca10e754ba53854f.tar.gz
Another pass through eisaconf. Ioaddrs and Maddrs are link lists now.
The Bt driver is the only one that actually registers multiple addresses. Probe output is formatted to 80 columns.
-rw-r--r--sys/dev/eisa/eisaconf.c342
-rw-r--r--sys/dev/eisa/eisaconf.h37
-rw-r--r--sys/i386/eisa/aha1742.c29
-rw-r--r--sys/i386/eisa/aic7770.c31
-rw-r--r--sys/i386/eisa/bt74x.c280
-rw-r--r--sys/i386/eisa/eisaconf.c342
-rw-r--r--sys/i386/eisa/eisaconf.h37
7 files changed, 846 insertions, 252 deletions
diff --git a/sys/dev/eisa/eisaconf.c b/sys/dev/eisa/eisaconf.c
index 288c66b..2c583aa 100644
--- a/sys/dev/eisa/eisaconf.c
+++ b/sys/dev/eisa/eisaconf.c
@@ -1,7 +1,7 @@
/*
* EISA bus probe and attach routines
*
- * Copyright (c) 1995 Justin T. Gibbs.
+ * Copyright (c) 1995, 1996 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -18,15 +18,15 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: eisaconf.c,v 1.11 1995/12/10 13:33:49 phk Exp $
+ * $Id: eisaconf.c,v 1.12 1996/01/03 06:28:01 gibbs Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/devconf.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
-#include <sys/conf.h>
+#include <sys/conf.h> /* For kdc_isa */
#include <sys/malloc.h>
-#include <sys/devconf.h>
#include <i386/eisa/eisaconf.h>
@@ -77,6 +77,30 @@ static struct eisa_driver mainboard_drv = {
DATA_SET (eisadriver_set, mainboard_drv);
/*
+ * Local function declarations and static variables
+ */
+void eisa_reg_print __P((struct eisa_device *e_dev, char *string,
+ char *separator));
+static int eisa_add_resvaddr __P((struct resvlist *head, u_long base,
+ u_long size, int flags));
+static int eisa_reg_resvaddr __P((struct eisa_device *e_dev,
+ struct resvlist *head, resvaddr_t *resvaddr,
+ int *reg_count));
+
+/*
+ * Keep some state about what we've printed so far
+ * to make probe output pretty.
+ */
+static struct {
+ int in_registration;/* reg_start has been called */
+ int num_interrupts;
+ int num_ioaddrs;
+ int num_maddrs;
+ int column; /* How much we have output so far. */
+#define MAX_COL 80
+} reg_state;
+
+/*
** probe for EISA devices
*/
void
@@ -112,6 +136,7 @@ eisa_configure()
}
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
@@ -131,9 +156,13 @@ eisa_configure()
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;
+
+ /* Initialize our lists of reserved addresses */
+ LIST_INIT(&(e_dev->ioconf.ioaddrs));
+ LIST_INIT(&(e_dev->ioconf.maddrs));
+
*eisa_dev_list_tail = dev_node;
eisa_dev_list_tail = &dev_node->next;
}
@@ -199,6 +228,7 @@ eisa_configure()
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.
@@ -213,20 +243,25 @@ eisa_configure()
*/
e_dev->unit = (*e_drv->unit)++;
if ((*e_drv->attach)(e_dev) < 0) {
- printf("%s0:%d <%s> attach failed\n",
+ /* Ensure registration has ended */
+ reg_state.in_registration = 0;
+ printf("\n%s0:%d <%s> attach failed\n",
mainboard_drv.name,
e_dev->ioconf.slot,
e_dev->full_name);
continue;
}
+ /* Ensure registration has ended */
+ reg_state.in_registration = 0;
e_dev->kdc->kdc_unit = e_dev->unit;
}
else {
/* Announce unattached device */
- printf("%s0:%d <%s> unknown device\n",
+ printf("%s0:%d <%s=0x%x> unknown device\n",
mainboard_drv.name,
e_dev->ioconf.slot,
- e_dev->full_name);
+ e_dev->full_name,
+ e_dev->id);
}
}
}
@@ -267,10 +302,57 @@ eisa_reg_start(e_dev)
/*
* Announce the device.
*/
- printf("%s%ld: <%s>",
- e_dev->driver->name,
- e_dev->unit,
- e_dev->full_name);
+ char *string;
+
+ reg_state.in_registration = 1;
+ reg_state.num_interrupts = 0;
+ reg_state.num_ioaddrs = 0;
+ reg_state.num_maddrs = 0;
+ reg_state.column = 0;
+
+ string = malloc(strlen(e_dev->full_name) + sizeof(" <>") + /*NULL*/1,
+ M_TEMP, M_NOWAIT);
+ if(!string) {
+ printf("eisa0: cannot malloc device description string\n");
+ return;
+ }
+ sprintf(string, " <%s>", e_dev->full_name);
+ eisa_reg_print(e_dev, string, /*separator=*/NULL);
+ free(string, M_TEMP);
+}
+
+/*
+ * Output registration information mindfull of screen wrap.
+ * Output an optional character separator before the string
+ * if the line does not wrap.
+ */
+void
+eisa_reg_print(e_dev, string, separator)
+ struct eisa_device *e_dev;
+ char *string;
+ char *separator;
+{
+ int len = strlen(string);
+
+ if( separator )
+ len++;
+
+ if(reg_state.column + len > MAX_COL) {
+ printf("\n");
+ reg_state.column = 0;
+ }
+ else if( separator ) {
+ printf("%c", *separator);
+ reg_state.column++;
+ }
+
+ if(reg_state.column == 0)
+ reg_state.column += printf("%s%ld:%s",
+ e_dev->driver->name,
+ e_dev->unit,
+ string);
+ else
+ reg_state.column += printf("%s", string);
}
/* Interrupt and I/O space registration facitlities */
@@ -278,19 +360,30 @@ void
eisa_reg_end(e_dev)
struct eisa_device *e_dev;
{
- /*
- * 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);
+ if( reg_state.in_registration )
+ {
+ /*
+ * 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.
+ */
+ char string[25];
+
+ if (e_dev->kdc && (e_dev->kdc->kdc_parent == &kdc_isa0)) {
+ sprintf(string, " on isa");
+ }
+ else {
+ sprintf(string, " on %s0 slot %d",
+ mainboard_drv.name,
+ e_dev->ioconf.slot);
+ }
+ eisa_reg_print(e_dev, string, NULL);
+ printf("\n");
+ reg_state.in_registration = 0;
}
+ else
+ printf("eisa_reg_end called outside of a "
+ "registration session\n");
}
int
@@ -313,6 +406,8 @@ eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared)
{
int result;
int s;
+ char string[25];
+ char separator = ',';
#if NOT_YET
/*
@@ -324,28 +419,35 @@ eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared)
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);
+ if (reg_state.in_registration) {
+ 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 ("\neisa_reg_int: result=%d\n", result);
+ splx(s);
+ return (result);
+ };
+ update_intr_masks();
splx(s);
- return (result);
- };
- update_intr_masks();
- splx(s);
+ }
+ else
+ return EPERM;
e_dev->ioconf.irq |= 1ul << irq;
- printf(" irq %d", irq);
+ sprintf(string, " irq %d", irq);
+ eisa_reg_print(e_dev, string, reg_state.num_interrupts ?
+ &separator : NULL);
+ reg_state.num_interrupts++;
return (0);
}
@@ -398,31 +500,146 @@ eisa_enable_intr(e_dev, irq)
return 0;
}
+static int
+eisa_add_resvaddr(head, base, size, flags)
+ struct resvlist *head;
+ u_long base;
+ u_long size;
+ int flags;
+{
+ resvaddr_t *reservation;
+
+ reservation = (resvaddr_t *)malloc(sizeof(resvaddr_t),
+ M_DEVBUF, M_NOWAIT);
+ if(!reservation)
+ return (ENOMEM);
+
+ reservation->addr = base;
+ reservation->size = size;
+ reservation->flags = flags;
+
+ if (!head->lh_first) {
+ LIST_INSERT_HEAD(head, reservation, links);
+ }
+ else {
+ resvaddr_t *node;
+ for(node = head->lh_first; node; node = node->links.le_next) {
+ if (node->addr > reservation->addr) {
+ /*
+ * List is sorted in increasing
+ * address order.
+ */
+ LIST_INSERT_BEFORE(node, reservation, links);
+ break;
+ }
+
+ if (node->addr == reservation->addr) {
+ /*
+ * If the entry we want to add
+ * matches any already in here,
+ * fail.
+ */
+ free(reservation, M_DEVBUF);
+ return (EEXIST);
+ }
+
+ if (!node->links.le_next) {
+ LIST_INSERT_AFTER(node, reservation, links);
+ break;
+ }
+ }
+ }
+ return (0);
+}
+
int
-eisa_add_iospace(e_dev, iobase, iosize)
+eisa_add_mspace(e_dev, mbase, msize, flags)
struct eisa_device *e_dev;
- u_long iobase;
- int iosize;
+ u_long mbase;
+ u_long msize;
+ int flags;
{
- /*
- * 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;
+ return eisa_add_resvaddr(&(e_dev->ioconf.maddrs), mbase, msize, flags);
}
int
-eisa_reg_iospace(e_dev, iobase, iosize)
+eisa_add_iospace(e_dev, iobase, iosize, flags)
struct eisa_device *e_dev;
u_long iobase;
- int iosize;
+ u_long iosize;
+ int flags;
{
- /*
- * We should develop a scheme for storing the results of
- * multiple calls to this function.
+ return eisa_add_resvaddr(&(e_dev->ioconf.ioaddrs), iobase, iosize,
+ flags);
+}
+
+static int
+eisa_reg_resvaddr(e_dev, head, resvaddr, reg_count)
+ struct eisa_device *e_dev;
+ struct resvlist *head;
+ resvaddr_t *resvaddr;
+ int *reg_count;
+{
+ if (reg_state.in_registration) {
+ resvaddr_t *node;
+ /*
+ * Ensure that this resvaddr is actually in the devices'
+ * reservation list.
+ */
+ for(node = head->lh_first; node;
+ node = node->links.le_next) {
+ if (node == resvaddr) {
+ char buf[35];
+ char separator = ',';
+ char *string = buf;
+
+ if (*reg_count == 0) {
+ /* First time */
+ string += sprintf(string, " at");
+ }
+
+ if (node->size == 1
+ || (node->flags & RESVADDR_BITMASK))
+ sprintf(string, " 0x%lx", node->addr);
+ else
+ sprintf(string, " 0x%lx-0x%lx",
+ node->addr,
+ node->addr + node->size - 1);
+ eisa_reg_print(e_dev, buf,
+ *reg_count ? &separator : NULL);
+ (*reg_count)++;
+ return (0);
+ }
+ }
+ return (ENOENT);
+ }
+ return EPERM;
+}
+
+int
+eisa_reg_mspace(e_dev, resvaddr)
+ struct eisa_device *e_dev;
+ resvaddr_t *resvaddr;
+{
+#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_MADDR;
+ if (haveseen_dev(dev, checkthese))
+ return -1;
+#endif
+ return (eisa_reg_resvaddr(e_dev, &(e_dev->ioconf.maddrs), resvaddr,
+ &(reg_state.num_maddrs)));
+}
+
+int
+eisa_reg_iospace(e_dev, resvaddr)
+ struct eisa_device *e_dev;
+ resvaddr_t *resvaddr;
+{
#ifdef NOT_YET
/*
* Punt on conflict detection for the moment.
@@ -433,11 +650,8 @@ eisa_reg_iospace(e_dev, iobase, iosize)
if (haveseen_dev(dev, checkthese))
return -1;
#endif
- e_dev->ioconf.iobase = iobase;
- e_dev->ioconf.iosize = iosize;
-
- printf(" at 0x%lx-0x%lx", iobase, iobase + iosize - 1);
- return (0);
+ return (eisa_reg_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), resvaddr,
+ &(reg_state.num_ioaddrs)));
}
int
diff --git a/sys/dev/eisa/eisaconf.h b/sys/dev/eisa/eisaconf.h
index 93cecf3..181c768 100644
--- a/sys/dev/eisa/eisaconf.h
+++ b/sys/dev/eisa/eisaconf.h
@@ -18,13 +18,16 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: eisaconf.h,v 1.5 1995/11/20 12:41:13 phk Exp $
+ * $Id: eisaconf.h,v 1.6 1995/11/21 12:52:49 bde Exp $
*/
#ifndef _I386_EISA_EISACONF_H_
#define _I386_EISA_EISACONF_H_ 1
+#include <sys/queue.h>
+
#define EISA_SLOTS 10 /* PCI clashes with higher ones.. fix later */
+#define EISA_SLOT_SIZE 0x1000
#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */
#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */
@@ -35,15 +38,27 @@
extern struct linker_set eisadriver_set;
-typedef u_long eisa_id_t; /* Should use u_int32? */
+typedef u_int32_t eisa_id_t;
+
+typedef struct resvaddr {
+ u_long addr; /* start address */
+ u_long size; /* size of reserved area */
+ int flags;
+#define RESVADDR_NONE 0x00
+#define RESVADDR_BITMASK 0x01 /* size is a mask of reserved
+ * bits at addr
+ */
+#define RESVADDR_RELOCATABLE 0x02
+ LIST_ENTRY(resvaddr) links; /* List links */
+} resvaddr_t;
+
+LIST_HEAD(resvlist, resvaddr);
struct eisa_ioconf {
- int slot;
- u_long iobase; /* base i/o address */
- int iosize; /* size of i/o space */
- u_short irq; /* interrupt request */
- caddr_t maddr; /* physical i/o memory address on bus (if any)*/
- int msize; /* size of i/o memory */
+ int slot;
+ struct resvlist ioaddrs; /* list of reserved I/O ranges */
+ struct resvlist maddrs; /* list of reserved memory ranges */
+ u_short irq; /* bitmask of interrupt */
};
struct kern_devconf;
@@ -81,8 +96,10 @@ int eisa_add_intr __P((struct eisa_device *, int));
int eisa_reg_intr __P((struct eisa_device *, int, void (*)(void *), void *, u_int *, int));
int eisa_release_intr __P((struct eisa_device *, int, void (*)(void *)));
int eisa_enable_intr __P((struct eisa_device *, int));
-int eisa_add_iospace __P((struct eisa_device *, u_long, int));
-int eisa_reg_iospace __P((struct eisa_device *, u_long, int));
+int eisa_add_iospace __P((struct eisa_device *, u_long, u_long, int));
+int eisa_reg_iospace __P((struct eisa_device *, resvaddr_t *));
+int eisa_add_mspace __P((struct eisa_device *, u_long, u_long, int));
+int eisa_reg_mspace __P((struct eisa_device *, resvaddr_t *));
int eisa_registerdev __P((struct eisa_device *, struct eisa_driver *, struct kern_devconf *));
diff --git a/sys/i386/eisa/aha1742.c b/sys/i386/eisa/aha1742.c
index 3344762..f9a5f40 100644
--- a/sys/i386/eisa/aha1742.c
+++ b/sys/i386/eisa/aha1742.c
@@ -14,7 +14,7 @@
*
* commenced: Sun Sep 27 18:14:01 PDT 1992
*
- * $Id: aha1742.c,v 1.47 1996/01/07 19:20:59 gibbs Exp $
+ * $Id: aha1742.c,v 1.48 1996/01/14 02:19:42 gibbs Exp $
*/
#include <sys/types.h>
@@ -26,12 +26,14 @@
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/systm.h>
-#include <sys/errno.h>
-#include <sys/ioctl.h>
+#include <sys/devconf.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/proc.h>
+#include <scsi/scsi_all.h>
+#include <scsi/scsiconf.h>
+
#include <machine/clock.h>
#include <vm/vm.h>
@@ -41,9 +43,6 @@
#else
#define NAHB 1
#endif /*KERNEL */
-#include <scsi/scsi_all.h>
-#include <scsi/scsiconf.h>
-#include <sys/devconf.h>
/* */
@@ -72,6 +71,7 @@ typedef unsigned long int physaddr;
#define EISA_DEVICE_ID_ADAPTEC_1740 0x04900000
#define AHB_EISA_IOSIZE 0x100
+#define AHB_EISA_SLOT_OFFSET 0xc00
/* AHA1740 EISA board control registers (Offset from slot base) */
#define EBCTRL 0x084
@@ -473,9 +473,10 @@ ahbprobe(void)
count = 0;
while ((e_dev = eisa_match_dev(e_dev, ahbmatch))) {
- iobase = e_dev->ioconf.iobase;
+ iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE) +
+ AHB_EISA_SLOT_OFFSET;
- eisa_add_iospace(e_dev, iobase, AHB_EISA_IOSIZE);
+ eisa_add_iospace(e_dev, iobase, AHB_EISA_IOSIZE, RESVADDR_NONE);
intdef = inb(INTDEF + iobase);
switch (intdef & 0x7) {
case INT9:
@@ -594,18 +595,24 @@ ahb_attach(e_dev)
*/
int unit = e_dev->unit;
struct ahb_data *ahb;
+ resvaddr_t *iospace;
int irq = ffs(e_dev->ioconf.irq) - 1;
- if(!(ahb_reset(e_dev->ioconf.iobase)))
+ iospace = e_dev->ioconf.ioaddrs.lh_first;
+
+ if(!iospace)
+ return -1;
+
+ if(!(ahb_reset(iospace->addr)))
return -1;
eisa_reg_start(e_dev);
- if(eisa_reg_iospace(e_dev, e_dev->ioconf.iobase, AHB_EISA_IOSIZE)) {
+ if(eisa_reg_iospace(e_dev, iospace)) {
eisa_reg_end(e_dev);
return -1;
}
- if(!(ahb = ahb_alloc(unit, e_dev->ioconf.iobase, irq))) {
+ if(!(ahb = ahb_alloc(unit, iospace->addr, irq))) {
ahb_free(ahb);
eisa_reg_end(e_dev);
return -1;
diff --git a/sys/i386/eisa/aic7770.c b/sys/i386/eisa/aic7770.c
index b7da311..2e215b0 100644
--- a/sys/i386/eisa/aic7770.c
+++ b/sys/i386/eisa/aic7770.c
@@ -2,7 +2,7 @@
* Product specific probe and attach routines for:
* 27/284X and aic7770 motherboard SCSI controllers
*
- * Copyright (c) 1995 Justin T. Gibbs
+ * Copyright (c) 1995, 1996 Justin T. Gibbs
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -19,7 +19,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: aic7770.c,v 1.21 1996/01/03 06:28:00 gibbs Exp $
+ * $Id: aic7770.c,v 1.22 1996/01/23 21:48:28 se Exp $
*/
#include "eisa.h"
@@ -44,8 +44,9 @@
#define EISA_DEVICE_ID_ADAPTEC_284xB 0x04907756 /* BIOS enabled */
#define EISA_DEVICE_ID_ADAPTEC_284x 0x04907757 /* BIOS disabled*/
-#define AHC_EISA_IOSIZE 0x100
-#define INTDEF 0x5cul /* Interrupt Definition Register */
+#define AHC_EISA_SLOT_OFFSET 0xc00
+#define AHC_EISA_IOSIZE 0x100
+#define INTDEF 0x5cul /* Interrupt Definition Register */
static int aic7770probe __P((void));
static int aic7770_attach __P((struct eisa_device *e_dev));
@@ -106,10 +107,11 @@ aic7770probe(void)
count = 0;
while ((e_dev = eisa_match_dev(e_dev, aic7770_match))) {
- iobase = e_dev->ioconf.iobase;
+ iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE)
+ + AHC_EISA_SLOT_OFFSET;
ahc_reset(iobase);
- eisa_add_iospace(e_dev, iobase, AHC_EISA_IOSIZE);
+ eisa_add_iospace(e_dev, iobase, AHC_EISA_IOSIZE, RESVADDR_NONE);
intdef = inb(INTDEF + iobase);
switch (intdef & 0xf) {
case 9:
@@ -154,10 +156,18 @@ aic7770_attach(e_dev)
{
ahc_type type;
struct ahc_data *ahc;
+ resvaddr_t *iospace;
u_long iobase;
int unit = e_dev->unit;
int irq = ffs(e_dev->ioconf.irq) - 1;
+ iospace = e_dev->ioconf.ioaddrs.lh_first;
+
+ if(!iospace)
+ return -1;
+
+ iobase = iospace->addr;
+
switch(e_dev->id) {
case EISA_DEVICE_ID_ADAPTEC_AIC7770:
type = AHC_AIC7770;
@@ -175,11 +185,11 @@ aic7770_attach(e_dev)
break;
}
- if(!(ahc = ahc_alloc(unit, e_dev->ioconf.iobase, type, AHC_FNONE)))
+ if(!(ahc = ahc_alloc(unit, iospace->addr, type, AHC_FNONE)))
return -1;
eisa_reg_start(e_dev);
- if(eisa_reg_iospace(e_dev, e_dev->ioconf.iobase, AHC_EISA_IOSIZE)) {
+ if(eisa_reg_iospace(e_dev, iospace)) {
ahc_free(ahc);
return -1;
}
@@ -211,10 +221,7 @@ aic7770_attach(e_dev)
/*
* Now that we know we own the resources we need, do the
* card initialization.
- */
- iobase = ahc->baseport;
-
- /*
+ *
* First, the aic7770 card specific setup.
*/
switch( ahc->type ) {
diff --git a/sys/i386/eisa/bt74x.c b/sys/i386/eisa/bt74x.c
index 5d52b07..6cc4dab 100644
--- a/sys/i386/eisa/bt74x.c
+++ b/sys/i386/eisa/bt74x.c
@@ -19,7 +19,7 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: bt74x.c,v 1.1 1995/12/12 08:47:11 gibbs Exp $
+ * $Id: bt74x.c,v 1.2 1995/12/14 14:19:13 peter Exp $
*/
#include "eisa.h"
@@ -37,9 +37,11 @@
#define EISA_DEVICE_ID_BUSLOGIC_74X_B 0x0ab34201
#define EISA_DEVICE_ID_BUSLOGIC_74X_C 0x0ab34202
+#define EISA_DEVICE_ID_AMI_4801 0x05a94801
-#define BT_IOSIZE 0x04 /* Move to central header */
-#define BT_EISA_IOSIZE 0x100
+#define BT_IOSIZE 0x04 /* Move to central header */
+#define BT_EISA_IOSIZE 0x100
+#define BT_EISA_SLOT_OFFSET 0xc00
#define EISA_IOCONF 0x08C
#define PORTADDR 0x07
@@ -60,6 +62,33 @@
#define EISA_IRQ_TYPE 0x08D
#define LEVEL 0x40
+/* Definitions for the AMI Series 48 controler */
+#define AMI_EISA_IOSIZE 0x500 /* Two separate ranges?? */
+#define AMI_EISA_SLOT_OFFSET 0x800
+#define AMI_EISA_IOCONF 0x000
+#define AMI_DMA_CHANNEL 0x03
+#define AMI_IRQ_CHANNEL 0x1c
+#define AMI_INT_15 0x14
+#define AMI_INT_14 0x10
+#define AMI_INT_12 0x0c
+#define AMI_INT_11 0x00
+#define AMI_INT_10 0x08
+#define AMI_INT_9 0x04
+#define AMI_BIOS_ADDR 0xe0
+
+#define AMI_EISA_IOCONF1 0x001
+#define AMI_PORTADDR 0x0e
+#define AMI_PORT_334 0x08
+#define AMI_PORT_330 0x00
+#define AMI_PORT_234 0x0c
+#define AMI_PORT_230 0x04
+#define AMI_PORT_134 0x0a
+#define AMI_PORT_130 0x02
+#define AMI_IRQ_LEVEL 0x01
+
+
+#define AMI_MISC2_OPTIONS 0x49E
+#define AMI_ENABLE_ISA_DMA 0x08
static int bt_eisa_probe __P((void));
static int bt_eisa_attach __P((struct eisa_device *e_dev));
@@ -98,6 +127,9 @@ bt_match(type)
case EISA_DEVICE_ID_BUSLOGIC_74X_C:
return ("Buslogic 74xC SCSI host adapter");
break;
+ case EISA_DEVICE_ID_AMI_4801:
+ return ("AMI Series 48 SCSI host adapter");
+ break;
default:
break;
}
@@ -118,74 +150,146 @@ bt_eisa_probe(void)
u_char ioconf;
u_long port;
int irq;
- iobase = e_dev->ioconf.iobase;
-
-#ifdef MULTIPLE_IOSPACES
- eisa_add_iospace(e_dev, iobase, BT_EISA_IOSIZE);
-#endif
-
- ioconf = inb(iobase + EISA_IOCONF);
- /* Determine "ISA" I/O port */
- switch (ioconf & PORTADDR) {
- case PORT_330:
- port = 0x330;
- break;
- case PORT_334:
- port = 0x334;
- break;
- case PORT_230:
- port = 0x230;
- break;
- case PORT_234:
- port = 0x234;
- break;
- case PORT_130:
- port = 0x130;
- break;
- case PORT_134:
- port = 0x134;
- break;
- default:
- /* Disabled */
- printf("bt: Buslogic EISA Adapter at slot %d "
- "has a disabled I/O port. Cannot "
- "attach.\n", e_dev->ioconf.slot);
- continue;
- }
+ iobase = (e_dev->ioconf.slot * EISA_SLOT_SIZE);
+ if(e_dev->id == EISA_DEVICE_ID_AMI_4801) {
+ u_char ioconf1;
+ iobase += AMI_EISA_SLOT_OFFSET;
+
+ eisa_add_iospace(e_dev, iobase, AMI_EISA_IOSIZE,
+ RESVADDR_NONE);
+
+ ioconf = inb(iobase + AMI_EISA_IOCONF);
+ ioconf1 = inb(iobase + AMI_EISA_IOCONF1);
+ /* Determine "ISA" I/O port */
+ switch (ioconf1 & AMI_PORTADDR) {
+ case AMI_PORT_330:
+ port = 0x330;
+ break;
+ case AMI_PORT_334:
+ port = 0x334;
+ break;
+ case AMI_PORT_230:
+ port = 0x230;
+ break;
+ case AMI_PORT_234:
+ port = 0x234;
+ break;
+ case AMI_PORT_134:
+ port = 0x134;
+ break;
+ case AMI_PORT_130:
+ port = 0x130;
+ break;
+ default:
+ /* Disabled */
+ printf("bt: AMI EISA Adapter at "
+ "slot %d has a disabled I/O "
+ "port. Cannot attach.\n",
+ e_dev->ioconf.slot);
+ continue;
+ }
- eisa_add_iospace(e_dev, port, BT_IOSIZE);
-
- /* Determine our IRQ */
- switch (ioconf & IRQ_CHANNEL) {
- case INT_11:
- irq = 11;
- break;
- case INT_10:
- irq = 10;
- break;
- case INT_15:
- irq = 15;
- break;
- case INT_12:
- irq = 12;
- break;
- case INT_14:
- irq = 14;
- break;
- case INT_9:
- irq = 9;
- break;
- default:
- /* Disabled */
- printf("bt: Buslogic EISA Adapter at slot %d "
- "has its IRQ disabled. Cannot "
- "attach.\n", e_dev->ioconf.slot);
- continue;
+ eisa_add_iospace(e_dev, port, BT_IOSIZE, RESVADDR_NONE);
+
+ /* Determine our IRQ */
+ switch (ioconf & AMI_IRQ_CHANNEL) {
+ case AMI_INT_11:
+ irq = 11;
+ break;
+ case AMI_INT_10:
+ irq = 10;
+ break;
+ case AMI_INT_15:
+ irq = 15;
+ break;
+ case AMI_INT_12:
+ irq = 12;
+ break;
+ case AMI_INT_14:
+ irq = 14;
+ break;
+ case AMI_INT_9:
+ irq = 9;
+ break;
+ default:
+ /* Disabled */
+ printf("bt: AMI EISA Adapter at "
+ "slot %d has its IRQ disabled. "
+ "Cannot attach.\n",
+ e_dev->ioconf.slot);
+ continue;
+ }
}
+ else {
+ iobase += BT_EISA_SLOT_OFFSET;
- eisa_add_intr(e_dev, irq);
+ eisa_add_iospace(e_dev, iobase, BT_EISA_IOSIZE,
+ RESVADDR_NONE);
+
+ ioconf = inb(iobase + EISA_IOCONF);
+ /* Determine "ISA" I/O port */
+ switch (ioconf & PORTADDR) {
+ case PORT_330:
+ port = 0x330;
+ break;
+ case PORT_334:
+ port = 0x334;
+ break;
+ case PORT_230:
+ port = 0x230;
+ break;
+ case PORT_234:
+ port = 0x234;
+ break;
+ case PORT_130:
+ port = 0x130;
+ break;
+ case PORT_134:
+ port = 0x134;
+ break;
+ default:
+ /* Disabled */
+ printf("bt: Buslogic EISA Adapter at "
+ "slot %d has a disabled I/O "
+ "port. Cannot attach.\n",
+ e_dev->ioconf.slot);
+ continue;
+ }
+ eisa_add_iospace(e_dev, port, BT_IOSIZE, RESVADDR_NONE);
+ /* Determine our IRQ */
+ switch (ioconf & IRQ_CHANNEL) {
+ case INT_11:
+ irq = 11;
+ break;
+ case INT_10:
+ irq = 10;
+ break;
+ case INT_15:
+ irq = 15;
+ break;
+ case INT_12:
+ irq = 12;
+ break;
+ case INT_14:
+ irq = 14;
+ break;
+ case INT_9:
+ irq = 9;
+ break;
+ default:
+ /* Disabled */
+ printf("bt: Buslogic EISA Adapter at "
+ "slot %d has its IRQ disabled. "
+ "Cannot attach.\n",
+ e_dev->ioconf.slot);
+ continue;
+ }
+
+ }
+ eisa_add_intr(e_dev, irq);
eisa_registerdev(e_dev, &bt_eisa_driver, &kdc_eisa_bt);
+
count++;
}
return count;
@@ -198,27 +302,41 @@ bt_eisa_attach(e_dev)
struct bt_data *bt;
int unit = e_dev->unit;
int irq = ffs(e_dev->ioconf.irq) - 1;
-#ifdef MULTIPLE_IOADDR
- u_char level_intr = inb((e_dev->ioconf.iobase[1]) + EISA_IRQ_TYPE)
- & LEVEL;
-#else
- u_char level_intr = inb((e_dev->ioconf.slot * 0x1c00) + EISA_IRQ_TYPE)
- & LEVEL;
-#endif
+ resvaddr_t *ioport;
+ resvaddr_t *eisa_ioport;
+ u_char level_intr;
+
+ /*
+ * The addresses are sorted in increasing order
+ * so we know the port to pass to the core bt
+ * driver comes first.
+ */
+ ioport = e_dev->ioconf.ioaddrs.lh_first;
+
+ if(!ioport)
+ return -1;
+
+ eisa_ioport = ioport->links.le_next;
+
+ if(!eisa_ioport)
+ return -1;
+
+ if(e_dev->id == EISA_DEVICE_ID_AMI_4801)
+ level_intr = inb(eisa_ioport->addr + AMI_EISA_IOCONF1)
+ & AMI_IRQ_LEVEL;
+ else
+ level_intr = inb(eisa_ioport->addr + EISA_IRQ_TYPE)
+ & LEVEL;
eisa_reg_start(e_dev);
- if(eisa_reg_iospace(e_dev, e_dev->ioconf.iobase, BT_IOSIZE)) {
+ if(eisa_reg_iospace(e_dev, ioport))
return -1;
- }
-#ifdef MULTIPLE_IOADDR
- /* Almost like this. Will depend on the definition of iobase */
- if(eisa_reg_iospace(e_dev, e_dev->ioconf.iobase[1], BT_EISA_IOSIZE)) {
+ if(eisa_reg_iospace(e_dev, eisa_ioport))
return -1;
-#endif
- if(!(bt = bt_alloc(unit, e_dev->ioconf.iobase))) {
+
+ if(!(bt = bt_alloc(unit, ioport->addr)))
return -1;
- }
if(eisa_reg_intr(e_dev, irq, bt_intr, (void *)bt, &bio_imask,
/*shared ==*/level_intr)) {
diff --git a/sys/i386/eisa/eisaconf.c b/sys/i386/eisa/eisaconf.c
index 288c66b..2c583aa 100644
--- a/sys/i386/eisa/eisaconf.c
+++ b/sys/i386/eisa/eisaconf.c
@@ -1,7 +1,7 @@
/*
* EISA bus probe and attach routines
*
- * Copyright (c) 1995 Justin T. Gibbs.
+ * Copyright (c) 1995, 1996 Justin T. Gibbs.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -18,15 +18,15 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: eisaconf.c,v 1.11 1995/12/10 13:33:49 phk Exp $
+ * $Id: eisaconf.c,v 1.12 1996/01/03 06:28:01 gibbs Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/devconf.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
-#include <sys/conf.h>
+#include <sys/conf.h> /* For kdc_isa */
#include <sys/malloc.h>
-#include <sys/devconf.h>
#include <i386/eisa/eisaconf.h>
@@ -77,6 +77,30 @@ static struct eisa_driver mainboard_drv = {
DATA_SET (eisadriver_set, mainboard_drv);
/*
+ * Local function declarations and static variables
+ */
+void eisa_reg_print __P((struct eisa_device *e_dev, char *string,
+ char *separator));
+static int eisa_add_resvaddr __P((struct resvlist *head, u_long base,
+ u_long size, int flags));
+static int eisa_reg_resvaddr __P((struct eisa_device *e_dev,
+ struct resvlist *head, resvaddr_t *resvaddr,
+ int *reg_count));
+
+/*
+ * Keep some state about what we've printed so far
+ * to make probe output pretty.
+ */
+static struct {
+ int in_registration;/* reg_start has been called */
+ int num_interrupts;
+ int num_ioaddrs;
+ int num_maddrs;
+ int column; /* How much we have output so far. */
+#define MAX_COL 80
+} reg_state;
+
+/*
** probe for EISA devices
*/
void
@@ -112,6 +136,7 @@ eisa_configure()
}
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
@@ -131,9 +156,13 @@ eisa_configure()
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;
+
+ /* Initialize our lists of reserved addresses */
+ LIST_INIT(&(e_dev->ioconf.ioaddrs));
+ LIST_INIT(&(e_dev->ioconf.maddrs));
+
*eisa_dev_list_tail = dev_node;
eisa_dev_list_tail = &dev_node->next;
}
@@ -199,6 +228,7 @@ eisa_configure()
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.
@@ -213,20 +243,25 @@ eisa_configure()
*/
e_dev->unit = (*e_drv->unit)++;
if ((*e_drv->attach)(e_dev) < 0) {
- printf("%s0:%d <%s> attach failed\n",
+ /* Ensure registration has ended */
+ reg_state.in_registration = 0;
+ printf("\n%s0:%d <%s> attach failed\n",
mainboard_drv.name,
e_dev->ioconf.slot,
e_dev->full_name);
continue;
}
+ /* Ensure registration has ended */
+ reg_state.in_registration = 0;
e_dev->kdc->kdc_unit = e_dev->unit;
}
else {
/* Announce unattached device */
- printf("%s0:%d <%s> unknown device\n",
+ printf("%s0:%d <%s=0x%x> unknown device\n",
mainboard_drv.name,
e_dev->ioconf.slot,
- e_dev->full_name);
+ e_dev->full_name,
+ e_dev->id);
}
}
}
@@ -267,10 +302,57 @@ eisa_reg_start(e_dev)
/*
* Announce the device.
*/
- printf("%s%ld: <%s>",
- e_dev->driver->name,
- e_dev->unit,
- e_dev->full_name);
+ char *string;
+
+ reg_state.in_registration = 1;
+ reg_state.num_interrupts = 0;
+ reg_state.num_ioaddrs = 0;
+ reg_state.num_maddrs = 0;
+ reg_state.column = 0;
+
+ string = malloc(strlen(e_dev->full_name) + sizeof(" <>") + /*NULL*/1,
+ M_TEMP, M_NOWAIT);
+ if(!string) {
+ printf("eisa0: cannot malloc device description string\n");
+ return;
+ }
+ sprintf(string, " <%s>", e_dev->full_name);
+ eisa_reg_print(e_dev, string, /*separator=*/NULL);
+ free(string, M_TEMP);
+}
+
+/*
+ * Output registration information mindfull of screen wrap.
+ * Output an optional character separator before the string
+ * if the line does not wrap.
+ */
+void
+eisa_reg_print(e_dev, string, separator)
+ struct eisa_device *e_dev;
+ char *string;
+ char *separator;
+{
+ int len = strlen(string);
+
+ if( separator )
+ len++;
+
+ if(reg_state.column + len > MAX_COL) {
+ printf("\n");
+ reg_state.column = 0;
+ }
+ else if( separator ) {
+ printf("%c", *separator);
+ reg_state.column++;
+ }
+
+ if(reg_state.column == 0)
+ reg_state.column += printf("%s%ld:%s",
+ e_dev->driver->name,
+ e_dev->unit,
+ string);
+ else
+ reg_state.column += printf("%s", string);
}
/* Interrupt and I/O space registration facitlities */
@@ -278,19 +360,30 @@ void
eisa_reg_end(e_dev)
struct eisa_device *e_dev;
{
- /*
- * 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);
+ if( reg_state.in_registration )
+ {
+ /*
+ * 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.
+ */
+ char string[25];
+
+ if (e_dev->kdc && (e_dev->kdc->kdc_parent == &kdc_isa0)) {
+ sprintf(string, " on isa");
+ }
+ else {
+ sprintf(string, " on %s0 slot %d",
+ mainboard_drv.name,
+ e_dev->ioconf.slot);
+ }
+ eisa_reg_print(e_dev, string, NULL);
+ printf("\n");
+ reg_state.in_registration = 0;
}
+ else
+ printf("eisa_reg_end called outside of a "
+ "registration session\n");
}
int
@@ -313,6 +406,8 @@ eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared)
{
int result;
int s;
+ char string[25];
+ char separator = ',';
#if NOT_YET
/*
@@ -324,28 +419,35 @@ eisa_reg_intr(e_dev, irq, func, arg, maskptr, shared)
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);
+ if (reg_state.in_registration) {
+ 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 ("\neisa_reg_int: result=%d\n", result);
+ splx(s);
+ return (result);
+ };
+ update_intr_masks();
splx(s);
- return (result);
- };
- update_intr_masks();
- splx(s);
+ }
+ else
+ return EPERM;
e_dev->ioconf.irq |= 1ul << irq;
- printf(" irq %d", irq);
+ sprintf(string, " irq %d", irq);
+ eisa_reg_print(e_dev, string, reg_state.num_interrupts ?
+ &separator : NULL);
+ reg_state.num_interrupts++;
return (0);
}
@@ -398,31 +500,146 @@ eisa_enable_intr(e_dev, irq)
return 0;
}
+static int
+eisa_add_resvaddr(head, base, size, flags)
+ struct resvlist *head;
+ u_long base;
+ u_long size;
+ int flags;
+{
+ resvaddr_t *reservation;
+
+ reservation = (resvaddr_t *)malloc(sizeof(resvaddr_t),
+ M_DEVBUF, M_NOWAIT);
+ if(!reservation)
+ return (ENOMEM);
+
+ reservation->addr = base;
+ reservation->size = size;
+ reservation->flags = flags;
+
+ if (!head->lh_first) {
+ LIST_INSERT_HEAD(head, reservation, links);
+ }
+ else {
+ resvaddr_t *node;
+ for(node = head->lh_first; node; node = node->links.le_next) {
+ if (node->addr > reservation->addr) {
+ /*
+ * List is sorted in increasing
+ * address order.
+ */
+ LIST_INSERT_BEFORE(node, reservation, links);
+ break;
+ }
+
+ if (node->addr == reservation->addr) {
+ /*
+ * If the entry we want to add
+ * matches any already in here,
+ * fail.
+ */
+ free(reservation, M_DEVBUF);
+ return (EEXIST);
+ }
+
+ if (!node->links.le_next) {
+ LIST_INSERT_AFTER(node, reservation, links);
+ break;
+ }
+ }
+ }
+ return (0);
+}
+
int
-eisa_add_iospace(e_dev, iobase, iosize)
+eisa_add_mspace(e_dev, mbase, msize, flags)
struct eisa_device *e_dev;
- u_long iobase;
- int iosize;
+ u_long mbase;
+ u_long msize;
+ int flags;
{
- /*
- * 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;
+ return eisa_add_resvaddr(&(e_dev->ioconf.maddrs), mbase, msize, flags);
}
int
-eisa_reg_iospace(e_dev, iobase, iosize)
+eisa_add_iospace(e_dev, iobase, iosize, flags)
struct eisa_device *e_dev;
u_long iobase;
- int iosize;
+ u_long iosize;
+ int flags;
{
- /*
- * We should develop a scheme for storing the results of
- * multiple calls to this function.
+ return eisa_add_resvaddr(&(e_dev->ioconf.ioaddrs), iobase, iosize,
+ flags);
+}
+
+static int
+eisa_reg_resvaddr(e_dev, head, resvaddr, reg_count)
+ struct eisa_device *e_dev;
+ struct resvlist *head;
+ resvaddr_t *resvaddr;
+ int *reg_count;
+{
+ if (reg_state.in_registration) {
+ resvaddr_t *node;
+ /*
+ * Ensure that this resvaddr is actually in the devices'
+ * reservation list.
+ */
+ for(node = head->lh_first; node;
+ node = node->links.le_next) {
+ if (node == resvaddr) {
+ char buf[35];
+ char separator = ',';
+ char *string = buf;
+
+ if (*reg_count == 0) {
+ /* First time */
+ string += sprintf(string, " at");
+ }
+
+ if (node->size == 1
+ || (node->flags & RESVADDR_BITMASK))
+ sprintf(string, " 0x%lx", node->addr);
+ else
+ sprintf(string, " 0x%lx-0x%lx",
+ node->addr,
+ node->addr + node->size - 1);
+ eisa_reg_print(e_dev, buf,
+ *reg_count ? &separator : NULL);
+ (*reg_count)++;
+ return (0);
+ }
+ }
+ return (ENOENT);
+ }
+ return EPERM;
+}
+
+int
+eisa_reg_mspace(e_dev, resvaddr)
+ struct eisa_device *e_dev;
+ resvaddr_t *resvaddr;
+{
+#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_MADDR;
+ if (haveseen_dev(dev, checkthese))
+ return -1;
+#endif
+ return (eisa_reg_resvaddr(e_dev, &(e_dev->ioconf.maddrs), resvaddr,
+ &(reg_state.num_maddrs)));
+}
+
+int
+eisa_reg_iospace(e_dev, resvaddr)
+ struct eisa_device *e_dev;
+ resvaddr_t *resvaddr;
+{
#ifdef NOT_YET
/*
* Punt on conflict detection for the moment.
@@ -433,11 +650,8 @@ eisa_reg_iospace(e_dev, iobase, iosize)
if (haveseen_dev(dev, checkthese))
return -1;
#endif
- e_dev->ioconf.iobase = iobase;
- e_dev->ioconf.iosize = iosize;
-
- printf(" at 0x%lx-0x%lx", iobase, iobase + iosize - 1);
- return (0);
+ return (eisa_reg_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), resvaddr,
+ &(reg_state.num_ioaddrs)));
}
int
diff --git a/sys/i386/eisa/eisaconf.h b/sys/i386/eisa/eisaconf.h
index 93cecf3..181c768 100644
--- a/sys/i386/eisa/eisaconf.h
+++ b/sys/i386/eisa/eisaconf.h
@@ -18,13 +18,16 @@
* 4. Modifications may be freely made to this file if the above conditions
* are met.
*
- * $Id: eisaconf.h,v 1.5 1995/11/20 12:41:13 phk Exp $
+ * $Id: eisaconf.h,v 1.6 1995/11/21 12:52:49 bde Exp $
*/
#ifndef _I386_EISA_EISACONF_H_
#define _I386_EISA_EISACONF_H_ 1
+#include <sys/queue.h>
+
#define EISA_SLOTS 10 /* PCI clashes with higher ones.. fix later */
+#define EISA_SLOT_SIZE 0x1000
#define EISA_MFCTR_CHAR0(ID) (char)(((ID>>26) & 0x1F) | '@') /* Bits 26-30 */
#define EISA_MFCTR_CHAR1(ID) (char)(((ID>>21) & 0x1F) | '@') /* Bits 21-25 */
@@ -35,15 +38,27 @@
extern struct linker_set eisadriver_set;
-typedef u_long eisa_id_t; /* Should use u_int32? */
+typedef u_int32_t eisa_id_t;
+
+typedef struct resvaddr {
+ u_long addr; /* start address */
+ u_long size; /* size of reserved area */
+ int flags;
+#define RESVADDR_NONE 0x00
+#define RESVADDR_BITMASK 0x01 /* size is a mask of reserved
+ * bits at addr
+ */
+#define RESVADDR_RELOCATABLE 0x02
+ LIST_ENTRY(resvaddr) links; /* List links */
+} resvaddr_t;
+
+LIST_HEAD(resvlist, resvaddr);
struct eisa_ioconf {
- int slot;
- u_long iobase; /* base i/o address */
- int iosize; /* size of i/o space */
- u_short irq; /* interrupt request */
- caddr_t maddr; /* physical i/o memory address on bus (if any)*/
- int msize; /* size of i/o memory */
+ int slot;
+ struct resvlist ioaddrs; /* list of reserved I/O ranges */
+ struct resvlist maddrs; /* list of reserved memory ranges */
+ u_short irq; /* bitmask of interrupt */
};
struct kern_devconf;
@@ -81,8 +96,10 @@ int eisa_add_intr __P((struct eisa_device *, int));
int eisa_reg_intr __P((struct eisa_device *, int, void (*)(void *), void *, u_int *, int));
int eisa_release_intr __P((struct eisa_device *, int, void (*)(void *)));
int eisa_enable_intr __P((struct eisa_device *, int));
-int eisa_add_iospace __P((struct eisa_device *, u_long, int));
-int eisa_reg_iospace __P((struct eisa_device *, u_long, int));
+int eisa_add_iospace __P((struct eisa_device *, u_long, u_long, int));
+int eisa_reg_iospace __P((struct eisa_device *, resvaddr_t *));
+int eisa_add_mspace __P((struct eisa_device *, u_long, u_long, int));
+int eisa_reg_mspace __P((struct eisa_device *, resvaddr_t *));
int eisa_registerdev __P((struct eisa_device *, struct eisa_driver *, struct kern_devconf *));
OpenPOWER on IntegriCloud