From nobody Tue Dec 27 01:19:56 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Ngxf43Rbxz2NPmB; Tue, 27 Dec 2022 01:19:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Ngxf43FKYz4lGT; Tue, 27 Dec 2022 01:19:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1672103996; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ec6aH6UDPvMdkwb6wXy6fheH/HbgZSYFz7hEd+WDeQk=; b=WGGu0cuItS/CZ1+w4t1U+v7c0AimSMezhm4yjUMkxKSCeHh4xKY7VTTxSNNyNRgDaIGxeR ybA93VxQJUwehI0/ku8rJ7O1g4AwOXvVOeggaRvSRwmcOhl0HenK6ES5wMr7nzZC87/FI6 NKogY4icBChpQyQxqpb9xp2vw2t3i7jAZrKyHcs7hFpU73gqgRyJ7+fJQ2+tgeaeHSycuJ g6GRNJTxQwaqDL1K6CaKaO/LO+Z6PJJQ473hlk2FSLsg3fsxA3hHCLdhOHDsU5wop+dUgC ZUUWjieKxM/bBd1GjT5ww1kqv9POYT9MnFUCV4UmW4lG40KiiBWBW574JlgreQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1672103996; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ec6aH6UDPvMdkwb6wXy6fheH/HbgZSYFz7hEd+WDeQk=; b=aiuwVRVKPXfsaTh84Q+7AyCK6PEeYqTE/M6/Aijrd4bZ9o+tax9HASQW9oOm8xtZ3ykS9x zM6CsBRKObnvT1Pfx/158yxv661bRkAt7TrxLFuPrt0EuQiLsbVNHpwJVSf4hxQsJkiE9G aTk8JJymzrhXOCNxIEyNb9yZ/SjHdygjRxP0D/6kkt9Hxma/qdGDqHHo4IZIiNPKCsa2BE nMFe7yZxAGjZ3C9f/+4Mm5tmQ1pgNpU+HmFcELQxraHNvqyUFfZHrR559juZQd1Utm+3lZ pblYuTBXToZYOuWBb181xYYOTksWYkVmOi9SAAeF3YUBi8Qrj/XIGqX/oR2HhQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1672103996; a=rsa-sha256; cv=none; b=txIAypDDKsoTMxtSgIxxM0Nt15cwClZv+tZERa0xa4TAIVO3SbgVre/zA2QvDAOl0l7tkC jNfqQHx2RhawbvEPg/Na+7s93v6cTtUPiEWkKA7iKyDk5xcqfx3KCoMJkGE5I1seI0jHK/ CFlWRU+MsP/pIYrIAk6OHlYqfT/TZXP5gf5u1cG1HjrMmdrtMaIp5csnrJDZe87trInj64 cm+CNP5MOsMmML7rcqKXkQPhxjzmPy9QU2eTkWgGG7f/zwq7+JE//61aHBdXZ7dJPn3HJd G6dGuh6rHJ+1+D2ymhcd7Q3+Tm6kh0wWgBcWA3g/7lu60xCENsNrIP4fknmUDg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Ngxf429jBzsM5; Tue, 27 Dec 2022 01:19:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 2BR1JujY024705; Tue, 27 Dec 2022 01:19:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 2BR1JunI024704; Tue, 27 Dec 2022 01:19:56 GMT (envelope-from git) Date: Tue, 27 Dec 2022 01:19:56 GMT Message-Id: <202212270119.2BR1JunI024704@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Vladimir Kondratyev Subject: git: b920ac9db657 - stable/13 - usb: real freebsd32 support for most ioctls List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: wulf X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: b920ac9db6577c18da5589b55b576cabfd2718c7 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by wulf: URL: https://cgit.FreeBSD.org/src/commit/?id=b920ac9db6577c18da5589b55b576cabfd2718c7 commit b920ac9db6577c18da5589b55b576cabfd2718c7 Author: Brooks Davis AuthorDate: 2021-12-17 21:28:13 +0000 Commit: Vladimir Kondratyev CommitDate: 2022-12-26 21:46:27 +0000 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. (cherry picked from commit 45b48cbc2b5819cd6e3dee3632d66e55d5d7c101) --- sys/dev/hid/hidraw.c | 93 +++++++++++++++++++++++++++++++-- sys/dev/usb/input/uhid.c | 25 +++++++-- sys/dev/usb/input/uhid_snes.c | 26 ++++++++-- sys/dev/usb/usb_dev.c | 12 +++++ sys/dev/usb/usb_generic.c | 118 ++++++++++++++++++++++++++++++++++++++++++ sys/dev/usb/usb_ioctl.h | 57 ++++++++++++++++++++ 6 files changed, 321 insertions(+), 10 deletions(-) diff --git a/sys/dev/hid/hidraw.c b/sys/dev/hid/hidraw.c index 8f66775bb791..7d1da583a817 100644 --- a/sys/dev/hid/hidraw.c +++ b/sys/dev/hid/hidraw.c @@ -41,6 +41,9 @@ __FBSDID("$FreeBSD$"); #include "opt_hid.h" #include +#ifdef COMPAT_FREEBSD32 +#include +#endif #include #include #include @@ -115,6 +118,31 @@ struct hidraw_softc { struct cdev *dev; }; +#ifdef COMPAT_FREEBSD32 +struct hidraw_gen_descriptor32 { + uint32_t hgd_data; /* void * */ + uint16_t hgd_lang_id; + uint16_t hgd_maxlen; + uint16_t hgd_actlen; + uint16_t hgd_offset; + uint8_t hgd_config_index; + uint8_t hgd_string_index; + uint8_t hgd_iface_index; + uint8_t hgd_altif_index; + uint8_t hgd_endpt_index; + uint8_t hgd_report_type; + uint8_t reserved[8]; +}; +#define HIDRAW_GET_REPORT_DESC32 \ + _IOC_NEWTYPE(HIDRAW_GET_REPORT_DESC, struct hidraw_gen_descriptor32) +#define HIDRAW_GET_REPORT32 \ + _IOC_NEWTYPE(HIDRAW_GET_REPORT, struct hidraw_gen_descriptor32) +#define HIDRAW_SET_REPORT_DESC32 \ + _IOC_NEWTYPE(HIDRAW_SET_REPORT_DESC, struct hidraw_gen_descriptor32) +#define HIDRAW_SET_REPORT32 \ + _IOC_NEWTYPE(HIDRAW_SET_REPORT, struct hidraw_gen_descriptor32) +#endif + static d_open_t hidraw_open; static d_read_t hidraw_read; static d_write_t hidraw_write; @@ -507,11 +535,35 @@ hidraw_write(struct cdev *dev, struct uio *uio, int flag) return (error); } +#ifdef COMPAT_FREEBSD32 +static void +update_hgd32(const struct hidraw_gen_descriptor *hgd, + struct hidraw_gen_descriptor32 *hgd32) +{ + /* Don't update hgd_data pointer */ + CP(*hgd, *hgd32, hgd_lang_id); + CP(*hgd, *hgd32, hgd_maxlen); + CP(*hgd, *hgd32, hgd_actlen); + CP(*hgd, *hgd32, hgd_offset); + CP(*hgd, *hgd32, hgd_config_index); + CP(*hgd, *hgd32, hgd_string_index); + CP(*hgd, *hgd32, hgd_iface_index); + CP(*hgd, *hgd32, hgd_altif_index); + CP(*hgd, *hgd32, hgd_endpt_index); + CP(*hgd, *hgd32, hgd_report_type); + /* Don't update reserved */ +} +#endif + static int hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { uint8_t local_buf[HIDRAW_LOCAL_BUFSIZE]; +#ifdef COMPAT_FREEBSD32 + struct hidraw_gen_descriptor local_hgd; + struct hidraw_gen_descriptor32 *hgd32 = NULL; +#endif void *buf; struct hidraw_softc *sc; struct hidraw_gen_descriptor *hgd; @@ -528,6 +580,32 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, if (sc == NULL) return (EIO); +#ifdef COMPAT_FREEBSD32 + hgd = (struct hidraw_gen_descriptor *)addr; + switch (cmd) { + case HIDRAW_GET_REPORT_DESC32: + case HIDRAW_GET_REPORT32: + case HIDRAW_SET_REPORT_DESC32: + case HIDRAW_SET_REPORT32: + cmd = _IOC_NEWTYPE(cmd, struct hidraw_gen_descriptor); + hgd32 = (struct hidraw_gen_descriptor32 *)addr; + hgd = &local_hgd; + PTRIN_CP(*hgd32, *hgd, hgd_data); + CP(*hgd32, *hgd, hgd_lang_id); + CP(*hgd32, *hgd, hgd_maxlen); + CP(*hgd32, *hgd, hgd_actlen); + CP(*hgd32, *hgd, hgd_offset); + CP(*hgd32, *hgd, hgd_config_index); + CP(*hgd32, *hgd, hgd_string_index); + CP(*hgd32, *hgd, hgd_iface_index); + CP(*hgd32, *hgd, hgd_altif_index); + CP(*hgd32, *hgd, hgd_endpt_index); + CP(*hgd32, *hgd, hgd_report_type); + /* Don't copy reserved */ + break; + } +#endif + /* fixed-length ioctls handling */ switch (cmd) { case FIONBIO: @@ -563,15 +641,19 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, mtx_lock(&sc->sc_mtx); sc->sc_state.uhid = true; mtx_unlock(&sc->sc_mtx); - hgd = (struct hidraw_gen_descriptor *)addr; if (sc->sc_rdesc->len > hgd->hgd_maxlen) { size = hgd->hgd_maxlen; } else { size = sc->sc_rdesc->len; } hgd->hgd_actlen = size; +#ifdef COMPAT_FREEBSD32 + if (hgd32 != NULL) + update_hgd32(hgd, hgd32); +#endif if (hgd->hgd_data == NULL) return (0); /* descriptor length only */ + return (copyout(sc->sc_rdesc->data, hgd->hgd_data, size)); @@ -594,7 +676,6 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, if (error != 0) return(error); - hgd = (struct hidraw_gen_descriptor *)addr; buf = HIDRAW_LOCAL_ALLOC(local_buf, hgd->hgd_maxlen); copyin(hgd->hgd_data, buf, hgd->hgd_maxlen); /* Lock newbus around set_report_descr call */ @@ -641,7 +722,6 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, case HIDRAW_GET_REPORT: if (!(sc->sc_fflags & FREAD)) return (EPERM); - hgd = (struct hidraw_gen_descriptor *)addr; switch (hgd->hgd_report_type) { case HID_INPUT_REPORT: size = sc->sc_rdesc->isize; @@ -667,12 +747,17 @@ hidraw_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, if (!error) error = copyout(buf, hgd->hgd_data, size); HIDRAW_LOCAL_FREE(local_buf, buf); +#ifdef COMPAT_FREEBSD32 + /* + * HIDRAW_GET_REPORT is declared _IOWR, but hgd is not written + * so we don't call update_hgd32(). + */ +#endif return (error); case HIDRAW_SET_REPORT: if (!(sc->sc_fflags & FWRITE)) return (EPERM); - hgd = (struct hidraw_gen_descriptor *)addr; switch (hgd->hgd_report_type) { case HID_INPUT_REPORT: size = sc->sc_rdesc->isize; diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c index cbab992a1343..d9653ae8761f 100644 --- a/sys/dev/usb/input/uhid.c +++ b/sys/dev/usb/input/uhid.c @@ -556,13 +556,30 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, { struct uhid_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 = addr; +#ifdef COMPAT_FREEBSD32 + switch (cmd) { + case USB_GET_REPORT_DESC32: + case USB_GET_REPORT32: + case USB_SET_REPORT32: + ugd32 = addr; + 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 = addr; if (sc->sc_repdesc_size > ugd->ugd_maxlen) { size = ugd->ugd_maxlen; } else { @@ -602,7 +619,6 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, error = EPERM; break; } - ugd = addr; switch (ugd->ugd_report_type) { case UHID_INPUT_REPORT: size = sc->sc_isize; @@ -630,7 +646,6 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, error = EPERM; break; } - ugd = addr; switch (ugd->ugd_report_type) { case UHID_INPUT_REPORT: size = sc->sc_isize; @@ -661,6 +676,10 @@ uhid_ioctl(struct usb_fifo *fifo, u_long cmd, void *addr, error = ENOIOCTL; break; } +#ifdef COMPAT_FREEBSD32 + if (ugd32 != NULL) + update_usb_gen_descriptor32(ugd32, ugd); +#endif return (error); } 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); } diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index 99b243464f6c..4811d280562c 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -32,6 +32,9 @@ #ifdef USB_GLOBAL_INCLUDE_FILE #include USB_GLOBAL_INCLUDE_FILE #else +#ifdef COMPAT_FREEBSD32 +#include +#endif #include #include #include @@ -1650,6 +1653,9 @@ usb_static_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, { union { struct usb_read_dir *urd; +#ifdef COMPAT_FREEBSD32 + struct usb_read_dir32 *urd32; +#endif void* data; } u; int err; @@ -1660,6 +1666,12 @@ usb_static_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, err = usb_read_symlink(u.urd->urd_data, u.urd->urd_startentry, u.urd->urd_maxlen); break; +#ifdef COMPAT_FREEBSD32 + case USB_READ_DIR32: + err = usb_read_symlink(PTRIN(u.urd32->urd_data), + u.urd32->urd_startentry, u.urd32->urd_maxlen); + break; +#endif case USB_DEV_QUIRK_GET: case USB_QUIRK_NAME_GET: case USB_DEV_QUIRK_ADD: diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index 8c9d910ee92e..b11168b6c81c 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -29,6 +29,9 @@ #ifdef USB_GLOBAL_INCLUDE_FILE #include USB_GLOBAL_INCLUDE_FILE #else +#ifdef COMPAT_FREEBSD32 +#include +#endif #include #include #include @@ -109,6 +112,9 @@ static int ugen_set_interface(struct usb_fifo *, uint8_t, uint8_t); static int ugen_get_cdesc(struct usb_fifo *, struct usb_gen_descriptor *); static int ugen_get_sdesc(struct usb_fifo *, struct usb_gen_descriptor *); static int ugen_get_iface_driver(struct usb_fifo *f, struct usb_gen_descriptor *ugd); +#ifdef COMPAT_FREEBSD32 +static int ugen_get32(u_long cmd, struct usb_fifo *f, struct usb_gen_descriptor32 *ugd32); +#endif static int ugen_re_enumerate(struct usb_fifo *); static int ugen_iface_ioctl(struct usb_fifo *, u_long, void *, int); static uint8_t ugen_fs_get_complete(struct usb_fifo *, uint8_t *); @@ -895,6 +901,31 @@ ugen_do_request(struct usb_fifo *f, struct usb_ctl_request *ur) return (error); } +#ifdef COMPAT_FREEBSD32 +static int +ugen_do_request32(struct usb_fifo *f, struct usb_ctl_request32 *ur32) +{ + struct usb_ctl_request ur; + int error; + + PTRIN_CP(*ur32, ur, ucr_data); + CP(*ur32, ur, ucr_flags); + CP(*ur32, ur, ucr_actlen); + CP(*ur32, ur, ucr_addr); + CP(*ur32, ur, ucr_request); + + error = ugen_do_request(f, &ur); + + /* Don't update ucr_data pointer */ + CP(ur, *ur32, ucr_flags); + CP(ur, *ur32, ucr_actlen); + CP(ur, *ur32, ucr_addr); + CP(ur, *ur32, ucr_request); + + return (error); +} +#endif + /*------------------------------------------------------------------------ * ugen_re_enumerate *------------------------------------------------------------------------*/ @@ -2144,6 +2175,14 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) error = ugen_get_iface_driver(f, addr); break; +#ifdef COMPAT_FREEBSD32 + case USB_GET_FULL_DESC32: + case USB_GET_STRING_DESC32: + case USB_GET_IFACE_DRIVER32: + error = ugen_get32(cmd, f, addr); + break; +#endif + case USB_REQUEST: case USB_DO_REQUEST: if (!(fflags & FWRITE)) { @@ -2153,6 +2192,17 @@ ugen_ioctl_post(struct usb_fifo *f, u_long cmd, void *addr, int fflags) error = ugen_do_request(f, addr); break; +#ifdef COMPAT_FREEBSD32 + case USB_REQUEST32: + case USB_DO_REQUEST32: + if (!(fflags & FWRITE)) { + error = EPERM; + break; + } + error = ugen_do_request32(f, addr); + break; +#endif + case USB_DEVICEINFO: case USB_GET_DEVICEINFO: error = ugen_fill_deviceinfo(f, addr); @@ -2315,4 +2365,72 @@ ugen_ctrl_fs_callback(struct usb_xfer *xfer, usb_error_t error) break; } } + +#ifdef COMPAT_FREEBSD32 +void +usb_gen_descriptor_from32(struct usb_gen_descriptor *ugd, + const struct usb_gen_descriptor32 *ugd32) +{ + PTRIN_CP(*ugd32, *ugd, ugd_data); + CP(*ugd32, *ugd, ugd_lang_id); + CP(*ugd32, *ugd, ugd_maxlen); + CP(*ugd32, *ugd, ugd_actlen); + CP(*ugd32, *ugd, ugd_offset); + CP(*ugd32, *ugd, ugd_config_index); + CP(*ugd32, *ugd, ugd_string_index); + CP(*ugd32, *ugd, ugd_iface_index); + CP(*ugd32, *ugd, ugd_altif_index); + CP(*ugd32, *ugd, ugd_endpt_index); + CP(*ugd32, *ugd, ugd_report_type); + /* Don't copy reserved */ +} + +void +update_usb_gen_descriptor32(struct usb_gen_descriptor32 *ugd32, + struct usb_gen_descriptor *ugd) +{ + /* Don't update ugd_data pointer */ + CP(*ugd32, *ugd, ugd_lang_id); + CP(*ugd32, *ugd, ugd_maxlen); + CP(*ugd32, *ugd, ugd_actlen); + CP(*ugd32, *ugd, ugd_offset); + CP(*ugd32, *ugd, ugd_config_index); + CP(*ugd32, *ugd, ugd_string_index); + CP(*ugd32, *ugd, ugd_iface_index); + CP(*ugd32, *ugd, ugd_altif_index); + CP(*ugd32, *ugd, ugd_endpt_index); + CP(*ugd32, *ugd, ugd_report_type); + /* Don't update reserved */ +} + +static int +ugen_get32(u_long cmd, struct usb_fifo *f, struct usb_gen_descriptor32 *ugd32) +{ + struct usb_gen_descriptor ugd; + int error; + + usb_gen_descriptor_from32(&ugd, ugd32); + switch (cmd) { + case USB_GET_FULL_DESC32: + error = ugen_get_cdesc(f, &ugd); + break; + + case USB_GET_STRING_DESC32: + error = ugen_get_sdesc(f, &ugd); + break; + + case USB_GET_IFACE_DRIVER32: + error = ugen_get_iface_driver(f, &ugd); + break; + default: + /* Can't happen except by programmer error */ + panic("%s: called with invalid cmd %lx", __func__, cmd); + } + update_usb_gen_descriptor32(ugd32, &ugd); + + return (error); +} + +#endif /* COMPAT_FREEBSD32 */ + #endif /* USB_HAVE_UGEN */ diff --git a/sys/dev/usb/usb_ioctl.h b/sys/dev/usb/usb_ioctl.h index 39783305ca6b..9d35588f1138 100644 --- a/sys/dev/usb/usb_ioctl.h +++ b/sys/dev/usb/usb_ioctl.h @@ -346,4 +346,61 @@ struct usb_gen_quirk { #define USB_DEV_QUIRK_ADD _IOW ('Q', 2, struct usb_gen_quirk) #define USB_DEV_QUIRK_REMOVE _IOW ('Q', 3, struct usb_gen_quirk) +#ifdef _KERNEL +#ifdef COMPAT_FREEBSD32 + +struct usb_read_dir32 { + uint32_t urd_data; + uint32_t urd_startentry; + uint32_t urd_maxlen; +}; +#define USB_READ_DIR32 \ + _IOC_NEWTYPE(USB_READ_DIR, struct usb_read_dir32) + +struct usb_ctl_request32 { + uint32_t ucr_data; + uint16_t ucr_flags; + uint16_t ucr_actlen; + uint8_t ucr_addr; + struct usb_device_request ucr_request; +}; +#define USB_REQUEST32 _IOC_NEWTYPE(USB_REQUEST, struct usb_ctl_request32) +#define USB_DO_REQUEST32 _IOC_NEWTYPE(USB_DO_REQUEST, struct usb_ctl_request32) + +struct usb_gen_descriptor32 { + uint32_t ugd_data; /* void * */ + uint16_t ugd_lang_id; + uint16_t ugd_maxlen; + uint16_t ugd_actlen; + uint16_t ugd_offset; + uint8_t ugd_config_index; + uint8_t ugd_string_index; + uint8_t ugd_iface_index; + uint8_t ugd_altif_index; + uint8_t ugd_endpt_index; + uint8_t ugd_report_type; + uint8_t reserved[8]; +}; + +#define USB_GET_REPORT_DESC32 \ + _IOC_NEWTYPE(USB_GET_REPORT_DESC, struct usb_gen_descriptor32) +#define USB_GET_REPORT32 \ + _IOC_NEWTYPE(USB_GET_REPORT, struct usb_gen_descriptor32) +#define USB_SET_REPORT32 \ + _IOC_NEWTYPE(USB_SET_REPORT, struct usb_gen_descriptor32) +#define USB_GET_FULL_DESC32 \ + _IOC_NEWTYPE(USB_GET_FULL_DESC, struct usb_gen_descriptor32) +#define USB_GET_STRING_DESC32 \ + _IOC_NEWTYPE(USB_GET_STRING_DESC, struct usb_gen_descriptor32) +#define USB_GET_IFACE_DRIVER32 \ + _IOC_NEWTYPE(USB_GET_IFACE_DRIVER, struct usb_gen_descriptor32) + +void usb_gen_descriptor_from32(struct usb_gen_descriptor *ugd, + const struct usb_gen_descriptor32 *ugd32); +void update_usb_gen_descriptor32(struct usb_gen_descriptor32 *ugd32, + struct usb_gen_descriptor *ugd); + +#endif /* COMPAT_FREEBSD32 */ +#endif /* _KERNEL */ + #endif /* _USB_IOCTL_H_ */