Commit 07814246 authored by Johan Hovold's avatar Johan Hovold

USB: serial: allow subdrivers to modify port-endpoint mapping

Allow subdrivers to modify the port-endpoint mapping by passing the
endpoint descriptors to calc_num_ports.

The callback can now also be used to verify that the required endpoints
exists and abort probing otherwise.

This will allow us to get rid of a few hacks in subdrivers that are
already modifying the port-endpoint mapping (or aborting probe due to
missing endpoints), but only after the port structures have been setup.
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
parent 2ac8fc51
...@@ -611,7 +611,8 @@ static int f81534_find_config_idx(struct usb_serial *serial, u8 *index) ...@@ -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 * The f81534_calc_num_ports() will run to "new style" with checking
* F81534_PORT_UNAVAILABLE section. * 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[F81534_CUSTOM_DATA_SIZE];
u8 setting_idx; u8 setting_idx;
......
...@@ -33,7 +33,8 @@ static int initial_wait; ...@@ -33,7 +33,8 @@ static int initial_wait;
/* Function prototypes for an ipaq */ /* Function prototypes for an ipaq */
static int ipaq_open(struct tty_struct *tty, static int ipaq_open(struct tty_struct *tty,
struct usb_serial_port *port); 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 int ipaq_startup(struct usb_serial *serial);
static const struct usb_device_id ipaq_id_table[] = { static const struct usb_device_id ipaq_id_table[] = {
...@@ -550,7 +551,8 @@ static int ipaq_open(struct tty_struct *tty, ...@@ -550,7 +551,8 @@ static int ipaq_open(struct tty_struct *tty,
return usb_serial_generic_open(tty, port); 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 * some devices have 3 endpoints, the 3rd of which
......
...@@ -973,7 +973,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb) ...@@ -973,7 +973,8 @@ static void mos7720_bulk_out_data_callback(struct urb *urb)
tty_port_tty_wakeup(&mos7720_port->port->port); 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); u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
if (product == MOSCHIP_DEVICE_ID_7715) if (product == MOSCHIP_DEVICE_ID_7715)
......
...@@ -2104,7 +2104,8 @@ static int mos7840_probe(struct usb_serial *serial, ...@@ -2104,7 +2104,8 @@ static int mos7840_probe(struct usb_serial *serial,
return 0; 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 device_type = (unsigned long)usb_get_serial_data(serial);
int mos7840_num_ports; int mos7840_num_ports;
......
...@@ -946,7 +946,8 @@ static void mxuport_set_termios(struct tty_struct *tty, ...@@ -946,7 +946,8 @@ static void mxuport_set_termios(struct tty_struct *tty,
* Determine how many ports this device has dynamically. It will be * Determine how many ports this device has dynamically. It will be
* called after the probe() callback is called, but before attach(). * 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); unsigned long features = (unsigned long)usb_get_serial_data(serial);
......
...@@ -246,7 +246,8 @@ static inline int update_mctrl(struct qt2_port_private *port_priv, ...@@ -246,7 +246,8 @@ static inline int update_mctrl(struct qt2_port_private *port_priv,
return status; 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; struct qt2_device_detail d;
int i; int i;
......
...@@ -85,7 +85,8 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable) ...@@ -85,7 +85,8 @@ static int sierra_vsc_set_nmea(struct usb_device *udev, __u16 enable)
USB_CTRL_SET_TIMEOUT); /* int timeout */ 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; int num_ports = 0;
u8 ifnum, numendpoints; u8 ifnum, numendpoints;
......
...@@ -710,17 +710,6 @@ static const struct tty_port_operations serial_port_ops = { ...@@ -710,17 +710,6 @@ static const struct tty_port_operations serial_port_ops = {
.shutdown = serial_port_shutdown, .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, static void find_endpoints(struct usb_serial *serial,
struct usb_serial_endpoints *epds) struct usb_serial_endpoints *epds)
{ {
...@@ -875,8 +864,12 @@ static int usb_serial_probe(struct usb_interface *interface, ...@@ -875,8 +864,12 @@ static int usb_serial_probe(struct usb_interface *interface,
#endif #endif
if (!num_ports) { if (!num_ports) {
/* if this device type has a calc_num_ports function, call it */ /* if this device type has a calc_num_ports function, call it */
if (type->calc_num_ports) if (type->calc_num_ports) {
num_ports = type->calc_num_ports(serial); retval = type->calc_num_ports(serial, epds);
if (retval < 0)
goto err_free_epds;
num_ports = retval;
}
if (!num_ports) if (!num_ports)
num_ports = type->num_ports; num_ports = type->num_ports;
} }
......
...@@ -40,7 +40,8 @@ static int visor_open(struct tty_struct *tty, struct usb_serial_port *port); ...@@ -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 void visor_close(struct usb_serial_port *port);
static int visor_probe(struct usb_serial *serial, static int visor_probe(struct usb_serial *serial,
const struct usb_device_id *id); 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 void visor_read_int_callback(struct urb *urb);
static int clie_3_5_startup(struct usb_serial *serial); static int clie_3_5_startup(struct usb_serial *serial);
static int treo_attach(struct usb_serial *serial); static int treo_attach(struct usb_serial *serial);
...@@ -466,7 +467,8 @@ static int visor_probe(struct usb_serial *serial, ...@@ -466,7 +467,8 @@ static int visor_probe(struct usb_serial *serial,
return retval; 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)); int num_ports = (int)(long)(usb_get_serial_data(serial));
......
...@@ -181,6 +181,17 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data) ...@@ -181,6 +181,17 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
serial->private = 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 * usb_serial_driver - describes a usb serial driver
* @description: pointer to a string that describes this driver. This string * @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) ...@@ -196,8 +207,9 @@ static inline void usb_set_serial_data(struct usb_serial *serial, void *data)
* (0 = end-point size) * (0 = end-point size)
* @bulk_out_size: bytes to allocate for bulk-out buffer (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 * @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 can also be used to verify the number of
* callback is called, but before attach() * 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. * @probe: pointer to the driver's probe function.
* This will be called when the device is inserted into the system, * This will be called when the device is inserted into the system,
* but before the device has been fully initialized by the usb_serial * but before the device has been fully initialized by the usb_serial
...@@ -249,7 +261,8 @@ struct usb_serial_driver { ...@@ -249,7 +261,8 @@ struct usb_serial_driver {
int (*probe)(struct usb_serial *serial, const struct usb_device_id *id); int (*probe)(struct usb_serial *serial, const struct usb_device_id *id);
int (*attach)(struct usb_serial *serial); 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 (*disconnect)(struct usb_serial *serial);
void (*release)(struct usb_serial *serial); void (*release)(struct usb_serial *serial);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment