Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/hid: allow to parametrize bus/vid/pid/rdesc on the test device

This will be useful to introduce variants in tests to test the
interactions between HID-BPF and some kernel modules.

Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Acked-by: Shuah Khan <skhan@linuxfoundation.org>
Link: https://patch.msgid.link/20241001-hid-bpf-hid-generic-v3-7-2ef1019468df@kernel.org
Signed-off-by: Benjamin Tissoires <bentiss@kernel.org>

+31 -19
+1 -1
tools/testing/selftests/hid/hid_bpf.c
··· 58 58 { 59 59 int err; 60 60 61 - err = setup_uhid(_metadata, &self->hid); 61 + err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a36, rdesc, sizeof(rdesc)); 62 62 ASSERT_OK(err); 63 63 } 64 64
+29 -17
tools/testing/selftests/hid/hid_common.h
··· 23 23 int dev_id; /* uniq (random) number to identify the device */ 24 24 int uhid_fd; 25 25 int hid_id; /* HID device id in the system */ 26 + __u16 bus; 27 + __u32 vid; 28 + __u32 pid; 26 29 pthread_t tid; /* thread for reading uhid events */ 27 30 }; 28 31 ··· 132 129 } 133 130 } 134 131 135 - static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb) 132 + static int uhid_create(struct __test_metadata *_metadata, int fd, int rand_nb, 133 + __u16 bus, __u32 vid, __u32 pid, __u8 *rdesc, 134 + size_t rdesc_size) 136 135 { 137 136 struct uhid_event ev; 138 137 char buf[25]; ··· 145 140 ev.type = UHID_CREATE; 146 141 strcpy((char *)ev.u.create.name, buf); 147 142 ev.u.create.rd_data = rdesc; 148 - ev.u.create.rd_size = sizeof(rdesc); 149 - ev.u.create.bus = BUS_USB; 150 - ev.u.create.vendor = 0x0001; 151 - ev.u.create.product = 0x0a37; 143 + ev.u.create.rd_size = rdesc_size; 144 + ev.u.create.bus = bus; 145 + ev.u.create.vendor = vid; 146 + ev.u.create.product = pid; 152 147 ev.u.create.version = 0; 153 148 ev.u.create.country = 0; 154 149 ··· 310 305 return uhid_write(_metadata, hid->uhid_fd, &ev); 311 306 } 312 307 313 - static bool match_sysfs_device(int dev_id, const char *workdir, struct dirent *dir) 308 + static bool match_sysfs_device(struct uhid_device *hid, const char *workdir, struct dirent *dir) 314 309 { 315 - const char *target = "0003:0001:0A37.*"; 310 + char target[20] = ""; 316 311 char phys[512]; 317 312 char uevent[1024]; 318 313 char temp[512]; 319 314 int fd, nread; 320 315 bool found = false; 316 + 317 + snprintf(target, sizeof(target), "%04X:%04X:%04X.*", hid->bus, hid->vid, hid->pid); 321 318 322 319 if (fnmatch(target, dir->d_name, 0)) 323 320 return false; ··· 331 324 if (fd < 0) 332 325 return false; 333 326 334 - sprintf(phys, "PHYS=%d", dev_id); 327 + sprintf(phys, "PHYS=%d", hid->dev_id); 335 328 336 329 nread = read(fd, temp, ARRAY_SIZE(temp)); 337 330 if (nread > 0 && (strstr(temp, phys)) != NULL) ··· 342 335 return found; 343 336 } 344 337 345 - static int get_hid_id(int dev_id) 338 + static int get_hid_id(struct uhid_device *hid) 346 339 { 347 340 const char *workdir = "/sys/devices/virtual/misc/uhid"; 348 341 const char *str_id; ··· 357 350 d = opendir(workdir); 358 351 if (d) { 359 352 while ((dir = readdir(d)) != NULL) { 360 - if (!match_sysfs_device(dev_id, workdir, dir)) 353 + if (!match_sysfs_device(hid, workdir, dir)) 361 354 continue; 362 355 363 - str_id = dir->d_name + sizeof("0003:0001:0A37."); 356 + str_id = dir->d_name + sizeof("0000:0000:0000."); 364 357 found = (int)strtol(str_id, NULL, 16); 365 358 366 359 break; ··· 374 367 return found; 375 368 } 376 369 377 - static int get_hidraw(int dev_id) 370 + static int get_hidraw(struct uhid_device *hid) 378 371 { 379 372 const char *workdir = "/sys/devices/virtual/misc/uhid"; 380 373 char sysfs[1024]; ··· 391 384 continue; 392 385 393 386 while ((dir = readdir(d)) != NULL) { 394 - if (!match_sysfs_device(dev_id, workdir, dir)) 387 + if (!match_sysfs_device(hid, workdir, dir)) 395 388 continue; 396 389 397 390 sprintf(sysfs, "%s/%s/hidraw", workdir, dir->d_name); ··· 423 416 int hidraw_number; 424 417 char hidraw_path[64] = { 0 }; 425 418 426 - hidraw_number = get_hidraw(hid->dev_id); 419 + hidraw_number = get_hidraw(hid); 427 420 if (hidraw_number < 0) 428 421 return hidraw_number; 429 422 ··· 432 425 return open(hidraw_path, O_RDWR | O_NONBLOCK); 433 426 } 434 427 435 - static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid) 428 + static int setup_uhid(struct __test_metadata *_metadata, struct uhid_device *hid, 429 + __u16 bus, __u32 vid, __u32 pid, const __u8 *rdesc, size_t rdesc_size) 436 430 { 437 431 const char *path = "/dev/uhid"; 438 432 time_t t; ··· 443 435 srand((unsigned int)time(&t)); 444 436 445 437 hid->dev_id = rand() % 1024; 438 + hid->bus = bus; 439 + hid->vid = vid; 440 + hid->pid = pid; 446 441 447 442 hid->uhid_fd = open(path, O_RDWR | O_CLOEXEC); 448 443 ASSERT_GE(hid->uhid_fd, 0) TH_LOG("open uhid-cdev failed; %d", hid->uhid_fd); 449 444 450 - ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id); 445 + ret = uhid_create(_metadata, hid->uhid_fd, hid->dev_id, bus, vid, pid, 446 + (__u8 *)rdesc, rdesc_size); 451 447 ASSERT_EQ(0, ret) { 452 448 TH_LOG("create uhid device failed: %d", ret); 453 449 close(hid->uhid_fd); ··· 459 447 } 460 448 461 449 /* locate the uevent file of the created device */ 462 - hid->hid_id = get_hid_id(hid->dev_id); 450 + hid->hid_id = get_hid_id(hid); 463 451 ASSERT_GT(hid->hid_id, 0) 464 452 TH_LOG("Could not locate uhid device id: %d", hid->hid_id); 465 453
+1 -1
tools/testing/selftests/hid/hidraw.c
··· 36 36 { 37 37 int err; 38 38 39 - err = setup_uhid(_metadata, &self->hid); 39 + err = setup_uhid(_metadata, &self->hid, BUS_USB, 0x0001, 0x0a37, rdesc, sizeof(rdesc)); 40 40 ASSERT_OK(err); 41 41 42 42 self->hidraw_fd = open_hidraw(&self->hid);