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>
