10 #include <linux/serial.h>
12 #include <linux/slab.h>
14 #define MAX_MODEM_BUF 256
15 #define WAKEUP_CHARS (MAX_MODEM_BUF / 2)
16 #define RS_ISR_PASS_LIMIT 256
17 #define BASE_BAUD (1843200 / 16)
22 #undef SERIAL_DEBUG_OPEN
23 #undef SERIAL_DEBUG_INTR
24 #undef SERIAL_DEBUG_FLOW
25 #undef SERIAL_DEBUG_REG
28 #ifdef SERIAL_DEBUG_REG
30 const char *ModemIn[] = {
"RBR",
"IER",
"IIR",
"LCR",
"MCR",
"LSR",
"MSR",
"SCR"};
31 const char *ModemOut[] = {
"THR",
"IER",
"FCR",
"LCR",
"MCR",
"LSR",
"MSR",
"SCR"};
34 static char *MInit_1 =
"AT&F&C1E0&D2\r\0";
35 static char *MInit_2 =
"ATL2M1S64=13\r\0";
36 static char *MInit_3 =
"AT+FCLASS=0\r\0";
37 static char *MInit_4 =
"ATV1S2=128X1\r\0";
38 static char *MInit_5 =
"AT\\V8\\N3\r\0";
39 static char *MInit_6 =
"ATL0M0&G0%E1\r\0";
40 static char *MInit_7 =
"AT%L1%M0%C3\r\0";
42 static char *MInit_speed28800 =
"AT%G0%B28800\r\0";
44 static char *MInit_dialout =
"ATs7=60 x1 d\r\0";
45 static char *MInit_dialin =
"ATs7=60 x1 a\r\0";
48 static inline unsigned int serial_in(
struct IsdnCardState *
cs,
int offset)
50 #ifdef SERIAL_DEBUG_REG
52 debugl1(cs,
"in %s %02x", ModemIn[offset], val);
55 return inb(cs->hw.elsa.base + 8 + offset);
59 static inline unsigned int serial_inp(
struct IsdnCardState *cs,
int offset)
61 #ifdef SERIAL_DEBUG_REG
62 #ifdef ELSA_SERIAL_NOPAUSE_IO
63 u_int val =
inb(cs->hw.elsa.base + 8 + offset);
64 debugl1(cs,
"inp %s %02x", ModemIn[offset], val);
66 u_int val =
inb_p(cs->hw.elsa.base + 8 + offset);
67 debugl1(cs,
"inP %s %02x", ModemIn[offset], val);
71 #ifdef ELSA_SERIAL_NOPAUSE_IO
72 return inb(cs->hw.elsa.base + 8 + offset);
74 return inb_p(cs->hw.elsa.base + 8 + offset);
79 static inline void serial_out(
struct IsdnCardState *cs,
int offset,
int value)
81 #ifdef SERIAL_DEBUG_REG
82 debugl1(cs,
"out %s %02x", ModemOut[offset], value);
84 outb(value, cs->hw.elsa.base + 8 + offset);
87 static inline void serial_outp(
struct IsdnCardState *cs,
int offset,
90 #ifdef SERIAL_DEBUG_REG
91 #ifdef ELSA_SERIAL_NOPAUSE_IO
92 debugl1(cs,
"outp %s %02x", ModemOut[offset], value);
94 debugl1(cs,
"outP %s %02x", ModemOut[offset], value);
97 #ifdef ELSA_SERIAL_NOPAUSE_IO
98 outb(value, cs->hw.elsa.base + 8 + offset);
100 outb_p(value, cs->hw.elsa.base + 8 + offset);
108 static void change_speed(
struct IsdnCardState *cs,
int baud)
110 int quot = 0, baud_base;
111 unsigned cval,
fcr = 0;
118 quot = baud_base /
baud;
121 quot = baud_base / 9600;
124 if ((baud_base / quot) < 2400)
134 debugl1(cs,
"modem quot=0x%x", quot);
142 static int mstartup(
struct IsdnCardState *cs)
192 cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0;
193 cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp = 0;
199 cs->hw.elsa.MFlag = 1;
208 static void mshutdown(
struct IsdnCardState *cs)
211 #ifdef SERIAL_DEBUG_OPEN
234 #ifdef SERIAL_DEBUG_OPEN
240 write_modem(
struct BCState *bcs) {
242 struct IsdnCardState *cs = bcs->cs;
247 if (bcs->tx_skb->len <= 0)
249 len = bcs->tx_skb->len;
252 fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
257 skb_copy_from_linear_data(bcs->tx_skb,
258 cs->hw.elsa.transbuf + fp, count);
260 cs->hw.elsa.transcnt +=
count;
265 skb_copy_from_linear_data(bcs->tx_skb,
266 cs->hw.elsa.transbuf + fp, count);
268 cs->hw.elsa.transcnt +=
count;
271 if (cs->hw.elsa.transcnt &&
280 modem_fill(
struct BCState *bcs) {
283 if (bcs->tx_skb->len) {
287 if (
test_bit(FLG_LLI_L1WAKEUP, &bcs->st->lli.flag) &&
288 (PACKET_NOACK != bcs->tx_skb->pkt_type)) {
291 bcs->ackcnt += bcs->hw.hscx.count;
292 spin_unlock_irqrestore(&bcs->aclock, flags);
300 bcs->hw.hscx.count = 0;
309 static inline void receive_chars(
struct IsdnCardState *cs,
319 cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
320 #ifdef SERIAL_DEBUG_INTR
321 printk(
"DR%02x:%02x...", ch, *status);
326 #ifdef SERIAL_DEBUG_INTR
327 printk(
"handling exept....");
332 if (cs->hw.elsa.MFlag == 2) {
333 if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
345 t +=
sprintf(t,
"modem read cnt %d", cs->hw.elsa.rcvcnt);
346 QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
349 cs->hw.elsa.rcvcnt = 0;
352 static inline void transmit_chars(
struct IsdnCardState *cs,
int *intr_done)
356 debugl1(cs,
"transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
357 cs->hw.elsa.transcnt);
359 if (cs->hw.elsa.transcnt <= 0) {
361 serial_out(cs,
UART_IER, cs->hw.elsa.IER);
368 cs->hw.elsa.transp = 0;
369 if (--cs->hw.elsa.transcnt <= 0)
371 }
while (--count > 0);
372 if ((cs->hw.elsa.transcnt <
WAKEUP_CHARS) && (cs->hw.elsa.MFlag == 2))
373 modem_fill(cs->hw.elsa.bcs);
375 #ifdef SERIAL_DEBUG_INTR
380 if (cs->hw.elsa.transcnt <= 0) {
387 static void rs_interrupt_elsa(
struct IsdnCardState *cs)
390 int pass_counter = 0;
392 #ifdef SERIAL_DEBUG_INTR
398 debugl1(cs,
"rs LSR %02x", status);
399 #ifdef SERIAL_DEBUG_INTR
400 printk(
"status = %x...", status);
402 if (status & UART_LSR_DR)
403 receive_chars(cs, &status);
405 transmit_chars(cs,
NULL);
407 printk(
"rs_single loop break.\n");
411 debugl1(cs,
"rs IIR %02x", iir);
412 if ((iir & 0xf) == 0) {
414 debugl1(cs,
"rs MSR %02x", msr);
417 #ifdef SERIAL_DEBUG_INTR
422 extern int open_hscxstate(
struct IsdnCardState *cs,
struct BCState *bcs);
427 close_elsastate(
struct BCState *bcs)
431 if (bcs->hw.hscx.rcvbuf) {
433 kfree(bcs->hw.hscx.rcvbuf);
434 bcs->hw.hscx.rcvbuf =
NULL;
447 modem_write_cmd(
struct IsdnCardState *cs,
u_char *
buf,
int len) {
456 fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
461 memcpy(cs->hw.elsa.transbuf + fp, msg, count);
462 cs->hw.elsa.transcnt +=
count;
467 memcpy(cs->hw.elsa.transbuf + fp, msg, count);
468 cs->hw.elsa.transcnt +=
count;
469 if (cs->hw.elsa.transcnt &&
477 modem_set_init(
struct IsdnCardState *cs) {
481 modem_write_cmd(cs, MInit_1,
strlen(MInit_1));
483 while (timeout-- && cs->hw.elsa.transcnt)
485 debugl1(cs,
"msi tout=%d", timeout);
487 modem_write_cmd(cs, MInit_2,
strlen(MInit_2));
489 while (timeout-- && cs->hw.elsa.transcnt)
491 debugl1(cs,
"msi tout=%d", timeout);
493 modem_write_cmd(cs, MInit_3,
strlen(MInit_3));
495 while (timeout-- && cs->hw.elsa.transcnt)
497 debugl1(cs,
"msi tout=%d", timeout);
499 modem_write_cmd(cs, MInit_4,
strlen(MInit_4));
501 while (timeout-- && cs->hw.elsa.transcnt)
503 debugl1(cs,
"msi tout=%d", timeout);
505 modem_write_cmd(cs, MInit_5,
strlen(MInit_5));
507 while (timeout-- && cs->hw.elsa.transcnt)
509 debugl1(cs,
"msi tout=%d", timeout);
511 modem_write_cmd(cs, MInit_6,
strlen(MInit_6));
513 while (timeout-- && cs->hw.elsa.transcnt)
515 debugl1(cs,
"msi tout=%d", timeout);
517 modem_write_cmd(cs, MInit_7,
strlen(MInit_7));
519 while (timeout-- && cs->hw.elsa.transcnt)
521 debugl1(cs,
"msi tout=%d", timeout);
526 modem_set_dial(
struct IsdnCardState *cs,
int outgoing) {
530 modem_write_cmd(cs, MInit_speed28800,
strlen(MInit_speed28800));
532 while (timeout-- && cs->hw.elsa.transcnt)
534 debugl1(cs,
"msi tout=%d", timeout);
537 modem_write_cmd(cs, MInit_dialout,
strlen(MInit_dialout));
539 modem_write_cmd(cs, MInit_dialin,
strlen(MInit_dialin));
541 while (timeout-- && cs->hw.elsa.transcnt)
543 debugl1(cs,
"msi tout=%d", timeout);
548 modem_l2l1(
struct PStack *
st,
int pr,
void *
arg)
550 struct BCState *bcs = st->l1.bcs;
561 bcs->hw.hscx.count = 0;
564 spin_unlock_irqrestore(&bcs->cs->lock, flags);
568 set_arcofi(bcs->cs, st->l1.bc);
571 bcs->cs->hw.elsa.MFlag = 2;
574 bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
577 bcs->cs->hw.elsa.MFlag = 1;
584 setstack_elsa(
struct PStack *st,
struct BCState *bcs)
587 bcs->channel = st->l1.bc;
588 switch (st->l1.mode) {
598 bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
599 skb_queue_head_init(&bcs->rqueue);
600 skb_queue_head_init(&bcs->squeue);
605 bcs->hw.hscx.rcvidx = 0;
607 bcs->cs->hw.elsa.bcs = bcs;
608 st->l2.l2l1 = modem_l2l1;
619 init_modem(
struct IsdnCardState *cs) {
621 cs->bcs[0].BC_SetStack = setstack_elsa;
622 cs->bcs[1].BC_SetStack = setstack_elsa;
623 cs->bcs[0].BC_Close = close_elsastate;
624 cs->bcs[1].BC_Close = close_elsastate;
628 "Elsa: No modem mem hw.elsa.rcvbuf\n");
634 "Elsa: No modem mem hw.elsa.transbuf\n");
635 kfree(cs->hw.elsa.rcvbuf);
636 cs->hw.elsa.rcvbuf =
NULL;
646 release_modem(
struct IsdnCardState *cs) {
648 cs->hw.elsa.MFlag = 0;
649 if (cs->hw.elsa.transbuf) {
650 if (cs->hw.elsa.rcvbuf) {
652 kfree(cs->hw.elsa.rcvbuf);
653 cs->hw.elsa.rcvbuf =
NULL;
655 kfree(cs->hw.elsa.transbuf);
656 cs->hw.elsa.transbuf =
NULL;