From owner-svn-src-head@FreeBSD.ORG Tue Sep 24 16:50:58 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 1FCDC3A8; Tue, 24 Sep 2013 16:50:58 +0000 (UTC) (envelope-from scottl@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 0BCF82A12; Tue, 24 Sep 2013 16:50:58 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r8OGowFI009043; Tue, 24 Sep 2013 16:50:58 GMT (envelope-from scottl@svn.freebsd.org) Received: (from scottl@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r8OGorvJ008976; Tue, 24 Sep 2013 16:50:53 GMT (envelope-from scottl@svn.freebsd.org) Message-Id: <201309241650.r8OGorvJ008976@svn.freebsd.org> From: Scott Long Date: Tue, 24 Sep 2013 16:50:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r255853 - in head/sys: cam cam/scsi dev/asr dev/firewire dev/hpt27xx dev/hptiop dev/hptmv dev/hptnr dev/hptrr dev/iir dev/tws X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 24 Sep 2013 16:50:58 -0000 Author: scottl Date: Tue Sep 24 16:50:53 2013 New Revision: 255853 URL: http://svnweb.freebsd.org/changeset/base/255853 Log: Update the CAM API for FreeBSD 10: - Remove the timeout_ch field. It's been deprecated since FreeBSD 7.0; MPSAFE drivers should be managing their own timeout storage. The remaining non-MPSAFE drivers have been modified to also manage their own storage, and should be considered for updating to MPSAFE (or removal) during the FreeBSD 10.x lifecycle. - Add fields related to soft timeouts and quality of service, to be used in upcoming work. - Add room for more flags in the CCB header and path_inq structures. - Begin support for extended 64-bit LUNs. - Bump the CAM version number to 0x18, but add compat shims. Tested with camcontrol and smartctl. Reviewed by: nathanw, ken, kib Approved by: re Obtained from: Netflix Modified: head/sys/cam/cam.h head/sys/cam/cam_ccb.h head/sys/cam/cam_compat.c head/sys/cam/cam_compat.h head/sys/cam/cam_xpt.c head/sys/cam/scsi/scsi_pass.c head/sys/dev/asr/asr.c head/sys/dev/firewire/sbp.c head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c head/sys/dev/hpt27xx/os_bsd.h head/sys/dev/hptiop/hptiop.c head/sys/dev/hptiop/hptiop.h head/sys/dev/hptmv/entry.c head/sys/dev/hptmv/osbsd.h head/sys/dev/hptnr/hptnr_osm_bsd.c head/sys/dev/hptnr/os_bsd.h head/sys/dev/hptrr/hptrr_osm_bsd.c head/sys/dev/hptrr/os_bsd.h head/sys/dev/iir/iir.c head/sys/dev/iir/iir.h head/sys/dev/tws/tws.c head/sys/dev/tws/tws_cam.c Modified: head/sys/cam/cam.h ============================================================================== --- head/sys/cam/cam.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/cam/cam.h Tue Sep 24 16:50:53 2013 (r255853) @@ -40,6 +40,10 @@ typedef u_int path_id_t; typedef u_int target_id_t; typedef u_int lun_id_t; +typedef union { + u_int64_t lun64; + u_int8_t lun[8]; +} lun64_id_t; #define CAM_XPT_PATH_ID ((path_id_t)~0) #define CAM_BUS_WILDCARD ((path_id_t)~0) @@ -120,69 +124,184 @@ enum { /* CAM Status field values */ typedef enum { - CAM_REQ_INPROG, /* CCB request is in progress */ - CAM_REQ_CMP, /* CCB request completed without error */ - CAM_REQ_ABORTED, /* CCB request aborted by the host */ - CAM_UA_ABORT, /* Unable to abort CCB request */ - CAM_REQ_CMP_ERR, /* CCB request completed with an error */ - CAM_BUSY, /* CAM subsystem is busy */ - CAM_REQ_INVALID, /* CCB request was invalid */ - CAM_PATH_INVALID, /* Supplied Path ID is invalid */ - CAM_DEV_NOT_THERE, /* SCSI Device Not Installed/there */ - CAM_UA_TERMIO, /* Unable to terminate I/O CCB request */ - CAM_SEL_TIMEOUT, /* Target Selection Timeout */ - CAM_CMD_TIMEOUT, /* Command timeout */ - CAM_SCSI_STATUS_ERROR, /* SCSI error, look at error code in CCB */ - CAM_MSG_REJECT_REC, /* Message Reject Received */ - CAM_SCSI_BUS_RESET, /* SCSI Bus Reset Sent/Received */ - CAM_UNCOR_PARITY, /* Uncorrectable parity error occurred */ - CAM_AUTOSENSE_FAIL = 0x10,/* Autosense: request sense cmd fail */ - CAM_NO_HBA, /* No HBA Detected error */ - CAM_DATA_RUN_ERR, /* Data Overrun error */ - CAM_UNEXP_BUSFREE, /* Unexpected Bus Free */ - CAM_SEQUENCE_FAIL, /* Target Bus Phase Sequence Failure */ - CAM_CCB_LEN_ERR, /* CCB length supplied is inadequate */ - CAM_PROVIDE_FAIL, /* Unable to provide requested capability */ - CAM_BDR_SENT, /* A SCSI BDR msg was sent to target */ - CAM_REQ_TERMIO, /* CCB request terminated by the host */ - CAM_UNREC_HBA_ERROR, /* Unrecoverable Host Bus Adapter Error */ - CAM_REQ_TOO_BIG, /* The request was too large for this host */ - CAM_REQUEUE_REQ, /* - * This request should be requeued to preserve - * transaction ordering. This typically occurs - * when the SIM recognizes an error that should - * freeze the queue and must place additional - * requests for the target at the sim level - * back into the XPT queue. - */ - CAM_ATA_STATUS_ERROR, /* ATA error, look at error code in CCB */ - CAM_SCSI_IT_NEXUS_LOST, /* Initiator/Target Nexus lost. */ - CAM_SMP_STATUS_ERROR, /* SMP error, look at error code in CCB */ - CAM_IDE = 0x33, /* Initiator Detected Error */ - CAM_RESRC_UNAVAIL, /* Resource Unavailable */ - CAM_UNACKED_EVENT, /* Unacknowledged Event by Host */ - CAM_MESSAGE_RECV, /* Message Received in Host Target Mode */ - CAM_INVALID_CDB, /* Invalid CDB received in Host Target Mode */ - CAM_LUN_INVALID, /* Lun supplied is invalid */ - CAM_TID_INVALID, /* Target ID supplied is invalid */ - CAM_FUNC_NOTAVAIL, /* The requested function is not available */ - CAM_NO_NEXUS, /* Nexus is not established */ - CAM_IID_INVALID, /* The initiator ID is invalid */ - CAM_CDB_RECVD, /* The SCSI CDB has been received */ - CAM_LUN_ALRDY_ENA, /* The LUN is already enabled for target mode */ - CAM_SCSI_BUSY, /* SCSI Bus Busy */ - - CAM_DEV_QFRZN = 0x40, /* The DEV queue is frozen w/this err */ - - /* Autosense data valid for target */ - CAM_AUTOSNS_VALID = 0x80, - CAM_RELEASE_SIMQ = 0x100,/* SIM ready to take more commands */ - CAM_SIM_QUEUED = 0x200,/* SIM has this command in it's queue */ + /* CCB request is in progress */ + CAM_REQ_INPROG = 0x00, - CAM_STATUS_MASK = 0x3F, /* Mask bits for just the status # */ + /* CCB request completed without error */ + CAM_REQ_CMP = 0x01, - /* Target Specific Adjunct Status */ - CAM_SENT_SENSE = 0x40000000 /* sent sense with status */ + /* CCB request aborted by the host */ + CAM_REQ_ABORTED = 0x02, + + /* Unable to abort CCB request */ + CAM_UA_ABORT = 0x03, + + /* CCB request completed with an error */ + CAM_REQ_CMP_ERR = 0x04, + + /* CAM subsystem is busy */ + CAM_BUSY = 0x05, + + /* CCB request was invalid */ + CAM_REQ_INVALID = 0x06, + + /* Supplied Path ID is invalid */ + CAM_PATH_INVALID = 0x07, + + /* SCSI Device Not Installed/there */ + CAM_DEV_NOT_THERE = 0x08, + + /* Unable to terminate I/O CCB request */ + CAM_UA_TERMIO = 0x09, + + /* Target Selection Timeout */ + CAM_SEL_TIMEOUT = 0x0a, + + /* Command timeout */ + CAM_CMD_TIMEOUT = 0x0b, + + /* SCSI error, look at error code in CCB */ + CAM_SCSI_STATUS_ERROR = 0x0c, + + /* Message Reject Received */ + CAM_MSG_REJECT_REC = 0x0d, + + /* SCSI Bus Reset Sent/Received */ + CAM_SCSI_BUS_RESET = 0x0e, + + /* Uncorrectable parity error occurred */ + CAM_UNCOR_PARITY = 0x0f, + + /* Autosense: request sense cmd fail */ + CAM_AUTOSENSE_FAIL = 0x10, + + /* No HBA Detected error */ + CAM_NO_HBA = 0x11, + + /* Data Overrun error */ + CAM_DATA_RUN_ERR = 0x12, + + /* Unexpected Bus Free */ + CAM_UNEXP_BUSFREE = 0x13, + + /* Target Bus Phase Sequence Failure */ + CAM_SEQUENCE_FAIL = 0x14, + + /* CCB length supplied is inadequate */ + CAM_CCB_LEN_ERR = 0x15, + + /* Unable to provide requested capability*/ + CAM_PROVIDE_FAIL = 0x16, + + /* A SCSI BDR msg was sent to target */ + CAM_BDR_SENT = 0x17, + + /* CCB request terminated by the host */ + CAM_REQ_TERMIO = 0x18, + + /* Unrecoverable Host Bus Adapter Error */ + CAM_UNREC_HBA_ERROR = 0x19, + + /* Request was too large for this host */ + CAM_REQ_TOO_BIG = 0x1a, + + /* + * This request should be requeued to preserve + * transaction ordering. This typically occurs + * when the SIM recognizes an error that should + * freeze the queue and must place additional + * requests for the target at the sim level + * back into the XPT queue. + */ + CAM_REQUEUE_REQ = 0x1b, + + /* ATA error, look at error code in CCB */ + CAM_ATA_STATUS_ERROR = 0x1c, + + /* Initiator/Target Nexus lost. */ + CAM_SCSI_IT_NEXUS_LOST = 0x1d, + + /* SMP error, look at error code in CCB */ + CAM_SMP_STATUS_ERROR = 0x1e, + + /* + * Command completed without error but exceeded the soft + * timeout threshold. + */ + CAM_REQ_SOFTTIMEOUT = 0x1f, + + /* + * 0x20 - 0x32 are unassigned + */ + + /* Initiator Detected Error */ + CAM_IDE = 0x33, + + /* Resource Unavailable */ + CAM_RESRC_UNAVAIL = 0x34, + + /* Unacknowledged Event by Host */ + CAM_UNACKED_EVENT = 0x35, + + /* Message Received in Host Target Mode */ + CAM_MESSAGE_RECV = 0x36, + + /* Invalid CDB received in Host Target Mode */ + CAM_INVALID_CDB = 0x37, + + /* Lun supplied is invalid */ + CAM_LUN_INVALID = 0x38, + + /* Target ID supplied is invalid */ + CAM_TID_INVALID = 0x39, + + /* The requested function is not available */ + CAM_FUNC_NOTAVAIL = 0x3a, + + /* Nexus is not established */ + CAM_NO_NEXUS = 0x3b, + + /* The initiator ID is invalid */ + CAM_IID_INVALID = 0x3c, + + /* The SCSI CDB has been received */ + CAM_CDB_RECVD = 0x3d, + + /* The LUN is already enabled for target mode */ + CAM_LUN_ALRDY_ENA = 0x3e, + + /* SCSI Bus Busy */ + CAM_SCSI_BUSY = 0x3f, + + + /* + * Flags + */ + + /* The DEV queue is frozen w/this err */ + CAM_DEV_QFRZN = 0x40, + + /* Autosense data valid for target */ + CAM_AUTOSNS_VALID = 0x80, + + /* SIM ready to take more commands */ + CAM_RELEASE_SIMQ = 0x100, + + /* SIM has this command in it's queue */ + CAM_SIM_QUEUED = 0x200, + + /* Quality of service data is valid */ + CAM_QOS_VALID = 0x400, + + /* Mask bits for just the status # */ + CAM_STATUS_MASK = 0x3F, + + /* + * Target Specific Adjunct Status + */ + + /* sent sense with status */ + CAM_SENT_SENSE = 0x40000000 } cam_status; typedef enum { Modified: head/sys/cam/cam_ccb.h ============================================================================== --- head/sys/cam/cam_ccb.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/cam/cam_ccb.h Tue Sep 24 16:50:53 2013 (r255853) @@ -107,6 +107,10 @@ typedef enum { CAM_SEND_STATUS = 0x40000000 /* Send status after data phase */ } ccb_flags; +typedef enum { + CAM_EXTLUN_VALID = 0x00000001,/* 64bit lun field is valid */ +} ccb_xflags; + /* XPT Opcodes for xpt_action */ typedef enum { /* Function code flags are bits greater than 0xff */ @@ -296,6 +300,12 @@ typedef union { u_int8_t bytes[CCB_SIM_PRIV_SIZE * sizeof(ccb_priv_entry)]; } ccb_spriv_area; +typedef struct { + struct timeval *etime; + uintptr_t sim_data; + uintptr_t periph_data; +} ccb_qos_area; + struct ccb_hdr { cam_pinfo pinfo; /* Info for priority scheduling */ camq_entry xpt_links; /* For chaining in the XPT layer */ @@ -310,16 +320,14 @@ struct ccb_hdr { path_id_t path_id; /* Path ID for the request */ target_id_t target_id; /* Target device ID */ lun_id_t target_lun; /* Target LUN number */ + lun64_id_t ext_lun; /* 64bit extended/multi-level LUNs */ u_int32_t flags; /* ccb_flags */ + u_int32_t xflags; /* Extended flags */ ccb_ppriv_area periph_priv; ccb_spriv_area sim_priv; - u_int32_t timeout; /* Timeout value */ - - /* - * Deprecated, only for use by non-MPSAFE SIMs. All others must - * allocate and initialize their own callout storage. - */ - struct callout_handle timeout_ch; + ccb_qos_area qos; + u_int32_t timeout; /* Hard timeout value in seconds */ + struct timeval softtimeout; /* Soft timeout value in sec + usec */ }; /* Get Device Information CCB */ @@ -541,7 +549,7 @@ struct ccb_dev_match { /* * Definitions for the path inquiry CCB fields. */ -#define CAM_VERSION 0x17 /* Hex value for current version */ +#define CAM_VERSION 0x18 /* Hex value for current version */ typedef enum { PI_MDP_ABLE = 0x80, /* Supports MDP message */ @@ -564,6 +572,7 @@ typedef enum { } pi_tmflag; typedef enum { + PIM_EXTLUNS = 0x100,/* 64bit extended LUNs supported */ PIM_SCANHILO = 0x80, /* Bus scans from high ID to low ID */ PIM_NOREMOVE = 0x40, /* Removeable devices not included in scan */ PIM_NOINITIATOR = 0x20, /* Initiator role not supported. */ @@ -595,8 +604,8 @@ struct ccb_pathinq { struct ccb_hdr 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 target_sprt; /* Flags for target mode support */ + u_int32_t hba_misc; /* Misc HBA features */ u_int16_t hba_eng_cnt; /* HBA engine count */ /* Vendor Unique capabilities */ u_int8_t vuhba_flags[VUHBALEN]; Modified: head/sys/cam/cam_compat.c ============================================================================== --- head/sys/cam/cam_compat.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/cam/cam_compat.c Tue Sep 24 16:50:53 2013 (r255853) @@ -44,23 +44,28 @@ __FBSDID("$FreeBSD$"); #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); + int -cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct thread *td) +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) { + switch (cmd) { case CAMIOCOMMAND_0x16: { union ccb *ccb; - ccb = (union ccb *)*addr; + ccb = (union ccb *)addr; if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS_0x16) { ccb->ccb_h.flags &= ~CAM_SG_LIST_PHYS_0x16; ccb->ccb_h.flags |= CAM_DATA_SG_PADDR; @@ -73,13 +78,21 @@ cam_compat_ioctl(struct cdev *dev, u_lon ccb->ccb_h.flags &= CAM_SCATTER_VALID_0x16; ccb->ccb_h.flags |= CAM_DATA_SG; } - *cmd = CAMIOCOMMAND; - error = EAGAIN; + cmd = CAMIOCOMMAND; + error = (cbfnp)(dev, cmd, addr, flag, td); break; } case CAMGETPASSTHRU_0x16: - *cmd = CAMGETPASSTHRU; - error = EAGAIN; + cmd = CAMGETPASSTHRU; + error = (cbfnp)(dev, cmd, addr, flag, td); + 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; default: error = ENOTTY; @@ -87,3 +100,105 @@ cam_compat_ioctl(struct cdev *dev, u_lon 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->ext_lun.lun64 = 0; + 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); + + 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; + + /* The PATH_INQ only needs special handling on the way out */ + if (ccb->ccb_h.func_code != XPT_PATH_INQ) { + bcopy(ccbb, ccbb17, CAM_0X17_DATA_LEN); + } else { + struct ccb_pathinq *cpi; + struct ccb_pathinq_0x17 *cpi17; + + 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; + } + + xpt_free_ccb(ccb); + + return (error); +} Modified: head/sys/cam/cam_compat.h ============================================================================== --- head/sys/cam/cam_compat.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/cam/cam_compat.h Tue Sep 24 16:50:53 2013 (r255853) @@ -31,7 +31,7 @@ #ifndef _CAM_CAM_COMPAT_H #define _CAM_CAM_COMPAT_H -int cam_compat_ioctl(struct cdev *dev, u_long *cmd, caddr_t *addr, int *flag, struct thread *td); +int cam_compat_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td, d_ioctl_t *cbfnp); /* Version 0x16 compatibility */ #define CAM_VERSION_0x16 0x16 @@ -44,5 +44,71 @@ int cam_compat_ioctl(struct cdev *dev, u #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 */ + lun_id_t 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)) + +#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) + #endif Modified: head/sys/cam/cam_xpt.c ============================================================================== --- head/sys/cam/cam_xpt.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/cam/cam_xpt.c Tue Sep 24 16:50:53 2013 (r255853) @@ -397,9 +397,7 @@ xptioctl(struct cdev *dev, u_long cmd, c int error; if ((error = xptdoioctl(dev, cmd, addr, flag, td)) == ENOTTY) { - error = cam_compat_ioctl(dev, &cmd, &addr, &flag, td); - if (error == EAGAIN) - return (xptdoioctl(dev, cmd, addr, flag, td)); + error = cam_compat_ioctl(dev, cmd, addr, flag, td, xptdoioctl); } return (error); } @@ -4385,8 +4383,6 @@ xpt_get_ccb(struct cam_ed *device) if (new_ccb == NULL) { return (NULL); } - if ((sim->flags & CAM_SIM_MPSAFE) == 0) - callout_handle_init(&new_ccb->ccb_h.timeout_ch); SLIST_INSERT_HEAD(&sim->ccb_freeq, &new_ccb->ccb_h, xpt_links.sle); sim->ccb_count++; Modified: head/sys/cam/scsi/scsi_pass.c ============================================================================== --- head/sys/cam/scsi/scsi_pass.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/cam/scsi/scsi_pass.c Tue Sep 24 16:50:53 2013 (r255853) @@ -580,9 +580,7 @@ passioctl(struct cdev *dev, u_long cmd, int error; if ((error = passdoioctl(dev, cmd, addr, flag, td)) == ENOTTY) { - error = cam_compat_ioctl(dev, &cmd, &addr, &flag, td); - if (error == EAGAIN) - return (passdoioctl(dev, cmd, addr, flag, td)); + error = cam_compat_ioctl(dev, cmd, addr, flag, td, passdoioctl); } return (error); } Modified: head/sys/dev/asr/asr.c ============================================================================== --- head/sys/dev/asr/asr.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/asr/asr.c Tue Sep 24 16:50:53 2013 (r255853) @@ -385,6 +385,21 @@ typedef struct Asr_softc { static STAILQ_HEAD(, Asr_softc) Asr_softc_list = STAILQ_HEAD_INITIALIZER(Asr_softc_list); +static __inline void +set_ccb_timeout_ch(union asr_ccb *ccb, struct callout_handle ch) +{ + ccb->ccb_h.sim_priv.entries[0].ptr = ch.callout; +} + +static __inline struct callout_handle +get_ccb_timeout_ch(union asr_ccb *ccb) +{ + struct callout_handle ch; + + ch.callout = ccb->ccb_h.sim_priv.entries[0].ptr; + return ch; +} + /* * Prototypes of the routines we have in this object. */ @@ -797,8 +812,8 @@ ASR_ccbAdd(Asr_softc_t *sc, union asr_cc */ ccb->ccb_h.timeout = 6 * 60 * 1000; } - ccb->ccb_h.timeout_ch = timeout(asr_timeout, (caddr_t)ccb, - (ccb->ccb_h.timeout * hz) / 1000); + set_ccb_timeout_ch(ccb, timeout(asr_timeout, (caddr_t)ccb, + (ccb->ccb_h.timeout * hz) / 1000)); } splx(s); } /* ASR_ccbAdd */ @@ -812,7 +827,7 @@ ASR_ccbRemove(Asr_softc_t *sc, union asr int s; s = splcam(); - untimeout(asr_timeout, (caddr_t)ccb, ccb->ccb_h.timeout_ch); + untimeout(asr_timeout, (caddr_t)ccb, get_ccb_timeout_ch(ccb)); LIST_REMOVE(&(ccb->ccb_h), sim_links.le); splx(s); } /* ASR_ccbRemove */ @@ -1322,9 +1337,9 @@ asr_timeout(void *arg) cam_sim_unit(xpt_path_sim(ccb->ccb_h.path)), s); if (ASR_reset (sc) == ENXIO) { /* Try again later */ - ccb->ccb_h.timeout_ch = timeout(asr_timeout, + set_ccb_timeout_ch(ccb, timeout(asr_timeout, (caddr_t)ccb, - (ccb->ccb_h.timeout * hz) / 1000); + (ccb->ccb_h.timeout * hz) / 1000)); } return; } @@ -1338,9 +1353,9 @@ asr_timeout(void *arg) if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_CMD_TIMEOUT) { debug_asr_printf (" AGAIN\nreinitializing adapter\n"); if (ASR_reset (sc) == ENXIO) { - ccb->ccb_h.timeout_ch = timeout(asr_timeout, + set_ccb_timeout_ch(ccb, timeout(asr_timeout, (caddr_t)ccb, - (ccb->ccb_h.timeout * hz) / 1000); + (ccb->ccb_h.timeout * hz) / 1000)); } splx(s); return; @@ -1349,8 +1364,8 @@ asr_timeout(void *arg) /* If the BUS reset does not take, then an adapter reset is next! */ ccb->ccb_h.status &= ~CAM_STATUS_MASK; ccb->ccb_h.status |= CAM_CMD_TIMEOUT; - ccb->ccb_h.timeout_ch = timeout(asr_timeout, (caddr_t)ccb, - (ccb->ccb_h.timeout * hz) / 1000); + set_ccb_timeout_ch(ccb, timeout(asr_timeout, (caddr_t)ccb, + (ccb->ccb_h.timeout * hz) / 1000)); ASR_resetBus (sc, cam_sim_bus(xpt_path_sim(ccb->ccb_h.path))); xpt_async (AC_BUS_RESET, ccb->ccb_h.path, NULL); splx(s); Modified: head/sys/dev/firewire/sbp.c ============================================================================== --- head/sys/dev/firewire/sbp.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/firewire/sbp.c Tue Sep 24 16:50:53 2013 (r255853) @@ -177,6 +177,7 @@ struct sbp_ocb { struct sbp_dev *sdev; int flags; /* XXX should be removed */ bus_dmamap_t dmamap; + struct callout_handle timeout_ch; }; #define OCB_ACT_MGM 0 @@ -591,6 +592,7 @@ END_DEBUG /* XXX */ goto next; } + callout_handle_init(&ocb->timeout_ch); sbp_free_ocb(sdev, ocb); } next: @@ -2763,7 +2765,7 @@ END_DEBUG STAILQ_REMOVE(&sdev->ocbs, ocb, sbp_ocb, ocb); if (ocb->ccb != NULL) untimeout(sbp_timeout, (caddr_t)ocb, - ocb->ccb->ccb_h.timeout_ch); + ocb->timeout_ch); if (ntohl(ocb->orb[4]) & 0xffff) { bus_dmamap_sync(sdev->target->sbp->dmat, ocb->dmamap, @@ -2836,7 +2838,7 @@ END_DEBUG STAILQ_INSERT_TAIL(&sdev->ocbs, ocb, ocb); if (ocb->ccb != NULL) - ocb->ccb->ccb_h.timeout_ch = timeout(sbp_timeout, (caddr_t)ocb, + ocb->timeout_ch = timeout(sbp_timeout, (caddr_t)ocb, (ocb->ccb->ccb_h.timeout * hz) / 1000); if (use_doorbell && prev == NULL) @@ -2930,7 +2932,7 @@ END_DEBUG } if (ocb->ccb != NULL) { untimeout(sbp_timeout, (caddr_t)ocb, - ocb->ccb->ccb_h.timeout_ch); + ocb->timeout_ch); ocb->ccb->ccb_h.status = status; SBP_LOCK(sdev->target->sbp); xpt_done(ocb->ccb); Modified: head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c ============================================================================== --- head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hpt27xx/hpt27xx_osm_bsd.c Tue Sep 24 16:50:53 2013 (r255853) @@ -432,7 +432,7 @@ static void os_cmddone(PCOMMAND pCmd) KdPrint(("os_cmddone(%p, %d)", pCmd, pCmd->Result)); - untimeout(hpt_timeout, pCmd, ccb->ccb_h.timeout_ch); + untimeout(hpt_timeout, pCmd, ext->timeout_ch); switch(pCmd->Result) { case RETURN_SUCCESS: @@ -510,8 +510,7 @@ static void hpt_io_dmamap_callback(void BUS_DMASYNC_PREWRITE); } } - - ext->ccb->ccb_h.timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); + ext->timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); ldm_queue_cmd(pCmd); } @@ -1048,6 +1047,7 @@ static void hpt_final_init(void *dummy) os_printk("Can't create dma map(%d)", i); return ; } + callout_handle_init(&ext->timeout_ch); } if ((devq = cam_simq_alloc(os_max_queue_comm)) == NULL) { Modified: head/sys/dev/hpt27xx/os_bsd.h ============================================================================== --- head/sys/dev/hpt27xx/os_bsd.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hpt27xx/os_bsd.h Tue Sep 24 16:50:53 2013 (r255853) @@ -174,6 +174,7 @@ typedef struct _os_cmdext { struct _os_cmdext *next; union ccb *ccb; bus_dmamap_t dma_map; + struct callout_handle timeout_ch; SG psg[os_max_sg_descriptors]; } OS_CMDEXT, *POS_CMDEXT; Modified: head/sys/dev/hptiop/hptiop.c ============================================================================== --- head/sys/dev/hptiop/hptiop.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptiop/hptiop.c Tue Sep 24 16:50:53 2013 (r255853) @@ -643,7 +643,7 @@ static void hptiop_request_callback_mvfr ccb = (union ccb *)srb->ccb; - untimeout(hptiop_reset_adapter, hba, ccb->ccb_h.timeout_ch); + untimeout(hptiop_reset_adapter, hba, srb->timeout_ch); if (ccb->ccb_h.flags & CAM_CDB_POINTER) cdb = ccb->csio.cdb_io.cdb_ptr; @@ -2629,7 +2629,7 @@ static void hptiop_post_req_mvfrey(struc BUS_SPACE_RD4_MVFREY2(inbound_write_ptr); if (req->header.type == IOP_REQUEST_TYPE_SCSI_COMMAND) { - ccb->ccb_h.timeout_ch = timeout(hptiop_reset_adapter, hba, 20*hz); + srb->timeout_ch = timeout(hptiop_reset_adapter, hba, 20*hz); } } @@ -2741,6 +2741,7 @@ static void hptiop_map_srb(void *arg, bu tmp_srb->phy_addr = phy_addr; } + callout_handle_init(&tmp_srb->timeout_ch); hptiop_free_srb(hba, tmp_srb); hba->srb[i] = tmp_srb; phy_addr += HPT_SRB_MAX_SIZE; Modified: head/sys/dev/hptiop/hptiop.h ============================================================================== --- head/sys/dev/hptiop/hptiop.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptiop/hptiop.h Tue Sep 24 16:50:53 2013 (r255853) @@ -460,6 +460,7 @@ struct hpt_iop_srb { u_int64_t phy_addr; u_int32_t srb_flag; int index; + struct callout_handle timeout_ch; }; #define hptiop_lock_adapter(hba) mtx_lock(&(hba)->lock) Modified: head/sys/dev/hptmv/entry.c ============================================================================== --- head/sys/dev/hptmv/entry.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptmv/entry.c Tue Sep 24 16:50:53 2013 (r255853) @@ -1438,6 +1438,7 @@ unregister: free(pAdapter->pbus_dmamap, M_DEVBUF); goto unregister; } + callout_handle_init(&pmap->timeout_ch); } /* setup PRD Tables */ KdPrint(("Allocate PRD Tables\n")); @@ -2758,7 +2759,7 @@ hpt_io_dmamap_callback(void *arg, bus_dm } } - ccb->ccb_h.timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz); + pmap->timeout_ch = timeout(hpt_timeout, (caddr_t)ccb, 20*hz); pVDev->pfnSendCommand(_VBUS_P pCmd); CheckPendingCall(_VBUS_P0); } @@ -2980,7 +2981,7 @@ fOsCommandDone(_VBUS_ARG PCommand pCmd) KdPrint(("fOsCommandDone(pcmd=%p, result=%d)\n", pCmd, pCmd->Result)); - untimeout(hpt_timeout, (caddr_t)ccb, ccb->ccb_h.timeout_ch); + untimeout(hpt_timeout, (caddr_t)ccb, pmap->timeout_ch); switch(pCmd->Result) { case RETURN_SUCCESS: Modified: head/sys/dev/hptmv/osbsd.h ============================================================================== --- head/sys/dev/hptmv/osbsd.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptmv/osbsd.h Tue Sep 24 16:50:53 2013 (r255853) @@ -153,6 +153,7 @@ typedef struct _BUS_DMAMAP { struct _BUS_DMAMAP *next; struct IALAdapter *pAdapter; bus_dmamap_t dma_map; + struct callout_handle timeout_ch; SCAT_GATH psg[MAX_SG_DESCRIPTORS]; } BUS_DMAMAP, *PBUS_DMAMAP; Modified: head/sys/dev/hptnr/hptnr_osm_bsd.c ============================================================================== --- head/sys/dev/hptnr/hptnr_osm_bsd.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptnr/hptnr_osm_bsd.c Tue Sep 24 16:50:53 2013 (r255853) @@ -432,7 +432,7 @@ static void os_cmddone(PCOMMAND pCmd) KdPrint(("os_cmddone(%p, %d)", pCmd, pCmd->Result)); - untimeout(hpt_timeout, pCmd, ccb->ccb_h.timeout_ch); + untimeout(hpt_timeout, pCmd, ext->timeout_ch); switch(pCmd->Result) { case RETURN_SUCCESS: @@ -511,7 +511,7 @@ static void hpt_io_dmamap_callback(void } } - ext->ccb->ccb_h.timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); + ext->timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); ldm_queue_cmd(pCmd); } @@ -1048,6 +1048,7 @@ static void hpt_final_init(void *dummy) os_printk("Can't create dma map(%d)", i); return ; } + callout_handle_init(&ext->timeout_ch); } if ((devq = cam_simq_alloc(os_max_queue_comm)) == NULL) { Modified: head/sys/dev/hptnr/os_bsd.h ============================================================================== --- head/sys/dev/hptnr/os_bsd.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptnr/os_bsd.h Tue Sep 24 16:50:53 2013 (r255853) @@ -176,6 +176,7 @@ typedef struct _os_cmdext { struct _os_cmdext *next; union ccb *ccb; bus_dmamap_t dma_map; + struct callout_handle timeout_ch; SG psg[os_max_sg_descriptors]; } OS_CMDEXT, *POS_CMDEXT; Modified: head/sys/dev/hptrr/hptrr_osm_bsd.c ============================================================================== --- head/sys/dev/hptrr/hptrr_osm_bsd.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptrr/hptrr_osm_bsd.c Tue Sep 24 16:50:53 2013 (r255853) @@ -440,7 +440,7 @@ static void os_cmddone(PCOMMAND pCmd) KdPrint(("os_cmddone(%p, %d)", pCmd, pCmd->Result)); - untimeout(hpt_timeout, pCmd, ccb->ccb_h.timeout_ch); + untimeout(hpt_timeout, pCmd, ext->timeout_ch); switch(pCmd->Result) { case RETURN_SUCCESS: @@ -519,7 +519,7 @@ static void hpt_io_dmamap_callback(void BUS_DMASYNC_PREWRITE); } } - ext->ccb->ccb_h.timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); + ext->timeout_ch = timeout(hpt_timeout, pCmd, HPT_OSM_TIMEOUT); ldm_queue_cmd(pCmd); } @@ -1058,6 +1058,7 @@ static void hpt_final_init(void *dummy) os_printk("Can't create dma map(%d)", i); return ; } + callout_handle_init(&ext->timeout_ch); } if ((devq = cam_simq_alloc(os_max_queue_comm)) == NULL) { Modified: head/sys/dev/hptrr/os_bsd.h ============================================================================== --- head/sys/dev/hptrr/os_bsd.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/hptrr/os_bsd.h Tue Sep 24 16:50:53 2013 (r255853) @@ -174,6 +174,7 @@ typedef struct _os_cmdext { struct _os_cmdext *next; union ccb *ccb; bus_dmamap_t dma_map; + struct callout_handle timeout_ch; SG psg[os_max_sg_descriptors]; } OS_CMDEXT, *POS_CMDEXT; Modified: head/sys/dev/iir/iir.c ============================================================================== --- head/sys/dev/iir/iir.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/iir/iir.c Tue Sep 24 16:50:53 2013 (r255853) @@ -270,6 +270,7 @@ iir_init(struct gdt_softc *gdt) gccb->gc_map_flag = TRUE; gccb->gc_scratch = &gdt->sc_gcscratch[GDT_SCRATCH_SZ * i]; gccb->gc_scratch_busbase = gdt->sc_gcscratch_busbase + GDT_SCRATCH_SZ * i; + callout_handle_init(&gccb->gc_timeout_ch); SLIST_INSERT_HEAD(&gdt->sc_free_gccb, gccb, sle); } gdt->sc_init_level++; @@ -1239,7 +1240,7 @@ gdtexecuteccb(void *arg, bus_dma_segment ccb->ccb_h.status |= CAM_SIM_QUEUED; /* timeout handling */ - ccb->ccb_h.timeout_ch = + gccb->gc_timeout_ch = timeout(iir_timeout, (caddr_t)gccb, (ccb->ccb_h.timeout * hz) / 1000); @@ -1747,7 +1748,7 @@ gdt_sync_event(struct gdt_softc *gdt, in printf("\n"); return (0); } else { - untimeout(iir_timeout, gccb, ccb->ccb_h.timeout_ch); + untimeout(iir_timeout, gccb, gccb->gc_timeout_ch); if (gdt->sc_status == GDT_S_BSY) { GDT_DPRINTF(GDT_D_DEBUG, ("gdt_sync_event(%p) gccb %p busy\n", gdt, gccb)); Modified: head/sys/dev/iir/iir.h ============================================================================== --- head/sys/dev/iir/iir.h Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/iir/iir.h Tue Sep 24 16:50:53 2013 (r255853) @@ -684,6 +684,7 @@ struct gdt_ccb { union ccb *gc_ccb; gdt_ucmd_t *gc_ucmd; bus_dmamap_t gc_dmamap; + struct callout_handle gc_timeout_ch; int gc_map_flag; int gc_timeout; u_int8_t gc_service; Modified: head/sys/dev/tws/tws.c ============================================================================== --- head/sys/dev/tws/tws.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/tws/tws.c Tue Sep 24 16:50:53 2013 (r255853) @@ -696,6 +696,7 @@ tws_init_reqs(struct tws_softc *sc, u_in sc->reqs[i].cmd_pkt->hdr.header_desc.size_header = 128; + callout_handle_init(&sc->reqs[i].thandle); sc->reqs[i].state = TWS_REQ_STATE_FREE; if ( i >= TWS_RESERVED_REQS ) tws_q_insert_tail(sc, &sc->reqs[i], TWS_FREE_Q); Modified: head/sys/dev/tws/tws_cam.c ============================================================================== --- head/sys/dev/tws/tws_cam.c Tue Sep 24 14:52:43 2013 (r255852) +++ head/sys/dev/tws/tws_cam.c Tue Sep 24 16:50:53 2013 (r255853) @@ -341,7 +341,7 @@ tws_scsi_complete(struct tws_request *re tws_q_remove_request(sc, req, TWS_BUSY_Q); mtx_unlock(&sc->q_lock); - untimeout(tws_timeout, req, req->ccb_ptr->ccb_h.timeout_ch); + untimeout(tws_timeout, req, req->thandle); tws_unmap_request(req->sc, req); @@ -454,7 +454,7 @@ tws_cmd_complete(struct tws_request *req { struct tws_softc *sc = req->sc; - untimeout(tws_timeout, req, req->ccb_ptr->ccb_h.timeout_ch); + untimeout(tws_timeout, req, req->thandle); tws_unmap_request(sc, req); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***