Subject: DIO patches
To: None <port-hp300@netbsd.org>
From: Gregory McGarry <g.mcgarry@ieee.org>
List: port-hp300
Date: 05/20/2003 18:45:35
--cNdxnHkX5QqsyA0e
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

There's a hack in the DIO code which allows the nhpib driver to attach
to an internal controller and a controller on DIO.  This appears to be
a leftover from 4.3BSD where it was not possible to have a driver
attach to different busses.  Of course, NetBSD has supported
bus-dependent attachments for a long time.

The first step to getting this fixed was to separate the DMA support
from the DIO bus.  That was committed some months ago.  Here's the
remaining patch which provides dio- and intio-specified bus
attachments for nhpib.  It also removes the ugly hack from dio.c.

	-- Gregory McGarry <g.mcgarry@ieee.org>

--cNdxnHkX5QqsyA0e
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="dio.diff"

Index: conf/GENERIC
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/conf/GENERIC,v
retrieving revision 1.92
diff -u -b -p -r1.92 GENERIC
--- conf/GENERIC	2003/04/26 14:10:12	1.92
+++ conf/GENERIC	2003/05/20 06:31:02
@@ -168,6 +168,7 @@ hil*		at intio?		# Human Interface Loop
 options 	UK_KEYBOARD		# include United Kingdom HIL keymap
 options 	SE_KEYBOARD		# include Swedish HIL keymap
 frodo*		at intio?		# Frodo utility chip found on 4xx's
+nhpib*		at intio?		# slow internal HP-IB
 
 # 8250-like serial ports found on Frodo ASIC
 #dnkbd0		at frodo? offset 0x0	# Domain keyboard flavor
Index: conf/files.hp300
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/conf/files.hp300,v
retrieving revision 1.64
diff -u -b -p -r1.64 files.hp300
--- conf/files.hp300	2003/03/06 18:28:52	1.64
+++ conf/files.hp300	2003/05/20 06:31:02
@@ -136,7 +136,8 @@ file	arch/hp300/dev/if_le.c		le
 define	hpibdev { }
 
 device	nhpib: hpibdev
-attach	nhpib at dio
+attach	nhpib at intio with nhpib_dio
+attach	nhpib at dio with nhpib_intio
 file	arch/hp300/dev/nhpib.c		nhpib
 
 device	fhpib: hpibdev
Index: dev/dca.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/dca.c,v
retrieving revision 1.54
diff -u -b -p -r1.54 dca.c
--- dev/dca.c	2003/03/06 18:24:52	1.54
+++ dev/dca.c	2003/05/20 06:31:03
@@ -101,14 +101,10 @@ __KERNEL_RCSID(0, "$NetBSD: dca.c,v 1.54
 #include <sys/syslog.h>
 #include <sys/device.h>
 
-#include <machine/autoconf.h>
 #include <machine/bus.h>
-#include <machine/cpu.h>
-#include <machine/intr.h>
 
 #include <dev/cons.h>
 
-#include <hp300/dev/dioreg.h>
 #include <hp300/dev/diovar.h>
 #include <hp300/dev/diodevs.h>
 #include <hp300/dev/dcareg.h>
@@ -120,6 +116,9 @@ struct	dca_softc {
 	int			sc_oflows;	/* overflow counter */
 	short			sc_flags;	/* state flags */
 
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+
 	/*
 	 * Bits for sc_flags.
 	 */
@@ -255,7 +254,6 @@ dcaattach(parent, self, aux)
 	struct dcadevice *dca;
 	int unit = self->dv_unit;
 	int scode = da->da_scode;
-	int ipl;
 
 	if (scode == dcaconscode) {
 		dca = dca_cn;
@@ -269,20 +267,21 @@ dcaattach(parent, self, aux)
 		cn_tab->cn_dev = makedev(cdevsw_lookup_major(&dca_cdevsw),
 					 unit);
 	} else {
-		dca = (struct dcadevice *)iomap(dio_scodetopa(da->da_scode),
-		    da->da_size);
-		if (dca == NULL) {
+
+		sc->sc_bst = da->da_bst;
+		if (bus_space_map(da->da_bst, da->da_addr, da->da_size,
+		     BUS_SPACE_MAP_LINEAR, &sc->sc_bsh)) {
 			printf("\n%s: can't map registers\n",
 			    sc->sc_dev.dv_xname);
 			return;
 		}
+		dca = (struct dcadevice *)bus_space_vaddr(sc->sc_bst,
+		    sc->sc_bsh);
+
 	}
 
 	sc->sc_dca = dca;
 
-	ipl = DIO_IPL(dca);
-	printf(" ipl %d", ipl);
-
 	DELAY(1000);
 	dca->dca_reset = 0xFF;
 	DELAY(1000);
@@ -294,7 +293,7 @@ dcaattach(parent, self, aux)
 		sc->sc_flags |= DCA_HASFIFO;
 
 	/* Establish interrupt handler. */
-	(void) dio_intr_establish(dcaintr, sc, ipl,
+	(void) dio_intr_establish(dcaintr, sc, da->da_ipl,
 	    (sc->sc_flags & DCA_HASFIFO) ? IPL_TTY : IPL_TTYNOBUF);
 
 	sc->sc_flags |= DCA_ACTIVE;
Index: dev/dcm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/dcm.c,v
retrieving revision 1.58
diff -u -b -p -r1.58 dcm.c
--- dev/dcm.c	2003/05/04 02:10:07	1.58
+++ dev/dcm.c	2003/05/20 06:31:03
@@ -106,13 +106,10 @@ __KERNEL_RCSID(0, "$NetBSD: dcm.c,v 1.58
 #include <sys/time.h>
 #include <sys/device.h>
 
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-#include <machine/intr.h>
+#include <machine/bus.h>
 
 #include <dev/cons.h>
 
-#include <hp300/dev/dioreg.h>
 #include <hp300/dev/diovar.h>
 #include <hp300/dev/diodevs.h>
 #include <hp300/dev/dcmreg.h>
@@ -249,6 +246,10 @@ static char iconv[16] = {
 
 struct	dcm_softc {
 	struct	device sc_dev;		/* generic device glue */
+
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+
 	struct	dcmdevice *sc_dcm;	/* pointer to hardware */
 	struct	tty *sc_tty[NDCMPORT];	/* our tty instances */
 	struct	modemreg *sc_modem[NDCMPORT]; /* modem control */
@@ -368,7 +369,7 @@ dcmattach(parent, self, aux)
 	struct dcmdevice *dcm;
 	int brd = self->dv_unit;
 	int scode = da->da_scode;
-	int i, mbits, code, ipl;
+	int i, mbits, code;
 
 	sc->sc_flags = 0;
 
@@ -384,20 +385,19 @@ dcmattach(parent, self, aux)
 		cn_tab->cn_dev = makedev(cdevsw_lookup_major(&dcm_cdevsw),
 					 (brd << 2) | DCMCONSPORT);
 	} else {
-		dcm = (struct dcmdevice *)iomap(dio_scodetopa(da->da_scode),
-		    da->da_size);
-		if (dcm == NULL) {
+		sc->sc_bst = da->da_bst;
+		if (bus_space_map(sc->sc_bst, da->da_addr, da->da_size,
+		    BUS_SPACE_MAP_LINEAR, &sc->sc_bsh)) {
 			printf("\n%s: can't map registers\n",
 			    sc->sc_dev.dv_xname);
 			return;
 		}
+		dcm = (struct dcmdevice *)bus_space_vaddr(sc->sc_bst,
+		    sc->sc_bsh);
 	}
 
 	sc->sc_dcm = dcm;
 
-	ipl = DIO_IPL(dcm);
-	printf(" ipl %d", ipl);
-
 	/*
 	 * XXX someone _should_ fix this; the self test screws
 	 * autoconfig messages.
@@ -415,7 +415,7 @@ dcmattach(parent, self, aux)
 	sc->sc_flags |= DCM_ACTIVE;
 
 	/* Establish the interrupt handler. */
-	(void) dio_intr_establish(dcmintr, sc, ipl, IPL_TTY);
+	(void) dio_intr_establish(dcmintr, sc, da->da_ipl, IPL_TTY);
 
 	if (dcmistype == DIS_TIMER)
 		dcmsetischeme(brd, DIS_RESET|DIS_TIMER);
Index: dev/dio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/dio.c,v
retrieving revision 1.22
diff -u -b -p -r1.22 dio.c
--- dev/dio.c	2003/04/01 20:41:36	1.22
+++ dev/dio.c	2003/05/20 06:31:03
@@ -50,6 +50,8 @@ __KERNEL_RCSID(0, "$NetBSD: dio.c,v 1.22
 #include <sys/kernel.h>
 #include <sys/device.h>
 
+#include <machine/bus.h>
+
 #include <uvm/uvm_extern.h>
 
 #include <machine/autoconf.h>
@@ -63,10 +65,12 @@ __KERNEL_RCSID(0, "$NetBSD: dio.c,v 1.22
 
 #include <hp300/dev/diodevs.h>
 #include <hp300/dev/diodevs_data.h>
+
+#include "locators.h"
+#define        diocf_scode             cf_loc[DIOCF_SCODE]
 
-extern	caddr_t internalhpib;
 
-int	dio_scodesize __P((struct dio_attach_args *));
+static int	dio_scodesize __P((struct dio_attach_args *));
 char	*dio_devinfo __P((struct dio_attach_args *, char *, size_t));
 
 int	diomatch __P((struct device *, struct cfdata *, void *));
@@ -100,7 +104,7 @@ dioattach(parent, self, aux)
 {
 	struct dio_attach_args da;
 	caddr_t pa, va;
-	int scode, scmax, didmap, scodesize;
+	int scode, scmax, scodesize;
 
 	printf("\n");
 
@@ -112,17 +116,11 @@ dioattach(parent, self, aux)
 			continue;
 		}
 
-		didmap = 0;
-
 		/*
 		 * Temporarily map the space corresponding to
 		 * the current select code unless:
-		 *	- this is the internal hpib select code,
 		 */
 		pa = dio_scodetopa(scode);
-		if ((scode == 7) && internalhpib)
-			va = internalhpib = (caddr_t)IIOV(pa);
-		else {
 			va = iomap(pa, PAGE_SIZE);
 			if (va == NULL) {
 				printf("%s: can't map scode %d\n",
@@ -130,12 +128,9 @@ dioattach(parent, self, aux)
 				scode++;
 				continue;
 			}
-			didmap = 1;
-		}
 
 		/* Check for hardware. */
 		if (badaddr(va)) {
-			if (didmap)
 				iounmap(va, PAGE_SIZE);
 			scode++;
 			continue;
@@ -145,25 +140,18 @@ dioattach(parent, self, aux)
 		memset(&da, 0, sizeof(da));
 		da.da_bst = HP300_BUS_SPACE_DIO;
 		da.da_scode = scode;
-		/*
-		 * Internal HP-IB doesn't always return a device ID,
-		 * so we rely on the sysflags.
-		 */
-		if ((scode == 7) && internalhpib)
-			da.da_id = DIO_DEVICE_ID_IHPIB;
-		else
-			da.da_id = DIO_ID(va);
 
+		da.da_id = DIO_ID(va);
 		if (DIO_ISFRAMEBUFFER(da.da_id))
 			da.da_secid = DIO_SECID(va);
-
+		da.da_addr = (bus_addr_t)dio_scodetopa(scode);
 		da.da_size = DIO_SIZE(scode, va);
 		scodesize = dio_scodesize(&da);
 		if (DIO_ISDIO(scode))
 			da.da_size *= scodesize;
+		da.da_ipl = DIO_IPL(va);
 
 		/* No longer need the device to be mapped. */
-		if (didmap)
 			iounmap(va, PAGE_SIZE);
 
 		/* Attach matching device. */
@@ -198,7 +186,7 @@ dioprint(aux, pnp)
 	if (pnp)
 		aprint_normal("%s at %s",
 		    dio_devinfo(da, buf, sizeof(buf)), pnp);
-	aprint_normal(" scode %d", da->da_scode);
+	aprint_normal(" scode %d ipl %d", da->da_scode, da->da_ipl);
 	return (UNCONF);
 }
 
@@ -211,9 +199,7 @@ dio_scodetopa(scode)
 {
 	u_long rval;
 
-	if (scode == 7 && internalhpib)
-		rval = DIO_IHPIBADDR;
-	else if (DIO_ISDIO(scode))
+	if (DIO_ISDIO(scode))
 		rval = DIO_BASE + (scode * DIO_DEVSIZE);
 	else if (DIO_ISDIOII(scode))
 		rval = DIOII_BASE + ((scode - DIOII_SCBASE) * DIOII_DEVSIZE);
@@ -227,20 +213,13 @@ dio_scodetopa(scode)
  * Return the select code size for this device, defaulting to 1
  * if we don't know what kind of device we have.
  */
-int
+static int
 dio_scodesize(da)
 	struct dio_attach_args *da;
 {
 	int i;
 
 	/*
-	 * Deal with lame internal HP-IB controllers which don't have
-	 * consistent/reliable device ids.
-	 */
-	if (da->da_scode == 7 && internalhpib)
-		return (1);
-
-	/*
 	 * Find the dio_devdata matchind the primary id.
 	 * If we're a framebuffer, we also check the secondary id.
 	 */
@@ -279,15 +258,6 @@ dio_devinfo(da, buf, buflen)
 #endif
 
 	memset(buf, 0, buflen);
-
-	/*
-	 * Deal with lame internal HP-IB controllers which don't have
-	 * consistent/reliable device ids.
-	 */
-	if (da->da_scode == 7 && internalhpib) {
-		sprintf(buf, DIO_DEVICE_DESC_IHPIB);
-		return (buf);
-	}
 
 #ifdef DIOVERBOSE
 	/*
Index: dev/diovar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/diovar.h,v
retrieving revision 1.7
diff -u -b -p -r1.7 diovar.h
--- dev/diovar.h	1998/01/11 21:53:05	1.7
+++ dev/diovar.h	2003/05/20 06:31:03
@@ -48,7 +48,9 @@
 struct dio_attach_args {
 	bus_space_tag_t da_bst;		/* bus space tag */
 	int	da_scode;		/* select code */
+	int	da_addr;		/* device address */
 	int	da_size;		/* size of address space */
+	int	da_ipl;			/* interrupt priority level */
 	u_int8_t da_id;			/* primary device id */
 	u_int8_t da_secid;		/* secondary device id */
 };
@@ -72,9 +74,6 @@ struct dio_devdesc {
 	u_int8_t dd_secid;		/* secondary device id */
 	const char *dd_desc;		/* description */
 };
-
-#include "locators.h"
-#define	diocf_scode		cf_loc[DIOCF_SCODE]
 
 #ifdef _KERNEL
 void	*dio_scodetopa __P((int));
Index: dev/intio.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/intio.c,v
retrieving revision 1.14
diff -u -b -p -r1.14 intio.c
--- dev/intio.c	2003/01/01 01:34:46	1.14
+++ dev/intio.c	2003/05/20 06:31:04
@@ -65,6 +65,7 @@ CFATTACH_DECL(intio, sizeof(struct devic
 const struct intio_builtins intio_3xx_builtins[] = {
 	{ "rtc",	0x020000,	-1},
 	{ "hil",	0x028000,	1},
+	{ "hpib",	0x078000,	3},
 	{ "dma",	0x100000,	1},
 	{ "fb",		0x160000,	-1},
 };
@@ -77,6 +78,7 @@ const struct intio_builtins intio_4xx_bu
 	{ "rtc",	0x020000,	-1},
 	{ "frodo",	0x01c000,	5},
 	{ "hil",	0x028000,	1},
+	{ "hpib",	0x078000,	3},
 	{ "dma",	0x100000,	1},
 };
 #define nintio_4xx_builtins \
@@ -84,6 +86,7 @@ const struct intio_builtins intio_4xx_bu
 #endif
 
 static int intio_matched = 0;
+extern caddr_t internalhpib;
 
 int
 intiomatch(parent, match, aux)
@@ -144,6 +147,14 @@ intioattach(parent, self, aux)
 	memset(&ia, 0, sizeof(ia));
 
 	for (i=0; i<ndevs; i++) {
+
+		/*
+		 * Internal HP-IB doesn't always return a device ID,
+		 * so we rely on the sysflags.
+		 */
+		if (ib[i].ib_offset == 0x078000 && !internalhpib)
+			continue;
+
 		strncpy(ia.ia_modname, ib[i].ib_modname, INTIO_MOD_LEN);
 		ia.ia_modname[INTIO_MOD_LEN] = '\0';
 		ia.ia_bst = HP300_BUS_SPACE_INTIO;
Index: dev/nhpib.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/nhpib.c,v
retrieving revision 1.26
diff -u -b -p -r1.26 nhpib.c
--- dev/nhpib.c	2002/10/02 05:15:53	1.26
+++ dev/nhpib.c	2003/05/20 06:31:05
@@ -85,13 +85,11 @@ __KERNEL_RCSID(0, "$NetBSD: nhpib.c,v 1.
 #include <sys/buf.h>
 #include <sys/device.h>
 
-#include <machine/autoconf.h>
-#include <machine/intr.h>
+#include <machine/bus.h>
 
-#include <hp300/dev/dioreg.h>
+#include <hp300/dev/intiovar.h>
 #include <hp300/dev/diovar.h>
 #include <hp300/dev/diodevs.h>
-
 #include <hp300/dev/dmavar.h>
 
 #include <hp300/dev/nhpibreg.h>
@@ -149,75 +147,129 @@ struct	hpib_controller nhpib_controller 
 
 struct nhpib_softc {
 	struct device sc_dev;		/* generic device glue */
+
+	bus_space_tag_t sc_bst;
+	bus_space_handle_t sc_bsh;
+
 	struct nhpibdevice *sc_regs;	/* device registers */
 	struct hpibbus_softc *sc_hpibbus; /* XXX */
+
+	int sc_myaddr;
+	int sc_type;
+
 	struct callout sc_read_ch;
 	struct callout sc_ppwatch_ch;
 };
+
+int	nhpib_dio_match __P((struct device *, struct cfdata *, void *));
+void	nhpib_dio_attach __P((struct device *, struct device *, void *));
+int	nhpib_intio_match __P((struct device *, struct cfdata *, void *));
+void	nhpib_intio_attach __P((struct device *, struct device *, void *));
+
+void	nhpib_common_attach(struct nhpib_softc *, const char *);
+
+CFATTACH_DECL(nhpib_dio, sizeof(struct nhpib_softc),
+    nhpib_dio_match, nhpib_dio_attach, NULL, NULL);
+
+CFATTACH_DECL(nhpib_intio, sizeof(struct nhpib_softc),
+    nhpib_intio_match, nhpib_intio_attach, NULL, NULL);
+
+int
+nhpib_intio_match(parent, match, aux)
+	struct device *parent;
+	struct cfdata *match;
+	void *aux;
+{
+	struct intio_attach_args *ia = aux;
 
-int	nhpibmatch __P((struct device *, struct cfdata *, void *));
-void	nhpibattach __P((struct device *, struct device *, void *));
+	if (strcmp("hpib", ia->ia_modname) == 0)
+		return (1);
 
-CFATTACH_DECL(nhpib, sizeof(struct nhpib_softc),
-    nhpibmatch, nhpibattach, NULL, NULL);
+	return (0);
+}
 
 int
-nhpibmatch(parent, match, aux)
+nhpib_dio_match(parent, match, aux)
 	struct device *parent;
 	struct cfdata *match;
 	void *aux;
 {
 	struct dio_attach_args *da = aux;
 
-	if (da->da_id == DIO_DEVICE_ID_NHPIB ||
-	    da->da_id == DIO_DEVICE_ID_IHPIB)
+	if (da->da_id == DIO_DEVICE_ID_NHPIB)
 		return (1);
 
 	return (0);
 }
 
 void
-nhpibattach(parent, self, aux)
+nhpib_intio_attach(parent, self, aux)
 	struct device *parent, *self;
 	void *aux;
 {
 	struct nhpib_softc *sc = (struct nhpib_softc *)self;
+	struct intio_attach_args *ia = aux;
+	const char *desc = "internal HP-IB";
+
+	sc->sc_bst = ia->ia_bst;
+	if (bus_space_map(ia->ia_bst, ia->ia_iobase, INTIO_DEVSIZE, 0,
+	    &sc->sc_bsh)) {
+		printf("%s: can't map registers\n", sc->sc_dev.dv_xname);
+		return;
+	}
+
+	sc->sc_myaddr = -1;
+	sc->sc_type = HPIBA;
+
+	nhpib_common_attach(sc, desc);
+
+	/* establish the interrupt handler */
+	(void) intio_intr_establish(nhpibintr, sc, ia->ia_ipl, IPL_BIO);
+}
+
+void
+nhpib_dio_attach(parent, self, aux)
+	struct device *parent, *self;
+	void *aux;
+{
+	struct nhpib_softc *sc = (struct nhpib_softc *)self;
 	struct dio_attach_args *da = aux;
-	struct hpibdev_attach_args ha; 
-	const char *desc;
-	int ipl, type = HPIBA;
+	const char *desc = DIO_DEVICE_DESC_NHPIB;
 
-	sc->sc_regs = (struct nhpibdevice *)iomap(dio_scodetopa(da->da_scode),
-	    da->da_size);
-	if (sc->sc_regs == NULL) {
-		printf("\n%s: can't map registers\n", self->dv_xname);
+	sc->sc_bst = da->da_bst;
+	if (bus_space_map(sc->sc_bst, da->da_addr, da->da_size, 0,
+	    &sc->sc_bsh)) {
+		printf("\n%s: can't map registers\n", sc->sc_dev.dv_xname);
 		return;
 	}
 
-	ipl = DIO_IPL(sc->sc_regs);
+	/* read address off switches */
+	sc->sc_myaddr = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 5);
+	sc->sc_type = HPIBB;
 
-	if (da->da_scode == 7 && internalhpib)
-		desc = DIO_DEVICE_DESC_IHPIB;
-	else if (da->da_id == DIO_DEVICE_ID_NHPIB) {
-		type = HPIBB;
-		desc = DIO_DEVICE_DESC_NHPIB;
-	} else
-		desc = "unknown HP-IB!";
+	nhpib_common_attach(sc, desc);
+
+	/* establish the interrupt handler */
+	(void)dio_intr_establish(nhpibintr, sc, da->da_ipl, IPL_BIO);
+}
 
-	printf(" ipl %d: %s\n", ipl, desc);
+void
+nhpib_common_attach(sc, desc)
+	struct nhpib_softc *sc;
+	const char *desc;
+{
+	struct hpibdev_attach_args ha; 
 
-	/* Establish the interrupt handler. */
-	(void) dio_intr_establish(nhpibintr, sc, ipl, IPL_BIO);
+	sc->sc_regs = bus_space_vaddr(sc->sc_bst, sc->sc_bsh);
 
 	callout_init(&sc->sc_read_ch);
 	callout_init(&sc->sc_ppwatch_ch);
 
 	ha.ha_ops = &nhpib_controller;
-	ha.ha_type = type;			/* XXX */
-	ha.ha_ba = (type == HPIBA) ? HPIBA_BA :
-	    (sc->sc_regs->hpib_csa & CSA_BA);
+	ha.ha_type = sc->sc_type;			/* XXX */
+	ha.ha_ba = sc->sc_myaddr;
 	ha.ha_softcpp = &sc->sc_hpibbus;	/* XXX */
-	(void)config_found(self, &ha, hpibdevprint);
+	(void)config_found((void *)sc, &ha, hpibdevprint);
 }
 
 void

--cNdxnHkX5QqsyA0e--