summaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/ipaq.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-26 15:23:24 -0700
committerDavid S. Miller <davem@davemloft.net>2009-03-26 15:23:24 -0700
commit08abe18af1f78ee80c3c3a5ac47c3e0ae0beadf6 (patch)
tree2be39bf8942edca1bcec735145e144a682ca9cd3 /drivers/usb/serial/ipaq.c
parentf0de70f8bb56952f6e016a65a8a8d006918f5bf6 (diff)
parent0384e2959127a56d0640505d004d8dd92f9c29f5 (diff)
Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts: drivers/net/wimax/i2400m/usb-notif.c
Diffstat (limited to 'drivers/usb/serial/ipaq.c')
-rw-r--r--drivers/usb/serial/ipaq.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 132be74d2b8..ef92095b073 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,
struct usb_serial_port *port, struct file *filp);
static void ipaq_close(struct tty_struct *tty,
struct usb_serial_port *port, struct file *filp);
+static int ipaq_calc_num_ports(struct usb_serial *serial);
static int ipaq_startup(struct usb_serial *serial);
static void ipaq_shutdown(struct usb_serial *serial);
static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port,
@@ -572,15 +573,10 @@ static struct usb_serial_driver ipaq_device = {
.description = "PocketPC PDA",
.usb_driver = &ipaq_driver,
.id_table = ipaq_id_table,
- /*
- * some devices have an extra endpoint, which
- * must be ignored as it would make the core
- * create a second port which oopses when used
- */
- .num_ports = 1,
.open = ipaq_open,
.close = ipaq_close,
.attach = ipaq_startup,
+ .calc_num_ports = ipaq_calc_num_ports,
.shutdown = ipaq_shutdown,
.write = ipaq_write,
.write_room = ipaq_write_room,
@@ -956,14 +952,49 @@ static void ipaq_destroy_lists(struct usb_serial_port *port)
}
+static int ipaq_calc_num_ports(struct usb_serial *serial)
+{
+ /*
+ * some devices have 3 endpoints, the 3rd of which
+ * must be ignored as it would make the core
+ * create a second port which oopses when used
+ */
+ int ipaq_num_ports = 1;
+
+ dbg("%s - numberofendpoints: %d", __FUNCTION__,
+ (int)serial->interface->cur_altsetting->desc.bNumEndpoints);
+
+ /*
+ * a few devices have 4 endpoints, seemingly Yakuma devices,
+ * and we need the second pair, so let them have 2 ports
+ *
+ * TODO: can we drop port 1 ?
+ */
+ if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) {
+ ipaq_num_ports = 2;
+ }
+
+ return ipaq_num_ports;
+}
+
+
static int ipaq_startup(struct usb_serial *serial)
{
dbg("%s", __func__);
if (serial->dev->actconfig->desc.bConfigurationValue != 1) {
+ /*
+ * FIXME: HP iPaq rx3715, possibly others, have 1 config that
+ * is labeled as 2
+ */
+
dev_err(&serial->dev->dev, "active config #%d != 1 ??\n",
serial->dev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
+
+ dbg("%s - iPAQ module configured for %d ports",
+ __FUNCTION__, serial->num_ports);
+
return usb_reset_configuration(serial->dev);
}