Re: [PATCH RESEND] HID: winwing: Enable rumble effects

From: Dan Carpenter

Date: Thu Feb 12 2026 - 00:31:29 EST


Hi Ivan,

kernel test robot noticed the following build warnings:

https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Ivan-Gorinov/HID-winwing-Enable-rumble-effects/20260211-133322
base: https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link: https://lore.kernel.org/r/20260211053116.GA20357%40altimeter-info
patch subject: [PATCH RESEND] HID: winwing: Enable rumble effects
config: parisc-randconfig-r071-20260211 (https://download.01.org/0day-ci/archive/20260212/202602120209.xYKh9QQp-lkp@xxxxxxxxx/config)
compiler: hppa-linux-gcc (GCC) 8.5.0
smatch version: v0.5.0-8994-gd50c5a4c

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
| Closes: https://lore.kernel.org/r/202602120209.xYKh9QQp-lkp@xxxxxxxxx/

smatch warnings:
drivers/hid/hid-winwing.c:235 winwing_haptic_rumble() warn: address of NULL pointer 'data->hdev'
drivers/hid/hid-winwing.c:308 winwing_haptic_rumble_cb() warn: can 'data' even be NULL?
drivers/hid/hid-winwing.c:339 winwing_init_ff() warn: variable dereferenced before check 'data' (see line 333)

vim +235 drivers/hid/hid-winwing.c

c4c97b07cd09c03 Ivan Gorinov 2026-02-11 221 static int winwing_haptic_rumble(struct winwing_drv_data *data)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 222 {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 223 __u8 *buf;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 224 __u8 m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 225
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 226 if (!data)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 227 return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 228
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 229 buf = data->report_rumble;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 230
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 231 if (!buf)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 232 return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 233
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 234 if (!data->hdev) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @235 hid_err(data->hdev, "data->hdev == NULL\n");
^^^^^^^^^^
This doesn't end up getting dereferenced because of dev_err() magic
but passing a NULL here is pointless.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11 236 return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 237 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 238
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 239 if (!data->hdev->ll_driver) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 240 hid_err(data->hdev, "data->hdev->ll_driver == NULL\n");
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 241 return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 242 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 243
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 244 m = convert_magnitude(data->rumble.strong_magnitude);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 245 if (m != data->rumble_left) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 246 int ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 247
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 248 buf[0] = 0x02;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 249 buf[1] = 0x01;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 250 buf[2] = 0xbf;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 251 buf[3] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 252 buf[4] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 253 buf[5] = 0x03;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 254 buf[6] = 0x49;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 255 buf[7] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 256 buf[8] = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 257 buf[9] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 258 buf[10] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 259 buf[11] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 260 buf[12] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 261 buf[13] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 262
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 263 ret = hid_hw_output_report(data->hdev, buf, 14);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 264 if (ret < 0) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 265 hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 266 return ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 267 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 268 data->rumble_left = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 269 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 270
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 271 m = convert_magnitude(data->rumble.weak_magnitude);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 272 if (m != data->rumble_right) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 273 int ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 274
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 275 buf[0] = 0x02;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 276 buf[1] = 0x03;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 277 buf[2] = 0xbf;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 278 buf[3] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 279 buf[4] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 280 buf[5] = 0x03;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 281 buf[6] = 0x49;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 282 buf[7] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 283 buf[8] = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 284 buf[9] = 0x00;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 285 buf[10] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 286 buf[11] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 287 buf[12] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 288 buf[13] = 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 289
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 290 ret = hid_hw_output_report(data->hdev, buf, 14);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 291 if (ret < 0) {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 292 hid_err(data->hdev, "error %d (%*ph)\n", ret, 14, buf);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 293 return ret;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 294 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 295 data->rumble_right = m;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 296 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 297
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 298 return 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 299 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 300
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 301
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 302 static void winwing_haptic_rumble_cb(struct work_struct *work)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 303 {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 304 struct winwing_drv_data *data;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 305
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 306 data = container_of(work, struct winwing_drv_data, rumble_work);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 307
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @308 if (data)

"data" can't be NULL. It's work minus an offset.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11 309 winwing_haptic_rumble(data);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 310 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 311
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 312 static int winwing_play_effect(struct input_dev *dev, void *context,
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 313 struct ff_effect *effect)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 314 {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 315 struct winwing_drv_data *data = (struct winwing_drv_data *) context;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 316
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 317 if (effect->type != FF_RUMBLE)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 318 return 0;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 319
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 320 if (!data)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 321 return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 322
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 323 data->rumble = effect->u.rumble;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 324
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 325 return schedule_work(&data->rumble_work);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 326 }
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 327
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 328 static int winwing_init_ff(struct hid_device *hdev, struct hid_input *hidinput)
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 329 {
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 330 struct winwing_drv_data *data;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 331
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 332 data = (struct winwing_drv_data *) hid_get_drvdata(hdev);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @333 data->report_rumble = devm_kzalloc(&hdev->dev, MAX_REPORT, GFP_KERNEL);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 334 data->rumble_left = -1;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 335 data->rumble_right = -1;
^^^^^^^^^^^^^^^^^^
Dereferences here.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11 336
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 337 input_set_capability(hidinput->input, EV_FF, FF_RUMBLE);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 338
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 @339 if (!data)
^^^^^^
Checked too late.

c4c97b07cd09c03 Ivan Gorinov 2026-02-11 340 return -EINVAL;
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 341
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 342 return input_ff_create_memless(hidinput->input, data,
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 343 winwing_play_effect);
c4c97b07cd09c03 Ivan Gorinov 2026-02-11 344 }

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki