From: Greg KH To: Alan Cox Cc: linux-usb-devel@lists.sourceforge.net Subject: [PATCH 05 of 15] USB Serial Empeg driver updated This patch updates the empeg driver. diff -Nru a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c --- a/drivers/usb/serial/empeg.c Thu Jan 3 21:41:53 2002 +++ b/drivers/usb/serial/empeg.c Thu Jan 3 21:41:53 2002 @@ -1,10 +1,10 @@ /* * USB Empeg empeg-car player driver * - * Copyright (C) 2000 + * Copyright (C) 2000, 2001 * Gary Brubaker (xavyer@ix.netcom.com) * - * 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 @@ -13,10 +13,13 @@ * * See Documentation/usb/usb-serial.txt for more information on using this driver * - * (07/29/2001) gb + * (07/16/2001) gb * remove unused code in empeg_close() (thanks to Oliver Neukum for pointing this * out) and rewrote empeg_set_termios(). * + * (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. * @@ -75,7 +78,7 @@ /* * Version Information */ -#define DRIVER_VERSION "v1.0.1" +#define DRIVER_VERSION "v1.2" #define DRIVER_AUTHOR "Greg Kroah-Hartman , Gary Brubaker " #define DRIVER_DESC "USB Empeg Mark I/II Driver" @@ -147,15 +150,14 @@ static int empeg_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; @@ -189,16 +191,15 @@ } - spin_unlock_irqrestore (&port->port_lock, flags); + up (&port->sem); - return 0; + return result; } static void empeg_close (struct usb_serial_port *port, struct file * filp) { struct usb_serial *serial; - unsigned long flags; if (port_paranoia_check (port, __FUNCTION__)) return; @@ -209,24 +210,25 @@ if (!serial) return; - spin_lock_irqsave (&port->port_lock, flags); + down (&port->sem); --port->open_count; if (port->open_count <= 0) { - /* shutdown our bulk read */ - usb_unlink_urb (port->read_urb); + if (serial->dev) { + /* shutdown our bulk read */ + usb_unlink_urb (port->read_urb); + } port->active = 0; 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); */ MOD_DEC_USE_COUNT; - } @@ -277,7 +279,10 @@ transfer_size = MIN (count, URB_TRANSFER_BUFFER_SIZE); if (from_user) { - copy_from_user (urb->transfer_buffer, current_position, transfer_size); + if (copy_from_user (urb->transfer_buffer, current_position, transfer_size)) { + bytes_sent = -EFAULT; + break; + } } else { memcpy (urb->transfer_buffer, current_position, transfer_size); } @@ -297,8 +302,11 @@ /* send it down the pipe */ status = usb_submit_urb(urb); - if (status) - dbg(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status); + if (status) { + err(__FUNCTION__ " - usb_submit_urb(write bulk) failed with status = %d", status); + bytes_sent = status; + break; + } current_position += transfer_size; bytes_sent += transfer_size; @@ -321,7 +329,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - spin_lock_irqsave (&port->port_lock, flags); + spin_lock_irqsave (&write_urb_pool_lock, flags); /* tally up the number of bytes available */ for (i = 0; i < NUM_URBS; ++i) { @@ -330,7 +338,7 @@ } } - spin_unlock_irqrestore (&port->port_lock, flags); + spin_unlock_irqrestore (&write_urb_pool_lock, flags); dbg(__FUNCTION__ " - returns %d", room); @@ -347,7 +355,7 @@ dbg(__FUNCTION__ " - port %d", port->number); - spin_lock_irqsave (&port->port_lock, flags); + spin_lock_irqsave (&write_urb_pool_lock, flags); /* tally up the number of bytes waiting */ for (i = 0; i < NUM_URBS; ++i) { @@ -356,7 +364,7 @@ } } - spin_unlock_irqrestore (&port->port_lock, flags); + spin_unlock_irqrestore (&write_urb_pool_lock, flags); dbg (__FUNCTION__ " - returns %d", chars); @@ -458,15 +466,13 @@ static void empeg_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; @@ -475,12 +481,11 @@ static void empeg_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; @@ -489,7 +494,7 @@ if (result) err(__FUNCTION__ " - failed submitting read urb, error %d", result); - spin_unlock_irqrestore (&port->port_lock, flags); + up (&port->sem); return;