aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOliver Neukum <oliver@neukum.org>2009-07-01 10:00:32 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2009-09-23 09:46:25 -0400
commit383cedc3bb435de7a27d31a92d622413daa5cb20 (patch)
tree1e2a24ac637c3287f9dac5ee0d44cded3c84dce3
parentab26d20f3ef1105d889f702cd01fba8c6fb32f73 (diff)
USB: serial: full autosuspend support for the option driver
this adds autosupport usable even in an always online mode. - enables remote wakeup on open - autoresume for sending - timeout based autosuspend if nothing is sent or recieved - autosuspend without remote wakeup support on open/close Signed-off-by: Oliver Neukum <oliver@neukum.org> Tested-off-by: Zhao Ming <zhao.ming9@zte.com.cn> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/option.c134
1 files changed, 116 insertions, 18 deletions
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 67862d71f068..f66e39883218 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -596,6 +596,7 @@ static struct usb_driver option_driver = {
596#ifdef CONFIG_PM 596#ifdef CONFIG_PM
597 .suspend = usb_serial_suspend, 597 .suspend = usb_serial_suspend,
598 .resume = usb_serial_resume, 598 .resume = usb_serial_resume,
599 .supports_autosuspend = 1,
599#endif 600#endif
600 .id_table = option_ids, 601 .id_table = option_ids,
601 .no_dynamic_id = 1, 602 .no_dynamic_id = 1,
@@ -643,6 +644,12 @@ static int debug;
643#define IN_BUFLEN 4096 644#define IN_BUFLEN 4096
644#define OUT_BUFLEN 4096 645#define OUT_BUFLEN 4096
645 646
647struct option_intf_private {
648 spinlock_t susp_lock;
649 unsigned int suspended:1;
650 int in_flight;
651};
652
646struct option_port_private { 653struct option_port_private {
647 /* Input endpoints and buffer for this port */ 654 /* Input endpoints and buffer for this port */
648 struct urb *in_urbs[N_IN_URB]; 655 struct urb *in_urbs[N_IN_URB];
@@ -651,6 +658,8 @@ struct option_port_private {
651 struct urb *out_urbs[N_OUT_URB]; 658 struct urb *out_urbs[N_OUT_URB];
652 u8 *out_buffer[N_OUT_URB]; 659 u8 *out_buffer[N_OUT_URB];
653 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;
654 663
655 /* Settings for the port */ 664 /* Settings for the port */
656 int rts_state; /* Handshaking pins (outputs) */ 665 int rts_state; /* Handshaking pins (outputs) */
@@ -697,12 +706,17 @@ module_exit(option_exit);
697static int option_probe(struct usb_serial *serial, 706static int option_probe(struct usb_serial *serial,
698 const struct usb_device_id *id) 707 const struct usb_device_id *id)
699{ 708{
709 struct option_intf_private *data;
700 /* 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 */
701 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID && 711 if (serial->dev->descriptor.idVendor == DLINK_VENDOR_ID &&
702 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 && 712 serial->dev->descriptor.idProduct == DLINK_PRODUCT_DWM_652 &&
703 serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8) 713 serial->interface->cur_altsetting->desc.bInterfaceClass == 0x8)
704 return -ENODEV; 714 return -ENODEV;
705 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);
706 return 0; 720 return 0;
707} 721}
708 722
@@ -759,12 +773,15 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
759 const unsigned char *buf, int count) 773 const unsigned char *buf, int count)
760{ 774{
761 struct option_port_private *portdata; 775 struct option_port_private *portdata;
776 struct option_intf_private *intfdata;
762 int i; 777 int i;
763 int left, todo; 778 int left, todo;
764 struct urb *this_urb = NULL; /* spurious */ 779 struct urb *this_urb = NULL; /* spurious */
765 int err; 780 int err;
781 unsigned long flags;
766 782
767 portdata = usb_get_serial_port_data(port); 783 portdata = usb_get_serial_port_data(port);
784 intfdata = port->serial->private;
768 785
769 dbg("%s: write (%d chars)", __func__, count); 786 dbg("%s: write (%d chars)", __func__, count);
770 787
@@ -786,17 +803,33 @@ static int option_write(struct tty_struct *tty, struct usb_serial_port *port,
786 dbg("%s: endpoint %d buf %d", __func__, 803 dbg("%s: endpoint %d buf %d", __func__,
787 usb_pipeendpoint(this_urb->pipe), i); 804 usb_pipeendpoint(this_urb->pipe), i);
788 805
806 err = usb_autopm_get_interface_async(port->serial->interface);
807 if (err < 0)
808 break;
809
789 /* send the data */ 810 /* send the data */
790 memcpy(this_urb->transfer_buffer, buf, todo); 811 memcpy(this_urb->transfer_buffer, buf, todo);
791 this_urb->transfer_buffer_length = todo; 812 this_urb->transfer_buffer_length = todo;
792 813
793 err = usb_submit_urb(this_urb, GFP_ATOMIC); 814 spin_lock_irqsave(&intfdata->susp_lock, flags);
794 if (err) { 815 if (intfdata->suspended) {
795 dbg("usb_submit_urb %p (write bulk) failed " 816 usb_anchor_urb(this_urb, &portdata->delayed);
796 "(%d)", this_urb, err); 817 spin_unlock_irqrestore(&intfdata->susp_lock, flags);
797 clear_bit(i, &portdata->out_busy); 818 } else {
798 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 }
799 } 831 }
832
800 portdata->tx_start_time[i] = jiffies; 833 portdata->tx_start_time[i] = jiffies;
801 buf += todo; 834 buf += todo;
802 left -= todo; 835 left -= todo;
@@ -840,7 +873,10 @@ static void option_indat_callback(struct urb *urb)
840 if (err) 873 if (err)
841 printk(KERN_ERR "%s: resubmit read urb failed. " 874 printk(KERN_ERR "%s: resubmit read urb failed. "
842 "(%d)", __func__, err); 875 "(%d)", __func__, err);
876 else
877 usb_mark_last_busy(port->serial->dev);
843 } 878 }
879
844 } 880 }
845 return; 881 return;
846} 882}
@@ -849,15 +885,21 @@ static void option_outdat_callback(struct urb *urb)
849{ 885{
850 struct usb_serial_port *port; 886 struct usb_serial_port *port;
851 struct option_port_private *portdata; 887 struct option_port_private *portdata;
888 struct option_intf_private *intfdata;
852 int i; 889 int i;
853 890
854 dbg("%s", __func__); 891 dbg("%s", __func__);
855 892
856 port = urb->context; 893 port = urb->context;
894 intfdata = port->serial->private;
857 895
858 usb_serial_port_softint(port); 896 usb_serial_port_softint(port);
859 897 usb_autopm_put_interface_async(port->serial->interface);
860 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
861 for (i = 0; i < N_OUT_URB; ++i) { 903 for (i = 0; i < N_OUT_URB; ++i) {
862 if (portdata->out_urbs[i] == urb) { 904 if (portdata->out_urbs[i] == urb) {
863 smp_mb__before_clear_bit(); 905 smp_mb__before_clear_bit();
@@ -967,10 +1009,13 @@ static int option_chars_in_buffer(struct tty_struct *tty)
967static int option_open(struct tty_struct *tty, struct usb_serial_port *port) 1009static int option_open(struct tty_struct *tty, struct usb_serial_port *port)
968{ 1010{
969 struct option_port_private *portdata; 1011 struct option_port_private *portdata;
1012 struct option_intf_private *intfdata;
1013 struct usb_serial *serial = port->serial;
970 int i, err; 1014 int i, err;
971 struct urb *urb; 1015 struct urb *urb;
972 1016
973 portdata = usb_get_serial_port_data(port); 1017 portdata = usb_get_serial_port_data(port);
1018 intfdata = serial->private;
974 1019
975 dbg("%s", __func__); 1020 dbg("%s", __func__);
976 1021
@@ -989,6 +1034,12 @@ static int option_open(struct tty_struct *tty, struct usb_serial_port *port)
989 1034
990 option_send_setup(port); 1035 option_send_setup(port);
991 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
992 return 0; 1043 return 0;
993} 1044}
994 1045
@@ -1013,16 +1064,23 @@ static void option_close(struct usb_serial_port *port)
1013 int i; 1064 int i;
1014 struct usb_serial *serial = port->serial; 1065 struct usb_serial *serial = port->serial;
1015 struct option_port_private *portdata; 1066 struct option_port_private *portdata;
1067 struct option_intf_private *intfdata = port->serial->private;
1016 1068
1017 dbg("%s", __func__); 1069 dbg("%s", __func__);
1018 portdata = usb_get_serial_port_data(port); 1070 portdata = usb_get_serial_port_data(port);
1019 1071
1020 if (serial->dev) { 1072 if (serial->dev) {
1021 /* 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
1022 for (i = 0; i < N_IN_URB; i++) 1078 for (i = 0; i < N_IN_URB; i++)
1023 usb_kill_urb(portdata->in_urbs[i]); 1079 usb_kill_urb(portdata->in_urbs[i]);
1024 for (i = 0; i < N_OUT_URB; i++) 1080 for (i = 0; i < N_OUT_URB; i++)
1025 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;
1026 } 1084 }
1027} 1085}
1028 1086
@@ -1127,6 +1185,7 @@ static int option_startup(struct usb_serial *serial)
1127 __func__, i); 1185 __func__, i);
1128 return 1; 1186 return 1;
1129 } 1187 }
1188 init_usb_anchor(&portdata->delayed);
1130 1189
1131 for (j = 0; j < N_IN_URB; j++) { 1190 for (j = 0; j < N_IN_URB; j++) {
1132 buffer = (u8 *)__get_free_page(GFP_KERNEL); 1191 buffer = (u8 *)__get_free_page(GFP_KERNEL);
@@ -1229,18 +1288,52 @@ static void option_release(struct usb_serial *serial)
1229#ifdef CONFIG_PM 1288#ifdef CONFIG_PM
1230static int option_suspend(struct usb_serial *serial, pm_message_t message) 1289static int option_suspend(struct usb_serial *serial, pm_message_t message)
1231{ 1290{
1291 struct option_intf_private *intfdata = serial->private;
1292 int b;
1293
1232 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);
1233 stop_read_write_urbs(serial); 1308 stop_read_write_urbs(serial);
1234 1309
1235 return 0; 1310 return 0;
1236} 1311}
1237 1312
1313static 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
1238static int option_resume(struct usb_serial *serial) 1329static int option_resume(struct usb_serial *serial)
1239{ 1330{
1240 int err, i, j; 1331 int i, j;
1241 struct usb_serial_port *port; 1332 struct usb_serial_port *port;
1242 struct urb *urb; 1333 struct option_intf_private *intfdata = serial->private;
1243 struct option_port_private *portdata; 1334 struct option_port_private *portdata;
1335 struct urb *urb;
1336 int err = 0;
1244 1337
1245 dbg("%s entered", __func__); 1338 dbg("%s entered", __func__);
1246 /* get the interrupt URBs resubmitted unconditionally */ 1339 /* get the interrupt URBs resubmitted unconditionally */
@@ -1255,7 +1348,7 @@ static int option_resume(struct usb_serial *serial)
1255 if (err < 0) { 1348 if (err < 0) {
1256 err("%s: Error %d for interrupt URB of port%d", 1349 err("%s: Error %d for interrupt URB of port%d",
1257 __func__, err, i); 1350 __func__, err, i);
1258 return err; 1351 goto err_out;
1259 } 1352 }
1260 } 1353 }
1261 1354
@@ -1263,27 +1356,32 @@ static int option_resume(struct usb_serial *serial)
1263 /* walk all ports */ 1356 /* walk all ports */
1264 port = serial->port[i]; 1357 port = serial->port[i];
1265 portdata = usb_get_serial_port_data(port); 1358 portdata = usb_get_serial_port_data(port);
1266 mutex_lock(&port->mutex);
1267 1359
1268 /* skip closed ports */ 1360 /* skip closed ports */
1269 if (!port->port.count) { 1361 spin_lock_irq(&intfdata->susp_lock);
1270 mutex_unlock(&port->mutex); 1362 if (!portdata->opened) {
1363 spin_unlock_irq(&intfdata->susp_lock);
1271 continue; 1364 continue;
1272 } 1365 }
1273 1366
1274 for (j = 0; j < N_IN_URB; j++) { 1367 for (j = 0; j < N_IN_URB; j++) {
1275 urb = portdata->in_urbs[j]; 1368 urb = portdata->in_urbs[j];
1276 err = usb_submit_urb(urb, GFP_NOIO); 1369 err = usb_submit_urb(urb, GFP_ATOMIC);
1277 if (err < 0) { 1370 if (err < 0) {
1278 mutex_unlock(&port->mutex);
1279 err("%s: Error %d for bulk URB %d", 1371 err("%s: Error %d for bulk URB %d",
1280 __func__, err, i); 1372 __func__, err, i);
1281 return err; 1373 spin_unlock_irq(&intfdata->susp_lock);
1374 goto err_out;
1282 } 1375 }
1283 } 1376 }
1284 mutex_unlock(&port->mutex); 1377 play_delayed(port);
1378 spin_unlock_irq(&intfdata->susp_lock);
1285 } 1379 }
1286 return 0; 1380 spin_lock_irq(&intfdata->susp_lock);
1381 intfdata->suspended = 0;
1382 spin_unlock_irq(&intfdata->susp_lock);
1383err_out:
1384 return err;
1287} 1385}
1288#endif 1386#endif
1289 1387