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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* $Id: icn.c,v 1.1.4.1 2001/11/20 14:19:37 kai Exp $
  2.  *
  3.  * ISDN low-level module for the ICN active ISDN-Card.
  4.  *
  5.  * Copyright 1994,95,96 by Fritz Elfert (fritz@isdn4linux.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 "icn.h"
  12. #include <linux/module.h>
  13. #include <linux/init.h>
  14. static int portbase = ICN_BASEADDR;
  15. static unsigned long membase = ICN_MEMADDR;
  16. static char *icn_id = "";
  17. static char *icn_id2 = "";
  18. MODULE_DESCRIPTION("ISDN4Linux: Driver for ICN active ISDN card");
  19. MODULE_AUTHOR("Fritz Elfert");
  20. MODULE_LICENSE("GPL");
  21. MODULE_PARM(portbase, "i");
  22. MODULE_PARM_DESC(portbase, "Port address of first card");
  23. MODULE_PARM(membase, "l");
  24. MODULE_PARM_DESC(membase, "Shared memory address of all cards");
  25. MODULE_PARM(icn_id, "s");
  26. MODULE_PARM_DESC(icn_id, "ID-String of first card");
  27. MODULE_PARM(icn_id2, "s");
  28. MODULE_PARM_DESC(icn_id2, "ID-String of first card, second S0 (4B only)");
  29. /*
  30.  * Verbose bootcode- and protocol-downloading.
  31.  */
  32. #undef BOOT_DEBUG
  33. /*
  34.  * Verbose Shmem-Mapping.
  35.  */
  36. #undef MAP_DEBUG
  37. static char
  38. *revision = "$Revision: 1.1.4.1 $";
  39. static int icn_addcard(int, char *, char *);
  40. /*
  41.  * Free send-queue completely.
  42.  * Parameter:
  43.  *   card   = pointer to card struct
  44.  *   channel = channel number
  45.  */
  46. static void
  47. icn_free_queue(icn_card * card, int channel)
  48. {
  49. struct sk_buff_head *queue = &card->spqueue[channel];
  50. struct sk_buff *skb;
  51. unsigned long flags;
  52. skb_queue_purge(queue);
  53. save_flags(flags);
  54. cli();
  55. card->xlen[channel] = 0;
  56. card->sndcount[channel] = 0;
  57. if ((skb = card->xskb[channel])) {
  58. card->xskb[channel] = NULL;
  59. restore_flags(flags);
  60. dev_kfree_skb(skb);
  61. } else
  62. restore_flags(flags);
  63. }
  64. /* Put a value into a shift-register, highest bit first.
  65.  * Parameters:
  66.  *            port     = port for output (bit 0 is significant)
  67.  *            val      = value to be output
  68.  *            firstbit = Bit-Number of highest bit
  69.  *            bitcount = Number of bits to output
  70.  */
  71. static inline void
  72. icn_shiftout(unsigned short port,
  73.      unsigned long val,
  74.      int firstbit,
  75.      int bitcount)
  76. {
  77. register u_char s;
  78. register u_char c;
  79. for (s = firstbit, c = bitcount; c > 0; s--, c--)
  80. OUTB_P((u_char) ((val >> s) & 1) ? 0xff : 0, port);
  81. }
  82. /*
  83.  * disable a cards shared memory
  84.  */
  85. static inline void
  86. icn_disable_ram(icn_card * card)
  87. {
  88. OUTB_P(0, ICN_MAPRAM);
  89. }
  90. /*
  91.  * enable a cards shared memory
  92.  */
  93. static inline void
  94. icn_enable_ram(icn_card * card)
  95. {
  96. OUTB_P(0xff, ICN_MAPRAM);
  97. }
  98. /*
  99.  * Map a cards channel0 (Bank0/Bank8) or channel1 (Bank4/Bank12)
  100.  */
  101. static inline void
  102. icn_map_channel(icn_card * card, int channel)
  103. {
  104. #ifdef MAP_DEBUG
  105. printk(KERN_DEBUG "icn_map_channel %d %dn", dev.channel, channel);
  106. #endif
  107. if ((channel == dev.channel) && (card == dev.mcard))
  108. return;
  109. if (dev.mcard)
  110. icn_disable_ram(dev.mcard);
  111. icn_shiftout(ICN_BANK, chan2bank[channel], 3, 4); /* Select Bank          */
  112. icn_enable_ram(card);
  113. dev.mcard = card;
  114. dev.channel = channel;
  115. #ifdef MAP_DEBUG
  116. printk(KERN_DEBUG "icn_map_channel donen");
  117. #endif
  118. }
  119. /*
  120.  * Lock a cards channel.
  121.  * Return 0 if requested card/channel is unmapped (failure).
  122.  * Return 1 on success.
  123.  */
  124. static inline int
  125. icn_lock_channel(icn_card * card, int channel)
  126. {
  127. register int retval;
  128. ulong flags;
  129. #ifdef MAP_DEBUG
  130. printk(KERN_DEBUG "icn_lock_channel %dn", channel);
  131. #endif
  132. save_flags(flags);
  133. cli();
  134. if ((dev.channel == channel) && (card == dev.mcard)) {
  135. dev.chanlock++;
  136. retval = 1;
  137. #ifdef MAP_DEBUG
  138. printk(KERN_DEBUG "icn_lock_channel %d OKn", channel);
  139. #endif
  140. } else {
  141. retval = 0;
  142. #ifdef MAP_DEBUG
  143. printk(KERN_DEBUG "icn_lock_channel %d FAILED, dc=%dn", channel, dev.channel);
  144. #endif
  145. }
  146. restore_flags(flags);
  147. return retval;
  148. }
  149. /*
  150.  * Release current card/channel lock
  151.  */
  152. static inline void
  153. icn_release_channel(void)
  154. {
  155. ulong flags;
  156. #ifdef MAP_DEBUG
  157. printk(KERN_DEBUG "icn_release_channel l=%dn", dev.chanlock);
  158. #endif
  159. save_flags(flags);
  160. cli();
  161. if (dev.chanlock > 0)
  162. dev.chanlock--;
  163. restore_flags(flags);
  164. }
  165. /*
  166.  * Try to map and lock a cards channel.
  167.  * Return 1 on success, 0 on failure.
  168.  */
  169. static inline int
  170. icn_trymaplock_channel(icn_card * card, int channel)
  171. {
  172. ulong flags;
  173. #ifdef MAP_DEBUG
  174. printk(KERN_DEBUG "trymaplock c=%d dc=%d l=%dn", channel, dev.channel,
  175.        dev.chanlock);
  176. #endif
  177. save_flags(flags);
  178. cli();
  179. if ((!dev.chanlock) ||
  180.     ((dev.channel == channel) && (dev.mcard == card))) {
  181. dev.chanlock++;
  182. icn_map_channel(card, channel);
  183. restore_flags(flags);
  184. #ifdef MAP_DEBUG
  185. printk(KERN_DEBUG "trymaplock %d OKn", channel);
  186. #endif
  187. return 1;
  188. }
  189. restore_flags(flags);
  190. #ifdef MAP_DEBUG
  191. printk(KERN_DEBUG "trymaplock %d FAILEDn", channel);
  192. #endif
  193. return 0;
  194. }
  195. /*
  196.  * Release current card/channel lock,
  197.  * then map same or other channel without locking.
  198.  */
  199. static inline void
  200. icn_maprelease_channel(icn_card * card, int channel)
  201. {
  202. ulong flags;
  203. #ifdef MAP_DEBUG
  204. printk(KERN_DEBUG "map_release c=%d l=%dn", channel, dev.chanlock);
  205. #endif
  206. save_flags(flags);
  207. cli();
  208. if (dev.chanlock > 0)
  209. dev.chanlock--;
  210. if (!dev.chanlock)
  211. icn_map_channel(card, channel);
  212. restore_flags(flags);
  213. }
  214. /* Get Data from the B-Channel, assemble fragmented packets and put them
  215.  * into receive-queue. Wake up any B-Channel-reading processes.
  216.  * This routine is called via timer-callback from icn_pollbchan().
  217.  */
  218. static void
  219. icn_pollbchan_receive(int channel, icn_card * card)
  220. {
  221. int mch = channel + ((card->secondhalf) ? 2 : 0);
  222. int eflag;
  223. int cnt;
  224. struct sk_buff *skb;
  225. if (icn_trymaplock_channel(card, mch)) {
  226. while (rbavl) {
  227. cnt = readb(&rbuf_l);
  228. if ((card->rcvidx[channel] + cnt) > 4000) {
  229. printk(KERN_WARNING
  230.        "icn: (%s) bogus packet on ch%d, dropping.n",
  231.        CID,
  232.        channel + 1);
  233. card->rcvidx[channel] = 0;
  234. eflag = 0;
  235. } else {
  236. memcpy_fromio(&card->rcvbuf[channel][card->rcvidx[channel]],
  237.       &rbuf_d, cnt);
  238. card->rcvidx[channel] += cnt;
  239. eflag = readb(&rbuf_f);
  240. }
  241. rbnext;
  242. icn_maprelease_channel(card, mch & 2);
  243. if (!eflag) {
  244. if ((cnt = card->rcvidx[channel])) {
  245. if (!(skb = dev_alloc_skb(cnt))) {
  246. printk(KERN_WARNING "icn: receive out of memoryn");
  247. break;
  248. }
  249. memcpy(skb_put(skb, cnt), card->rcvbuf[channel], cnt);
  250. card->rcvidx[channel] = 0;
  251. card->interface.rcvcallb_skb(card->myid, channel, skb);
  252. }
  253. }
  254. if (!icn_trymaplock_channel(card, mch))
  255. break;
  256. }
  257. icn_maprelease_channel(card, mch & 2);
  258. }
  259. }
  260. /* Send data-packet to B-Channel, split it up into fragments of
  261.  * ICN_FRAGSIZE length. If last fragment is sent out, signal
  262.  * success to upper layers via statcallb with ISDN_STAT_BSENT argument.
  263.  * This routine is called via timer-callback from icn_pollbchan() or
  264.  * directly from icn_sendbuf().
  265.  */
  266. static void
  267. icn_pollbchan_send(int channel, icn_card * card)
  268. {
  269. int mch = channel + ((card->secondhalf) ? 2 : 0);
  270. int cnt;
  271. unsigned long flags;
  272. struct sk_buff *skb;
  273. isdn_ctrl cmd;
  274. if (!(card->sndcount[channel] || card->xskb[channel] ||
  275.       skb_queue_len(&card->spqueue[channel])))
  276. return;
  277. if (icn_trymaplock_channel(card, mch)) {
  278. while (sbfree && 
  279.        (card->sndcount[channel] ||
  280. skb_queue_len(&card->spqueue[channel]) ||
  281. card->xskb[channel])) {
  282. save_flags(flags);
  283. cli();
  284. if (card->xmit_lock[channel]) {
  285. restore_flags(flags);
  286. break;
  287. }
  288. card->xmit_lock[channel]++;
  289. restore_flags(flags);
  290. skb = card->xskb[channel];
  291. if (!skb) {
  292. skb = skb_dequeue(&card->spqueue[channel]);
  293. if (skb) {
  294. /* Pop ACK-flag off skb.
  295.  * Store length to xlen.
  296.  */
  297. if (*(skb_pull(skb,1)))
  298. card->xlen[channel] = skb->len;
  299. else
  300. card->xlen[channel] = 0;
  301. }
  302. }
  303. if (!skb)
  304. break;
  305. if (skb->len > ICN_FRAGSIZE) {
  306. writeb(0xff, &sbuf_f);
  307. cnt = ICN_FRAGSIZE;
  308. } else {
  309. writeb(0x0, &sbuf_f);
  310. cnt = skb->len;
  311. }
  312. writeb(cnt, &sbuf_l);
  313. memcpy_toio(&sbuf_d, skb->data, cnt);
  314. skb_pull(skb, cnt);
  315. card->sndcount[channel] -= cnt;
  316. sbnext; /* switch to next buffer        */
  317. icn_maprelease_channel(card, mch & 2);
  318. if (!skb->len) {
  319. save_flags(flags);
  320. cli();
  321. if (card->xskb[channel])
  322. card->xskb[channel] = NULL;
  323. restore_flags(flags);
  324. dev_kfree_skb(skb);
  325. if (card->xlen[channel]) {
  326. cmd.command = ISDN_STAT_BSENT;
  327. cmd.driver = card->myid;
  328. cmd.arg = channel;
  329. cmd.parm.length = card->xlen[channel];
  330. card->interface.statcallb(&cmd);
  331. }
  332. } else {
  333. save_flags(flags);
  334. cli();
  335. card->xskb[channel] = skb;
  336. restore_flags(flags);
  337. }
  338. card->xmit_lock[channel] = 0;
  339. if (!icn_trymaplock_channel(card, mch))
  340. break;
  341. }
  342. icn_maprelease_channel(card, mch & 2);
  343. }
  344. }
  345. /* Send/Receive Data to/from the B-Channel.
  346.  * This routine is called via timer-callback.
  347.  * It schedules itself while any B-Channel is open.
  348.  */
  349. static void
  350. icn_pollbchan(unsigned long data)
  351. {
  352. icn_card *card = (icn_card *) data;
  353. unsigned long flags;
  354. if (card->flags & ICN_FLAGS_B1ACTIVE) {
  355. icn_pollbchan_receive(0, card);
  356. icn_pollbchan_send(0, card);
  357. }
  358. if (card->flags & ICN_FLAGS_B2ACTIVE) {
  359. icn_pollbchan_receive(1, card);
  360. icn_pollbchan_send(1, card);
  361. }
  362. if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE)) {
  363. /* schedule b-channel polling again */
  364. save_flags(flags);
  365. cli();
  366. mod_timer(&card->rb_timer, jiffies+ICN_TIMER_BCREAD);
  367. card->flags |= ICN_FLAGS_RBTIMER;
  368. restore_flags(flags);
  369. } else
  370. card->flags &= ~ICN_FLAGS_RBTIMER;
  371. }
  372. typedef struct icn_stat {
  373. char *statstr;
  374. int command;
  375. int action;
  376. } icn_stat;
  377. /* *INDENT-OFF* */
  378. static icn_stat icn_stat_table[] =
  379. {
  380. {"BCON_",          ISDN_STAT_BCONN, 1}, /* B-Channel connected        */
  381. {"BDIS_",          ISDN_STAT_BHUP,  2}, /* B-Channel disconnected     */
  382. /*
  383. ** add d-channel connect and disconnect support to link-level
  384. */
  385. {"DCON_",          ISDN_STAT_DCONN, 10}, /* D-Channel connected        */
  386. {"DDIS_",          ISDN_STAT_DHUP,  11}, /* D-Channel disconnected     */
  387. {"DCAL_I",         ISDN_STAT_ICALL, 3}, /* Incoming call dialup-line  */
  388. {"DSCA_I",         ISDN_STAT_ICALL, 3}, /* Incoming call 1TR6-SPV     */
  389. {"FCALL",          ISDN_STAT_ICALL, 4}, /* Leased line connection up  */
  390. {"CIF",            ISDN_STAT_CINF,  5}, /* Charge-info, 1TR6-type     */
  391. {"AOC",            ISDN_STAT_CINF,  6}, /* Charge-info, DSS1-type     */
  392. {"CAU",            ISDN_STAT_CAUSE, 7}, /* Cause code                 */
  393. {"TEI OK",         ISDN_STAT_RUN,   0}, /* Card connected to wallplug */
  394. {"NO D-CHAN",      ISDN_STAT_NODCH, 0}, /* No D-channel available     */
  395. {"E_L1: ACT FAIL", ISDN_STAT_BHUP,  8}, /* Layer-1 activation failed  */
  396. {"E_L2: DATA LIN", ISDN_STAT_BHUP,  8}, /* Layer-2 data link lost     */
  397. {"E_L1: ACTIVATION FAILED",
  398.    ISDN_STAT_BHUP,  8}, /* Layer-1 activation failed  */
  399. {NULL, 0, -1}
  400. };
  401. /* *INDENT-ON* */
  402. /*
  403.  * Check Statusqueue-Pointer from isdn-cards.
  404.  * If there are new status-replies from the interface, check
  405.  * them against B-Channel-connects/disconnects and set flags accordingly.
  406.  * Wake-Up any processes, who are reading the status-device.
  407.  * If there are B-Channels open, initiate a timer-callback to
  408.  * icn_pollbchan().
  409.  * This routine is called periodically via timer.
  410.  */
  411. static void
  412. icn_parse_status(u_char * status, int channel, icn_card * card)
  413. {
  414. icn_stat *s = icn_stat_table;
  415. int action = -1;
  416. unsigned long flags;
  417. isdn_ctrl cmd;
  418. while (s->statstr) {
  419. if (!strncmp(status, s->statstr, strlen(s->statstr))) {
  420. cmd.command = s->command;
  421. action = s->action;
  422. break;
  423. }
  424. s++;
  425. }
  426. if (action == -1)
  427. return;
  428. cmd.driver = card->myid;
  429. cmd.arg = channel;
  430. switch (action) {
  431. case 11:
  432. save_flags(flags);
  433. cli();
  434. icn_free_queue(card,channel);
  435. card->rcvidx[channel] = 0;
  436. if (card->flags & 
  437.     ((channel)?ICN_FLAGS_B2ACTIVE:ICN_FLAGS_B1ACTIVE)) {
  438. isdn_ctrl ncmd;
  439. card->flags &= ~((channel)?
  440.  ICN_FLAGS_B2ACTIVE:ICN_FLAGS_B1ACTIVE);
  441. memset(&ncmd, 0, sizeof(ncmd));
  442. ncmd.driver = card->myid;
  443. ncmd.arg = channel;
  444. ncmd.command = ISDN_STAT_BHUP;
  445. restore_flags(flags);
  446. card->interface.statcallb(&cmd);
  447. } else
  448. restore_flags(flags);
  449. break;
  450. case 1:
  451. icn_free_queue(card,channel);
  452. card->flags |= (channel) ?
  453.     ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE;
  454. break;
  455. case 2:
  456. card->flags &= ~((channel) ?
  457. ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE);
  458. icn_free_queue(card, channel);
  459. save_flags(flags);
  460. cli();
  461. card->rcvidx[channel] = 0;
  462. restore_flags(flags);
  463. break;
  464. case 3:
  465. {
  466. char *t = status + 6;
  467. char *s = strpbrk(t, ",");
  468. *s++ = '';
  469. strncpy(cmd.parm.setup.phone, t,
  470. sizeof(cmd.parm.setup.phone));
  471. s = strpbrk(t = s, ",");
  472. *s++ = '';
  473. if (!strlen(t))
  474. cmd.parm.setup.si1 = 0;
  475. else
  476. cmd.parm.setup.si1 =
  477.     simple_strtoul(t, NULL, 10);
  478. s = strpbrk(t = s, ",");
  479. *s++ = '';
  480. if (!strlen(t))
  481. cmd.parm.setup.si2 = 0;
  482. else
  483. cmd.parm.setup.si2 =
  484.     simple_strtoul(t, NULL, 10);
  485. strncpy(cmd.parm.setup.eazmsn, s,
  486. sizeof(cmd.parm.setup.eazmsn));
  487. }
  488. cmd.parm.setup.plan = 0;
  489. cmd.parm.setup.screen = 0;
  490. break;
  491. case 4:
  492. sprintf(cmd.parm.setup.phone, "LEASED%d", card->myid);
  493. sprintf(cmd.parm.setup.eazmsn, "%d", channel + 1);
  494. cmd.parm.setup.si1 = 7;
  495. cmd.parm.setup.si2 = 0;
  496. cmd.parm.setup.plan = 0;
  497. cmd.parm.setup.screen = 0;
  498. break;
  499. case 5:
  500. strncpy(cmd.parm.num, status + 3, sizeof(cmd.parm.num) - 1);
  501. break;
  502. case 6:
  503. sprintf(cmd.parm.num, "%d",
  504.      (int) simple_strtoul(status + 7, NULL, 16));
  505. break;
  506. case 7:
  507. status += 3;
  508. if (strlen(status) == 4)
  509. sprintf(cmd.parm.num, "%s%c%c",
  510.      status + 2, *status, *(status + 1));
  511. else
  512. strncpy(cmd.parm.num, status + 1, sizeof(cmd.parm.num) - 1);
  513. break;
  514. case 8:
  515. card->flags &= ~ICN_FLAGS_B1ACTIVE;
  516. icn_free_queue(card, 0);
  517. save_flags(flags);
  518. cli();
  519. card->rcvidx[0] = 0;
  520. restore_flags(flags);
  521. cmd.arg = 0;
  522. cmd.driver = card->myid;
  523. card->interface.statcallb(&cmd);
  524. cmd.command = ISDN_STAT_DHUP;
  525. cmd.arg = 0;
  526. cmd.driver = card->myid;
  527. card->interface.statcallb(&cmd);
  528. cmd.command = ISDN_STAT_BHUP;
  529. card->flags &= ~ICN_FLAGS_B2ACTIVE;
  530. icn_free_queue(card, 1);
  531. save_flags(flags);
  532. cli();
  533. card->rcvidx[1] = 0;
  534. restore_flags(flags);
  535. cmd.arg = 1;
  536. cmd.driver = card->myid;
  537. card->interface.statcallb(&cmd);
  538. cmd.command = ISDN_STAT_DHUP;
  539. cmd.arg = 1;
  540. cmd.driver = card->myid;
  541. break;
  542. }
  543. card->interface.statcallb(&cmd);
  544. return;
  545. }
  546. static void
  547. icn_putmsg(icn_card * card, unsigned char c)
  548. {
  549. ulong flags;
  550. save_flags(flags);
  551. cli();
  552. *card->msg_buf_write++ = (c == 0xff) ? 'n' : c;
  553. if (card->msg_buf_write == card->msg_buf_read) {
  554. if (++card->msg_buf_read > card->msg_buf_end)
  555. card->msg_buf_read = card->msg_buf;
  556. }
  557. if (card->msg_buf_write > card->msg_buf_end)
  558. card->msg_buf_write = card->msg_buf;
  559. restore_flags(flags);
  560. }
  561. static void
  562. icn_polldchan(unsigned long data)
  563. {
  564. icn_card *card = (icn_card *) data;
  565. int mch = card->secondhalf ? 2 : 0;
  566. int avail = 0;
  567. int left;
  568. u_char c;
  569. int ch;
  570. unsigned long flags;
  571. int i;
  572. u_char *p;
  573. isdn_ctrl cmd;
  574. if (icn_trymaplock_channel(card, mch)) {
  575. avail = msg_avail;
  576. for (left = avail, i = readb(&msg_o); left > 0; i++, left--) {
  577. c = readb(&dev.shmem->comm_buffers.iopc_buf[i & 0xff]);
  578. icn_putmsg(card, c);
  579. if (c == 0xff) {
  580. card->imsg[card->iptr] = 0;
  581. card->iptr = 0;
  582. if (card->imsg[0] == '0' && card->imsg[1] >= '0' &&
  583.     card->imsg[1] <= '2' && card->imsg[2] == ';') {
  584. ch = (card->imsg[1] - '0') - 1;
  585. p = &card->imsg[3];
  586. icn_parse_status(p, ch, card);
  587. } else {
  588. p = card->imsg;
  589. if (!strncmp(p, "DRV1.", 5)) {
  590. u_char vstr[10];
  591. u_char *q = vstr;
  592. printk(KERN_INFO "icn: (%s) %sn", CID, p);
  593. if (!strncmp(p + 7, "TC", 2)) {
  594. card->ptype = ISDN_PTYPE_1TR6;
  595. card->interface.features |= ISDN_FEATURE_P_1TR6;
  596. printk(KERN_INFO
  597.        "icn: (%s) 1TR6-Protocol loaded and runningn", CID);
  598. }
  599. if (!strncmp(p + 7, "EC", 2)) {
  600. card->ptype = ISDN_PTYPE_EURO;
  601. card->interface.features |= ISDN_FEATURE_P_EURO;
  602. printk(KERN_INFO
  603.        "icn: (%s) Euro-Protocol loaded and runningn", CID);
  604. }
  605. p = strstr(card->imsg, "BRV") + 3;
  606. while (*p) {
  607. if (*p >= '0' && *p <= '9')
  608. *q++ = *p;
  609. p++;
  610. }
  611. *q = '';
  612. strcat(vstr, "000");
  613. vstr[3] = '';
  614. card->fw_rev = (int) simple_strtoul(vstr, NULL, 10);
  615. continue;
  616. }
  617. }
  618. } else {
  619. card->imsg[card->iptr] = c;
  620. if (card->iptr < 59)
  621. card->iptr++;
  622. }
  623. }
  624. writeb((readb(&msg_o) + avail) & 0xff, &msg_o);
  625. icn_release_channel();
  626. }
  627. if (avail) {
  628. cmd.command = ISDN_STAT_STAVAIL;
  629. cmd.driver = card->myid;
  630. cmd.arg = avail;
  631. card->interface.statcallb(&cmd);
  632. }
  633. if (card->flags & (ICN_FLAGS_B1ACTIVE | ICN_FLAGS_B2ACTIVE))
  634. if (!(card->flags & ICN_FLAGS_RBTIMER)) {
  635. /* schedule b-channel polling */
  636. card->flags |= ICN_FLAGS_RBTIMER;
  637. save_flags(flags);
  638. cli();
  639. del_timer(&card->rb_timer);
  640. card->rb_timer.function = icn_pollbchan;
  641. card->rb_timer.data = (unsigned long) card;
  642. card->rb_timer.expires = jiffies + ICN_TIMER_BCREAD;
  643. add_timer(&card->rb_timer);
  644. restore_flags(flags);
  645. }
  646. /* schedule again */
  647. save_flags(flags);
  648. cli();
  649. mod_timer(&card->st_timer, jiffies+ICN_TIMER_DCREAD);
  650. restore_flags(flags);
  651. }
  652. /* Append a packet to the transmit buffer-queue.
  653.  * Parameters:
  654.  *   channel = Number of B-channel
  655.  *   skb     = pointer to sk_buff
  656.  *   card    = pointer to card-struct
  657.  * Return:
  658.  *   Number of bytes transferred, -E??? on error
  659.  */
  660. static int
  661. icn_sendbuf(int channel, int ack, struct sk_buff *skb, icn_card * card)
  662. {
  663. int len = skb->len;
  664. unsigned long flags;
  665. struct sk_buff *nskb;
  666. if (len > 4000) {
  667. printk(KERN_WARNING
  668.        "icn: Send packet too largen");
  669. return -EINVAL;
  670. }
  671. if (len) {
  672. if (!(card->flags & (channel) ? ICN_FLAGS_B2ACTIVE : ICN_FLAGS_B1ACTIVE))
  673. return 0;
  674. if (card->sndcount[channel] > ICN_MAX_SQUEUE)
  675. return 0;
  676. save_flags(flags);
  677. cli();
  678. nskb = skb_clone(skb, GFP_ATOMIC);
  679. if (nskb) {
  680. /* Push ACK flag as one
  681.  * byte in front of data.
  682.  */
  683. *(skb_push(nskb, 1)) = ack?1:0;
  684. skb_queue_tail(&card->spqueue[channel], nskb);
  685. dev_kfree_skb(skb);
  686. } else
  687. len = 0;
  688. card->sndcount[channel] += len;
  689. restore_flags(flags);
  690. }
  691. return len;
  692. }
  693. /*
  694.  * Check card's status after starting the bootstrap loader.
  695.  * On entry, the card's shared memory has already to be mapped.
  696.  * Return:
  697.  *   0 on success (Boot loader ready)
  698.  *   -EIO on failure (timeout)
  699.  */
  700. static int
  701. icn_check_loader(int cardnumber)
  702. {
  703. int timer = 0;
  704. while (1) {
  705. #ifdef BOOT_DEBUG
  706. printk(KERN_DEBUG "Loader %d ?n", cardnumber);
  707. #endif
  708. if (readb(&dev.shmem->data_control.scns) ||
  709.     readb(&dev.shmem->data_control.scnr)) {
  710. if (timer++ > 5) {
  711. printk(KERN_WARNING
  712.        "icn: Boot-Loader %d timed out.n",
  713.        cardnumber);
  714. icn_release_channel();
  715. return -EIO;
  716. }
  717. #ifdef BOOT_DEBUG
  718. printk(KERN_DEBUG "Loader %d TO?n", cardnumber);
  719. #endif
  720. current->state = TASK_INTERRUPTIBLE;
  721. schedule_timeout(ICN_BOOT_TIMEOUT1);
  722. } else {
  723. #ifdef BOOT_DEBUG
  724. printk(KERN_DEBUG "Loader %d OKn", cardnumber);
  725. #endif
  726. icn_release_channel();
  727. return 0;
  728. }
  729. }
  730. }
  731. /* Load the boot-code into the interface-card's memory and start it.
  732.  * Always called from user-process.
  733.  *
  734.  * Parameters:
  735.  *            buffer = pointer to packet
  736.  * Return:
  737.  *        0 if successfully loaded
  738.  */
  739. #ifdef BOOT_DEBUG
  740. #define SLEEP(sec) { 
  741. int slsec = sec; 
  742.   printk(KERN_DEBUG "SLEEP(%d)n",slsec); 
  743.   while (slsec) { 
  744.     current->state = TASK_INTERRUPTIBLE; 
  745.     schedule_timeout(HZ); 
  746.     slsec--; 
  747.   } 
  748. }
  749. #else
  750. #define SLEEP(sec)
  751. #endif
  752. static int
  753. icn_loadboot(u_char * buffer, icn_card * card)
  754. {
  755. int ret;
  756. u_char *codebuf;
  757. unsigned long flags;
  758. #ifdef BOOT_DEBUG
  759. printk(KERN_DEBUG "icn_loadboot called, buffaddr=%08lxn", (ulong) buffer);
  760. #endif
  761. if (!(codebuf = kmalloc(ICN_CODE_STAGE1, GFP_KERNEL))) {
  762. printk(KERN_WARNING "icn: Could not allocate code buffern");
  763. return -ENOMEM;
  764. }
  765. if ((ret = copy_from_user(codebuf, buffer, ICN_CODE_STAGE1))) {
  766. kfree(codebuf);
  767. return ret;
  768. }
  769. if (!card->rvalid) {
  770. if (check_region(card->port, ICN_PORTLEN)) {
  771. printk(KERN_WARNING
  772.        "icn: (%s) ports 0x%03x-0x%03x in use.n",
  773.        CID,
  774.        card->port,
  775.        card->port + ICN_PORTLEN);
  776. kfree(codebuf);
  777. return -EBUSY;
  778. }
  779. request_region(card->port, ICN_PORTLEN, card->regname);
  780. card->rvalid = 1;
  781. if (card->doubleS0)
  782. card->other->rvalid = 1;
  783. }
  784. if (!dev.mvalid) {
  785. if (check_mem_region(dev.memaddr, 0x4000)) {
  786. printk(KERN_WARNING
  787.        "icn: memory at 0x%08lx in use.n", dev.memaddr);
  788. return -EBUSY;
  789. }
  790. request_mem_region(dev.memaddr, 0x4000, "icn-isdn (all cards)");
  791. dev.shmem = ioremap(dev.memaddr, 0x4000);
  792. dev.mvalid = 1;
  793. }
  794. OUTB_P(0, ICN_RUN);     /* Reset Controller */
  795. OUTB_P(0, ICN_MAPRAM);  /* Disable RAM      */
  796. icn_shiftout(ICN_CFG, 0x0f, 3, 4); /* Windowsize= 16k  */
  797. icn_shiftout(ICN_CFG, dev.memaddr, 23, 10); /* Set RAM-Addr.    */
  798. #ifdef BOOT_DEBUG
  799. printk(KERN_DEBUG "shmem=%08lxn", dev.memaddr);
  800. #endif
  801. SLEEP(1);
  802. #ifdef BOOT_DEBUG
  803. printk(KERN_DEBUG "Map Bank 0n");
  804. #endif
  805. save_flags(flags);
  806. cli();
  807. icn_map_channel(card, 0); /* Select Bank 0    */
  808. icn_lock_channel(card, 0); /* Lock Bank 0      */
  809. restore_flags(flags);
  810. SLEEP(1);
  811. memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code        */
  812. #ifdef BOOT_DEBUG
  813. printk(KERN_DEBUG "Bootloader transferredn");
  814. #endif
  815. if (card->doubleS0) {
  816. SLEEP(1);
  817. #ifdef BOOT_DEBUG
  818. printk(KERN_DEBUG "Map Bank 8n");
  819. #endif
  820. save_flags(flags);
  821. cli();
  822. icn_release_channel();
  823. icn_map_channel(card, 2); /* Select Bank 8   */
  824. icn_lock_channel(card, 2); /* Lock Bank 8     */
  825. restore_flags(flags);
  826. SLEEP(1);
  827. memcpy_toio(dev.shmem, codebuf, ICN_CODE_STAGE1); /* Copy code        */
  828. #ifdef BOOT_DEBUG
  829. printk(KERN_DEBUG "Bootloader transferredn");
  830. #endif
  831. }
  832. kfree(codebuf);
  833. SLEEP(1);
  834. OUTB_P(0xff, ICN_RUN);  /* Start Boot-Code */
  835. if ((ret = icn_check_loader(card->doubleS0 ? 2 : 1)))
  836. return ret;
  837. if (!card->doubleS0)
  838. return 0;
  839. /* reached only, if we have a Double-S0-Card */
  840. #ifdef BOOT_DEBUG
  841. printk(KERN_DEBUG "Map Bank 0n");
  842. #endif
  843. save_flags(flags);
  844. cli();
  845. icn_map_channel(card, 0); /* Select Bank 0   */
  846. icn_lock_channel(card, 0); /* Lock Bank 0     */
  847. restore_flags(flags);
  848. SLEEP(1);
  849. return (icn_check_loader(1));
  850. }
  851. static int
  852. icn_loadproto(u_char * buffer, icn_card * card)
  853. {
  854. register u_char *p = buffer;
  855. u_char codebuf[256];
  856. uint left = ICN_CODE_STAGE2;
  857. uint cnt;
  858. int timer;
  859. int ret;
  860. unsigned long flags;
  861. #ifdef BOOT_DEBUG
  862. printk(KERN_DEBUG "icn_loadproto calledn");
  863. #endif
  864. if ((ret = verify_area(VERIFY_READ, (void *) buffer, ICN_CODE_STAGE2)))
  865. return ret;
  866. timer = 0;
  867. save_flags(flags);
  868. cli();
  869. if (card->secondhalf) {
  870. icn_map_channel(card, 2);
  871. icn_lock_channel(card, 2);
  872. } else {
  873. icn_map_channel(card, 0);
  874. icn_lock_channel(card, 0);
  875. }
  876. restore_flags(flags);
  877. while (left) {
  878. if (sbfree) {   /* If there is a free buffer...  */
  879. cnt = left;
  880. if (cnt > 256)
  881. cnt = 256;
  882. if (copy_from_user(codebuf, p, cnt)) {
  883. icn_maprelease_channel(card, 0);
  884. return -EFAULT;
  885. }
  886. memcpy_toio(&sbuf_l, codebuf, cnt); /* copy data                     */
  887. sbnext; /* switch to next buffer         */
  888. p += cnt;
  889. left -= cnt;
  890. timer = 0;
  891. } else {
  892. #ifdef BOOT_DEBUG
  893. printk(KERN_DEBUG "boot 2 !sbfreen");
  894. #endif
  895. if (timer++ > 5) {
  896. icn_maprelease_channel(card, 0);
  897. return -EIO;
  898. }
  899. current->state = TASK_INTERRUPTIBLE;
  900. schedule_timeout(10);
  901. }
  902. }
  903. writeb(0x20, &sbuf_n);
  904. timer = 0;
  905. while (1) {
  906. if (readb(&cmd_o) || readb(&cmd_i)) {
  907. #ifdef BOOT_DEBUG
  908. printk(KERN_DEBUG "Proto?n");
  909. #endif
  910. if (timer++ > 5) {
  911. printk(KERN_WARNING
  912.        "icn: (%s) Protocol timed out.n",
  913.        CID);
  914. #ifdef BOOT_DEBUG
  915. printk(KERN_DEBUG "Proto TO!n");
  916. #endif
  917. icn_maprelease_channel(card, 0);
  918. return -EIO;
  919. }
  920. #ifdef BOOT_DEBUG
  921. printk(KERN_DEBUG "Proto TO?n");
  922. #endif
  923. current->state = TASK_INTERRUPTIBLE;
  924. schedule_timeout(ICN_BOOT_TIMEOUT1);
  925. } else {
  926. if ((card->secondhalf) || (!card->doubleS0)) {
  927. #ifdef BOOT_DEBUG
  928. printk(KERN_DEBUG "Proto loaded, install poll-timer %dn",
  929.        card->secondhalf);
  930. #endif
  931. save_flags(flags);
  932. cli();
  933. init_timer(&card->st_timer);
  934. card->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
  935. card->st_timer.function = icn_polldchan;
  936. card->st_timer.data = (unsigned long) card;
  937. add_timer(&card->st_timer);
  938. card->flags |= ICN_FLAGS_RUNNING;
  939. if (card->doubleS0) {
  940. init_timer(&card->other->st_timer);
  941. card->other->st_timer.expires = jiffies + ICN_TIMER_DCREAD;
  942. card->other->st_timer.function = icn_polldchan;
  943. card->other->st_timer.data = (unsigned long) card->other;
  944. add_timer(&card->other->st_timer);
  945. card->other->flags |= ICN_FLAGS_RUNNING;
  946. }
  947. restore_flags(flags);
  948. }
  949. icn_maprelease_channel(card, 0);
  950. return 0;
  951. }
  952. }
  953. }
  954. /* Read the Status-replies from the Interface */
  955. static int
  956. icn_readstatus(u_char * buf, int len, int user, icn_card * card)
  957. {
  958. int count;
  959. u_char *p;
  960. for (p = buf, count = 0; count < len; p++, count++) {
  961. if (card->msg_buf_read == card->msg_buf_write)
  962. return count;
  963. if (user)
  964. put_user(*card->msg_buf_read++, p);
  965. else
  966. *p = *card->msg_buf_read++;
  967. if (card->msg_buf_read > card->msg_buf_end)
  968. card->msg_buf_read = card->msg_buf;
  969. }
  970. return count;
  971. }
  972. /* Put command-strings into the command-queue of the Interface */
  973. static int
  974. icn_writecmd(const u_char * buf, int len, int user, icn_card * card)
  975. {
  976. int mch = card->secondhalf ? 2 : 0;
  977. int pp;
  978. int i;
  979. int count;
  980. int xcount;
  981. int ocount;
  982. int loop;
  983. unsigned long flags;
  984. int lastmap_channel;
  985. struct icn_card *lastmap_card;
  986. u_char *p;
  987. isdn_ctrl cmd;
  988. u_char msg[0x100];
  989. ocount = 1;
  990. xcount = loop = 0;
  991. while (len) {
  992. count = cmd_free;
  993. if (count > len)
  994. count = len;
  995. if (user)
  996. copy_from_user(msg, buf, count);
  997. else
  998. memcpy(msg, buf, count);
  999. save_flags(flags);
  1000. cli();
  1001. lastmap_card = dev.mcard;
  1002. lastmap_channel = dev.channel;
  1003. icn_map_channel(card, mch);
  1004. icn_putmsg(card, '>');
  1005. for (p = msg, pp = readb(&cmd_i), i = count; i > 0; i--, p++, pp
  1006.      ++) {
  1007. writeb((*p == 'n') ? 0xff : *p,
  1008.    &dev.shmem->comm_buffers.pcio_buf[pp & 0xff]);
  1009. len--;
  1010. xcount++;
  1011. icn_putmsg(card, *p);
  1012. if ((*p == 'n') && (i > 1)) {
  1013. icn_putmsg(card, '>');
  1014. ocount++;
  1015. }
  1016. ocount++;
  1017. }
  1018. writeb((readb(&cmd_i) + count) & 0xff, &cmd_i);
  1019. if (lastmap_card)
  1020. icn_map_channel(lastmap_card, lastmap_channel);
  1021. restore_flags(flags);
  1022. if (len) {
  1023. mdelay(1);
  1024. if (loop++ > 20)
  1025. break;
  1026. } else
  1027. break;
  1028. }
  1029. if (len && (!user))
  1030. printk(KERN_WARNING "icn: writemsg incomplete!n");
  1031. cmd.command = ISDN_STAT_STAVAIL;
  1032. cmd.driver = card->myid;
  1033. cmd.arg = ocount;
  1034. card->interface.statcallb(&cmd);
  1035. return xcount;
  1036. }
  1037. /*
  1038.  * Delete card's pending timers, send STOP to linklevel
  1039.  */
  1040. static void
  1041. icn_stopcard(icn_card * card)
  1042. {
  1043. unsigned long flags;
  1044. isdn_ctrl cmd;
  1045. save_flags(flags);
  1046. cli();
  1047. if (card->flags & ICN_FLAGS_RUNNING) {
  1048. card->flags &= ~ICN_FLAGS_RUNNING;
  1049. del_timer(&card->st_timer);
  1050. del_timer(&card->rb_timer);
  1051. cmd.command = ISDN_STAT_STOP;
  1052. cmd.driver = card->myid;
  1053. card->interface.statcallb(&cmd);
  1054. if (card->doubleS0)
  1055. icn_stopcard(card->other);
  1056. }
  1057. restore_flags(flags);
  1058. }
  1059. static void
  1060. icn_stopallcards(void)
  1061. {
  1062. icn_card *p = cards;
  1063. while (p) {
  1064. icn_stopcard(p);
  1065. p = p->next;
  1066. }
  1067. }
  1068. /*
  1069.  * Unmap all cards, because some of them may be mapped accidetly during
  1070.  * autoprobing of some network drivers (SMC-driver?)
  1071.  */
  1072. static void
  1073. icn_disable_cards(void)
  1074. {
  1075. icn_card *card = cards;
  1076. while (card) {
  1077. if (check_region(card->port, ICN_PORTLEN)) {
  1078. printk(KERN_WARNING
  1079.        "icn: (%s) ports 0x%03x-0x%03x in use.n",
  1080.        CID,
  1081.        card->port,
  1082.        card->port + ICN_PORTLEN);
  1083. } else {
  1084. OUTB_P(0, ICN_RUN); /* Reset Controller     */
  1085. OUTB_P(0, ICN_MAPRAM); /* Disable RAM          */
  1086. }
  1087. card = card->next;
  1088. }
  1089. }
  1090. static int
  1091. icn_command(isdn_ctrl * c, icn_card * card)
  1092. {
  1093. ulong a;
  1094. ulong flags;
  1095. int i;
  1096. char cbuf[60];
  1097. isdn_ctrl cmd;
  1098. icn_cdef cdef;
  1099. switch (c->command) {
  1100. case ISDN_CMD_IOCTL:
  1101. memcpy(&a, c->parm.num, sizeof(ulong));
  1102. switch (c->arg) {
  1103. case ICN_IOCTL_SETMMIO:
  1104. if (dev.memaddr != (a & 0x0ffc000)) {
  1105. if (check_mem_region(a & 0x0ffc000, 0x4000)) {
  1106. printk(KERN_WARNING
  1107.        "icn: memory at 0x%08lx in use.n",
  1108.        a & 0x0ffc000);
  1109. return -EINVAL;
  1110. }
  1111. icn_stopallcards();
  1112. save_flags(flags);
  1113. cli();
  1114. if (dev.mvalid) {
  1115. iounmap(dev.shmem);
  1116. release_mem_region(dev.memaddr, 0x4000);
  1117. }
  1118. dev.mvalid = 0;
  1119. dev.memaddr = a & 0x0ffc000;
  1120. restore_flags(flags);
  1121. printk(KERN_INFO
  1122.        "icn: (%s) mmio set to 0x%08lxn",
  1123.        CID,
  1124.        dev.memaddr);
  1125. }
  1126. break;
  1127. case ICN_IOCTL_GETMMIO:
  1128. return (long) dev.memaddr;
  1129. case ICN_IOCTL_SETPORT:
  1130. if (a == 0x300 || a == 0x310 || a == 0x320 || a == 0x330
  1131.     || a == 0x340 || a == 0x350 || a == 0x360 ||
  1132.     a == 0x308 || a == 0x318 || a == 0x328 || a == 0x338
  1133.     || a == 0x348 || a == 0x358 || a == 0x368) {
  1134. if (card->port != (unsigned short) a) {
  1135. if (check_region((unsigned short) a, ICN_PORTLEN)) {
  1136. printk(KERN_WARNING
  1137.        "icn: (%s) ports 0x%03x-0x%03x in use.n",
  1138.        CID, (int) a, (int) a + ICN_PORTLEN);
  1139. return -EINVAL;
  1140. }
  1141. icn_stopcard(card);
  1142. save_flags(flags);
  1143. cli();
  1144. if (card->rvalid)
  1145. release_region(card->port, ICN_PORTLEN);
  1146. card->port = (unsigned short) a;
  1147. card->rvalid = 0;
  1148. if (card->doubleS0) {
  1149. card->other->port = (unsigned short) a;
  1150. card->other->rvalid = 0;
  1151. }
  1152. restore_flags(flags);
  1153. printk(KERN_INFO
  1154.        "icn: (%s) port set to 0x%03xn",
  1155. CID, card->port);
  1156. }
  1157. } else
  1158. return -EINVAL;
  1159. break;
  1160. case ICN_IOCTL_GETPORT:
  1161. return (int) card->port;
  1162. case ICN_IOCTL_GETDOUBLE:
  1163. return (int) card->doubleS0;
  1164. case ICN_IOCTL_DEBUGVAR:
  1165. if ((i = copy_to_user((char *) a,
  1166.   (char *) &card, sizeof(ulong))))
  1167. return i;
  1168. a += sizeof(ulong);
  1169. {
  1170. ulong l = (ulong) & dev;
  1171. if ((i = copy_to_user((char *) a,
  1172.      (char *) &l, sizeof(ulong))))
  1173. return i;
  1174. }
  1175. return 0;
  1176. case ICN_IOCTL_LOADBOOT:
  1177. if (dev.firstload) {
  1178. icn_disable_cards();
  1179. dev.firstload = 0;
  1180. }
  1181. icn_stopcard(card);
  1182. return (icn_loadboot((u_char *) a, card));
  1183. case ICN_IOCTL_LOADPROTO:
  1184. icn_stopcard(card);
  1185. if ((i = (icn_loadproto((u_char *) a, card))))
  1186. return i;
  1187. if (card->doubleS0)
  1188. i = icn_loadproto((u_char *) (a + ICN_CODE_STAGE2), card->other);
  1189. return i;
  1190. break;
  1191. case ICN_IOCTL_ADDCARD:
  1192. if (!dev.firstload)
  1193. return -EBUSY;
  1194. if ((i = copy_from_user((char *) &cdef, (char *) a, sizeof(cdef))))
  1195. return i;
  1196. return (icn_addcard(cdef.port, cdef.id1, cdef.id2));
  1197. break;
  1198. case ICN_IOCTL_LEASEDCFG:
  1199. if (a) {
  1200. if (!card->leased) {
  1201. card->leased = 1;
  1202. while (card->ptype == ISDN_PTYPE_UNKNOWN) {
  1203. schedule_timeout(ICN_BOOT_TIMEOUT1);
  1204. }
  1205. schedule_timeout(ICN_BOOT_TIMEOUT1);
  1206. sprintf(cbuf, "00;FV2ONn01;EAZ%cn02;EAZ%cn",
  1207. (a & 1)?'1':'C', (a & 2)?'2':'C');
  1208. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1209. printk(KERN_INFO
  1210.        "icn: (%s) Leased-line mode enabledn",
  1211.        CID);
  1212. cmd.command = ISDN_STAT_RUN;
  1213. cmd.driver = card->myid;
  1214. cmd.arg = 0;
  1215. card->interface.statcallb(&cmd);
  1216. }
  1217. } else {
  1218. if (card->leased) {
  1219. card->leased = 0;
  1220. sprintf(cbuf, "00;FV2OFFn");
  1221. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1222. printk(KERN_INFO
  1223.        "icn: (%s) Leased-line mode disabledn",
  1224.        CID);
  1225. cmd.command = ISDN_STAT_RUN;
  1226. cmd.driver = card->myid;
  1227. cmd.arg = 0;
  1228. card->interface.statcallb(&cmd);
  1229. }
  1230. }
  1231. return 0;
  1232. default:
  1233. return -EINVAL;
  1234. }
  1235. break;
  1236. case ISDN_CMD_DIAL:
  1237. if (!card->flags & ICN_FLAGS_RUNNING)
  1238. return -ENODEV;
  1239. if (card->leased)
  1240. break;
  1241. if ((c->arg & 255) < ICN_BCH) {
  1242. char *p;
  1243. char dial[50];
  1244. char dcode[4];
  1245. a = c->arg;
  1246. p = c->parm.setup.phone;
  1247. if (*p == 's' || *p == 'S') {
  1248. /* Dial for SPV */
  1249. p++;
  1250. strcpy(dcode, "SCA");
  1251. } else
  1252. /* Normal Dial */
  1253. strcpy(dcode, "CAL");
  1254. strcpy(dial, p);
  1255. sprintf(cbuf, "%02d;D%s_R%s,%02d,%02d,%sn", (int) (a + 1),
  1256. dcode, dial, c->parm.setup.si1,
  1257. c->parm.setup.si2, c->parm.setup.eazmsn);
  1258. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1259. }
  1260. break;
  1261. case ISDN_CMD_ACCEPTD:
  1262. if (!card->flags & ICN_FLAGS_RUNNING)
  1263. return -ENODEV;
  1264. if (c->arg < ICN_BCH) {
  1265. a = c->arg + 1;
  1266. if (card->fw_rev >= 300) {
  1267. switch (card->l2_proto[a - 1]) {
  1268. case ISDN_PROTO_L2_X75I:
  1269. sprintf(cbuf, "%02d;BX75n", (int) a);
  1270. break;
  1271. case ISDN_PROTO_L2_HDLC:
  1272. sprintf(cbuf, "%02d;BTRAn", (int) a);
  1273. break;
  1274. }
  1275. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1276. }
  1277. sprintf(cbuf, "%02d;DCON_Rn", (int) a);
  1278. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1279. }
  1280. break;
  1281. case ISDN_CMD_ACCEPTB:
  1282. if (!card->flags & ICN_FLAGS_RUNNING)
  1283. return -ENODEV;
  1284. if (c->arg < ICN_BCH) {
  1285. a = c->arg + 1;
  1286. if (card->fw_rev >= 300)
  1287. switch (card->l2_proto[a - 1]) {
  1288. case ISDN_PROTO_L2_X75I:
  1289. sprintf(cbuf, "%02d;BCON_R,BX75n", (int) a);
  1290. break;
  1291. case ISDN_PROTO_L2_HDLC:
  1292. sprintf(cbuf, "%02d;BCON_R,BTRAn", (int) a);
  1293. break;
  1294. } else
  1295. sprintf(cbuf, "%02d;BCON_Rn", (int) a);
  1296. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1297. }
  1298. break;
  1299. case ISDN_CMD_HANGUP:
  1300. if (!card->flags & ICN_FLAGS_RUNNING)
  1301. return -ENODEV;
  1302. if (c->arg < ICN_BCH) {
  1303. a = c->arg + 1;
  1304. sprintf(cbuf, "%02d;BDIS_Rn%02d;DDIS_Rn", (int) a, (int) a);
  1305. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1306. }
  1307. break;
  1308. case ISDN_CMD_SETEAZ:
  1309. if (!card->flags & ICN_FLAGS_RUNNING)
  1310. return -ENODEV;
  1311. if (card->leased)
  1312. break;
  1313. if (c->arg < ICN_BCH) {
  1314. a = c->arg + 1;
  1315. if (card->ptype == ISDN_PTYPE_EURO) {
  1316. sprintf(cbuf, "%02d;MS%s%sn", (int) a,
  1317. c->parm.num[0] ? "N" : "ALL", c->parm.num);
  1318. } else
  1319. sprintf(cbuf, "%02d;EAZ%sn", (int) a,
  1320. c->parm.num[0] ? (char *)(c->parm.num) : "0123456789");
  1321. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1322. }
  1323. break;
  1324. case ISDN_CMD_CLREAZ:
  1325. if (!card->flags & ICN_FLAGS_RUNNING)
  1326. return -ENODEV;
  1327. if (card->leased)
  1328. break;
  1329. if (c->arg < ICN_BCH) {
  1330. a = c->arg + 1;
  1331. if (card->ptype == ISDN_PTYPE_EURO)
  1332. sprintf(cbuf, "%02d;MSNCn", (int) a);
  1333. else
  1334. sprintf(cbuf, "%02d;EAZCn", (int) a);
  1335. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1336. }
  1337. break;
  1338. case ISDN_CMD_SETL2:
  1339. if (!card->flags & ICN_FLAGS_RUNNING)
  1340. return -ENODEV;
  1341. if ((c->arg & 255) < ICN_BCH) {
  1342. a = c->arg;
  1343. switch (a >> 8) {
  1344. case ISDN_PROTO_L2_X75I:
  1345. sprintf(cbuf, "%02d;BX75n", (int) (a & 255) + 1);
  1346. break;
  1347. case ISDN_PROTO_L2_HDLC:
  1348. sprintf(cbuf, "%02d;BTRAn", (int) (a & 255) + 1);
  1349. break;
  1350. default:
  1351. return -EINVAL;
  1352. }
  1353. i = icn_writecmd(cbuf, strlen(cbuf), 0, card);
  1354. card->l2_proto[a & 255] = (a >> 8);
  1355. }
  1356. break;
  1357. case ISDN_CMD_GETL2:
  1358. if (!card->flags & ICN_FLAGS_RUNNING)
  1359. return -ENODEV;
  1360. if ((c->arg & 255) < ICN_BCH)
  1361. return card->l2_proto[c->arg & 255];
  1362. else
  1363. return -ENODEV;
  1364. case ISDN_CMD_SETL3:
  1365. if (!card->flags & ICN_FLAGS_RUNNING)
  1366. return -ENODEV;
  1367. return 0;
  1368. case ISDN_CMD_GETL3:
  1369. if (!card->flags & ICN_FLAGS_RUNNING)
  1370. return -ENODEV;
  1371. if ((c->arg & 255) < ICN_BCH)
  1372. return ISDN_PROTO_L3_TRANS;
  1373. else
  1374. return -ENODEV;
  1375. case ISDN_CMD_GETEAZ:
  1376. if (!card->flags & ICN_FLAGS_RUNNING)
  1377. return -ENODEV;
  1378. break;
  1379. case ISDN_CMD_SETSIL:
  1380. if (!card->flags & ICN_FLAGS_RUNNING)
  1381. return -ENODEV;
  1382. break;
  1383. case ISDN_CMD_GETSIL:
  1384. if (!card->flags & ICN_FLAGS_RUNNING)
  1385. return -ENODEV;
  1386. break;
  1387. case ISDN_CMD_LOCK:
  1388. MOD_INC_USE_COUNT;
  1389. break;
  1390. case ISDN_CMD_UNLOCK:
  1391. MOD_DEC_USE_COUNT;
  1392. break;
  1393. default:
  1394. return -EINVAL;
  1395. }
  1396. return 0;
  1397. }
  1398. /*
  1399.  * Find card with given driverId
  1400.  */
  1401. static inline icn_card *
  1402. icn_findcard(int driverid)
  1403. {
  1404. icn_card *p = cards;
  1405. while (p) {
  1406. if (p->myid == driverid)
  1407. return p;
  1408. p = p->next;
  1409. }
  1410. return (icn_card *) 0;
  1411. }
  1412. /*
  1413.  * Wrapper functions for interface to linklevel
  1414.  */
  1415. static int
  1416. if_command(isdn_ctrl * c)
  1417. {
  1418. icn_card *card = icn_findcard(c->driver);
  1419. if (card)
  1420. return (icn_command(c, card));
  1421. printk(KERN_ERR
  1422.        "icn: if_command %d called with invalid driverId %d!n",
  1423.        c->command, c->driver);
  1424. return -ENODEV;
  1425. }
  1426. static int
  1427. if_writecmd(const u_char * buf, int len, int user, int id, int channel)
  1428. {
  1429. icn_card *card = icn_findcard(id);
  1430. if (card) {
  1431. if (!card->flags & ICN_FLAGS_RUNNING)
  1432. return -ENODEV;
  1433. return (icn_writecmd(buf, len, user, card));
  1434. }
  1435. printk(KERN_ERR
  1436.        "icn: if_writecmd called with invalid driverId!n");
  1437. return -ENODEV;
  1438. }
  1439. static int
  1440. if_readstatus(u_char * buf, int len, int user, int id, int channel)
  1441. {
  1442. icn_card *card = icn_findcard(id);
  1443. if (card) {
  1444. if (!card->flags & ICN_FLAGS_RUNNING)
  1445. return -ENODEV;
  1446. return (icn_readstatus(buf, len, user, card));
  1447. }
  1448. printk(KERN_ERR
  1449.        "icn: if_readstatus called with invalid driverId!n");
  1450. return -ENODEV;
  1451. }
  1452. static int
  1453. if_sendbuf(int id, int channel, int ack, struct sk_buff *skb)
  1454. {
  1455. icn_card *card = icn_findcard(id);
  1456. if (card) {
  1457. if (!card->flags & ICN_FLAGS_RUNNING)
  1458. return -ENODEV;
  1459. return (icn_sendbuf(channel, ack, skb, card));
  1460. }
  1461. printk(KERN_ERR
  1462.        "icn: if_sendbuf called with invalid driverId!n");
  1463. return -ENODEV;
  1464. }
  1465. /*
  1466.  * Allocate a new card-struct, initialize it
  1467.  * link it into cards-list and register it at linklevel.
  1468.  */
  1469. static icn_card *
  1470. icn_initcard(int port, char *id)
  1471. {
  1472. icn_card *card;
  1473. int i;
  1474. if (!(card = (icn_card *) kmalloc(sizeof(icn_card), GFP_KERNEL))) {
  1475. printk(KERN_WARNING
  1476.        "icn: (%s) Could not allocate card-struct.n", id);
  1477. return (icn_card *) 0;
  1478. }
  1479. memset((char *) card, 0, sizeof(icn_card));
  1480. card->port = port;
  1481. card->interface.hl_hdrlen = 1;
  1482. card->interface.channels = ICN_BCH;
  1483. card->interface.maxbufsize = 4000;
  1484. card->interface.command = if_command;
  1485. card->interface.writebuf_skb = if_sendbuf;
  1486. card->interface.writecmd = if_writecmd;
  1487. card->interface.readstat = if_readstatus;
  1488. card->interface.features = ISDN_FEATURE_L2_X75I |
  1489.     ISDN_FEATURE_L2_HDLC |
  1490.     ISDN_FEATURE_L3_TRANS |
  1491.     ISDN_FEATURE_P_UNKNOWN;
  1492. card->ptype = ISDN_PTYPE_UNKNOWN;
  1493. strncpy(card->interface.id, id, sizeof(card->interface.id) - 1);
  1494. card->msg_buf_write = card->msg_buf;
  1495. card->msg_buf_read = card->msg_buf;
  1496. card->msg_buf_end = &card->msg_buf[sizeof(card->msg_buf) - 1];
  1497. for (i = 0; i < ICN_BCH; i++) {
  1498. card->l2_proto[i] = ISDN_PROTO_L2_X75I;
  1499. skb_queue_head_init(&card->spqueue[i]);
  1500. }
  1501. card->next = cards;
  1502. cards = card;
  1503. if (!register_isdn(&card->interface)) {
  1504. cards = cards->next;
  1505. printk(KERN_WARNING
  1506.        "icn: Unable to register %sn", id);
  1507. kfree(card);
  1508. return (icn_card *) 0;
  1509. }
  1510. card->myid = card->interface.channels;
  1511. sprintf(card->regname, "icn-isdn (%s)", card->interface.id);
  1512. return card;
  1513. }
  1514. static int
  1515. icn_addcard(int port, char *id1, char *id2)
  1516. {
  1517. icn_card *card;
  1518. icn_card *card2;
  1519. if (!(card = icn_initcard(port, id1))) {
  1520. return -EIO;
  1521. }
  1522. if (!strlen(id2)) {
  1523. printk(KERN_INFO
  1524.        "icn: (%s) ICN-2B, port 0x%x addedn",
  1525.        card->interface.id, port);
  1526. return 0;
  1527. }
  1528. if (!(card2 = icn_initcard(port, id2))) {
  1529. printk(KERN_INFO
  1530.        "icn: (%s) half ICN-4B, port 0x%x addedn",
  1531.        card2->interface.id, port);
  1532. return 0;
  1533. }
  1534. card->doubleS0 = 1;
  1535. card->secondhalf = 0;
  1536. card->other = card2;
  1537. card2->doubleS0 = 1;
  1538. card2->secondhalf = 1;
  1539. card2->other = card;
  1540. printk(KERN_INFO
  1541.        "icn: (%s and %s) ICN-4B, port 0x%x addedn",
  1542.        card->interface.id, card2->interface.id, port);
  1543. return 0;
  1544. }
  1545. #ifndef MODULE
  1546. static int __init
  1547. icn_setup(char *line)
  1548. {
  1549. char *p, *str;
  1550. int ints[3];
  1551. static char sid[20];
  1552. static char sid2[20];
  1553. str = get_options(line, 2, ints);
  1554. if (ints[0])
  1555. portbase = ints[1];
  1556. if (ints[0] > 1)
  1557. membase = (unsigned long)ints[2];
  1558. if (str && *str) {
  1559. strcpy(sid, str);
  1560. icn_id = sid;
  1561. if ((p = strchr(sid, ','))) {
  1562. *p++ = 0;
  1563. strcpy(sid2, p);
  1564. icn_id2 = sid2;
  1565. }
  1566. }
  1567. return(1);
  1568. }
  1569. __setup("icn=", icn_setup);
  1570. #endif /* MODULE */
  1571. static int __init icn_init(void)
  1572. {
  1573. char *p;
  1574. char rev[10];
  1575. memset(&dev, 0, sizeof(icn_dev));
  1576. dev.memaddr = (membase & 0x0ffc000);
  1577. dev.channel = -1;
  1578. dev.mcard = NULL;
  1579. dev.firstload = 1;
  1580. if ((p = strchr(revision, ':'))) {
  1581. strcpy(rev, p + 1);
  1582. p = strchr(rev, '$');
  1583. *p = 0;
  1584. } else
  1585. strcpy(rev, " ??? ");
  1586. printk(KERN_NOTICE "ICN-ISDN-driver Rev%smem=0x%08lxn", rev,
  1587.        dev.memaddr);
  1588. return (icn_addcard(portbase, icn_id, icn_id2));
  1589. }
  1590. static void __exit icn_exit(void)
  1591. {
  1592. isdn_ctrl cmd;
  1593. icn_card *card = cards;
  1594. icn_card *last;
  1595. int i;
  1596. icn_stopallcards();
  1597. while (card) {
  1598. cmd.command = ISDN_STAT_UNLOAD;
  1599. cmd.driver = card->myid;
  1600. card->interface.statcallb(&cmd);
  1601. if (card->rvalid) {
  1602. OUTB_P(0, ICN_RUN); /* Reset Controller     */
  1603. OUTB_P(0, ICN_MAPRAM); /* Disable RAM          */
  1604. if (card->secondhalf || (!card->doubleS0)) {
  1605. release_region(card->port, ICN_PORTLEN);
  1606. card->rvalid = 0;
  1607. }
  1608. for (i = 0; i < ICN_BCH; i++)
  1609. icn_free_queue(card, i);
  1610. }
  1611. card = card->next;
  1612. }
  1613. card = cards;
  1614. while (card) {
  1615. last = card;
  1616. card = card->next;
  1617. kfree(last);
  1618. }
  1619. if (dev.mvalid) {
  1620. iounmap(dev.shmem);
  1621. release_mem_region(dev.memaddr, 0x4000);
  1622. }
  1623. printk(KERN_NOTICE "ICN-ISDN-driver unloadedn");
  1624. }
  1625. module_init(icn_init);
  1626. module_exit(icn_exit);