summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jslaby@suse.cz>2010-06-21 17:02:40 +0200
committerGreg Kroah-Hartman <gregkh@suse.de>2010-06-30 08:16:06 -0700
commit10ca4425714a6115c5d865718d64874a1e1ea09a (patch)
treeeac8a90e3b0b9436efe5c969510b22d2cdb657b5
parent1c815577823951ff082fe1201fdd5efec5e6e8ea (diff)
USB: gadget/printer, fix sleep inside atomic
Stanse found that sleep is called inside atomic context created by lock_printer_io spinlock in several functions. It's used in process context only and some functions sleep inside its critical section. As this is not allowed for spinlocks, switch it to mutex. Signed-off-by: Jiri Slaby <jslaby@suse.cz> Cc: Craig W. Nadler <craig@nadler.us> Acked-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/gadget/printer.c32
1 files changed, 16 insertions, 16 deletions
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index 43abf55d8c6..4c3ac5c4223 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -82,7 +82,7 @@ static struct class *usb_gadget_class;
struct printer_dev {
spinlock_t lock; /* lock this structure */
/* lock buffer lists during read/write calls */
- spinlock_t lock_printer_io;
+ struct mutex lock_printer_io;
struct usb_gadget *gadget;
struct usb_request *req; /* for control responses */
u8 config;
@@ -567,7 +567,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
DBG(dev, "printer_read trying to read %d bytes\n", (int)len);
- spin_lock(&dev->lock_printer_io);
+ mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
/* We will use this flag later to check if a printer reset happened
@@ -601,7 +601,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
* call or not.
*/
if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -648,7 +648,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
if (dev->reset_printer) {
list_add(&current_rx_req->list, &dev->rx_reqs);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -673,7 +673,7 @@ printer_read(struct file *fd, char __user *buf, size_t len, loff_t *ptr)
dev->current_rx_buf = current_rx_buf;
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
DBG(dev, "printer_read returned %d bytes\n", (int)bytes_copied);
@@ -697,7 +697,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (len == 0)
return -EINVAL;
- spin_lock(&dev->lock_printer_io);
+ mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
/* Check if a printer reset happens while we have interrupts on */
@@ -713,7 +713,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
* a NON-Blocking call or not.
*/
if (fd->f_flags & (O_NONBLOCK|O_NDELAY)) {
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -752,7 +752,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (copy_from_user(req->buf, buf, size)) {
list_add(&req->list, &dev->tx_reqs);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return bytes_copied;
}
@@ -766,14 +766,14 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
if (dev->reset_printer) {
list_add(&req->list, &dev->tx_reqs);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
if (usb_ep_queue(dev->in_ep, req, GFP_ATOMIC)) {
list_add(&req->list, &dev->tx_reqs);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
return -EAGAIN;
}
@@ -782,7 +782,7 @@ printer_write(struct file *fd, const char __user *buf, size_t len, loff_t *ptr)
}
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
DBG(dev, "printer_write sent %d bytes\n", (int)bytes_copied);
@@ -820,11 +820,11 @@ printer_poll(struct file *fd, poll_table *wait)
unsigned long flags;
int status = 0;
- spin_lock(&dev->lock_printer_io);
+ mutex_lock(&dev->lock_printer_io);
spin_lock_irqsave(&dev->lock, flags);
setup_rx_reqs(dev);
spin_unlock_irqrestore(&dev->lock, flags);
- spin_unlock(&dev->lock_printer_io);
+ mutex_unlock(&dev->lock_printer_io);
poll_wait(fd, &dev->rx_wait, wait);
poll_wait(fd, &dev->tx_wait, wait);
@@ -1461,7 +1461,7 @@ autoconf_fail:
}
spin_lock_init(&dev->lock);
- spin_lock_init(&dev->lock_printer_io);
+ mutex_init(&dev->lock_printer_io);
INIT_LIST_HEAD(&dev->tx_reqs);
INIT_LIST_HEAD(&dev->tx_reqs_active);
INIT_LIST_HEAD(&dev->rx_reqs);
@@ -1594,7 +1594,7 @@ cleanup(void)
{
int status;
- spin_lock(&usb_printer_gadget.lock_printer_io);
+ mutex_lock(&usb_printer_gadget.lock_printer_io);
class_destroy(usb_gadget_class);
unregister_chrdev_region(g_printer_devno, 2);
@@ -1602,6 +1602,6 @@ cleanup(void)
if (status)
ERROR(dev, "usb_gadget_unregister_driver %x\n", status);
- spin_unlock(&usb_printer_gadget.lock_printer_io);
+ mutex_unlock(&usb_printer_gadget.lock_printer_io);
}
module_exit(cleanup);