--- /dev/null
+From: Gerald Schaefer <geraldsc@de.ibm.com>
+Subject: zfcp: fix hexdump data in s390dbf traces
+References: bnc#440610
+
+Symptom: Hexdump data in s390dbf traces is incomplete
+Problem: The length of the data traced was wrong and the SAN payload
+ was read from a different place then it was written to.
+Solution: Fix the mentioned problems, now we have complete RSCN
+ traces (up to 1024 bytes)
+
+Acked-by: John Jolly <jjolly@suse.de>
+---
+
+ drivers/s390/scsi/zfcp_dbf.c | 42 ++++++++++++++++--------------------------
+ drivers/s390/scsi/zfcp_dbf.h | 8 ++------
+ 2 files changed, 18 insertions(+), 32 deletions(-)
+
+diff -urpN linux-2.6/drivers/s390/scsi/zfcp_dbf.c linux-2.6-patched/drivers/s390/scsi/zfcp_dbf.c
+--- linux-2.6/drivers/s390/scsi/zfcp_dbf.c 2008-11-04 09:46:57.000000000 +0100
++++ linux-2.6-patched/drivers/s390/scsi/zfcp_dbf.c 2008-11-04 09:47:18.000000000 +0100
+@@ -32,7 +32,7 @@ static void zfcp_dbf_hexdump(debug_info_
+ dump->offset = offset;
+ dump->size = min(from_len - offset, room);
+ memcpy(dump->data, from + offset, dump->size);
+- debug_event(dbf, level, dump, dump->size);
++ debug_event(dbf, level, dump, dump->size + sizeof(*dump));
+ }
+ }
+
+@@ -110,7 +110,7 @@ static int zfcp_dbf_view_header(debug_in
+ 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,
++ zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset,
+ dump->total_size);
+ if ((dump->offset + dump->size) == dump->total_size)
+ p += sprintf(p, "\n");
+@@ -368,6 +368,7 @@ static void zfcp_hba_dbf_view_response(c
+ break;
+ zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
+ zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
++ p += sprintf(*p, "\n");
+ break;
+
+ case FSF_QTCB_OPEN_PORT_WITH_DID:
+@@ -467,7 +468,8 @@ static int zfcp_hba_dbf_view_format(debu
+ else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0)
+ 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;
+ }
+
+@@ -882,6 +884,7 @@ void zfcp_san_dbf_event_ct_request(struc
+ struct ct_hdr *hdr = sg_virt(ct->req);
+ struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
+ struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
++ int level = 3;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+@@ -898,9 +901,10 @@ void zfcp_san_dbf_event_ct_request(struc
+ 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));
++ 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);
+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+ }
+
+@@ -916,6 +920,7 @@ void zfcp_san_dbf_event_ct_response(stru
+ struct ct_hdr *hdr = sg_virt(ct->resp);
+ struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
+ struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
++ int level = 3;
+ unsigned long flags;
+
+ spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+@@ -931,9 +936,10 @@ void zfcp_san_dbf_event_ct_response(stru
+ 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));
++ 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);
+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+ }
+
+@@ -956,7 +962,7 @@ static void zfcp_san_dbf_event_els(const
+ 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));
++ buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD));
+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+ }
+
+@@ -1010,8 +1016,6 @@ static int zfcp_san_dbf_view_format(debu
+ char *out_buf, const char *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;
+
+ if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+@@ -1031,9 +1035,6 @@ static int zfcp_san_dbf_view_format(debu
+ 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(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);
+@@ -1041,23 +1042,12 @@ static int zfcp_san_dbf_view_format(debu
+ 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(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);
+ }
+-
+- zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total);
+- if (buflen == total)
+- p += sprintf(p, "\n");
+-
+ return p - out_buf;
+ }
+
+diff -urpN linux-2.6/drivers/s390/scsi/zfcp_dbf.h linux-2.6-patched/drivers/s390/scsi/zfcp_dbf.h
+--- linux-2.6/drivers/s390/scsi/zfcp_dbf.h 2008-11-04 09:46:30.000000000 +0100
++++ linux-2.6-patched/drivers/s390/scsi/zfcp_dbf.h 2008-11-04 09:47:18.000000000 +0100
+@@ -163,8 +163,6 @@ struct zfcp_san_dbf_record_ct_request {
+ u8 options;
+ u16 max_res_size;
+ u32 len;
+-#define ZFCP_DBF_CT_PAYLOAD 24
+- u8 payload[ZFCP_DBF_CT_PAYLOAD];
+ } __attribute__ ((packed));
+
+ struct zfcp_san_dbf_record_ct_response {
+@@ -174,15 +172,11 @@ struct zfcp_san_dbf_record_ct_response {
+ u8 expl;
+ u8 vendor_unique;
+ u32 len;
+- u8 payload[ZFCP_DBF_CT_PAYLOAD];
+ } __attribute__ ((packed));
+
+ struct zfcp_san_dbf_record_els {
+ u8 ls_code;
+ u32 len;
+-#define ZFCP_DBF_ELS_PAYLOAD 32
+-#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
+- u8 payload[ZFCP_DBF_ELS_PAYLOAD];
+ } __attribute__ ((packed));
+
+ 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_els els;
+ } u;
++#define ZFCP_DBF_SAN_MAX_PAYLOAD 1024
++ u8 payload[32];
+ } __attribute__ ((packed));
+
+ struct zfcp_scsi_dbf_record {