Commit 005b3f57 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina

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: default avatarPeter Wu <peter@lekensteyn.nl>
Tested-by: default avatarPeter Wu <peter@lekensteyn.nl>
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent f677bb15
......@@ -89,6 +89,7 @@ struct hidpp_device {
struct hid_device *hid_dev;
struct mutex send_mutex;
void *send_receive_buf;
char *name; /* will never be NULL and should not be freed */
wait_queue_head_t wait;
bool answer_available;
u8 protocol_major;
......@@ -1080,6 +1081,7 @@ static void hidpp_input_close(struct input_dev *dev)
static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
{
struct input_dev *input_dev = devm_input_allocate_device(&hdev->dev);
struct hidpp_device *hidpp = hid_get_drvdata(hdev);
if (!input_dev)
return NULL;
......@@ -1088,7 +1090,7 @@ static struct input_dev *hidpp_allocate_input(struct hid_device *hdev)
input_dev->open = hidpp_input_open;
input_dev->close = hidpp_input_close;
input_dev->name = hdev->name;
input_dev->name = hidpp->name;
input_dev->phys = hdev->phys;
input_dev->uniq = hdev->uniq;
input_dev->id.bustype = hdev->bus;
......@@ -1130,22 +1132,28 @@ static void hidpp_connect_event(struct hidpp_device *hidpp)
hid_info(hdev, "HID++ %u.%u device connected.\n",
hidpp->protocol_major, hidpp->protocol_minor);
if (!hidpp->name || hidpp->name == hdev->name) {
name = hidpp_get_device_name(hidpp);
if (!name) {
hid_err(hdev,
"unable to retrieve the name of the device");
return;
}
devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
kfree(name);
if (!devm_name)
return;
hidpp->name = devm_name;
}
input = hidpp_allocate_input(hdev);
if (!input) {
hid_err(hdev, "cannot allocate new input device: %d\n", ret);
return;
}
name = hidpp_get_device_name(hidpp);
if (!name) {
hid_err(hdev, "unable to retrieve the name of the device");
} else {
devm_name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "%s", name);
if (devm_name)
input->name = devm_name;
kfree(name);
}
hidpp_populate_input(hidpp, input, false);
ret = input_register_device(input);
......@@ -1168,6 +1176,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id)
return -ENOMEM;
hidpp->hid_dev = hdev;
hidpp->name = hdev->name;
hid_set_drvdata(hdev, hidpp);
hidpp->quirks = id->driver_data;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment