Date: Tue, 17 Mar 1998 16:30:47 -0800 (PST) From: nsayer@quack.kfu.com To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/6046: New EISA probe/attach code for si driver Message-ID: <199803180030.QAA10726@zephyr.specialix.com>
next in thread | raw e-mail | index | archive | help
>Number: 6046
>Category: kern
>Synopsis: New EISA probe/attach code for si driver
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Tue Mar 17 16:40:01 PST 1998
>Last-Modified:
>Originator: Nick Sayer
>Organization:
Specialix, Inc.
>Release: FreeBSD 2.2.2-RELEASE i386
>Environment:
EISA SI/XIO host cards
>Description:
I don't have an EISA machine to test this code, which I largely stole from
the existing code in /sys/i386/eisa, but this gunk compiles and at least
looks more reasonably correct than the old code.
I seriously doubt that PCI and EISA cards could coexist correctly in a
machine with this driver. I believe they would have a propensity to
squish each other's unit numbers. Anyone contemplating mixing PCI
and EISA cards is likely to be seriously deranged.
>How-To-Repeat:
>Fix:
--- si.c.orig Sun Mar 8 23:07:07 1998
+++ si.c Tue Mar 17 16:25:21 1998
@@ -145,6 +145,25 @@
#endif
+#if NEISA > 0
+
+static int si_eisa_probe __P((void));
+static int si_eisa_attach __P((struct eisa_device *ed));
+
+static u_long si_eisa_count;
+
+static struct eisa_driver si_eisa_driver = {
+ "si",
+ si_eisa_probe,
+ si_eisa_attach,
+ NULL,
+ &si_eisa_unit,
+};
+
+DATA_SET(eisadriver_set, si_eisa_driver);
+
+#endif
+
static d_open_t siopen;
static d_close_t siclose;
static d_read_t siread;
@@ -204,8 +223,9 @@
caddr_t sc_maddr; /* kvaddr of iomem */
int sc_nport; /* # ports on this card */
int sc_irq; /* copy of attach irq */
+#if NEISA > 0
int sc_eisa_iobase; /* EISA io port address */
- int sc_eisa_irqbits;
+#endif
#ifdef DEVFS
struct {
void *ttyd;
@@ -370,6 +390,92 @@
#endif
+#if NEISA > 0
+
+static char *
+si_eisa_match(type)
+eisa_id_t type;
+{
+ if (type == SIEISADEVID)
+ return ("Specialix SI/XIO EISA host card");
+ return (NULL);
+}
+
+int si_eisa_probe(void)
+{
+ struct eisa_device *ed = NULL;
+ int count;
+
+ for (count=0; (ed=eisa_match_dev(ed, si_eisa_match)) != NULL; count++)
+ {
+ u_long port,maddr;
+
+ port = (ed->ioconf.slot * EISA_SLOT_SIZE) + SIEISABASE;
+ eisa_add_iospace(ed, iobase, SIEISAIOSIZE, RESVADDR_NONE);
+ maddr = (inb(iobase+1) << 24) | (inb(iobase) << 16);
+ eisa_add_mspace(ed, maddr, SIEISA_MEMSIZE, RESVADDR_NONE);
+ eisa_add_intr(ed, irq);
+ eisa_registerdev(ed, &ed_eisa_driver);
+ count++;
+ }
+ return count;
+}
+
+static int
+si_eisa_attach(ed)
+struct eisa_device ed;
+{
+ struct isa_device id;
+ vm_offset_t maddr,iospace;
+ u_int irq;
+ struct si_softc *sc;
+
+ sc = si_softc[ed->unit];
+
+ sc->sc_type = SIEISA;
+ sc->sc_typename = si_type[sc->sc_type];
+
+ if ((iospace = ed->ioconf.ioaddrs.lh_first) == NULL) {
+ printf("si%d: no iospace??\n", ed->unit);
+ return -1;
+ }
+ sc->sc_eisa_iobase = iospace;
+
+ sc->sc_irq = ((inb(iospace+2) >> 4) & 0xf);
+
+ if ((maddr = ed->ioconf.maddrs.lh_first) == NULL) {
+ printf("si%d: where am I??\n", ed->unit);
+ return -1;
+ }
+ eisa_reg_start(ed);
+ if (eisa_reg_iospace(ed, iospace)) {
+ printf("si%d: failed to register iospace 0x%x\n",
+ ed->unit, iospace);
+ return -1;
+ }
+ if (eisa_reg_mspace(ed, maddr)) {
+ printf("si%d: failed to register memspace 0x%x\n",
+ ed->unit, maddr);
+ return -1;
+ }
+ if (eisa_reg_intr(ed, irq, siintr, irq, &tty_imask, 1)) {
+ printf("si%d: failed to register interrupt %d\n",
+ ed->unit, irq);
+ return -1;
+ }
+ eisa_reg_end(ed);
+ if (eisa_enable_intr(ed, irq)) {
+ return -1;
+ }
+
+ id.id_unit = unit;
+ id.id_maddr = (caddr_t) maddr;
+ id.id_irq = irq;
+ siattach(&id);
+}
+
+#endif
+
/* Look for a valid board at the given mem addr */
static int
siprobe(id)
@@ -428,39 +534,6 @@
}
}
-#if NEISA > 0
- if (id->id_iobase > 0x0fff) { /* EISA card */
- int irq, port;
- unsigned long base;
- int eisa_irqs[] = { 0,IRQ1,IRQ2,IRQ3,IRQ4,IRQ5,IRQ6,IRQ7,
- IRQ8,IRQ9,IRQ10,IRQ11,IRQ12,IRQ13,IRQ14,IRQ15 };
-
- port = id->id_iobase;
- base = (inb(port+1) << 24) | (inb(port) << 16);
- irq = ((inb(port+2) >> 4) & 0xf);
-
- id->id_irq = eisa_irqs[irq];
-
- DPRINT((0, DBG_AUTOBOOT,
- "si%d: EISA base %x, irq %x, id_irq %x, port %x\n",
- id->id_unit, base, irq, id->id_irq, port));
-
- if ((id->id_irq&(IRQ1|IRQ2|IRQ8|IRQ13)) != 0)
- goto bad_irq;
-
- id->id_iobase &= 0xf000;
- id->id_iosize = 0x0fff;
-
- type = EISA;
- outb(p+2, (BYTE)irq << 4);
-
- sc->sc_eisa_iobase = p;
- sc->sc_eisa_irqbits = irq << 4;
- ramsize = SIEISA_RAMSIZE;
- goto got_card;
- }
-#endif
-
/* Is there anything out there? (0x17 is just an arbitrary number) */
*maddr = 0x17;
if (*maddr != 0x17) {
@@ -590,9 +663,6 @@
}
id->id_msize = SIJETISA_MEMSIZE;
break;
- case SIEISA:
- id->id_msize = SIEISA_MEMSIZE;
- break;
case SI2: /* MCA */
default:
printf("si%d: %s not supported\n", id->id_unit, si_type[type]);
@@ -672,7 +742,7 @@
#if NEISA > 0
/* modify the download code to tell it that it's on an EISA */
*(maddr+0x42) = 1;
- outb(sc->sc_eisa_iobase+2, sc->sc_eisa_irqbits | 4);
+ outb(sc->sc_eisa_iobase+2, (sc->sc_irq<<4) | 4);
(void)inb(sc->sc_eisa_iobase+3); /* reset interrupt */
break;
#endif /* fall-through if not EISA */
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199803180030.QAA10726>
