From 95da310e66ee8090119596c70ca8432e57f9a97f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 Jul 2008 11:09:07 +0100 Subject: 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 Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/usb/serial/omninet.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'drivers/usb/serial/omninet.c') diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 7b7422f4947..5a2d045562f 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -61,12 +61,12 @@ static int debug; #define BT_IGNITIONPRO_ID 0x2000 /* This one seems to be a re-branded ZyXEL device */ /* function prototypes */ -static int omninet_open (struct usb_serial_port *port, struct file *filp); -static void omninet_close (struct usb_serial_port *port, struct file *filp); +static int omninet_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); +static void omninet_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); static void omninet_read_bulk_callback (struct urb *urb); static void omninet_write_bulk_callback (struct urb *urb); -static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count); -static int omninet_write_room (struct usb_serial_port *port); +static int omninet_write (struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); +static int omninet_write_room (struct tty_struct *tty); static void omninet_shutdown (struct usb_serial *serial); static int omninet_attach (struct usb_serial *serial); @@ -157,7 +157,8 @@ static int omninet_attach (struct usb_serial *serial) return 0; } -static int omninet_open (struct usb_serial_port *port, struct file *filp) +static int omninet_open(struct tty_struct *tty, + struct usb_serial_port *port, struct file *filp) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport; @@ -166,7 +167,7 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) dbg("%s - port %d", __func__, port->number); wport = serial->port[1]; - wport->tty = port->tty; + wport->port.tty = tty; /* FIXME */ /* Start reading from the device */ usb_fill_bulk_urb(port->read_urb, serial->dev, @@ -181,7 +182,8 @@ static int omninet_open (struct usb_serial_port *port, struct file *filp) return result; } -static void omninet_close (struct usb_serial_port *port, struct file * filp) +static void omninet_close(struct tty_struct *tty, + struct usb_serial_port *port, struct file * filp) { dbg("%s - port %d", __func__, port->number); usb_kill_urb(port->read_urb); @@ -221,9 +223,9 @@ static void omninet_read_bulk_callback (struct urb *urb) if (urb->actual_length && header->oh_len) { for (i = 0; i < header->oh_len; i++) { - tty_insert_flip_char(port->tty, data[OMNINET_DATAOFFSET + i], 0); + tty_insert_flip_char(port->port.tty, data[OMNINET_DATAOFFSET + i], 0); } - tty_flip_buffer_push(port->tty); + tty_flip_buffer_push(port->port.tty); } /* Continue trying to always read */ @@ -238,7 +240,8 @@ static void omninet_read_bulk_callback (struct urb *urb) return; } -static int omninet_write (struct usb_serial_port *port, const unsigned char *buf, int count) +static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, + const unsigned char *buf, int count) { struct usb_serial *serial = port->serial; struct usb_serial_port *wport = serial->port[1]; @@ -290,8 +293,9 @@ static int omninet_write (struct usb_serial_port *port, const unsigned char *buf } -static int omninet_write_room (struct usb_serial_port *port) +static int omninet_write_room (struct tty_struct *tty) { + struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; struct usb_serial_port *wport = serial->port[1]; -- cgit v1.2.3-70-g09d2 From f89d0dff2507b6bd486b7db59a5f6a733fbfaa12 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 Jul 2008 11:15:54 +0100 Subject: tty-usb-omninet: Coding style Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/usb/serial/omninet.c | 160 +++++++++++++++++++++++-------------------- 1 file changed, 87 insertions(+), 73 deletions(-) (limited to 'drivers/usb/serial/omninet.c') diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 5a2d045562f..5a76f327ef5 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -5,26 +5,28 @@ * modify it under the terms of the GNU General Public License version * 2 as published by the Free Software Foundation. * - * See Documentation/usb/usb-serial.txt for more information on using this driver + * See Documentation/usb/usb-serial.txt for more information on using this + * driver * * Please report both successes and troubles to the author at omninet@kroah.com - * + * * (05/30/2001) gkh - * switched from using spinlock to a semaphore, which fixes lots of problems. + * switched from using spinlock to a semaphore, which fixes lots of + * problems. * * (04/08/2001) gb * Identify version on module load. * * (11/01/2000) Adam J. Richter * usb_device_id table support - * + * * (10/05/2000) gkh * Fixed bug with urb->dev not being set properly, now that the usb * core needs it. - * + * * (08/28/2000) gkh * Added locks for SMP safeness. - * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more + * Fixed MOD_INC and MOD_DEC logic and the ability to open a port more * than once. * Fixed potential race in omninet_write_bulk_callback * @@ -43,7 +45,7 @@ #include #include #include -#include +#include #include #include @@ -58,25 +60,29 @@ static int debug; #define ZYXEL_VENDOR_ID 0x0586 #define ZYXEL_OMNINET_ID 0x1000 -#define BT_IGNITIONPRO_ID 0x2000 /* This one seems to be a re-branded ZyXEL device */ +/* This one seems to be a re-branded ZyXEL device */ +#define BT_IGNITIONPRO_ID 0x2000 /* function prototypes */ -static int omninet_open (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); -static void omninet_close (struct tty_struct *tty, struct usb_serial_port *port, struct file *filp); -static void omninet_read_bulk_callback (struct urb *urb); -static void omninet_write_bulk_callback (struct urb *urb); -static int omninet_write (struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count); -static int omninet_write_room (struct tty_struct *tty); -static void omninet_shutdown (struct usb_serial *serial); -static int omninet_attach (struct usb_serial *serial); - -static struct usb_device_id id_table [] = { +static int omninet_open(struct tty_struct *tty, struct usb_serial_port *port, + struct file *filp); +static void omninet_close(struct tty_struct *tty, struct usb_serial_port *port, + struct file *filp); +static void omninet_read_bulk_callback(struct urb *urb); +static void omninet_write_bulk_callback(struct urb *urb); +static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, + const unsigned char *buf, int count); +static int omninet_write_room(struct tty_struct *tty); +static void omninet_shutdown(struct usb_serial *serial); +static int omninet_attach(struct usb_serial *serial); + +static struct usb_device_id id_table[] = { { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, { USB_DEVICE(ZYXEL_VENDOR_ID, BT_IGNITIONPRO_ID) }, { } /* Terminating entry */ }; -MODULE_DEVICE_TABLE (usb, id_table); +MODULE_DEVICE_TABLE(usb, id_table); static struct usb_driver omninet_driver = { .name = "omninet", @@ -130,27 +136,26 @@ static struct usb_serial_driver zyxel_omninet_device = { * */ -struct omninet_header -{ +struct omninet_header { __u8 oh_seq; __u8 oh_len; __u8 oh_xxx; __u8 oh_pad; }; -struct omninet_data -{ - __u8 od_outseq; // Sequence number for bulk_out URBs +struct omninet_data { + __u8 od_outseq; /* Sequence number for bulk_out URBs */ }; -static int omninet_attach (struct usb_serial *serial) +static int omninet_attach(struct usb_serial *serial) { struct omninet_data *od; struct usb_serial_port *port = serial->port[0]; - od = kmalloc( sizeof(struct omninet_data), GFP_KERNEL ); - if( !od ) { - err("%s- kmalloc(%Zd) failed.", __func__, sizeof(struct omninet_data)); + od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); + if (!od) { + err("%s- kmalloc(%Zd) failed.", + __func__, sizeof(struct omninet_data)); return -ENOMEM; } usb_set_serial_port_data(port, od); @@ -170,20 +175,21 @@ static int omninet_open(struct tty_struct *tty, wport->port.tty = tty; /* FIXME */ /* Start reading from the device */ - usb_fill_bulk_urb(port->read_urb, serial->dev, - usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress), - port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, - omninet_read_bulk_callback, port); + usb_fill_bulk_urb(port->read_urb, serial->dev, + usb_rcvbulkpipe(serial->dev, + port->bulk_in_endpointAddress), + port->read_urb->transfer_buffer, + port->read_urb->transfer_buffer_length, + omninet_read_bulk_callback, port); result = usb_submit_urb(port->read_urb, GFP_KERNEL); - if (result) { - err("%s - failed submitting read urb, error %d", __func__, result); - } - + if (result) + err("%s - failed submitting read urb, error %d", + __func__, result); return result; } static void omninet_close(struct tty_struct *tty, - struct usb_serial_port *port, struct file * filp) + struct usb_serial_port *port, struct file *filp) { dbg("%s - port %d", __func__, port->number); usb_kill_urb(port->read_urb); @@ -194,7 +200,7 @@ static void omninet_close(struct tty_struct *tty, #define OMNINET_HEADERLEN sizeof(struct omninet_header) #define OMNINET_BULKOUTSIZE (64 - OMNINET_HEADERLEN) -static void omninet_read_bulk_callback (struct urb *urb) +static void omninet_read_bulk_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; unsigned char *data = urb->transfer_buffer; @@ -211,31 +217,34 @@ static void omninet_read_bulk_callback (struct urb *urb) return; } - if ((debug) && (header->oh_xxx != 0x30)) { + if (debug && header->oh_xxx != 0x30) { if (urb->actual_length) { - printk (KERN_DEBUG __FILE__ ": omninet_read %d: ", header->oh_len); - for (i = 0; i < (header->oh_len + OMNINET_HEADERLEN); i++) { - printk ("%.2x ", data[i]); - } - printk ("\n"); + printk(KERN_DEBUG __FILE__ + ": omninet_read %d: ", header->oh_len); + for (i = 0; i < (header->oh_len + + OMNINET_HEADERLEN); i++) + printk("%.2x ", data[i]); + printk("\n"); } } if (urb->actual_length && header->oh_len) { - for (i = 0; i < header->oh_len; i++) { - tty_insert_flip_char(port->port.tty, data[OMNINET_DATAOFFSET + i], 0); - } - tty_flip_buffer_push(port->port.tty); + for (i = 0; i < header->oh_len; i++) + tty_insert_flip_char(port->port.tty, + data[OMNINET_DATAOFFSET + i], 0); + tty_flip_buffer_push(port->port.tty); } /* Continue trying to always read */ - usb_fill_bulk_urb(urb, port->serial->dev, - usb_rcvbulkpipe(port->serial->dev, port->bulk_in_endpointAddress), - urb->transfer_buffer, urb->transfer_buffer_length, - omninet_read_bulk_callback, port); + usb_fill_bulk_urb(urb, port->serial->dev, + usb_rcvbulkpipe(port->serial->dev, + port->bulk_in_endpointAddress), + urb->transfer_buffer, urb->transfer_buffer_length, + omninet_read_bulk_callback, port); result = usb_submit_urb(urb, GFP_ATOMIC); if (result) - err("%s - failed resubmitting read urb, error %d", __func__, result); + err("%s - failed resubmitting read urb, error %d", + __func__, result); return; } @@ -243,11 +252,12 @@ static void omninet_read_bulk_callback (struct urb *urb) static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, const unsigned char *buf, int count) { - struct usb_serial *serial = port->serial; - struct usb_serial_port *wport = serial->port[1]; + struct usb_serial *serial = port->serial; + struct usb_serial_port *wport = serial->port[1]; - struct omninet_data *od = usb_get_serial_port_data(port); - struct omninet_header *header = (struct omninet_header *) wport->write_urb->transfer_buffer; + struct omninet_data *od = usb_get_serial_port_data(port); + struct omninet_header *header = (struct omninet_header *) + wport->write_urb->transfer_buffer; int result; @@ -255,7 +265,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, if (count == 0) { dbg("%s - write request of 0 bytes", __func__); - return (0); + return 0; } spin_lock_bh(&wport->lock); @@ -269,9 +279,11 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count; - memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count); + memcpy(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, + buf, count); - usb_serial_debug_data(debug, &port->dev, __func__, count, wport->write_urb->transfer_buffer); + usb_serial_debug_data(debug, &port->dev, __func__, count, + wport->write_urb->transfer_buffer); header->oh_seq = od->od_outseq++; header->oh_len = count; @@ -285,7 +297,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, result = usb_submit_urb(wport->write_urb, GFP_ATOMIC); if (result) { wport->write_urb_busy = 0; - err("%s - failed submitting write urb, error %d", __func__, result); + err("%s - failed submitting write urb, error %d", + __func__, result); } else result = count; @@ -293,7 +306,7 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, } -static int omninet_write_room (struct tty_struct *tty) +static int omninet_write_room(struct tty_struct *tty) { struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = port->serial; @@ -307,12 +320,13 @@ static int omninet_write_room (struct tty_struct *tty) dbg("%s - returns %d", __func__, room); - return (room); + return room; } -static void omninet_write_bulk_callback (struct urb *urb) +static void omninet_write_bulk_callback(struct urb *urb) { -/* struct omninet_header *header = (struct omninet_header *) urb->transfer_buffer; */ +/* struct omninet_header *header = (struct omninet_header *) + urb->transfer_buffer; */ struct usb_serial_port *port = urb->context; int status = urb->status; @@ -329,18 +343,18 @@ static void omninet_write_bulk_callback (struct urb *urb) } -static void omninet_shutdown (struct usb_serial *serial) +static void omninet_shutdown(struct usb_serial *serial) { struct usb_serial_port *wport = serial->port[1]; struct usb_serial_port *port = serial->port[0]; - dbg ("%s", __func__); + dbg("%s", __func__); usb_kill_urb(wport->write_urb); kfree(usb_get_serial_port_data(port)); } -static int __init omninet_init (void) +static int __init omninet_init(void) { int retval; retval = usb_serial_register(&zyxel_omninet_device); @@ -358,18 +372,18 @@ failed_usb_serial_register: } -static void __exit omninet_exit (void) +static void __exit omninet_exit(void) { - usb_deregister (&omninet_driver); - usb_serial_deregister (&zyxel_omninet_device); + usb_deregister(&omninet_driver); + usb_serial_deregister(&zyxel_omninet_device); } module_init(omninet_init); module_exit(omninet_exit); -MODULE_AUTHOR( DRIVER_AUTHOR ); -MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); module_param(debug, bool, S_IRUGO | S_IWUSR); -- cgit v1.2.3-70-g09d2 From 4944d40054d73b2f8d7d546f55c206eb3baf2710 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 22 Jul 2008 11:16:03 +0100 Subject: omninet: Use string flip functions Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/usb/serial/omninet.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb/serial/omninet.c') diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 5a76f327ef5..ae8e227f3db 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c @@ -206,8 +206,8 @@ static void omninet_read_bulk_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; struct omninet_header *header = (struct omninet_header *) &data[0]; int status = urb->status; - int i; int result; + int i; dbg("%s - port %d", __func__, port->number); @@ -229,9 +229,8 @@ static void omninet_read_bulk_callback(struct urb *urb) } if (urb->actual_length && header->oh_len) { - for (i = 0; i < header->oh_len; i++) - tty_insert_flip_char(port->port.tty, - data[OMNINET_DATAOFFSET + i], 0); + tty_insert_flip_string(port->port.tty, + data + OMNINET_DATAOFFSET, header->oh_len); tty_flip_buffer_push(port->port.tty); } -- cgit v1.2.3-70-g09d2