patch-2.4.6 linux/drivers/usb/serial/whiteheat.c
Next file: linux/drivers/usb/storage/debug.c
Previous file: linux/drivers/usb/serial/visor.h
Back to the patch index
Back to the overall index
- Lines: 201
- Date:
Wed Jun 20 16:52:30 2001
- Orig file:
v2.4.5/linux/drivers/usb/serial/whiteheat.c
- Orig date:
Mon May 21 15:02:06 2001
diff -u --recursive --new-file v2.4.5/linux/drivers/usb/serial/whiteheat.c linux/drivers/usb/serial/whiteheat.c
@@ -11,6 +11,9 @@
*
* 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.
+ *
* (04/08/2001) gb
* Identify version on module load.
*
@@ -85,7 +88,7 @@
/*
* Version Information
*/
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>"
#define DRIVER_DESC "USB ConnectTech WhiteHEAT driver"
@@ -251,6 +254,7 @@
struct usb_serial_port *port;
int timeout;
__u8 *transfer_buffer;
+ int retval = 0;
dbg(__FUNCTION__" - command %d", command);
@@ -263,9 +267,10 @@
memcpy (&transfer_buffer[1], data, datasize);
port->write_urb->transfer_buffer_length = datasize + 1;
port->write_urb->dev = serial->dev;
- if (usb_submit_urb (port->write_urb)) {
+ retval = usb_submit_urb (port->write_urb);
+ if (retval) {
dbg (__FUNCTION__" - submit urb failed");
- return -1;
+ goto exit;
}
/* wait for the command to complete */
@@ -276,20 +281,21 @@
if (info->command_finished == FALSE) {
dbg (__FUNCTION__ " - command timed out.");
- return -1;
+ retval = -ETIMEDOUT;
+ goto exit;
}
if (info->command_finished == WHITEHEAT_CMD_FAILURE) {
dbg (__FUNCTION__ " - command failed.");
- return -1;
+ retval = -EIO;
+ goto exit;
}
- if (info->command_finished == WHITEHEAT_CMD_COMPLETE) {
+ if (info->command_finished == WHITEHEAT_CMD_COMPLETE)
dbg (__FUNCTION__ " - command completed.");
- return 0;
- }
- return 0;
+exit:
+ return retval;
}
@@ -298,10 +304,12 @@
struct whiteheat_min_set open_command;
struct usb_serial_port *command_port;
struct whiteheat_private *info;
- int result;
+ int retval = 0;
dbg(__FUNCTION__" - port %d", port->number);
+ down (&port->sem);
+
++port->open_count;
MOD_INC_USE_COUNT;
@@ -314,7 +322,8 @@
info = (struct whiteheat_private *)kmalloc (sizeof(struct whiteheat_private), GFP_KERNEL);
if (info == NULL) {
err(__FUNCTION__ " - out of memory");
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto error_exit;
}
init_waitqueue_head(&info->wait_command);
@@ -323,27 +332,45 @@
command_port->read_urb->complete = command_port_read_callback;
command_port->read_urb->dev = port->serial->dev;
command_port->tty = port->tty; /* need this to "fake" our our sanity check macros */
- usb_submit_urb (command_port->read_urb);
+ retval = usb_submit_urb (command_port->read_urb);
+ if (retval) {
+ err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
+ goto error_exit;
+ }
}
/* Start reading from the device */
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);
+ retval = usb_submit_urb(port->read_urb);
+ if (retval) {
+ err(__FUNCTION__ " - failed submitting read urb, error %d", retval);
+ goto error_exit;
+ }
/* send an open port command */
/* firmware uses 1 based port numbering */
open_command.port = port->number - port->serial->minor + 1;
- whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+ retval = whiteheat_send_cmd (port->serial, WHITEHEAT_OPEN, (__u8 *)&open_command, sizeof(open_command));
+ if (retval)
+ goto error_exit;
/* Need to do device specific setup here (control lines, baud rate, etc.) */
/* FIXME!!! */
}
dbg(__FUNCTION__ " - exit");
+ up (&port->sem);
- return 0;
+ return retval;
+
+error_exit:
+ --port->open_count;
+ MOD_DEC_USE_COUNT;
+
+ dbg(__FUNCTION__ " - error_exit");
+ up (&port->sem);
+
+ return retval;
}
@@ -353,6 +380,7 @@
dbg(__FUNCTION__ " - port %d", port->number);
+ down (&port->sem);
--port->open_count;
if (port->open_count <= 0) {
@@ -370,6 +398,7 @@
port->active = 0;
}
MOD_DEC_USE_COUNT;
+ up (&port->sem);
}
@@ -388,18 +417,19 @@
dbg(__FUNCTION__ " -port %d", port->number);
+ down (&port->sem);
/* check that they really want us to change something */
if (old_termios) {
if ((cflag == old_termios->c_cflag) &&
(RELEVANT_IFLAG(port->tty->termios->c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) {
dbg(__FUNCTION__ " - nothing to change...");
- return;
+ goto exit;
}
}
if ((!port->tty) || (!port->tty->termios)) {
dbg(__FUNCTION__" - no tty structures");
- return;
+ goto exit;
}
/* set the port number */
@@ -466,6 +496,8 @@
/* now send the message to the device */
whiteheat_send_cmd (port->serial, WHITEHEAT_SETUP_PORT, (__u8 *)&port_settings, sizeof(port_settings));
+exit:
+ up (&port->sem);
return;
}
@@ -626,8 +658,7 @@
{
usb_serial_register (&whiteheat_fake_device);
usb_serial_register (&whiteheat_device);
- info(DRIVER_VERSION " " DRIVER_AUTHOR);
- info(DRIVER_DESC);
+ info(DRIVER_VERSION ":" DRIVER_DESC);
return 0;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)