xref: /freebsd/sys/cam/cam_compat.c (revision 4eee292ab66316c01bae887e6d5a3468e1c27e77)
125a2902cSScott Long /*-
225a2902cSScott Long  * CAM ioctl compatibility shims
325a2902cSScott Long  *
44d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
5bec9534dSPedro F. Giffuni  *
625a2902cSScott Long  * Copyright (c) 2013 Scott Long
725a2902cSScott Long  * All rights reserved.
825a2902cSScott Long  *
925a2902cSScott Long  * Redistribution and use in source and binary forms, with or without
1025a2902cSScott Long  * modification, are permitted provided that the following conditions
1125a2902cSScott Long  * are met:
1225a2902cSScott Long  * 1. Redistributions of source code must retain the above copyright
1325a2902cSScott Long  *    notice, this list of conditions, and the following disclaimer,
1425a2902cSScott Long  *    without modification, immediately at the beginning of the file.
1525a2902cSScott Long  * 2. The name of the author may not be used to endorse or promote products
1625a2902cSScott Long  *    derived from this software without specific prior written permission.
1725a2902cSScott Long  *
1825a2902cSScott Long  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1925a2902cSScott Long  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2025a2902cSScott Long  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2125a2902cSScott Long  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
2225a2902cSScott Long  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2325a2902cSScott Long  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2425a2902cSScott Long  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2525a2902cSScott Long  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2625a2902cSScott Long  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2725a2902cSScott Long  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2825a2902cSScott Long  * SUCH DAMAGE.
2925a2902cSScott Long  *
3025a2902cSScott Long  */
3125a2902cSScott Long 
3225a2902cSScott Long #include <sys/param.h>
3325a2902cSScott Long #include <sys/systm.h>
3425a2902cSScott Long #include <sys/types.h>
3525a2902cSScott Long #include <sys/kernel.h>
3625a2902cSScott Long #include <sys/conf.h>
3725a2902cSScott Long #include <sys/fcntl.h>
3825a2902cSScott Long 
3925a2902cSScott Long #include <sys/lock.h>
4025a2902cSScott Long #include <sys/mutex.h>
4125a2902cSScott Long #include <sys/sysctl.h>
4225a2902cSScott Long #include <sys/kthread.h>
4325a2902cSScott Long 
4425a2902cSScott Long #include <cam/cam.h>
4525a2902cSScott Long #include <cam/cam_ccb.h>
46f564de00SScott Long #include <cam/cam_xpt.h>
4725a2902cSScott Long #include <cam/cam_compat.h>
4892be6c51SNathan Whitehorn #include <cam/cam_periph.h>
4925a2902cSScott Long 
5025a2902cSScott Long #include <cam/scsi/scsi_pass.h>
5125a2902cSScott Long 
52f564de00SScott Long static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr,
53f564de00SScott Long     int flag, struct thread *td, d_ioctl_t *cbfnp);
5492be6c51SNathan Whitehorn static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr,
5592be6c51SNathan Whitehorn     int flag, struct thread *td, d_ioctl_t *cbfnp);
568f9be1eeSAlexander Motin static int cam_compat_handle_0x19(struct cdev *dev, u_long cmd, caddr_t addr,
578f9be1eeSAlexander Motin     int flag, struct thread *td, d_ioctl_t *cbfnp);
5892be6c51SNathan Whitehorn static int cam_compat_translate_dev_match_0x18(union ccb *ccb);
59f564de00SScott Long 
6025a2902cSScott Long int
61f564de00SScott Long cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
62f564de00SScott Long     struct thread *td, d_ioctl_t *cbfnp)
6325a2902cSScott Long {
6425a2902cSScott Long 	int error;
6525a2902cSScott Long 
66f564de00SScott Long 	switch (cmd) {
6725a2902cSScott Long 	case CAMIOCOMMAND_0x16:
6825a2902cSScott Long 	{
6992be6c51SNathan Whitehorn 		struct ccb_hdr_0x17 *hdr17;
7025a2902cSScott Long 
7192be6c51SNathan Whitehorn 		hdr17 = (struct ccb_hdr_0x17 *)addr;
7292be6c51SNathan Whitehorn 		if (hdr17->flags & CAM_SG_LIST_PHYS_0x16) {
7392be6c51SNathan Whitehorn 			hdr17->flags &= ~CAM_SG_LIST_PHYS_0x16;
7492be6c51SNathan Whitehorn 			hdr17->flags |= CAM_DATA_SG_PADDR;
7525a2902cSScott Long 		}
7692be6c51SNathan Whitehorn 		if (hdr17->flags & CAM_DATA_PHYS_0x16) {
7792be6c51SNathan Whitehorn 			hdr17->flags &= ~CAM_DATA_PHYS_0x16;
7892be6c51SNathan Whitehorn 			hdr17->flags |= CAM_DATA_PADDR;
7925a2902cSScott Long 		}
8092be6c51SNathan Whitehorn 		if (hdr17->flags & CAM_SCATTER_VALID_0x16) {
8192be6c51SNathan Whitehorn 			hdr17->flags &= CAM_SCATTER_VALID_0x16;
8292be6c51SNathan Whitehorn 			hdr17->flags |= CAM_DATA_SG;
8325a2902cSScott Long 		}
84f564de00SScott Long 		cmd = CAMIOCOMMAND;
8592be6c51SNathan Whitehorn 		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
8625a2902cSScott Long 		break;
8725a2902cSScott Long 	}
8825a2902cSScott Long 	case CAMGETPASSTHRU_0x16:
89f564de00SScott Long 		cmd = CAMGETPASSTHRU;
9092be6c51SNathan Whitehorn 		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
91f564de00SScott Long 		break;
92f564de00SScott Long 	case CAMIOCOMMAND_0x17:
93f564de00SScott Long 		cmd = CAMIOCOMMAND;
94f564de00SScott Long 		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
95f564de00SScott Long 		break;
96f564de00SScott Long 	case CAMGETPASSTHRU_0x17:
97f564de00SScott Long 		cmd = CAMGETPASSTHRU;
98f564de00SScott Long 		error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp);
9925a2902cSScott Long 		break;
10092be6c51SNathan Whitehorn 	case CAMIOCOMMAND_0x18:
10192be6c51SNathan Whitehorn 		cmd = CAMIOCOMMAND;
10292be6c51SNathan Whitehorn 		error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
10392be6c51SNathan Whitehorn 		break;
10492be6c51SNathan Whitehorn 	case CAMGETPASSTHRU_0x18:
10592be6c51SNathan Whitehorn 		cmd = CAMGETPASSTHRU;
10692be6c51SNathan Whitehorn 		error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp);
10792be6c51SNathan Whitehorn 		break;
1088f9be1eeSAlexander Motin 	case CAMIOCOMMAND_0x19:
1098f9be1eeSAlexander Motin 		cmd = CAMIOCOMMAND;
1108f9be1eeSAlexander Motin 		error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
1118f9be1eeSAlexander Motin 		break;
1128f9be1eeSAlexander Motin 	case CAMGETPASSTHRU_0x19:
1138f9be1eeSAlexander Motin 		cmd = CAMGETPASSTHRU;
1148f9be1eeSAlexander Motin 		error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
1158f9be1eeSAlexander Motin 		break;
1168f9be1eeSAlexander Motin 	case CAMIOQUEUE_0x19:
1178f9be1eeSAlexander Motin 		cmd = CAMIOQUEUE;
1188f9be1eeSAlexander Motin 		error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
1198f9be1eeSAlexander Motin 		break;
1208f9be1eeSAlexander Motin 	case CAMIOGET_0x19:
1218f9be1eeSAlexander Motin 		cmd = CAMIOGET;
1228f9be1eeSAlexander Motin 		error = cam_compat_handle_0x19(dev, cmd, addr, flag, td, cbfnp);
1238f9be1eeSAlexander Motin 		break;
12425a2902cSScott Long 	default:
12525a2902cSScott Long 		error = ENOTTY;
12625a2902cSScott Long 	}
12725a2902cSScott Long 
12825a2902cSScott Long 	return (error);
12925a2902cSScott Long }
130f564de00SScott Long 
131f564de00SScott Long static int
132f564de00SScott Long cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
133f564de00SScott Long     struct thread *td, d_ioctl_t *cbfnp)
134f564de00SScott Long {
135f564de00SScott Long 	union ccb		*ccb;
136f564de00SScott Long 	struct ccb_hdr		*hdr;
137f564de00SScott Long 	struct ccb_hdr_0x17	*hdr17;
138f564de00SScott Long 	uint8_t			*ccbb, *ccbb17;
139f564de00SScott Long 	u_int			error;
140f564de00SScott Long 
141f564de00SScott Long 	hdr17 = (struct ccb_hdr_0x17 *)addr;
142f564de00SScott Long 	ccb = xpt_alloc_ccb();
143f564de00SScott Long 	hdr = &ccb->ccb_h;
144f564de00SScott Long 
145f564de00SScott Long 	hdr->pinfo = hdr17->pinfo;
146f564de00SScott Long 	hdr->xpt_links = hdr17->xpt_links;
147f564de00SScott Long 	hdr->sim_links = hdr17->sim_links;
148f564de00SScott Long 	hdr->periph_links = hdr17->periph_links;
149f564de00SScott Long 	hdr->retry_count = hdr17->retry_count;
150f564de00SScott Long 	hdr->cbfcnp = hdr17->cbfcnp;
151f564de00SScott Long 	hdr->func_code = hdr17->func_code;
152f564de00SScott Long 	hdr->status = hdr17->status;
153f564de00SScott Long 	hdr->path = hdr17->path;
154f564de00SScott Long 	hdr->path_id = hdr17->path_id;
155f564de00SScott Long 	hdr->target_id = hdr17->target_id;
156f564de00SScott Long 	hdr->target_lun = hdr17->target_lun;
157f564de00SScott Long 	hdr->flags = hdr17->flags;
158f564de00SScott Long 	hdr->xflags = 0;
159f564de00SScott Long 	hdr->periph_priv = hdr17->periph_priv;
160f564de00SScott Long 	hdr->sim_priv = hdr17->sim_priv;
161f564de00SScott Long 	hdr->timeout = hdr17->timeout;
162f564de00SScott Long 	hdr->softtimeout.tv_sec = 0;
163f564de00SScott Long 	hdr->softtimeout.tv_usec = 0;
164f564de00SScott Long 
165f564de00SScott Long 	ccbb = (uint8_t *)&hdr[1];
166f564de00SScott Long 	ccbb17 = (uint8_t *)&hdr17[1];
167d3c5b1feSAlexander Motin 	if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) {
168d3c5b1feSAlexander Motin 		struct ccb_trans_settings *cts;
169d3c5b1feSAlexander Motin 		struct ccb_trans_settings_0x17 *cts17;
170d3c5b1feSAlexander Motin 
171d3c5b1feSAlexander Motin 		cts = &ccb->cts;
172d3c5b1feSAlexander Motin 		cts17 = (struct ccb_trans_settings_0x17 *)hdr17;
173d3c5b1feSAlexander Motin 		cts->type = cts17->type;
174d3c5b1feSAlexander Motin 		cts->protocol = cts17->protocol;
175d3c5b1feSAlexander Motin 		cts->protocol_version = cts17->protocol_version;
176d3c5b1feSAlexander Motin 		cts->transport = cts17->transport;
177d3c5b1feSAlexander Motin 		cts->transport_version = cts17->transport_version;
178d3c5b1feSAlexander Motin 		bcopy(&cts17->proto_specific, &cts->proto_specific,
179d3c5b1feSAlexander Motin 		    sizeof(cts17->proto_specific));
180d3c5b1feSAlexander Motin 		bcopy(&cts17->xport_specific, &cts->xport_specific,
181d3c5b1feSAlexander Motin 		    sizeof(cts17->xport_specific));
182d3c5b1feSAlexander Motin 	} else {
183f564de00SScott Long 		bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN);
184d3c5b1feSAlexander Motin 	}
185f564de00SScott Long 
1868f9be1eeSAlexander Motin 	error = cam_compat_handle_0x19(dev, cmd, (caddr_t)ccb, flag, td, cbfnp);
187f564de00SScott Long 
188f564de00SScott Long 	hdr17->pinfo = hdr->pinfo;
189f564de00SScott Long 	hdr17->xpt_links = hdr->xpt_links;
190f564de00SScott Long 	hdr17->sim_links = hdr->sim_links;
191f564de00SScott Long 	hdr17->periph_links = hdr->periph_links;
192f564de00SScott Long 	hdr17->retry_count = hdr->retry_count;
193f564de00SScott Long 	hdr17->cbfcnp = hdr->cbfcnp;
194f564de00SScott Long 	hdr17->func_code = hdr->func_code;
195f564de00SScott Long 	hdr17->status = hdr->status;
196f564de00SScott Long 	hdr17->path = hdr->path;
197f564de00SScott Long 	hdr17->path_id = hdr->path_id;
198f564de00SScott Long 	hdr17->target_id = hdr->target_id;
199f564de00SScott Long 	hdr17->target_lun = hdr->target_lun;
200f564de00SScott Long 	hdr17->flags = hdr->flags;
201f564de00SScott Long 	hdr17->periph_priv = hdr->periph_priv;
202f564de00SScott Long 	hdr17->sim_priv = hdr->sim_priv;
203f564de00SScott Long 	hdr17->timeout = hdr->timeout;
204f564de00SScott Long 
20592be6c51SNathan Whitehorn 	if (ccb->ccb_h.func_code == XPT_PATH_INQ) {
206f564de00SScott Long 		struct ccb_pathinq	*cpi;
207f564de00SScott Long 		struct ccb_pathinq_0x17 *cpi17;
208f564de00SScott Long 
20992be6c51SNathan Whitehorn 		/* The PATH_INQ only needs special handling on the way out */
210f564de00SScott Long 		cpi = &ccb->cpi;
211f564de00SScott Long 		cpi17 = (struct ccb_pathinq_0x17 *)hdr17;
212f564de00SScott Long 		cpi17->version_num = cpi->version_num;
213f564de00SScott Long 		cpi17->hba_inquiry = cpi->hba_inquiry;
2147af2f2c8SWarner Losh 		cpi17->target_sprt = (uint8_t)cpi->target_sprt;
2157af2f2c8SWarner Losh 		cpi17->hba_misc = (uint8_t)cpi->hba_misc;
216f564de00SScott Long 		cpi17->hba_eng_cnt = cpi->hba_eng_cnt;
217f564de00SScott Long 		bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN);
218f564de00SScott Long 		cpi17->max_target = cpi->max_target;
219f564de00SScott Long 		cpi17->max_lun = cpi->max_lun;
220f564de00SScott Long 		cpi17->async_flags = cpi->async_flags;
221f564de00SScott Long 		cpi17->hpath_id = cpi->hpath_id;
222f564de00SScott Long 		cpi17->initiator_id = cpi->initiator_id;
223f564de00SScott Long 		bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN);
224f564de00SScott Long 		bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN);
225f564de00SScott Long 		bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN);
226f564de00SScott Long 		cpi17->unit_number = cpi->unit_number;
227f564de00SScott Long 		cpi17->bus_id = cpi->bus_id;
228f564de00SScott Long 		cpi17->base_transfer_speed = cpi->base_transfer_speed;
229f564de00SScott Long 		cpi17->protocol = cpi->protocol;
230f564de00SScott Long 		cpi17->protocol_version = cpi->protocol_version;
231f564de00SScott Long 		cpi17->transport = cpi->transport;
232f564de00SScott Long 		cpi17->transport_version = cpi->transport_version;
233f564de00SScott Long 		bcopy(&cpi->xport_specific, &cpi17->xport_specific,
234f564de00SScott Long 		    PATHINQ_SETTINGS_SIZE);
235f564de00SScott Long 		cpi17->maxio = cpi->maxio;
236f564de00SScott Long 		cpi17->hba_vendor = cpi->hba_vendor;
237f564de00SScott Long 		cpi17->hba_device = cpi->hba_device;
238f564de00SScott Long 		cpi17->hba_subvendor = cpi->hba_subvendor;
239f564de00SScott Long 		cpi17->hba_subdevice = cpi->hba_subdevice;
240d3c5b1feSAlexander Motin 	} else if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) {
241d3c5b1feSAlexander Motin 		struct ccb_trans_settings *cts;
242d3c5b1feSAlexander Motin 		struct ccb_trans_settings_0x17 *cts17;
243d3c5b1feSAlexander Motin 
244d3c5b1feSAlexander Motin 		cts = &ccb->cts;
245d3c5b1feSAlexander Motin 		cts17 = (struct ccb_trans_settings_0x17 *)hdr17;
24670612504SAlexander Motin 		cts17->type = cts->type;
247d3c5b1feSAlexander Motin 		cts17->protocol = cts->protocol;
248d3c5b1feSAlexander Motin 		cts17->protocol_version = cts->protocol_version;
249d3c5b1feSAlexander Motin 		cts17->transport = cts->transport;
250d3c5b1feSAlexander Motin 		cts17->transport_version = cts->transport_version;
251d3c5b1feSAlexander Motin 		bcopy(&cts->proto_specific, &cts17->proto_specific,
252d3c5b1feSAlexander Motin 		    sizeof(cts17->proto_specific));
253d3c5b1feSAlexander Motin 		bcopy(&cts->xport_specific, &cts17->xport_specific,
254d3c5b1feSAlexander Motin 		    sizeof(cts17->xport_specific));
25592be6c51SNathan Whitehorn 	} else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
25692be6c51SNathan Whitehorn 		/* Copy the rest of the header over */
25792be6c51SNathan Whitehorn 		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
25892be6c51SNathan Whitehorn 
25992be6c51SNathan Whitehorn 		cam_compat_translate_dev_match_0x18(ccb);
26092be6c51SNathan Whitehorn 	} else {
26192be6c51SNathan Whitehorn 		bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN);
262f564de00SScott Long 	}
263f564de00SScott Long 
264f564de00SScott Long 	xpt_free_ccb(ccb);
265f564de00SScott Long 
266f564de00SScott Long 	return (error);
267f564de00SScott Long }
26892be6c51SNathan Whitehorn 
26992be6c51SNathan Whitehorn static int
27092be6c51SNathan Whitehorn cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
27192be6c51SNathan Whitehorn     struct thread *td, d_ioctl_t *cbfnp)
27292be6c51SNathan Whitehorn {
27392be6c51SNathan Whitehorn 	union ccb		*ccb;
27492be6c51SNathan Whitehorn 	struct ccb_hdr		*hdr;
27592be6c51SNathan Whitehorn 	struct ccb_hdr_0x18	*hdr18;
27692be6c51SNathan Whitehorn 	uint8_t			*ccbb, *ccbb18;
27792be6c51SNathan Whitehorn 	u_int			error;
27892be6c51SNathan Whitehorn 
27992be6c51SNathan Whitehorn 	hdr18 = (struct ccb_hdr_0x18 *)addr;
28092be6c51SNathan Whitehorn 	ccb = xpt_alloc_ccb();
28192be6c51SNathan Whitehorn 	hdr = &ccb->ccb_h;
28292be6c51SNathan Whitehorn 
28392be6c51SNathan Whitehorn 	hdr->pinfo = hdr18->pinfo;
28492be6c51SNathan Whitehorn 	hdr->xpt_links = hdr18->xpt_links;
28592be6c51SNathan Whitehorn 	hdr->sim_links = hdr18->sim_links;
28692be6c51SNathan Whitehorn 	hdr->periph_links = hdr18->periph_links;
28792be6c51SNathan Whitehorn 	hdr->retry_count = hdr18->retry_count;
28892be6c51SNathan Whitehorn 	hdr->cbfcnp = hdr18->cbfcnp;
28992be6c51SNathan Whitehorn 	hdr->func_code = hdr18->func_code;
29092be6c51SNathan Whitehorn 	hdr->status = hdr18->status;
29192be6c51SNathan Whitehorn 	hdr->path = hdr18->path;
29292be6c51SNathan Whitehorn 	hdr->path_id = hdr18->path_id;
29392be6c51SNathan Whitehorn 	hdr->target_id = hdr18->target_id;
29492be6c51SNathan Whitehorn 	hdr->target_lun = hdr18->target_lun;
29592be6c51SNathan Whitehorn 	if (hdr18->xflags & CAM_EXTLUN_VALID_0x18)
29692be6c51SNathan Whitehorn 		hdr->target_lun = hdr18->ext_lun;
29792be6c51SNathan Whitehorn 	hdr->flags = hdr18->flags;
29892be6c51SNathan Whitehorn 	hdr->xflags = hdr18->xflags;
29992be6c51SNathan Whitehorn 	hdr->periph_priv = hdr18->periph_priv;
30092be6c51SNathan Whitehorn 	hdr->sim_priv = hdr18->sim_priv;
30192be6c51SNathan Whitehorn 	hdr->timeout = hdr18->timeout;
30292be6c51SNathan Whitehorn 	hdr->softtimeout.tv_sec = 0;
30392be6c51SNathan Whitehorn 	hdr->softtimeout.tv_usec = 0;
30492be6c51SNathan Whitehorn 
30592be6c51SNathan Whitehorn 	ccbb = (uint8_t *)&hdr[1];
30692be6c51SNathan Whitehorn 	ccbb18 = (uint8_t *)&hdr18[1];
307d3c5b1feSAlexander Motin 	if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) {
308d3c5b1feSAlexander Motin 		struct ccb_trans_settings *cts;
309d3c5b1feSAlexander Motin 		struct ccb_trans_settings_0x18 *cts18;
310d3c5b1feSAlexander Motin 
311d3c5b1feSAlexander Motin 		cts = &ccb->cts;
312d3c5b1feSAlexander Motin 		cts18 = (struct ccb_trans_settings_0x18 *)hdr18;
313d3c5b1feSAlexander Motin 		cts->type = cts18->type;
314d3c5b1feSAlexander Motin 		cts->protocol = cts18->protocol;
315d3c5b1feSAlexander Motin 		cts->protocol_version = cts18->protocol_version;
316d3c5b1feSAlexander Motin 		cts->transport = cts18->transport;
317d3c5b1feSAlexander Motin 		cts->transport_version = cts18->transport_version;
318d3c5b1feSAlexander Motin 		bcopy(&cts18->proto_specific, &cts->proto_specific,
319d3c5b1feSAlexander Motin 		    sizeof(cts18->proto_specific));
320d3c5b1feSAlexander Motin 		bcopy(&cts18->xport_specific, &cts->xport_specific,
321d3c5b1feSAlexander Motin 		    sizeof(cts18->xport_specific));
322d3c5b1feSAlexander Motin 	} else {
32392be6c51SNathan Whitehorn 		bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN);
324d3c5b1feSAlexander Motin 	}
32592be6c51SNathan Whitehorn 
3268f9be1eeSAlexander Motin 	error = cam_compat_handle_0x19(dev, cmd, (caddr_t)ccb, flag, td, cbfnp);
32792be6c51SNathan Whitehorn 
32892be6c51SNathan Whitehorn 	hdr18->pinfo = hdr->pinfo;
32992be6c51SNathan Whitehorn 	hdr18->xpt_links = hdr->xpt_links;
33092be6c51SNathan Whitehorn 	hdr18->sim_links = hdr->sim_links;
33192be6c51SNathan Whitehorn 	hdr18->periph_links = hdr->periph_links;
33292be6c51SNathan Whitehorn 	hdr18->retry_count = hdr->retry_count;
33392be6c51SNathan Whitehorn 	hdr18->cbfcnp = hdr->cbfcnp;
33492be6c51SNathan Whitehorn 	hdr18->func_code = hdr->func_code;
33592be6c51SNathan Whitehorn 	hdr18->status = hdr->status;
33692be6c51SNathan Whitehorn 	hdr18->path = hdr->path;
33792be6c51SNathan Whitehorn 	hdr18->path_id = hdr->path_id;
33892be6c51SNathan Whitehorn 	hdr18->target_id = hdr->target_id;
33992be6c51SNathan Whitehorn 	hdr18->target_lun = hdr->target_lun;
34092be6c51SNathan Whitehorn 	hdr18->ext_lun = hdr->target_lun;
34192be6c51SNathan Whitehorn 	hdr18->flags = hdr->flags;
34292be6c51SNathan Whitehorn 	hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18;
34392be6c51SNathan Whitehorn 	hdr18->periph_priv = hdr->periph_priv;
34492be6c51SNathan Whitehorn 	hdr18->sim_priv = hdr->sim_priv;
34592be6c51SNathan Whitehorn 	hdr18->timeout = hdr->timeout;
34692be6c51SNathan Whitehorn 
347d3c5b1feSAlexander Motin 	if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) {
348d3c5b1feSAlexander Motin 		struct ccb_trans_settings *cts;
349d3c5b1feSAlexander Motin 		struct ccb_trans_settings_0x18 *cts18;
35092be6c51SNathan Whitehorn 
351d3c5b1feSAlexander Motin 		cts = &ccb->cts;
352d3c5b1feSAlexander Motin 		cts18 = (struct ccb_trans_settings_0x18 *)hdr18;
35370612504SAlexander Motin 		cts18->type = cts->type;
354d3c5b1feSAlexander Motin 		cts18->protocol = cts->protocol;
355d3c5b1feSAlexander Motin 		cts18->protocol_version = cts->protocol_version;
356d3c5b1feSAlexander Motin 		cts18->transport = cts->transport;
357d3c5b1feSAlexander Motin 		cts18->transport_version = cts->transport_version;
358d3c5b1feSAlexander Motin 		bcopy(&cts->proto_specific, &cts18->proto_specific,
359d3c5b1feSAlexander Motin 		    sizeof(cts18->proto_specific));
360d3c5b1feSAlexander Motin 		bcopy(&cts->xport_specific, &cts18->xport_specific,
361d3c5b1feSAlexander Motin 		    sizeof(cts18->xport_specific));
362d3c5b1feSAlexander Motin 	} else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) {
363d3c5b1feSAlexander Motin 		bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
36492be6c51SNathan Whitehorn 		cam_compat_translate_dev_match_0x18(ccb);
365d3c5b1feSAlexander Motin 	} else {
366d3c5b1feSAlexander Motin 		bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN);
367d3c5b1feSAlexander Motin 	}
36892be6c51SNathan Whitehorn 
36992be6c51SNathan Whitehorn 	xpt_free_ccb(ccb);
37092be6c51SNathan Whitehorn 
37192be6c51SNathan Whitehorn 	return (error);
37292be6c51SNathan Whitehorn }
37392be6c51SNathan Whitehorn 
37492be6c51SNathan Whitehorn static int
37592be6c51SNathan Whitehorn cam_compat_translate_dev_match_0x18(union ccb *ccb)
37692be6c51SNathan Whitehorn {
37792be6c51SNathan Whitehorn 	struct dev_match_result		*dm;
37892be6c51SNathan Whitehorn 	struct dev_match_result_0x18	*dm18;
37992be6c51SNathan Whitehorn 	struct cam_periph_map_info	mapinfo;
380*d068ea16SMark Johnston 	int error, i;
38192be6c51SNathan Whitehorn 
38292be6c51SNathan Whitehorn 	/* Remap the CCB into kernel address space */
38392be6c51SNathan Whitehorn 	bzero(&mapinfo, sizeof(mapinfo));
384*d068ea16SMark Johnston 	error = cam_periph_mapmem(ccb, &mapinfo, maxphys);
385*d068ea16SMark Johnston 	if (error != 0)
386*d068ea16SMark Johnston 		return (error);
38792be6c51SNathan Whitehorn 
38892be6c51SNathan Whitehorn 	dm = ccb->cdm.matches;
38992be6c51SNathan Whitehorn 	/* Translate in-place: old fields are smaller */
39092be6c51SNathan Whitehorn 	dm18 = (struct dev_match_result_0x18 *)(dm);
39192be6c51SNathan Whitehorn 
39292be6c51SNathan Whitehorn 	for (i = 0; i < ccb->cdm.num_matches; i++) {
39392be6c51SNathan Whitehorn 		dm18[i].type = dm[i].type;
39492be6c51SNathan Whitehorn 		switch (dm[i].type) {
39592be6c51SNathan Whitehorn 		case DEV_MATCH_PERIPH:
39692be6c51SNathan Whitehorn 			memcpy(&dm18[i].result.periph_result.periph_name,
39792be6c51SNathan Whitehorn 			    &dm[i].result.periph_result.periph_name,
39892be6c51SNathan Whitehorn 			    DEV_IDLEN);
39992be6c51SNathan Whitehorn 			dm18[i].result.periph_result.unit_number =
40092be6c51SNathan Whitehorn 			   dm[i].result.periph_result.unit_number;
40192be6c51SNathan Whitehorn 			dm18[i].result.periph_result.path_id =
40292be6c51SNathan Whitehorn 			   dm[i].result.periph_result.path_id;
40392be6c51SNathan Whitehorn 			dm18[i].result.periph_result.target_id =
40492be6c51SNathan Whitehorn 			   dm[i].result.periph_result.target_id;
40592be6c51SNathan Whitehorn 			dm18[i].result.periph_result.target_lun =
40692be6c51SNathan Whitehorn 			   dm[i].result.periph_result.target_lun;
40792be6c51SNathan Whitehorn 			break;
40892be6c51SNathan Whitehorn 		case DEV_MATCH_DEVICE:
40992be6c51SNathan Whitehorn 			dm18[i].result.device_result.path_id =
41092be6c51SNathan Whitehorn 			   dm[i].result.device_result.path_id;
41192be6c51SNathan Whitehorn 			dm18[i].result.device_result.target_id =
41292be6c51SNathan Whitehorn 			   dm[i].result.device_result.target_id;
41392be6c51SNathan Whitehorn 			dm18[i].result.device_result.target_lun =
41492be6c51SNathan Whitehorn 			   dm[i].result.device_result.target_lun;
41592be6c51SNathan Whitehorn 			dm18[i].result.device_result.protocol =
41692be6c51SNathan Whitehorn 			   dm[i].result.device_result.protocol;
41792be6c51SNathan Whitehorn 			memcpy(&dm18[i].result.device_result.inq_data,
41892be6c51SNathan Whitehorn 			    &dm[i].result.device_result.inq_data,
41992be6c51SNathan Whitehorn 			    sizeof(struct scsi_inquiry_data));
42092be6c51SNathan Whitehorn 			memcpy(&dm18[i].result.device_result.ident_data,
42192be6c51SNathan Whitehorn 			    &dm[i].result.device_result.ident_data,
42292be6c51SNathan Whitehorn 			    sizeof(struct ata_params));
42392be6c51SNathan Whitehorn 			dm18[i].result.device_result.flags =
42492be6c51SNathan Whitehorn 			   dm[i].result.device_result.flags;
42592be6c51SNathan Whitehorn 			break;
42692be6c51SNathan Whitehorn 		case DEV_MATCH_BUS:
42792be6c51SNathan Whitehorn 			memcpy(&dm18[i].result.bus_result,
42892be6c51SNathan Whitehorn 			    &dm[i].result.bus_result,
42992be6c51SNathan Whitehorn 			    sizeof(struct bus_match_result));
43092be6c51SNathan Whitehorn 			break;
43192be6c51SNathan Whitehorn 		}
43292be6c51SNathan Whitehorn 	}
43392be6c51SNathan Whitehorn 
434*d068ea16SMark Johnston 	return (cam_periph_unmapmem(ccb, &mapinfo));
43592be6c51SNathan Whitehorn }
4368f9be1eeSAlexander Motin 
4378f9be1eeSAlexander Motin static int
4388f9be1eeSAlexander Motin cam_compat_handle_0x19(struct cdev *dev, u_long cmd, caddr_t addr, int flag,
4398f9be1eeSAlexander Motin     struct thread *td, d_ioctl_t *cbfnp)
4408f9be1eeSAlexander Motin {
4418f9be1eeSAlexander Motin 	struct cam_periph_map_info mapinfo;
442*d068ea16SMark Johnston 	union ccb *ccb = (union ccb *)addr;
443*d068ea16SMark Johnston 	int error;
4448f9be1eeSAlexander Motin 
4458f9be1eeSAlexander Motin 	if (cmd == CAMIOCOMMAND && ccb->ccb_h.func_code == XPT_DEV_MATCH) {
4468f9be1eeSAlexander Motin 		bzero(&mapinfo, sizeof(mapinfo));
447*d068ea16SMark Johnston 		error = cam_periph_mapmem(ccb, &mapinfo, maxphys);
448*d068ea16SMark Johnston 		if (error != 0)
449*d068ea16SMark Johnston 			return (error);
4508f9be1eeSAlexander Motin 		for (int i = 0; i < ccb->cdm.num_patterns; i++) {
4518f9be1eeSAlexander Motin 			struct dev_match_pattern *p = &ccb->cdm.patterns[i];
4528f9be1eeSAlexander Motin 
4538f9be1eeSAlexander Motin 			if (p->type == DEV_MATCH_BUS &&
4548f9be1eeSAlexander Motin 			    p->pattern.bus_pattern.flags == 0x00f)
4558f9be1eeSAlexander Motin 				p->pattern.bus_pattern.flags = BUS_MATCH_ANY;
4568f9be1eeSAlexander Motin 			if (p->type == DEV_MATCH_DEVICE &&
4578f9be1eeSAlexander Motin 			    p->pattern.device_pattern.flags == 0x00f)
4588f9be1eeSAlexander Motin 				p->pattern.device_pattern.flags = DEV_MATCH_ANY;
4598f9be1eeSAlexander Motin 			if (p->type == DEV_MATCH_PERIPH &&
4608f9be1eeSAlexander Motin 			    p->pattern.periph_pattern.flags == 0x01f)
4618f9be1eeSAlexander Motin 				p->pattern.periph_pattern.flags = PERIPH_MATCH_ANY;
4628f9be1eeSAlexander Motin 		}
463*d068ea16SMark Johnston 		error = cam_periph_unmapmem(ccb, &mapinfo);
464*d068ea16SMark Johnston 		if (error != 0)
465*d068ea16SMark Johnston 			return (error);
4668f9be1eeSAlexander Motin 	}
4678f9be1eeSAlexander Motin 	return ((cbfnp)(dev, cmd, addr, flag, td));
4688f9be1eeSAlexander Motin }
469