xref: /linux/drivers/isdn/hardware/mISDN/mISDNipac.c (revision c0c914eca7f251c70facc37dfebeaf176601918d)
1 /*
2  * isac.c   ISAC specific routines
3  *
4  * Author       Karsten Keil <keil@isdn4linux.de>
5  *
6  * Copyright 2009  by Karsten Keil <keil@isdn4linux.de>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22 
23 #include <linux/irqreturn.h>
24 #include <linux/slab.h>
25 #include <linux/module.h>
26 #include <linux/mISDNhw.h>
27 #include "ipac.h"
28 
29 
30 #define DBUSY_TIMER_VALUE	80
31 #define ARCOFI_USE		1
32 
33 #define ISAC_REV		"2.0"
34 
35 MODULE_AUTHOR("Karsten Keil");
36 MODULE_VERSION(ISAC_REV);
37 MODULE_LICENSE("GPL v2");
38 
39 #define ReadISAC(is, o)		(is->read_reg(is->dch.hw, o + is->off))
40 #define	WriteISAC(is, o, v)	(is->write_reg(is->dch.hw, o + is->off, v))
41 #define ReadHSCX(h, o)		(h->ip->read_reg(h->ip->hw, h->off + o))
42 #define WriteHSCX(h, o, v)	(h->ip->write_reg(h->ip->hw, h->off + o, v))
43 #define ReadIPAC(ip, o)		(ip->read_reg(ip->hw, o))
44 #define WriteIPAC(ip, o, v)	(ip->write_reg(ip->hw, o, v))
45 
46 static inline void
47 ph_command(struct isac_hw *isac, u8 command)
48 {
49 	pr_debug("%s: ph_command %x\n", isac->name, command);
50 	if (isac->type & IPAC_TYPE_ISACX)
51 		WriteISAC(isac, ISACX_CIX0, (command << 4) | 0xE);
52 	else
53 		WriteISAC(isac, ISAC_CIX0, (command << 2) | 3);
54 }
55 
56 static void
57 isac_ph_state_change(struct isac_hw *isac)
58 {
59 	switch (isac->state) {
60 	case (ISAC_IND_RS):
61 	case (ISAC_IND_EI):
62 		ph_command(isac, ISAC_CMD_DUI);
63 	}
64 	schedule_event(&isac->dch, FLG_PHCHANGE);
65 }
66 
67 static void
68 isac_ph_state_bh(struct dchannel *dch)
69 {
70 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
71 
72 	switch (isac->state) {
73 	case ISAC_IND_RS:
74 	case ISAC_IND_EI:
75 		dch->state = 0;
76 		l1_event(dch->l1, HW_RESET_IND);
77 		break;
78 	case ISAC_IND_DID:
79 		dch->state = 3;
80 		l1_event(dch->l1, HW_DEACT_CNF);
81 		break;
82 	case ISAC_IND_DR:
83 		dch->state = 3;
84 		l1_event(dch->l1, HW_DEACT_IND);
85 		break;
86 	case ISAC_IND_PU:
87 		dch->state = 4;
88 		l1_event(dch->l1, HW_POWERUP_IND);
89 		break;
90 	case ISAC_IND_RSY:
91 		if (dch->state <= 5) {
92 			dch->state = 5;
93 			l1_event(dch->l1, ANYSIGNAL);
94 		} else {
95 			dch->state = 8;
96 			l1_event(dch->l1, LOSTFRAMING);
97 		}
98 		break;
99 	case ISAC_IND_ARD:
100 		dch->state = 6;
101 		l1_event(dch->l1, INFO2);
102 		break;
103 	case ISAC_IND_AI8:
104 		dch->state = 7;
105 		l1_event(dch->l1, INFO4_P8);
106 		break;
107 	case ISAC_IND_AI10:
108 		dch->state = 7;
109 		l1_event(dch->l1, INFO4_P10);
110 		break;
111 	}
112 	pr_debug("%s: TE newstate %x\n", isac->name, dch->state);
113 }
114 
115 void
116 isac_empty_fifo(struct isac_hw *isac, int count)
117 {
118 	u8 *ptr;
119 
120 	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
121 
122 	if (!isac->dch.rx_skb) {
123 		isac->dch.rx_skb = mI_alloc_skb(isac->dch.maxlen, GFP_ATOMIC);
124 		if (!isac->dch.rx_skb) {
125 			pr_info("%s: D receive out of memory\n", isac->name);
126 			WriteISAC(isac, ISAC_CMDR, 0x80);
127 			return;
128 		}
129 	}
130 	if ((isac->dch.rx_skb->len + count) >= isac->dch.maxlen) {
131 		pr_debug("%s: %s overrun %d\n", isac->name, __func__,
132 			 isac->dch.rx_skb->len + count);
133 		WriteISAC(isac, ISAC_CMDR, 0x80);
134 		return;
135 	}
136 	ptr = skb_put(isac->dch.rx_skb, count);
137 	isac->read_fifo(isac->dch.hw, isac->off, ptr, count);
138 	WriteISAC(isac, ISAC_CMDR, 0x80);
139 	if (isac->dch.debug & DEBUG_HW_DFIFO) {
140 		char	pfx[MISDN_MAX_IDLEN + 16];
141 
142 		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-recv %s %d ",
143 			 isac->name, count);
144 		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
145 	}
146 }
147 
148 static void
149 isac_fill_fifo(struct isac_hw *isac)
150 {
151 	int count, more;
152 	u8 *ptr;
153 
154 	if (!isac->dch.tx_skb)
155 		return;
156 	count = isac->dch.tx_skb->len - isac->dch.tx_idx;
157 	if (count <= 0)
158 		return;
159 
160 	more = 0;
161 	if (count > 32) {
162 		more = !0;
163 		count = 32;
164 	}
165 	pr_debug("%s: %s  %d\n", isac->name, __func__, count);
166 	ptr = isac->dch.tx_skb->data + isac->dch.tx_idx;
167 	isac->dch.tx_idx += count;
168 	isac->write_fifo(isac->dch.hw, isac->off, ptr, count);
169 	WriteISAC(isac, ISAC_CMDR, more ? 0x8 : 0xa);
170 	if (test_and_set_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
171 		pr_debug("%s: %s dbusytimer running\n", isac->name, __func__);
172 		del_timer(&isac->dch.timer);
173 	}
174 	init_timer(&isac->dch.timer);
175 	isac->dch.timer.expires = jiffies + ((DBUSY_TIMER_VALUE * HZ)/1000);
176 	add_timer(&isac->dch.timer);
177 	if (isac->dch.debug & DEBUG_HW_DFIFO) {
178 		char	pfx[MISDN_MAX_IDLEN + 16];
179 
180 		snprintf(pfx, MISDN_MAX_IDLEN + 15, "D-send %s %d ",
181 			 isac->name, count);
182 		print_hex_dump_bytes(pfx, DUMP_PREFIX_OFFSET, ptr, count);
183 	}
184 }
185 
186 static void
187 isac_rme_irq(struct isac_hw *isac)
188 {
189 	u8 val, count;
190 
191 	val = ReadISAC(isac, ISAC_RSTA);
192 	if ((val & 0x70) != 0x20) {
193 		if (val & 0x40) {
194 			pr_debug("%s: ISAC RDO\n", isac->name);
195 #ifdef ERROR_STATISTIC
196 			isac->dch.err_rx++;
197 #endif
198 		}
199 		if (!(val & 0x20)) {
200 			pr_debug("%s: ISAC CRC error\n", isac->name);
201 #ifdef ERROR_STATISTIC
202 			isac->dch.err_crc++;
203 #endif
204 		}
205 		WriteISAC(isac, ISAC_CMDR, 0x80);
206 		if (isac->dch.rx_skb)
207 			dev_kfree_skb(isac->dch.rx_skb);
208 		isac->dch.rx_skb = NULL;
209 	} else {
210 		count = ReadISAC(isac, ISAC_RBCL) & 0x1f;
211 		if (count == 0)
212 			count = 32;
213 		isac_empty_fifo(isac, count);
214 		recv_Dchannel(&isac->dch);
215 	}
216 }
217 
218 static void
219 isac_xpr_irq(struct isac_hw *isac)
220 {
221 	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
222 		del_timer(&isac->dch.timer);
223 	if (isac->dch.tx_skb && isac->dch.tx_idx < isac->dch.tx_skb->len) {
224 		isac_fill_fifo(isac);
225 	} else {
226 		if (isac->dch.tx_skb)
227 			dev_kfree_skb(isac->dch.tx_skb);
228 		if (get_next_dframe(&isac->dch))
229 			isac_fill_fifo(isac);
230 	}
231 }
232 
233 static void
234 isac_retransmit(struct isac_hw *isac)
235 {
236 	if (test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags))
237 		del_timer(&isac->dch.timer);
238 	if (test_bit(FLG_TX_BUSY, &isac->dch.Flags)) {
239 		/* Restart frame */
240 		isac->dch.tx_idx = 0;
241 		isac_fill_fifo(isac);
242 	} else if (isac->dch.tx_skb) { /* should not happen */
243 		pr_info("%s: tx_skb exist but not busy\n", isac->name);
244 		test_and_set_bit(FLG_TX_BUSY, &isac->dch.Flags);
245 		isac->dch.tx_idx = 0;
246 		isac_fill_fifo(isac);
247 	} else {
248 		pr_info("%s: ISAC XDU no TX_BUSY\n", isac->name);
249 		if (get_next_dframe(&isac->dch))
250 			isac_fill_fifo(isac);
251 	}
252 }
253 
254 static void
255 isac_mos_irq(struct isac_hw *isac)
256 {
257 	u8 val;
258 	int ret;
259 
260 	val = ReadISAC(isac, ISAC_MOSR);
261 	pr_debug("%s: ISAC MOSR %02x\n", isac->name, val);
262 #if ARCOFI_USE
263 	if (val & 0x08) {
264 		if (!isac->mon_rx) {
265 			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
266 			if (!isac->mon_rx) {
267 				pr_info("%s: ISAC MON RX out of memory!\n",
268 					isac->name);
269 				isac->mocr &= 0xf0;
270 				isac->mocr |= 0x0a;
271 				WriteISAC(isac, ISAC_MOCR, isac->mocr);
272 				goto afterMONR0;
273 			} else
274 				isac->mon_rxp = 0;
275 		}
276 		if (isac->mon_rxp >= MAX_MON_FRAME) {
277 			isac->mocr &= 0xf0;
278 			isac->mocr |= 0x0a;
279 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
280 			isac->mon_rxp = 0;
281 			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
282 			goto afterMONR0;
283 		}
284 		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR0);
285 		pr_debug("%s: ISAC MOR0 %02x\n", isac->name,
286 			 isac->mon_rx[isac->mon_rxp - 1]);
287 		if (isac->mon_rxp == 1) {
288 			isac->mocr |= 0x04;
289 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
290 		}
291 	}
292 afterMONR0:
293 	if (val & 0x80) {
294 		if (!isac->mon_rx) {
295 			isac->mon_rx = kmalloc(MAX_MON_FRAME, GFP_ATOMIC);
296 			if (!isac->mon_rx) {
297 				pr_info("%s: ISAC MON RX out of memory!\n",
298 					isac->name);
299 				isac->mocr &= 0x0f;
300 				isac->mocr |= 0xa0;
301 				WriteISAC(isac, ISAC_MOCR, isac->mocr);
302 				goto afterMONR1;
303 			} else
304 				isac->mon_rxp = 0;
305 		}
306 		if (isac->mon_rxp >= MAX_MON_FRAME) {
307 			isac->mocr &= 0x0f;
308 			isac->mocr |= 0xa0;
309 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
310 			isac->mon_rxp = 0;
311 			pr_debug("%s: ISAC MON RX overflow!\n", isac->name);
312 			goto afterMONR1;
313 		}
314 		isac->mon_rx[isac->mon_rxp++] = ReadISAC(isac, ISAC_MOR1);
315 		pr_debug("%s: ISAC MOR1 %02x\n", isac->name,
316 			 isac->mon_rx[isac->mon_rxp - 1]);
317 		isac->mocr |= 0x40;
318 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
319 	}
320 afterMONR1:
321 	if (val & 0x04) {
322 		isac->mocr &= 0xf0;
323 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
324 		isac->mocr |= 0x0a;
325 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
326 		if (isac->monitor) {
327 			ret = isac->monitor(isac->dch.hw, MONITOR_RX_0,
328 					    isac->mon_rx, isac->mon_rxp);
329 			if (ret)
330 				kfree(isac->mon_rx);
331 		} else {
332 			pr_info("%s: MONITOR 0 received %d but no user\n",
333 				isac->name, isac->mon_rxp);
334 			kfree(isac->mon_rx);
335 		}
336 		isac->mon_rx = NULL;
337 		isac->mon_rxp = 0;
338 	}
339 	if (val & 0x40) {
340 		isac->mocr &= 0x0f;
341 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
342 		isac->mocr |= 0xa0;
343 		WriteISAC(isac, ISAC_MOCR, isac->mocr);
344 		if (isac->monitor) {
345 			ret = isac->monitor(isac->dch.hw, MONITOR_RX_1,
346 					    isac->mon_rx, isac->mon_rxp);
347 			if (ret)
348 				kfree(isac->mon_rx);
349 		} else {
350 			pr_info("%s: MONITOR 1 received %d but no user\n",
351 				isac->name, isac->mon_rxp);
352 			kfree(isac->mon_rx);
353 		}
354 		isac->mon_rx = NULL;
355 		isac->mon_rxp = 0;
356 	}
357 	if (val & 0x02) {
358 		if ((!isac->mon_tx) || (isac->mon_txc &&
359 					(isac->mon_txp >= isac->mon_txc) && !(val & 0x08))) {
360 			isac->mocr &= 0xf0;
361 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
362 			isac->mocr |= 0x0a;
363 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
364 			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
365 				if (isac->monitor)
366 					ret = isac->monitor(isac->dch.hw,
367 							    MONITOR_TX_0, NULL, 0);
368 			}
369 			kfree(isac->mon_tx);
370 			isac->mon_tx = NULL;
371 			isac->mon_txc = 0;
372 			isac->mon_txp = 0;
373 			goto AfterMOX0;
374 		}
375 		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
376 			if (isac->monitor)
377 				ret = isac->monitor(isac->dch.hw,
378 						    MONITOR_TX_0, NULL, 0);
379 			kfree(isac->mon_tx);
380 			isac->mon_tx = NULL;
381 			isac->mon_txc = 0;
382 			isac->mon_txp = 0;
383 			goto AfterMOX0;
384 		}
385 		WriteISAC(isac, ISAC_MOX0, isac->mon_tx[isac->mon_txp++]);
386 		pr_debug("%s: ISAC %02x -> MOX0\n", isac->name,
387 			 isac->mon_tx[isac->mon_txp - 1]);
388 	}
389 AfterMOX0:
390 	if (val & 0x20) {
391 		if ((!isac->mon_tx) || (isac->mon_txc &&
392 					(isac->mon_txp >= isac->mon_txc) && !(val & 0x80))) {
393 			isac->mocr &= 0x0f;
394 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
395 			isac->mocr |= 0xa0;
396 			WriteISAC(isac, ISAC_MOCR, isac->mocr);
397 			if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
398 				if (isac->monitor)
399 					ret = isac->monitor(isac->dch.hw,
400 							    MONITOR_TX_1, NULL, 0);
401 			}
402 			kfree(isac->mon_tx);
403 			isac->mon_tx = NULL;
404 			isac->mon_txc = 0;
405 			isac->mon_txp = 0;
406 			goto AfterMOX1;
407 		}
408 		if (isac->mon_txc && (isac->mon_txp >= isac->mon_txc)) {
409 			if (isac->monitor)
410 				ret = isac->monitor(isac->dch.hw,
411 						    MONITOR_TX_1, NULL, 0);
412 			kfree(isac->mon_tx);
413 			isac->mon_tx = NULL;
414 			isac->mon_txc = 0;
415 			isac->mon_txp = 0;
416 			goto AfterMOX1;
417 		}
418 		WriteISAC(isac, ISAC_MOX1, isac->mon_tx[isac->mon_txp++]);
419 		pr_debug("%s: ISAC %02x -> MOX1\n", isac->name,
420 			 isac->mon_tx[isac->mon_txp - 1]);
421 	}
422 AfterMOX1:
423 	val = 0; /* dummy to avoid warning */
424 #endif
425 }
426 
427 static void
428 isac_cisq_irq(struct isac_hw *isac) {
429 	u8 val;
430 
431 	val = ReadISAC(isac, ISAC_CIR0);
432 	pr_debug("%s: ISAC CIR0 %02X\n", isac->name, val);
433 	if (val & 2) {
434 		pr_debug("%s: ph_state change %x->%x\n", isac->name,
435 			 isac->state, (val >> 2) & 0xf);
436 		isac->state = (val >> 2) & 0xf;
437 		isac_ph_state_change(isac);
438 	}
439 	if (val & 1) {
440 		val = ReadISAC(isac, ISAC_CIR1);
441 		pr_debug("%s: ISAC CIR1 %02X\n", isac->name, val);
442 	}
443 }
444 
445 static void
446 isacsx_cic_irq(struct isac_hw *isac)
447 {
448 	u8 val;
449 
450 	val = ReadISAC(isac, ISACX_CIR0);
451 	pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
452 	if (val & ISACX_CIR0_CIC0) {
453 		pr_debug("%s: ph_state change %x->%x\n", isac->name,
454 			 isac->state, val >> 4);
455 		isac->state = val >> 4;
456 		isac_ph_state_change(isac);
457 	}
458 }
459 
460 static void
461 isacsx_rme_irq(struct isac_hw *isac)
462 {
463 	int count;
464 	u8 val;
465 
466 	val = ReadISAC(isac, ISACX_RSTAD);
467 	if ((val & (ISACX_RSTAD_VFR |
468 		    ISACX_RSTAD_RDO |
469 		    ISACX_RSTAD_CRC |
470 		    ISACX_RSTAD_RAB))
471 	    != (ISACX_RSTAD_VFR | ISACX_RSTAD_CRC)) {
472 		pr_debug("%s: RSTAD %#x, dropped\n", isac->name, val);
473 #ifdef ERROR_STATISTIC
474 		if (val & ISACX_RSTAD_CRC)
475 			isac->dch.err_rx++;
476 		else
477 			isac->dch.err_crc++;
478 #endif
479 		WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
480 		if (isac->dch.rx_skb)
481 			dev_kfree_skb(isac->dch.rx_skb);
482 		isac->dch.rx_skb = NULL;
483 	} else {
484 		count = ReadISAC(isac, ISACX_RBCLD) & 0x1f;
485 		if (count == 0)
486 			count = 32;
487 		isac_empty_fifo(isac, count);
488 		if (isac->dch.rx_skb) {
489 			skb_trim(isac->dch.rx_skb, isac->dch.rx_skb->len - 1);
490 			pr_debug("%s: dchannel received %d\n", isac->name,
491 				 isac->dch.rx_skb->len);
492 			recv_Dchannel(&isac->dch);
493 		}
494 	}
495 }
496 
497 irqreturn_t
498 mISDNisac_irq(struct isac_hw *isac, u8 val)
499 {
500 	if (unlikely(!val))
501 		return IRQ_NONE;
502 	pr_debug("%s: ISAC interrupt %02x\n", isac->name, val);
503 	if (isac->type & IPAC_TYPE_ISACX) {
504 		if (val & ISACX__CIC)
505 			isacsx_cic_irq(isac);
506 		if (val & ISACX__ICD) {
507 			val = ReadISAC(isac, ISACX_ISTAD);
508 			pr_debug("%s: ISTAD %02x\n", isac->name, val);
509 			if (val & ISACX_D_XDU) {
510 				pr_debug("%s: ISAC XDU\n", isac->name);
511 #ifdef ERROR_STATISTIC
512 				isac->dch.err_tx++;
513 #endif
514 				isac_retransmit(isac);
515 			}
516 			if (val & ISACX_D_XMR) {
517 				pr_debug("%s: ISAC XMR\n", isac->name);
518 #ifdef ERROR_STATISTIC
519 				isac->dch.err_tx++;
520 #endif
521 				isac_retransmit(isac);
522 			}
523 			if (val & ISACX_D_XPR)
524 				isac_xpr_irq(isac);
525 			if (val & ISACX_D_RFO) {
526 				pr_debug("%s: ISAC RFO\n", isac->name);
527 				WriteISAC(isac, ISACX_CMDRD, ISACX_CMDRD_RMC);
528 			}
529 			if (val & ISACX_D_RME)
530 				isacsx_rme_irq(isac);
531 			if (val & ISACX_D_RPF)
532 				isac_empty_fifo(isac, 0x20);
533 		}
534 	} else {
535 		if (val & 0x80)	/* RME */
536 			isac_rme_irq(isac);
537 		if (val & 0x40)	/* RPF */
538 			isac_empty_fifo(isac, 32);
539 		if (val & 0x10)	/* XPR */
540 			isac_xpr_irq(isac);
541 		if (val & 0x04)	/* CISQ */
542 			isac_cisq_irq(isac);
543 		if (val & 0x20)	/* RSC - never */
544 			pr_debug("%s: ISAC RSC interrupt\n", isac->name);
545 		if (val & 0x02)	/* SIN - never */
546 			pr_debug("%s: ISAC SIN interrupt\n", isac->name);
547 		if (val & 0x01) {	/* EXI */
548 			val = ReadISAC(isac, ISAC_EXIR);
549 			pr_debug("%s: ISAC EXIR %02x\n", isac->name, val);
550 			if (val & 0x80)	/* XMR */
551 				pr_debug("%s: ISAC XMR\n", isac->name);
552 			if (val & 0x40) { /* XDU */
553 				pr_debug("%s: ISAC XDU\n", isac->name);
554 #ifdef ERROR_STATISTIC
555 				isac->dch.err_tx++;
556 #endif
557 				isac_retransmit(isac);
558 			}
559 			if (val & 0x04)	/* MOS */
560 				isac_mos_irq(isac);
561 		}
562 	}
563 	return IRQ_HANDLED;
564 }
565 EXPORT_SYMBOL(mISDNisac_irq);
566 
567 static int
568 isac_l1hw(struct mISDNchannel *ch, struct sk_buff *skb)
569 {
570 	struct mISDNdevice	*dev = container_of(ch, struct mISDNdevice, D);
571 	struct dchannel		*dch = container_of(dev, struct dchannel, dev);
572 	struct isac_hw		*isac = container_of(dch, struct isac_hw, dch);
573 	int			ret = -EINVAL;
574 	struct mISDNhead	*hh = mISDN_HEAD_P(skb);
575 	u32			id;
576 	u_long			flags;
577 
578 	switch (hh->prim) {
579 	case PH_DATA_REQ:
580 		spin_lock_irqsave(isac->hwlock, flags);
581 		ret = dchannel_senddata(dch, skb);
582 		if (ret > 0) { /* direct TX */
583 			id = hh->id; /* skb can be freed */
584 			isac_fill_fifo(isac);
585 			ret = 0;
586 			spin_unlock_irqrestore(isac->hwlock, flags);
587 			queue_ch_frame(ch, PH_DATA_CNF, id, NULL);
588 		} else
589 			spin_unlock_irqrestore(isac->hwlock, flags);
590 		return ret;
591 	case PH_ACTIVATE_REQ:
592 		ret = l1_event(dch->l1, hh->prim);
593 		break;
594 	case PH_DEACTIVATE_REQ:
595 		test_and_clear_bit(FLG_L2_ACTIVATED, &dch->Flags);
596 		ret = l1_event(dch->l1, hh->prim);
597 		break;
598 	}
599 
600 	if (!ret)
601 		dev_kfree_skb(skb);
602 	return ret;
603 }
604 
605 static int
606 isac_ctrl(struct isac_hw *isac, u32 cmd, unsigned long para)
607 {
608 	u8 tl = 0;
609 	unsigned long flags;
610 	int ret = 0;
611 
612 	switch (cmd) {
613 	case HW_TESTLOOP:
614 		spin_lock_irqsave(isac->hwlock, flags);
615 		if (!(isac->type & IPAC_TYPE_ISACX)) {
616 			/* TODO: implement for IPAC_TYPE_ISACX */
617 			if (para & 1) /* B1 */
618 				tl |= 0x0c;
619 			else if (para & 2) /* B2 */
620 				tl |= 0x3;
621 			/* we only support IOM2 mode */
622 			WriteISAC(isac, ISAC_SPCR, tl);
623 			if (tl)
624 				WriteISAC(isac, ISAC_ADF1, 0x8);
625 			else
626 				WriteISAC(isac, ISAC_ADF1, 0x0);
627 		}
628 		spin_unlock_irqrestore(isac->hwlock, flags);
629 		break;
630 	case HW_TIMER3_VALUE:
631 		ret = l1_event(isac->dch.l1, HW_TIMER3_VALUE | (para & 0xff));
632 		break;
633 	default:
634 		pr_debug("%s: %s unknown command %x %lx\n", isac->name,
635 			 __func__, cmd, para);
636 		ret = -1;
637 	}
638 	return ret;
639 }
640 
641 static int
642 isac_l1cmd(struct dchannel *dch, u32 cmd)
643 {
644 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
645 	u_long flags;
646 
647 	pr_debug("%s: cmd(%x) state(%02x)\n", isac->name, cmd, isac->state);
648 	switch (cmd) {
649 	case INFO3_P8:
650 		spin_lock_irqsave(isac->hwlock, flags);
651 		ph_command(isac, ISAC_CMD_AR8);
652 		spin_unlock_irqrestore(isac->hwlock, flags);
653 		break;
654 	case INFO3_P10:
655 		spin_lock_irqsave(isac->hwlock, flags);
656 		ph_command(isac, ISAC_CMD_AR10);
657 		spin_unlock_irqrestore(isac->hwlock, flags);
658 		break;
659 	case HW_RESET_REQ:
660 		spin_lock_irqsave(isac->hwlock, flags);
661 		if ((isac->state == ISAC_IND_EI) ||
662 		    (isac->state == ISAC_IND_DR) ||
663 		    (isac->state == ISAC_IND_RS))
664 			ph_command(isac, ISAC_CMD_TIM);
665 		else
666 			ph_command(isac, ISAC_CMD_RS);
667 		spin_unlock_irqrestore(isac->hwlock, flags);
668 		break;
669 	case HW_DEACT_REQ:
670 		skb_queue_purge(&dch->squeue);
671 		if (dch->tx_skb) {
672 			dev_kfree_skb(dch->tx_skb);
673 			dch->tx_skb = NULL;
674 		}
675 		dch->tx_idx = 0;
676 		if (dch->rx_skb) {
677 			dev_kfree_skb(dch->rx_skb);
678 			dch->rx_skb = NULL;
679 		}
680 		test_and_clear_bit(FLG_TX_BUSY, &dch->Flags);
681 		if (test_and_clear_bit(FLG_BUSY_TIMER, &dch->Flags))
682 			del_timer(&dch->timer);
683 		break;
684 	case HW_POWERUP_REQ:
685 		spin_lock_irqsave(isac->hwlock, flags);
686 		ph_command(isac, ISAC_CMD_TIM);
687 		spin_unlock_irqrestore(isac->hwlock, flags);
688 		break;
689 	case PH_ACTIVATE_IND:
690 		test_and_set_bit(FLG_ACTIVE, &dch->Flags);
691 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
692 			    GFP_ATOMIC);
693 		break;
694 	case PH_DEACTIVATE_IND:
695 		test_and_clear_bit(FLG_ACTIVE, &dch->Flags);
696 		_queue_data(&dch->dev.D, cmd, MISDN_ID_ANY, 0, NULL,
697 			    GFP_ATOMIC);
698 		break;
699 	default:
700 		pr_debug("%s: %s unknown command %x\n", isac->name,
701 			 __func__, cmd);
702 		return -1;
703 	}
704 	return 0;
705 }
706 
707 static void
708 isac_release(struct isac_hw *isac)
709 {
710 	if (isac->type & IPAC_TYPE_ISACX)
711 		WriteISAC(isac, ISACX_MASK, 0xff);
712 	else
713 		WriteISAC(isac, ISAC_MASK, 0xff);
714 	if (isac->dch.timer.function != NULL) {
715 		del_timer(&isac->dch.timer);
716 		isac->dch.timer.function = NULL;
717 	}
718 	kfree(isac->mon_rx);
719 	isac->mon_rx = NULL;
720 	kfree(isac->mon_tx);
721 	isac->mon_tx = NULL;
722 	if (isac->dch.l1)
723 		l1_event(isac->dch.l1, CLOSE_CHANNEL);
724 	mISDN_freedchannel(&isac->dch);
725 }
726 
727 static void
728 dbusy_timer_handler(struct isac_hw *isac)
729 {
730 	int rbch, star;
731 	u_long flags;
732 
733 	if (test_bit(FLG_BUSY_TIMER, &isac->dch.Flags)) {
734 		spin_lock_irqsave(isac->hwlock, flags);
735 		rbch = ReadISAC(isac, ISAC_RBCH);
736 		star = ReadISAC(isac, ISAC_STAR);
737 		pr_debug("%s: D-Channel Busy RBCH %02x STAR %02x\n",
738 			 isac->name, rbch, star);
739 		if (rbch & ISAC_RBCH_XAC) /* D-Channel Busy */
740 			test_and_set_bit(FLG_L1_BUSY, &isac->dch.Flags);
741 		else {
742 			/* discard frame; reset transceiver */
743 			test_and_clear_bit(FLG_BUSY_TIMER, &isac->dch.Flags);
744 			if (isac->dch.tx_idx)
745 				isac->dch.tx_idx = 0;
746 			else
747 				pr_info("%s: ISAC D-Channel Busy no tx_idx\n",
748 					isac->name);
749 			/* Transmitter reset */
750 			WriteISAC(isac, ISAC_CMDR, 0x01);
751 		}
752 		spin_unlock_irqrestore(isac->hwlock, flags);
753 	}
754 }
755 
756 static int
757 open_dchannel_caller(struct isac_hw *isac, struct channel_req *rq, void *caller)
758 {
759 	pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
760 		 isac->dch.dev.id, caller);
761 	if (rq->protocol != ISDN_P_TE_S0)
762 		return -EINVAL;
763 	if (rq->adr.channel == 1)
764 		/* E-Channel not supported */
765 		return -EINVAL;
766 	rq->ch = &isac->dch.dev.D;
767 	rq->ch->protocol = rq->protocol;
768 	if (isac->dch.state == 7)
769 		_queue_data(rq->ch, PH_ACTIVATE_IND, MISDN_ID_ANY,
770 			    0, NULL, GFP_KERNEL);
771 	return 0;
772 }
773 
774 static int
775 open_dchannel(struct isac_hw *isac, struct channel_req *rq)
776 {
777 	return open_dchannel_caller(isac, rq, __builtin_return_address(0));
778 }
779 
780 static const char *ISACVer[] =
781 {"2086/2186 V1.1", "2085 B1", "2085 B2",
782  "2085 V2.3"};
783 
784 static int
785 isac_init(struct isac_hw *isac)
786 {
787 	u8 val;
788 	int err = 0;
789 
790 	if (!isac->dch.l1) {
791 		err = create_l1(&isac->dch, isac_l1cmd);
792 		if (err)
793 			return err;
794 	}
795 	isac->mon_tx = NULL;
796 	isac->mon_rx = NULL;
797 	isac->dch.timer.function = (void *) dbusy_timer_handler;
798 	isac->dch.timer.data = (long)isac;
799 	init_timer(&isac->dch.timer);
800 	isac->mocr = 0xaa;
801 	if (isac->type & IPAC_TYPE_ISACX) {
802 		/* Disable all IRQ */
803 		WriteISAC(isac, ISACX_MASK, 0xff);
804 		val = ReadISAC(isac, ISACX_STARD);
805 		pr_debug("%s: ISACX STARD %x\n", isac->name, val);
806 		val = ReadISAC(isac, ISACX_ISTAD);
807 		pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
808 		val = ReadISAC(isac, ISACX_ISTA);
809 		pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
810 		/* clear LDD */
811 		WriteISAC(isac, ISACX_TR_CONF0, 0x00);
812 		/* enable transmitter */
813 		WriteISAC(isac, ISACX_TR_CONF2, 0x00);
814 		/* transparent mode 0, RAC, stop/go */
815 		WriteISAC(isac, ISACX_MODED, 0xc9);
816 		/* all HDLC IRQ unmasked */
817 		val = ReadISAC(isac, ISACX_ID);
818 		if (isac->dch.debug & DEBUG_HW)
819 			pr_notice("%s: ISACX Design ID %x\n",
820 				  isac->name, val & 0x3f);
821 		val = ReadISAC(isac, ISACX_CIR0);
822 		pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
823 		isac->state = val >> 4;
824 		isac_ph_state_change(isac);
825 		ph_command(isac, ISAC_CMD_RS);
826 		WriteISAC(isac, ISACX_MASK, IPACX__ON);
827 		WriteISAC(isac, ISACX_MASKD, 0x00);
828 	} else { /* old isac */
829 		WriteISAC(isac, ISAC_MASK, 0xff);
830 		val = ReadISAC(isac, ISAC_STAR);
831 		pr_debug("%s: ISAC STAR %x\n", isac->name, val);
832 		val = ReadISAC(isac, ISAC_MODE);
833 		pr_debug("%s: ISAC MODE %x\n", isac->name, val);
834 		val = ReadISAC(isac, ISAC_ADF2);
835 		pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
836 		val = ReadISAC(isac, ISAC_ISTA);
837 		pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
838 		if (val & 0x01) {
839 			val = ReadISAC(isac, ISAC_EXIR);
840 			pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
841 		}
842 		val = ReadISAC(isac, ISAC_RBCH);
843 		if (isac->dch.debug & DEBUG_HW)
844 			pr_notice("%s: ISAC version (%x): %s\n", isac->name,
845 				  val, ISACVer[(val >> 5) & 3]);
846 		isac->type |= ((val >> 5) & 3);
847 		if (!isac->adf2)
848 			isac->adf2 = 0x80;
849 		if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
850 			pr_info("%s: only support IOM2 mode but adf2=%02x\n",
851 				isac->name, isac->adf2);
852 			isac_release(isac);
853 			return -EINVAL;
854 		}
855 		WriteISAC(isac, ISAC_ADF2, isac->adf2);
856 		WriteISAC(isac, ISAC_SQXR, 0x2f);
857 		WriteISAC(isac, ISAC_SPCR, 0x00);
858 		WriteISAC(isac, ISAC_STCR, 0x70);
859 		WriteISAC(isac, ISAC_MODE, 0xc9);
860 		WriteISAC(isac, ISAC_TIMR, 0x00);
861 		WriteISAC(isac, ISAC_ADF1, 0x00);
862 		val = ReadISAC(isac, ISAC_CIR0);
863 		pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
864 		isac->state = (val >> 2) & 0xf;
865 		isac_ph_state_change(isac);
866 		ph_command(isac, ISAC_CMD_RS);
867 		WriteISAC(isac, ISAC_MASK, 0);
868 	}
869 	return err;
870 }
871 
872 int
873 mISDNisac_init(struct isac_hw *isac, void *hw)
874 {
875 	mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
876 	isac->dch.hw = hw;
877 	isac->dch.dev.D.send = isac_l1hw;
878 	isac->init = isac_init;
879 	isac->release = isac_release;
880 	isac->ctrl = isac_ctrl;
881 	isac->open = open_dchannel;
882 	isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
883 	isac->dch.dev.nrbchan = 2;
884 	return 0;
885 }
886 EXPORT_SYMBOL(mISDNisac_init);
887 
888 static void
889 waitforCEC(struct hscx_hw *hx)
890 {
891 	u8 starb, to = 50;
892 
893 	while (to) {
894 		starb = ReadHSCX(hx, IPAC_STARB);
895 		if (!(starb & 0x04))
896 			break;
897 		udelay(1);
898 		to--;
899 	}
900 	if (to < 50)
901 		pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
902 			 50 - to);
903 	if (!to)
904 		pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
905 }
906 
907 
908 static void
909 waitforXFW(struct hscx_hw *hx)
910 {
911 	u8 starb, to = 50;
912 
913 	while (to) {
914 		starb = ReadHSCX(hx, IPAC_STARB);
915 		if ((starb & 0x44) == 0x40)
916 			break;
917 		udelay(1);
918 		to--;
919 	}
920 	if (to < 50)
921 		pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
922 			 50 - to);
923 	if (!to)
924 		pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
925 }
926 
927 static void
928 hscx_cmdr(struct hscx_hw *hx, u8 cmd)
929 {
930 	if (hx->ip->type & IPAC_TYPE_IPACX)
931 		WriteHSCX(hx, IPACX_CMDRB, cmd);
932 	else {
933 		waitforCEC(hx);
934 		WriteHSCX(hx, IPAC_CMDRB, cmd);
935 	}
936 }
937 
938 static void
939 hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
940 {
941 	u8 *p;
942 	int maxlen;
943 
944 	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
945 	if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
946 		hscx->bch.dropcnt += count;
947 		hscx_cmdr(hscx, 0x80); /* RMC */
948 		return;
949 	}
950 	maxlen = bchannel_get_rxbuf(&hscx->bch, count);
951 	if (maxlen < 0) {
952 		hscx_cmdr(hscx, 0x80); /* RMC */
953 		if (hscx->bch.rx_skb)
954 			skb_trim(hscx->bch.rx_skb, 0);
955 		pr_warning("%s.B%d: No bufferspace for %d bytes\n",
956 			   hscx->ip->name, hscx->bch.nr, count);
957 		return;
958 	}
959 	p = skb_put(hscx->bch.rx_skb, count);
960 
961 	if (hscx->ip->type & IPAC_TYPE_IPACX)
962 		hscx->ip->read_fifo(hscx->ip->hw,
963 				    hscx->off + IPACX_RFIFOB, p, count);
964 	else
965 		hscx->ip->read_fifo(hscx->ip->hw,
966 				    hscx->off, p, count);
967 
968 	hscx_cmdr(hscx, 0x80); /* RMC */
969 
970 	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
971 		snprintf(hscx->log, 64, "B%1d-recv %s %d ",
972 			 hscx->bch.nr, hscx->ip->name, count);
973 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
974 	}
975 }
976 
977 static void
978 hscx_fill_fifo(struct hscx_hw *hscx)
979 {
980 	int count, more;
981 	u8 *p;
982 
983 	if (!hscx->bch.tx_skb) {
984 		if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
985 			return;
986 		count = hscx->fifo_size;
987 		more = 1;
988 		p = hscx->log;
989 		memset(p, hscx->bch.fill[0], count);
990 	} else {
991 		count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
992 		if (count <= 0)
993 			return;
994 		p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
995 
996 		more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
997 		if (count > hscx->fifo_size) {
998 			count = hscx->fifo_size;
999 			more = 1;
1000 		}
1001 		pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
1002 			 count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
1003 		hscx->bch.tx_idx += count;
1004 	}
1005 	if (hscx->ip->type & IPAC_TYPE_IPACX)
1006 		hscx->ip->write_fifo(hscx->ip->hw,
1007 				     hscx->off + IPACX_XFIFOB, p, count);
1008 	else {
1009 		waitforXFW(hscx);
1010 		hscx->ip->write_fifo(hscx->ip->hw,
1011 				     hscx->off, p, count);
1012 	}
1013 	hscx_cmdr(hscx, more ? 0x08 : 0x0a);
1014 
1015 	if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
1016 		snprintf(hscx->log, 64, "B%1d-send %s %d ",
1017 			 hscx->bch.nr, hscx->ip->name, count);
1018 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
1019 	}
1020 }
1021 
1022 static void
1023 hscx_xpr(struct hscx_hw *hx)
1024 {
1025 	if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) {
1026 		hscx_fill_fifo(hx);
1027 	} else {
1028 		if (hx->bch.tx_skb)
1029 			dev_kfree_skb(hx->bch.tx_skb);
1030 		if (get_next_bframe(&hx->bch)) {
1031 			hscx_fill_fifo(hx);
1032 			test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1033 		} else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
1034 			hscx_fill_fifo(hx);
1035 		}
1036 	}
1037 }
1038 
1039 static void
1040 ipac_rme(struct hscx_hw *hx)
1041 {
1042 	int count;
1043 	u8 rstab;
1044 
1045 	if (hx->ip->type & IPAC_TYPE_IPACX)
1046 		rstab = ReadHSCX(hx, IPACX_RSTAB);
1047 	else
1048 		rstab = ReadHSCX(hx, IPAC_RSTAB);
1049 	pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
1050 	if ((rstab & 0xf0) != 0xa0) {
1051 		/* !(VFR && !RDO && CRC && !RAB) */
1052 		if (!(rstab & 0x80)) {
1053 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1054 				pr_notice("%s: B%1d invalid frame\n",
1055 					  hx->ip->name, hx->bch.nr);
1056 		}
1057 		if (rstab & 0x40) {
1058 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1059 				pr_notice("%s: B%1d RDO proto=%x\n",
1060 					  hx->ip->name, hx->bch.nr,
1061 					  hx->bch.state);
1062 		}
1063 		if (!(rstab & 0x20)) {
1064 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1065 				pr_notice("%s: B%1d CRC error\n",
1066 					  hx->ip->name, hx->bch.nr);
1067 		}
1068 		hscx_cmdr(hx, 0x80); /* Do RMC */
1069 		return;
1070 	}
1071 	if (hx->ip->type & IPAC_TYPE_IPACX)
1072 		count = ReadHSCX(hx, IPACX_RBCLB);
1073 	else
1074 		count = ReadHSCX(hx, IPAC_RBCLB);
1075 	count &= (hx->fifo_size - 1);
1076 	if (count == 0)
1077 		count = hx->fifo_size;
1078 	hscx_empty_fifo(hx, count);
1079 	if (!hx->bch.rx_skb)
1080 		return;
1081 	if (hx->bch.rx_skb->len < 2) {
1082 		pr_debug("%s: B%1d frame to short %d\n",
1083 			 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
1084 		skb_trim(hx->bch.rx_skb, 0);
1085 	} else {
1086 		skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
1087 		recv_Bchannel(&hx->bch, 0, false);
1088 	}
1089 }
1090 
1091 static void
1092 ipac_irq(struct hscx_hw *hx, u8 ista)
1093 {
1094 	u8 istab, m, exirb = 0;
1095 
1096 	if (hx->ip->type & IPAC_TYPE_IPACX)
1097 		istab = ReadHSCX(hx, IPACX_ISTAB);
1098 	else if (hx->ip->type & IPAC_TYPE_IPAC) {
1099 		istab = ReadHSCX(hx, IPAC_ISTAB);
1100 		m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
1101 		if (m & ista) {
1102 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1103 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1104 				 hx->bch.nr, exirb);
1105 		}
1106 	} else if (hx->bch.nr & 2) { /* HSCX B */
1107 		if (ista & (HSCX__EXA | HSCX__ICA))
1108 			ipac_irq(&hx->ip->hscx[0], ista);
1109 		if (ista & HSCX__EXB) {
1110 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1111 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1112 				 hx->bch.nr, exirb);
1113 		}
1114 		istab = ista & 0xF8;
1115 	} else { /* HSCX A */
1116 		istab = ReadHSCX(hx, IPAC_ISTAB);
1117 		if (ista & HSCX__EXA) {
1118 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1119 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1120 				 hx->bch.nr, exirb);
1121 		}
1122 		istab = istab & 0xF8;
1123 	}
1124 	if (exirb & IPAC_B_XDU)
1125 		istab |= IPACX_B_XDU;
1126 	if (exirb & IPAC_B_RFO)
1127 		istab |= IPACX_B_RFO;
1128 	pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
1129 
1130 	if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
1131 		return;
1132 
1133 	if (istab & IPACX_B_RME)
1134 		ipac_rme(hx);
1135 
1136 	if (istab & IPACX_B_RPF) {
1137 		hscx_empty_fifo(hx, hx->fifo_size);
1138 		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
1139 			recv_Bchannel(&hx->bch, 0, false);
1140 	}
1141 
1142 	if (istab & IPACX_B_RFO) {
1143 		pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
1144 		hscx_cmdr(hx, 0x40);	/* RRES */
1145 	}
1146 
1147 	if (istab & IPACX_B_XPR)
1148 		hscx_xpr(hx);
1149 
1150 	if (istab & IPACX_B_XDU) {
1151 		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
1152 			if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
1153 				test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1154 			hscx_xpr(hx);
1155 			return;
1156 		}
1157 		pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
1158 			 hx->bch.nr, hx->bch.tx_idx);
1159 		hx->bch.tx_idx = 0;
1160 		hscx_cmdr(hx, 0x01);	/* XRES */
1161 	}
1162 }
1163 
1164 irqreturn_t
1165 mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
1166 {
1167 	int cnt = maxloop + 1;
1168 	u8 ista, istad;
1169 	struct isac_hw  *isac = &ipac->isac;
1170 
1171 	if (ipac->type & IPAC_TYPE_IPACX) {
1172 		ista = ReadIPAC(ipac, ISACX_ISTA);
1173 		while (ista && --cnt) {
1174 			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1175 			if (ista & IPACX__ICA)
1176 				ipac_irq(&ipac->hscx[0], ista);
1177 			if (ista & IPACX__ICB)
1178 				ipac_irq(&ipac->hscx[1], ista);
1179 			if (ista & (ISACX__ICD | ISACX__CIC))
1180 				mISDNisac_irq(&ipac->isac, ista);
1181 			ista = ReadIPAC(ipac, ISACX_ISTA);
1182 		}
1183 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1184 		ista = ReadIPAC(ipac, IPAC_ISTA);
1185 		while (ista && --cnt) {
1186 			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1187 			if (ista & (IPAC__ICD | IPAC__EXD)) {
1188 				istad = ReadISAC(isac, ISAC_ISTA);
1189 				pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1190 				if (istad & IPAC_D_TIN2)
1191 					pr_debug("%s TIN2 irq\n", ipac->name);
1192 				if (ista & IPAC__EXD)
1193 					istad |= 1; /* ISAC EXI */
1194 				mISDNisac_irq(isac, istad);
1195 			}
1196 			if (ista & (IPAC__ICA | IPAC__EXA))
1197 				ipac_irq(&ipac->hscx[0], ista);
1198 			if (ista & (IPAC__ICB | IPAC__EXB))
1199 				ipac_irq(&ipac->hscx[1], ista);
1200 			ista = ReadIPAC(ipac, IPAC_ISTA);
1201 		}
1202 	} else if (ipac->type & IPAC_TYPE_HSCX) {
1203 		while (--cnt) {
1204 			ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
1205 			pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
1206 			if (ista)
1207 				ipac_irq(&ipac->hscx[1], ista);
1208 			istad = ReadISAC(isac, ISAC_ISTA);
1209 			pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1210 			if (istad)
1211 				mISDNisac_irq(isac, istad);
1212 			if (0 == (ista | istad))
1213 				break;
1214 		}
1215 	}
1216 	if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
1217 		return IRQ_NONE;
1218 	if (cnt < maxloop)
1219 		pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
1220 			 maxloop - cnt, smp_processor_id());
1221 	if (maxloop && !cnt)
1222 		pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
1223 			  maxloop, smp_processor_id());
1224 	return IRQ_HANDLED;
1225 }
1226 EXPORT_SYMBOL(mISDNipac_irq);
1227 
1228 static int
1229 hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
1230 {
1231 	pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
1232 		 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
1233 	if (hscx->ip->type & IPAC_TYPE_IPACX) {
1234 		if (hscx->bch.nr & 1) { /* B1 and ICA */
1235 			WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
1236 			WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
1237 		} else { /* B2 and ICB */
1238 			WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
1239 			WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
1240 		}
1241 		switch (bprotocol) {
1242 		case ISDN_P_NONE: /* init */
1243 			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* rec off */
1244 			WriteHSCX(hscx, IPACX_EXMB,  0x30);	/* std adj. */
1245 			WriteHSCX(hscx, IPACX_MASKB, 0xFF);	/* ints off */
1246 			hscx_cmdr(hscx, 0x41);
1247 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1248 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1249 			break;
1250 		case ISDN_P_B_RAW:
1251 			WriteHSCX(hscx, IPACX_MODEB, 0x88);	/* ex trans */
1252 			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* trans */
1253 			hscx_cmdr(hscx, 0x41);
1254 			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1255 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1256 			break;
1257 		case ISDN_P_B_HDLC:
1258 			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* trans */
1259 			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* hdlc,crc */
1260 			hscx_cmdr(hscx, 0x41);
1261 			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1262 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1263 			break;
1264 		default:
1265 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1266 				bprotocol);
1267 			return -ENOPROTOOPT;
1268 		}
1269 	} else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
1270 		WriteHSCX(hscx, IPAC_CCR1, 0x82);
1271 		WriteHSCX(hscx, IPAC_CCR2, 0x30);
1272 		WriteHSCX(hscx, IPAC_XCCR, 0x07);
1273 		WriteHSCX(hscx, IPAC_RCCR, 0x07);
1274 		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1275 		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1276 		switch (bprotocol) {
1277 		case ISDN_P_NONE:
1278 			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1279 			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1280 			WriteHSCX(hscx, IPAC_MODEB, 0x84);
1281 			WriteHSCX(hscx, IPAC_CCR1, 0x82);
1282 			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
1283 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1284 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1285 			break;
1286 		case ISDN_P_B_RAW:
1287 			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
1288 			WriteHSCX(hscx, IPAC_CCR1, 0x82);
1289 			hscx_cmdr(hscx, 0x41);
1290 			WriteHSCX(hscx, IPAC_MASKB, 0);
1291 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1292 			break;
1293 		case ISDN_P_B_HDLC:
1294 			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1295 			WriteHSCX(hscx, IPAC_CCR1, 0x8a);
1296 			hscx_cmdr(hscx, 0x41);
1297 			WriteHSCX(hscx, IPAC_MASKB, 0);
1298 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1299 			break;
1300 		default:
1301 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1302 				bprotocol);
1303 			return -ENOPROTOOPT;
1304 		}
1305 	} else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
1306 		WriteHSCX(hscx, IPAC_CCR1, 0x85);
1307 		WriteHSCX(hscx, IPAC_CCR2, 0x30);
1308 		WriteHSCX(hscx, IPAC_XCCR, 0x07);
1309 		WriteHSCX(hscx, IPAC_RCCR, 0x07);
1310 		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1311 		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1312 		switch (bprotocol) {
1313 		case ISDN_P_NONE:
1314 			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1315 			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1316 			WriteHSCX(hscx, IPAC_MODEB, 0x84);
1317 			WriteHSCX(hscx, IPAC_CCR1, 0x85);
1318 			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
1319 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1320 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1321 			break;
1322 		case ISDN_P_B_RAW:
1323 			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
1324 			WriteHSCX(hscx, IPAC_CCR1, 0x85);
1325 			hscx_cmdr(hscx, 0x41);
1326 			WriteHSCX(hscx, IPAC_MASKB, 0);
1327 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1328 			break;
1329 		case ISDN_P_B_HDLC:
1330 			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1331 			WriteHSCX(hscx, IPAC_CCR1, 0x8d);
1332 			hscx_cmdr(hscx, 0x41);
1333 			WriteHSCX(hscx, IPAC_MASKB, 0);
1334 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1335 			break;
1336 		default:
1337 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1338 				bprotocol);
1339 			return -ENOPROTOOPT;
1340 		}
1341 	} else
1342 		return -EINVAL;
1343 	hscx->bch.state = bprotocol;
1344 	return 0;
1345 }
1346 
1347 static int
1348 hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1349 {
1350 	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1351 	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
1352 	int ret = -EINVAL;
1353 	struct mISDNhead *hh = mISDN_HEAD_P(skb);
1354 	unsigned long flags;
1355 
1356 	switch (hh->prim) {
1357 	case PH_DATA_REQ:
1358 		spin_lock_irqsave(hx->ip->hwlock, flags);
1359 		ret = bchannel_senddata(bch, skb);
1360 		if (ret > 0) { /* direct TX */
1361 			ret = 0;
1362 			hscx_fill_fifo(hx);
1363 		}
1364 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1365 		return ret;
1366 	case PH_ACTIVATE_REQ:
1367 		spin_lock_irqsave(hx->ip->hwlock, flags);
1368 		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1369 			ret = hscx_mode(hx, ch->protocol);
1370 		else
1371 			ret = 0;
1372 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1373 		if (!ret)
1374 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
1375 				    NULL, GFP_KERNEL);
1376 		break;
1377 	case PH_DEACTIVATE_REQ:
1378 		spin_lock_irqsave(hx->ip->hwlock, flags);
1379 		mISDN_clear_bchannel(bch);
1380 		hscx_mode(hx, ISDN_P_NONE);
1381 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1382 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
1383 			    NULL, GFP_KERNEL);
1384 		ret = 0;
1385 		break;
1386 	default:
1387 		pr_info("%s: %s unknown prim(%x,%x)\n",
1388 			hx->ip->name, __func__, hh->prim, hh->id);
1389 		ret = -EINVAL;
1390 	}
1391 	if (!ret)
1392 		dev_kfree_skb(skb);
1393 	return ret;
1394 }
1395 
1396 static int
1397 channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1398 {
1399 	return mISDN_ctrl_bchannel(bch, cq);
1400 }
1401 
1402 static int
1403 hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1404 {
1405 	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1406 	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
1407 	int ret = -EINVAL;
1408 	u_long flags;
1409 
1410 	pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
1411 	switch (cmd) {
1412 	case CLOSE_CHANNEL:
1413 		test_and_clear_bit(FLG_OPEN, &bch->Flags);
1414 		cancel_work_sync(&bch->workq);
1415 		spin_lock_irqsave(hx->ip->hwlock, flags);
1416 		mISDN_clear_bchannel(bch);
1417 		hscx_mode(hx, ISDN_P_NONE);
1418 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1419 		ch->protocol = ISDN_P_NONE;
1420 		ch->peer = NULL;
1421 		module_put(hx->ip->owner);
1422 		ret = 0;
1423 		break;
1424 	case CONTROL_CHANNEL:
1425 		ret = channel_bctrl(bch, arg);
1426 		break;
1427 	default:
1428 		pr_info("%s: %s unknown prim(%x)\n",
1429 			hx->ip->name, __func__, cmd);
1430 	}
1431 	return ret;
1432 }
1433 
1434 static void
1435 free_ipac(struct ipac_hw *ipac)
1436 {
1437 	isac_release(&ipac->isac);
1438 }
1439 
1440 static const char *HSCXVer[] =
1441 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1442  "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1443 
1444 
1445 
1446 static void
1447 hscx_init(struct hscx_hw *hx)
1448 {
1449 	u8 val;
1450 
1451 	WriteHSCX(hx, IPAC_RAH2, 0xFF);
1452 	WriteHSCX(hx, IPAC_XBCH, 0x00);
1453 	WriteHSCX(hx, IPAC_RLCR, 0x00);
1454 
1455 	if (hx->ip->type & IPAC_TYPE_HSCX) {
1456 		WriteHSCX(hx, IPAC_CCR1, 0x85);
1457 		val = ReadHSCX(hx, HSCX_VSTR);
1458 		pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
1459 		if (hx->bch.debug & DEBUG_HW)
1460 			pr_notice("%s: HSCX version %s\n", hx->ip->name,
1461 				  HSCXVer[val & 0x0f]);
1462 	} else
1463 		WriteHSCX(hx, IPAC_CCR1, 0x82);
1464 	WriteHSCX(hx, IPAC_CCR2, 0x30);
1465 	WriteHSCX(hx, IPAC_XCCR, 0x07);
1466 	WriteHSCX(hx, IPAC_RCCR, 0x07);
1467 }
1468 
1469 static int
1470 ipac_init(struct ipac_hw *ipac)
1471 {
1472 	u8 val;
1473 
1474 	if (ipac->type & IPAC_TYPE_HSCX) {
1475 		hscx_init(&ipac->hscx[0]);
1476 		hscx_init(&ipac->hscx[1]);
1477 		val = ReadIPAC(ipac, IPAC_ID);
1478 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1479 		hscx_init(&ipac->hscx[0]);
1480 		hscx_init(&ipac->hscx[1]);
1481 		WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
1482 		val = ReadIPAC(ipac, IPAC_CONF);
1483 		/* conf is default 0, but can be overwritten by card setup */
1484 		pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
1485 			 val, ipac->conf);
1486 		WriteIPAC(ipac, IPAC_CONF, ipac->conf);
1487 		val = ReadIPAC(ipac, IPAC_ID);
1488 		if (ipac->hscx[0].bch.debug & DEBUG_HW)
1489 			pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
1490 	}
1491 	/* nothing special for IPACX to do here */
1492 	return isac_init(&ipac->isac);
1493 }
1494 
1495 static int
1496 open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
1497 {
1498 	struct bchannel		*bch;
1499 
1500 	if (rq->adr.channel == 0 || rq->adr.channel > 2)
1501 		return -EINVAL;
1502 	if (rq->protocol == ISDN_P_NONE)
1503 		return -EINVAL;
1504 	bch = &ipac->hscx[rq->adr.channel - 1].bch;
1505 	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1506 		return -EBUSY; /* b-channel can be only open once */
1507 	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1508 	bch->ch.protocol = rq->protocol;
1509 	rq->ch = &bch->ch;
1510 	return 0;
1511 }
1512 
1513 static int
1514 channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
1515 {
1516 	int	ret = 0;
1517 
1518 	switch (cq->op) {
1519 	case MISDN_CTRL_GETOP:
1520 		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
1521 		break;
1522 	case MISDN_CTRL_LOOP:
1523 		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
1524 		if (cq->channel < 0 || cq->channel > 3) {
1525 			ret = -EINVAL;
1526 			break;
1527 		}
1528 		ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
1529 		break;
1530 	case MISDN_CTRL_L1_TIMER3:
1531 		ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1);
1532 		break;
1533 	default:
1534 		pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
1535 		ret = -EINVAL;
1536 		break;
1537 	}
1538 	return ret;
1539 }
1540 
1541 static int
1542 ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1543 {
1544 	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1545 	struct dchannel *dch = container_of(dev, struct dchannel, dev);
1546 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
1547 	struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
1548 	struct channel_req *rq;
1549 	int err = 0;
1550 
1551 	pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
1552 	switch (cmd) {
1553 	case OPEN_CHANNEL:
1554 		rq = arg;
1555 		if (rq->protocol == ISDN_P_TE_S0)
1556 			err = open_dchannel_caller(isac, rq, __builtin_return_address(0));
1557 		else
1558 			err = open_bchannel(ipac, rq);
1559 		if (err)
1560 			break;
1561 		if (!try_module_get(ipac->owner))
1562 			pr_info("%s: cannot get module\n", ipac->name);
1563 		break;
1564 	case CLOSE_CHANNEL:
1565 		pr_debug("%s: dev(%d) close from %p\n", ipac->name,
1566 			 dch->dev.id, __builtin_return_address(0));
1567 		module_put(ipac->owner);
1568 		break;
1569 	case CONTROL_CHANNEL:
1570 		err = channel_ctrl(ipac, arg);
1571 		break;
1572 	default:
1573 		pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
1574 		return -EINVAL;
1575 	}
1576 	return err;
1577 }
1578 
1579 u32
1580 mISDNipac_init(struct ipac_hw *ipac, void *hw)
1581 {
1582 	u32 ret;
1583 	u8 i;
1584 
1585 	ipac->hw = hw;
1586 	if (ipac->isac.dch.debug & DEBUG_HW)
1587 		pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
1588 	if (ipac->type & IPAC_TYPE_HSCX) {
1589 		ipac->isac.type = IPAC_TYPE_ISAC;
1590 		ipac->hscx[0].off = 0;
1591 		ipac->hscx[1].off = 0x40;
1592 		ipac->hscx[0].fifo_size = 32;
1593 		ipac->hscx[1].fifo_size = 32;
1594 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1595 		ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
1596 		ipac->hscx[0].off = 0;
1597 		ipac->hscx[1].off = 0x40;
1598 		ipac->hscx[0].fifo_size = 64;
1599 		ipac->hscx[1].fifo_size = 64;
1600 	} else if (ipac->type & IPAC_TYPE_IPACX) {
1601 		ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
1602 		ipac->hscx[0].off = IPACX_OFF_ICA;
1603 		ipac->hscx[1].off = IPACX_OFF_ICB;
1604 		ipac->hscx[0].fifo_size = 64;
1605 		ipac->hscx[1].fifo_size = 64;
1606 	} else
1607 		return 0;
1608 
1609 	mISDNisac_init(&ipac->isac, hw);
1610 
1611 	ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
1612 
1613 	for (i = 0; i < 2; i++) {
1614 		ipac->hscx[i].bch.nr = i + 1;
1615 		set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
1616 		list_add(&ipac->hscx[i].bch.ch.list,
1617 			 &ipac->isac.dch.dev.bchannels);
1618 		mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
1619 				   ipac->hscx[i].fifo_size);
1620 		ipac->hscx[i].bch.ch.nr = i + 1;
1621 		ipac->hscx[i].bch.ch.send = &hscx_l2l1;
1622 		ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
1623 		ipac->hscx[i].bch.hw = hw;
1624 		ipac->hscx[i].ip = ipac;
1625 		/* default values for IOM time slots
1626 		 * can be overwriten by card */
1627 		ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
1628 	}
1629 
1630 	ipac->init = ipac_init;
1631 	ipac->release = free_ipac;
1632 
1633 	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1634 		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1635 	return ret;
1636 }
1637 EXPORT_SYMBOL(mISDNipac_init);
1638 
1639 static int __init
1640 isac_mod_init(void)
1641 {
1642 	pr_notice("mISDNipac module version %s\n", ISAC_REV);
1643 	return 0;
1644 }
1645 
1646 static void __exit
1647 isac_mod_cleanup(void)
1648 {
1649 	pr_notice("mISDNipac module unloaded\n");
1650 }
1651 module_init(isac_mod_init);
1652 module_exit(isac_mod_cleanup);
1653