static int nullmodem_open(struct tty_struct *tty, struct file *file) { struct nullmodem_pair *pair = &pair_table[tty->index/2]; struct nullmodem_end *end = ((tty->index&1) ? &pair->b : &pair->a); unsigned long flags; int index; int err = -ENOMEM; dprintf("%s - #%d c:%d\n", __FUNCTION__, tty->index, tty->count); if (tty->count > 1) return 0; index = tty->index; tport[index].tty=tty; tty->port = &tport[index]; spin_lock_irqsave(&end->pair->spin, flags); if (kfifo_alloc(&end->fifo, TX_BUF_SIZE, GFP_KERNEL)) goto exit; tty->driver_data = end; end->tty = tty; end->nominal_bit_count = 0; end->actual_bit_count = 0; handle_termios(tty); err = 0; exit: spin_unlock_irqrestore(&end->pair->spin, flags); return err; }
// Emulated ioctl implementation VISIBLE long ioctl(int fd, int cmd, void* arg) { IOCTL_STEP(handle_filio(fd, cmd, arg, &retval)); IOCTL_STEP(handle_termios(fd, cmd, arg, &retval)); run_ioctl: return __real_ioctl(fd, cmd, arg); }
static void nullmodem_set_termios(struct tty_struct *tty, struct ktermios *old_termios) { struct nullmodem_end *end = tty->driver_data; unsigned long flags; unsigned int cflag; dprintf("%s - #%d\n", __FUNCTION__, tty->index); cflag = tty->termios.c_cflag; /* check that they really want us to change something */ if (old_termios) { if (cflag == old_termios->c_cflag && RELEVANT_IFLAG(tty->termios.c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag)) { dprintf(" - nothing to change...\n"); return; } } spin_lock_irqsave(&end->pair->spin, flags); handle_termios(tty); spin_unlock_irqrestore(&end->pair->spin, flags); #ifdef SCULL_DEBUG speed_t speed = tty_get_baud_rate(tty); dprintf(" - baud = %u", speed); dprintf(" - ispeed = %u", tty->termios.c_ispeed); dprintf(" - ospeed = %u", tty->termios.c_ospeed); /* get the byte size */ switch (cflag & CSIZE) { case CS5: dprintf(" - data bits = 5\n"); break; case CS6: dprintf(" - data bits = 6\n"); break; case CS7: dprintf(" - data bits = 7\n"); break; default: case CS8: dprintf(" - data bits = 8\n"); break; } /* determine the parity */ if (cflag & PARENB) if (cflag & PARODD) dprintf(" - parity = odd\n"); else dprintf(" - parity = even\n"); else dprintf(" - parity = none\n"); /* figure out the stop bits requested */ if (cflag & CSTOPB) dprintf(" - stop bits = 2\n"); else dprintf(" - stop bits = 1\n"); /* figure out the hardware flow control settings */ if (cflag & CRTSCTS) dprintf(" - RTS/CTS is enabled\n"); else dprintf(" - RTS/CTS is disabled\n"); /* determine software flow control */ /* if we are implementing XON/XOFF, set the start and * stop character in the device */ /* if we are implementing INBOUND XON/XOFF */ if (I_IXOFF(tty)) dprintf(" - INBOUND XON/XOFF is enabled, " "XON = %2x, XOFF = %2x\n", START_CHAR(tty), STOP_CHAR(tty)); else dprintf(" - INBOUND XON/XOFF is disabled\n"); /* if we are implementing OUTBOUND XON/XOFF */ if (I_IXON(tty)) dprintf(" - OUTBOUND XON/XOFF is enabled, " "XON = %2x, XOFF = %2x\n", START_CHAR(tty), STOP_CHAR(tty)); else dprintf(" - OUTBOUND XON/XOFF is disabled\n"); #endif }