elsa_ser.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:17k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: elsa_ser.c,v 1.1.4.1 2001/11/20 14:19:35 kai Exp $
  2.  *
  3.  * stuff for the serial modem on ELSA cards
  4.  *
  5.  * This software may be used and distributed according to the terms
  6.  * of the GNU General Public License, incorporated herein by reference.
  7.  *
  8.  */
  9. #include <linux/config.h>
  10. #include <linux/serial.h>
  11. #include <linux/serial_reg.h>
  12. #define MAX_MODEM_BUF 256
  13. #define WAKEUP_CHARS (MAX_MODEM_BUF/2)
  14. #define RS_ISR_PASS_LIMIT 256
  15. #define BASE_BAUD ( 1843200 / 16 )
  16. //#define SERIAL_DEBUG_OPEN 1
  17. //#define SERIAL_DEBUG_INTR 1
  18. //#define SERIAL_DEBUG_FLOW 1
  19. #undef SERIAL_DEBUG_OPEN
  20. #undef SERIAL_DEBUG_INTR
  21. #undef SERIAL_DEBUG_FLOW
  22. #undef SERIAL_DEBUG_REG
  23. //#define SERIAL_DEBUG_REG 1
  24. #ifdef SERIAL_DEBUG_REG
  25. static u_char deb[32];
  26. const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
  27. const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
  28. #endif
  29. static char *MInit_1 = "AT&F&C1E0&D2r";
  30. static char *MInit_2 = "ATL2M1S64=13r";
  31. static char *MInit_3 = "AT+FCLASS=0r";
  32. static char *MInit_4 = "ATV1S2=128X1r";
  33. static char *MInit_5 = "AT\V8\N3r";
  34. static char *MInit_6 = "ATL0M0&G0%E1r";
  35. static char *MInit_7 = "AT%L1%M0%C3r";
  36. static char *MInit_speed28800 = "AT%G0%B28800r";
  37. static char *MInit_dialout = "ATs7=60 x1 dr";
  38. static char *MInit_dialin = "ATs7=60 x1 ar";
  39. static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
  40. {
  41. #ifdef SERIAL_DEBUG_REG
  42. u_int val = inb(cs->hw.elsa.base + 8 + offset);
  43. debugl1(cs,"in   %s %02x",ModemIn[offset], val);
  44. return(val);
  45. #else
  46. return inb(cs->hw.elsa.base + 8 + offset);
  47. #endif
  48. }
  49. static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
  50. {
  51. #ifdef SERIAL_DEBUG_REG
  52. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  53. u_int val = inb(cs->hw.elsa.base + 8 + offset);
  54. debugl1(cs,"inp  %s %02x",ModemIn[offset], val);
  55. #else
  56. u_int val = inb_p(cs->hw.elsa.base + 8 + offset);
  57. debugl1(cs,"inP  %s %02x",ModemIn[offset], val);
  58. #endif
  59. return(val);
  60. #else
  61. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  62. return inb(cs->hw.elsa.base + 8 + offset);
  63. #else
  64. return inb_p(cs->hw.elsa.base + 8 + offset);
  65. #endif
  66. #endif
  67. }
  68. static inline void serial_out(struct IsdnCardState *cs, int offset, int value)
  69. {
  70. #ifdef SERIAL_DEBUG_REG
  71. debugl1(cs,"out  %s %02x",ModemOut[offset], value);
  72. #endif
  73. outb(value, cs->hw.elsa.base + 8 + offset);
  74. }
  75. static inline void serial_outp(struct IsdnCardState *cs, int offset,
  76.        int value)
  77. {
  78. #ifdef SERIAL_DEBUG_REG
  79. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  80. debugl1(cs,"outp %s %02x",ModemOut[offset], value);
  81. #else
  82. debugl1(cs,"outP %s %02x",ModemOut[offset], value);
  83. #endif
  84. #endif
  85. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  86. outb(value, cs->hw.elsa.base + 8 + offset);
  87. #else
  88.      outb_p(value, cs->hw.elsa.base + 8 + offset);
  89. #endif
  90. }
  91. /*
  92.  * This routine is called to set the UART divisor registers to match
  93.  * the specified baud rate for a serial port.
  94.  */
  95. static void change_speed(struct IsdnCardState *cs, int baud)
  96. {
  97. int quot = 0, baud_base;
  98. unsigned cval, fcr = 0;
  99. int bits;
  100. unsigned long flags;
  101. /* byte size and parity */
  102. cval = 0x03; bits = 10;
  103. /* Determine divisor based on baud rate */
  104. baud_base = BASE_BAUD;
  105. quot = baud_base / baud;
  106. /* If the quotient is ever zero, default to 9600 bps */
  107. if (!quot)
  108. quot = baud_base / 9600;
  109. /* Set up FIFO's */
  110. if ((baud_base / quot) < 2400)
  111. fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
  112. else
  113. fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
  114. serial_outp(cs, UART_FCR, fcr);
  115. /* CTS flow control flag and modem status interrupts */
  116. cs->hw.elsa.IER &= ~UART_IER_MSI;
  117. cs->hw.elsa.IER |= UART_IER_MSI;
  118. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  119. debugl1(cs,"modem quot=0x%x", quot);
  120. save_flags(flags);
  121. cli();
  122. serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
  123. serial_outp(cs, UART_DLL, quot & 0xff); /* LS of divisor */
  124. serial_outp(cs, UART_DLM, quot >> 8); /* MS of divisor */
  125. serial_outp(cs, UART_LCR, cval); /* reset DLAB */
  126. serial_inp(cs, UART_RX);
  127. restore_flags(flags);
  128. }
  129. static int mstartup(struct IsdnCardState *cs)
  130. {
  131. unsigned long flags;
  132. int retval=0;
  133. save_flags(flags); cli();
  134. /*
  135.  * Clear the FIFO buffers and disable them
  136.  * (they will be reenabled in change_speed())
  137.  */
  138. serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
  139. /*
  140.  * At this point there's no way the LSR could still be 0xFF;
  141.  * if it is, then bail out, because there's likely no UART
  142.  * here.
  143.  */
  144. if (serial_inp(cs, UART_LSR) == 0xff) {
  145. retval = -ENODEV;
  146. goto errout;
  147. }
  148. /*
  149.  * Clear the interrupt registers.
  150.  */
  151. (void) serial_inp(cs, UART_RX);
  152. (void) serial_inp(cs, UART_IIR);
  153. (void) serial_inp(cs, UART_MSR);
  154. /*
  155.  * Now, initialize the UART 
  156.  */
  157. serial_outp(cs, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
  158. cs->hw.elsa.MCR = 0;
  159. cs->hw.elsa.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
  160. serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
  161. /*
  162.  * Finally, enable interrupts
  163.  */
  164. cs->hw.elsa.IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
  165. serial_outp(cs, UART_IER, cs->hw.elsa.IER); /* enable interrupts */
  166. /*
  167.  * And clear the interrupt registers again for luck.
  168.  */
  169. (void)serial_inp(cs, UART_LSR);
  170. (void)serial_inp(cs, UART_RX);
  171. (void)serial_inp(cs, UART_IIR);
  172. (void)serial_inp(cs, UART_MSR);
  173. cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0;
  174. cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp =0;
  175. /*
  176.  * and set the speed of the serial port
  177.  */
  178. change_speed(cs, BASE_BAUD);
  179. cs->hw.elsa.MFlag = 1;
  180. errout:
  181. restore_flags(flags);
  182. return retval;
  183. }
  184. /*
  185.  * This routine will shutdown a serial port; interrupts are disabled, and
  186.  * DTR is dropped if the hangup on close termio flag is on.
  187.  */
  188. static void mshutdown(struct IsdnCardState *cs)
  189. {
  190. unsigned long flags;
  191. #ifdef SERIAL_DEBUG_OPEN
  192. printk(KERN_DEBUG"Shutting down serial ....");
  193. #endif
  194. save_flags(flags); cli(); /* Disable interrupts */
  195. /*
  196.  * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
  197.  * here so the queue might never be waken up
  198.  */
  199. cs->hw.elsa.IER = 0;
  200. serial_outp(cs, UART_IER, 0x00); /* disable all intrs */
  201. cs->hw.elsa.MCR &= ~UART_MCR_OUT2;
  202. /* disable break condition */
  203. serial_outp(cs, UART_LCR, serial_inp(cs, UART_LCR) & ~UART_LCR_SBC);
  204. cs->hw.elsa.MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
  205. serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
  206. /* disable FIFO's */
  207. serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
  208. serial_inp(cs, UART_RX);    /* read data port to reset things */
  209. restore_flags(flags);
  210. #ifdef SERIAL_DEBUG_OPEN
  211. printk(" donen");
  212. #endif
  213. }
  214. inline int
  215. write_modem(struct BCState *bcs) {
  216. int ret=0;
  217. struct IsdnCardState *cs = bcs->cs;
  218. int count, len, fp;
  219. long flags;
  220. if (!bcs->tx_skb)
  221. return 0;
  222. if (bcs->tx_skb->len <= 0)
  223. return 0;
  224. save_flags(flags);
  225. cli();
  226. len = bcs->tx_skb->len;
  227. if (len > MAX_MODEM_BUF - cs->hw.elsa.transcnt)
  228. len = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
  229. fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
  230. fp &= (MAX_MODEM_BUF -1);
  231. count = len;
  232. if (count > MAX_MODEM_BUF - fp) {
  233. count = MAX_MODEM_BUF - fp;
  234. memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, count);
  235. skb_pull(bcs->tx_skb, count);
  236. cs->hw.elsa.transcnt += count;
  237. ret = count;
  238. count = len - count;
  239. fp = 0;
  240. }
  241. memcpy((cs->hw.elsa.transbuf + fp), bcs->tx_skb->data, count);
  242. skb_pull(bcs->tx_skb, count);
  243. cs->hw.elsa.transcnt += count;
  244. ret += count;
  245. if (cs->hw.elsa.transcnt && 
  246.     !(cs->hw.elsa.IER & UART_IER_THRI)) {
  247. cs->hw.elsa.IER |= UART_IER_THRI;
  248. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  249. }
  250. restore_flags(flags);
  251. return(ret);
  252. }
  253. inline void
  254. modem_fill(struct BCState *bcs) {
  255. if (bcs->tx_skb) {
  256. if (bcs->tx_skb->len) {
  257. write_modem(bcs);
  258. return;
  259. } else {
  260. if (bcs->st->lli.l1writewakeup &&
  261. (PACKET_NOACK != bcs->tx_skb->pkt_type))
  262. bcs->st->lli.l1writewakeup(bcs->st,
  263. bcs->hw.hscx.count);
  264. dev_kfree_skb_any(bcs->tx_skb);
  265. bcs->tx_skb = NULL;
  266. }
  267. }
  268. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  269. bcs->hw.hscx.count = 0;
  270. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  271. write_modem(bcs);
  272. } else {
  273. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  274. hscx_sched_event(bcs, B_XMTBUFREADY);
  275. }
  276. }
  277. static inline void receive_chars(struct IsdnCardState *cs,
  278.  int *status)
  279. {
  280. unsigned char ch;
  281. struct sk_buff *skb;
  282. do {
  283. ch = serial_in(cs, UART_RX);
  284. if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF)
  285. break;
  286. cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
  287. #ifdef SERIAL_DEBUG_INTR
  288. printk("DR%02x:%02x...", ch, *status);
  289. #endif
  290. if (*status & (UART_LSR_BI | UART_LSR_PE |
  291.        UART_LSR_FE | UART_LSR_OE)) {
  292. #ifdef SERIAL_DEBUG_INTR
  293. printk("handling exept....");
  294. #endif
  295. }
  296. *status = serial_inp(cs, UART_LSR);
  297. } while (*status & UART_LSR_DR);
  298. if (cs->hw.elsa.MFlag == 2) {
  299. if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
  300. printk(KERN_WARNING "ElsaSER: receive out of memoryn");
  301. else {
  302. memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf, 
  303. cs->hw.elsa.rcvcnt);
  304. skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
  305. }
  306. hscx_sched_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
  307. } else {
  308. char tmp[128];
  309. char *t = tmp;
  310. t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt);
  311. QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
  312. debugl1(cs, tmp);
  313. }
  314. cs->hw.elsa.rcvcnt = 0;
  315. }
  316. static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
  317. {
  318. int count;
  319. debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp, 
  320. cs->hw.elsa.transcnt);
  321. if (cs->hw.elsa.transcnt <= 0) {
  322. cs->hw.elsa.IER &= ~UART_IER_THRI;
  323. serial_out(cs, UART_IER, cs->hw.elsa.IER);
  324. return;
  325. }
  326. count = 16;
  327. do {
  328. serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
  329. if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
  330. cs->hw.elsa.transp=0;
  331. if (--cs->hw.elsa.transcnt <= 0)
  332. break;
  333. } while (--count > 0);
  334. if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
  335. modem_fill(cs->hw.elsa.bcs);
  336. #ifdef SERIAL_DEBUG_INTR
  337. printk("THRE...");
  338. #endif
  339. if (intr_done)
  340. *intr_done = 0;
  341. if (cs->hw.elsa.transcnt <= 0) {
  342. cs->hw.elsa.IER &= ~UART_IER_THRI;
  343. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  344. }
  345. }
  346. static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
  347. {
  348. int status, iir, msr;
  349. int pass_counter = 0;
  350. #ifdef SERIAL_DEBUG_INTR
  351. printk("rs_interrupt_single(%d)...", irq);
  352. #endif
  353. do {
  354. status = serial_inp(cs, UART_LSR);
  355. debugl1(cs,"rs LSR %02x", status);
  356. #ifdef SERIAL_DEBUG_INTR
  357. printk("status = %x...", status);
  358. #endif
  359. if (status & UART_LSR_DR)
  360. receive_chars(cs, &status);
  361. if (status & UART_LSR_THRE)
  362. transmit_chars(cs, 0);
  363. if (pass_counter++ > RS_ISR_PASS_LIMIT) {
  364. printk("rs_single loop break.n");
  365. break;
  366. }
  367. iir = serial_inp(cs, UART_IIR);
  368. debugl1(cs,"rs IIR %02x", iir);
  369. if ((iir & 0xf) == 0) {
  370. msr = serial_inp(cs, UART_MSR);
  371. debugl1(cs,"rs MSR %02x", msr);
  372. }
  373. } while (!(iir & UART_IIR_NO_INT));
  374. #ifdef SERIAL_DEBUG_INTR
  375. printk("end.n");
  376. #endif
  377. }
  378. extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
  379. extern void modehscx(struct BCState *bcs, int mode, int bc);
  380. extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
  381. void
  382. close_elsastate(struct BCState *bcs)
  383. {
  384. modehscx(bcs, 0, bcs->channel);
  385. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  386. if (bcs->hw.hscx.rcvbuf) {
  387. if (bcs->mode != L1_MODE_MODEM)
  388. kfree(bcs->hw.hscx.rcvbuf);
  389. bcs->hw.hscx.rcvbuf = NULL;
  390. }
  391. skb_queue_purge(&bcs->rqueue);
  392. skb_queue_purge(&bcs->squeue);
  393. if (bcs->tx_skb) {
  394. dev_kfree_skb_any(bcs->tx_skb);
  395. bcs->tx_skb = NULL;
  396. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  397. }
  398. }
  399. }
  400. void
  401. modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
  402. int count, fp;
  403. u_char *msg = buf;
  404. long flags;
  405. if (!len)
  406. return;
  407. save_flags(flags);
  408. cli();
  409. if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
  410. restore_flags(flags);
  411. return;
  412. }
  413. fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
  414. fp &= (MAX_MODEM_BUF -1);
  415. count = len;
  416. if (count > MAX_MODEM_BUF - fp) {
  417. count = MAX_MODEM_BUF - fp;
  418. memcpy(cs->hw.elsa.transbuf + fp, msg, count);
  419. cs->hw.elsa.transcnt += count;
  420. msg += count;
  421. count = len - count;
  422. fp = 0;
  423. }
  424. memcpy(cs->hw.elsa.transbuf + fp, msg, count);
  425. cs->hw.elsa.transcnt += count;
  426. if (cs->hw.elsa.transcnt && 
  427.     !(cs->hw.elsa.IER & UART_IER_THRI)) {
  428. cs->hw.elsa.IER |= UART_IER_THRI;
  429. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  430. }
  431. restore_flags(flags);
  432. }
  433. void
  434. modem_set_init(struct IsdnCardState *cs) {
  435. long flags;
  436. int timeout;
  437. #define RCV_DELAY 20000
  438. save_flags(flags);
  439. sti();
  440. modem_write_cmd(cs, MInit_1, strlen(MInit_1));
  441. timeout = 1000;
  442. while(timeout-- && cs->hw.elsa.transcnt)
  443. udelay(1000);
  444. debugl1(cs, "msi tout=%d", timeout);
  445. udelay(RCV_DELAY);
  446. modem_write_cmd(cs, MInit_2, strlen(MInit_2));
  447. timeout = 1000;
  448. while(timeout-- && cs->hw.elsa.transcnt)
  449. udelay(1000);
  450. debugl1(cs, "msi tout=%d", timeout);
  451. udelay(RCV_DELAY);
  452. modem_write_cmd(cs, MInit_3, strlen(MInit_3));
  453. timeout = 1000;
  454. while(timeout-- && cs->hw.elsa.transcnt)
  455. udelay(1000);
  456. debugl1(cs, "msi tout=%d", timeout);
  457. udelay(RCV_DELAY);
  458. modem_write_cmd(cs, MInit_4, strlen(MInit_4));
  459. timeout = 1000;
  460. while(timeout-- && cs->hw.elsa.transcnt)
  461. udelay(1000);
  462. debugl1(cs, "msi tout=%d", timeout);
  463. udelay(RCV_DELAY );
  464. modem_write_cmd(cs, MInit_5, strlen(MInit_5));
  465. timeout = 1000;
  466. while(timeout-- && cs->hw.elsa.transcnt)
  467. udelay(1000);
  468. debugl1(cs, "msi tout=%d", timeout);
  469. udelay(RCV_DELAY);
  470. modem_write_cmd(cs, MInit_6, strlen(MInit_6));
  471. timeout = 1000;
  472. while(timeout-- && cs->hw.elsa.transcnt)
  473. udelay(1000);
  474. debugl1(cs, "msi tout=%d", timeout);
  475. udelay(RCV_DELAY);
  476. modem_write_cmd(cs, MInit_7, strlen(MInit_7));
  477. timeout = 1000;
  478. while(timeout-- && cs->hw.elsa.transcnt)
  479. udelay(1000);
  480. debugl1(cs, "msi tout=%d", timeout);
  481. udelay(RCV_DELAY);
  482. restore_flags(flags);
  483. }
  484. void
  485. modem_set_dial(struct IsdnCardState *cs, int outgoing) {
  486. long flags;
  487. int timeout;
  488. #define RCV_DELAY 20000
  489. save_flags(flags);
  490. sti();
  491. modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
  492. timeout = 1000;
  493. while(timeout-- && cs->hw.elsa.transcnt)
  494. udelay(1000);
  495. debugl1(cs, "msi tout=%d", timeout);
  496. udelay(RCV_DELAY);
  497. if (outgoing)
  498. modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
  499. else
  500. modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
  501. timeout = 1000;
  502. while(timeout-- && cs->hw.elsa.transcnt)
  503. udelay(1000);
  504. debugl1(cs, "msi tout=%d", timeout);
  505. udelay(RCV_DELAY);
  506. restore_flags(flags);
  507. }
  508. void
  509. modem_l2l1(struct PStack *st, int pr, void *arg)
  510. {
  511. struct sk_buff *skb = arg;
  512. long flags;
  513. if (pr == (PH_DATA | REQUEST)) {
  514. save_flags(flags);
  515. cli();
  516. if (st->l1.bcs->tx_skb) {
  517. skb_queue_tail(&st->l1.bcs->squeue, skb);
  518. restore_flags(flags);
  519. } else {
  520. st->l1.bcs->tx_skb = skb;
  521. test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
  522. st->l1.bcs->hw.hscx.count = 0;
  523. restore_flags(flags);
  524. write_modem(st->l1.bcs);
  525. }
  526. } else if (pr == (PH_ACTIVATE | REQUEST)) {
  527. test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  528. st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
  529. set_arcofi(st->l1.bcs->cs, st->l1.bc);
  530. mstartup(st->l1.bcs->cs);
  531. modem_set_dial(st->l1.bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
  532. st->l1.bcs->cs->hw.elsa.MFlag=2;
  533. } else if (pr == (PH_DEACTIVATE | REQUEST)) {
  534. test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
  535. st->l1.bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
  536. arcofi_fsm(st->l1.bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
  537. interruptible_sleep_on(&st->l1.bcs->cs->dc.isac.arcofi_wait);
  538. st->l1.bcs->cs->hw.elsa.MFlag=1;
  539. } else {
  540. printk(KERN_WARNING"ElsaSer: unknown pr %xn", pr);
  541. }
  542. }
  543. int
  544. setstack_elsa(struct PStack *st, struct BCState *bcs)
  545. {
  546. bcs->channel = st->l1.bc;
  547. switch (st->l1.mode) {
  548. case L1_MODE_HDLC:
  549. case L1_MODE_TRANS:
  550. if (open_hscxstate(st->l1.hardware, bcs))
  551. return (-1);
  552. st->l2.l2l1 = hscx_l2l1;
  553. break;
  554. case L1_MODE_MODEM:
  555. bcs->mode = L1_MODE_MODEM;
  556. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  557. bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
  558. skb_queue_head_init(&bcs->rqueue);
  559. skb_queue_head_init(&bcs->squeue);
  560. }
  561. bcs->tx_skb = NULL;
  562. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  563. bcs->event = 0;
  564. bcs->hw.hscx.rcvidx = 0;
  565. bcs->tx_cnt = 0;
  566. bcs->cs->hw.elsa.bcs = bcs;
  567. st->l2.l2l1 = modem_l2l1;
  568. break;
  569. }
  570. st->l1.bcs = bcs;
  571. setstack_manager(st);
  572. bcs->st = st;
  573. setstack_l1_B(st);
  574. return (0);
  575. }
  576. void
  577. init_modem(struct IsdnCardState *cs) {
  578. cs->bcs[0].BC_SetStack = setstack_elsa;
  579. cs->bcs[1].BC_SetStack = setstack_elsa;
  580. cs->bcs[0].BC_Close = close_elsastate;
  581. cs->bcs[1].BC_Close = close_elsastate;
  582. if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
  583. GFP_ATOMIC))) {
  584. printk(KERN_WARNING
  585. "Elsa: No modem mem hw.elsa.rcvbufn");
  586. return;
  587. }
  588. if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
  589. GFP_ATOMIC))) {
  590. printk(KERN_WARNING
  591. "Elsa: No modem mem hw.elsa.transbufn");
  592. kfree(cs->hw.elsa.rcvbuf);
  593. cs->hw.elsa.rcvbuf = NULL;
  594. return;
  595. }
  596. if (mstartup(cs)) {
  597. printk(KERN_WARNING "Elsa: problem startup modemn");
  598. }
  599. modem_set_init(cs);
  600. }
  601. void
  602. release_modem(struct IsdnCardState *cs) {
  603. cs->hw.elsa.MFlag = 0;
  604. if (cs->hw.elsa.transbuf) {
  605. if (cs->hw.elsa.rcvbuf) {
  606. mshutdown(cs);
  607. kfree(cs->hw.elsa.rcvbuf);
  608. cs->hw.elsa.rcvbuf = NULL;
  609. }
  610. kfree(cs->hw.elsa.transbuf);
  611. cs->hw.elsa.transbuf = NULL;
  612. }
  613. }