diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h index 006b4e0dc7e5..35296ce9ef1a 100644 --- a/sys/cam/cam_ccb.h +++ b/sys/cam/cam_ccb.h @@ -541,7 +541,7 @@ struct ccb_dev_match { /* * Definitions for the path inquiry CCB fields. */ -#define CAM_VERSION 0x16 /* Hex value for current version */ +#define CAM_VERSION 0x17 /* Hex value for current version */ typedef enum { PI_MDP_ABLE = 0x80, /* Supports MDP message */ diff --git a/sys/cam/cam_compat.c b/sys/cam/cam_compat.c new file mode 100644 index 000000000000..a24debc1d797 --- /dev/null +++ b/sys/cam/cam_compat.c @@ -0,0 +1,89 @@ +/*- + * CAM ioctl compatibility shims + * + * Copyright (c) 2013 Scott Long + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "opt_cam.h" + +int +cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct thread *td) +{ + int error; + + switch (*cmd) { + case CAMIOCOMMAND_0x16: + { + union ccb *ccb; + + ccb = (union ccb *)*addr; + if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) { + ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16; + ccb->ccb_h.flags |= CAM_DATA_SG_PADDR; + } + if (ccb->ccb_h.flags & CAM_DATA_PHYS_0x16) { + ccb->ccb_h.flags &= ~CAM_DATA_PHYS_0x16; + ccb->ccb_h.flags |= CAM_DATA_PADDR; + } + if (ccb->ccb_h.flags & CAM_SCATTER_VALID_0x16) { + ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16; + ccb->ccb_h.flags |= CAM_DATA_SG; + } + *cmd = CAMIOCOMMAND; + error = EAGAIN; + break; + } + case CAMGETPASSTHRU_0x16: + *cmd = CAMGETPASSTHRU; + error = EAGAIN; + break; + default: + error = ENOTTY; + } + + return (error); +} diff --git a/sys/cam/cam_compat.h b/sys/cam/cam_compat.h new file mode 100644 index 000000000000..b23e7b27c7bf --- /dev/null +++ b/sys/cam/cam_compat.h @@ -0,0 +1,48 @@ +/*- + * CAM ioctl compatibility shims + * + * Copyright (c) 2013 Scott Long + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions, and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _CAM_CAM_COMPAT_H +#define _CAM_CAM_COMPAT_H + +int cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct thread *td); + +/* Version 0x16 compatibility */ +#define CAM_VERSION_0x16 0x16 + +/* The size of the union ccb didn't change when going to 0x17 */ +#define CAMIOCOMMAND_0x16 _IOWR(CAM_VERSION_0x16, 2, union ccb) +#define CAMGETPASSTHRU_0x16 _IOWR(CAM_VERSION_0x16, 3, union ccb) + +#define CAM_SCATTER_VALID_0x16 0x10 +#define CAM_SG_LIST_PHYS_0x16 0x40000 +#define CAM_DATA_PHYS_0x16 0x20000 + +#endif + diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index a4c83b114136..3511265d1d04 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -180,6 +181,7 @@ PERIPHDRIVER_DECLARE(xpt, xpt_driver); static d_open_t xptopen; static d_close_t xptclose; static d_ioctl_t xptioctl; +static d_ioctl_t xptdoioctl; static struct cdevsw xpt_cdevsw = { .d_version = D_VERSION, @@ -395,6 +397,19 @@ xptioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td { int error; + if ((error = xptdoioctl(dev, cmd, addr, flag, td)) == ENOTTY) { + error = cam_compat_ioctl(dev, &cmd, &addr, &flag, td); + if (error == EAGAIN) + return (xptdoioctl(dev, cmd, addr, flag, td)); + } + return (error); +} + +static int +xptdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) +{ + int error; + error = 0; switch(cmd) { diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 2b8b176017de..61f4f4249798 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -87,6 +88,7 @@ struct pass_softc { static d_open_t passopen; static d_close_t passclose; static d_ioctl_t passioctl; +static d_ioctl_t passdoioctl; static periph_init_t passinit; static periph_ctor_t passregister; @@ -574,6 +576,19 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) static int passioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) +{ + int error; + + if ((error = passdoioctl(dev, cmd, addr, flag, td)) == ENOTTY) { + error = cam_compat_ioctl(dev, &cmd, &addr, &flag, td); + if (error == EAGAIN) + return (passdoioctl(dev, cmd, addr, flag, td)); + } + return (error); +} + +static int +passdoioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { struct cam_periph *periph; struct pass_softc *softc;