Ejemplo n.º 1
0
Archivo: tty.c Proyecto: DIKU-EDU/kudos
/**
 * TTY's interrupt handler. Functinality depends on status of TTY's
 * status port. On WIRQ status writes internal buffer from
 * tty_real_device_t data structure to data port. On RIRQ
 * status reads data from data port to the internal buffer.
 * Implements read from the gbd interface.
 *
 * @param device Pointer to the TTY device.
 */
void tty_interrupt_handle(device_t *device) {
  volatile tty_io_area_t *iobase = (tty_io_area_t *)device->io_address;
  volatile tty_real_device_t *tty_rd
    = (tty_real_device_t *)device->real_device;

  if(TTY_STATUS_WIRQ(iobase->status)) {
    spinlock_acquire(tty_rd->slock);

    iobase->command = TTY_COMMAND_WIRQD;
    iobase->command = TTY_COMMAND_WIRQ;
    while(!TTY_STATUS_WBUSY(iobase->status) && tty_rd->write_count > 0) {
      iobase->command = TTY_COMMAND_WIRQ;
      iobase->data = tty_rd->write_buf[tty_rd->write_head];
      tty_rd->write_head = (tty_rd->write_head + 1) % TTY_BUF_SIZE;
      tty_rd->write_count--;
    }
    iobase->command = TTY_COMMAND_WIRQE;

    if (tty_rd->write_count == 0)
      sleepq_wake_all((void *)tty_rd->write_buf);

    spinlock_release(tty_rd->slock);
  }

  if(TTY_STATUS_RIRQ(iobase->status)) {
    spinlock_acquire(tty_rd->slock);

    iobase->command = TTY_COMMAND_RIRQ;

    if (TTY_STATUS_ERROR(iobase->status))
      KERNEL_PANIC("Could not issue RIRQ to TTY.");

    while (TTY_STATUS_RAVAIL(iobase->status)) {
      char data = iobase->data;
      int index;

      if (tty_rd->read_count > TTY_BUF_SIZE)
        continue;

      index = (tty_rd->read_head + tty_rd->read_count) % TTY_BUF_SIZE;

      tty_rd->read_buf[index] = data;
      tty_rd->read_count++;
    }

    spinlock_release(tty_rd->slock);
    sleepq_wake_all((void *)tty_rd->read_buf);

  }
}
Ejemplo n.º 2
0
/**
 * Gets one character from the TTY.
 *
 * @return The character read from the TTY. If the
 * \texttt{polltty_iobase} is invalid, returns 0.
 *
 */
int polltty_getchar() 
{
    /* Check that the iobase is valid */
    if (polltty_iobase == 0)
        return 0;

    /* Wait until there is a character available */
    while(TTY_STATUS_RAVAIL(polltty_iobase->status) == 0);

    /* Clear interrupt */
    polltty_iobase->command = TTY_COMMAND_RIRQ;

    return polltty_iobase->data;
}