Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / dev / isapnp / isic_isapnp_siemens_isurf.c
blob6eeedfba829ed0854020c4a0534ee4b82e837d94
1 /*
2 * Copyright (c) 1999 Udo Schweigert. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the author nor the names of any co-contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 * 4. Altered versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software and/or documentation.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
31 *---------------------------------------------------------------------------
32 * Based on ELSA Quickstep 1000pro PCI driver (i4b_elsa_qs1p.c)
33 *---------------------------------------------------------------------------
34 * In case of trouble please contact Udo Schweigert <ust@cert.siemens.de>
35 *---------------------------------------------------------------------------
37 * Siemens I-Surf 2.0 PnP specific routines for isic driver
38 * --------------------------------------------------------
40 * $Id: isic_isapnp_siemens_isurf.c,v 1.11 2007/10/19 12:00:32 ad Exp $
42 * last edit-date: [Fri Jan 5 11:38:29 2001]
44 *---------------------------------------------------------------------------*/
46 #include <sys/cdefs.h>
47 __KERNEL_RCSID(0, "$NetBSD: isic_isapnp_siemens_isurf.c,v 1.10 2007/03/04 06:02:13 christos Exp $");
49 #include <sys/param.h>
50 #include <sys/kernel.h>
51 #include <sys/systm.h>
52 #include <sys/mbuf.h>
54 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
55 #include <sys/callout.h>
56 #endif
58 #if defined(__FreeBSD__)
59 #if __FreeBSD__ >= 3
60 #include <sys/ioccom.h>
61 #else
62 #include <sys/ioctl.h>
63 #endif
65 #include <machine/clock.h>
66 #include <i386/isa/isa_device.h>
68 #else
69 #include <sys/bus.h>
70 #include <sys/device.h>
71 #endif
73 #include <sys/socket.h>
74 #include <net/if.h>
76 #if defined(__FreeBSD__)
77 #include <machine/i4b_ioctl.h>
78 #else
79 #include <netisdn/i4b_ioctl.h>
80 #endif
82 #include <netisdn/i4b_global.h>
83 #include <netisdn/i4b_debug.h>
84 #include <netisdn/i4b_l2.h>
85 #include <netisdn/i4b_l1l2.h>
86 #include <netisdn/i4b_mbuf.h>
88 #include <dev/ic/isic_l1.h>
89 #include <dev/ic/ipac.h>
90 #include <dev/ic/isac.h>
91 #include <dev/ic/hscx.h>
93 #if !defined(__FreeBSD__)
94 void isic_attach_siemens_isurf(struct isic_softc *sc);
95 #endif
97 /* masks for register encoded in base addr */
99 #define SIE_ISURF_BASE_MASK 0x0ffff
100 #define SIE_ISURF_OFF_MASK 0xf0000
102 /* register id's to be encoded in base addr */
104 #define SIE_ISURF_IDISAC 0x00000
105 #define SIE_ISURF_IDHSCXA 0x10000
106 #define SIE_ISURF_IDHSCXB 0x20000
107 #define SIE_ISURF_IDIPAC 0x40000
109 /* offsets from base address */
111 #define SIE_ISURF_OFF_ALE 0x00
112 #define SIE_ISURF_OFF_RW 0x01
114 /*---------------------------------------------------------------------------*
115 * Siemens I-Surf 2.0 PnP ISAC get fifo routine
116 *---------------------------------------------------------------------------*/
117 #if defined(__FreeBSD__)
119 static void
120 siemens_isurf_read_fifo(void *buf, const void *base, size_t len)
122 if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
124 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
125 insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len);
127 else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
129 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
130 insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len);
132 else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */
134 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
135 insb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (u_char *)buf, (u_int)len);
139 #else
141 static void
142 siemens_isurf_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
144 bus_space_tag_t t = sc->sc_maps[0].t;
145 bus_space_handle_t h = sc->sc_maps[0].h;
146 switch (what) {
147 case ISIC_WHAT_ISAC:
148 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
149 bus_space_read_multi_1(t, h, SIE_ISURF_OFF_RW, buf, size);
150 break;
151 case ISIC_WHAT_HSCXA:
152 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
153 bus_space_read_multi_1(t, h, SIE_ISURF_OFF_RW, buf, size);
154 break;
155 case ISIC_WHAT_HSCXB:
156 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
157 bus_space_read_multi_1(t, h, SIE_ISURF_OFF_RW, buf, size);
158 break;
162 #endif
164 /*---------------------------------------------------------------------------*
165 * Siemens I-Surf 2.0 PnP ISAC put fifo routine
166 *---------------------------------------------------------------------------*/
167 #if defined(__FreeBSD__)
169 static void
170 siemens_isurf_write_fifo(void *base, const void *buf, size_t len)
172 if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
174 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
175 outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
177 else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
179 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
180 outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
182 else /* if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC) */
184 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
185 outsb((((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW), (const u_char *)buf, (u_int)len);
189 #else
191 static void
192 siemens_isurf_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
194 bus_space_tag_t t = sc->sc_maps[0].t;
195 bus_space_handle_t h = sc->sc_maps[0].h;
196 switch (what) {
197 case ISIC_WHAT_ISAC:
198 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF);
199 bus_space_write_multi_1(t, h, SIE_ISURF_OFF_RW, buf, size);
200 break;
201 case ISIC_WHAT_HSCXA:
202 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF);
203 bus_space_write_multi_1(t, h, SIE_ISURF_OFF_RW, buf, size);
204 break;
205 case ISIC_WHAT_HSCXB:
206 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF);
207 bus_space_write_multi_1(t, h, SIE_ISURF_OFF_RW, buf, size);
208 break;
212 #endif
214 /*---------------------------------------------------------------------------*
215 * Siemens I-Surf 2.0 PnP ISAC put register routine
216 *---------------------------------------------------------------------------*/
217 #if defined(__FreeBSD__)
219 static void
220 siemens_isurf_write_reg(u_char *base, u_int offset, u_int v)
222 if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
224 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
225 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
227 else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
229 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
230 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
232 else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC)
234 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
235 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
237 else /* IPAC */
239 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
240 outb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW, (u_char)v);
244 #else
246 static void
247 siemens_isurf_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
249 bus_space_tag_t t = sc->sc_maps[0].t;
250 bus_space_handle_t h = sc->sc_maps[0].h;
251 switch (what) {
252 case ISIC_WHAT_ISAC:
253 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF+offs);
254 bus_space_write_1(t, h, SIE_ISURF_OFF_RW, data);
255 break;
256 case ISIC_WHAT_HSCXA:
257 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF+offs);
258 bus_space_write_1(t, h, SIE_ISURF_OFF_RW, data);
259 break;
260 case ISIC_WHAT_HSCXB:
261 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF+offs);
262 bus_space_write_1(t, h, SIE_ISURF_OFF_RW, data);
263 break;
264 case ISIC_WHAT_IPAC:
265 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_IPAC_OFF+offs);
266 bus_space_write_1(t, h, SIE_ISURF_OFF_RW, data);
267 break;
271 #endif
273 /*---------------------------------------------------------------------------*
274 * Siemens I-Surf 2.0 PnP ISAC get register routine
275 *---------------------------------------------------------------------------*/
276 #if defined(__FreeBSD__)
278 static u_char
279 siemens_isurf_read_reg(u_char *base, u_int offset)
281 if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXB)
283 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXB_OFF));
284 return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
286 else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDHSCXA)
288 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_HSCXA_OFF));
289 return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
291 else if(((u_int)base & SIE_ISURF_OFF_MASK) == SIE_ISURF_IDISAC)
293 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_ISAC_OFF));
294 return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
296 else /* IPAC */
298 outb((u_int)((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_ALE, (u_char)(offset+IPAC_IPAC_OFF));
299 return(inb(((u_int)base & SIE_ISURF_BASE_MASK) + SIE_ISURF_OFF_RW));
303 #else
305 static u_int8_t
306 siemens_isurf_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
308 bus_space_tag_t t = sc->sc_maps[0].t;
309 bus_space_handle_t h = sc->sc_maps[0].h;
310 switch (what) {
311 case ISIC_WHAT_ISAC:
312 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_ISAC_OFF+offs);
313 return bus_space_read_1(t, h, SIE_ISURF_OFF_RW);
314 case ISIC_WHAT_HSCXA:
315 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXA_OFF+offs);
316 return bus_space_read_1(t, h, SIE_ISURF_OFF_RW);
317 case ISIC_WHAT_HSCXB:
318 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_HSCXB_OFF+offs);
319 return bus_space_read_1(t, h, SIE_ISURF_OFF_RW);
320 case ISIC_WHAT_IPAC:
321 bus_space_write_1(t, h, SIE_ISURF_OFF_ALE, IPAC_IPAC_OFF+offs);
322 return bus_space_read_1(t, h, SIE_ISURF_OFF_RW);
324 return 0;
327 #endif
329 /*---------------------------------------------------------------------------*
330 * isic_probe_siemens_isurf - probe for Siemens I-Surf 2.0 PnP
331 *---------------------------------------------------------------------------*/
332 #if defined(__FreeBSD__)
335 isic_probe_siemens_isurf(struct isa_device *dev, unsigned int iobase2)
337 struct isic_softc *sc = &l1_sc[dev->id_unit];
339 /* check max unit range */
341 if(dev->id_unit >= ISIC_MAXUNIT)
343 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Siemens I-Surf 2.0 PnP\n",
344 dev->id_unit, dev->id_unit);
345 return(0);
347 sc->sc_unit = dev->id_unit;
349 /* check IRQ validity */
351 switch(ffs(dev->id_irq) - 1)
353 case 3:
354 case 4:
355 case 5:
356 case 7:
357 case 10:
358 case 11:
359 case 12:
360 case 15:
361 break;
363 default:
364 printf("isic%d: Error, invalid IRQ [%d] specified for Siemens I-Surf 2.0 PnP!\n",
365 dev->id_unit, ffs(dev->id_irq)-1);
366 return(0);
367 break;
369 sc->sc_irq = dev->id_irq;
371 /* check if memory addr specified */
373 if(dev->id_maddr)
375 printf("isic%d: Error, mem addr 0x%lx specified for Siemens I-Surf 2.0 PnP!\n",
376 dev->id_unit, (u_long)dev->id_maddr);
377 return(0);
379 dev->id_msize = 0;
381 /* check if we got an iobase */
383 if(!((dev->id_iobase >= 0x100) && (dev->id_iobase <= 0xfffc)))
385 printf("isic%d: Error, invalid iobase 0x%x specified for Siemens I-Surf 2.0 PnP!\n",
386 dev->id_unit, dev->id_iobase);
387 return(0);
389 sc->sc_port = dev->id_iobase;
392 /* setup access routines */
394 sc->clearirq = NULL;
395 sc->readreg = siemens_isurf_read_reg;
396 sc->writereg = siemens_isurf_write_reg;
398 sc->readfifo = siemens_isurf_read_fifo;
399 sc->writefifo = siemens_isurf_write_fifo;
401 /* setup card type */
403 sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2;
405 /* setup IOM bus type */
407 sc->sc_bustyp = BUS_TYPE_IOM2;
409 /* setup chip type = IPAC ! */
411 sc->sc_ipac = 1;
412 sc->sc_bfifolen = IPAC_BFIFO_LEN;
415 return (1);
418 /*---------------------------------------------------------------------------*
419 * isic_attach_siemens_isurf - attach for Siemens I-Surf 2.0 PnP
420 *---------------------------------------------------------------------------*/
422 isic_attach_siemens_isurf(struct isa_device *dev, unsigned int iobase2)
424 struct isic_softc *sc = &l1_sc[dev->id_unit];
426 /* setup ISAC and HSCX base addr */
428 ISAC_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDISAC);
429 HSCX_A_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXA);
430 HSCX_B_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDHSCXB);
431 IPAC_BASE = (void *) ((u_int)sc->sc_port | SIE_ISURF_IDIPAC);
433 /* enable hscx/isac irq's */
434 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
436 IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
437 IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
438 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
439 IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
441 return(1);
444 #else
446 void
447 isic_attach_siemens_isurf(struct isic_softc *sc)
449 /* setup access routines */
451 sc->clearirq = NULL;
452 sc->readreg = siemens_isurf_read_reg;
453 sc->writereg = siemens_isurf_write_reg;
455 sc->readfifo = siemens_isurf_read_fifo;
456 sc->writefifo = siemens_isurf_write_fifo;
458 /* setup card type */
460 sc->sc_cardtyp = CARD_TYPEP_SIE_ISURF2;
462 /* setup IOM bus type */
464 sc->sc_bustyp = BUS_TYPE_IOM2;
466 /* setup chip type = IPAC ! */
468 sc->sc_ipac = 1;
469 sc->sc_bfifolen = IPAC_BFIFO_LEN;
471 /* enable hscx/isac irq's */
473 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
475 IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
476 IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
477 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
478 IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
481 #endif