1251837Sscottl/*-
2251837Sscottl * CAM ioctl compatibility shims
3251837Sscottl *
4251837Sscottl * Copyright (c) 2013 Scott Long
5251837Sscottl * All rights reserved.
6251837Sscottl *
7251837Sscottl * Redistribution and use in source and binary forms, with or without
8251837Sscottl * modification, are permitted provided that the following conditions
9251837Sscottl * are met:
10251837Sscottl * 1. Redistributions of source code must retain the above copyright
11251837Sscottl *    notice, this list of conditions, and the following disclaimer,
12251837Sscottl *    without modification, immediately at the beginning of the file.
13251837Sscottl * 2. The name of the author may not be used to endorse or promote products
14251837Sscottl *    derived from this software without specific prior written permission.
15251837Sscottl *
16251837Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17251837Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18251837Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19251837Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20251837Sscottl * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21251837Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22251837Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23251837Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24251837Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25251837Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26251837Sscottl * SUCH DAMAGE.
27251837Sscottl *
28251837Sscottl */
29251837Sscottl
30251837Sscottl#include <sys/cdefs.h>
31251837Sscottl__FBSDID("$FreeBSD: stable/10/sys/cam/cam_compat.c 306750 2016-10-06 03:20:47Z mav $");
32251837Sscottl
33251837Sscottl#include <sys/param.h>
34251837Sscottl#include <sys/systm.h>
35251837Sscottl#include <sys/types.h>
36251837Sscottl#include <sys/kernel.h>
37251837Sscottl#include <sys/conf.h>
38251837Sscottl#include <sys/fcntl.h>
39251837Sscottl
40251837Sscottl#include <sys/lock.h>
41251837Sscottl#include <sys/mutex.h>
42251837Sscottl#include <sys/sysctl.h>
43251837Sscottl#include <sys/kthread.h>
44251837Sscottl
45251837Sscottl#include <cam/cam.h>
46251837Sscottl#include <cam/cam_ccb.h>
47255870Sscottl#include <cam/cam_xpt.h>
48251837Sscottl#include <cam/cam_compat.h>
49251837Sscottl
50251837Sscottl#include <cam/scsi/scsi_pass.h>
51251837Sscottl
52251837Sscottl#include "opt_cam.h"
53251837Sscottl
54255870Sscottlstatic int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
55255870Sscottl    int flag, struct thread *td, d_ioctl_t *cbfnp);
56255870Sscottl
57251837Sscottlint
58255870Sscottlcam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
59255870Sscottl    struct thread *td, d_ioctl_t *cbfnp)
60251837Sscottl{
61251837Sscottl	int error;
62251837Sscottl
63255870Sscottl	switch (cmd) {
64251837Sscottl	case CAMIOCOMMAND_0x16:
65251837Sscottl	{
66306750Smav		struct ccb_hdr_0x17 *hdr17;
67251837Sscottl
68306750Smav		hdr17 = (struct ccb_hdr_0x17 *)addr;
69306750Smav		if (hdr17->flags & CAM_SG_LIST_PHYS_0x16) {
70306750Smav			hdr17->flags &= ~CAM_SG_LIST_PHYS_0x16;
71306750Smav			hdr17->flags |= CAM_DATA_SG_PADDR;
72251837Sscottl		}
73306750Smav		if (hdr17->flags & CAM_DATA_PHYS_0x16) {
74306750Smav			hdr17->flags &= ~CAM_DATA_PHYS_0x16;
75306750Smav			hdr17->flags |= CAM_DATA_PADDR;
76251837Sscottl		}
77306750Smav		if (hdr17->flags & CAM_SCATTER_VALID_0x16) {
78306750Smav			hdr17->flags &= CAM_SCATTER_VALID_0x16;
79306750Smav			hdr17->flags |= CAM_DATA_SG;
80251837Sscottl		}
81255870Sscottl		cmd = CAMIOCOMMAND;
82306750Smav		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
83251837Sscottl		break;
84251837Sscottl	}
85251837Sscottl	case CAMGETPASSTHRU_0x16:
86255870Sscottl		cmd = CAMGETPASSTHRU;
87306750Smav		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
88251837Sscottl		break;
89255870Sscottl	case CAMIOCOMMAND_0x17:
90255870Sscottl		cmd = CAMIOCOMMAND;
91255870Sscottl		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
92255870Sscottl		break;
93255870Sscottl	case CAMGETPASSTHRU_0x17:
94255870Sscottl		cmd = CAMGETPASSTHRU;
95255870Sscottl		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
96255870Sscottl		break;
97251837Sscottl	default:
98251837Sscottl		error = ENOTTY;
99251837Sscottl	}
100251837Sscottl
101251837Sscottl	return (error);
102251837Sscottl}
103255870Sscottl
104255870Sscottlstatic int
105255870Sscottlcam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
106255870Sscottl    struct thread *td, d_ioctl_t *cbfnp)
107255870Sscottl{
108255870Sscottl	union ccb		*ccb;
109255870Sscottl	struct ccb_hdr		*hdr;
110255870Sscottl	struct ccb_hdr_0x17	*hdr17;
111255870Sscottl	uint8_t			*ccbb, *ccbb17;
112255870Sscottl	u_int			error;
113255870Sscottl
114255870Sscottl	hdr17 = (struct ccb_hdr_0x17 *)addr;
115255870Sscottl	ccb = xpt_alloc_ccb();
116255870Sscottl	hdr = &ccb->ccb_h;
117255870Sscottl
118255870Sscottl	hdr->pinfo = hdr17->pinfo;
119255870Sscottl	hdr->xpt_links = hdr17->xpt_links;
120255870Sscottl	hdr->sim_links = hdr17->sim_links;
121255870Sscottl	hdr->periph_links = hdr17->periph_links;
122255870Sscottl	hdr->retry_count = hdr17->retry_count;
123255870Sscottl	hdr->cbfcnp = hdr17->cbfcnp;
124255870Sscottl	hdr->func_code = hdr17->func_code;
125255870Sscottl	hdr->status = hdr17->status;
126255870Sscottl	hdr->path = hdr17->path;
127255870Sscottl	hdr->path_id = hdr17->path_id;
128255870Sscottl	hdr->target_id = hdr17->target_id;
129255870Sscottl	hdr->target_lun = hdr17->target_lun;
130255870Sscottl	hdr->ext_lun.lun64 = 0;
131255870Sscottl	hdr->flags = hdr17->flags;
132255870Sscottl	hdr->xflags = 0;
133255870Sscottl	hdr->periph_priv = hdr17->periph_priv;
134255870Sscottl	hdr->sim_priv = hdr17->sim_priv;
135255870Sscottl	hdr->timeout = hdr17->timeout;
136255870Sscottl	hdr->softtimeout.tv_sec = 0;
137255870Sscottl	hdr->softtimeout.tv_usec = 0;
138255870Sscottl
139255870Sscottl	ccbb = (uint8_t *)&hdr[1];
140255870Sscottl	ccbb17 = (uint8_t *)&hdr17[1];
141255870Sscottl	bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN);
142255870Sscottl
143255870Sscottl	error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td);
144255870Sscottl
145255870Sscottl	hdr17->pinfo = hdr->pinfo;
146255870Sscottl	hdr17->xpt_links = hdr->xpt_links;
147255870Sscottl	hdr17->sim_links = hdr->sim_links;
148255870Sscottl	hdr17->periph_links = hdr->periph_links;
149255870Sscottl	hdr17->retry_count = hdr->retry_count;
150255870Sscottl	hdr17->cbfcnp = hdr->cbfcnp;
151255870Sscottl	hdr17->func_code = hdr->func_code;
152255870Sscottl	hdr17->status = hdr->status;
153255870Sscottl	hdr17->path = hdr->path;
154255870Sscottl	hdr17->path_id = hdr->path_id;
155255870Sscottl	hdr17->target_id = hdr->target_id;
156255870Sscottl	hdr17->target_lun = hdr->target_lun;
157255870Sscottl	hdr17->flags = hdr->flags;
158255870Sscottl	hdr17->periph_priv = hdr->periph_priv;
159255870Sscottl	hdr17->sim_priv = hdr->sim_priv;
160255870Sscottl	hdr17->timeout = hdr->timeout;
161255870Sscottl
162255870Sscottl	/* The PATH_INQ only needs special handling on the way out */
163255870Sscottl	if (ccb->ccb_h.func_code != XPT_PATH_INQ) {
164255870Sscottl		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
165255870Sscottl	} else {
166255870Sscottl		struct ccb_pathinq	*cpi;
167255870Sscottl		struct ccb_pathinq_0x17 *cpi17;
168255870Sscottl
169255870Sscottl		cpi = &ccb->cpi;
170255870Sscottl		cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
171255870Sscottl		cpi17->version_num = cpi->version_num;
172255870Sscottl		cpi17->hba_inquiry = cpi->hba_inquiry;
173255870Sscottl		cpi17->target_sprt = (u_int8_t)cpi->target_sprt;
174255870Sscottl		cpi17->hba_misc = (u_int8_t)cpi->hba_misc;
175255870Sscottl		cpi17->hba_eng_cnt = cpi->hba_eng_cnt;
176255870Sscottl		bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN);
177255870Sscottl		cpi17->max_target = cpi->max_target;
178255870Sscottl		cpi17->max_lun = cpi->max_lun;
179255870Sscottl		cpi17->async_flags = cpi->async_flags;
180255870Sscottl		cpi17->hpath_id = cpi->hpath_id;
181255870Sscottl		cpi17->initiator_id = cpi->initiator_id;
182255870Sscottl		bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN);
183255870Sscottl		bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN);
184255870Sscottl		bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN);
185255870Sscottl		cpi17->unit_number = cpi->unit_number;
186255870Sscottl		cpi17->bus_id = cpi->bus_id;
187255870Sscottl		cpi17->base_transfer_speed = cpi->base_transfer_speed;
188255870Sscottl		cpi17->protocol = cpi->protocol;
189255870Sscottl		cpi17->protocol_version = cpi->protocol_version;
190255870Sscottl		cpi17->transport = cpi->transport;
191255870Sscottl		cpi17->transport_version = cpi->transport_version;
192255870Sscottl		bcopy(&cpi->xport_specific, &cpi17->xport_specific,
193255870Sscottl		    PATHINQ_SETTINGS_SIZE);
194255870Sscottl		cpi17->maxio = cpi->maxio;
195255870Sscottl		cpi17->hba_vendor = cpi->hba_vendor;
196255870Sscottl		cpi17->hba_device = cpi->hba_device;
197255870Sscottl		cpi17->hba_subvendor = cpi->hba_subvendor;
198255870Sscottl		cpi17->hba_subdevice = cpi->hba_subdevice;
199255870Sscottl	}
200255870Sscottl
201255870Sscottl	xpt_free_ccb(ccb);
202255870Sscottl
203255870Sscottl	return (error);
204255870Sscottl}
205