Messages in this thread | | | From | Chris Wulff <> | Subject | [PATCH v2 0/1] USB: gadget: f_hid: Add GET_REPORT via userspace IOCTL | Date | Wed, 17 Apr 2024 18:26:52 +0000 |
| |
This patch has been cleaned up with suggestions from Greg KH (https://lore.kernel.org/lkml/Y+4Wwm1kFTUEED89@kroah.com/T/#r12e1bcf3ec45e19d7e2247f7070faac19e0fb60d)
Additional changes since v1: * Fixes race conditions during gadget unbind * 32/64 bit compatibility fixes (compat ioctl and uapi structure padding)
Additional testing has also been done on Zynq UltraScale+ with the DWC3 driver.
Example userspace code to respond to GET_REPORT --- #include <stdint.h> #include <poll.h> #include <linux/usb/g_hid.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h>
void handleGetReport(int hidgfd) { uint8_t reportId = 0; int ret = ioctl(hidgfd, GADGET_HID_READ_GET_REPORT_ID, &reportId); if (ret >= 0 && reportId > 0) { struct usb_hidg_report report = {}; report.report_id = reportId; report.userspace_req = 1; report.length = 0;
switch (reportId) { case 0x01: // report 0x01 requested report.length = 2; report.data[0] = reportId, // Report ID report.data[1] = 0x00; // Report Data break;
default: // Unknown report (return empty report so the host doesn't have to wait for the timeout) break; }
ioctl(hidgfd, GADGET_HID_WRITE_GET_REPORT, &report); } }
int main(int argc, char **argv) {
int hidgfd = open("/dev/hidg0", O_RDWR | O_NONBLOCK); if (hidgfd < 0) { return -1; }
struct pollfd fdset[1];
fdset[0].fd = hidgfd; fdset[0].events = POLLIN | POLLPRI;
int running = 1; while (running) { int rc, fd;
fdset[0].revents = 0;
rc = poll(fdset, 1, 1000); // Wait up to a second
if (rc > 0) { if (fdset[0].revents & POLLPRI) { // Process Get Report handleGetReport(hidgfd); }
/* POLLIN can be processed here for output reports */ } }
close(hidgfd);
return 0; }
| |