1 /*- 2 * CAM ioctl compatibility shims 3 * 4 * Copyright (c) 2013 Scott Long 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. 13 * 2. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 * 28 */ 29 30 #include <sys/cdefs.h> 31 __FBSDID("$FreeBSD$"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/types.h> 36 #include <sys/kernel.h> 37 #include <sys/conf.h> 38 #include <sys/fcntl.h> 39 40 #include <sys/lock.h> 41 #include <sys/mutex.h> 42 #include <sys/sysctl.h> 43 #include <sys/kthread.h> 44 45 #include <cam/cam.h> 46 #include <cam/cam_ccb.h> 47 #include <cam/cam_xpt.h> 48 #include <cam/cam_compat.h> 49 50 #include <cam/scsi/scsi_pass.h> 51 52 #include "opt_cam.h" 53 54 static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, 55 int flag, struct thread *td, d_ioctl_t *cbfnp); 56 57 int 58 cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 59 struct thread *td, d_ioctl_t *cbfnp) 60 { 61 int error; 62 63 switch (cmd) { 64 case CAMIOCOMMAND_0x16: 65 { 66 union ccb *ccb; 67 68 ccb = (union ccb *)addr; 69 if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) { 70 ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16; 71 ccb->ccb_h.flags |= CAM_DATA_SG_PADDR; 72 } 73 if (ccb->ccb_h.flags & CAM_DATA_PHYS_0x16) { 74 ccb->ccb_h.flags &= ~CAM_DATA_PHYS_0x16; 75 ccb->ccb_h.flags |= CAM_DATA_PADDR; 76 } 77 if (ccb->ccb_h.flags & CAM_SCATTER_VALID_0x16) { 78 ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16; 79 ccb->ccb_h.flags |= CAM_DATA_SG; 80 } 81 cmd = CAMIOCOMMAND; 82 error = (cbfnp)(dev, cmd, addr, flag, td); 83 break; 84 } 85 case CAMGETPASSTHRU_0x16: 86 cmd = CAMGETPASSTHRU; 87 error = (cbfnp)(dev, cmd, addr, flag, td); 88 break; 89 case CAMIOCOMMAND_0x17: 90 cmd = CAMIOCOMMAND; 91 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp); 92 break; 93 case CAMGETPASSTHRU_0x17: 94 cmd = CAMGETPASSTHRU; 95 error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp); 96 break; 97 default: 98 error = ENOTTY; 99 } 100 101 return (error); 102 } 103 104 static int 105 cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag, 106 struct thread *td, d_ioctl_t *cbfnp) 107 { 108 union ccb *ccb; 109 struct ccb_hdr *hdr; 110 struct ccb_hdr_0x17 *hdr17; 111 uint8_t *ccbb, *ccbb17; 112 u_int error; 113 114 hdr17 = (struct ccb_hdr_0x17 *)addr; 115 ccb = xpt_alloc_ccb(); 116 hdr = &ccb->ccb_h; 117 118 hdr->pinfo = hdr17->pinfo; 119 hdr->xpt_links = hdr17->xpt_links; 120 hdr->sim_links = hdr17->sim_links; 121 hdr->periph_links = hdr17->periph_links; 122 hdr->retry_count = hdr17->retry_count; 123 hdr->cbfcnp = hdr17->cbfcnp; 124 hdr->func_code = hdr17->func_code; 125 hdr->status = hdr17->status; 126 hdr->path = hdr17->path; 127 hdr->path_id = hdr17->path_id; 128 hdr->target_id = hdr17->target_id; 129 hdr->target_lun = hdr17->target_lun; 130 hdr->ext_lun.lun64 = 0; 131 hdr->flags = hdr17->flags; 132 hdr->xflags = 0; 133 hdr->periph_priv = hdr17->periph_priv; 134 hdr->sim_priv = hdr17->sim_priv; 135 hdr->timeout = hdr17->timeout; 136 hdr->softtimeout.tv_sec = 0; 137 hdr->softtimeout.tv_usec = 0; 138 139 ccbb = (uint8_t *)&hdr[1]; 140 ccbb17 = (uint8_t *)&hdr17[1]; 141 bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN); 142 143 error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td); 144 145 hdr17->pinfo = hdr->pinfo; 146 hdr17->xpt_links = hdr->xpt_links; 147 hdr17->sim_links = hdr->sim_links; 148 hdr17->periph_links = hdr->periph_links; 149 hdr17->retry_count = hdr->retry_count; 150 hdr17->cbfcnp = hdr->cbfcnp; 151 hdr17->func_code = hdr->func_code; 152 hdr17->status = hdr->status; 153 hdr17->path = hdr->path; 154 hdr17->path_id = hdr->path_id; 155 hdr17->target_id = hdr->target_id; 156 hdr17->target_lun = hdr->target_lun; 157 hdr17->flags = hdr->flags; 158 hdr17->periph_priv = hdr->periph_priv; 159 hdr17->sim_priv = hdr->sim_priv; 160 hdr17->timeout = hdr->timeout; 161 162 /* The PATH_INQ only needs special handling on the way out */ 163 if (ccb->ccb_h.func_code != XPT_PATH_INQ) { 164 bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN); 165 } else { 166 struct ccb_pathinq *cpi; 167 struct ccb_pathinq_0x17 *cpi17; 168 169 cpi = &ccb->cpi; 170 cpi17 = (struct ccb_pathinq_0x17 *)hdr17; 171 cpi17->version_num = cpi->version_num; 172 cpi17->hba_inquiry = cpi->hba_inquiry; 173 cpi17->target_sprt = (u_int8_t)cpi->target_sprt; 174 cpi17->hba_misc = (u_int8_t)cpi->hba_misc; 175 cpi17->hba_eng_cnt = cpi->hba_eng_cnt; 176 bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN); 177 cpi17->max_target = cpi->max_target; 178 cpi17->max_lun = cpi->max_lun; 179 cpi17->async_flags = cpi->async_flags; 180 cpi17->hpath_id = cpi->hpath_id; 181 cpi17->initiator_id = cpi->initiator_id; 182 bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN); 183 bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN); 184 bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN); 185 cpi17->unit_number = cpi->unit_number; 186 cpi17->bus_id = cpi->bus_id; 187 cpi17->base_transfer_speed = cpi->base_transfer_speed; 188 cpi17->protocol = cpi->protocol; 189 cpi17->protocol_version = cpi->protocol_version; 190 cpi17->transport = cpi->transport; 191 cpi17->transport_version = cpi->transport_version; 192 bcopy(&cpi->xport_specific, &cpi17->xport_specific, 193 PATHINQ_SETTINGS_SIZE); 194 cpi17->maxio = cpi->maxio; 195 cpi17->hba_vendor = cpi->hba_vendor; 196 cpi17->hba_device = cpi->hba_device; 197 cpi17->hba_subvendor = cpi->hba_subvendor; 198 cpi17->hba_subdevice = cpi->hba_subdevice; 199 } 200 201 xpt_free_ccb(ccb); 202 203 return (error); 204 } 205