📄 usbserial.c
字号:
static int serial_refcount;static struct tty_driver serial_tty_driver;static struct tty_struct * serial_tty[SERIAL_TTY_MINORS];static struct termios * serial_termios[SERIAL_TTY_MINORS];static struct termios * serial_termios_locked[SERIAL_TTY_MINORS];static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */static LIST_HEAD(usb_serial_driver_list);static struct usb_serial *get_serial_by_minor (int minor){ return serial_table[minor];}static struct usb_serial *get_free_serial (int num_ports, int *minor){ struct usb_serial *serial = NULL; int i, j; int good_spot; dbg(__FUNCTION__ " %d", num_ports); *minor = 0; for (i = 0; i < SERIAL_TTY_MINORS; ++i) { if (serial_table[i]) continue; good_spot = 1; for (j = 1; j <= num_ports-1; ++j) if (serial_table[i+j]) good_spot = 0; if (good_spot == 0) continue; if (!(serial = kmalloc(sizeof(struct usb_serial), GFP_KERNEL))) { err(__FUNCTION__ " - Out of memory"); return NULL; } memset(serial, 0, sizeof(struct usb_serial)); serial->magic = USB_SERIAL_MAGIC; serial_table[i] = serial; *minor = i; dbg(__FUNCTION__ " - minor base = %d", *minor); for (i = *minor+1; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) serial_table[i] = serial; return serial; } return NULL;}static void return_serial (struct usb_serial *serial){ int i; dbg(__FUNCTION__); if (serial == NULL) return; for (i = 0; i < serial->num_ports; ++i) { serial_table[serial->minor + i] = NULL; } return;}#ifdef USES_EZUSB_FUNCTIONS/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */#define CPUCS_REG 0x7F92int ezusb_writememory (struct usb_serial *serial, int address, unsigned char *data, int length, __u8 bRequest){ int result; unsigned char *transfer_buffer; /* dbg("ezusb_writememory %x, %d", address, length); */ if (!serial->dev) { dbg(__FUNCTION__ " - no physical device present, failing."); return -ENODEV; } transfer_buffer = kmalloc (length, GFP_KERNEL); if (!transfer_buffer) { err(__FUNCTION__ " - kmalloc(%d) failed.", length); return -ENOMEM; } memcpy (transfer_buffer, data, length); result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), bRequest, 0x40, address, 0, transfer_buffer, length, 300); kfree (transfer_buffer); return result;}int ezusb_set_reset (struct usb_serial *serial, unsigned char reset_bit){ int response; dbg(__FUNCTION__ " - %d", reset_bit); response = ezusb_writememory (serial, CPUCS_REG, &reset_bit, 1, 0xa0); if (response < 0) { err(__FUNCTION__ "- %d failed", reset_bit); } return response;}#endif /* USES_EZUSB_FUNCTIONS *//***************************************************************************** * Driver tty interface functions *****************************************************************************/static int serial_open (struct tty_struct *tty, struct file * filp){ struct usb_serial *serial; struct usb_serial_port *port; int portNumber; dbg(__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; port->tty = tty; /* pass on to the driver specific version of this function if it is available */ if (serial->type->open) { return (serial->type->open(port, filp)); } else { return (generic_open(port, filp)); }}static void serial_close(struct tty_struct *tty, struct file * filp){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return; } dbg(__FUNCTION__ " - port %d", port->number); if (!port->active) { dbg (__FUNCTION__ " - port not opened"); return; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->close) { serial->type->close(port, filp); } else { generic_close(port, filp); }} static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return -ENODEV; } dbg(__FUNCTION__ " - port %d, %d byte(s)", port->number, count); if (!port->active) { dbg (__FUNCTION__ " - port not opened"); return -EINVAL; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->write) { return (serial->type->write(port, from_user, buf, count)); } else { return (generic_write(port, from_user, buf, count)); }}static int serial_write_room (struct tty_struct *tty) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return -ENODEV; } dbg(__FUNCTION__ " - port %d", port->number); if (!port->active) { dbg (__FUNCTION__ " - port not open"); return -EINVAL; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->write_room) { return (serial->type->write_room(port)); } else { return (generic_write_room(port)); }}static int serial_chars_in_buffer (struct tty_struct *tty) { struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return -ENODEV; } if (!port->active) { dbg (__FUNCTION__ " - port not open"); return -EINVAL; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->chars_in_buffer) { return (serial->type->chars_in_buffer(port)); } else { return (generic_chars_in_buffer(port)); }}static void serial_throttle (struct tty_struct * tty){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return; } dbg(__FUNCTION__ " - port %d", port->number); if (!port->active) { dbg (__FUNCTION__ " - port not open"); return; } /* pass on to the driver specific version of this function */ if (serial->type->throttle) { serial->type->throttle(port); } return;}static void serial_unthrottle (struct tty_struct * tty){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return; } dbg(__FUNCTION__ " - port %d", port->number); if (!port->active) { dbg (__FUNCTION__ " - port not open"); return; } /* pass on to the driver specific version of this function */ if (serial->type->unthrottle) { serial->type->unthrottle(port); } return;}static int serial_ioctl (struct tty_struct *tty, struct file * file, unsigned int cmd, unsigned long arg){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return -ENODEV; } dbg(__FUNCTION__ " - port %d, cmd 0x%.4x", port->number, cmd); if (!port->active) { dbg (__FUNCTION__ " - port not open"); return -ENODEV; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->ioctl) { return (serial->type->ioctl(port, file, cmd, arg)); } else { return -ENOIOCTLCMD; }}static void serial_set_termios (struct tty_struct *tty, struct termios * old){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return; } dbg(__FUNCTION__ " - port %d", port->number); if (!port->active) { dbg (__FUNCTION__ " - port not open"); return; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->set_termios) { serial->type->set_termios(port, old); } return;}static void serial_break (struct tty_struct *tty, int break_state){ struct usb_serial_port *port = (struct usb_serial_port *) tty->driver_data; struct usb_serial *serial = get_usb_serial (port, __FUNCTION__); if (!serial) { return; } dbg(__FUNCTION__ " - port %d", port->number); if (!port->active) { dbg (__FUNCTION__ " - port not open"); return; } /* pass on to the driver specific version of this function if it is available */ if (serial->type->break_ctl) { serial->type->break_ctl(port, break_state); }}static void serial_shutdown (struct usb_serial *serial){ if (serial->type->shutdown) { serial->type->shutdown(serial); } else { generic_shutdown(serial); }}/***************************************************************************** * generic devices specific driver functions *****************************************************************************/static int generic_open (struct usb_serial_port *port, struct file *filp){ struct usb_serial *serial = port->serial;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -