diff options
-rw-r--r-- | drivers/hid/hid-core.c | 474 | ||||
-rw-r--r-- | drivers/hid/hid-input.c | 2 | ||||
-rw-r--r-- | drivers/hid/usbhid/hid-core.c | 44 | ||||
-rw-r--r-- | drivers/hid/usbhid/usbhid.h | 2 | ||||
-rw-r--r-- | include/linux/hid.h | 104 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 64 |
6 files changed, 586 insertions, 104 deletions
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 426ac5add585..017fc20167d4 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -534,9 +534,10 @@ static void hid_free_report(struct hid_report *report) | |||
534 | * Free a device structure, all reports, and all fields. | 534 | * Free a device structure, all reports, and all fields. |
535 | */ | 535 | */ |
536 | 536 | ||
537 | void hid_free_device(struct hid_device *device) | 537 | static void hid_device_release(struct device *dev) |
538 | { | 538 | { |
539 | unsigned i,j; | 539 | struct hid_device *device = container_of(dev, struct hid_device, dev); |
540 | unsigned i, j; | ||
540 | 541 | ||
541 | for (i = 0; i < HID_REPORT_TYPES; i++) { | 542 | for (i = 0; i < HID_REPORT_TYPES; i++) { |
542 | struct hid_report_enum *report_enum = device->report_enum + i; | 543 | struct hid_report_enum *report_enum = device->report_enum + i; |
@@ -552,7 +553,6 @@ void hid_free_device(struct hid_device *device) | |||
552 | kfree(device->collection); | 553 | kfree(device->collection); |
553 | kfree(device); | 554 | kfree(device); |
554 | } | 555 | } |
555 | EXPORT_SYMBOL_GPL(hid_free_device); | ||
556 | 556 | ||
557 | /* | 557 | /* |
558 | * Fetch a report description item from the data stream. We support long | 558 | * Fetch a report description item from the data stream. We support long |
@@ -622,18 +622,24 @@ static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) | |||
622 | return NULL; | 622 | return NULL; |
623 | } | 623 | } |
624 | 624 | ||
625 | /* | 625 | /** |
626 | * hid_parse_report - parse device report | ||
627 | * | ||
628 | * @device: hid device | ||
629 | * @start: report start | ||
630 | * @size: report size | ||
631 | * | ||
626 | * Parse a report description into a hid_device structure. Reports are | 632 | * Parse a report description into a hid_device structure. Reports are |
627 | * enumerated, fields are attached to these reports. | 633 | * enumerated, fields are attached to these reports. |
634 | * 0 returned on success, otherwise nonzero error value. | ||
628 | */ | 635 | */ |
629 | 636 | int hid_parse_report(struct hid_device *device, __u8 *start, | |
630 | struct hid_device *hid_parse_report(__u8 *start, unsigned size) | 637 | unsigned size) |
631 | { | 638 | { |
632 | struct hid_device *device; | ||
633 | struct hid_parser *parser; | 639 | struct hid_parser *parser; |
634 | struct hid_item item; | 640 | struct hid_item item; |
635 | __u8 *end; | 641 | __u8 *end; |
636 | unsigned i; | 642 | int ret; |
637 | static int (*dispatch_type[])(struct hid_parser *parser, | 643 | static int (*dispatch_type[])(struct hid_parser *parser, |
638 | struct hid_item *item) = { | 644 | struct hid_item *item) = { |
639 | hid_parser_main, | 645 | hid_parser_main, |
@@ -642,76 +648,54 @@ struct hid_device *hid_parse_report(__u8 *start, unsigned size) | |||
642 | hid_parser_reserved | 648 | hid_parser_reserved |
643 | }; | 649 | }; |
644 | 650 | ||
645 | if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL))) | 651 | device->rdesc = kmalloc(size, GFP_KERNEL); |
646 | return NULL; | 652 | if (device->rdesc == NULL) |
647 | 653 | return -ENOMEM; | |
648 | if (!(device->collection = kzalloc(sizeof(struct hid_collection) * | ||
649 | HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { | ||
650 | kfree(device); | ||
651 | return NULL; | ||
652 | } | ||
653 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | ||
654 | |||
655 | for (i = 0; i < HID_REPORT_TYPES; i++) | ||
656 | INIT_LIST_HEAD(&device->report_enum[i].report_list); | ||
657 | |||
658 | if (!(device->rdesc = kmalloc(size, GFP_KERNEL))) { | ||
659 | kfree(device->collection); | ||
660 | kfree(device); | ||
661 | return NULL; | ||
662 | } | ||
663 | memcpy(device->rdesc, start, size); | 654 | memcpy(device->rdesc, start, size); |
664 | device->rsize = size; | 655 | device->rsize = size; |
665 | 656 | ||
666 | if (!(parser = vmalloc(sizeof(struct hid_parser)))) { | 657 | parser = vmalloc(sizeof(struct hid_parser)); |
667 | kfree(device->rdesc); | 658 | if (!parser) { |
668 | kfree(device->collection); | 659 | ret = -ENOMEM; |
669 | kfree(device); | 660 | goto err; |
670 | return NULL; | ||
671 | } | 661 | } |
662 | |||
672 | memset(parser, 0, sizeof(struct hid_parser)); | 663 | memset(parser, 0, sizeof(struct hid_parser)); |
673 | parser->device = device; | 664 | parser->device = device; |
674 | 665 | ||
675 | end = start + size; | 666 | end = start + size; |
667 | ret = -EINVAL; | ||
676 | while ((start = fetch_item(start, end, &item)) != NULL) { | 668 | while ((start = fetch_item(start, end, &item)) != NULL) { |
677 | 669 | ||
678 | if (item.format != HID_ITEM_FORMAT_SHORT) { | 670 | if (item.format != HID_ITEM_FORMAT_SHORT) { |
679 | dbg_hid("unexpected long global item\n"); | 671 | dbg_hid("unexpected long global item\n"); |
680 | hid_free_device(device); | 672 | goto err; |
681 | vfree(parser); | ||
682 | return NULL; | ||
683 | } | 673 | } |
684 | 674 | ||
685 | if (dispatch_type[item.type](parser, &item)) { | 675 | if (dispatch_type[item.type](parser, &item)) { |
686 | dbg_hid("item %u %u %u %u parsing failed\n", | 676 | dbg_hid("item %u %u %u %u parsing failed\n", |
687 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); | 677 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); |
688 | hid_free_device(device); | 678 | goto err; |
689 | vfree(parser); | ||
690 | return NULL; | ||
691 | } | 679 | } |
692 | 680 | ||
693 | if (start == end) { | 681 | if (start == end) { |
694 | if (parser->collection_stack_ptr) { | 682 | if (parser->collection_stack_ptr) { |
695 | dbg_hid("unbalanced collection at end of report description\n"); | 683 | dbg_hid("unbalanced collection at end of report description\n"); |
696 | hid_free_device(device); | 684 | goto err; |
697 | vfree(parser); | ||
698 | return NULL; | ||
699 | } | 685 | } |
700 | if (parser->local.delimiter_depth) { | 686 | if (parser->local.delimiter_depth) { |
701 | dbg_hid("unbalanced delimiter at end of report description\n"); | 687 | dbg_hid("unbalanced delimiter at end of report description\n"); |
702 | hid_free_device(device); | 688 | goto err; |
703 | vfree(parser); | ||
704 | return NULL; | ||
705 | } | 689 | } |
706 | vfree(parser); | 690 | vfree(parser); |
707 | return device; | 691 | return 0; |
708 | } | 692 | } |
709 | } | 693 | } |
710 | 694 | ||
711 | dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); | 695 | dbg_hid("item fetching failed at offset %d\n", (int)(end - start)); |
712 | hid_free_device(device); | 696 | err: |
713 | vfree(parser); | 697 | vfree(parser); |
714 | return NULL; | 698 | return ret; |
715 | } | 699 | } |
716 | EXPORT_SYMBOL_GPL(hid_parse_report); | 700 | EXPORT_SYMBOL_GPL(hid_parse_report); |
717 | 701 | ||
@@ -815,9 +799,73 @@ static __inline__ int search(__s32 *array, __s32 value, unsigned n) | |||
815 | return -1; | 799 | return -1; |
816 | } | 800 | } |
817 | 801 | ||
818 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt) | 802 | /** |
803 | * hid_match_report - check if driver's raw_event should be called | ||
804 | * | ||
805 | * @hid: hid device | ||
806 | * @report_type: type to match against | ||
807 | * | ||
808 | * compare hid->driver->report_table->report_type to report->type | ||
809 | */ | ||
810 | static int hid_match_report(struct hid_device *hid, struct hid_report *report) | ||
819 | { | 811 | { |
812 | const struct hid_report_id *id = hid->driver->report_table; | ||
813 | |||
814 | if (!id) /* NULL means all */ | ||
815 | return 1; | ||
816 | |||
817 | for (; id->report_type != HID_TERMINATOR; id++) | ||
818 | if (id->report_type == HID_ANY_ID || | ||
819 | id->report_type == report->type) | ||
820 | return 1; | ||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | /** | ||
825 | * hid_match_usage - check if driver's event should be called | ||
826 | * | ||
827 | * @hid: hid device | ||
828 | * @usage: usage to match against | ||
829 | * | ||
830 | * compare hid->driver->usage_table->usage_{type,code} to | ||
831 | * usage->usage_{type,code} | ||
832 | */ | ||
833 | static int hid_match_usage(struct hid_device *hid, struct hid_usage *usage) | ||
834 | { | ||
835 | const struct hid_usage_id *id = hid->driver->usage_table; | ||
836 | |||
837 | if (!id) /* NULL means all */ | ||
838 | return 1; | ||
839 | |||
840 | for (; id->usage_type != HID_ANY_ID - 1; id++) | ||
841 | if ((id->usage_hid == HID_ANY_ID || | ||
842 | id->usage_hid == usage->hid) && | ||
843 | (id->usage_type == HID_ANY_ID || | ||
844 | id->usage_type == usage->type) && | ||
845 | (id->usage_code == HID_ANY_ID || | ||
846 | id->usage_code == usage->code)) | ||
847 | return 1; | ||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, | ||
852 | struct hid_usage *usage, __s32 value, int interrupt) | ||
853 | { | ||
854 | struct hid_driver *hdrv = hid->driver; | ||
855 | int ret; | ||
856 | |||
820 | hid_dump_input(usage, value); | 857 | hid_dump_input(usage, value); |
858 | |||
859 | if (hdrv && hdrv->event && hid_match_usage(hid, usage)) { | ||
860 | ret = hdrv->event(hid, field, usage, value); | ||
861 | if (ret != 0) { | ||
862 | if (ret < 0) | ||
863 | dbg_hid("%s's event failed with %d\n", | ||
864 | hdrv->name, ret); | ||
865 | return; | ||
866 | } | ||
867 | } | ||
868 | |||
821 | if (hid->claimed & HID_CLAIMED_INPUT) | 869 | if (hid->claimed & HID_CLAIMED_INPUT) |
822 | hidinput_hid_event(hid, field, usage, value); | 870 | hidinput_hid_event(hid, field, usage, value); |
823 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) | 871 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt && hid->hiddev_hid_event) |
@@ -946,44 +994,47 @@ int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) | |||
946 | } | 994 | } |
947 | EXPORT_SYMBOL_GPL(hid_set_field); | 995 | EXPORT_SYMBOL_GPL(hid_set_field); |
948 | 996 | ||
949 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | 997 | static struct hid_report *hid_get_report(struct hid_report_enum *report_enum, |
998 | const u8 *data) | ||
950 | { | 999 | { |
951 | struct hid_report_enum *report_enum = hid->report_enum + type; | ||
952 | struct hid_report *report; | 1000 | struct hid_report *report; |
953 | int n, rsize, i; | 1001 | unsigned int n = 0; /* Normally report number is 0 */ |
954 | 1002 | ||
955 | if (!hid) | 1003 | /* Device uses numbered reports, data[0] is report number */ |
956 | return -ENODEV; | 1004 | if (report_enum->numbered) |
1005 | n = *data; | ||
957 | 1006 | ||
958 | if (!size) { | 1007 | report = report_enum->report_id_hash[n]; |
959 | dbg_hid("empty report\n"); | 1008 | if (report == NULL) |
960 | return -1; | 1009 | dbg_hid("undefined report_id %u received\n", n); |
961 | } | ||
962 | 1010 | ||
963 | dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); | 1011 | return report; |
1012 | } | ||
964 | 1013 | ||
965 | n = 0; /* Normally report number is 0 */ | 1014 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, |
966 | if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ | 1015 | int interrupt) |
967 | n = *data++; | 1016 | { |
968 | size--; | 1017 | struct hid_report_enum *report_enum = hid->report_enum + type; |
969 | } | 1018 | struct hid_report *report; |
1019 | unsigned int a; | ||
1020 | int rsize, csize = size; | ||
1021 | u8 *cdata = data; | ||
970 | 1022 | ||
971 | /* dump the report */ | 1023 | report = hid_get_report(report_enum, data); |
972 | dbg_hid("report %d (size %u) = ", n, size); | 1024 | if (!report) |
973 | for (i = 0; i < size; i++) | 1025 | return; |
974 | dbg_hid_line(" %02x", data[i]); | ||
975 | dbg_hid_line("\n"); | ||
976 | 1026 | ||
977 | if (!(report = report_enum->report_id_hash[n])) { | 1027 | if (report_enum->numbered) { |
978 | dbg_hid("undefined report_id %d received\n", n); | 1028 | cdata++; |
979 | return -1; | 1029 | csize--; |
980 | } | 1030 | } |
981 | 1031 | ||
982 | rsize = ((report->size - 1) >> 3) + 1; | 1032 | rsize = ((report->size - 1) >> 3) + 1; |
983 | 1033 | ||
984 | if (size < rsize) { | 1034 | if (csize < rsize) { |
985 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, size, rsize); | 1035 | dbg_hid("report %d is too short, (%d < %d)\n", report->id, |
986 | memset(data + size, 0, rsize - size); | 1036 | csize, rsize); |
1037 | memset(cdata + csize, 0, rsize - csize); | ||
987 | } | 1038 | } |
988 | 1039 | ||
989 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) | 1040 | if ((hid->claimed & HID_CLAIMED_HIDDEV) && hid->hiddev_report_event) |
@@ -996,24 +1047,295 @@ int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int i | |||
996 | hidraw_report_event(hid, data, size); | 1047 | hidraw_report_event(hid, data, size); |
997 | } | 1048 | } |
998 | 1049 | ||
999 | for (n = 0; n < report->maxfield; n++) | 1050 | for (a = 0; a < report->maxfield; a++) |
1000 | hid_input_field(hid, report->field[n], data, interrupt); | 1051 | hid_input_field(hid, report->field[a], cdata, interrupt); |
1001 | 1052 | ||
1002 | if (hid->claimed & HID_CLAIMED_INPUT) | 1053 | if (hid->claimed & HID_CLAIMED_INPUT) |
1003 | hidinput_report_event(hid, report); | 1054 | hidinput_report_event(hid, report); |
1055 | } | ||
1056 | EXPORT_SYMBOL_GPL(hid_report_raw_event); | ||
1057 | |||
1058 | /** | ||
1059 | * hid_input_report - report data from lower layer (usb, bt...) | ||
1060 | * | ||
1061 | * @hid: hid device | ||
1062 | * @type: HID report type (HID_*_REPORT) | ||
1063 | * @data: report contents | ||
1064 | * @size: size of data parameter | ||
1065 | * @interrupt: called from atomic? | ||
1066 | * | ||
1067 | * This is data entry for lower layers. | ||
1068 | */ | ||
1069 | int hid_input_report(struct hid_device *hid, int type, u8 *data, int size, int interrupt) | ||
1070 | { | ||
1071 | struct hid_report_enum *report_enum = hid->report_enum + type; | ||
1072 | struct hid_driver *hdrv = hid->driver; | ||
1073 | struct hid_report *report; | ||
1074 | unsigned int i; | ||
1075 | int ret; | ||
1076 | |||
1077 | if (!hid || !hid->driver) | ||
1078 | return -ENODEV; | ||
1079 | |||
1080 | if (!size) { | ||
1081 | dbg_hid("empty report\n"); | ||
1082 | return -1; | ||
1083 | } | ||
1084 | |||
1085 | dbg_hid("report (size %u) (%snumbered)\n", size, report_enum->numbered ? "" : "un"); | ||
1086 | |||
1087 | report = hid_get_report(report_enum, data); | ||
1088 | if (!report) | ||
1089 | return -1; | ||
1090 | |||
1091 | /* dump the report */ | ||
1092 | dbg_hid("report %d (size %u) = ", report->id, size); | ||
1093 | for (i = 0; i < size; i++) | ||
1094 | dbg_hid_line(" %02x", data[i]); | ||
1095 | dbg_hid_line("\n"); | ||
1096 | |||
1097 | if (hdrv && hdrv->raw_event && hid_match_report(hid, report)) { | ||
1098 | ret = hdrv->raw_event(hid, report, data, size); | ||
1099 | if (ret != 0) | ||
1100 | return ret < 0 ? ret : 0; | ||
1101 | } | ||
1102 | |||
1103 | hid_report_raw_event(hid, type, data, size, interrupt); | ||
1004 | 1104 | ||
1005 | return 0; | 1105 | return 0; |
1006 | } | 1106 | } |
1007 | EXPORT_SYMBOL_GPL(hid_input_report); | 1107 | EXPORT_SYMBOL_GPL(hid_input_report); |
1008 | 1108 | ||
1109 | static bool hid_match_one_id(struct hid_device *hdev, | ||
1110 | const struct hid_device_id *id) | ||
1111 | { | ||
1112 | return id->bus == hdev->bus && | ||
1113 | (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && | ||
1114 | (id->product == HID_ANY_ID || id->product == hdev->product); | ||
1115 | } | ||
1116 | |||
1117 | static const struct hid_device_id *hid_match_id(struct hid_device *hdev, | ||
1118 | const struct hid_device_id *id) | ||
1119 | { | ||
1120 | for (; id->bus; id++) | ||
1121 | if (hid_match_one_id(hdev, id)) | ||
1122 | return id; | ||
1123 | |||
1124 | return NULL; | ||
1125 | } | ||
1126 | |||
1127 | static const struct hid_device_id hid_blacklist[] = { | ||
1128 | { } | ||
1129 | }; | ||
1130 | |||
1131 | static int hid_bus_match(struct device *dev, struct device_driver *drv) | ||
1132 | { | ||
1133 | struct hid_driver *hdrv = container_of(drv, struct hid_driver, driver); | ||
1134 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1135 | |||
1136 | if (!hid_match_id(hdev, hdrv->id_table)) | ||
1137 | return 0; | ||
1138 | |||
1139 | /* generic wants all non-blacklisted */ | ||
1140 | if (!strncmp(hdrv->name, "generic-", 8)) | ||
1141 | return !hid_match_id(hdev, hid_blacklist); | ||
1142 | |||
1143 | return 1; | ||
1144 | } | ||
1145 | |||
1146 | static int hid_device_probe(struct device *dev) | ||
1147 | { | ||
1148 | struct hid_driver *hdrv = container_of(dev->driver, | ||
1149 | struct hid_driver, driver); | ||
1150 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1151 | const struct hid_device_id *id; | ||
1152 | int ret = 0; | ||
1153 | |||
1154 | if (!hdev->driver) { | ||
1155 | if (hdrv->probe) { | ||
1156 | ret = -ENODEV; | ||
1157 | |||
1158 | id = hid_match_id(hdev, hdrv->id_table); | ||
1159 | if (id) | ||
1160 | ret = hdrv->probe(hdev, id); | ||
1161 | } | ||
1162 | if (!ret) | ||
1163 | hdev->driver = hdrv; | ||
1164 | } | ||
1165 | return ret; | ||
1166 | } | ||
1167 | |||
1168 | static int hid_device_remove(struct device *dev) | ||
1169 | { | ||
1170 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1171 | struct hid_driver *hdrv = hdev->driver; | ||
1172 | |||
1173 | if (hdrv) { | ||
1174 | if (hdrv->remove) | ||
1175 | hdrv->remove(hdev); | ||
1176 | hdev->driver = NULL; | ||
1177 | } | ||
1178 | |||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | ||
1183 | { | ||
1184 | struct hid_device *hdev = container_of(dev, struct hid_device, dev); | ||
1185 | |||
1186 | if (add_uevent_var(env, "HID_ID=%04X:%08X:%08X", | ||
1187 | hdev->bus, hdev->vendor, hdev->product)) | ||
1188 | return -ENOMEM; | ||
1189 | |||
1190 | if (add_uevent_var(env, "HID_NAME=%s", hdev->name)) | ||
1191 | return -ENOMEM; | ||
1192 | |||
1193 | if (add_uevent_var(env, "HID_PHYS=%s", hdev->phys)) | ||
1194 | return -ENOMEM; | ||
1195 | |||
1196 | if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) | ||
1197 | return -ENOMEM; | ||
1198 | |||
1199 | if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", | ||
1200 | hdev->bus, hdev->vendor, hdev->product)) | ||
1201 | return -ENOMEM; | ||
1202 | |||
1203 | return 0; | ||
1204 | } | ||
1205 | |||
1206 | static struct bus_type hid_bus_type = { | ||
1207 | .name = "hid", | ||
1208 | .match = hid_bus_match, | ||
1209 | .probe = hid_device_probe, | ||
1210 | .remove = hid_device_remove, | ||
1211 | .uevent = hid_uevent, | ||
1212 | }; | ||
1213 | |||
1214 | int hid_add_device(struct hid_device *hdev) | ||
1215 | { | ||
1216 | static atomic_t id = ATOMIC_INIT(0); | ||
1217 | int ret; | ||
1218 | |||
1219 | if (WARN_ON(hdev->status & HID_STAT_ADDED)) | ||
1220 | return -EBUSY; | ||
1221 | |||
1222 | /* XXX hack, any other cleaner solution < 20 bus_id bytes? */ | ||
1223 | sprintf(hdev->dev.bus_id, "%04X:%04X:%04X.%04X", hdev->bus, | ||
1224 | hdev->vendor, hdev->product, atomic_inc_return(&id)); | ||
1225 | |||
1226 | ret = device_add(&hdev->dev); | ||
1227 | if (!ret) | ||
1228 | hdev->status |= HID_STAT_ADDED; | ||
1229 | |||
1230 | return ret; | ||
1231 | } | ||
1232 | EXPORT_SYMBOL_GPL(hid_add_device); | ||
1233 | |||
1234 | /** | ||
1235 | * hid_allocate_device - allocate new hid device descriptor | ||
1236 | * | ||
1237 | * Allocate and initialize hid device, so that hid_destroy_device might be | ||
1238 | * used to free it. | ||
1239 | * | ||
1240 | * New hid_device pointer is returned on success, otherwise ERR_PTR encoded | ||
1241 | * error value. | ||
1242 | */ | ||
1243 | struct hid_device *hid_allocate_device(void) | ||
1244 | { | ||
1245 | struct hid_device *hdev; | ||
1246 | unsigned int i; | ||
1247 | int ret = -ENOMEM; | ||
1248 | |||
1249 | hdev = kzalloc(sizeof(*hdev), GFP_KERNEL); | ||
1250 | if (hdev == NULL) | ||
1251 | return ERR_PTR(ret); | ||
1252 | |||
1253 | device_initialize(&hdev->dev); | ||
1254 | hdev->dev.release = hid_device_release; | ||
1255 | hdev->dev.bus = &hid_bus_type; | ||
1256 | |||
1257 | hdev->collection = kcalloc(HID_DEFAULT_NUM_COLLECTIONS, | ||
1258 | sizeof(struct hid_collection), GFP_KERNEL); | ||
1259 | if (hdev->collection == NULL) | ||
1260 | goto err; | ||
1261 | hdev->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | ||
1262 | |||
1263 | for (i = 0; i < HID_REPORT_TYPES; i++) | ||
1264 | INIT_LIST_HEAD(&hdev->report_enum[i].report_list); | ||
1265 | |||
1266 | return hdev; | ||
1267 | err: | ||
1268 | put_device(&hdev->dev); | ||
1269 | return ERR_PTR(ret); | ||
1270 | } | ||
1271 | EXPORT_SYMBOL_GPL(hid_allocate_device); | ||
1272 | |||
1273 | static void hid_remove_device(struct hid_device *hdev) | ||
1274 | { | ||
1275 | if (hdev->status & HID_STAT_ADDED) { | ||
1276 | device_del(&hdev->dev); | ||
1277 | hdev->status &= ~HID_STAT_ADDED; | ||
1278 | } | ||
1279 | } | ||
1280 | |||
1281 | /** | ||
1282 | * hid_destroy_device - free previously allocated device | ||
1283 | * | ||
1284 | * @hdev: hid device | ||
1285 | * | ||
1286 | * If you allocate hid_device through hid_allocate_device, you should ever | ||
1287 | * free by this function. | ||
1288 | */ | ||
1289 | void hid_destroy_device(struct hid_device *hdev) | ||
1290 | { | ||
1291 | hid_remove_device(hdev); | ||
1292 | put_device(&hdev->dev); | ||
1293 | } | ||
1294 | EXPORT_SYMBOL_GPL(hid_destroy_device); | ||
1295 | |||
1296 | int __hid_register_driver(struct hid_driver *hdrv, struct module *owner, | ||
1297 | const char *mod_name) | ||
1298 | { | ||
1299 | hdrv->driver.name = hdrv->name; | ||
1300 | hdrv->driver.bus = &hid_bus_type; | ||
1301 | hdrv->driver.owner = owner; | ||
1302 | hdrv->driver.mod_name = mod_name; | ||
1303 | |||
1304 | return driver_register(&hdrv->driver); | ||
1305 | } | ||
1306 | EXPORT_SYMBOL_GPL(__hid_register_driver); | ||
1307 | |||
1308 | void hid_unregister_driver(struct hid_driver *hdrv) | ||
1309 | { | ||
1310 | driver_unregister(&hdrv->driver); | ||
1311 | } | ||
1312 | EXPORT_SYMBOL_GPL(hid_unregister_driver); | ||
1313 | |||
1009 | static int __init hid_init(void) | 1314 | static int __init hid_init(void) |
1010 | { | 1315 | { |
1011 | return hidraw_init(); | 1316 | int ret; |
1317 | |||
1318 | ret = bus_register(&hid_bus_type); | ||
1319 | if (ret) { | ||
1320 | printk(KERN_ERR "HID: can't register hid bus\n"); | ||
1321 | goto err; | ||
1322 | } | ||
1323 | |||
1324 | ret = hidraw_init(); | ||
1325 | if (ret) | ||
1326 | goto err_bus; | ||
1327 | |||
1328 | return 0; | ||
1329 | err_bus: | ||
1330 | bus_unregister(&hid_bus_type); | ||
1331 | err: | ||
1332 | return ret; | ||
1012 | } | 1333 | } |
1013 | 1334 | ||
1014 | static void __exit hid_exit(void) | 1335 | static void __exit hid_exit(void) |
1015 | { | 1336 | { |
1016 | hidraw_exit(); | 1337 | hidraw_exit(); |
1338 | bus_unregister(&hid_bus_type); | ||
1017 | } | 1339 | } |
1018 | 1340 | ||
1019 | module_init(hid_init); | 1341 | module_init(hid_init); |
diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 1b2e8dc3398d..4ae5603804e7 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c | |||
@@ -1032,7 +1032,7 @@ int hidinput_connect(struct hid_device *hid) | |||
1032 | input_dev->id.vendor = hid->vendor; | 1032 | input_dev->id.vendor = hid->vendor; |
1033 | input_dev->id.product = hid->product; | 1033 | input_dev->id.product = hid->product; |
1034 | input_dev->id.version = hid->version; | 1034 | input_dev->id.version = hid->version; |
1035 | input_dev->dev.parent = hid->dev; | 1035 | input_dev->dev.parent = hid->dev.parent; |
1036 | hidinput->input = input_dev; | 1036 | hidinput->input = input_dev; |
1037 | list_add_tail(&hidinput->list, &hid->inputs); | 1037 | list_add_tail(&hidinput->list, &hid->inputs); |
1038 | } | 1038 | } |
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 27fe4d8912cb..5955d05ae542 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c | |||
@@ -770,8 +770,15 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
770 | dbg_hid_line(" %02x", (unsigned char) rdesc[n]); | 770 | dbg_hid_line(" %02x", (unsigned char) rdesc[n]); |
771 | dbg_hid_line("\n"); | 771 | dbg_hid_line("\n"); |
772 | 772 | ||
773 | if (!(hid = hid_parse_report(rdesc, n))) { | 773 | hid = hid_allocate_device(); |
774 | if (IS_ERR(hid)) { | ||
775 | kfree(rdesc); | ||
776 | return NULL; | ||
777 | } | ||
778 | |||
779 | if (hid_parse_report(hid, rdesc, n)) { | ||
774 | dbg_hid("parsing report descriptor failed\n"); | 780 | dbg_hid("parsing report descriptor failed\n"); |
781 | hid_destroy_device(hid); | ||
775 | kfree(rdesc); | 782 | kfree(rdesc); |
776 | return NULL; | 783 | return NULL; |
777 | } | 784 | } |
@@ -798,10 +805,8 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
798 | if (insize > HID_MAX_BUFFER_SIZE) | 805 | if (insize > HID_MAX_BUFFER_SIZE) |
799 | insize = HID_MAX_BUFFER_SIZE; | 806 | insize = HID_MAX_BUFFER_SIZE; |
800 | 807 | ||
801 | if (hid_alloc_buffers(dev, hid)) { | 808 | if (hid_alloc_buffers(dev, hid)) |
802 | hid_free_buffers(dev, hid); | ||
803 | goto fail; | 809 | goto fail; |
804 | } | ||
805 | 810 | ||
806 | hid->name[0] = 0; | 811 | hid->name[0] = 0; |
807 | 812 | ||
@@ -881,7 +886,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
881 | 886 | ||
882 | hid->version = le16_to_cpu(hdesc->bcdHID); | 887 | hid->version = le16_to_cpu(hdesc->bcdHID); |
883 | hid->country = hdesc->bCountryCode; | 888 | hid->country = hdesc->bCountryCode; |
884 | hid->dev = &intf->dev; | 889 | hid->dev.parent = &intf->dev; |
885 | usbhid->intf = intf; | 890 | usbhid->intf = intf; |
886 | usbhid->ifnum = interface->desc.bInterfaceNumber; | 891 | usbhid->ifnum = interface->desc.bInterfaceNumber; |
887 | 892 | ||
@@ -925,7 +930,7 @@ fail: | |||
925 | hid_free_buffers(dev, hid); | 930 | hid_free_buffers(dev, hid); |
926 | kfree(usbhid); | 931 | kfree(usbhid); |
927 | fail_no_usbhid: | 932 | fail_no_usbhid: |
928 | hid_free_device(hid); | 933 | hid_destroy_device(hid); |
929 | 934 | ||
930 | return NULL; | 935 | return NULL; |
931 | } | 936 | } |
@@ -964,14 +969,14 @@ static void hid_disconnect(struct usb_interface *intf) | |||
964 | 969 | ||
965 | hid_free_buffers(hid_to_usb_dev(hid), hid); | 970 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
966 | kfree(usbhid); | 971 | kfree(usbhid); |
967 | hid_free_device(hid); | 972 | hid_destroy_device(hid); |
968 | } | 973 | } |
969 | 974 | ||
970 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | 975 | static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) |
971 | { | 976 | { |
972 | struct hid_device *hid; | 977 | struct hid_device *hid; |
973 | char path[64]; | 978 | char path[64]; |
974 | int i; | 979 | int i, ret; |
975 | char *c; | 980 | char *c; |
976 | 981 | ||
977 | dbg_hid("HID probe called for ifnum %d\n", | 982 | dbg_hid("HID probe called for ifnum %d\n", |
@@ -1037,7 +1042,12 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1037 | printk(": USB HID v%x.%02x %s [%s] on %s\n", | 1042 | printk(": USB HID v%x.%02x %s [%s] on %s\n", |
1038 | hid->version >> 8, hid->version & 0xff, c, hid->name, path); | 1043 | hid->version >> 8, hid->version & 0xff, c, hid->name, path); |
1039 | 1044 | ||
1040 | return 0; | 1045 | ret = hid_add_device(hid); |
1046 | if (ret) { | ||
1047 | dev_err(&intf->dev, "can't add hid device: %d\n", ret); | ||
1048 | hid_disconnect(intf); | ||
1049 | } | ||
1050 | return ret; | ||
1041 | } | 1051 | } |
1042 | 1052 | ||
1043 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) | 1053 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) |
@@ -1107,9 +1117,22 @@ static struct usb_driver hid_driver = { | |||
1107 | .supports_autosuspend = 1, | 1117 | .supports_autosuspend = 1, |
1108 | }; | 1118 | }; |
1109 | 1119 | ||
1120 | static const struct hid_device_id hid_usb_table[] = { | ||
1121 | { HID_USB_DEVICE(HID_ANY_ID, HID_ANY_ID) }, | ||
1122 | { } | ||
1123 | }; | ||
1124 | |||
1125 | static struct hid_driver hid_usb_driver = { | ||
1126 | .name = "generic-usb", | ||
1127 | .id_table = hid_usb_table, | ||
1128 | }; | ||
1129 | |||
1110 | static int __init hid_init(void) | 1130 | static int __init hid_init(void) |
1111 | { | 1131 | { |
1112 | int retval; | 1132 | int retval; |
1133 | retval = hid_register_driver(&hid_usb_driver); | ||
1134 | if (retval) | ||
1135 | goto hid_register_fail; | ||
1113 | retval = usbhid_quirks_init(quirks_param); | 1136 | retval = usbhid_quirks_init(quirks_param); |
1114 | if (retval) | 1137 | if (retval) |
1115 | goto usbhid_quirks_init_fail; | 1138 | goto usbhid_quirks_init_fail; |
@@ -1127,6 +1150,8 @@ usb_register_fail: | |||
1127 | hiddev_init_fail: | 1150 | hiddev_init_fail: |
1128 | usbhid_quirks_exit(); | 1151 | usbhid_quirks_exit(); |
1129 | usbhid_quirks_init_fail: | 1152 | usbhid_quirks_init_fail: |
1153 | hid_unregister_driver(&hid_usb_driver); | ||
1154 | hid_register_fail: | ||
1130 | return retval; | 1155 | return retval; |
1131 | } | 1156 | } |
1132 | 1157 | ||
@@ -1135,6 +1160,7 @@ static void __exit hid_exit(void) | |||
1135 | usb_deregister(&hid_driver); | 1160 | usb_deregister(&hid_driver); |
1136 | hiddev_exit(); | 1161 | hiddev_exit(); |
1137 | usbhid_quirks_exit(); | 1162 | usbhid_quirks_exit(); |
1163 | hid_unregister_driver(&hid_usb_driver); | ||
1138 | } | 1164 | } |
1139 | 1165 | ||
1140 | module_init(hid_init); | 1166 | module_init(hid_init); |
diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 62d2d7c925bd..b47f991867e9 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h | |||
@@ -82,7 +82,7 @@ struct usbhid_device { | |||
82 | }; | 82 | }; |
83 | 83 | ||
84 | #define hid_to_usb_dev(hid_dev) \ | 84 | #define hid_to_usb_dev(hid_dev) \ |
85 | container_of(hid_dev->dev->parent, struct usb_device, dev) | 85 | container_of(hid_dev->dev.parent->parent, struct usb_device, dev) |
86 | 86 | ||
87 | #endif | 87 | #endif |
88 | 88 | ||
diff --git a/include/linux/hid.h b/include/linux/hid.h index b7a17762a0b2..c4bea0eda85b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h | |||
@@ -418,6 +418,8 @@ struct hid_control_fifo { | |||
418 | #define HID_CLAIMED_HIDDEV 2 | 418 | #define HID_CLAIMED_HIDDEV 2 |
419 | #define HID_CLAIMED_HIDRAW 4 | 419 | #define HID_CLAIMED_HIDRAW 4 |
420 | 420 | ||
421 | #define HID_STAT_ADDED 1 | ||
422 | |||
421 | #define HID_CTRL_RUNNING 1 | 423 | #define HID_CTRL_RUNNING 1 |
422 | #define HID_OUT_RUNNING 2 | 424 | #define HID_OUT_RUNNING 2 |
423 | #define HID_IN_RUNNING 3 | 425 | #define HID_IN_RUNNING 3 |
@@ -432,22 +434,26 @@ struct hid_input { | |||
432 | struct input_dev *input; | 434 | struct input_dev *input; |
433 | }; | 435 | }; |
434 | 436 | ||
437 | struct hid_driver; | ||
438 | |||
435 | struct hid_device { /* device report descriptor */ | 439 | struct hid_device { /* device report descriptor */ |
436 | __u8 *rdesc; | 440 | __u8 *rdesc; |
437 | unsigned rsize; | 441 | unsigned rsize; |
438 | struct hid_collection *collection; /* List of HID collections */ | 442 | struct hid_collection *collection; /* List of HID collections */ |
439 | unsigned collection_size; /* Number of allocated hid_collections */ | 443 | unsigned collection_size; /* Number of allocated hid_collections */ |
440 | unsigned maxcollection; /* Number of parsed collections */ | 444 | unsigned maxcollection; /* Number of parsed collections */ |
441 | unsigned maxapplication; /* Number of applications */ | 445 | unsigned maxapplication; /* Number of applications */ |
442 | unsigned short bus; /* BUS ID */ | 446 | __u16 bus; /* BUS ID */ |
443 | unsigned short vendor; /* Vendor ID */ | 447 | __u32 vendor; /* Vendor ID */ |
444 | unsigned short product; /* Product ID */ | 448 | __u32 product; /* Product ID */ |
445 | unsigned version; /* HID version */ | 449 | __u32 version; /* HID version */ |
446 | unsigned country; /* HID country */ | 450 | unsigned country; /* HID country */ |
447 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; | 451 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; |
448 | 452 | ||
449 | struct device *dev; /* device */ | 453 | struct device dev; /* device */ |
454 | struct hid_driver *driver; | ||
450 | 455 | ||
456 | unsigned int status; /* see STAT flags above */ | ||
451 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | 457 | unsigned claimed; /* Claimed by hidinput, hiddev? */ |
452 | unsigned quirks; /* Various quirks the device can pull on us */ | 458 | unsigned quirks; /* Various quirks the device can pull on us */ |
453 | 459 | ||
@@ -483,6 +489,16 @@ struct hid_device { /* device report descriptor */ | |||
483 | #endif | 489 | #endif |
484 | }; | 490 | }; |
485 | 491 | ||
492 | static inline void *hid_get_drvdata(struct hid_device *hdev) | ||
493 | { | ||
494 | return dev_get_drvdata(&hdev->dev); | ||
495 | } | ||
496 | |||
497 | static inline void hid_set_drvdata(struct hid_device *hdev, void *data) | ||
498 | { | ||
499 | dev_set_drvdata(&hdev->dev, data); | ||
500 | } | ||
501 | |||
486 | #define HID_GLOBAL_STACK_SIZE 4 | 502 | #define HID_GLOBAL_STACK_SIZE 4 |
487 | #define HID_COLLECTION_STACK_SIZE 4 | 503 | #define HID_COLLECTION_STACK_SIZE 4 |
488 | 504 | ||
@@ -511,6 +527,61 @@ struct hid_descriptor { | |||
511 | struct hid_class_descriptor desc[1]; | 527 | struct hid_class_descriptor desc[1]; |
512 | } __attribute__ ((packed)); | 528 | } __attribute__ ((packed)); |
513 | 529 | ||
530 | #define HID_DEVICE(b, ven, prod) \ | ||
531 | .bus = (b), \ | ||
532 | .vendor = (ven), .product = (prod) | ||
533 | |||
534 | #define HID_USB_DEVICE(ven, prod) HID_DEVICE(BUS_USB, ven, prod) | ||
535 | #define HID_BLUETOOTH_DEVICE(ven, prod) HID_DEVICE(BUS_BLUETOOTH, ven, prod) | ||
536 | |||
537 | #define HID_REPORT_ID(rep) \ | ||
538 | .report_type = (rep) | ||
539 | #define HID_USAGE_ID(uhid, utype, ucode) \ | ||
540 | .usage_hid = (uhid), .usage_type = (utype), .usage_code = (ucode) | ||
541 | /* we don't want to catch types and codes equal to 0 */ | ||
542 | #define HID_TERMINATOR (HID_ANY_ID - 1) | ||
543 | |||
544 | struct hid_report_id { | ||
545 | __u32 report_type; | ||
546 | }; | ||
547 | struct hid_usage_id { | ||
548 | __u32 usage_hid; | ||
549 | __u32 usage_type; | ||
550 | __u32 usage_code; | ||
551 | }; | ||
552 | |||
553 | /** | ||
554 | * struct hid_driver | ||
555 | * @name: driver name (e.g. "Footech_bar-wheel") | ||
556 | * @id_table: which devices is this driver for (must be non-NULL for probe | ||
557 | * to be called) | ||
558 | * @probe: new device inserted | ||
559 | * @remove: device removed (NULL if not a hot-plug capable driver) | ||
560 | * @report_table: on which reports to call raw_event (NULL means all) | ||
561 | * @raw_event: if report in report_table, this hook is called (NULL means nop) | ||
562 | * @usage_table: on which events to call event (NULL means all) | ||
563 | * @event: if usage in usage_table, this hook is called (NULL means nop) | ||
564 | * | ||
565 | * raw_event and event should return 0 on no action performed, 1 when no | ||
566 | * further processing should be done and negative on error | ||
567 | */ | ||
568 | struct hid_driver { | ||
569 | char *name; | ||
570 | const struct hid_device_id *id_table; | ||
571 | |||
572 | int (*probe)(struct hid_device *dev, const struct hid_device_id *id); | ||
573 | void (*remove)(struct hid_device *dev); | ||
574 | |||
575 | const struct hid_report_id *report_table; | ||
576 | int (*raw_event)(struct hid_device *hdev, struct hid_report *report, | ||
577 | u8 *data, int size); | ||
578 | const struct hid_usage_id *usage_table; | ||
579 | int (*event)(struct hid_device *hdev, struct hid_field *field, | ||
580 | struct hid_usage *usage, __s32 value); | ||
581 | /* private: */ | ||
582 | struct device_driver driver; | ||
583 | }; | ||
584 | |||
514 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ | 585 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ |
515 | /* We ignore a few input applications that are not widely used */ | 586 | /* We ignore a few input applications that are not widely used */ |
516 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) | 587 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001) || (a == 0x000d0002)) |
@@ -521,6 +592,17 @@ struct hid_descriptor { | |||
521 | extern int hid_debug; | 592 | extern int hid_debug; |
522 | #endif | 593 | #endif |
523 | 594 | ||
595 | extern int hid_add_device(struct hid_device *); | ||
596 | extern void hid_destroy_device(struct hid_device *); | ||
597 | |||
598 | extern int __must_check __hid_register_driver(struct hid_driver *, | ||
599 | struct module *, const char *mod_name); | ||
600 | static inline int __must_check hid_register_driver(struct hid_driver *driver) | ||
601 | { | ||
602 | return __hid_register_driver(driver, THIS_MODULE, KBUILD_MODNAME); | ||
603 | } | ||
604 | extern void hid_unregister_driver(struct hid_driver *); | ||
605 | |||
524 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | 606 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
525 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); | 607 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); |
526 | extern int hidinput_connect(struct hid_device *); | 608 | extern int hidinput_connect(struct hid_device *); |
@@ -533,8 +615,14 @@ int hidinput_mapping_quirks(struct hid_usage *, struct input_dev *, unsigned lon | |||
533 | int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | 615 | int hidinput_event_quirks(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); |
534 | int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); | 616 | int hidinput_apple_event(struct hid_device *, struct input_dev *, struct hid_usage *, __s32); |
535 | void hid_output_report(struct hid_report *report, __u8 *data); | 617 | void hid_output_report(struct hid_report *report, __u8 *data); |
536 | void hid_free_device(struct hid_device *device); | 618 | struct hid_device *hid_allocate_device(void); |
537 | struct hid_device *hid_parse_report(__u8 *start, unsigned size); | 619 | int hid_parse_report(struct hid_device *hid, __u8 *start, unsigned size); |
620 | |||
621 | void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, | ||
622 | int interrupt); | ||
623 | |||
624 | extern int hid_generic_init(void); | ||
625 | extern void hid_generic_exit(void); | ||
538 | 626 | ||
539 | /* HID quirks API */ | 627 | /* HID quirks API */ |
540 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); | 628 | u32 usbhid_lookup_quirk(const u16 idVendor, const u16 idProduct); |
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 96434d774c84..56a51f91591a 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -578,7 +578,7 @@ static int hidp_session(void *arg) | |||
578 | if (session->hid) { | 578 | if (session->hid) { |
579 | if (session->hid->claimed & HID_CLAIMED_INPUT) | 579 | if (session->hid->claimed & HID_CLAIMED_INPUT) |
580 | hidinput_disconnect(session->hid); | 580 | hidinput_disconnect(session->hid); |
581 | hid_free_device(session->hid); | 581 | hid_destroy_device(session->hid); |
582 | } | 582 | } |
583 | 583 | ||
584 | /* Wakeup user-space polling for socket errors */ | 584 | /* Wakeup user-space polling for socket errors */ |
@@ -698,12 +698,13 @@ static void hidp_setup_quirks(struct hid_device *hid) | |||
698 | hid->quirks = hidp_blacklist[n].quirks; | 698 | hid->quirks = hidp_blacklist[n].quirks; |
699 | } | 699 | } |
700 | 700 | ||
701 | static void hidp_setup_hid(struct hidp_session *session, | 701 | static int hidp_setup_hid(struct hidp_session *session, |
702 | struct hidp_connadd_req *req) | 702 | struct hidp_connadd_req *req) |
703 | { | 703 | { |
704 | struct hid_device *hid = session->hid; | 704 | struct hid_device *hid = session->hid; |
705 | struct hid_report *report; | 705 | struct hid_report *report; |
706 | bdaddr_t src, dst; | 706 | bdaddr_t src, dst; |
707 | int ret; | ||
707 | 708 | ||
708 | baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); | 709 | baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); |
709 | baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); | 710 | baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); |
@@ -721,7 +722,7 @@ static void hidp_setup_hid(struct hidp_session *session, | |||
721 | strncpy(hid->phys, batostr(&src), 64); | 722 | strncpy(hid->phys, batostr(&src), 64); |
722 | strncpy(hid->uniq, batostr(&dst), 64); | 723 | strncpy(hid->uniq, batostr(&dst), 64); |
723 | 724 | ||
724 | hid->dev = hidp_get_device(session); | 725 | hid->dev.parent = hidp_get_device(session); |
725 | 726 | ||
726 | hid->hid_open = hidp_open; | 727 | hid->hid_open = hidp_open; |
727 | hid->hid_close = hidp_close; | 728 | hid->hid_close = hidp_close; |
@@ -738,6 +739,15 @@ static void hidp_setup_hid(struct hidp_session *session, | |||
738 | 739 | ||
739 | if (hidinput_connect(hid) == 0) | 740 | if (hidinput_connect(hid) == 0) |
740 | hid->claimed |= HID_CLAIMED_INPUT; | 741 | hid->claimed |= HID_CLAIMED_INPUT; |
742 | |||
743 | ret = hid_add_device(hid); | ||
744 | if (ret) { | ||
745 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
746 | hidinput_disconnect(hid); | ||
747 | skb_queue_purge(&session->intr_transmit); | ||
748 | } | ||
749 | |||
750 | return ret; | ||
741 | } | 751 | } |
742 | 752 | ||
743 | int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) | 753 | int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) |
@@ -771,11 +781,19 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
771 | return -EFAULT; | 781 | return -EFAULT; |
772 | } | 782 | } |
773 | 783 | ||
774 | session->hid = hid_parse_report(buf, req->rd_size); | 784 | session->hid = hid_allocate_device(); |
785 | if (IS_ERR(session->hid)) { | ||
786 | kfree(buf); | ||
787 | kfree(session); | ||
788 | return PTR_ERR(session->hid); | ||
789 | } | ||
790 | |||
791 | err = hid_parse_report(session->hid, buf, req->rd_size); | ||
775 | 792 | ||
776 | kfree(buf); | 793 | kfree(buf); |
777 | 794 | ||
778 | if (!session->hid) { | 795 | if (err) { |
796 | hid_destroy_device(session->hid); | ||
779 | kfree(session); | 797 | kfree(session); |
780 | return -EINVAL; | 798 | return -EINVAL; |
781 | } | 799 | } |
@@ -822,8 +840,11 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
822 | goto failed; | 840 | goto failed; |
823 | } | 841 | } |
824 | 842 | ||
825 | if (session->hid) | 843 | if (session->hid) { |
826 | hidp_setup_hid(session, req); | 844 | err = hidp_setup_hid(session, req); |
845 | if (err) | ||
846 | goto failed; | ||
847 | } | ||
827 | 848 | ||
828 | __hidp_link_session(session); | 849 | __hidp_link_session(session); |
829 | 850 | ||
@@ -859,7 +880,7 @@ failed: | |||
859 | up_write(&hidp_session_sem); | 880 | up_write(&hidp_session_sem); |
860 | 881 | ||
861 | if (session->hid) | 882 | if (session->hid) |
862 | hid_free_device(session->hid); | 883 | hid_destroy_device(session->hid); |
863 | 884 | ||
864 | input_free_device(session->input); | 885 | input_free_device(session->input); |
865 | kfree(session); | 886 | kfree(session); |
@@ -950,18 +971,43 @@ int hidp_get_conninfo(struct hidp_conninfo *ci) | |||
950 | return err; | 971 | return err; |
951 | } | 972 | } |
952 | 973 | ||
974 | static const struct hid_device_id hidp_table[] = { | ||
975 | { HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) }, | ||
976 | { } | ||
977 | }; | ||
978 | |||
979 | static struct hid_driver hidp_driver = { | ||
980 | .name = "generic-bluetooth", | ||
981 | .id_table = hidp_table, | ||
982 | }; | ||
983 | |||
953 | static int __init hidp_init(void) | 984 | static int __init hidp_init(void) |
954 | { | 985 | { |
986 | int ret; | ||
987 | |||
955 | l2cap_load(); | 988 | l2cap_load(); |
956 | 989 | ||
957 | BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); | 990 | BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); |
958 | 991 | ||
959 | return hidp_init_sockets(); | 992 | ret = hid_register_driver(&hidp_driver); |
993 | if (ret) | ||
994 | goto err; | ||
995 | |||
996 | ret = hidp_init_sockets(); | ||
997 | if (ret) | ||
998 | goto err_drv; | ||
999 | |||
1000 | return 0; | ||
1001 | err_drv: | ||
1002 | hid_unregister_driver(&hidp_driver); | ||
1003 | err: | ||
1004 | return ret; | ||
960 | } | 1005 | } |
961 | 1006 | ||
962 | static void __exit hidp_exit(void) | 1007 | static void __exit hidp_exit(void) |
963 | { | 1008 | { |
964 | hidp_cleanup_sockets(); | 1009 | hidp_cleanup_sockets(); |
1010 | hid_unregister_driver(&hidp_driver); | ||
965 | } | 1011 | } |
966 | 1012 | ||
967 | module_init(hidp_init); | 1013 | module_init(hidp_init); |