2 * Copyright (c) 2000 Hans Petter Selasky. 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_ihfc_pnp.c - common hfc ISA PnP-bus interface
28 * -------------------------------------------------
30 * - Everything which has got anything to to with "PnP" bus setup has
31 * been put here, except the chip spesific "PnP" setup.
34 * last edit-date: [Tue Jan 23 16:03:33 2001]
36 * $Id: i4b_ihfc_pnp.c,v 1.9 2000/09/19 13:50:36 hm Exp $
38 * $FreeBSD: src/sys/i4b/layer1/ihfc/i4b_ihfc_pnp.c,v 1.5.2.1 2001/08/10 14:08:37 obrien Exp $
39 * $DragonFly: src/sys/net/i4b/layer1/ihfc/i4b_ihfc_pnp.c,v 1.2 2003/06/17 04:28:40 dillon Exp $
41 *---------------------------------------------------------------------------*/
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/kernel.h>
50 #include <sys/socket.h>
54 #include <i4b/include/i4b_global.h>
56 #include <machine/i4b_ioctl.h>
57 #include <machine/i4b_trace.h>
59 #include <i4b/layer1/i4b_l1.h>
60 #include <i4b/layer1/ihfc/i4b_ihfc.h>
61 #include <i4b/layer1/ihfc/i4b_ihfc_ext.h>
63 #include <machine/bus.h>
64 #include <machine/resource.h>
68 #include <isa/isavar.h>
70 /*---------------------------------------------------------------------------*
72 *---------------------------------------------------------------------------*/
73 ihfc_sc_t ihfc_softc[IHFC_MAXUNIT];
75 /*---------------------------------------------------------------------------*
77 *---------------------------------------------------------------------------*/
78 static int ihfc_isa_probe (device_t dev);
79 static int ihfc_pnp_probe (device_t dev);
80 static int ihfc_pnp_attach (device_t dev);
81 static int ihfc_pnp_detach (device_t dev, u_int flag);
82 static int ihfc_pnp_shutdown (device_t dev);
84 const struct ihfc_pnp_ids
86 u_long vid; /* vendor id */
88 u_char hfc; /* chip type */
89 u_char iirq; /* internal irq */
90 u_short iio; /* internal io-address */
91 u_char stdel; /* S/T delay compensation */
95 { 0x10262750, CARD_TYPEP_16_3C, HFC_S, 2, 0x200, 0x2d},
96 { 0x20262750, CARD_TYPEP_16_3C, HFC_SP, 0, 0x000, 0x0f},
97 { 0x1411d805, CARD_TYPEP_ACERP10, HFC_S, 1, 0x300, 0x0e},
101 typedef const struct ihfc_pnp_ids ihfc_id_t;
103 /*---------------------------------------------------------------------------*
106 * IIRQx: Internal IRQ cross reference for a card
107 * IRQx : Supported IRQ's for a card
108 * IOx : Supported IO-bases for a card
110 * IO0, IRQ0, IIRQ0: TELEINT ISDN SPEED No. 1
111 * IIRQ3: Teles 16.3c PnP (B version)
112 *---------------------------------------------------------------------------*/
113 /* IRQ -> 0 1 2 3 4 5 6 7 8 9 a b c d e f */
114 #define IIRQ0 ((const u_char []){ 0, 0, 0, 1, 2, 3, 0, 4, 0, 0, 5, 6, 0, 0, 0, 0 })
115 #define IRQ0 ((const u_char []){ 3, 4, 5, 7, 0xa, 0xb, 0 })
117 #define IO0 ((const u_long []){ 0x300, 0x330, 0x278, 0x2e8, 0 })
119 #define IIRQ3 ((const u_char []){ 0, 0, 0, 7, 0, 1, 0, 0, 0, 2, 3, 4, 5, 0, 0, 6 })
121 /*---------------------------------------------------------------------------*
123 *---------------------------------------------------------------------------*/
124 static device_method_t ihfc_pnp_methods[] =
126 DEVMETHOD(device_probe, ihfc_pnp_probe),
127 DEVMETHOD(device_attach, ihfc_pnp_attach),
128 DEVMETHOD(device_shutdown, ihfc_pnp_shutdown),
132 static driver_t ihfc_pnp_driver =
139 static devclass_t ihfc_devclass;
141 DRIVER_MODULE(ihfcpnp, isa, ihfc_pnp_driver, ihfc_devclass, 0, 0);
143 /*---------------------------------------------------------------------------*
144 * probe for ISA "PnP" card
145 *---------------------------------------------------------------------------*/
147 ihfc_pnp_probe(device_t dev)
149 u_int unit = device_get_unit(dev); /* get unit */
150 u_int32_t vid = isa_get_vendorid(dev); /* vendor id */
151 ihfc_id_t *ids = &ihfc_pnp_ids[0]; /* ids ptr */
152 ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
153 u_char flag = 0; /* flag */
154 void *dummy = 0; /* a dummy */
158 if (unit >= IHFC_MAXUNIT)
160 printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit);
164 if (!vid) return ihfc_isa_probe(dev);
168 for ( ;(ids->vid); ids++)
174 bzero(sc, sizeof(ihfc_sc_t)); /* reset data structure.*
175 * Zero is default for *
176 * most, so calling the *
177 * int. handler now will*
178 * not be a problem. */
180 S_IOBASE[0] = bus_alloc_resource(
181 dev, SYS_RES_IOPORT, &S_IORID[0],
182 0UL, ~0UL, 2, RF_ACTIVE
185 S_IRQ = bus_alloc_resource(
186 dev, SYS_RES_IRQ, &S_IRQRID,
187 0UL, ~0UL, 1, RF_ACTIVE
190 S_DLP = IHFC_DLP; /* set D-priority */
191 S_HFC = ids->hfc; /* set chip type */
192 S_I4BFLAG = ids->flag; /* set flag */
193 S_NTMODE = IHFC_NTMODE; /* set mode */
194 S_STDEL = ids->stdel; /* set delay */
196 S_I4BUNIT = L0IHFCUNIT(unit); /* set "i4b" unit */
197 S_TRACE = TRACE_OFF; /* set trace mask */
198 S_UNIT = unit; /* set up unit numbers */
200 if (S_IOBASE[0] && S_IRQ)
209 S_IIO = rman_get_start(S_IOBASE[0]) & 0x3ff;
210 S_IIRQ = IIRQ3[rman_get_start(S_IRQ) & 0xf];
213 /* setup interrupt routine now to avvoid stray *
216 bus_setup_intr(dev, S_IRQ, INTR_TYPE_NET, (void(*)(void*))
217 HFC_INTR, sc, &dummy);
221 if (!HFC_CONTROL(sc, 1))
224 return 0; /* success */
228 printf("ihfc%d: Chip seems corrupted. "
229 "Please hard reboot your computer!\n",
234 ihfc_pnp_detach(dev, flag);
239 return ENXIO; /* failure */
242 /*---------------------------------------------------------------------------*
243 * probe for "ISA" cards
244 *---------------------------------------------------------------------------*/
246 ihfc_isa_probe(device_t dev)
248 u_int unit = device_get_unit(dev); /* get unit */
249 ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
250 const u_char *irq = &IRQ0[0]; /* irq's to try */
251 const u_long *iobase = &IO0[0]; /* iobases to try */
252 u_char flag = 0; /* flag */
253 void *dummy = 0; /* a dummy */
257 bzero(sc, sizeof(ihfc_sc_t)); /* reset data structure *
258 * We must reset the *
259 * datastructure here, *
260 * else we risk zero-out *
261 * our gotten resources. */
264 j0: while(*irq) /* get supported IRQ */
266 if ((S_IRQ = bus_alloc_resource(
267 dev, SYS_RES_IRQ, &S_IRQRID,
268 *irq, *irq, 1, RF_ACTIVE
276 while(*iobase) /* get supported IO-PORT */
278 if ((S_IOBASE[0] = bus_alloc_resource(
279 dev, SYS_RES_IOPORT, &S_IORID[0],
280 *iobase, *iobase, 2, RF_ACTIVE
290 if (*irq && *iobase) /* we got our resources, now test chip */
292 S_DLP = IHFC_DLP; /* set D-priority */
293 S_HFC = HFC_1; /* set chip type */
294 S_I4BFLAG = CARD_TYPEP_TELEINT_NO_1; /* set flag */
295 S_NTMODE = IHFC_NTMODE; /* set mode */
296 S_STDEL = 0x00; /* set delay (not used) */
298 S_I4BUNIT = L0IHFCUNIT(unit); /* set "i4b" unit */
299 S_TRACE = TRACE_OFF; /* set trace mask */
300 S_UNIT = unit; /* set up unit numbers */
302 S_IIRQ = IIRQ0[*irq]; /* set internal irq */
303 S_IIO = *iobase; /* set internal iobase */
305 /* setup interrupt routine now to avvoid stray *
308 bus_setup_intr(dev, S_IRQ, INTR_TYPE_NET, (void(*)(void*))
309 HFC_INTR, sc, &dummy);
313 if (!HFC_CONTROL(sc, 1))
315 device_set_desc(dev, "TELEINT ISDN SPEED No. 1");
318 return 0; /* success */
322 ihfc_pnp_detach(dev, flag);
324 if (*irq && *++iobase) goto j0; /* try again */
328 printf("ihfc%d: Chip not found. "
329 "A hard reboot may help!\n", unit);
331 return ENXIO; /* failure */
334 /*---------------------------------------------------------------------------*
335 * attach ISA "PnP" card
336 *---------------------------------------------------------------------------*/
338 ihfc_pnp_attach(device_t dev)
340 u_int unit = device_get_unit(dev); /* get unit */
341 ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
346 ihfc_B_linkinit(sc); /* Setup B-Channel linktabs */
348 i4b_l1_mph_status_ind(S_I4BUNIT, STI_ATTACH, S_I4BFLAG, &ihfc_l1mux_func);
350 HFC_INIT(sc, 0, 0, 1); /* Setup D - Channel */
352 HFC_INIT(sc, 2, 0, 0); /* Init B1 - Channel */
353 HFC_INIT(sc, 4, 0, 0); /* Init B2 - Channel */
356 return 0; /* success */
359 return ENXIO; /* failure */
362 /*---------------------------------------------------------------------------*
363 * shutdown for our ISA PnP card
364 *---------------------------------------------------------------------------*/
366 ihfc_pnp_shutdown(device_t dev)
368 u_int unit = device_get_unit(dev); /* get unit */
369 ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
374 if (unit >= IHFC_MAXUNIT)
376 printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit);
380 HFC_CONTROL(sc, 2); /* shutdown chip */
390 /*---------------------------------------------------------------------------*
391 * detach for our ISA PnP card
393 * flag: bit[0] set: teardown interrupt handler too
394 *---------------------------------------------------------------------------*/
396 ihfc_pnp_detach (device_t dev, u_int flag)
398 u_int unit = device_get_unit(dev); /* get unit */
399 ihfc_sc_t *sc = &ihfc_softc[unit]; /* softc */
402 if (unit >= IHFC_MAXUNIT)
404 printf("ihfc%d: Error, unit %d >= IHFC_MAXUNIT", unit, unit);
408 /* free interrupt resources */
414 /* tear down interrupt handler */
415 bus_teardown_intr(dev, S_IRQ, (void(*)(void *))HFC_INTR);
419 bus_release_resource(dev, SYS_RES_IRQ, S_IRQRID, S_IRQ);
428 for (i = IHFC_IO_BASES; i--;)
432 bus_release_resource(dev, SYS_RES_IOPORT,
433 S_IORID[i], S_IOBASE[i]);
442 #endif /* NIHFC > 0 */