Example #1
0
static int uart_close(FAR struct file *filep)
{
    FAR struct inode *inode = filep->f_inode;
    FAR uart_dev_t   *dev   = inode->i_private;
    irqstate_t        flags;

    uart_takesem(&dev->closesem);
    if (dev->open_count > 1)
    {
        dev->open_count--;
        uart_givesem(&dev->closesem);
        return OK;
    }

    /* There are no more references to the port */

    dev->open_count = 0;

    /* Stop accepting input */

    uart_disablerxint(dev);

    /* Now we wait for the transmit buffer to clear */

    while (dev->xmit.head != dev->xmit.tail)
    {
#ifndef CONFIG_DISABLE_SIGNALS
        usleep(HALF_SECOND_USEC);
#else
        up_mdelay(HALF_SECOND_MSEC);
#endif
    }

    /* And wait for the TX fifo to drain */

    while (!uart_txempty(dev))
    {
#ifndef CONFIG_DISABLE_SIGNALS
        usleep(HALF_SECOND_USEC);
#else
        up_mdelay(HALF_SECOND_MSEC);
#endif
    }

    /* Free the IRQ and disable the UART */

    flags = irqsave();       /* Disable interrupts */
    uart_detach(dev);        /* Detach interrupts */
    if (!dev->isconsole)     /* Check for the serial console UART */
    {
        uart_shutdown(dev);  /* Disable the UART */
    }
    irqrestore(flags);

    uart_givesem(&dev->closesem);
    return OK;
}
Example #2
0
static int uart_close(FAR struct file *filep)
{
  FAR struct inode *inode = filep->f_inode;
  FAR uart_dev_t   *dev   = inode->i_private;
  irqstate_t        flags;

  /* Get exclusive access to the close semaphore (to synchronize open/close operations.
   * NOTE: that we do not let this wait be interrupted by a signal.  Technically, we
   * should, but almost no one every checks the return value from close() so we avoid
   * a potential memory leak by ignoring signals in this case.
   */

  (void)uart_takesem(&dev->closesem, false);
  if (dev->open_count > 1)
    {
      dev->open_count--;
      uart_givesem(&dev->closesem);
      return OK;
    }

  /* There are no more references to the port */

  dev->open_count = 0;

  /* Stop accepting input */

  uart_disablerxint(dev);

  /* Now we wait for the transmit buffer to clear */

  while (dev->xmit.head != dev->xmit.tail)
    {
#ifndef CONFIG_DISABLE_SIGNALS
      usleep(HALF_SECOND_USEC);
#else
      up_mdelay(HALF_SECOND_MSEC);
#endif
    }

  /* And wait for the TX fifo to drain */

  while (!uart_txempty(dev))
    {
#ifndef CONFIG_DISABLE_SIGNALS
      usleep(HALF_SECOND_USEC);
#else
      up_mdelay(HALF_SECOND_MSEC);
#endif
    }

  /* Free the IRQ and disable the UART */

  flags = irqsave();       /* Disable interrupts */
  uart_detach(dev);        /* Detach interrupts */
  if (!dev->isconsole)     /* Check for the serial console UART */
    {
      uart_shutdown(dev);  /* Disable the UART */
    }
  irqrestore(flags);

  uart_givesem(&dev->closesem);
  return OK;
 }
Example #3
0
static int uart_close(FAR struct file *filep)
{
  FAR struct inode *inode = filep->f_inode;
  FAR uart_dev_t   *dev   = inode->i_private;
  irqstate_t        flags;

  /* Get exclusive access to the close semaphore (to synchronize open/close operations.
   * NOTE: that we do not let this wait be interrupted by a signal.  Technically, we
   * should, but almost no one every checks the return value from close() so we avoid
   * a potential memory leak by ignoring signals in this case.
   */

  (void)uart_takesem(&dev->closesem, false);
  if (dev->open_count > 1)
    {
      dev->open_count--;
      uart_givesem(&dev->closesem);
      return OK;
    }

  /* There are no more references to the port */

  dev->open_count = 0;

  /* Stop accepting input */

  uart_disablerxint(dev);

  /* Now we wait for the transmit buffer to clear */

  while (dev->xmit.head != dev->xmit.tail)
    {
#ifndef CONFIG_DISABLE_SIGNALS
      usleep(HALF_SECOND_USEC);
#else
      up_mdelay(HALF_SECOND_MSEC);
#endif
    }

  /* And wait for the TX fifo to drain */

  while (!uart_txempty(dev))
    {
#ifndef CONFIG_DISABLE_SIGNALS
      usleep(HALF_SECOND_USEC);
#else
      up_mdelay(HALF_SECOND_MSEC);
#endif
    }

  /* Free the IRQ and disable the UART */

  flags = irqsave();       /* Disable interrupts */
  uart_detach(dev);        /* Detach interrupts */
  if (!dev->isconsole)     /* Check for the serial console UART */
    {
      uart_shutdown(dev);  /* Disable the UART */
    }

  irqrestore(flags);

  /* We need to re-initialize the semaphores if this is the last close
   * of the device, as the close might be caused by pthread_cancel() of
   * a thread currently blocking on any of them.
   *
   * REVISIT:  This logic *only* works in the case where the cancelled
   * thread had the only reference to the serial driver.  If there other
   * references, then the this logic will not be executed and the
   * semaphore count will still be incorrect.
   */

  sem_reinit(&dev->xmitsem,  0, 0);
  sem_reinit(&dev->recvsem,  0, 0);
  sem_reinit(&dev->xmit.sem, 0, 1);
  sem_reinit(&dev->recv.sem, 0, 1);
#ifndef CONFIG_DISABLE_POLL
  sem_reinit(&dev->pollsem,  0, 1);
#endif

  uart_givesem(&dev->closesem);
  return OK;
}