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