Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 207972
b: refs/heads/master
c: 0daeed3
h: refs/heads/master
v: v3
  • Loading branch information
Andi Kleen authored and Greg Kroah-Hartman committed Aug 10, 2010
1 parent 0e68d61 commit ca21411
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c532b29a6f6d31e84a7c88f995eebdc75ebd4248
refs/heads/master: 0daeed381c6a33fdbdc3b0e9f09d96f0a2a8a195
30 changes: 14 additions & 16 deletions trunk/drivers/usb/serial/usb-serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,7 @@ static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
return id;
}

/* Caller must hold table_lock */
static struct usb_serial_driver *search_serial_device(
struct usb_interface *iface)
{
Expand Down Expand Up @@ -718,17 +719,23 @@ int usb_serial_probe(struct usb_interface *interface,
int num_ports = 0;
int max_endpoints;

lock_kernel(); /* guard against unloading a serial driver module */
mutex_lock(&table_lock);
type = search_serial_device(interface);
if (!type) {
unlock_kernel();
mutex_unlock(&table_lock);
dbg("none matched");
return -ENODEV;
}

if (!try_module_get(type->driver.owner)) {
mutex_unlock(&table_lock);
dev_err(&interface->dev, "module get failed, exiting\n");
return -EIO;
}
mutex_unlock(&table_lock);

serial = create_serial(dev, interface, type);
if (!serial) {
unlock_kernel();
dev_err(&interface->dev, "%s - out of memory\n", __func__);
return -ENOMEM;
}
Expand All @@ -737,20 +744,11 @@ int usb_serial_probe(struct usb_interface *interface,
if (type->probe) {
const struct usb_device_id *id;

if (!try_module_get(type->driver.owner)) {
unlock_kernel();
dev_err(&interface->dev,
"module get failed, exiting\n");
kfree(serial);
return -EIO;
}

id = get_iface_id(type, interface);
retval = type->probe(serial, id);
module_put(type->driver.owner);

if (retval) {
unlock_kernel();
dbg("sub driver rejected device");
kfree(serial);
return retval;
Expand Down Expand Up @@ -822,7 +820,6 @@ int usb_serial_probe(struct usb_interface *interface,
* properly during a later invocation of usb_serial_probe
*/
if (num_bulk_in == 0 || num_bulk_out == 0) {
unlock_kernel();
dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n");
kfree(serial);
return -ENODEV;
Expand All @@ -835,7 +832,6 @@ int usb_serial_probe(struct usb_interface *interface,
if (type == &usb_serial_generic_device) {
num_ports = num_bulk_out;
if (num_ports == 0) {
unlock_kernel();
dev_err(&interface->dev,
"Generic device with no bulk out, not allowed.\n");
kfree(serial);
Expand All @@ -847,7 +843,6 @@ int usb_serial_probe(struct usb_interface *interface,
/* if this device type has a calc_num_ports function, call it */
if (type->calc_num_ports) {
if (!try_module_get(type->driver.owner)) {
unlock_kernel();
dev_err(&interface->dev,
"module get failed, exiting\n");
kfree(serial);
Expand Down Expand Up @@ -878,7 +873,6 @@ int usb_serial_probe(struct usb_interface *interface,
max_endpoints = max(max_endpoints, num_interrupt_out);
max_endpoints = max(max_endpoints, (int)serial->num_ports);
serial->num_port_pointers = max_endpoints;
unlock_kernel();

dbg("%s - setting up %d port structures for this device",
__func__, max_endpoints);
Expand Down Expand Up @@ -1349,6 +1343,7 @@ int usb_serial_register(struct usb_serial_driver *driver)
driver->description = driver->driver.name;

/* Add this device to our list of devices */
mutex_lock(&table_lock);
list_add(&driver->driver_list, &usb_serial_driver_list);

retval = usb_serial_bus_register(driver);
Expand All @@ -1360,6 +1355,7 @@ int usb_serial_register(struct usb_serial_driver *driver)
printk(KERN_INFO "USB Serial support registered for %s\n",
driver->description);

mutex_unlock(&table_lock);
return retval;
}
EXPORT_SYMBOL_GPL(usb_serial_register);
Expand All @@ -1370,8 +1366,10 @@ void usb_serial_deregister(struct usb_serial_driver *device)
/* must be called with BKL held */
printk(KERN_INFO "USB Serial deregistering driver %s\n",
device->description);
mutex_lock(&table_lock);
list_del(&device->driver_list);
usb_serial_bus_deregister(device);
mutex_unlock(&table_lock);
}
EXPORT_SYMBOL_GPL(usb_serial_deregister);

Expand Down

0 comments on commit ca21411

Please sign in to comment.