Index: head/sys/cam/cam_compat.c =================================================================== --- head/sys/cam/cam_compat.c (revision 306746) +++ head/sys/cam/cam_compat.c (revision 306747) @@ -1,355 +1,421 @@ /*- * 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 __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "opt_cam.h" static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp); static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp); static int cam_compat_translate_dev_match_0x18(union ccb *ccb); int cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp) { int error; switch (cmd) { case CAMIOCOMMAND_0x16: { struct ccb_hdr_0x17 *hdr17; hdr17 = (struct ccb_hdr_0x17 *)addr; if (hdr17->flags & CAM_SG_LIST_PHYS_0x16) { hdr17->flags &= ~CAM_SG_LIST_PHYS_0x16; hdr17->flags |= CAM_DATA_SG_PADDR; } if (hdr17->flags & CAM_DATA_PHYS_0x16) { hdr17->flags &= ~CAM_DATA_PHYS_0x16; hdr17->flags |= CAM_DATA_PADDR; } if (hdr17->flags & CAM_SCATTER_VALID_0x16) { hdr17->flags &= CAM_SCATTER_VALID_0x16; hdr17->flags |= CAM_DATA_SG; } cmd = CAMIOCOMMAND; error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp); break; } case CAMGETPASSTHRU_0x16: cmd = CAMGETPASSTHRU; error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp); break; case CAMIOCOMMAND_0x17: cmd = CAMIOCOMMAND; error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp); break; case CAMGETPASSTHRU_0x17: cmd = CAMGETPASSTHRU; error = cam_compat_handle_0x17(dev, cmd, addr, flag, td, cbfnp); break; case CAMIOCOMMAND_0x18: cmd = CAMIOCOMMAND; error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp); break; case CAMGETPASSTHRU_0x18: cmd = CAMGETPASSTHRU; error = cam_compat_handle_0x18(dev, cmd, addr, flag, td, cbfnp); break; default: error = ENOTTY; } return (error); } static int cam_compat_handle_0x17(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp) { union ccb *ccb; struct ccb_hdr *hdr; struct ccb_hdr_0x17 *hdr17; uint8_t *ccbb, *ccbb17; u_int error; hdr17 = (struct ccb_hdr_0x17 *)addr; ccb = xpt_alloc_ccb(); hdr = &ccb->ccb_h; hdr->pinfo = hdr17->pinfo; hdr->xpt_links = hdr17->xpt_links; hdr->sim_links = hdr17->sim_links; hdr->periph_links = hdr17->periph_links; hdr->retry_count = hdr17->retry_count; hdr->cbfcnp = hdr17->cbfcnp; hdr->func_code = hdr17->func_code; hdr->status = hdr17->status; hdr->path = hdr17->path; hdr->path_id = hdr17->path_id; hdr->target_id = hdr17->target_id; hdr->target_lun = hdr17->target_lun; hdr->flags = hdr17->flags; hdr->xflags = 0; hdr->periph_priv = hdr17->periph_priv; hdr->sim_priv = hdr17->sim_priv; hdr->timeout = hdr17->timeout; hdr->softtimeout.tv_sec = 0; hdr->softtimeout.tv_usec = 0; ccbb = (uint8_t *)&hdr[1]; ccbb17 = (uint8_t *)&hdr17[1]; - bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN); + if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) { + struct ccb_trans_settings *cts; + struct ccb_trans_settings_0x17 *cts17; + cts = &ccb->cts; + cts17 = (struct ccb_trans_settings_0x17 *)hdr17; + cts->type = cts17->type; + cts->protocol = cts17->protocol; + cts->protocol_version = cts17->protocol_version; + cts->transport = cts17->transport; + cts->transport_version = cts17->transport_version; + bcopy(&cts17->proto_specific, &cts->proto_specific, + sizeof(cts17->proto_specific)); + bcopy(&cts17->xport_specific, &cts->xport_specific, + sizeof(cts17->xport_specific)); + } else { + bcopy(ccbb17, ccbb, CAM_0X17_DATA_LEN); + } + error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td); hdr17->pinfo = hdr->pinfo; hdr17->xpt_links = hdr->xpt_links; hdr17->sim_links = hdr->sim_links; hdr17->periph_links = hdr->periph_links; hdr17->retry_count = hdr->retry_count; hdr17->cbfcnp = hdr->cbfcnp; hdr17->func_code = hdr->func_code; hdr17->status = hdr->status; hdr17->path = hdr->path; hdr17->path_id = hdr->path_id; hdr17->target_id = hdr->target_id; hdr17->target_lun = hdr->target_lun; hdr17->flags = hdr->flags; hdr17->periph_priv = hdr->periph_priv; hdr17->sim_priv = hdr->sim_priv; hdr17->timeout = hdr->timeout; if (ccb->ccb_h.func_code == XPT_PATH_INQ) { struct ccb_pathinq *cpi; struct ccb_pathinq_0x17 *cpi17; /* The PATH_INQ only needs special handling on the way out */ cpi = &ccb->cpi; cpi17 = (struct ccb_pathinq_0x17 *)hdr17; cpi17->version_num = cpi->version_num; cpi17->hba_inquiry = cpi->hba_inquiry; cpi17->target_sprt = (u_int8_t)cpi->target_sprt; cpi17->hba_misc = (u_int8_t)cpi->hba_misc; cpi17->hba_eng_cnt = cpi->hba_eng_cnt; bcopy(&cpi->vuhba_flags[0], &cpi17->vuhba_flags[0], VUHBALEN); cpi17->max_target = cpi->max_target; cpi17->max_lun = cpi->max_lun; cpi17->async_flags = cpi->async_flags; cpi17->hpath_id = cpi->hpath_id; cpi17->initiator_id = cpi->initiator_id; bcopy(&cpi->sim_vid[0], &cpi17->sim_vid[0], SIM_IDLEN); bcopy(&cpi->hba_vid[0], &cpi17->hba_vid[0], HBA_IDLEN); bcopy(&cpi->dev_name[0], &cpi17->dev_name[0], DEV_IDLEN); cpi17->unit_number = cpi->unit_number; cpi17->bus_id = cpi->bus_id; cpi17->base_transfer_speed = cpi->base_transfer_speed; cpi17->protocol = cpi->protocol; cpi17->protocol_version = cpi->protocol_version; cpi17->transport = cpi->transport; cpi17->transport_version = cpi->transport_version; bcopy(&cpi->xport_specific, &cpi17->xport_specific, PATHINQ_SETTINGS_SIZE); cpi17->maxio = cpi->maxio; cpi17->hba_vendor = cpi->hba_vendor; cpi17->hba_device = cpi->hba_device; cpi17->hba_subvendor = cpi->hba_subvendor; cpi17->hba_subdevice = cpi->hba_subdevice; + } else if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) { + struct ccb_trans_settings *cts; + struct ccb_trans_settings_0x17 *cts17; + + cts = &ccb->cts; + cts17 = (struct ccb_trans_settings_0x17 *)hdr17; + cts17->type = cts17->type; + cts17->protocol = cts->protocol; + cts17->protocol_version = cts->protocol_version; + cts17->transport = cts->transport; + cts17->transport_version = cts->transport_version; + bcopy(&cts->proto_specific, &cts17->proto_specific, + sizeof(cts17->proto_specific)); + bcopy(&cts->xport_specific, &cts17->xport_specific, + sizeof(cts17->xport_specific)); } else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) { /* Copy the rest of the header over */ bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN); cam_compat_translate_dev_match_0x18(ccb); } else { bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN); } xpt_free_ccb(ccb); return (error); } static int cam_compat_handle_0x18(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp) { union ccb *ccb; struct ccb_hdr *hdr; struct ccb_hdr_0x18 *hdr18; uint8_t *ccbb, *ccbb18; u_int error; hdr18 = (struct ccb_hdr_0x18 *)addr; ccb = xpt_alloc_ccb(); hdr = &ccb->ccb_h; hdr->pinfo = hdr18->pinfo; hdr->xpt_links = hdr18->xpt_links; hdr->sim_links = hdr18->sim_links; hdr->periph_links = hdr18->periph_links; hdr->retry_count = hdr18->retry_count; hdr->cbfcnp = hdr18->cbfcnp; hdr->func_code = hdr18->func_code; hdr->status = hdr18->status; hdr->path = hdr18->path; hdr->path_id = hdr18->path_id; hdr->target_id = hdr18->target_id; hdr->target_lun = hdr18->target_lun; if (hdr18->xflags & CAM_EXTLUN_VALID_0x18) hdr->target_lun = hdr18->ext_lun; hdr->flags = hdr18->flags; hdr->xflags = hdr18->xflags; hdr->periph_priv = hdr18->periph_priv; hdr->sim_priv = hdr18->sim_priv; hdr->timeout = hdr18->timeout; hdr->softtimeout.tv_sec = 0; hdr->softtimeout.tv_usec = 0; ccbb = (uint8_t *)&hdr[1]; ccbb18 = (uint8_t *)&hdr18[1]; - bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN); + if (ccb->ccb_h.func_code == XPT_SET_TRAN_SETTINGS) { + struct ccb_trans_settings *cts; + struct ccb_trans_settings_0x18 *cts18; + cts = &ccb->cts; + cts18 = (struct ccb_trans_settings_0x18 *)hdr18; + cts->type = cts18->type; + cts->protocol = cts18->protocol; + cts->protocol_version = cts18->protocol_version; + cts->transport = cts18->transport; + cts->transport_version = cts18->transport_version; + bcopy(&cts18->proto_specific, &cts->proto_specific, + sizeof(cts18->proto_specific)); + bcopy(&cts18->xport_specific, &cts->xport_specific, + sizeof(cts18->xport_specific)); + } else { + bcopy(ccbb18, ccbb, CAM_0X18_DATA_LEN); + } + error = (cbfnp)(dev, cmd, (caddr_t)ccb, flag, td); hdr18->pinfo = hdr->pinfo; hdr18->xpt_links = hdr->xpt_links; hdr18->sim_links = hdr->sim_links; hdr18->periph_links = hdr->periph_links; hdr18->retry_count = hdr->retry_count; hdr18->cbfcnp = hdr->cbfcnp; hdr18->func_code = hdr->func_code; hdr18->status = hdr->status; hdr18->path = hdr->path; hdr18->path_id = hdr->path_id; hdr18->target_id = hdr->target_id; hdr18->target_lun = hdr->target_lun; hdr18->ext_lun = hdr->target_lun; hdr18->flags = hdr->flags; hdr18->xflags = hdr->xflags | CAM_EXTLUN_VALID_0x18; hdr18->periph_priv = hdr->periph_priv; hdr18->sim_priv = hdr->sim_priv; hdr18->timeout = hdr->timeout; - bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN); + if (ccb->ccb_h.func_code == XPT_GET_TRAN_SETTINGS) { + struct ccb_trans_settings *cts; + struct ccb_trans_settings_0x18 *cts18; - if (ccb->ccb_h.func_code == XPT_DEV_MATCH) + cts = &ccb->cts; + cts18 = (struct ccb_trans_settings_0x18 *)hdr18; + cts18->type = cts18->type; + cts18->protocol = cts->protocol; + cts18->protocol_version = cts->protocol_version; + cts18->transport = cts->transport; + cts18->transport_version = cts->transport_version; + bcopy(&cts->proto_specific, &cts18->proto_specific, + sizeof(cts18->proto_specific)); + bcopy(&cts->xport_specific, &cts18->xport_specific, + sizeof(cts18->xport_specific)); + } else if (ccb->ccb_h.func_code == XPT_DEV_MATCH) { + bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN); cam_compat_translate_dev_match_0x18(ccb); + } else { + bcopy(ccbb, ccbb18, CAM_0X18_DATA_LEN); + } xpt_free_ccb(ccb); return (error); } static int cam_compat_translate_dev_match_0x18(union ccb *ccb) { struct dev_match_result *dm; struct dev_match_result_0x18 *dm18; struct cam_periph_map_info mapinfo; int i; /* Remap the CCB into kernel address space */ bzero(&mapinfo, sizeof(mapinfo)); cam_periph_mapmem(ccb, &mapinfo, MAXPHYS); dm = ccb->cdm.matches; /* Translate in-place: old fields are smaller */ dm18 = (struct dev_match_result_0x18 *)(dm); for (i = 0; i < ccb->cdm.num_matches; i++) { dm18[i].type = dm[i].type; switch (dm[i].type) { case DEV_MATCH_PERIPH: memcpy(&dm18[i].result.periph_result.periph_name, &dm[i].result.periph_result.periph_name, DEV_IDLEN); dm18[i].result.periph_result.unit_number = dm[i].result.periph_result.unit_number; dm18[i].result.periph_result.path_id = dm[i].result.periph_result.path_id; dm18[i].result.periph_result.target_id = dm[i].result.periph_result.target_id; dm18[i].result.periph_result.target_lun = dm[i].result.periph_result.target_lun; break; case DEV_MATCH_DEVICE: dm18[i].result.device_result.path_id = dm[i].result.device_result.path_id; dm18[i].result.device_result.target_id = dm[i].result.device_result.target_id; dm18[i].result.device_result.target_lun = dm[i].result.device_result.target_lun; dm18[i].result.device_result.protocol = dm[i].result.device_result.protocol; memcpy(&dm18[i].result.device_result.inq_data, &dm[i].result.device_result.inq_data, sizeof(struct scsi_inquiry_data)); memcpy(&dm18[i].result.device_result.ident_data, &dm[i].result.device_result.ident_data, sizeof(struct ata_params)); dm18[i].result.device_result.flags = dm[i].result.device_result.flags; break; case DEV_MATCH_BUS: memcpy(&dm18[i].result.bus_result, &dm[i].result.bus_result, sizeof(struct bus_match_result)); break; } } cam_periph_unmapmem(ccb, &mapinfo); return (0); } Index: head/sys/cam/cam_compat.h =================================================================== --- head/sys/cam/cam_compat.h (revision 306746) +++ head/sys/cam/cam_compat.h (revision 306747) @@ -1,179 +1,223 @@ /*- * 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 /* No user-servicable parts in here. */ #ifdef _KERNEL int cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, int(*cbfnp)(struct cdev *, u_long, caddr_t, int, struct thread *)); /* 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 CAMIOCOMMAND_0x16 _IOC(IOC_INOUT, CAM_VERSION_0x16, 2, CAM_0X17_LEN) +#define CAMGETPASSTHRU_0x16 _IOC(IOC_INOUT, CAM_VERSION_0x16, 3, CAM_0X17_LEN) #define CAM_SCATTER_VALID_0x16 0x00000010 #define CAM_SG_LIST_PHYS_0x16 0x00040000 #define CAM_DATA_PHYS_0x16 0x00200000 /* Version 0x17 compatibility */ #define CAM_VERSION_0x17 0x17 struct ccb_hdr_0x17 { cam_pinfo pinfo; /* Info for priority scheduling */ camq_entry xpt_links; /* For chaining in the XPT layer */ camq_entry sim_links; /* For chaining in the SIM layer */ camq_entry periph_links; /* For chaining in the type driver */ u_int32_t retry_count; void (*cbfcnp)(struct cam_periph *, union ccb *); xpt_opcode func_code; /* XPT function code */ u_int32_t status; /* Status returned by CAM subsystem */ struct cam_path *path; /* Compiled path for this ccb */ path_id_t path_id; /* Path ID for the request */ target_id_t target_id; /* Target device ID */ u_int target_lun; /* Target LUN number */ u_int32_t flags; /* ccb_flags */ ccb_ppriv_area periph_priv; ccb_spriv_area sim_priv; u_int32_t timeout; /* Hard timeout value in seconds */ struct callout_handle timeout_ch; }; struct ccb_pathinq_0x17 { struct ccb_hdr_0x17 ccb_h; u_int8_t version_num; /* Version number for the SIM/HBA */ u_int8_t hba_inquiry; /* Mimic of INQ byte 7 for the HBA */ u_int8_t target_sprt; /* Flags for target mode support */ u_int8_t hba_misc; /* Misc HBA features */ u_int16_t hba_eng_cnt; /* HBA engine count */ /* Vendor Unique capabilities */ u_int8_t vuhba_flags[VUHBALEN]; u_int32_t max_target; /* Maximum supported Target */ u_int32_t max_lun; /* Maximum supported Lun */ u_int32_t async_flags; /* Installed Async handlers */ path_id_t hpath_id; /* Highest Path ID in the subsystem */ target_id_t initiator_id; /* ID of the HBA on the SCSI bus */ char sim_vid[SIM_IDLEN]; /* Vendor ID of the SIM */ char hba_vid[HBA_IDLEN]; /* Vendor ID of the HBA */ char dev_name[DEV_IDLEN];/* Device name for SIM */ u_int32_t unit_number; /* Unit number for SIM */ u_int32_t bus_id; /* Bus ID for SIM */ u_int32_t base_transfer_speed;/* Base bus speed in KB/sec */ cam_proto protocol; u_int protocol_version; cam_xport transport; u_int transport_version; union { struct ccb_pathinq_settings_spi spi; struct ccb_pathinq_settings_fc fc; struct ccb_pathinq_settings_sas sas; char ccb_pathinq_settings_opaque[PATHINQ_SETTINGS_SIZE]; } xport_specific; u_int maxio; /* Max supported I/O size, in bytes. */ u_int16_t hba_vendor; /* HBA vendor ID */ u_int16_t hba_device; /* HBA device ID */ u_int16_t hba_subvendor; /* HBA subvendor ID */ u_int16_t hba_subdevice; /* HBA subdevice ID */ }; -#define CAM_0X17_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr) + sizeof(struct ccb_hdr_0x17)) -#define CAM_0X17_DATA_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr_0x17)) +struct ccb_trans_settings_0x17 { + struct ccb_hdr_0x17 ccb_h; + cts_type type; /* Current or User settings */ + cam_proto protocol; + u_int protocol_version; + cam_xport transport; + u_int transport_version; + union { + u_int valid; /* Which fields to honor */ + struct ccb_trans_settings_ata ata; + struct ccb_trans_settings_scsi scsi; + } proto_specific; + union { + u_int valid; /* Which fields to honor */ + struct ccb_trans_settings_spi spi; + struct ccb_trans_settings_fc fc; + struct ccb_trans_settings_sas sas; + struct ccb_trans_settings_pata ata; + struct ccb_trans_settings_sata sata; + } xport_specific; +}; +#define CAM_0X17_DATA_LEN CAM_0X18_DATA_LEN +#define CAM_0X17_LEN (sizeof(struct ccb_hdr_0x17) + CAM_0X17_DATA_LEN) + #define CAMIOCOMMAND_0x17 _IOC(IOC_INOUT, CAM_VERSION_0x17, 2, CAM_0X17_LEN) #define CAMGETPASSTHRU_0x17 _IOC(IOC_INOUT, CAM_VERSION_0x17, 3, CAM_0X17_LEN) /* Version 0x18 compatibility */ #define CAM_VERSION_0x18 0x18 struct ccb_hdr_0x18 { cam_pinfo pinfo; /* Info for priority scheduling */ camq_entry xpt_links; /* For chaining in the XPT layer */ camq_entry sim_links; /* For chaining in the SIM layer */ camq_entry periph_links; /* For chaining in the type driver */ u_int32_t retry_count; void (*cbfcnp)(struct cam_periph *, union ccb *); xpt_opcode func_code; /* XPT function code */ u_int32_t status; /* Status returned by CAM subsystem */ struct cam_path *path; /* Compiled path for this ccb */ path_id_t path_id; /* Path ID for the request */ target_id_t target_id; /* Target device ID */ u_int target_lun; /* Target LUN number */ u_int64_t ext_lun; /* 64-bit LUN, more or less */ u_int32_t flags; /* ccb_flags */ u_int32_t xflags; /* extended ccb_flags */ ccb_ppriv_area periph_priv; ccb_spriv_area sim_priv; ccb_qos_area qos; u_int32_t timeout; /* Hard timeout value in seconds */ struct timeval softtimeout; /* Soft timeout value in sec + usec */ }; typedef enum { CAM_EXTLUN_VALID_0x18 = 0x00000001,/* 64bit lun field is valid */ } ccb_xflags_0x18; +struct ccb_trans_settings_0x18 { + struct ccb_hdr_0x18 ccb_h; + cts_type type; /* Current or User settings */ + cam_proto protocol; + u_int protocol_version; + cam_xport transport; + u_int transport_version; + union { + u_int valid; /* Which fields to honor */ + struct ccb_trans_settings_ata ata; + struct ccb_trans_settings_scsi scsi; + } proto_specific; + union { + u_int valid; /* Which fields to honor */ + struct ccb_trans_settings_spi spi; + struct ccb_trans_settings_fc fc; + struct ccb_trans_settings_sas sas; + struct ccb_trans_settings_pata ata; + struct ccb_trans_settings_sata sata; + } xport_specific; +}; + struct dev_match_result_0x18 { dev_match_type type; union { struct { char periph_name[DEV_IDLEN]; u_int32_t unit_number; path_id_t path_id; target_id_t target_id; u_int target_lun; } periph_result; struct { path_id_t path_id; target_id_t target_id; u_int target_lun; cam_proto protocol; struct scsi_inquiry_data inq_data; struct ata_params ident_data; dev_result_flags flags; } device_result; struct bus_match_result bus_result; } result; }; -#define CAM_0X18_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr) + sizeof(struct ccb_hdr_0x18)) -#define CAM_0X18_DATA_LEN (sizeof(union ccb) - sizeof(struct ccb_hdr_0x18)) +#define CAM_0X18_DATA_LEN (sizeof(union ccb) - 2*sizeof(void *) - sizeof(struct ccb_hdr)) +#define CAM_0X18_LEN (sizeof(struct ccb_hdr_0x18) + CAM_0X18_DATA_LEN) #define CAMIOCOMMAND_0x18 _IOC(IOC_INOUT, CAM_VERSION_0x18, 2, CAM_0X18_LEN) #define CAMGETPASSTHRU_0x18 _IOC(IOC_INOUT, CAM_VERSION_0x18, 3, CAM_0X18_LEN) #endif #endif