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>
This commit is contained in:
parent
cd38c1e1ae
commit
063a2da8f0
|
@ -662,16 +662,14 @@ exit:
|
||||||
|
|
||||||
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,
|
||||||
/* 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,
|
||||||
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 {
|
||||||
};
|
};
|
||||||
#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)
|
||||||
* 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()
|
||||||
|
|
Reference in New Issue