aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/usb/input/uhid_snes.c
diff options
context:
space:
mode:
authorBrooks Davis <brooks@FreeBSD.org>2021-12-17 21:28:13 +0000
committerBrooks Davis <brooks@FreeBSD.org>2021-12-17 21:28:13 +0000
commit45b48cbc2b5819cd6e3dee3632d66e55d5d7c101 (patch)
tree09688edfee03fb45f8d8d6de0d0316ab9b62fd50 /sys/dev/usb/input/uhid_snes.c
parent16f02a4cb4594326b6687eeedde5feb9cb40cba4 (diff)
downloadsrc-45b48cbc2b5819cd6e3dee3632d66e55d5d7c101.tar.gz
src-45b48cbc2b5819cd6e3dee3632d66e55d5d7c101.zip
usb: real freebsd32 support for most ioctls
Use thunks or alternative access methods to support ioctls without the COMPAT_32BIT hacks that store pointers in uint64_t's on 32-bit platforms. This should allow a normal i386 libusb to work. On CheriBSD, the sizes of the structs will differ between CheriABI (the default) and freebsd64 no matter what so we need proper compat support there. This change paves the way. Reviewed by: hselasky, jrtc27 (prior version)
Diffstat (limited to 'sys/dev/usb/input/uhid_snes.c')
-rw-r--r--sys/dev/usb/input/uhid_snes.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/sys/dev/usb/input/uhid_snes.c b/sys/dev/usb/input/uhid_snes.c
index 181e38eba7b1..9bce3d10941f 100644
--- a/sys/dev/usb/input/uhid_snes.c
+++ b/sys/dev/usb/input/uhid_snes.c
@@ -281,13 +281,30 @@ uhid_snes_ioctl(struct usb_fifo *fifo, u_long cmd, void *data, int fflags)
{
struct uhid_snes_softc *sc = usb_fifo_softc(fifo);
struct usb_gen_descriptor *ugd;
+#ifdef COMPAT_FREEBSD32
+ struct usb_gen_descriptor local_ugd;
+ struct usb_gen_descriptor32 *ugd32 = NULL;
+#endif
uint32_t size;
int error = 0;
uint8_t id;
+ ugd = data;
+#ifdef COMPAT_FREEBSD32
+ switch (cmd) {
+ case USB_GET_REPORT_DESC32:
+ case USB_GET_REPORT32:
+ case USB_SET_REPORT32:
+ ugd32 = data;
+ ugd = &local_ugd;
+ usb_gen_descriptor_from32(ugd, ugd32);
+ cmd = _IOC_NEWTYPE(cmd, struct usb_gen_descriptor);
+ break;
+ }
+#endif
+
switch (cmd) {
case USB_GET_REPORT_DESC:
- ugd = data;
if (sc->sc_repdesc_size > ugd->ugd_maxlen) {
size = ugd->ugd_maxlen;
} else {
@@ -328,7 +345,6 @@ uhid_snes_ioctl(struct usb_fifo *fifo, u_long cmd, void *data, int fflags)
error = EPERM;
break;
}
- ugd = data;
switch (ugd->ugd_report_type) {
case UHID_INPUT_REPORT:
size = sc->sc_isize;
@@ -356,7 +372,6 @@ uhid_snes_ioctl(struct usb_fifo *fifo, u_long cmd, void *data, int fflags)
error = EPERM;
break;
}
- ugd = data;
switch (ugd->ugd_report_type) {
case UHID_INPUT_REPORT:
size = sc->sc_isize;
@@ -388,6 +403,11 @@ uhid_snes_ioctl(struct usb_fifo *fifo, u_long cmd, void *data, int fflags)
error = EINVAL;
break;
}
+
+#ifdef COMPAT_FREEBSD32
+ if (ugd32 != NULL)
+ update_usb_gen_descriptor32(ugd32, ugd);
+#endif
return (error);
}