summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew de los Reyes <adlr@chromium.org>2013-01-05 14:06:32 -0800
committerPeter Wu <lekensteyn@gmail.com>2013-08-26 15:01:17 +0200
commit2a6240971bfc0b3d7ef50d93a9ea09c1c8915f77 (patch)
treeade99562fb9d538652b7f291af6feb079ebae1ee
parentd8dfad3876e4386666b759da3c833d62fb8b2267 (diff)
downloadlinux-2a6240971bfc0b3d7ef50d93a9ea09c1c8915f77.tar.gz
CHROMIUM: HID: logitech-dj: Delay creation of enumerated devices until connected.
This is necessary because it's impossible to communicate with devices that aren't connected and future patches will need to communicate with devices during probe(). By waiting until the device is connected, we ensure that we only register the device when it's active and ready for use. BUG=chromium-os:39354 TEST=manually tested on Link Change-Id: Id91f554f683d454e5de31e3741b448271623e02b Signed-off-by: Dennis Kempin <denniskempin@chromium.org> Reviewed-on: https://gerrit.chromium.org/gerrit/57249 Reviewed-by: Andrew de los Reyes <adlr@chromium.org> Conflicts: drivers/hid/hid-logitech-dj.c
-rw-r--r--drivers/hid/hid-logitech-dj.c35
-rw-r--r--drivers/hid/hid-logitech-dj.h1
2 files changed, 27 insertions, 9 deletions
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c
index cd33084c7860..a7c0da78b3b8 100644
--- a/drivers/hid/hid-logitech-dj.c
+++ b/drivers/hid/hid-logitech-dj.c
@@ -290,17 +290,8 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev,
djrcv_dev->paired_dj_devices[dj_report->device_index] = dj_dev;
- if (hid_add_device(dj_hiddev)) {
- dev_err(&djrcv_hdev->dev, "%s: failed adding dj_device\n",
- __func__);
- goto hid_add_device_fail;
- }
-
return;
-hid_add_device_fail:
- djrcv_dev->paired_dj_devices[dj_report->device_index] = NULL;
- kfree(dj_dev);
dj_device_allocate_fail:
hid_destroy_device(dj_hiddev);
}
@@ -309,11 +300,15 @@ static void delayedwork_callback(struct work_struct *work)
{
struct dj_receiver_dev *djrcv_dev =
container_of(work, struct dj_receiver_dev, work);
+ struct hid_device *djrcv_hdev = djrcv_dev->hdev;
+ struct dj_device *djdev;
struct dj_report dj_report;
unsigned long flags;
int count;
int retval;
+ u8 param_status;
+ bool connected;
dbg_hid("%s\n", __func__);
@@ -345,6 +340,27 @@ static void delayedwork_callback(struct work_struct *work)
case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED:
logi_dj_recv_destroy_djhid_device(djrcv_dev, &dj_report);
break;
+ case REPORT_TYPE_NOTIF_CONNECTION_STATUS:
+ param_status = dj_report.report_params[
+ CONNECTION_STATUS_PARAM_STATUS];
+ connected = param_status != STATUS_LINKLOSS;
+ djdev = djrcv_dev->paired_dj_devices[dj_report.device_index];
+ dbg_hid("%s: got REPORT_TYPE_NOTIF_CONNECTION_STATUS %d %d\n", __func__, djdev ? djdev->hid_device_started : -1, connected);
+ if (!djdev) {
+ dev_err(&djrcv_dev->hdev->dev, "%s:"
+ "dj_dev null, unexpected device index\n",
+ __func__);
+ return;
+ }
+ if (!djdev->hid_device_started && connected) {
+ if (hid_add_device(djdev->hdev)) {
+ dev_err(&djrcv_hdev->dev,
+ "%s: failed adding dj_device\n",
+ __func__);
+ } else {
+ djdev->hid_device_started = 1;
+ }
+ }
default:
/* A normal report (i. e. not belonging to a pair/unpair notification)
* arriving here, means that the report arrived but we did not have a
@@ -718,6 +734,7 @@ static int logi_dj_raw_event(struct hid_device *hdev,
STATUS_LINKLOSS) {
logi_dj_recv_forward_null_report(djrcv_dev, dj_report);
}
+ logi_dj_recv_queue_notification(djrcv_dev, dj_report);
break;
default:
logi_dj_recv_forward_report(djrcv_dev, dj_report);
diff --git a/drivers/hid/hid-logitech-dj.h b/drivers/hid/hid-logitech-dj.h
index 4a4000340ce1..767decaad964 100644
--- a/drivers/hid/hid-logitech-dj.h
+++ b/drivers/hid/hid-logitech-dj.h
@@ -109,6 +109,7 @@ struct dj_device {
struct dj_receiver_dev *dj_receiver_dev;
u32 reports_supported;
u8 device_index;
+ unsigned hid_device_started:1;
};
/**