Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 04 Feb 2000 21:38:41 +0100
From:      Gary Jennejohn <garyj@muc.de>
To:        freebsd-isdn@freebsd.org
Subject:   newbus-ified USR Sportster TA driver
Message-ID:  <200002042038.VAA02179@peedub.muc.de>

next in thread | raw e-mail | index | archive | help
OK, I have said driver for *FreeBSD-current* sort of working.

I say "sort of working", because the card I have has a defective
ISAC and I can't fully test the driver.

Probe and attach work OK and isdnd finds and tries to use the card. Except
for probe and attach the driver is pretty much the same as the old one, so
I expect it to work.

Those of you who have this card - PLEASE TEST !!!

Appended is the required patch. Change into /sys and apply it, generate
a new kernel and try it out.

Feedback is required so that Hellmuth can commit this thing.

================================= PATCH ==============================

--- isa/isavar.h.orig	Wed Feb  2 17:01:04 2000
+++ isa/isavar.h	Fri Feb  4 10:47:07 2000
@@ -49,7 +49,7 @@
 #define ISA_ORDER_SPECULATIVE	1 /* legacy non-sensitive hardware */
 #define ISA_ORDER_PNP		2 /* plug-and-play hardware */
 
-#define	ISA_NPORT	32
+#define	ISA_NPORT	50
 #define	ISA_NMEM	8
 #define	ISA_NIRQ	2
 #define	ISA_NDRQ	2
--- i4b/layer1/i4b_usr_sti.c.orig	Wed Feb  2 11:09:13 2000
+++ i4b/layer1/i4b_usr_sti.c	Fri Feb  4 10:51:38 2000
@@ -54,6 +54,10 @@
 #ifdef __FreeBSD__
 #include <machine/clock.h>
 #include <i386/isa/isa_device.h>
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
 #else
 #include <machine/bus.h>
 #include <sys/device.h>
@@ -92,92 +96,291 @@
 
 #ifdef __FreeBSD__
 
+/* prototypes */
+int isic_probe_usrtai __P((device_t));
+int isic_attach_usrtai __P((device_t));
+
 #define ADDR(reg)	\
 	(((reg/4) * 1024) + ((reg%4) * 2))
 
+#ifdef USRTA_DEBUG_PORTACCESS
+int debugcntr;
+#define USRTA_DEBUG(fmt) \
+		if (++debugcntr < 1000) printf fmt;
+#else
+#define USRTA_DEBUG(fmt)
+#endif
+
 /*---------------------------------------------------------------------------*
  *	USRobotics read fifo routine
  *---------------------------------------------------------------------------*/
 static void		
-usrtai_read_fifo(void *buf, const void *base, size_t len)
+usrtai_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
 {
 	register int offset = 0;
+	register unsigned int base = 0;
+
+USRTA_DEBUG(("usrtai_read_fifo: what %d size %d\n", what, size))
+	switch (what)
+	{
+		case ISIC_WHAT_ISAC:
+			base = (unsigned int)ISAC_BASE;
+			break;
+		case ISIC_WHAT_HSCXA:
+			base = (unsigned int)HSCX_A_BASE;
+			break;
+		case ISIC_WHAT_HSCXB:
+			base = (unsigned int)HSCX_B_BASE;
+			break;
+		default:
+			printf("usrtai_read_fifo: invalid what %d\n", what);
+			return;
+	}
 
-	for(;len > 0; len--, offset++)	
-		*((u_char *)buf + offset) = inb((int)base + ADDR(offset));
+	for(;size > 0; size--, offset++)	
+	{
+		*((u_char *)buf + offset) = inb(base + ADDR(offset));
+	}
 }
 
 /*---------------------------------------------------------------------------*
  *	USRobotics write fifo routine
  *---------------------------------------------------------------------------*/
 static void
-usrtai_write_fifo(void *base, const void *buf, size_t len)
+usrtai_write_fifo(struct l1_softc *sc, int what, void *data, size_t size)
 {
 	register int offset = 0;
+	register unsigned int base = 0;
+
+USRTA_DEBUG(("usrtai_write_fifo: what %d size %d\n", what, size))
+	switch (what)
+	{
+		case ISIC_WHAT_ISAC:
+			base = (unsigned int)ISAC_BASE;
+			break;
+		case ISIC_WHAT_HSCXA:
+			base = (unsigned int)HSCX_A_BASE;
+			break;
+		case ISIC_WHAT_HSCXB:
+			base = (unsigned int)HSCX_B_BASE;
+			break;
+		default:
+			printf("usrtai_write_fifo: invalid what %d\n", what);
+			return;
+	}
+
 	
-	for(;len > 0; len--, offset++)
-		outb((int)base + ADDR(offset), *((u_char *)buf + offset));
+	for(;size > 0; size--, offset++)
+	{
+		outb(base + ADDR(offset), *((u_char *)data + offset));
+	}
 }
 
 /*---------------------------------------------------------------------------*
  *	USRobotics write register routine
  *---------------------------------------------------------------------------*/
 static void
-usrtai_write_reg(u_char *base, u_int offset, u_int v)
+usrtai_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
 {
-	outb((int)base + ADDR(offset), (u_char)v);
+	register unsigned int base = 0;
+
+USRTA_DEBUG(("usrtai_write_reg: what %d ADDR(%d) %d data %#x\n", what, offs, ADDR(offs), data))
+	switch (what)
+	{
+		case ISIC_WHAT_ISAC:
+			base = (unsigned int)ISAC_BASE;
+			break;
+		case ISIC_WHAT_HSCXA:
+			base = (unsigned int)HSCX_A_BASE;
+			break;
+		case ISIC_WHAT_HSCXB:
+			base = (unsigned int)HSCX_B_BASE;
+			break;
+		default:
+			printf("usrtai_write_reg invalid what %d\n", what);
+			return;
+	}
+
+	outb(base + ADDR(offs), (u_char)data);
 }
 
 /*---------------------------------------------------------------------------*
  *	USRobotics read register routine
  *---------------------------------------------------------------------------*/
-static u_char
-usrtai_read_reg(u_char *base, u_int offset)
+static u_int8_t
+usrtai_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
 {
-	return(inb((int)base + ADDR(offset)));
+	register unsigned int base = 0;
+	u_int8_t byte;
+
+USRTA_DEBUG(("usrtai_read_reg: what %d ADDR(%d) %d..", what, offs, ADDR(offs)))
+	switch (what)
+	{
+		case ISIC_WHAT_ISAC:
+			base = (unsigned int)ISAC_BASE;
+			break;
+		case ISIC_WHAT_HSCXA:
+			base = (unsigned int)HSCX_A_BASE;
+			break;
+		case ISIC_WHAT_HSCXB:
+			base = (unsigned int)HSCX_B_BASE;
+			break;
+		default:
+			printf("usrtai_read_reg: invalid what %d\n", what);
+			return(0);
+	}
+
+	byte = inb(base + ADDR(offs));
+USRTA_DEBUG(("usrtai_read_reg: got %#x\n", byte))
+	return(byte);
+}
+
+/*---------------------------------------------------------------------------*
+ *	allocate an io port - based on code in isa_isic.c
+ *---------------------------------------------------------------------------*/
+static int
+usrtai_alloc_port(device_t dev)
+{ 
+	size_t unit = device_get_unit(dev);
+	struct l1_softc *sc = &l1_sc[unit];
+	int i, num = 0;
+	bus_size_t base;
+
+	/* 49 io mappings: 1 config and 48x8 registers */
+
+	/* config at offset 0x8000 */
+	base = sc->sc_port + 0x8000;
+	if (base < 0 || base > 0x0ffff)
+		return 1;
+	sc->sc_resources.io_rid[num] = num;
+
+	bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1);
+
+	if(!(sc->sc_resources.io_base[num] =
+		bus_alloc_resource(dev, SYS_RES_IOPORT,
+				   &sc->sc_resources.io_rid[num],
+				   0ul, ~0ul, 1, RF_ACTIVE)))
+	{
+		printf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base);
+		isic_detach_common(dev);
+		return(ENXIO);
+	}
+	num++;
+
+	/* HSCX A at offset 0 */
+	base = sc->sc_port;
+	for (i = 0; i < 16; i++) {
+		if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
+			return 1;
+		sc->sc_resources.io_rid[num] = num;
+
+		bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
+
+		if(!(sc->sc_resources.io_base[num] =
+			bus_alloc_resource(dev, SYS_RES_IOPORT,
+					   &sc->sc_resources.io_rid[num],
+					   0ul, ~0ul, 1, RF_ACTIVE)))
+		{
+			printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
+			isic_detach_common(dev);
+			return(ENXIO);
+		}
+		++num;
+	}
+
+	/* HSCX B at offset 0x4000 */
+	base = sc->sc_port + 0x4000;
+	for (i = 0; i < 16; i++) {
+		if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
+			return 1;
+		sc->sc_resources.io_rid[num] = num;
+
+		bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
+
+		if(!(sc->sc_resources.io_base[num] =
+			bus_alloc_resource(dev, SYS_RES_IOPORT,
+					   &sc->sc_resources.io_rid[num],
+					   0ul, ~0ul, 1, RF_ACTIVE)))
+		{
+			printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
+			isic_detach_common(dev);
+			return(ENXIO);
+		}
+		++num;
+	}
+
+	/* ISAC at offset 0xc000 */
+	base = sc->sc_port + 0xc000;
+	for (i = 0; i < 16; i++) {
+		if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
+			return 1;
+		sc->sc_resources.io_rid[num] = num;
+
+		bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
+
+		if(!(sc->sc_resources.io_base[num] =
+			bus_alloc_resource(dev, SYS_RES_IOPORT,
+					   &sc->sc_resources.io_rid[num],
+					   0ul, ~0ul, 1, RF_ACTIVE)))
+		{
+			printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
+			isic_detach_common(dev);
+			return(ENXIO);
+		}
+		++num;
+	}
+
+	return(0);
 }
 
 /*---------------------------------------------------------------------------*
  *	isic_probe_usrtai - probe for USR
  *---------------------------------------------------------------------------*/
 int
-isic_probe_usrtai(struct isa_device *dev)
+isic_probe_usrtai(device_t dev)
 {
-	struct isic_softc *sc = &isic_sc[dev->id_unit];
-	
-	/* check max unit range */
-	
-	if(dev->id_unit >= ISIC_MAXUNIT)
-	{
-		printf("isic%d: Error, unit %d >= MAXUNIT for USR Sportster TA!\n",
-				dev->id_unit, dev->id_unit);
-		return(0);	
-	}	
-	sc->sc_unit = dev->id_unit;
+	size_t unit = device_get_unit(dev);	/* get unit */
+	struct l1_softc *sc = 0;	/* pointer to softc */
+	void *ih = 0;			/* dummy */
 
-	/* check IRQ validity */
+	/* check max unit range */
 
-	if((intr_no[ffs(dev->id_irq) - 1]) == 0)
+	if(unit >= ISIC_MAXUNIT)
 	{
-		printf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n",
-			dev->id_unit, (ffs(dev->id_irq))-1);
-		return(0);
+		printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n",
+				unit, unit);
+		return(ENXIO);	
 	}
-	sc->sc_irq = dev->id_irq;
-
-	/* check if memory addr specified */
 
-	if(dev->id_maddr)
+	sc = &l1_sc[unit];			/* get pointer to softc */
+	sc->sc_unit = unit;			/* set unit */
+	sc->sc_flags = FLAG_USR_ISDN_TA_INT;	/* set flags */
+
+	/* see if an io base was supplied */
+	
+	if(!(sc->sc_resources.io_base[0] =
+			bus_alloc_resource(dev, SYS_RES_IOPORT,
+	                                   &sc->sc_resources.io_rid[0],
+	                                   0ul, ~0ul, 1, RF_ACTIVE)))
 	{
-		printf("isic%d: Error, mem addr 0x%lx specified for USR Sportster TA!\n",
-			dev->id_unit, (u_long)dev->id_maddr);
-		return(0);
+		printf("isic%d: Could not get iobase for USR Sportster TA!\n",
+				unit);
+		return(ENXIO);
 	}
-	dev->id_msize = 0;
+
+	/* set io base */
+
+	sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);
+	
+	/* release io base */
 	
+	bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
+		sc->sc_resources.io_base[0]);
+
+
 	/* check if we got an iobase */
 
-	switch(dev->id_iobase)
+	switch(sc->sc_port)
 	{
 		case 0x200:
 		case 0x208:
@@ -199,12 +402,49 @@
 			
 		default:
 			printf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n",
-				dev->id_unit, dev->id_iobase);
+				unit, sc->sc_port);
 			return(0);
 			break;
 	}
-	sc->sc_port = dev->id_iobase;
-	
+
+	/* allocate all the ports needed */
+
+	if(usrtai_alloc_port(dev))
+	{
+		printf("isic%d: Could not get the ports for USR Sportster TA!\n", unit);
+		isic_detach_common(dev);
+		return(ENXIO);
+	}
+
+	/* get our irq */
+
+	if(!(sc->sc_resources.irq =
+		bus_alloc_resource(dev, SYS_RES_IRQ,
+				   &sc->sc_resources.irq_rid,
+				   0ul, ~0ul, 1, RF_ACTIVE)))
+	{
+		printf("isic%d: Could not get an irq for USR Sportster TA!\n",unit);
+		isic_detach_common(dev);
+		return ENXIO;
+	}
+
+	/* get the irq number */
+	sc->sc_irq = rman_get_start(sc->sc_resources.irq);
+
+	/* register interrupt routine */
+	bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
+			(void(*)(void *))(isicintr),
+			sc, &ih);
+
+	/* check IRQ validity */
+
+	if(intr_no[sc->sc_irq] == 0)
+	{
+		printf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n",
+			unit, sc->sc_irq);
+		return(1);
+	}
+
 	/* setup ISAC access routines */
 
 	sc->clearirq = NULL;
@@ -227,9 +467,9 @@
 	
 	/* setup ISAC and HSCX base addr */
 	
-	ISAC_BASE   = (caddr_t)dev->id_iobase + USR_ISAC_OFF;
-	HSCX_A_BASE = (caddr_t)dev->id_iobase + USR_HSCXA_OFF;
-	HSCX_B_BASE = (caddr_t)dev->id_iobase + USR_HSCXB_OFF;
+	ISAC_BASE   = (caddr_t)sc->sc_port + USR_ISAC_OFF;
+	HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF;
+	HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF;
 
 	/* 
 	 * Read HSCX A/B VSTR.  Expected value for USR Sportster TA based
@@ -240,48 +480,52 @@
             ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
 	{
 		printf("isic%d: HSCX VSTR test failed for USR Sportster TA\n",
-			dev->id_unit);
+			unit);
 		printf("isic%d: HSC0: VSTR: %#x\n",
-			dev->id_unit, HSCX_READ(0, H_VSTR));
+			unit, HSCX_READ(0, H_VSTR));
 		printf("isic%d: HSC1: VSTR: %#x\n",
-			dev->id_unit, HSCX_READ(1, H_VSTR));
-		return (0);
+			unit, HSCX_READ(1, H_VSTR));
+		return (1);
 	}                   
 	
-	return (1);
+	return (0);
 }
 
 /*---------------------------------------------------------------------------*
  *	isic_attach_usrtai - attach USR
  *---------------------------------------------------------------------------*/
 int
-isic_attach_usrtai(struct isa_device *dev)
+isic_attach_usrtai(device_t dev)
 {
 	u_char irq = 0;
+	size_t unit = device_get_unit(dev);	/* get unit */
+	struct l1_softc *sc = 0;	/* pointer to softc */
 	
+	sc = &l1_sc[unit];			/* get pointer to softc */
+
 	/* reset the HSCX and ISAC chips */
 	
-	outb(dev->id_iobase + USR_INTL_OFF, USR_RES_BIT);
+	outb(sc->sc_port + USR_INTL_OFF, USR_RES_BIT);
 	DELAY(SEC_DELAY / 10);
 
-	outb(dev->id_iobase + USR_INTL_OFF, 0x00);
+	outb(sc->sc_port + USR_INTL_OFF, 0x00);
 	DELAY(SEC_DELAY / 10);
 
 	/* setup IRQ */
 
-	if((irq = intr_no[ffs(dev->id_irq) - 1]) == 0)
+	if((irq = intr_no[sc->sc_irq]) == 0)
 	{
 		printf("isic%d: Attach error, invalid IRQ [%d] specified for USR Sportster TA!\n",
-			dev->id_unit, ffs(dev->id_irq)-1);
-		return(0);
+			unit, sc->sc_irq);
+		return(1);
 	}
 
 	/* configure and enable irq */
 
-	outb(dev->id_iobase + USR_INTL_OFF, irq | USR_INTE_BIT);
+	outb(sc->sc_port + USR_INTL_OFF, irq | USR_INTE_BIT);
 	DELAY(SEC_DELAY / 10);
 
-	return (1);
+	return (0);
 }
 
 #else /* end of FreeBSD, start NetBSD */
--- conf/files.i386.orig	Fri Feb  4 21:28:22 2000
+++ conf/files.i386	Fri Feb  4 21:28:34 2000
@@ -383,7 +383,7 @@
 i4b/layer1/i4b_tel_s016.c	optional	isic
 i4b/layer1/i4b_tel_s0163.c	optional	isic
 i4b/layer1/i4b_tel_s08.c	optional	isic
-#i4b/layer1/i4b_usr_sti.c	optional	isic
+i4b/layer1/i4b_usr_sti.c	optional	isic
 isa/atkbd_isa.c			optional	atkbd
 isa/atkbdc_isa.c		optional	atkbdc
 isa/ppc.c			optional	ppc

--------
Gary Jennejohn / garyj@muc.de garyj@fkr.cpqcorp.net gj@freebsd.org




To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-isdn" in the body of the message




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