ChangeSet 1.1743.3.10, 2004/05/25 11:00:18-07:00, [EMAIL PROTECTED]

[PATCH] USB: Fix down() in hard IRQ in powermate driver

Fixes this warning:

May 18 06:56:01 Knoppix kernel: Debug: sleeping function called from
invalid context at include/asm/semaphore.h:119
May 18 06:56:01 Knoppix kernel: in_atomic():1, irqs_disabled():0
May 18 06:56:01 Knoppix kernel: Call Trace:
May 18 06:56:01 Knoppix kernel:  [<c0117083>] __might_sleep+0xb2/0xd3
May 18 06:56:01 Knoppix kernel:  [<f88b92f4>] powermate_config_complete+0x33/0x77 
[powermate]
May 18 06:56:01 Knoppix kernel:  [<c02c6760>] usb_hcd_giveback_urb+0x25/0x39
May 18 06:56:01 Knoppix kernel:  [<c02d7194>] uhci_finish_urb+0x54/0xa1
May 18 06:56:01 Knoppix kernel:  [<c02d7224>] uhci_finish_completion+0x43/0x55
May 18 06:56:01 Knoppix kernel:  [<c02d737d>] uhci_irq+0xf8/0x179
May 18 06:56:01 Knoppix kernel:  [<c02c67aa>] usb_hcd_irq+0x36/0x67
May 18 06:56:01 Knoppix kernel:  [<c01060c6>] handle_IRQ_event+0x3a/0x64
May 18 06:56:01 Knoppix kernel:  [<c0106479>] do_IRQ+0xb8/0x192
May 18 06:56:01 Knoppix kernel:  [<c0104850>] common_interrupt+0x18/0x20

Attached patch uses spinlocks instead of a semaphore so that we can't sleep
when in_atomic().


 drivers/usb/input/powermate.c |   20 ++++++++++++--------
 1 files changed, 12 insertions(+), 8 deletions(-)


diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c     Fri May 28 14:41:06 2004
+++ b/drivers/usb/input/powermate.c     Fri May 28 14:41:06 2004
@@ -33,6 +33,7 @@
 #include <linux/input.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/spinlock.h>
 #include <linux/usb.h>
 
 #define POWERMATE_VENDOR       0x077d  /* Griffin Technology, Inc. */
@@ -67,7 +68,7 @@
        dma_addr_t configcr_dma;
        struct usb_device *udev;
        struct input_dev input;
-       struct semaphore lock;
+       spinlock_t lock;
        int static_brightness;
        int pulse_speed;
        int pulse_table;
@@ -116,7 +117,7 @@
                     __FUNCTION__, retval);
 }
 
-/* Decide if we need to issue a control message and do so. Must be called with 
pm->lock down */
+/* Decide if we need to issue a control message and do so. Must be called with 
pm->lock taken */
 static void powermate_sync_state(struct powermate_device *pm)
 {
        if (pm->requires_update == 0) 
@@ -194,19 +195,22 @@
 static void powermate_config_complete(struct urb *urb, struct pt_regs *regs)
 {
        struct powermate_device *pm = urb->context;
+       unsigned long flags;
 
        if (urb->status)
                printk(KERN_ERR "powermate: config urb returned %d\n", urb->status);
        
-       down(&pm->lock);
+       spin_lock_irqsave(&pm->lock, flags);
        powermate_sync_state(pm);
-       up(&pm->lock);
+       spin_unlock_irqrestore(&pm->lock, flags);
 }
 
 /* Set the LED up as described and begin the sync with the hardware if required */
 static void powermate_pulse_led(struct powermate_device *pm, int static_brightness, 
int pulse_speed, 
                                int pulse_table, int pulse_asleep, int pulse_awake)
 {
+       unsigned long flags;
+
        if (pulse_speed < 0)
                pulse_speed = 0;
        if (pulse_table < 0)
@@ -219,7 +223,8 @@
        pulse_asleep = !!pulse_asleep;
        pulse_awake = !!pulse_awake;
 
-       down(&pm->lock);
+
+       spin_lock_irqsave(&pm->lock, flags);
 
        /* mark state updates which are required */
        if (static_brightness != pm->static_brightness){
@@ -242,7 +247,7 @@
 
        powermate_sync_state(pm);
    
-       up(&pm->lock);
+       spin_unlock_irqrestore(&pm->lock, flags);
 }
 
 /* Callback from the Input layer when an event arrives from userspace to configure 
the LED */
@@ -344,7 +349,7 @@
                return -ENOMEM;
        }
 
-       init_MUTEX(&pm->lock);
+       pm->lock = SPIN_LOCK_UNLOCKED;
        init_input_dev(&pm->input);
 
        /* get a handle to the interrupt data pipe */
@@ -411,7 +416,6 @@
 
        usb_set_intfdata(intf, NULL);
        if (pm) {
-               down(&pm->lock);
                pm->requires_update = 0;
                usb_unlink_urb(pm->irq);
                input_unregister_device(&pm->input);



-------------------------------------------------------
This SF.Net email is sponsored by: Oracle 10g
Get certified on the hottest thing ever to hit the market... Oracle 10g.
Take an Oracle 10g class now, and we'll give you the exam FREE.
http://ads.osdn.com/?ad_id149&alloc_id�66&op=click
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to