int i, j;
struct hid_report *report;
struct hid_report_enum *report_enum;
- struct list_head *list;
struct hid_field *field;
if (uref->report_type < HID_REPORT_TYPE_MIN ||
report_enum = hid->report_enum +
(uref->report_type - HID_REPORT_TYPE_MIN);
- list = report_enum->report_list.next;
- while (list != &report_enum->report_list) {
- report = (struct hid_report *) list;
+
+ list_for_each_entry(report, &report_enum->report_list, list)
for (i = 0; i < report->maxfield; i++) {
field = report->field[i];
for (j = 0; j < field->maxusage; j++) {
}
}
}
- list = list->next;
- }
return NULL;
}
return retval < 0 ? retval : 0;
}
-/*
- * De-allocate a hiddev structure
- */
-static struct usb_class_driver hiddev_class;
-static void hiddev_cleanup(struct hiddev *hiddev)
-{
- hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
- usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
- kfree(hiddev);
-}
/*
* release file op
if (list->hiddev->exist)
hid_close(list->hiddev->hid);
else
- hiddev_cleanup(list->hiddev);
+ kfree(list->hiddev);
}
kfree(list);
dinfo.busnum = dev->bus->busnum;
dinfo.devnum = dev->devnum;
dinfo.ifnum = hid->ifnum;
- dinfo.vendor = dev->descriptor.idVendor;
- dinfo.product = dev->descriptor.idProduct;
- dinfo.version = dev->descriptor.bcdDevice;
+ dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor);
+ dinfo.product = le16_to_cpu(dev->descriptor.idProduct);
+ dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice);
dinfo.num_applications = hid->maxapplication;
if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
return -EFAULT;
goto inval;
field = report->field[uref->field_index];
- if (uref->usage_index >= field->maxusage)
- goto inval;
- if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
- if (uref_multi->num_values >= HID_MAX_USAGES ||
- uref->usage_index >= field->maxusage ||
- (uref->usage_index + uref_multi->num_values) >= field->maxusage)
+ if (cmd == HIDIOCGCOLLECTIONINDEX) {
+ if (uref->usage_index >= field->maxusage)
goto inval;
+ } else if (uref->usage_index >= field->report_count)
+ goto inval;
+
+ else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+ (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+ uref->usage_index + uref_multi->num_values >= field->report_count))
+ goto inval;
}
- }
switch (cmd) {
case HIDIOCGUSAGE:
* This is where hid.c calls us to disconnect a hiddev device from the
* corresponding hid device (usually because the usb device has disconnected)
*/
+static struct usb_class_driver hiddev_class;
void hiddev_disconnect(struct hid_device *hid)
{
struct hiddev *hiddev = hid->hiddev;
hiddev->exist = 0;
+ hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL;
+ usb_deregister_dev(hiddev->hid->intf, &hiddev_class);
+
if (hiddev->open) {
hid_close(hiddev->hid);
wake_up_interruptible(&hiddev->wait);
} else {
- hiddev_cleanup(hiddev);
+ kfree(hiddev);
}
}