summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/cam_ccb.h2
-rw-r--r--sys/cam/cam_compat.c89
-rw-r--r--sys/cam/cam_compat.h48
-rw-r--r--sys/cam/cam_xpt.c15
-rw-r--r--sys/cam/scsi/scsi_pass.c15
5 files changed, 168 insertions, 1 deletions
diff --git a/sys/cam/cam_ccb.h b/sys/cam/cam_ccb.h
index 006b4e0..35296ce 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 0000000..a24debc
--- /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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/types.h>
+#include <sys/kernel.h>
+#include <sys/conf.h>
+#include <sys/fcntl.h>
+
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/kthread.h>
+
+#include <cam/cam.h>
+#include <cam/cam_ccb.h>
+#include <cam/cam_compat.h>
+
+#include <cam/scsi/scsi_pass.h>
+
+#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 0000000..b23e7b2
--- /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 a4c83b1..3511265 100644
--- a/sys/cam/cam_xpt.c
+++ b/sys/cam/cam_xpt.c
@@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_xpt_periph.h>
#include <cam/cam_xpt_internal.h>
#include <cam/cam_debug.h>
+#include <cam/cam_compat.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
@@ -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 2b8b176..61f4f42 100644
--- a/sys/cam/scsi/scsi_pass.c
+++ b/sys/cam/scsi/scsi_pass.c
@@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_xpt_periph.h>
#include <cam/cam_debug.h>
#include <cam/cam_sim.h>
+#include <cam/cam_compat.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_pass.h>
@@ -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;
@@ -575,6 +577,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;
int error;
OpenPOWER on IntegriCloud