diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 11:25:31 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 11:25:31 -0700 |
commit | 2cca775baecbfede2fec20c99add709232311fe7 (patch) | |
tree | b0eefe80881d263ba7976174144ae4e9cf238425 /drivers/s390/scsi/zfcp_dbf.c | |
parent | eddeb0e2d863e3941d8768e70cb50c6120e61fa0 (diff) | |
parent | 94795b61e84994a3b058f92d041d1fb3d869c7d5 (diff) | |
download | blackbird-op-linux-2cca775baecbfede2fec20c99add709232311fe7.tar.gz blackbird-op-linux-2cca775baecbfede2fec20c99add709232311fe7.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (137 commits)
[SCSI] iscsi: bidi support for iscsi_tcp
[SCSI] iscsi: bidi support at the generic libiscsi level
[SCSI] iscsi: extended cdb support
[SCSI] zfcp: Fix error handling for blocked unit for send FCP command
[SCSI] zfcp: Remove zfcp_erp_wait from slave destory handler to fix deadlock
[SCSI] zfcp: fix 31 bit compile warnings
[SCSI] bsg: no need to set BSG_F_BLOCK bit in bsg_complete_all_commands
[SCSI] bsg: remove minor in struct bsg_device
[SCSI] bsg: use better helper list functions
[SCSI] bsg: replace kobject_get with blk_get_queue
[SCSI] bsg: takes a ref to struct device in fops->open
[SCSI] qla1280: remove version check
[SCSI] libsas: fix endianness bug in sas_ata
[SCSI] zfcp: fix compiler warning caused by poking inside new semaphore (linux-next)
[SCSI] aacraid: Do not describe check_reset parameter with its value
[SCSI] aacraid: Fix down_interruptible() to check the return value
[SCSI] sun3_scsi_vme: add MODULE_LICENSE
[SCSI] st: rename flush_write_buffer()
[SCSI] tgt: use KMEM_CACHE macro
[SCSI] initio: fix big endian problems for auto request sense
...
Diffstat (limited to 'drivers/s390/scsi/zfcp_dbf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 1281 |
1 files changed, 801 insertions, 480 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 701046c9bb33..37b85c67b11d 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c @@ -31,123 +31,128 @@ MODULE_PARM_DESC(dbfsize, #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER -static int -zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) +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); + debug_event(dbf, level, dump, dump->size); + } +} + +/* FIXME: this duplicate this code in s390 debug feature */ +static void zfcp_dbf_timestamp(unsigned long long stck, struct timespec *time) { unsigned long long sec; - struct timespec dbftime; - int len = 0; stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); sec = stck >> 12; do_div(sec, 1000000); - dbftime.tv_sec = sec; + time->tv_sec = sec; stck -= (sec * 1000000) << 12; - dbftime.tv_nsec = ((stck * 1000) >> 12); - len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n", - label, dbftime.tv_sec, dbftime.tv_nsec); - - return len; + time->tv_nsec = ((stck * 1000) >> 12); } -static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag) +static void zfcp_dbf_tag(char **p, const char *label, const char *tag) { - int len = 0, i; + int i; - len += sprintf(out_buf + len, "%-24s", label); + *p += sprintf(*p, "%-24s", label); for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) - len += sprintf(out_buf + len, "%c", tag[i]); - len += sprintf(out_buf + len, "\n"); + *p += sprintf(*p, "%c", tag[i]); + *p += sprintf(*p, "\n"); +} - return len; +static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2) +{ + *buf += sprintf(*buf, "%-24s%s\n", s1, s2); } -static int -zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...) +static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...) { va_list arg; - int len = 0; - len += sprintf(out_buf + len, "%-24s", label); + *buf += sprintf(*buf, "%-24s", s); va_start(arg, format); - len += vsprintf(out_buf + len, format, arg); + *buf += vsprintf(*buf, format, arg); va_end(arg); - len += sprintf(out_buf + len, "\n"); - - return len; + *buf += sprintf(*buf, "\n"); } -static int -zfcp_dbf_view_dump(char *out_buf, const char *label, - char *buffer, int buflen, int offset, int total_size) +static void zfcp_dbf_outd(char **p, const char *label, char *buffer, + int buflen, int offset, int total_size) { - int len = 0; - - if (offset == 0) - len += sprintf(out_buf + len, "%-24s ", label); - + if (!offset) + *p += sprintf(*p, "%-24s ", label); while (buflen--) { if (offset > 0) { if ((offset % 32) == 0) - len += sprintf(out_buf + len, "\n%-24c ", ' '); + *p += sprintf(*p, "\n%-24c ", ' '); else if ((offset % 4) == 0) - len += sprintf(out_buf + len, " "); + *p += sprintf(*p, " "); } - len += sprintf(out_buf + len, "%02x", *buffer++); + *p += sprintf(*p, "%02x", *buffer++); if (++offset == total_size) { - len += sprintf(out_buf + len, "\n"); + *p += sprintf(*p, "\n"); break; } } - - if (total_size == 0) - len += sprintf(out_buf + len, "\n"); - - return len; + if (!total_size) + *p += sprintf(*p, "\n"); } -static int -zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area, - debug_entry_t * entry, char *out_buf) +static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view, + int area, debug_entry_t *entry, char *out_buf) { struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); - int len = 0; + struct timespec t; + char *p = out_buf; if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { - len += zfcp_dbf_stck(out_buf + len, "timestamp", - entry->id.stck); - len += zfcp_dbf_view(out_buf + len, "cpu", "%02i", - entry->id.fields.cpuid); - } else { - len += zfcp_dbf_view_dump(out_buf + len, NULL, - dump->data, - dump->size, - dump->offset, dump->total_size); + zfcp_dbf_timestamp(entry->id.stck, &t); + zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu", + t.tv_sec, t.tv_nsec); + zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); + } else { + zfcp_dbf_outd(&p, NULL, dump->data, dump->size, dump->offset, + dump->total_size); if ((dump->offset + dump->size) == dump->total_size) - len += sprintf(out_buf + len, "\n"); + p += sprintf(p, "\n"); } - - return len; + return p - out_buf; } +/** + * zfcp_hba_dbf_event_fsf_response - trace event for request completion + * @fsf_req: request that has been completed + */ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_adapter *adapter = fsf_req->adapter; struct fsf_qtcb *qtcb = fsf_req->qtcb; union fsf_prot_status_qual *prot_status_qual = - &qtcb->prefix.prot_status_qual; + &qtcb->prefix.prot_status_qual; 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; - struct zfcp_hba_dbf_record_response *response = &rec->type.response; + struct zfcp_hba_dbf_record_response *response = &rec->u.response; int level; unsigned long flags; spin_lock_irqsave(&adapter->hba_dbf_lock, flags); - memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); + memset(rec, 0, sizeof(*rec)); strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && @@ -161,6 +166,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) { strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE); level = 4; + } else if (qtcb->header.log_length) { + strncpy(rec->tag2, "qtcb", ZFCP_DBF_TAG_SIZE); + level = 5; } else { strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE); level = 6; @@ -188,11 +196,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) break; scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; - if (scsi_cmnd != NULL) { - response->data.send_fcp.scsi_cmnd - = (unsigned long)scsi_cmnd; - response->data.send_fcp.scsi_serial - = scsi_cmnd->serial_number; + if (scsi_cmnd) { + response->u.fcp.cmnd = (unsigned long)scsi_cmnd; + response->u.fcp.serial = scsi_cmnd->serial_number; } break; @@ -200,25 +206,25 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) case FSF_QTCB_CLOSE_PORT: case FSF_QTCB_CLOSE_PHYSICAL_PORT: port = (struct zfcp_port *)fsf_req->data; - response->data.port.wwpn = port->wwpn; - response->data.port.d_id = port->d_id; - response->data.port.port_handle = qtcb->header.port_handle; + response->u.port.wwpn = port->wwpn; + response->u.port.d_id = port->d_id; + response->u.port.port_handle = qtcb->header.port_handle; break; case FSF_QTCB_OPEN_LUN: case FSF_QTCB_CLOSE_LUN: unit = (struct zfcp_unit *)fsf_req->data; port = unit->port; - response->data.unit.wwpn = port->wwpn; - response->data.unit.fcp_lun = unit->fcp_lun; - response->data.unit.port_handle = qtcb->header.port_handle; - response->data.unit.lun_handle = qtcb->header.lun_handle; + 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; break; case FSF_QTCB_SEND_ELS: send_els = (struct zfcp_send_els *)fsf_req->data; - response->data.send_els.d_id = qtcb->bottom.support.d_id; - response->data.send_els.ls_code = send_els->ls_code >> 24; + response->u.els.d_id = qtcb->bottom.support.d_id; + response->u.els.ls_code = send_els->ls_code >> 24; break; case FSF_QTCB_ABORT_FCP_CMND: @@ -230,39 +236,54 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) break; } - debug_event(adapter->hba_dbf, level, - rec, sizeof(struct zfcp_hba_dbf_record)); + debug_event(adapter->hba_dbf, level, rec, sizeof(*rec)); + + /* 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); + } + spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); } -void -zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, - struct fsf_status_read_buffer *status_buffer) +/** + * 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 + */ +void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, + struct fsf_status_read_buffer *status_buffer) { struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; unsigned long flags; spin_lock_irqsave(&adapter->hba_dbf_lock, flags); - memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); + memset(rec, 0, sizeof(*rec)); strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); - rec->type.status.failed = adapter->status_read_failed; + rec->u.status.failed = adapter->status_read_failed; if (status_buffer != NULL) { - rec->type.status.status_type = status_buffer->status_type; - rec->type.status.status_subtype = status_buffer->status_subtype; - memcpy(&rec->type.status.queue_designator, + rec->u.status.status_type = status_buffer->status_type; + rec->u.status.status_subtype = status_buffer->status_subtype; + memcpy(&rec->u.status.queue_designator, &status_buffer->queue_designator, sizeof(struct fsf_queue_designator)); switch (status_buffer->status_type) { case FSF_STATUS_READ_SENSE_DATA_AVAIL: - rec->type.status.payload_size = + rec->u.status.payload_size = ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; break; case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: - rec->type.status.payload_size = + rec->u.status.payload_size = ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; break; @@ -270,119 +291,101 @@ zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, switch (status_buffer->status_subtype) { case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: case FSF_STATUS_READ_SUB_FDISC_FAILED: - rec->type.status.payload_size = + rec->u.status.payload_size = sizeof(struct fsf_link_down_info); } break; case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: - rec->type.status.payload_size = + rec->u.status.payload_size = ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT; break; } - memcpy(&rec->type.status.payload, - &status_buffer->payload, rec->type.status.payload_size); + memcpy(&rec->u.status.payload, + &status_buffer->payload, rec->u.status.payload_size); } - debug_event(adapter->hba_dbf, 2, - rec, sizeof(struct zfcp_hba_dbf_record)); + debug_event(adapter->hba_dbf, 2, rec, sizeof(*rec)); spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); } -void -zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, - unsigned int qdio_error, unsigned int siga_error, - int sbal_index, int sbal_count) +/** + * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure + * @adapter: adapter affected by this QDIO related event + * @status: as passed by qdio module + * @qdio_error: as passed by qdio module + * @siga_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 + */ +void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, + unsigned int qdio_error, unsigned int siga_error, + int sbal_index, int sbal_count) { - struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; + struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf; unsigned long flags; spin_lock_irqsave(&adapter->hba_dbf_lock, flags); - memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); - strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE); - rec->type.qdio.status = status; - rec->type.qdio.qdio_error = qdio_error; - rec->type.qdio.siga_error = siga_error; - rec->type.qdio.sbal_index = sbal_index; - rec->type.qdio.sbal_count = sbal_count; - debug_event(adapter->hba_dbf, 0, - rec, sizeof(struct zfcp_hba_dbf_record)); + memset(r, 0, sizeof(*r)); + strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE); + r->u.qdio.status = status; + r->u.qdio.qdio_error = qdio_error; + r->u.qdio.siga_error = siga_error; + r->u.qdio.sbal_index = sbal_index; + r->u.qdio.sbal_count = sbal_count; + debug_event(adapter->hba_dbf, 0, r, sizeof(*r)); spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); } -static int -zfcp_hba_dbf_view_response(char *out_buf, - struct zfcp_hba_dbf_record_response *rec) -{ - int len = 0; - - len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x", - rec->fsf_command); - len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", - rec->fsf_reqid); - len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", - rec->fsf_seqno); - len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); - len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x", - rec->fsf_prot_status); - len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x", - rec->fsf_status); - len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual", - rec->fsf_prot_status_qual, - FSF_PROT_STATUS_QUAL_SIZE, - 0, FSF_PROT_STATUS_QUAL_SIZE); - len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual", - rec->fsf_status_qual, - FSF_STATUS_QUALIFIER_SIZE, - 0, FSF_STATUS_QUALIFIER_SIZE); - len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x", - rec->fsf_req_status); - len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x", - rec->sbal_first); - len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x", - rec->sbal_curr); - len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x", - rec->sbal_last); - len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool); - - switch (rec->fsf_command) { +static void zfcp_hba_dbf_view_response(char **p, + struct zfcp_hba_dbf_record_response *r) +{ + struct timespec t; + + 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); + zfcp_dbf_timestamp(r->fsf_issued, &t); + 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, + FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE); + zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual, + FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE); + zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status); + zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first); + zfcp_dbf_out(p, "sbal_curr", "0x%02x", r->sbal_curr); + zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last); + zfcp_dbf_out(p, "pool", "0x%02x", r->pool); + + switch (r->fsf_command) { case FSF_QTCB_FCP_CMND: - if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) + if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) break; - len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", - rec->data.send_fcp.scsi_cmnd); - len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", - rec->data.send_fcp.scsi_serial); + zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); + zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); break; case FSF_QTCB_OPEN_PORT_WITH_DID: case FSF_QTCB_CLOSE_PORT: case FSF_QTCB_CLOSE_PHYSICAL_PORT: - len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", - rec->data.port.wwpn); - len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", - rec->data.port.d_id); - len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", - rec->data.port.port_handle); + 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); break; case FSF_QTCB_OPEN_LUN: case FSF_QTCB_CLOSE_LUN: - len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", - rec->data.unit.wwpn); - len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx", - rec->data.unit.fcp_lun); - len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", - rec->data.unit.port_handle); - len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x", - rec->data.unit.lun_handle); + 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); break; case FSF_QTCB_SEND_ELS: - len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", - rec->data.send_els.d_id); - len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", - rec->data.send_els.ls_code); + 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); break; case FSF_QTCB_ABORT_FCP_CMND: @@ -393,74 +396,52 @@ zfcp_hba_dbf_view_response(char *out_buf, case FSF_QTCB_UPLOAD_CONTROL_FILE: break; } - - return len; } -static int -zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec) +static void zfcp_hba_dbf_view_status(char **p, + struct zfcp_hba_dbf_record_status *r) { - int len = 0; - - len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed); - len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x", - rec->status_type); - len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x", - rec->status_subtype); - len += zfcp_dbf_view_dump(out_buf + len, "queue_designator", - (char *)&rec->queue_designator, - sizeof(struct fsf_queue_designator), - 0, sizeof(struct fsf_queue_designator)); - len += zfcp_dbf_view_dump(out_buf + len, "payload", - (char *)&rec->payload, - rec->payload_size, 0, rec->payload_size); - - return len; + 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, + sizeof(struct fsf_queue_designator), 0, + sizeof(struct fsf_queue_designator)); + zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0, + r->payload_size); } -static int -zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec) +static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r) { - int len = 0; - - len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status); - len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x", - rec->qdio_error); - len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x", - rec->siga_error); - len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x", - rec->sbal_index); - len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x", - rec->sbal_count); - - return len; + zfcp_dbf_out(p, "status", "0x%08x", r->status); + zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error); + zfcp_dbf_out(p, "siga_error", "0x%08x", r->siga_error); + zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index); + zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); } -static int -zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view, - char *out_buf, const char *in_buf) +static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view, + char *out_buf, const char *in_buf) { - struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf; - int len = 0; + struct zfcp_hba_dbf_record *r = (struct zfcp_hba_dbf_record *)in_buf; + char *p = out_buf; - if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) + if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) return 0; - len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); - if (isalpha(rec->tag2[0])) - len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); - if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) - len += zfcp_hba_dbf_view_response(out_buf + len, - &rec->type.response); - else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) - len += zfcp_hba_dbf_view_status(out_buf + len, - &rec->type.status); - else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) - len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio); + zfcp_dbf_tag(&p, "tag", r->tag); + if (isalpha(r->tag2[0])) + zfcp_dbf_tag(&p, "tag2", r->tag2); - len += sprintf(out_buf + len, "\n"); + if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) + zfcp_hba_dbf_view_response(&p, &r->u.response); + else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) + zfcp_hba_dbf_view_status(&p, &r->u.status); + else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) + zfcp_hba_dbf_view_qdio(&p, &r->u.qdio); - return len; + p += sprintf(p, "\n"); + return p - out_buf; } static struct debug_view zfcp_hba_dbf_view = { @@ -472,219 +453,570 @@ static struct debug_view zfcp_hba_dbf_view = { NULL }; -static void -_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req, - u32 s_id, u32 d_id, void *buffer, int buflen) +static const char *zfcp_rec_dbf_tags[] = { + [ZFCP_REC_DBF_ID_THREAD] = "thread", + [ZFCP_REC_DBF_ID_TARGET] = "target", + [ZFCP_REC_DBF_ID_TRIGGER] = "trigger", + [ZFCP_REC_DBF_ID_ACTION] = "action", +}; + +static const char *zfcp_rec_dbf_ids[] = { + [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", + [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", + [55] = "port access denied ct", + [56] = "port access denied els", + [57] = "port access denied open port", + [58] = "port access denied close physical", + [59] = "unit access denied open unit", + [60] = "shared unit access denied open unit", + [61] = "unit access denied fcp", + [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", + [77] = "recovery opening nameserver port", + [78] = "duplicate request id", + [79] = "link down", + [80] = "exclusive read-only unit access unsupported", + [81] = "shared read-write unit access unsupported", + [82] = "incoming rscn", + [83] = "incoming plogi", + [84] = "incoming logo", + [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", + [123] = "fc service class not supported ct", + [124] = "fc service class not supported els", + [125] = "need newer zfcp", + [126] = "need newer microcode", + [127] = "arbitrated loop not supported", + [128] = "unknown topology", + [129] = "qtcb size mismatch", + [130] = "unknown fsf status ecd", + [131] = "fcp request too big", + [132] = "fc service class not supported fcp", + [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", + [140] = "qdio error", + [141] = "scsi host reset", + [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", +}; + +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) { + 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; + 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; + 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; + 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; + } + p += sprintf(p, "\n"); + return p - buf; +} + +static struct debug_view zfcp_rec_dbf_view = { + "structured", + NULL, + &zfcp_dbf_view_header, + &zfcp_rec_dbf_view_format, + NULL, + NULL +}; + +/** + * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation + * @id2: identifier for event + * @adapter: adapter + * @lock: non-zero value indicates that erp_lock has not yet been acquired + */ +void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter, int lock) +{ + struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf; + unsigned long flags = 0; + struct list_head *entry; + unsigned ready = 0, running = 0, total; + + if (lock) + read_lock_irqsave(&adapter->erp_lock, flags); + list_for_each(entry, &adapter->erp_ready_head) + ready++; + list_for_each(entry, &adapter->erp_running_head) + running++; + total = adapter->erp_total_count; + if (lock) + read_unlock_irqrestore(&adapter->erp_lock, flags); + + 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; + debug_event(adapter->rec_dbf, 5, r, sizeof(*r)); + spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags); +} + +static void zfcp_rec_dbf_event_target(u8 id2, void *ref, + 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; + r->u.target.ref = (unsigned long)ref; + 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 + */ +void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter) +{ + 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 + */ +void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port) { - struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data; - struct zfcp_port *port = send_ct->port; struct zfcp_adapter *adapter = port->adapter; - struct ct_hdr *header = (struct ct_hdr *)buffer; - struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; - struct zfcp_san_dbf_record_ct *ct = &rec->type.ct; + + 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 + */ +void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit) +{ + 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); +} + +/** + * 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 + */ +void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need, + void *action, struct zfcp_adapter *adapter, + 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->san_dbf_lock, flags); - memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); - 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; - if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { - ct->type.request.cmd_req_code = header->cmd_rsp_code; - ct->type.request.revision = header->revision; - ct->type.request.gs_type = header->gs_type; - ct->type.request.gs_subtype = header->gs_subtype; - ct->type.request.options = header->options; - ct->type.request.max_res_size = header->max_res_size; - } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { - ct->type.response.cmd_rsp_code = header->cmd_rsp_code; - ct->type.response.revision = header->revision; - ct->type.response.reason_code = header->reason_code; - ct->type.response.reason_code_expl = header->reason_code_expl; - ct->type.response.vendor_unique = header->vendor_unique; + spin_lock_irqsave(&adapter->rec_dbf_lock, flags); + memset(r, 0, sizeof(*r)); + r->id = ZFCP_REC_DBF_ID_TRIGGER; + r->id2 = id2; + r->u.trigger.ref = (unsigned long)ref; + r->u.trigger.want = want; + r->u.trigger.need = need; + r->u.trigger.action = (unsigned long)action; + r->u.trigger.as = atomic_read(&adapter->status); + if (port) { + r->u.trigger.ps = atomic_read(&port->status); + r->u.trigger.wwpn = port->wwpn; } - ct->payload_size = - min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD); - memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size); - debug_event(adapter->san_dbf, 3, - rec, sizeof(struct zfcp_san_dbf_record)); - spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); + 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); } +/** + * 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; + r->u.action.action = (unsigned long)erp_action; + r->u.action.status = erp_action->status; + r->u.action.step = erp_action->step; + r->u.action.fsf_req = (unsigned long)erp_action->fsf_req; + debug_event(adapter->rec_dbf, 4, r, sizeof(*r)); + spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags); +} + +/** + * zfcp_san_dbf_event_ct_request - trace event for issued CT request + * @fsf_req: request containing issued CT data + */ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_port *port = ct->port; struct zfcp_adapter *adapter = port->adapter; + struct ct_hdr *hdr = zfcp_sg_to_address(ct->req); + struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; + struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; + unsigned long flags; - _zfcp_san_dbf_event_common_ct("octc", fsf_req, - fc_host_port_id(adapter->scsi_host), - port->d_id, zfcp_sg_to_address(ct->req), - ct->req->length); + 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); + r->d_id = port->d_id; + 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), + ZFCP_DBF_CT_PAYLOAD); + memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len); + debug_event(adapter->san_dbf, 3, r, sizeof(*r)); + spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); } +/** + * zfcp_san_dbf_event_ct_response - trace event for completion of CT request + * @fsf_req: request containing CT response + */ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; struct zfcp_port *port = ct->port; struct zfcp_adapter *adapter = port->adapter; + struct ct_hdr *hdr = zfcp_sg_to_address(ct->resp); + struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; + struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; + unsigned long flags; - _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id, - fc_host_port_id(adapter->scsi_host), - zfcp_sg_to_address(ct->resp), - ct->resp->length); + 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; + r->s_id = port->d_id; + 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), + ZFCP_DBF_CT_PAYLOAD); + memcpy(rct->payload, (void *)hdr + sizeof(struct ct_hdr), rct->len); + debug_event(adapter->san_dbf, 3, r, sizeof(*r)); + spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); } -static void -_zfcp_san_dbf_event_common_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) +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) { struct zfcp_adapter *adapter = fsf_req->adapter; struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; - struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; unsigned long flags; - int offset = 0; spin_lock_irqsave(&adapter->san_dbf_lock, flags); - do { - memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); - if (offset == 0) { - 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; - rec->type.els.ls_code = ls_code; - buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD); - rec->type.els.payload_size = buflen; - memcpy(rec->type.els.payload, - buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD)); - offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD); - } 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_san_dbf_record) - - (int)sizeof(struct zfcp_dbf_dump)); - memcpy(dump->data, buffer + offset, dump->size); - offset += dump->size; - } - debug_event(adapter->san_dbf, level, - rec, sizeof(struct zfcp_san_dbf_record)); - } while (offset < buflen); + memset(rec, 0, sizeof(*rec)); + 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; + rec->u.els.ls_code = ls_code; + debug_event(adapter->san_dbf, level, rec, sizeof(*rec)); + zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level, + buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD)); spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); } +/** + * zfcp_san_dbf_event_els_request - trace event for issued ELS + * @fsf_req: request containing issued ELS + */ void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; - _zfcp_san_dbf_event_common_els("oels", 2, fsf_req, - fc_host_port_id(els->adapter->scsi_host), - els->d_id, - *(u8 *) zfcp_sg_to_address(els->req), - zfcp_sg_to_address(els->req), - els->req->length); + zfcp_san_dbf_event_els("oels", 2, fsf_req, + fc_host_port_id(els->adapter->scsi_host), + els->d_id, *(u8 *) zfcp_sg_to_address(els->req), + zfcp_sg_to_address(els->req), els->req->length); } +/** + * zfcp_san_dbf_event_els_response - trace event for completed ELS + * @fsf_req: request containing ELS response + */ void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) { struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; - _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id, - fc_host_port_id(els->adapter->scsi_host), - *(u8 *) zfcp_sg_to_address(els->req), - zfcp_sg_to_address(els->resp), - els->resp->length); + zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id, + fc_host_port_id(els->adapter->scsi_host), + *(u8 *)zfcp_sg_to_address(els->req), + zfcp_sg_to_address(els->resp), + els->resp->length); } +/** + * zfcp_san_dbf_event_incoming_els - trace event for incomig ELS + * @fsf_req: request containing unsolicited status buffer with incoming ELS + */ void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) { struct zfcp_adapter *adapter = fsf_req->adapter; - struct fsf_status_read_buffer *status_buffer = - (struct fsf_status_read_buffer *)fsf_req->data; - int length = (int)status_buffer->length - - (int)((void *)&status_buffer->payload - (void *)status_buffer); - - _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id, - fc_host_port_id(adapter->scsi_host), - *(u8 *) status_buffer->payload, - (void *)status_buffer->payload, length); + 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), + *(u8 *)buf->payload, (void *)buf->payload, + length); } -static int -zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view, - char *out_buf, const char *in_buf) +static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view, + char *out_buf, const char *in_buf) { - struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf; + struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf; char *buffer = NULL; int buflen = 0, total = 0; - int len = 0; + char *p = out_buf; - if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) + if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) return 0; - len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); - len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", - rec->fsf_reqid); - len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", - rec->fsf_seqno); - len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id); - len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id); - - if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { - len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x", - rec->type.ct.type.request.cmd_req_code); - len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", - rec->type.ct.type.request.revision); - len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x", - rec->type.ct.type.request.gs_type); - len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x", - rec->type.ct.type.request.gs_subtype); - len += zfcp_dbf_view(out_buf + len, "options", "0x%02x", - rec->type.ct.type.request.options); - len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x", - rec->type.ct.type.request.max_res_size); - total = rec->type.ct.payload_size; - buffer = rec->type.ct.payload; + zfcp_dbf_tag(&p, "tag", r->tag); + 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) { + 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); + total = ct->len; + buffer = ct->payload; buflen = min(total, ZFCP_DBF_CT_PAYLOAD); - } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { - len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x", - rec->type.ct.type.response.cmd_rsp_code); - len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", - rec->type.ct.type.response.revision); - len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x", - rec->type.ct.type.response.reason_code); - len += - zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x", - rec->type.ct.type.response.reason_code_expl); - len += - zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x", - rec->type.ct.type.response.vendor_unique); - total = rec->type.ct.payload_size; - buffer = rec->type.ct.payload; + } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { + 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); + total = ct->len; + buffer = ct->payload; buflen = min(total, ZFCP_DBF_CT_PAYLOAD); - } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || - strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || - strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { - len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", - rec->type.els.ls_code); - total = rec->type.els.payload_size; - buffer = rec->type.els.payload; + } 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) { + struct zfcp_san_dbf_record_els *els = &r->u.els; + zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code); + total = els->len; + buffer = els->payload; buflen = min(total, ZFCP_DBF_ELS_PAYLOAD); } - len += zfcp_dbf_view_dump(out_buf + len, "payload", - buffer, buflen, 0, total); - + zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total); if (buflen == total) - len += sprintf(out_buf + len, "\n"); + p += sprintf(p, "\n"); - return len; + return p - out_buf; } static struct debug_view zfcp_san_dbf_view = { @@ -696,12 +1028,11 @@ static struct debug_view zfcp_san_dbf_view = { NULL }; -static void -_zfcp_scsi_dbf_event_common(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) +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) { struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; @@ -712,7 +1043,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, spin_lock_irqsave(&adapter->scsi_dbf_lock, flags); do { - memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record)); + memset(rec, 0, sizeof(*rec)); if (offset == 0) { strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); @@ -738,20 +1069,16 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, fcp_sns_info = zfcp_get_fcp_sns_info_ptr(fcp_rsp); - rec->type.fcp.rsp_validity = - fcp_rsp->validity.value; - rec->type.fcp.rsp_scsi_status = - fcp_rsp->scsi_status; - rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid; + rec->rsp_validity = fcp_rsp->validity.value; + rec->rsp_scsi_status = fcp_rsp->scsi_status; + rec->rsp_resid = fcp_rsp->fcp_resid; if (fcp_rsp->validity.bits.fcp_rsp_len_valid) - rec->type.fcp.rsp_code = - *(fcp_rsp_info + 3); + rec->rsp_code = *(fcp_rsp_info + 3); if (fcp_rsp->validity.bits.fcp_sns_len_valid) { buflen = min((int)fcp_rsp->fcp_sns_len, ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); - rec->type.fcp.sns_info_len = buflen; - memcpy(rec->type.fcp.sns_info, - fcp_sns_info, + rec->sns_info_len = buflen; + memcpy(rec->sns_info, fcp_sns_info, min(buflen, ZFCP_DBF_SCSI_FCP_SNS_INFO)); offset += min(buflen, @@ -762,7 +1089,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, rec->fsf_seqno = fsf_req->seq_no; rec->fsf_issued = fsf_req->issued; } - rec->type.old_fsf_reqid = old_req_id; + rec->old_fsf_reqid = old_req_id; } else { strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); dump->total_size = buflen; @@ -774,108 +1101,101 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, memcpy(dump->data, fcp_sns_info + offset, dump->size); offset += dump->size; } - debug_event(adapter->scsi_dbf, level, - rec, sizeof(struct zfcp_scsi_dbf_record)); + debug_event(adapter->scsi_dbf, level, rec, sizeof(*rec)); } while (offset < buflen); spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags); } -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) +/** + * 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) + */ +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) { - _zfcp_scsi_dbf_event_common("rslt", tag, level, - adapter, scsi_cmnd, fsf_req, 0); + zfcp_scsi_dbf_event("rslt", tag, level, adapter, scsi_cmnd, fsf_req, 0); } -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) +/** + * 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 + */ +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) { - _zfcp_scsi_dbf_event_common("abrt", tag, 1, - adapter, scsi_cmnd, new_fsf_req, old_req_id); + zfcp_scsi_dbf_event("abrt", tag, 1, adapter, scsi_cmnd, new_fsf_req, + old_req_id); } -void -zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, - struct scsi_cmnd *scsi_cmnd) +/** + * 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 + */ +void zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, + struct zfcp_unit *unit, + struct scsi_cmnd *scsi_cmnd) { - struct zfcp_adapter *adapter = unit->port->adapter; - - _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", - tag, 1, adapter, scsi_cmnd, NULL, 0); + zfcp_scsi_dbf_event(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1, + unit->port->adapter, scsi_cmnd, NULL, 0); } -static int -zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, - char *out_buf, const char *in_buf) +static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view, + char *out_buf, const char *in_buf) { - struct zfcp_scsi_dbf_record *rec = - (struct zfcp_scsi_dbf_record *)in_buf; - int len = 0; + struct zfcp_scsi_dbf_record *r = (struct zfcp_scsi_dbf_record *)in_buf; + struct timespec t; + char *p = out_buf; - if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) + if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) return 0; - len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); - len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); - len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id); - len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x", - rec->scsi_lun); - len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x", - rec->scsi_result); - len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", - rec->scsi_cmnd); - len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", - rec->scsi_serial); - len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode", - rec->scsi_opcode, - ZFCP_DBF_SCSI_OPCODE, - 0, ZFCP_DBF_SCSI_OPCODE); - len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x", - rec->scsi_retries); - len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", - rec->scsi_allowed); - if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { - len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx", - rec->type.old_fsf_reqid); - } - len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", - rec->fsf_reqid); - len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", - rec->fsf_seqno); - len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); - if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) { - len += - zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x", - rec->type.fcp.rsp_validity); - len += - zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status", - "0x%02x", rec->type.fcp.rsp_scsi_status); - len += - zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x", - rec->type.fcp.rsp_resid); - len += - zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x", - rec->type.fcp.rsp_code); - len += - zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x", - rec->type.fcp.sns_info_len); - len += - zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info", - rec->type.fcp.sns_info, - min((int)rec->type.fcp.sns_info_len, - ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, - rec->type.fcp.sns_info_len); + zfcp_dbf_tag(&p, "tag", r->tag); + zfcp_dbf_tag(&p, "tag2", r->tag2); + 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); + zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE, + 0, ZFCP_DBF_SCSI_OPCODE); + 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) + zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid); + 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) { + 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, + ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, + r->sns_info_len); } - - len += sprintf(out_buf + len, "\n"); - - return len; + p += sprintf(p, "\n"); + return p - out_buf; } static struct debug_view zfcp_scsi_dbf_view = { @@ -897,13 +1217,14 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter) char dbf_name[DEBUG_MAX_NAME_LEN]; /* debug feature area which records recovery activity */ - sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter)); - adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2, - sizeof(struct zfcp_erp_dbf_record)); - if (!adapter->erp_dbf) + 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->erp_dbf, &debug_hex_ascii_view); - debug_set_level(adapter->erp_dbf, 3); + 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); /* debug feature area which records HBA (FSF and QDIO) conditions */ sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter)); @@ -952,11 +1273,11 @@ void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) debug_unregister(adapter->scsi_dbf); debug_unregister(adapter->san_dbf); debug_unregister(adapter->hba_dbf); - debug_unregister(adapter->erp_dbf); + debug_unregister(adapter->rec_dbf); adapter->scsi_dbf = NULL; adapter->san_dbf = NULL; adapter->hba_dbf = NULL; - adapter->erp_dbf = NULL; + adapter->rec_dbf = NULL; } #undef ZFCP_LOG_AREA |