b1.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:17k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: b1.c,v 1.1.4.1 2001/11/20 14:19:34 kai Exp $
  2.  * 
  3.  * Common module for AVM B1 cards.
  4.  * 
  5.  * Copyright 1999 by Carsten Paeth <calle@calle.de>
  6.  *
  7.  * This software may be used and distributed according to the terms
  8.  * of the GNU General Public License, incorporated herein by reference.
  9.  *
  10.  */
  11. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/skbuff.h>
  14. #include <linux/delay.h>
  15. #include <linux/mm.h>
  16. #include <linux/interrupt.h>
  17. #include <linux/ioport.h>
  18. #include <linux/capi.h>
  19. #include <linux/kernelcapi.h>
  20. #include <asm/io.h>
  21. #include <linux/init.h>
  22. #include <asm/uaccess.h>
  23. #include <linux/netdevice.h>
  24. #include "capilli.h"
  25. #include "avmcard.h"
  26. #include "capicmd.h"
  27. #include "capiutil.h"
  28. static char *revision = "$Revision: 1.1.4.1 $";
  29. /* ------------------------------------------------------------- */
  30. MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards");
  31. MODULE_AUTHOR("Carsten Paeth");
  32. MODULE_LICENSE("GPL");
  33. /* ------------------------------------------------------------- */
  34. int b1_irq_table[16] =
  35. {0,
  36.  0,
  37.  0,
  38.  192, /* irq 3 */
  39.  32, /* irq 4 */
  40.  160, /* irq 5 */
  41.  96, /* irq 6 */
  42.  224, /* irq 7 */
  43.  0,
  44.  64, /* irq 9 */
  45.  80, /* irq 10 */
  46.  208, /* irq 11 */
  47.  48, /* irq 12 */
  48.  0,
  49.  0,
  50.  112, /* irq 15 */
  51. };
  52. /* ------------------------------------------------------------- */
  53. int b1_detect(unsigned int base, enum avmcardtype cardtype)
  54. {
  55. int onoff, i;
  56. /*
  57.  * Statusregister 0000 00xx 
  58.  */
  59. if ((inb(base + B1_INSTAT) & 0xfc)
  60.     || (inb(base + B1_OUTSTAT) & 0xfc))
  61. return 1;
  62. /*
  63.  * Statusregister 0000 001x 
  64.  */
  65. b1outp(base, B1_INSTAT, 0x2); /* enable irq */
  66. /* b1outp(base, B1_OUTSTAT, 0x2); */
  67. if ((inb(base + B1_INSTAT) & 0xfe) != 0x2
  68.     /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */)
  69. return 2;
  70. /*
  71.  * Statusregister 0000 000x 
  72.  */
  73. b1outp(base, B1_INSTAT, 0x0); /* disable irq */
  74. b1outp(base, B1_OUTSTAT, 0x0);
  75. if ((inb(base + B1_INSTAT) & 0xfe)
  76.     || (inb(base + B1_OUTSTAT) & 0xfe))
  77. return 3;
  78.         
  79. for (onoff = !0, i= 0; i < 10 ; i++) {
  80. b1_set_test_bit(base, cardtype, onoff);
  81. if (b1_get_test_bit(base, cardtype) != onoff)
  82.    return 4;
  83. onoff = !onoff;
  84. }
  85. if (cardtype == avm_m1)
  86.    return 0;
  87.         if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01)
  88.    return 5;
  89. return 0;
  90. }
  91. void b1_getrevision(avmcard *card)
  92. {
  93.     card->class = inb(card->port + B1_ANALYSE);
  94.     card->revision = inb(card->port + B1_REVISION);
  95. }
  96. int b1_load_t4file(avmcard *card, capiloaddatapart * t4file)
  97. {
  98. unsigned char buf[256];
  99. unsigned char *dp;
  100. int i, left, retval;
  101. unsigned int base = card->port;
  102. dp = t4file->data;
  103. left = t4file->len;
  104. while (left > sizeof(buf)) {
  105. if (t4file->user) {
  106. retval = copy_from_user(buf, dp, sizeof(buf));
  107. if (retval)
  108. return -EFAULT;
  109. } else {
  110. memcpy(buf, dp, sizeof(buf));
  111. }
  112. for (i = 0; i < sizeof(buf); i++)
  113. if (b1_save_put_byte(base, buf[i]) < 0) {
  114. printk(KERN_ERR "%s: corrupted firmware file ?n",
  115. card->name);
  116. return -EIO;
  117. }
  118. left -= sizeof(buf);
  119. dp += sizeof(buf);
  120. }
  121. if (left) {
  122. if (t4file->user) {
  123. retval = copy_from_user(buf, dp, left);
  124. if (retval)
  125. return -EFAULT;
  126. } else {
  127. memcpy(buf, dp, left);
  128. }
  129. for (i = 0; i < left; i++)
  130. if (b1_save_put_byte(base, buf[i]) < 0) {
  131. printk(KERN_ERR "%s: corrupted firmware file ?n",
  132. card->name);
  133. return -EIO;
  134. }
  135. }
  136. return 0;
  137. }
  138. int b1_load_config(avmcard *card, capiloaddatapart * config)
  139. {
  140. unsigned char buf[256];
  141. unsigned char *dp;
  142. unsigned int base = card->port;
  143. int i, j, left, retval;
  144. dp = config->data;
  145. left = config->len;
  146. if (left) {
  147. b1_put_byte(base, SEND_CONFIG);
  148.          b1_put_word(base, 1);
  149. b1_put_byte(base, SEND_CONFIG);
  150.          b1_put_word(base, left);
  151. }
  152. while (left > sizeof(buf)) {
  153. if (config->user) {
  154. retval = copy_from_user(buf, dp, sizeof(buf));
  155. if (retval)
  156. return -EFAULT;
  157. } else {
  158. memcpy(buf, dp, sizeof(buf));
  159. }
  160. for (i = 0; i < sizeof(buf); ) {
  161. b1_put_byte(base, SEND_CONFIG);
  162. for (j=0; j < 4; j++) {
  163. b1_put_byte(base, buf[i++]);
  164. }
  165. }
  166. left -= sizeof(buf);
  167. dp += sizeof(buf);
  168. }
  169. if (left) {
  170. if (config->user) {
  171. retval = copy_from_user(buf, dp, left);
  172. if (retval)
  173. return -EFAULT;
  174. } else {
  175. memcpy(buf, dp, left);
  176. }
  177. for (i = 0; i < left; ) {
  178. b1_put_byte(base, SEND_CONFIG);
  179. for (j=0; j < 4; j++) {
  180. if (i < left)
  181. b1_put_byte(base, buf[i++]);
  182. else
  183. b1_put_byte(base, 0);
  184. }
  185. }
  186. }
  187. return 0;
  188. }
  189. int b1_loaded(avmcard *card)
  190. {
  191. unsigned int base = card->port;
  192. unsigned long stop;
  193. unsigned char ans;
  194. unsigned long tout = 2;
  195. for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
  196. if (b1_tx_empty(base))
  197. break;
  198. }
  199. if (!b1_tx_empty(base)) {
  200. printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?n",
  201. card->name);
  202. return 0;
  203. }
  204. b1_put_byte(base, SEND_POLL);
  205. for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) {
  206. if (b1_rx_full(base)) {
  207. if ((ans = b1_get_byte(base)) == RECEIVE_POLL) {
  208. return 1;
  209. }
  210. printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not runningn",
  211. card->name, ans);
  212. return 0;
  213. }
  214. }
  215. printk(KERN_ERR "%s: b1_loaded: firmware not runningn", card->name);
  216. return 0;
  217. }
  218. /* ------------------------------------------------------------- */
  219. int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data)
  220. {
  221. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  222. avmcard *card = cinfo->card;
  223. unsigned int port = card->port;
  224. unsigned long flags;
  225. int retval;
  226. b1_reset(port);
  227. if ((retval = b1_load_t4file(card, &data->firmware))) {
  228. b1_reset(port);
  229. printk(KERN_ERR "%s: failed to load t4file!!n",
  230. card->name);
  231. return retval;
  232. }
  233. b1_disable_irq(port);
  234. if (data->configuration.len > 0 && data->configuration.data) {
  235. if ((retval = b1_load_config(card, &data->configuration))) {
  236. b1_reset(port);
  237. printk(KERN_ERR "%s: failed to load config!!n",
  238. card->name);
  239. return retval;
  240. }
  241. }
  242. if (!b1_loaded(card)) {
  243. printk(KERN_ERR "%s: failed to load t4file.n", card->name);
  244. return -EIO;
  245. }
  246. save_flags(flags);
  247. cli();
  248. b1_setinterrupt(port, card->irq, card->cardtype);
  249. b1_put_byte(port, SEND_INIT);
  250. b1_put_word(port, CAPI_MAXAPPL);
  251. b1_put_word(port, AVM_NCCI_PER_CHANNEL*2);
  252. b1_put_word(port, ctrl->cnr - 1);
  253. restore_flags(flags);
  254. return 0;
  255. }
  256. void b1_reset_ctr(struct capi_ctr *ctrl)
  257. {
  258. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  259. avmcard *card = cinfo->card;
  260. unsigned int port = card->port;
  261. b1_reset(port);
  262. b1_reset(port);
  263. memset(cinfo->version, 0, sizeof(cinfo->version));
  264. ctrl->reseted(ctrl);
  265. }
  266. void b1_register_appl(struct capi_ctr *ctrl,
  267. __u16 appl,
  268. capi_register_params *rp)
  269. {
  270. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  271. avmcard *card = cinfo->card;
  272. unsigned int port = card->port;
  273. unsigned long flags;
  274. int nconn, want = rp->level3cnt;
  275. if (want > 0) nconn = want;
  276. else nconn = ctrl->profile.nbchannel * -want;
  277. if (nconn == 0) nconn = ctrl->profile.nbchannel;
  278. save_flags(flags);
  279. cli();
  280. b1_put_byte(port, SEND_REGISTER);
  281. b1_put_word(port, appl);
  282. b1_put_word(port, 1024 * (nconn+1));
  283. b1_put_word(port, nconn);
  284. b1_put_word(port, rp->datablkcnt);
  285. b1_put_word(port, rp->datablklen);
  286. restore_flags(flags);
  287. ctrl->appl_registered(ctrl, appl);
  288. }
  289. void b1_release_appl(struct capi_ctr *ctrl, __u16 appl)
  290. {
  291. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  292. avmcard *card = cinfo->card;
  293. unsigned int port = card->port;
  294. unsigned long flags;
  295. save_flags(flags);
  296. cli();
  297. b1_put_byte(port, SEND_RELEASE);
  298. b1_put_word(port, appl);
  299. restore_flags(flags);
  300. }
  301. void b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb)
  302. {
  303. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  304. avmcard *card = cinfo->card;
  305. unsigned int port = card->port;
  306. unsigned long flags;
  307. __u16 len = CAPIMSG_LEN(skb->data);
  308. __u8 cmd = CAPIMSG_COMMAND(skb->data);
  309. __u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data);
  310. save_flags(flags);
  311. cli();
  312. if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) {
  313. __u16 dlen = CAPIMSG_DATALEN(skb->data);
  314. b1_put_byte(port, SEND_DATA_B3_REQ);
  315. b1_put_slice(port, skb->data, len);
  316. b1_put_slice(port, skb->data + len, dlen);
  317. } else {
  318. b1_put_byte(port, SEND_MESSAGE);
  319. b1_put_slice(port, skb->data, len);
  320. }
  321. restore_flags(flags);
  322. dev_kfree_skb_any(skb);
  323. }
  324. /* ------------------------------------------------------------- */
  325. void b1_parse_version(avmctrl_info *cinfo)
  326. {
  327. struct capi_ctr *ctrl = cinfo->capi_ctrl;
  328. avmcard *card = cinfo->card;
  329. capi_profile *profp;
  330. __u8 *dversion;
  331. __u8 flag;
  332. int i, j;
  333. for (j = 0; j < AVM_MAXVERSION; j++)
  334. cinfo->version[j] = "" + 1;
  335. for (i = 0, j = 0;
  336.      j < AVM_MAXVERSION && i < cinfo->versionlen;
  337.      j++, i += cinfo->versionbuf[i] + 1)
  338. cinfo->version[j] = &cinfo->versionbuf[i + 1];
  339. strncpy(ctrl->serial, cinfo->version[VER_SERIAL], CAPI_SERIAL_LEN);
  340. memcpy(&ctrl->profile, cinfo->version[VER_PROFILE],sizeof(capi_profile));
  341. strncpy(ctrl->manu, "AVM GmbH", CAPI_MANUFACTURER_LEN);
  342. dversion = cinfo->version[VER_DRIVER];
  343. ctrl->version.majorversion = 2;
  344. ctrl->version.minorversion = 0;
  345. ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4);
  346. ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf);
  347. ctrl->version.minormanuversion = (dversion[3] - '0') << 4;
  348. ctrl->version.minormanuversion |=
  349. (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf);
  350. profp = &ctrl->profile;
  351. flag = ((__u8 *)(profp->manu))[1];
  352. switch (flag) {
  353. case 0: if (cinfo->version[VER_CARDTYPE])
  354.            strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]);
  355.         else strcpy(cinfo->cardname, "B1");
  356. break;
  357. case 3: strcpy(cinfo->cardname,"PCMCIA B"); break;
  358. case 4: strcpy(cinfo->cardname,"PCMCIA M1"); break;
  359. case 5: strcpy(cinfo->cardname,"PCMCIA M2"); break;
  360. case 6: strcpy(cinfo->cardname,"B1 V3.0"); break;
  361. case 7: strcpy(cinfo->cardname,"B1 PCI"); break;
  362. default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break;
  363.         }
  364.         printk(KERN_NOTICE "%s: card %d "%s" ready.n",
  365. card->name, ctrl->cnr, cinfo->cardname);
  366.         flag = ((__u8 *)(profp->manu))[3];
  367.         if (flag)
  368. printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%sn",
  369. card->name,
  370. ctrl->cnr,
  371. (flag & 0x01) ? " DSS1" : "",
  372. (flag & 0x02) ? " CT1" : "",
  373. (flag & 0x04) ? " VN3" : "",
  374. (flag & 0x08) ? " NI1" : "",
  375. (flag & 0x10) ? " AUSTEL" : "",
  376. (flag & 0x20) ? " ESS" : "",
  377. (flag & 0x40) ? " 1TR6" : ""
  378. );
  379.         flag = ((__u8 *)(profp->manu))[5];
  380. if (flag)
  381. printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%sn",
  382. card->name,
  383. ctrl->cnr,
  384. (flag & 0x01) ? " point to point" : "",
  385. (flag & 0x02) ? " point to multipoint" : "",
  386. (flag & 0x08) ? " leased line without D-channel" : "",
  387. (flag & 0x04) ? " leased line with D-channel" : ""
  388. );
  389. }
  390. /* ------------------------------------------------------------- */
  391. void b1_handle_interrupt(avmcard * card)
  392. {
  393. avmctrl_info *cinfo = &card->ctrlinfo[0];
  394. struct capi_ctr *ctrl = cinfo->capi_ctrl;
  395. unsigned char b1cmd;
  396. struct sk_buff *skb;
  397. unsigned ApplId;
  398. unsigned MsgLen;
  399. unsigned DataB3Len;
  400. unsigned NCCI;
  401. unsigned WindowSize;
  402. if (!b1_rx_full(card->port))
  403.    return;
  404. b1cmd = b1_get_byte(card->port);
  405. switch (b1cmd) {
  406. case RECEIVE_DATA_B3_IND:
  407. ApplId = (unsigned) b1_get_word(card->port);
  408. MsgLen = b1_get_slice(card->port, card->msgbuf);
  409. DataB3Len = b1_get_slice(card->port, card->databuf);
  410. if (MsgLen < 30) { /* not CAPI 64Bit */
  411. memset(card->msgbuf+MsgLen, 0, 30-MsgLen);
  412. MsgLen = 30;
  413. CAPIMSG_SETLEN(card->msgbuf, 30);
  414. }
  415. if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) {
  416. printk(KERN_ERR "%s: incoming packet droppedn",
  417. card->name);
  418. } else {
  419. memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
  420. memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len);
  421. ctrl->handle_capimsg(ctrl, ApplId, skb);
  422. }
  423. break;
  424. case RECEIVE_MESSAGE:
  425. ApplId = (unsigned) b1_get_word(card->port);
  426. MsgLen = b1_get_slice(card->port, card->msgbuf);
  427. if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) {
  428. printk(KERN_ERR "%s: incoming packet droppedn",
  429. card->name);
  430. } else {
  431. memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen);
  432. ctrl->handle_capimsg(ctrl, ApplId, skb);
  433. }
  434. break;
  435. case RECEIVE_NEW_NCCI:
  436. ApplId = b1_get_word(card->port);
  437. NCCI = b1_get_word(card->port);
  438. WindowSize = b1_get_word(card->port);
  439. ctrl->new_ncci(ctrl, ApplId, NCCI, WindowSize);
  440. break;
  441. case RECEIVE_FREE_NCCI:
  442. ApplId = b1_get_word(card->port);
  443. NCCI = b1_get_word(card->port);
  444. if (NCCI != 0xffffffff)
  445. ctrl->free_ncci(ctrl, ApplId, NCCI);
  446. else ctrl->appl_released(ctrl, ApplId);
  447. break;
  448. case RECEIVE_START:
  449.     /* b1_put_byte(card->port, SEND_POLLACK); */
  450. ctrl->resume_output(ctrl);
  451. break;
  452. case RECEIVE_STOP:
  453. ctrl->suspend_output(ctrl);
  454. break;
  455. case RECEIVE_INIT:
  456. cinfo->versionlen = b1_get_slice(card->port, cinfo->versionbuf);
  457. b1_parse_version(cinfo);
  458. printk(KERN_INFO "%s: %s-card (%s) now activen",
  459.        card->name,
  460.        cinfo->version[VER_CARDTYPE],
  461.        cinfo->version[VER_DRIVER]);
  462. ctrl->ready(ctrl);
  463. break;
  464. case RECEIVE_TASK_READY:
  465. ApplId = (unsigned) b1_get_word(card->port);
  466. MsgLen = b1_get_slice(card->port, card->msgbuf);
  467. card->msgbuf[MsgLen] = 0;
  468. while (    MsgLen > 0
  469.        && (   card->msgbuf[MsgLen-1] == 'n'
  470.    || card->msgbuf[MsgLen-1] == 'r')) {
  471. card->msgbuf[MsgLen-1] = 0;
  472. MsgLen--;
  473. }
  474. printk(KERN_INFO "%s: task %d "%s" ready.n",
  475. card->name, ApplId, card->msgbuf);
  476. break;
  477. case RECEIVE_DEBUGMSG:
  478. MsgLen = b1_get_slice(card->port, card->msgbuf);
  479. card->msgbuf[MsgLen] = 0;
  480. while (    MsgLen > 0
  481.        && (   card->msgbuf[MsgLen-1] == 'n'
  482.    || card->msgbuf[MsgLen-1] == 'r')) {
  483. card->msgbuf[MsgLen-1] = 0;
  484. MsgLen--;
  485. }
  486. printk(KERN_INFO "%s: DEBUG: %sn", card->name, card->msgbuf);
  487. break;
  488. case 0xff:
  489. printk(KERN_ERR "%s: card removed ?n", card->name);
  490. return;
  491. default:
  492. printk(KERN_ERR "%s: b1_interrupt: 0x%x ???n",
  493. card->name, b1cmd);
  494. return;
  495. }
  496. }
  497. /* ------------------------------------------------------------- */
  498. int b1ctl_read_proc(char *page, char **start, off_t off,
  499.          int count, int *eof, struct capi_ctr *ctrl)
  500. {
  501. avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata);
  502. avmcard *card = cinfo->card;
  503. __u8 flag;
  504. int len = 0;
  505. char *s;
  506. len += sprintf(page+len, "%-16s %sn", "name", card->name);
  507. len += sprintf(page+len, "%-16s 0x%xn", "io", card->port);
  508. len += sprintf(page+len, "%-16s %dn", "irq", card->irq);
  509. switch (card->cardtype) {
  510. case avm_b1isa: s = "B1 ISA"; break;
  511. case avm_b1pci: s = "B1 PCI"; break;
  512. case avm_b1pcmcia: s = "B1 PCMCIA"; break;
  513. case avm_m1: s = "M1"; break;
  514. case avm_m2: s = "M2"; break;
  515. case avm_t1isa: s = "T1 ISA (HEMA)"; break;
  516. case avm_t1pci: s = "T1 PCI"; break;
  517. case avm_c4: s = "C4"; break;
  518. case avm_c2: s = "C2"; break;
  519. default: s = "???"; break;
  520. }
  521. len += sprintf(page+len, "%-16s %sn", "type", s);
  522. if (card->cardtype == avm_t1isa)
  523.    len += sprintf(page+len, "%-16s %dn", "cardnr", card->cardnr);
  524. if ((s = cinfo->version[VER_DRIVER]) != 0)
  525.    len += sprintf(page+len, "%-16s %sn", "ver_driver", s);
  526. if ((s = cinfo->version[VER_CARDTYPE]) != 0)
  527.    len += sprintf(page+len, "%-16s %sn", "ver_cardtype", s);
  528. if ((s = cinfo->version[VER_SERIAL]) != 0)
  529.    len += sprintf(page+len, "%-16s %sn", "ver_serial", s);
  530. if (card->cardtype != avm_m1) {
  531.          flag = ((__u8 *)(ctrl->profile.manu))[3];
  532.          if (flag)
  533. len += sprintf(page+len, "%-16s%s%s%s%s%s%s%sn",
  534. "protocol",
  535. (flag & 0x01) ? " DSS1" : "",
  536. (flag & 0x02) ? " CT1" : "",
  537. (flag & 0x04) ? " VN3" : "",
  538. (flag & 0x08) ? " NI1" : "",
  539. (flag & 0x10) ? " AUSTEL" : "",
  540. (flag & 0x20) ? " ESS" : "",
  541. (flag & 0x40) ? " 1TR6" : ""
  542. );
  543. }
  544. if (card->cardtype != avm_m1) {
  545.          flag = ((__u8 *)(ctrl->profile.manu))[5];
  546. if (flag)
  547. len += sprintf(page+len, "%-16s%s%s%s%sn",
  548. "linetype",
  549. (flag & 0x01) ? " point to point" : "",
  550. (flag & 0x02) ? " point to multipoint" : "",
  551. (flag & 0x08) ? " leased line without D-channel" : "",
  552. (flag & 0x04) ? " leased line with D-channel" : ""
  553. );
  554. }
  555. len += sprintf(page+len, "%-16s %sn", "cardname", cinfo->cardname);
  556. if (off+count >= len)
  557.    *eof = 1;
  558. if (len < off)
  559.            return 0;
  560. *start = page + off;
  561. return ((count < len-off) ? count : len-off);
  562. }
  563. /* ------------------------------------------------------------- */
  564. EXPORT_SYMBOL(b1_irq_table);
  565. EXPORT_SYMBOL(b1_detect);
  566. EXPORT_SYMBOL(b1_getrevision);
  567. EXPORT_SYMBOL(b1_load_t4file);
  568. EXPORT_SYMBOL(b1_load_config);
  569. EXPORT_SYMBOL(b1_loaded);
  570. EXPORT_SYMBOL(b1_load_firmware);
  571. EXPORT_SYMBOL(b1_reset_ctr);
  572. EXPORT_SYMBOL(b1_register_appl);
  573. EXPORT_SYMBOL(b1_release_appl);
  574. EXPORT_SYMBOL(b1_send_message);
  575. EXPORT_SYMBOL(b1_parse_version);
  576. EXPORT_SYMBOL(b1_handle_interrupt);
  577. EXPORT_SYMBOL(b1ctl_read_proc);
  578. static int __init b1_init(void)
  579. {
  580. char *p;
  581. char rev[32];
  582. if ((p = strchr(revision, ':')) != 0 && p[1]) {
  583. strncpy(rev, p + 2, sizeof(rev));
  584. rev[sizeof(rev)-1] = 0;
  585. if ((p = strchr(rev, '$')) != 0 && p > rev)
  586.    *(p-1) = 0;
  587. } else
  588. strcpy(rev, "1.0");
  589. printk(KERN_INFO "b1: revision %sn", rev);
  590. return 0;
  591. }
  592. static void __exit b1_exit(void)
  593. {
  594. }
  595. module_init(b1_init);
  596. module_exit(b1_exit);