]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - drivers/hid/usbhid/hid-core.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / drivers / hid / usbhid / hid-core.c
index 5489eab3a6bd09e9aaf443cc7961f52267aff4a6..b336dd84036f403abdc7891b8e9bb2592dc5705c 100644 (file)
@@ -67,7 +67,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying "
  * Input submission and I/O error handler.
  */
 static DEFINE_MUTEX(hid_open_mut);
-static struct workqueue_struct *resumption_waker;
 
 static void hid_io_error(struct hid_device *hid);
 static int hid_submit_out(struct hid_device *hid);
@@ -136,10 +135,10 @@ static void hid_reset(struct work_struct *work)
                        hid_io_error(hid);
                break;
        default:
-               err_hid("can't reset device, %s-%s/input%d, status %d",
-                               hid_to_usb_dev(hid)->bus->bus_name,
-                               hid_to_usb_dev(hid)->devpath,
-                               usbhid->ifnum, rc);
+               hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n",
+                       hid_to_usb_dev(hid)->bus->bus_name,
+                       hid_to_usb_dev(hid)->devpath,
+                       usbhid->ifnum, rc);
                /* FALLTHROUGH */
        case -EHOSTUNREACH:
        case -ENODEV:
@@ -278,18 +277,18 @@ static void hid_irq_in(struct urb *urb)
                hid_io_error(hid);
                return;
        default:                /* error */
-               dev_warn(&urb->dev->dev, "input irq status %d  "
-                               "received\n", urb->status);
+               hid_warn(urb->dev, "input irq status %d received\n",
+                        urb->status);
        }
 
        status = usb_submit_urb(urb, GFP_ATOMIC);
        if (status) {
                clear_bit(HID_IN_RUNNING, &usbhid->iofl);
                if (status != -EPERM) {
-                       err_hid("can't resubmit intr, %s-%s/input%d, status %d",
-                                       hid_to_usb_dev(hid)->bus->bus_name,
-                                       hid_to_usb_dev(hid)->devpath,
-                                       usbhid->ifnum, status);
+                       hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n",
+                               hid_to_usb_dev(hid)->bus->bus_name,
+                               hid_to_usb_dev(hid)->devpath,
+                               usbhid->ifnum, status);
                        hid_io_error(hid);
                }
        }
@@ -300,10 +299,19 @@ static int hid_submit_out(struct hid_device *hid)
        struct hid_report *report;
        char *raw_report;
        struct usbhid_device *usbhid = hid->driver_data;
+       int r;
 
        report = usbhid->out[usbhid->outtail].report;
        raw_report = usbhid->out[usbhid->outtail].raw_report;
 
+       r = usb_autopm_get_interface_async(usbhid->intf);
+       if (r < 0)
+               return -1;
+
+       /*
+        * if the device hasn't been woken, we leave the output
+        * to resume()
+        */
        if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
                usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0);
                usbhid->urbout->dev = hid_to_usb_dev(hid);
@@ -313,17 +321,11 @@ static int hid_submit_out(struct hid_device *hid)
                dbg_hid("submitting out urb\n");
 
                if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) {
-                       err_hid("usb_submit_urb(out) failed");
+                       hid_err(hid, "usb_submit_urb(out) failed\n");
+                       usb_autopm_put_interface_async(usbhid->intf);
                        return -1;
                }
                usbhid->last_out = jiffies;
-       } else {
-               /*
-                * queue work to wake up the device.
-                * as the work queue is freezeable, this is safe
-                * with respect to STD and STR
-                */
-               queue_work(resumption_waker, &usbhid->restart_work);
        }
 
        return 0;
@@ -334,13 +336,16 @@ static int hid_submit_ctrl(struct hid_device *hid)
        struct hid_report *report;
        unsigned char dir;
        char *raw_report;
-       int len;
+       int len, r;
        struct usbhid_device *usbhid = hid->driver_data;
 
        report = usbhid->ctrl[usbhid->ctrltail].report;
        raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report;
        dir = usbhid->ctrl[usbhid->ctrltail].dir;
 
+       r = usb_autopm_get_interface_async(usbhid->intf);
+       if (r < 0)
+               return -1;
        if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) {
                len = ((report->size - 1) >> 3) + 1 + (report->id > 0);
                if (dir == USB_DIR_OUT) {
@@ -375,17 +380,11 @@ static int hid_submit_ctrl(struct hid_device *hid)
                        usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength);
 
                if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) {
-                       err_hid("usb_submit_urb(ctrl) failed");
+                       usb_autopm_put_interface_async(usbhid->intf);
+                       hid_err(hid, "usb_submit_urb(ctrl) failed\n");
                        return -1;
                }
                usbhid->last_ctrl = jiffies;
-       } else {
-               /*
-                * queue work to wake up the device.
-                * as the work queue is freezeable, this is safe
-                * with respect to STD and STR
-                */
-               queue_work(resumption_waker, &usbhid->restart_work);
        }
 
        return 0;
@@ -413,8 +412,8 @@ static void hid_irq_out(struct urb *urb)
        case -ENOENT:
                break;
        default:                /* error */
-               dev_warn(&urb->dev->dev, "output irq status %d "
-                               "received\n", urb->status);
+               hid_warn(urb->dev, "output irq status %d received\n",
+                        urb->status);
        }
 
        spin_lock_irqsave(&usbhid->lock, flags);
@@ -435,6 +434,7 @@ static void hid_irq_out(struct urb *urb)
 
        clear_bit(HID_OUT_RUNNING, &usbhid->iofl);
        spin_unlock_irqrestore(&usbhid->lock, flags);
+       usb_autopm_put_interface_async(usbhid->intf);
        wake_up(&usbhid->wait);
 }
 
@@ -466,8 +466,7 @@ static void hid_ctrl(struct urb *urb)
        case -EPIPE:            /* report not available */
                break;
        default:                /* error */
-               dev_warn(&urb->dev->dev, "ctrl urb status %d "
-                               "received\n", status);
+               hid_warn(urb->dev, "ctrl urb status %d received\n", status);
        }
 
        if (unplug)
@@ -481,11 +480,13 @@ static void hid_ctrl(struct urb *urb)
                        wake_up(&usbhid->wait);
                }
                spin_unlock(&usbhid->lock);
+               usb_autopm_put_interface_async(usbhid->intf);
                return;
        }
 
        clear_bit(HID_CTRL_RUNNING, &usbhid->iofl);
        spin_unlock(&usbhid->lock);
+       usb_autopm_put_interface_async(usbhid->intf);
        wake_up(&usbhid->wait);
 }
 
@@ -501,13 +502,13 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
 
        if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) {
                if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) {
-                       dev_warn(&hid->dev, "output queue full\n");
+                       hid_warn(hid, "output queue full\n");
                        return;
                }
 
                usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC);
                if (!usbhid->out[usbhid->outhead].raw_report) {
-                       dev_warn(&hid->dev, "output queueing failed\n");
+                       hid_warn(hid, "output queueing failed\n");
                        return;
                }
                hid_output_report(report, usbhid->out[usbhid->outhead].raw_report);
@@ -532,14 +533,14 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re
        }
 
        if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) {
-               dev_warn(&hid->dev, "control queue full\n");
+               hid_warn(hid, "control queue full\n");
                return;
        }
 
        if (dir == USB_DIR_OUT) {
                usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC);
                if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) {
-                       dev_warn(&hid->dev, "control queueing failed\n");
+                       hid_warn(hid, "control queueing failed\n");
                        return;
                }
                hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report);
@@ -590,7 +591,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un
                return -1;
 
        if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) {
-               dev_warn(&dev->dev, "event field not found\n");
+               hid_warn(dev, "event field not found\n");
                return -1;
        }
 
@@ -656,7 +657,7 @@ int usbhid_open(struct hid_device *hid)
        mutex_lock(&hid_open_mut);
        if (!hid->open++) {
                res = usb_autopm_get_interface(usbhid->intf);
-               /* the device must be awake to reliable request remote wakeup */
+               /* the device must be awake to reliably request remote wakeup */
                if (res < 0) {
                        hid->open--;
                        mutex_unlock(&hid_open_mut);
@@ -722,7 +723,7 @@ void usbhid_init_reports(struct hid_device *hid)
        }
 
        if (err)
-               dev_warn(&hid->dev, "timeout initializing reports\n");
+               hid_warn(hid, "timeout initializing reports\n");
 }
 
 /*
@@ -857,18 +858,6 @@ static void usbhid_restart_queues(struct usbhid_device *usbhid)
        usbhid_restart_ctrl_queue(usbhid);
 }
 
-static void __usbhid_restart_queues(struct work_struct *work)
-{
-       struct usbhid_device *usbhid =
-               container_of(work, struct usbhid_device, restart_work);
-       int r;
-
-       r = usb_autopm_get_interface(usbhid->intf);
-       if (r < 0)
-               return;
-       usb_autopm_put_interface(usbhid->intf);
-}
-
 static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid)
 {
        struct usbhid_device *usbhid = hid->driver_data;
@@ -1140,8 +1129,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
                if (usb_endpoint_is_int_in(&interface->endpoint[n].desc))
                        has_in++;
        if (!has_in) {
-               dev_err(&intf->dev, "couldn't find an input interrupt "
-                               "endpoint\n");
+               hid_err(intf, "couldn't find an input interrupt endpoint\n");
                return -ENODEV;
        }
 
@@ -1206,14 +1194,13 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id *
 
        init_waitqueue_head(&usbhid->wait);
        INIT_WORK(&usbhid->reset_work, hid_reset);
-       INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues);
        setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid);
        spin_lock_init(&usbhid->lock);
 
        ret = hid_add_device(hid);
        if (ret) {
                if (ret != -ENODEV)
-                       dev_err(&intf->dev, "can't add hid device: %d\n", ret);
+                       hid_err(intf, "can't add hid device: %d\n", ret);
                goto err_free;
        }
 
@@ -1241,7 +1228,6 @@ static void usbhid_disconnect(struct usb_interface *intf)
 static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid)
 {
        del_timer_sync(&usbhid->io_retry);
-       cancel_work_sync(&usbhid->restart_work);
        cancel_work_sync(&usbhid->reset_work);
 }
 
@@ -1262,7 +1248,6 @@ static int hid_pre_reset(struct usb_interface *intf)
        spin_lock_irq(&usbhid->lock);
        set_bit(HID_RESET_PENDING, &usbhid->iofl);
        spin_unlock_irq(&usbhid->lock);
-       cancel_work_sync(&usbhid->restart_work);
        hid_cease_io(usbhid);
 
        return 0;
@@ -1461,9 +1446,6 @@ static int __init hid_init(void)
 {
        int retval = -ENOMEM;
 
-       resumption_waker = create_freezeable_workqueue("usbhid_resumer");
-       if (!resumption_waker)
-               goto no_queue;
        retval = hid_register_driver(&hid_usb_driver);
        if (retval)
                goto hid_register_fail;
@@ -1481,8 +1463,6 @@ usb_register_fail:
 usbhid_quirks_init_fail:
        hid_unregister_driver(&hid_usb_driver);
 hid_register_fail:
-       destroy_workqueue(resumption_waker);
-no_queue:
        return retval;
 }
 
@@ -1491,7 +1471,6 @@ static void __exit hid_exit(void)
        usb_deregister(&hid_driver);
        usbhid_quirks_exit();
        hid_unregister_driver(&hid_usb_driver);
-       destroy_workqueue(resumption_waker);
 }
 
 module_init(hid_init);