summaryrefslogtreecommitdiff
path: root/dtrace/iotrace.d
blob: 265d3c659dba2d5bb9cd1a1fc1a3c751ce161f47 (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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
/* start with dtrace -C -s <file> */

#define request_get_target_id(request) \
                ((*request->ccb).ccb_h.target_id)

#define request_get_func_code(request) \
                ((*request->ccb).ccb_h.func_code)

#define request_get_req_map(request) \
                ((*request->ccb).ctio.req_map)

#define request_get_address(request) \
                (request->req_pbuf)

#define mpt_get_dev_unit(mpt) \
                (mpt->dev->unit)

#define indexfunc(mpt, request) \
        mpt_get_dev_unit(mpt), request->serno

#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)

/**
 * void mpt_send_cmd(struct mpt_softc *mpt, request_t *re
 *
fbt::mpt_send_cmd:entry
/request_get_func_code(args[1]) == XPT_SCSI_IO/
{
        requests[ indexfunc(args[0], args[1]) ] = time;
}
fbt::mpt_send_cmd:entry
/  request_get_func_code(args[1]) == XPT_SCSI_IO 
&& &(args[1]->links) != NULL /
{
        requests[ indexfunc(args[0], args[1]) ] = time;
        @next[  mpt_get_dev_unit(args[0]), request_get_target_id(args[1]) ] = count();
}
*/

/**
 * static void
 * mpt_execute_req_a64(void *arg, bus_dma_segment_t *dm_segs, int nseg, int error)
*/
fbt::mpt_execute_req_a64:entry
{
        req = (request_t*)args[0];
        mpt = (struct mpt_softc*) req->ccb->ccb_h.sim_priv.entries[0].ptr;

        requests[indexfunc(mpt,req)] = time;
}

struct MSG_SCSI_IO_REQUEST
{
    U8                      TargetID;           /* 00h */
    U8                      Bus;                /* 01h */
    U8                      ChainOffset;        /* 02h */
    U8                      Function;           /* 03h */
    U8                      CDBLength;          /* 04h */
    U8                      SenseBufferLength;  /* 05h */
    U8                      Reserved;           /* 06h */
    U8                      MsgFlags;           /* 07h */
    U32                     MsgContext;         /* 08h */
    U8                      LUN[8];             /* 0Ch */
    U32                     Control;            /* 14h */
    U8                      CDB[16];            /* 18h */
    U32                     DataLength;         /* 28h */
    U32                     SenseBufferLowAddr; /* 2Ch */
    SGE_SIMPLE64*           SGL;                /* 30h */
};
 
struct SGE_SIMPLE64
{
    U32                     FlagsLength;
    U64                     Address;
} 
struct U64
{
    uint32_t          Low;
   uint32_t      High;
};


/**
 * mpt_scsi_reply_handler(struct mpt_softc *mpt, request_t *req,
 *   uint32_t reply_desc, MSG_DEFAULT_REPLY *reply_frame)
 */
fbt::mpt_scsi_reply_handler:entry
/request_get_func_code(args[1]) == XPT_SCSI_IO &&
 requests[ indexfunc(args[0], args[1]) ] != 0/
{
        start = requests[ indexfunc(args[0], args[1]) ];
        hdrp = (MSG_SCSI_IO_REQUEST*) args[1]->req_vbuf;
        se = (SGE_SIMPLE64*) hdrp->SGL;
        printf("%u,%u,%u,%u\n",  mpt_get_dev_unit(args[0]), request_get_target_id(args[1]), args[1]->req_pbuf, se.Low, time-start);
        requests[ indexfunc(args[0], args[1]) ] = 0;
}

/*
fbt::mpt_scsi_reply_handler:entry
/request_get_func_code(args[1]) == XPT_SCSI_IO &&
 requests[ indexfunc(args[0], args[1]) ] != 0/
{
        start = requests[ indexfunc(args[0], args[1]) ];
        @delay[ mpt_get_dev_unit(args[0]), request_get_target_id(args[1]) ] = quantize( time - start );
        requests[ indexfunc(args[0], args[1]) ] = 0;
}

profile:::tick-1sec
{
        printa(@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 *
};
*/