diff options
Diffstat (limited to 'usb.current/usb-gadget-printer-fix-sleep-inside-atomic.patch')
| -rw-r--r-- | usb.current/usb-gadget-printer-fix-sleep-inside-atomic.patch | 163 |
1 files changed, 163 insertions, 0 deletions
diff --git a/usb.current/usb-gadget-printer-fix-sleep-inside-atomic.patch b/usb.current/usb-gadget-printer-fix-sleep-inside-atomic.patch new file mode 100644 index 00000000000000..67fc5e5596ec9f --- /dev/null +++ b/usb.current/usb-gadget-printer-fix-sleep-inside-atomic.patch @@ -0,0 +1,163 @@ +From jslaby@suse.cz Mon Jun 21 14:19:25 2010 +From: Jiri Slaby <jslaby@suse.cz> +Date: Mon, 21 Jun 2010 17:02:40 +0200 +Subject: USB: gadget/printer, fix sleep inside atomic +To: gregkh@suse.de +Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, jirislaby@gmail.com, "Craig W. Nadler" <craig@nadler.us>, David Brownell <dbrownell@users.sourceforge.net> +Message-ID: <1277132560-14284-1-git-send-email-jslaby@suse.cz> + + +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> +Cc: David Brownell <dbrownell@users.sourceforge.net> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + drivers/usb/gadget/printer.c | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +--- 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 __use + + 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 __use + * 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 __use + if (dev->reset_printer) { + list_add(¤t_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 __use + 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 cha + 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 cha + * 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 cha + + 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 cha + 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 cha + } + + 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 + 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); |
