OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [isdn/] [hisax/] [elsa_ser.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
#include <linux/serial.h>
2
#include <linux/serial_reg.h>
3
 
4
#define MAX_MODEM_BUF   256
5
#define WAKEUP_CHARS    (MAX_MODEM_BUF/2)
6
#define RS_ISR_PASS_LIMIT 256
7
#define BASE_BAUD ( 1843200 / 16 )
8
 
9
#ifndef MIN
10
#define MIN(a,b)        ((a) < (b) ? (a) : (b))
11
#endif
12
 
13
//#define SERIAL_DEBUG_OPEN 1
14
//#define SERIAL_DEBUG_INTR 1
15
//#define SERIAL_DEBUG_FLOW 1
16
#undef SERIAL_DEBUG_OPEN
17
#undef SERIAL_DEBUG_INTR
18
#undef SERIAL_DEBUG_FLOW
19
#undef SERIAL_DEBUG_REG
20
//#define SERIAL_DEBUG_REG 1
21
 
22
#ifdef SERIAL_DEBUG_REG
23
static u_char deb[32];
24
const char *ModemIn[] = {"RBR","IER","IIR","LCR","MCR","LSR","MSR","SCR"};
25
const char *ModemOut[] = {"THR","IER","FCR","LCR","MCR","LSR","MSR","SCR"};
26
#endif
27
 
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
 
36
static char *MInit_speed28800 = "AT%G0%B28800\r\0";
37
 
38
static char *MInit_dialout = "ATs7=60 x1 d\r\0";
39
static char *MInit_dialin = "ATs7=60 x1 a\r\0";
40
 
41
 
42
static inline unsigned int serial_in(struct IsdnCardState *cs, int offset)
43
{
44
#ifdef SERIAL_DEBUG_REG
45
        u_int val = inb(cs->hw.elsa.base + 8 + offset);
46
        debugl1(cs,"in   %s %02x",ModemIn[offset], val);
47
        return(val);
48
#else
49
        return inb(cs->hw.elsa.base + 8 + offset);
50
#endif
51
}
52
 
53
static inline unsigned int serial_inp(struct IsdnCardState *cs, int offset)
54
{
55
#ifdef SERIAL_DEBUG_REG
56
#ifdef CONFIG_SERIAL_NOPAUSE_IO
57
        u_int val = inb(cs->hw.elsa.base + 8 + offset);
58
        debugl1(cs,"inp  %s %02x",ModemIn[offset], val);
59
#else
60
        u_int val = inb_p(cs->hw.elsa.base + 8 + offset);
61
        debugl1(cs,"inP  %s %02x",ModemIn[offset], val);
62
#endif
63
        return(val);
64
#else
65
#ifdef CONFIG_SERIAL_NOPAUSE_IO
66
        return inb(cs->hw.elsa.base + 8 + offset);
67
#else
68
        return inb_p(cs->hw.elsa.base + 8 + offset);
69
#endif
70
#endif
71
}
72
 
73
static inline void serial_out(struct IsdnCardState *cs, int offset, int value)
74
{
75
#ifdef SERIAL_DEBUG_REG
76
        debugl1(cs,"out  %s %02x",ModemOut[offset], value);
77
#endif
78
        outb(value, cs->hw.elsa.base + 8 + offset);
79
}
80
 
81
static inline void serial_outp(struct IsdnCardState *cs, int offset,
82
                               int value)
83
{
84
#ifdef SERIAL_DEBUG_REG
85
#ifdef CONFIG_SERIAL_NOPAUSE_IO
86
        debugl1(cs,"outp %s %02x",ModemOut[offset], value);
87
#else
88
        debugl1(cs,"outP %s %02x",ModemOut[offset], value);
89
#endif
90
#endif
91
#ifdef CONFIG_SERIAL_NOPAUSE_IO
92
        outb(value, cs->hw.elsa.base + 8 + offset);
93
#else
94
        outb_p(value, cs->hw.elsa.base + 8 + offset);
95
#endif
96
}
97
 
98
/*
99
 * This routine is called to set the UART divisor registers to match
100
 * the specified baud rate for a serial port.
101
 */
102
static void change_speed(struct IsdnCardState *cs, int baud)
103
{
104
        int     quot = 0, baud_base;
105
        unsigned cval, fcr = 0;
106
        int     bits;
107
        unsigned long   flags;
108
 
109
 
110
        /* byte size and parity */
111
        cval = 0x03; bits = 10;
112
        /* Determine divisor based on baud rate */
113
        baud_base = BASE_BAUD;
114
        quot = baud_base / baud;
115
        /* If the quotient is ever zero, default to 9600 bps */
116
        if (!quot)
117
                quot = baud_base / 9600;
118
 
119
        /* Set up FIFO's */
120
        if ((baud_base / quot) < 2400)
121
                fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_1;
122
        else
123
                fcr = UART_FCR_ENABLE_FIFO | UART_FCR_TRIGGER_8;
124
        serial_outp(cs, UART_FCR, fcr);
125
        /* CTS flow control flag and modem status interrupts */
126
        cs->hw.elsa.IER &= ~UART_IER_MSI;
127
        cs->hw.elsa.IER |= UART_IER_MSI;
128
        serial_outp(cs, UART_IER, cs->hw.elsa.IER);
129
 
130
        debugl1(cs,"modem quot=0x%x", quot);
131
        save_flags(flags);
132
        cli();
133
        serial_outp(cs, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */
134
        serial_outp(cs, UART_DLL, quot & 0xff);         /* LS of divisor */
135
        serial_outp(cs, UART_DLM, quot >> 8);           /* MS of divisor */
136
        serial_outp(cs, UART_LCR, cval);                /* reset DLAB */
137
        serial_inp(cs, UART_RX);
138
        restore_flags(flags);
139
}
140
 
141
static int mstartup(struct IsdnCardState *cs)
142
{
143
        unsigned long flags;
144
        int     retval=0;
145
 
146
 
147
        save_flags(flags); cli();
148
 
149
        /*
150
         * Clear the FIFO buffers and disable them
151
         * (they will be reenabled in change_speed())
152
         */
153
        serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
154
 
155
        /*
156
         * At this point there's no way the LSR could still be 0xFF;
157
         * if it is, then bail out, because there's likely no UART
158
         * here.
159
         */
160
        if (serial_inp(cs, UART_LSR) == 0xff) {
161
                retval = -ENODEV;
162
                goto errout;
163
        }
164
 
165
        /*
166
         * Clear the interrupt registers.
167
         */
168
        (void) serial_inp(cs, UART_RX);
169
        (void) serial_inp(cs, UART_IIR);
170
        (void) serial_inp(cs, UART_MSR);
171
 
172
        /*
173
         * Now, initialize the UART
174
         */
175
        serial_outp(cs, UART_LCR, UART_LCR_WLEN8);      /* reset DLAB */
176
 
177
        cs->hw.elsa.MCR = 0;
178
        cs->hw.elsa.MCR = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
179
        serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
180
 
181
        /*
182
         * Finally, enable interrupts
183
         */
184
        cs->hw.elsa.IER = UART_IER_MSI | UART_IER_RLSI | UART_IER_RDI;
185
        serial_outp(cs, UART_IER, cs->hw.elsa.IER);     /* enable interrupts */
186
 
187
        /*
188
         * And clear the interrupt registers again for luck.
189
         */
190
        (void)serial_inp(cs, UART_LSR);
191
        (void)serial_inp(cs, UART_RX);
192
        (void)serial_inp(cs, UART_IIR);
193
        (void)serial_inp(cs, UART_MSR);
194
 
195
        cs->hw.elsa.transcnt = cs->hw.elsa.transp = 0;
196
        cs->hw.elsa.rcvcnt = cs->hw.elsa.rcvp =0;
197
 
198
        /*
199
         * and set the speed of the serial port
200
         */
201
        change_speed(cs, BASE_BAUD);
202
        cs->hw.elsa.MFlag = 1;
203
errout:
204
        restore_flags(flags);
205
        return retval;
206
}
207
 
208
/*
209
 * This routine will shutdown a serial port; interrupts are disabled, and
210
 * DTR is dropped if the hangup on close termio flag is on.
211
 */
212
static void mshutdown(struct IsdnCardState *cs)
213
{
214
        unsigned long   flags;
215
 
216
 
217
#ifdef SERIAL_DEBUG_OPEN
218
        printk(KERN_DEBUG"Shutting down serial ....");
219
#endif
220
 
221
        save_flags(flags); cli(); /* Disable interrupts */
222
 
223
        /*
224
         * clear delta_msr_wait queue to avoid mem leaks: we may free the irq
225
         * here so the queue might never be waken up
226
         */
227
 
228
        cs->hw.elsa.IER = 0;
229
        serial_outp(cs, UART_IER, 0x00);        /* disable all intrs */
230
        cs->hw.elsa.MCR &= ~UART_MCR_OUT2;
231
 
232
        /* disable break condition */
233
        serial_outp(cs, UART_LCR, serial_inp(cs, UART_LCR) & ~UART_LCR_SBC);
234
 
235
        cs->hw.elsa.MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
236
        serial_outp(cs, UART_MCR, cs->hw.elsa.MCR);
237
 
238
        /* disable FIFO's */
239
        serial_outp(cs, UART_FCR, (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT));
240
        serial_inp(cs, UART_RX);    /* read data port to reset things */
241
 
242
        restore_flags(flags);
243
#ifdef SERIAL_DEBUG_OPEN
244
        printk(" done\n");
245
#endif
246
}
247
 
248
inline int
249
write_modem(struct BCState *bcs) {
250
        int ret=0;
251
        struct IsdnCardState *cs = bcs->cs;
252
        int count, len, fp, buflen;
253
        long flags;
254
 
255
        if (!bcs->tx_skb)
256
                return 0;
257
        if (bcs->tx_skb->len <= 0)
258
                return 0;
259
        save_flags(flags);
260
        cli();
261
        buflen = MAX_MODEM_BUF - cs->hw.elsa.transcnt;
262
        len = MIN(buflen, bcs->tx_skb->len);
263
        fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
264
        fp &= (MAX_MODEM_BUF -1);
265
        count = MIN(len, MAX_MODEM_BUF - fp);
266
        if (count < len) {
267
                memcpy(cs->hw.elsa.transbuf + fp, bcs->tx_skb->data, count);
268
                skb_pull(bcs->tx_skb, count);
269
                cs->hw.elsa.transcnt += count;
270
                ret = count;
271
                count = len - count;
272
                fp = 0;
273
        }
274
        memcpy((cs->hw.elsa.transbuf + fp), bcs->tx_skb->data, count);
275
        skb_pull(bcs->tx_skb, count);
276
        cs->hw.elsa.transcnt += count;
277
        ret += count;
278
 
279
        if (cs->hw.elsa.transcnt &&
280
            !(cs->hw.elsa.IER & UART_IER_THRI)) {
281
                        cs->hw.elsa.IER |= UART_IER_THRI;
282
                serial_outp(cs, UART_IER, cs->hw.elsa.IER);
283
        }
284
        restore_flags(flags);
285
        return(ret);
286
}
287
 
288
inline void
289
modem_fill(struct BCState *bcs) {
290
 
291
        if (bcs->tx_skb) {
292
                if (bcs->tx_skb->len) {
293
                        write_modem(bcs);
294
                        return;
295
                } else {
296
                        if (bcs->st->lli.l1writewakeup &&
297
                                (PACKET_NOACK != bcs->tx_skb->pkt_type))
298
                                        bcs->st->lli.l1writewakeup(bcs->st,
299
                                                bcs->hw.hscx.count);
300
                        dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
301
                        bcs->tx_skb = NULL;
302
                }
303
        }
304
        if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
305
                bcs->hw.hscx.count = 0;
306
                test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
307
                write_modem(bcs);
308
        } else {
309
                test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
310
                hscx_sched_event(bcs, B_XMTBUFREADY);
311
        }
312
}
313
 
314
static inline void receive_chars(struct IsdnCardState *cs,
315
                                 int *status)
316
{
317
        unsigned char ch;
318
        struct sk_buff *skb;
319
 
320
        do {
321
                ch = serial_in(cs, UART_RX);
322
                if (cs->hw.elsa.rcvcnt >= MAX_MODEM_BUF)
323
                        break;
324
                cs->hw.elsa.rcvbuf[cs->hw.elsa.rcvcnt++] = ch;
325
#ifdef SERIAL_DEBUG_INTR
326
                printk("DR%02x:%02x...", ch, *status);
327
#endif
328
                if (*status & (UART_LSR_BI | UART_LSR_PE |
329
                               UART_LSR_FE | UART_LSR_OE)) {
330
 
331
#ifdef SERIAL_DEBUG_INTR
332
                        printk("handling exept....");
333
#endif
334
                }
335
                *status = serial_inp(cs, UART_LSR);
336
        } while (*status & UART_LSR_DR);
337
        if (cs->hw.elsa.MFlag == 2) {
338
                if (!(skb = dev_alloc_skb(cs->hw.elsa.rcvcnt)))
339
                        printk(KERN_WARNING "ElsaSER: receive out of memory\n");
340
                else {
341
                        memcpy(skb_put(skb, cs->hw.elsa.rcvcnt), cs->hw.elsa.rcvbuf,
342
                                cs->hw.elsa.rcvcnt);
343
                        skb_queue_tail(& cs->hw.elsa.bcs->rqueue, skb);
344
                }
345
                hscx_sched_event(cs->hw.elsa.bcs, B_RCVBUFREADY);
346
        } else {
347
                char tmp[128];
348
                char *t = tmp;
349
 
350
                t += sprintf(t, "modem read cnt %d", cs->hw.elsa.rcvcnt);
351
                QuickHex(t, cs->hw.elsa.rcvbuf, cs->hw.elsa.rcvcnt);
352
                debugl1(cs, tmp);
353
        }
354
        cs->hw.elsa.rcvcnt = 0;
355
}
356
 
357
static inline void transmit_chars(struct IsdnCardState *cs, int *intr_done)
358
{
359
        int count;
360
 
361
        debugl1(cs, "transmit_chars: p(%x) cnt(%x)", cs->hw.elsa.transp,
362
                cs->hw.elsa.transcnt);
363
 
364
        if (cs->hw.elsa.transcnt <= 0) {
365
                cs->hw.elsa.IER &= ~UART_IER_THRI;
366
                serial_out(cs, UART_IER, cs->hw.elsa.IER);
367
                return;
368
        }
369
        count = 16;
370
        do {
371
                serial_outp(cs, UART_TX, cs->hw.elsa.transbuf[cs->hw.elsa.transp++]);
372
                if (cs->hw.elsa.transp >= MAX_MODEM_BUF)
373
                        cs->hw.elsa.transp=0;
374
                if (--cs->hw.elsa.transcnt <= 0)
375
                        break;
376
        } while (--count > 0);
377
        if ((cs->hw.elsa.transcnt < WAKEUP_CHARS) && (cs->hw.elsa.MFlag==2))
378
                modem_fill(cs->hw.elsa.bcs);
379
 
380
#ifdef SERIAL_DEBUG_INTR
381
        printk("THRE...");
382
#endif
383
        if (intr_done)
384
                *intr_done = 0;
385
        if (cs->hw.elsa.transcnt <= 0) {
386
                cs->hw.elsa.IER &= ~UART_IER_THRI;
387
                serial_outp(cs, UART_IER, cs->hw.elsa.IER);
388
        }
389
}
390
 
391
#if 0
392
static inline void check_modem_status(struct IsdnCardState *cs)
393
{
394
        int     status;
395
        struct async_struct *info = cs->hw.elsa.info;
396
        struct  async_icount *icount;
397
 
398
        status = serial_inp(info, UART_MSR);
399
 
400
        if (status & UART_MSR_ANY_DELTA) {
401
                icount = &info->state->icount;
402
                /* update input line counters */
403
                if (status & UART_MSR_TERI)
404
                        icount->rng++;
405
                if (status & UART_MSR_DDSR)
406
                        icount->dsr++;
407
                if (status & UART_MSR_DDCD) {
408
                        icount->dcd++;
409
                }
410
                if (status & UART_MSR_DCTS)
411
                        icount->cts++;
412
//              wake_up_interruptible(&info->delta_msr_wait);
413
        }
414
 
415
        if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
416
#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
417
                printk("ttys%d CD now %s...", info->line,
418
                       (status & UART_MSR_DCD) ? "on" : "off");
419
#endif          
420
                if (status & UART_MSR_DCD)
421
//                      wake_up_interruptible(&info->open_wait);
422
;
423
                else if (!((info->flags & ASYNC_CALLOUT_ACTIVE) &&
424
                           (info->flags & ASYNC_CALLOUT_NOHUP))) {
425
#ifdef SERIAL_DEBUG_OPEN
426
                        printk("doing serial hangup...");
427
#endif
428
                        if (info->tty)
429
                                tty_hangup(info->tty);
430
                }
431
        }
432
#if 0
433
        if (info->flags & ASYNC_CTS_FLOW) {
434
                if (info->tty->hw_stopped) {
435
                        if (status & UART_MSR_CTS) {
436
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
437
                                printk("CTS tx start...");
438
#endif
439
                                info->tty->hw_stopped = 0;
440
                                info->IER |= UART_IER_THRI;
441
                                serial_outp(info, UART_IER, info->IER);
442
//                              rs_sched_event(info, RS_EVENT_WRITE_WAKEUP);
443
                                return;
444
                        }
445
                } else {
446
                        if (!(status & UART_MSR_CTS)) {
447
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
448
                                printk("CTS tx stop...");
449
#endif
450
                                info->tty->hw_stopped = 1;
451
                                info->IER &= ~UART_IER_THRI;
452
                                serial_outp(info, UART_IER, info->IER);
453
                        }
454
                }
455
        }
456
#endif 0
457
}
458
#endif
459
 
460
static void rs_interrupt_elsa(int irq, struct IsdnCardState *cs)
461
{
462
        int status, iir, msr;
463
        int pass_counter = 0;
464
 
465
#ifdef SERIAL_DEBUG_INTR
466
        printk("rs_interrupt_single(%d)...", irq);
467
#endif
468
 
469
        do {
470
                status = serial_inp(cs, UART_LSR);
471
                debugl1(cs,"rs LSR %02x", status);
472
#ifdef SERIAL_DEBUG_INTR
473
                printk("status = %x...", status);
474
#endif
475
                if (status & UART_LSR_DR)
476
                        receive_chars(cs, &status);
477
                if (status & UART_LSR_THRE)
478
                        transmit_chars(cs, 0);
479
                if (pass_counter++ > RS_ISR_PASS_LIMIT) {
480
                        printk("rs_single loop break.\n");
481
                        break;
482
                }
483
                iir = serial_inp(cs, UART_IIR);
484
                debugl1(cs,"rs IIR %02x", iir);
485
                if ((iir & 0xf) == 0) {
486
                        msr = serial_inp(cs, UART_MSR);
487
                        debugl1(cs,"rs MSR %02x", msr);
488
                }
489
        } while (!(iir & UART_IIR_NO_INT));
490
#ifdef SERIAL_DEBUG_INTR
491
        printk("end.\n");
492
#endif
493
}
494
 
495
extern int open_hscxstate(struct IsdnCardState *cs, struct BCState *bcs);
496
extern void modehscx(struct BCState *bcs, int mode, int bc);
497
extern void hscx_l2l1(struct PStack *st, int pr, void *arg);
498
 
499
void
500
close_elsastate(struct BCState *bcs)
501
{
502
        struct sk_buff *skb;
503
 
504
        modehscx(bcs, 0, bcs->channel);
505
        if (test_and_clear_bit(BC_FLG_INIT, &bcs->Flag)) {
506
                if (bcs->hw.hscx.rcvbuf) {
507
                        if (bcs->mode != L1_MODE_MODEM)
508
                                kfree(bcs->hw.hscx.rcvbuf);
509
                        bcs->hw.hscx.rcvbuf = NULL;
510
                }
511
                while ((skb = skb_dequeue(&bcs->rqueue))) {
512
                        dev_kfree_skb(skb, FREE_READ);
513
                }
514
                while ((skb = skb_dequeue(&bcs->squeue))) {
515
                        dev_kfree_skb(skb, FREE_WRITE);
516
                }
517
                if (bcs->tx_skb) {
518
                        dev_kfree_skb(bcs->tx_skb, FREE_WRITE);
519
                        bcs->tx_skb = NULL;
520
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
521
                }
522
        }
523
}
524
 
525
void
526
modem_write_cmd(struct IsdnCardState *cs, u_char *buf, int len) {
527
        int count, fp;
528
        u_char *msg = buf;
529
        long flags;
530
 
531
        if (!len)
532
                return;
533
        save_flags(flags);
534
        cli();
535
        if (len > (MAX_MODEM_BUF - cs->hw.elsa.transcnt)) {
536
                restore_flags(flags);
537
                return;
538
        }
539
        fp = cs->hw.elsa.transcnt + cs->hw.elsa.transp;
540
        fp &= (MAX_MODEM_BUF -1);
541
        count = MIN(len, MAX_MODEM_BUF - fp);
542
        if (count < len) {
543
                memcpy(cs->hw.elsa.transbuf + fp, msg, count);
544
                cs->hw.elsa.transcnt += count;
545
                msg += count;
546
                count = len - count;
547
                fp = 0;
548
        }
549
        memcpy(cs->hw.elsa.transbuf + fp, msg, count);
550
        cs->hw.elsa.transcnt += count;
551
        if (cs->hw.elsa.transcnt &&
552
            !(cs->hw.elsa.IER & UART_IER_THRI)) {
553
                cs->hw.elsa.IER |= UART_IER_THRI;
554
                serial_outp(cs, UART_IER, cs->hw.elsa.IER);
555
        }
556
        restore_flags(flags);
557
}
558
 
559
void
560
modem_set_init(struct IsdnCardState *cs) {
561
        long flags;
562
        int timeout;
563
 
564
#define RCV_DELAY 20000 
565
        save_flags(flags);
566
        sti();
567
        modem_write_cmd(cs, MInit_1, strlen(MInit_1));
568
        timeout = 1000;
569
        while(timeout-- && cs->hw.elsa.transcnt)
570
                udelay(1000);
571
        debugl1(cs, "msi tout=%d", timeout);
572
        udelay(RCV_DELAY);
573
        modem_write_cmd(cs, MInit_2, strlen(MInit_2));
574
        timeout = 1000;
575
        while(timeout-- && cs->hw.elsa.transcnt)
576
                udelay(1000);
577
        debugl1(cs, "msi tout=%d", timeout);
578
        udelay(RCV_DELAY);
579
        modem_write_cmd(cs, MInit_3, strlen(MInit_3));
580
        timeout = 1000;
581
        while(timeout-- && cs->hw.elsa.transcnt)
582
                udelay(1000);
583
        debugl1(cs, "msi tout=%d", timeout);
584
        udelay(RCV_DELAY);
585
        modem_write_cmd(cs, MInit_4, strlen(MInit_4));
586
        timeout = 1000;
587
        while(timeout-- && cs->hw.elsa.transcnt)
588
                udelay(1000);
589
        debugl1(cs, "msi tout=%d", timeout);
590
        udelay(RCV_DELAY );
591
        modem_write_cmd(cs, MInit_5, strlen(MInit_5));
592
        timeout = 1000;
593
        while(timeout-- && cs->hw.elsa.transcnt)
594
                udelay(1000);
595
        debugl1(cs, "msi tout=%d", timeout);
596
        udelay(RCV_DELAY);
597
        modem_write_cmd(cs, MInit_6, strlen(MInit_6));
598
        timeout = 1000;
599
        while(timeout-- && cs->hw.elsa.transcnt)
600
                udelay(1000);
601
        debugl1(cs, "msi tout=%d", timeout);
602
        udelay(RCV_DELAY);
603
        modem_write_cmd(cs, MInit_7, strlen(MInit_7));
604
        timeout = 1000;
605
        while(timeout-- && cs->hw.elsa.transcnt)
606
                udelay(1000);
607
        debugl1(cs, "msi tout=%d", timeout);
608
        udelay(RCV_DELAY);
609
        restore_flags(flags);
610
}
611
 
612
void
613
modem_set_dial(struct IsdnCardState *cs, int outgoing) {
614
        long flags;
615
        int timeout;
616
#define RCV_DELAY 20000 
617
 
618
        save_flags(flags);
619
        sti();
620
        modem_write_cmd(cs, MInit_speed28800, strlen(MInit_speed28800));
621
        timeout = 1000;
622
        while(timeout-- && cs->hw.elsa.transcnt)
623
                udelay(1000);
624
        debugl1(cs, "msi tout=%d", timeout);
625
        udelay(RCV_DELAY);
626
        if (outgoing)
627
                modem_write_cmd(cs, MInit_dialout, strlen(MInit_dialout));
628
        else
629
                modem_write_cmd(cs, MInit_dialin, strlen(MInit_dialin));
630
        timeout = 1000;
631
        while(timeout-- && cs->hw.elsa.transcnt)
632
                udelay(1000);
633
        debugl1(cs, "msi tout=%d", timeout);
634
        udelay(RCV_DELAY);
635
        restore_flags(flags);
636
}
637
 
638
void
639
modem_l2l1(struct PStack *st, int pr, void *arg)
640
{
641
        struct sk_buff *skb = arg;
642
        long flags;
643
 
644
        if (pr == (PH_DATA | REQUEST)) {
645
                save_flags(flags);
646
                cli();
647
                if (st->l1.bcs->tx_skb) {
648
                        skb_queue_tail(&st->l1.bcs->squeue, skb);
649
                        restore_flags(flags);
650
                } else {
651
                        st->l1.bcs->tx_skb = skb;
652
                        test_and_set_bit(BC_FLG_BUSY, &st->l1.bcs->Flag);
653
                        st->l1.bcs->hw.hscx.count = 0;
654
                        restore_flags(flags);
655
                        write_modem(st->l1.bcs);
656
                }
657
        } else if (pr == (PH_ACTIVATE | REQUEST)) {
658
                test_and_set_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
659
                st->l1.l1l2(st, PH_ACTIVATE | CONFIRM, NULL);
660
                set_arcofi(st->l1.bcs->cs, st->l1.bc);
661
                mstartup(st->l1.bcs->cs);
662
                modem_set_dial(st->l1.bcs->cs, test_bit(FLG_ORIG, &st->l2.flag));
663
                st->l1.bcs->cs->hw.elsa.MFlag=2;
664
        } else if (pr == (PH_DEACTIVATE | REQUEST)) {
665
                test_and_clear_bit(BC_FLG_ACTIV, &st->l1.bcs->Flag);
666
                send_arcofi(st->l1.bcs->cs, ARCOFI_XOP_0, st->l1.bc, 0);
667
                st->l1.bcs->cs->hw.elsa.MFlag=1;
668
        } else {
669
                printk(KERN_WARNING"ElsaSer: unknown pr %x\n", pr);
670
        }
671
}
672
 
673
int
674
setstack_elsa(struct PStack *st, struct BCState *bcs)
675
{
676
 
677
        bcs->channel = st->l1.bc;
678
        switch (st->l1.mode) {
679
                case L1_MODE_HDLC:
680
                case L1_MODE_TRANS:
681
                        if (open_hscxstate(st->l1.hardware, bcs))
682
                                return (-1);
683
                        st->l2.l2l1 = hscx_l2l1;
684
                        break;
685
                case L1_MODE_MODEM:
686
                        bcs->mode = L1_MODE_MODEM;
687
                        if (!test_and_set_bit(BC_FLG_INIT, &bcs->Flag)) {
688
                                bcs->hw.hscx.rcvbuf = bcs->cs->hw.elsa.rcvbuf;
689
                                skb_queue_head_init(&bcs->rqueue);
690
                                skb_queue_head_init(&bcs->squeue);
691
                        }
692
                        bcs->tx_skb = NULL;
693
                        test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
694
                        bcs->event = 0;
695
                        bcs->hw.hscx.rcvidx = 0;
696
                        bcs->tx_cnt = 0;
697
                        bcs->cs->hw.elsa.bcs = bcs;
698
                        st->l2.l2l1 = modem_l2l1;
699
                        break;
700
        }
701
        st->l1.bcs = bcs;
702
        setstack_manager(st);
703
        bcs->st = st;
704
        setstack_l1_B(st);
705
        return (0);
706
}
707
 
708
void
709
init_modem(struct IsdnCardState *cs) {
710
 
711
        cs->bcs[0].BC_SetStack = setstack_elsa;
712
        cs->bcs[1].BC_SetStack = setstack_elsa;
713
        cs->bcs[0].BC_Close = close_elsastate;
714
        cs->bcs[1].BC_Close = close_elsastate;
715
        if (!(cs->hw.elsa.rcvbuf = kmalloc(MAX_MODEM_BUF,
716
                GFP_ATOMIC))) {
717
                printk(KERN_WARNING
718
                        "Elsa: No modem mem hw.elsa.rcvbuf\n");
719
                return;
720
        }
721
        if (!(cs->hw.elsa.transbuf = kmalloc(MAX_MODEM_BUF,
722
                GFP_ATOMIC))) {
723
                printk(KERN_WARNING
724
                        "Elsa: No modem mem hw.elsa.transbuf\n");
725
                kfree(cs->hw.elsa.rcvbuf);
726
                cs->hw.elsa.rcvbuf = NULL;
727
                return;
728
        }
729
        if (mstartup(cs)) {
730
                printk(KERN_WARNING "Elsa: problem startup modem\n");
731
        }
732
        modem_set_init(cs);
733
}
734
 
735
void
736
release_modem(struct IsdnCardState *cs) {
737
 
738
        cs->hw.elsa.MFlag = 0;
739
        if (cs->hw.elsa.transbuf) {
740
                if (cs->hw.elsa.rcvbuf) {
741
                        mshutdown(cs);
742
                        kfree(cs->hw.elsa.rcvbuf);
743
                        cs->hw.elsa.rcvbuf = NULL;
744
                }
745
                kfree(cs->hw.elsa.transbuf);
746
                cs->hw.elsa.transbuf = NULL;
747
        }
748
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.