diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_dbf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 433 |
1 files changed, 117 insertions, 316 deletions
diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c index 6ece47e5148c..b57a47b64b80 100644 --- a/drivers/s390/scsi/zfcp_dbf.c +++ b/drivers/s390/scsi/zfcp_dbf.c | |||
@@ -22,22 +22,34 @@ 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; | 28 | } |
30 | int room = to_len - sizeof(*dump); | 29 | |
31 | 30 | static inline | |
32 | for (offset = 0; offset < from_len; offset += dump->size) { | 31 | void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area, |
33 | memset(to, 0, to_len); | 32 | u64 req_id) |
34 | strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); | 33 | { |
35 | dump->total_size = from_len; | 34 | struct zfcp_dbf_pay *pl = &dbf->pay_buf; |
36 | dump->offset = offset; | 35 | u16 offset = 0, rec_length; |
37 | dump->size = min(from_len - offset, room); | 36 | |
38 | memcpy(dump->data, from + offset, dump->size); | 37 | spin_lock(&dbf->pay_lock); |
39 | debug_event(dbf, level, dump, dump->size + sizeof(*dump)); | 38 | memset(pl, 0, sizeof(*pl)); |
39 | pl->fsf_req_id = req_id; | ||
40 | memcpy(pl->area, area, ZFCP_DBF_TAG_LEN); | ||
41 | |||
42 | while (offset < length) { | ||
43 | rec_length = min((u16) ZFCP_DBF_PAY_MAX_REC, | ||
44 | (u16) (length - offset)); | ||
45 | memcpy(pl->data, data + offset, rec_length); | ||
46 | debug_event(dbf->pay, 1, pl, zfcp_dbf_plen(rec_length)); | ||
47 | |||
48 | offset += rec_length; | ||
49 | pl->counter++; | ||
40 | } | 50 | } |
51 | |||
52 | spin_unlock(&dbf->pay_lock); | ||
41 | } | 53 | } |
42 | 54 | ||
43 | static void zfcp_dbf_tag(char **p, const char *label, const char *tag) | 55 | static void zfcp_dbf_tag(char **p, const char *label, const char *tag) |
@@ -104,336 +116,117 @@ static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view, | |||
104 | return p - out_buf; | 116 | return p - out_buf; |
105 | } | 117 | } |
106 | 118 | ||
107 | void _zfcp_dbf_hba_fsf_response(const char *tag2, int level, | 119 | /** |
108 | struct zfcp_fsf_req *fsf_req, | 120 | * zfcp_dbf_hba_fsf_res - trace event for fsf responses |
109 | struct zfcp_dbf *dbf) | 121 | * @tag: tag indicating which kind of unsolicited status has been received |
110 | { | 122 | * @req: request for which a response was received |
111 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | 123 | */ |
112 | union fsf_prot_status_qual *prot_status_qual = | 124 | void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req) |
113 | &qtcb->prefix.prot_status_qual; | ||
114 | union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; | ||
115 | struct scsi_cmnd *scsi_cmnd; | ||
116 | struct zfcp_port *port; | ||
117 | struct zfcp_unit *unit; | ||
118 | struct zfcp_send_els *send_els; | ||
119 | struct zfcp_dbf_hba_record *rec = &dbf->hba_buf; | ||
120 | struct zfcp_dbf_hba_record_response *response = &rec->u.response; | ||
121 | unsigned long flags; | ||
122 | |||
123 | spin_lock_irqsave(&dbf->hba_lock, flags); | ||
124 | memset(rec, 0, sizeof(*rec)); | ||
125 | strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); | ||
126 | strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); | ||
127 | |||
128 | response->fsf_command = fsf_req->fsf_command; | ||
129 | response->fsf_reqid = fsf_req->req_id; | ||
130 | response->fsf_seqno = fsf_req->seq_no; | ||
131 | response->fsf_issued = fsf_req->issued; | ||
132 | response->fsf_prot_status = qtcb->prefix.prot_status; | ||
133 | response->fsf_status = qtcb->header.fsf_status; | ||
134 | memcpy(response->fsf_prot_status_qual, | ||
135 | prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE); | ||
136 | memcpy(response->fsf_status_qual, | ||
137 | fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); | ||
138 | response->fsf_req_status = fsf_req->status; | ||
139 | response->sbal_first = fsf_req->qdio_req.sbal_first; | ||
140 | response->sbal_last = fsf_req->qdio_req.sbal_last; | ||
141 | response->sbal_response = fsf_req->qdio_req.sbal_response; | ||
142 | response->pool = fsf_req->pool != NULL; | ||
143 | response->erp_action = (unsigned long)fsf_req->erp_action; | ||
144 | |||
145 | switch (fsf_req->fsf_command) { | ||
146 | case FSF_QTCB_FCP_CMND: | ||
147 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | ||
148 | break; | ||
149 | scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | ||
150 | if (scsi_cmnd) { | ||
151 | response->u.fcp.cmnd = (unsigned long)scsi_cmnd; | ||
152 | response->u.fcp.data_dir = | ||
153 | qtcb->bottom.io.data_direction; | ||
154 | } | ||
155 | break; | ||
156 | |||
157 | case FSF_QTCB_OPEN_PORT_WITH_DID: | ||
158 | case FSF_QTCB_CLOSE_PORT: | ||
159 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | ||
160 | port = (struct zfcp_port *)fsf_req->data; | ||
161 | response->u.port.wwpn = port->wwpn; | ||
162 | response->u.port.d_id = port->d_id; | ||
163 | response->u.port.port_handle = qtcb->header.port_handle; | ||
164 | break; | ||
165 | |||
166 | case FSF_QTCB_OPEN_LUN: | ||
167 | case FSF_QTCB_CLOSE_LUN: | ||
168 | unit = (struct zfcp_unit *)fsf_req->data; | ||
169 | port = unit->port; | ||
170 | response->u.unit.wwpn = port->wwpn; | ||
171 | response->u.unit.fcp_lun = unit->fcp_lun; | ||
172 | response->u.unit.port_handle = qtcb->header.port_handle; | ||
173 | response->u.unit.lun_handle = qtcb->header.lun_handle; | ||
174 | break; | ||
175 | |||
176 | case FSF_QTCB_SEND_ELS: | ||
177 | send_els = (struct zfcp_send_els *)fsf_req->data; | ||
178 | response->u.els.d_id = ntoh24(qtcb->bottom.support.d_id); | ||
179 | break; | ||
180 | |||
181 | case FSF_QTCB_ABORT_FCP_CMND: | ||
182 | case FSF_QTCB_SEND_GENERIC: | ||
183 | case FSF_QTCB_EXCHANGE_CONFIG_DATA: | ||
184 | case FSF_QTCB_EXCHANGE_PORT_DATA: | ||
185 | case FSF_QTCB_DOWNLOAD_CONTROL_FILE: | ||
186 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | ||
187 | break; | ||
188 | } | ||
189 | |||
190 | debug_event(dbf->hba, level, rec, sizeof(*rec)); | ||
191 | |||
192 | /* have fcp channel microcode fixed to use as little as possible */ | ||
193 | if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) { | ||
194 | /* adjust length skipping trailing zeros */ | ||
195 | char *buf = (char *)qtcb + qtcb->header.log_start; | ||
196 | int len = qtcb->header.log_length; | ||
197 | for (; len && !buf[len - 1]; len--); | ||
198 | zfcp_dbf_hexdump(dbf->hba, rec, sizeof(*rec), level, buf, | ||
199 | len); | ||
200 | } | ||
201 | |||
202 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | ||
203 | } | ||
204 | |||
205 | void _zfcp_dbf_hba_fsf_unsol(const char *tag, int level, struct zfcp_dbf *dbf, | ||
206 | struct fsf_status_read_buffer *status_buffer) | ||
207 | { | 125 | { |
208 | struct zfcp_dbf_hba_record *rec = &dbf->hba_buf; | 126 | struct zfcp_dbf *dbf = req->adapter->dbf; |
127 | struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix; | ||
128 | struct fsf_qtcb_header *q_head = &req->qtcb->header; | ||
129 | struct zfcp_dbf_hba *rec = &dbf->hba_buf; | ||
209 | unsigned long flags; | 130 | unsigned long flags; |
210 | 131 | ||
211 | spin_lock_irqsave(&dbf->hba_lock, flags); | 132 | spin_lock_irqsave(&dbf->hba_lock, flags); |
212 | memset(rec, 0, sizeof(*rec)); | 133 | memset(rec, 0, sizeof(*rec)); |
213 | strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); | ||
214 | strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); | ||
215 | |||
216 | rec->u.status.failed = atomic_read(&dbf->adapter->stat_miss); | ||
217 | if (status_buffer != NULL) { | ||
218 | rec->u.status.status_type = status_buffer->status_type; | ||
219 | rec->u.status.status_subtype = status_buffer->status_subtype; | ||
220 | memcpy(&rec->u.status.queue_designator, | ||
221 | &status_buffer->queue_designator, | ||
222 | sizeof(struct fsf_queue_designator)); | ||
223 | |||
224 | switch (status_buffer->status_type) { | ||
225 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | ||
226 | rec->u.status.payload_size = | ||
227 | ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; | ||
228 | break; | ||
229 | 134 | ||
230 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | 135 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
231 | rec->u.status.payload_size = | 136 | rec->id = ZFCP_DBF_HBA_RES; |
232 | ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; | 137 | rec->fsf_req_id = req->req_id; |
233 | break; | 138 | rec->fsf_req_status = req->status; |
234 | 139 | rec->fsf_cmd = req->fsf_command; | |
235 | case FSF_STATUS_READ_LINK_DOWN: | 140 | rec->fsf_seq_no = req->seq_no; |
236 | switch (status_buffer->status_subtype) { | 141 | rec->u.res.req_issued = req->issued; |
237 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: | 142 | rec->u.res.prot_status = q_pref->prot_status; |
238 | case FSF_STATUS_READ_SUB_FDISC_FAILED: | 143 | rec->u.res.fsf_status = q_head->fsf_status; |
239 | rec->u.status.payload_size = | 144 | |
240 | sizeof(struct fsf_link_down_info); | 145 | memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual, |
241 | } | 146 | FSF_PROT_STATUS_QUAL_SIZE); |
242 | break; | 147 | memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual, |
243 | 148 | FSF_STATUS_QUALIFIER_SIZE); | |
244 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: | 149 | |
245 | rec->u.status.payload_size = | 150 | if (req->fsf_command != FSF_QTCB_FCP_CMND) { |
246 | ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT; | 151 | rec->pl_len = q_head->log_length; |
247 | break; | 152 | zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, |
248 | } | 153 | rec->pl_len, "fsf_res", req->req_id); |
249 | memcpy(&rec->u.status.payload, | ||
250 | &status_buffer->payload, rec->u.status.payload_size); | ||
251 | } | 154 | } |
252 | 155 | ||
253 | debug_event(dbf->hba, level, rec, sizeof(*rec)); | 156 | debug_event(dbf->hba, 1, rec, sizeof(*rec)); |
254 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | 157 | spin_unlock_irqrestore(&dbf->hba_lock, flags); |
255 | } | 158 | } |
256 | 159 | ||
257 | /** | 160 | /** |
258 | * zfcp_dbf_hba_qdio - trace event for QDIO related failure | 161 | * zfcp_dbf_hba_fsf_uss - trace event for an unsolicited status buffer |
259 | * @qdio: qdio structure affected by this QDIO related event | 162 | * @tag: tag indicating which kind of unsolicited status has been received |
260 | * @qdio_error: as passed by qdio module | 163 | * @req: request providing the unsolicited status |
261 | * @sbal_index: first buffer with error condition, as passed by qdio module | ||
262 | * @sbal_count: number of buffers affected, as passed by qdio module | ||
263 | */ | 164 | */ |
264 | void zfcp_dbf_hba_qdio(struct zfcp_dbf *dbf, unsigned int qdio_error, | 165 | void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req) |
265 | int sbal_index, int sbal_count) | ||
266 | { | 166 | { |
267 | struct zfcp_dbf_hba_record *r = &dbf->hba_buf; | 167 | struct zfcp_dbf *dbf = req->adapter->dbf; |
168 | struct fsf_status_read_buffer *srb = req->data; | ||
169 | struct zfcp_dbf_hba *rec = &dbf->hba_buf; | ||
268 | unsigned long flags; | 170 | unsigned long flags; |
269 | 171 | ||
270 | spin_lock_irqsave(&dbf->hba_lock, flags); | 172 | spin_lock_irqsave(&dbf->hba_lock, flags); |
271 | memset(r, 0, sizeof(*r)); | 173 | memset(rec, 0, sizeof(*rec)); |
272 | strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE); | 174 | |
273 | r->u.qdio.qdio_error = qdio_error; | 175 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
274 | r->u.qdio.sbal_index = sbal_index; | 176 | rec->id = ZFCP_DBF_HBA_USS; |
275 | r->u.qdio.sbal_count = sbal_count; | 177 | rec->fsf_req_id = req->req_id; |
276 | debug_event(dbf->hba, 0, r, sizeof(*r)); | 178 | rec->fsf_req_status = req->status; |
179 | rec->fsf_cmd = req->fsf_command; | ||
180 | |||
181 | if (!srb) | ||
182 | goto log; | ||
183 | |||
184 | rec->u.uss.status_type = srb->status_type; | ||
185 | rec->u.uss.status_subtype = srb->status_subtype; | ||
186 | rec->u.uss.d_id = ntoh24(srb->d_id); | ||
187 | rec->u.uss.lun = srb->fcp_lun; | ||
188 | memcpy(&rec->u.uss.queue_designator, &srb->queue_designator, | ||
189 | sizeof(rec->u.uss.queue_designator)); | ||
190 | |||
191 | /* status read buffer payload length */ | ||
192 | rec->pl_len = (!srb->length) ? 0 : srb->length - | ||
193 | offsetof(struct fsf_status_read_buffer, payload); | ||
194 | |||
195 | if (rec->pl_len) | ||
196 | zfcp_dbf_pl_write(dbf, srb->payload.data, rec->pl_len, | ||
197 | "fsf_uss", req->req_id); | ||
198 | log: | ||
199 | debug_event(dbf->hba, 2, rec, sizeof(*rec)); | ||
277 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | 200 | spin_unlock_irqrestore(&dbf->hba_lock, flags); |
278 | } | 201 | } |
279 | 202 | ||
280 | /** | 203 | /** |
281 | * zfcp_dbf_hba_berr - trace event for bit error threshold | 204 | * zfcp_dbf_hba_bit_err - trace event for bit error conditions |
282 | * @dbf: dbf structure affected by this QDIO related event | 205 | * @tag: tag indicating which kind of unsolicited status has been received |
283 | * @req: fsf request | 206 | * @req: request which caused the bit_error condition |
284 | */ | 207 | */ |
285 | void zfcp_dbf_hba_berr(struct zfcp_dbf *dbf, struct zfcp_fsf_req *req) | 208 | void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req) |
286 | { | 209 | { |
287 | struct zfcp_dbf_hba_record *r = &dbf->hba_buf; | 210 | struct zfcp_dbf *dbf = req->adapter->dbf; |
211 | struct zfcp_dbf_hba *rec = &dbf->hba_buf; | ||
288 | struct fsf_status_read_buffer *sr_buf = req->data; | 212 | struct fsf_status_read_buffer *sr_buf = req->data; |
289 | struct fsf_bit_error_payload *err = &sr_buf->payload.bit_error; | ||
290 | unsigned long flags; | 213 | unsigned long flags; |
291 | 214 | ||
292 | spin_lock_irqsave(&dbf->hba_lock, flags); | 215 | spin_lock_irqsave(&dbf->hba_lock, flags); |
293 | memset(r, 0, sizeof(*r)); | 216 | memset(rec, 0, sizeof(*rec)); |
294 | strncpy(r->tag, "berr", ZFCP_DBF_TAG_SIZE); | ||
295 | memcpy(&r->u.berr, err, sizeof(struct fsf_bit_error_payload)); | ||
296 | debug_event(dbf->hba, 0, r, sizeof(*r)); | ||
297 | spin_unlock_irqrestore(&dbf->hba_lock, flags); | ||
298 | } | ||
299 | static void zfcp_dbf_hba_view_response(char **p, | ||
300 | struct zfcp_dbf_hba_record_response *r) | ||
301 | { | ||
302 | struct timespec t; | ||
303 | |||
304 | zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command); | ||
305 | zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid); | ||
306 | zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno); | ||
307 | stck_to_timespec(r->fsf_issued, &t); | ||
308 | zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec); | ||
309 | zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status); | ||
310 | zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status); | ||
311 | zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual, | ||
312 | FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE); | ||
313 | zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual, | ||
314 | FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE); | ||
315 | zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status); | ||
316 | zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first); | ||
317 | zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last); | ||
318 | zfcp_dbf_out(p, "sbal_response", "0x%02x", r->sbal_response); | ||
319 | zfcp_dbf_out(p, "pool", "0x%02x", r->pool); | ||
320 | |||
321 | switch (r->fsf_command) { | ||
322 | case FSF_QTCB_FCP_CMND: | ||
323 | if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) | ||
324 | break; | ||
325 | zfcp_dbf_out(p, "data_direction", "0x%04x", r->u.fcp.data_dir); | ||
326 | zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd); | ||
327 | *p += sprintf(*p, "\n"); | ||
328 | break; | ||
329 | |||
330 | case FSF_QTCB_OPEN_PORT_WITH_DID: | ||
331 | case FSF_QTCB_CLOSE_PORT: | ||
332 | case FSF_QTCB_CLOSE_PHYSICAL_PORT: | ||
333 | zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn); | ||
334 | zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id); | ||
335 | zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle); | ||
336 | break; | ||
337 | |||
338 | case FSF_QTCB_OPEN_LUN: | ||
339 | case FSF_QTCB_CLOSE_LUN: | ||
340 | zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn); | ||
341 | zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun); | ||
342 | zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle); | ||
343 | zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle); | ||
344 | break; | ||
345 | |||
346 | case FSF_QTCB_SEND_ELS: | ||
347 | zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id); | ||
348 | break; | ||
349 | |||
350 | case FSF_QTCB_ABORT_FCP_CMND: | ||
351 | case FSF_QTCB_SEND_GENERIC: | ||
352 | case FSF_QTCB_EXCHANGE_CONFIG_DATA: | ||
353 | case FSF_QTCB_EXCHANGE_PORT_DATA: | ||
354 | case FSF_QTCB_DOWNLOAD_CONTROL_FILE: | ||
355 | case FSF_QTCB_UPLOAD_CONTROL_FILE: | ||
356 | break; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static void zfcp_dbf_hba_view_status(char **p, | ||
361 | struct zfcp_dbf_hba_record_status *r) | ||
362 | { | ||
363 | zfcp_dbf_out(p, "failed", "0x%02x", r->failed); | ||
364 | zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type); | ||
365 | zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype); | ||
366 | zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator, | ||
367 | sizeof(struct fsf_queue_designator), 0, | ||
368 | sizeof(struct fsf_queue_designator)); | ||
369 | zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0, | ||
370 | r->payload_size); | ||
371 | } | ||
372 | |||
373 | static void zfcp_dbf_hba_view_qdio(char **p, struct zfcp_dbf_hba_record_qdio *r) | ||
374 | { | ||
375 | zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error); | ||
376 | zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index); | ||
377 | zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count); | ||
378 | } | ||
379 | |||
380 | static void zfcp_dbf_hba_view_berr(char **p, struct fsf_bit_error_payload *r) | ||
381 | { | ||
382 | zfcp_dbf_out(p, "link_failures", "%d", r->link_failure_error_count); | ||
383 | zfcp_dbf_out(p, "loss_of_sync_err", "%d", r->loss_of_sync_error_count); | ||
384 | zfcp_dbf_out(p, "loss_of_sig_err", "%d", r->loss_of_signal_error_count); | ||
385 | zfcp_dbf_out(p, "prim_seq_err", "%d", | ||
386 | r->primitive_sequence_error_count); | ||
387 | zfcp_dbf_out(p, "inval_trans_word_err", "%d", | ||
388 | r->invalid_transmission_word_error_count); | ||
389 | zfcp_dbf_out(p, "CRC_errors", "%d", r->crc_error_count); | ||
390 | zfcp_dbf_out(p, "prim_seq_event_to", "%d", | ||
391 | r->primitive_sequence_event_timeout_count); | ||
392 | zfcp_dbf_out(p, "elast_buf_overrun_err", "%d", | ||
393 | r->elastic_buffer_overrun_error_count); | ||
394 | zfcp_dbf_out(p, "adv_rec_buf2buf_cred", "%d", | ||
395 | r->advertised_receive_b2b_credit); | ||
396 | zfcp_dbf_out(p, "curr_rec_buf2buf_cred", "%d", | ||
397 | r->current_receive_b2b_credit); | ||
398 | zfcp_dbf_out(p, "adv_trans_buf2buf_cred", "%d", | ||
399 | r->advertised_transmit_b2b_credit); | ||
400 | zfcp_dbf_out(p, "curr_trans_buf2buf_cred", "%d", | ||
401 | r->current_transmit_b2b_credit); | ||
402 | } | ||
403 | |||
404 | static int zfcp_dbf_hba_view_format(debug_info_t *id, struct debug_view *view, | ||
405 | char *out_buf, const char *in_buf) | ||
406 | { | ||
407 | struct zfcp_dbf_hba_record *r = (struct zfcp_dbf_hba_record *)in_buf; | ||
408 | char *p = out_buf; | ||
409 | |||
410 | if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) | ||
411 | return 0; | ||
412 | 217 | ||
413 | zfcp_dbf_tag(&p, "tag", r->tag); | 218 | memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN); |
414 | if (isalpha(r->tag2[0])) | 219 | rec->id = ZFCP_DBF_HBA_BIT; |
415 | zfcp_dbf_tag(&p, "tag2", r->tag2); | 220 | rec->fsf_req_id = req->req_id; |
416 | 221 | rec->fsf_req_status = req->status; | |
417 | if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) | 222 | rec->fsf_cmd = req->fsf_command; |
418 | zfcp_dbf_hba_view_response(&p, &r->u.response); | 223 | memcpy(&rec->u.be, &sr_buf->payload.bit_error, |
419 | else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) | 224 | sizeof(struct fsf_bit_error_payload)); |
420 | zfcp_dbf_hba_view_status(&p, &r->u.status); | 225 | |
421 | else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) | 226 | debug_event(dbf->hba, 1, rec, sizeof(*rec)); |
422 | zfcp_dbf_hba_view_qdio(&p, &r->u.qdio); | 227 | spin_unlock_irqrestore(&dbf->hba_lock, flags); |
423 | else if (strncmp(r->tag, "berr", ZFCP_DBF_TAG_SIZE) == 0) | ||
424 | zfcp_dbf_hba_view_berr(&p, &r->u.berr); | ||
425 | |||
426 | if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) != 0) | ||
427 | p += sprintf(p, "\n"); | ||
428 | return p - out_buf; | ||
429 | } | 228 | } |
430 | 229 | ||
431 | static struct debug_view zfcp_dbf_hba_view = { | ||
432 | .name = "structured", | ||
433 | .header_proc = zfcp_dbf_view_header, | ||
434 | .format_proc = zfcp_dbf_hba_view_format, | ||
435 | }; | ||
436 | |||
437 | static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, | 230 | static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec, |
438 | struct zfcp_adapter *adapter, | 231 | struct zfcp_adapter *adapter, |
439 | struct zfcp_port *port, | 232 | struct zfcp_port *port, |
@@ -758,6 +551,7 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter) | |||
758 | 551 | ||
759 | dbf->adapter = adapter; | 552 | dbf->adapter = adapter; |
760 | 553 | ||
554 | spin_lock_init(&dbf->pay_lock); | ||
761 | spin_lock_init(&dbf->hba_lock); | 555 | spin_lock_init(&dbf->hba_lock); |
762 | spin_lock_init(&dbf->san_lock); | 556 | spin_lock_init(&dbf->san_lock); |
763 | spin_lock_init(&dbf->scsi_lock); | 557 | spin_lock_init(&dbf->scsi_lock); |
@@ -771,11 +565,17 @@ int zfcp_dbf_adapter_register(struct zfcp_adapter *adapter) | |||
771 | 565 | ||
772 | /* debug feature area which records HBA (FSF and QDIO) conditions */ | 566 | /* debug feature area which records HBA (FSF and QDIO) conditions */ |
773 | sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev)); | 567 | sprintf(dbf_name, "zfcp_%s_hba", dev_name(&adapter->ccw_device->dev)); |
774 | dbf->hba = zfcp_dbf_reg(dbf_name, 3, &zfcp_dbf_hba_view, | 568 | dbf->hba = zfcp_dbf_reg(dbf_name, 3, NULL, sizeof(struct zfcp_dbf_hba)); |
775 | sizeof(struct zfcp_dbf_hba_record)); | ||
776 | if (!dbf->hba) | 569 | if (!dbf->hba) |
777 | goto err_out; | 570 | goto err_out; |
778 | 571 | ||
572 | /* debug feature area which records payload info */ | ||
573 | sprintf(dbf_name, "zfcp_%s_pay", dev_name(&adapter->ccw_device->dev)); | ||
574 | dbf->pay = zfcp_dbf_reg(dbf_name, 3, NULL, | ||
575 | sizeof(struct zfcp_dbf_pay)); | ||
576 | if (!dbf->pay) | ||
577 | goto err_out; | ||
578 | |||
779 | /* debug feature area which records SAN command failures and recovery */ | 579 | /* debug feature area which records SAN command failures and recovery */ |
780 | sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev)); | 580 | sprintf(dbf_name, "zfcp_%s_san", dev_name(&adapter->ccw_device->dev)); |
781 | dbf->san = zfcp_dbf_reg(dbf_name, 3, NULL, sizeof(struct zfcp_dbf_san)); | 581 | dbf->san = zfcp_dbf_reg(dbf_name, 3, NULL, sizeof(struct zfcp_dbf_san)); |
@@ -808,6 +608,7 @@ void zfcp_dbf_adapter_unregister(struct zfcp_dbf *dbf) | |||
808 | debug_unregister(dbf->scsi); | 608 | debug_unregister(dbf->scsi); |
809 | debug_unregister(dbf->san); | 609 | debug_unregister(dbf->san); |
810 | debug_unregister(dbf->hba); | 610 | debug_unregister(dbf->hba); |
611 | debug_unregister(dbf->pay); | ||
811 | debug_unregister(dbf->rec); | 612 | debug_unregister(dbf->rec); |
812 | dbf->adapter->dbf = NULL; | 613 | dbf->adapter->dbf = NULL; |
813 | kfree(dbf); | 614 | kfree(dbf); |