From: Greg KH To: Alan Cox 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; }