Ticket #2153: 0001-termios-Pass-Termios-context-to-device-callbacks.patch

File 0001-termios-Pass-Termios-context-to-device-callbacks.patch, 11.0 KB (added by Sebastian Huber, on Nov 29, 2013 at 7:18:09 AM)

Potential fix.

  • cpukit/libcsupport/include/rtems/libio.h

    From 399ab454d4aa9e9b71cfbbecef95255f96d2a0f4 Mon Sep 17 00:00:00 2001
    From: Sebastian Huber <sebastian.huber@embedded-brains.de>
    Date: Fri, 29 Nov 2013 09:14:40 +0100
    Subject: [PATCH] termios: Pass Termios context to device callbacks
    
    ---
     cpukit/libcsupport/include/rtems/libio.h |   17 ++++----
     cpukit/libcsupport/src/termios.c         |   60 ++++++++++++------------------
     2 files changed, 33 insertions(+), 44 deletions(-)
    
    diff --git a/cpukit/libcsupport/include/rtems/libio.h b/cpukit/libcsupport/include/rtems/libio.h
    index c1b7b73..d922a2f 100644
    a b extern const rtems_filesystem_mount_configuration 
    17811781/**@{**/
    17821782
    17831783typedef struct rtems_termios_callbacks {
    1784   int    (*firstOpen)(int major, int minor, void *arg);
    1785   int    (*lastClose)(int major, int minor, void *arg);
    1786   int    (*pollRead)(int minor);
    1787   ssize_t (*write)(int minor, const char *buf, size_t len);
    1788   int    (*setAttributes)(int minor, const struct termios *t);
    1789   int    (*stopRemoteTx)(int minor);
    1790   int    (*startRemoteTx)(int minor);
     1784  int    (*firstOpen)(struct rtems_termios_tty *tty, void *arg);
     1785  void   (*lastClose)(struct rtems_termios_tty *tty, void *arg);
     1786  int    (*pollRead)(struct rtems_termios_tty *tty);
     1787  void   (*write)(struct rtems_termios_tty *tty, const char *buf, size_t len);
     1788  int    (*setAttributes)(struct rtems_termios_tty *tty, const struct termios *t);
     1789  void   (*stopRemoteTx)(struct rtems_termios_tty *tty);
     1790  void   (*startRemoteTx)(struct rtems_termios_tty *tty);
    17911791  int    outputUsesInterrupts;
    17921792} rtems_termios_callbacks;
    17931793
    rtems_status_code rtems_termios_bufsize ( 
    18071807rtems_status_code rtems_termios_open (
    18081808  rtems_device_major_number      major,
    18091809  rtems_device_minor_number      minor,
    1810   void                          *arg,
     1810  rtems_libio_open_close_args_t *args,
     1811  struct rtems_termios_tty      *tty,
    18111812  const rtems_termios_callbacks *callbacks
    18121813);
    18131814
  • cpukit/libcsupport/src/termios.c

    diff --git a/cpukit/libcsupport/src/termios.c b/cpukit/libcsupport/src/termios.c
    index bc79665..976a7e7 100644
    a b rtems_status_code 
    109109rtems_termios_open (
    110110  rtems_device_major_number      major,
    111111  rtems_device_minor_number      minor,
    112   void                          *arg,
     112  rtems_libio_open_close_args_t *args,
     113  struct rtems_termios_tty      *tty,
    113114  const rtems_termios_callbacks *callbacks
    114115)
    115116{
    116117  rtems_status_code sc;
    117   rtems_libio_open_close_args_t *args = arg;
    118   struct rtems_termios_tty *tty;
    119118
    120119  /*
    121120   * See if the device has already been opened
    rtems_termios_open ( 
    130129      break;
    131130  }
    132131
    133   if (tty == NULL) {
     132  if (tty->forw == NULL) {
    134133    static char c = 'a';
    135134
    136135    /*
    137      * Create a new device
    138      */
    139     tty = calloc (1, sizeof (struct rtems_termios_tty));
    140     if (tty == NULL) {
    141       rtems_semaphore_release (rtems_termios_ttyMutex);
    142       return RTEMS_NO_MEMORY;
    143     }
    144     /*
    145136     * allocate raw input buffer
    146137     */
    147138    tty->rawInBuf.Size = RAW_INPUT_BUFFER_SIZE;
    148139    tty->rawInBuf.theBuf = malloc (tty->rawInBuf.Size);
    149140    if (tty->rawInBuf.theBuf == NULL) {
    150             free(tty);
    151141      rtems_semaphore_release (rtems_termios_ttyMutex);
    152142      return RTEMS_NO_MEMORY;
    153143    }
    rtems_termios_open ( 
    158148    tty->rawOutBuf.theBuf = malloc (tty->rawOutBuf.Size);
    159149    if (tty->rawOutBuf.theBuf == NULL) {
    160150            free((void *)(tty->rawInBuf.theBuf));
    161             free(tty);
    162151      rtems_semaphore_release (rtems_termios_ttyMutex);
    163152      return RTEMS_NO_MEMORY;
    164153    }
    rtems_termios_open ( 
    169158    if (tty->cbuf == NULL) {
    170159            free((void *)(tty->rawOutBuf.theBuf));
    171160            free((void *)(tty->rawInBuf.theBuf));
    172             free(tty);
    173161      rtems_semaphore_release (rtems_termios_ttyMutex);
    174162      return RTEMS_NO_MEMORY;
    175163    }
    rtems_termios_open ( 
    311299  args->iop->data1 = tty;
    312300  if (!tty->refcount++) {
    313301    if (tty->device.firstOpen)
    314       (*tty->device.firstOpen)(major, minor, arg);
     302      (*tty->device.firstOpen)(tty, arg);
    315303
    316304    /*
    317305     * start I/O tasks, if needed
    rtems_termios_close (void *arg) 
    420408        rtems_fatal_error_occurred (sc);
    421409    }
    422410    if (tty->device.lastClose)
    423        (*tty->device.lastClose)(tty->major, tty->minor, arg);
     411       (*tty->device.lastClose)(tty, arg);
    424412    if (tty->forw == NULL) {
    425413      rtems_termios_ttyTail = tty->back;
    426414      if ( rtems_termios_ttyTail != NULL ) {
    termios_set_flowctrl(struct rtems_termios_tty *tty) 
    489477      if (tty->rawOutBufState != rob_idle) {
    490478        /* if chars available, call write function... */
    491479        (*tty->device.write)(
    492           tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
     480          tty, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
    493481      }
    494482      /* reenable interrupts */
    495483      rtems_termios_interrupt_lock_release (tty, level);
    termios_set_flowctrl(struct rtems_termios_tty *tty) 
    510498
    511499    /* restart remote Tx, if it was stopped */
    512500    if ((tty->flow_ctrl & FL_IRTSOFF) && (tty->device.startRemoteTx != NULL)) {
    513       tty->device.startRemoteTx(tty->minor);
     501      tty->device.startRemoteTx(tty);
    514502    }
    515503    tty->flow_ctrl &= ~(FL_IRTSOFF);
    516504  }
    rtems_termios_ioctl (void *arg) 
    662650      }
    663651    }
    664652    if (tty->device.setAttributes)
    665       (*tty->device.setAttributes)(tty->minor, &tty->termios);
     653      (*tty->device.setAttributes)(tty, &tty->termios);
    666654    break;
    667655
    668656  case RTEMS_IO_TCDRAIN:
    rtems_termios_puts ( 
    747735  rtems_status_code sc;
    748736
    749737  if (tty->device.outputUsesInterrupts == TERMIOS_POLLED) {
    750     (*tty->device.write)(tty->minor, buf, len);
     738    (*tty->device.write)(tty, buf, len);
    751739    return;
    752740  }
    753741  newHead = tty->rawOutBuf.Head;
    rtems_termios_puts ( 
    781769      /* check, whether XOFF has been received */
    782770      if (!(tty->flow_ctrl & FL_ORCVXOF)) {
    783771        (*tty->device.write)(
    784           tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
     772          tty, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail],1);
    785773      } else {
    786774        /* remember that output has been stopped due to flow ctrl*/
    787775        tty->flow_ctrl |= FL_OSTOP;
    fillBufferPoll (struct rtems_termios_tty *tty) 
    10671055
    10681056  if (tty->termios.c_lflag & ICANON) {
    10691057    for (;;) {
    1070       n = (*tty->device.pollRead)(tty->minor);
     1058      n = (*tty->device.pollRead)(tty);
    10711059      if (n < 0) {
    10721060        rtems_task_wake_after (1);
    10731061      } else {
    fillBufferPoll (struct rtems_termios_tty *tty) 
    10801068
    10811069    then = rtems_clock_get_ticks_since_boot();
    10821070    for (;;) {
    1083       n = (*tty->device.pollRead)(tty->minor);
     1071      n = (*tty->device.pollRead)(tty);
    10841072      if (n < 0) {
    10851073        if (tty->termios.c_cc[VMIN]) {
    10861074          if (tty->termios.c_cc[VTIME] && tty->ccount) {
    fillBufferQueue (struct rtems_termios_tty *tty) 
    11431131          || (tty->flow_ctrl & FL_OSTOP))) {
    11441132          /* XON should be sent now... */
    11451133          (*tty->device.write)(
    1146             tty->minor, (void *)&(tty->termios.c_cc[VSTART]), 1);
     1134            tty, (void *)&(tty->termios.c_cc[VSTART]), 1);
    11471135        } else if (tty->flow_ctrl & FL_MDRTS) {
    11481136          tty->flow_ctrl &= ~FL_IRTSOFF;
    11491137          /* activate RTS line */
    11501138          if (tty->device.startRemoteTx != NULL) {
    1151             tty->device.startRemoteTx(tty->minor);
     1139            tty->device.startRemoteTx(tty);
    11521140          }
    11531141        }
    11541142      }
    rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len) 
    13011289        if (tty->rawOutBufState != rob_idle) {
    13021290          /* if chars available, call write function... */
    13031291          (*tty->device.write)(
    1304             tty->minor, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
     1292            tty, &tty->rawOutBuf.theBuf[tty->rawOutBuf.Tail], 1);
    13051293        }
    13061294        /* reenable interrupts */
    13071295        rtems_termios_interrupt_lock_release (tty, level);
    rtems_termios_enqueue_raw_characters (void *ttyp, const char *buf, int len) 
    13221310            /* if tx is stopped due to XOFF or out of data */
    13231311            /*    call write function here                 */
    13241312            tty->flow_ctrl |= FL_ISNTXOF;
    1325             (*tty->device.write)(tty->minor,
     1313            (*tty->device.write)(tty,
    13261314                (void *)&(tty->termios.c_cc[VSTOP]), 1);
    13271315          }
    13281316        } else if ((tty->flow_ctrl & (FL_MDRTS | FL_IRTSOFF)) == (FL_MDRTS) ) {
    13291317          tty->flow_ctrl |= FL_IRTSOFF;
    13301318          /* deactivate RTS line */
    13311319          if (tty->device.stopRemoteTx != NULL) {
    1332             tty->device.stopRemoteTx(tty->minor);
     1320            tty->device.stopRemoteTx(tty);
    13331321          }
    13341322        }
    13351323      }
    rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) 
    13781366  if ((tty->flow_ctrl & (FL_MDXOF | FL_IREQXOF | FL_ISNTXOF))
    13791367      == (FL_MDXOF | FL_IREQXOF)) {
    13801368    /* XOFF should be sent now... */
    1381     (*tty->device.write)(tty->minor, (void *)&(tty->termios.c_cc[VSTOP]), 1);
     1369    (*tty->device.write)(tty, (void *)&(tty->termios.c_cc[VSTOP]), 1);
    13821370
    13831371    tty->t_dqlen--;
    13841372    tty->flow_ctrl |= FL_ISNTXOF;
    rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) 
    13941382     * buffer, although the corresponding data is not yet out!
    13951383     * Therefore the dequeue "length" should be reduced by 1
    13961384     */
    1397     (*tty->device.write)(tty->minor, (void *)&(tty->termios.c_cc[VSTART]), 1);
     1385    (*tty->device.write)(tty, (void *)&(tty->termios.c_cc[VSTART]), 1);
    13981386
    13991387    tty->t_dqlen--;
    14001388    tty->flow_ctrl &= ~FL_ISNTXOF;
    rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) 
    14111399      wakeUpWriterTask = true;
    14121400    }
    14131401
    1414     (*tty->device.write) (tty->minor, NULL, 0);
     1402    (*tty->device.write) (tty, NULL, 0);
    14151403    nToSend = 0;
    14161404  } else {
    14171405    len = tty->t_dqlen;
    rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) 
    14311419       * Buffer has become empty
    14321420       */
    14331421      tty->rawOutBufState = rob_idle;
    1434       (*tty->device.write) (tty->minor, NULL, 0);
     1422      (*tty->device.write) (tty, NULL, 0);
    14351423      nToSend = 0;
    14361424
    14371425      /*
    rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) 
    14481436      /* set flag, that output has been stopped */
    14491437      tty->flow_ctrl |= FL_OSTOP;
    14501438      tty->rawOutBufState = rob_busy; /*apm*/
    1451       (*tty->device.write) (tty->minor, NULL, 0);
     1439      (*tty->device.write) (tty, NULL, 0);
    14521440      nToSend = 0;
    14531441    } else {
    14541442      /*
    rtems_termios_refill_transmitter (struct rtems_termios_tty *tty) 
    14661454      }
    14671455      tty->rawOutBufState = rob_busy; /*apm*/
    14681456      (*tty->device.write)(
    1469         tty->minor, &tty->rawOutBuf.theBuf[newTail], nToSend);
     1457        tty, &tty->rawOutBuf.theBuf[newTail], nToSend);
    14701458    }
    14711459    tty->rawOutBuf.Tail = newTail; /*apm*/
    14721460  }
    static rtems_task rtems_termios_rxdaemon(rtems_task_argument argument) 
    15881576    /*
    15891577     * do something
    15901578     */
    1591     c = tty->device.pollRead(tty->minor);
     1579    c = tty->device.pollRead(tty);
    15921580    if (c != EOF) {
    15931581      /*
    15941582       * pollRead did call enqueue on its own