/* ARGSUSED */
int
pppopen(struct rtems_termios_tty *tty)
{
    int                        i;
    register struct ppp_softc *sc;
    struct mbuf *m = (struct mbuf *)0;

    if (tty->t_line == PPPDISC) {
	sc = (struct ppp_softc *)tty->t_sc;
	if (sc != NULL && sc->sc_devp == (void *)tty) {
	    return (0);
	}
    }

    if ((sc = pppalloc(1)) == NULL) {
	return ENXIO;
    }

    if (sc->sc_relinq)
	(*sc->sc_relinq)(sc);	/* get previous owner to relinquish the unit */

    sc->sc_ilen = 0;
    sc->sc_m = NULL;
    bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
    sc->sc_asyncmap[0] = 0xffffffff;
    sc->sc_asyncmap[3] = 0x60000000;
    sc->sc_rasyncmap = 0;
    sc->sc_devp = tty;
    sc->sc_start = pppasyncstart;
    sc->sc_ctlp = pppasyncctlp;
    sc->sc_relinq = pppasyncrelinq;
    sc->sc_outm = NULL;
    sc->sc_outmc = NULL;
    
    /* preallocate mbufs for free queue */
    rtems_bsdnet_semaphore_obtain();
    for (i=0; i<NUM_MBUFQ; i++) {
      pppallocmbuf(sc, &m);
      if ( i == 0 ) {
        /* use first mbuf for rx iterrupt handling */
        sc->sc_m = m;
      }
      else {
        /* enqueue mbuf for later use */
        IF_ENQUEUE(&sc->sc_freeq, m);
      }
      m = (struct mbuf *)0;
    }
    rtems_bsdnet_semaphore_release();

    /* initialize values */
    sc->sc_if.if_flags |= IFF_RUNNING;
    sc->sc_if.if_baudrate =
	rtems_termios_baud_to_number(tty->termios.c_cflag & CBAUD);

    tty->t_sc = (void *)sc;

    return ( RTEMS_SUCCESSFUL );
}
Beispiel #2
0
static rtems_task ppp_rxdaemon(rtems_task_argument arg)
{
  rtems_event_set             events;
  rtems_interrupt_level       level;
  struct ppp_softc           *sc = (struct ppp_softc *)arg;
  struct mbuf                *mp = (struct mbuf      *)0;
  struct mbuf                *m;

  /* enter processing loop */
  while ( 1 ) {
    /* wait for event */
    rtems_event_receive(RX_PACKET|RX_MBUF|RX_EMPTY,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
    if ( events & RX_EMPTY ) {
      printf("RX: QUEUE is EMPTY\n");
      events &= ~RX_EMPTY;
    }

    if ( events ) {
      /* get the network semaphore */
      rtems_bsdnet_semaphore_obtain();

      /* check to see if new packet was received */
      if ( events & RX_PACKET ) {
        /* get received packet mbuf chain */
        rtems_interrupt_disable(level);
        IF_DEQUEUE(&sc->sc_rawq, m);
        rtems_interrupt_enable(level);

        /* ensure packet was retrieved */
        if ( m != (struct mbuf *)0 ) {
          /* process the received packet */
          mp = ppp_inproc(sc, m);
        }
      }

      /* allocate a new mbuf to replace one */
      if ( mp == NULL ) {
        pppallocmbuf(sc, &mp);
      }

      /* place mbuf on freeq */
      rtems_interrupt_disable(level);
      IF_ENQUEUE(&sc->sc_freeq, mp);
      rtems_interrupt_enable(level);
      mp = (struct mbuf *)0;

      /* release the network semaphore */
      rtems_bsdnet_semaphore_release();

      /* check to see if queue is empty */
      if ( sc->sc_rawq.ifq_head ) {
        /* queue is not empty - post another event */
        rtems_event_send(sc->sc_rxtask, RX_PACKET);
      }
    }
  }
}