summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-12-17 21:50:23 +0100
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-08 00:44:33 +0100
commit93bacefc4cc0b53e1cb6a336d43847154fdf6886 (patch)
tree4a82a9d2693d1165c58602a0bf4a8e5c76c541ef /drivers/usb/serial/usb-serial.c
parentohci: Add support for OHCI controller on the of_platform bus (diff)
downloadlinux-93bacefc4cc0b53e1cb6a336d43847154fdf6886.tar.xz
linux-93bacefc4cc0b53e1cb6a336d43847154fdf6886.zip
USB serial: add dynamic id support to usb-serial core
Thanks to Johannes Hölzl <johannes.hoelzl@gmx.de> for fixing a few things and getting it all working properly. This adds support for dynamic usb ids to the usb serial core. The file "new_id" will show up under the usb serial driver, not the usb driver associated with the usb-serial driver (yeah, it can be a bit confusing at first glance...) This patch also modifies the USB core to allow the usb-serial core to reuse much of the dynamic id logic. Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Johannes Hölzl <johannes.hoelzl@gmx.de>
Diffstat (limited to 'drivers/usb/serial/usb-serial.c')
-rw-r--r--drivers/usb/serial/usb-serial.c41
1 files changed, 36 insertions, 5 deletions
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 716f6806cc89..90beb5c50e59 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -596,6 +596,39 @@ static struct usb_serial * create_serial (struct usb_device *dev,
return serial;
}
+static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
+ struct usb_serial_driver *drv)
+{
+ struct usb_dynid *dynid;
+
+ spin_lock(&drv->dynids.lock);
+ list_for_each_entry(dynid, &drv->dynids.list, node) {
+ if (usb_match_one_id(intf, &dynid->id)) {
+ spin_unlock(&drv->dynids.lock);
+ return &dynid->id;
+ }
+ }
+ spin_unlock(&drv->dynids.lock);
+ return NULL;
+}
+
+static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
+ struct usb_interface *intf)
+{
+ const struct usb_device_id *id;
+
+ id = usb_match_id(intf, drv->id_table);
+ if (id) {
+ dbg("static descriptor matches");
+ goto exit;
+ }
+ id = match_dynamic_id(intf, drv);
+ if (id)
+ dbg("dynamic descriptor matches");
+exit:
+ return id;
+}
+
static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
{
struct list_head *p;
@@ -605,11 +638,9 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac
/* Check if the usb id matches a known device */
list_for_each(p, &usb_serial_driver_list) {
t = list_entry(p, struct usb_serial_driver, driver_list);
- id = usb_match_id(iface, t->id_table);
- if (id != NULL) {
- dbg("descriptor matches");
+ id = get_iface_id(t, iface);
+ if (id)
return t;
- }
}
return NULL;
@@ -661,7 +692,7 @@ int usb_serial_probe(struct usb_interface *interface,
return -EIO;
}
- id = usb_match_id(interface, type->id_table);
+ id = get_iface_id(type, interface);
retval = type->probe(serial, id);
module_put(type->driver.owner);