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>
This commit is contained in:
@ -28,24 +28,16 @@
|
||||
#include "hcd.h"
|
||||
#include "usb.h"
|
||||
|
||||
static int usb_match_one_id(struct usb_interface *interface,
|
||||
const struct usb_device_id *id);
|
||||
|
||||
struct usb_dynid {
|
||||
struct list_head node;
|
||||
struct usb_device_id id;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_HOTPLUG
|
||||
|
||||
/*
|
||||
* Adds a new dynamic USBdevice ID to this driver,
|
||||
* and cause the driver to probe for all devices again.
|
||||
*/
|
||||
static ssize_t store_new_id(struct device_driver *driver,
|
||||
const char *buf, size_t count)
|
||||
ssize_t usb_store_new_id(struct usb_dynids *dynids,
|
||||
struct device_driver *driver,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_driver *usb_drv = to_usb_driver(driver);
|
||||
struct usb_dynid *dynid;
|
||||
u32 idVendor = 0;
|
||||
u32 idProduct = 0;
|
||||
@ -65,9 +57,9 @@ static ssize_t store_new_id(struct device_driver *driver,
|
||||
dynid->id.idProduct = idProduct;
|
||||
dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE;
|
||||
|
||||
spin_lock(&usb_drv->dynids.lock);
|
||||
list_add_tail(&usb_drv->dynids.list, &dynid->node);
|
||||
spin_unlock(&usb_drv->dynids.lock);
|
||||
spin_lock(&dynids->lock);
|
||||
list_add_tail(&dynids->list, &dynid->node);
|
||||
spin_unlock(&dynids->lock);
|
||||
|
||||
if (get_driver(driver)) {
|
||||
retval = driver_attach(driver);
|
||||
@ -78,6 +70,15 @@ static ssize_t store_new_id(struct device_driver *driver,
|
||||
return retval;
|
||||
return count;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_store_new_id);
|
||||
|
||||
static ssize_t store_new_id(struct device_driver *driver,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct usb_driver *usb_drv = to_usb_driver(driver);
|
||||
|
||||
return usb_store_new_id(&usb_drv->dynids, driver, buf, count);
|
||||
}
|
||||
static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
|
||||
|
||||
static int usb_create_newid_file(struct usb_driver *usb_drv)
|
||||
@ -365,8 +366,8 @@ void usb_driver_release_interface(struct usb_driver *driver,
|
||||
EXPORT_SYMBOL(usb_driver_release_interface);
|
||||
|
||||
/* returns 0 if no match, 1 if match */
|
||||
static int usb_match_one_id(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
int usb_match_one_id(struct usb_interface *interface,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_host_interface *intf;
|
||||
struct usb_device *dev;
|
||||
@ -432,6 +433,8 @@ static int usb_match_one_id(struct usb_interface *interface,
|
||||
|
||||
return 1;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_match_one_id);
|
||||
|
||||
/**
|
||||
* usb_match_id - find first usb_device_id matching device or interface
|
||||
* @interface: the interface of interest
|
||||
|
Reference in New Issue
Block a user