return id;
 }
 
+/* Caller must hold table_lock */
 static struct usb_serial_driver *search_serial_device(
                                        struct usb_interface *iface)
 {
        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;
        }
        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;
                 * 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;
        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);
                /* 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);
        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);
                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);
                printk(KERN_INFO "USB Serial support registered for %s\n",
                                                driver->description);
 
+       mutex_unlock(&table_lock);
        return retval;
 }
 EXPORT_SYMBOL_GPL(usb_serial_register);
        /* 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);