mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-25 01:30:52 +07:00
HID: core: replace the collection tree pointers with indices
Previously, the pointer to the parent collection was stored. If a device
exceeds 16 collections (HID_DEFAULT_NUM_COLLECTIONS), the array to store
the collections is reallocated, the pointer to the parent collection becomes
invalid.
Replace the pointers with an index-based lookup into the collections array.
Fixes: c53431eb69
("HID: core: store the collections as a basic tree")
Reported-by: Pandruvada, Srinivas <srinivas.pandruvada@intel.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Tested-by: Kyle Pelton <kyle.d.pelton@linux.intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
This commit is contained in:
parent
cf26057a94
commit
ee46967fc6
@ -125,6 +125,7 @@ static int open_collection(struct hid_parser *parser, unsigned type)
|
|||||||
{
|
{
|
||||||
struct hid_collection *collection;
|
struct hid_collection *collection;
|
||||||
unsigned usage;
|
unsigned usage;
|
||||||
|
int collection_index;
|
||||||
|
|
||||||
usage = parser->local.usage[0];
|
usage = parser->local.usage[0];
|
||||||
|
|
||||||
@ -167,13 +168,13 @@ static int open_collection(struct hid_parser *parser, unsigned type)
|
|||||||
parser->collection_stack[parser->collection_stack_ptr++] =
|
parser->collection_stack[parser->collection_stack_ptr++] =
|
||||||
parser->device->maxcollection;
|
parser->device->maxcollection;
|
||||||
|
|
||||||
collection = parser->device->collection +
|
collection_index = parser->device->maxcollection++;
|
||||||
parser->device->maxcollection++;
|
collection = parser->device->collection + collection_index;
|
||||||
collection->type = type;
|
collection->type = type;
|
||||||
collection->usage = usage;
|
collection->usage = usage;
|
||||||
collection->level = parser->collection_stack_ptr - 1;
|
collection->level = parser->collection_stack_ptr - 1;
|
||||||
collection->parent = parser->active_collection;
|
collection->parent_idx = parser->active_collection_idx;
|
||||||
parser->active_collection = collection;
|
parser->active_collection_idx = collection_index;
|
||||||
|
|
||||||
if (type == HID_COLLECTION_APPLICATION)
|
if (type == HID_COLLECTION_APPLICATION)
|
||||||
parser->device->maxapplication++;
|
parser->device->maxapplication++;
|
||||||
@ -192,8 +193,13 @@ static int close_collection(struct hid_parser *parser)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
parser->collection_stack_ptr--;
|
parser->collection_stack_ptr--;
|
||||||
if (parser->active_collection)
|
if (parser->active_collection_idx != -1) {
|
||||||
parser->active_collection = parser->active_collection->parent;
|
struct hid_device *device = parser->device;
|
||||||
|
struct hid_collection *c;
|
||||||
|
|
||||||
|
c = &device->collection[parser->active_collection_idx];
|
||||||
|
parser->active_collection_idx = c->parent_idx;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -819,6 +825,7 @@ static int hid_scan_report(struct hid_device *hid)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
parser->device = hid;
|
parser->device = hid;
|
||||||
|
parser->active_collection_idx = -1;
|
||||||
hid->group = HID_GROUP_GENERIC;
|
hid->group = HID_GROUP_GENERIC;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1006,10 +1013,12 @@ static void hid_apply_multiplier_to_field(struct hid_device *hid,
|
|||||||
usage = &field->usage[i];
|
usage = &field->usage[i];
|
||||||
|
|
||||||
collection = &hid->collection[usage->collection_index];
|
collection = &hid->collection[usage->collection_index];
|
||||||
while (collection && collection != multiplier_collection)
|
while (collection->parent_idx != -1 &&
|
||||||
collection = collection->parent;
|
collection != multiplier_collection)
|
||||||
|
collection = &hid->collection[collection->parent_idx];
|
||||||
|
|
||||||
if (collection || multiplier_collection == NULL)
|
if (collection->parent_idx != -1 ||
|
||||||
|
multiplier_collection == NULL)
|
||||||
usage->resolution_multiplier = effective_multiplier;
|
usage->resolution_multiplier = effective_multiplier;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1044,9 +1053,9 @@ static void hid_apply_multiplier(struct hid_device *hid,
|
|||||||
* applicable fields later.
|
* applicable fields later.
|
||||||
*/
|
*/
|
||||||
multiplier_collection = &hid->collection[multiplier->usage->collection_index];
|
multiplier_collection = &hid->collection[multiplier->usage->collection_index];
|
||||||
while (multiplier_collection &&
|
while (multiplier_collection->parent_idx != -1 &&
|
||||||
multiplier_collection->type != HID_COLLECTION_LOGICAL)
|
multiplier_collection->type != HID_COLLECTION_LOGICAL)
|
||||||
multiplier_collection = multiplier_collection->parent;
|
multiplier_collection = &hid->collection[multiplier_collection->parent_idx];
|
||||||
|
|
||||||
effective_multiplier = hid_calculate_multiplier(hid, multiplier);
|
effective_multiplier = hid_calculate_multiplier(hid, multiplier);
|
||||||
|
|
||||||
@ -1170,6 +1179,7 @@ int hid_open_report(struct hid_device *device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
parser->device = device;
|
parser->device = device;
|
||||||
|
parser->active_collection_idx = -1;
|
||||||
|
|
||||||
end = start + size;
|
end = start + size;
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ struct hid_local {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct hid_collection {
|
struct hid_collection {
|
||||||
struct hid_collection *parent;
|
int parent_idx; /* device->collection */
|
||||||
unsigned type;
|
unsigned type;
|
||||||
unsigned usage;
|
unsigned usage;
|
||||||
unsigned level;
|
unsigned level;
|
||||||
@ -658,7 +658,7 @@ struct hid_parser {
|
|||||||
unsigned int *collection_stack;
|
unsigned int *collection_stack;
|
||||||
unsigned int collection_stack_ptr;
|
unsigned int collection_stack_ptr;
|
||||||
unsigned int collection_stack_size;
|
unsigned int collection_stack_size;
|
||||||
struct hid_collection *active_collection;
|
int active_collection_idx; /* device->collection */
|
||||||
struct hid_device *device;
|
struct hid_device *device;
|
||||||
unsigned int scan_flags;
|
unsigned int scan_flags;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user