[SCSI] zfcp: Fix hexdump data in s390dbf traces

Fix multiple problems found in the hexdump data:
 - length calculation was wrong, traces were incomplete
 - FC payloads were dumped in different record than the output
   function tried to read
 - minor fixes in output
 - allow complete RSCN traces (up to 1024 bytes according to spec)

Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
Christof Schmitt 2008-11-04 16:35:12 +01:00 committed by James Bottomley
parent 7ea633ffad
commit d94ce6c6e9
2 changed files with 18 additions and 32 deletions

View File

@ -30,7 +30,7 @@ static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
dump->offset = offset; dump->offset = offset;
dump->size = min(from_len - offset, room); dump->size = min(from_len - offset, room);
memcpy(dump->data, from + offset, dump->size); memcpy(dump->data, from + offset, dump->size);
debug_event(dbf, level, dump, dump->size); debug_event(dbf, level, dump, dump->size + sizeof(*dump));
} }
} }
@ -108,7 +108,7 @@ static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
t.tv_sec, t.tv_nsec); t.tv_sec, t.tv_nsec);
zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
} else { } else {
zfcp_dbf_outd(&p, NULL, dump->data, dump->size, dump->offset, zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset,
dump->total_size); dump->total_size);
if ((dump->offset + dump->size) == dump->total_size) if ((dump->offset + dump->size) == dump->total_size)
p += sprintf(p, "\n"); p += sprintf(p, "\n");
@ -366,6 +366,7 @@ static void zfcp_hba_dbf_view_response(char **p,
break; break;
zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
p += sprintf(*p, "\n");
break; break;
case FSF_QTCB_OPEN_PORT_WITH_DID: case FSF_QTCB_OPEN_PORT_WITH_DID:
@ -465,7 +466,8 @@ static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0) else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
zfcp_hba_dbf_view_berr(&p, &r->u.berr); zfcp_hba_dbf_view_berr(&p, &r->u.berr);
p += sprintf(p, "\n"); if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0)
p += sprintf(p, "\n");
return p - out_buf; return p - out_buf;
} }
@ -880,6 +882,7 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
struct ct_hdr *hdr = sg_virt(ct->req); struct ct_hdr *hdr = sg_virt(ct->req);
struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req; struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
int level = 3;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&adapter->san_dbf_lock, flags); spin_lock_irqsave(&adapter->san_dbf_lock, flags);
@ -896,9 +899,10 @@ void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
oct->options = hdr->options; oct->options = hdr->options;
oct->max_res_size = hdr->max_res_size; oct->max_res_size = hdr->max_res_size;
oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr), oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
ZFCP_DBF_CT_PAYLOAD); ZFCP_DBF_SAN_MAX_PAYLOAD);
memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len); debug_event(adapter->san_dbf, level, r, sizeof(*r));
debug_event(adapter->san_dbf, 3, r, sizeof(*r)); zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
(void *)hdr + sizeof(struct ct_hdr), oct->len);
spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
} }
@ -914,6 +918,7 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
struct ct_hdr *hdr = sg_virt(ct->resp); struct ct_hdr *hdr = sg_virt(ct->resp);
struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf; struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp; struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
int level = 3;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&adapter->san_dbf_lock, flags); spin_lock_irqsave(&adapter->san_dbf_lock, flags);
@ -929,9 +934,10 @@ void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
rct->expl = hdr->reason_code_expl; rct->expl = hdr->reason_code_expl;
rct->vendor_unique = hdr->vendor_unique; rct->vendor_unique = hdr->vendor_unique;
rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr), rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
ZFCP_DBF_CT_PAYLOAD); ZFCP_DBF_SAN_MAX_PAYLOAD);
memcpy(rct->payload, (void *)hdr + sizeof(struct ct_hdr), rct->len); debug_event(adapter->san_dbf, level, r, sizeof(*r));
debug_event(adapter->san_dbf, 3, r, sizeof(*r)); zfcp_dbf_hexdump(adapter->san_dbf, r, sizeof(*r), level,
(void *)hdr + sizeof(struct ct_hdr), rct->len);
spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
} }
@ -954,7 +960,7 @@ static void zfcp_san_dbf_event_els(const char *tag, int level,
rec->u.els.ls_code = ls_code; rec->u.els.ls_code = ls_code;
debug_event(adapter->san_dbf, level, rec, sizeof(*rec)); debug_event(adapter->san_dbf, level, rec, sizeof(*rec));
zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level, zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level,
buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD)); buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
} }
@ -1008,8 +1014,6 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
char *out_buf, const char *in_buf) char *out_buf, const char *in_buf)
{ {
struct zfcp_san_dbf_record *r = (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;
char *p = out_buf; char *p = out_buf;
if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
@ -1029,9 +1033,6 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype); zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype);
zfcp_dbf_out(&p, "options", "0x%02x", ct->options); zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size); 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(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp; 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, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
@ -1039,23 +1040,12 @@ static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code); 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, "reason_code_expl", "0x%02x", ct->expl);
zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique); 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(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
struct zfcp_san_dbf_record_els *els = &r->u.els; struct zfcp_san_dbf_record_els *els = &r->u.els;
zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code); zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
total = els->len;
buffer = els->payload;
buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
} }
zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total);
if (buflen == total)
p += sprintf(p, "\n");
return p - out_buf; return p - out_buf;
} }

View File

@ -163,8 +163,6 @@ struct zfcp_san_dbf_record_ct_request {
u8 options; u8 options;
u16 max_res_size; u16 max_res_size;
u32 len; u32 len;
#define ZFCP_DBF_CT_PAYLOAD 24
u8 payload[ZFCP_DBF_CT_PAYLOAD];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_san_dbf_record_ct_response { struct zfcp_san_dbf_record_ct_response {
@ -174,15 +172,11 @@ struct zfcp_san_dbf_record_ct_response {
u8 expl; u8 expl;
u8 vendor_unique; u8 vendor_unique;
u32 len; u32 len;
u8 payload[ZFCP_DBF_CT_PAYLOAD];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_san_dbf_record_els { struct zfcp_san_dbf_record_els {
u8 ls_code; u8 ls_code;
u32 len; u32 len;
#define ZFCP_DBF_ELS_PAYLOAD 32
#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
u8 payload[ZFCP_DBF_ELS_PAYLOAD];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_san_dbf_record { struct zfcp_san_dbf_record {
@ -196,6 +190,8 @@ struct zfcp_san_dbf_record {
struct zfcp_san_dbf_record_ct_response ct_resp; struct zfcp_san_dbf_record_ct_response ct_resp;
struct zfcp_san_dbf_record_els els; struct zfcp_san_dbf_record_els els;
} u; } u;
#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
u8 payload[32];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct zfcp_scsi_dbf_record { struct zfcp_scsi_dbf_record {