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(struct isac_hw *isac, struct channel_req *rq)
758 {
759 	pr_debug("%s: %s dev(%d) open from %p\n", isac->name, __func__,
760 		 isac->dch.dev.id, __builtin_return_address(1));
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 const char *ISACVer[] =
775 {"2086/2186 V1.1", "2085 B1", "2085 B2",
776  "2085 V2.3"};
777 
778 static int
779 isac_init(struct isac_hw *isac)
780 {
781 	u8 val;
782 	int err = 0;
783 
784 	if (!isac->dch.l1) {
785 		err = create_l1(&isac->dch, isac_l1cmd);
786 		if (err)
787 			return err;
788 	}
789 	isac->mon_tx = NULL;
790 	isac->mon_rx = NULL;
791 	isac->dch.timer.function = (void *) dbusy_timer_handler;
792 	isac->dch.timer.data = (long)isac;
793 	init_timer(&isac->dch.timer);
794 	isac->mocr = 0xaa;
795 	if (isac->type & IPAC_TYPE_ISACX) {
796 		/* Disable all IRQ */
797 		WriteISAC(isac, ISACX_MASK, 0xff);
798 		val = ReadISAC(isac, ISACX_STARD);
799 		pr_debug("%s: ISACX STARD %x\n", isac->name, val);
800 		val = ReadISAC(isac, ISACX_ISTAD);
801 		pr_debug("%s: ISACX ISTAD %x\n", isac->name, val);
802 		val = ReadISAC(isac, ISACX_ISTA);
803 		pr_debug("%s: ISACX ISTA %x\n", isac->name, val);
804 		/* clear LDD */
805 		WriteISAC(isac, ISACX_TR_CONF0, 0x00);
806 		/* enable transmitter */
807 		WriteISAC(isac, ISACX_TR_CONF2, 0x00);
808 		/* transparent mode 0, RAC, stop/go */
809 		WriteISAC(isac, ISACX_MODED, 0xc9);
810 		/* all HDLC IRQ unmasked */
811 		val = ReadISAC(isac, ISACX_ID);
812 		if (isac->dch.debug & DEBUG_HW)
813 			pr_notice("%s: ISACX Design ID %x\n",
814 				  isac->name, val & 0x3f);
815 		val = ReadISAC(isac, ISACX_CIR0);
816 		pr_debug("%s: ISACX CIR0 %02X\n", isac->name, val);
817 		isac->state = val >> 4;
818 		isac_ph_state_change(isac);
819 		ph_command(isac, ISAC_CMD_RS);
820 		WriteISAC(isac, ISACX_MASK, IPACX__ON);
821 		WriteISAC(isac, ISACX_MASKD, 0x00);
822 	} else { /* old isac */
823 		WriteISAC(isac, ISAC_MASK, 0xff);
824 		val = ReadISAC(isac, ISAC_STAR);
825 		pr_debug("%s: ISAC STAR %x\n", isac->name, val);
826 		val = ReadISAC(isac, ISAC_MODE);
827 		pr_debug("%s: ISAC MODE %x\n", isac->name, val);
828 		val = ReadISAC(isac, ISAC_ADF2);
829 		pr_debug("%s: ISAC ADF2 %x\n", isac->name, val);
830 		val = ReadISAC(isac, ISAC_ISTA);
831 		pr_debug("%s: ISAC ISTA %x\n", isac->name, val);
832 		if (val & 0x01) {
833 			val = ReadISAC(isac, ISAC_EXIR);
834 			pr_debug("%s: ISAC EXIR %x\n", isac->name, val);
835 		}
836 		val = ReadISAC(isac, ISAC_RBCH);
837 		if (isac->dch.debug & DEBUG_HW)
838 			pr_notice("%s: ISAC version (%x): %s\n", isac->name,
839 				  val, ISACVer[(val >> 5) & 3]);
840 		isac->type |= ((val >> 5) & 3);
841 		if (!isac->adf2)
842 			isac->adf2 = 0x80;
843 		if (!(isac->adf2 & 0x80)) { /* only IOM 2 Mode */
844 			pr_info("%s: only support IOM2 mode but adf2=%02x\n",
845 				isac->name, isac->adf2);
846 			isac_release(isac);
847 			return -EINVAL;
848 		}
849 		WriteISAC(isac, ISAC_ADF2, isac->adf2);
850 		WriteISAC(isac, ISAC_SQXR, 0x2f);
851 		WriteISAC(isac, ISAC_SPCR, 0x00);
852 		WriteISAC(isac, ISAC_STCR, 0x70);
853 		WriteISAC(isac, ISAC_MODE, 0xc9);
854 		WriteISAC(isac, ISAC_TIMR, 0x00);
855 		WriteISAC(isac, ISAC_ADF1, 0x00);
856 		val = ReadISAC(isac, ISAC_CIR0);
857 		pr_debug("%s: ISAC CIR0 %x\n", isac->name, val);
858 		isac->state = (val >> 2) & 0xf;
859 		isac_ph_state_change(isac);
860 		ph_command(isac, ISAC_CMD_RS);
861 		WriteISAC(isac, ISAC_MASK, 0);
862 	}
863 	return err;
864 }
865 
866 int
867 mISDNisac_init(struct isac_hw *isac, void *hw)
868 {
869 	mISDN_initdchannel(&isac->dch, MAX_DFRAME_LEN_L1, isac_ph_state_bh);
870 	isac->dch.hw = hw;
871 	isac->dch.dev.D.send = isac_l1hw;
872 	isac->init = isac_init;
873 	isac->release = isac_release;
874 	isac->ctrl = isac_ctrl;
875 	isac->open = open_dchannel;
876 	isac->dch.dev.Dprotocols = (1 << ISDN_P_TE_S0);
877 	isac->dch.dev.nrbchan = 2;
878 	return 0;
879 }
880 EXPORT_SYMBOL(mISDNisac_init);
881 
882 static void
883 waitforCEC(struct hscx_hw *hx)
884 {
885 	u8 starb, to = 50;
886 
887 	while (to) {
888 		starb = ReadHSCX(hx, IPAC_STARB);
889 		if (!(starb & 0x04))
890 			break;
891 		udelay(1);
892 		to--;
893 	}
894 	if (to < 50)
895 		pr_debug("%s: B%1d CEC %d us\n", hx->ip->name, hx->bch.nr,
896 			 50 - to);
897 	if (!to)
898 		pr_info("%s: B%1d CEC timeout\n", hx->ip->name, hx->bch.nr);
899 }
900 
901 
902 static void
903 waitforXFW(struct hscx_hw *hx)
904 {
905 	u8 starb, to = 50;
906 
907 	while (to) {
908 		starb = ReadHSCX(hx, IPAC_STARB);
909 		if ((starb & 0x44) == 0x40)
910 			break;
911 		udelay(1);
912 		to--;
913 	}
914 	if (to < 50)
915 		pr_debug("%s: B%1d XFW %d us\n", hx->ip->name, hx->bch.nr,
916 			 50 - to);
917 	if (!to)
918 		pr_info("%s: B%1d XFW timeout\n", hx->ip->name, hx->bch.nr);
919 }
920 
921 static void
922 hscx_cmdr(struct hscx_hw *hx, u8 cmd)
923 {
924 	if (hx->ip->type & IPAC_TYPE_IPACX)
925 		WriteHSCX(hx, IPACX_CMDRB, cmd);
926 	else {
927 		waitforCEC(hx);
928 		WriteHSCX(hx, IPAC_CMDRB, cmd);
929 	}
930 }
931 
932 static void
933 hscx_empty_fifo(struct hscx_hw *hscx, u8 count)
934 {
935 	u8 *p;
936 	int maxlen;
937 
938 	pr_debug("%s: B%1d %d\n", hscx->ip->name, hscx->bch.nr, count);
939 	if (test_bit(FLG_RX_OFF, &hscx->bch.Flags)) {
940 		hscx->bch.dropcnt += count;
941 		hscx_cmdr(hscx, 0x80); /* RMC */
942 		return;
943 	}
944 	maxlen = bchannel_get_rxbuf(&hscx->bch, count);
945 	if (maxlen < 0) {
946 		hscx_cmdr(hscx, 0x80); /* RMC */
947 		if (hscx->bch.rx_skb)
948 			skb_trim(hscx->bch.rx_skb, 0);
949 		pr_warning("%s.B%d: No bufferspace for %d bytes\n",
950 			   hscx->ip->name, hscx->bch.nr, count);
951 		return;
952 	}
953 	p = skb_put(hscx->bch.rx_skb, count);
954 
955 	if (hscx->ip->type & IPAC_TYPE_IPACX)
956 		hscx->ip->read_fifo(hscx->ip->hw,
957 				    hscx->off + IPACX_RFIFOB, p, count);
958 	else
959 		hscx->ip->read_fifo(hscx->ip->hw,
960 				    hscx->off, p, count);
961 
962 	hscx_cmdr(hscx, 0x80); /* RMC */
963 
964 	if (hscx->bch.debug & DEBUG_HW_BFIFO) {
965 		snprintf(hscx->log, 64, "B%1d-recv %s %d ",
966 			 hscx->bch.nr, hscx->ip->name, count);
967 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
968 	}
969 }
970 
971 static void
972 hscx_fill_fifo(struct hscx_hw *hscx)
973 {
974 	int count, more;
975 	u8 *p;
976 
977 	if (!hscx->bch.tx_skb) {
978 		if (!test_bit(FLG_TX_EMPTY, &hscx->bch.Flags))
979 			return;
980 		count = hscx->fifo_size;
981 		more = 1;
982 		p = hscx->log;
983 		memset(p, hscx->bch.fill[0], count);
984 	} else {
985 		count = hscx->bch.tx_skb->len - hscx->bch.tx_idx;
986 		if (count <= 0)
987 			return;
988 		p = hscx->bch.tx_skb->data + hscx->bch.tx_idx;
989 
990 		more = test_bit(FLG_TRANSPARENT, &hscx->bch.Flags) ? 1 : 0;
991 		if (count > hscx->fifo_size) {
992 			count = hscx->fifo_size;
993 			more = 1;
994 		}
995 		pr_debug("%s: B%1d %d/%d/%d\n", hscx->ip->name, hscx->bch.nr,
996 			 count, hscx->bch.tx_idx, hscx->bch.tx_skb->len);
997 		hscx->bch.tx_idx += count;
998 	}
999 	if (hscx->ip->type & IPAC_TYPE_IPACX)
1000 		hscx->ip->write_fifo(hscx->ip->hw,
1001 				     hscx->off + IPACX_XFIFOB, p, count);
1002 	else {
1003 		waitforXFW(hscx);
1004 		hscx->ip->write_fifo(hscx->ip->hw,
1005 				     hscx->off, p, count);
1006 	}
1007 	hscx_cmdr(hscx, more ? 0x08 : 0x0a);
1008 
1009 	if (hscx->bch.tx_skb && (hscx->bch.debug & DEBUG_HW_BFIFO)) {
1010 		snprintf(hscx->log, 64, "B%1d-send %s %d ",
1011 			 hscx->bch.nr, hscx->ip->name, count);
1012 		print_hex_dump_bytes(hscx->log, DUMP_PREFIX_OFFSET, p, count);
1013 	}
1014 }
1015 
1016 static void
1017 hscx_xpr(struct hscx_hw *hx)
1018 {
1019 	if (hx->bch.tx_skb && hx->bch.tx_idx < hx->bch.tx_skb->len) {
1020 		hscx_fill_fifo(hx);
1021 	} else {
1022 		if (hx->bch.tx_skb)
1023 			dev_kfree_skb(hx->bch.tx_skb);
1024 		if (get_next_bframe(&hx->bch)) {
1025 			hscx_fill_fifo(hx);
1026 			test_and_clear_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1027 		} else if (test_bit(FLG_TX_EMPTY, &hx->bch.Flags)) {
1028 			hscx_fill_fifo(hx);
1029 		}
1030 	}
1031 }
1032 
1033 static void
1034 ipac_rme(struct hscx_hw *hx)
1035 {
1036 	int count;
1037 	u8 rstab;
1038 
1039 	if (hx->ip->type & IPAC_TYPE_IPACX)
1040 		rstab = ReadHSCX(hx, IPACX_RSTAB);
1041 	else
1042 		rstab = ReadHSCX(hx, IPAC_RSTAB);
1043 	pr_debug("%s: B%1d RSTAB %02x\n", hx->ip->name, hx->bch.nr, rstab);
1044 	if ((rstab & 0xf0) != 0xa0) {
1045 		/* !(VFR && !RDO && CRC && !RAB) */
1046 		if (!(rstab & 0x80)) {
1047 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1048 				pr_notice("%s: B%1d invalid frame\n",
1049 					  hx->ip->name, hx->bch.nr);
1050 		}
1051 		if (rstab & 0x40) {
1052 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1053 				pr_notice("%s: B%1d RDO proto=%x\n",
1054 					  hx->ip->name, hx->bch.nr,
1055 					  hx->bch.state);
1056 		}
1057 		if (!(rstab & 0x20)) {
1058 			if (hx->bch.debug & DEBUG_HW_BCHANNEL)
1059 				pr_notice("%s: B%1d CRC error\n",
1060 					  hx->ip->name, hx->bch.nr);
1061 		}
1062 		hscx_cmdr(hx, 0x80); /* Do RMC */
1063 		return;
1064 	}
1065 	if (hx->ip->type & IPAC_TYPE_IPACX)
1066 		count = ReadHSCX(hx, IPACX_RBCLB);
1067 	else
1068 		count = ReadHSCX(hx, IPAC_RBCLB);
1069 	count &= (hx->fifo_size - 1);
1070 	if (count == 0)
1071 		count = hx->fifo_size;
1072 	hscx_empty_fifo(hx, count);
1073 	if (!hx->bch.rx_skb)
1074 		return;
1075 	if (hx->bch.rx_skb->len < 2) {
1076 		pr_debug("%s: B%1d frame to short %d\n",
1077 			 hx->ip->name, hx->bch.nr, hx->bch.rx_skb->len);
1078 		skb_trim(hx->bch.rx_skb, 0);
1079 	} else {
1080 		skb_trim(hx->bch.rx_skb, hx->bch.rx_skb->len - 1);
1081 		recv_Bchannel(&hx->bch, 0, false);
1082 	}
1083 }
1084 
1085 static void
1086 ipac_irq(struct hscx_hw *hx, u8 ista)
1087 {
1088 	u8 istab, m, exirb = 0;
1089 
1090 	if (hx->ip->type & IPAC_TYPE_IPACX)
1091 		istab = ReadHSCX(hx, IPACX_ISTAB);
1092 	else if (hx->ip->type & IPAC_TYPE_IPAC) {
1093 		istab = ReadHSCX(hx, IPAC_ISTAB);
1094 		m = (hx->bch.nr & 1) ? IPAC__EXA : IPAC__EXB;
1095 		if (m & ista) {
1096 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1097 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1098 				 hx->bch.nr, exirb);
1099 		}
1100 	} else if (hx->bch.nr & 2) { /* HSCX B */
1101 		if (ista & (HSCX__EXA | HSCX__ICA))
1102 			ipac_irq(&hx->ip->hscx[0], ista);
1103 		if (ista & HSCX__EXB) {
1104 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1105 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1106 				 hx->bch.nr, exirb);
1107 		}
1108 		istab = ista & 0xF8;
1109 	} else { /* HSCX A */
1110 		istab = ReadHSCX(hx, IPAC_ISTAB);
1111 		if (ista & HSCX__EXA) {
1112 			exirb = ReadHSCX(hx, IPAC_EXIRB);
1113 			pr_debug("%s: B%1d EXIRB %02x\n", hx->ip->name,
1114 				 hx->bch.nr, exirb);
1115 		}
1116 		istab = istab & 0xF8;
1117 	}
1118 	if (exirb & IPAC_B_XDU)
1119 		istab |= IPACX_B_XDU;
1120 	if (exirb & IPAC_B_RFO)
1121 		istab |= IPACX_B_RFO;
1122 	pr_debug("%s: B%1d ISTAB %02x\n", hx->ip->name, hx->bch.nr, istab);
1123 
1124 	if (!test_bit(FLG_ACTIVE, &hx->bch.Flags))
1125 		return;
1126 
1127 	if (istab & IPACX_B_RME)
1128 		ipac_rme(hx);
1129 
1130 	if (istab & IPACX_B_RPF) {
1131 		hscx_empty_fifo(hx, hx->fifo_size);
1132 		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags))
1133 			recv_Bchannel(&hx->bch, 0, false);
1134 	}
1135 
1136 	if (istab & IPACX_B_RFO) {
1137 		pr_debug("%s: B%1d RFO error\n", hx->ip->name, hx->bch.nr);
1138 		hscx_cmdr(hx, 0x40);	/* RRES */
1139 	}
1140 
1141 	if (istab & IPACX_B_XPR)
1142 		hscx_xpr(hx);
1143 
1144 	if (istab & IPACX_B_XDU) {
1145 		if (test_bit(FLG_TRANSPARENT, &hx->bch.Flags)) {
1146 			if (test_bit(FLG_FILLEMPTY, &hx->bch.Flags))
1147 				test_and_set_bit(FLG_TX_EMPTY, &hx->bch.Flags);
1148 			hscx_xpr(hx);
1149 			return;
1150 		}
1151 		pr_debug("%s: B%1d XDU error at len %d\n", hx->ip->name,
1152 			 hx->bch.nr, hx->bch.tx_idx);
1153 		hx->bch.tx_idx = 0;
1154 		hscx_cmdr(hx, 0x01);	/* XRES */
1155 	}
1156 }
1157 
1158 irqreturn_t
1159 mISDNipac_irq(struct ipac_hw *ipac, int maxloop)
1160 {
1161 	int cnt = maxloop + 1;
1162 	u8 ista, istad;
1163 	struct isac_hw  *isac = &ipac->isac;
1164 
1165 	if (ipac->type & IPAC_TYPE_IPACX) {
1166 		ista = ReadIPAC(ipac, ISACX_ISTA);
1167 		while (ista && cnt--) {
1168 			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1169 			if (ista & IPACX__ICA)
1170 				ipac_irq(&ipac->hscx[0], ista);
1171 			if (ista & IPACX__ICB)
1172 				ipac_irq(&ipac->hscx[1], ista);
1173 			if (ista & (ISACX__ICD | ISACX__CIC))
1174 				mISDNisac_irq(&ipac->isac, ista);
1175 			ista = ReadIPAC(ipac, ISACX_ISTA);
1176 		}
1177 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1178 		ista = ReadIPAC(ipac, IPAC_ISTA);
1179 		while (ista && cnt--) {
1180 			pr_debug("%s: ISTA %02x\n", ipac->name, ista);
1181 			if (ista & (IPAC__ICD | IPAC__EXD)) {
1182 				istad = ReadISAC(isac, ISAC_ISTA);
1183 				pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1184 				if (istad & IPAC_D_TIN2)
1185 					pr_debug("%s TIN2 irq\n", ipac->name);
1186 				if (ista & IPAC__EXD)
1187 					istad |= 1; /* ISAC EXI */
1188 				mISDNisac_irq(isac, istad);
1189 			}
1190 			if (ista & (IPAC__ICA | IPAC__EXA))
1191 				ipac_irq(&ipac->hscx[0], ista);
1192 			if (ista & (IPAC__ICB | IPAC__EXB))
1193 				ipac_irq(&ipac->hscx[1], ista);
1194 			ista = ReadIPAC(ipac, IPAC_ISTA);
1195 		}
1196 	} else if (ipac->type & IPAC_TYPE_HSCX) {
1197 		while (cnt) {
1198 			ista = ReadIPAC(ipac, IPAC_ISTAB + ipac->hscx[1].off);
1199 			pr_debug("%s: B2 ISTA %02x\n", ipac->name, ista);
1200 			if (ista)
1201 				ipac_irq(&ipac->hscx[1], ista);
1202 			istad = ReadISAC(isac, ISAC_ISTA);
1203 			pr_debug("%s: ISTAD %02x\n", ipac->name, istad);
1204 			if (istad)
1205 				mISDNisac_irq(isac, istad);
1206 			if (0 == (ista | istad))
1207 				break;
1208 			cnt--;
1209 		}
1210 	}
1211 	if (cnt > maxloop) /* only for ISAC/HSCX without PCI IRQ test */
1212 		return IRQ_NONE;
1213 	if (cnt < maxloop)
1214 		pr_debug("%s: %d irqloops cpu%d\n", ipac->name,
1215 			 maxloop - cnt, smp_processor_id());
1216 	if (maxloop && !cnt)
1217 		pr_notice("%s: %d IRQ LOOP cpu%d\n", ipac->name,
1218 			  maxloop, smp_processor_id());
1219 	return IRQ_HANDLED;
1220 }
1221 EXPORT_SYMBOL(mISDNipac_irq);
1222 
1223 static int
1224 hscx_mode(struct hscx_hw *hscx, u32 bprotocol)
1225 {
1226 	pr_debug("%s: HSCX %c protocol %x-->%x ch %d\n", hscx->ip->name,
1227 		 '@' + hscx->bch.nr, hscx->bch.state, bprotocol, hscx->bch.nr);
1228 	if (hscx->ip->type & IPAC_TYPE_IPACX) {
1229 		if (hscx->bch.nr & 1) { /* B1 and ICA */
1230 			WriteIPAC(hscx->ip, ISACX_BCHA_TSDP_BC1, 0x80);
1231 			WriteIPAC(hscx->ip, ISACX_BCHA_CR, 0x88);
1232 		} else { /* B2 and ICB */
1233 			WriteIPAC(hscx->ip, ISACX_BCHB_TSDP_BC1, 0x81);
1234 			WriteIPAC(hscx->ip, ISACX_BCHB_CR, 0x88);
1235 		}
1236 		switch (bprotocol) {
1237 		case ISDN_P_NONE: /* init */
1238 			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* rec off */
1239 			WriteHSCX(hscx, IPACX_EXMB,  0x30);	/* std adj. */
1240 			WriteHSCX(hscx, IPACX_MASKB, 0xFF);	/* ints off */
1241 			hscx_cmdr(hscx, 0x41);
1242 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1243 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1244 			break;
1245 		case ISDN_P_B_RAW:
1246 			WriteHSCX(hscx, IPACX_MODEB, 0x88);	/* ex trans */
1247 			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* trans */
1248 			hscx_cmdr(hscx, 0x41);
1249 			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1250 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1251 			break;
1252 		case ISDN_P_B_HDLC:
1253 			WriteHSCX(hscx, IPACX_MODEB, 0xC0);	/* trans */
1254 			WriteHSCX(hscx, IPACX_EXMB,  0x00);	/* hdlc,crc */
1255 			hscx_cmdr(hscx, 0x41);
1256 			WriteHSCX(hscx, IPACX_MASKB, IPACX_B_ON);
1257 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1258 			break;
1259 		default:
1260 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1261 				bprotocol);
1262 			return -ENOPROTOOPT;
1263 		}
1264 	} else if (hscx->ip->type & IPAC_TYPE_IPAC) { /* IPAC */
1265 		WriteHSCX(hscx, IPAC_CCR1, 0x82);
1266 		WriteHSCX(hscx, IPAC_CCR2, 0x30);
1267 		WriteHSCX(hscx, IPAC_XCCR, 0x07);
1268 		WriteHSCX(hscx, IPAC_RCCR, 0x07);
1269 		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1270 		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1271 		switch (bprotocol) {
1272 		case ISDN_P_NONE:
1273 			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1274 			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1275 			WriteHSCX(hscx, IPAC_MODEB, 0x84);
1276 			WriteHSCX(hscx, IPAC_CCR1, 0x82);
1277 			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
1278 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1279 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1280 			break;
1281 		case ISDN_P_B_RAW:
1282 			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
1283 			WriteHSCX(hscx, IPAC_CCR1, 0x82);
1284 			hscx_cmdr(hscx, 0x41);
1285 			WriteHSCX(hscx, IPAC_MASKB, 0);
1286 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1287 			break;
1288 		case ISDN_P_B_HDLC:
1289 			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1290 			WriteHSCX(hscx, IPAC_CCR1, 0x8a);
1291 			hscx_cmdr(hscx, 0x41);
1292 			WriteHSCX(hscx, IPAC_MASKB, 0);
1293 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1294 			break;
1295 		default:
1296 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1297 				bprotocol);
1298 			return -ENOPROTOOPT;
1299 		}
1300 	} else if (hscx->ip->type & IPAC_TYPE_HSCX) { /* HSCX */
1301 		WriteHSCX(hscx, IPAC_CCR1, 0x85);
1302 		WriteHSCX(hscx, IPAC_CCR2, 0x30);
1303 		WriteHSCX(hscx, IPAC_XCCR, 0x07);
1304 		WriteHSCX(hscx, IPAC_RCCR, 0x07);
1305 		WriteHSCX(hscx, IPAC_TSAX, hscx->slot);
1306 		WriteHSCX(hscx, IPAC_TSAR, hscx->slot);
1307 		switch (bprotocol) {
1308 		case ISDN_P_NONE:
1309 			WriteHSCX(hscx, IPAC_TSAX, 0x1F);
1310 			WriteHSCX(hscx, IPAC_TSAR, 0x1F);
1311 			WriteHSCX(hscx, IPAC_MODEB, 0x84);
1312 			WriteHSCX(hscx, IPAC_CCR1, 0x85);
1313 			WriteHSCX(hscx, IPAC_MASKB, 0xFF);	/* ints off */
1314 			test_and_clear_bit(FLG_HDLC, &hscx->bch.Flags);
1315 			test_and_clear_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1316 			break;
1317 		case ISDN_P_B_RAW:
1318 			WriteHSCX(hscx, IPAC_MODEB, 0xe4);	/* ex trans */
1319 			WriteHSCX(hscx, IPAC_CCR1, 0x85);
1320 			hscx_cmdr(hscx, 0x41);
1321 			WriteHSCX(hscx, IPAC_MASKB, 0);
1322 			test_and_set_bit(FLG_TRANSPARENT, &hscx->bch.Flags);
1323 			break;
1324 		case ISDN_P_B_HDLC:
1325 			WriteHSCX(hscx, IPAC_MODEB, 0x8c);
1326 			WriteHSCX(hscx, IPAC_CCR1, 0x8d);
1327 			hscx_cmdr(hscx, 0x41);
1328 			WriteHSCX(hscx, IPAC_MASKB, 0);
1329 			test_and_set_bit(FLG_HDLC, &hscx->bch.Flags);
1330 			break;
1331 		default:
1332 			pr_info("%s: protocol not known %x\n", hscx->ip->name,
1333 				bprotocol);
1334 			return -ENOPROTOOPT;
1335 		}
1336 	} else
1337 		return -EINVAL;
1338 	hscx->bch.state = bprotocol;
1339 	return 0;
1340 }
1341 
1342 static int
1343 hscx_l2l1(struct mISDNchannel *ch, struct sk_buff *skb)
1344 {
1345 	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1346 	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
1347 	int ret = -EINVAL;
1348 	struct mISDNhead *hh = mISDN_HEAD_P(skb);
1349 	unsigned long flags;
1350 
1351 	switch (hh->prim) {
1352 	case PH_DATA_REQ:
1353 		spin_lock_irqsave(hx->ip->hwlock, flags);
1354 		ret = bchannel_senddata(bch, skb);
1355 		if (ret > 0) { /* direct TX */
1356 			ret = 0;
1357 			hscx_fill_fifo(hx);
1358 		}
1359 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1360 		return ret;
1361 	case PH_ACTIVATE_REQ:
1362 		spin_lock_irqsave(hx->ip->hwlock, flags);
1363 		if (!test_and_set_bit(FLG_ACTIVE, &bch->Flags))
1364 			ret = hscx_mode(hx, ch->protocol);
1365 		else
1366 			ret = 0;
1367 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1368 		if (!ret)
1369 			_queue_data(ch, PH_ACTIVATE_IND, MISDN_ID_ANY, 0,
1370 				    NULL, GFP_KERNEL);
1371 		break;
1372 	case PH_DEACTIVATE_REQ:
1373 		spin_lock_irqsave(hx->ip->hwlock, flags);
1374 		mISDN_clear_bchannel(bch);
1375 		hscx_mode(hx, ISDN_P_NONE);
1376 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1377 		_queue_data(ch, PH_DEACTIVATE_IND, MISDN_ID_ANY, 0,
1378 			    NULL, GFP_KERNEL);
1379 		ret = 0;
1380 		break;
1381 	default:
1382 		pr_info("%s: %s unknown prim(%x,%x)\n",
1383 			hx->ip->name, __func__, hh->prim, hh->id);
1384 		ret = -EINVAL;
1385 	}
1386 	if (!ret)
1387 		dev_kfree_skb(skb);
1388 	return ret;
1389 }
1390 
1391 static int
1392 channel_bctrl(struct bchannel *bch, struct mISDN_ctrl_req *cq)
1393 {
1394 	return mISDN_ctrl_bchannel(bch, cq);
1395 }
1396 
1397 static int
1398 hscx_bctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1399 {
1400 	struct bchannel *bch = container_of(ch, struct bchannel, ch);
1401 	struct hscx_hw	*hx = container_of(bch, struct hscx_hw, bch);
1402 	int ret = -EINVAL;
1403 	u_long flags;
1404 
1405 	pr_debug("%s: %s cmd:%x %p\n", hx->ip->name, __func__, cmd, arg);
1406 	switch (cmd) {
1407 	case CLOSE_CHANNEL:
1408 		test_and_clear_bit(FLG_OPEN, &bch->Flags);
1409 		cancel_work_sync(&bch->workq);
1410 		spin_lock_irqsave(hx->ip->hwlock, flags);
1411 		mISDN_clear_bchannel(bch);
1412 		hscx_mode(hx, ISDN_P_NONE);
1413 		spin_unlock_irqrestore(hx->ip->hwlock, flags);
1414 		ch->protocol = ISDN_P_NONE;
1415 		ch->peer = NULL;
1416 		module_put(hx->ip->owner);
1417 		ret = 0;
1418 		break;
1419 	case CONTROL_CHANNEL:
1420 		ret = channel_bctrl(bch, arg);
1421 		break;
1422 	default:
1423 		pr_info("%s: %s unknown prim(%x)\n",
1424 			hx->ip->name, __func__, cmd);
1425 	}
1426 	return ret;
1427 }
1428 
1429 static void
1430 free_ipac(struct ipac_hw *ipac)
1431 {
1432 	isac_release(&ipac->isac);
1433 }
1434 
1435 static const char *HSCXVer[] =
1436 {"A1", "?1", "A2", "?3", "A3", "V2.1", "?6", "?7",
1437  "?8", "?9", "?10", "?11", "?12", "?13", "?14", "???"};
1438 
1439 
1440 
1441 static void
1442 hscx_init(struct hscx_hw *hx)
1443 {
1444 	u8 val;
1445 
1446 	WriteHSCX(hx, IPAC_RAH2, 0xFF);
1447 	WriteHSCX(hx, IPAC_XBCH, 0x00);
1448 	WriteHSCX(hx, IPAC_RLCR, 0x00);
1449 
1450 	if (hx->ip->type & IPAC_TYPE_HSCX) {
1451 		WriteHSCX(hx, IPAC_CCR1, 0x85);
1452 		val = ReadHSCX(hx, HSCX_VSTR);
1453 		pr_debug("%s: HSCX VSTR %02x\n", hx->ip->name, val);
1454 		if (hx->bch.debug & DEBUG_HW)
1455 			pr_notice("%s: HSCX version %s\n", hx->ip->name,
1456 				  HSCXVer[val & 0x0f]);
1457 	} else
1458 		WriteHSCX(hx, IPAC_CCR1, 0x82);
1459 	WriteHSCX(hx, IPAC_CCR2, 0x30);
1460 	WriteHSCX(hx, IPAC_XCCR, 0x07);
1461 	WriteHSCX(hx, IPAC_RCCR, 0x07);
1462 }
1463 
1464 static int
1465 ipac_init(struct ipac_hw *ipac)
1466 {
1467 	u8 val;
1468 
1469 	if (ipac->type & IPAC_TYPE_HSCX) {
1470 		hscx_init(&ipac->hscx[0]);
1471 		hscx_init(&ipac->hscx[1]);
1472 		val = ReadIPAC(ipac, IPAC_ID);
1473 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1474 		hscx_init(&ipac->hscx[0]);
1475 		hscx_init(&ipac->hscx[1]);
1476 		WriteIPAC(ipac, IPAC_MASK, IPAC__ON);
1477 		val = ReadIPAC(ipac, IPAC_CONF);
1478 		/* conf is default 0, but can be overwritten by card setup */
1479 		pr_debug("%s: IPAC CONF %02x/%02x\n", ipac->name,
1480 			 val, ipac->conf);
1481 		WriteIPAC(ipac, IPAC_CONF, ipac->conf);
1482 		val = ReadIPAC(ipac, IPAC_ID);
1483 		if (ipac->hscx[0].bch.debug & DEBUG_HW)
1484 			pr_notice("%s: IPAC Design ID %02x\n", ipac->name, val);
1485 	}
1486 	/* nothing special for IPACX to do here */
1487 	return isac_init(&ipac->isac);
1488 }
1489 
1490 static int
1491 open_bchannel(struct ipac_hw *ipac, struct channel_req *rq)
1492 {
1493 	struct bchannel		*bch;
1494 
1495 	if (rq->adr.channel == 0 || rq->adr.channel > 2)
1496 		return -EINVAL;
1497 	if (rq->protocol == ISDN_P_NONE)
1498 		return -EINVAL;
1499 	bch = &ipac->hscx[rq->adr.channel - 1].bch;
1500 	if (test_and_set_bit(FLG_OPEN, &bch->Flags))
1501 		return -EBUSY; /* b-channel can be only open once */
1502 	test_and_clear_bit(FLG_FILLEMPTY, &bch->Flags);
1503 	bch->ch.protocol = rq->protocol;
1504 	rq->ch = &bch->ch;
1505 	return 0;
1506 }
1507 
1508 static int
1509 channel_ctrl(struct ipac_hw *ipac, struct mISDN_ctrl_req *cq)
1510 {
1511 	int	ret = 0;
1512 
1513 	switch (cq->op) {
1514 	case MISDN_CTRL_GETOP:
1515 		cq->op = MISDN_CTRL_LOOP | MISDN_CTRL_L1_TIMER3;
1516 		break;
1517 	case MISDN_CTRL_LOOP:
1518 		/* cq->channel: 0 disable, 1 B1 loop 2 B2 loop, 3 both */
1519 		if (cq->channel < 0 || cq->channel > 3) {
1520 			ret = -EINVAL;
1521 			break;
1522 		}
1523 		ret = ipac->ctrl(ipac, HW_TESTLOOP, cq->channel);
1524 		break;
1525 	case MISDN_CTRL_L1_TIMER3:
1526 		ret = ipac->isac.ctrl(&ipac->isac, HW_TIMER3_VALUE, cq->p1);
1527 		break;
1528 	default:
1529 		pr_info("%s: unknown CTRL OP %x\n", ipac->name, cq->op);
1530 		ret = -EINVAL;
1531 		break;
1532 	}
1533 	return ret;
1534 }
1535 
1536 static int
1537 ipac_dctrl(struct mISDNchannel *ch, u32 cmd, void *arg)
1538 {
1539 	struct mISDNdevice *dev = container_of(ch, struct mISDNdevice, D);
1540 	struct dchannel *dch = container_of(dev, struct dchannel, dev);
1541 	struct isac_hw *isac = container_of(dch, struct isac_hw, dch);
1542 	struct ipac_hw *ipac = container_of(isac, struct ipac_hw, isac);
1543 	struct channel_req *rq;
1544 	int err = 0;
1545 
1546 	pr_debug("%s: DCTRL: %x %p\n", ipac->name, cmd, arg);
1547 	switch (cmd) {
1548 	case OPEN_CHANNEL:
1549 		rq = arg;
1550 		if (rq->protocol == ISDN_P_TE_S0)
1551 			err = open_dchannel(isac, rq);
1552 		else
1553 			err = open_bchannel(ipac, rq);
1554 		if (err)
1555 			break;
1556 		if (!try_module_get(ipac->owner))
1557 			pr_info("%s: cannot get module\n", ipac->name);
1558 		break;
1559 	case CLOSE_CHANNEL:
1560 		pr_debug("%s: dev(%d) close from %p\n", ipac->name,
1561 			 dch->dev.id, __builtin_return_address(0));
1562 		module_put(ipac->owner);
1563 		break;
1564 	case CONTROL_CHANNEL:
1565 		err = channel_ctrl(ipac, arg);
1566 		break;
1567 	default:
1568 		pr_debug("%s: unknown DCTRL command %x\n", ipac->name, cmd);
1569 		return -EINVAL;
1570 	}
1571 	return err;
1572 }
1573 
1574 u32
1575 mISDNipac_init(struct ipac_hw *ipac, void *hw)
1576 {
1577 	u32 ret;
1578 	u8 i;
1579 
1580 	ipac->hw = hw;
1581 	if (ipac->isac.dch.debug & DEBUG_HW)
1582 		pr_notice("%s: ipac type %x\n", ipac->name, ipac->type);
1583 	if (ipac->type & IPAC_TYPE_HSCX) {
1584 		ipac->isac.type = IPAC_TYPE_ISAC;
1585 		ipac->hscx[0].off = 0;
1586 		ipac->hscx[1].off = 0x40;
1587 		ipac->hscx[0].fifo_size = 32;
1588 		ipac->hscx[1].fifo_size = 32;
1589 	} else if (ipac->type & IPAC_TYPE_IPAC) {
1590 		ipac->isac.type = IPAC_TYPE_IPAC | IPAC_TYPE_ISAC;
1591 		ipac->hscx[0].off = 0;
1592 		ipac->hscx[1].off = 0x40;
1593 		ipac->hscx[0].fifo_size = 64;
1594 		ipac->hscx[1].fifo_size = 64;
1595 	} else if (ipac->type & IPAC_TYPE_IPACX) {
1596 		ipac->isac.type = IPAC_TYPE_IPACX | IPAC_TYPE_ISACX;
1597 		ipac->hscx[0].off = IPACX_OFF_ICA;
1598 		ipac->hscx[1].off = IPACX_OFF_ICB;
1599 		ipac->hscx[0].fifo_size = 64;
1600 		ipac->hscx[1].fifo_size = 64;
1601 	} else
1602 		return 0;
1603 
1604 	mISDNisac_init(&ipac->isac, hw);
1605 
1606 	ipac->isac.dch.dev.D.ctrl = ipac_dctrl;
1607 
1608 	for (i = 0; i < 2; i++) {
1609 		ipac->hscx[i].bch.nr = i + 1;
1610 		set_channelmap(i + 1, ipac->isac.dch.dev.channelmap);
1611 		list_add(&ipac->hscx[i].bch.ch.list,
1612 			 &ipac->isac.dch.dev.bchannels);
1613 		mISDN_initbchannel(&ipac->hscx[i].bch, MAX_DATA_MEM,
1614 				   ipac->hscx[i].fifo_size);
1615 		ipac->hscx[i].bch.ch.nr = i + 1;
1616 		ipac->hscx[i].bch.ch.send = &hscx_l2l1;
1617 		ipac->hscx[i].bch.ch.ctrl = hscx_bctrl;
1618 		ipac->hscx[i].bch.hw = hw;
1619 		ipac->hscx[i].ip = ipac;
1620 		/* default values for IOM time slots
1621 		 * can be overwriten by card */
1622 		ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03;
1623 	}
1624 
1625 	ipac->init = ipac_init;
1626 	ipac->release = free_ipac;
1627 
1628 	ret =	(1 << (ISDN_P_B_RAW & ISDN_P_B_MASK)) |
1629 		(1 << (ISDN_P_B_HDLC & ISDN_P_B_MASK));
1630 	return ret;
1631 }
1632 EXPORT_SYMBOL(mISDNipac_init);
1633 
1634 static int __init
1635 isac_mod_init(void)
1636 {
1637 	pr_notice("mISDNipac module version %s\n", ISAC_REV);
1638 	return 0;
1639 }
1640 
1641 static void __exit
1642 isac_mod_cleanup(void)
1643 {
1644 	pr_notice("mISDNipac module unloaded\n");
1645 }
1646 module_init(isac_mod_init);
1647 module_exit(isac_mod_cleanup);
1648