aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorOliver Neukum <oneukum@suse.de>2007-01-13 01:31:27 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:38 -0500
commit4b10f0f3a0d4caa8b615cd1f770a70912967a3cd (patch)
tree3a3b96e0f40bfc774aeb6790f7ed371afef11748 /drivers/usb/serial/usb-serial.c
parent34ef50e5b1f96c2d8c0f3d28b7d407743806256c (diff)
USB: race fixes for usb-serial, step 2
- take BKL before looking up a driver to associate with a device to make sure the module is not unloaded after looking up but before association & bumping module count Signed-off-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 3780362eb9f0..685fb69bcc32 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -685,14 +685,17 @@ int usb_serial_probe(struct usb_interface *interface,
685 int num_ports = 0; 685 int num_ports = 0;
686 int max_endpoints; 686 int max_endpoints;
687 687
688 lock_kernel(); /* guard against unloading a serial driver module */
688 type = search_serial_device(interface); 689 type = search_serial_device(interface);
689 if (!type) { 690 if (!type) {
691 unlock_kernel();
690 dbg("none matched"); 692 dbg("none matched");
691 return -ENODEV; 693 return -ENODEV;
692 } 694 }
693 695
694 serial = create_serial (dev, interface, type); 696 serial = create_serial (dev, interface, type);
695 if (!serial) { 697 if (!serial) {
698 unlock_kernel();
696 dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); 699 dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__);
697 return -ENOMEM; 700 return -ENOMEM;
698 } 701 }
@@ -702,6 +705,7 @@ int usb_serial_probe(struct usb_interface *interface,
702 const struct usb_device_id *id; 705 const struct usb_device_id *id;
703 706
704 if (!try_module_get(type->driver.owner)) { 707 if (!try_module_get(type->driver.owner)) {
708 unlock_kernel();
705 dev_err(&interface->dev, "module get failed, exiting\n"); 709 dev_err(&interface->dev, "module get failed, exiting\n");
706 kfree (serial); 710 kfree (serial);
707 return -EIO; 711 return -EIO;
@@ -712,6 +716,7 @@ int usb_serial_probe(struct usb_interface *interface,
712 module_put(type->driver.owner); 716 module_put(type->driver.owner);
713 717
714 if (retval) { 718 if (retval) {
719 unlock_kernel();
715 dbg ("sub driver rejected device"); 720 dbg ("sub driver rejected device");
716 kfree (serial); 721 kfree (serial);
717 return retval; 722 return retval;
@@ -781,6 +786,7 @@ int usb_serial_probe(struct usb_interface *interface,
781 * properly during a later invocation of usb_serial_probe 786 * properly during a later invocation of usb_serial_probe
782 */ 787 */
783 if (num_bulk_in == 0 || num_bulk_out == 0) { 788 if (num_bulk_in == 0 || num_bulk_out == 0) {
789 unlock_kernel();
784 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); 790 dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
785 kfree (serial); 791 kfree (serial);
786 return -ENODEV; 792 return -ENODEV;
@@ -796,6 +802,7 @@ int usb_serial_probe(struct usb_interface *interface,
796 if (type == &usb_serial_generic_device) { 802 if (type == &usb_serial_generic_device) {
797 num_ports = num_bulk_out; 803 num_ports = num_bulk_out;
798 if (num_ports == 0) { 804 if (num_ports == 0) {
805 unlock_kernel();
799 dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); 806 dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n");
800 kfree (serial); 807 kfree (serial);
801 return -EIO; 808 return -EIO;
@@ -806,6 +813,7 @@ int usb_serial_probe(struct usb_interface *interface,
806 /* if this device type has a calc_num_ports function, call it */ 813 /* if this device type has a calc_num_ports function, call it */
807 if (type->calc_num_ports) { 814 if (type->calc_num_ports) {
808 if (!try_module_get(type->driver.owner)) { 815 if (!try_module_get(type->driver.owner)) {
816 unlock_kernel();
809 dev_err(&interface->dev, "module get failed, exiting\n"); 817 dev_err(&interface->dev, "module get failed, exiting\n");
810 kfree (serial); 818 kfree (serial);
811 return -EIO; 819 return -EIO;
@@ -831,6 +839,8 @@ int usb_serial_probe(struct usb_interface *interface,
831 max_endpoints = max(max_endpoints, num_interrupt_out); 839 max_endpoints = max(max_endpoints, num_interrupt_out);
832 max_endpoints = max(max_endpoints, (int)serial->num_ports); 840 max_endpoints = max(max_endpoints, (int)serial->num_ports);
833 serial->num_port_pointers = max_endpoints; 841 serial->num_port_pointers = max_endpoints;
842 unlock_kernel();
843
834 dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); 844 dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints);
835 for (i = 0; i < max_endpoints; ++i) { 845 for (i = 0; i < max_endpoints; ++i) {
836 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); 846 port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL);
@@ -1187,7 +1197,7 @@ static void fixup_generic(struct usb_serial_driver *device)
1187 set_to_generic_if_null(device, shutdown); 1197 set_to_generic_if_null(device, shutdown);
1188} 1198}
1189 1199
1190int usb_serial_register(struct usb_serial_driver *driver) 1200int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */
1191{ 1201{
1192 int retval; 1202 int retval;
1193 1203
@@ -1211,7 +1221,7 @@ int usb_serial_register(struct usb_serial_driver *driver)
1211} 1221}
1212 1222
1213 1223
1214void usb_serial_deregister(struct usb_serial_driver *device) 1224void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */
1215{ 1225{
1216 info("USB Serial deregistering driver %s", device->description); 1226 info("USB Serial deregistering driver %s", device->description);
1217 list_del(&device->driver_list); 1227 list_del(&device->driver_list);