aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Tissoires <benjamin.tissoires@redhat.com>2015-01-08 14:37:12 -0500
committerJiri Kosina <jkosina@suse.cz>2015-01-09 05:29:39 -0500
commit005b3f574a0a53f476a62da5c861c1c9bf8177b7 (patch)
treefd01a7f003d61703438f88aa718c0dbae2fbed52
parentf677bb150c2f7b96ebcd377cd722e9d2649e9400 (diff)
HID: logitech-hidpp: store the name of the device in struct hidpp
If a disconnect occurs while getting the actual name of the device (which can take several HID transactions), the name of the device will be the hid name, provided by the Unifying Receiver. This means that in some cases, the user space will see a different name that what it usually sees when there is no disconnect. We should store the name of the device in the struct hidpp. That way, if a disconnect occurs while we are accessing the name, hidpp_connect_event() can fail, and the input node is not created. The input node will be created only if we have a connection which lasts long enough to retrieve all the requested information: name, protocol, and specific configuration. Reviewed-by: Peter Wu <peter@lekensteyn.nl> Tested-by: Peter Wu <peter@lekensteyn.nl> Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
-rw-r--r--drivers/hid/hid-logitech-hidpp.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index cf5795552bcc..acb632db3bb5 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -89,6 +89,7 @@ struct hidpp_device {
89 struct hid_device *hid_dev; 89 struct hid_device *hid_dev;
90 struct mutex send_mutex; 90 struct mutex send_mutex;
91 void *send_receive_buf; 91 void *send_receive_buf;
92 char *name; /* will never be NULL and should not be freed */
92 wait_queue_head_t wait; 93 wait_queue_head_t wait;
93 bool answer_available; 94 bool answer_available;
94 u8 protocol_major; 95 u8 protocol_major;
@@ -1080,6 +1081,7 @@ static void hidpp_input_close(struct input_dev *dev)
1080static struct input_dev *hidpp_allocate_input(struct hid_device *hdev) 1081static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
1081{ 1082{
1082 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev); 1083 struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
1084 struct hidpp_device *hidpp = hid_get_drvdata(hdev);
1083 1085
1084 if (!input_dev) 1086 if (!input_dev)
1085 return NULL; 1087 return NULL;
@@ -1088,7 +1090,7 @@ static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
1088 input_dev->open = hidpp_input_open; 1090 input_dev->open = hidpp_input_open;
1089 input_dev->close = hidpp_input_close; 1091 input_dev->close = hidpp_input_close;
1090 1092
1091 input_dev->name = hdev->name; 1093 input_dev->name = hidpp->name;
1092 input_dev->phys = hdev->phys; 1094 input_dev->phys = hdev->phys;
1093 input_dev->uniq = hdev->uniq; 1095 input_dev->uniq = hdev->uniq;
1094 input_dev->id.bustype = hdev->bus; 1096 input_dev->id.bustype = hdev->bus;
@@ -1130,22 +1132,28 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
1130 hid_info(hdev, "HID++ %u.%u device connected.\n", 1132 hid_info(hdev, "HID++ %u.%u device connected.\n",
1131 hidpp->protocol_major, hidpp->protocol_minor); 1133 hidpp->protocol_major, hidpp->protocol_minor);
1132 1134
1135 if (!hidpp->name || hidpp->name == hdev->name) {
1136 name = hidpp_get_device_name(hidpp);
1137 if (!name) {
1138 hid_err(hdev,
1139 "unable to retrieve the name of the device");
1140 return;
1141 }
1142
1143 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
1144 kfree(name);
1145 if (!devm_name)
1146 return;
1147
1148 hidpp->name = devm_name;
1149 }
1150
1133 input = hidpp_allocate_input(hdev); 1151 input = hidpp_allocate_input(hdev);
1134 if (!input) { 1152 if (!input) {
1135 hid_err(hdev, "cannot allocate new input device: %d\n", ret); 1153 hid_err(hdev, "cannot allocate new input device: %d\n", ret);
1136 return; 1154 return;
1137 } 1155 }
1138 1156
1139 name = hidpp_get_device_name(hidpp);
1140 if (!name) {
1141 hid_err(hdev, "unable to retrieve the name of the device");
1142 } else {
1143 devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
1144 if (devm_name)
1145 input->name = devm_name;
1146 kfree(name);
1147 }
1148
1149 hidpp_populate_input(hidpp, input, false); 1157 hidpp_populate_input(hidpp, input, false);
1150 1158
1151 ret = input_register_device(input); 1159 ret = input_register_device(input);
@@ -1168,6 +1176,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
1168 return -ENOMEM; 1176 return -ENOMEM;
1169 1177
1170 hidpp->hid_dev = hdev; 1178 hidpp->hid_dev = hdev;
1179 hidpp->name = hdev->name;
1171 hid_set_drvdata(hdev, hidpp); 1180 hid_set_drvdata(hdev, hidpp);
1172 1181
1173 hidpp->quirks = id->driver_data; 1182 hidpp->quirks = id->driver_data;