aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/usb-serial.c
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@suse.de>2006-12-17 15:50:23 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2007-02-07 18:44:33 -0500
commit93bacefc4cc0b53e1cb6a336d43847154fdf6886 (patch)
tree4a82a9d2693d1165c58602a0bf4a8e5c76c541ef /drivers/usb/serial/usb-serial.c
parent495a678fc62e850d15f860d39faee07ba0a8910c (diff)
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,
596 return serial; 596 return serial;
597} 597}
598 598
599static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf,
600 struct usb_serial_driver *drv)
601{
602 struct usb_dynid *dynid;
603
604 spin_lock(&drv->dynids.lock);
605 list_for_each_entry(dynid, &drv->dynids.list, node) {
606 if (usb_match_one_id(intf, &dynid->id)) {
607 spin_unlock(&drv->dynids.lock);
608 return &dynid->id;
609 }
610 }
611 spin_unlock(&drv->dynids.lock);
612 return NULL;
613}
614
615static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
616 struct usb_interface *intf)
617{
618 const struct usb_device_id *id;
619
620 id = usb_match_id(intf, drv->id_table);
621 if (id) {
622 dbg("static descriptor matches");
623 goto exit;
624 }
625 id = match_dynamic_id(intf, drv);
626 if (id)
627 dbg("dynamic descriptor matches");
628exit:
629 return id;
630}
631
599static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) 632static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
600{ 633{
601 struct list_head *p; 634 struct list_head *p;
@@ -605,11 +638,9 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac
605 /* Check if the usb id matches a known device */ 638 /* Check if the usb id matches a known device */
606 list_for_each(p, &usb_serial_driver_list) { 639 list_for_each(p, &usb_serial_driver_list) {
607 t = list_entry(p, struct usb_serial_driver, driver_list); 640 t = list_entry(p, struct usb_serial_driver, driver_list);
608 id = usb_match_id(iface, t->id_table); 641 id = get_iface_id(t, iface);
609 if (id != NULL) { 642 if (id)
610 dbg("descriptor matches");
611 return t; 643 return t;
612 }
613 } 644 }
614 645
615 return NULL; 646 return NULL;
@@ -661,7 +692,7 @@ int usb_serial_probe(struct usb_interface *interface,
661 return -EIO; 692 return -EIO;
662 } 693 }
663 694
664 id = usb_match_id(interface, type->id_table); 695 id = get_iface_id(type, interface);
665 retval = type->probe(serial, id); 696 retval = type->probe(serial, id);
666 module_put(type->driver.owner); 697 module_put(type->driver.owner);
667 698