This patch updates the visor driver.

diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c        Thu Jan  3 21:41:53 2002
+++ b/drivers/usb/serial/visor.c        Thu Jan  3 21:41:53 2002
@@ -1,7 +1,8 @@
 /*
- * USB HandSpring Visor driver
+ * USB HandSpring Visor, Palm m50x, and Sony Clie driver
+ * (supports all of the Palm OS USB devices)
  *
- *     Copyright (C) 1999, 2000
+ *     Copyright (C) 1999 - 2001
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -11,6 +12,19 @@
  *
  * See Documentation/usb/usb-serial.txt for more information on using this driver
  * 
+ * (08/30/2001) gkh
+ *     Added support for the Clie devices, both the 3.5 and 4.0 os versions.
+ *     Many thanks to Daniel Burke, and Bryan Payne for helping with this.
+ *
+ * (08/23/2001) gkh
+ *     fixed a few potential bugs pointed out by Oliver Neukum.
+ *
+ * (05/30/2001) gkh
+ *     switched from using spinlock to a semaphore, which fixes lots of problems.
+ *
+ * (05/28/2000) gkh
+ *     Added initial support for the Palm m500 and Palm m505 devices.
+ *
  * (04/08/2001) gb
  *     Identify version on module load.
  *
@@ -27,8 +41,11 @@
  * 
  * (11/12/2000) gkh
  *     Fixed bug with data being dropped on the floor by forcing tty->low_latency
- *     to be on.  This fixes the OHCI issue!
+ *     to be on.  Hopefully this fixes the OHCI issue!
  *
+ * (11/01/2000) Adam J. Richter
+ *     usb_device_id table support
+ * 
  * (10/05/2000) gkh
  *     Fixed bug with urb->dev not being set properly, now that the usb
  *     core needs it.
@@ -106,9 +123,9 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.4"
 #define DRIVER_AUTHOR "Greg Kroah-Hartman <[EMAIL PROTECTED]>"
-#define DRIVER_DESC "USB HandSpring Visor driver"
+#define DRIVER_DESC "USB HandSpring Visor, Palm m50x, Sony Clie driver"
 
 #define MIN(a,b)                (((a)<(b))?(a):(b))
 
@@ -127,13 +144,14 @@
 static void visor_write_bulk_callback  (struct urb *urb);
 static void visor_read_bulk_callback   (struct urb *urb);
 
+
 /* All of the device info needed for the Handspring Visor */
 static __u16   handspring_vendor_id    = HANDSPRING_VENDOR_ID;
 static __u16   handspring_product_id   = HANDSPRING_VISOR_ID;
 struct usb_serial_device_type handspring_device = {
        name:                   "Handspring Visor",
-       idVendor:               &handspring_vendor_id,  /* the Handspring vendor ID */
-       idProduct:              &handspring_product_id, /* the Handspring Visor 
product id */
+       idVendor:               &handspring_vendor_id,
+       idProduct:              &handspring_product_id,
        needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have 
an interrupt in endpoint */
        needs_bulk_in:          MUST_HAVE,              /* this device must have a 
bulk in endpoint */
        needs_bulk_out:         MUST_HAVE,              /* this device must have a 
bulk out endpoint */
@@ -156,6 +174,117 @@
        read_bulk_callback:     visor_read_bulk_callback,
 };
 
+/* device info for the Palm M500 */
+static __u16   palm_vendor_id  = PALM_VENDOR_ID;
+static __u16   palm_m500_id    = PALM_M500_ID;
+static __u16   palm_m505_id    = PALM_M505_ID;
+struct usb_serial_device_type palm_m500_device = {
+       name:                   "Palm M500",
+       idVendor:               &palm_vendor_id,
+       idProduct:              &palm_m500_id,
+       needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have 
+an interrupt in endpoint */
+       needs_bulk_in:          MUST_HAVE,              /* this device must have a 
+bulk in endpoint */
+       needs_bulk_out:         MUST_HAVE,              /* this device must have a 
+bulk out endpoint */
+       num_interrupt_in:       0,
+       num_bulk_in:            2,
+       num_bulk_out:           2,
+       num_ports:              2,
+       open:                   visor_open,
+       close:                  visor_close,
+       throttle:               visor_throttle,
+       unthrottle:             visor_unthrottle,
+       startup:                visor_startup,
+       shutdown:               visor_shutdown,
+       ioctl:                  visor_ioctl,
+       set_termios:            visor_set_termios,
+       write:                  visor_write,
+       write_room:             visor_write_room,
+       chars_in_buffer:        visor_chars_in_buffer,
+       write_bulk_callback:    visor_write_bulk_callback,
+       read_bulk_callback:     visor_read_bulk_callback,
+};
+
+/* device info for the Palm M505 */
+struct usb_serial_device_type palm_m505_device = {
+       name:                   "Palm M505",
+       idVendor:               &palm_vendor_id,
+       idProduct:              &palm_m505_id,
+       needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have 
+an interrupt in endpoint */
+       needs_bulk_in:          MUST_HAVE,              /* this device must have a 
+bulk in endpoint */
+       needs_bulk_out:         MUST_HAVE,              /* this device must have a 
+bulk out endpoint */
+       num_interrupt_in:       0,
+       num_bulk_in:            2,
+       num_bulk_out:           2,
+       num_ports:              2,
+       open:                   visor_open,
+       close:                  visor_close,
+       throttle:               visor_throttle,
+       unthrottle:             visor_unthrottle,
+       startup:                visor_startup,
+       shutdown:               visor_shutdown,
+       ioctl:                  visor_ioctl,
+       set_termios:            visor_set_termios,
+       write:                  visor_write,
+       write_room:             visor_write_room,
+       chars_in_buffer:        visor_chars_in_buffer,
+       write_bulk_callback:    visor_write_bulk_callback,
+       read_bulk_callback:     visor_read_bulk_callback,
+};
+
+/* device info for the Sony Clie OS version 3.5 */
+static __u16   sony_vendor_id  = SONY_VENDOR_ID;
+static __u16   sony_3_5_id     = SONY_CLIE_3_5_ID;
+static __u16   sony_4_0_id     = SONY_CLIE_4_0_ID;
+static struct usb_serial_device_type clie_3_5_device = {
+       name:                   "Sony Clie 3.5",
+       idVendor:               &sony_vendor_id,
+       idProduct:              &sony_3_5_id,
+       needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have 
+an interrupt in endpoint */
+       needs_bulk_in:          MUST_HAVE,              /* this device must have a 
+bulk in endpoint */
+       needs_bulk_out:         MUST_HAVE,              /* this device must have a 
+bulk out endpoint */
+       num_interrupt_in:       0,
+       num_bulk_in:            1,
+       num_bulk_out:           1,
+       num_ports:              1,
+       open:                   visor_open,
+       close:                  visor_close,
+       throttle:               visor_throttle,
+       unthrottle:             visor_unthrottle,
+       ioctl:                  visor_ioctl,
+       set_termios:            visor_set_termios,
+       write:                  visor_write,
+       write_room:             visor_write_room,
+       chars_in_buffer:        visor_chars_in_buffer,
+       write_bulk_callback:    visor_write_bulk_callback,
+       read_bulk_callback:     visor_read_bulk_callback,
+};
+
+/* device info for the Sony Clie OS version 4.0 */
+static struct usb_serial_device_type clie_4_0_device = {
+       name:                   "Sony Clie 4.0",
+       idVendor:               &sony_vendor_id,
+       idProduct:              &sony_4_0_id,
+       needs_interrupt_in:     MUST_HAVE_NOT,          /* this device must not have 
+an interrupt in endpoint */
+       needs_bulk_in:          MUST_HAVE,              /* this device must have a 
+bulk in endpoint */
+       needs_bulk_out:         MUST_HAVE,              /* this device must have a 
+bulk out endpoint */
+       num_interrupt_in:       0,
+       num_bulk_in:            2,
+       num_bulk_out:           2,
+       num_ports:              2,
+       open:                   visor_open,
+       close:                  visor_close,
+       throttle:               visor_throttle,
+       unthrottle:             visor_unthrottle,
+       startup:                visor_startup,
+       shutdown:               visor_shutdown,
+       ioctl:                  visor_ioctl,
+       set_termios:            visor_set_termios,
+       write:                  visor_write,
+       write_room:             visor_write_room,
+       chars_in_buffer:        visor_chars_in_buffer,
+       write_bulk_callback:    visor_write_bulk_callback,
+       read_bulk_callback:     visor_read_bulk_callback,
+};
 
 #define NUM_URBS                       24
 #define URB_TRANSFER_BUFFER_SIZE       768
@@ -171,15 +300,14 @@
 static int visor_open (struct usb_serial_port *port, struct file *filp)
 {
        struct usb_serial *serial = port->serial;
-       unsigned long flags;
-       int result;
+       int result = 0;
 
        if (port_paranoia_check (port, __FUNCTION__))
                return -ENODEV;
        
        dbg(__FUNCTION__ " - port %d", port->number);
 
-       spin_lock_irqsave (&port->port_lock, flags);
+       down (&port->sem);
        
        ++port->open_count;
        MOD_INC_USE_COUNT;
@@ -204,9 +332,9 @@
                        err(__FUNCTION__ " - failed submitting read urb, error %d", 
result);
        }
        
-       spin_unlock_irqrestore (&port->port_lock, flags);
+       up (&port->sem);
        
-       return 0;
+       return result;
 }
 
 
@@ -214,7 +342,6 @@
 {
        struct usb_serial *serial;
        unsigned char *transfer_buffer;
-       unsigned long flags;
 
        if (port_paranoia_check (port, __FUNCTION__))
                return;
@@ -225,28 +352,33 @@
        if (!serial)
                return;
        
-       spin_lock_irqsave (&port->port_lock, flags);
+       down (&port->sem);
 
        --port->open_count;
 
        if (port->open_count <= 0) {
-               transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
-               if (!transfer_buffer) {
-                       err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
-               } else {
-                       /* send a shutdown message to the device */
-                       usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
VISOR_CLOSE_NOTIFICATION,
-                                       0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 
300);
-                       kfree (transfer_buffer);
+               if (serial->dev) {
+                       /* only send a shutdown message if the 
+                        * device is still here */
+                       transfer_buffer =  kmalloc (0x12, GFP_KERNEL);
+                       if (!transfer_buffer) {
+                               err(__FUNCTION__ " - kmalloc(%d) failed.", 0x12);
+                       } else {
+                               /* send a shutdown message to the device */
+                               usb_control_msg (serial->dev,
+                                                usb_rcvctrlpipe(serial->dev, 0),
+                                                VISOR_CLOSE_NOTIFICATION, 0xc2,
+                                                0x0000, 0x0000, 
+                                                transfer_buffer, 0x12, 300);
+                               kfree (transfer_buffer);
+                       }
+                       /* shutdown our bulk read */
+                       usb_unlink_urb (port->read_urb);
                }
-
-               /* shutdown our bulk read */
-               usb_unlink_urb (port->read_urb);
                port->active = 0;
                port->open_count = 0;
-
        }
-       spin_unlock_irqrestore (&port->port_lock, flags);
+       up (&port->sem);
 
        /* Uncomment the following line if you want to see some statistics in your 
syslog */
        /* info ("Bytes In = %d  Bytes Out = %d", bytes_in, bytes_out); */
@@ -268,8 +400,6 @@
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
-       usb_serial_debug_data (__FILE__, __FUNCTION__, count, buf);
-       
        while (count > 0) {
                /* try to find a free urb in our list of them */
                urb = NULL;
@@ -294,11 +424,17 @@
                }
                
                transfer_size = MIN (count, URB_TRANSFER_BUFFER_SIZE);
-               if (from_user)
-                       copy_from_user (urb->transfer_buffer, current_position, 
transfer_size);
-               else
+               if (from_user) {
+                       if (copy_from_user (urb->transfer_buffer, current_position, 
+transfer_size)) {
+                               bytes_sent = -EFAULT;
+                               break;
+                       }
+               } else {
                        memcpy (urb->transfer_buffer, current_position, transfer_size);
-               
+               }
+
+               usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, 
+urb->transfer_buffer);
+
                /* build up our urb */
                FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, 
port->bulk_out_endpointAddress), 
                                urb->transfer_buffer, transfer_size, 
visor_write_bulk_callback, port);
@@ -306,8 +442,11 @@
 
                /* send it down the pipe */
                status = usb_submit_urb(urb);
-               if (status)
-                       dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with 
status = %d", status);
+               if (status) {
+                       err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with 
+status = %d", status);
+                       bytes_sent = status;
+                       break;
+               }
 
                current_position += transfer_size;
                bytes_sent += transfer_size;
@@ -328,7 +467,7 @@
 
        dbg(__FUNCTION__ " - port %d", port->number);
        
-       spin_lock_irqsave (&port->port_lock, flags);
+       spin_lock_irqsave (&write_urb_pool_lock, flags);
 
        for (i = 0; i < NUM_URBS; ++i) {
                if (write_urb_pool[i]->status != -EINPROGRESS) {
@@ -336,7 +475,7 @@
                }
        }
        
-       spin_unlock_irqrestore (&port->port_lock, flags);
+       spin_unlock_irqrestore (&write_urb_pool_lock, flags);
        
        dbg(__FUNCTION__ " - returns %d", room);
        return (room);
@@ -351,7 +490,7 @@
 
        dbg(__FUNCTION__ " - port %d", port->number);
        
-       spin_lock_irqsave (&port->port_lock, flags);
+       spin_lock_irqsave (&write_urb_pool_lock, flags);
 
        for (i = 0; i < NUM_URBS; ++i) {
                if (write_urb_pool[i]->status == -EINPROGRESS) {
@@ -359,7 +498,7 @@
                }
        }
        
-       spin_unlock_irqrestore (&port->port_lock, flags);
+       spin_unlock_irqrestore (&write_urb_pool_lock, flags);
 
        dbg (__FUNCTION__ " - returns %d", chars);
        return (chars);
@@ -441,15 +580,14 @@
 
 static void visor_throttle (struct usb_serial_port *port)
 {
-       unsigned long flags;
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
-       spin_lock_irqsave (&port->port_lock, flags);
+       down (&port->sem);
 
        usb_unlink_urb (port->read_urb);
 
-       spin_unlock_irqrestore (&port->port_lock, flags);
+       up (&port->sem);
 
        return;
 }
@@ -457,19 +595,18 @@
 
 static void visor_unthrottle (struct usb_serial_port *port)
 {
-       unsigned long flags;
        int result;
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
-       spin_lock_irqsave (&port->port_lock, flags);
+       down (&port->sem);
 
        port->read_urb->dev = port->serial->dev;
        result = usb_submit_urb(port->read_urb);
        if (result)
                err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 
-       spin_unlock_irqrestore (&port->port_lock, flags);
+       up (&port->sem);
 
        return;
 }
@@ -527,6 +664,29 @@
                }
        }
 
+       if ((serial->dev->descriptor.idVendor == PALM_VENDOR_ID) ||
+           (serial->dev->descriptor.idVendor == SONY_VENDOR_ID)) {
+               /* Palm OS 4.0 Hack */
+               response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 
+0), 
+                                           PALM_GET_SOME_UNKNOWN_INFORMATION,
+                                           0xc2, 0x0000, 0x0000, transfer_buffer, 
+                                           0x14, 300);
+               if (response < 0) {
+                       err(__FUNCTION__ " - error getting first unknown palm 
+command");
+               } else {
+                       usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, 
+transfer_buffer);
+               }
+               response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 
+0), 
+                                           PALM_GET_SOME_UNKNOWN_INFORMATION,
+                                           0xc2, 0x0000, 0x0000, transfer_buffer, 
+                                           0x14, 300);
+               if (response < 0) {
+                       err(__FUNCTION__ " - error getting second unknown palm 
+command");
+               } else {
+                       usb_serial_debug_data (__FILE__, __FUNCTION__, 0x14, 
+transfer_buffer);
+               }
+       }
+
        /* ask for the number of bytes available, but ignore the response as it is 
broken */
        response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
VISOR_REQUEST_BYTES_AVAILABLE,
                                        0xc2, 0x0000, 0x0005, transfer_buffer, 0x02, 
300);
@@ -567,10 +727,16 @@
 /* This function is all nice and good, but we don't change anything based on it :) */
 static void visor_set_termios (struct usb_serial_port *port, struct termios 
*old_termios)
 {
-       unsigned int cflag = port->tty->termios->c_cflag;
+       unsigned int cflag;
 
        dbg(__FUNCTION__ " - port %d", port->number);
 
+       if ((!port->tty) || (!port->tty->termios)) {
+               dbg(__FUNCTION__" - no tty structures");
+               return;
+       }
+
+       cflag = port->tty->termios->c_cflag;
        /* check that they really want us to change something */
        if (old_termios) {
                if ((cflag == old_termios->c_cflag) &&
@@ -580,11 +746,6 @@
                }
        }
 
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg(__FUNCTION__" - no tty structures");
-               return;
-       }
-
        /* get the byte size */
        switch (cflag & CSIZE) {
                case CS5:       dbg(__FUNCTION__ " - data bits = 5");   break;
@@ -635,6 +796,10 @@
        int i;
 
        usb_serial_register (&handspring_device);
+       usb_serial_register (&palm_m500_device);
+       usb_serial_register (&palm_m505_device);
+       usb_serial_register (&clie_3_5_device);
+       usb_serial_register (&clie_4_0_device);
        
        /* create our write urb pool and transfer buffers */ 
        spin_lock_init (&write_urb_pool_lock);
@@ -654,7 +819,7 @@
                }
        }
 
-       info(DRIVER_VERSION ":" DRIVER_DESC);
+       info(DRIVER_DESC " " DRIVER_VERSION);
 
        return 0;
 }
@@ -666,6 +831,10 @@
        unsigned long flags;
 
        usb_serial_deregister (&handspring_device);
+       usb_serial_deregister (&palm_m500_device);
+       usb_serial_deregister (&palm_m505_device);
+       usb_serial_deregister (&clie_3_5_device);
+       usb_serial_deregister (&clie_4_0_device);
 
        spin_lock_irqsave (&write_urb_pool_lock, flags);
 
diff -Nru a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
--- a/drivers/usb/serial/visor.h        Thu Jan  3 21:41:53 2002
+++ b/drivers/usb/serial/visor.h        Thu Jan  3 21:41:53 2002
@@ -1,7 +1,7 @@
 /*
  * USB HandSpring Visor driver
  *
- *     Copyright (C) 1999, 2000
+ *     Copyright (C) 1999 - 2001
  *         Greg Kroah-Hartman ([EMAIL PROTECTED])
  *
  *     This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,14 @@
 #define HANDSPRING_VENDOR_ID           0x082d
 #define HANDSPRING_VISOR_ID            0x0100
 
+#define PALM_VENDOR_ID                 0x0830
+#define PALM_M500_ID                   0x0001
+#define PALM_M505_ID                   0x0002
+
+#define SONY_VENDOR_ID                 0x054C
+#define SONY_CLIE_3_5_ID               0x0038
+#define SONY_CLIE_4_0_ID               0x0066
+
 /****************************************************************************
  * Handspring Visor Vendor specific request codes (bRequest values)
  * A big thank you to Handspring for providing the following information.
@@ -29,7 +37,7 @@
 
 /****************************************************************************
  * VISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that
- * are available to be transfered to the host for the specified endpoint.
+ * are available to be transferred to the host for the specified endpoint.
  * Currently this is not used, and always returns 0x0001
  ****************************************************************************/
 #define VISOR_REQUEST_BYTES_AVAILABLE          0x01
@@ -69,6 +77,13 @@
 #define VISOR_FUNCTION_HOTSYNC         0x02
 #define VISOR_FUNCTION_CONSOLE         0x03
 #define VISOR_FUNCTION_REMOTE_FILE_SYS 0x04
+
+
+/****************************************************************************
+ * PALM_GET_SOME_UNKNOWN_INFORMATION is sent by the host during enumeration to
+ * get some information from the M series devices, that is currently unknown.
+ ****************************************************************************/
+#define PALM_GET_SOME_UNKNOWN_INFORMATION      0x04
 
 #endif
 


_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to