Skip site navigation (1)Skip section navigation (2)
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>