blob: b37b9332583466b84feccfc1311aa319cab18bc9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
#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 *
};
*/
|