HID: Add device group to modalias
HID devices are only partially presented to userland. Hotplugged devices emit events containing a modalias based on the basic bus, vendor and product entities. However, in practise a hid device can depend on details such as a single usb interface or a particular item in a report descriptor. This patch adds a device group to the hid device id, and broadcasts it using uevent and the device modalias. The module alias generation is modified to match. As a consequence, a device with a non-zero group will be processed by the corresponding group driver instead of by the generic hid driver. Signed-off-by: Henrik Rydberg <rydberg@euromail.se> Acked-by: Benjamin Tissoires <benjamin.tissoires@gmail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
a7197c2e41
commit
4d53b8012f
|
@ -1222,6 +1222,7 @@ static bool hid_match_one_id(struct hid_device *hdev,
|
||||||
const struct hid_device_id *id)
|
const struct hid_device_id *id)
|
||||||
{
|
{
|
||||||
return id->bus == hdev->bus &&
|
return id->bus == hdev->bus &&
|
||||||
|
(id->group == HID_GROUP_ANY || id->group == hdev->group) &&
|
||||||
(id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) &&
|
(id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) &&
|
||||||
(id->product == HID_ANY_ID || id->product == hdev->product);
|
(id->product == HID_ANY_ID || id->product == hdev->product);
|
||||||
}
|
}
|
||||||
|
@ -1694,6 +1695,7 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
dynid->id.bus = bus;
|
dynid->id.bus = bus;
|
||||||
|
dynid->id.group = HID_GROUP_ANY;
|
||||||
dynid->id.vendor = vendor;
|
dynid->id.vendor = vendor;
|
||||||
dynid->id.product = product;
|
dynid->id.product = product;
|
||||||
dynid->id.driver_data = driver_data;
|
dynid->id.driver_data = driver_data;
|
||||||
|
@ -1817,6 +1819,23 @@ static int hid_device_remove(struct device *dev)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = snprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n",
|
||||||
|
hdev->bus, hdev->group, hdev->vendor, hdev->product);
|
||||||
|
|
||||||
|
return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct device_attribute hid_dev_attrs[] = {
|
||||||
|
__ATTR_RO(modalias),
|
||||||
|
__ATTR_NULL,
|
||||||
|
};
|
||||||
|
|
||||||
static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
|
static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
struct hid_device *hdev = container_of(dev, struct hid_device, dev);
|
||||||
|
@ -1834,8 +1853,8 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq))
|
if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X",
|
if (add_uevent_var(env, "MODALIAS=hid:b%04Xg%04Xv%08Xp%08X",
|
||||||
hdev->bus, hdev->vendor, hdev->product))
|
hdev->bus, hdev->group, hdev->vendor, hdev->product))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1843,6 +1862,7 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env)
|
||||||
|
|
||||||
static struct bus_type hid_bus_type = {
|
static struct bus_type hid_bus_type = {
|
||||||
.name = "hid",
|
.name = "hid",
|
||||||
|
.dev_attrs = hid_dev_attrs,
|
||||||
.match = hid_bus_match,
|
.match = hid_bus_match,
|
||||||
.probe = hid_device_probe,
|
.probe = hid_device_probe,
|
||||||
.remove = hid_device_remove,
|
.remove = hid_device_remove,
|
||||||
|
|
|
@ -476,6 +476,7 @@ struct hid_device { /* device report descriptor */
|
||||||
unsigned maxcollection; /* Number of parsed collections */
|
unsigned maxcollection; /* Number of parsed collections */
|
||||||
unsigned maxapplication; /* Number of applications */
|
unsigned maxapplication; /* Number of applications */
|
||||||
__u16 bus; /* BUS ID */
|
__u16 bus; /* BUS ID */
|
||||||
|
__u16 group; /* Report group */
|
||||||
__u32 vendor; /* Vendor ID */
|
__u32 vendor; /* Vendor ID */
|
||||||
__u32 product; /* Product ID */
|
__u32 product; /* Product ID */
|
||||||
__u32 version; /* HID version */
|
__u32 version; /* HID version */
|
||||||
|
|
|
@ -132,10 +132,11 @@ struct usb_device_id {
|
||||||
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
|
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
|
||||||
|
|
||||||
#define HID_ANY_ID (~0)
|
#define HID_ANY_ID (~0)
|
||||||
|
#define HID_GROUP_ANY 0x0000
|
||||||
|
|
||||||
struct hid_device_id {
|
struct hid_device_id {
|
||||||
__u16 bus;
|
__u16 bus;
|
||||||
__u16 pad1;
|
__u16 group;
|
||||||
__u32 vendor;
|
__u32 vendor;
|
||||||
__u32 product;
|
__u32 product;
|
||||||
kernel_ulong_t driver_data
|
kernel_ulong_t driver_data
|
||||||
|
|
|
@ -336,10 +336,12 @@ static int do_hid_entry(const char *filename,
|
||||||
struct hid_device_id *id, char *alias)
|
struct hid_device_id *id, char *alias)
|
||||||
{
|
{
|
||||||
id->bus = TO_NATIVE(id->bus);
|
id->bus = TO_NATIVE(id->bus);
|
||||||
|
id->group = TO_NATIVE(id->group);
|
||||||
id->vendor = TO_NATIVE(id->vendor);
|
id->vendor = TO_NATIVE(id->vendor);
|
||||||
id->product = TO_NATIVE(id->product);
|
id->product = TO_NATIVE(id->product);
|
||||||
|
|
||||||
sprintf(alias, "hid:b%04X", id->bus);
|
sprintf(alias, "hid:b%04X", id->bus);
|
||||||
|
ADD(alias, "g", id->group != HID_GROUP_ANY, id->group);
|
||||||
ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor);
|
ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor);
|
||||||
ADD(alias, "p", id->product != HID_ANY_ID, id->product);
|
ADD(alias, "p", id->product != HID_ANY_ID, id->product);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue