elsa_ser.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657
  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/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&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 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. /* 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. memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, 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. memcpy((cs->hw.elsa.transbuf + fp), bcs->tx_skb->data, count);
  229. skb_pull(bcs->tx_skb, count);
  230. cs->hw.elsa.transcnt += count;
  231. ret += count;
  232. if (cs->hw.elsa.transcnt &&
  233. !(cs->hw.elsa.IER & UART_IER_THRI)) {
  234. cs->hw.elsa.IER |= UART_IER_THRI;
  235. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  236. }
  237. return(ret);
  238. }
  239. static inline void
  240. modem_fill(struct BCState *bcs) {
  241. if (bcs->tx_skb) {
  242. if (bcs->tx_skb->len) {
  243. write_modem(bcs);
  244. return;
  245. } else {
  246. if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
  247. (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
  248. u_long flags;
  249. spin_lock_irqsave(&bcs->aclock, flags);
  250. bcs->ackcnt += bcs->hw.hscx.count;
  251. spin_unlock_irqrestore(&bcs->aclock, flags);
  252. schedule_event(bcs, B_ACKPENDING);
  253. }
  254. dev_kfree_skb_any(bcs->tx_skb);
  255. bcs->tx_skb = NULL;
  256. }
  257. }
  258. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  259. bcs->hw.hscx.count = 0;
  260. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  261. write_modem(bcs);
  262. } else {
  263. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  264. schedule_event(bcs, B_XMTBUFREADY);
  265. }
  266. }
  267. static inline void receive_chars(struct IsdnCardState *cs,
  268. int *status)
  269. {
  270. unsigned char ch;
  271. struct sk_buff *skb;
  272. do {
  273. ch = serial_in(cs, UART_RX);
  274. if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF)
  275. break;
  276. cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
  277. #ifdef SERIAL_DEBUG_INTR
  278. printk("DR%02x:%02x...", ch, *status);
  279. #endif
  280. if (*status & (UART_LSR_BI | UART_LSR_PE |
  281. UART_LSR_FE | UART_LSR_OE)) {
  282. #ifdef SERIAL_DEBUG_INTR
  283. printk("handling exept....");
  284. #endif
  285. }
  286. *status = serial_inp(cs, UART_LSR);
  287. } while (*status & UART_LSR_DR);
  288. if (cs->hw.elsa.MFlag == 2) {
  289. if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
  290. printk(KERN_WARNING "ElsaSER: receive out of memory\n");
  291. else {
  292. memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf,
  293. cs->hw.elsa.rcvcnt);
  294. skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
  295. }
  296. schedule_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
  297. } else {
  298. char tmp[128];
  299. char *t = tmp;
  300. t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt);
  301. QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
  302. debugl1(cs, tmp);
  303. }
  304. cs->hw.elsa.rcvcnt = 0;
  305. }
  306. static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
  307. {
  308. int count;
  309. debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
  310. cs->hw.elsa.transcnt);
  311. if (cs->hw.elsa.transcnt <= 0) {
  312. cs->hw.elsa.IER &= ~UART_IER_THRI;
  313. serial_out(cs, UART_IER, cs->hw.elsa.IER);
  314. return;
  315. }
  316. count = 16;
  317. do {
  318. serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
  319. if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
  320. cs->hw.elsa.transp=0;
  321. if (--cs->hw.elsa.transcnt <= 0)
  322. break;
  323. } while (--count > 0);
  324. if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
  325. modem_fill(cs->hw.elsa.bcs);
  326. #ifdef SERIAL_DEBUG_INTR
  327. printk("THRE...");
  328. #endif
  329. if (intr_done)
  330. *intr_done = 0;
  331. if (cs->hw.elsa.transcnt <= 0) {
  332. cs->hw.elsa.IER &= ~UART_IER_THRI;
  333. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  334. }
  335. }
  336. static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
  337. {
  338. int status, iir, msr;
  339. int pass_counter = 0;
  340. #ifdef SERIAL_DEBUG_INTR
  341. printk("rs_interrupt_single(%d)...", irq);
  342. #endif
  343. do {
  344. status = serial_inp(cs, UART_LSR);
  345. debugl1(cs,"rs LSR %02x", status);
  346. #ifdef SERIAL_DEBUG_INTR
  347. printk("status = %x...", status);
  348. #endif
  349. if (status & UART_LSR_DR)
  350. receive_chars(cs, &status);
  351. if (status & UART_LSR_THRE)
  352. transmit_chars(cs, NULL);
  353. if (pass_counter++ > RS_ISR_PASS_LIMIT) {
  354. printk("rs_single loop break.\n");
  355. break;
  356. }
  357. iir = serial_inp(cs, UART_IIR);
  358. debugl1(cs,"rs IIR %02x", iir);
  359. if ((iir & 0xf) == 0) {
  360. msr = serial_inp(cs, UART_MSR);
  361. debugl1(cs,"rs MSR %02x", msr);
  362. }
  363. } while (!(iir & UART_IIR_NO_INT));
  364. #ifdef SERIAL_DEBUG_INTR
  365. printk("end.\n");
  366. #endif
  367. }
  368. extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
  369. extern void modehscx(struct BCState *bcs, int mode, int bc);
  370. extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
  371. static void
  372. close_elsastate(struct BCState *bcs)
  373. {
  374. modehscx(bcs, 0, bcs->channel);
  375. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  376. if (bcs->hw.hscx.rcvbuf) {
  377. if (bcs->mode != L1_MODE_MODEM)
  378. kfree(bcs->hw.hscx.rcvbuf);
  379. bcs->hw.hscx.rcvbuf = NULL;
  380. }
  381. skb_queue_purge(&bcs->rqueue);
  382. skb_queue_purge(&bcs->squeue);
  383. if (bcs->tx_skb) {
  384. dev_kfree_skb_any(bcs->tx_skb);
  385. bcs->tx_skb = NULL;
  386. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  387. }
  388. }
  389. }
  390. static void
  391. modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
  392. int count, fp;
  393. u_char *msg = buf;
  394. if (!len)
  395. return;
  396. if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
  397. return;
  398. }
  399. fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
  400. fp &= (MAX_MODEM_BUF -1);
  401. count = len;
  402. if (count > MAX_MODEM_BUF - fp) {
  403. count = MAX_MODEM_BUF - fp;
  404. memcpy(cs->hw.elsa.transbuf + fp, msg, count);
  405. cs->hw.elsa.transcnt += count;
  406. msg += count;
  407. count = len - count;
  408. fp = 0;
  409. }
  410. memcpy(cs->hw.elsa.transbuf + fp, msg, count);
  411. cs->hw.elsa.transcnt += count;
  412. if (cs->hw.elsa.transcnt &&
  413. !(cs->hw.elsa.IER & UART_IER_THRI)) {
  414. cs->hw.elsa.IER |= UART_IER_THRI;
  415. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  416. }
  417. }
  418. static void
  419. modem_set_init(struct IsdnCardState *cs) {
  420. int timeout;
  421. #define RCV_DELAY 20000
  422. modem_write_cmd(cs, MInit_1, strlen(MInit_1));
  423. timeout = 1000;
  424. while(timeout-- && cs->hw.elsa.transcnt)
  425. udelay(1000);
  426. debugl1(cs, "msi tout=%d", timeout);
  427. udelay(RCV_DELAY);
  428. modem_write_cmd(cs, MInit_2, strlen(MInit_2));
  429. timeout = 1000;
  430. while(timeout-- && cs->hw.elsa.transcnt)
  431. udelay(1000);
  432. debugl1(cs, "msi tout=%d", timeout);
  433. udelay(RCV_DELAY);
  434. modem_write_cmd(cs, MInit_3, strlen(MInit_3));
  435. timeout = 1000;
  436. while(timeout-- && cs->hw.elsa.transcnt)
  437. udelay(1000);
  438. debugl1(cs, "msi tout=%d", timeout);
  439. udelay(RCV_DELAY);
  440. modem_write_cmd(cs, MInit_4, strlen(MInit_4));
  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_5, strlen(MInit_5));
  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_6, strlen(MInit_6));
  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_7, strlen(MInit_7));
  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. }
  465. static void
  466. modem_set_dial(struct IsdnCardState *cs, int outgoing) {
  467. int timeout;
  468. #define RCV_DELAY 20000
  469. modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
  470. timeout = 1000;
  471. while(timeout-- && cs->hw.elsa.transcnt)
  472. udelay(1000);
  473. debugl1(cs, "msi tout=%d", timeout);
  474. udelay(RCV_DELAY);
  475. if (outgoing)
  476. modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
  477. else
  478. modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
  479. timeout = 1000;
  480. while(timeout-- && cs->hw.elsa.transcnt)
  481. udelay(1000);
  482. debugl1(cs, "msi tout=%d", timeout);
  483. udelay(RCV_DELAY);
  484. }
  485. static void
  486. modem_l2l1(struct PStack *st, int pr, void *arg)
  487. {
  488. struct BCState *bcs = st->l1.bcs;
  489. struct sk_buff *skb = arg;
  490. u_long flags;
  491. if (pr == (PH_DATA | REQUEST)) {
  492. spin_lock_irqsave(&bcs->cs->lock, flags);
  493. if (bcs->tx_skb) {
  494. skb_queue_tail(&bcs->squeue, skb);
  495. } else {
  496. bcs->tx_skb = skb;
  497. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  498. bcs->hw.hscx.count = 0;
  499. write_modem(bcs);
  500. }
  501. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  502. } else if (pr == (PH_ACTIVATE | REQUEST)) {
  503. test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
  504. st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
  505. set_arcofi(bcs->cs, st->l1.bc);
  506. mstartup(bcs->cs);
  507. modem_set_dial(bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
  508. bcs->cs->hw.elsa.MFlag=2;
  509. } else if (pr == (PH_DEACTIVATE | REQUEST)) {
  510. test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
  511. bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
  512. arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
  513. interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait);
  514. bcs->cs->hw.elsa.MFlag=1;
  515. } else {
  516. printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
  517. }
  518. }
  519. static int
  520. setstack_elsa(struct PStack *st, struct BCState *bcs)
  521. {
  522. bcs->channel = st->l1.bc;
  523. switch (st->l1.mode) {
  524. case L1_MODE_HDLC:
  525. case L1_MODE_TRANS:
  526. if (open_hscxstate(st->l1.hardware, bcs))
  527. return (-1);
  528. st->l2.l2l1 = hscx_l2l1;
  529. break;
  530. case L1_MODE_MODEM:
  531. bcs->mode = L1_MODE_MODEM;
  532. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  533. bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
  534. skb_queue_head_init(&bcs->rqueue);
  535. skb_queue_head_init(&bcs->squeue);
  536. }
  537. bcs->tx_skb = NULL;
  538. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  539. bcs->event = 0;
  540. bcs->hw.hscx.rcvidx = 0;
  541. bcs->tx_cnt = 0;
  542. bcs->cs->hw.elsa.bcs = bcs;
  543. st->l2.l2l1 = modem_l2l1;
  544. break;
  545. }
  546. st->l1.bcs = bcs;
  547. setstack_manager(st);
  548. bcs->st = st;
  549. setstack_l1_B(st);
  550. return (0);
  551. }
  552. static void
  553. init_modem(struct IsdnCardState *cs) {
  554. cs->bcs[0].BC_SetStack = setstack_elsa;
  555. cs->bcs[1].BC_SetStack = setstack_elsa;
  556. cs->bcs[0].BC_Close = close_elsastate;
  557. cs->bcs[1].BC_Close = close_elsastate;
  558. if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
  559. GFP_ATOMIC))) {
  560. printk(KERN_WARNING
  561. "Elsa: No modem mem hw.elsa.rcvbuf\n");
  562. return;
  563. }
  564. if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
  565. GFP_ATOMIC))) {
  566. printk(KERN_WARNING
  567. "Elsa: No modem mem hw.elsa.transbuf\n");
  568. kfree(cs->hw.elsa.rcvbuf);
  569. cs->hw.elsa.rcvbuf = NULL;
  570. return;
  571. }
  572. if (mstartup(cs)) {
  573. printk(KERN_WARNING "Elsa: problem startup modem\n");
  574. }
  575. modem_set_init(cs);
  576. }
  577. static void
  578. release_modem(struct IsdnCardState *cs) {
  579. cs->hw.elsa.MFlag = 0;
  580. if (cs->hw.elsa.transbuf) {
  581. if (cs->hw.elsa.rcvbuf) {
  582. mshutdown(cs);
  583. kfree(cs->hw.elsa.rcvbuf);
  584. cs->hw.elsa.rcvbuf = NULL;
  585. }
  586. kfree(cs->hw.elsa.transbuf);
  587. cs->hw.elsa.transbuf = NULL;
  588. }
  589. }