Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 24 Sep 2013 16:50:53 +0000 (UTC)
From:      Scott Long <scottl@FreeBSD.org>
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
Message-ID:  <201309241650.r8OGorvJ008976@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <cam/cam.h>
 #include <cam/cam_ccb.h>
+#include <cam/cam_xpt.h>
 #include <cam/cam_compat.h>
 
 #include <cam/scsi/scsi_pass.h>
 
 #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 ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201309241650.r8OGorvJ008976>