Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / isdn / hisax / elsa_ser.c
blob74bedf8f6f1488813017a5594bdfffafcca8135f
1 /* $Id: elsa_ser.c,v 2.10 2000/11/19 17:02:47 kai Exp $
3 * stuff for the serial modem on ELSA cards
5 * This file is (c) under GNU PUBLIC LICENSE
7 */
8 #include <linux/config.h>
9 #include <linux/serial.h>
10 #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 )
17 #ifndef MIN
18 #define MIN(a,b) ((a) < (b) ? (a) : (b))
19 #endif
21 //#define SERIAL_DEBUG_OPEN 1
22 //#define SERIAL_DEBUG_INTR 1
23 //#define SERIAL_DEBUG_FLOW 1
24 #undef SERIAL_DEBUG_OPEN
25 #undef SERIAL_DEBUG_INTR
26 #undef SERIAL_DEBUG_FLOW
27 #undef SERIAL_DEBUG_REG
28 //#define SERIAL_DEBUG_REG 1
30 #ifdef SERIAL_DEBUG_REG
31 static u_char deb[32];
32 const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
33 const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
34 #endif
36 static char *MInit_1 = "AT&F&C1E0&D2\r\0";
37 static char *MInit_2 = "ATL2M1S64=13\r\0";
38 static char *MInit_3 = "AT+FCLASS=0\r\0";
39 static char *MInit_4 = "ATV1S2=128X1\r\0";
40 static char *MInit_5 = "AT\\V8\\N3\r\0";
41 static char *MInit_6 = "ATL0M0&G0%E1\r\0";
42 static char *MInit_7 = "AT%L1%M0%C3\r\0";
44 static char *MInit_speed28800 = "AT%G0%B28800\r\0";
46 static char *MInit_dialout = "ATs7=60 x1 d\r\0";
47 static char *MInit_dialin = "ATs7=60 x1 a\r\0";
50 static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
52 #ifdef SERIAL_DEBUG_REG
53 u_int val = inb(cs->hw.elsa.base + 8 + offset);
54 debugl1(cs,"in %s %02x",ModemIn[offset], val);
55 return(val);
56 #else
57 return inb(cs->hw.elsa.base + 8 + offset);
58 #endif
61 static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
63 #ifdef SERIAL_DEBUG_REG
64 #ifdef CONFIG_SERIAL_NOPAUSE_IO
65 u_int val = inb(cs->hw.elsa.base + 8 + offset);
66 debugl1(cs,"inp %s %02x",ModemIn[offset], val);
67 #else
68 u_int val = inb_p(cs->hw.elsa.base + 8 + offset);
69 debugl1(cs,"inP %s %02x",ModemIn[offset], val);
70 #endif
71 return(val);
72 #else
73 #ifdef CONFIG_SERIAL_NOPAUSE_IO
74 return inb(cs->hw.elsa.base + 8 + offset);
75 #else
76 return inb_p(cs->hw.elsa.base + 8 + offset);
77 #endif
78 #endif
81 static inline void serial_out(struct IsdnCardState *cs, int offset, int value)
83 #ifdef SERIAL_DEBUG_REG
84 debugl1(cs,"out %s %02x",ModemOut[offset], value);
85 #endif
86 outb(value, cs->hw.elsa.base + 8 + offset);
89 static inline void serial_outp(struct IsdnCardState *cs, int offset,
90 int value)
92 #ifdef SERIAL_DEBUG_REG
93 #ifdef CONFIG_SERIAL_NOPAUSE_IO
94 debugl1(cs,"outp %s %02x",ModemOut[offset], value);
95 #else
96 debugl1(cs,"outP %s %02x",ModemOut[offset], value);
97 #endif
98 #endif
99 #ifdef CONFIG_SERIAL_NOPAUSE_IO
100 outb(value, cs->hw.elsa.base + 8 + offset);
101 #else
102 outb_p(value, cs->hw.elsa.base + 8 + offset);
103 #endif
107 * This routine is called to set the UART divisor registers to match
108 * the specified baud rate for a serial port.
110 static void change_speed(struct IsdnCardState *cs, int baud)
112 int quot = 0, baud_base;
113 unsigned cval, fcr = 0;
114 int bits;
115 unsigned long flags;
118 /* byte size and parity */
119 cval = 0x03; bits = 10;
120 /* Determine divisor based on baud rate */
121 baud_base = BASE_BAUD;
122 quot = baud_base / baud;
123 /* If the quotient is ever zero, default to 9600 bps */
124 if (!quot)
125 quot = baud_base / 9600;
127 /* Set up FIFO's */
128 if ((baud_base / quot) < 2400)
129 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
130 else
131 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
132 serial_outp(cs, UART_FCR, fcr);
133 /* CTS flow control flag and modem status interrupts */
134 cs->hw.elsa.IER &= ~UART_IER_MSI;
135 cs->hw.elsa.IER |= UART_IER_MSI;
136 serial_outp(cs, UART_IER, cs->hw.elsa.IER);
138 debugl1(cs,"modem quot=0x%x", quot);
139 save_flags(flags);
140 cli();
141 serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
142 serial_outp(cs, UART_DLL, quot & 0xff); /* LS of divisor */
143 serial_outp(cs, UART_DLM, quot >> 8); /* MS of divisor */
144 serial_outp(cs, UART_LCR, cval); /* reset DLAB */
145 serial_inp(cs, UART_RX);
146 restore_flags(flags);
149 static int mstartup(struct IsdnCardState *cs)
151 unsigned long flags;
152 int retval=0;
155 save_flags(flags); cli();
158 * Clear the FIFO buffers and disable them
159 * (they will be reenabled in change_speed())
161 serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
164 * At this point there's no way the LSR could still be 0xFF;
165 * if it is, then bail out, because there's likely no UART
166 * here.
168 if (serial_inp(cs, UART_LSR) == 0xff) {
169 retval = -ENODEV;
170 goto errout;
174 * Clear the interrupt registers.
176 (void) serial_inp(cs, UART_RX);
177 (void) serial_inp(cs, UART_IIR);
178 (void) serial_inp(cs, UART_MSR);
181 * Now, initialize the UART
183 serial_outp(cs, UART_LCR, UART_LCR_WLEN8); /* reset DLAB */
185 cs->hw.elsa.MCR = 0;
186 cs->hw.elsa.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
187 serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
190 * Finally, enable interrupts
192 cs->hw.elsa.IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
193 serial_outp(cs, UART_IER, cs->hw.elsa.IER); /* enable interrupts */
196 * And clear the interrupt registers again for luck.
198 (void)serial_inp(cs, UART_LSR);
199 (void)serial_inp(cs, UART_RX);
200 (void)serial_inp(cs, UART_IIR);
201 (void)serial_inp(cs, UART_MSR);
203 cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0;
204 cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp =0;
207 * and set the speed of the serial port
209 change_speed(cs, BASE_BAUD);
210 cs->hw.elsa.MFlag = 1;
211 errout:
212 restore_flags(flags);
213 return retval;
217 * This routine will shutdown a serial port; interrupts are disabled, and
218 * DTR is dropped if the hangup on close termio flag is on.
220 static void mshutdown(struct IsdnCardState *cs)
222 unsigned long flags;
225 #ifdef SERIAL_DEBUG_OPEN
226 printk(KERN_DEBUG"Shutting down serial ....");
227 #endif
229 save_flags(flags); cli(); /* Disable interrupts */
232 * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
233 * here so the queue might never be waken up
236 cs->hw.elsa.IER = 0;
237 serial_outp(cs, UART_IER, 0x00); /* disable all intrs */
238 cs->hw.elsa.MCR &= ~UART_MCR_OUT2;
240 /* disable break condition */
241 serial_outp(cs, UART_LCR, serial_inp(cs, UART_LCR) & ~UART_LCR_SBC);
243 cs->hw.elsa.MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
244 serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
246 /* disable FIFO's */
247 serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
248 serial_inp(cs, UART_RX); /* read data port to reset things */
250 restore_flags(flags);
251 #ifdef SERIAL_DEBUG_OPEN
252 printk(" done\n");
253 #endif
256 inline int
257 write_modem(struct BCState *bcs) {
258 int ret=0;
259 struct IsdnCardState *cs = bcs->cs;
260 int count, len, fp, buflen;
261 long flags;
263 if (!bcs->tx_skb)
264 return 0;
265 if (bcs->tx_skb->len <= 0)
266 return 0;
267 save_flags(flags);
268 cli();
269 buflen = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
270 len = MIN(buflen, bcs->tx_skb->len);
271 fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
272 fp &= (MAX_MODEM_BUF -1);
273 count = MIN(len, MAX_MODEM_BUF - fp);
274 if (count < len) {
275 memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, count);
276 skb_pull(bcs->tx_skb, count);
277 cs->hw.elsa.transcnt += count;
278 ret = count;
279 count = len - count;
280 fp = 0;
282 memcpy((cs->hw.elsa.transbuf + fp), bcs->tx_skb->data, count);
283 skb_pull(bcs->tx_skb, count);
284 cs->hw.elsa.transcnt += count;
285 ret += count;
287 if (cs->hw.elsa.transcnt &&
288 !(cs->hw.elsa.IER & UART_IER_THRI)) {
289 cs->hw.elsa.IER |= UART_IER_THRI;
290 serial_outp(cs, UART_IER, cs->hw.elsa.IER);
292 restore_flags(flags);
293 return(ret);
296 inline void
297 modem_fill(struct BCState *bcs) {
299 if (bcs->tx_skb) {
300 if (bcs->tx_skb->len) {
301 write_modem(bcs);
302 return;
303 } else {
304 if (bcs->st->lli.l1writewakeup &&
305 (PACKET_NOACK != bcs->tx_skb->pkt_type))
306 bcs->st->lli.l1writewakeup(bcs->st,
307 bcs->hw.hscx.count);
308 dev_kfree_skb_any(bcs->tx_skb);
309 bcs->tx_skb = NULL;
312 if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
313 bcs->hw.hscx.count = 0;
314 test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
315 write_modem(bcs);
316 } else {
317 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
318 hscx_sched_event(bcs, B_XMTBUFREADY);
322 static inline void receive_chars(struct IsdnCardState *cs,
323 int *status)
325 unsigned char ch;
326 struct sk_buff *skb;
328 do {
329 ch = serial_in(cs, UART_RX);
330 if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF)
331 break;
332 cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
333 #ifdef SERIAL_DEBUG_INTR
334 printk("DR%02x:%02x...", ch, *status);
335 #endif
336 if (*status & (UART_LSR_BI | UART_LSR_PE |
337 UART_LSR_FE | UART_LSR_OE)) {
339 #ifdef SERIAL_DEBUG_INTR
340 printk("handling exept....");
341 #endif
343 *status = serial_inp(cs, UART_LSR);
344 } while (*status & UART_LSR_DR);
345 if (cs->hw.elsa.MFlag == 2) {
346 if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
347 printk(KERN_WARNING "ElsaSER: receive out of memory\n");
348 else {
349 memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf,
350 cs->hw.elsa.rcvcnt);
351 skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
353 hscx_sched_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
354 } else {
355 char tmp[128];
356 char *t = tmp;
358 t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt);
359 QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
360 debugl1(cs, tmp);
362 cs->hw.elsa.rcvcnt = 0;
365 static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
367 int count;
369 debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
370 cs->hw.elsa.transcnt);
372 if (cs->hw.elsa.transcnt <= 0) {
373 cs->hw.elsa.IER &= ~UART_IER_THRI;
374 serial_out(cs, UART_IER, cs->hw.elsa.IER);
375 return;
377 count = 16;
378 do {
379 serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
380 if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
381 cs->hw.elsa.transp=0;
382 if (--cs->hw.elsa.transcnt <= 0)
383 break;
384 } while (--count > 0);
385 if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
386 modem_fill(cs->hw.elsa.bcs);
388 #ifdef SERIAL_DEBUG_INTR
389 printk("THRE...");
390 #endif
391 if (intr_done)
392 *intr_done = 0;
393 if (cs->hw.elsa.transcnt <= 0) {
394 cs->hw.elsa.IER &= ~UART_IER_THRI;
395 serial_outp(cs, UART_IER, cs->hw.elsa.IER);
400 static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
402 int status, iir, msr;
403 int pass_counter = 0;
405 #ifdef SERIAL_DEBUG_INTR
406 printk("rs_interrupt_single(%d)...", irq);
407 #endif
409 do {
410 status = serial_inp(cs, UART_LSR);
411 debugl1(cs,"rs LSR %02x", status);
412 #ifdef SERIAL_DEBUG_INTR
413 printk("status = %x...", status);
414 #endif
415 if (status & UART_LSR_DR)
416 receive_chars(cs, &status);
417 if (status & UART_LSR_THRE)
418 transmit_chars(cs, 0);
419 if (pass_counter++ > RS_ISR_PASS_LIMIT) {
420 printk("rs_single loop break.\n");
421 break;
423 iir = serial_inp(cs, UART_IIR);
424 debugl1(cs,"rs IIR %02x", iir);
425 if ((iir & 0xf) == 0) {
426 msr = serial_inp(cs, UART_MSR);
427 debugl1(cs,"rs MSR %02x", msr);
429 } while (!(iir & UART_IIR_NO_INT));
430 #ifdef SERIAL_DEBUG_INTR
431 printk("end.\n");
432 #endif
435 extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
436 extern void modehscx(struct BCState *bcs, int mode, int bc);
437 extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
439 void
440 close_elsastate(struct BCState *bcs)
442 struct sk_buff *skb;
444 modehscx(bcs, 0, bcs->channel);
445 if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
446 if (bcs->hw.hscx.rcvbuf) {
447 if (bcs->mode != L1_MODE_MODEM)
448 kfree(bcs->hw.hscx.rcvbuf);
449 bcs->hw.hscx.rcvbuf = NULL;
451 while ((skb = skb_dequeue(&bcs->rqueue))) {
452 dev_kfree_skb_any(skb);
454 while ((skb = skb_dequeue(&bcs->squeue))) {
455 dev_kfree_skb_any(skb);
457 if (bcs->tx_skb) {
458 dev_kfree_skb_any(bcs->tx_skb);
459 bcs->tx_skb = NULL;
460 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
465 void
466 modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
467 int count, fp;
468 u_char *msg = buf;
469 long flags;
471 if (!len)
472 return;
473 save_flags(flags);
474 cli();
475 if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
476 restore_flags(flags);
477 return;
479 fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
480 fp &= (MAX_MODEM_BUF -1);
481 count = MIN(len, MAX_MODEM_BUF - fp);
482 if (count < len) {
483 memcpy(cs->hw.elsa.transbuf + fp, msg, count);
484 cs->hw.elsa.transcnt += count;
485 msg += count;
486 count = len - count;
487 fp = 0;
489 memcpy(cs->hw.elsa.transbuf + fp, msg, count);
490 cs->hw.elsa.transcnt += count;
491 if (cs->hw.elsa.transcnt &&
492 !(cs->hw.elsa.IER & UART_IER_THRI)) {
493 cs->hw.elsa.IER |= UART_IER_THRI;
494 serial_outp(cs, UART_IER, cs->hw.elsa.IER);
496 restore_flags(flags);
499 void
500 modem_set_init(struct IsdnCardState *cs) {
501 long flags;
502 int timeout;
504 #define RCV_DELAY 20000
505 save_flags(flags);
506 sti();
507 modem_write_cmd(cs, MInit_1, strlen(MInit_1));
508 timeout = 1000;
509 while(timeout-- && cs->hw.elsa.transcnt)
510 udelay(1000);
511 debugl1(cs, "msi tout=%d", timeout);
512 udelay(RCV_DELAY);
513 modem_write_cmd(cs, MInit_2, strlen(MInit_2));
514 timeout = 1000;
515 while(timeout-- && cs->hw.elsa.transcnt)
516 udelay(1000);
517 debugl1(cs, "msi tout=%d", timeout);
518 udelay(RCV_DELAY);
519 modem_write_cmd(cs, MInit_3, strlen(MInit_3));
520 timeout = 1000;
521 while(timeout-- && cs->hw.elsa.transcnt)
522 udelay(1000);
523 debugl1(cs, "msi tout=%d", timeout);
524 udelay(RCV_DELAY);
525 modem_write_cmd(cs, MInit_4, strlen(MInit_4));
526 timeout = 1000;
527 while(timeout-- && cs->hw.elsa.transcnt)
528 udelay(1000);
529 debugl1(cs, "msi tout=%d", timeout);
530 udelay(RCV_DELAY );
531 modem_write_cmd(cs, MInit_5, strlen(MInit_5));
532 timeout = 1000;
533 while(timeout-- && cs->hw.elsa.transcnt)
534 udelay(1000);
535 debugl1(cs, "msi tout=%d", timeout);
536 udelay(RCV_DELAY);
537 modem_write_cmd(cs, MInit_6, strlen(MInit_6));
538 timeout = 1000;
539 while(timeout-- && cs->hw.elsa.transcnt)
540 udelay(1000);
541 debugl1(cs, "msi tout=%d", timeout);
542 udelay(RCV_DELAY);
543 modem_write_cmd(cs, MInit_7, strlen(MInit_7));
544 timeout = 1000;
545 while(timeout-- && cs->hw.elsa.transcnt)
546 udelay(1000);
547 debugl1(cs, "msi tout=%d", timeout);
548 udelay(RCV_DELAY);
549 restore_flags(flags);
552 void
553 modem_set_dial(struct IsdnCardState *cs, int outgoing) {
554 long flags;
555 int timeout;
556 #define RCV_DELAY 20000
558 save_flags(flags);
559 sti();
560 modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
561 timeout = 1000;
562 while(timeout-- && cs->hw.elsa.transcnt)
563 udelay(1000);
564 debugl1(cs, "msi tout=%d", timeout);
565 udelay(RCV_DELAY);
566 if (outgoing)
567 modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
568 else
569 modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
570 timeout = 1000;
571 while(timeout-- && cs->hw.elsa.transcnt)
572 udelay(1000);
573 debugl1(cs, "msi tout=%d", timeout);
574 udelay(RCV_DELAY);
575 restore_flags(flags);
578 void
579 modem_l2l1(struct PStack *st, int pr, void *arg)
581 struct sk_buff *skb = arg;
582 long flags;
584 if (pr == (PH_DATA | REQUEST)) {
585 save_flags(flags);
586 cli();
587 if (st->l1.bcs->tx_skb) {
588 skb_queue_tail(&st->l1.bcs->squeue, skb);
589 restore_flags(flags);
590 } else {
591 st->l1.bcs->tx_skb = skb;
592 test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
593 st->l1.bcs->hw.hscx.count = 0;
594 restore_flags(flags);
595 write_modem(st->l1.bcs);
597 } else if (pr == (PH_ACTIVATE | REQUEST)) {
598 test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
599 st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
600 set_arcofi(st->l1.bcs->cs, st->l1.bc);
601 mstartup(st->l1.bcs->cs);
602 modem_set_dial(st->l1.bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
603 st->l1.bcs->cs->hw.elsa.MFlag=2;
604 } else if (pr == (PH_DEACTIVATE | REQUEST)) {
605 test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
606 st->l1.bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
607 arcofi_fsm(st->l1.bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
608 interruptible_sleep_on(&st->l1.bcs->cs->dc.isac.arcofi_wait);
609 st->l1.bcs->cs->hw.elsa.MFlag=1;
610 } else {
611 printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
616 setstack_elsa(struct PStack *st, struct BCState *bcs)
619 bcs->channel = st->l1.bc;
620 switch (st->l1.mode) {
621 case L1_MODE_HDLC:
622 case L1_MODE_TRANS:
623 if (open_hscxstate(st->l1.hardware, bcs))
624 return (-1);
625 st->l2.l2l1 = hscx_l2l1;
626 break;
627 case L1_MODE_MODEM:
628 bcs->mode = L1_MODE_MODEM;
629 if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
630 bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
631 skb_queue_head_init(&bcs->rqueue);
632 skb_queue_head_init(&bcs->squeue);
634 bcs->tx_skb = NULL;
635 test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
636 bcs->event = 0;
637 bcs->hw.hscx.rcvidx = 0;
638 bcs->tx_cnt = 0;
639 bcs->cs->hw.elsa.bcs = bcs;
640 st->l2.l2l1 = modem_l2l1;
641 break;
643 st->l1.bcs = bcs;
644 setstack_manager(st);
645 bcs->st = st;
646 setstack_l1_B(st);
647 return (0);
650 void
651 init_modem(struct IsdnCardState *cs) {
653 cs->bcs[0].BC_SetStack = setstack_elsa;
654 cs->bcs[1].BC_SetStack = setstack_elsa;
655 cs->bcs[0].BC_Close = close_elsastate;
656 cs->bcs[1].BC_Close = close_elsastate;
657 if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
658 GFP_ATOMIC))) {
659 printk(KERN_WARNING
660 "Elsa: No modem mem hw.elsa.rcvbuf\n");
661 return;
663 if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
664 GFP_ATOMIC))) {
665 printk(KERN_WARNING
666 "Elsa: No modem mem hw.elsa.transbuf\n");
667 kfree(cs->hw.elsa.rcvbuf);
668 cs->hw.elsa.rcvbuf = NULL;
669 return;
671 if (mstartup(cs)) {
672 printk(KERN_WARNING "Elsa: problem startup modem\n");
674 modem_set_init(cs);
677 void
678 release_modem(struct IsdnCardState *cs) {
680 cs->hw.elsa.MFlag = 0;
681 if (cs->hw.elsa.transbuf) {
682 if (cs->hw.elsa.rcvbuf) {
683 mshutdown(cs);
684 kfree(cs->hw.elsa.rcvbuf);
685 cs->hw.elsa.rcvbuf = NULL;
687 kfree(cs->hw.elsa.transbuf);
688 cs->hw.elsa.transbuf = NULL;