Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 4 Feb 1998 16:17:13 -0800 (PST)
From:      nick@specialix.com
To:        FreeBSD-gnats-submit@FreeBSD.ORG
Subject:   kern/5654: si driver support for Specialix Jet ISA (SX) host cards
Message-ID:  <199802050017.QAA00642@dial.kfu.com>

next in thread | raw e-mail | index | archive | help

>Number:         5654
>Category:       kern
>Synopsis:       si driver support for Specialix Jet ISA (SX) host cards
>Confidential:   No
>Severity:       non-critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          support
>Submitter-Id:   current-users
>Arrival-Date:   Wed Feb  4 16:20:01 PST 1998
>Last-Modified:
>Originator:     Nick Sayer
>Organization:
Specialix, Inc.
>Release:        FreeBSD 2.2.2-RELEASE i386
>Environment:


>Description:

This patch is against 2.2.2-RELEASE. It adds support for the old PCI
card, and the SX PCI and ISA host cards to the si driver.

>How-To-Repeat:

>Fix:
	
--- sys/i386/isa/si.c.orig	Sun Oct 26 11:40:46 1997
+++ sys/i386/isa/si.c	Wed Feb  4 13:45:06 1998
@@ -71,12 +71,20 @@
 #include <machine/si.h>
 #include <machine/stdarg.h>
 
+#include "pci.h"
+#if NPCI > 0
+#include <pci/pcivar.h>
+#include <pci/pcireg.h>
+#endif
+
 #include "si.h"
 
 /*
  * This device driver is designed to interface the Specialix International
  * range of serial multiplexor cards (SI/XIO) to BSDI/386 on an ISA bus machine.
  *
+ * [ 10/22/97 - And also on PCI machines -NS ]
+ *
  * The controller is interfaced to the host via dual port ram
  * and a (programmable - SIHOST2) interrupt at IRQ 11,12 or 15.
  */
@@ -111,6 +119,30 @@
 struct isa_driver sidriver =
 	{ siprobe, siattach, "si" };
 
+#if NPCI > 0
+
+/*
+ * NOTE! No checking is done to make sure that PCI and ISA unit numbers
+ * don't collide. Surely something evil would result. Don't let it happen
+ * to you.
+ */
+
+static char *sipciprobe __P((pcici_t, pcidi_t));
+static void sipciattach __P((pcici_t, int));
+
+static u_long sipcicount;
+
+static struct pci_device sipcidev = {
+	"si",
+	sipciprobe,
+	sipciattach,
+	&sipcicount,
+	NULL,
+};
+
+DATA_SET (pcidevice_set, sipcidev);
+
+#endif
 
 static	d_open_t	siopen;
 static	d_close_t	siclose;
@@ -120,6 +152,8 @@
 static	d_stop_t	sistop;
 static	d_devtotty_t	sidevtotty;
 
+void		siintr __P((int));
+
 #define CDEV_MAJOR 68
 static struct cdevsw si_cdevsw = 
 	{ siopen,	siclose,	siread,		siwrite,	/*68*/
@@ -145,9 +179,17 @@
 
 static struct tty *si_tty;
 
-/* where the firmware lives; defined in si_code.c */
+/* where the firmware lives; defined in si_code.c and si_jet.c */
+/* old: si_code.c */
 extern int si_dsize;
 extern unsigned char si_download[];
+/* new: si_jet.c */
+extern int si3_dsize;
+extern unsigned char si3_download[];
+extern unsigned short si3_bootloadaddr;
+extern int si3_bsize;
+extern unsigned char si3_bootstrap[];
+
 
 struct si_softc {
 	int 		sc_type;	/* adapter type */
@@ -248,8 +290,83 @@
 	"SI2",				/* MCA */
 	"SIHOST2",
 	"SIEISA",
+	"SIPCI",
+	"SXPCI",
+	"SXISA",
 };
 
+#if NPCI > 0
+
+static char *
+sipciprobe(configid, deviceid)
+pcici_t configid;
+pcidi_t deviceid;
+{
+	switch (deviceid)
+	{
+		case 0x400011cb:
+			return("Specialix SI/XIO PCI host card");
+			break;
+		case 0x200011cb:
+			if (pci_conf_read(configid, SIJETSSIDREG) == 0x020011cb)
+				return("Specialix SX PCI host card");
+			else
+				return NULL;
+			break;
+		default: return NULL;
+	}
+	/*NOTREACHED*/
+}
+
+void
+sipciattach(configid, unit)
+pcici_t configid;
+int unit;
+{
+	struct isa_device id;
+	vm_offset_t vaddr,paddr;
+	u_long mapval;
+
+	switch ( pci_conf_read(configid, 0) >> 16 )
+	{
+		case 0x4000:
+			si_softc[unit].sc_type = SIPCI;
+			mapval = SIPCIBADR;
+		break;
+		case 0x2000:
+			si_softc[unit].sc_type = SIJETPCI;
+			mapval = SIJETBADR;
+		break;
+	}
+	if (!pci_map_mem(configid, mapval, &vaddr, &paddr))
+	{
+		printf("si%d: couldn't map memory\n", unit);
+	}
+
+	/*
+	 * We're cheating here a little bit. The argument to an ISA
+	 * interrupt routine is the unit number. The argument to a
+	 * PCI interrupt handler is a void *, but we're simply going
+	 * to be lazy and hand it the unit number.
+	 */
+	if (!pci_map_int(configid, (pci_inthand_t *) siintr, (void *)unit, &tty_imask)) {
+		printf("si%d: couldn't map interrupt\n", unit);
+	}
+	si_softc[unit].sc_typename = si_type[si_softc[unit].sc_type];
+
+	/*
+	 * More cheating: We're going to dummy up a struct isa_device
+	 * and call the other attach routine. We don't really have to
+	 * fill in very much of the structure, since we filled in a
+	 * little of the soft state already.
+	 */
+	id.id_unit=unit;
+	id.id_maddr=(caddr_t) vaddr;
+	siattach(&id);
+}
+
+#endif
+
 /* Look for a valid board at the given mem addr */
 static int
 siprobe(id)
@@ -351,9 +468,34 @@
 		return(0);
 	}
 	/*
+	 * Let's look first for a JET ISA card, since that's pretty easy
+	 */
+	DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
+		"si%d: JET first check - 0x%x\n",
+		id->id_unit, (*(maddr+SIJETIDBASE))));
+	if (*(maddr+SIJETIDBASE) != (SISPLXID&0xff))
+		goto try_mk2;
+	DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
+		"si%d: JET second check - 0x%x\n",
+		id->id_unit, (*(maddr+SIJETIDBASE+2))));
+	if (*(maddr+SIJETIDBASE+2) != ((SISPLXID&0xff00)>>8))
+		goto try_mk2;
+	/* It must be a Jet ISA or RIO card */
+	DPRINT((0, DBG_AUTOBOOT|DBG_FAIL,
+		"si%d: JET id check - 0x%x\n",
+		id->id_unit, (*(maddr+SIUNIQID))));
+	if ((*(maddr+SIUNIQID) & 0xf0) !=0x20)
+		goto try_mk2;
+	/* It must be a Jet ISA SI/XIO card */
+	*(maddr + SIJETCONFIG) = 0;
+	type = SIJETISA;
+	ramsize = SIJET_RAMSIZE;
+	goto got_card;
+	/*
 	 * OK, now to see if whatever responded is really an SI card.
-	 * Try for a MK II first (SIHOST2)
+	 * Try for a MK II next (SIHOST2)
 	 */
+try_mk2:
 	for (i=SIPLSIG; i<SIPLSIG+8; i++)
 		if ((*(maddr+i) & 7) != (~(BYTE)i & 7))
 			goto try_mk1;
@@ -439,6 +581,12 @@
 		}
 		id->id_msize = SIHOST_MEMSIZE;
 		break;
+	case SIJETISA:
+		if ((id->id_irq&(IRQ9|IRQ10|IRQ11|IRQ12|IRQ15)) == 0) {
+			goto bad_irq;
+		}
+		id->id_msize = SIJET_MEMSIZE;
+		break;
 	case SIEISA:
 		id->id_msize = SIEISA_MEMSIZE;
 		break;
@@ -477,17 +625,45 @@
 	sc->sc_maddr = id->id_maddr;
 	sc->sc_irq = id->id_irq;
 
+	DPRINT((0, DBG_AUTOBOOT, "si%d: type: %s paddr: %x maddr: %x\n", unit,
+		sc->sc_typename, sc->sc_paddr, sc->sc_maddr));
+
 	sc->sc_ports = NULL;			/* mark as uninitialised */
 
 	maddr = sc->sc_maddr;
 
 	/*
 	 * OK, now lets download the firmware and try and boot the CPU..
+	 *
+	 * You can't use bcopy, since some cards won't take 32 bit writes.
 	 */
-
-	DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n",
-		id->id_unit, si_dsize));
-	bcopy(si_download, maddr, si_dsize);
+	if ((sc->sc_type == SIJETISA) || (sc->sc_type == SIJETPCI))
+	{
+		DPRINT((0, DBG_DOWNLOAD, "si%d: jet_download: nbytes %d\n",
+			id->id_unit, si3_dsize));
+		{
+			u_int i;
+			for (i=0;i<si3_dsize;i++)
+				maddr[i]=si3_download[i];
+		}
+		DPRINT((0, DBG_DOWNLOAD, "si%d: jet_bootstrap: nbytes %d -> %x\n",
+			id->id_unit, si3_bsize, si3_bootloadaddr));
+		{
+			u_int i;
+			for (i=0;i<si3_bsize;i++)
+				maddr[i+si3_bootloadaddr]=si3_bootstrap[i];
+		}
+	}
+	else
+	{
+		DPRINT((0, DBG_DOWNLOAD, "si%d: si_download: nbytes %d\n",
+			id->id_unit, si_dsize));
+		{
+			u_int i;
+			for (i=0;i<si_dsize;i++)
+				maddr[i]=si_download[i];
+		}
+	}
 
 	switch (sc->sc_type) {
 	case SIEISA:
@@ -504,6 +680,20 @@
 		 * these one day, if FreeBSD ever supports it.
 		 */
 		return 0;
+	case SIPCI:
+		/* modify the Z280 firmware to tell it that it's on a PCI */
+		*(maddr+0x42) = 1;
+		*(maddr+SIPCIRESET) = 1;
+		*(maddr+SIPCIINTCL) = 0;
+		break;
+	case SIJETPCI:
+		*(maddr+SIJETRESET) = 0;
+		*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN;
+		break;
+	case SIJETISA:
+		*(maddr+SIJETRESET) = 0;
+		*(maddr+SIJETCONFIG) = SIJETBUSEN|SIJETIRQEN|(sc->sc_irq<<4);
+		break;
 	case SIHOST:
 		*(maddr+SIRESET_CL) = 0;
 		*(maddr+SIINTCL_CL) = 0;
@@ -1686,7 +1876,7 @@
 		regp = (struct si_reg *)sc->sc_maddr;
 		/*
 		 * See if there has been a pending interrupt for 2 seconds
-		 * or so. The test <int_scounter >= 200) won't correspond
+		 * or so. The test (int_scounter >= 200) won't correspond
 		 * to 2 seconds if int_count gets changed.
 		 */
 		if (regp->int_pending != 0) {
@@ -1777,6 +1967,17 @@
 			((volatile struct si_reg *)maddr)->int_pending = 0;
 			*(maddr+SIPLIRQCLR) = 0x00;
 			*(maddr+SIPLIRQCLR) = 0x10;
+			break;
+		case SIPCI:
+			maddr = sc->sc_maddr;
+			((volatile struct si_reg *)maddr)->int_pending = 0;
+			*(maddr+SIPCIINTCL) = 0x0;
+			break;
+		case SIJETPCI:
+		case SIJETISA:
+			maddr = sc->sc_maddr;
+			((volatile struct si_reg *)maddr)->int_pending = 0;
+			*(maddr+SIJETINTCL) = 0x0;
 			break;
 		case SIEISA:
 #if NEISA > 0
--- sys/i386/isa/sireg.h.orig	Mon Nov 27 18:07:36 1995
+++ sys/i386/isa/sireg.h	Wed Feb  4 13:45:17 1998
@@ -56,10 +56,31 @@
 #define SIINTCL		0xA000			/* Clear host int */
 #define SIINTCL_CL 	0xE000			/* Clear host int */
 
+/* SI old PCI */
+#define SIPCIBADR	0x10			/* Which BADR to map in RAM */
+#define SIPCI_MEMSIZE	0x100000		/* Mapping size */
+#define SIPCIRESET	0xc0001			/* 0 = Reset */
+#define SIPCIINTCL	0x40001			/* 0 = clear int */
+
+/* SI Jet PCI */
+#define SIJETSSIDREG	0x2c			/* Is it a SI/XIO or RIO? */
+#define SIJETBADR	0x18			/* Which BADR to map in RAM */
+/* SI Jet PCI & ISA */
+#define SIJETIDBASE	0x7c00			/* ID ROM base */
+#define SISPLXID	0x984d			/* Specialix ID */
+#define SIUNIQID	0x7c0e			/* & 0xf0 = 0x20 for Si/XIO */
+#define SIJETRESET	0x7d00
+#define SIJETINTCL	0x7d80
+#define SIJETCONFIG	0x7c00			/* for ISA, top nibble = IRQ */
+#define SIJETBUSEN	0x2
+#define SIJETIRQEN	0x4
+
 /*
  * MEMSIZE is the total shared mem region
  * RAMSIZE is value to use when probing
  */
+#define SIJET_MEMSIZE		0x10000
+#define SIJET_RAMSIZE		0x7000
 #define	SIHOST_MEMSIZE		0x10000
 #define	SIHOST_RAMSIZE		0x8000
 #define	SIHOST2_MEMSIZE		0x8000
--- sys/i386/include/si.h.orig	Wed Feb  4 13:44:36 1998
+++ sys/i386/include/si.h	Wed Feb  4 13:46:22 1998
@@ -88,6 +88,10 @@
 #define	SI2		2
 #define	SIHOST2		3
 #define	SIEISA		4
+#define SIPCI		5
+#define SIJETPCI	6
+#define SIJETISA	7
+
 
 /* Buffer parameters */
 #define	SI_BUFFERSIZE	256
--- sys/i386/conf/files.i386.orig	Wed Feb  4 16:02:14 1998
+++ sys/i386/conf/files.i386	Wed Feb  4 13:48:23 1998
@@ -147,6 +147,7 @@
 i386/isa/seagate.c		optional	sea	device-driver
 i386/isa/si.c			optional	si	device-driver
 i386/isa/si_code.c		optional	si	device-driver
+i386/isa/si_jet.c		optional	si	device-driver
 i386/isa/sio.c			optional	sio	device-driver
 i386/isa/sound/dev_table.c	optional	snd	device-driver
 i386/isa/sound/soundcard.c	optional	snd	device-driver
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199802050017.QAA00642>