elsa_ser.c 17 KB

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