On Wed, May 23, 2001 at 11:28:45PM -0700, David A. Desrosiers wrote: > You will get as far as a connect, but that's it. I was able to get it > connected to my box, and seen, but nothing magical will happen at that point. > I don't know enough about USB to figure this one out. Greg? That's as much as I can figure out at this moment too. Attached below is a clean patch against 2.4.5-pre5 that adds support for the Palm m500 and m505 devices. This is so you don't have to hunt for the two different patches I sent out in the past, and so that you can still use a Visor with this patch applied. It doesn't seem to work yet, but if people could help out and try it, I would really appreciate it. Kernel debug logs from loading the modules with "debug=1" and then trying to sync are appreciated. Please let me know how this works. 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