|
@@ -46,7 +46,6 @@ static int clie_5_calc_num_ports(struct usb_serial *serial,
|
|
struct usb_serial_endpoints *epds);
|
|
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 palm_os_3_probe(struct usb_serial *serial,
|
|
static int palm_os_3_probe(struct usb_serial *serial,
|
|
const struct usb_device_id *id);
|
|
const struct usb_device_id *id);
|
|
static int palm_os_4_probe(struct usb_serial *serial,
|
|
static int palm_os_4_probe(struct usb_serial *serial,
|
|
@@ -176,7 +175,6 @@ static struct usb_serial_driver handspring_device = {
|
|
.close = visor_close,
|
|
.close = visor_close,
|
|
.throttle = usb_serial_generic_throttle,
|
|
.throttle = usb_serial_generic_throttle,
|
|
.unthrottle = usb_serial_generic_unthrottle,
|
|
.unthrottle = usb_serial_generic_unthrottle,
|
|
- .attach = treo_attach,
|
|
|
|
.probe = visor_probe,
|
|
.probe = visor_probe,
|
|
.calc_num_ports = visor_calc_num_ports,
|
|
.calc_num_ports = visor_calc_num_ports,
|
|
.read_int_callback = visor_read_int_callback,
|
|
.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,
|
|
static int visor_calc_num_ports(struct usb_serial *serial,
|
|
struct usb_serial_endpoints *epds)
|
|
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));
|
|
int num_ports = (int)(long)(usb_get_serial_data(serial));
|
|
|
|
|
|
if (num_ports)
|
|
if (num_ports)
|
|
usb_set_serial_data(serial, NULL);
|
|
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;
|
|
return num_ports;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -553,62 +575,6 @@ out:
|
|
return result;
|
|
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_usb_serial_driver(serial_drivers, id_table_combined);
|
|
|
|
|
|
MODULE_AUTHOR(DRIVER_AUTHOR);
|
|
MODULE_AUTHOR(DRIVER_AUTHOR);
|