elsa_ser.c 17 KB

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