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
This commit is contained in:
Warner Losh 2024-07-24 22:47:45 -06:00
parent 0a59a6b02f
commit 028b16e208
2 changed files with 27 additions and 1 deletions

View file

@ -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,

View file

@ -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);