diff --git a/drivers/usb/serial/f81534.c b/drivers/usb/serial/f81534.c index 22f23a429a95cb6a1cdeaca445a92035fd3e98e8..385087c008ed6dc956d58312a46beca2dc2d2c0d 100644 --- a/drivers/usb/serial/f81534.c +++ b/drivers/usb/serial/f81534.c @@ -611,7 +611,8 @@ static int f81534_find_config_idx(struct usb_serial *serial, u8 *index) * The f81534_calc_num_ports() will run to "new style" with checking * F81534_PORT_UNAVAILABLE section. */ -static int f81534_calc_num_ports(struct usb_serial *serial) +static int f81534_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { u8 setting[F81534_CUSTOM_DATA_SIZE]; u8 setting_idx; diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index ec1b8f2c11837fecd39468c1e053880d72da9f94..df5f1a7d7c6ffd92b8ba5d7d6294b25c2373d0f3 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -33,7 +33,8 @@ static int initial_wait; /* Function prototypes for an ipaq */ static int ipaq_open(struct tty_struct *tty, struct usb_serial_port *port); -static int ipaq_calc_num_ports(struct usb_serial *serial); +static int ipaq_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds); static int ipaq_startup(struct usb_serial *serial); static const struct usb_device_id ipaq_id_table[] = { @@ -550,7 +551,8 @@ static int ipaq_open(struct tty_struct *tty, return usb_serial_generic_open(tty, port); } -static int ipaq_calc_num_ports(struct usb_serial *serial) +static int ipaq_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { /* * some devices have 3 endpoints, the 3rd of which diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index df45ebad5f6f80ff425204f2192ffce73d315095..9ec3e4fb96789af6ebef8af64d89f474a753294f 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c @@ -973,7 +973,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) tty_port_tty_wakeup(&mos7720_port->port->port); } -static int mos77xx_calc_num_ports(struct usb_serial *serial) +static int mos77xx_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); if (product == MOSCHIP_DEVICE_ID_7715) diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 3821c53fcee9ec2c269ce562ef25d7a67ed34965..326d6c5055ef4c2a8cde9c8f2b85f04b425518bb 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c @@ -2104,7 +2104,8 @@ static int mos7840_probe(struct usb_serial *serial, return 0; } -static int mos7840_calc_num_ports(struct usb_serial *serial) +static int mos7840_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { int device_type = (unsigned long)usb_get_serial_data(serial); int mos7840_num_ports; diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c index c88215a0fa3d8d0eaa22be4e873cf59d2525e481..bf543e6c05ea30036f084df635cd3fcc75e37f23 100644 --- a/drivers/usb/serial/mxuport.c +++ b/drivers/usb/serial/mxuport.c @@ -946,7 +946,8 @@ static void mxuport_set_termios(struct tty_struct *tty, * Determine how many ports this device has dynamically. It will be * called after the probe() callback is called, but before attach(). */ -static int mxuport_calc_num_ports(struct usb_serial *serial) +static int mxuport_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { unsigned long features = (unsigned long)usb_get_serial_data(serial); diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index fdbb904d153f735b83c007137eaa42d5bf76a6b4..6ddcaa2de90244baa562129aa49abd061442fc2e 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c @@ -246,7 +246,8 @@ static inline int update_mctrl(struct qt2_port_private *port_priv, return status; } -static int qt2_calc_num_ports(struct usb_serial *serial) +static int qt2_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { struct qt2_device_detail d; int i; diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 465e851b281585b3b7445177868a061cecfd3c15..4c4ac4705ac03f8d850a653fe91e35b78bfe25b6 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c @@ -85,7 +85,8 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) USB_CTRL_SET_TIMEOUT); /* int timeout */ } -static int sierra_calc_num_ports(struct usb_serial *serial) +static int sierra_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { int num_ports = 0; u8 ifnum, numendpoints; diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 747dd414bef9bc16fcdcc5bf50e8fc7ab58ea082..f0761f491c5f393480653637fe0195dea2d90250 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -710,17 +710,6 @@ static const struct tty_port_operations serial_port_ops = { .shutdown = serial_port_shutdown, }; -struct usb_serial_endpoints { - unsigned char num_bulk_in; - unsigned char num_bulk_out; - unsigned char num_interrupt_in; - unsigned char num_interrupt_out; - struct usb_endpoint_descriptor *bulk_in[MAX_NUM_PORTS]; - struct usb_endpoint_descriptor *bulk_out[MAX_NUM_PORTS]; - struct usb_endpoint_descriptor *interrupt_in[MAX_NUM_PORTS]; - struct usb_endpoint_descriptor *interrupt_out[MAX_NUM_PORTS]; -}; - static void find_endpoints(struct usb_serial *serial, struct usb_serial_endpoints *epds) { @@ -875,8 +864,12 @@ static int usb_serial_probe(struct usb_interface *interface, #endif if (!num_ports) { /* if this device type has a calc_num_ports function, call it */ - if (type->calc_num_ports) - num_ports = type->calc_num_ports(serial); + if (type->calc_num_ports) { + retval = type->calc_num_ports(serial, epds); + if (retval < 0) + goto err_free_epds; + num_ports = retval; + } if (!num_ports) num_ports = type->num_ports; } diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 337a0be89fcf0767f67731a9b0a50700e1df9318..3f943f877ac2ec3143b2424093d52cb35bbdbcee 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -40,7 +40,8 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); static void visor_close(struct usb_serial_port *port); static int visor_probe(struct usb_serial *serial, const struct usb_device_id *id); -static int visor_calc_num_ports(struct usb_serial *serial); +static int visor_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds); static void visor_read_int_callback(struct urb *urb); static int clie_3_5_startup(struct usb_serial *serial); static int treo_attach(struct usb_serial *serial); @@ -466,7 +467,8 @@ static int visor_probe(struct usb_serial *serial, return retval; } -static int visor_calc_num_ports(struct usb_serial *serial) +static int visor_calc_num_ports(struct usb_serial *serial, + struct usb_serial_endpoints *epds) { int num_ports = (int)(long)(usb_get_serial_data(serial)); diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h index f1b8a84937626cc66fea2153c657889cd65c6c31..da528818cfd89c392089feeb17db7bafe9b2dd1f 100644 --- a/include/linux/usb/serial.h +++ b/include/linux/usb/serial.h @@ -181,6 +181,17 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) serial->private = data; } +struct usb_serial_endpoints { + unsigned char num_bulk_in; + unsigned char num_bulk_out; + unsigned char num_interrupt_in; + unsigned char num_interrupt_out; + struct usb_endpoint_descriptor *bulk_in[MAX_NUM_PORTS]; + struct usb_endpoint_descriptor *bulk_out[MAX_NUM_PORTS]; + struct usb_endpoint_descriptor *interrupt_in[MAX_NUM_PORTS]; + struct usb_endpoint_descriptor *interrupt_out[MAX_NUM_PORTS]; +}; + /** * usb_serial_driver - describes a usb serial driver * @description: pointer to a string that describes this driver. This string @@ -196,8 +207,9 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) * (0 = end-point size) * @bulk_out_size: bytes to allocate for bulk-out buffer (0 = end-point size) * @calc_num_ports: pointer to a function to determine how many ports this - * device has dynamically. It will be called after the probe() - * callback is called, but before attach() + * device has dynamically. It can also be used to verify the number of + * endpoints or to modify the port-endpoint mapping. It will be called + * after the probe() callback is called, but before attach(). * @probe: pointer to the driver's probe function. * This will be called when the device is inserted into the system, * but before the device has been fully initialized by the usb_serial @@ -249,7 +261,8 @@ struct usb_serial_driver { int (*probe)(struct usb_serial *serial, const struct usb_device_id *id); int (*attach)(struct usb_serial *serial); - int (*calc_num_ports) (struct usb_serial *serial); + int (*calc_num_ports)(struct usb_serial *serial, + struct usb_serial_endpoints *epds); void (*disconnect)(struct usb_serial *serial); void (*release)(struct usb_serial *serial);