diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_dbf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 1179 |
1 files changed, 293 insertions, 886 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index a86117b0d6e1..96d1462e0bf5 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Debug traces for zfcp. | 4 | * Debug traces for zfcp. |
5 | * | 5 | * |
6 | * Copyright IBM Corporation 2002, 2009 | 6 | * Copyright IBM Corporation 2002, 2010 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define KMSG_COMPONENT "zfcp" | 9 | #define KMSG_COMPONENT "zfcp" |
@@ -22,982 +22,392 @@ module_param(dbfsize, uint, 0400); | |||
22 | MODULE_PARM_DESC(dbfsize, | 22 | MODULE_PARM_DESC(dbfsize, |
23 | "number of pages for each debug feature area (default 4)"); | 23 | "number of pages for each debug feature area (default 4)"); |
24 | 24 | ||
25 | static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len, | 25 | static inline unsigned int zfcp_dbf_plen(unsigned int offset) |
26 | int level, char *from, int from_len) | ||
27 | { | 26 | { |
28 | int offset; | 27 | return sizeof(struct zfcp_dbf_pay) + offset - ZFCP_DBF_PAY_MAX_REC; |
29 | struct zfcp_dbf_dump *dump = to; | ||
30 | int room = to_len - sizeof(*dump); | ||
31 | |||
32 | for (offset = 0; offset < from_len; offset += dump->size) { | ||
33 | memset(to, 0, to_len); | ||
34 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | ||
35 | dump->total_size = from_len; | ||
36 | dump->offset = offset; | ||
37 | dump->size = min(from_len - offset, room); | ||
38 | memcpy(dump->data, from + offset, dump->size); | ||
39 | debug_event(dbf, level, dump, dump->size + sizeof(*dump)); | ||
40 | } | ||
41 | } | 28 | } |
42 | 29 | ||
43 | static void zfcp_dbf_tag(char **p, const char *label, const char *tag) | 30 | static inline |
31 | void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area, | ||
32 | u64 req_id) | ||
44 | { | 33 | { |
45 | int i; | 34 | struct zfcp_dbf_pay *pl = &dbf->pay_buf; |
46 | 35 | u16 offset = 0, rec_length; | |
47 | *p += sprintf(*p, "%-24s", label); | ||
48 | for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) | ||
49 | *p += sprintf(*p, "%c", tag[i]); | ||
50 | *p += sprintf(*p, "\n"); | ||
51 | } | ||
52 | 36 | ||
53 | static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2) | 37 | spin_lock(&dbf->pay_lock); |
54 | { | 38 | memset(pl, 0, sizeof(*pl)); |
55 | *buf += sprintf(*buf, "%-24s%s\n", s1, s2); | 39 | pl->fsf_req_id = req_id; |
56 | } | 40 | memcpy(pl->area, area, ZFCP_DBF_TAG_LEN); |
57 | 41 | ||
58 | static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...) | 42 | while (offset < length) { |
59 | { | 43 | rec_length = min((u16) ZFCP_DBF_PAY_MAX_REC, |
60 | va_list arg; | 44 | (u16) (length - offset)); |
45 | memcpy(pl->data, data + offset, rec_length); | ||
46 | debug_event(dbf->pay, 1, pl, zfcp_dbf_plen(rec_length)); | ||
61 | 47 | ||
62 | *buf += sprintf(*buf, "%-24s", s); | 48 | offset += rec_length; |
63 | va_start(arg, format); | 49 | pl->counter++; |
64 | *buf += vsprintf(*buf, format, arg); | ||
65 | va_end(arg); | ||
66 | *buf += sprintf(*buf, "\n"); | ||
67 | } | ||
68 | |||
69 | static void zfcp_dbf_outd(char **p, const char *label, char *buffer, | ||
70 | int buflen, int offset, int total_size) | ||
71 | { | ||
72 | if (!offset) | ||
73 | *p += sprintf(*p, "%-24s ", label); | ||
74 | while (buflen--) { | ||
75 | if (offset > 0) { | ||
76 | if ((offset % 32) == 0) | ||
77 | *p += sprintf(*p, "\n%-24c ", ' '); | ||
78 | else if ((offset % 4) == 0) | ||
79 | *p += sprintf(*p, " "); | ||
80 | } | ||
81 | *p += sprintf(*p, "%02x", *buffer++); | ||
82 | if (++offset == total_size) { | ||
83 | *p += sprintf(*p, "\n"); | ||
84 | break; | ||
85 | } | ||
86 | } | 50 | } |
87 | if (!total_size) | ||
88 | *p += sprintf(*p, "\n"); | ||
89 | } | ||
90 | 51 | ||
91 | static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view, | 52 | spin_unlock(&dbf->pay_lock); |
92 | int area, debug_entry_t *entry, char *out_buf) | ||
93 | { | ||
94 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); | ||
95 | struct timespec t; | ||
96 | char *p = out_buf; | ||
97 | |||
98 | if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { | ||
99 | stck_to_timespec(entry->id.stck, &t); | ||
100 | zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu", | ||
101 | t.tv_sec, t.tv_nsec); | ||
102 | zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid); | ||
103 | } else { | ||
104 | zfcp_dbf_outd(&p, "", dump->data, dump->size, dump->offset, | ||
105 | dump->total_size); | ||
106 | if ((dump->offset + dump->size) == dump->total_size) | ||
107 | p += sprintf(p, "\n"); | ||
108 | } | ||
109 | return p - out_buf; | ||
110 | } | 53 | } |
111 | 54 | ||
112 | void _zfcp_dbf_hba_fsf_response(const char *tag2, int level, | 55 | /** |
113 | struct zfcp_fsf_req *fsf_req, | 56 | * zfcp_dbf_hba_fsf_res - trace event for fsf responses |
114 | struct zfcp_dbf *dbf) | 57 | * @tag: tag indicating which kind of unsolicited status has been received |
58 | * @req: request for which a response was received | ||
59 | */ | ||
60 | void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) | ||
115 | { | 61 | { |
116 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | 62 | struct zfcp_dbf *dbf = req->adapter->dbf; |
117 | union fsf_prot_status_qual *prot_status_qual = | 63 | struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix; |
118 | &qtcb->prefix.prot_status_qual; | 64 | struct fsf_qtcb_header *q_head = &req->qtcb->header; |
119 | union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; | 65 | struct zfcp_dbf_hba *rec = &dbf->hba_buf; |
120 | struct scsi_cmnd *scsi_cmnd; | ||
121 | struct zfcp_port *port; | ||
122 | struct zfcp_unit *unit; | ||
123 | struct zfcp_send_els *send_els; | ||
124 | struct zfcp_dbf_hba_record *rec = &dbf->hba_buf; | ||
125 | struct zfcp_dbf_hba_record_response *response = &rec->u.response; | ||
126 | unsigned long flags; | 66 | unsigned long flags; |
127 | 67 | ||
128 | spin_lock_irqsave(&dbf->hba_lock, flags); | 68 | spin_lock_irqsave(&dbf->hba_lock, flags); |
129 | memset(rec, 0, sizeof(*rec)); | 69 | memset(rec, 0, sizeof(*rec)); |
130 | strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); | ||
131 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | ||
132 | |||
133 | response->fsf_command = fsf_req->fsf_command; | ||
134 | response->fsf_reqid = fsf_req->req_id; | ||
135 | response->fsf_seqno = fsf_req->seq_no; | ||
136 | response->fsf_issued = fsf_req->issued; | ||
137 | response->fsf_prot_status = qtcb->prefix.prot_status; | ||
138 | response->fsf_status = qtcb->header.fsf_status; | ||
139 | memcpy(response->fsf_prot_status_qual, | ||
140 | prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE); | ||
141 | memcpy(response->fsf_status_qual, | ||
142 | fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); | ||
143 | response->fsf_req_status = fsf_req->status; | ||
144 | response->sbal_first = fsf_req->qdio_req.sbal_first; | ||
145 | response->sbal_last = fsf_req->qdio_req.sbal_last; | ||
146 | response->sbal_response = fsf_req->qdio_req.sbal_response; | ||
147 | response->pool = fsf_req->pool != NULL; | ||
148 | response->erp_action = (unsigned long)fsf_req->erp_action; | ||
149 | |||
150 | switch (fsf_req->fsf_command) { | ||
151 | case FSF_QTCB_FCP_CMND: | ||
152 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | ||
153 | break; | ||
154 | scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | ||
155 | if (scsi_cmnd) { | ||
156 | response->u.fcp.cmnd = (unsigned long)scsi_cmnd; | ||
157 | response->u.fcp.serial = scsi_cmnd->serial_number; | ||
158 | response->u.fcp.data_dir = | ||
159 | qtcb->bottom.io.data_direction; | ||
160 | } | ||
161 | break; | ||
162 | |||
163 | case FSF_QTCB_OPEN_PORT_WITH_DID: | ||
164 | case FSF_QTCB_CLOSE_PORT: | ||
165 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | ||
166 | port = (struct zfcp_port *)fsf_req->data; | ||
167 | response->u.port.wwpn = port->wwpn; | ||
168 | response->u.port.d_id = port->d_id; | ||
169 | response->u.port.port_handle = qtcb->header.port_handle; | ||
170 | break; | ||
171 | |||
172 | case FSF_QTCB_OPEN_LUN: | ||
173 | case FSF_QTCB_CLOSE_LUN: | ||
174 | unit = (struct zfcp_unit *)fsf_req->data; | ||
175 | port = unit->port; | ||
176 | response->u.unit.wwpn = port->wwpn; | ||
177 | response->u.unit.fcp_lun = unit->fcp_lun; | ||
178 | response->u.unit.port_handle = qtcb->header.port_handle; | ||
179 | response->u.unit.lun_handle = qtcb->header.lun_handle; | ||
180 | break; | ||
181 | |||
182 | case FSF_QTCB_SEND_ELS: | ||
183 | send_els = (struct zfcp_send_els *)fsf_req->data; | ||
184 | response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id); | ||
185 | break; | ||
186 | |||
187 | case FSF_QTCB_ABORT_FCP_CMND: | ||
188 | case FSF_QTCB_SEND_GENERIC: | ||
189 | case FSF_QTCB_EXCHANGE_CONFIG_DATA: | ||
190 | case FSF_QTCB_EXCHANGE_PORT_DATA: | ||
191 | case FSF_QTCB_DOWNLOAD_CONTROL_FILE: | ||
192 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | ||
193 | break; | ||
194 | } | ||
195 | |||
196 | debug_event(dbf->hba, level, rec, sizeof(*rec)); | ||
197 | 70 | ||
198 | /* have fcp channel microcode fixed to use as little as possible */ | 71 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
199 | if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) { | 72 | rec->id = ZFCP_DBF_HBA_RES; |
200 | /* adjust length skipping trailing zeros */ | 73 | rec->fsf_req_id = req->req_id; |
201 | char *buf = (char *)qtcb + qtcb->header.log_start; | 74 | rec->fsf_req_status = req->status; |
202 | int len = qtcb->header.log_length; | 75 | rec->fsf_cmd = req->fsf_command; |
203 | for (; len && !buf[len - 1]; len--); | 76 | rec->fsf_seq_no = req->seq_no; |
204 | zfcp_dbf_hexdump(dbf->hba, rec, sizeof(*rec), level, buf, | 77 | rec->u.res.req_issued = req->issued; |
205 | len); | 78 | rec->u.res.prot_status = q_pref->prot_status; |
79 | rec->u.res.fsf_status = q_head->fsf_status; | ||
80 | |||
81 | memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual, | ||
82 | FSF_PROT_STATUS_QUAL_SIZE); | ||
83 | memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual, | ||
84 | FSF_STATUS_QUALIFIER_SIZE); | ||
85 | |||
86 | if (req->fsf_command != FSF_QTCB_FCP_CMND) { | ||
87 | rec->pl_len = q_head->log_length; | ||
88 | zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, | ||
89 | rec->pl_len, "fsf_res", req->req_id); | ||
206 | } | 90 | } |
207 | 91 | ||
208 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | 92 | debug_event(dbf->hba, 1, rec, sizeof(*rec)); |
209 | } | ||
210 | |||
211 | void _zfcp_dbf_hba_fsf_unsol(const char *tag, int level, struct zfcp_dbf *dbf, | ||
212 | struct fsf_status_read_buffer *status_buffer) | ||
213 | { | ||
214 | struct zfcp_dbf_hba_record *rec = &dbf->hba_buf; | ||
215 | unsigned long flags; | ||
216 | |||
217 | spin_lock_irqsave(&dbf->hba_lock, flags); | ||
218 | memset(rec, 0, sizeof(*rec)); | ||
219 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); | ||
220 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); | ||
221 | |||
222 | rec->u.status.failed = atomic_read(&dbf->adapter->stat_miss); | ||
223 | if (status_buffer != NULL) { | ||
224 | rec->u.status.status_type = status_buffer->status_type; | ||
225 | rec->u.status.status_subtype = status_buffer->status_subtype; | ||
226 | memcpy(&rec->u.status.queue_designator, | ||
227 | &status_buffer->queue_designator, | ||
228 | sizeof(struct fsf_queue_designator)); | ||
229 | |||
230 | switch (status_buffer->status_type) { | ||
231 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | ||
232 | rec->u.status.payload_size = | ||
233 | ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; | ||
234 | break; | ||
235 | |||
236 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | ||
237 | rec->u.status.payload_size = | ||
238 | ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; | ||
239 | break; | ||
240 | |||
241 | case FSF_STATUS_READ_LINK_DOWN: | ||
242 | switch (status_buffer->status_subtype) { | ||
243 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: | ||
244 | case FSF_STATUS_READ_SUB_FDISC_FAILED: | ||
245 | rec->u.status.payload_size = | ||
246 | sizeof(struct fsf_link_down_info); | ||
247 | } | ||
248 | break; | ||
249 | |||
250 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: | ||
251 | rec->u.status.payload_size = | ||
252 | ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT; | ||
253 | break; | ||
254 | } | ||
255 | memcpy(&rec->u.status.payload, | ||
256 | &status_buffer->payload, rec->u.status.payload_size); | ||
257 | } | ||
258 | |||
259 | debug_event(dbf->hba, level, rec, sizeof(*rec)); | ||
260 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | 93 | spin_unlock_irqrestore(&dbf->hba_lock, flags); |
261 | } | 94 | } |
262 | 95 | ||
263 | /** | 96 | /** |
264 | * zfcp_dbf_hba_qdio - trace event for QDIO related failure | 97 | * zfcp_dbf_hba_fsf_uss - trace event for an unsolicited status buffer |
265 | * @qdio: qdio structure affected by this QDIO related event | 98 | * @tag: tag indicating which kind of unsolicited status has been received |
266 | * @qdio_error: as passed by qdio module | 99 | * @req: request providing the unsolicited status |
267 | * @sbal_index: first buffer with error condition, as passed by qdio module | ||
268 | * @sbal_count: number of buffers affected, as passed by qdio module | ||
269 | */ | 100 | */ |
270 | void zfcp_dbf_hba_qdio(struct zfcp_dbf *dbf, unsigned int qdio_error, | 101 | void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req) |
271 | int sbal_index, int sbal_count) | ||
272 | { | 102 | { |
273 | struct zfcp_dbf_hba_record *r = &dbf->hba_buf; | 103 | struct zfcp_dbf *dbf = req->adapter->dbf; |
104 | struct fsf_status_read_buffer *srb = req->data; | ||
105 | struct zfcp_dbf_hba *rec = &dbf->hba_buf; | ||
274 | unsigned long flags; | 106 | unsigned long flags; |
275 | 107 | ||
276 | spin_lock_irqsave(&dbf->hba_lock, flags); | 108 | spin_lock_irqsave(&dbf->hba_lock, flags); |
277 | memset(r, 0, sizeof(*r)); | 109 | memset(rec, 0, sizeof(*rec)); |
278 | strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE); | 110 | |
279 | r->u.qdio.qdio_error = qdio_error; | 111 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
280 | r->u.qdio.sbal_index = sbal_index; | 112 | rec->id = ZFCP_DBF_HBA_USS; |
281 | r->u.qdio.sbal_count = sbal_count; | 113 | rec->fsf_req_id = req->req_id; |
282 | debug_event(dbf->hba, 0, r, sizeof(*r)); | 114 | rec->fsf_req_status = req->status; |
115 | rec->fsf_cmd = req->fsf_command; | ||
116 | |||
117 | if (!srb) | ||
118 | goto log; | ||
119 | |||
120 | rec->u.uss.status_type = srb->status_type; | ||
121 | rec->u.uss.status_subtype = srb->status_subtype; | ||
122 | rec->u.uss.d_id = ntoh24(srb->d_id); | ||
123 | rec->u.uss.lun = srb->fcp_lun; | ||
124 | memcpy(&rec->u.uss.queue_designator, &srb->queue_designator, | ||
125 | sizeof(rec->u.uss.queue_designator)); | ||
126 | |||
127 | /* status read buffer payload length */ | ||
128 | rec->pl_len = (!srb->length) ? 0 : srb->length - | ||
129 | offsetof(struct fsf_status_read_buffer, payload); | ||
130 | |||
131 | if (rec->pl_len) | ||
132 | zfcp_dbf_pl_write(dbf, srb->payload.data, rec->pl_len, | ||
133 | "fsf_uss", req->req_id); | ||
134 | log: | ||
135 | debug_event(dbf->hba, 2, rec, sizeof(*rec)); | ||
283 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | 136 | spin_unlock_irqrestore(&dbf->hba_lock, flags); |
284 | } | 137 | } |
285 | 138 | ||
286 | /** | 139 | /** |
287 | * zfcp_dbf_hba_berr - trace event for bit error threshold | 140 | * zfcp_dbf_hba_bit_err - trace event for bit error conditions |
288 | * @dbf: dbf structure affected by this QDIO related event | 141 | * @tag: tag indicating which kind of unsolicited status has been received |
289 | * @req: fsf request | 142 | * @req: request which caused the bit_error condition |
290 | */ | 143 | */ |
291 | void zfcp_dbf_hba_berr(struct zfcp_dbf *dbf, struct zfcp_fsf_req *req) | 144 | void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req) |
292 | { | 145 | { |
293 | struct zfcp_dbf_hba_record *r = &dbf->hba_buf; | 146 | struct zfcp_dbf *dbf = req->adapter->dbf; |
147 | struct zfcp_dbf_hba *rec = &dbf->hba_buf; | ||
294 | struct fsf_status_read_buffer *sr_buf = req->data; | 148 | struct fsf_status_read_buffer *sr_buf = req->data; |
295 | struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error; | ||
296 | unsigned long flags; | 149 | unsigned long flags; |
297 | 150 | ||
298 | spin_lock_irqsave(&dbf->hba_lock, flags); | 151 | spin_lock_irqsave(&dbf->hba_lock, flags); |
299 | memset(r, 0, sizeof(*r)); | 152 | memset(rec, 0, sizeof(*rec)); |
300 | strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE); | ||
301 | memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload)); | ||
302 | debug_event(dbf->hba, 0, r, sizeof(*r)); | ||
303 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | ||
304 | } | ||
305 | static void zfcp_dbf_hba_view_response(char **p, | ||
306 | struct zfcp_dbf_hba_record_response *r) | ||
307 | { | ||
308 | struct timespec t; | ||
309 | |||
310 | zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command); | ||
311 | zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); | ||
312 | zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno); | ||
313 | stck_to_timespec(r->fsf_issued, &t); | ||
314 | zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec); | ||
315 | zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status); | ||
316 | zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status); | ||
317 | zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual, | ||
318 | FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE); | ||
319 | zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual, | ||
320 | FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE); | ||
321 | zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status); | ||
322 | zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first); | ||
323 | zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last); | ||
324 | zfcp_dbf_out(p, "sbal_response", "0x%02x", r->sbal_response); | ||
325 | zfcp_dbf_out(p, "pool", "0x%02x", r->pool); | ||
326 | |||
327 | switch (r->fsf_command) { | ||
328 | case FSF_QTCB_FCP_CMND: | ||
329 | if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | ||
330 | break; | ||
331 | zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir); | ||
332 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); | ||
333 | zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial); | ||
334 | *p += sprintf(*p, "\n"); | ||
335 | break; | ||
336 | |||
337 | case FSF_QTCB_OPEN_PORT_WITH_DID: | ||
338 | case FSF_QTCB_CLOSE_PORT: | ||
339 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | ||
340 | zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn); | ||
341 | zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id); | ||
342 | zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle); | ||
343 | break; | ||
344 | |||
345 | case FSF_QTCB_OPEN_LUN: | ||
346 | case FSF_QTCB_CLOSE_LUN: | ||
347 | zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn); | ||
348 | zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun); | ||
349 | zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle); | ||
350 | zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle); | ||
351 | break; | ||
352 | |||
353 | case FSF_QTCB_SEND_ELS: | ||
354 | zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id); | ||
355 | break; | ||
356 | |||
357 | case FSF_QTCB_ABORT_FCP_CMND: | ||
358 | case FSF_QTCB_SEND_GENERIC: | ||
359 | case FSF_QTCB_EXCHANGE_CONFIG_DATA: | ||
360 | case FSF_QTCB_EXCHANGE_PORT_DATA: | ||
361 | case FSF_QTCB_DOWNLOAD_CONTROL_FILE: | ||
362 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | ||
363 | break; | ||
364 | } | ||
365 | } | ||
366 | |||
367 | static void zfcp_dbf_hba_view_status(char **p, | ||
368 | struct zfcp_dbf_hba_record_status *r) | ||
369 | { | ||
370 | zfcp_dbf_out(p, "failed", "0x%02x", r->failed); | ||
371 | zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type); | ||
372 | zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype); | ||
373 | zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator, | ||
374 | sizeof(struct fsf_queue_designator), 0, | ||
375 | sizeof(struct fsf_queue_designator)); | ||
376 | zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0, | ||
377 | r->payload_size); | ||
378 | } | ||
379 | |||
380 | static void zfcp_dbf_hba_view_qdio(char **p, struct zfcp_dbf_hba_record_qdio *r) | ||
381 | { | ||
382 | zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error); | ||
383 | zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index); | ||
384 | zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); | ||
385 | } | ||
386 | 153 | ||
387 | static void zfcp_dbf_hba_view_berr(char **p, struct fsf_bit_error_payload *r) | 154 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
388 | { | 155 | rec->id = ZFCP_DBF_HBA_BIT; |
389 | zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count); | 156 | rec->fsf_req_id = req->req_id; |
390 | zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count); | 157 | rec->fsf_req_status = req->status; |
391 | zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count); | 158 | rec->fsf_cmd = req->fsf_command; |
392 | zfcp_dbf_out(p, "prim_seq_err", "%d", | 159 | memcpy(&rec->u.be, &sr_buf->payload.bit_error, |
393 | r->primitive_sequence_error_count); | 160 | sizeof(struct fsf_bit_error_payload)); |
394 | zfcp_dbf_out(p, "inval_trans_word_err", "%d", | ||
395 | r->invalid_transmission_word_error_count); | ||
396 | zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count); | ||
397 | zfcp_dbf_out(p, "prim_seq_event_to", "%d", | ||
398 | r->primitive_sequence_event_timeout_count); | ||
399 | zfcp_dbf_out(p, "elast_buf_overrun_err", "%d", | ||
400 | r->elastic_buffer_overrun_error_count); | ||
401 | zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d", | ||
402 | r->advertised_receive_b2b_credit); | ||
403 | zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d", | ||
404 | r->current_receive_b2b_credit); | ||
405 | zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d", | ||
406 | r->advertised_transmit_b2b_credit); | ||
407 | zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d", | ||
408 | r->current_transmit_b2b_credit); | ||
409 | } | ||
410 | 161 | ||
411 | static int zfcp_dbf_hba_view_format(debug_info_t *id, struct debug_view *view, | 162 | debug_event(dbf->hba, 1, rec, sizeof(*rec)); |
412 | char *out_buf, const char *in_buf) | 163 | spin_unlock_irqrestore(&dbf->hba_lock, flags); |
413 | { | ||
414 | struct zfcp_dbf_hba_record *r = (struct zfcp_dbf_hba_record *)in_buf; | ||
415 | char *p = out_buf; | ||
416 | |||
417 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | ||
418 | return 0; | ||
419 | |||
420 | zfcp_dbf_tag(&p, "tag", r->tag); | ||
421 | if (isalpha(r->tag2[0])) | ||
422 | zfcp_dbf_tag(&p, "tag2", r->tag2); | ||
423 | |||
424 | if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) | ||
425 | zfcp_dbf_hba_view_response(&p, &r->u.response); | ||
426 | else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) | ||
427 | zfcp_dbf_hba_view_status(&p, &r->u.status); | ||
428 | else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) | ||
429 | zfcp_dbf_hba_view_qdio(&p, &r->u.qdio); | ||
430 | else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0) | ||
431 | zfcp_dbf_hba_view_berr(&p, &r->u.berr); | ||
432 | |||
433 | if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0) | ||
434 | p += sprintf(p, "\n"); | ||
435 | return p - out_buf; | ||
436 | } | 164 | } |
437 | 165 | ||
438 | static struct debug_view zfcp_dbf_hba_view = { | 166 | static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, |
439 | .name = "structured", | 167 | struct zfcp_adapter *adapter, |
440 | .header_proc = zfcp_dbf_view_header, | 168 | struct zfcp_port *port, |
441 | .format_proc = zfcp_dbf_hba_view_format, | 169 | struct scsi_device *sdev) |
442 | }; | ||
443 | |||
444 | static const char *zfcp_dbf_rec_tags[] = { | ||
445 | [ZFCP_REC_DBF_ID_THREAD] = "thread", | ||
446 | [ZFCP_REC_DBF_ID_TARGET] = "target", | ||
447 | [ZFCP_REC_DBF_ID_TRIGGER] = "trigger", | ||
448 | [ZFCP_REC_DBF_ID_ACTION] = "action", | ||
449 | }; | ||
450 | |||
451 | static int zfcp_dbf_rec_view_format(debug_info_t *id, struct debug_view *view, | ||
452 | char *buf, const char *_rec) | ||
453 | { | 170 | { |
454 | struct zfcp_dbf_rec_record *r = (struct zfcp_dbf_rec_record *)_rec; | 171 | rec->adapter_status = atomic_read(&adapter->status); |
455 | char *p = buf; | 172 | if (port) { |
456 | char hint[ZFCP_DBF_ID_SIZE + 1]; | 173 | rec->port_status = atomic_read(&port->status); |
457 | 174 | rec->wwpn = port->wwpn; | |
458 | memcpy(hint, r->id2, ZFCP_DBF_ID_SIZE); | 175 | rec->d_id = port->d_id; |
459 | hint[ZFCP_DBF_ID_SIZE] = 0; | 176 | } |
460 | zfcp_dbf_outs(&p, "tag", zfcp_dbf_rec_tags[r->id]); | 177 | if (sdev) { |
461 | zfcp_dbf_outs(&p, "hint", hint); | 178 | rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status); |
462 | switch (r->id) { | 179 | rec->lun = zfcp_scsi_dev_lun(sdev); |
463 | case ZFCP_REC_DBF_ID_THREAD: | ||
464 | zfcp_dbf_out(&p, "total", "%d", r->u.thread.total); | ||
465 | zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready); | ||
466 | zfcp_dbf_out(&p, "running", "%d", r->u.thread.running); | ||
467 | break; | ||
468 | case ZFCP_REC_DBF_ID_TARGET: | ||
469 | zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref); | ||
470 | zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status); | ||
471 | zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count); | ||
472 | zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id); | ||
473 | zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn); | ||
474 | zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun); | ||
475 | break; | ||
476 | case ZFCP_REC_DBF_ID_TRIGGER: | ||
477 | zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref); | ||
478 | zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action); | ||
479 | zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want); | ||
480 | zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need); | ||
481 | zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn); | ||
482 | zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun); | ||
483 | zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as); | ||
484 | zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps); | ||
485 | zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us); | ||
486 | break; | ||
487 | case ZFCP_REC_DBF_ID_ACTION: | ||
488 | zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action); | ||
489 | zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req); | ||
490 | zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status); | ||
491 | zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step); | ||
492 | break; | ||
493 | } | 180 | } |
494 | p += sprintf(p, "\n"); | ||
495 | return p - buf; | ||
496 | } | 181 | } |
497 | 182 | ||
498 | static struct debug_view zfcp_dbf_rec_view = { | ||
499 | .name = "structured", | ||
500 | .header_proc = zfcp_dbf_view_header, | ||
501 | .format_proc = zfcp_dbf_rec_view_format, | ||
502 | }; | ||
503 | |||
504 | /** | 183 | /** |
505 | * zfcp_dbf_rec_thread - trace event related to recovery thread operation | 184 | * zfcp_dbf_rec_trig - trace event related to triggered recovery |
506 | * @id2: identifier for event | 185 | * @tag: identifier for event |
507 | * @dbf: reference to dbf structure | 186 | * @adapter: adapter on which the erp_action should run |
508 | * This function assumes that the caller is holding erp_lock. | 187 | * @port: remote port involved in the erp_action |
188 | * @sdev: scsi device involved in the erp_action | ||
189 | * @want: wanted erp_action | ||
190 | * @need: required erp_action | ||
191 | * | ||
192 | * The adapter->erp_lock has to be held. | ||
509 | */ | 193 | */ |
510 | void zfcp_dbf_rec_thread(char *id2, struct zfcp_dbf *dbf) | 194 | void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter, |
195 | struct zfcp_port *port, struct scsi_device *sdev, | ||
196 | u8 want, u8 need) | ||
511 | { | 197 | { |
512 | struct zfcp_adapter *adapter = dbf->adapter; | 198 | struct zfcp_dbf *dbf = adapter->dbf; |
513 | struct zfcp_dbf_rec_record *r = &dbf->rec_buf; | 199 | struct zfcp_dbf_rec *rec = &dbf->rec_buf; |
514 | unsigned long flags = 0; | ||
515 | struct list_head *entry; | 200 | struct list_head *entry; |
516 | unsigned ready = 0, running = 0, total; | ||
517 | |||
518 | list_for_each(entry, &adapter->erp_ready_head) | ||
519 | ready++; | ||
520 | list_for_each(entry, &adapter->erp_running_head) | ||
521 | running++; | ||
522 | total = adapter->erp_total_count; | ||
523 | |||
524 | spin_lock_irqsave(&dbf->rec_lock, flags); | ||
525 | memset(r, 0, sizeof(*r)); | ||
526 | r->id = ZFCP_REC_DBF_ID_THREAD; | ||
527 | memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE); | ||
528 | r->u.thread.total = total; | ||
529 | r->u.thread.ready = ready; | ||
530 | r->u.thread.running = running; | ||
531 | debug_event(dbf->rec, 6, r, sizeof(*r)); | ||
532 | spin_unlock_irqrestore(&dbf->rec_lock, flags); | ||
533 | } | ||
534 | |||
535 | /** | ||
536 | * zfcp_dbf_rec_thread - trace event related to recovery thread operation | ||
537 | * @id2: identifier for event | ||
538 | * @adapter: adapter | ||
539 | * This function assumes that the caller does not hold erp_lock. | ||
540 | */ | ||
541 | void zfcp_dbf_rec_thread_lock(char *id2, struct zfcp_dbf *dbf) | ||
542 | { | ||
543 | struct zfcp_adapter *adapter = dbf->adapter; | ||
544 | unsigned long flags; | ||
545 | |||
546 | read_lock_irqsave(&adapter->erp_lock, flags); | ||
547 | zfcp_dbf_rec_thread(id2, dbf); | ||
548 | read_unlock_irqrestore(&adapter->erp_lock, flags); | ||
549 | } | ||
550 | |||
551 | static void zfcp_dbf_rec_target(char *id2, void *ref, struct zfcp_dbf *dbf, | ||
552 | atomic_t *status, atomic_t *erp_count, u64 wwpn, | ||
553 | u32 d_id, u64 fcp_lun) | ||
554 | { | ||
555 | struct zfcp_dbf_rec_record *r = &dbf->rec_buf; | ||
556 | unsigned long flags; | 201 | unsigned long flags; |
557 | 202 | ||
558 | spin_lock_irqsave(&dbf->rec_lock, flags); | 203 | spin_lock_irqsave(&dbf->rec_lock, flags); |
559 | memset(r, 0, sizeof(*r)); | 204 | memset(rec, 0, sizeof(*rec)); |
560 | r->id = ZFCP_REC_DBF_ID_TARGET; | ||
561 | memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE); | ||
562 | r->u.target.ref = (unsigned long)ref; | ||
563 | r->u.target.status = atomic_read(status); | ||
564 | r->u.target.wwpn = wwpn; | ||
565 | r->u.target.d_id = d_id; | ||
566 | r->u.target.fcp_lun = fcp_lun; | ||
567 | r->u.target.erp_count = atomic_read(erp_count); | ||
568 | debug_event(dbf->rec, 3, r, sizeof(*r)); | ||
569 | spin_unlock_irqrestore(&dbf->rec_lock, flags); | ||
570 | } | ||
571 | |||
572 | /** | ||
573 | * zfcp_dbf_rec_adapter - trace event for adapter state change | ||
574 | * @id: identifier for trigger of state change | ||
575 | * @ref: additional reference (e.g. request) | ||
576 | * @dbf: reference to dbf structure | ||
577 | */ | ||
578 | void zfcp_dbf_rec_adapter(char *id, void *ref, struct zfcp_dbf *dbf) | ||
579 | { | ||
580 | struct zfcp_adapter *adapter = dbf->adapter; | ||
581 | |||
582 | zfcp_dbf_rec_target(id, ref, dbf, &adapter->status, | ||
583 | &adapter->erp_counter, 0, 0, | ||
584 | ZFCP_DBF_INVALID_LUN); | ||
585 | } | ||
586 | |||
587 | /** | ||
588 | * zfcp_dbf_rec_port - trace event for port state change | ||
589 | * @id: identifier for trigger of state change | ||
590 | * @ref: additional reference (e.g. request) | ||
591 | * @port: port | ||
592 | */ | ||
593 | void zfcp_dbf_rec_port(char *id, void *ref, struct zfcp_port *port) | ||
594 | { | ||
595 | struct zfcp_dbf *dbf = port->adapter->dbf; | ||
596 | 205 | ||
597 | zfcp_dbf_rec_target(id, ref, dbf, &port->status, | 206 | rec->id = ZFCP_DBF_REC_TRIG; |
598 | &port->erp_counter, port->wwpn, port->d_id, | 207 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
599 | ZFCP_DBF_INVALID_LUN); | 208 | zfcp_dbf_set_common(rec, adapter, port, sdev); |
600 | } | ||
601 | 209 | ||
602 | /** | 210 | list_for_each(entry, &adapter->erp_ready_head) |
603 | * zfcp_dbf_rec_unit - trace event for unit state change | 211 | rec->u.trig.ready++; |
604 | * @id: identifier for trigger of state change | ||
605 | * @ref: additional reference (e.g. request) | ||
606 | * @unit: unit | ||
607 | */ | ||
608 | void zfcp_dbf_rec_unit(char *id, void *ref, struct zfcp_unit *unit) | ||
609 | { | ||
610 | struct zfcp_port *port = unit->port; | ||
611 | struct zfcp_dbf *dbf = port->adapter->dbf; | ||
612 | 212 | ||
613 | zfcp_dbf_rec_target(id, ref, dbf, &unit->status, | 213 | list_for_each(entry, &adapter->erp_running_head) |
614 | &unit->erp_counter, port->wwpn, port->d_id, | 214 | rec->u.trig.running++; |
615 | unit->fcp_lun); | ||
616 | } | ||
617 | 215 | ||
618 | /** | 216 | rec->u.trig.want = want; |
619 | * zfcp_dbf_rec_trigger - trace event for triggered error recovery | 217 | rec->u.trig.need = need; |
620 | * @id2: identifier for error recovery trigger | ||
621 | * @ref: additional reference (e.g. request) | ||
622 | * @want: originally requested error recovery action | ||
623 | * @need: error recovery action actually initiated | ||
624 | * @action: address of error recovery action struct | ||
625 | * @adapter: adapter | ||
626 | * @port: port | ||
627 | * @unit: unit | ||
628 | */ | ||
629 | void zfcp_dbf_rec_trigger(char *id2, void *ref, u8 want, u8 need, void *action, | ||
630 | struct zfcp_adapter *adapter, struct zfcp_port *port, | ||
631 | struct zfcp_unit *unit) | ||
632 | { | ||
633 | struct zfcp_dbf *dbf = adapter->dbf; | ||
634 | struct zfcp_dbf_rec_record *r = &dbf->rec_buf; | ||
635 | unsigned long flags; | ||
636 | 218 | ||
637 | spin_lock_irqsave(&dbf->rec_lock, flags); | 219 | debug_event(dbf->rec, 1, rec, sizeof(*rec)); |
638 | memset(r, 0, sizeof(*r)); | ||
639 | r->id = ZFCP_REC_DBF_ID_TRIGGER; | ||
640 | memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE); | ||
641 | r->u.trigger.ref = (unsigned long)ref; | ||
642 | r->u.trigger.want = want; | ||
643 | r->u.trigger.need = need; | ||
644 | r->u.trigger.action = (unsigned long)action; | ||
645 | r->u.trigger.as = atomic_read(&adapter->status); | ||
646 | if (port) { | ||
647 | r->u.trigger.ps = atomic_read(&port->status); | ||
648 | r->u.trigger.wwpn = port->wwpn; | ||
649 | } | ||
650 | if (unit) | ||
651 | r->u.trigger.us = atomic_read(&unit->status); | ||
652 | r->u.trigger.fcp_lun = unit ? unit->fcp_lun : ZFCP_DBF_INVALID_LUN; | ||
653 | debug_event(dbf->rec, action ? 1 : 4, r, sizeof(*r)); | ||
654 | spin_unlock_irqrestore(&dbf->rec_lock, flags); | 220 | spin_unlock_irqrestore(&dbf->rec_lock, flags); |
655 | } | 221 | } |
656 | 222 | ||
223 | |||
657 | /** | 224 | /** |
658 | * zfcp_dbf_rec_action - trace event showing progress of recovery action | 225 | * zfcp_dbf_rec_run - trace event related to running recovery |
659 | * @id2: identifier | 226 | * @tag: identifier for event |
660 | * @erp_action: error recovery action struct pointer | 227 | * @erp: erp_action running |
661 | */ | 228 | */ |
662 | void zfcp_dbf_rec_action(char *id2, struct zfcp_erp_action *erp_action) | 229 | void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp) |
663 | { | 230 | { |
664 | struct zfcp_dbf *dbf = erp_action->adapter->dbf; | 231 | struct zfcp_dbf *dbf = erp->adapter->dbf; |
665 | struct zfcp_dbf_rec_record *r = &dbf->rec_buf; | 232 | struct zfcp_dbf_rec *rec = &dbf->rec_buf; |
666 | unsigned long flags; | 233 | unsigned long flags; |
667 | 234 | ||
668 | spin_lock_irqsave(&dbf->rec_lock, flags); | 235 | spin_lock_irqsave(&dbf->rec_lock, flags); |
669 | memset(r, 0, sizeof(*r)); | 236 | memset(rec, 0, sizeof(*rec)); |
670 | r->id = ZFCP_REC_DBF_ID_ACTION; | ||
671 | memcpy(r->id2, id2, ZFCP_DBF_ID_SIZE); | ||
672 | r->u.action.action = (unsigned long)erp_action; | ||
673 | r->u.action.status = erp_action->status; | ||
674 | r->u.action.step = erp_action->step; | ||
675 | r->u.action.fsf_req = erp_action->fsf_req_id; | ||
676 | debug_event(dbf->rec, 5, r, sizeof(*r)); | ||
677 | spin_unlock_irqrestore(&dbf->rec_lock, flags); | ||
678 | } | ||
679 | 237 | ||
680 | /** | 238 | rec->id = ZFCP_DBF_REC_RUN; |
681 | * zfcp_dbf_san_ct_request - trace event for issued CT request | 239 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
682 | * @fsf_req: request containing issued CT data | 240 | zfcp_dbf_set_common(rec, erp->adapter, erp->port, erp->sdev); |
683 | * @d_id: destination id where ct request is sent to | ||
684 | */ | ||
685 | void zfcp_dbf_san_ct_request(struct zfcp_fsf_req *fsf_req, u32 d_id) | ||
686 | { | ||
687 | struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data; | ||
688 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
689 | struct zfcp_dbf *dbf = adapter->dbf; | ||
690 | struct fc_ct_hdr *hdr = sg_virt(ct->req); | ||
691 | struct zfcp_dbf_san_record *r = &dbf->san_buf; | ||
692 | struct zfcp_dbf_san_record_ct_request *oct = &r->u.ct_req; | ||
693 | int level = 3; | ||
694 | unsigned long flags; | ||
695 | 241 | ||
696 | spin_lock_irqsave(&dbf->san_lock, flags); | 242 | rec->u.run.fsf_req_id = erp->fsf_req_id; |
697 | memset(r, 0, sizeof(*r)); | 243 | rec->u.run.rec_status = erp->status; |
698 | strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE); | 244 | rec->u.run.rec_step = erp->step; |
699 | r->fsf_reqid = fsf_req->req_id; | 245 | rec->u.run.rec_action = erp->action; |
700 | r->fsf_seqno = fsf_req->seq_no; | ||
701 | oct->d_id = d_id; | ||
702 | oct->cmd_req_code = hdr->ct_cmd; | ||
703 | oct->revision = hdr->ct_rev; | ||
704 | oct->gs_type = hdr->ct_fs_type; | ||
705 | oct->gs_subtype = hdr->ct_fs_subtype; | ||
706 | oct->options = hdr->ct_options; | ||
707 | oct->max_res_size = hdr->ct_mr_size; | ||
708 | oct->len = min((int)ct->req->length - (int)sizeof(struct fc_ct_hdr), | ||
709 | ZFCP_DBF_SAN_MAX_PAYLOAD); | ||
710 | debug_event(dbf->san, level, r, sizeof(*r)); | ||
711 | zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level, | ||
712 | (void *)hdr + sizeof(struct fc_ct_hdr), oct->len); | ||
713 | spin_unlock_irqrestore(&dbf->san_lock, flags); | ||
714 | } | ||
715 | 246 | ||
716 | /** | 247 | if (erp->sdev) |
717 | * zfcp_dbf_san_ct_response - trace event for completion of CT request | 248 | rec->u.run.rec_count = |
718 | * @fsf_req: request containing CT response | 249 | atomic_read(&sdev_to_zfcp(erp->sdev)->erp_counter); |
719 | */ | 250 | else if (erp->port) |
720 | void zfcp_dbf_san_ct_response(struct zfcp_fsf_req *fsf_req) | 251 | rec->u.run.rec_count = atomic_read(&erp->port->erp_counter); |
721 | { | 252 | else |
722 | struct zfcp_fsf_ct_els *ct = (struct zfcp_fsf_ct_els *)fsf_req->data; | 253 | rec->u.run.rec_count = atomic_read(&erp->adapter->erp_counter); |
723 | struct zfcp_adapter *adapter = fsf_req->adapter; | ||
724 | struct fc_ct_hdr *hdr = sg_virt(ct->resp); | ||
725 | struct zfcp_dbf *dbf = adapter->dbf; | ||
726 | struct zfcp_dbf_san_record *r = &dbf->san_buf; | ||
727 | struct zfcp_dbf_san_record_ct_response *rct = &r->u.ct_resp; | ||
728 | int level = 3; | ||
729 | unsigned long flags; | ||
730 | 254 | ||
731 | spin_lock_irqsave(&dbf->san_lock, flags); | 255 | debug_event(dbf->rec, 1, rec, sizeof(*rec)); |
732 | memset(r, 0, sizeof(*r)); | 256 | spin_unlock_irqrestore(&dbf->rec_lock, flags); |
733 | strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE); | ||
734 | r->fsf_reqid = fsf_req->req_id; | ||
735 | r->fsf_seqno = fsf_req->seq_no; | ||
736 | rct->cmd_rsp_code = hdr->ct_cmd; | ||
737 | rct->revision = hdr->ct_rev; | ||
738 | rct->reason_code = hdr->ct_reason; | ||
739 | rct->expl = hdr->ct_explan; | ||
740 | rct->vendor_unique = hdr->ct_vendor; | ||
741 | rct->max_res_size = hdr->ct_mr_size; | ||
742 | rct->len = min((int)ct->resp->length - (int)sizeof(struct fc_ct_hdr), | ||
743 | ZFCP_DBF_SAN_MAX_PAYLOAD); | ||
744 | debug_event(dbf->san, level, r, sizeof(*r)); | ||
745 | zfcp_dbf_hexdump(dbf->san, r, sizeof(*r), level, | ||
746 | (void *)hdr + sizeof(struct fc_ct_hdr), rct->len); | ||
747 | spin_unlock_irqrestore(&dbf->san_lock, flags); | ||
748 | } | 257 | } |
749 | 258 | ||
750 | static void zfcp_dbf_san_els(const char *tag, int level, | 259 | static inline |
751 | struct zfcp_fsf_req *fsf_req, u32 d_id, | 260 | void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len, |
752 | void *buffer, int buflen) | 261 | u64 req_id, u32 d_id) |
753 | { | 262 | { |
754 | struct zfcp_adapter *adapter = fsf_req->adapter; | 263 | struct zfcp_dbf_san *rec = &dbf->san_buf; |
755 | struct zfcp_dbf *dbf = adapter->dbf; | 264 | u16 rec_len; |
756 | struct zfcp_dbf_san_record *rec = &dbf->san_buf; | ||
757 | unsigned long flags; | 265 | unsigned long flags; |
758 | 266 | ||
759 | spin_lock_irqsave(&dbf->san_lock, flags); | 267 | spin_lock_irqsave(&dbf->san_lock, flags); |
760 | memset(rec, 0, sizeof(*rec)); | 268 | memset(rec, 0, sizeof(*rec)); |
761 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | 269 | |
762 | rec->fsf_reqid = fsf_req->req_id; | 270 | rec->id = id; |
763 | rec->fsf_seqno = fsf_req->seq_no; | 271 | rec->fsf_req_id = req_id; |
764 | rec->u.els.d_id = d_id; | 272 | rec->d_id = d_id; |
765 | debug_event(dbf->san, level, rec, sizeof(*rec)); | 273 | rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD); |
766 | zfcp_dbf_hexdump(dbf->san, rec, sizeof(*rec), level, | 274 | memcpy(rec->payload, data, rec_len); |
767 | buffer, min(buflen, ZFCP_DBF_SAN_MAX_PAYLOAD)); | 275 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
276 | |||
277 | debug_event(dbf->san, 1, rec, sizeof(*rec)); | ||
768 | spin_unlock_irqrestore(&dbf->san_lock, flags); | 278 | spin_unlock_irqrestore(&dbf->san_lock, flags); |
769 | } | 279 | } |
770 | 280 | ||
771 | /** | 281 | /** |
772 | * zfcp_dbf_san_els_request - trace event for issued ELS | 282 | * zfcp_dbf_san_req - trace event for issued SAN request |
773 | * @fsf_req: request containing issued ELS | 283 | * @tag: indentifier for event |
284 | * @fsf_req: request containing issued CT data | ||
285 | * d_id: destination ID | ||
774 | */ | 286 | */ |
775 | void zfcp_dbf_san_els_request(struct zfcp_fsf_req *fsf_req) | 287 | void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id) |
776 | { | 288 | { |
777 | struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data; | 289 | struct zfcp_dbf *dbf = fsf->adapter->dbf; |
778 | u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id); | 290 | struct zfcp_fsf_ct_els *ct_els = fsf->data; |
291 | u16 length; | ||
779 | 292 | ||
780 | zfcp_dbf_san_els("oels", 2, fsf_req, d_id, | 293 | length = (u16)(ct_els->req->length + FC_CT_HDR_LEN); |
781 | sg_virt(els->req), els->req->length); | 294 | zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length, |
295 | fsf->req_id, d_id); | ||
782 | } | 296 | } |
783 | 297 | ||
784 | /** | 298 | /** |
785 | * zfcp_dbf_san_els_response - trace event for completed ELS | 299 | * zfcp_dbf_san_res - trace event for received SAN request |
786 | * @fsf_req: request containing ELS response | 300 | * @tag: indentifier for event |
301 | * @fsf_req: request containing issued CT data | ||
787 | */ | 302 | */ |
788 | void zfcp_dbf_san_els_response(struct zfcp_fsf_req *fsf_req) | 303 | void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf) |
789 | { | 304 | { |
790 | struct zfcp_fsf_ct_els *els = (struct zfcp_fsf_ct_els *)fsf_req->data; | 305 | struct zfcp_dbf *dbf = fsf->adapter->dbf; |
791 | u32 d_id = ntoh24(fsf_req->qtcb->bottom.support.d_id); | 306 | struct zfcp_fsf_ct_els *ct_els = fsf->data; |
307 | u16 length; | ||
792 | 308 | ||
793 | zfcp_dbf_san_els("rels", 2, fsf_req, d_id, | 309 | length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN); |
794 | sg_virt(els->resp), els->resp->length); | 310 | zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length, |
311 | fsf->req_id, 0); | ||
795 | } | 312 | } |
796 | 313 | ||
797 | /** | 314 | /** |
798 | * zfcp_dbf_san_incoming_els - trace event for incomig ELS | 315 | * zfcp_dbf_san_in_els - trace event for incoming ELS |
799 | * @fsf_req: request containing unsolicited status buffer with incoming ELS | 316 | * @tag: indentifier for event |
317 | * @fsf_req: request containing issued CT data | ||
800 | */ | 318 | */ |
801 | void zfcp_dbf_san_incoming_els(struct zfcp_fsf_req *fsf_req) | 319 | void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) |
802 | { | 320 | { |
803 | struct fsf_status_read_buffer *buf = | 321 | struct zfcp_dbf *dbf = fsf->adapter->dbf; |
804 | (struct fsf_status_read_buffer *)fsf_req->data; | 322 | struct fsf_status_read_buffer *srb = |
805 | int length = (int)buf->length - | 323 | (struct fsf_status_read_buffer *) fsf->data; |
806 | (int)((void *)&buf->payload - (void *)buf); | 324 | u16 length; |
807 | 325 | ||
808 | zfcp_dbf_san_els("iels", 1, fsf_req, ntoh24(buf->d_id), | 326 | length = (u16)(srb->length - |
809 | (void *)buf->payload.data, length); | 327 | offsetof(struct fsf_status_read_buffer, payload)); |
810 | } | 328 | zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length, |
811 | 329 | fsf->req_id, ntoh24(srb->d_id)); | |
812 | static int zfcp_dbf_san_view_format(debug_info_t *id, struct debug_view *view, | ||
813 | char *out_buf, const char *in_buf) | ||
814 | { | ||
815 | struct zfcp_dbf_san_record *r = (struct zfcp_dbf_san_record *)in_buf; | ||
816 | char *p = out_buf; | ||
817 | |||
818 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | ||
819 | return 0; | ||
820 | |||
821 | zfcp_dbf_tag(&p, "tag", r->tag); | ||
822 | zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); | ||
823 | zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno); | ||
824 | |||
825 | if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
826 | struct zfcp_dbf_san_record_ct_request *ct = &r->u.ct_req; | ||
827 | zfcp_dbf_out(&p, "d_id", "0x%06x", ct->d_id); | ||
828 | zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code); | ||
829 | zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision); | ||
830 | zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type); | ||
831 | zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype); | ||
832 | zfcp_dbf_out(&p, "options", "0x%02x", ct->options); | ||
833 | zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size); | ||
834 | } else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { | ||
835 | struct zfcp_dbf_san_record_ct_response *ct = &r->u.ct_resp; | ||
836 | zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code); | ||
837 | zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision); | ||
838 | zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code); | ||
839 | zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl); | ||
840 | zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique); | ||
841 | zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size); | ||
842 | } else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || | ||
843 | strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || | ||
844 | strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { | ||
845 | struct zfcp_dbf_san_record_els *els = &r->u.els; | ||
846 | zfcp_dbf_out(&p, "d_id", "0x%06x", els->d_id); | ||
847 | } | ||
848 | return p - out_buf; | ||
849 | } | 330 | } |
850 | 331 | ||
851 | static struct debug_view zfcp_dbf_san_view = { | 332 | /** |
852 | .name = "structured", | 333 | * zfcp_dbf_scsi - trace event for scsi commands |
853 | .header_proc = zfcp_dbf_view_header, | 334 | * @tag: identifier for event |
854 | .format_proc = zfcp_dbf_san_view_format, | 335 | * @sc: pointer to struct scsi_cmnd |
855 | }; | 336 | * @fsf: pointer to struct zfcp_fsf_req |
856 | 337 | */ | |
857 | void _zfcp_dbf_scsi(const char *tag, const char *tag2, int level, | 338 | void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf) |
858 | struct zfcp_dbf *dbf, struct scsi_cmnd *scsi_cmnd, | ||
859 | struct zfcp_fsf_req *fsf_req, unsigned long old_req_id) | ||
860 | { | 339 | { |
861 | struct zfcp_dbf_scsi_record *rec = &dbf->scsi_buf; | 340 | struct zfcp_adapter *adapter = |
862 | struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; | 341 | (struct zfcp_adapter *) sc->device->host->hostdata[0]; |
863 | unsigned long flags; | 342 | struct zfcp_dbf *dbf = adapter->dbf; |
343 | struct zfcp_dbf_scsi *rec = &dbf->scsi_buf; | ||
864 | struct fcp_resp_with_ext *fcp_rsp; | 344 | struct fcp_resp_with_ext *fcp_rsp; |
865 | struct fcp_resp_rsp_info *fcp_rsp_info = NULL; | 345 | struct fcp_resp_rsp_info *fcp_rsp_info; |
866 | char *fcp_sns_info = NULL; | 346 | unsigned long flags; |
867 | int offset = 0, buflen = 0; | ||
868 | 347 | ||
869 | spin_lock_irqsave(&dbf->scsi_lock, flags); | 348 | spin_lock_irqsave(&dbf->scsi_lock, flags); |
870 | do { | 349 | memset(rec, 0, sizeof(*rec)); |
871 | memset(rec, 0, sizeof(*rec)); | ||
872 | if (offset == 0) { | ||
873 | strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); | ||
874 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | ||
875 | if (scsi_cmnd != NULL) { | ||
876 | if (scsi_cmnd->device) { | ||
877 | rec->scsi_id = scsi_cmnd->device->id; | ||
878 | rec->scsi_lun = scsi_cmnd->device->lun; | ||
879 | } | ||
880 | rec->scsi_result = scsi_cmnd->result; | ||
881 | rec->scsi_cmnd = (unsigned long)scsi_cmnd; | ||
882 | rec->scsi_serial = scsi_cmnd->serial_number; | ||
883 | memcpy(rec->scsi_opcode, scsi_cmnd->cmnd, | ||
884 | min((int)scsi_cmnd->cmd_len, | ||
885 | ZFCP_DBF_SCSI_OPCODE)); | ||
886 | rec->scsi_retries = scsi_cmnd->retries; | ||
887 | rec->scsi_allowed = scsi_cmnd->allowed; | ||
888 | } | ||
889 | if (fsf_req != NULL) { | ||
890 | fcp_rsp = (struct fcp_resp_with_ext *) | ||
891 | &(fsf_req->qtcb->bottom.io.fcp_rsp); | ||
892 | fcp_rsp_info = (struct fcp_resp_rsp_info *) | ||
893 | &fcp_rsp[1]; | ||
894 | fcp_sns_info = (char *) &fcp_rsp[1]; | ||
895 | if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) | ||
896 | fcp_sns_info += fcp_rsp->ext.fr_sns_len; | ||
897 | |||
898 | rec->rsp_validity = fcp_rsp->resp.fr_flags; | ||
899 | rec->rsp_scsi_status = fcp_rsp->resp.fr_status; | ||
900 | rec->rsp_resid = fcp_rsp->ext.fr_resid; | ||
901 | if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) | ||
902 | rec->rsp_code = fcp_rsp_info->rsp_code; | ||
903 | if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) { | ||
904 | buflen = min(fcp_rsp->ext.fr_sns_len, | ||
905 | (u32)ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); | ||
906 | rec->sns_info_len = buflen; | ||
907 | memcpy(rec->sns_info, fcp_sns_info, | ||
908 | min(buflen, | ||
909 | ZFCP_DBF_SCSI_FCP_SNS_INFO)); | ||
910 | offset += min(buflen, | ||
911 | ZFCP_DBF_SCSI_FCP_SNS_INFO); | ||
912 | } | ||
913 | |||
914 | rec->fsf_reqid = fsf_req->req_id; | ||
915 | rec->fsf_seqno = fsf_req->seq_no; | ||
916 | rec->fsf_issued = fsf_req->issued; | ||
917 | } | ||
918 | rec->old_fsf_reqid = old_req_id; | ||
919 | } else { | ||
920 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | ||
921 | dump->total_size = buflen; | ||
922 | dump->offset = offset; | ||
923 | dump->size = min(buflen - offset, | ||
924 | (int)sizeof(struct | ||
925 | zfcp_dbf_scsi_record) - | ||
926 | (int)sizeof(struct zfcp_dbf_dump)); | ||
927 | memcpy(dump->data, fcp_sns_info + offset, dump->size); | ||
928 | offset += dump->size; | ||
929 | } | ||
930 | debug_event(dbf->scsi, level, rec, sizeof(*rec)); | ||
931 | } while (offset < buflen); | ||
932 | spin_unlock_irqrestore(&dbf->scsi_lock, flags); | ||
933 | } | ||
934 | 350 | ||
935 | static int zfcp_dbf_scsi_view_format(debug_info_t *id, struct debug_view *view, | 351 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
936 | char *out_buf, const char *in_buf) | 352 | rec->id = ZFCP_DBF_SCSI_CMND; |
937 | { | 353 | rec->scsi_result = sc->result; |
938 | struct zfcp_dbf_scsi_record *r = (struct zfcp_dbf_scsi_record *)in_buf; | 354 | rec->scsi_retries = sc->retries; |
939 | struct timespec t; | 355 | rec->scsi_allowed = sc->allowed; |
940 | char *p = out_buf; | 356 | rec->scsi_id = sc->device->id; |
941 | 357 | rec->scsi_lun = sc->device->lun; | |
942 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | 358 | rec->host_scribble = (unsigned long)sc->host_scribble; |
943 | return 0; | 359 | |
944 | 360 | memcpy(rec->scsi_opcode, sc->cmnd, | |
945 | zfcp_dbf_tag(&p, "tag", r->tag); | 361 | min((int)sc->cmd_len, ZFCP_DBF_SCSI_OPCODE)); |
946 | zfcp_dbf_tag(&p, "tag2", r->tag2); | 362 | |
947 | zfcp_dbf_out(&p, "scsi_id", "0x%08x", r->scsi_id); | 363 | if (fsf) { |
948 | zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun); | 364 | rec->fsf_req_id = fsf->req_id; |
949 | zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result); | 365 | fcp_rsp = (struct fcp_resp_with_ext *) |
950 | zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd); | 366 | &(fsf->qtcb->bottom.io.fcp_rsp); |
951 | zfcp_dbf_out(&p, "scsi_serial", "0x%016Lx", r->scsi_serial); | 367 | memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT); |
952 | zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE, | 368 | if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) { |
953 | 0, ZFCP_DBF_SCSI_OPCODE); | 369 | fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; |
954 | zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries); | 370 | rec->fcp_rsp_info = fcp_rsp_info->rsp_code; |
955 | zfcp_dbf_out(&p, "scsi_allowed", "0x%02x", r->scsi_allowed); | 371 | } |
956 | if (strncmp(r->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) | 372 | if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) { |
957 | zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid); | 373 | rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE, |
958 | zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); | 374 | (u16)ZFCP_DBF_PAY_MAX_REC); |
959 | zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno); | 375 | zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len, |
960 | stck_to_timespec(r->fsf_issued, &t); | 376 | "fcp_sns", fsf->req_id); |
961 | zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec); | 377 | } |
962 | |||
963 | if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) { | ||
964 | zfcp_dbf_out(&p, "fcp_rsp_validity", "0x%02x", r->rsp_validity); | ||
965 | zfcp_dbf_out(&p, "fcp_rsp_scsi_status", "0x%02x", | ||
966 | r->rsp_scsi_status); | ||
967 | zfcp_dbf_out(&p, "fcp_rsp_resid", "0x%08x", r->rsp_resid); | ||
968 | zfcp_dbf_out(&p, "fcp_rsp_code", "0x%08x", r->rsp_code); | ||
969 | zfcp_dbf_out(&p, "fcp_sns_info_len", "0x%08x", r->sns_info_len); | ||
970 | zfcp_dbf_outd(&p, "fcp_sns_info", r->sns_info, | ||
971 | min((int)r->sns_info_len, | ||
972 | ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, | ||
973 | r->sns_info_len); | ||
974 | } | 378 | } |
975 | p += sprintf(p, "\n"); | ||
976 | return p - out_buf; | ||
977 | } | ||
978 | 379 | ||
979 | static struct debug_view zfcp_dbf_scsi_view = { | 380 | debug_event(dbf->scsi, 1, rec, sizeof(*rec)); |
980 | .name = "structured", | 381 | spin_unlock_irqrestore(&dbf->scsi_lock, flags); |
981 | .header_proc = zfcp_dbf_view_header, | 382 | } |
982 | .format_proc = zfcp_dbf_scsi_view_format, | ||
983 | }; | ||
984 | 383 | ||
985 | static debug_info_t *zfcp_dbf_reg(const char *name, int level, | 384 | static debug_info_t *zfcp_dbf_reg(const char *name, int size, int rec_size) |
986 | struct debug_view *view, int size) | ||
987 | { | 385 | { |
988 | struct debug_info *d; | 386 | struct debug_info *d; |
989 | 387 | ||
990 | d = debug_register(name, dbfsize, level, size); | 388 | d = debug_register(name, size, 1, rec_size); |
991 | if (!d) | 389 | if (!d) |
992 | return NULL; | 390 | return NULL; |
993 | 391 | ||
994 | debug_register_view(d, &debug_hex_ascii_view); | 392 | debug_register_view(d, &debug_hex_ascii_view); |
995 | debug_register_view(d, view); | 393 | debug_set_level(d, 3); |
996 | debug_set_level(d, level); | ||
997 | 394 | ||
998 | return d; | 395 | return d; |
999 | } | 396 | } |
1000 | 397 | ||
398 | static void zfcp_dbf_unregister(struct zfcp_dbf *dbf) | ||
399 | { | ||
400 | if (!dbf) | ||
401 | return; | ||
402 | |||
403 | debug_unregister(dbf->scsi); | ||
404 | debug_unregister(dbf->san); | ||
405 | debug_unregister(dbf->hba); | ||
406 | debug_unregister(dbf->pay); | ||
407 | debug_unregister(dbf->rec); | ||
408 | kfree(dbf); | ||
409 | } | ||
410 | |||
1001 | /** | 411 | /** |
1002 | * zfcp_adapter_debug_register - registers debug feature for an adapter | 412 | * zfcp_adapter_debug_register - registers debug feature for an adapter |
1003 | * @adapter: pointer to adapter for which debug features should be registered | 413 | * @adapter: pointer to adapter for which debug features should be registered |
@@ -1005,69 +415,66 @@ static debug_info_t *zfcp_dbf_reg(const char *name, int level, | |||
1005 | */ | 415 | */ |
1006 | int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter) | 416 | int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter) |
1007 | { | 417 | { |
1008 | char dbf_name[DEBUG_MAX_NAME_LEN]; | 418 | char name[DEBUG_MAX_NAME_LEN]; |
1009 | struct zfcp_dbf *dbf; | 419 | struct zfcp_dbf *dbf; |
1010 | 420 | ||
1011 | dbf = kzalloc(sizeof(struct zfcp_dbf), GFP_KERNEL); | 421 | dbf = kzalloc(sizeof(struct zfcp_dbf), GFP_KERNEL); |
1012 | if (!dbf) | 422 | if (!dbf) |
1013 | return -ENOMEM; | 423 | return -ENOMEM; |
1014 | 424 | ||
1015 | dbf->adapter = adapter; | 425 | spin_lock_init(&dbf->pay_lock); |
1016 | |||
1017 | spin_lock_init(&dbf->hba_lock); | 426 | spin_lock_init(&dbf->hba_lock); |
1018 | spin_lock_init(&dbf->san_lock); | 427 | spin_lock_init(&dbf->san_lock); |
1019 | spin_lock_init(&dbf->scsi_lock); | 428 | spin_lock_init(&dbf->scsi_lock); |
1020 | spin_lock_init(&dbf->rec_lock); | 429 | spin_lock_init(&dbf->rec_lock); |
1021 | 430 | ||
1022 | /* debug feature area which records recovery activity */ | 431 | /* debug feature area which records recovery activity */ |
1023 | sprintf(dbf_name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev)); | 432 | sprintf(name, "zfcp_%s_rec", dev_name(&adapter->ccw_device->dev)); |
1024 | dbf->rec = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_rec_view, | 433 | dbf->rec = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_rec)); |
1025 | sizeof(struct zfcp_dbf_rec_record)); | ||
1026 | if (!dbf->rec) | 434 | if (!dbf->rec) |
1027 | goto err_out; | 435 | goto err_out; |
1028 | 436 | ||
1029 | /* debug feature area which records HBA (FSF and QDIO) conditions */ | 437 | /* debug feature area which records HBA (FSF and QDIO) conditions */ |
1030 | sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev)); | 438 | sprintf(name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev)); |
1031 | dbf->hba = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_hba_view, | 439 | dbf->hba = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_hba)); |
1032 | sizeof(struct zfcp_dbf_hba_record)); | ||
1033 | if (!dbf->hba) | 440 | if (!dbf->hba) |
1034 | goto err_out; | 441 | goto err_out; |
1035 | 442 | ||
443 | /* debug feature area which records payload info */ | ||
444 | sprintf(name, "zfcp_%s_pay", dev_name(&adapter->ccw_device->dev)); | ||
445 | dbf->pay = zfcp_dbf_reg(name, dbfsize * 2, sizeof(struct zfcp_dbf_pay)); | ||
446 | if (!dbf->pay) | ||
447 | goto err_out; | ||
448 | |||
1036 | /* debug feature area which records SAN command failures and recovery */ | 449 | /* debug feature area which records SAN command failures and recovery */ |
1037 | sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev)); | 450 | sprintf(name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev)); |
1038 | dbf->san = zfcp_dbf_reg(dbf_name, 6, &zfcp_dbf_san_view, | 451 | dbf->san = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_san)); |
1039 | sizeof(struct zfcp_dbf_san_record)); | ||
1040 | if (!dbf->san) | 452 | if (!dbf->san) |
1041 | goto err_out; | 453 | goto err_out; |
1042 | 454 | ||
1043 | /* debug feature area which records SCSI command failures and recovery */ | 455 | /* debug feature area which records SCSI command failures and recovery */ |
1044 | sprintf(dbf_name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev)); | 456 | sprintf(name, "zfcp_%s_scsi", dev_name(&adapter->ccw_device->dev)); |
1045 | dbf->scsi = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_scsi_view, | 457 | dbf->scsi = zfcp_dbf_reg(name, dbfsize, sizeof(struct zfcp_dbf_scsi)); |
1046 | sizeof(struct zfcp_dbf_scsi_record)); | ||
1047 | if (!dbf->scsi) | 458 | if (!dbf->scsi) |
1048 | goto err_out; | 459 | goto err_out; |
1049 | 460 | ||
1050 | adapter->dbf = dbf; | 461 | adapter->dbf = dbf; |
1051 | return 0; | ||
1052 | 462 | ||
463 | return 0; | ||
1053 | err_out: | 464 | err_out: |
1054 | zfcp_dbf_adapter_unregister(dbf); | 465 | zfcp_dbf_unregister(dbf); |
1055 | return -ENOMEM; | 466 | return -ENOMEM; |
1056 | } | 467 | } |
1057 | 468 | ||
1058 | /** | 469 | /** |
1059 | * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter | 470 | * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter |
1060 | * @dbf: pointer to dbf for which debug features should be unregistered | 471 | * @adapter: pointer to adapter for which debug features should be unregistered |
1061 | */ | 472 | */ |
1062 | void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf) | 473 | void zfcp_dbf_adapter_unregister(struct zfcp_adapter *adapter) |
1063 | { | 474 | { |
1064 | if (!dbf) | 475 | struct zfcp_dbf *dbf = adapter->dbf; |
1065 | return; | 476 | |
1066 | debug_unregister(dbf->scsi); | 477 | adapter->dbf = NULL; |
1067 | debug_unregister(dbf->san); | 478 | zfcp_dbf_unregister(dbf); |
1068 | debug_unregister(dbf->hba); | ||
1069 | debug_unregister(dbf->rec); | ||
1070 | dbf->adapter->dbf = NULL; | ||
1071 | kfree(dbf); | ||
1072 | } | 479 | } |
1073 | 480 | ||