USB: serial: visor: clean up treo endpoint hack
Use the new endpoint-remap functionality to configure the ports for treo devices instead of poking around in the port structures after the ports have been setup. Signed-off-by: Johan Hovold <johan@kernel.org>
This commit is contained in:
Родитель
da2befa6d5
Коммит
ea3c6ebdcb
|
@ -46,7 +46,6 @@ static int clie_5_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);
|
||||
static int palm_os_3_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id);
|
||||
static int palm_os_4_probe(struct usb_serial *serial,
|
||||
|
@ -176,7 +175,6 @@ static struct usb_serial_driver handspring_device = {
|
|||
.close = visor_close,
|
||||
.throttle = usb_serial_generic_throttle,
|
||||
.unthrottle = usb_serial_generic_unthrottle,
|
||||
.attach = treo_attach,
|
||||
.probe = visor_probe,
|
||||
.calc_num_ports = visor_calc_num_ports,
|
||||
.read_int_callback = visor_read_int_callback,
|
||||
|
@ -471,11 +469,35 @@ static int visor_probe(struct usb_serial *serial,
|
|||
static int visor_calc_num_ports(struct usb_serial *serial,
|
||||
struct usb_serial_endpoints *epds)
|
||||
{
|
||||
unsigned int vid = le16_to_cpu(serial->dev->descriptor.idVendor);
|
||||
int num_ports = (int)(long)(usb_get_serial_data(serial));
|
||||
|
||||
if (num_ports)
|
||||
usb_set_serial_data(serial, NULL);
|
||||
|
||||
/*
|
||||
* Only swap the bulk endpoints for the Handspring devices with
|
||||
* interrupt in endpoints, which for now are the Treo devices.
|
||||
*/
|
||||
if (!(vid == HANDSPRING_VENDOR_ID || vid == KYOCERA_VENDOR_ID) ||
|
||||
epds->num_interrupt_in == 0)
|
||||
goto out;
|
||||
|
||||
if (epds->num_bulk_in < 2 || epds->num_interrupt_in < 2) {
|
||||
dev_err(&serial->interface->dev, "missing endpoints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* It appears that Treos and Kyoceras want to use the
|
||||
* 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
|
||||
* so let's swap the 1st and 2nd bulk in and interrupt endpoints.
|
||||
* Note that swapping the bulk out endpoints would break lots of
|
||||
* apps that want to communicate on the second port.
|
||||
*/
|
||||
swap(epds->bulk_in[0], epds->bulk_in[1]);
|
||||
swap(epds->interrupt_in[0], epds->interrupt_in[1]);
|
||||
out:
|
||||
return num_ports;
|
||||
}
|
||||
|
||||
|
@ -553,62 +575,6 @@ out:
|
|||
return result;
|
||||
}
|
||||
|
||||
static int treo_attach(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *swap_port;
|
||||
|
||||
/* Only do this endpoint hack for the Handspring devices with
|
||||
* interrupt in endpoints, which for now are the Treo devices. */
|
||||
if (!((le16_to_cpu(serial->dev->descriptor.idVendor)
|
||||
== HANDSPRING_VENDOR_ID) ||
|
||||
(le16_to_cpu(serial->dev->descriptor.idVendor)
|
||||
== KYOCERA_VENDOR_ID)) ||
|
||||
(serial->num_interrupt_in == 0))
|
||||
return 0;
|
||||
|
||||
if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) {
|
||||
dev_err(&serial->interface->dev, "missing endpoints\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
* It appears that Treos and Kyoceras want to use the
|
||||
* 1st bulk in endpoint to communicate with the 2nd bulk out endpoint,
|
||||
* so let's swap the 1st and 2nd bulk in and interrupt endpoints.
|
||||
* Note that swapping the bulk out endpoints would break lots of
|
||||
* apps that want to communicate on the second port.
|
||||
*/
|
||||
#define COPY_PORT(dest, src) \
|
||||
do { \
|
||||
int i; \
|
||||
\
|
||||
for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) { \
|
||||
dest->read_urbs[i] = src->read_urbs[i]; \
|
||||
dest->read_urbs[i]->context = dest; \
|
||||
dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \
|
||||
} \
|
||||
dest->read_urb = src->read_urb; \
|
||||
dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\
|
||||
dest->bulk_in_buffer = src->bulk_in_buffer; \
|
||||
dest->bulk_in_size = src->bulk_in_size; \
|
||||
dest->interrupt_in_urb = src->interrupt_in_urb; \
|
||||
dest->interrupt_in_urb->context = dest; \
|
||||
dest->interrupt_in_endpointAddress = \
|
||||
src->interrupt_in_endpointAddress;\
|
||||
dest->interrupt_in_buffer = src->interrupt_in_buffer; \
|
||||
} while (0);
|
||||
|
||||
swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL);
|
||||
if (!swap_port)
|
||||
return -ENOMEM;
|
||||
COPY_PORT(swap_port, serial->port[0]);
|
||||
COPY_PORT(serial->port[0], serial->port[1]);
|
||||
COPY_PORT(serial->port[1], swap_port);
|
||||
kfree(swap_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_usb_serial_driver(serial_drivers, id_table_combined);
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
|
|
Загрузка…
Ссылка в новой задаче