zfcp_dbf.h 9.4 KB
Newer Older
1
/*
2 3
 * zfcp device driver
 * debug feature declarations
4
 *
5
 * Copyright IBM Corp. 2008, 2010
6 7 8 9 10
 */

#ifndef ZFCP_DBF_H
#define ZFCP_DBF_H

11
#include <scsi/fc/fc_fcp.h>
12
#include "zfcp_ext.h"
13
#include "zfcp_fsf.h"
14
#include "zfcp_def.h"
15

16
#define ZFCP_DBF_TAG_LEN       7
17
#define ZFCP_DBF_TAG_SIZE      4
18
#define ZFCP_DBF_ID_SIZE       7
19

20 21
#define ZFCP_DBF_INVALID_LUN	0xFFFFFFFFFFFFFFFFull

22 23 24 25 26 27 28 29
struct zfcp_dbf_dump {
	u8 tag[ZFCP_DBF_TAG_SIZE];
	u32 total_size;		/* size of total dump data */
	u32 offset;		/* how much data has being already dumped */
	u32 size;		/* how much data comes with this record */
	u8 data[];		/* dump data */
} __attribute__ ((packed));

30 31 32 33 34 35 36 37
/**
 * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
 * @ready: number of ready recovery actions
 * @running: number of running recovery actions
 * @want: wanted recovery action
 * @need: needed recovery action
 */
struct zfcp_dbf_rec_trigger {
38 39 40 41
	u32 ready;
	u32 running;
	u8 want;
	u8 need;
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
} __packed;

/**
 * struct zfcp_dbf_rec_running - trace record for running recovery
 * @fsf_req_id: request id for fsf requests
 * @rec_status: status of the fsf request
 * @rec_step: current step of the recovery action
 * rec_count: recovery counter
 */
struct zfcp_dbf_rec_running {
	u64 fsf_req_id;
	u32 rec_status;
	u16 rec_step;
	u8 rec_action;
	u8 rec_count;
} __packed;
58

59 60 61 62 63 64 65 66
/**
 * enum zfcp_dbf_rec_id - recovery trace record id
 * @ZFCP_DBF_REC_TRIG: triggered recovery identifier
 * @ZFCP_DBF_REC_RUN: running recovery identifier
 */
enum zfcp_dbf_rec_id {
	ZFCP_DBF_REC_TRIG	= 1,
	ZFCP_DBF_REC_RUN	= 2,
67
};
68

69 70 71 72 73 74 75 76 77 78 79 80 81 82
/**
 * struct zfcp_dbf_rec - trace record for error recovery actions
 * @id: unique number of recovery record type
 * @tag: identifier string specifying the location of initiation
 * @lun: logical unit number
 * @wwpn: word wide port number
 * @d_id: destination ID
 * @adapter_status: current status of the adapter
 * @port_status: current status of the port
 * @lun_status: current status of the lun
 * @u.trig: structure zfcp_dbf_rec_trigger
 * @u.run: structure zfcp_dbf_rec_running
 */
struct zfcp_dbf_rec {
83
	u8 id;
84 85 86 87 88 89 90
	char tag[ZFCP_DBF_TAG_LEN];
	u64 lun;
	u64 wwpn;
	u32 d_id;
	u32 adapter_status;
	u32 port_status;
	u32 lun_status;
91
	union {
92 93
		struct zfcp_dbf_rec_trigger trig;
		struct zfcp_dbf_rec_running run;
94
	} u;
95
} __packed;
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
/**
 * enum zfcp_dbf_san_id - SAN trace record identifier
 * @ZFCP_DBF_SAN_REQ: request trace record id
 * @ZFCP_DBF_SAN_RES: response trace record id
 * @ZFCP_DBF_SAN_ELS: extended link service record id
 */
enum zfcp_dbf_san_id {
	ZFCP_DBF_SAN_REQ	= 1,
	ZFCP_DBF_SAN_RES	= 2,
	ZFCP_DBF_SAN_ELS	= 3,
};

/** struct zfcp_dbf_san - trace record for SAN requests and responses
 * @id: unique number of recovery record type
 * @tag: identifier string specifying the location of initiation
 * @fsf_req_id: request id for fsf requests
 * @payload: unformatted information related to request/response
 * @d_id: destination id
 */
struct zfcp_dbf_san {
	u8 id;
	char tag[ZFCP_DBF_TAG_LEN];
	u64 fsf_req_id;
	u32 d_id;
#define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
	char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
} __packed;

125 126 127 128 129 130 131 132 133 134 135 136
/**
 * struct zfcp_dbf_hba_res - trace record for hba responses
 * @req_issued: timestamp when request was issued
 * @prot_status: protocol status
 * @prot_status_qual: protocol status qualifier
 * @fsf_status: fsf status
 * @fsf_status_qual: fsf status qualifier
 */
struct zfcp_dbf_hba_res {
	u64 req_issued;
	u32 prot_status;
	u8  prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
137
	u32 fsf_status;
138 139
	u8  fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
} __packed;
140

141 142 143 144 145 146 147 148 149
/**
 * struct zfcp_dbf_hba_uss - trace record for unsolicited status
 * @status_type: type of unsolicited status
 * @status_subtype: subtype of unsolicited status
 * @d_id: destination ID
 * @lun: logical unit number
 * @queue_designator: queue designator
 */
struct zfcp_dbf_hba_uss {
150 151
	u32 status_type;
	u32 status_subtype;
152 153 154 155
	u32 d_id;
	u64 lun;
	u64 queue_designator;
} __packed;
156

157 158 159 160 161 162 163 164 165 166 167
/**
 * enum zfcp_dbf_hba_id - HBA trace record identifier
 * @ZFCP_DBF_HBA_RES: response trace record
 * @ZFCP_DBF_HBA_USS: unsolicited status trace record
 * @ZFCP_DBF_HBA_BIT: bit error trace record
 */
enum zfcp_dbf_hba_id {
	ZFCP_DBF_HBA_RES	= 1,
	ZFCP_DBF_HBA_USS	= 2,
	ZFCP_DBF_HBA_BIT	= 3,
};
168

169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
/**
 * struct zfcp_dbf_hba - common trace record for HBA records
 * @id: unique number of recovery record type
 * @tag: identifier string specifying the location of initiation
 * @fsf_req_id: request id for fsf requests
 * @fsf_req_status: status of fsf request
 * @fsf_cmd: fsf command
 * @fsf_seq_no: fsf sequence number
 * @pl_len: length of payload stored as zfcp_dbf_pay
 * @u: record type specific data
 */
struct zfcp_dbf_hba {
	u8 id;
	char tag[ZFCP_DBF_TAG_LEN];
	u64 fsf_req_id;
	u32 fsf_req_status;
	u32 fsf_cmd;
	u32 fsf_seq_no;
	u16 pl_len;
188
	union {
189 190 191
		struct zfcp_dbf_hba_res res;
		struct zfcp_dbf_hba_uss uss;
		struct fsf_bit_error_payload be;
192
	} u;
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
} __packed;

/**
 * struct zfcp_dbf_pay - trace record for unformatted payload information
 * @area: area this record is originated from
 * @counter: ascending record number
 * @fsf_req_id: request id of fsf request
 * @data: unformatted data
 */
struct zfcp_dbf_pay {
	char area[ZFCP_DBF_TAG_LEN];
	char counter;
	u64 fsf_req_id;
#define ZFCP_DBF_PAY_MAX_REC 0x100
	char data[ZFCP_DBF_PAY_MAX_REC];
} __packed;
209

S
Swen Schillig 已提交
210
struct zfcp_dbf_scsi_record {
211 212 213 214 215 216 217 218 219 220 221 222 223
	u8 tag[ZFCP_DBF_TAG_SIZE];
	u8 tag2[ZFCP_DBF_TAG_SIZE];
	u32 scsi_id;
	u32 scsi_lun;
	u32 scsi_result;
	u64 scsi_cmnd;
#define ZFCP_DBF_SCSI_OPCODE	16
	u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
	u8 scsi_retries;
	u8 scsi_allowed;
	u64 fsf_reqid;
	u32 fsf_seqno;
	u64 fsf_issued;
224 225 226 227 228
	u64 old_fsf_reqid;
	u8 rsp_validity;
	u8 rsp_scsi_status;
	u32 rsp_resid;
	u8 rsp_code;
229 230
#define ZFCP_DBF_SCSI_FCP_SNS_INFO	16
#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO	256
231 232
	u32 sns_info_len;
	u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
233 234
} __attribute__ ((packed));

235
struct zfcp_dbf {
236
	debug_info_t			*pay;
S
Swen Schillig 已提交
237 238 239 240
	debug_info_t			*rec;
	debug_info_t			*hba;
	debug_info_t			*san;
	debug_info_t			*scsi;
241
	spinlock_t			pay_lock;
S
Swen Schillig 已提交
242 243 244 245
	spinlock_t			rec_lock;
	spinlock_t			hba_lock;
	spinlock_t			san_lock;
	spinlock_t			scsi_lock;
246
	struct zfcp_dbf_rec		rec_buf;
247
	struct zfcp_dbf_hba		hba_buf;
248
	struct zfcp_dbf_san		san_buf;
S
Swen Schillig 已提交
249
	struct zfcp_dbf_scsi_record	scsi_buf;
250
	struct zfcp_dbf_pay		pay_buf;
S
Swen Schillig 已提交
251
	struct zfcp_adapter		*adapter;
252 253
};

254
static inline
255
void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
256
{
257 258
	if (level <= req->adapter->dbf->hba->level)
		zfcp_dbf_hba_fsf_res(tag, req);
259 260 261
}

/**
S
Swen Schillig 已提交
262
 * zfcp_dbf_hba_fsf_response - trace event for request completion
263 264
 * @fsf_req: request that has been completed
 */
265 266
static inline
void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
267 268 269 270 271
{
	struct fsf_qtcb *qtcb = req->qtcb;

	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
	    (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
272
		zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
273 274

	} else if (qtcb->header.fsf_status != FSF_GOOD) {
275
		zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req);
276 277 278

	} else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
		   (req->fsf_command == FSF_QTCB_OPEN_LUN)) {
279
		zfcp_dbf_hba_fsf_resp("fs_open", 4, req);
280 281

	} else if (qtcb->header.log_length) {
282
		zfcp_dbf_hba_fsf_resp("fs_qtcb", 5, req);
283 284

	} else {
285
		zfcp_dbf_hba_fsf_resp("fs_norm", 6, req);
286 287 288
	}
}

289
static inline
S
Swen Schillig 已提交
290 291 292
void zfcp_dbf_scsi(const char *tag, const char *tag2, int level,
		   struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
		   struct zfcp_fsf_req *req, unsigned long old_id)
293
{
S
Swen Schillig 已提交
294 295
	if (level <= dbf->scsi->level)
		_zfcp_dbf_scsi(tag, tag2, level, dbf, scmd, req, old_id);
296 297 298
}

/**
S
Swen Schillig 已提交
299
 * zfcp_dbf_scsi_result - trace event for SCSI command completion
300
 * @dbf: adapter dbf trace
301
 * @scmd: SCSI command pointer
302
 * @req: FSF request used to issue SCSI command
303 304
 */
static inline
305 306
void zfcp_dbf_scsi_result(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd,
			  struct zfcp_fsf_req *req)
307
{
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324
	if (scmd->result != 0)
		zfcp_dbf_scsi("rslt", "erro", 3, dbf, scmd, req, 0);
	else if (scmd->retries > 0)
		zfcp_dbf_scsi("rslt", "retr", 4, dbf, scmd, req, 0);
	else
		zfcp_dbf_scsi("rslt", "norm", 6, dbf, scmd, req, 0);
}

/**
 * zfcp_dbf_scsi_fail_send - trace event for failure to send SCSI command
 * @dbf: adapter dbf trace
 * @scmd: SCSI command pointer
 */
static inline
void zfcp_dbf_scsi_fail_send(struct zfcp_dbf *dbf, struct scsi_cmnd *scmd)
{
	zfcp_dbf_scsi("rslt", "fail", 4, dbf, scmd, NULL, 0);
325 326 327
}

/**
S
Swen Schillig 已提交
328
 * zfcp_dbf_scsi_abort - trace event for SCSI command abort
329 330 331 332 333 334 335
 * @tag: tag indicating success or failure of abort operation
 * @adapter: adapter thas has been used to issue SCSI command to be aborted
 * @scmd: SCSI command to be aborted
 * @new_req: request containing abort (might be NULL)
 * @old_id: identifier of request containg SCSI command to be aborted
 */
static inline
S
Swen Schillig 已提交
336 337 338
void zfcp_dbf_scsi_abort(const char *tag, struct zfcp_dbf *dbf,
			 struct scsi_cmnd *scmd, struct zfcp_fsf_req *new_req,
			 unsigned long old_id)
339
{
S
Swen Schillig 已提交
340
	zfcp_dbf_scsi("abrt", tag, 1, dbf, scmd, new_req, old_id);
341 342 343
}

/**
S
Swen Schillig 已提交
344
 * zfcp_dbf_scsi_devreset - trace event for Logical Unit or Target Reset
345
 * @tag: tag indicating success or failure of reset operation
346
 * @scmnd: SCSI command which caused this error recovery
347 348 349
 * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
 */
static inline
350
void zfcp_dbf_scsi_devreset(const char *tag, struct scsi_cmnd *scmnd, u8 flag)
351
{
352 353
	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);

354
	zfcp_dbf_scsi(flag == FCP_TMF_TGT_RESET ? "trst" : "lrst", tag, 1,
355
		      zfcp_sdev->port->adapter->dbf, scmnd, NULL, 0);
356 357
}

358
#endif /* ZFCP_DBF_H */