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>