Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+24 -58
+24 -58
drivers/usb/serial/visor.c
··· 46 46 struct usb_serial_endpoints *epds); 47 47 static void visor_read_int_callback(struct urb *urb); 48 48 static int clie_3_5_startup(struct usb_serial *serial); 49 - static int treo_attach(struct usb_serial *serial); 50 49 static int palm_os_3_probe(struct usb_serial *serial, 51 50 const struct usb_device_id *id); 52 51 static int palm_os_4_probe(struct usb_serial *serial, ··· 175 176 .close = visor_close, 176 177 .throttle = usb_serial_generic_throttle, 177 178 .unthrottle = usb_serial_generic_unthrottle, 178 - .attach = treo_attach, 179 179 .probe = visor_probe, 180 180 .calc_num_ports = visor_calc_num_ports, 181 181 .read_int_callback = visor_read_int_callback, ··· 469 471 static int visor_calc_num_ports(struct usb_serial *serial, 470 472 struct usb_serial_endpoints *epds) 471 473 { 474 + unsigned int vid = le16_to_cpu(serial->dev->descriptor.idVendor); 472 475 int num_ports = (int)(long)(usb_get_serial_data(serial)); 473 476 474 477 if (num_ports) 475 478 usb_set_serial_data(serial, NULL); 476 479 480 + /* 481 + * Only swap the bulk endpoints for the Handspring devices with 482 + * interrupt in endpoints, which for now are the Treo devices. 483 + */ 484 + if (!(vid == HANDSPRING_VENDOR_ID || vid == KYOCERA_VENDOR_ID) || 485 + epds->num_interrupt_in == 0) 486 + goto out; 487 + 488 + if (epds->num_bulk_in < 2 || epds->num_interrupt_in < 2) { 489 + dev_err(&serial->interface->dev, "missing endpoints\n"); 490 + return -ENODEV; 491 + } 492 + 493 + /* 494 + * It appears that Treos and Kyoceras want to use the 495 + * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, 496 + * so let's swap the 1st and 2nd bulk in and interrupt endpoints. 497 + * Note that swapping the bulk out endpoints would break lots of 498 + * apps that want to communicate on the second port. 499 + */ 500 + swap(epds->bulk_in[0], epds->bulk_in[1]); 501 + swap(epds->interrupt_in[0], epds->interrupt_in[1]); 502 + out: 477 503 return num_ports; 478 504 } 479 505 ··· 573 551 kfree(data); 574 552 575 553 return result; 576 - } 577 - 578 - static int treo_attach(struct usb_serial *serial) 579 - { 580 - struct usb_serial_port *swap_port; 581 - 582 - /* Only do this endpoint hack for the Handspring devices with 583 - * interrupt in endpoints, which for now are the Treo devices. */ 584 - if (!((le16_to_cpu(serial->dev->descriptor.idVendor) 585 - == HANDSPRING_VENDOR_ID) || 586 - (le16_to_cpu(serial->dev->descriptor.idVendor) 587 - == KYOCERA_VENDOR_ID)) || 588 - (serial->num_interrupt_in == 0)) 589 - return 0; 590 - 591 - if (serial->num_bulk_in < 2 || serial->num_interrupt_in < 2) { 592 - dev_err(&serial->interface->dev, "missing endpoints\n"); 593 - return -ENODEV; 594 - } 595 - 596 - /* 597 - * It appears that Treos and Kyoceras want to use the 598 - * 1st bulk in endpoint to communicate with the 2nd bulk out endpoint, 599 - * so let's swap the 1st and 2nd bulk in and interrupt endpoints. 600 - * Note that swapping the bulk out endpoints would break lots of 601 - * apps that want to communicate on the second port. 602 - */ 603 - #define COPY_PORT(dest, src) \ 604 - do { \ 605 - int i; \ 606 - \ 607 - for (i = 0; i < ARRAY_SIZE(src->read_urbs); ++i) { \ 608 - dest->read_urbs[i] = src->read_urbs[i]; \ 609 - dest->read_urbs[i]->context = dest; \ 610 - dest->bulk_in_buffers[i] = src->bulk_in_buffers[i]; \ 611 - } \ 612 - dest->read_urb = src->read_urb; \ 613 - dest->bulk_in_endpointAddress = src->bulk_in_endpointAddress;\ 614 - dest->bulk_in_buffer = src->bulk_in_buffer; \ 615 - dest->bulk_in_size = src->bulk_in_size; \ 616 - dest->interrupt_in_urb = src->interrupt_in_urb; \ 617 - dest->interrupt_in_urb->context = dest; \ 618 - dest->interrupt_in_endpointAddress = \ 619 - src->interrupt_in_endpointAddress;\ 620 - dest->interrupt_in_buffer = src->interrupt_in_buffer; \ 621 - } while (0); 622 - 623 - swap_port = kmalloc(sizeof(*swap_port), GFP_KERNEL); 624 - if (!swap_port) 625 - return -ENOMEM; 626 - COPY_PORT(swap_port, serial->port[0]); 627 - COPY_PORT(serial->port[0], serial->port[1]); 628 - COPY_PORT(serial->port[1], swap_port); 629 - kfree(swap_port); 630 - 631 - return 0; 632 554 } 633 555 634 556 module_usb_serial_driver(serial_drivers, id_table_combined);