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