aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c109
1 files changed, 72 insertions, 37 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 97355a15bbea..6a1b609a0d94 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * USB Serial Converter driver 2 * USB Serial Converter driver
3 * 3 *
4 * Copyright (C) 1999 - 2005 Greg Kroah-Hartman (greg@kroah.com) 4 * Copyright (C) 1999 - 2012 Greg Kroah-Hartman (greg@kroah.com)
5 * Copyright (C) 2000 Peter Berger (pberger@brimson.com) 5 * Copyright (C) 2000 Peter Berger (pberger@brimson.com)
6 * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com) 6 * Copyright (C) 2000 Al Borchers (borchers@steinerpoint.com)
7 * 7 *
@@ -43,17 +43,6 @@
43#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/" 43#define DRIVER_AUTHOR "Greg Kroah-Hartman, greg@kroah.com, http://www.kroah.com/linux/"
44#define DRIVER_DESC "USB Serial Driver core" 44#define DRIVER_DESC "USB Serial Driver core"
45 45
46/* Driver structure we register with the USB core */
47static struct usb_driver usb_serial_driver = {
48 .name = "usbserial",
49 .probe = usb_serial_probe,
50 .disconnect = usb_serial_disconnect,
51 .suspend = usb_serial_suspend,
52 .resume = usb_serial_resume,
53 .no_dynamic_id = 1,
54 .supports_autosuspend = 1,
55};
56
57/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead 46/* There is no MODULE_DEVICE_TABLE for usbserial.c. Instead
58 the MODULE_DEVICE_TABLE declarations in each serial driver 47 the MODULE_DEVICE_TABLE declarations in each serial driver
59 cause the "hotplug" program to pull in whatever module is necessary 48 cause the "hotplug" program to pull in whatever module is necessary
@@ -710,7 +699,7 @@ static const struct tty_port_operations serial_port_ops = {
710 .shutdown = serial_down, 699 .shutdown = serial_down,
711}; 700};
712 701
713int usb_serial_probe(struct usb_interface *interface, 702static int usb_serial_probe(struct usb_interface *interface,
714 const struct usb_device_id *id) 703 const struct usb_device_id *id)
715{ 704{
716 struct usb_device *dev = interface_to_usbdev(interface); 705 struct usb_device *dev = interface_to_usbdev(interface);
@@ -856,6 +845,8 @@ int usb_serial_probe(struct usb_interface *interface,
856 module_put(type->driver.owner); 845 module_put(type->driver.owner);
857 return -EIO; 846 return -EIO;
858 } 847 }
848 dev_info(&interface->dev, "The \"generic\" usb-serial driver is only for testing and one-off prototypes.\n");
849 dev_info(&interface->dev, "Tell linux-usb@vger.kernel.org to add your device to a proper driver.\n");
859 } 850 }
860#endif 851#endif
861 if (!num_ports) { 852 if (!num_ports) {
@@ -1043,6 +1034,8 @@ int usb_serial_probe(struct usb_interface *interface,
1043 dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined"); 1034 dbg("the device claims to support interrupt out transfers, but write_int_callback is not defined");
1044 } 1035 }
1045 1036
1037 usb_set_intfdata(interface, serial);
1038
1046 /* if this device type has an attach function, call it */ 1039 /* if this device type has an attach function, call it */
1047 if (type->attach) { 1040 if (type->attach) {
1048 retval = type->attach(serial); 1041 retval = type->attach(serial);
@@ -1087,10 +1080,7 @@ int usb_serial_probe(struct usb_interface *interface,
1087 serial->disconnected = 0; 1080 serial->disconnected = 0;
1088 1081
1089 usb_serial_console_init(debug, minor); 1082 usb_serial_console_init(debug, minor);
1090
1091exit: 1083exit:
1092 /* success */
1093 usb_set_intfdata(interface, serial);
1094 module_put(type->driver.owner); 1084 module_put(type->driver.owner);
1095 return 0; 1085 return 0;
1096 1086
@@ -1099,9 +1089,8 @@ probe_error:
1099 module_put(type->driver.owner); 1089 module_put(type->driver.owner);
1100 return -EIO; 1090 return -EIO;
1101} 1091}
1102EXPORT_SYMBOL_GPL(usb_serial_probe);
1103 1092
1104void usb_serial_disconnect(struct usb_interface *interface) 1093static void usb_serial_disconnect(struct usb_interface *interface)
1105{ 1094{
1106 int i; 1095 int i;
1107 struct usb_serial *serial = usb_get_intfdata(interface); 1096 struct usb_serial *serial = usb_get_intfdata(interface);
@@ -1112,7 +1101,6 @@ void usb_serial_disconnect(struct usb_interface *interface)
1112 dbg("%s", __func__); 1101 dbg("%s", __func__);
1113 1102
1114 mutex_lock(&serial->disc_mutex); 1103 mutex_lock(&serial->disc_mutex);
1115 usb_set_intfdata(interface, NULL);
1116 /* must set a flag, to signal subdrivers */ 1104 /* must set a flag, to signal subdrivers */
1117 serial->disconnected = 1; 1105 serial->disconnected = 1;
1118 mutex_unlock(&serial->disc_mutex); 1106 mutex_unlock(&serial->disc_mutex);
@@ -1137,7 +1125,6 @@ void usb_serial_disconnect(struct usb_interface *interface)
1137 usb_serial_put(serial); 1125 usb_serial_put(serial);
1138 dev_info(dev, "device disconnected\n"); 1126 dev_info(dev, "device disconnected\n");
1139} 1127}
1140EXPORT_SYMBOL_GPL(usb_serial_disconnect);
1141 1128
1142int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) 1129int usb_serial_suspend(struct usb_interface *intf, pm_message_t message)
1143{ 1130{
@@ -1181,6 +1168,22 @@ int usb_serial_resume(struct usb_interface *intf)
1181} 1168}
1182EXPORT_SYMBOL(usb_serial_resume); 1169EXPORT_SYMBOL(usb_serial_resume);
1183 1170
1171static int usb_serial_reset_resume(struct usb_interface *intf)
1172{
1173 struct usb_serial *serial = usb_get_intfdata(intf);
1174 int rv;
1175
1176 serial->suspending = 0;
1177 if (serial->type->reset_resume)
1178 rv = serial->type->reset_resume(serial);
1179 else {
1180 rv = -EOPNOTSUPP;
1181 intf->needs_binding = 1;
1182 }
1183
1184 return rv;
1185}
1186
1184static const struct tty_operations serial_ops = { 1187static const struct tty_operations serial_ops = {
1185 .open = serial_open, 1188 .open = serial_open,
1186 .close = serial_close, 1189 .close = serial_close,
@@ -1204,6 +1207,17 @@ static const struct tty_operations serial_ops = {
1204 1207
1205struct tty_driver *usb_serial_tty_driver; 1208struct tty_driver *usb_serial_tty_driver;
1206 1209
1210/* Driver structure we register with the USB core */
1211static struct usb_driver usb_serial_driver = {
1212 .name = "usbserial",
1213 .probe = usb_serial_probe,
1214 .disconnect = usb_serial_disconnect,
1215 .suspend = usb_serial_suspend,
1216 .resume = usb_serial_resume,
1217 .no_dynamic_id = 1,
1218 .supports_autosuspend = 1,
1219};
1220
1207static int __init usb_serial_init(void) 1221static int __init usb_serial_init(void)
1208{ 1222{
1209 int i; 1223 int i;
@@ -1338,7 +1352,6 @@ static int usb_serial_register(struct usb_serial_driver *driver)
1338 driver->description); 1352 driver->description);
1339 return -EINVAL; 1353 return -EINVAL;
1340 } 1354 }
1341 driver->usb_driver->supports_autosuspend = 1;
1342 1355
1343 /* Add this device to our list of devices */ 1356 /* Add this device to our list of devices */
1344 mutex_lock(&table_lock); 1357 mutex_lock(&table_lock);
@@ -1369,18 +1382,19 @@ static void usb_serial_deregister(struct usb_serial_driver *device)
1369 1382
1370/** 1383/**
1371 * usb_serial_register_drivers - register drivers for a usb-serial module 1384 * usb_serial_register_drivers - register drivers for a usb-serial module
1372 * @udriver: usb_driver used for matching devices/interfaces
1373 * @serial_drivers: NULL-terminated array of pointers to drivers to be registered 1385 * @serial_drivers: NULL-terminated array of pointers to drivers to be registered
1386 * @name: name of the usb_driver for this set of @serial_drivers
1387 * @id_table: list of all devices this @serial_drivers set binds to
1374 * 1388 *
1375 * Registers @udriver and all the drivers in the @serial_drivers array. 1389 * Registers all the drivers in the @serial_drivers array, and dynamically
1376 * Automatically fills in the .no_dynamic_id field in @udriver and 1390 * creates a struct usb_driver with the name @name and id_table of @id_table.
1377 * the .usb_driver field in each serial driver.
1378 */ 1391 */
1379int usb_serial_register_drivers(struct usb_driver *udriver, 1392int usb_serial_register_drivers(struct usb_serial_driver *const serial_drivers[],
1380 struct usb_serial_driver * const serial_drivers[]) 1393 const char *name,
1394 const struct usb_device_id *id_table)
1381{ 1395{
1382 int rc; 1396 int rc;
1383 const struct usb_device_id *saved_id_table; 1397 struct usb_driver *udriver;
1384 struct usb_serial_driver * const *sd; 1398 struct usb_serial_driver * const *sd;
1385 1399
1386 /* 1400 /*
@@ -1391,12 +1405,30 @@ int usb_serial_register_drivers(struct usb_driver *udriver,
1391 * Performance hack: We don't want udriver to be probed until 1405 * Performance hack: We don't want udriver to be probed until
1392 * the serial drivers are registered, because the probe would 1406 * the serial drivers are registered, because the probe would
1393 * simply fail for lack of a matching serial driver. 1407 * simply fail for lack of a matching serial driver.
1394 * Therefore save off udriver's id_table until we are all set. 1408 * So we leave udriver's id_table set to NULL until we are all set.
1409 *
1410 * Suspend/resume support is implemented in the usb-serial core,
1411 * so fill in the PM-related fields in udriver.
1395 */ 1412 */
1396 saved_id_table = udriver->id_table; 1413 udriver = kzalloc(sizeof(*udriver), GFP_KERNEL);
1397 udriver->id_table = NULL; 1414 if (!udriver)
1415 return -ENOMEM;
1398 1416
1417 udriver->name = name;
1399 udriver->no_dynamic_id = 1; 1418 udriver->no_dynamic_id = 1;
1419 udriver->supports_autosuspend = 1;
1420 udriver->suspend = usb_serial_suspend;
1421 udriver->resume = usb_serial_resume;
1422 udriver->probe = usb_serial_probe;
1423 udriver->disconnect = usb_serial_disconnect;
1424
1425 /* we only set the reset_resume field if the serial_driver has one */
1426 for (sd = serial_drivers; *sd; ++sd) {
1427 if ((*sd)->reset_resume)
1428 udriver->reset_resume = usb_serial_reset_resume;
1429 break;
1430 }
1431
1400 rc = usb_register(udriver); 1432 rc = usb_register(udriver);
1401 if (rc) 1433 if (rc)
1402 return rc; 1434 return rc;
@@ -1408,8 +1440,8 @@ int usb_serial_register_drivers(struct usb_driver *udriver,
1408 goto failed; 1440 goto failed;
1409 } 1441 }
1410 1442
1411 /* Now restore udriver's id_table and look for matches */ 1443 /* Now set udriver's id_table and look for matches */
1412 udriver->id_table = saved_id_table; 1444 udriver->id_table = id_table;
1413 rc = driver_attach(&udriver->drvwrap.driver); 1445 rc = driver_attach(&udriver->drvwrap.driver);
1414 return 0; 1446 return 0;
1415 1447
@@ -1423,17 +1455,20 @@ EXPORT_SYMBOL_GPL(usb_serial_register_drivers);
1423 1455
1424/** 1456/**
1425 * usb_serial_deregister_drivers - deregister drivers for a usb-serial module 1457 * usb_serial_deregister_drivers - deregister drivers for a usb-serial module
1426 * @udriver: usb_driver to unregister
1427 * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered 1458 * @serial_drivers: NULL-terminated array of pointers to drivers to be deregistered
1428 * 1459 *
1429 * Deregisters @udriver and all the drivers in the @serial_drivers array. 1460 * Deregisters all the drivers in the @serial_drivers array and deregisters and
1461 * frees the struct usb_driver that was created by the call to
1462 * usb_serial_register_drivers().
1430 */ 1463 */
1431void usb_serial_deregister_drivers(struct usb_driver *udriver, 1464void usb_serial_deregister_drivers(struct usb_serial_driver *const serial_drivers[])
1432 struct usb_serial_driver * const serial_drivers[])
1433{ 1465{
1466 struct usb_driver *udriver = (*serial_drivers)->usb_driver;
1467
1434 for (; *serial_drivers; ++serial_drivers) 1468 for (; *serial_drivers; ++serial_drivers)
1435 usb_serial_deregister(*serial_drivers); 1469 usb_serial_deregister(*serial_drivers);
1436 usb_deregister(udriver); 1470 usb_deregister(udriver);
1471 kfree(udriver);
1437} 1472}
1438EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers); 1473EXPORT_SYMBOL_GPL(usb_serial_deregister_drivers);
1439 1474