2 * Copyright (c) 1997, 2001 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 *---------------------------------------------------------------------------
27 * i4b_usr_sti.c - USRobotics Sportster ISDN TA intern (Tina-pp)
28 * -------------------------------------------------------------
30 * $FreeBSD: src/sys/i4b/layer1/isic/i4b_usr_sti.c,v 1.5.2.1 2001/08/10 14:08:39 obrien Exp $
32 * last edit-date: [Wed Jan 24 09:28:12 2001]
34 *---------------------------------------------------------------------------*/
39 #if (NISIC > 0) && defined(USR_STI)
41 #include <sys/param.h>
42 #include <sys/systm.h>
44 #include <machine/bus.h>
47 #include <sys/socket.h>
50 #include <machine/i4b_ioctl.h>
51 #include <machine/i4b_trace.h>
53 #include <i4b/layer1/i4b_l1.h>
54 #include <i4b/layer1/isic/i4b_isic.h>
55 #include <i4b/layer1/isic/i4b_hscx.h>
57 /*---------------------------------------------------------------------------*
58 * USR Sportster TA intern special registers
59 *---------------------------------------------------------------------------*/
60 #define USR_HSCXA_OFF 0x0000
61 #define USR_HSCXB_OFF 0x4000
62 #define USR_INTL_OFF 0x8000
63 #define USR_ISAC_OFF 0xc000
65 #define USR_RES_BIT 0x80 /* 0 = normal, 1 = reset ISAC/HSCX */
66 #define USR_INTE_BIT 0x40 /* 0 = IRQ disabled, 1 = IRQ's enabled */
67 #define USR_IL_MASK 0x07 /* IRQ level config */
69 static u_char intr_no[] = { 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 3, 4, 5, 0, 6, 7 };
72 (((reg/4) * 1024) + ((reg%4) * 2))
74 #ifdef USRTA_DEBUG_PORTACCESS
76 #define USRTA_DEBUG(fmt) \
77 if (++debugcntr < 1000) printf fmt;
79 #define USRTA_DEBUG(fmt)
82 /*---------------------------------------------------------------------------*
83 * USRobotics read fifo routine
84 *---------------------------------------------------------------------------*/
86 usrtai_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
88 register int offset = 0;
89 register unsigned int base = 0;
91 USRTA_DEBUG(("usrtai_read_fifo: what %d size %d\n", what, size))
95 base = (unsigned int)ISAC_BASE;
98 base = (unsigned int)HSCX_A_BASE;
100 case ISIC_WHAT_HSCXB:
101 base = (unsigned int)HSCX_B_BASE;
104 printf("usrtai_read_fifo: invalid what %d\n", what);
108 for(;size > 0; size--, offset++)
110 *((u_char *)buf + offset) = inb(base + ADDR(offset));
114 /*---------------------------------------------------------------------------*
115 * USRobotics write fifo routine
116 *---------------------------------------------------------------------------*/
118 usrtai_write_fifo(struct l1_softc *sc, int what, void *data, size_t size)
120 register int offset = 0;
121 register unsigned int base = 0;
123 USRTA_DEBUG(("usrtai_write_fifo: what %d size %d\n", what, size))
127 base = (unsigned int)ISAC_BASE;
129 case ISIC_WHAT_HSCXA:
130 base = (unsigned int)HSCX_A_BASE;
132 case ISIC_WHAT_HSCXB:
133 base = (unsigned int)HSCX_B_BASE;
136 printf("usrtai_write_fifo: invalid what %d\n", what);
141 for(;size > 0; size--, offset++)
143 outb(base + ADDR(offset), *((u_char *)data + offset));
147 /*---------------------------------------------------------------------------*
148 * USRobotics write register routine
149 *---------------------------------------------------------------------------*/
151 usrtai_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
153 register unsigned int base = 0;
155 USRTA_DEBUG(("usrtai_write_reg: what %d ADDR(%d) %d data %#x\n", what, offs, ADDR(offs), data))
159 base = (unsigned int)ISAC_BASE;
161 case ISIC_WHAT_HSCXA:
162 base = (unsigned int)HSCX_A_BASE;
164 case ISIC_WHAT_HSCXB:
165 base = (unsigned int)HSCX_B_BASE;
168 printf("usrtai_write_reg invalid what %d\n", what);
172 outb(base + ADDR(offs), (u_char)data);
175 /*---------------------------------------------------------------------------*
176 * USRobotics read register routine
177 *---------------------------------------------------------------------------*/
179 usrtai_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
181 register unsigned int base = 0;
184 USRTA_DEBUG(("usrtai_read_reg: what %d ADDR(%d) %d..", what, offs, ADDR(offs)))
188 base = (unsigned int)ISAC_BASE;
190 case ISIC_WHAT_HSCXA:
191 base = (unsigned int)HSCX_A_BASE;
193 case ISIC_WHAT_HSCXB:
194 base = (unsigned int)HSCX_B_BASE;
197 printf("usrtai_read_reg: invalid what %d\n", what);
201 byte = inb(base + ADDR(offs));
202 USRTA_DEBUG(("usrtai_read_reg: got %#x\n", byte))
206 /*---------------------------------------------------------------------------*
207 * allocate an io port - based on code in isa_isic.c
208 *---------------------------------------------------------------------------*/
210 usrtai_alloc_port(device_t dev)
212 size_t unit = device_get_unit(dev);
213 struct l1_softc *sc = &l1_sc[unit];
217 /* 49 io mappings: 1 config and 48x8 registers */
219 /* config at offset 0x8000 */
220 base = sc->sc_port + 0x8000;
221 if (base < 0 || base > 0x0ffff)
223 sc->sc_resources.io_rid[num] = num;
225 bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1);
227 if(!(sc->sc_resources.io_base[num] =
228 bus_alloc_resource(dev, SYS_RES_IOPORT,
229 &sc->sc_resources.io_rid[num],
230 0ul, ~0ul, 1, RF_ACTIVE)))
232 printf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base);
233 isic_detach_common(dev);
238 /* HSCX A at offset 0 */
240 for (i = 0; i < 16; i++) {
241 if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
243 sc->sc_resources.io_rid[num] = num;
245 bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
247 if(!(sc->sc_resources.io_base[num] =
248 bus_alloc_resource(dev, SYS_RES_IOPORT,
249 &sc->sc_resources.io_rid[num],
250 0ul, ~0ul, 1, RF_ACTIVE)))
252 printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
253 isic_detach_common(dev);
259 /* HSCX B at offset 0x4000 */
260 base = sc->sc_port + 0x4000;
261 for (i = 0; i < 16; i++) {
262 if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
264 sc->sc_resources.io_rid[num] = num;
266 bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
268 if(!(sc->sc_resources.io_base[num] =
269 bus_alloc_resource(dev, SYS_RES_IOPORT,
270 &sc->sc_resources.io_rid[num],
271 0ul, ~0ul, 1, RF_ACTIVE)))
273 printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
274 isic_detach_common(dev);
280 /* ISAC at offset 0xc000 */
281 base = sc->sc_port + 0xc000;
282 for (i = 0; i < 16; i++) {
283 if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
285 sc->sc_resources.io_rid[num] = num;
287 bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
289 if(!(sc->sc_resources.io_base[num] =
290 bus_alloc_resource(dev, SYS_RES_IOPORT,
291 &sc->sc_resources.io_rid[num],
292 0ul, ~0ul, 1, RF_ACTIVE)))
294 printf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
295 isic_detach_common(dev);
304 /*---------------------------------------------------------------------------*
305 * isic_probe_usrtai - probe for USR
306 *---------------------------------------------------------------------------*/
308 isic_probe_usrtai(device_t dev)
310 size_t unit = device_get_unit(dev); /* get unit */
311 struct l1_softc *sc = 0; /* pointer to softc */
312 void *ih = 0; /* dummy */
314 /* check max unit range */
316 if(unit >= ISIC_MAXUNIT)
318 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n",
323 sc = &l1_sc[unit]; /* get pointer to softc */
324 sc->sc_unit = unit; /* set unit */
326 /* see if an io base was supplied */
328 if(!(sc->sc_resources.io_base[0] =
329 bus_alloc_resource(dev, SYS_RES_IOPORT,
330 &sc->sc_resources.io_rid[0],
331 0ul, ~0ul, 1, RF_ACTIVE)))
333 printf("isic%d: Could not get iobase for USR Sportster TA!\n",
340 sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);
342 /* release io base */
344 bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
345 sc->sc_resources.io_base[0]);
348 /* check if we got an iobase */
371 printf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n",
377 /* allocate all the ports needed */
379 if(usrtai_alloc_port(dev))
381 printf("isic%d: Could not get the ports for USR Sportster TA!\n", unit);
382 isic_detach_common(dev);
388 if(!(sc->sc_resources.irq =
389 bus_alloc_resource(dev, SYS_RES_IRQ,
390 &sc->sc_resources.irq_rid,
391 0ul, ~0ul, 1, RF_ACTIVE)))
393 printf("isic%d: Could not get an irq for USR Sportster TA!\n",unit);
394 isic_detach_common(dev);
398 /* get the irq number */
399 sc->sc_irq = rman_get_start(sc->sc_resources.irq);
401 /* register interrupt routine */
402 bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
403 (void(*)(void *))(isicintr),
406 /* check IRQ validity */
408 if(intr_no[sc->sc_irq] == 0)
410 printf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n",
415 /* setup ISAC access routines */
418 sc->readreg = usrtai_read_reg;
419 sc->writereg = usrtai_write_reg;
421 sc->readfifo = usrtai_read_fifo;
422 sc->writefifo = usrtai_write_fifo;
424 /* setup card type */
426 sc->sc_cardtyp = CARD_TYPEP_USRTA;
428 /* setup IOM bus type */
430 sc->sc_bustyp = BUS_TYPE_IOM2;
433 sc->sc_bfifolen = HSCX_FIFO_LEN;
435 /* setup ISAC and HSCX base addr */
437 ISAC_BASE = (caddr_t)sc->sc_port + USR_ISAC_OFF;
438 HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF;
439 HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF;
442 * Read HSCX A/B VSTR. Expected value for USR Sportster TA based
443 * boards is 0x05 in the least significant bits.
446 if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
447 ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
449 printf("isic%d: HSCX VSTR test failed for USR Sportster TA\n",
451 printf("isic%d: HSC0: VSTR: %#x\n",
452 unit, HSCX_READ(0, H_VSTR));
453 printf("isic%d: HSC1: VSTR: %#x\n",
454 unit, HSCX_READ(1, H_VSTR));
461 /*---------------------------------------------------------------------------*
462 * isic_attach_usrtai - attach USR
463 *---------------------------------------------------------------------------*/
465 isic_attach_usrtai(device_t dev)
468 size_t unit = device_get_unit(dev); /* get unit */
469 struct l1_softc *sc = 0; /* pointer to softc */
471 sc = &l1_sc[unit]; /* get pointer to softc */
473 /* reset the HSCX and ISAC chips */
475 outb(sc->sc_port + USR_INTL_OFF, USR_RES_BIT);
476 DELAY(SEC_DELAY / 10);
478 outb(sc->sc_port + USR_INTL_OFF, 0x00);
479 DELAY(SEC_DELAY / 10);
483 if((irq = intr_no[sc->sc_irq]) == 0)
485 printf("isic%d: Attach error, invalid IRQ [%d] specified for USR Sportster TA!\n",
490 /* configure and enable irq */
492 outb(sc->sc_port + USR_INTL_OFF, irq | USR_INTE_BIT);
493 DELAY(SEC_DELAY / 10);
498 #endif /* ISIC > 0 */