📄 io_ti.c
字号:
urb = port->read_urb; if (!urb) { err ("%s - no read urb present, exiting", __FUNCTION__); return -EINVAL; } urb->complete = edge_bulk_in_callback; urb->context = edge_port; urb->dev = dev; status = usb_submit_urb (urb); if (status) { err ("%s - read bulk usb_submit_urb failed with value %d", __FUNCTION__, status); return status; } ++edge_serial->num_ports_open; dbg("%s - exited", __FUNCTION__); return 0;}static void edge_close (struct usb_serial_port *port, struct file * filp){ struct usb_serial *serial; struct edgeport_serial *edge_serial; struct edgeport_port *edge_port; int port_number; int status; if (port_paranoia_check (port, __FUNCTION__)) return; dbg("%s - port %d", __FUNCTION__, port->number); serial = get_usb_serial (port, __FUNCTION__); if (!serial) return; edge_serial = (struct edgeport_serial *)serial->private; edge_port = (struct edgeport_port *)port->private; if ((edge_serial == NULL) || (edge_port == NULL)) return; if (serial->dev) { /* The bulkreadcompletion routine will check * this flag and dump add read data */ edge_port->close_pending = 1; /* chase the port close */ TIChasePort (edge_port); usb_unlink_urb (port->read_urb); /* assuming we can still talk to the device, * send a close port command to it */ dbg("%s - send umpc_close_port", __FUNCTION__); port_number = port->number - port->serial->minor; status = TIWriteCommandSync (port->serial->dev, UMPC_CLOSE_PORT, (__u8)(UMPM_UART1_PORT + port_number), 0, NULL, 0); --edge_port->edge_serial->num_ports_open; if (edge_port->edge_serial->num_ports_open <= 0) { /* last port is now closed, let's shut down our interrupt urb */ usb_unlink_urb (serial->port[0].interrupt_in_urb); edge_port->edge_serial->num_ports_open = 0; } edge_port->close_pending = 0; } dbg("%s - exited", __FUNCTION__);}static int edge_write (struct usb_serial_port *port, int from_user, const unsigned char *data, int count){ struct usb_serial *serial = port->serial; struct edgeport_port *edge_port = port->private; int result; dbg("%s - port %d", __FUNCTION__, port->number); if (count == 0) { dbg("%s - write request of 0 bytes", __FUNCTION__); return 0; } if (edge_port == NULL) return -ENODEV; if (edge_port->close_pending == 1) return -ENODEV; if (port->write_urb->status == -EINPROGRESS) { dbg ("%s - already writing", __FUNCTION__); return 0; } count = min (count, port->bulk_out_size); if (from_user) { if (copy_from_user(port->write_urb->transfer_buffer, data, count)) return -EFAULT; } else { memcpy (port->write_urb->transfer_buffer, data, count); } usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer); /* set up our urb */ usb_fill_bulk_urb (port->write_urb, serial->dev, usb_sndbulkpipe (serial->dev, port->bulk_out_endpointAddress), port->write_urb->transfer_buffer, count, edge_bulk_out_callback, port); /* send the data out the bulk port */ result = usb_submit_urb(port->write_urb); if (result) err("%s - failed submitting write urb, error %d", __FUNCTION__, result); else result = count; if (result > 0) edge_port->icount.tx += count; return result;}static int edge_write_room (struct usb_serial_port *port){ struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); int room = 0; dbg("%s", __FUNCTION__); if (edge_port == NULL) return -ENODEV; if (edge_port->close_pending == 1) return -ENODEV; dbg("%s - port %d", __FUNCTION__, port->number); if (port->write_urb->status != -EINPROGRESS) room = port->bulk_out_size; dbg("%s - returns %d", __FUNCTION__, room); return room;}static int edge_chars_in_buffer (struct usb_serial_port *port){ struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); int chars = 0; dbg("%s", __FUNCTION__); if (edge_port == NULL) return -ENODEV; if (edge_port->close_pending == 1) return -ENODEV; dbg("%s - port %d", __FUNCTION__, port->number); if (port->write_urb->status == -EINPROGRESS) chars = port->write_urb->transfer_buffer_length; dbg ("%s - returns %d", __FUNCTION__, chars); return chars;}static void edge_throttle (struct usb_serial_port *port){ struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); struct tty_struct *tty; int status; dbg("%s - port %d", __FUNCTION__, port->number); if (edge_port == NULL) return; tty = port->tty; if (!tty) { dbg ("%s - no tty available", __FUNCTION__); return; } /* if we are implementing XON/XOFF, send the stop character */ if (I_IXOFF(tty)) { unsigned char stop_char = STOP_CHAR(tty); status = edge_write (port, 0, &stop_char, 1); if (status <= 0) { return; } } /* if we are implementing RTS/CTS, toggle that line */ if (tty->termios->c_cflag & CRTSCTS) { status = TIClearRts (edge_port); } usb_unlink_urb (port->read_urb);}static void edge_unthrottle (struct usb_serial_port *port){ struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); struct tty_struct *tty; int status; dbg("%s - port %d", __FUNCTION__, port->number); if (edge_port == NULL) return; tty = port->tty; if (!tty) { dbg ("%s - no tty available", __FUNCTION__); return; } /* if we are implementing XON/XOFF, send the start character */ if (I_IXOFF(tty)) { unsigned char start_char = START_CHAR(tty); status = edge_write (port, 0, &start_char, 1); if (status <= 0) { return; } } /* if we are implementing RTS/CTS, toggle that line */ if (tty->termios->c_cflag & CRTSCTS) { status = TISetRts (edge_port); } port->read_urb->dev = port->serial->dev; status = usb_submit_urb (port->read_urb); if (status) { err ("%s - usb_submit_urb failed with value %d", __FUNCTION__, status); }}static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios){ struct ump_uart_config *config; struct tty_struct *tty; int baud; int round; unsigned cflag; int status; int port_number = edge_port->port->number - edge_port->port->serial->minor; dbg("%s - port %d", __FUNCTION__, edge_port->port->number); tty = edge_port->port->tty; if ((!tty) || (!tty->termios)) { dbg("%s - no tty structures", __FUNCTION__); return; } config = kmalloc (sizeof (*config), GFP_KERNEL); if (!config) { err ("%s - out of memory", __FUNCTION__); return; } cflag = tty->termios->c_cflag; config->wFlags = 0; /* These flags must be set */ config->wFlags |= UMP_MASK_UART_FLAGS_RECEIVE_MS_INT; config->wFlags |= UMP_MASK_UART_FLAGS_AUTO_START_ON_ERR; config->bUartMode = 0; switch (cflag & CSIZE) { case CS5: config->bDataBits = UMP_UART_CHAR5BITS; dbg ("%s - data bits = 5", __FUNCTION__); break; case CS6: config->bDataBits = UMP_UART_CHAR6BITS; dbg ("%s - data bits = 6", __FUNCTION__); break; case CS7: config->bDataBits = UMP_UART_CHAR7BITS; dbg ("%s - data bits = 7", __FUNCTION__); break; default: case CS8: config->bDataBits = UMP_UART_CHAR8BITS; dbg ("%s - data bits = 8", __FUNCTION__); break; } if (cflag & PARENB) { if (cflag & PARODD) { config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; config->bParity = UMP_UART_ODDPARITY; dbg("%s - parity = odd", __FUNCTION__); } else { config->wFlags |= UMP_MASK_UART_FLAGS_PARITY; config->bParity = UMP_UART_EVENPARITY; dbg("%s - parity = even", __FUNCTION__); } } else { config->bParity = UMP_UART_NOPARITY; dbg("%s - parity = none", __FUNCTION__); } if (cflag & CSTOPB) { config->bStopBits = UMP_UART_STOPBIT2; dbg("%s - stop bits = 2", __FUNCTION__); } else { config->bStopBits = UMP_UART_STOPBIT1; dbg("%s - stop bits = 1", __FUNCTION__); } /* figure out the flow control settings */ if (cflag & CRTSCTS) { config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X_CTS_FLOW; config->wFlags |= UMP_MASK_UART_FLAGS_RTS_FLOW; dbg("%s - RTS/CTS is enabled", __FUNCTION__); } else { dbg("%s - RTS/CTS is disabled", __FUNCTION__); } /* if we are implementing XON/XOFF, set the start and stop character in the device */ if (I_IXOFF(tty) || I_IXON(tty)) { config->cXon = START_CHAR(tty); config->cXoff = STOP_CHAR(tty); /* if we are implementing INBOUND XON/XOFF */ if (I_IXOFF(tty)) { config->wFlags |= UMP_MASK_UART_FLAGS_IN_X; dbg ("%s - INBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __FUNCTION__, config->cXon, config->cXoff); } else { dbg ("%s - INBOUND XON/XOFF is disabled", __FUNCTION__); } /* if we are implementing OUTBOUND XON/XOFF */ if (I_IXON(tty)) { config->wFlags |= UMP_MASK_UART_FLAGS_OUT_X; dbg ("%s - OUTBOUND XON/XOFF is enabled, XON = %2x, XOFF = %2x", __FUNCTION__, config->cXon, config->cXoff); } else { dbg ("%s - OUTBOUND XON/XOFF is disabled", __FUNCTION__); } } /* Round the baud rate */ baud = tty_get_baud_rate(tty); if (!baud) { /* pick a default, any default... */ baud = 9600; } config->wBaudRate = (__u16)(461550L / baud); round = 4615500L / baud; if ((round - (config->wBaudRate * 10)) >= 5) config->wBaudRate++; dbg ("%s - baud rate = %d, wBaudRate = %d", __FUNCTION__, baud, config->wBaudRate); dbg ("wBaudRate: %d", (int)(461550L / config->wBaudRate)); dbg ("wFlags: 0x%x", config->wFlags); dbg ("bDataBits: %d", config->bDataBits); dbg ("bParity: %d", config->bParity); dbg ("bStopBits: %d", config->bStopBits); dbg ("cXon: %d", config->cXon); dbg ("cXoff: %d", config->cXoff); dbg ("bUartMode: %d", config->bUartMode); /* move the word values into big endian mode */ cpu_to_be16s (&config->wFlags); cpu_to_be16s (&config->wBaudRate); status = TIWriteCommandSync (edge_port->port->serial->dev, UMPC_SET_CONFIG, (__u8)(UMPM_UART1_PORT + port_number), 0, (__u8 *)config, sizeof(*config)); if (status) { dbg ("%s - error %d when trying to write config to device", __FUNCTION__, status); } kfree (config); return;}static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios){ struct edgeport_port *edge_port = (struct edgeport_port *)(port->private); struct tty_struct *tty = port->tty; unsigned int cflag; if (!port->tty || !port->tty->termios) { dbg ("%s - no tty or termios", __FUNCTION__); return; } 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))) { dbg ("%s - nothing to change", __FUNCTION__); return; } } dbg("%s - clfag %08x iflag %08x", __FUNCTION__, tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag)); if (old_termios) { dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__, old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag)); } dbg("%s - port %d", __FUNCTION__, port->number); if (edge_port == NULL) return; /* change the port settings to the new ones specified */ change_port_settings (edge_port, old_termios); return;}static int set_modem_info (struct edgeport_port *edge_port, unsigned int cmd, unsigned int *value){ unsigned int mcr = edge_port->shadow_mcr; unsigned int arg; if (copy_from_user(&arg, value, sizeof(int))) return -EFAULT; switch (cmd) { case TIOCMBIS: if (arg & TIOCM_RTS) mcr |= MCR_RTS; if (arg & TIOCM_DTR) mcr |= MCR_RTS; if (arg & TIOCM_LOOP) mcr |= MCR_LOOPBACK; break; case TIOCMBIC: if (arg & TIOCM_RTS) mcr &= ~MCR_RTS; if (arg & TIOCM_DTR) mcr &= ~MCR_RTS; if (arg & TIOCM_LOOP) mcr &= ~MCR_LOOPBACK; break; case TIOCMSET: /* turn off the RTS and DTR and LOOPBACK * and then only turn on what was asked to */ mcr &= ~(MCR_RTS | MCR_DTR | MCR_LOOPBACK); mcr |= ((arg & TIOCM_RTS) ? MCR_RTS : 0); mcr |= ((arg & TIOCM_DTR) ? MCR_DTR : 0); mcr |= ((arg & TIOCM_LOOP) ? MCR_LOOPBACK : 0); break; } edge_port->shadow_mcr = mcr; TIRestoreMCR (edge_port, mcr); return 0;}static
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -