diff options
| -rw-r--r-- | drivers/hid/hid-cherry.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-huion.c | 128 | ||||
| -rw-r--r-- | drivers/hid/hid-kye.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-lg.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-lg4ff.c | 4 | ||||
| -rw-r--r-- | drivers/hid/hid-logitech-dj.c | 15 | ||||
| -rw-r--r-- | drivers/hid/hid-monterey.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-petalynx.c | 2 | ||||
| -rw-r--r-- | drivers/hid/hid-rmi.c | 13 | ||||
| -rw-r--r-- | drivers/hid/hid-sensor-hub.c | 33 | ||||
| -rw-r--r-- | drivers/hid/hid-sunplus.c | 2 |
11 files changed, 114 insertions, 93 deletions
diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index 1bdcccc54a1d..f745d2c1325e 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c | |||
| @@ -28,7 +28,7 @@ | |||
| 28 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 28 | static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 29 | unsigned int *rsize) | 29 | unsigned int *rsize) |
| 30 | { | 30 | { |
| 31 | if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { | 31 | if (*rsize >= 18 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { |
| 32 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); | 32 | hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); |
| 33 | rdesc[11] = rdesc[16] = 0xff; | 33 | rdesc[11] = rdesc[16] = 0xff; |
| 34 | rdesc[12] = rdesc[17] = 0x03; | 34 | rdesc[12] = rdesc[17] = 0x03; |
diff --git a/drivers/hid/hid-huion.c b/drivers/hid/hid-huion.c index 60f44cd1b0ed..61b68ca27790 100644 --- a/drivers/hid/hid-huion.c +++ b/drivers/hid/hid-huion.c | |||
| @@ -84,6 +84,15 @@ static const __u8 huion_tablet_rdesc_template[] = { | |||
| 84 | 0xC0 /* End Collection */ | 84 | 0xC0 /* End Collection */ |
| 85 | }; | 85 | }; |
| 86 | 86 | ||
| 87 | /* Parameter indices */ | ||
| 88 | enum huion_prm { | ||
| 89 | HUION_PRM_X_LM = 1, | ||
| 90 | HUION_PRM_Y_LM = 2, | ||
| 91 | HUION_PRM_PRESSURE_LM = 4, | ||
| 92 | HUION_PRM_RESOLUTION = 5, | ||
| 93 | HUION_PRM_NUM | ||
| 94 | }; | ||
| 95 | |||
| 87 | /* Driver data */ | 96 | /* Driver data */ |
| 88 | struct huion_drvdata { | 97 | struct huion_drvdata { |
| 89 | __u8 *rdesc; | 98 | __u8 *rdesc; |
| @@ -115,7 +124,12 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
| 115 | int rc; | 124 | int rc; |
| 116 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); | 125 | struct usb_device *usb_dev = hid_to_usb_dev(hdev); |
| 117 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); | 126 | struct huion_drvdata *drvdata = hid_get_drvdata(hdev); |
| 118 | __le16 buf[6]; | 127 | __le16 *buf = NULL; |
| 128 | size_t len; | ||
| 129 | s32 params[HUION_PH_ID_NUM]; | ||
| 130 | s32 resolution; | ||
| 131 | __u8 *p; | ||
| 132 | s32 v; | ||
| 119 | 133 | ||
| 120 | /* | 134 | /* |
| 121 | * Read string descriptor containing tablet parameters. The specific | 135 | * Read string descriptor containing tablet parameters. The specific |
| @@ -123,65 +137,79 @@ static int huion_tablet_enable(struct hid_device *hdev) | |||
| 123 | * driver traffic. | 137 | * driver traffic. |
| 124 | * NOTE: This enables fully-functional tablet mode. | 138 | * NOTE: This enables fully-functional tablet mode. |
| 125 | */ | 139 | */ |
| 140 | len = HUION_PRM_NUM * sizeof(*buf); | ||
| 141 | buf = kmalloc(len, GFP_KERNEL); | ||
| 142 | if (buf == NULL) { | ||
| 143 | hid_err(hdev, "failed to allocate parameter buffer\n"); | ||
| 144 | rc = -ENOMEM; | ||
| 145 | goto cleanup; | ||
| 146 | } | ||
| 126 | rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), | 147 | rc = usb_control_msg(usb_dev, usb_rcvctrlpipe(usb_dev, 0), |
| 127 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 148 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
| 128 | (USB_DT_STRING << 8) + 0x64, | 149 | (USB_DT_STRING << 8) + 0x64, |
| 129 | 0x0409, buf, sizeof(buf), | 150 | 0x0409, buf, len, |
| 130 | USB_CTRL_GET_TIMEOUT); | 151 | USB_CTRL_GET_TIMEOUT); |
| 131 | if (rc == -EPIPE) | 152 | if (rc == -EPIPE) { |
| 132 | hid_warn(hdev, "device parameters not found\n"); | 153 | hid_err(hdev, "device parameters not found\n"); |
| 133 | else if (rc < 0) | 154 | rc = -ENODEV; |
| 134 | hid_warn(hdev, "failed to get device parameters: %d\n", rc); | 155 | goto cleanup; |
| 135 | else if (rc != sizeof(buf)) | 156 | } else if (rc < 0) { |
| 136 | hid_warn(hdev, "invalid device parameters\n"); | 157 | hid_err(hdev, "failed to get device parameters: %d\n", rc); |
| 137 | else { | 158 | rc = -ENODEV; |
| 138 | s32 params[HUION_PH_ID_NUM]; | 159 | goto cleanup; |
| 139 | s32 resolution; | 160 | } else if (rc != len) { |
| 140 | __u8 *p; | 161 | hid_err(hdev, "invalid device parameters\n"); |
| 141 | s32 v; | 162 | rc = -ENODEV; |
| 163 | goto cleanup; | ||
| 164 | } | ||
| 142 | 165 | ||
| 143 | /* Extract device parameters */ | 166 | /* Extract device parameters */ |
| 144 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[1]); | 167 | params[HUION_PH_ID_X_LM] = le16_to_cpu(buf[HUION_PRM_X_LM]); |
| 145 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[2]); | 168 | params[HUION_PH_ID_Y_LM] = le16_to_cpu(buf[HUION_PRM_Y_LM]); |
| 146 | params[HUION_PH_ID_PRESSURE_LM] = le16_to_cpu(buf[4]); | 169 | params[HUION_PH_ID_PRESSURE_LM] = |
| 147 | resolution = le16_to_cpu(buf[5]); | 170 | le16_to_cpu(buf[HUION_PRM_PRESSURE_LM]); |
| 148 | if (resolution == 0) { | 171 | resolution = le16_to_cpu(buf[HUION_PRM_RESOLUTION]); |
| 149 | params[HUION_PH_ID_X_PM] = 0; | 172 | if (resolution == 0) { |
| 150 | params[HUION_PH_ID_Y_PM] = 0; | 173 | params[HUION_PH_ID_X_PM] = 0; |
| 151 | } else { | 174 | params[HUION_PH_ID_Y_PM] = 0; |
| 152 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * | 175 | } else { |
| 153 | 1000 / resolution; | 176 | params[HUION_PH_ID_X_PM] = params[HUION_PH_ID_X_LM] * |
| 154 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * | 177 | 1000 / resolution; |
| 155 | 1000 / resolution; | 178 | params[HUION_PH_ID_Y_PM] = params[HUION_PH_ID_Y_LM] * |
| 156 | } | 179 | 1000 / resolution; |
| 180 | } | ||
| 157 | 181 | ||
| 158 | /* Allocate fixed report descriptor */ | 182 | /* Allocate fixed report descriptor */ |
| 159 | drvdata->rdesc = devm_kmalloc(&hdev->dev, | 183 | drvdata->rdesc = devm_kmalloc(&hdev->dev, |
| 160 | sizeof(huion_tablet_rdesc_template), | 184 | sizeof(huion_tablet_rdesc_template), |
| 161 | GFP_KERNEL); | 185 | GFP_KERNEL); |
| 162 | if (drvdata->rdesc == NULL) { | 186 | if (drvdata->rdesc == NULL) { |
| 163 | hid_err(hdev, "failed to allocate fixed rdesc\n"); | 187 | hid_err(hdev, "failed to allocate fixed rdesc\n"); |
| 164 | return -ENOMEM; | 188 | rc = -ENOMEM; |
| 165 | } | 189 | goto cleanup; |
| 166 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | 190 | } |
| 191 | drvdata->rsize = sizeof(huion_tablet_rdesc_template); | ||
| 167 | 192 | ||
| 168 | /* Format fixed report descriptor */ | 193 | /* Format fixed report descriptor */ |
| 169 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, | 194 | memcpy(drvdata->rdesc, huion_tablet_rdesc_template, |
| 170 | drvdata->rsize); | 195 | drvdata->rsize); |
| 171 | for (p = drvdata->rdesc; | 196 | for (p = drvdata->rdesc; |
| 172 | p <= drvdata->rdesc + drvdata->rsize - 4;) { | 197 | p <= drvdata->rdesc + drvdata->rsize - 4;) { |
| 173 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && | 198 | if (p[0] == 0xFE && p[1] == 0xED && p[2] == 0x1D && |
| 174 | p[3] < sizeof(params)) { | 199 | p[3] < sizeof(params)) { |
| 175 | v = params[p[3]]; | 200 | v = params[p[3]]; |
| 176 | put_unaligned(cpu_to_le32(v), (s32 *)p); | 201 | put_unaligned(cpu_to_le32(v), (s32 *)p); |
| 177 | p += 4; | 202 | p += 4; |
| 178 | } else { | 203 | } else { |
| 179 | p++; | 204 | p++; |
| 180 | } | ||
| 181 | } | 205 | } |
| 182 | } | 206 | } |
| 183 | 207 | ||
| 184 | return 0; | 208 | rc = 0; |
| 209 | |||
| 210 | cleanup: | ||
| 211 | kfree(buf); | ||
| 212 | return rc; | ||
| 185 | } | 213 | } |
| 186 | 214 | ||
| 187 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) | 215 | static int huion_probe(struct hid_device *hdev, const struct hid_device_id *id) |
diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index e77696367591..b92bf01a1ae8 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c | |||
| @@ -300,7 +300,7 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 300 | * - change the button usage range to 4-7 for the extra | 300 | * - change the button usage range to 4-7 for the extra |
| 301 | * buttons | 301 | * buttons |
| 302 | */ | 302 | */ |
| 303 | if (*rsize >= 74 && | 303 | if (*rsize >= 75 && |
| 304 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && | 304 | rdesc[61] == 0x05 && rdesc[62] == 0x08 && |
| 305 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && | 305 | rdesc[63] == 0x19 && rdesc[64] == 0x08 && |
| 306 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && | 306 | rdesc[65] == 0x29 && rdesc[66] == 0x0f && |
diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index a976f48263f6..f91ff145db9a 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c | |||
| @@ -345,14 +345,14 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, | |||
| 345 | struct usb_device_descriptor *udesc; | 345 | struct usb_device_descriptor *udesc; |
| 346 | __u16 bcdDevice, rev_maj, rev_min; | 346 | __u16 bcdDevice, rev_maj, rev_min; |
| 347 | 347 | ||
| 348 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && | 348 | if ((drv_data->quirks & LG_RDESC) && *rsize >= 91 && rdesc[83] == 0x26 && |
| 349 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { | 349 | rdesc[84] == 0x8c && rdesc[85] == 0x02) { |
| 350 | hid_info(hdev, | 350 | hid_info(hdev, |
| 351 | "fixing up Logitech keyboard report descriptor\n"); | 351 | "fixing up Logitech keyboard report descriptor\n"); |
| 352 | rdesc[84] = rdesc[89] = 0x4d; | 352 | rdesc[84] = rdesc[89] = 0x4d; |
| 353 | rdesc[85] = rdesc[90] = 0x10; | 353 | rdesc[85] = rdesc[90] = 0x10; |
| 354 | } | 354 | } |
| 355 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && | 355 | if ((drv_data->quirks & LG_RDESC_REL_ABS) && *rsize >= 51 && |
| 356 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && | 356 | rdesc[32] == 0x81 && rdesc[33] == 0x06 && |
| 357 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { | 357 | rdesc[49] == 0x81 && rdesc[50] == 0x06) { |
| 358 | hid_info(hdev, | 358 | hid_info(hdev, |
diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index cc2bd2022198..7835717bc020 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c | |||
| @@ -451,13 +451,13 @@ static ssize_t lg4ff_range_store(struct device *dev, struct device_attribute *at | |||
| 451 | drv_data = hid_get_drvdata(hid); | 451 | drv_data = hid_get_drvdata(hid); |
| 452 | if (!drv_data) { | 452 | if (!drv_data) { |
| 453 | hid_err(hid, "Private driver data not found!\n"); | 453 | hid_err(hid, "Private driver data not found!\n"); |
| 454 | return 0; | 454 | return -EINVAL; |
| 455 | } | 455 | } |
| 456 | 456 | ||
| 457 | entry = drv_data->device_props; | 457 | entry = drv_data->device_props; |
| 458 | if (!entry) { | 458 | if (!entry) { |
| 459 | hid_err(hid, "Device properties not found!\n"); | 459 | hid_err(hid, "Device properties not found!\n"); |
| 460 | return 0; | 460 | return -EINVAL; |
| 461 | } | 461 | } |
| 462 | 462 | ||
| 463 | if (range == 0) | 463 | if (range == 0) |
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 486dbde2ba2d..b7ba82960c79 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c | |||
| @@ -238,13 +238,6 @@ static void logi_dj_recv_add_djhid_device(struct dj_receiver_dev *djrcv_dev, | |||
| 238 | return; | 238 | return; |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
| 242 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
| 243 | dev_err(&djrcv_hdev->dev, "%s: invalid device index:%d\n", | ||
| 244 | __func__, dj_report->device_index); | ||
| 245 | return; | ||
| 246 | } | ||
| 247 | |||
| 248 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { | 241 | if (djrcv_dev->paired_dj_devices[dj_report->device_index]) { |
| 249 | /* The device is already known. No need to reallocate it. */ | 242 | /* The device is already known. No need to reallocate it. */ |
| 250 | dbg_hid("%s: device is already known\n", __func__); | 243 | dbg_hid("%s: device is already known\n", __func__); |
| @@ -557,7 +550,7 @@ static int logi_dj_ll_raw_request(struct hid_device *hid, | |||
| 557 | if (!out_buf) | 550 | if (!out_buf) |
| 558 | return -ENOMEM; | 551 | return -ENOMEM; |
| 559 | 552 | ||
| 560 | if (count < DJREPORT_SHORT_LENGTH - 2) | 553 | if (count > DJREPORT_SHORT_LENGTH - 2) |
| 561 | count = DJREPORT_SHORT_LENGTH - 2; | 554 | count = DJREPORT_SHORT_LENGTH - 2; |
| 562 | 555 | ||
| 563 | out_buf[0] = REPORT_ID_DJ_SHORT; | 556 | out_buf[0] = REPORT_ID_DJ_SHORT; |
| @@ -690,6 +683,12 @@ static int logi_dj_raw_event(struct hid_device *hdev, | |||
| 690 | * device (via hid_input_report() ) and return 1 so hid-core does not do | 683 | * device (via hid_input_report() ) and return 1 so hid-core does not do |
| 691 | * anything else with it. | 684 | * anything else with it. |
| 692 | */ | 685 | */ |
| 686 | if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || | ||
| 687 | (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { | ||
| 688 | dev_err(&hdev->dev, "%s: invalid device index:%d\n", | ||
| 689 | __func__, dj_report->device_index); | ||
| 690 | return false; | ||
| 691 | } | ||
| 693 | 692 | ||
| 694 | spin_lock_irqsave(&djrcv_dev->lock, flags); | 693 | spin_lock_irqsave(&djrcv_dev->lock, flags); |
| 695 | if (dj_report->report_id == REPORT_ID_DJ_SHORT) { | 694 | if (dj_report->report_id == REPORT_ID_DJ_SHORT) { |
diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c index 9e14c00eb1b6..25daf28b26bd 100644 --- a/drivers/hid/hid-monterey.c +++ b/drivers/hid/hid-monterey.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 24 | static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 25 | unsigned int *rsize) | 25 | unsigned int *rsize) |
| 26 | { | 26 | { |
| 27 | if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { | 27 | if (*rsize >= 31 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { |
| 28 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); | 28 | hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); |
| 29 | rdesc[30] = 0x0c; | 29 | rdesc[30] = 0x0c; |
| 30 | } | 30 | } |
diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 736b2502df4f..6aca4f2554bf 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c | |||
| @@ -25,7 +25,7 @@ | |||
| 25 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 25 | static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 26 | unsigned int *rsize) | 26 | unsigned int *rsize) |
| 27 | { | 27 | { |
| 28 | if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && | 28 | if (*rsize >= 62 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && |
| 29 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && | 29 | rdesc[41] == 0x00 && rdesc[59] == 0x26 && |
| 30 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { | 30 | rdesc[60] == 0xf9 && rdesc[61] == 0x00) { |
| 31 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); | 31 | hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); |
diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c index 0dc25142f451..8389e8109218 100644 --- a/drivers/hid/hid-rmi.c +++ b/drivers/hid/hid-rmi.c | |||
| @@ -909,10 +909,15 @@ static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) | |||
| 909 | return ret; | 909 | return ret; |
| 910 | } | 910 | } |
| 911 | 911 | ||
| 912 | if (!test_bit(RMI_STARTED, &data->flags)) { | 912 | if (!test_bit(RMI_STARTED, &data->flags)) |
| 913 | hid_hw_stop(hdev); | 913 | /* |
| 914 | return -EIO; | 914 | * The device maybe in the bootloader if rmi_input_configured |
| 915 | } | 915 | * failed to find F11 in the PDT. Print an error, but don't |
| 916 | * return an error from rmi_probe so that hidraw will be | ||
| 917 | * accessible from userspace. That way a userspace tool | ||
| 918 | * can be used to reload working firmware on the touchpad. | ||
| 919 | */ | ||
| 920 | hid_err(hdev, "Device failed to be properly configured\n"); | ||
| 916 | 921 | ||
| 917 | return 0; | 922 | return 0; |
| 918 | } | 923 | } |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index e244e449cbba..2ac25760a9a9 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
| @@ -604,9 +604,9 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 604 | ret = -EINVAL; | 604 | ret = -EINVAL; |
| 605 | goto err_stop_hw; | 605 | goto err_stop_hw; |
| 606 | } | 606 | } |
| 607 | sd->hid_sensor_hub_client_devs = kzalloc(dev_cnt * | 607 | sd->hid_sensor_hub_client_devs = devm_kzalloc(&hdev->dev, dev_cnt * |
| 608 | sizeof(struct mfd_cell), | 608 | sizeof(struct mfd_cell), |
| 609 | GFP_KERNEL); | 609 | GFP_KERNEL); |
| 610 | if (sd->hid_sensor_hub_client_devs == NULL) { | 610 | if (sd->hid_sensor_hub_client_devs == NULL) { |
| 611 | hid_err(hdev, "Failed to allocate memory for mfd cells\n"); | 611 | hid_err(hdev, "Failed to allocate memory for mfd cells\n"); |
| 612 | ret = -ENOMEM; | 612 | ret = -ENOMEM; |
| @@ -618,11 +618,12 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 618 | 618 | ||
| 619 | if (collection->type == HID_COLLECTION_PHYSICAL) { | 619 | if (collection->type == HID_COLLECTION_PHYSICAL) { |
| 620 | 620 | ||
| 621 | hsdev = kzalloc(sizeof(*hsdev), GFP_KERNEL); | 621 | hsdev = devm_kzalloc(&hdev->dev, sizeof(*hsdev), |
| 622 | GFP_KERNEL); | ||
| 622 | if (!hsdev) { | 623 | if (!hsdev) { |
| 623 | hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); | 624 | hid_err(hdev, "cannot allocate hid_sensor_hub_device\n"); |
| 624 | ret = -ENOMEM; | 625 | ret = -ENOMEM; |
| 625 | goto err_no_mem; | 626 | goto err_stop_hw; |
| 626 | } | 627 | } |
| 627 | hsdev->hdev = hdev; | 628 | hsdev->hdev = hdev; |
| 628 | hsdev->vendor_id = hdev->vendor; | 629 | hsdev->vendor_id = hdev->vendor; |
| @@ -631,13 +632,13 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 631 | if (last_hsdev) | 632 | if (last_hsdev) |
| 632 | last_hsdev->end_collection_index = i; | 633 | last_hsdev->end_collection_index = i; |
| 633 | last_hsdev = hsdev; | 634 | last_hsdev = hsdev; |
| 634 | name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", | 635 | name = devm_kasprintf(&hdev->dev, GFP_KERNEL, |
| 635 | collection->usage); | 636 | "HID-SENSOR-%x", |
| 637 | collection->usage); | ||
| 636 | if (name == NULL) { | 638 | if (name == NULL) { |
| 637 | hid_err(hdev, "Failed MFD device name\n"); | 639 | hid_err(hdev, "Failed MFD device name\n"); |
| 638 | ret = -ENOMEM; | 640 | ret = -ENOMEM; |
| 639 | kfree(hsdev); | 641 | goto err_stop_hw; |
| 640 | goto err_no_mem; | ||
| 641 | } | 642 | } |
| 642 | sd->hid_sensor_hub_client_devs[ | 643 | sd->hid_sensor_hub_client_devs[ |
| 643 | sd->hid_sensor_client_cnt].id = | 644 | sd->hid_sensor_client_cnt].id = |
| @@ -661,16 +662,10 @@ static int sensor_hub_probe(struct hid_device *hdev, | |||
| 661 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, | 662 | ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, |
| 662 | sd->hid_sensor_client_cnt, NULL, 0, NULL); | 663 | sd->hid_sensor_client_cnt, NULL, 0, NULL); |
| 663 | if (ret < 0) | 664 | if (ret < 0) |
| 664 | goto err_no_mem; | 665 | goto err_stop_hw; |
| 665 | 666 | ||
| 666 | return ret; | 667 | return ret; |
| 667 | 668 | ||
| 668 | err_no_mem: | ||
| 669 | for (i = 0; i < sd->hid_sensor_client_cnt; ++i) { | ||
| 670 | kfree(sd->hid_sensor_hub_client_devs[i].name); | ||
| 671 | kfree(sd->hid_sensor_hub_client_devs[i].platform_data); | ||
| 672 | } | ||
| 673 | kfree(sd->hid_sensor_hub_client_devs); | ||
| 674 | err_stop_hw: | 669 | err_stop_hw: |
| 675 | hid_hw_stop(hdev); | 670 | hid_hw_stop(hdev); |
| 676 | 671 | ||
| @@ -681,7 +676,6 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 681 | { | 676 | { |
| 682 | struct sensor_hub_data *data = hid_get_drvdata(hdev); | 677 | struct sensor_hub_data *data = hid_get_drvdata(hdev); |
| 683 | unsigned long flags; | 678 | unsigned long flags; |
| 684 | int i; | ||
| 685 | 679 | ||
| 686 | hid_dbg(hdev, " hardware removed\n"); | 680 | hid_dbg(hdev, " hardware removed\n"); |
| 687 | hid_hw_close(hdev); | 681 | hid_hw_close(hdev); |
| @@ -691,11 +685,6 @@ static void sensor_hub_remove(struct hid_device *hdev) | |||
| 691 | complete(&data->pending.ready); | 685 | complete(&data->pending.ready); |
| 692 | spin_unlock_irqrestore(&data->lock, flags); | 686 | spin_unlock_irqrestore(&data->lock, flags); |
| 693 | mfd_remove_devices(&hdev->dev); | 687 | mfd_remove_devices(&hdev->dev); |
| 694 | for (i = 0; i < data->hid_sensor_client_cnt; ++i) { | ||
| 695 | kfree(data->hid_sensor_hub_client_devs[i].name); | ||
| 696 | kfree(data->hid_sensor_hub_client_devs[i].platform_data); | ||
| 697 | } | ||
| 698 | kfree(data->hid_sensor_hub_client_devs); | ||
| 699 | hid_set_drvdata(hdev, NULL); | 688 | hid_set_drvdata(hdev, NULL); |
| 700 | mutex_destroy(&data->mutex); | 689 | mutex_destroy(&data->mutex); |
| 701 | } | 690 | } |
diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c index 87fc91e1c8de..91072fa54663 100644 --- a/drivers/hid/hid-sunplus.c +++ b/drivers/hid/hid-sunplus.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, | 24 | static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
| 25 | unsigned int *rsize) | 25 | unsigned int *rsize) |
| 26 | { | 26 | { |
| 27 | if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && | 27 | if (*rsize >= 112 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && |
| 28 | rdesc[106] == 0x03) { | 28 | rdesc[106] == 0x03) { |
| 29 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); | 29 | hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); |
| 30 | rdesc[105] = rdesc[110] = 0x03; | 30 | rdesc[105] = rdesc[110] = 0x03; |
