Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=063a2da8f01806906f7d7b1a1424b9afddebc443
Commit:     063a2da8f01806906f7d7b1a1424b9afddebc443
Parent:     cd38c1e1ae5273c28a12baacaf17c1faa062661f
Author:     Alan Stern <[EMAIL PROTECTED]>
AuthorDate: Wed Oct 10 16:24:06 2007 -0400
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Fri Oct 12 14:55:34 2007 -0700

    USB: serial core should respect driver requirements
    
    This patch (as997) fixes a bug in the USB serial core.  The core needs
    to pay attention to drivers' requirements regarding the number and
    type of endpoints a device has.
    
    At the same time, the patch changes the NUM_DONT_CARE constant (which
    is stored in a single-byte field) from -1 to a safer, unsigned value.
    It also improves the kerneldoc for several fields in the
    usb_serial_driver structure.
    
    Finally, the patch replaces a list_for_each() with list_for_each_entry().
    
    Signed-off-by: Alan Stern <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/serial/usb-serial.c |   31 ++++++++++++++++++++++---------
 include/linux/usb/serial.h      |   20 +++++++++++++-------
 2 files changed, 35 insertions(+), 16 deletions(-)

diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 26e015c..4b1bd7d 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -662,16 +662,14 @@ exit:
 
 static struct usb_serial_driver *search_serial_device(struct usb_interface 
*iface)
 {
-       struct list_head *p;
        const struct usb_device_id *id;
-       struct usb_serial_driver *t;
+       struct usb_serial_driver *drv;
 
        /* 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 = get_iface_id(t, iface);
+       list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
+               id = get_iface_id(drv, iface);
                if (id)
-                       return t;
+                       return drv;
        }
 
        return NULL;
@@ -811,9 +809,6 @@ int usb_serial_probe(struct usb_interface *interface,
        /* END HORRIBLE HACK FOR PL2303 */
 #endif
 
-       /* found all that we need */
-       dev_info(&interface->dev, "%s converter detected\n", type->description);
-
 #ifdef CONFIG_USB_SERIAL_GENERIC
        if (type == &usb_serial_generic_device) {
                num_ports = num_bulk_out;
@@ -847,6 +842,24 @@ int usb_serial_probe(struct usb_interface *interface,
        serial->num_interrupt_in = num_interrupt_in;
        serial->num_interrupt_out = num_interrupt_out;
 
+       /* check that the device meets the driver's requirements */
+       if ((type->num_interrupt_in != NUM_DONT_CARE &&
+                               type->num_interrupt_in != num_interrupt_in)
+                       || (type->num_interrupt_out != NUM_DONT_CARE &&
+                               type->num_interrupt_out != num_interrupt_out)
+                       || (type->num_bulk_in != NUM_DONT_CARE &&
+                               type->num_bulk_in != num_bulk_in)
+                       || (type->num_bulk_out != NUM_DONT_CARE &&
+                               type->num_bulk_out != num_bulk_out)) {
+               dbg("wrong number of endpoints");
+               kfree(serial);
+               return -EIO;
+       }
+
+       /* found all that we need */
+       dev_info(&interface->dev, "%s converter detected\n",
+                       type->description);
+
        /* create our ports, we need as many as the max endpoints */
        /* we don't use num_ports here cauz some devices have more endpoint 
pairs than ports */
        max_endpoints = max(num_bulk_in, num_bulk_out);
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index e8b8928..488ce12 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -141,7 +141,7 @@ struct usb_serial {
 };
 #define to_usb_serial(d) container_of(d, struct usb_serial, kref)
 
-#define NUM_DONT_CARE  (-1)
+#define NUM_DONT_CARE  99
 
 /* get and set the serial private data pointer helper functions */
 static inline void *usb_get_serial_data (struct usb_serial *serial)
@@ -160,12 +160,18 @@ static inline void usb_set_serial_data (struct usb_serial 
*serial, void *data)
  *     in the syslog messages when a device is inserted or removed.
  * @id_table: pointer to a list of usb_device_id structures that define all
  *     of the devices this structure can support.
- * @num_interrupt_in: the number of interrupt in endpoints this device will
- *     have.
- * @num_interrupt_out: the number of interrupt out endpoints this device will
- *     have.
- * @num_bulk_in: the number of bulk in endpoints this device will have.
- * @num_bulk_out: the number of bulk out endpoints this device will have.
+ * @num_interrupt_in: If a device doesn't have this many interrupt-in
+ *     endpoints, it won't be sent to the driver's attach() method.
+ *     (But it might still be sent to the probe() method.)
+ * @num_interrupt_out: If a device doesn't have this many interrupt-out
+ *     endpoints, it won't be sent to the driver's attach() method.
+ *     (But it might still be sent to the probe() method.)
+ * @num_bulk_in: If a device doesn't have this many bulk-in
+ *     endpoints, it won't be sent to the driver's attach() method.
+ *     (But it might still be sent to the probe() method.)
+ * @num_bulk_out: If a device doesn't have this many bulk-out
+ *     endpoints, it won't be sent to the driver's attach() method.
+ *     (But it might still be sent to the probe() method.)
  * @num_ports: the number of different ports this device will have.
  * @calc_num_ports: pointer to a function to determine how many ports this
  *     device has dynamically.  It will be called after the probe()
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to