source: rtems/c/src/libnetworking/pppd/modem_example/modem.c @ a8c33268

4.104.114.84.95
Last change on this file since a8c33268 was edeed26, checked in by Joel Sherrill <joel.sherrill@…>, on 06/12/00 at 15:39:38

Merge lossage. Apparently the DOS/UNIX CRLF issue got lost.

  • Property mode set to 100644
File size: 31.7 KB
Line 
1/*
2 *  Modem device driver for RTEMS
3 *  Author: Tomasz Domin (dot@comarch.pl)
4 *  Copyright (C) 1998 by ComArch SA
5 *  Driver will use termios for character output and ppp specific out procecedures for network protocols
6 */
7
8#include <bsp.h>
9#include <rtems.h>
10#include <rtems/libio.h>
11#include <sys/ttycom.h>
12#include <unistd.h>
13#include <sys/errno.h>
14#include <rtems/rtems/event.h>
15#include <rtems/rtems/tasks.h>
16#include <mpc823.h>
17#include <sys/param.h>
18#include <sys/systm.h>
19#include <sys/proc.h>
20#include <sys/mbuf.h>
21#include <sys/socket.h>
22#include <sys/ioctl.h>
23#include <sys/file.h>
24
25#include <sys/kernel.h>
26#include <sys/conf.h>
27#include <net/if.h>
28#include <net/ppp_defs.h>
29#include <sys/fcntl.h>
30#include "ppp.h"
31#include <net/if_pppvar.h>
32#include <net/if_ppp.h>
33/* RTEMS specific */
34rtems_id modem_task_id;
35#include "16550.h"
36#include <mpc823.h>
37#define ESCAPE_P(c)     (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
38#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
39
40#define M_DATASTART(m)  \
41        (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
42            (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
43
44#define M_DATASIZE(m)   \
45        (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
46            (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
47
48
49struct rtems_termios_tty *modem_tty;
50/*
51 * RTEMS event used by interrupt handler to signal daemons.
52 * This must *not* be the same event used by the KA9Q task synchronization.
53 */
54#define INTERRUPT_EVENT       RTEMS_EVENT_1
55#define START_TRANSMIT_EVENT    RTEMS_EVENT_2
56#define PPP_LOWAT       100     /* Process more output when < LOWAT on queue */
57#define PPP_HIWAT       400     /* Don't start a new packet if HIWAT on que */
58
59/*
60 * RTEMS event used to start transmit daemon.
61 * This must not be the same as INTERRUPT_EVENT.
62 */
63
64/*static struct modem_tty *tp=&modem_tp;*/
65static rtems_id modem_rx_task,modem_tx_task;
66
67
68
69/* internal FIFO buffers for input and output characters */
70#define MODEM_BUFFER_LENGTH 4096
71#define RTS_STOP_SIZE MODEM_BUFFER_LENGTH-128
72#define RTS_START_SIZE 16
73
74int xmt_start,xmt_len;
75int rcv_start,rcv_len;
76
77static unsigned char xmt_buf[MODEM_BUFFER_LENGTH];
78static unsigned char rcv_buf[MODEM_BUFFER_LENGTH];
79
80static volatile char _tx_stop = 0 ,_modem_cd=0;
81struct ModemData
82{
83        int t_line;
84        struct ppp_softc *t_sc;
85        rtems_id pppsem;
86        int offhook;
87} ModemData;
88
89int pppstart(struct tty *ignore);
90static u_short fcstab[256] = {
91        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
92        0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
93        0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
94        0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
95        0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
96        0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
97        0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
98        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
99        0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
100        0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
101        0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
102        0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
103        0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
104        0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
105        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
106        0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
107        0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
108        0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
109        0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
110        0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
111        0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
112        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
113        0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
114        0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
115        0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
116        0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
117        0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
118        0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
119        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
120        0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
121        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
122        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
123};
124
125
126static u_short
127pppfcs(fcs, cp, len)
128    register u_short fcs;
129    register u_char *cp;
130    register int len;
131{
132    while (len--)
133        fcs = PPP_FCS(fcs, *cp++);
134    return (fcs);
135}
136
137static void
138ppp_timeout(x)
139    void *x;
140{
141    struct ppp_softc *sc = ModemData.t_sc;
142    struct tty *tp = (struct tty *) sc->sc_devp;
143    int s;
144
145    sc->sc_flags &= ~SC_TIMEOUT;
146    pppstart(tp);
147}
148
149static void
150pppasyncrelinq(sc)
151    struct ppp_softc *sc;
152{
153    int s;
154
155    if (sc->sc_outm) {
156        m_freem(sc->sc_outm);
157        sc->sc_outm = NULL;
158    }
159    if (sc->sc_m) {
160        m_freem(sc->sc_m);
161        sc->sc_m = NULL;
162    }
163    if (sc->sc_flags & SC_TIMEOUT) {
164        untimeout(ppp_timeout, (void *) sc);
165        sc->sc_flags &= ~SC_TIMEOUT;
166    }
167}
168
169/* Put data in input queue */
170int
171pppstart(struct tty *ignore)
172{
173    register struct ppp_softc *sc = ModemData.t_sc;
174
175    /*
176     * If there is stuff in the output queue, send it now.
177     * We are being called in lieu of ttstart and must do what it would.
178     */
179        rtems_event_send(modem_tx_task,START_TRANSMIT_EVENT);
180        sc->sc_if.if_flags  |= IFF_OACTIVE;
181       
182    /*
183     * If the transmit queue has drained and the tty has not hung up
184     * or been disconnected from the ppp unit, then tell if_ppp.c that
185     * we need more output.
186     */
187/*    if (CCOUNT(&tp->t_outq) < PPP_LOWAT
188        && !((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)
189        && sc != NULL && tp == (struct tty *) sc->sc_devp) {
190        ppp_restart(sc);
191    }
192*/
193    return 0;
194}
195int putc(unsigned char c)
196{       
197        int level;
198       
199        if (xmt_len<MODEM_BUFFER_LENGTH-1)
200        {
201                _CPU_ISR_Disable(level);
202                xmt_buf[(xmt_start+xmt_len)%MODEM_BUFFER_LENGTH]=c;
203                xmt_len++;
204                _CPU_ISR_Enable(level);
205                return 0;
206        }
207        return 1;
208}
209
210void  unputc(void)
211{       
212        int level;
213       
214        if (xmt_len==0)
215                return;
216        _CPU_ISR_Disable(level);
217                xmt_len--;
218        _CPU_ISR_Enable(level);
219}
220
221static void
222pppasyncstart(sc)
223    register struct ppp_softc *sc;
224{
225    /* Call pppstart to start output again if necessary. */
226    pppstart(sc->sc_devp);
227
228    /*
229     * This timeout is needed for operation on a pseudo-tty,
230     * because the pty code doesn't call pppstart after it has
231     * drained the t_outq.
232     */
233/*    if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
234        timeout(ppp_timeout, (void *) sc, 1);
235        sc->sc_flags |= SC_TIMEOUT;
236    }
237*/
238
239}
240
241
242void modem_sendpacket()
243{
244  struct mbuf *l = NULL;
245  rtems_unsigned16 status;
246  int curr;
247  register struct mbuf *m;
248  register int len;
249  register u_char *start, *stop, *cp;
250  int n, ndone, done, idle;
251  struct mbuf *m2;
252  int s;
253   register struct ppp_softc *sc=ModemData.t_sc;
254 
255
256   while (xmt_len < PPP_HIWAT) {
257        /*
258         * See if we have an existing packet partly sent.
259         * If not, get a new packet and start sending it.
260         */
261        m = sc->sc_outm;
262        if (m == NULL) {
263            /*
264             * Get another packet to be sent.
265             
266             */
267            m = ppp_dequeue(sc);
268            if (m == NULL)
269            {
270                        break;
271                 }
272
273            /*
274             * The extra PPP_FLAG will start up a new packet, and thus
275             * will flush any accumulated garbage.  We do this whenever
276             * the line may have been idle for some time.
277             */
278            if (xmt_len == 0) {
279                ++sc->sc_stats.ppp_obytes;
280                         putc(PPP_FLAG);
281            }
282
283            /* Calculate the FCS for the first mbuf's worth. */
284            sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
285            microtime(&sc->sc_if.if_lastchange);
286        }
287
288        for (;;) {
289            start = mtod(m, u_char *);
290            len = m->m_len;
291            stop = start + len;
292            while (len > 0) {
293                /*
294                 * Find out how many bytes in the string we can
295                 * handle without doing something special.
296                 */
297                for (cp = start; cp < stop; cp++)
298                    if (ESCAPE_P(*cp))
299                                break;
300                n = cp - start;
301                if (n) {
302                        register int i;
303                    /* NetBSD (0.9 or later), 4.3-Reno or similar. */
304                         for(i=0;i<n;i++)
305                                if (putc(start[i]))
306                                        break;
307                    ndone = i;
308                    len -= ndone;
309                    start += ndone;
310                    sc->sc_stats.ppp_obytes += ndone;
311
312                    if (ndone < n)
313                        break;  /* packet doesn't fit */
314                }
315                /*
316                 * If there are characters left in the mbuf,
317                 * the first one must be special.
318                 * Put it out in a different form.
319                 */
320                if (len) {
321                    if (putc(PPP_ESCAPE))
322                        break;
323                    if (putc(*start ^ PPP_TRANS)) {
324                         unputc();
325                        break;
326                    }
327                    sc->sc_stats.ppp_obytes += 2;
328                    start++;
329                    len--;
330                }
331            }
332
333            /*
334             * If we didn't empty this mbuf, remember where we're up to.
335             * If we emptied the last mbuf, try to add the FCS and closing
336             * flag, and if we can't, leave sc_outm pointing to m, but with
337             * m->m_len == 0, to remind us to output the FCS and flag later.
338             */
339            done = len == 0;
340            if (done && m->m_next == NULL) {
341                u_char *p, *q;
342                int c;
343                u_char endseq[8];
344
345                /*
346                 * We may have to escape the bytes in the FCS.
347                 */
348                p = endseq;
349                c = ~sc->sc_outfcs & 0xFF;
350                if (ESCAPE_P(c)) {
351                    *p++ = PPP_ESCAPE;
352                    *p++ = c ^ PPP_TRANS;
353                } else
354                    *p++ = c;
355                c = (~sc->sc_outfcs >> 8) & 0xFF;
356                if (ESCAPE_P(c)) {
357                    *p++ = PPP_ESCAPE;
358                    *p++ = c ^ PPP_TRANS;
359                } else
360                    *p++ = c;
361                *p++ = PPP_FLAG;
362
363                /*
364                 * Try to output the FCS and flag.  If the bytes
365                 * don't all fit, back out.
366                 */
367                for (q = endseq; q < p; ++q)
368                    if (putc(*q)) {
369                        done = 0;
370                        for (; q > endseq; --q)
371                            unputc();
372                        break;
373                    }
374                if (done)
375                    sc->sc_stats.ppp_obytes += q - endseq;
376            }
377
378            if (!done) {
379                /* remember where we got to */
380                m->m_data = start;
381                m->m_len = len;
382                break;
383            }
384
385            /* Finished with this mbuf; free it and move on. */
386            MFREE(m, m2);
387            m = m2;
388            if (m == NULL) {
389                /* Finished a packet */
390                break;
391            }
392            sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
393        }
394
395        /*
396         * If m == NULL, we have finished a packet.
397         * If m != NULL, we've either done as much work this time
398         * as we need to, or else we've filled up the output queue.
399         */
400        sc->sc_outm = m;
401        if (m)
402            break;
403    }
404
405}
406
407static void
408pppasyncctlp(sc)
409    struct ppp_softc *sc;
410{
411        rtems_semaphore_release(ModemData.pppsem);
412}
413
414
415static unsigned paritytab[8] = {
416    0x96696996, 0x69969669, 0x69969669, 0x96696996,
417    0x69969669, 0x96696996, 0x96696996, 0x69969669
418};
419#define MAX_DUMP_BYTES  128
420
421static void
422pppdumpb(b, l)
423    u_char *b;
424    int l;
425{
426    char buf[3*MAX_DUMP_BYTES+4];
427    char *bp = buf;
428    static char digits[] = "0123456789abcdef";
429
430    while (l--) {
431        if (bp >= buf + sizeof(buf) - 3) {
432            *bp++ = '>';
433            break;
434        }
435        *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
436        *bp++ = digits[*b++ & 0xf];
437        *bp++ = ' ';
438    }
439
440    *bp = 0;
441
442}
443
444static void
445ppplogchar(sc, c)
446    struct ppp_softc *sc;
447    int c;
448{
449    if (c >= 0)
450        sc->sc_rawin[sc->sc_rawin_count++] = c;
451    if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
452        || (c < 0 && sc->sc_rawin_count > 0)) {
453/*      printf("ppp%d input: ", sc->sc_if.if_unit);
454*/      pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
455        sc->sc_rawin_count = 0;
456    }
457}
458static void
459pppgetm(sc)
460    register struct ppp_softc *sc;
461{
462    struct mbuf *m, **mp;
463    int len;
464    mp = &sc->sc_m;
465    for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
466        if ((m = *mp) == NULL) {
467            MGETHDR(m, M_DONTWAIT, MT_DATA);
468            if (m == NULL)
469                break;
470            *mp = m;
471            MCLGET(m, M_DONTWAIT);
472        }
473        len -= M_DATASIZE(m);
474        mp = &m->m_next;
475    }
476}
477
478
479int
480pppinput(c)
481    int c;
482 
483{
484    register struct ppp_softc *sc=ModemData.t_sc;
485    struct mbuf *m;
486    int ilen, s;
487
488    if (sc == NULL )
489        return 0;
490
491    ++sc->sc_stats.ppp_ibytes;
492/*
493    if (c & TTY_FE) {*/
494        /* framing error or overrun on this char - abort packet */
495/*      if (sc->sc_flags & SC_DEBUG)
496            printf("ppp%d: bad char %x\n", sc->sc_if.if_unit, c);
497        goto flush;
498    }*/
499
500    c &= 0xff;
501
502    /*
503     * Handle software flow control of output.
504     */
505/*    if (tp->t_iflag & IXON) {
506        if (c == tp->t_cc[VSTOP] ) {
507            if ((tp->t_state & TS_TTSTOP) == 0) {
508                tp->t_state |= TS_TTSTOP;
509                sccppp_stop_transmission(tp);
510            }
511            return 0;
512        }
513        if (c == tp->t_cc[VSTART]  ) {
514            tp->t_state &= ~TS_TTSTOP;
515                sccppp_start_transmission(tp);
516            return 0;
517        }
518    }
519*/
520
521    if (c & 0x80)
522        sc->sc_flags |= SC_RCV_B7_1;
523    else
524        sc->sc_flags |= SC_RCV_B7_0;
525    if (paritytab[c >> 5] & (1 << (c & 0x1F)))
526        sc->sc_flags |= SC_RCV_ODDP;
527    else
528        sc->sc_flags |= SC_RCV_EVNP;
529
530
531/*    if (sc->sc_flags & SC_LOG_RAWIN)*/
532//      ppplogchar(sc, c);
533
534    if (c == PPP_FLAG) {
535        ilen = sc->sc_ilen;
536        sc->sc_ilen = 0;
537
538        if (sc->sc_rawin_count > 0)
539            ppplogchar(sc, -1);
540
541        /*
542         * If SC_ESCAPED is set, then we've seen the packet
543         * abort sequence
544         */
545        if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
546            || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
547            sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
548            if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
549                if (sc->sc_flags & SC_DEBUG)
550                    printf("ppp%d: bad fcs %x, pkt len %d\n",
551                           sc->sc_if.if_unit, sc->sc_fcs, ilen);
552                sc->sc_if.if_ierrors++;
553                sc->sc_stats.ppp_ierrors++;
554            } else
555                sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
556            return 0;
557        }
558
559        if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
560            if (ilen) {
561                if (sc->sc_flags & SC_DEBUG)
562/*                  printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
563*/              sc->sc_if.if_ierrors++;
564                sc->sc_stats.ppp_ierrors++;
565                sc->sc_flags |= SC_PKTLOST;
566                splx(s);
567            }
568            return 0;
569        }
570
571        /*
572         * Remove FCS trailer.  Somewhat painful...
573         */
574        ilen -= 2;
575        if (--sc->sc_mc->m_len == 0) {
576            for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
577                ;
578            sc->sc_mc = m;
579        }
580        sc->sc_mc->m_len--;
581
582        /* excise this mbuf chain */
583        m = sc->sc_m;
584        sc->sc_m = sc->sc_mc->m_next;
585        sc->sc_mc->m_next = NULL;
586        ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
587        if (sc->sc_flags & SC_PKTLOST) {
588            sc->sc_flags &= ~SC_PKTLOST;
589        }
590
591        pppgetm(sc);
592        return 0;
593    }
594
595    if (sc->sc_flags & SC_FLUSH) {
596        if (sc->sc_flags & SC_LOG_FLUSH)
597            ppplogchar(sc, c);
598        return 0;
599    }
600
601    if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
602        return 0;
603
604    if (sc->sc_flags & SC_ESCAPED) {
605        sc->sc_flags &= ~SC_ESCAPED;
606        c ^= PPP_TRANS;
607    } else if (c == PPP_ESCAPE) {
608        sc->sc_flags |= SC_ESCAPED;
609        return 0;
610    }
611
612    /*
613     * Initialize buffer on first octet received.
614     * First octet could be address or protocol (when compressing
615     * address/control).
616     * Second octet is control.
617     * Third octet is first or second (when compressing protocol)
618     * octet of protocol.
619     * Fourth octet is second octet of protocol.
620     */
621    if (sc->sc_ilen == 0) {
622        /* reset the first input mbuf */
623        if (sc->sc_m == NULL) {
624            pppgetm(sc);
625            if (sc->sc_m == NULL) {
626                if (sc->sc_flags & SC_DEBUG)
627/*                  printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
628*/              goto flush;
629            }
630        }
631        m = sc->sc_m;
632        m->m_len = 0;
633        m->m_data = M_DATASTART(sc->sc_m);
634        sc->sc_mc = m;
635        sc->sc_mp = mtod(m, char *);
636        sc->sc_fcs = PPP_INITFCS;
637        if (c != PPP_ALLSTATIONS) {
638            if (sc->sc_flags & SC_REJ_COMP_AC) {
639                if (sc->sc_flags & SC_DEBUG)
640/*                  printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
641                           sc->sc_if.if_unit, c);*/
642                goto flush;
643            }
644            *sc->sc_mp++ = PPP_ALLSTATIONS;
645            *sc->sc_mp++ = PPP_UI;
646            sc->sc_ilen += 2;
647            m->m_len += 2;
648        }
649    }
650    if (sc->sc_ilen == 1 && c != PPP_UI) {
651        if (sc->sc_flags & SC_DEBUG)
652/*          printf("ppp%d: missing UI (0x3), got 0x%x\n",
653                   sc->sc_if.if_unit, c);
654*/      goto flush;
655    }
656    if (sc->sc_ilen == 2 && (c & 1) == 1) {
657        /* a compressed protocol */
658        *sc->sc_mp++ = 0;
659        sc->sc_ilen++;
660        sc->sc_mc->m_len++;
661    }
662    if (sc->sc_ilen == 3 && (c & 1) == 0) {
663        if (sc->sc_flags & SC_DEBUG)
664/*          printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
665                   (sc->sc_mp[-1] << 8) + c);
666*/      goto flush;
667    }
668
669    /* packet beyond configured mru? */
670    if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
671        if (sc->sc_flags & SC_DEBUG)
672/*          printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
673*/      goto flush;
674    }
675
676    /* is this mbuf full? */
677    m = sc->sc_mc;
678    if (M_TRAILINGSPACE(m) <= 0) {
679        if (m->m_next == NULL) {
680            pppgetm(sc);
681            if (m->m_next == NULL) {
682                if (sc->sc_flags & SC_DEBUG)
683/*                  printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
684*/              goto flush;
685            }
686        }
687        sc->sc_mc = m = m->m_next;
688        m->m_len = 0;
689        m->m_data = M_DATASTART(m);
690        sc->sc_mp = mtod(m, char *);
691    }
692
693    ++m->m_len;
694    *sc->sc_mp++ = c;
695    sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
696    return 0;
697
698 flush:
699    if (!(sc->sc_flags & SC_FLUSH)) {
700        sc->sc_if.if_ierrors++;
701        sc->sc_stats.ppp_ierrors++;
702        sc->sc_flags |= SC_FLUSH;
703        if (sc->sc_flags & SC_LOG_FLUSH)
704            ppplogchar(sc, c);
705    }
706    return 0;
707}
708
709
710void
711modem_txDaemon (void *arg)
712{
713        rtems_event_set events;
714        register int level,i,maxonce;
715        while (1)
716        {
717                if (xmt_len==0) //jezeli nic nie ma to czekajmy na event
718                        rtems_event_receive(START_TRANSMIT_EVENT|INTERRUPT_EVENT,RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT,&events);
719                /* wait for transmit buffer to become empty */
720
721                while(_tx_stop) //tu czekamy na start transmisji
722                        rtems_event_receive(INTERRUPT_EVENT|START_TRANSMIT_EVENT,RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT,&events);
723
724                _CPU_ISR_Disable(level);
725                if (*LSR & THRE) //jezeli nie ma transmisji to wyslijmy pierwsze bajty, jezeli jest, same pojda
726                {
727                        maxonce=(xmt_len>14)?14:xmt_len;
728                        if (maxonce>0)
729                        {
730                                for (i=0;i<maxonce;i++)
731                                {
732                                        *THR=xmt_buf[xmt_start];
733                                        xmt_start=(xmt_start+1)%MODEM_BUFFER_LENGTH;
734                                }
735                                xmt_len-=maxonce;
736                        }
737                }
738                _CPU_ISR_Enable(level);
739                if ((ModemData.t_line==PPPDISC))
740                {
741                        rtems_bsdnet_semaphore_obtain();
742                        modem_sendpacket();
743                        rtems_bsdnet_semaphore_release();
744                }
745
746        }
747}
748
749static void modem_rxDaemon (void *arg)
750{
751        rtems_event_set events;
752        unsigned char bufor_posr[MODEM_BUFFER_LENGTH];
753        register unsigned char ch;
754        int level,i,j;
755        while(1)
756        {
757                /* wait for interrupt */               
758                i=0;
759                _CPU_ISR_Disable(level);
760                while(rcv_len>0)
761                {
762                                bufor_posr[i++]=rcv_buf[rcv_start];
763                                rcv_start=(rcv_start+1)%MODEM_BUFFER_LENGTH;
764                                rcv_len--;
765                }
766                _CPU_ISR_Enable(level);
767                if (ModemData.t_line==PPPDISC)
768                {
769                        rtems_bsdnet_semaphore_obtain();
770                        for(j=0;j<i;j++)
771                                pppinput(bufor_posr[j]);                       
772                        rtems_bsdnet_semaphore_release();
773                }
774                else
775                        if (i!=0)rtems_termios_enqueue_raw_characters(modem_tty,bufor_posr,i);
776                rtems_event_receive(INTERRUPT_EVENT,RTEMS_EVENT_ANY | RTEMS_WAIT, RTEMS_NO_TIMEOUT,&events);
777        }
778}
779#define CLK_FREQ 1843200
780void set_modem_speed(int speed)
781{
782  *LCR = (char)(DLAB);
783  *DLL = (char)((int)(CLK_FREQ/speed/16.0+0.5) & 0xFF);
784  *DLM = (char)(((int)(CLK_FREQ/speed/16.0+0.5) & 0xFF00) >> 8);
785  *LCR = (char)(WL_8 ); /* 8 bitowe slowo */
786}
787
788
789static void
790modem_init (int speed)  /* port is the SMC number (i.e. 1 or 2) */
791{
792        set_modem_speed(speed);
793  /* Line control setup */
794
795  *LCR = (char)(WL_8 ); /* 8 bitowe slowo */
796  /* bylo NSB - bylo 2 jest 1*/
797
798  /* Interrupt setup */
799  *IER = (char) 0x0f;           /* enable transmit, receive, modem stat int */
800 
801  /* FIFO setup */
802  *FCR = (char)(FIFO_E | 0xc0);
803
804  /* Modem control setup */
805  *MCR = (char) RTS|DTR|OUT2;
806
807  /* init tx_stop with CTS */
808  _tx_stop = ( (*MDSR & CTS) ? 0 : 1);
809}
810
811void set_modem_dtr(int how)
812{
813        unsigned char znak;
814        znak=*MCR;
815        *MCR=(how)?(znak|DTR):(znak&(~DTR));   
816}       
817void modem_status()
818{
819        unsigned char status;
820        status=*MDSR;
821
822/*      printf("Modem Status %x ",status);
823*/      if (status&CTS)
824        {
825                _tx_stop=0;
826                rtems_event_send (modem_tx_task, START_TRANSMIT_EVENT|INTERRUPT_EVENT);
827        }
828        else
829        {
830                _tx_stop=1;
831        }
832        if (status&DCD)
833                _modem_cd=1;
834        else
835                _modem_cd=0;   
836}
837
838static rtems_isr
839modemInterruptHandler (rtems_vector_number v)
840{
841  register char a,i,ch;
842  register int maxonce;
843        static errcount = 0;
844  for(;;)
845  {
846          a=*IIR & (NIP | IID_MASK); /* read interrupt id register */
847          switch (a) {
848                  case 0x04: case 0x0c:
849                  /*
850                   * Buffer received?
851                   */
852                while( (*LSR & DR) != 0)
853                {
854                        ch=*RBR;
855                        rcv_buf[(rcv_start+rcv_len)%MODEM_BUFFER_LENGTH]=ch;
856                        rcv_len++;
857                }
858            rtems_event_send (modem_rx_task, INTERRUPT_EVENT);
859            break;
860          case 0x02:
861                  /*
862                   * Buffer transmitted ?
863                   */
864                if (*LSR & THRE) //jezeli nie ma transmisji (a nie powinno byc) to wyslijmy  bajty
865                {
866                        maxonce=(xmt_len>14)?14:xmt_len;
867                        if (maxonce>0)
868                        {
869                                for (i=0;i<maxonce;i++)
870                                {
871                                        *THR=xmt_buf[xmt_start];
872                                        xmt_start=(xmt_start+1)%MODEM_BUFFER_LENGTH;
873                                }
874                                xmt_len-=maxonce;
875                        }
876                }
877                rtems_event_send (modem_tx_task, INTERRUPT_EVENT);
878           break;
879          case 0x00:
880                        modem_status();
881                        break;
882          case 0x01:
883                        return;
884          case 0x06:
885                ch=*RBR;
886                errcount++;
887                break;
888                                       
889                default:
890                    break;
891          }
892  }
893}
894
895
896void modem_flush(int mode)
897{
898        if (mode&FWRITE)
899        {
900        }
901        if (mode&FREAD)
902        {
903   }
904
905}
906
907
908
909int modemWriteTermios(int minor, const char *buf, int len)
910{
911        int level;
912        int i,maxonce;
913        if (len<=0)
914                return 0;
915               
916        if (ModemData.t_line!=PPPDISC)
917        {
918        _CPU_ISR_Disable(level);
919        for(i=0;i<len;i++)
920        {
921                if (xmt_len>=MODEM_BUFFER_LENGTH)
922                        break;
923                xmt_buf[(xmt_start+xmt_len)%MODEM_BUFFER_LENGTH]=buf[i];
924                xmt_len++;
925        }
926                _CPU_ISR_Enable(level);
927        }
928        rtems_event_send(modem_tx_task,START_TRANSMIT_EVENT);
929        return i;
930}
931
932
933/*
934 * Initialize and register the device
935 */
936rtems_device_driver modem_initialize(
937  rtems_device_major_number  major,
938  rtems_device_minor_number  minor,
939  void                      *arg
940)
941{
942        rtems_status_code status;
943        rtems_isr_entry old_handler;
944        rtems_status_code sc;
945   rtems_termios_initialize ();
946        sc = rtems_semaphore_create (
947                        rtems_build_name ('M', 'D', 'M', 'P'),
948                        0,
949                        RTEMS_COUNTING_SEMAPHORE,
950                        RTEMS_NO_PRIORITY_CEILING,
951                        &ModemData.pppsem); 
952        if (sc != RTEMS_SUCCESSFUL)
953                rtems_fatal_error_occurred (sc);
954        modem_init(9600);
955
956        sc = rtems_interrupt_catch (modemInterruptHandler,
957                                                PPC_IRQ_IRQ4,
958                                                &old_handler);
959
960        /*
961         * Register the devices
962         */
963        modem_tx_task=0;
964        modem_rx_task=0;
965        status = rtems_io_register_name ("/dev/modem", major, 0);
966        if (status != RTEMS_SUCCESSFUL)
967                rtems_fatal_error_occurred (status);
968        return RTEMS_SUCCESSFUL;
969}
970
971rtems_device_driver modem_first_open(
972  rtems_device_major_number major,
973  rtems_device_minor_number minor,
974  void                    * arg
975)
976{
977        modem_tty=(struct rtems_termios_tty *)(((rtems_libio_open_close_args_t *)arg)->iop->data1);
978        return RTEMS_SUCCESSFUL;
979}
980rtems_device_driver modem_last_close(
981  rtems_device_major_number major,
982  rtems_device_minor_number minor,
983  void                    * arg
984)
985{
986  m823.siu.simask &=(~M823_SIMASK_IRM4); /* block the interrupts */
987        return RTEMS_SUCCESSFUL;
988}
989
990static int
991modemSetAttr(int minor, const struct termios *t)
992{
993  int baud;
994
995  switch (t->c_cflag & CBAUD)
996    {
997    case B50:   
998      baud = 50;
999      break;
1000    case B75:   
1001      baud = 75;       
1002      break;
1003    case B110: 
1004      baud = 110;       
1005      break;
1006    case B134: 
1007      baud = 134;       
1008      break;
1009    case B150: 
1010      baud = 150;       
1011      break;
1012    case B200:
1013      baud = 200;       
1014      break;
1015    case B300: 
1016      baud = 300;
1017      break;
1018    case B600: 
1019      baud = 600;       
1020      break;
1021    case B1200:
1022      baud = 1200;
1023      break;
1024    case B1800:
1025      baud = 1800;     
1026      break;
1027    case B2400:
1028      baud = 2400;
1029      break;
1030    case B4800:
1031      baud = 4800;
1032      break;
1033    case B9600:
1034      baud = 9600;
1035      break;
1036    case B19200:
1037      baud = 19200;
1038      break;
1039    case B38400:
1040      baud = 38400;
1041      break;
1042    case B57600:       
1043      baud = 57600;
1044      break;
1045    case B115200:
1046      baud = 115200;
1047      break;
1048    default:
1049      baud = 0;
1050      rtems_fatal_error_occurred (RTEMS_INTERNAL_ERROR);
1051      return 0;
1052    }
1053        set_modem_speed(baud);
1054        return RTEMS_SUCCESSFUL;
1055}
1056
1057
1058/*
1059 * Open the device
1060 */
1061
1062       
1063
1064rtems_device_driver modem_open(
1065  rtems_device_major_number major,
1066  rtems_device_minor_number minor,
1067  void                    * arg
1068)
1069{
1070    int error, s;
1071  rtems_status_code              status;
1072   register struct ppp_softc *sc;
1073  static rtems_termios_callbacks cb =
1074  {
1075    modem_first_open,                 /* firstOpen */
1076    modem_last_close,       /* lastClose */
1077    NULL,                     /* poll read  */
1078    modemWriteTermios, /* write */
1079    modemSetAttr,                     /* setAttributes */
1080    NULL,                     /* stopRemoteTx */
1081    NULL,                     /* startRemoteTx */
1082    0                         /* outputUsesInterrupts */
1083  };     
1084
1085        if (ModemData.t_line == PPPDISC)
1086        {
1087                sc = ModemData.t_sc;
1088                if (sc != NULL && sc->sc_devp == (void *) &ModemData)
1089                {
1090                        return (0);
1091                }
1092        }
1093
1094        if ((ModemData.t_sc= sc = pppalloc(1)) == NULL)
1095                return 2;
1096
1097    if (sc->sc_relinq)
1098        (*sc->sc_relinq)(sc);   /* get previous owner to relinquish the unit */
1099
1100    sc->sc_ilen = 0;
1101    sc->sc_m = NULL;
1102    bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
1103    sc->sc_asyncmap[0] = 0xffffffff;
1104    sc->sc_asyncmap[3] = 0x60000000;
1105    sc->sc_rasyncmap = 0;
1106    sc->sc_devp = &ModemData;
1107    sc->sc_start = pppasyncstart;
1108    sc->sc_ctlp = pppasyncctlp;
1109    sc->sc_relinq = pppasyncrelinq;
1110    sc->sc_outm = NULL;
1111    pppgetm(sc);
1112    sc->sc_if.if_flags |= IFF_RUNNING;
1113    sc->sc_if.if_baudrate = 38400;
1114
1115        status = rtems_termios_open (major, minor, arg, &cb);
1116  if(status != RTEMS_SUCCESSFUL)
1117    {
1118/*      printf("Error openning console device\n");
1119*/      return status;
1120    }
1121
1122
1123/* init rx and tx task for device */
1124        xmt_start=xmt_len=0;
1125        rcv_start=rcv_len=0;
1126
1127        if (modem_rx_task==0 && modem_tx_task==0)
1128        {
1129        rtems_status_code sc;
1130        sc = rtems_task_create (rtems_build_name ('M', 'D', 't', 'x'),
1131                        101,
1132                        16*1024,
1133                        RTEMS_PREEMPT|RTEMS_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
1134                        RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
1135                        &modem_tx_task);
1136        if (sc != RTEMS_SUCCESSFUL) {
1137                         
1138        }
1139
1140        sc = rtems_task_start (modem_tx_task, (void *)modem_txDaemon, 0);
1141        if (sc != RTEMS_SUCCESSFUL) {
1142                 
1143        }
1144
1145        sc = rtems_task_create (rtems_build_name ('M', 'D', 'r', 'x'),
1146                        101,
1147                        16*1024,
1148                        RTEMS_PREEMPT|RTEMS_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
1149                        RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
1150                        &modem_rx_task);
1151        if (sc != RTEMS_SUCCESSFUL) {
1152                         
1153        }
1154
1155        sc = rtems_task_start (modem_rx_task, (void *)modem_rxDaemon, 0);
1156        if (sc != RTEMS_SUCCESSFUL) {
1157                         
1158        }
1159
1160        }
1161  /* Enable modem interrupts */
1162  m823.siu.simask |= M823_SIMASK_IRM4;
1163
1164  return RTEMS_SUCCESSFUL;
1165}
1166 
1167/*
1168 * Close the device
1169 */
1170rtems_device_driver modem_close(
1171  rtems_device_major_number major,
1172  rtems_device_minor_number minor,
1173  void                    * arg
1174)
1175{
1176    register struct ppp_softc *sc;
1177    modem_flush( FREAD|FWRITE);
1178
1179    ModemData.t_line = 0;
1180    sc = ModemData.t_sc;
1181    if (sc != NULL) {
1182                ModemData.t_sc = NULL;
1183                if (&ModemData == (struct tty *) sc->sc_devp) {
1184                rtems_bsdnet_semaphore_obtain();
1185            pppasyncrelinq(sc);
1186            pppdealloc(sc);
1187                rtems_bsdnet_semaphore_release();
1188        }
1189    }
1190    return RTEMS_SUCCESSFUL;
1191}
1192
1193/* for now works only as serial device */
1194
1195
1196rtems_device_driver modem_read(
1197  rtems_device_major_number major,
1198  rtems_device_minor_number minor,
1199  void                    * arg
1200)
1201{
1202  rtems_libio_rw_args_t *rw_args=  (rtems_libio_rw_args_t *)arg;
1203  char *buffer;
1204  int count=0,maximum;
1205  rtems_status_code              sc;
1206
1207  buffer = rw_args->buffer;
1208  maximum = rw_args->count;
1209  if (ModemData.t_line==PPPDISC)
1210  {
1211
1212    struct mbuf *m, *m0;
1213    register int s;
1214    int error = 0;
1215    rtems_status_code status;
1216    rtems_interval    ticks;
1217        register struct ppp_softc *sc = (struct ppp_softc *)ModemData.t_sc;
1218         ticks=1000000/rtems_bsdnet_microseconds_per_tick;
1219
1220    if (sc == NULL)
1221        return 0;
1222    /*
1223     * Loop waiting for input, checking that nothing disasterous
1224     * happens in the meantime.
1225     */
1226    for (;;) {
1227                if (sc->sc_inq.ifq_head != NULL)
1228                {
1229/*            printf("Read : Dane sa w buforze\n");
1230*/                      break;
1231                }
1232/*      printf("Read : Czekam na dane\n");
1233*/
1234                status=rtems_semaphore_obtain(ModemData.pppsem,RTEMS_WAIT,ticks);
1235                if (_modem_cd==0)
1236                {
1237                        rw_args->bytes_moved =0;
1238                        return RTEMS_SUCCESSFUL;
1239                }
1240               
1241                if (status==RTEMS_TIMEOUT)
1242                        return status;
1243        }
1244        rtems_bsdnet_semaphore_obtain();
1245    IF_DEQUEUE(&sc->sc_inq, m0);
1246        rtems_bsdnet_semaphore_release();
1247
1248  for (m = m0; m && (count+m->m_next->m_len<maximum); m = m->m_next) /* check if packet will fit in buffer */
1249  {
1250                memcpy(buffer,mtod(m, u_char *),m->m_len);
1251                count+=m->m_len;
1252                buffer+=m->m_len;
1253  }
1254   m_freem(m0);
1255  rw_args->bytes_moved = count;
1256
1257  }
1258        else
1259                  sc = rtems_termios_read (arg);
1260
1261  count=rw_args->bytes_moved;
1262  return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
1263}
1264
1265/*
1266 * Write to the device
1267 */
1268rtems_device_driver modem_write(
1269  rtems_device_major_number major,
1270  rtems_device_minor_number minor,
1271  void                    * arg
1272)
1273{
1274  int count,len;
1275  rtems_libio_rw_args_t *rw_args;
1276  char *out_buffer;
1277  int n,maximum;
1278  rw_args = (rtems_libio_rw_args_t *) arg;
1279
1280  out_buffer = rw_args->buffer;
1281  maximum = rw_args->count;
1282
1283        if (ModemData.t_line==PPPDISC)
1284        {
1285                register struct ppp_softc *sc = (struct ppp_softc *)ModemData.t_sc;
1286           struct sockaddr dst;
1287                struct mbuf *m, *m0, **mp;     
1288                rtems_bsdnet_semaphore_obtain();
1289                for (mp = &m0; maximum; mp = &m->m_next)
1290                {
1291                        MGET(m, M_WAIT, MT_DATA);
1292                        if ((*mp = m) == NULL)
1293                        {
1294                                rtems_bsdnet_semaphore_release();
1295                            m_freem(m0);
1296                            return (ENOBUFS);
1297                        }
1298                        m->m_len = 0;
1299                        if (maximum>= MCLBYTES / 2)
1300                    MCLGET(m, M_DONTWAIT);
1301                        len = M_TRAILINGSPACE(m);
1302                        if (len > maximum)
1303                        {
1304                                memcpy(mtod(m, u_char *),out_buffer,maximum);
1305                                m->m_len=maximum;
1306                                maximum=0;
1307                        }
1308                        else
1309                        {
1310                                memcpy(mtod(m, u_char *),out_buffer,len);
1311                                maximum-=len;
1312                                m->m_len=len;
1313                                out_buffer+=len;
1314                        }
1315                }
1316               
1317            dst.sa_family = AF_UNSPEC;
1318            bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
1319            m0->m_data += PPP_HDRLEN;
1320            m0->m_len -= PPP_HDRLEN;
1321
1322/*              printf("Wysylam %d bajtow \n",m0->m_len);
1323*/              n=pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
1324                rtems_bsdnet_semaphore_release();
1325                return n;
1326        }
1327        else
1328           return rtems_termios_write (arg);
1329}
1330
1331
1332
1333/*
1334 * Handle ioctl request.
1335 * Should set hardware line speed, bits/char, etc.
1336 */
1337rtems_device_driver modem_control(
1338  rtems_device_major_number major,
1339  rtems_device_minor_number minor,
1340  void                    * arg
1341)
1342{
1343        rtems_libio_ioctl_args_t *args=(rtems_libio_ioctl_args_t *)arg;
1344        struct ppp_softc *sc=ModemData.t_sc;
1345    int cmd;
1346    caddr_t data;
1347    int error=RTEMS_SUCCESSFUL;
1348
1349        data=args->buffer;
1350        cmd=args->command;
1351
1352    switch (cmd) {
1353        case RTEMS_IO_GET_ATTRIBUTES:
1354        case RTEMS_IO_SET_ATTRIBUTES:
1355        case RTEMS_IO_TCDRAIN:
1356                return rtems_termios_ioctl (arg);
1357        break; 
1358   case PPPIOCSASYNCMAP:
1359                sc->sc_asyncmap[0] = *(u_int *)data;
1360                break;
1361
1362   case PPPIOCGASYNCMAP:
1363                *(u_int *)data = sc->sc_asyncmap[0];
1364        break;
1365       
1366        case PPPIOCSRASYNCMAP:
1367                sc->sc_rasyncmap = *(u_int *)data;
1368        break;
1369
1370        case TIOCSETD:
1371                ModemData.t_line=*(int*)data;
1372        break;
1373        case TIOCGETD: 
1374                *(int*)data=ModemData.t_line;
1375        break;         
1376        case TIOCMBIS:
1377                if ((*(int*)data)&TIOCM_DTR)
1378                        set_modem_dtr(1);
1379                break;
1380        case TIOCMBIC:
1381                if ((*(int*)data)&TIOCM_DTR)
1382                        set_modem_dtr(0);
1383                break; 
1384   case PPPIOCGRASYNCMAP:
1385                *(u_int *)data = sc->sc_rasyncmap;
1386        break;
1387
1388        case PPPIOCSXASYNCMAP:
1389                bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
1390                sc->sc_asyncmap[1] = 0;             /* mustn't escape 0x20 - 0x3f */
1391                sc->sc_asyncmap[2] &= ~0x40000000;  /* mustn't escape 0x5e */
1392                sc->sc_asyncmap[3] |= 0x60000000;   /* must escape 0x7d, 0x7e */
1393                break;
1394
1395   case PPPIOCGXASYNCMAP:
1396                bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
1397                break;
1398
1399        default:
1400        rtems_bsdnet_semaphore_obtain();
1401        error = pppioctl(sc, cmd, data, 0, NULL);
1402                if (error == 0 && cmd == PPPIOCSMRU)
1403                        pppgetm(sc);
1404        rtems_bsdnet_semaphore_release();
1405       
1406        }
1407        return error;
1408
1409}
1410
1411
1412
1413void
1414wait_input(timo)
1415    struct timeval *timo;
1416{
1417    int n;
1418    rtems_event_set events;
1419    rtems_interval    ticks;
1420  rtems_status_code              err;
1421        int czekaj=1;
1422    register struct ppp_softc *sc = (struct ppp_softc *)ModemData.t_sc;
1423    ticks = 1+(timo->tv_sec*1000000+timo->tv_usec)/rtems_bsdnet_microseconds_per_tick;
1424        while (czekaj)
1425        {
1426                       
1427                if (sc->sc_inq.ifq_head != NULL)
1428                        break;
1429/*      printf("Wait : Czekam na dane przez %d ticks\n",ticks);
1430*/              err=rtems_semaphore_obtain(ModemData.pppsem,RTEMS_WAIT,ticks);
1431                if (err==RTEMS_TIMEOUT)
1432                {
1433/*                      printf("TIMEOUT :Brak danych\n");
1434*/                      break;
1435                }
1436        }
1437
1438}
Note: See TracBrowser for help on using the repository browser.