Skip to content

Commit

Permalink
USB: mutexification of rio500
Browse files Browse the repository at this point in the history
this makes the rio500 misc usb driver use mutexes and turns uninterruptible
sleep into interruptible sleep where the semantics are not affected.

Signed-off-by: Oliver Neukum <oliver@neukum.name>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
  • Loading branch information
Oliver Neukum authored and gregkh committed Feb 7, 2007
1 parent 4727810 commit 2cba72f
Showing 1 changed file with 30 additions and 24 deletions.
54 changes: 30 additions & 24 deletions drivers/usb/misc/rio500.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct rio_usb_data {
char *obuf, *ibuf; /* transfer buffers */
char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */
wait_queue_head_t wait_q; /* for timeouts */
struct semaphore lock; /* general race avoidance */
struct mutex lock; /* general race avoidance */
};

static struct rio_usb_data rio_instance;
Expand All @@ -78,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file)
{
struct rio_usb_data *rio = &rio_instance;

down(&(rio->lock));
mutex_lock(&(rio->lock));

if (rio->isopen || !rio->present) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return -EBUSY;
}
rio->isopen = 1;

init_waitqueue_head(&rio->wait_q);

up(&(rio->lock));
mutex_unlock(&(rio->lock));

info("Rio opened.");

Expand Down Expand Up @@ -117,7 +117,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
int retries;
int retval=0;

down(&(rio->lock));
mutex_lock(&(rio->lock));
/* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL ||
rio->present == 0 ||
Expand Down Expand Up @@ -257,7 +257,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,


err_out:
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return retval;
}

Expand All @@ -275,14 +275,17 @@ write_rio(struct file *file, const char __user *buffer,
int result = 0;
int maxretry;
int errn = 0;
int intr;

down(&(rio->lock));
intr = mutex_lock_interruptible(&(rio->lock));
if (intr)
return -EINTR;
/* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL ||
rio->present == 0 ||
rio->rio_dev == NULL )
{
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return -ENODEV;
}

Expand All @@ -305,7 +308,7 @@ write_rio(struct file *file, const char __user *buffer,
goto error;
}
if (signal_pending(current)) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return bytes_written ? bytes_written : -EINTR;
}

Expand Down Expand Up @@ -341,12 +344,12 @@ write_rio(struct file *file, const char __user *buffer,
buffer += copy_size;
} while (count > 0);

up(&(rio->lock));
mutex_unlock(&(rio->lock));

return bytes_written ? bytes_written : -EIO;

error:
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return errn;
}

Expand All @@ -361,14 +364,17 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
int result;
int maxretry = 10;
char *ibuf;
int intr;

down(&(rio->lock));
intr = mutex_lock_interruptible(&(rio->lock));
if (intr)
return -EINTR;
/* Sanity check to make sure rio is connected, powered, etc */
if ( rio == NULL ||
rio->present == 0 ||
rio->rio_dev == NULL )
{
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return -ENODEV;
}

Expand All @@ -379,11 +385,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)

while (count > 0) {
if (signal_pending(current)) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return read_count ? read_count : -EINTR;
}
if (!rio->rio_dev) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return -ENODEV;
}
this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count;
Expand All @@ -400,7 +406,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
count = this_read = partial;
} else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */
if (!maxretry--) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
err("read_rio: maxretry timeout");
return -ETIME;
}
Expand All @@ -409,26 +415,26 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
finish_wait(&rio->wait_q, &wait);
continue;
} else if (result != -EREMOTEIO) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
err("Read Whoops - result:%u partial:%u this_read:%u",
result, partial, this_read);
return -EIO;
} else {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return (0);
}

if (this_read) {
if (copy_to_user(buffer, ibuf, this_read)) {
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return -EFAULT;
}
count -= this_read;
read_count += this_read;
buffer += this_read;
}
}
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return read_count;
}

Expand Down Expand Up @@ -480,7 +486,7 @@ static int probe_rio(struct usb_interface *intf,
}
dbg("probe_rio: ibuf address:%p", rio->ibuf);

init_MUTEX(&(rio->lock));
mutex_init(&(rio->lock));

usb_set_intfdata (intf, rio);
rio->present = 1;
Expand All @@ -496,12 +502,12 @@ static void disconnect_rio(struct usb_interface *intf)
if (rio) {
usb_deregister_dev(intf, &usb_rio_class);

down(&(rio->lock));
mutex_lock(&(rio->lock));
if (rio->isopen) {
rio->isopen = 0;
/* better let it finish - the release will do whats needed */
rio->rio_dev = NULL;
up(&(rio->lock));
mutex_unlock(&(rio->lock));
return;
}
kfree(rio->ibuf);
Expand All @@ -510,7 +516,7 @@ static void disconnect_rio(struct usb_interface *intf)
info("USB Rio disconnected.");

rio->present = 0;
up(&(rio->lock));
mutex_unlock(&(rio->lock));
}
}

Expand Down

0 comments on commit 2cba72f

Please sign in to comment.