提交 063a2da8 编写于 作者: A Alan Stern 提交者: Greg Kroah-Hartman

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: NAlan Stern <stern@rowland.harvard.edu>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 cd38c1e1
...@@ -662,16 +662,14 @@ static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, ...@@ -662,16 +662,14 @@ static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv,
static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) static struct usb_serial_driver *search_serial_device(struct usb_interface *iface)
{ {
struct list_head *p;
const struct usb_device_id *id; 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 */ /* Check if the usb id matches a known device */
list_for_each(p, &usb_serial_driver_list) { list_for_each_entry(drv, &usb_serial_driver_list, driver_list) {
t = list_entry(p, struct usb_serial_driver, driver_list); id = get_iface_id(drv, iface);
id = get_iface_id(t, iface);
if (id) if (id)
return t; return drv;
} }
return NULL; return NULL;
...@@ -811,9 +809,6 @@ int usb_serial_probe(struct usb_interface *interface, ...@@ -811,9 +809,6 @@ int usb_serial_probe(struct usb_interface *interface,
/* END HORRIBLE HACK FOR PL2303 */ /* END HORRIBLE HACK FOR PL2303 */
#endif #endif
/* found all that we need */
dev_info(&interface->dev, "%s converter detected\n", type->description);
#ifdef CONFIG_USB_SERIAL_GENERIC #ifdef CONFIG_USB_SERIAL_GENERIC
if (type == &usb_serial_generic_device) { if (type == &usb_serial_generic_device) {
num_ports = num_bulk_out; num_ports = num_bulk_out;
...@@ -847,6 +842,24 @@ int usb_serial_probe(struct usb_interface *interface, ...@@ -847,6 +842,24 @@ int usb_serial_probe(struct usb_interface *interface,
serial->num_interrupt_in = num_interrupt_in; serial->num_interrupt_in = num_interrupt_in;
serial->num_interrupt_out = num_interrupt_out; 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 */ /* 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 */ /* 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); max_endpoints = max(num_bulk_in, num_bulk_out);
......
...@@ -141,7 +141,7 @@ struct usb_serial { ...@@ -141,7 +141,7 @@ struct usb_serial {
}; };
#define to_usb_serial(d) container_of(d, struct usb_serial, kref) #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 */ /* get and set the serial private data pointer helper functions */
static inline void *usb_get_serial_data (struct usb_serial *serial) 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,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. * 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 * @id_table: pointer to a list of usb_device_id structures that define all
* of the devices this structure can support. * of the devices this structure can support.
* @num_interrupt_in: the number of interrupt in endpoints this device will * @num_interrupt_in: If a device doesn't have this many interrupt-in
* have. * endpoints, it won't be sent to the driver's attach() method.
* @num_interrupt_out: the number of interrupt out endpoints this device will * (But it might still be sent to the probe() method.)
* have. * @num_interrupt_out: If a device doesn't have this many interrupt-out
* @num_bulk_in: the number of bulk in endpoints this device will have. * endpoints, it won't be sent to the driver's attach() method.
* @num_bulk_out: the number of bulk out endpoints this device will have. * (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. * @num_ports: the number of different ports this device will have.
* @calc_num_ports: pointer to a function to determine how many ports this * @calc_num_ports: pointer to a function to determine how many ports this
* device has dynamically. It will be called after the probe() * device has dynamically. It will be called after the probe()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册