static void rs_flush_buffer(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) return; local_irq_save(flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; local_irq_restore(flags); tty_wakeup(tty); }
/* * ------------------------------------------------------------ * rs_throttle() * * This routine is called by the upper-layer tty layer to signal that * incoming characters should be throttled. * ------------------------------------------------------------ */ static void rs_throttle(struct tty_struct * tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_throttle")) return; if (I_IXOFF(tty)) info->x_char = STOP_CHAR(tty); /* Turn off RTS line (do this atomic) */ }
static int rs_write_room(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; int ret; if (serial_paranoia_check(info, tty->name, "rs_write_room")) return 0; ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1; if (ret < 0) ret = 0; return ret; }
static int rs_360_write(struct tty_struct * tty, const unsigned char *buf, int count) { int c, ret = 0; ser_info_t *info = (ser_info_t *)tty->driver_data; volatile QUICC_BD *bdp; #ifdef CONFIG_KGDB /* Try to let stub handle output. Returns true if it did. */ if (kgdb_output_string(buf, count)) return ret; #endif if (serial_paranoia_check(info, tty->name, "rs_write")) return 0; if (!tty) return 0; bdp = info->tx_cur; while (1) { c = min(count, TX_BUF_SIZE); if (c <= 0) break; if (bdp->status & BD_SC_READY) { info->flags |= TX_WAKEUP; break; } /* memcpy(__va(bdp->buf), buf, c); */ memcpy((void *)bdp->buf, buf, c); bdp->length = c; bdp->status |= BD_SC_READY; buf += c; count -= c; ret += c; /* Get next BD. */ if (bdp->status & BD_SC_WRAP) bdp = info->tx_bd_base; else bdp++; info->tx_cur = (QUICC_BD *)bdp; } return ret; }
static void rs_360_flush_buffer(struct tty_struct *tty) { ser_info_t *info = (ser_info_t *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) return; /* There is nothing to "flush", whatever we gave the CPM * is on its way out. */ tty_wakeup(tty); info->flags &= ~TX_WAKEUP; }
/* * ------------------------------------------------------------ * rs_stop() and rs_start() * * This routines are called before setting or resetting tty->stopped. * They enable or disable transmitter interrupts, as necessary. * ------------------------------------------------------------ */ static void rs_stop(struct tty_struct *tty) { struct NIOS_serial *info = (struct NIOS_serial *)tty->driver_data; np_uart * uart= (np_uart *)(info->port); unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_stop")) return; save_flags(flags); cli(); uart->np_uartcontrol &= ~np_uartcontrol_itrdy_mask; restore_flags(flags); }
static void xmbrs_start(struct tty_struct *tty) { volatile unsigned int *uartp; struct xmb_serial *info = (struct xmb_serial *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "xmbrs_start")) return; uartp = (volatile unsigned int *) info->addr; save_flags_cli(flags); EnableInterrupts(uartp); restore_flags(flags); }
static void rs_start(struct tty_struct *tty) { struct LEON_serial *info = (struct LEON_serial *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_start")) return; save_flags(flags); cli(); if (info->xmit_cnt && info->xmit_buf && !(leon->uartctrl1 & UCTRL_TE)) leon->uartctrl1 |= UCTRL_TE | UCTRL_TI; restore_flags(flags); }
/* * ------------------------------------------------------------ * rs_stop() and rs_start() * * This routines are called before setting or resetting tty->stopped. * They enable or disable transmitter interrupts, as necessary. * ------------------------------------------------------------ */ static void rs_stop(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; m68328_uart *uart = &uart_addr[info->line]; unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_stop")) return; local_irq_save(flags); uart->ustcnt &= ~USTCNT_TXEN; local_irq_restore(flags); }
static void rs_flush_buffer(struct tty_struct *tty) { struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "rs_flush_buffer")) return; cli(); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; sti(); wake_up_interruptible(&tty->write_wait); if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup) (tty->ldisc.write_wakeup)(tty); }
static void rs_stop(struct tty_struct *tty) { struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "rs_stop")) return; #if 0 save_flags(flags); cli(); tx_stop(info->uart); restore_flags(flags); #endif }
/* * ------------------------------------------------------------ * rs_stop() and rs_start() * * This routines are called before setting or resetting tty->stopped. * They enable or disable transmitter interrupts, as necessary. * ------------------------------------------------------------ */ static void rs_stop(struct tty_struct *tty) { struct bf535_serial *info = (struct bf535_serial *)tty->driver_data; unsigned long flags = 0; unsigned int idx = (unsigned int) info->hub2; if (serial_paranoia_check(info, tty->device, "rs_stop")) return; save_flags(flags); cli(); ACCESS_PORT_IER(idx) /* Change access to IER & data port */ UART_IER(idx) = 0; restore_flags(flags); }
static void rs_start(struct tty_struct *tty) { struct s3c3410_serial *info = (struct s3c3410_serial *) tty->driver_data; unsigned long flags = 0; if (serial_paranoia_check(info, tty->device, "rs_start")) return; save_flags(flags); cli(); rx_start(info->use_ints); tx_start(info->use_ints); restore_flags(flags); }
/* * This routine is called whenever a serial port is opened. It * enables interrupts for a serial port, linking in its S structure into * the IRQ chain. It also performs the serial-specific * initialization for the tty structure. */ int rs_open(struct tty_struct *tty, struct file * filp) { int retval, line; struct cnxt_serial *info; line = MINOR(tty->device) - tty->driver.minor_start; if (line != 0) /* we have exactly one */ return -ENODEV; info = &uart_info; if (serial_paranoia_check(info, tty->device, "rs_open")) return -ENODEV; info->count++; tty->driver_data = info; info->tty = tty; /* * Start up serial port */ retval = startup(info); if (retval) return retval; retval = block_til_ready(tty, filp, info); if (retval) { printk("rs_open returning after block_til_ready with %d\n", retval); return retval; } if ((info->count == 1) && (info->flags & S_SPLIT_TERMIOS)) { if (tty->driver.subtype == SERIAL_TYPE_NORMAL) *tty->termios = info->normal_termios; else *tty->termios = info->callout_termios; change_speed(info); } info->session = current->session; info->pgrp = current->pgrp; // Enable GPIO interrupt line for console uart SetGPIOIntEnable(GPIOINT_UART1, IRQ_ON); return 0; }
static void rs_start(struct tty_struct *tty) { unsigned long flags; struct cnxt_serial *info = (struct cnxt_serial *)tty->driver_data; if (serial_paranoia_check(info,tty->device, "rs_start")) return; save_flags(flags); cli(); tx_start(info->uart, info->use_ints); start_rx(); restore_flags(flags); }
static int rs_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg) { struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; int retval; if (serial_paranoia_check(info, tty->name, "rs_ioctl")) return -ENODEV; if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGWILD) && (cmd != TIOCSERSWILD) && (cmd != TIOCSERGSTRUCT)) { if (tty->flags & (1 << TTY_IO_ERROR)) return -EIO; } switch (cmd) { case TCSBRK: /* SVID version: non-zero arg --> no break */ retval = tty_check_change(tty); if (retval) return retval; tty_wait_until_sent(tty, 0); if (!arg) send_break(info, 250); /* 1/4 second */ return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ retval = tty_check_change(tty); if (retval) return retval; tty_wait_until_sent(tty, 0); send_break(info, arg ? arg*(100) : 250); return 0; case TIOCGSERIAL: return get_serial_info(info, (struct serial_struct *) arg); case TIOCSSERIAL: return set_serial_info(info, (struct serial_struct *) arg); case TIOCSERGETLSR: /* Get line status register */ return get_lsr_info(info, (unsigned int *) arg); case TIOCSERGSTRUCT: if (copy_to_user((struct m68k_serial *) arg, info, sizeof(struct m68k_serial))) return -EFAULT; return 0; default: return -ENOIOCTLCMD; } return 0; }
/* * rs_hangup() --- called by tty_hangup() when a hangup is signaled. */ void rs_hangup(struct tty_struct *tty) { struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_hangup")) return; rs_flush_buffer(tty); shutdown(info, tty); info->tport.count = 0; info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; tty_port_tty_set(&info->tport, NULL); wake_up_interruptible(&info->tport.open_wait); }
/* * rs_hangup() --- called by tty_hangup() when a hangup is signaled. */ static void rs_hangup(struct tty_struct *tty) { struct serial_state *info = tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_hangup")) return; rs_flush_buffer(tty); shutdown(tty, info); info->tport.count = 0; info->tport.flags &= ~ASYNC_NORMAL_ACTIVE; info->tport.tty = NULL; wake_up_interruptible(&info->tport.open_wait); }
static int mcfrs_write(struct tty_struct * tty, const unsigned char *buf, int count) { volatile unsigned char *uartp; struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; unsigned long flags; int c, total = 0; #if 0 printk("%s(%d): mcfrs_write(tty=%x,buf=%x,count=%d)\n", __FILE__, __LINE__, (int)tty, (int)buf, count); #endif if (serial_paranoia_check(info, tty->name, "mcfrs_write")) return 0; if (!tty || !info->xmit_buf) return 0; local_save_flags(flags); while (1) { local_irq_disable(); c = min(count, (int) min(((int)SERIAL_XMIT_SIZE) - info->xmit_cnt - 1, ((int)SERIAL_XMIT_SIZE) - info->xmit_head)); local_irq_restore(flags); if (c <= 0) break; memcpy(info->xmit_buf + info->xmit_head, buf, c); local_irq_disable(); info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt += c; local_irq_restore(flags); buf += c; count -= c; total += c; } local_irq_disable(); uartp = info->addr; info->imr |= MCFUART_UIR_TXREADY; uartp[MCFUART_UIMR] = info->imr; local_irq_restore(flags); return total; }
/***************************************************************************** * Driver tty interface functions *****************************************************************************/ static int serial_open (struct tty_struct *tty, struct file * filp) { struct usb_serial *serial; struct usb_serial_port *port; unsigned int portNumber; int retval = 0; dbg("%s", __FUNCTION__); /* initialize the pointer incase something fails */ tty->driver_data = NULL; /* get the serial object associated with this tty pointer */ serial = get_serial_by_minor (MINOR(tty->device)); if (serial_paranoia_check (serial, __FUNCTION__)) return -ENODEV; /* set up our port structure making the tty driver remember our port object, and us it */ portNumber = MINOR(tty->device) - serial->minor; port = &serial->port[portNumber]; tty->driver_data = port; down (&port->sem); port->tty = tty; /* lock this module before we call it */ if (serial->type->owner) __MOD_INC_USE_COUNT(serial->type->owner); ++port->open_count; if (port->open_count == 1) { /* only call the device specific open if this * is the first time the port is opened */ if (serial->type->open) retval = serial->type->open(port, filp); else retval = generic_open(port, filp); } if (retval) { port->open_count = 0; if (serial->type->owner) __MOD_DEC_USE_COUNT(serial->type->owner); } up (&port->sem); return retval; }
/* * This routine is called whenever a serial port is opened. It * enables interrupts for a serial port, linking in its structure into * the IRQ chain. It also performs the serial-specific * initialization for the tty structure. */ int xmbrs_open(struct tty_struct *tty, struct file * filp) { struct xmb_serial *info; int retval, line; line = MINOR(tty->device) - tty->driver.minor_start; if ((line < 0) || (line >= NR_PORTS)) return -ENODEV; info = xmbrs_table + line; if (serial_paranoia_check(info, tty->device, "xmbrs_open")) return -ENODEV; #ifdef SERIAL_DEBUG_OPEN printk("xmbrs_open ttyS%d, count = %d\n", info->line, info->count); #endif info->count++; tty->driver_data = info; info->tty = tty; /* * Start up serial port */ retval = startup(info); if (retval) return retval; retval = block_til_ready(tty, filp, info); if (retval) { #ifdef SERIAL_DEBUG_OPEN printk("xmbrs_open returning after block_til_ready with %d\n", retval); #endif return retval; } if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) { if (tty->driver.subtype == SERIAL_TYPE_NORMAL) *tty->termios = info->normal_termios; else *tty->termios = info->callout_termios; } info->session = current->session; info->pgrp = current->pgrp; #ifdef SERIAL_DEBUG_OPEN printk("xmbrs_open ttyS%d successful...\n", info->line); #endif return 0; }
/* * rs_hangup() --- called by tty_hangup() when a hangup is signaled. */ void rs_hangup(struct tty_struct *tty) { struct m68k_serial * info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_hangup")) return; rs_flush_buffer(tty); shutdown(info); info->event = 0; info->count = 0; info->flags &= ~S_NORMAL_ACTIVE; info->tty = NULL; wake_up_interruptible(&info->open_wait); }
/* * xmbrs_hangup() --- called by tty_hangup() when a hangup is signaled. */ void xmbrs_hangup(struct tty_struct *tty) { struct xmb_serial * info = (struct xmb_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->device, "xmbrs_hangup")) return; xmbrs_flush_buffer(tty); shutdown(info); info->event = 0; info->count = 0; info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE); info->tty = 0; wake_up_interruptible(&info->open_wait); }
static void rs_set_ldisc(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_set_ldisc")) return; info->is_cons = (tty->termios->c_line == N_TTY); #ifdef CONFIG_DEBUG_PRINTK printk("ttyS%d console mode %s\n", info->line, info->is_cons ? "on" : "off"); #else ; #endif }
/* * ------------------------------------------------------------ * mcfrs_stop() and mcfrs_start() * * This routines are called before setting or resetting tty->stopped. * They enable or disable transmitter interrupts, as necessary. * ------------------------------------------------------------ */ static void mcfrs_stop(struct tty_struct *tty) { volatile unsigned char *uartp; struct mcf_serial *info = (struct mcf_serial *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->name, "mcfrs_stop")) return; local_irq_save(flags); uartp = info->addr; info->imr &= ~MCFUART_UIR_TXREADY; uartp[MCFUART_UIMR] = info->imr; local_irq_restore(flags); }
static int rs_write(struct tty_struct * tty, const unsigned char *buf, int count) { int c, ret = 0; struct async_struct *info; unsigned long flags; info = tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_write")) return 0; if (!info->xmit.buf) return 0; local_irq_save(flags); while (1) { c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE); if (count < c) c = count; if (c <= 0) { break; } memcpy(info->xmit.buf + info->xmit.head, buf, c); info->xmit.head = ((info->xmit.head + c) & (SERIAL_XMIT_SIZE-1)); buf += c; count -= c; ret += c; } local_irq_restore(flags); if (info->xmit.head != info->xmit.tail && !tty->stopped && !tty->hw_stopped && !(info->IER & UART_IER_THRI)) { info->IER |= UART_IER_THRI; local_irq_disable(); custom.intena = IF_SETCLR | IF_TBE; mb(); /* set a pending Tx Interrupt, transmitter should restart now */ custom.intreq = IF_SETCLR | IF_TBE; mb(); local_irq_restore(flags); } return ret; }
static void rs_unthrottle(struct tty_struct * tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; if (serial_paranoia_check(info, tty->name, "rs_unthrottle")) return; if (I_IXOFF(tty)) { if (info->x_char) info->x_char = 0; else info->x_char = START_CHAR(tty); } /* Assert RTS line (do this atomic) */ }
static void rs_flush_chars(struct tty_struct *tty) { struct LEON_serial *info = (struct LEON_serial *)tty->driver_data; unsigned long flags; if (serial_paranoia_check(info, tty->device, "rs_flush_chars")) return; save_flags(flags); cli(); if (info->xmit_cnt > 0 && !tty->stopped && !tty->hw_stopped && info->xmit_buf) { /* Enable transmitter */ leon->uartctrl1 |= UCTRL_TE | UCTRL_TI; } restore_flags(flags); }
static void rs_start(struct tty_struct *tty) { struct bf535_serial *info = (struct bf535_serial *)tty->driver_data; unsigned long flags = 0; unsigned int idx = (unsigned int) info->hub2; if (serial_paranoia_check(info, tty->device, "rs_start")) return; save_flags(flags); cli(); ACCESS_PORT_IER(idx) /* Change access to IER & data port */ if (info->xmit_cnt && info->xmit_buf && !(UART_IER(idx) & UART_IER_ETBEI)) UART_IER(idx) |= UART_IER_ETBEI; restore_flags(flags); }
static struct usb_serial *get_usb_serial(struct usb_serial_port *port, const char *function) { /* if no port was specified, or it fails a paranoia check */ if (!port || port_paranoia_check(port, function) || serial_paranoia_check(port->serial, function)) { /* * then say that we dont have a valid usb_serial thing, * which will end up genrating -ENODEV return values */ return NULL; } return port->serial; }