2 * $Id: b1.c,v 1.20 2000/11/23 20:45:14 kai Exp $
4 * Common module for AVM B1 cards.
6 * (c) Copyright 1999 by Carsten Paeth (calle@calle.in-berlin.de)
9 * Revision 1.20 2000/11/23 20:45:14 kai
10 * fixed module_init/exit stuff
11 * Note: compiled-in kernel doesn't work pre 2.2.18 anymore.
13 * Revision 1.19 2000/11/19 17:02:47 kai
14 * compatibility cleanup - part 3
16 * Revision 1.18 2000/11/19 17:01:53 kai
17 * compatibility cleanup - part 2
19 * Revision 1.17 2000/11/01 14:05:02 calle
20 * - use module_init/module_exit from linux/init.h.
21 * - all static struct variables are initialized with "membername:" now.
22 * - avm_cs.c, let it work with newer pcmcia-cs.
24 * Revision 1.16 2000/08/04 15:36:31 calle
25 * copied wrong from file to file :-(
27 * Revision 1.15 2000/08/04 12:20:08 calle
28 * - Fix unsigned/signed warning in the right way ...
30 * Revision 1.14 2000/06/19 16:51:53 keil
31 * don't free skb in irq context
33 * Revision 1.13 2000/01/25 14:33:38 calle
34 * - Added Support AVM B1 PCI V4.0 (tested with prototype)
35 * - splitted up t1pci.c into b1dma.c for common function with b1pciv4
36 * - support for revision register
38 * Revision 1.12 1999/11/05 16:38:01 calle
39 * Cleanups before kernel 2.4:
40 * - Changed all messages to use card->name or driver->name instead of
42 * - Moved some data from struct avmcard into new struct avmctrl_info.
43 * Changed all lowlevel capi driver to match the new structur.
45 * Revision 1.11 1999/10/11 22:04:12 keil
46 * COMPAT_NEED_UACCESS (no include in isdn_compat.h)
48 * Revision 1.10 1999/09/15 08:16:03 calle
49 * Implementation of 64Bit extention complete.
51 * Revision 1.9 1999/09/07 09:02:53 calle
52 * SETDATA removed. Now inside the kernel the datapart of DATA_B3_REQ and
53 * DATA_B3_IND is always directly after the CAPI message. The "Data" member
54 * ist never used inside the kernel.
56 * Revision 1.8 1999/08/22 20:26:22 calle
57 * backported changes from kernel 2.3.14:
58 * - several #include "config.h" gone, others come.
59 * - "struct device" changed to "struct net_device" in 2.3.14, added a
60 * define in isdn_compat.h for older kernel versions.
62 * Revision 1.7 1999/08/04 10:10:09 calle
63 * Bugfix: corrected /proc functions, added structure for new AVM cards.
65 * Revision 1.6 1999/07/23 08:51:04 calle
66 * small fix and typo in checkin before.
68 * Revision 1.5 1999/07/23 08:41:48 calle
69 * prepared for new AVM cards.
71 * Revision 1.4 1999/07/09 15:05:38 keil
72 * compat.h is now isdn_compat.h
74 * Revision 1.3 1999/07/06 07:41:59 calle
75 * - changes in /proc interface
76 * - check and changed calls to [dev_]kfree_skb and [dev_]alloc_skb.
78 * Revision 1.2 1999/07/05 15:09:47 calle
79 * - renamed "appl_release" to "appl_released".
80 * - version und profile data now cleared on controller reset
81 * - extended /proc interface, to allow driver and controller specific
82 * informations to include by driver hackers.
84 * Revision 1.1 1999/07/01 15:26:23 calle
85 * complete new version (I love it):
86 * + new hardware independed "capi_driver" interface that will make it easy to:
87 * - support other controllers with CAPI-2.0 (i.e. USB Controller)
88 * - write a CAPI-2.0 for the passive cards
89 * - support serial link CAPI-2.0 boxes.
90 * + wrote "capi_driver" for all supported cards.
91 * + "capi_driver" (supported cards) now have to be configured with
92 * make menuconfig, in the past all supported cards where included
94 * + new and better informations in /proc/capi/
95 * + new ioctl to switch trace of capi messages per controller
96 * using "avmcapictrl trace [contr] on|off|...."
97 * + complete testcircle with all supported cards and also the
98 * PCMCIA cards (now patch for pcmcia-cs-3.0.13 needed) done.
103 #include <linux/module.h>
104 #include <linux/kernel.h>
105 #include <linux/skbuff.h>
106 #include <linux/delay.h>
107 #include <linux/mm.h>
108 #include <linux/interrupt.h>
109 #include <linux/ioport.h>
110 #include <linux/capi.h>
112 #include <linux/init.h>
113 #include <asm/uaccess.h>
114 #include <linux/netdevice.h>
118 #include "capiutil.h"
120 static char *revision
= "$Revision: 1.20 $";
122 /* ------------------------------------------------------------- */
124 MODULE_AUTHOR("Carsten Paeth <calle@calle.in-berlin.de>");
126 /* ------------------------------------------------------------- */
128 int b1_irq_table
[16] =
147 /* ------------------------------------------------------------- */
149 int b1_detect(unsigned int base
, enum avmcardtype cardtype
)
154 * Statusregister 0000 00xx
156 if ((inb(base
+ B1_INSTAT
) & 0xfc)
157 || (inb(base
+ B1_OUTSTAT
) & 0xfc))
160 * Statusregister 0000 001x
162 b1outp(base
, B1_INSTAT
, 0x2); /* enable irq */
163 /* b1outp(base, B1_OUTSTAT, 0x2); */
164 if ((inb(base
+ B1_INSTAT
) & 0xfe) != 0x2
165 /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */)
168 * Statusregister 0000 000x
170 b1outp(base
, B1_INSTAT
, 0x0); /* disable irq */
171 b1outp(base
, B1_OUTSTAT
, 0x0);
172 if ((inb(base
+ B1_INSTAT
) & 0xfe)
173 || (inb(base
+ B1_OUTSTAT
) & 0xfe))
176 for (onoff
= !0, i
= 0; i
< 10 ; i
++) {
177 b1_set_test_bit(base
, cardtype
, onoff
);
178 if (b1_get_test_bit(base
, cardtype
) != onoff
)
183 if (cardtype
== avm_m1
)
186 if ((b1_rd_reg(base
, B1_STAT1(cardtype
)) & 0x0f) != 0x01)
192 void b1_getrevision(avmcard
*card
)
194 card
->class = inb(card
->port
+ B1_ANALYSE
);
195 card
->revision
= inb(card
->port
+ B1_REVISION
);
198 int b1_load_t4file(avmcard
*card
, capiloaddatapart
* t4file
)
200 unsigned char buf
[256];
203 unsigned int base
= card
->port
;
207 while (left
> sizeof(buf
)) {
209 retval
= copy_from_user(buf
, dp
, sizeof(buf
));
213 memcpy(buf
, dp
, sizeof(buf
));
215 for (i
= 0; i
< sizeof(buf
); i
++)
216 if (b1_save_put_byte(base
, buf
[i
]) < 0) {
217 printk(KERN_ERR
"%s: corrupted firmware file ?\n",
226 retval
= copy_from_user(buf
, dp
, left
);
230 memcpy(buf
, dp
, left
);
232 for (i
= 0; i
< left
; i
++)
233 if (b1_save_put_byte(base
, buf
[i
]) < 0) {
234 printk(KERN_ERR
"%s: corrupted firmware file ?\n",
242 int b1_load_config(avmcard
*card
, capiloaddatapart
* config
)
244 unsigned char buf
[256];
246 unsigned int base
= card
->port
;
247 int i
, j
, left
, retval
;
252 b1_put_byte(base
, SEND_CONFIG
);
253 b1_put_word(base
, 1);
254 b1_put_byte(base
, SEND_CONFIG
);
255 b1_put_word(base
, left
);
257 while (left
> sizeof(buf
)) {
259 retval
= copy_from_user(buf
, dp
, sizeof(buf
));
263 memcpy(buf
, dp
, sizeof(buf
));
265 for (i
= 0; i
< sizeof(buf
); ) {
266 b1_put_byte(base
, SEND_CONFIG
);
267 for (j
=0; j
< 4; j
++) {
268 b1_put_byte(base
, buf
[i
++]);
276 retval
= copy_from_user(buf
, dp
, left
);
280 memcpy(buf
, dp
, left
);
282 for (i
= 0; i
< left
; ) {
283 b1_put_byte(base
, SEND_CONFIG
);
284 for (j
=0; j
< 4; j
++) {
286 b1_put_byte(base
, buf
[i
++]);
288 b1_put_byte(base
, 0);
295 int b1_loaded(avmcard
*card
)
297 unsigned int base
= card
->port
;
300 unsigned long tout
= 2;
302 for (stop
= jiffies
+ tout
* HZ
; time_before(jiffies
, stop
);) {
303 if (b1_tx_empty(base
))
306 if (!b1_tx_empty(base
)) {
307 printk(KERN_ERR
"%s: b1_loaded: tx err, corrupted t4 file ?\n",
311 b1_put_byte(base
, SEND_POLL
);
312 for (stop
= jiffies
+ tout
* HZ
; time_before(jiffies
, stop
);) {
313 if (b1_rx_full(base
)) {
314 if ((ans
= b1_get_byte(base
)) == RECEIVE_POLL
) {
317 printk(KERN_ERR
"%s: b1_loaded: got 0x%x, firmware not running\n",
322 printk(KERN_ERR
"%s: b1_loaded: firmware not running\n", card
->name
);
326 /* ------------------------------------------------------------- */
328 int b1_load_firmware(struct capi_ctr
*ctrl
, capiloaddata
*data
)
330 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
331 avmcard
*card
= cinfo
->card
;
332 unsigned int port
= card
->port
;
338 if ((retval
= b1_load_t4file(card
, &data
->firmware
))) {
340 printk(KERN_ERR
"%s: failed to load t4file!!\n",
345 b1_disable_irq(port
);
347 if (data
->configuration
.len
> 0 && data
->configuration
.data
) {
348 if ((retval
= b1_load_config(card
, &data
->configuration
))) {
350 printk(KERN_ERR
"%s: failed to load config!!\n",
356 if (!b1_loaded(card
)) {
357 printk(KERN_ERR
"%s: failed to load t4file.\n", card
->name
);
363 b1_setinterrupt(port
, card
->irq
, card
->cardtype
);
364 b1_put_byte(port
, SEND_INIT
);
365 b1_put_word(port
, AVM_NAPPS
);
366 b1_put_word(port
, AVM_NCCI_PER_CHANNEL
*2);
367 b1_put_word(port
, ctrl
->cnr
- 1);
368 restore_flags(flags
);
373 void b1_reset_ctr(struct capi_ctr
*ctrl
)
375 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
376 avmcard
*card
= cinfo
->card
;
377 unsigned int port
= card
->port
;
382 memset(cinfo
->version
, 0, sizeof(cinfo
->version
));
386 void b1_register_appl(struct capi_ctr
*ctrl
,
388 capi_register_params
*rp
)
390 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
391 avmcard
*card
= cinfo
->card
;
392 unsigned int port
= card
->port
;
394 int nconn
, want
= rp
->level3cnt
;
396 if (want
> 0) nconn
= want
;
397 else nconn
= ctrl
->profile
.nbchannel
* -want
;
398 if (nconn
== 0) nconn
= ctrl
->profile
.nbchannel
;
402 b1_put_byte(port
, SEND_REGISTER
);
403 b1_put_word(port
, appl
);
404 b1_put_word(port
, 1024 * (nconn
+1));
405 b1_put_word(port
, nconn
);
406 b1_put_word(port
, rp
->datablkcnt
);
407 b1_put_word(port
, rp
->datablklen
);
408 restore_flags(flags
);
410 ctrl
->appl_registered(ctrl
, appl
);
413 void b1_release_appl(struct capi_ctr
*ctrl
, __u16 appl
)
415 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
416 avmcard
*card
= cinfo
->card
;
417 unsigned int port
= card
->port
;
422 b1_put_byte(port
, SEND_RELEASE
);
423 b1_put_word(port
, appl
);
424 restore_flags(flags
);
427 void b1_send_message(struct capi_ctr
*ctrl
, struct sk_buff
*skb
)
429 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
430 avmcard
*card
= cinfo
->card
;
431 unsigned int port
= card
->port
;
433 __u16 len
= CAPIMSG_LEN(skb
->data
);
434 __u8 cmd
= CAPIMSG_COMMAND(skb
->data
);
435 __u8 subcmd
= CAPIMSG_SUBCOMMAND(skb
->data
);
439 if (CAPICMD(cmd
, subcmd
) == CAPI_DATA_B3_REQ
) {
440 __u16 dlen
= CAPIMSG_DATALEN(skb
->data
);
441 b1_put_byte(port
, SEND_DATA_B3_REQ
);
442 b1_put_slice(port
, skb
->data
, len
);
443 b1_put_slice(port
, skb
->data
+ len
, dlen
);
445 b1_put_byte(port
, SEND_MESSAGE
);
446 b1_put_slice(port
, skb
->data
, len
);
448 restore_flags(flags
);
449 dev_kfree_skb_any(skb
);
452 /* ------------------------------------------------------------- */
454 void b1_parse_version(avmctrl_info
*cinfo
)
456 struct capi_ctr
*ctrl
= cinfo
->capi_ctrl
;
457 avmcard
*card
= cinfo
->card
;
463 for (j
= 0; j
< AVM_MAXVERSION
; j
++)
464 cinfo
->version
[j
] = "\0\0" + 1;
466 j
< AVM_MAXVERSION
&& i
< cinfo
->versionlen
;
467 j
++, i
+= cinfo
->versionbuf
[i
] + 1)
468 cinfo
->version
[j
] = &cinfo
->versionbuf
[i
+ 1];
470 strncpy(ctrl
->serial
, cinfo
->version
[VER_SERIAL
], CAPI_SERIAL_LEN
);
471 memcpy(&ctrl
->profile
, cinfo
->version
[VER_PROFILE
],sizeof(capi_profile
));
472 strncpy(ctrl
->manu
, "AVM GmbH", CAPI_MANUFACTURER_LEN
);
473 dversion
= cinfo
->version
[VER_DRIVER
];
474 ctrl
->version
.majorversion
= 2;
475 ctrl
->version
.minorversion
= 0;
476 ctrl
->version
.majormanuversion
= (((dversion
[0] - '0') & 0xf) << 4);
477 ctrl
->version
.majormanuversion
|= ((dversion
[2] - '0') & 0xf);
478 ctrl
->version
.minormanuversion
= (dversion
[3] - '0') << 4;
479 ctrl
->version
.minormanuversion
|=
480 (dversion
[5] - '0') * 10 + ((dversion
[6] - '0') & 0xf);
482 profp
= &ctrl
->profile
;
484 flag
= ((__u8
*)(profp
->manu
))[1];
486 case 0: if (cinfo
->version
[VER_CARDTYPE
])
487 strcpy(cinfo
->cardname
, cinfo
->version
[VER_CARDTYPE
]);
488 else strcpy(cinfo
->cardname
, "B1");
490 case 3: strcpy(cinfo
->cardname
,"PCMCIA B"); break;
491 case 4: strcpy(cinfo
->cardname
,"PCMCIA M1"); break;
492 case 5: strcpy(cinfo
->cardname
,"PCMCIA M2"); break;
493 case 6: strcpy(cinfo
->cardname
,"B1 V3.0"); break;
494 case 7: strcpy(cinfo
->cardname
,"B1 PCI"); break;
495 default: sprintf(cinfo
->cardname
, "AVM?%u", (unsigned int)flag
); break;
497 printk(KERN_NOTICE
"%s: card %d \"%s\" ready.\n",
498 card
->name
, ctrl
->cnr
, cinfo
->cardname
);
500 flag
= ((__u8
*)(profp
->manu
))[3];
502 printk(KERN_NOTICE
"%s: card %d Protocol:%s%s%s%s%s%s%s\n",
505 (flag
& 0x01) ? " DSS1" : "",
506 (flag
& 0x02) ? " CT1" : "",
507 (flag
& 0x04) ? " VN3" : "",
508 (flag
& 0x08) ? " NI1" : "",
509 (flag
& 0x10) ? " AUSTEL" : "",
510 (flag
& 0x20) ? " ESS" : "",
511 (flag
& 0x40) ? " 1TR6" : ""
514 flag
= ((__u8
*)(profp
->manu
))[5];
516 printk(KERN_NOTICE
"%s: card %d Linetype:%s%s%s%s\n",
519 (flag
& 0x01) ? " point to point" : "",
520 (flag
& 0x02) ? " point to multipoint" : "",
521 (flag
& 0x08) ? " leased line without D-channel" : "",
522 (flag
& 0x04) ? " leased line with D-channel" : ""
526 /* ------------------------------------------------------------- */
528 void b1_handle_interrupt(avmcard
* card
)
530 avmctrl_info
*cinfo
= &card
->ctrlinfo
[0];
531 struct capi_ctr
*ctrl
= cinfo
->capi_ctrl
;
541 if (!b1_rx_full(card
->port
))
544 b1cmd
= b1_get_byte(card
->port
);
548 case RECEIVE_DATA_B3_IND
:
550 ApplId
= (unsigned) b1_get_word(card
->port
);
551 MsgLen
= b1_get_slice(card
->port
, card
->msgbuf
);
552 DataB3Len
= b1_get_slice(card
->port
, card
->databuf
);
554 if (MsgLen
< 30) { /* not CAPI 64Bit */
555 memset(card
->msgbuf
+MsgLen
, 0, 30-MsgLen
);
557 CAPIMSG_SETLEN(card
->msgbuf
, 30);
559 if (!(skb
= alloc_skb(DataB3Len
+ MsgLen
, GFP_ATOMIC
))) {
560 printk(KERN_ERR
"%s: incoming packet dropped\n",
563 memcpy(skb_put(skb
, MsgLen
), card
->msgbuf
, MsgLen
);
564 memcpy(skb_put(skb
, DataB3Len
), card
->databuf
, DataB3Len
);
565 ctrl
->handle_capimsg(ctrl
, ApplId
, skb
);
569 case RECEIVE_MESSAGE
:
571 ApplId
= (unsigned) b1_get_word(card
->port
);
572 MsgLen
= b1_get_slice(card
->port
, card
->msgbuf
);
573 if (!(skb
= alloc_skb(MsgLen
, GFP_ATOMIC
))) {
574 printk(KERN_ERR
"%s: incoming packet dropped\n",
577 memcpy(skb_put(skb
, MsgLen
), card
->msgbuf
, MsgLen
);
578 ctrl
->handle_capimsg(ctrl
, ApplId
, skb
);
582 case RECEIVE_NEW_NCCI
:
584 ApplId
= b1_get_word(card
->port
);
585 NCCI
= b1_get_word(card
->port
);
586 WindowSize
= b1_get_word(card
->port
);
588 ctrl
->new_ncci(ctrl
, ApplId
, NCCI
, WindowSize
);
592 case RECEIVE_FREE_NCCI
:
594 ApplId
= b1_get_word(card
->port
);
595 NCCI
= b1_get_word(card
->port
);
597 if (NCCI
!= 0xffffffff)
598 ctrl
->free_ncci(ctrl
, ApplId
, NCCI
);
599 else ctrl
->appl_released(ctrl
, ApplId
);
603 /* b1_put_byte(card->port, SEND_POLLACK); */
604 ctrl
->resume_output(ctrl
);
608 ctrl
->suspend_output(ctrl
);
613 cinfo
->versionlen
= b1_get_slice(card
->port
, cinfo
->versionbuf
);
614 b1_parse_version(cinfo
);
615 printk(KERN_INFO
"%s: %s-card (%s) now active\n",
617 cinfo
->version
[VER_CARDTYPE
],
618 cinfo
->version
[VER_DRIVER
]);
622 case RECEIVE_TASK_READY
:
623 ApplId
= (unsigned) b1_get_word(card
->port
);
624 MsgLen
= b1_get_slice(card
->port
, card
->msgbuf
);
625 card
->msgbuf
[MsgLen
] = 0;
627 && ( card
->msgbuf
[MsgLen
-1] == '\n'
628 || card
->msgbuf
[MsgLen
-1] == '\r')) {
629 card
->msgbuf
[MsgLen
-1] = 0;
632 printk(KERN_INFO
"%s: task %d \"%s\" ready.\n",
633 card
->name
, ApplId
, card
->msgbuf
);
636 case RECEIVE_DEBUGMSG
:
637 MsgLen
= b1_get_slice(card
->port
, card
->msgbuf
);
638 card
->msgbuf
[MsgLen
] = 0;
640 && ( card
->msgbuf
[MsgLen
-1] == '\n'
641 || card
->msgbuf
[MsgLen
-1] == '\r')) {
642 card
->msgbuf
[MsgLen
-1] = 0;
645 printk(KERN_INFO
"%s: DEBUG: %s\n", card
->name
, card
->msgbuf
);
649 printk(KERN_ERR
"%s: card removed ?\n", card
->name
);
652 printk(KERN_ERR
"%s: b1_interrupt: 0x%x ???\n",
658 /* ------------------------------------------------------------- */
659 int b1ctl_read_proc(char *page
, char **start
, off_t off
,
660 int count
, int *eof
, struct capi_ctr
*ctrl
)
662 avmctrl_info
*cinfo
= (avmctrl_info
*)(ctrl
->driverdata
);
663 avmcard
*card
= cinfo
->card
;
668 len
+= sprintf(page
+len
, "%-16s %s\n", "name", card
->name
);
669 len
+= sprintf(page
+len
, "%-16s 0x%x\n", "io", card
->port
);
670 len
+= sprintf(page
+len
, "%-16s %d\n", "irq", card
->irq
);
671 switch (card
->cardtype
) {
672 case avm_b1isa
: s
= "B1 ISA"; break;
673 case avm_b1pci
: s
= "B1 PCI"; break;
674 case avm_b1pcmcia
: s
= "B1 PCMCIA"; break;
675 case avm_m1
: s
= "M1"; break;
676 case avm_m2
: s
= "M2"; break;
677 case avm_t1isa
: s
= "T1 ISA (HEMA)"; break;
678 case avm_t1pci
: s
= "T1 PCI"; break;
679 case avm_c4
: s
= "C4"; break;
680 default: s
= "???"; break;
682 len
+= sprintf(page
+len
, "%-16s %s\n", "type", s
);
683 if (card
->cardtype
== avm_t1isa
)
684 len
+= sprintf(page
+len
, "%-16s %d\n", "cardnr", card
->cardnr
);
685 if ((s
= cinfo
->version
[VER_DRIVER
]) != 0)
686 len
+= sprintf(page
+len
, "%-16s %s\n", "ver_driver", s
);
687 if ((s
= cinfo
->version
[VER_CARDTYPE
]) != 0)
688 len
+= sprintf(page
+len
, "%-16s %s\n", "ver_cardtype", s
);
689 if ((s
= cinfo
->version
[VER_SERIAL
]) != 0)
690 len
+= sprintf(page
+len
, "%-16s %s\n", "ver_serial", s
);
692 if (card
->cardtype
!= avm_m1
) {
693 flag
= ((__u8
*)(ctrl
->profile
.manu
))[3];
695 len
+= sprintf(page
+len
, "%-16s%s%s%s%s%s%s%s\n",
697 (flag
& 0x01) ? " DSS1" : "",
698 (flag
& 0x02) ? " CT1" : "",
699 (flag
& 0x04) ? " VN3" : "",
700 (flag
& 0x08) ? " NI1" : "",
701 (flag
& 0x10) ? " AUSTEL" : "",
702 (flag
& 0x20) ? " ESS" : "",
703 (flag
& 0x40) ? " 1TR6" : ""
706 if (card
->cardtype
!= avm_m1
) {
707 flag
= ((__u8
*)(ctrl
->profile
.manu
))[5];
709 len
+= sprintf(page
+len
, "%-16s%s%s%s%s\n",
711 (flag
& 0x01) ? " point to point" : "",
712 (flag
& 0x02) ? " point to multipoint" : "",
713 (flag
& 0x08) ? " leased line without D-channel" : "",
714 (flag
& 0x04) ? " leased line with D-channel" : ""
717 len
+= sprintf(page
+len
, "%-16s %s\n", "cardname", cinfo
->cardname
);
719 if (off
+count
>= len
)
724 return ((count
< len
-off
) ? count
: len
-off
);
727 /* ------------------------------------------------------------- */
729 EXPORT_SYMBOL(b1_irq_table
);
731 EXPORT_SYMBOL(b1_detect
);
732 EXPORT_SYMBOL(b1_getrevision
);
733 EXPORT_SYMBOL(b1_load_t4file
);
734 EXPORT_SYMBOL(b1_load_config
);
735 EXPORT_SYMBOL(b1_loaded
);
736 EXPORT_SYMBOL(b1_load_firmware
);
737 EXPORT_SYMBOL(b1_reset_ctr
);
738 EXPORT_SYMBOL(b1_register_appl
);
739 EXPORT_SYMBOL(b1_release_appl
);
740 EXPORT_SYMBOL(b1_send_message
);
742 EXPORT_SYMBOL(b1_parse_version
);
743 EXPORT_SYMBOL(b1_handle_interrupt
);
745 EXPORT_SYMBOL(b1ctl_read_proc
);
747 static int __init
b1_init(void)
752 if ((p
= strchr(revision
, ':'))) {
753 strncpy(rev
, p
+ 1, sizeof(rev
));
754 p
= strchr(rev
, '$');
759 printk(KERN_INFO
"b1: revision %s\n", rev
);
764 static void __exit
b1_exit(void)
768 module_init(b1_init
);
769 module_exit(b1_exit
);