fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / drivers / usb / serial / ipaq.c
index 9a5c979..42f757a 100644 (file)
@@ -44,7 +44,6 @@
  *     Thanks to info from Heath Robinson and Arieh Davidoff.
  */
 
-#include <linux/config.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
 #include <linux/init.h>
@@ -56,7 +55,7 @@
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
-#include "usb-serial.h"
+#include <linux/usb/serial.h>
 #include "ipaq.h"
 
 #define KP_RETRIES     100
@@ -71,6 +70,8 @@
 
 static __u16 product, vendor;
 static int debug;
+static int connect_retries = KP_RETRIES;
+static int initial_wait;
 
 /* Function prototypes for an ipaq */
 static int  ipaq_open (struct usb_serial_port *port, struct file *filp);
@@ -82,8 +83,8 @@ static int ipaq_write(struct usb_serial_port *port, const unsigned char *buf,
 static int ipaq_write_bulk(struct usb_serial_port *port, const unsigned char *buf,
                           int count);
 static void ipaq_write_gather(struct usb_serial_port *port);
-static void ipaq_read_bulk_callback (struct urb *urb, struct pt_regs *regs);
-static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs);
+static void ipaq_read_bulk_callback (struct urb *urb);
+static void ipaq_write_bulk_callback(struct urb *urb);
 static int ipaq_write_room(struct usb_serial_port *port);
 static int ipaq_chars_in_buffer(struct usb_serial_port *port);
 static void ipaq_destroy_lists(struct usb_serial_port *port);
@@ -249,6 +250,9 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x04C5, 0x1058) }, /* FUJITSU USB Sync */
        { USB_DEVICE(0x04C5, 0x1079) }, /* FUJITSU USB Sync */
        { USB_DEVICE(0x04DA, 0x2500) }, /* Panasonic USB Sync */
+       { USB_DEVICE(0x04DD, 0x9102) }, /* SHARP WS003SH USB Modem */
+       { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */
+       { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */
        { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */
        { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */
        { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */
@@ -316,6 +320,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x0B05, 0x9200) }, /* ASUS USB Sync */
        { USB_DEVICE(0x0B05, 0x9202) }, /* ASUS USB Sync */
        { USB_DEVICE(0x0BB4, 0x00CE) }, /* HTC USB Sync */
+       { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC USB Modem */
        { USB_DEVICE(0x0BB4, 0x0A01) }, /* PocketPC USB Sync */
        { USB_DEVICE(0x0BB4, 0x0A02) }, /* PocketPC USB Sync */
        { USB_DEVICE(0x0BB4, 0x0A03) }, /* PocketPC USB Sync */
@@ -475,6 +480,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x0BB4, 0x0A9D) }, /* SmartPhone USB Sync */
        { USB_DEVICE(0x0BB4, 0x0A9E) }, /* SmartPhone USB Sync */
        { USB_DEVICE(0x0BB4, 0x0A9F) }, /* SmartPhone USB Sync */
+       { USB_DEVICE(0x0BB4, 0x0BCE) }, /* "High Tech Computer Corp" */
        { USB_DEVICE(0x0BF8, 0x1001) }, /* Fujitsu Siemens Computers USB Sync */
        { USB_DEVICE(0x0C44, 0x03A2) }, /* Motorola iDEN Smartphone */
        { USB_DEVICE(0x0C8E, 0x6000) }, /* Cesscom Luxian Series */
@@ -583,13 +589,13 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
        struct ipaq_private     *priv;
        struct ipaq_packet      *pkt;
        int                     i, result = 0;
-       int                     retries = KP_RETRIES;
+       int                     retries = connect_retries;
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        bytes_in = 0;
        bytes_out = 0;
-       priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
+       priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL);
        if (priv == NULL) {
                err("%s - Out of memory", __FUNCTION__);
                return -ENOMEM;
@@ -647,16 +653,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
        port->read_urb->transfer_buffer_length = URBDATA_SIZE;
        port->bulk_out_size = port->write_urb->transfer_buffer_length = URBDATA_SIZE;
        
-       /* Start reading from the device */
-       usb_fill_bulk_urb(port->read_urb, serial->dev, 
-                     usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
-                     port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
-                     ipaq_read_bulk_callback, port);
-       result = usb_submit_urb(port->read_urb, GFP_KERNEL);
-       if (result) {
-               err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
-               goto error;
-       }
+       msleep(1000*initial_wait);
 
        /*
         * Send out control message observed in win98 sniffs. Not sure what
@@ -670,12 +667,31 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp)
                result = usb_control_msg(serial->dev,
                                usb_sndctrlpipe(serial->dev, 0), 0x22, 0x21,
                                0x1, 0, NULL, 0, 100);
-               if (result == 0) {
-                       return 0;
-               }
+               if (!result)
+                       break;
+
+               msleep(1000);
        }
-       err("%s - failed doing control urb, error %d", __FUNCTION__, result);
-       goto error;
+
+       if (!retries && result) {
+               err("%s - failed doing control urb, error %d", __FUNCTION__,
+                   result);
+               goto error;
+       }
+
+       /* Start reading from the device */
+       usb_fill_bulk_urb(port->read_urb, serial->dev,
+                     usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
+                     port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
+                     ipaq_read_bulk_callback, port);
+
+       result = usb_submit_urb(port->read_urb, GFP_KERNEL);
+       if (result) {
+               err("%s - failed submitting read urb, error %d", __FUNCTION__, result);
+               goto error;
+       }
+
+       return 0;
 
 enomem:
        result = -ENOMEM;
@@ -706,7 +722,7 @@ static void ipaq_close(struct usb_serial_port *port, struct file *filp)
        /* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
 }
 
-static void ipaq_read_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ipaq_read_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port  *port = (struct usb_serial_port *)urb->context;
        struct tty_struct       *tty;
@@ -844,7 +860,7 @@ static void ipaq_write_gather(struct usb_serial_port *port)
        return;
 }
 
-static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void ipaq_write_bulk_callback(struct urb *urb)
 {
        struct usb_serial_port  *port = (struct usb_serial_port *)urb->context;
        struct ipaq_private     *priv = usb_get_serial_port_data(port);
@@ -855,6 +871,7 @@ static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
        
        if (urb->status) {
                dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status);
+               return;
        }
 
        spin_lock_irqsave(&write_list_lock, flags);
@@ -870,7 +887,7 @@ static void ipaq_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
                spin_unlock_irqrestore(&write_list_lock, flags);
        }
 
-       schedule_work(&port->work);
+       usb_serial_port_softint(port);
 }
 
 static int ipaq_write_room(struct usb_serial_port *port)
@@ -967,3 +984,9 @@ MODULE_PARM_DESC(vendor, "User specified USB idVendor");
 
 module_param(product, ushort, 0);
 MODULE_PARM_DESC(product, "User specified USB idProduct");
+
+module_param(connect_retries, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(connect_retries, "Maximum number of connect retries (one second each)");
+
+module_param(initial_wait, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(initial_wait, "Time to wait before attempting a connection (in seconds)");