#define time (timestamp/1000) #define XPT_FC_QUEUED 0x100 #define XPT_FC_DEV_QUEUED 0x800 #define XPT_SCSI_IO (0x01 | XPT_FC_DEV_QUEUED | XPT_FC_QUEUED) fbt::xpt_action:entry /args[0]->ccb_h.func_code == XPT_SCSI_IO / { ccb = args[0]; requests[ccb] = time; } fbt::xpt_done:entry /args[0]->ccb_h.func_code == XPT_SCSI_IO / { ccb = args[0]; delay = (requests[ccb] == 0) ? 0 : time - requests[ccb] ; requests[ ccb ] = 0; target = ccb->ccb_h.target_id; /* Controller Port 0..7 */ mpt = (struct mpt_softc*) ccb->ccb_h.sim_priv.entries[0].ptr; unit = mpt->dev->unit; /* Controller ID */ printf("%u,%u,%u\n", unit, target, delay); } /* * Code-Excerpts for reference union ccb { struct ccb_hdr ccb_h; struct ccb_scsiio csio; struct ccb_getdev cgd; struct ccb_getdevlist cgdl; struct ccb_pathinq cpi; struct ccb_relsim crs; struct ccb_setasync csa; struct ccb_setdev csd; struct ccb_pathstats cpis; struct ccb_getdevstats cgds; struct ccb_dev_match cdm; struct ccb_trans_settings cts; struct ccb_calc_geometry ccg; struct ccb_sim_knob knob; struct ccb_abort cab; struct ccb_resetbus crb; struct ccb_resetdev crd; struct ccb_termio tio; struct ccb_accept_tio atio; struct ccb_scsiio ctio; struct ccb_en_lun cel; struct ccb_immed_notify cin; struct ccb_notify_ack cna; struct ccb_immediate_notify cin1; struct ccb_notify_acknowledge cna2; struct ccb_eng_inq cei; struct ccb_eng_exec cee; struct ccb_rescan crcn; struct ccb_debug cdbg; struct ccb_ataio ataio; }; struct ccb_hdr { 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 *); * Callback on completion function * 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; * 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; }; func_code: XPT_SCSI_IO = (0x01 | XPT_FC_DEV_QUEUED = 0x800 | XPT_FC_QUEUED, XPT_FC_QUEUED = 0x100) = 0x901 * SCSI I/O Request CCB used for the XPT_SCSI_IO and XPT_CONT_TARGET_IO * function codes. struct ccb_scsiio { struct ccb_hdr ccb_h; union ccb *next_ccb; * Ptr for next CCB for action * u_int8_t *req_map; * Ptr to mapping info * u_int8_t *data_ptr; * Ptr to the data buf/SG list * u_int32_t dxfer_len; * Data transfer length * * Autosense storage * struct scsi_sense_data sense_data; u_int8_t sense_len; * Number of bytes to autosense * u_int8_t cdb_len; * Number of bytes for the CDB * u_int16_t sglist_cnt; * Number of SG list entries * u_int8_t scsi_status; * Returned SCSI status * u_int8_t sense_resid; * Autosense resid length: 2's comp * u_int32_t resid; * Transfer residual length: 2's comp * cdb_t cdb_io; * Union for CDB bytes/pointer * u_int8_t *msg_ptr; * Pointer to the message buffer * u_int16_t msg_len; * Number of bytes for the Message * u_int8_t tag_action; * What to do for tag queueing * * * The tag action should be either the define below (to send a * non-tagged transaction) or one of the defined scsi tag messages * from scsi_message.h. * #define CAM_TAG_ACTION_NONE 0x00 u_int tag_id; * tag id from initator (target mode) * u_int init_id; * initiator id of who selected * }; request_t => req_entry struct req_entry { struct req_entry { TAILQ_ENTRY(req_entry) links; * Pointer to next in list * mpt_req_state_t state; * Request State Information * uint16_t index; * Index of this entry * uint16_t IOCStatus; * Completion status * uint16_t ResponseCode; * TMF Reponse Code * uint16_t serno; * serial number * union ccb *ccb; * CAM request * void *req_vbuf; * Virtual Address of Entry * void *sense_vbuf; * Virtual Address of sense data * bus_addr_t req_pbuf; * Physical Address of Entry * bus_addr_t sense_pbuf; * Physical Address of sense data * bus_dmamap_t dmap; * DMA map for data buffers * struct req_entry *chain; * for SGE overallocations * struct callout callout; * Timeout for the request * }; */