Commit c554bb04 authored by Benjamin Tissoires's avatar Benjamin Tissoires Committed by Jiri Kosina

HID: input: append a suffix matching the application

Given that we create one input node per application, we should name
the input node accordingly to not lose userspace.
Signed-off-by: default avatarBenjamin Tissoires <benjamin.tissoires@redhat.com>
Signed-off-by: default avatarJiri Kosina <jkosina@suse.cz>
parent f07b3c1d
...@@ -1500,15 +1500,56 @@ static void report_features(struct hid_device *hid) ...@@ -1500,15 +1500,56 @@ static void report_features(struct hid_device *hid)
} }
} }
static struct hid_input *hidinput_allocate(struct hid_device *hid) static struct hid_input *hidinput_allocate(struct hid_device *hid,
unsigned int application)
{ {
struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); struct hid_input *hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL);
struct input_dev *input_dev = input_allocate_device(); struct input_dev *input_dev = input_allocate_device();
if (!hidinput || !input_dev) { const char *suffix = NULL;
kfree(hidinput);
input_free_device(input_dev); if (!hidinput || !input_dev)
hid_err(hid, "Out of memory during hid input probe\n"); goto fail;
return NULL;
if ((hid->quirks & HID_QUIRK_INPUT_PER_APP) &&
hid->maxapplication > 1) {
switch (application) {
case HID_GD_KEYBOARD:
suffix = "Keyboard";
break;
case HID_GD_KEYPAD:
suffix = "Keypad";
break;
case HID_GD_MOUSE:
suffix = "Mouse";
break;
case HID_DG_STYLUS:
suffix = "Pen";
break;
case HID_DG_TOUCHSCREEN:
suffix = "Touchscreen";
break;
case HID_DG_TOUCHPAD:
suffix = "Touchpad";
break;
case HID_GD_SYSTEM_CONTROL:
suffix = "System Control";
break;
case HID_CP_CONSUMER_CONTROL:
suffix = "Consumer Control";
break;
case HID_GD_WIRELESS_RADIO_CTLS:
suffix = "Wireless Radio Control";
break;
default:
break;
}
}
if (suffix) {
hidinput->name = kasprintf(GFP_KERNEL, "%s %s",
hid->name, suffix);
if (!hidinput->name)
goto fail;
} }
input_set_drvdata(input_dev, hid); input_set_drvdata(input_dev, hid);
...@@ -1518,7 +1559,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) ...@@ -1518,7 +1559,7 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
input_dev->setkeycode = hidinput_setkeycode; input_dev->setkeycode = hidinput_setkeycode;
input_dev->getkeycode = hidinput_getkeycode; input_dev->getkeycode = hidinput_getkeycode;
input_dev->name = hid->name; input_dev->name = hidinput->name ? hidinput->name : hid->name;
input_dev->phys = hid->phys; input_dev->phys = hid->phys;
input_dev->uniq = hid->uniq; input_dev->uniq = hid->uniq;
input_dev->id.bustype = hid->bus; input_dev->id.bustype = hid->bus;
...@@ -1533,6 +1574,12 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid) ...@@ -1533,6 +1574,12 @@ static struct hid_input *hidinput_allocate(struct hid_device *hid)
INIT_LIST_HEAD(&hidinput->reports); INIT_LIST_HEAD(&hidinput->reports);
return hidinput; return hidinput;
fail:
kfree(hidinput);
input_free_device(input_dev);
hid_err(hid, "Out of memory during hid input probe\n");
return NULL;
} }
static bool hidinput_has_been_populated(struct hid_input *hidinput) static bool hidinput_has_been_populated(struct hid_input *hidinput)
...@@ -1578,6 +1625,7 @@ static void hidinput_cleanup_hidinput(struct hid_device *hid, ...@@ -1578,6 +1625,7 @@ static void hidinput_cleanup_hidinput(struct hid_device *hid,
list_del(&hidinput->list); list_del(&hidinput->list);
input_free_device(hidinput->input); input_free_device(hidinput->input);
kfree(hidinput->name);
for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) { for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) {
if (k == HID_OUTPUT_REPORT && if (k == HID_OUTPUT_REPORT &&
...@@ -1646,6 +1694,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) ...@@ -1646,6 +1694,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
struct hid_driver *drv = hid->driver; struct hid_driver *drv = hid->driver;
struct hid_report *report; struct hid_report *report;
struct hid_input *next, *hidinput = NULL; struct hid_input *next, *hidinput = NULL;
unsigned int application;
int i, k; int i, k;
INIT_LIST_HEAD(&hid->inputs); INIT_LIST_HEAD(&hid->inputs);
...@@ -1678,6 +1727,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) ...@@ -1678,6 +1727,8 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
if (!report->maxfield) if (!report->maxfield)
continue; continue;
application = report->application;
/* /*
* Find the previous hidinput report attached * Find the previous hidinput report attached
* to this report id. * to this report id.
...@@ -1689,7 +1740,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) ...@@ -1689,7 +1740,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force)
hidinput = hidinput_match_application(report); hidinput = hidinput_match_application(report);
if (!hidinput) { if (!hidinput) {
hidinput = hidinput_allocate(hid); hidinput = hidinput_allocate(hid, application);
if (!hidinput) if (!hidinput)
goto out_unwind; goto out_unwind;
} }
......
...@@ -512,6 +512,7 @@ struct hid_input { ...@@ -512,6 +512,7 @@ struct hid_input {
struct list_head list; struct list_head list;
struct hid_report *report; struct hid_report *report;
struct input_dev *input; struct input_dev *input;
const char *name;
bool registered; bool registered;
struct list_head reports; /* the list of reports */ struct list_head reports; /* the list of reports */
}; };
......
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