Attached below is a patch that adds initial support for the Palm m500
and Palm m505 devices.  If anyone with these devices could test out the
patch and let me know if it works or not, I would appreciate it.  Either
way, could you also send the output of the kernel debug log (load the
module with "debug=1") when you try to sync the device.

The patch is against 2.4.5-pre5 but should apply to 2.4.4 easily.

thanks,

greg k-h
diff -Nru a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
--- a/drivers/usb/serial/visor.c        Thu May 24 00:31:30 2001
+++ b/drivers/usb/serial/visor.c        Thu May 24 00:31:30 2001
@@ -131,8 +131,26 @@
 static void visor_read_bulk_callback   (struct urb *urb);
 
 
+static __devinitdata struct usb_device_id visor_id_table [] = {
+       { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
+       { }                                     /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id palm_m500_id_table [] = {
+       { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
+       { }                                     /* Terminating entry */
+};
+
+static __devinitdata struct usb_device_id palm_m505_id_table [] = {
+       { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
+       { }                                     /* Terminating entry */
+};
+
+
 static __devinitdata struct usb_device_id id_table [] = {
        { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
+       { USB_DEVICE(PALM_VENDOR_ID, PALM_M500_ID) },
+       { USB_DEVICE(PALM_VENDOR_ID, PALM_M505_ID) },
        { }                                     /* Terminating entry */
 };
 
@@ -143,7 +161,33 @@
 /* All of the device info needed for the Handspring Visor */
 struct usb_serial_device_type handspring_device = {
        name:                   "Handspring Visor",
-       id_table:               id_table,
+       id_table:               visor_id_table,
+       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 M500 */
+struct usb_serial_device_type palm_m500_device = {
+       name:                   "Palm M500",
+       id_table:               palm_m500_id_table,
        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 */
@@ -166,6 +210,31 @@
        read_bulk_callback:     visor_read_bulk_callback,
 };
 
+/* device info for the Palm M505 */
+struct usb_serial_device_type palm_m505_device = {
+       name:                   "Palm M505",
+       id_table:               palm_m505_id_table,
+       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
@@ -501,39 +570,63 @@
        dbg(__FUNCTION__ " - Set config to 1");
        usb_set_configuration (serial->dev, 1);
 
-       /* send a get connection info request */
-       response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 0), 
VISOR_GET_CONNECTION_INFORMATION,
-                                       0xc2, 0x0000, 0x0000, transfer_buffer, 0x12, 
300);
-       if (response < 0) {
-               err(__FUNCTION__ " - error getting connection information");
-       } else {
-               struct visor_connection_info *connection_info = (struct 
visor_connection_info *)transfer_buffer;
-               char *string;
-
-               le16_to_cpus(&connection_info->num_ports);
-               info("%s: Number of ports: %d", serial->type->name, 
connection_info->num_ports);
-               for (i = 0; i < connection_info->num_ports; ++i) {
-                       switch (connection_info->connections[i].port_function_id) {
-                               case VISOR_FUNCTION_GENERIC:
-                                       string = "Generic";
-                                       break;
-                               case VISOR_FUNCTION_DEBUGGER:
-                                       string = "Debugger";
-                                       break;
-                               case VISOR_FUNCTION_HOTSYNC:
-                                       string = "HotSync";
-                                       break;
-                               case VISOR_FUNCTION_CONSOLE:
-                                       string = "Console";
-                                       break;
-                               case VISOR_FUNCTION_REMOTE_FILE_SYS:
-                                       string = "Remote File System";
-                                       break;
-                               default:
-                                       string = "unknown";
-                                       break;  
+       if (serial->dev->descriptor.idVendor == HANDSPRING_VENDOR_ID) {
+               /* send a get connection info request */
+               response = usb_control_msg (serial->dev, usb_rcvctrlpipe(serial->dev, 
+0), VISOR_GET_CONNECTION_INFORMATION,
+                                               0xc2, 0x0000, 0x0000, transfer_buffer, 
+0x12, 300);
+               if (response < 0) {
+                       err(__FUNCTION__ " - error getting connection information");
+               } else {
+                       struct visor_connection_info *connection_info = (struct 
+visor_connection_info *)transfer_buffer;
+                       char *string;
+       
+                       le16_to_cpus(&connection_info->num_ports);
+                       info("%s: Number of ports: %d", serial->type->name, 
+connection_info->num_ports);
+                       for (i = 0; i < connection_info->num_ports; ++i) {
+                               switch 
+(connection_info->connections[i].port_function_id) {
+                                       case VISOR_FUNCTION_GENERIC:
+                                               string = "Generic";
+                                               break;
+                                       case VISOR_FUNCTION_DEBUGGER:
+                                               string = "Debugger";
+                                               break;
+                                       case VISOR_FUNCTION_HOTSYNC:
+                                               string = "HotSync";
+                                               break;
+                                       case VISOR_FUNCTION_CONSOLE:
+                                               string = "Console";
+                                               break;
+                                       case VISOR_FUNCTION_REMOTE_FILE_SYS:
+                                               string = "Remote File System";
+                                               break;
+                                       default:
+                                               string = "unknown";
+                                               break;  
+                               }
+                               info("%s: port %d, is for %s use and is bound to 
+ttyUSB%d", serial->type->name, connection_info->connections[i].port, string, 
+serial->minor + i);
                        }
-                       info("%s: port %d, is for %s use and is bound to ttyUSB%d", 
serial->type->name, connection_info->connections[i].port, string, serial->minor + i);
+               }
+       }
+
+       if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID) {
+               /* Palm USB 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);
                }
        }
 
@@ -645,6 +738,8 @@
        int i;
 
        usb_serial_register (&handspring_device);
+       usb_serial_register (&palm_m500_device);
+       usb_serial_register (&palm_m505_device);
        
        /* create our write urb pool and transfer buffers */ 
        spin_lock_init (&write_urb_pool_lock);
@@ -677,6 +772,8 @@
        unsigned long flags;
 
        usb_serial_deregister (&handspring_device);
+       usb_serial_deregister (&palm_m500_device);
+       usb_serial_deregister (&palm_m505_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 May 24 00:31:29 2001
+++ b/drivers/usb/serial/visor.h        Thu May 24 00:31:29 2001
@@ -20,6 +20,10 @@
 #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
+
 /****************************************************************************
  * Handspring Visor Vendor specific request codes (bRequest values)
  * A big thank you to Handspring for providing the following information.
@@ -69,6 +73,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
 

Reply via email to