Commit ba460e48 authored by Matthias Urlichs's avatar Matthias Urlichs Committed by Linus Torvalds

[PATCH] Option Card driver update, Maintainer entry

This patch updates the Option Card driver:
- remove a deadlock
- add sponsor notice
- add new card
- renamed the device to what's usually printed on it
- removed some dead code
- clean up a bunch of irregular whitespace (end-of-line, tabs)

Also add a MAINTAINERS entry for the Option Card driver.
Signed-Off-By: default avatarMatthias Urlichs <smurf@smurf.noris.de>
Cc: Greg KH <greg@kroah.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 98848fa8
......@@ -2420,6 +2420,12 @@ L: linux-usb-users@lists.sourceforge.net
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB OPTION-CARD DRIVER
P: Matthias Urlichs
M: smurf@smurf.noris.de
L: linux-usb-devel@lists.sourceforge.net
S: Maintained
USB OV511 DRIVER
P: Mark McClelland
M: mmcclell@bigfoot.com
......
......@@ -12,14 +12,25 @@
History:
2005-05-19 v0.1 Initial version, based on incomplete docs
and analysis of misbehavior of the standard driver
and analysis of misbehavior with the standard driver
2005-05-20 v0.2 Extended the input buffer to avoid losing
random 64-byte chunks of data
2005-05-21 v0.3 implemented chars_in_buffer()
turned on low_latency
simplified the code somewhat
2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load
removed some dead code
added sponsor notice
coding style clean-up
2005-06-20 v0.4.1 add missing braces :-/
killed end-of-line whitespace
2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2
Work sponsored by: Sigos GmbH, Germany <info@sigos.de>
*/
#define DRIVER_VERSION "v0.3"
#define DRIVER_VERSION "v0.4"
#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"
#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"
......@@ -44,7 +55,6 @@ static int option_write_room (struct usb_serial_port *port);
static void option_instat_callback(struct urb *urb, struct pt_regs *regs);
static int option_write (struct usb_serial_port *port,
const unsigned char *buf, int count);
......@@ -63,11 +73,14 @@ static int option_send_setup (struct usb_serial_port *port);
#define OPTION_VENDOR_ID 0x0AF0
#define OPTION_PRODUCT_OLD 0x5000
#define OPTION_PRODUCT_WLAN 0x6000
#define OPTION_PRODUCT_FUSION 0x6000
#define OPTION_PRODUCT_FUSION2 0x6300
static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },
{ } /* Terminating entry */
};
......@@ -86,13 +99,13 @@ static struct usb_driver option_driver = {
*/
static struct usb_serial_device_type option_3port_device = {
.owner = THIS_MODULE,
.name = "Option 3-port card",
.name = "Option 3G data card",
.short_name = "option",
.id_table = option_ids,
.num_interrupt_in = NUM_DONT_CARE,
.num_bulk_in = NUM_DONT_CARE,
.num_bulk_out = NUM_DONT_CARE,
.num_ports = 1, /* 3 */
.num_ports = 1, /* 3, but the card reports its ports separately */
.open = option_open,
.close = option_close,
.write = option_write,
......@@ -110,14 +123,19 @@ static struct usb_serial_device_type option_3port_device = {
.read_int_callback = option_instat_callback,
};
#ifdef CONFIG_USB_DEBUG
static int debug;
#else
#define debug 0
#endif
/* per port private data */
#define N_IN_URB 4
#define N_OUT_URB 1
#define IN_BUFLEN 1024
#define OUT_BUFLEN 1024
#define OUT_BUFLEN 128
struct option_port_private {
/* Input endpoints and buffer for this port */
......@@ -134,7 +152,6 @@ struct option_port_private {
int dsr_state;
int dcd_state;
int ri_state;
// int break_on;
unsigned long tx_start_time[N_OUT_URB];
};
......@@ -204,7 +221,7 @@ option_set_termios (struct usb_serial_port *port,
}
static int
option_tiocmget(struct usb_serial_port *port, struct file *file)
option_tiocmget (struct usb_serial_port *port, struct file *file)
{
unsigned int value;
struct option_port_private *portdata;
......@@ -250,7 +267,7 @@ option_ioctl (struct usb_serial_port *port, struct file *file,
/* Write */
static int
option_write(struct usb_serial_port *port,
option_write (struct usb_serial_port *port,
const unsigned char *buf, int count)
{
struct option_port_private *portdata;
......@@ -263,58 +280,37 @@ option_write(struct usb_serial_port *port,
dbg("%s: write (%d chars)", __FUNCTION__, count);
#if 0
spin_lock(&port->lock);
if (port->write_urb_busy) {
spin_unlock(&port->lock);
dbg("%s: already writing", __FUNCTION__);
return 0;
}
port->write_urb_busy = 1;
spin_unlock(&port->lock);
#endif
i = 0;
left = count;
while (left>0) {
for (i=0; left > 0 && i < N_OUT_URB; i++) {
todo = left;
if (todo > OUT_BUFLEN)
todo = OUT_BUFLEN;
for (;i < N_OUT_URB; i++) {
/* Check we have a valid urb/endpoint before we use it... */
this_urb = portdata->out_urbs[i];
if (this_urb->status != -EINPROGRESS)
break;
if (this_urb->status == -EINPROGRESS) {
if (this_urb->transfer_flags & URB_ASYNC_UNLINK)
continue;
if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))
continue;
this_urb->transfer_flags |= URB_ASYNC_UNLINK;
usb_unlink_urb(this_urb);
continue;
}
if (i == N_OUT_URB) {
/* no bulk out free! */
dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);
#if 0
port->write_urb_busy = 0;
#endif
return count-left;
}
if (this_urb->status != 0)
dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);
dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);
/* send the data */
memcpy (this_urb->transfer_buffer, buf, todo);
/* send the data out the bulk port */
this_urb->transfer_buffer_length = todo;
this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;
this_urb->dev = port->serial->dev;
err = usb_submit_urb(this_urb, GFP_ATOMIC);
if (err) {
dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);
dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);
continue;
}
portdata->tx_start_time[i] = jiffies;
......@@ -323,9 +319,6 @@ option_write(struct usb_serial_port *port,
}
count -= left;
#if 0
port->write_urb_busy = 0;
#endif
dbg("%s: wrote (did %d)", __FUNCTION__, count);
return count;
}
......@@ -444,10 +437,11 @@ option_write_room (struct usb_serial_port *port)
portdata = usb_get_serial_port_data(port);
for (i=0; i < N_OUT_URB; i++)
for (i=0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i];
if (this_urb && this_urb->status != -EINPROGRESS)
data_len += OUT_BUFLEN;
}
dbg("%s: %d", __FUNCTION__, data_len);
return data_len;
......@@ -464,11 +458,11 @@ option_chars_in_buffer (struct usb_serial_port *port)
portdata = usb_get_serial_port_data(port);
for (i=0; i < N_OUT_URB; i++)
for (i=0; i < N_OUT_URB; i++) {
this_urb = portdata->out_urbs[i];
if (this_urb && this_urb->status == -EINPROGRESS)
data_len += this_urb->transfer_buffer_length;
}
dbg("%s: %d", __FUNCTION__, data_len);
return data_len;
}
......@@ -528,7 +522,7 @@ option_open (struct usb_serial_port *port, struct file *filp)
}
static inline void
stop_urb(struct urb *urb)
stop_urb (struct urb *urb)
{
if (urb && urb->status == -EINPROGRESS) {
urb->transfer_flags &= ~URB_ASYNC_UNLINK;
......@@ -537,7 +531,7 @@ stop_urb(struct urb *urb)
}
static void
option_close(struct usb_serial_port *port, struct file *filp)
option_close (struct usb_serial_port *port, struct file *filp)
{
int i;
struct usb_serial *serial = port->serial;
......@@ -589,7 +583,7 @@ option_setup_urb (struct usb_serial *serial, int endpoint,
/* Setup urbs */
static void
option_setup_urbs(struct usb_serial *serial)
option_setup_urbs (struct usb_serial *serial)
{
int j;
struct usb_serial_port *port;
......@@ -617,7 +611,7 @@ option_setup_urbs(struct usb_serial *serial)
static int
option_send_setup(struct usb_serial_port *port)
option_send_setup (struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct option_port_private *portdata;
......@@ -724,6 +718,8 @@ MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_VERSION(DRIVER_VERSION);
MODULE_LICENSE("GPL");
#ifdef CONFIG_USB_DEBUG
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug messages");
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment