zfcp_dbf.c 43.7 KB
Newer Older
1
/*
C
Christof Schmitt 已提交
2
 * zfcp device driver
3
 *
C
Christof Schmitt 已提交
4
 * Debug traces for zfcp.
5
 *
C
Christof Schmitt 已提交
6
 * Copyright IBM Corporation 2002, 2008
7 8
 */

9 10 11
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

12
#include <linux/ctype.h>
13
#include <asm/debug.h>
14 15 16 17 18 19 20 21
#include "zfcp_ext.h"

static u32 dbfsize = 4;

module_param(dbfsize, uint, 0400);
MODULE_PARM_DESC(dbfsize,
		 "number of pages for each debug feature area (default 4)");

22 23 24 25 26 27 28 29 30 31 32 33 34 35
static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
			     int level, char *from, int from_len)
{
	int offset;
	struct zfcp_dbf_dump *dump = to;
	int room = to_len - sizeof(*dump);

	for (offset = 0; offset < from_len; offset += dump->size) {
		memset(to, 0, to_len);
		strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
		dump->total_size = from_len;
		dump->offset = offset;
		dump->size = min(from_len - offset, room);
		memcpy(dump->data, from + offset, dump->size);
36
		debug_event(dbf, level, dump, dump->size + sizeof(*dump));
37 38 39
	}
}

40 41
/* FIXME: this duplicate this code in s390 debug feature */
static void zfcp_dbf_timestamp(unsigned long long stck, struct timespec *time)
42 43 44 45 46 47
{
	unsigned long long sec;

	stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
	sec = stck >> 12;
	do_div(sec, 1000000);
48
	time->tv_sec = sec;
49
	stck -= (sec * 1000000) << 12;
50
	time->tv_nsec = ((stck * 1000) >> 12);
51 52
}

53
static void zfcp_dbf_tag(char **p, const char *label, const char *tag)
54
{
55
	int i;
56

57
	*p += sprintf(*p, "%-24s", label);
58
	for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
59 60
		*p += sprintf(*p, "%c", tag[i]);
	*p += sprintf(*p, "\n");
61 62
}

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2)
{
	*buf += sprintf(*buf, "%-24s%s\n", s1, s2);
}

static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...)
{
	va_list arg;

	*buf += sprintf(*buf, "%-24s", s);
	va_start(arg, format);
	*buf += vsprintf(*buf, format, arg);
	va_end(arg);
	*buf += sprintf(*buf, "\n");
}

79 80
static void zfcp_dbf_outd(char **p, const char *label, char *buffer,
			  int buflen, int offset, int total_size)
81
{
82 83
	if (!offset)
		*p += sprintf(*p, "%-24s  ", label);
84 85 86
	while (buflen--) {
		if (offset > 0) {
			if ((offset % 32) == 0)
87
				*p += sprintf(*p, "\n%-24c  ", ' ');
88
			else if ((offset % 4) == 0)
89
				*p += sprintf(*p, " ");
90
		}
91
		*p += sprintf(*p, "%02x", *buffer++);
92
		if (++offset == total_size) {
93
			*p += sprintf(*p, "\n");
94 95 96
			break;
		}
	}
97 98
	if (!total_size)
		*p += sprintf(*p, "\n");
99 100
}

101 102
static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
				int area, debug_entry_t *entry, char *out_buf)
103 104
{
	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
105
	struct timespec t;
106
	char *p = out_buf;
107 108

	if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
109
		zfcp_dbf_timestamp(entry->id.stck, &t);
110 111 112 113
		zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu",
			     t.tv_sec, t.tv_nsec);
		zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
	} else	{
114
		zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset,
115
			      dump->total_size);
116
		if ((dump->offset + dump->size) == dump->total_size)
117
			p += sprintf(p, "\n");
118
	}
119
	return p - out_buf;
120 121
}

122 123 124 125
/**
 * zfcp_hba_dbf_event_fsf_response - trace event for request completion
 * @fsf_req: request that has been completed
 */
126
void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
127 128 129 130
{
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct fsf_qtcb *qtcb = fsf_req->qtcb;
	union fsf_prot_status_qual *prot_status_qual =
131
					&qtcb->prefix.prot_status_qual;
132 133 134 135 136 137
	union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
	struct scsi_cmnd *scsi_cmnd;
	struct zfcp_port *port;
	struct zfcp_unit *unit;
	struct zfcp_send_els *send_els;
	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
138
	struct zfcp_hba_dbf_record_response *response = &rec->u.response;
139 140 141 142
	int level;
	unsigned long flags;

	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
143
	memset(rec, 0, sizeof(*rec));
144 145 146 147 148 149 150 151 152 153 154 155 156
	strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);

	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
	    (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {
		strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);
		level = 1;
	} else if (qtcb->header.fsf_status != FSF_GOOD) {
		strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);
		level = 1;
	} else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
		   (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
		strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
		level = 4;
157 158 159
	} else if (qtcb->header.log_length) {
		strncpy(rec->tag2, "qtcb", ZFCP_DBF_TAG_SIZE);
		level = 5;
160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
	} else {
		strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
		level = 6;
	}

	response->fsf_command = fsf_req->fsf_command;
	response->fsf_reqid = (unsigned long)fsf_req;
	response->fsf_seqno = fsf_req->seq_no;
	response->fsf_issued = fsf_req->issued;
	response->fsf_prot_status = qtcb->prefix.prot_status;
	response->fsf_status = qtcb->header.fsf_status;
	memcpy(response->fsf_prot_status_qual,
	       prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);
	memcpy(response->fsf_status_qual,
	       fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);
	response->fsf_req_status = fsf_req->status;
	response->sbal_first = fsf_req->sbal_first;
177
	response->sbal_last = fsf_req->sbal_last;
178
	response->sbal_response = fsf_req->sbal_response;
179 180 181 182 183 184 185 186
	response->pool = fsf_req->pool != NULL;
	response->erp_action = (unsigned long)fsf_req->erp_action;

	switch (fsf_req->fsf_command) {
	case FSF_QTCB_FCP_CMND:
		if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
			break;
		scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
187 188 189
		if (scsi_cmnd) {
			response->u.fcp.cmnd = (unsigned long)scsi_cmnd;
			response->u.fcp.serial = scsi_cmnd->serial_number;
190 191 192 193 194 195 196
		}
		break;

	case FSF_QTCB_OPEN_PORT_WITH_DID:
	case FSF_QTCB_CLOSE_PORT:
	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
		port = (struct zfcp_port *)fsf_req->data;
197 198 199
		response->u.port.wwpn = port->wwpn;
		response->u.port.d_id = port->d_id;
		response->u.port.port_handle = qtcb->header.port_handle;
200 201 202 203 204 205
		break;

	case FSF_QTCB_OPEN_LUN:
	case FSF_QTCB_CLOSE_LUN:
		unit = (struct zfcp_unit *)fsf_req->data;
		port = unit->port;
206 207 208 209
		response->u.unit.wwpn = port->wwpn;
		response->u.unit.fcp_lun = unit->fcp_lun;
		response->u.unit.port_handle = qtcb->header.port_handle;
		response->u.unit.lun_handle = qtcb->header.lun_handle;
210 211 212 213
		break;

	case FSF_QTCB_SEND_ELS:
		send_els = (struct zfcp_send_els *)fsf_req->data;
214 215
		response->u.els.d_id = qtcb->bottom.support.d_id;
		response->u.els.ls_code = send_els->ls_code >> 24;
216 217 218 219 220 221 222 223 224 225 226
		break;

	case FSF_QTCB_ABORT_FCP_CMND:
	case FSF_QTCB_SEND_GENERIC:
	case FSF_QTCB_EXCHANGE_CONFIG_DATA:
	case FSF_QTCB_EXCHANGE_PORT_DATA:
	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
	case FSF_QTCB_UPLOAD_CONTROL_FILE:
		break;
	}

227
	debug_event(adapter->hba_dbf, level, rec, sizeof(*rec));
228 229 230 231 232 233 234 235 236 237 238

	/* have fcp channel microcode fixed to use as little as possible */
	if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) {
		/* adjust length skipping trailing zeros */
		char *buf = (char *)qtcb + qtcb->header.log_start;
		int len = qtcb->header.log_length;
		for (; len && !buf[len - 1]; len--);
		zfcp_dbf_hexdump(adapter->hba_dbf, rec, sizeof(*rec), level,
				 buf, len);
	}

239 240 241
	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}

242 243 244 245 246 247
/**
 * zfcp_hba_dbf_event_fsf_unsol - trace event for an unsolicited status buffer
 * @tag: tag indicating which kind of unsolicited status has been received
 * @adapter: adapter that has issued the unsolicited status buffer
 * @status_buffer: buffer containing payload of unsolicited status
 */
248 249
void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
				  struct fsf_status_read_buffer *status_buffer)
250 251 252 253 254
{
	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
	unsigned long flags;

	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
255
	memset(rec, 0, sizeof(*rec));
256 257 258
	strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
	strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);

259
	rec->u.status.failed = atomic_read(&adapter->stat_miss);
260
	if (status_buffer != NULL) {
261 262 263
		rec->u.status.status_type = status_buffer->status_type;
		rec->u.status.status_subtype = status_buffer->status_subtype;
		memcpy(&rec->u.status.queue_designator,
264 265 266 267 268
		       &status_buffer->queue_designator,
		       sizeof(struct fsf_queue_designator));

		switch (status_buffer->status_type) {
		case FSF_STATUS_READ_SENSE_DATA_AVAIL:
269
			rec->u.status.payload_size =
270 271 272 273
			    ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
			break;

		case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
274
			rec->u.status.payload_size =
275 276 277 278
			    ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
			break;

		case FSF_STATUS_READ_LINK_DOWN:
279 280 281
			switch (status_buffer->status_subtype) {
			case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
			case FSF_STATUS_READ_SUB_FDISC_FAILED:
282
				rec->u.status.payload_size =
283 284
					sizeof(struct fsf_link_down_info);
			}
285 286
			break;

287
		case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
288
			rec->u.status.payload_size =
289 290
			    ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
			break;
291
		}
292 293
		memcpy(&rec->u.status.payload,
		       &status_buffer->payload, rec->u.status.payload_size);
294 295
	}

296
	debug_event(adapter->hba_dbf, 2, rec, sizeof(*rec));
297 298 299
	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}

300 301 302 303 304 305 306
/**
 * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure
 * @adapter: adapter affected by this QDIO related event
 * @qdio_error: as passed by qdio module
 * @sbal_index: first buffer with error condition, as passed by qdio module
 * @sbal_count: number of buffers affected, as passed by qdio module
 */
J
Jan Glauber 已提交
307 308 309
void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter,
			     unsigned int qdio_error, int sbal_index,
			     int sbal_count)
310
{
311
	struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
312 313 314
	unsigned long flags;

	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
315 316 317 318 319 320
	memset(r, 0, sizeof(*r));
	strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE);
	r->u.qdio.qdio_error = qdio_error;
	r->u.qdio.sbal_index = sbal_index;
	r->u.qdio.sbal_count = sbal_count;
	debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
321 322 323
	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}

324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
/**
 * zfcp_hba_dbf_event_berr - trace event for bit error threshold
 * @adapter: adapter affected by this QDIO related event
 * @req: fsf request
 */
void zfcp_hba_dbf_event_berr(struct zfcp_adapter *adapter,
			     struct zfcp_fsf_req *req)
{
	struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
	struct fsf_status_read_buffer *sr_buf = req->data;
	struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error;
	unsigned long flags;

	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE);
	memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload));
	debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
}
344 345
static void zfcp_hba_dbf_view_response(char **p,
				       struct zfcp_hba_dbf_record_response *r)
346
{
347
	struct timespec t;
348

349 350 351
	zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command);
	zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
	zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno);
352
	zfcp_dbf_timestamp(r->fsf_issued, &t);
353 354 355 356
	zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
	zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status);
	zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status);
	zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual,
357
		      FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE);
358
	zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual,
359
		      FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE);
360 361
	zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status);
	zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first);
362
	zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last);
363
	zfcp_dbf_out(p, "sbal_response", "0x%02x", r->sbal_response);
364
	zfcp_dbf_out(p, "pool", "0x%02x", r->pool);
365 366

	switch (r->fsf_command) {
367
	case FSF_QTCB_FCP_CMND:
368
		if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
369
			break;
370 371
		zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
		zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
372
		p += sprintf(*p, "\n");
373 374 375 376 377
		break;

	case FSF_QTCB_OPEN_PORT_WITH_DID:
	case FSF_QTCB_CLOSE_PORT:
	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
378 379 380
		zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn);
		zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id);
		zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle);
381 382 383 384
		break;

	case FSF_QTCB_OPEN_LUN:
	case FSF_QTCB_CLOSE_LUN:
385 386 387 388
		zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn);
		zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun);
		zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle);
		zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle);
389 390 391
		break;

	case FSF_QTCB_SEND_ELS:
392 393
		zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
		zfcp_dbf_out(p, "ls_code", "0x%02x", r->u.els.ls_code);
394 395 396 397 398 399 400 401 402 403 404 405
		break;

	case FSF_QTCB_ABORT_FCP_CMND:
	case FSF_QTCB_SEND_GENERIC:
	case FSF_QTCB_EXCHANGE_CONFIG_DATA:
	case FSF_QTCB_EXCHANGE_PORT_DATA:
	case FSF_QTCB_DOWNLOAD_CONTROL_FILE:
	case FSF_QTCB_UPLOAD_CONTROL_FILE:
		break;
	}
}

406 407
static void zfcp_hba_dbf_view_status(char **p,
				     struct zfcp_hba_dbf_record_status *r)
408
{
409 410 411 412
	zfcp_dbf_out(p, "failed", "0x%02x", r->failed);
	zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type);
	zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype);
	zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator,
413 414
		      sizeof(struct fsf_queue_designator), 0,
		      sizeof(struct fsf_queue_designator));
415
	zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0,
416
		      r->payload_size);
417 418
}

419
static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r)
420
{
421 422 423
	zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error);
	zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index);
	zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
424 425
}

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449
static void zfcp_hba_dbf_view_berr(char **p, struct fsf_bit_error_payload *r)
{
	zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count);
	zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count);
	zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count);
	zfcp_dbf_out(p, "prim_seq_err", "%d",
		     r->primitive_sequence_error_count);
	zfcp_dbf_out(p, "inval_trans_word_err", "%d",
		     r->invalid_transmission_word_error_count);
	zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count);
	zfcp_dbf_out(p, "prim_seq_event_to", "%d",
		     r->primitive_sequence_event_timeout_count);
	zfcp_dbf_out(p, "elast_buf_overrun_err", "%d",
		     r->elastic_buffer_overrun_error_count);
	zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d",
		     r->advertised_receive_b2b_credit);
	zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d",
		     r->current_receive_b2b_credit);
	zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d",
		     r->advertised_transmit_b2b_credit);
	zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d",
		     r->current_transmit_b2b_credit);
}

450 451
static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
				    char *out_buf, const char *in_buf)
452
{
453 454
	struct zfcp_hba_dbf_record *r = (struct zfcp_hba_dbf_record *)in_buf;
	char *p = out_buf;
455

456
	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
457 458
		return 0;

459 460 461 462 463
	zfcp_dbf_tag(&p, "tag", r->tag);
	if (isalpha(r->tag2[0]))
		zfcp_dbf_tag(&p, "tag2", r->tag2);

	if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
464
		zfcp_hba_dbf_view_response(&p, &r->u.response);
465
	else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
466
		zfcp_hba_dbf_view_status(&p, &r->u.status);
467
	else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
468
		zfcp_hba_dbf_view_qdio(&p, &r->u.qdio);
469 470
	else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
		zfcp_hba_dbf_view_berr(&p, &r->u.berr);
471

472 473
	if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0)
		p += sprintf(p, "\n");
474
	return p - out_buf;
475 476
}

477
static struct debug_view zfcp_hba_dbf_view = {
478 479 480 481 482 483 484 485
	"structured",
	NULL,
	&zfcp_dbf_view_header,
	&zfcp_hba_dbf_view_format,
	NULL,
	NULL
};

486
static const char *zfcp_rec_dbf_tags[] = {
487
	[ZFCP_REC_DBF_ID_THREAD] = "thread",
488
	[ZFCP_REC_DBF_ID_TARGET] = "target",
489
	[ZFCP_REC_DBF_ID_TRIGGER] = "trigger",
490
	[ZFCP_REC_DBF_ID_ACTION] = "action",
491 492 493
};

static const char *zfcp_rec_dbf_ids[] = {
494 495 496 497 498 499 500 501 502
	[1]	= "new",
	[2]	= "ready",
	[3]	= "kill",
	[4]	= "down sleep",
	[5]	= "down wakeup",
	[6]	= "down sleep ecd",
	[7]	= "down wakeup ecd",
	[8]	= "down sleep epd",
	[9]	= "down wakeup epd",
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547
	[10]	= "online",
	[11]	= "operational",
	[12]	= "scsi slave destroy",
	[13]	= "propagate failed adapter",
	[14]	= "propagate failed port",
	[15]	= "block adapter",
	[16]	= "unblock adapter",
	[17]	= "block port",
	[18]	= "unblock port",
	[19]	= "block unit",
	[20]	= "unblock unit",
	[21]	= "unit recovery failed",
	[22]	= "port recovery failed",
	[23]	= "adapter recovery failed",
	[24]	= "qdio queues down",
	[25]	= "p2p failed",
	[26]	= "nameserver lookup failed",
	[27]	= "nameserver port failed",
	[28]	= "link up",
	[29]	= "link down",
	[30]	= "link up status read",
	[31]	= "open port failed",
	[32]	= "open port failed",
	[33]	= "close port",
	[34]	= "open unit failed",
	[35]	= "exclusive open unit failed",
	[36]	= "shared open unit failed",
	[37]	= "link down",
	[38]	= "link down status read no link",
	[39]	= "link down status read fdisc login",
	[40]	= "link down status read firmware update",
	[41]	= "link down status read unknown reason",
	[42]	= "link down ecd incomplete",
	[43]	= "link down epd incomplete",
	[44]	= "sysfs adapter recovery",
	[45]	= "sysfs port recovery",
	[46]	= "sysfs unit recovery",
	[47]	= "port boxed abort",
	[48]	= "unit boxed abort",
	[49]	= "port boxed ct",
	[50]	= "port boxed close physical",
	[51]	= "port boxed open unit",
	[52]	= "port boxed close unit",
	[53]	= "port boxed fcp",
	[54]	= "unit boxed fcp",
C
Christof Schmitt 已提交
548 549 550 551 552
	[55]	= "port access denied",
	[56]	= "",
	[57]	= "",
	[58]	= "",
	[59]	= "unit access denied",
553
	[60]	= "shared unit access denied open unit",
C
Christof Schmitt 已提交
554
	[61]	= "",
555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572
	[62]	= "request timeout",
	[63]	= "adisc link test reject or timeout",
	[64]	= "adisc link test d_id changed",
	[65]	= "adisc link test failed",
	[66]	= "recovery out of memory",
	[67]	= "adapter recovery repeated after state change",
	[68]	= "port recovery repeated after state change",
	[69]	= "unit recovery repeated after state change",
	[70]	= "port recovery follow-up after successful adapter recovery",
	[71]	= "adapter recovery escalation after failed adapter recovery",
	[72]	= "port recovery follow-up after successful physical port "
		  "recovery",
	[73]	= "adapter recovery escalation after failed physical port "
		  "recovery",
	[74]	= "unit recovery follow-up after successful port recovery",
	[75]	= "physical port recovery escalation after failed port "
		  "recovery",
	[76]	= "port recovery escalation after failed unit recovery",
573
	[77]	= "",
574 575 576 577 578
	[78]	= "duplicate request id",
	[79]	= "link down",
	[80]	= "exclusive read-only unit access unsupported",
	[81]	= "shared read-write unit access unsupported",
	[82]	= "incoming rscn",
579
	[83]	= "incoming wwpn",
580
	[84]	= "wka port handle not valid close port",
581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618
	[85]	= "online",
	[86]	= "offline",
	[87]	= "ccw device gone",
	[88]	= "ccw device no path",
	[89]	= "ccw device operational",
	[90]	= "ccw device shutdown",
	[91]	= "sysfs port addition",
	[92]	= "sysfs port removal",
	[93]	= "sysfs adapter recovery",
	[94]	= "sysfs unit addition",
	[95]	= "sysfs unit removal",
	[96]	= "sysfs port recovery",
	[97]	= "sysfs unit recovery",
	[98]	= "sequence number mismatch",
	[99]	= "link up",
	[100]	= "error state",
	[101]	= "status read physical port closed",
	[102]	= "link up status read",
	[103]	= "too many failed status read buffers",
	[104]	= "port handle not valid abort",
	[105]	= "lun handle not valid abort",
	[106]	= "port handle not valid ct",
	[107]	= "port handle not valid close port",
	[108]	= "port handle not valid close physical port",
	[109]	= "port handle not valid open unit",
	[110]	= "port handle not valid close unit",
	[111]	= "lun handle not valid close unit",
	[112]	= "port handle not valid fcp",
	[113]	= "lun handle not valid fcp",
	[114]	= "handle mismatch fcp",
	[115]	= "lun not valid fcp",
	[116]	= "qdio send failed",
	[117]	= "version mismatch",
	[118]	= "incompatible qtcb type",
	[119]	= "unknown protocol status",
	[120]	= "unknown fsf command",
	[121]	= "no recommendation for status qualifier",
	[122]	= "status read physical port closed in error",
C
Christof Schmitt 已提交
619 620
	[123]	= "fc service class not supported",
	[124]	= "",
621 622 623
	[125]	= "need newer zfcp",
	[126]	= "need newer microcode",
	[127]	= "arbitrated loop not supported",
624
	[128]	= "",
625 626 627
	[129]	= "qtcb size mismatch",
	[130]	= "unknown fsf status ecd",
	[131]	= "fcp request too big",
C
Christof Schmitt 已提交
628
	[132]	= "",
629 630 631 632 633 634 635
	[133]	= "data direction not valid fcp",
	[134]	= "command length not valid fcp",
	[135]	= "status read act update",
	[136]	= "status read cfdc update",
	[137]	= "hbaapi port open",
	[138]	= "hbaapi unit open",
	[139]	= "hbaapi unit shutdown",
S
Swen Schillig 已提交
636
	[140]	= "qdio error outbound",
637
	[141]	= "scsi host reset",
638 639 640 641 642
	[142]	= "dismissing fsf request for recovery action",
	[143]	= "recovery action timed out",
	[144]	= "recovery action gone",
	[145]	= "recovery action being processed",
	[146]	= "recovery action ready for next step",
S
Swen Schillig 已提交
643
	[147]	= "qdio error inbound",
644 645 646 647
	[148]   = "nameserver needed for port scan",
	[149]   = "port scan",
	[150]	= "ptp attach",
	[151]   = "port validation failed",
648 649 650 651 652 653 654 655 656 657 658 659
};

static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
				    char *buf, const char *_rec)
{
	struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec;
	char *p = buf;

	zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]);
	zfcp_dbf_outs(&p, "hint", zfcp_rec_dbf_ids[r->id2]);
	zfcp_dbf_out(&p, "id", "%d", r->id2);
	switch (r->id) {
660 661 662 663 664
	case ZFCP_REC_DBF_ID_THREAD:
		zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
		zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready);
		zfcp_dbf_out(&p, "running", "%d", r->u.thread.running);
		break;
665 666 667 668 669 670 671 672
	case ZFCP_REC_DBF_ID_TARGET:
		zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref);
		zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status);
		zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count);
		zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id);
		zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn);
		zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun);
		break;
673 674 675 676 677 678 679 680 681 682 683
	case ZFCP_REC_DBF_ID_TRIGGER:
		zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref);
		zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action);
		zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want);
		zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need);
		zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn);
		zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
		zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
		zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
		zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us);
		break;
684 685 686 687 688 689
	case ZFCP_REC_DBF_ID_ACTION:
		zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
		zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req);
		zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status);
		zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step);
		break;
690
	}
691 692
	p += sprintf(p, "\n");
	return p - buf;
693 694 695 696 697 698 699 700 701 702 703
}

static struct debug_view zfcp_rec_dbf_view = {
	"structured",
	NULL,
	&zfcp_dbf_view_header,
	&zfcp_rec_dbf_view_format,
	NULL,
	NULL
};

704 705 706 707
/**
 * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation
 * @id2: identifier for event
 * @adapter: adapter
708
 * This function assumes that the caller is holding erp_lock.
709
 */
710
void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter)
711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729
{
	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
	unsigned long flags = 0;
	struct list_head *entry;
	unsigned ready = 0, running = 0, total;

	list_for_each(entry, &adapter->erp_ready_head)
		ready++;
	list_for_each(entry, &adapter->erp_running_head)
		running++;
	total = adapter->erp_total_count;

	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	r->id = ZFCP_REC_DBF_ID_THREAD;
	r->id2 = id2;
	r->u.thread.total = total;
	r->u.thread.ready = ready;
	r->u.thread.running = running;
730
	debug_event(adapter->rec_dbf, 6, r, sizeof(*r));
731 732 733
	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
}

734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
/**
 * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation
 * @id2: identifier for event
 * @adapter: adapter
 * This function assumes that the caller does not hold erp_lock.
 */
void zfcp_rec_dbf_event_thread_lock(u8 id2, struct zfcp_adapter *adapter)
{
	unsigned long flags;

	read_lock_irqsave(&adapter->erp_lock, flags);
	zfcp_rec_dbf_event_thread(id2, adapter);
	read_unlock_irqrestore(&adapter->erp_lock, flags);
}

749
static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
750 751 752 753 754 755 756 757 758 759 760
				      struct zfcp_adapter *adapter,
				      atomic_t *status, atomic_t *erp_count,
				      u64 wwpn, u32 d_id, u64 fcp_lun)
{
	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
	unsigned long flags;

	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	r->id = ZFCP_REC_DBF_ID_TARGET;
	r->id2 = id2;
761
	r->u.target.ref = (unsigned long)ref;
762 763 764 765 766 767 768 769 770 771 772 773 774 775 776
	r->u.target.status = atomic_read(status);
	r->u.target.wwpn = wwpn;
	r->u.target.d_id = d_id;
	r->u.target.fcp_lun = fcp_lun;
	r->u.target.erp_count = atomic_read(erp_count);
	debug_event(adapter->rec_dbf, 3, r, sizeof(*r));
	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
}

/**
 * zfcp_rec_dbf_event_adapter - trace event for adapter state change
 * @id: identifier for trigger of state change
 * @ref: additional reference (e.g. request)
 * @adapter: adapter
 */
777
void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter)
778 779 780 781 782 783 784 785 786 787 788
{
	zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status,
				  &adapter->erp_counter, 0, 0, 0);
}

/**
 * zfcp_rec_dbf_event_port - trace event for port state change
 * @id: identifier for trigger of state change
 * @ref: additional reference (e.g. request)
 * @port: port
 */
789
void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port)
790 791 792 793 794 795 796 797 798 799 800 801 802 803
{
	struct zfcp_adapter *adapter = port->adapter;

	zfcp_rec_dbf_event_target(id, ref, adapter, &port->status,
				  &port->erp_counter, port->wwpn, port->d_id,
				  0);
}

/**
 * zfcp_rec_dbf_event_unit - trace event for unit state change
 * @id: identifier for trigger of state change
 * @ref: additional reference (e.g. request)
 * @unit: unit
 */
804
void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit)
805 806 807 808 809 810 811 812 813
{
	struct zfcp_port *port = unit->port;
	struct zfcp_adapter *adapter = port->adapter;

	zfcp_rec_dbf_event_target(id, ref, adapter, &unit->status,
				  &unit->erp_counter, port->wwpn, port->d_id,
				  unit->fcp_lun);
}

814 815 816 817 818 819 820 821 822 823 824
/**
 * zfcp_rec_dbf_event_trigger - trace event for triggered error recovery
 * @id2: identifier for error recovery trigger
 * @ref: additional reference (e.g. request)
 * @want: originally requested error recovery action
 * @need: error recovery action actually initiated
 * @action: address of error recovery action struct
 * @adapter: adapter
 * @port: port
 * @unit: unit
 */
825 826
void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
				void *action, struct zfcp_adapter *adapter,
827 828 829 830 831 832 833 834 835
				struct zfcp_port *port, struct zfcp_unit *unit)
{
	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
	unsigned long flags;

	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	r->id = ZFCP_REC_DBF_ID_TRIGGER;
	r->id2 = id2;
836
	r->u.trigger.ref = (unsigned long)ref;
837 838
	r->u.trigger.want = want;
	r->u.trigger.need = need;
839
	r->u.trigger.action = (unsigned long)action;
840 841 842 843 844 845 846 847 848 849 850 851 852
	r->u.trigger.as = atomic_read(&adapter->status);
	if (port) {
		r->u.trigger.ps = atomic_read(&port->status);
		r->u.trigger.wwpn = port->wwpn;
	}
	if (unit) {
		r->u.trigger.us = atomic_read(&unit->status);
		r->u.trigger.fcp_lun = unit->fcp_lun;
	}
	debug_event(adapter->rec_dbf, action ? 1 : 4, r, sizeof(*r));
	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
}

853 854 855 856 857 858 859 860 861 862 863 864 865 866 867
/**
 * zfcp_rec_dbf_event_action - trace event showing progress of recovery action
 * @id2: identifier
 * @erp_action: error recovery action struct pointer
 */
void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
{
	struct zfcp_adapter *adapter = erp_action->adapter;
	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
	unsigned long flags;

	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	r->id = ZFCP_REC_DBF_ID_ACTION;
	r->id2 = id2;
868
	r->u.action.action = (unsigned long)erp_action;
869 870
	r->u.action.status = erp_action->status;
	r->u.action.step = erp_action->step;
871
	r->u.action.fsf_req = (unsigned long)erp_action->fsf_req;
872
	debug_event(adapter->rec_dbf, 5, r, sizeof(*r));
873 874 875
	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
}

876 877 878 879
/**
 * zfcp_san_dbf_event_ct_request - trace event for issued CT request
 * @fsf_req: request containing issued CT data
 */
880
void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
881 882
{
	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
883 884
	struct zfcp_wka_port *wka_port = ct->wka_port;
	struct zfcp_adapter *adapter = wka_port->adapter;
885
	struct ct_hdr *hdr = sg_virt(ct->req);
886 887
	struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
	struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
888
	int level = 3;
889
	unsigned long flags;
890

891 892 893 894 895 896
	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
	r->fsf_reqid = (unsigned long)fsf_req;
	r->fsf_seqno = fsf_req->seq_no;
	r->s_id = fc_host_port_id(adapter->scsi_host);
897
	r->d_id = wka_port->d_id;
898 899 900 901 902 903 904
	oct->cmd_req_code = hdr->cmd_rsp_code;
	oct->revision = hdr->revision;
	oct->gs_type = hdr->gs_type;
	oct->gs_subtype = hdr->gs_subtype;
	oct->options = hdr->options;
	oct->max_res_size = hdr->max_res_size;
	oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
905 906 907 908
		       ZFCP_DBF_SAN_MAX_PAYLOAD);
	debug_event(adapter->san_dbf, level, r, sizeof(*r));
	zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
			 (void *)hdr + sizeof(struct ct_hdr), oct->len);
909
	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
910 911
}

912 913 914 915
/**
 * zfcp_san_dbf_event_ct_response - trace event for completion of CT request
 * @fsf_req: request containing CT response
 */
916
void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
917 918
{
	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
919 920
	struct zfcp_wka_port *wka_port = ct->wka_port;
	struct zfcp_adapter *adapter = wka_port->adapter;
921
	struct ct_hdr *hdr = sg_virt(ct->resp);
922 923
	struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
	struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
924
	int level = 3;
925
	unsigned long flags;
926

927 928 929 930 931
	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
	memset(r, 0, sizeof(*r));
	strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
	r->fsf_reqid = (unsigned long)fsf_req;
	r->fsf_seqno = fsf_req->seq_no;
932
	r->s_id = wka_port->d_id;
933 934 935 936 937 938 939
	r->d_id = fc_host_port_id(adapter->scsi_host);
	rct->cmd_rsp_code = hdr->cmd_rsp_code;
	rct->revision = hdr->revision;
	rct->reason_code = hdr->reason_code;
	rct->expl = hdr->reason_code_expl;
	rct->vendor_unique = hdr->vendor_unique;
	rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
940 941 942 943
		       ZFCP_DBF_SAN_MAX_PAYLOAD);
	debug_event(adapter->san_dbf, level, r, sizeof(*r));
	zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
			 (void *)hdr + sizeof(struct ct_hdr), rct->len);
944
	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
945 946
}

947 948 949 950
static void zfcp_san_dbf_event_els(const char *tag, int level,
				   struct zfcp_fsf_req *fsf_req, u32 s_id,
				   u32 d_id, u8 ls_code, void *buffer,
				   int buflen)
951 952 953 954 955 956
{
	struct zfcp_adapter *adapter = fsf_req->adapter;
	struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
	unsigned long flags;

	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
957
	memset(rec, 0, sizeof(*rec));
958 959 960 961 962
	strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
	rec->fsf_reqid = (unsigned long)fsf_req;
	rec->fsf_seqno = fsf_req->seq_no;
	rec->s_id = s_id;
	rec->d_id = d_id;
963
	rec->u.els.ls_code = ls_code;
964 965
	debug_event(adapter->san_dbf, level, rec, sizeof(*rec));
	zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level,
966
			 buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
967 968 969
	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
}

970 971 972 973
/**
 * zfcp_san_dbf_event_els_request - trace event for issued ELS
 * @fsf_req: request containing issued ELS
 */
974
void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
975 976 977
{
	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;

978 979
	zfcp_san_dbf_event_els("oels", 2, fsf_req,
			       fc_host_port_id(els->adapter->scsi_host),
980 981
			       els->d_id, *(u8 *) sg_virt(els->req),
			       sg_virt(els->req), els->req->length);
982 983
}

984 985 986 987
/**
 * zfcp_san_dbf_event_els_response - trace event for completed ELS
 * @fsf_req: request containing ELS response
 */
988
void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
989 990 991
{
	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;

992 993
	zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id,
			       fc_host_port_id(els->adapter->scsi_host),
994
			       *(u8 *)sg_virt(els->req), sg_virt(els->resp),
995
			       els->resp->length);
996 997
}

998 999 1000 1001
/**
 * zfcp_san_dbf_event_incoming_els - trace event for incomig ELS
 * @fsf_req: request containing unsolicited status buffer with incoming ELS
 */
1002
void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
1003 1004
{
	struct zfcp_adapter *adapter = fsf_req->adapter;
1005 1006 1007 1008 1009 1010 1011
	struct fsf_status_read_buffer *buf =
			(struct fsf_status_read_buffer *)fsf_req->data;
	int length = (int)buf->length -
		     (int)((void *)&buf->payload - (void *)buf);

	zfcp_san_dbf_event_els("iels", 1, fsf_req, buf->d_id,
			       fc_host_port_id(adapter->scsi_host),
S
Swen Schillig 已提交
1012
			       buf->payload.data[0], (void *)buf->payload.data,
1013
			       length);
1014 1015
}

1016 1017
static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
				    char *out_buf, const char *in_buf)
1018
{
1019 1020
	struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf;
	char *p = out_buf;
1021

1022
	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
1023 1024
		return 0;

1025
	zfcp_dbf_tag(&p, "tag", r->tag);
1026 1027 1028 1029 1030 1031
	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
	zfcp_dbf_out(&p, "s_id", "0x%06x", r->s_id);
	zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id);

	if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
1032 1033 1034 1035 1036 1037 1038
		struct zfcp_san_dbf_record_ct_request *ct = &r->u.ct_req;
		zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
		zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
		zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype);
		zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
		zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
1039
	} else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
1040 1041 1042 1043 1044 1045
		struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp;
		zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
		zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
		zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
		zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
1046 1047 1048
	} else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
		   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
		   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
1049 1050
		struct zfcp_san_dbf_record_els *els = &r->u.els;
		zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
1051
	}
1052
	return p - out_buf;
1053 1054
}

1055
static struct debug_view zfcp_san_dbf_view = {
1056 1057 1058 1059 1060 1061 1062 1063
	"structured",
	NULL,
	&zfcp_dbf_view_header,
	&zfcp_san_dbf_view_format,
	NULL,
	NULL
};

1064 1065 1066 1067 1068
static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level,
				struct zfcp_adapter *adapter,
				struct scsi_cmnd *scsi_cmnd,
				struct zfcp_fsf_req *fsf_req,
				unsigned long old_req_id)
1069 1070 1071 1072 1073 1074 1075 1076 1077 1078
{
	struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
	unsigned long flags;
	struct fcp_rsp_iu *fcp_rsp;
	char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;
	int offset = 0, buflen = 0;

	spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
	do {
1079
		memset(rec, 0, sizeof(*rec));
1080 1081 1082
		if (offset == 0) {
			strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
			strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
1083 1084 1085 1086 1087 1088 1089 1090
			if (scsi_cmnd != NULL) {
				if (scsi_cmnd->device) {
					rec->scsi_id = scsi_cmnd->device->id;
					rec->scsi_lun = scsi_cmnd->device->lun;
				}
				rec->scsi_result = scsi_cmnd->result;
				rec->scsi_cmnd = (unsigned long)scsi_cmnd;
				rec->scsi_serial = scsi_cmnd->serial_number;
1091
				memcpy(rec->scsi_opcode, scsi_cmnd->cmnd,
1092 1093 1094 1095
					min((int)scsi_cmnd->cmd_len,
						ZFCP_DBF_SCSI_OPCODE));
				rec->scsi_retries = scsi_cmnd->retries;
				rec->scsi_allowed = scsi_cmnd->allowed;
1096 1097 1098 1099
			}
			if (fsf_req != NULL) {
				fcp_rsp = (struct fcp_rsp_iu *)
				    &(fsf_req->qtcb->bottom.io.fcp_rsp);
1100
				fcp_rsp_info = (unsigned char *) &fcp_rsp[1];
1101 1102 1103
				fcp_sns_info =
				    zfcp_get_fcp_sns_info_ptr(fcp_rsp);

1104 1105 1106
				rec->rsp_validity = fcp_rsp->validity.value;
				rec->rsp_scsi_status = fcp_rsp->scsi_status;
				rec->rsp_resid = fcp_rsp->fcp_resid;
1107
				if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
1108
					rec->rsp_code = *(fcp_rsp_info + 3);
1109 1110 1111
				if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
					buflen = min((int)fcp_rsp->fcp_sns_len,
						     ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
1112 1113
					rec->sns_info_len = buflen;
					memcpy(rec->sns_info, fcp_sns_info,
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123
					       min(buflen,
						   ZFCP_DBF_SCSI_FCP_SNS_INFO));
					offset += min(buflen,
						      ZFCP_DBF_SCSI_FCP_SNS_INFO);
				}

				rec->fsf_reqid = (unsigned long)fsf_req;
				rec->fsf_seqno = fsf_req->seq_no;
				rec->fsf_issued = fsf_req->issued;
			}
1124
			rec->old_fsf_reqid = old_req_id;
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
		} else {
			strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
			dump->total_size = buflen;
			dump->offset = offset;
			dump->size = min(buflen - offset,
					 (int)sizeof(struct
						     zfcp_scsi_dbf_record) -
					 (int)sizeof(struct zfcp_dbf_dump));
			memcpy(dump->data, fcp_sns_info + offset, dump->size);
			offset += dump->size;
		}
1136
		debug_event(adapter->scsi_dbf, level, rec, sizeof(*rec));
1137 1138 1139 1140
	} while (offset < buflen);
	spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
}

1141 1142 1143 1144 1145 1146 1147 1148
/**
 * zfcp_scsi_dbf_event_result - trace event for SCSI command completion
 * @tag: tag indicating success or failure of SCSI command
 * @level: trace level applicable for this event
 * @adapter: adapter that has been used to issue the SCSI command
 * @scsi_cmnd: SCSI command pointer
 * @fsf_req: request used to issue SCSI command (might be NULL)
 */
1149 1150 1151 1152
void zfcp_scsi_dbf_event_result(const char *tag, int level,
				struct zfcp_adapter *adapter,
				struct scsi_cmnd *scsi_cmnd,
				struct zfcp_fsf_req *fsf_req)
1153
{
1154
	zfcp_scsi_dbf_event("rslt", tag, level, adapter, scsi_cmnd, fsf_req, 0);
1155 1156
}

1157 1158 1159 1160 1161 1162 1163 1164
/**
 * zfcp_scsi_dbf_event_abort - trace event for SCSI command abort
 * @tag: tag indicating success or failure of abort operation
 * @adapter: adapter thas has been used to issue SCSI command to be aborted
 * @scsi_cmnd: SCSI command to be aborted
 * @new_fsf_req: request containing abort (might be NULL)
 * @old_req_id: identifier of request containg SCSI command to be aborted
 */
1165 1166 1167 1168
void zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
			       struct scsi_cmnd *scsi_cmnd,
			       struct zfcp_fsf_req *new_fsf_req,
			       unsigned long old_req_id)
1169
{
1170 1171
	zfcp_scsi_dbf_event("abrt", tag, 1, adapter, scsi_cmnd, new_fsf_req,
			    old_req_id);
1172 1173
}

1174 1175 1176 1177 1178 1179 1180
/**
 * zfcp_scsi_dbf_event_devreset - trace event for Logical Unit or Target Reset
 * @tag: tag indicating success or failure of reset operation
 * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
 * @unit: unit that needs reset
 * @scsi_cmnd: SCSI command which caused this error recovery
 */
1181 1182 1183
void zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag,
				  struct zfcp_unit *unit,
				  struct scsi_cmnd *scsi_cmnd)
1184
{
1185 1186
	zfcp_scsi_dbf_event(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1,
			    unit->port->adapter, scsi_cmnd, NULL, 0);
1187 1188
}

1189 1190
static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view,
				     char *out_buf, const char *in_buf)
1191
{
1192
	struct zfcp_scsi_dbf_record *r = (struct zfcp_scsi_dbf_record *)in_buf;
1193
	struct timespec t;
1194
	char *p = out_buf;
1195

1196
	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
1197 1198
		return 0;

1199 1200
	zfcp_dbf_tag(&p, "tag", r->tag);
	zfcp_dbf_tag(&p, "tag2", r->tag2);
1201 1202 1203 1204 1205
	zfcp_dbf_out(&p, "scsi_id", "0x%08x", r->scsi_id);
	zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun);
	zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result);
	zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd);
	zfcp_dbf_out(&p, "scsi_serial", "0x%016Lx", r->scsi_serial);
1206 1207
	zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE,
		      0, ZFCP_DBF_SCSI_OPCODE);
1208 1209 1210
	zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries);
	zfcp_dbf_out(&p, "scsi_allowed", "0x%02x", r->scsi_allowed);
	if (strncmp(r->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0)
1211
		zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid);
1212 1213 1214 1215 1216 1217
	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
	zfcp_dbf_timestamp(r->fsf_issued, &t);
	zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);

	if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
1218 1219 1220 1221 1222 1223 1224 1225
		zfcp_dbf_out(&p, "fcp_rsp_validity", "0x%02x", r->rsp_validity);
		zfcp_dbf_out(&p, "fcp_rsp_scsi_status", "0x%02x",
			     r->rsp_scsi_status);
		zfcp_dbf_out(&p, "fcp_rsp_resid", "0x%08x", r->rsp_resid);
		zfcp_dbf_out(&p, "fcp_rsp_code", "0x%08x", r->rsp_code);
		zfcp_dbf_out(&p, "fcp_sns_info_len", "0x%08x", r->sns_info_len);
		zfcp_dbf_outd(&p, "fcp_sns_info", r->sns_info,
			      min((int)r->sns_info_len,
1226
			      ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
1227
			      r->sns_info_len);
1228
	}
1229 1230
	p += sprintf(p, "\n");
	return p - out_buf;
1231 1232
}

1233
static struct debug_view zfcp_scsi_dbf_view = {
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250
	"structured",
	NULL,
	&zfcp_dbf_view_header,
	&zfcp_scsi_dbf_view_format,
	NULL,
	NULL
};

/**
 * zfcp_adapter_debug_register - registers debug feature for an adapter
 * @adapter: pointer to adapter for which debug features should be registered
 * return: -ENOMEM on error, 0 otherwise
 */
int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
{
	char dbf_name[DEBUG_MAX_NAME_LEN];

1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
	/* debug feature area which records recovery activity */
	sprintf(dbf_name, "zfcp_%s_rec", zfcp_get_busid_by_adapter(adapter));
	adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1,
					  sizeof(struct zfcp_rec_dbf_record));
	if (!adapter->rec_dbf)
		goto failed;
	debug_register_view(adapter->rec_dbf, &debug_hex_ascii_view);
	debug_register_view(adapter->rec_dbf, &zfcp_rec_dbf_view);
	debug_set_level(adapter->rec_dbf, 3);

1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307
	/* debug feature area which records HBA (FSF and QDIO) conditions */
	sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
	adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,
					  sizeof(struct zfcp_hba_dbf_record));
	if (!adapter->hba_dbf)
		goto failed;
	debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);
	debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);
	debug_set_level(adapter->hba_dbf, 3);

	/* debug feature area which records SAN command failures and recovery */
	sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));
	adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,
					  sizeof(struct zfcp_san_dbf_record));
	if (!adapter->san_dbf)
		goto failed;
	debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);
	debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);
	debug_set_level(adapter->san_dbf, 6);

	/* debug feature area which records SCSI command failures and recovery */
	sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));
	adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,
					   sizeof(struct zfcp_scsi_dbf_record));
	if (!adapter->scsi_dbf)
		goto failed;
	debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);
	debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);
	debug_set_level(adapter->scsi_dbf, 3);

	return 0;

 failed:
	zfcp_adapter_debug_unregister(adapter);

	return -ENOMEM;
}

/**
 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter
 * @adapter: pointer to adapter for which debug features should be unregistered
 */
void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
{
	debug_unregister(adapter->scsi_dbf);
	debug_unregister(adapter->san_dbf);
	debug_unregister(adapter->hba_dbf);
1308
	debug_unregister(adapter->rec_dbf);
1309 1310 1311
	adapter->scsi_dbf = NULL;
	adapter->san_dbf = NULL;
	adapter->hba_dbf = NULL;
1312
	adapter->rec_dbf = NULL;
1313
}