From b748bb71b50fcea991e5c17bb3e10b5f38d21eaa Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Fri, 24 Apr 2009 18:41:49 -0700 Subject: USB: serial: sierra driver performance improvements - Version number set to 1.3.4 - Increased the number of input/output URBs for improved performance (numbers based on an measurement study triggered by a user request). We performed the testing using a network simulator that provided full speeds in the uplink and downlink directions and this combination of URBs provided the best throughput. Signed-off-by: Elina Pasheva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 17ac34f4d66..9826c85a812 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -14,7 +14,7 @@ Whom based his on the Keyspan driver by Hugh Blemings */ -#define DRIVER_VERSION "v.1.3.3" +#define DRIVER_VERSION "v.1.3.4" #define DRIVER_AUTHOR "Kevin Lloyd " #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -30,8 +30,8 @@ #define SWIMS_USB_REQUEST_SetPower 0x00 #define SWIMS_USB_REQUEST_SetNmea 0x07 -#define N_IN_URB 4 -#define N_OUT_URB 4 +#define N_IN_URB 8 +#define N_OUT_URB 64 #define IN_BUFLEN 4096 static int debug; -- cgit v1.2.3 From 5d44b36120d5b67081419d9307a526a0dfd949fc Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Mon, 27 Apr 2009 18:41:52 -0700 Subject: USB: serial: sierra driver debug info visibility improvement - Version number set to 1.3.5 - Added "\n" at the end of each string in dev_dbg() code to improve the debug information visibility. Without this change the debug logs are very difficult to read. Signed-off-by: Elina Pasheva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 9826c85a812..f75688416b6 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -14,7 +14,7 @@ Whom based his on the Keyspan driver by Hugh Blemings */ -#define DRIVER_VERSION "v.1.3.4" +#define DRIVER_VERSION "v.1.3.5" #define DRIVER_AUTHOR "Kevin Lloyd " #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -46,7 +46,7 @@ struct sierra_iface_info { static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) { int result; - dev_dbg(&udev->dev, "%s", __func__); + dev_dbg(&udev->dev, "%s\n", __func__); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), SWIMS_USB_REQUEST_SetPower, /* __u8 request */ USB_TYPE_VENDOR, /* __u8 request type */ @@ -61,7 +61,7 @@ static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) { int result; - dev_dbg(&udev->dev, "%s", __func__); + dev_dbg(&udev->dev, "%s\n", __func__); result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), SWIMS_USB_REQUEST_SetNmea, /* __u8 request */ USB_TYPE_VENDOR, /* __u8 request type */ @@ -77,7 +77,7 @@ static int sierra_calc_num_ports(struct usb_serial *serial) { int result; int *num_ports = usb_get_serial_data(serial); - dev_dbg(&serial->dev->dev, "%s", __func__); + dev_dbg(&serial->dev->dev, "%s\n", __func__); result = *num_ports; @@ -111,7 +111,7 @@ static int sierra_calc_interface(struct usb_serial *serial) int interface; struct usb_interface *p_interface; struct usb_host_interface *p_host_interface; - dev_dbg(&serial->dev->dev, "%s", __func__); + dev_dbg(&serial->dev->dev, "%s\n", __func__); /* Get the interface structure pointer from the serial struct */ p_interface = serial->interface; @@ -136,7 +136,7 @@ static int sierra_probe(struct usb_serial *serial, u8 ifnum; u8 numendpoints; - dev_dbg(&serial->dev->dev, "%s", __func__); + dev_dbg(&serial->dev->dev, "%s\n", __func__); num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); if (!num_ports) @@ -289,7 +289,7 @@ static int sierra_send_setup(struct usb_serial_port *port) __u16 interface = 0; int val = 0; - dev_dbg(&port->dev, "%s", __func__); + dev_dbg(&port->dev, "%s\n", __func__); portdata = usb_get_serial_port_data(port); @@ -332,7 +332,7 @@ static int sierra_send_setup(struct usb_serial_port *port) static void sierra_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { - dev_dbg(&port->dev, "%s", __func__); + dev_dbg(&port->dev, "%s\n", __func__); tty_termios_copy_hw(tty->termios, old_termios); sierra_send_setup(port); } @@ -343,7 +343,7 @@ static int sierra_tiocmget(struct tty_struct *tty, struct file *file) unsigned int value; struct sierra_port_private *portdata; - dev_dbg(&port->dev, "%s", __func__); + dev_dbg(&port->dev, "%s\n", __func__); portdata = usb_get_serial_port_data(port); value = ((portdata->rts_state) ? TIOCM_RTS : 0) | @@ -394,14 +394,14 @@ static void sierra_outdat_callback(struct urb *urb) int status = urb->status; unsigned long flags; - dev_dbg(&port->dev, "%s - port %d", __func__, port->number); + dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); /* free up the transfer buffer, as usb_free_urb() does not do this */ kfree(urb->transfer_buffer); if (status) dev_dbg(&port->dev, "%s - nonzero write bulk status " - "received: %d", __func__, status); + "received: %d\n", __func__, status); spin_lock_irqsave(&portdata->lock, flags); --portdata->outstanding_urbs; @@ -423,7 +423,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, portdata = usb_get_serial_port_data(port); - dev_dbg(&port->dev, "%s: write (%d chars)", __func__, count); + dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count); spin_lock_irqsave(&portdata->lock, flags); if (portdata->outstanding_urbs > N_OUT_URB) { @@ -498,7 +498,7 @@ static void sierra_indat_callback(struct urb *urb) if (status) { dev_dbg(&port->dev, "%s: nonzero status: %d on" - " endpoint %02x.", __func__, status, endpoint); + " endpoint %02x\n", __func__, status, endpoint); } else { if (urb->actual_length) { tty = tty_port_tty_get(&port->port); @@ -508,7 +508,7 @@ static void sierra_indat_callback(struct urb *urb) tty_kref_put(tty); } else dev_dbg(&port->dev, "%s: empty read urb" - " received", __func__); + " received\n", __func__); /* Resubmit urb so we continue receiving */ if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { @@ -529,8 +529,8 @@ static void sierra_instat_callback(struct urb *urb) struct sierra_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; - dev_dbg(&port->dev, "%s", __func__); - dev_dbg(&port->dev, "%s: urb %p port %p has data %p", __func__, + dev_dbg(&port->dev, "%s\n", __func__); + dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__, urb, port, portdata); if (status == 0) { @@ -550,7 +550,7 @@ static void sierra_instat_callback(struct urb *urb) sizeof(struct usb_ctrlrequest)); struct tty_struct *tty; - dev_dbg(&port->dev, "%s: signal x%x", __func__, + dev_dbg(&port->dev, "%s: signal x%x\n", __func__, signals); old_dcd_state = portdata->dcd_state; @@ -565,12 +565,12 @@ static void sierra_instat_callback(struct urb *urb) tty_hangup(tty); tty_kref_put(tty); } else { - dev_dbg(&port->dev, "%s: type %x req %x", + dev_dbg(&port->dev, "%s: type %x req %x\n", __func__, req_pkt->bRequestType, req_pkt->bRequest); } } else - dev_dbg(&port->dev, "%s: error %d", __func__, status); + dev_dbg(&port->dev, "%s: error %d\n", __func__, status); /* Resubmit urb so we continue receiving IRQ data */ if (status != -ESHUTDOWN) { @@ -578,7 +578,7 @@ static void sierra_instat_callback(struct urb *urb) err = usb_submit_urb(urb, GFP_ATOMIC); if (err) dev_dbg(&port->dev, "%s: resubmit intr urb " - "failed. (%d)", __func__, err); + "failed. (%d)\n", __func__, err); } } @@ -588,7 +588,7 @@ static int sierra_write_room(struct tty_struct *tty) struct sierra_port_private *portdata = usb_get_serial_port_data(port); unsigned long flags; - dev_dbg(&port->dev, "%s - port %d", __func__, port->number); + dev_dbg(&port->dev, "%s - port %d\n", __func__, port->number); /* try to give a good number back based on if we have any free urbs at * this point in time */ @@ -729,7 +729,7 @@ static int sierra_open(struct tty_struct *tty, portdata = usb_get_serial_port_data(port); - dev_dbg(&port->dev, "%s", __func__); + dev_dbg(&port->dev, "%s\n", __func__); /* Set some sane defaults */ portdata->rts_state = 1; @@ -782,7 +782,7 @@ static int sierra_startup(struct usb_serial *serial) struct sierra_port_private *portdata; int i; - dev_dbg(&serial->dev->dev, "%s", __func__); + dev_dbg(&serial->dev->dev, "%s\n", __func__); /* Set Device mode to D0 */ sierra_set_power_state(serial->dev, 0x0000); @@ -797,7 +797,7 @@ static int sierra_startup(struct usb_serial *serial) portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); if (!portdata) { dev_dbg(&port->dev, "%s: kmalloc for " - "sierra_port_private (%d) failed!.", + "sierra_port_private (%d) failed!.\n", __func__, i); return -ENOMEM; } @@ -815,7 +815,7 @@ static void sierra_shutdown(struct usb_serial *serial) struct usb_serial_port *port; struct sierra_port_private *portdata; - dev_dbg(&serial->dev->dev, "%s", __func__); + dev_dbg(&serial->dev->dev, "%s\n", __func__); for (i = 0; i < serial->num_ports; ++i) { port = serial->port[i]; -- cgit v1.2.3 From 40d2ff32f102e69d482480265ec60ffb86b028de Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Wed, 29 Apr 2009 10:26:46 -0700 Subject: USB: serial: sierra driver write path improvements - Updated Copyright notice with new authors names - Version number set to 1.3.6 - Added a MAX_TRANSFER constant following Greg Kroah-Hartman's recommended setting of PAGE_SIZE-512 for USB transfer buffers and modified accordingly sierra_write() function. Signed-off-by: Elina Pasheva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 52 ++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index f75688416b6..27f41f95aef 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -1,7 +1,10 @@ /* USB Driver for Sierra Wireless - Copyright (C) 2006, 2007, 2008 Kevin Lloyd + Copyright (C) 2006, 2007, 2008 Kevin Lloyd , + + Copyright (C) 2008, 2009 Elina Pasheva, Matthew Safar, Rory Filer + IMPORTANT DISCLAIMER: This driver is not commercially supported by Sierra Wireless. Use at your own risk. @@ -14,8 +17,8 @@ Whom based his on the Keyspan driver by Hugh Blemings */ -#define DRIVER_VERSION "v.1.3.5" -#define DRIVER_AUTHOR "Kevin Lloyd " +#define DRIVER_VERSION "v.1.3.6" +#define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" #include @@ -34,6 +37,11 @@ #define N_OUT_URB 64 #define IN_BUFLEN 4096 +#define MAX_TRANSFER (PAGE_SIZE - 512) +/* MAX_TRANSFER is chosen so that the VM is not stressed by + allocations > PAGE_SIZE and the number of packets in a page + is an integer 512 is the largest possible packet on EHCI */ + static int debug; static int nmea; @@ -419,50 +427,58 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, unsigned long flags; unsigned char *buffer; struct urb *urb; - int status; + size_t writesize = min((size_t)count, (size_t)MAX_TRANSFER); + int retval = 0; + + /* verify that we actually have some data to write */ + if (count == 0) + return 0; portdata = usb_get_serial_port_data(port); - dev_dbg(&port->dev, "%s: write (%d chars)\n", __func__, count); + dev_dbg(&port->dev, "%s: write (%d bytes)\n", __func__, writesize); spin_lock_irqsave(&portdata->lock, flags); + dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, + portdata->outstanding_urbs); if (portdata->outstanding_urbs > N_OUT_URB) { spin_unlock_irqrestore(&portdata->lock, flags); dev_dbg(&port->dev, "%s - write limit hit\n", __func__); return 0; } portdata->outstanding_urbs++; + dev_dbg(&port->dev, "%s - 1, outstanding_urbs: %d\n", __func__, + portdata->outstanding_urbs); spin_unlock_irqrestore(&portdata->lock, flags); - buffer = kmalloc(count, GFP_ATOMIC); + buffer = kmalloc(writesize, GFP_ATOMIC); if (!buffer) { dev_err(&port->dev, "out of memory\n"); - count = -ENOMEM; + retval = -ENOMEM; goto error_no_buffer; } urb = usb_alloc_urb(0, GFP_ATOMIC); if (!urb) { dev_err(&port->dev, "no more free urbs\n"); - count = -ENOMEM; + retval = -ENOMEM; goto error_no_urb; } - memcpy(buffer, buf, count); + memcpy(buffer, buf, writesize); - usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); + usb_serial_debug_data(debug, &port->dev, __func__, writesize, buffer); usb_fill_bulk_urb(urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), - buffer, count, sierra_outdat_callback, port); + buffer, writesize, sierra_outdat_callback, port); /* send it down the pipe */ - status = usb_submit_urb(urb, GFP_ATOMIC); - if (status) { + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) { dev_err(&port->dev, "%s - usb_submit_urb(write bulk) failed " - "with status = %d\n", __func__, status); - count = status; + "with status = %d\n", __func__, retval); goto error; } @@ -470,7 +486,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, * really free it when it is finished with it */ usb_free_urb(urb); - return count; + return writesize; error: usb_free_urb(urb); error_no_urb: @@ -478,8 +494,10 @@ error_no_urb: error_no_buffer: spin_lock_irqsave(&portdata->lock, flags); --portdata->outstanding_urbs; + dev_dbg(&port->dev, "%s - 2. outstanding_urbs: %d\n", __func__, + portdata->outstanding_urbs); spin_unlock_irqrestore(&portdata->lock, flags); - return count; + return retval; } static void sierra_indat_callback(struct urb *urb) -- cgit v1.2.3 From b0cda8c5f7b652c6c27bcb3891d174534d2f1a91 Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Wed, 29 Apr 2009 10:29:21 -0700 Subject: USB: serial: sierra driver read path bug fix This patch fixes a problem in function sierra_indat_callback() which would stop receiving traffic from a modem if a number of URB failures occur. Failed URBs are not resubmitted for the next read and there is only a limited number of URBs allocated for the IN path. After this number of failures, the receive path stops working on a particular interface. Signed-off-by: Elina Pasheva --- drivers/usb/serial/sierra.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 27f41f95aef..f494c5f659e 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -509,10 +509,10 @@ static void sierra_indat_callback(struct urb *urb) unsigned char *data = urb->transfer_buffer; int status = urb->status; - dbg("%s: %p", __func__, urb); - endpoint = usb_pipeendpoint(urb->pipe); - port = urb->context; + port = urb->context; + + dev_dbg(&port->dev, "%s: %p\n", __func__, urb); if (status) { dev_dbg(&port->dev, "%s: nonzero status: %d on" @@ -520,22 +520,28 @@ static void sierra_indat_callback(struct urb *urb) } else { if (urb->actual_length) { tty = tty_port_tty_get(&port->port); + tty_buffer_request_room(tty, urb->actual_length); tty_insert_flip_string(tty, data, urb->actual_length); tty_flip_buffer_push(tty); + tty_kref_put(tty); - } else + usb_serial_debug_data(debug, &port->dev, __func__, + urb->actual_length, data); + } else { dev_dbg(&port->dev, "%s: empty read urb" " received\n", __func__); - - /* Resubmit urb so we continue receiving */ - if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err) - dev_err(&port->dev, "resubmit read urb failed." - "(%d)\n", err); } } + + /* Resubmit urb so we continue receiving */ + if (port->port.count && status != -ESHUTDOWN && status != -EPERM) { + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err) + dev_err(&port->dev, "resubmit read urb failed." + "(%d)\n", err); + } + return; } -- cgit v1.2.3 From 238ebd138c9704e1162030c1e600bc06142cb2c8 Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Tue, 12 May 2009 13:12:24 -0700 Subject: USB: serial: sierra driver zero length packet fix - Fixed a problem with transferring packets with size a multiple of Bulk Xfer size in function sierra_write(). Added transfer flag URB_ZERO_PACKET before submitting the urb to trigger Zero-length data transfer when packet size is a multiple of Bulk Xfer. Signed-off-by: Elina Pasheva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index f494c5f659e..9d11fe47633 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -17,7 +17,7 @@ Whom based his on the Keyspan driver by Hugh Blemings */ -#define DRIVER_VERSION "v.1.3.6" +#define DRIVER_VERSION "v.1.3.7" #define DRIVER_AUTHOR "Kevin Lloyd, Elina Pasheva, Matthew Safar, Rory Filer" #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" @@ -474,6 +474,9 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, port->bulk_out_endpointAddress), buffer, writesize, sierra_outdat_callback, port); + /* Handle the need to send a zero length packet */ + urb->transfer_flags |= URB_ZERO_PACKET; + /* send it down the pipe */ retval = usb_submit_urb(urb, GFP_ATOMIC); if (retval) { -- cgit v1.2.3 From c76a23da8e9a39222c4a7c29b0c5348cd8902a2b Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Tue, 12 May 2009 13:12:37 -0700 Subject: USB: serial: sierra driver interrupt urb resubmit fix - Fixed a problem when re-submitting urb from interrupt callback in function sierra_instat_callback(). This suppresses also issuing of error messages in /var/log/kern.log - Removed redundant debug message at the beginning of sierra_instat_callback() function - Changed a debug message to be an error message Signed-off-by: Elina Pasheva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 9d11fe47633..bcfe0ac1e22 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -556,7 +556,6 @@ static void sierra_instat_callback(struct urb *urb) struct sierra_port_private *portdata = usb_get_serial_port_data(port); struct usb_serial *serial = port->serial; - dev_dbg(&port->dev, "%s\n", __func__); dev_dbg(&port->dev, "%s: urb %p port %p has data %p\n", __func__, urb, port, portdata); @@ -600,12 +599,12 @@ static void sierra_instat_callback(struct urb *urb) dev_dbg(&port->dev, "%s: error %d\n", __func__, status); /* Resubmit urb so we continue receiving IRQ data */ - if (status != -ESHUTDOWN) { + if (port->port.count && status != -ESHUTDOWN && status != -ENOENT) { urb->dev = serial->dev; err = usb_submit_urb(urb, GFP_ATOMIC); if (err) - dev_dbg(&port->dev, "%s: resubmit intr urb " - "failed. (%d)\n", __func__, err); + dev_err(&port->dev, "%s: resubmit intr urb " + "failed. (%d)\n", __func__, err); } } -- cgit v1.2.3 From 9636b683769a6c3acfe121314ee9d7e19157f109 Mon Sep 17 00:00:00 2001 From: Elina Pasheva Date: Tue, 12 May 2009 13:12:54 -0700 Subject: USB: serial: sierra driver sierra_calc_num_ports() fix - Removed potential kernel oops from sierra_calc_num_ports() function. Calling this function twice would likely have caused an oops because the function releases allocated memory after the first call. - Modified sierra_probe() function to reflect the changes in sierra_calc_num_ports(). Signed-off-by: Elina Pasheva Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 49 +++++++++++++-------------------------------- 1 file changed, 14 insertions(+), 35 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index bcfe0ac1e22..f047ab5fa97 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -83,18 +83,22 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) static int sierra_calc_num_ports(struct usb_serial *serial) { - int result; - int *num_ports = usb_get_serial_data(serial); - dev_dbg(&serial->dev->dev, "%s\n", __func__); + int num_ports = 0; + u8 ifnum, numendpoints; - result = *num_ports; + dev_dbg(&serial->dev->dev, "%s\n", __func__); - if (result) { - kfree(num_ports); - usb_set_serial_data(serial, NULL); - } + ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; + numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints; - return result; + /* Dummy interface present on some SKUs should be ignored */ + if (ifnum == 0x99) + num_ports = 0; + else if (numendpoints <= 3) + num_ports = 1; + else + num_ports = (numendpoints-1)/2; + return num_ports; } static int is_blacklisted(const u8 ifnum, @@ -140,23 +144,12 @@ static int sierra_probe(struct usb_serial *serial, { int result = 0; struct usb_device *udev; - int *num_ports; u8 ifnum; - u8 numendpoints; - - dev_dbg(&serial->dev->dev, "%s\n", __func__); - num_ports = kmalloc(sizeof(*num_ports), GFP_KERNEL); - if (!num_ports) - return -ENOMEM; - - ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; - numendpoints = serial->interface->cur_altsetting->desc.bNumEndpoints; udev = serial->dev; + dev_dbg(&udev->dev, "%s\n", __func__); - /* Figure out the interface number from the serial structure */ ifnum = sierra_calc_interface(serial); - /* * If this interface supports more than 1 alternate * select the 2nd one @@ -168,20 +161,6 @@ static int sierra_probe(struct usb_serial *serial, usb_set_interface(udev, ifnum, 1); } - /* Dummy interface present on some SKUs should be ignored */ - if (ifnum == 0x99) - *num_ports = 0; - else if (numendpoints <= 3) - *num_ports = 1; - else - *num_ports = (numendpoints-1)/2; - - /* - * save off our num_ports info so that we can use it in the - * calc_num_ports callback - */ - usb_set_serial_data(serial, (void *)num_ports); - /* ifnum could have changed - by calling usb_set_interface */ ifnum = sierra_calc_interface(serial); -- cgit v1.2.3 From 0b10395ab86c11bef10e882a4323367e6735c9b2 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 12 May 2009 15:27:59 -0700 Subject: + drivers-usb-serial-sierrac-fix-printk-warning.patch added to -mm tree drivers/usb/serial/sierra.c: In function 'sierra_write': drivers/usb/serial/sierra.c:375: warning: format '%d' expects type 'int', but argument 5 has type 'size_t' Signed-off-by: Andrew Morton Cc: Elina Pasheva Cc: Rory Filer Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index f047ab5fa97..a88cde95016 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -415,7 +415,7 @@ static int sierra_write(struct tty_struct *tty, struct usb_serial_port *port, portdata = usb_get_serial_port_data(port); - dev_dbg(&port->dev, "%s: write (%d bytes)\n", __func__, writesize); + dev_dbg(&port->dev, "%s: write (%zd bytes)\n", __func__, writesize); spin_lock_irqsave(&portdata->lock, flags); dev_dbg(&port->dev, "%s - outstanding_urbs: %d\n", __func__, -- cgit v1.2.3 From f9c99bb8b3a1ec81af68d484a551307326c2e933 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 2 Jun 2009 11:53:55 -0400 Subject: USB: usb-serial: replace shutdown with disconnect, release This patch (as1254) splits up the shutdown method of usb_serial_driver into a disconnect and a release method. The problem is that the usb-serial core was calling shutdown during disconnect handling, but drivers didn't expect it to be called until after all the open file references had been closed. The result was an oops when the close method tried to use memory that had been deallocated by shutdown. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/sierra.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/usb/serial/sierra.c') diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index a88cde95016..032f7aeb40a 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -814,7 +814,7 @@ static int sierra_startup(struct usb_serial *serial) return 0; } -static void sierra_shutdown(struct usb_serial *serial) +static void sierra_disconnect(struct usb_serial *serial) { int i; struct usb_serial_port *port; @@ -853,7 +853,7 @@ static struct usb_serial_driver sierra_device = { .tiocmget = sierra_tiocmget, .tiocmset = sierra_tiocmset, .attach = sierra_startup, - .shutdown = sierra_shutdown, + .disconnect = sierra_disconnect, .read_int_callback = sierra_instat_callback, }; -- cgit v1.2.3