patch-2.4.6 linux/drivers/usb/serial/visor.c
Next file: linux/drivers/usb/serial/visor.h
Previous file: linux/drivers/usb/serial/usbserial.c
Back to the patch index
Back to the overall index
- Lines: 325
- Date:
Wed Jun 20 16:52:30 2001
- Orig file:
v2.4.5/linux/drivers/usb/serial/visor.c
- Orig date:
Mon May 21 15:02:06 2001
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/visor.c linux/drivers/usb/serial/visor.c
@@ -1,7 +1,7 @@
/*
* USB HandSpring Visor driver
*
- * Copyright (C) 1999, 2000
+ * Copyright (C) 1999 - 2001
* Greg Kroah-Hartman (greg@kroah.com)
*
* This program is free software; you can redistribute it and/or modify
@@ -11,6 +11,12 @@
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
+ * (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.
*
@@ -109,7 +115,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.2"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB HandSpring Visor driver"
@@ -131,8 +137,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 +167,7 @@
/* 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 */
@@ -166,6 +190,57 @@
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 */
+ 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",
+ 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
@@ -181,15 +256,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;
@@ -214,9 +288,9 @@
err(__FUNCTION__ " - failed submitting read urb, error %d", result);
}
- spin_unlock_irqrestore (&port->port_lock, flags);
+ up (&port->sem);
- return 0;
+ return result;
}
@@ -224,7 +298,6 @@
{
struct usb_serial *serial;
unsigned char *transfer_buffer;
- unsigned long flags;
if (port_paranoia_check (port, __FUNCTION__))
return;
@@ -235,7 +308,7 @@
if (!serial)
return;
- spin_lock_irqsave (&port->port_lock, flags);
+ down (&port->sem);
--port->open_count;
@@ -256,7 +329,7 @@
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); */
@@ -338,7 +411,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) {
@@ -346,7 +419,7 @@
}
}
- spin_unlock_irqrestore (&port->port_lock, flags);
+ spin_unlock_irqrestore (&write_urb_pool_lock, flags);
dbg(__FUNCTION__ " - returns %d", room);
return (room);
@@ -361,7 +434,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) {
@@ -369,7 +442,7 @@
}
}
- spin_unlock_irqrestore (&port->port_lock, flags);
+ spin_unlock_irqrestore (&write_urb_pool_lock, flags);
dbg (__FUNCTION__ " - returns %d", chars);
return (chars);
@@ -451,15 +524,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;
}
@@ -467,19 +539,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;
}
@@ -496,6 +567,10 @@
return -ENOMEM;
}
+ /* force debugging on for the palm devices for now */
+ if (serial->dev->descriptor.idVendor == PALM_VENDOR_ID)
+ debug = 1;
+
dbg(__FUNCTION__);
dbg(__FUNCTION__ " - Set config to 1");
@@ -537,6 +612,28 @@
}
}
+ 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);
+ }
+ }
+
/* 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);
@@ -645,6 +742,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);
@@ -664,8 +763,7 @@
}
}
- info(DRIVER_VERSION " " DRIVER_AUTHOR);
- info(DRIVER_DESC);
+ info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
@@ -677,6 +775,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);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)