ChangeSet 1.1068.7.1, 2003/03/05 11:41:00-08:00, greg@kroah.com [PATCH] USB: add support for Treo devices to the visor driver. Finally... drivers/usb/serial/visor.c | 49 ++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 48 insertions(+), 1 deletion(-) diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c --- a/drivers/usb/serial/visor.c Thu Mar 6 16:08:41 2003 +++ b/drivers/usb/serial/visor.c Thu Mar 6 16:08:41 2003 @@ -12,6 +12,9 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * + * (03/05/2003) gkh + * Think Treo support is now working. + * * (04/03/2002) gkh * Added support for the Sony OS 4.1 devices. Thanks to Hiroyuki ARAKI * for the information. @@ -156,7 +159,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v2.0" +#define DRIVER_VERSION "v2.1" #define DRIVER_AUTHOR "Greg Kroah-Hartman " #define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clié driver" @@ -177,6 +180,7 @@ static void visor_read_bulk_callback (struct urb *urb, struct pt_regs *regs); static void visor_read_int_callback (struct urb *urb, struct pt_regs *regs); 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, const struct usb_device_id *id); @@ -262,6 +266,7 @@ .close = visor_close, .throttle = visor_throttle, .unthrottle = visor_unthrottle, + .attach = treo_attach, .probe = visor_probe, .calc_num_ports = visor_calc_num_ports, .shutdown = visor_shutdown, @@ -797,6 +802,48 @@ if (result != 1) { dev_err(dev, "%s: get interface number bad return length: %d\n", __FUNCTION__, result); return -EIO; + } + + return 0; +} + +static int treo_attach (struct usb_serial *serial) +{ + struct usb_serial_port *port; + int i; + + /* Only do this endpoint hack for the Handspring devices with + * interrupt in endpoints, which for now are the Treo devices. */ + if ((serial->dev->descriptor.idVendor != HANDSPRING_VENDOR_ID) || + (serial->num_interrupt_in == 0)) + return 0; + + dbg("%s", __FUNCTION__); + + /* Ok, this is pretty ugly, but these devices want to use the + * interrupt endpoint as paired up with a bulk endpoint for a + * "virtual serial port". So let's force the endpoints to be + * where we want them to be. */ + for (i = serial->num_bulk_in; i < serial->num_ports; ++i) { + port = &serial->port[i]; + port->read_urb = serial->port[0].read_urb; + port->bulk_in_endpointAddress = serial->port[0].bulk_in_endpointAddress; + port->bulk_in_buffer = serial->port[0].bulk_in_buffer; + } + + for (i = serial->num_bulk_out; i < serial->num_ports; ++i) { + port = &serial->port[i]; + port->write_urb = serial->port[0].write_urb; + port->bulk_out_size = serial->port[0].bulk_out_size; + port->bulk_out_endpointAddress = serial->port[0].bulk_out_endpointAddress; + port->bulk_out_buffer = serial->port[0].bulk_out_buffer; + } + + for (i = serial->num_interrupt_in; i < serial->num_ports; ++i) { + port = &serial->port[i]; + port->interrupt_in_urb = serial->port[0].interrupt_in_urb; + port->interrupt_in_endpointAddress = serial->port[0].interrupt_in_endpointAddress; + port->interrupt_in_buffer = serial->port[0].interrupt_in_buffer; } return 0;