[RFC] USB: allow new_id to provide driver_info

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



A number of USB drivers are unable to successfully probe a new
device without some driver specific information in the
driver_info field. By copying the driver_info from the first
device in the static device id list, we can enable dynamic
device IDs for such drivers as well.

This will make the first device a generic template for dynamic
IDs, with no way to specify another template device.

Signed-off-by: Bjørn Mork <bjorn@xxxxxxx>
---
I'd really like to see some way to make dynamic device IDs work
for e.g. usbnet based minidrivers. This patch is one way to do
that.

Another possibility would be to let the user provide a 
"template device" from the driver built-in list along with the
new device ID.  Something like

 # echo "8086 10f5 8086 10f4" > /sys/bus/usb/drivers/foo/new_id

where the two last numbers would specify a device already
supported by the driver. This might be better for drivers with
a number of different driver_info options, and would also
provide support for complex class and protocol matching, as long
as an existing entry has the wanted configuration.

But it would make it necessary to extend the new_id interface
yet again, and in a way which cannot easily be combined with the
recently added interface class match.  Which makes me hesitate...

Therefore this patch, which is sufficient for most of the
drivers.

What do you think?

BTW, another wishlist item is the ability to view the dynamic
device list.  Any objections against providing a read method
for the new_id (and maybe also remove_id) file?


Bjørn

 drivers/usb/core/driver.c |    8 +++++++-
 drivers/usb/serial/bus.c  |   10 ++++++++--
 include/linux/usb.h       |    1 +
 3 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 112a7ae..c3d0924 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -40,6 +40,7 @@
  */
 ssize_t usb_store_new_id(struct usb_dynids *dynids,
 			 struct device_driver *driver,
+			 kernel_ulong_t	driver_info,
 			 const char *buf, size_t count)
 {
 	struct usb_dynid *dynid;
@@ -66,6 +67,7 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids,
 		dynid->id.bInterfaceClass = (u8)bInterfaceClass;
 		dynid->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
 	}
+	dynid->id.driver_info = driver_info;
 
 	spin_lock(&dynids->lock);
 	list_add_tail(&dynid->node, &dynids->list);
@@ -83,8 +85,12 @@ 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);
+	kernel_ulong_t driver_info = 0;
 
-	return usb_store_new_id(&usb_drv->dynids, driver, buf, count);
+	if (usb_drv->id_table)
+		driver_info = usb_drv->id_table[0].driver_info;
+	return usb_store_new_id(&usb_drv->dynids, driver, driver_info,
+				buf, count);
 }
 static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
 
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index ed8adb0..cde24cc 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -115,12 +115,18 @@ static ssize_t store_new_id(struct device_driver *driver,
 			    const char *buf, size_t count)
 {
 	struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
-	ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count);
+	kernel_ulong_t driver_info = 0;
+	ssize_t retval;
+
+	if (usb_drv->id_table)
+		driver_info = usb_drv->id_table[0].driver_info;
+	retval = usb_store_new_id(&usb_drv->dynids, driver, driver_info,
+				  buf, count);
 
 	if (retval >= 0 && usb_drv->usb_driver != NULL)
 		retval = usb_store_new_id(&usb_drv->usb_driver->dynids,
 					  &usb_drv->usb_driver->drvwrap.driver,
-					  buf, count);
+					  driver_info, buf, count);
 	return retval;
 }
 
diff --git a/include/linux/usb.h b/include/linux/usb.h
index 5483cd7..828062c 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -788,6 +788,7 @@ struct usb_dynid {
 
 extern ssize_t usb_store_new_id(struct usb_dynids *dynids,
 				struct device_driver *driver,
+				kernel_ulong_t driver_info,
 				const char *buf, size_t count);
 
 /**
-- 
1.7.10

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux