diff options
Diffstat (limited to 'drivers/usb/serial/option.c')
-rw-r--r-- | drivers/usb/serial/option.c | 144 |
1 files changed, 122 insertions, 22 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index c784ddbe7b61..f66e39883218 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -45,8 +45,7 @@ | |||
45 | /* Function prototypes */ | 45 | /* Function prototypes */ |
46 | static int option_probe(struct usb_serial *serial, | 46 | static int option_probe(struct usb_serial *serial, |
47 | const struct usb_device_id *id); | 47 | const struct usb_device_id *id); |
48 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port, | 48 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port); |
49 | struct file *filp); | ||
50 | static void option_close(struct usb_serial_port *port); | 49 | static void option_close(struct usb_serial_port *port); |
51 | static void option_dtr_rts(struct usb_serial_port *port, int on); | 50 | static void option_dtr_rts(struct usb_serial_port *port, int on); |
52 | 51 | ||
@@ -292,6 +291,7 @@ static int option_resume(struct usb_serial *serial); | |||
292 | 291 | ||
293 | #define TELIT_VENDOR_ID 0x1bc7 | 292 | #define TELIT_VENDOR_ID 0x1bc7 |
294 | #define TELIT_PRODUCT_UC864E 0x1003 | 293 | #define TELIT_PRODUCT_UC864E 0x1003 |
294 | #define TELIT_PRODUCT_UC864G 0x1004 | ||
295 | 295 | ||
296 | /* ZTE PRODUCTS */ | 296 | /* ZTE PRODUCTS */ |
297 | #define ZTE_VENDOR_ID 0x19d2 | 297 | #define ZTE_VENDOR_ID 0x19d2 |
@@ -300,6 +300,7 @@ static int option_resume(struct usb_serial *serial); | |||
300 | #define ZTE_PRODUCT_MF626 0x0031 | 300 | #define ZTE_PRODUCT_MF626 0x0031 |
301 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | 301 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe |
302 | #define ZTE_PRODUCT_AC8710 0xfff1 | 302 | #define ZTE_PRODUCT_AC8710 0xfff1 |
303 | #define ZTE_PRODUCT_AC2726 0xfff5 | ||
303 | 304 | ||
304 | #define BENQ_VENDOR_ID 0x04a5 | 305 | #define BENQ_VENDOR_ID 0x04a5 |
305 | #define BENQ_PRODUCT_H10 0x4068 | 306 | #define BENQ_PRODUCT_H10 0x4068 |
@@ -503,6 +504,7 @@ static struct usb_device_id option_ids[] = { | |||
503 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 504 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
504 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 505 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
505 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 506 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
507 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864G) }, | ||
506 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ | 508 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */ |
507 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, | 509 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0002, 0xff, 0xff, 0xff) }, |
508 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, | 510 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0003, 0xff, 0xff, 0xff) }, |
@@ -572,6 +574,7 @@ static struct usb_device_id option_ids[] = { | |||
572 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, | 574 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, |
573 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, | 575 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, |
574 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, | 576 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, |
577 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) }, | ||
575 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, | 578 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
576 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, | 579 | { USB_DEVICE(DLINK_VENDOR_ID, DLINK_PRODUCT_DWM_652) }, |
577 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, | 580 | { USB_DEVICE(QISDA_VENDOR_ID, QISDA_PRODUCT_H21_4512) }, |
@@ -593,6 +596,7 @@ static struct usb_driver option_driver = { | |||
593 | #ifdef CONFIG_PM | 596 | #ifdef CONFIG_PM |
594 | .suspend = usb_serial_suspend, | 597 | .suspend = usb_serial_suspend, |
595 | .resume = usb_serial_resume, | 598 | .resume = usb_serial_resume, |
599 | .supports_autosuspend = 1, | ||
596 | #endif | 600 | #endif |
597 | .id_table = option_ids, | 601 | .id_table = option_ids, |
598 | .no_dynamic_id = 1, | 602 | .no_dynamic_id = 1, |
@@ -640,6 +644,12 @@ static int debug; | |||
640 | #define IN_BUFLEN 4096 | 644 | #define IN_BUFLEN 4096 |
641 | #define OUT_BUFLEN 4096 | 645 | #define OUT_BUFLEN 4096 |
642 | 646 | ||
647 | struct option_intf_private { | ||
648 | spinlock_t susp_lock; | ||
649 | unsigned int suspended:1; | ||
650 | int in_flight; | ||
651 | }; | ||
652 | |||
643 | struct option_port_private { | 653 | struct option_port_private { |
644 | /* Input endpoints and buffer for this port */ | 654 | /* Input endpoints and buffer for this port */ |
645 | struct urb *in_urbs[N_IN_URB]; | 655 | struct urb *in_urbs[N_IN_URB]; |
@@ -648,6 +658,8 @@ struct option_port_private { | |||
648 | struct urb *out_urbs[N_OUT_URB]; | 658 | struct urb *out_urbs[N_OUT_URB]; |
649 | u8 *out_buffer[N_OUT_URB]; | 659 | u8 *out_buffer[N_OUT_URB]; |
650 | unsigned long out_busy; /* Bit vector of URBs in use */ | 660 | unsigned long out_busy; /* Bit vector of URBs in use */ |
661 | int opened; | ||
662 | struct usb_anchor delayed; | ||
651 | 663 | ||
652 | /* Settings for the port */ | 664 | /* Settings for the port */ |
653 | int rts_state; /* Handshaking pins (outputs) */ | 665 | int rts_state; /* Handshaking pins (outputs) */ |
@@ -694,12 +706,17 @@ module_exit(option_exit); | |||
694 | static int option_probe(struct usb_serial *serial, | 706 | static int option_probe(struct usb_serial *serial, |
695 | const struct usb_device_id *id) | 707 | const struct usb_device_id *id) |
696 | { | 708 | { |
709 | struct option_intf_private *data; | ||
697 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ | 710 | /* D-Link DWM 652 still exposes CD-Rom emulation interface in modem mode */ |
698 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && | 711 | if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && |
699 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && | 712 | serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && |
700 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) | 713 | serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) |
701 | return -ENODEV; | 714 | return -ENODEV; |
702 | 715 | ||
716 | data = serial->private = kzalloc(sizeof(struct option_intf_private), GFP_KERNEL); | ||
717 | if (!data) | ||
718 | return -ENOMEM; | ||
719 | spin_lock_init(&data->susp_lock); | ||
703 | return 0; | 720 | return 0; |
704 | } | 721 | } |
705 | 722 | ||
@@ -756,12 +773,15 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
756 | const unsigned char *buf, int count) | 773 | const unsigned char *buf, int count) |
757 | { | 774 | { |
758 | struct option_port_private *portdata; | 775 | struct option_port_private *portdata; |
776 | struct option_intf_private *intfdata; | ||
759 | int i; | 777 | int i; |
760 | int left, todo; | 778 | int left, todo; |
761 | struct urb *this_urb = NULL; /* spurious */ | 779 | struct urb *this_urb = NULL; /* spurious */ |
762 | int err; | 780 | int err; |
781 | unsigned long flags; | ||
763 | 782 | ||
764 | portdata = usb_get_serial_port_data(port); | 783 | portdata = usb_get_serial_port_data(port); |
784 | intfdata = port->serial->private; | ||
765 | 785 | ||
766 | dbg("%s: write (%d chars)", __func__, count); | 786 | dbg("%s: write (%d chars)", __func__, count); |
767 | 787 | ||
@@ -783,17 +803,33 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
783 | dbg("%s: endpoint %d buf %d", __func__, | 803 | dbg("%s: endpoint %d buf %d", __func__, |
784 | usb_pipeendpoint(this_urb->pipe), i); | 804 | usb_pipeendpoint(this_urb->pipe), i); |
785 | 805 | ||
806 | err = usb_autopm_get_interface_async(port->serial->interface); | ||
807 | if (err < 0) | ||
808 | break; | ||
809 | |||
786 | /* send the data */ | 810 | /* send the data */ |
787 | memcpy(this_urb->transfer_buffer, buf, todo); | 811 | memcpy(this_urb->transfer_buffer, buf, todo); |
788 | this_urb->transfer_buffer_length = todo; | 812 | this_urb->transfer_buffer_length = todo; |
789 | 813 | ||
790 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | 814 | spin_lock_irqsave(&intfdata->susp_lock, flags); |
791 | if (err) { | 815 | if (intfdata->suspended) { |
792 | dbg("usb_submit_urb %p (write bulk) failed " | 816 | usb_anchor_urb(this_urb, &portdata->delayed); |
793 | "(%d)", this_urb, err); | 817 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); |
794 | clear_bit(i, &portdata->out_busy); | 818 | } else { |
795 | continue; | 819 | intfdata->in_flight++; |
820 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
821 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
822 | if (err) { | ||
823 | dbg("usb_submit_urb %p (write bulk) failed " | ||
824 | "(%d)", this_urb, err); | ||
825 | clear_bit(i, &portdata->out_busy); | ||
826 | spin_lock_irqsave(&intfdata->susp_lock, flags); | ||
827 | intfdata->in_flight--; | ||
828 | spin_unlock_irqrestore(&intfdata->susp_lock, flags); | ||
829 | continue; | ||
830 | } | ||
796 | } | 831 | } |
832 | |||
797 | portdata->tx_start_time[i] = jiffies; | 833 | portdata->tx_start_time[i] = jiffies; |
798 | buf += todo; | 834 | buf += todo; |
799 | left -= todo; | 835 | left -= todo; |
@@ -837,7 +873,10 @@ static void option_indat_callback(struct urb *urb) | |||
837 | if (err) | 873 | if (err) |
838 | printk(KERN_ERR "%s: resubmit read urb failed. " | 874 | printk(KERN_ERR "%s: resubmit read urb failed. " |
839 | "(%d)", __func__, err); | 875 | "(%d)", __func__, err); |
876 | else | ||
877 | usb_mark_last_busy(port->serial->dev); | ||
840 | } | 878 | } |
879 | |||
841 | } | 880 | } |
842 | return; | 881 | return; |
843 | } | 882 | } |
@@ -846,15 +885,21 @@ static void option_outdat_callback(struct urb *urb) | |||
846 | { | 885 | { |
847 | struct usb_serial_port *port; | 886 | struct usb_serial_port *port; |
848 | struct option_port_private *portdata; | 887 | struct option_port_private *portdata; |
888 | struct option_intf_private *intfdata; | ||
849 | int i; | 889 | int i; |
850 | 890 | ||
851 | dbg("%s", __func__); | 891 | dbg("%s", __func__); |
852 | 892 | ||
853 | port = urb->context; | 893 | port = urb->context; |
894 | intfdata = port->serial->private; | ||
854 | 895 | ||
855 | usb_serial_port_softint(port); | 896 | usb_serial_port_softint(port); |
856 | 897 | usb_autopm_put_interface_async(port->serial->interface); | |
857 | portdata = usb_get_serial_port_data(port); | 898 | portdata = usb_get_serial_port_data(port); |
899 | spin_lock(&intfdata->susp_lock); | ||
900 | intfdata->in_flight--; | ||
901 | spin_unlock(&intfdata->susp_lock); | ||
902 | |||
858 | for (i = 0; i < N_OUT_URB; ++i) { | 903 | for (i = 0; i < N_OUT_URB; ++i) { |
859 | if (portdata->out_urbs[i] == urb) { | 904 | if (portdata->out_urbs[i] == urb) { |
860 | smp_mb__before_clear_bit(); | 905 | smp_mb__before_clear_bit(); |
@@ -961,14 +1006,16 @@ static int option_chars_in_buffer(struct tty_struct *tty) | |||
961 | return data_len; | 1006 | return data_len; |
962 | } | 1007 | } |
963 | 1008 | ||
964 | static int option_open(struct tty_struct *tty, | 1009 | static int option_open(struct tty_struct *tty, struct usb_serial_port *port) |
965 | struct usb_serial_port *port, struct file *filp) | ||
966 | { | 1010 | { |
967 | struct option_port_private *portdata; | 1011 | struct option_port_private *portdata; |
1012 | struct option_intf_private *intfdata; | ||
1013 | struct usb_serial *serial = port->serial; | ||
968 | int i, err; | 1014 | int i, err; |
969 | struct urb *urb; | 1015 | struct urb *urb; |
970 | 1016 | ||
971 | portdata = usb_get_serial_port_data(port); | 1017 | portdata = usb_get_serial_port_data(port); |
1018 | intfdata = serial->private; | ||
972 | 1019 | ||
973 | dbg("%s", __func__); | 1020 | dbg("%s", __func__); |
974 | 1021 | ||
@@ -987,6 +1034,12 @@ static int option_open(struct tty_struct *tty, | |||
987 | 1034 | ||
988 | option_send_setup(port); | 1035 | option_send_setup(port); |
989 | 1036 | ||
1037 | serial->interface->needs_remote_wakeup = 1; | ||
1038 | spin_lock_irq(&intfdata->susp_lock); | ||
1039 | portdata->opened = 1; | ||
1040 | spin_unlock_irq(&intfdata->susp_lock); | ||
1041 | usb_autopm_put_interface(serial->interface); | ||
1042 | |||
990 | return 0; | 1043 | return 0; |
991 | } | 1044 | } |
992 | 1045 | ||
@@ -1011,16 +1064,23 @@ static void option_close(struct usb_serial_port *port) | |||
1011 | int i; | 1064 | int i; |
1012 | struct usb_serial *serial = port->serial; | 1065 | struct usb_serial *serial = port->serial; |
1013 | struct option_port_private *portdata; | 1066 | struct option_port_private *portdata; |
1067 | struct option_intf_private *intfdata = port->serial->private; | ||
1014 | 1068 | ||
1015 | dbg("%s", __func__); | 1069 | dbg("%s", __func__); |
1016 | portdata = usb_get_serial_port_data(port); | 1070 | portdata = usb_get_serial_port_data(port); |
1017 | 1071 | ||
1018 | if (serial->dev) { | 1072 | if (serial->dev) { |
1019 | /* Stop reading/writing urbs */ | 1073 | /* Stop reading/writing urbs */ |
1074 | spin_lock_irq(&intfdata->susp_lock); | ||
1075 | portdata->opened = 0; | ||
1076 | spin_unlock_irq(&intfdata->susp_lock); | ||
1077 | |||
1020 | for (i = 0; i < N_IN_URB; i++) | 1078 | for (i = 0; i < N_IN_URB; i++) |
1021 | usb_kill_urb(portdata->in_urbs[i]); | 1079 | usb_kill_urb(portdata->in_urbs[i]); |
1022 | for (i = 0; i < N_OUT_URB; i++) | 1080 | for (i = 0; i < N_OUT_URB; i++) |
1023 | usb_kill_urb(portdata->out_urbs[i]); | 1081 | usb_kill_urb(portdata->out_urbs[i]); |
1082 | usb_autopm_get_interface(serial->interface); | ||
1083 | serial->interface->needs_remote_wakeup = 0; | ||
1024 | } | 1084 | } |
1025 | } | 1085 | } |
1026 | 1086 | ||
@@ -1125,6 +1185,7 @@ static int option_startup(struct usb_serial *serial) | |||
1125 | __func__, i); | 1185 | __func__, i); |
1126 | return 1; | 1186 | return 1; |
1127 | } | 1187 | } |
1188 | init_usb_anchor(&portdata->delayed); | ||
1128 | 1189 | ||
1129 | for (j = 0; j < N_IN_URB; j++) { | 1190 | for (j = 0; j < N_IN_URB; j++) { |
1130 | buffer = (u8 *)__get_free_page(GFP_KERNEL); | 1191 | buffer = (u8 *)__get_free_page(GFP_KERNEL); |
@@ -1227,18 +1288,52 @@ static void option_release(struct usb_serial *serial) | |||
1227 | #ifdef CONFIG_PM | 1288 | #ifdef CONFIG_PM |
1228 | static int option_suspend(struct usb_serial *serial, pm_message_t message) | 1289 | static int option_suspend(struct usb_serial *serial, pm_message_t message) |
1229 | { | 1290 | { |
1291 | struct option_intf_private *intfdata = serial->private; | ||
1292 | int b; | ||
1293 | |||
1230 | dbg("%s entered", __func__); | 1294 | dbg("%s entered", __func__); |
1295 | |||
1296 | if (serial->dev->auto_pm) { | ||
1297 | spin_lock_irq(&intfdata->susp_lock); | ||
1298 | b = intfdata->in_flight; | ||
1299 | spin_unlock_irq(&intfdata->susp_lock); | ||
1300 | |||
1301 | if (b) | ||
1302 | return -EBUSY; | ||
1303 | } | ||
1304 | |||
1305 | spin_lock_irq(&intfdata->susp_lock); | ||
1306 | intfdata->suspended = 1; | ||
1307 | spin_unlock_irq(&intfdata->susp_lock); | ||
1231 | stop_read_write_urbs(serial); | 1308 | stop_read_write_urbs(serial); |
1232 | 1309 | ||
1233 | return 0; | 1310 | return 0; |
1234 | } | 1311 | } |
1235 | 1312 | ||
1313 | static void play_delayed(struct usb_serial_port *port) | ||
1314 | { | ||
1315 | struct option_intf_private *data; | ||
1316 | struct option_port_private *portdata; | ||
1317 | struct urb *urb; | ||
1318 | int err; | ||
1319 | |||
1320 | portdata = usb_get_serial_port_data(port); | ||
1321 | data = port->serial->private; | ||
1322 | while ((urb = usb_get_from_anchor(&portdata->delayed))) { | ||
1323 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
1324 | if (!err) | ||
1325 | data->in_flight++; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1236 | static int option_resume(struct usb_serial *serial) | 1329 | static int option_resume(struct usb_serial *serial) |
1237 | { | 1330 | { |
1238 | int err, i, j; | 1331 | int i, j; |
1239 | struct usb_serial_port *port; | 1332 | struct usb_serial_port *port; |
1240 | struct urb *urb; | 1333 | struct option_intf_private *intfdata = serial->private; |
1241 | struct option_port_private *portdata; | 1334 | struct option_port_private *portdata; |
1335 | struct urb *urb; | ||
1336 | int err = 0; | ||
1242 | 1337 | ||
1243 | dbg("%s entered", __func__); | 1338 | dbg("%s entered", __func__); |
1244 | /* get the interrupt URBs resubmitted unconditionally */ | 1339 | /* get the interrupt URBs resubmitted unconditionally */ |
@@ -1253,7 +1348,7 @@ static int option_resume(struct usb_serial *serial) | |||
1253 | if (err < 0) { | 1348 | if (err < 0) { |
1254 | err("%s: Error %d for interrupt URB of port%d", | 1349 | err("%s: Error %d for interrupt URB of port%d", |
1255 | __func__, err, i); | 1350 | __func__, err, i); |
1256 | return err; | 1351 | goto err_out; |
1257 | } | 1352 | } |
1258 | } | 1353 | } |
1259 | 1354 | ||
@@ -1261,27 +1356,32 @@ static int option_resume(struct usb_serial *serial) | |||
1261 | /* walk all ports */ | 1356 | /* walk all ports */ |
1262 | port = serial->port[i]; | 1357 | port = serial->port[i]; |
1263 | portdata = usb_get_serial_port_data(port); | 1358 | portdata = usb_get_serial_port_data(port); |
1264 | mutex_lock(&port->mutex); | ||
1265 | 1359 | ||
1266 | /* skip closed ports */ | 1360 | /* skip closed ports */ |
1267 | if (!port->port.count) { | 1361 | spin_lock_irq(&intfdata->susp_lock); |
1268 | mutex_unlock(&port->mutex); | 1362 | if (!portdata->opened) { |
1363 | spin_unlock_irq(&intfdata->susp_lock); | ||
1269 | continue; | 1364 | continue; |
1270 | } | 1365 | } |
1271 | 1366 | ||
1272 | for (j = 0; j < N_IN_URB; j++) { | 1367 | for (j = 0; j < N_IN_URB; j++) { |
1273 | urb = portdata->in_urbs[j]; | 1368 | urb = portdata->in_urbs[j]; |
1274 | err = usb_submit_urb(urb, GFP_NOIO); | 1369 | err = usb_submit_urb(urb, GFP_ATOMIC); |
1275 | if (err < 0) { | 1370 | if (err < 0) { |
1276 | mutex_unlock(&port->mutex); | ||
1277 | err("%s: Error %d for bulk URB %d", | 1371 | err("%s: Error %d for bulk URB %d", |
1278 | __func__, err, i); | 1372 | __func__, err, i); |
1279 | return err; | 1373 | spin_unlock_irq(&intfdata->susp_lock); |
1374 | goto err_out; | ||
1280 | } | 1375 | } |
1281 | } | 1376 | } |
1282 | mutex_unlock(&port->mutex); | 1377 | play_delayed(port); |
1378 | spin_unlock_irq(&intfdata->susp_lock); | ||
1283 | } | 1379 | } |
1284 | return 0; | 1380 | spin_lock_irq(&intfdata->susp_lock); |
1381 | intfdata->suspended = 0; | ||
1382 | spin_unlock_irq(&intfdata->susp_lock); | ||
1383 | err_out: | ||
1384 | return err; | ||
1285 | } | 1385 | } |
1286 | #endif | 1386 | #endif |
1287 | 1387 | ||