unix: add HIDRAW ioctls This change adds (most) of the ioctl API for the Linux HIDRAW interface. Reading and writing non-numbered HID reports is done using the read and write system calls respectively. Some of the HIDIOC* request numbers are exported directly while others are kept unexported. This is because some of the #defines require a len attribute that doesn't have a specific well defined value. Wrapper types are added for most of the request numbers as is standard. No wrapper is added for HIDIOCGRDESCSIZE as it would just be IoctlGetUint32. The HIDIOC[GS]FEATURE, HIDIOC[GS]INPUT and HIDIOC[GS]OUTPUT request numbers, which are required for numbered HID reports, are entirely ommitted as the len attribute has to be a runtime variable. These could be added later by doing something like `HIDIOCGFEATURE(0) | (len << _IOC_SIZESHIFT)`, with care taken that len doesn't overflow _IOC_XSIZEMASK. Outdated documentation for the HIDRAW interface is available at: https://www.kernel.org/doc/Documentation/hid/hidraw.txt. Change-Id: I2ae5060f0f46150f6fb52959c2e55f50927c1f69 Reviewed-on: https://go-review.googlesource.com/c/sys/+/289169 Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org>
diff --git a/unix/linux/types.go b/unix/linux/types.go index 3e5f1ea..ab2be60 100644 --- a/unix/linux/types.go +++ b/unix/linux/types.go
@@ -96,6 +96,7 @@ #include <linux/fsverity.h> #include <linux/genetlink.h> #include <linux/hdreg.h> +#include <linux/hidraw.h> #include <linux/icmpv6.h> #include <linux/if_alg.h> #include <linux/if_bridge.h> @@ -3633,3 +3634,8 @@ ETHTOOL_A_TUNNEL_INFO_UDP_PORTS = C.ETHTOOL_A_TUNNEL_INFO_UDP_PORTS ETHTOOL_A_TUNNEL_INFO_MAX = C.ETHTOOL_A_TUNNEL_INFO_MAX ) + +type ( + HIDRawReportDescriptor C.struct_hidraw_report_descriptor + HIDRawDevInfo C.struct_hidraw_devinfo +)
diff --git a/unix/mkerrors.sh b/unix/mkerrors.sh index ca98cb4..809ab06 100755 --- a/unix/mkerrors.sh +++ b/unix/mkerrors.sh
@@ -214,6 +214,7 @@ #include <linux/fsverity.h> #include <linux/genetlink.h> #include <linux/hdreg.h> +#include <linux/hidraw.h> #include <linux/icmpv6.h> #include <linux/if.h> #include <linux/if_addr.h> @@ -224,6 +225,7 @@ #include <linux/if_tun.h> #include <linux/if_packet.h> #include <linux/if_xdp.h> +#include <linux/input.h> #include <linux/kexec.h> #include <linux/keyctl.h> #include <linux/loop.h> @@ -300,6 +302,17 @@ // Including linux/l2tp.h here causes conflicts between linux/in.h // and netinet/in.h included via net/route.h above. #define IPPROTO_L2TP 115 + +// Copied from linux/hid.h. +// Keep in sync with the size of the referenced fields. +#define _HIDIOCGRAWNAME_LEN 128 // sizeof_field(struct hid_device, name) +#define _HIDIOCGRAWPHYS_LEN 64 // sizeof_field(struct hid_device, phys) +#define _HIDIOCGRAWUNIQ_LEN 64 // sizeof_field(struct hid_device, uniq) + +#define _HIDIOCGRAWNAME HIDIOCGRAWNAME(_HIDIOCGRAWNAME_LEN) +#define _HIDIOCGRAWPHYS HIDIOCGRAWPHYS(_HIDIOCGRAWPHYS_LEN) +#define _HIDIOCGRAWUNIQ HIDIOCGRAWUNIQ(_HIDIOCGRAWUNIQ_LEN) + ' includes_NetBSD=' @@ -447,6 +460,8 @@ $2 !~ /^EPROC_/ && $2 !~ /^EQUIV_/ && $2 !~ /^EXPR_/ && + $2 !~ /^EVIOC/ && + $2 !~ /^EV_/ && $2 ~ /^E[A-Z0-9_]+$/ || $2 ~ /^B[0-9_]+$/ || $2 ~ /^(OLD|NEW)DEV$/ || @@ -481,7 +496,7 @@ $2 ~ /^LOCK_(SH|EX|NB|UN)$/ || $2 ~ /^LO_(KEY|NAME)_SIZE$/ || $2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ || - $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|EV|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ || + $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ || $2 ~ /^TP_STATUS_/ || $2 ~ /^FALLOC_/ || $2 == "ICMPV6_FILTER" || @@ -571,6 +586,9 @@ $2 ~ /^W[A-Z0-9]+$/ || $2 ~/^PPPIOC/ || $2 ~ /^FAN_|FANOTIFY_/ || + $2 == "HID_MAX_DESCRIPTOR_SIZE" || + $2 ~ /^_?HIDIOC/ || + $2 ~ /^BUS_(USB|HIL|BLUETOOTH|VIRTUAL)$/ || $2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)} $2 ~ /^__WCOREFLAG$/ {next} $2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
diff --git a/unix/syscall_linux.go b/unix/syscall_linux.go index 1b21035..ad49b27 100644 --- a/unix/syscall_linux.go +++ b/unix/syscall_linux.go
@@ -153,6 +153,36 @@ return ioctl(fd, WDIOC_KEEPALIVE, 0) } +func IoctlHIDGetDesc(fd int, value *HIDRawReportDescriptor) error { + err := ioctl(fd, HIDIOCGRDESC, uintptr(unsafe.Pointer(value))) + runtime.KeepAlive(value) + return err +} + +func IoctlHIDGetRawInfo(fd int) (*HIDRawDevInfo, error) { + var value HIDRawDevInfo + err := ioctl(fd, HIDIOCGRAWINFO, uintptr(unsafe.Pointer(&value))) + return &value, err +} + +func IoctlHIDGetRawName(fd int) (string, error) { + var value [_HIDIOCGRAWNAME_LEN]byte + err := ioctl(fd, _HIDIOCGRAWNAME, uintptr(unsafe.Pointer(&value[0]))) + return ByteSliceToString(value[:]), err +} + +func IoctlHIDGetRawPhys(fd int) (string, error) { + var value [_HIDIOCGRAWPHYS_LEN]byte + err := ioctl(fd, _HIDIOCGRAWPHYS, uintptr(unsafe.Pointer(&value[0]))) + return ByteSliceToString(value[:]), err +} + +func IoctlHIDGetRawUniq(fd int) (string, error) { + var value [_HIDIOCGRAWUNIQ_LEN]byte + err := ioctl(fd, _HIDIOCGRAWUNIQ, uintptr(unsafe.Pointer(&value[0]))) + return ByteSliceToString(value[:]), err +} + //sys Linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) {
diff --git a/unix/zerrors_linux.go b/unix/zerrors_linux.go index 14fb7a9..504dd6c 100644 --- a/unix/zerrors_linux.go +++ b/unix/zerrors_linux.go
@@ -245,6 +245,10 @@ BS0 = 0x0 BTRFS_SUPER_MAGIC = 0x9123683e BTRFS_TEST_MAGIC = 0x73727279 + BUS_BLUETOOTH = 0x5 + BUS_HIL = 0x4 + BUS_USB = 0x3 + BUS_VIRTUAL = 0x6 CAN_BCM = 0x2 CAN_EFF_FLAG = 0x80000000 CAN_EFF_ID_BITS = 0x1d @@ -964,6 +968,7 @@ HDIO_SET_XFER = 0x306 HDIO_TRISTATE_HWIF = 0x31b HDIO_UNREGISTER_HWIF = 0x32a + HID_MAX_DESCRIPTOR_SIZE = 0x1000 HOSTFS_SUPER_MAGIC = 0xc0ffee HPFS_SUPER_MAGIC = 0xf995e849 HUGETLBFS_MAGIC = 0x958458f6 @@ -2736,6 +2741,9 @@ Z3FOLD_MAGIC = 0x33 ZONEFS_MAGIC = 0x5a4f4653 ZSMALLOC_MAGIC = 0x58295829 + _HIDIOCGRAWNAME_LEN = 0x80 + _HIDIOCGRAWPHYS_LEN = 0x40 + _HIDIOCGRAWUNIQ_LEN = 0x40 ) // Errors
diff --git a/unix/zerrors_linux_386.go b/unix/zerrors_linux_386.go index 59c0765..e91a1a9 100644 --- a/unix/zerrors_linux_386.go +++ b/unix/zerrors_linux_386.go
@@ -94,6 +94,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x80084803 + HIDIOCGRDESC = 0x90044802 + HIDIOCGRDESCSIZE = 0x80044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -486,6 +489,9 @@ X86_FXSR_MAGIC = 0x0 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x80804804 + _HIDIOCGRAWPHYS = 0x80404805 + _HIDIOCGRAWUNIQ = 0x80404808 ) // Errors
diff --git a/unix/zerrors_linux_amd64.go b/unix/zerrors_linux_amd64.go index 0f2a91b..a9cbac6 100644 --- a/unix/zerrors_linux_amd64.go +++ b/unix/zerrors_linux_amd64.go
@@ -94,6 +94,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x80084803 + HIDIOCGRDESC = 0x90044802 + HIDIOCGRDESCSIZE = 0x80044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -486,6 +489,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x80804804 + _HIDIOCGRAWPHYS = 0x80404805 + _HIDIOCGRAWUNIQ = 0x80404808 ) // Errors
diff --git a/unix/zerrors_linux_arm.go b/unix/zerrors_linux_arm.go index fb06da7..d74f3c1 100644 --- a/unix/zerrors_linux_arm.go +++ b/unix/zerrors_linux_arm.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x80084803 + HIDIOCGRDESC = 0x90044802 + HIDIOCGRDESCSIZE = 0x80044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -492,6 +495,9 @@ WORDSIZE = 0x20 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x80804804 + _HIDIOCGRAWPHYS = 0x80404805 + _HIDIOCGRAWUNIQ = 0x80404808 ) // Errors
diff --git a/unix/zerrors_linux_arm64.go b/unix/zerrors_linux_arm64.go index 05a37e0..e153899 100644 --- a/unix/zerrors_linux_arm64.go +++ b/unix/zerrors_linux_arm64.go
@@ -96,6 +96,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x80084803 + HIDIOCGRDESC = 0x90044802 + HIDIOCGRDESCSIZE = 0x80044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -483,6 +486,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x80804804 + _HIDIOCGRAWPHYS = 0x80404805 + _HIDIOCGRAWUNIQ = 0x80404808 ) // Errors
diff --git a/unix/zerrors_linux_mips.go b/unix/zerrors_linux_mips.go index 5cd949b..5e8e71f 100644 --- a/unix/zerrors_linux_mips.go +++ b/unix/zerrors_linux_mips.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x18 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -488,6 +491,9 @@ WORDSIZE = 0x20 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 ) // Errors
diff --git a/unix/zerrors_linux_mips64.go b/unix/zerrors_linux_mips64.go index 38d992f..e670ee1 100644 --- a/unix/zerrors_linux_mips64.go +++ b/unix/zerrors_linux_mips64.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x18 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -488,6 +491,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 ) // Errors
diff --git a/unix/zerrors_linux_mips64le.go b/unix/zerrors_linux_mips64le.go index d8cc51b..dd11eac 100644 --- a/unix/zerrors_linux_mips64le.go +++ b/unix/zerrors_linux_mips64le.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x18 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -488,6 +491,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 ) // Errors
diff --git a/unix/zerrors_linux_mipsle.go b/unix/zerrors_linux_mipsle.go index f1375e8..a0a5b22 100644 --- a/unix/zerrors_linux_mipsle.go +++ b/unix/zerrors_linux_mipsle.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x18 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x100 @@ -488,6 +491,9 @@ WORDSIZE = 0x20 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 ) // Errors
diff --git a/unix/zerrors_linux_ppc64.go b/unix/zerrors_linux_ppc64.go index 063308e..e60102f 100644 --- a/unix/zerrors_linux_ppc64.go +++ b/unix/zerrors_linux_ppc64.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -548,6 +551,9 @@ WORDSIZE = 0x40 XCASE = 0x4000 XTABS = 0xc00 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 ) // Errors
diff --git a/unix/zerrors_linux_ppc64le.go b/unix/zerrors_linux_ppc64le.go index 0b5dcbf..838ff4e 100644 --- a/unix/zerrors_linux_ppc64le.go +++ b/unix/zerrors_linux_ppc64le.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x4000 ICANON = 0x100 IEXTEN = 0x400 @@ -548,6 +551,9 @@ WORDSIZE = 0x40 XCASE = 0x4000 XTABS = 0xc00 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 ) // Errors
diff --git a/unix/zerrors_linux_riscv64.go b/unix/zerrors_linux_riscv64.go index e0cab46..7cc98f0 100644 --- a/unix/zerrors_linux_riscv64.go +++ b/unix/zerrors_linux_riscv64.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x80084803 + HIDIOCGRDESC = 0x90044802 + HIDIOCGRDESCSIZE = 0x80044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -473,6 +476,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x80804804 + _HIDIOCGRAWPHYS = 0x80404805 + _HIDIOCGRAWUNIQ = 0x80404808 ) // Errors
diff --git a/unix/zerrors_linux_s390x.go b/unix/zerrors_linux_s390x.go index 4e69033..a508392 100644 --- a/unix/zerrors_linux_s390x.go +++ b/unix/zerrors_linux_s390x.go
@@ -93,6 +93,9 @@ F_SETOWN = 0x8 F_UNLCK = 0x2 F_WRLCK = 0x1 + HIDIOCGRAWINFO = 0x80084803 + HIDIOCGRDESC = 0x90044802 + HIDIOCGRDESCSIZE = 0x80044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -546,6 +549,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x80804804 + _HIDIOCGRAWPHYS = 0x80404805 + _HIDIOCGRAWUNIQ = 0x80404808 ) // Errors
diff --git a/unix/zerrors_linux_sparc64.go b/unix/zerrors_linux_sparc64.go index fa650b1..d5e2dc9 100644 --- a/unix/zerrors_linux_sparc64.go +++ b/unix/zerrors_linux_sparc64.go
@@ -97,6 +97,9 @@ F_SETOWN = 0x6 F_UNLCK = 0x3 F_WRLCK = 0x2 + HIDIOCGRAWINFO = 0x40084803 + HIDIOCGRDESC = 0x50044802 + HIDIOCGRDESCSIZE = 0x40044801 HUPCL = 0x400 ICANON = 0x2 IEXTEN = 0x8000 @@ -536,6 +539,9 @@ WORDSIZE = 0x40 XCASE = 0x4 XTABS = 0x1800 + _HIDIOCGRAWNAME = 0x40804804 + _HIDIOCGRAWPHYS = 0x40404805 + _HIDIOCGRAWUNIQ = 0x40404808 __TIOCFLUSH = 0x80047410 )
diff --git a/unix/ztypes_linux.go b/unix/ztypes_linux.go index d12ad28..3f922db 100644 --- a/unix/ztypes_linux.go +++ b/unix/ztypes_linux.go
@@ -3682,3 +3682,15 @@ ETHTOOL_A_TUNNEL_INFO_UDP_PORTS = 0x2 ETHTOOL_A_TUNNEL_INFO_MAX = 0x2 ) + +type ( + HIDRawReportDescriptor struct { + Size uint32 + Value [4096]uint8 + } + HIDRawDevInfo struct { + Bustype uint32 + Vendor int16 + Product int16 + } +)