vserver 2.0 rc7
[linux-2.6.git] / drivers / usb / input / powermate.c
index 37b0536..7fa2f9b 100644 (file)
@@ -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 @@ struct powermate_device {
        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 @@ exit:
                     __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) 
@@ -181,7 +182,7 @@ static void powermate_sync_state(struct powermate_device *pm)
        pm->configcr->wLength = 0;
 
        usb_fill_control_urb(pm->config, pm->udev, usb_sndctrlpipe(pm->udev, 0),
-                            (void *) pm->configcr, 0, 0,
+                            (void *) pm->configcr, NULL, 0,
                             powermate_config_complete, pm);
        pm->config->setup_dma = pm->configcr_dma;
        pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP;
@@ -194,19 +195,22 @@ static void powermate_sync_state(struct powermate_device *pm)
 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 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
        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 @@ static void powermate_pulse_led(struct powermate_device *pm, int static_brightne
 
        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 */
@@ -315,7 +320,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
        usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
                0x0a, USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                0, interface->desc.bInterfaceNumber, NULL, 0,
-               HZ * USB_CTRL_SET_TIMEOUT);
+               USB_CTRL_SET_TIMEOUT);
 
        if (!(pm = kmalloc(sizeof(struct powermate_device), GFP_KERNEL)))
                return -ENOMEM;
@@ -344,7 +349,7 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
                return -ENOMEM;
        }
 
-       init_MUTEX(&pm->lock);
+       spin_lock_init(&pm->lock);
        init_input_dev(&pm->input);
 
        /* get a handle to the interrupt data pipe */
@@ -370,12 +375,13 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
                return -EIO; /* failure */
        }
 
-       switch (udev->descriptor.idProduct) {
+       switch (le16_to_cpu(udev->descriptor.idProduct)) {
        case POWERMATE_PRODUCT_NEW: pm->input.name = pm_name_powermate; break;
        case POWERMATE_PRODUCT_OLD: pm->input.name = pm_name_soundknob; break;
        default: 
-         pm->input.name = pm_name_soundknob;
-         printk(KERN_WARNING "powermate: unknown product id %04x\n", udev->descriptor.idProduct);
+               pm->input.name = pm_name_soundknob;
+               printk(KERN_WARNING "powermate: unknown product id %04x\n",
+                      le16_to_cpu(udev->descriptor.idProduct));
        }
 
        pm->input.private = pm;
@@ -384,11 +390,12 @@ static int powermate_probe(struct usb_interface *intf, const struct usb_device_i
        pm->input.relbit[LONG(REL_DIAL)] = BIT(REL_DIAL);
        pm->input.mscbit[LONG(MSC_PULSELED)] = BIT(MSC_PULSELED);
        pm->input.id.bustype = BUS_USB;
-       pm->input.id.vendor = udev->descriptor.idVendor;
-       pm->input.id.product = udev->descriptor.idProduct;
-       pm->input.id.version = udev->descriptor.bcdDevice;
+       pm->input.id.vendor = le16_to_cpu(udev->descriptor.idVendor);
+       pm->input.id.product = le16_to_cpu(udev->descriptor.idProduct);
+       pm->input.id.version = le16_to_cpu(udev->descriptor.bcdDevice);
        pm->input.event = powermate_input_event;
        pm->input.dev = &intf->dev;
+       pm->input.phys = pm->phys;
 
        input_register_device(&pm->input);
 
@@ -411,9 +418,8 @@ static void powermate_disconnect(struct usb_interface *intf)
 
        usb_set_intfdata(intf, NULL);
        if (pm) {
-               down(&pm->lock);
                pm->requires_update = 0;
-               usb_unlink_urb(pm->irq);
+               usb_kill_urb(pm->irq);
                input_unregister_device(&pm->input);
                usb_free_urb(pm->irq);
                usb_free_urb(pm->config);