From: Greg KH <greg@kroah.com>
To: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: linux-usb-devel@lists.sourceforge.net
Subject: [PATCH 12 of 15] USB Serial Omninet driver updated

This patch updates the omninet driver.



diff -Nru a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
--- a/drivers/usb/serial/omninet.c	Thu Jan  3 21:41:53 2002
+++ b/drivers/usb/serial/omninet.c	Thu Jan  3 21:41:53 2002
@@ -10,6 +10,9 @@
  *
  * Please report both successes and troubles to the author at omninet@kroah.com
  * 
+ * (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.
  *
@@ -57,7 +60,7 @@
 /*
  * Version Information
  */
-#define DRIVER_VERSION "v1.0.0"
+#define DRIVER_VERSION "v1.1"
 #define DRIVER_AUTHOR "Anonymous"
 #define DRIVER_DESC "USB ZyXEL omni.net LCD PLUS Driver"
 
@@ -77,7 +80,7 @@
 static __u16	zyxel_vendor_id			= ZYXEL_VENDOR_ID;
 static __u16	zyxel_omninet_product_id	= ZYXEL_OMNINET_ID;
 
-struct usb_serial_device_type zyxel_omninet_device = {
+static struct usb_serial_device_type zyxel_omninet_device = {
 	name:			"ZyXEL - omni.net lcd plus usb",
 	idVendor:		&zyxel_vendor_id,
 	idProduct:		&zyxel_omninet_product_id,
@@ -139,8 +142,7 @@
 	struct usb_serial	*serial;
 	struct usb_serial_port	*wport;
 	struct omninet_data	*od;
-	unsigned long		flags;
-	int			result;
+	int			result = 0;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return -ENODEV;
@@ -151,7 +153,7 @@
 	if (!serial)
 		return -ENODEV;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	MOD_INC_USE_COUNT;
 	++port->open_count;
@@ -164,7 +166,7 @@
 			err(__FUNCTION__"- kmalloc(%Zd) failed.", sizeof(struct omninet_data));
 			--port->open_count;
 			port->active = 0;
-			spin_unlock_irqrestore (&port->port_lock, flags);
+			up (&port->sem);
 			MOD_DEC_USE_COUNT;
 			return -ENOMEM;
 		}
@@ -183,9 +185,9 @@
 			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
 
-	return (0);
+	return result;
 }
 
 static void omninet_close (struct usb_serial_port *port, struct file * filp)
@@ -193,7 +195,6 @@
 	struct usb_serial 	*serial;
 	struct usb_serial_port 	*wport;
 	struct omninet_data 	*od;
-	unsigned long		flags;
 
 	if (port_paranoia_check (port, __FUNCTION__))
 		return;
@@ -204,25 +205,26 @@
 	if (!serial)
 		return;
 
-	spin_lock_irqsave (&port->port_lock, flags);
+	down (&port->sem);
 
 	--port->open_count;
-	MOD_DEC_USE_COUNT;
 
 	if (port->open_count <= 0) {
-		od = (struct omninet_data *)port->private;
-		wport = &serial->port[1];
-
-		usb_unlink_urb (wport->write_urb);
-		usb_unlink_urb (port->read_urb);
+		if (serial->dev) {
+			wport = &serial->port[1];
+			usb_unlink_urb (wport->write_urb);
+			usb_unlink_urb (port->read_urb);
+		}
 
 		port->active = 0;
 		port->open_count = 0;
+		od = (struct omninet_data *)port->private;
 		if (od)
 			kfree(od);
 	}
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
+	up (&port->sem);
+	MOD_DEC_USE_COUNT;
 }
 
 
@@ -290,7 +292,6 @@
 	struct omninet_data 	*od 	= (struct omninet_data   *) port->private;
 	struct omninet_header	*header = (struct omninet_header *) wport->write_urb->transfer_buffer;
 
-	unsigned long		flags;
 	int			result;
 
 //	dbg("omninet_write port %d", port->number);
@@ -304,12 +305,13 @@
 		return (0);
 	}
 
-	spin_lock_irqsave (&port->port_lock, flags);
-	
 	count = (count > OMNINET_BULKOUTSIZE) ? OMNINET_BULKOUTSIZE : count;
 
 	if (from_user) {
-		copy_from_user(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
+		if (copy_from_user(wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count) != 0) {
+			result = -EFAULT;
+			goto exit;
+		}
 	}
 	else {
 		memcpy (wport->write_urb->transfer_buffer + OMNINET_DATAOFFSET, buf, count);
@@ -327,16 +329,13 @@
 
 	wport->write_urb->dev = serial->dev;
 	result = usb_submit_urb(wport->write_urb);
-	if (result) {
+	if (result)
 		err(__FUNCTION__ " - failed submitting write urb, error %d", result);
-		spin_unlock_irqrestore (&port->port_lock, flags);
-		return 0;
-	}
-
-//	dbg("omninet_write returns %d", count);
+	else
+		result = count;
 
-	spin_unlock_irqrestore (&port->port_lock, flags);
-	return (count);
+exit:	
+	return result;
 }
 
 

