Merge branches 'for-3.18/always-poll-quirk', 'for-3.18/logitech', 'for-3.18/picolcd...
[sfrench/cifs-2.6.git] / drivers / hid / hid-logitech-dj.c
index b7ba82960c7925c5d04eb898af55a95b3be058f4..71f569292cab24d35a43ca82197422406891bc10 100644 (file)
@@ -385,18 +385,6 @@ static void logi_dj_recv_forward_null_report(struct dj_receiver_dev *djrcv_dev,
 
        djdev = djrcv_dev->paired_dj_devices[dj_report->device_index];
 
-       if (!djdev) {
-               dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
-                       " is NULL, index %d\n", dj_report->device_index);
-               kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
-
-               if (schedule_work(&djrcv_dev->work) == 0) {
-                       dbg_hid("%s: did not schedule the work item, was already "
-                       "queued\n", __func__);
-               }
-               return;
-       }
-
        memset(reportbuffer, 0, sizeof(reportbuffer));
 
        for (i = 0; i < NUMBER_OF_HID_REPORTS; i++) {
@@ -421,18 +409,6 @@ static void logi_dj_recv_forward_report(struct dj_receiver_dev *djrcv_dev,
 
        dj_device = djrcv_dev->paired_dj_devices[dj_report->device_index];
 
-       if (dj_device == NULL) {
-               dbg_hid("djrcv_dev->paired_dj_devices[dj_report->device_index]"
-                       " is NULL, index %d\n", dj_report->device_index);
-               kfifo_in(&djrcv_dev->notif_fifo, dj_report, sizeof(struct dj_report));
-
-               if (schedule_work(&djrcv_dev->work) == 0) {
-                       dbg_hid("%s: did not schedule the work item, was already "
-                       "queued\n", __func__);
-               }
-               return;
-       }
-
        if ((dj_report->report_type > ARRAY_SIZE(hid_reportid_size_map) - 1) ||
            (hid_reportid_size_map[dj_report->report_type] == 0)) {
                dbg_hid("invalid report type:%x\n", dj_report->report_type);
@@ -656,7 +632,6 @@ static int logi_dj_raw_event(struct hid_device *hdev,
        struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev);
        struct dj_report *dj_report = (struct dj_report *) data;
        unsigned long flags;
-       bool report_processed = false;
 
        dbg_hid("%s, size:%d\n", __func__, size);
 
@@ -683,34 +658,53 @@ static int logi_dj_raw_event(struct hid_device *hdev,
         * device (via hid_input_report() ) and return 1 so hid-core does not do
         * anything else with it.
         */
+
+       /* case 1) */
+       if (data[0] != REPORT_ID_DJ_SHORT)
+               return false;
+
        if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) ||
            (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) {
-               dev_err(&hdev->dev, "%s: invalid device index:%d\n",
+               /*
+                * Device index is wrong, bail out.
+                * This driver can ignore safely the receiver notifications,
+                * so ignore those reports too.
+                */
+               if (dj_report->device_index != DJ_RECEIVER_INDEX)
+                       dev_err(&hdev->dev, "%s: invalid device index:%d\n",
                                __func__, dj_report->device_index);
                return false;
        }
 
        spin_lock_irqsave(&djrcv_dev->lock, flags);
-       if (dj_report->report_id == REPORT_ID_DJ_SHORT) {
-               switch (dj_report->report_type) {
-               case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
-               case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
-                       logi_dj_recv_queue_notification(djrcv_dev, dj_report);
-                       break;
-               case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
-                       if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
-                           STATUS_LINKLOSS) {
-                               logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
-                       }
-                       break;
-               default:
-                       logi_dj_recv_forward_report(djrcv_dev, dj_report);
+
+       if (!djrcv_dev->paired_dj_devices[dj_report->device_index]) {
+               /* received an event for an unknown device, bail out */
+               logi_dj_recv_queue_notification(djrcv_dev, dj_report);
+               goto out;
+       }
+
+       switch (dj_report->report_type) {
+       case REPORT_TYPE_NOTIF_DEVICE_PAIRED:
+               /* pairing notifications are handled above the switch */
+               break;
+       case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
+               logi_dj_recv_queue_notification(djrcv_dev, dj_report);
+               break;
+       case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
+               if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] ==
+                   STATUS_LINKLOSS) {
+                       logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
                }
-               report_processed = true;
+               break;
+       default:
+               logi_dj_recv_forward_report(djrcv_dev, dj_report);
        }
+
+out:
        spin_unlock_irqrestore(&djrcv_dev->lock, flags);
 
-       return report_processed;
+       return true;
 }
 
 static int logi_dj_probe(struct hid_device *hdev,