diff options
author | Alan Cox <alan@redhat.com> | 2008-07-22 14:09:07 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-23 00:03:22 +0400 |
commit | 95da310e66ee8090119596c70ca8432e57f9a97f (patch) | |
tree | 7f18c30e9c9ad4d7d53df6453fa338be06f09a85 /include/linux/usb | |
parent | 1aa3692da57c773e5c76de55c5c4a953962d360e (diff) | |
download | linux-95da310e66ee8090119596c70ca8432e57f9a97f.tar.xz |
usb_serial: API all change
USB serial likes to use port->tty back pointers for the real work it does and
to do so without any actual locking. Unfortunately when you consider hangup
events, hangup/parallel reopen or even worse hangup followed by parallel close
events the tty->port and port->tty pointers are not guaranteed to be the same
as port->tty is the active tty while tty->port is the port the tty may or
may not still be attached to.
So rework the entire API to pass the tty struct. For console cases we need
to pass both for now. This shows up multiple drivers that immediately crash
with USB console some of which have been fixed in the process.
Longer term we need a proper tty as console abstraction
Signed-off-by: Alan Cox <alan@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/linux/usb')
-rw-r--r-- | include/linux/usb/serial.h | 56 |
1 files changed, 30 insertions, 26 deletions
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index 8f891cbaf9ab..09a3e6a7518f 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -62,7 +62,7 @@ */ struct usb_serial_port { struct usb_serial *serial; - struct tty_struct *tty; + struct tty_port port; spinlock_t lock; struct mutex mutex; unsigned char number; @@ -89,7 +89,6 @@ struct usb_serial_port { wait_queue_head_t write_wait; struct work_struct work; - int open_count; char throttled; char throttle_req; char console; @@ -217,22 +216,27 @@ struct usb_serial_driver { int (*resume)(struct usb_serial *serial); /* serial function calls */ - int (*open)(struct usb_serial_port *port, struct file *filp); - void (*close)(struct usb_serial_port *port, struct file *filp); - int (*write)(struct usb_serial_port *port, const unsigned char *buf, - int count); - int (*write_room)(struct usb_serial_port *port); - int (*ioctl)(struct usb_serial_port *port, struct file *file, + /* Called by console with tty = NULL and by tty */ + int (*open)(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + void (*close)(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); + int (*write)(struct tty_struct *tty, struct usb_serial_port *port, + const unsigned char *buf, int count); + /* Called only by the tty layer */ + int (*write_room)(struct tty_struct *tty); + int (*ioctl)(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg); - void (*set_termios)(struct usb_serial_port *port, struct ktermios *old); - void (*break_ctl)(struct usb_serial_port *port, int break_state); - int (*chars_in_buffer)(struct usb_serial_port *port); - void (*throttle)(struct usb_serial_port *port); - void (*unthrottle)(struct usb_serial_port *port); - int (*tiocmget)(struct usb_serial_port *port, struct file *file); - int (*tiocmset)(struct usb_serial_port *port, struct file *file, + void (*set_termios)(struct tty_struct *tty, + struct usb_serial_port *port, struct ktermios *old); + void (*break_ctl)(struct tty_struct *tty, int break_state); + int (*chars_in_buffer)(struct tty_struct *tty); + void (*throttle)(struct tty_struct *tty); + void (*unthrottle)(struct tty_struct *tty); + int (*tiocmget)(struct tty_struct *tty, struct file *file); + int (*tiocmset)(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); - + /* USB events */ void (*read_int_callback)(struct urb *urb); void (*write_int_callback)(struct urb *urb); void (*read_bulk_callback)(struct urb *urb); @@ -270,19 +274,19 @@ static inline void usb_serial_console_disconnect(struct usb_serial *serial) {} /* Functions needed by other parts of the usbserial core */ extern struct usb_serial *usb_serial_get_by_index(unsigned int minor); extern void usb_serial_put(struct usb_serial *serial); -extern int usb_serial_generic_open(struct usb_serial_port *port, - struct file *filp); -extern int usb_serial_generic_write(struct usb_serial_port *port, - const unsigned char *buf, int count); -extern void usb_serial_generic_close(struct usb_serial_port *port, - struct file *filp); +extern int usb_serial_generic_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); +extern int usb_serial_generic_write(struct tty_struct *tty, + struct usb_serial_port *port, const unsigned char *buf, int count); +extern void usb_serial_generic_close(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp); extern int usb_serial_generic_resume(struct usb_serial *serial); -extern int usb_serial_generic_write_room(struct usb_serial_port *port); -extern int usb_serial_generic_chars_in_buffer(struct usb_serial_port *port); +extern int usb_serial_generic_write_room(struct tty_struct *tty); +extern int usb_serial_generic_chars_in_buffer(struct tty_struct *tty); extern void usb_serial_generic_read_bulk_callback(struct urb *urb); extern void usb_serial_generic_write_bulk_callback(struct urb *urb); -extern void usb_serial_generic_throttle(struct usb_serial_port *port); -extern void usb_serial_generic_unthrottle(struct usb_serial_port *port); +extern void usb_serial_generic_throttle(struct tty_struct *tty); +extern void usb_serial_generic_unthrottle(struct tty_struct *tty); extern void usb_serial_generic_shutdown(struct usb_serial *serial); extern int usb_serial_generic_register(int debug); extern void usb_serial_generic_deregister(void); |