git: 028b16e2088a - main - cam: better ioctl compatibility for cd
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 25 Jul 2024 04:49:07 UTC
The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=028b16e2088a682c1abfb74fa5eb7ff64405ffff commit 028b16e2088a682c1abfb74fa5eb7ff64405ffff Author: Warner Losh <imp@FreeBSD.org> AuthorDate: 2024-07-25 04:47:45 +0000 Commit: Warner Losh <imp@FreeBSD.org> CommitDate: 2024-07-25 04:47:45 +0000 cam: better ioctl compatibility for cd Unlike xpt and pass driver, there's no test for ENOTTY in cdioctl to try the compatbility ioctls. Add one. However, this is a disk ioctl, not a cdev ioctl. To get around this, we cast the struct disk * to a struct cdev * to pass through. We cast it back in a simple wrapper function. PR: 198336 Sponsored by: Netflix MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D42666 Differential Revision: https://reviews.freebsd.org/D35312 --- sys/cam/cam_compat.c | 6 ++++++ sys/cam/cam_periph.c | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c index fdb4ee8717ec..896b071f86dc 100644 --- a/sys/cam/cam_compat.c +++ b/sys/cam/cam_compat.c @@ -49,6 +49,12 @@ #include <cam/scsi/scsi_pass.h> +/* + * Note: struct cdev *dev parameter here is simply passed through. For cdioctl + * we need to pass down a struct periph * which has been cast to a cdev and that + * is cast back again in cdioctl_dev(). + */ + static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp); static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index e957edee67f1..ed90ef91abce 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -1122,6 +1122,20 @@ cam_periph_unmapmem(union ccb *ccb, struct cam_periph_map_info *mapinfo) return (error); } +static int +cam_periph_ioctl_compat(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) +{ + struct cam_periph *periph; + + /* + * For compat, we need to cast struct periph * into struct cdev *dev and + * then back again. + */ + periph = (struct cam_periph *)(void *)dev; + cam_periph_assert(periph, MA_OWNED); + return (cam_periph_ioctl(periph, cmd, addr, cderror)); +} + int cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr, int (*error_routine)(union ccb *ccb, @@ -1178,7 +1192,13 @@ cam_periph_ioctl(struct cam_periph *periph, u_long cmd, caddr_t addr, break; default: - error = ENOTTY; + /* + * We assume that the compat layer doesn't care about + * the dev parameter. It just passes it through, so + * cheat a little. + */ + error = cam_compat_ioctl((struct cdev *)(void *)periph, + cmd, addr, flag, td, cam_periph_ioctl_compat); break; } return(error);