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 $
31 * $DragonFly: src/sys/net/i4b/layer1/isic/i4b_usr_sti.c,v 1.8 2006/12/22 23:44:56 swildner Exp $
33 * last edit-date: [Wed Jan 24 09:28:12 2001]
35 *---------------------------------------------------------------------------*/
40 #if (NISIC > 0) && defined(USR_STI)
42 #include <sys/param.h>
43 #include <sys/systm.h>
46 #include <sys/socket.h>
49 #include <net/i4b/include/machine/i4b_ioctl.h>
50 #include <net/i4b/include/machine/i4b_trace.h>
52 #include "../i4b_l1.h"
56 /*---------------------------------------------------------------------------*
57 * USR Sportster TA intern special registers
58 *---------------------------------------------------------------------------*/
59 #define USR_HSCXA_OFF 0x0000
60 #define USR_HSCXB_OFF 0x4000
61 #define USR_INTL_OFF 0x8000
62 #define USR_ISAC_OFF 0xc000
64 #define USR_RES_BIT 0x80 /* 0 = normal, 1 = reset ISAC/HSCX */
65 #define USR_INTE_BIT 0x40 /* 0 = IRQ disabled, 1 = IRQ's enabled */
66 #define USR_IL_MASK 0x07 /* IRQ level config */
68 static u_char intr_no[] = { 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 3, 4, 5, 0, 6, 7 };
71 (((reg/4) * 1024) + ((reg%4) * 2))
73 #ifdef USRTA_DEBUG_PORTACCESS
75 #define USRTA_DEBUG(fmt) \
76 if (++debugcntr < 1000) kprintf fmt;
78 #define USRTA_DEBUG(fmt)
81 /*---------------------------------------------------------------------------*
82 * USRobotics read fifo routine
83 *---------------------------------------------------------------------------*/
85 usrtai_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
88 unsigned int base = 0;
90 USRTA_DEBUG(("usrtai_read_fifo: what %d size %d\n", what, size))
94 base = (unsigned int)ISAC_BASE;
97 base = (unsigned int)HSCX_A_BASE;
100 base = (unsigned int)HSCX_B_BASE;
103 kprintf("usrtai_read_fifo: invalid what %d\n", what);
107 for(;size > 0; size--, offset++)
109 *((u_char *)buf + offset) = inb(base + ADDR(offset));
113 /*---------------------------------------------------------------------------*
114 * USRobotics write fifo routine
115 *---------------------------------------------------------------------------*/
117 usrtai_write_fifo(struct l1_softc *sc, int what, void *data, size_t size)
120 unsigned int base = 0;
122 USRTA_DEBUG(("usrtai_write_fifo: what %d size %d\n", what, size))
126 base = (unsigned int)ISAC_BASE;
128 case ISIC_WHAT_HSCXA:
129 base = (unsigned int)HSCX_A_BASE;
131 case ISIC_WHAT_HSCXB:
132 base = (unsigned int)HSCX_B_BASE;
135 kprintf("usrtai_write_fifo: invalid what %d\n", what);
140 for(;size > 0; size--, offset++)
142 outb(base + ADDR(offset), *((u_char *)data + offset));
146 /*---------------------------------------------------------------------------*
147 * USRobotics write register routine
148 *---------------------------------------------------------------------------*/
150 usrtai_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
152 unsigned int base = 0;
154 USRTA_DEBUG(("usrtai_write_reg: what %d ADDR(%d) %d data %#x\n", what, offs, ADDR(offs), data))
158 base = (unsigned int)ISAC_BASE;
160 case ISIC_WHAT_HSCXA:
161 base = (unsigned int)HSCX_A_BASE;
163 case ISIC_WHAT_HSCXB:
164 base = (unsigned int)HSCX_B_BASE;
167 kprintf("usrtai_write_reg invalid what %d\n", what);
171 outb(base + ADDR(offs), (u_char)data);
174 /*---------------------------------------------------------------------------*
175 * USRobotics read register routine
176 *---------------------------------------------------------------------------*/
178 usrtai_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
180 unsigned int base = 0;
183 USRTA_DEBUG(("usrtai_read_reg: what %d ADDR(%d) %d..", what, offs, ADDR(offs)))
187 base = (unsigned int)ISAC_BASE;
189 case ISIC_WHAT_HSCXA:
190 base = (unsigned int)HSCX_A_BASE;
192 case ISIC_WHAT_HSCXB:
193 base = (unsigned int)HSCX_B_BASE;
196 kprintf("usrtai_read_reg: invalid what %d\n", what);
200 byte = inb(base + ADDR(offs));
201 USRTA_DEBUG(("usrtai_read_reg: got %#x\n", byte))
205 /*---------------------------------------------------------------------------*
206 * allocate an io port - based on code in isa_isic.c
207 *---------------------------------------------------------------------------*/
209 usrtai_alloc_port(device_t dev)
211 size_t unit = device_get_unit(dev);
212 struct l1_softc *sc = &l1_sc[unit];
216 /* 49 io mappings: 1 config and 48x8 registers */
218 /* config at offset 0x8000 */
219 base = sc->sc_port + 0x8000;
220 if (base < 0 || base > 0x0ffff)
222 sc->sc_resources.io_rid[num] = num;
224 bus_set_resource(dev, SYS_RES_IOPORT, num, base, 1);
226 if(!(sc->sc_resources.io_base[num] =
227 bus_alloc_resource(dev, SYS_RES_IOPORT,
228 &sc->sc_resources.io_rid[num],
229 0ul, ~0ul, 1, RF_ACTIVE)))
231 kprintf("isic%d: Error, failed to reserve io #%dport %#x!\n", unit, num, base);
232 isic_detach_common(dev);
237 /* HSCX A at offset 0 */
239 for (i = 0; i < 16; i++) {
240 if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
242 sc->sc_resources.io_rid[num] = num;
244 bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
246 if(!(sc->sc_resources.io_base[num] =
247 bus_alloc_resource(dev, SYS_RES_IOPORT,
248 &sc->sc_resources.io_rid[num],
249 0ul, ~0ul, 1, RF_ACTIVE)))
251 kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
252 isic_detach_common(dev);
258 /* HSCX B at offset 0x4000 */
259 base = sc->sc_port + 0x4000;
260 for (i = 0; i < 16; i++) {
261 if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
263 sc->sc_resources.io_rid[num] = num;
265 bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
267 if(!(sc->sc_resources.io_base[num] =
268 bus_alloc_resource(dev, SYS_RES_IOPORT,
269 &sc->sc_resources.io_rid[num],
270 0ul, ~0ul, 1, RF_ACTIVE)))
272 kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
273 isic_detach_common(dev);
279 /* ISAC at offset 0xc000 */
280 base = sc->sc_port + 0xc000;
281 for (i = 0; i < 16; i++) {
282 if (base+i*1024 < 0 || base+i*1024+8 > 0x0ffff)
284 sc->sc_resources.io_rid[num] = num;
286 bus_set_resource(dev, SYS_RES_IOPORT, num, base+i*1024, 8);
288 if(!(sc->sc_resources.io_base[num] =
289 bus_alloc_resource(dev, SYS_RES_IOPORT,
290 &sc->sc_resources.io_rid[num],
291 0ul, ~0ul, 1, RF_ACTIVE)))
293 kprintf("isic%d: Error, failed to reserve io #%d port %#x!\n", unit, num, base+i*1024);
294 isic_detach_common(dev);
303 /*---------------------------------------------------------------------------*
304 * isic_probe_usrtai - probe for USR
305 *---------------------------------------------------------------------------*/
307 isic_probe_usrtai(device_t dev)
309 size_t unit = device_get_unit(dev); /* get unit */
310 struct l1_softc *sc = 0; /* pointer to softc */
311 void *ih = 0; /* dummy */
313 /* check max unit range */
315 if(unit >= ISIC_MAXUNIT)
317 kprintf("isic%d: Error, unit %d >= ISIC_MAXUNIT for USR Sportster TA!\n",
322 sc = &l1_sc[unit]; /* get pointer to softc */
323 sc->sc_unit = unit; /* set unit */
325 /* see if an io base was supplied */
327 if(!(sc->sc_resources.io_base[0] =
328 bus_alloc_resource(dev, SYS_RES_IOPORT,
329 &sc->sc_resources.io_rid[0],
330 0ul, ~0ul, 1, RF_ACTIVE)))
332 kprintf("isic%d: Could not get iobase for USR Sportster TA!\n",
339 sc->sc_port = rman_get_start(sc->sc_resources.io_base[0]);
341 /* release io base */
343 bus_release_resource(dev, SYS_RES_IOPORT, sc->sc_resources.io_rid[0],
344 sc->sc_resources.io_base[0]);
347 /* check if we got an iobase */
370 kprintf("isic%d: Error, invalid iobase 0x%x specified for USR Sportster TA!\n",
376 /* allocate all the ports needed */
378 if(usrtai_alloc_port(dev))
380 kprintf("isic%d: Could not get the ports for USR Sportster TA!\n", unit);
381 isic_detach_common(dev);
387 if(!(sc->sc_resources.irq =
388 bus_alloc_resource(dev, SYS_RES_IRQ,
389 &sc->sc_resources.irq_rid,
390 0ul, ~0ul, 1, RF_ACTIVE)))
392 kprintf("isic%d: Could not get an irq for USR Sportster TA!\n",unit);
393 isic_detach_common(dev);
397 /* get the irq number */
398 sc->sc_irq = rman_get_start(sc->sc_resources.irq);
400 /* register interrupt routine */
401 bus_setup_intr(dev, sc->sc_resources.irq, 0,
402 (void(*)(void *))(isicintr), sc, &ih, NULL);
404 /* check IRQ validity */
406 if(intr_no[sc->sc_irq] == 0)
408 kprintf("isic%d: Error, invalid IRQ [%d] specified for USR Sportster TA!\n",
413 /* setup ISAC access routines */
416 sc->readreg = usrtai_read_reg;
417 sc->writereg = usrtai_write_reg;
419 sc->readfifo = usrtai_read_fifo;
420 sc->writefifo = usrtai_write_fifo;
422 /* setup card type */
424 sc->sc_cardtyp = CARD_TYPEP_USRTA;
426 /* setup IOM bus type */
428 sc->sc_bustyp = BUS_TYPE_IOM2;
431 sc->sc_bfifolen = HSCX_FIFO_LEN;
433 /* setup ISAC and HSCX base addr */
435 ISAC_BASE = (caddr_t)sc->sc_port + USR_ISAC_OFF;
436 HSCX_A_BASE = (caddr_t)sc->sc_port + USR_HSCXA_OFF;
437 HSCX_B_BASE = (caddr_t)sc->sc_port + USR_HSCXB_OFF;
440 * Read HSCX A/B VSTR. Expected value for USR Sportster TA based
441 * boards is 0x05 in the least significant bits.
444 if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
445 ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
447 kprintf("isic%d: HSCX VSTR test failed for USR Sportster TA\n",
449 kprintf("isic%d: HSC0: VSTR: %#x\n",
450 unit, HSCX_READ(0, H_VSTR));
451 kprintf("isic%d: HSC1: VSTR: %#x\n",
452 unit, HSCX_READ(1, H_VSTR));
459 /*---------------------------------------------------------------------------*
460 * isic_attach_usrtai - attach USR
461 *---------------------------------------------------------------------------*/
463 isic_attach_usrtai(device_t dev)
466 size_t unit = device_get_unit(dev); /* get unit */
467 struct l1_softc *sc = 0; /* pointer to softc */
469 sc = &l1_sc[unit]; /* get pointer to softc */
471 /* reset the HSCX and ISAC chips */
473 outb(sc->sc_port + USR_INTL_OFF, USR_RES_BIT);
474 DELAY(SEC_DELAY / 10);
476 outb(sc->sc_port + USR_INTL_OFF, 0x00);
477 DELAY(SEC_DELAY / 10);
481 if((irq = intr_no[sc->sc_irq]) == 0)
483 kprintf("isic%d: Attach error, invalid IRQ [%d] specified for USR Sportster TA!\n",
488 /* configure and enable irq */
490 outb(sc->sc_port + USR_INTL_OFF, irq | USR_INTE_BIT);
491 DELAY(SEC_DELAY / 10);
496 #endif /* ISIC > 0 */