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>