aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb
diff options
context:
space:
mode:
authorElina Pasheva <epasheva@sierrawireless.com>2009-10-16 15:04:54 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-10-30 17:57:33 -0400
commit3c77d5137d3f4ff41721e9b4f4812db56a6065c0 (patch)
treec64aec5e5d05e7087c8d9703b51d0d3454d2b4c4 /drivers/usb
parent40ac7b62d8c132c73a709bd83858b3419f38ec23 (diff)
USB: serial: sierra driver send_setup() autopm fix
This patch presents a fix for the autosuspend feature implementation in sierra usb serial driver for function sierra_send_setup(). Because it is possible to call sierra_send_setup() before sierra_open() or after sierra_close() we added a get/put interface activity to assure that the usb control can happen even when the device is autosuspended. Signed-off-by: Elina Pasheva <epasheva@sierrawireless.com> Tested-by: Matthew Safar <msafar@sierrawireless.com> Cc: stable <stable@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/serial/sierra.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index 45883988a005..3ec79dfc41fd 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -296,7 +296,6 @@ struct sierra_port_private {
296 int dsr_state; 296 int dsr_state;
297 int dcd_state; 297 int dcd_state;
298 int ri_state; 298 int ri_state;
299
300 unsigned int opened:1; 299 unsigned int opened:1;
301}; 300};
302 301
@@ -306,6 +305,8 @@ static int sierra_send_setup(struct usb_serial_port *port)
306 struct sierra_port_private *portdata; 305 struct sierra_port_private *portdata;
307 __u16 interface = 0; 306 __u16 interface = 0;
308 int val = 0; 307 int val = 0;
308 int do_send = 0;
309 int retval;
309 310
310 dev_dbg(&port->dev, "%s\n", __func__); 311 dev_dbg(&port->dev, "%s\n", __func__);
311 312
@@ -324,10 +325,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
324 */ 325 */
325 if (port->interrupt_in_urb) { 326 if (port->interrupt_in_urb) {
326 /* send control message */ 327 /* send control message */
327 return usb_control_msg(serial->dev, 328 do_send = 1;
328 usb_rcvctrlpipe(serial->dev, 0),
329 0x22, 0x21, val, interface,
330 NULL, 0, USB_CTRL_SET_TIMEOUT);
331 } 329 }
332 } 330 }
333 331
@@ -339,12 +337,18 @@ static int sierra_send_setup(struct usb_serial_port *port)
339 interface = 1; 337 interface = 1;
340 else if (port->bulk_out_endpointAddress == 5) 338 else if (port->bulk_out_endpointAddress == 5)
341 interface = 2; 339 interface = 2;
342 return usb_control_msg(serial->dev, 340
343 usb_rcvctrlpipe(serial->dev, 0), 341 do_send = 1;
344 0x22, 0x21, val, interface,
345 NULL, 0, USB_CTRL_SET_TIMEOUT);
346 } 342 }
347 return 0; 343 if (!do_send)
344 return 0;
345
346 usb_autopm_get_interface(serial->interface);
347 retval = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
348 0x22, 0x21, val, interface, NULL, 0, USB_CTRL_SET_TIMEOUT);
349 usb_autopm_put_interface(serial->interface);
350
351 return retval;
348} 352}
349 353
350static void sierra_set_termios(struct tty_struct *tty, 354static void sierra_set_termios(struct tty_struct *tty,