diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2007-10-10 16:24:06 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-10-12 17:55:34 -0400 |
commit | 063a2da8f01806906f7d7b1a1424b9afddebc443 (patch) | |
tree | 960243995fe608580e842b1a34228a3f991ea4dc | |
parent | cd38c1e1ae5273c28a12baacaf17c1faa062661f (diff) |
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 <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/serial/usb-serial.c | 31 | ||||
-rw-r--r-- | 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 26e015c39a31..4b1bd7def4a5 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -662,16 +662,14 @@ exit: | |||
662 | 662 | ||
663 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) | 663 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) |
664 | { | 664 | { |
665 | struct list_head *p; | ||
666 | const struct usb_device_id *id; | 665 | const struct usb_device_id *id; |
667 | struct usb_serial_driver *t; | 666 | struct usb_serial_driver *drv; |
668 | 667 | ||
669 | /* Check if the usb id matches a known device */ | 668 | /* Check if the usb id matches a known device */ |
670 | list_for_each(p, &usb_serial_driver_list) { | 669 | list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { |
671 | t = list_entry(p, struct usb_serial_driver, driver_list); | 670 | id = get_iface_id(drv, iface); |
672 | id = get_iface_id(t, iface); | ||
673 | if (id) | 671 | if (id) |
674 | return t; | 672 | return drv; |
675 | } | 673 | } |
676 | 674 | ||
677 | return NULL; | 675 | return NULL; |
@@ -811,9 +809,6 @@ int usb_serial_probe(struct usb_interface *interface, | |||
811 | /* END HORRIBLE HACK FOR PL2303 */ | 809 | /* END HORRIBLE HACK FOR PL2303 */ |
812 | #endif | 810 | #endif |
813 | 811 | ||
814 | /* found all that we need */ | ||
815 | dev_info(&interface->dev, "%s converter detected\n", type->description); | ||
816 | |||
817 | #ifdef CONFIG_USB_SERIAL_GENERIC | 812 | #ifdef CONFIG_USB_SERIAL_GENERIC |
818 | if (type == &usb_serial_generic_device) { | 813 | if (type == &usb_serial_generic_device) { |
819 | num_ports = num_bulk_out; | 814 | num_ports = num_bulk_out; |
@@ -847,6 +842,24 @@ int usb_serial_probe(struct usb_interface *interface, | |||
847 | serial->num_interrupt_in = num_interrupt_in; | 842 | serial->num_interrupt_in = num_interrupt_in; |
848 | serial->num_interrupt_out = num_interrupt_out; | 843 | serial->num_interrupt_out = num_interrupt_out; |
849 | 844 | ||
845 | /* check that the device meets the driver's requirements */ | ||
846 | if ((type->num_interrupt_in != NUM_DONT_CARE && | ||
847 | type->num_interrupt_in != num_interrupt_in) | ||
848 | || (type->num_interrupt_out != NUM_DONT_CARE && | ||
849 | type->num_interrupt_out != num_interrupt_out) | ||
850 | || (type->num_bulk_in != NUM_DONT_CARE && | ||
851 | type->num_bulk_in != num_bulk_in) | ||
852 | || (type->num_bulk_out != NUM_DONT_CARE && | ||
853 | type->num_bulk_out != num_bulk_out)) { | ||
854 | dbg("wrong number of endpoints"); | ||
855 | kfree(serial); | ||
856 | return -EIO; | ||
857 | } | ||
858 | |||
859 | /* found all that we need */ | ||
860 | dev_info(&interface->dev, "%s converter detected\n", | ||
861 | type->description); | ||
862 | |||
850 | /* create our ports, we need as many as the max endpoints */ | 863 | /* create our ports, we need as many as the max endpoints */ |
851 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ | 864 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ |
852 | max_endpoints = max(num_bulk_in, num_bulk_out); | 865 | max_endpoints = max(num_bulk_in, num_bulk_out); |
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index e8b8928232c8..488ce128885c 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h | |||
@@ -141,7 +141,7 @@ struct usb_serial { | |||
141 | }; | 141 | }; |
142 | #define to_usb_serial(d) container_of(d, struct usb_serial, kref) | 142 | #define to_usb_serial(d) container_of(d, struct usb_serial, kref) |
143 | 143 | ||
144 | #define NUM_DONT_CARE (-1) | 144 | #define NUM_DONT_CARE 99 |
145 | 145 | ||
146 | /* get and set the serial private data pointer helper functions */ | 146 | /* get and set the serial private data pointer helper functions */ |
147 | static inline void *usb_get_serial_data (struct usb_serial *serial) | 147 | 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) | |||
160 | * in the syslog messages when a device is inserted or removed. | 160 | * in the syslog messages when a device is inserted or removed. |
161 | * @id_table: pointer to a list of usb_device_id structures that define all | 161 | * @id_table: pointer to a list of usb_device_id structures that define all |
162 | * of the devices this structure can support. | 162 | * of the devices this structure can support. |
163 | * @num_interrupt_in: the number of interrupt in endpoints this device will | 163 | * @num_interrupt_in: If a device doesn't have this many interrupt-in |
164 | * have. | 164 | * endpoints, it won't be sent to the driver's attach() method. |
165 | * @num_interrupt_out: the number of interrupt out endpoints this device will | 165 | * (But it might still be sent to the probe() method.) |
166 | * have. | 166 | * @num_interrupt_out: If a device doesn't have this many interrupt-out |
167 | * @num_bulk_in: the number of bulk in endpoints this device will have. | 167 | * endpoints, it won't be sent to the driver's attach() method. |
168 | * @num_bulk_out: the number of bulk out endpoints this device will have. | 168 | * (But it might still be sent to the probe() method.) |
169 | * @num_bulk_in: If a device doesn't have this many bulk-in | ||
170 | * endpoints, it won't be sent to the driver's attach() method. | ||
171 | * (But it might still be sent to the probe() method.) | ||
172 | * @num_bulk_out: If a device doesn't have this many bulk-out | ||
173 | * endpoints, it won't be sent to the driver's attach() method. | ||
174 | * (But it might still be sent to the probe() method.) | ||
169 | * @num_ports: the number of different ports this device will have. | 175 | * @num_ports: the number of different ports this device will have. |
170 | * @calc_num_ports: pointer to a function to determine how many ports this | 176 | * @calc_num_ports: pointer to a function to determine how many ports this |
171 | * device has dynamically. It will be called after the probe() | 177 | * device has dynamically. It will be called after the probe() |