diff options
author | Mark Ellis <mark@mpellis.org.uk> | 2009-03-09 18:24:29 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2009-03-24 19:20:45 -0400 |
commit | 1b8fb4141eb52f4aace9f152dad3e4c1609b76fe (patch) | |
tree | 500fd00be0cc7056c0b9741ec641e94a087a58a5 | |
parent | 49121aa14c2a372a5fd01982df900257784be63d (diff) |
USB: ipaq: handle 4 endpoint devices
The ipaq driver currently enforces one port on all devices. This
is correct for 2 and 3 endpoint devices, but with 4 endpoint devices
meaningful communication occurs on the second pair.
This patch allows 2 ports for 4 endpoint devices.
Signed-off-by: Mark Ellis <mark@mpellis.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/serial/ipaq.c | 43 |
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 132be74d2b89..ef92095b0732 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -78,6 +78,7 @@ static int ipaq_open(struct tty_struct *tty, | |||
78 | struct usb_serial_port *port, struct file *filp); | 78 | struct usb_serial_port *port, struct file *filp); |
79 | static void ipaq_close(struct tty_struct *tty, | 79 | static void ipaq_close(struct tty_struct *tty, |
80 | struct usb_serial_port *port, struct file *filp); | 80 | struct usb_serial_port *port, struct file *filp); |
81 | static int ipaq_calc_num_ports(struct usb_serial *serial); | ||
81 | static int ipaq_startup(struct usb_serial *serial); | 82 | static int ipaq_startup(struct usb_serial *serial); |
82 | static void ipaq_shutdown(struct usb_serial *serial); | 83 | static void ipaq_shutdown(struct usb_serial *serial); |
83 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, | 84 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, |
@@ -572,15 +573,10 @@ static struct usb_serial_driver ipaq_device = { | |||
572 | .description = "PocketPC PDA", | 573 | .description = "PocketPC PDA", |
573 | .usb_driver = &ipaq_driver, | 574 | .usb_driver = &ipaq_driver, |
574 | .id_table = ipaq_id_table, | 575 | .id_table = ipaq_id_table, |
575 | /* | ||
576 | * some devices have an extra endpoint, which | ||
577 | * must be ignored as it would make the core | ||
578 | * create a second port which oopses when used | ||
579 | */ | ||
580 | .num_ports = 1, | ||
581 | .open = ipaq_open, | 576 | .open = ipaq_open, |
582 | .close = ipaq_close, | 577 | .close = ipaq_close, |
583 | .attach = ipaq_startup, | 578 | .attach = ipaq_startup, |
579 | .calc_num_ports = ipaq_calc_num_ports, | ||
584 | .shutdown = ipaq_shutdown, | 580 | .shutdown = ipaq_shutdown, |
585 | .write = ipaq_write, | 581 | .write = ipaq_write, |
586 | .write_room = ipaq_write_room, | 582 | .write_room = ipaq_write_room, |
@@ -956,14 +952,49 @@ static void ipaq_destroy_lists(struct usb_serial_port *port) | |||
956 | } | 952 | } |
957 | 953 | ||
958 | 954 | ||
955 | static int ipaq_calc_num_ports(struct usb_serial *serial) | ||
956 | { | ||
957 | /* | ||
958 | * some devices have 3 endpoints, the 3rd of which | ||
959 | * must be ignored as it would make the core | ||
960 | * create a second port which oopses when used | ||
961 | */ | ||
962 | int ipaq_num_ports = 1; | ||
963 | |||
964 | dbg("%s - numberofendpoints: %d", __FUNCTION__, | ||
965 | (int)serial->interface->cur_altsetting->desc.bNumEndpoints); | ||
966 | |||
967 | /* | ||
968 | * a few devices have 4 endpoints, seemingly Yakuma devices, | ||
969 | * and we need the second pair, so let them have 2 ports | ||
970 | * | ||
971 | * TODO: can we drop port 1 ? | ||
972 | */ | ||
973 | if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) { | ||
974 | ipaq_num_ports = 2; | ||
975 | } | ||
976 | |||
977 | return ipaq_num_ports; | ||
978 | } | ||
979 | |||
980 | |||
959 | static int ipaq_startup(struct usb_serial *serial) | 981 | static int ipaq_startup(struct usb_serial *serial) |
960 | { | 982 | { |
961 | dbg("%s", __func__); | 983 | dbg("%s", __func__); |
962 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { | 984 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { |
985 | /* | ||
986 | * FIXME: HP iPaq rx3715, possibly others, have 1 config that | ||
987 | * is labeled as 2 | ||
988 | */ | ||
989 | |||
963 | dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", | 990 | dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", |
964 | serial->dev->actconfig->desc.bConfigurationValue); | 991 | serial->dev->actconfig->desc.bConfigurationValue); |
965 | return -ENODEV; | 992 | return -ENODEV; |
966 | } | 993 | } |
994 | |||
995 | dbg("%s - iPAQ module configured for %d ports", | ||
996 | __FUNCTION__, serial->num_ports); | ||
997 | |||
967 | return usb_reset_configuration(serial->dev); | 998 | return usb_reset_configuration(serial->dev); |
968 | } | 999 | } |
969 | 1000 | ||