elsa_ser.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  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. #define MAX_MODEM_BUF 256
  12. #define WAKEUP_CHARS (MAX_MODEM_BUF/2)
  13. #define RS_ISR_PASS_LIMIT 256
  14. #define BASE_BAUD ( 1843200 / 16 )
  15. //#define SERIAL_DEBUG_OPEN 1
  16. //#define SERIAL_DEBUG_INTR 1
  17. //#define SERIAL_DEBUG_FLOW 1
  18. #undef SERIAL_DEBUG_OPEN
  19. #undef SERIAL_DEBUG_INTR
  20. #undef SERIAL_DEBUG_FLOW
  21. #undef SERIAL_DEBUG_REG
  22. //#define SERIAL_DEBUG_REG 1
  23. #ifdef SERIAL_DEBUG_REG
  24. static u_char deb[32];
  25. const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
  26. const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
  27. #endif
  28. static char *MInit_1 = "AT&F&C1E0&D2\r\0";
  29. static char *MInit_2 = "ATL2M1S64=13\r\0";
  30. static char *MInit_3 = "AT+FCLASS=0\r\0";
  31. static char *MInit_4 = "ATV1S2=128X1\r\0";
  32. static char *MInit_5 = "AT\\V8\\N3\r\0";
  33. static char *MInit_6 = "ATL0M0&G0%E1\r\0";
  34. static char *MInit_7 = "AT%L1%M0%C3\r\0";
  35. static char *MInit_speed28800 = "AT%G0%B28800\r\0";
  36. static char *MInit_dialout = "ATs7=60 x1 d\r\0";
  37. static char *MInit_dialin = "ATs7=60 x1 a\r\0";
  38. static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
  39. {
  40. #ifdef SERIAL_DEBUG_REG
  41. u_int val = inb(cs->hw.elsa.base + 8 + offset);
  42. debugl1(cs,"in %s %02x",ModemIn[offset], val);
  43. return(val);
  44. #else
  45. return inb(cs->hw.elsa.base + 8 + offset);
  46. #endif
  47. }
  48. static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
  49. {
  50. #ifdef SERIAL_DEBUG_REG
  51. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  52. u_int val = inb(cs->hw.elsa.base + 8 + offset);
  53. debugl1(cs,"inp %s %02x",ModemIn[offset], val);
  54. #else
  55. u_int val = inb_p(cs->hw.elsa.base + 8 + offset);
  56. debugl1(cs,"inP %s %02x",ModemIn[offset], val);
  57. #endif
  58. return(val);
  59. #else
  60. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  61. return inb(cs->hw.elsa.base + 8 + offset);
  62. #else
  63. return inb_p(cs->hw.elsa.base + 8 + offset);
  64. #endif
  65. #endif
  66. }
  67. static inline void serial_out(struct IsdnCardState *cs, int offset, int value)
  68. {
  69. #ifdef SERIAL_DEBUG_REG
  70. debugl1(cs,"out %s %02x",ModemOut[offset], value);
  71. #endif
  72. outb(value, cs->hw.elsa.base + 8 + offset);
  73. }
  74. static inline void serial_outp(struct IsdnCardState *cs, int offset,
  75. int value)
  76. {
  77. #ifdef SERIAL_DEBUG_REG
  78. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  79. debugl1(cs,"outp %s %02x",ModemOut[offset], value);
  80. #else
  81. debugl1(cs,"outP %s %02x",ModemOut[offset], value);
  82. #endif
  83. #endif
  84. #ifdef CONFIG_SERIAL_NOPAUSE_IO
  85. outb(value, cs->hw.elsa.base + 8 + offset);
  86. #else
  87. outb_p(value, cs->hw.elsa.base + 8 + offset);
  88. #endif
  89. }
  90. /*
  91. * This routine is called to set the UART divisor registers to match
  92. * the specified baud rate for a serial port.
  93. */
  94. static void change_speed(struct IsdnCardState *cs, int baud)
  95. {
  96. int quot = 0, baud_base;
  97. unsigned cval, fcr = 0;
  98. int bits;
  99. /* byte size and parity */
  100. cval = 0x03; bits = 10;
  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. memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, count);
  221. skb_pull(bcs->tx_skb, count);
  222. cs->hw.elsa.transcnt += count;
  223. ret = count;
  224. count = len - count;
  225. fp = 0;
  226. }
  227. memcpy((cs->hw.elsa.transbuf + fp), bcs->tx_skb->data, count);
  228. skb_pull(bcs->tx_skb, count);
  229. cs->hw.elsa.transcnt += count;
  230. ret += count;
  231. if (cs->hw.elsa.transcnt &&
  232. !(cs->hw.elsa.IER & UART_IER_THRI)) {
  233. cs->hw.elsa.IER |= UART_IER_THRI;
  234. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  235. }
  236. return(ret);
  237. }
  238. static inline void
  239. modem_fill(struct BCState *bcs) {
  240. if (bcs->tx_skb) {
  241. if (bcs->tx_skb->len) {
  242. write_modem(bcs);
  243. return;
  244. } else {
  245. if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
  246. (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
  247. u_long flags;
  248. spin_lock_irqsave(&bcs->aclock, flags);
  249. bcs->ackcnt += bcs->hw.hscx.count;
  250. spin_unlock_irqrestore(&bcs->aclock, flags);
  251. schedule_event(bcs, B_ACKPENDING);
  252. }
  253. dev_kfree_skb_any(bcs->tx_skb);
  254. bcs->tx_skb = NULL;
  255. }
  256. }
  257. if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
  258. bcs->hw.hscx.count = 0;
  259. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  260. write_modem(bcs);
  261. } else {
  262. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  263. schedule_event(bcs, B_XMTBUFREADY);
  264. }
  265. }
  266. static inline void receive_chars(struct IsdnCardState *cs,
  267. int *status)
  268. {
  269. unsigned char ch;
  270. struct sk_buff *skb;
  271. do {
  272. ch = serial_in(cs, UART_RX);
  273. if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF)
  274. break;
  275. cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
  276. #ifdef SERIAL_DEBUG_INTR
  277. printk("DR%02x:%02x...", ch, *status);
  278. #endif
  279. if (*status & (UART_LSR_BI | UART_LSR_PE |
  280. UART_LSR_FE | UART_LSR_OE)) {
  281. #ifdef SERIAL_DEBUG_INTR
  282. printk("handling exept....");
  283. #endif
  284. }
  285. *status = serial_inp(cs, UART_LSR);
  286. } while (*status & UART_LSR_DR);
  287. if (cs->hw.elsa.MFlag == 2) {
  288. if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
  289. printk(KERN_WARNING "ElsaSER: receive out of memory\n");
  290. else {
  291. memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf,
  292. cs->hw.elsa.rcvcnt);
  293. skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
  294. }
  295. schedule_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
  296. } else {
  297. char tmp[128];
  298. char *t = tmp;
  299. t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt);
  300. QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
  301. debugl1(cs, tmp);
  302. }
  303. cs->hw.elsa.rcvcnt = 0;
  304. }
  305. static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
  306. {
  307. int count;
  308. debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
  309. cs->hw.elsa.transcnt);
  310. if (cs->hw.elsa.transcnt <= 0) {
  311. cs->hw.elsa.IER &= ~UART_IER_THRI;
  312. serial_out(cs, UART_IER, cs->hw.elsa.IER);
  313. return;
  314. }
  315. count = 16;
  316. do {
  317. serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
  318. if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
  319. cs->hw.elsa.transp=0;
  320. if (--cs->hw.elsa.transcnt <= 0)
  321. break;
  322. } while (--count > 0);
  323. if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
  324. modem_fill(cs->hw.elsa.bcs);
  325. #ifdef SERIAL_DEBUG_INTR
  326. printk("THRE...");
  327. #endif
  328. if (intr_done)
  329. *intr_done = 0;
  330. if (cs->hw.elsa.transcnt <= 0) {
  331. cs->hw.elsa.IER &= ~UART_IER_THRI;
  332. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  333. }
  334. }
  335. static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
  336. {
  337. int status, iir, msr;
  338. int pass_counter = 0;
  339. #ifdef SERIAL_DEBUG_INTR
  340. printk("rs_interrupt_single(%d)...", irq);
  341. #endif
  342. do {
  343. status = serial_inp(cs, UART_LSR);
  344. debugl1(cs,"rs LSR %02x", status);
  345. #ifdef SERIAL_DEBUG_INTR
  346. printk("status = %x...", status);
  347. #endif
  348. if (status & UART_LSR_DR)
  349. receive_chars(cs, &status);
  350. if (status & UART_LSR_THRE)
  351. transmit_chars(cs, NULL);
  352. if (pass_counter++ > RS_ISR_PASS_LIMIT) {
  353. printk("rs_single loop break.\n");
  354. break;
  355. }
  356. iir = serial_inp(cs, UART_IIR);
  357. debugl1(cs,"rs IIR %02x", iir);
  358. if ((iir & 0xf) == 0) {
  359. msr = serial_inp(cs, UART_MSR);
  360. debugl1(cs,"rs MSR %02x", msr);
  361. }
  362. } while (!(iir & UART_IIR_NO_INT));
  363. #ifdef SERIAL_DEBUG_INTR
  364. printk("end.\n");
  365. #endif
  366. }
  367. extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
  368. extern void modehscx(struct BCState *bcs, int mode, int bc);
  369. extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
  370. static void
  371. close_elsastate(struct BCState *bcs)
  372. {
  373. modehscx(bcs, 0, bcs->channel);
  374. if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
  375. if (bcs->hw.hscx.rcvbuf) {
  376. if (bcs->mode != L1_MODE_MODEM)
  377. kfree(bcs->hw.hscx.rcvbuf);
  378. bcs->hw.hscx.rcvbuf = NULL;
  379. }
  380. skb_queue_purge(&bcs->rqueue);
  381. skb_queue_purge(&bcs->squeue);
  382. if (bcs->tx_skb) {
  383. dev_kfree_skb_any(bcs->tx_skb);
  384. bcs->tx_skb = NULL;
  385. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  386. }
  387. }
  388. }
  389. static void
  390. modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
  391. int count, fp;
  392. u_char *msg = buf;
  393. if (!len)
  394. return;
  395. if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
  396. return;
  397. }
  398. fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
  399. fp &= (MAX_MODEM_BUF -1);
  400. count = len;
  401. if (count > MAX_MODEM_BUF - fp) {
  402. count = MAX_MODEM_BUF - fp;
  403. memcpy(cs->hw.elsa.transbuf + fp, msg, count);
  404. cs->hw.elsa.transcnt += count;
  405. msg += count;
  406. count = len - count;
  407. fp = 0;
  408. }
  409. memcpy(cs->hw.elsa.transbuf + fp, msg, count);
  410. cs->hw.elsa.transcnt += count;
  411. if (cs->hw.elsa.transcnt &&
  412. !(cs->hw.elsa.IER & UART_IER_THRI)) {
  413. cs->hw.elsa.IER |= UART_IER_THRI;
  414. serial_outp(cs, UART_IER, cs->hw.elsa.IER);
  415. }
  416. }
  417. static void
  418. modem_set_init(struct IsdnCardState *cs) {
  419. int timeout;
  420. #define RCV_DELAY 20000
  421. modem_write_cmd(cs, MInit_1, strlen(MInit_1));
  422. timeout = 1000;
  423. while(timeout-- && cs->hw.elsa.transcnt)
  424. udelay(1000);
  425. debugl1(cs, "msi tout=%d", timeout);
  426. udelay(RCV_DELAY);
  427. modem_write_cmd(cs, MInit_2, strlen(MInit_2));
  428. timeout = 1000;
  429. while(timeout-- && cs->hw.elsa.transcnt)
  430. udelay(1000);
  431. debugl1(cs, "msi tout=%d", timeout);
  432. udelay(RCV_DELAY);
  433. modem_write_cmd(cs, MInit_3, strlen(MInit_3));
  434. timeout = 1000;
  435. while(timeout-- && cs->hw.elsa.transcnt)
  436. udelay(1000);
  437. debugl1(cs, "msi tout=%d", timeout);
  438. udelay(RCV_DELAY);
  439. modem_write_cmd(cs, MInit_4, strlen(MInit_4));
  440. timeout = 1000;
  441. while(timeout-- && cs->hw.elsa.transcnt)
  442. udelay(1000);
  443. debugl1(cs, "msi tout=%d", timeout);
  444. udelay(RCV_DELAY );
  445. modem_write_cmd(cs, MInit_5, strlen(MInit_5));
  446. timeout = 1000;
  447. while(timeout-- && cs->hw.elsa.transcnt)
  448. udelay(1000);
  449. debugl1(cs, "msi tout=%d", timeout);
  450. udelay(RCV_DELAY);
  451. modem_write_cmd(cs, MInit_6, strlen(MInit_6));
  452. timeout = 1000;
  453. while(timeout-- && cs->hw.elsa.transcnt)
  454. udelay(1000);
  455. debugl1(cs, "msi tout=%d", timeout);
  456. udelay(RCV_DELAY);
  457. modem_write_cmd(cs, MInit_7, strlen(MInit_7));
  458. timeout = 1000;
  459. while(timeout-- && cs->hw.elsa.transcnt)
  460. udelay(1000);
  461. debugl1(cs, "msi tout=%d", timeout);
  462. udelay(RCV_DELAY);
  463. }
  464. static void
  465. modem_set_dial(struct IsdnCardState *cs, int outgoing) {
  466. int timeout;
  467. #define RCV_DELAY 20000
  468. modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
  469. timeout = 1000;
  470. while(timeout-- && cs->hw.elsa.transcnt)
  471. udelay(1000);
  472. debugl1(cs, "msi tout=%d", timeout);
  473. udelay(RCV_DELAY);
  474. if (outgoing)
  475. modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
  476. else
  477. modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
  478. timeout = 1000;
  479. while(timeout-- && cs->hw.elsa.transcnt)
  480. udelay(1000);
  481. debugl1(cs, "msi tout=%d", timeout);
  482. udelay(RCV_DELAY);
  483. }
  484. static void
  485. modem_l2l1(struct PStack *st, int pr, void *arg)
  486. {
  487. struct BCState *bcs = st->l1.bcs;
  488. struct sk_buff *skb = arg;
  489. u_long flags;
  490. if (pr == (PH_DATA | REQUEST)) {
  491. spin_lock_irqsave(&bcs->cs->lock, flags);
  492. if (bcs->tx_skb) {
  493. skb_queue_tail(&bcs->squeue, skb);
  494. } else {
  495. bcs->tx_skb = skb;
  496. test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
  497. bcs->hw.hscx.count = 0;
  498. write_modem(bcs);
  499. }
  500. spin_unlock_irqrestore(&bcs->cs->lock, flags);
  501. } else if (pr == (PH_ACTIVATE | REQUEST)) {
  502. test_and_set_bit(BC_FLG_ACTIV, &bcs->Flag);
  503. st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
  504. set_arcofi(bcs->cs, st->l1.bc);
  505. mstartup(bcs->cs);
  506. modem_set_dial(bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
  507. bcs->cs->hw.elsa.MFlag=2;
  508. } else if (pr == (PH_DEACTIVATE | REQUEST)) {
  509. test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
  510. bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
  511. arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
  512. interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait);
  513. bcs->cs->hw.elsa.MFlag=1;
  514. } else {
  515. printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
  516. }
  517. }
  518. static int
  519. setstack_elsa(struct PStack *st, struct BCState *bcs)
  520. {
  521. bcs->channel = st->l1.bc;
  522. switch (st->l1.mode) {
  523. case L1_MODE_HDLC:
  524. case L1_MODE_TRANS:
  525. if (open_hscxstate(st->l1.hardware, bcs))
  526. return (-1);
  527. st->l2.l2l1 = hscx_l2l1;
  528. break;
  529. case L1_MODE_MODEM:
  530. bcs->mode = L1_MODE_MODEM;
  531. if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
  532. bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
  533. skb_queue_head_init(&bcs->rqueue);
  534. skb_queue_head_init(&bcs->squeue);
  535. }
  536. bcs->tx_skb = NULL;
  537. test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
  538. bcs->event = 0;
  539. bcs->hw.hscx.rcvidx = 0;
  540. bcs->tx_cnt = 0;
  541. bcs->cs->hw.elsa.bcs = bcs;
  542. st->l2.l2l1 = modem_l2l1;
  543. break;
  544. }
  545. st->l1.bcs = bcs;
  546. setstack_manager(st);
  547. bcs->st = st;
  548. setstack_l1_B(st);
  549. return (0);
  550. }
  551. static void
  552. init_modem(struct IsdnCardState *cs) {
  553. cs->bcs[0].BC_SetStack = setstack_elsa;
  554. cs->bcs[1].BC_SetStack = setstack_elsa;
  555. cs->bcs[0].BC_Close = close_elsastate;
  556. cs->bcs[1].BC_Close = close_elsastate;
  557. if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
  558. GFP_ATOMIC))) {
  559. printk(KERN_WARNING
  560. "Elsa: No modem mem hw.elsa.rcvbuf\n");
  561. return;
  562. }
  563. if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
  564. GFP_ATOMIC))) {
  565. printk(KERN_WARNING
  566. "Elsa: No modem mem hw.elsa.transbuf\n");
  567. kfree(cs->hw.elsa.rcvbuf);
  568. cs->hw.elsa.rcvbuf = NULL;
  569. return;
  570. }
  571. if (mstartup(cs)) {
  572. printk(KERN_WARNING "Elsa: problem startup modem\n");
  573. }
  574. modem_set_init(cs);
  575. }
  576. static void
  577. release_modem(struct IsdnCardState *cs) {
  578. cs->hw.elsa.MFlag = 0;
  579. if (cs->hw.elsa.transbuf) {
  580. if (cs->hw.elsa.rcvbuf) {
  581. mshutdown(cs);
  582. kfree(cs->hw.elsa.rcvbuf);
  583. cs->hw.elsa.rcvbuf = NULL;
  584. }
  585. kfree(cs->hw.elsa.transbuf);
  586. cs->hw.elsa.transbuf = NULL;
  587. }
  588. }