diff options
author | Swen Schillig <swen@vnet.ibm.com> | 2010-12-02 09:16:14 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-12-21 13:24:45 -0500 |
commit | a54ca0f62f953898b05549391ac2a8a4dad6482b (patch) | |
tree | f7376c8be33b2247e9dcc694cf88f38304847e79 | |
parent | 2c55b750a884b86dea8b4cc5f15e1484cc47a25c (diff) |
[SCSI] zfcp: Redesign of the debug tracing for HBA records.
This patch is the continuation to redesign the zfcp tracing to a more
straight-forward and easy to extend scheme.
This patch deals with all trace records of the zfcp HBA area.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.c | 433 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_dbf.h | 197 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_ext.h | 10 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 18 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 2 |
5 files changed, 229 insertions, 431 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); |
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h index a3af6bd3d5aa..5dc0b414cf28 100644 --- a/drivers/s390/scsi/zfcp_dbf.h +++ b/drivers/s390/scsi/zfcp_dbf.h | |||
@@ -1,22 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * This file is part of the zfcp device driver for | 2 | * zfcp device driver |
3 | * FCP adapters for IBM System z9 and zSeries. | 3 | * debug feature declarations |
4 | * | 4 | * |
5 | * Copyright IBM Corp. 2008, 2009 | 5 | * Copyright IBM Corp. 2008, 2010 |
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2, or (at your option) | ||
10 | * any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | 6 | */ |
21 | 7 | ||
22 | #ifndef ZFCP_DBF_H | 8 | #ifndef ZFCP_DBF_H |
@@ -136,73 +122,90 @@ struct zfcp_dbf_san { | |||
136 | char payload[ZFCP_DBF_SAN_MAX_PAYLOAD]; | 122 | char payload[ZFCP_DBF_SAN_MAX_PAYLOAD]; |
137 | } __packed; | 123 | } __packed; |
138 | 124 | ||
139 | struct zfcp_dbf_hba_record_response { | 125 | /** |
140 | u32 fsf_command; | 126 | * struct zfcp_dbf_hba_res - trace record for hba responses |
141 | u64 fsf_reqid; | 127 | * @req_issued: timestamp when request was issued |
142 | u32 fsf_seqno; | 128 | * @prot_status: protocol status |
143 | u64 fsf_issued; | 129 | * @prot_status_qual: protocol status qualifier |
144 | u32 fsf_prot_status; | 130 | * @fsf_status: fsf status |
131 | * @fsf_status_qual: fsf status qualifier | ||
132 | */ | ||
133 | struct zfcp_dbf_hba_res { | ||
134 | u64 req_issued; | ||
135 | u32 prot_status; | ||
136 | u8 prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; | ||
145 | u32 fsf_status; | 137 | u32 fsf_status; |
146 | u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE]; | 138 | u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; |
147 | u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE]; | 139 | } __packed; |
148 | u32 fsf_req_status; | ||
149 | u8 sbal_first; | ||
150 | u8 sbal_last; | ||
151 | u8 sbal_response; | ||
152 | u8 pool; | ||
153 | u64 erp_action; | ||
154 | union { | ||
155 | struct { | ||
156 | u64 cmnd; | ||
157 | u32 data_dir; | ||
158 | } fcp; | ||
159 | struct { | ||
160 | u64 wwpn; | ||
161 | u32 d_id; | ||
162 | u32 port_handle; | ||
163 | } port; | ||
164 | struct { | ||
165 | u64 wwpn; | ||
166 | u64 fcp_lun; | ||
167 | u32 port_handle; | ||
168 | u32 lun_handle; | ||
169 | } unit; | ||
170 | struct { | ||
171 | u32 d_id; | ||
172 | } els; | ||
173 | } u; | ||
174 | } __attribute__ ((packed)); | ||
175 | 140 | ||
176 | struct zfcp_dbf_hba_record_status { | 141 | /** |
177 | u8 failed; | 142 | * struct zfcp_dbf_hba_uss - trace record for unsolicited status |
143 | * @status_type: type of unsolicited status | ||
144 | * @status_subtype: subtype of unsolicited status | ||
145 | * @d_id: destination ID | ||
146 | * @lun: logical unit number | ||
147 | * @queue_designator: queue designator | ||
148 | */ | ||
149 | struct zfcp_dbf_hba_uss { | ||
178 | u32 status_type; | 150 | u32 status_type; |
179 | u32 status_subtype; | 151 | u32 status_subtype; |
180 | struct fsf_queue_designator | 152 | u32 d_id; |
181 | queue_designator; | 153 | u64 lun; |
182 | u32 payload_size; | 154 | u64 queue_designator; |
183 | #define ZFCP_DBF_UNSOL_PAYLOAD 80 | 155 | } __packed; |
184 | #define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32 | ||
185 | #define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56 | ||
186 | #define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32) | ||
187 | u8 payload[ZFCP_DBF_UNSOL_PAYLOAD]; | ||
188 | } __attribute__ ((packed)); | ||
189 | 156 | ||
190 | struct zfcp_dbf_hba_record_qdio { | 157 | /** |
191 | u32 qdio_error; | 158 | * enum zfcp_dbf_hba_id - HBA trace record identifier |
192 | u8 sbal_index; | 159 | * @ZFCP_DBF_HBA_RES: response trace record |
193 | u8 sbal_count; | 160 | * @ZFCP_DBF_HBA_USS: unsolicited status trace record |
194 | } __attribute__ ((packed)); | 161 | * @ZFCP_DBF_HBA_BIT: bit error trace record |
162 | */ | ||
163 | enum zfcp_dbf_hba_id { | ||
164 | ZFCP_DBF_HBA_RES = 1, | ||
165 | ZFCP_DBF_HBA_USS = 2, | ||
166 | ZFCP_DBF_HBA_BIT = 3, | ||
167 | }; | ||
195 | 168 | ||
196 | struct zfcp_dbf_hba_record { | 169 | /** |
197 | u8 tag[ZFCP_DBF_TAG_SIZE]; | 170 | * struct zfcp_dbf_hba - common trace record for HBA records |
198 | u8 tag2[ZFCP_DBF_TAG_SIZE]; | 171 | * @id: unique number of recovery record type |
172 | * @tag: identifier string specifying the location of initiation | ||
173 | * @fsf_req_id: request id for fsf requests | ||
174 | * @fsf_req_status: status of fsf request | ||
175 | * @fsf_cmd: fsf command | ||
176 | * @fsf_seq_no: fsf sequence number | ||
177 | * @pl_len: length of payload stored as zfcp_dbf_pay | ||
178 | * @u: record type specific data | ||
179 | */ | ||
180 | struct zfcp_dbf_hba { | ||
181 | u8 id; | ||
182 | char tag[ZFCP_DBF_TAG_LEN]; | ||
183 | u64 fsf_req_id; | ||
184 | u32 fsf_req_status; | ||
185 | u32 fsf_cmd; | ||
186 | u32 fsf_seq_no; | ||
187 | u16 pl_len; | ||
199 | union { | 188 | union { |
200 | struct zfcp_dbf_hba_record_response response; | 189 | struct zfcp_dbf_hba_res res; |
201 | struct zfcp_dbf_hba_record_status status; | 190 | struct zfcp_dbf_hba_uss uss; |
202 | struct zfcp_dbf_hba_record_qdio qdio; | 191 | struct fsf_bit_error_payload be; |
203 | struct fsf_bit_error_payload berr; | ||
204 | } u; | 192 | } u; |
205 | } __attribute__ ((packed)); | 193 | } __packed; |
194 | |||
195 | /** | ||
196 | * struct zfcp_dbf_pay - trace record for unformatted payload information | ||
197 | * @area: area this record is originated from | ||
198 | * @counter: ascending record number | ||
199 | * @fsf_req_id: request id of fsf request | ||
200 | * @data: unformatted data | ||
201 | */ | ||
202 | struct zfcp_dbf_pay { | ||
203 | char area[ZFCP_DBF_TAG_LEN]; | ||
204 | char counter; | ||
205 | u64 fsf_req_id; | ||
206 | #define ZFCP_DBF_PAY_MAX_REC 0x100 | ||
207 | char data[ZFCP_DBF_PAY_MAX_REC]; | ||
208 | } __packed; | ||
206 | 209 | ||
207 | struct zfcp_dbf_scsi_record { | 210 | struct zfcp_dbf_scsi_record { |
208 | u8 tag[ZFCP_DBF_TAG_SIZE]; | 211 | u8 tag[ZFCP_DBF_TAG_SIZE]; |
@@ -230,71 +233,57 @@ struct zfcp_dbf_scsi_record { | |||
230 | } __attribute__ ((packed)); | 233 | } __attribute__ ((packed)); |
231 | 234 | ||
232 | struct zfcp_dbf { | 235 | struct zfcp_dbf { |
236 | debug_info_t *pay; | ||
233 | debug_info_t *rec; | 237 | debug_info_t *rec; |
234 | debug_info_t *hba; | 238 | debug_info_t *hba; |
235 | debug_info_t *san; | 239 | debug_info_t *san; |
236 | debug_info_t *scsi; | 240 | debug_info_t *scsi; |
241 | spinlock_t pay_lock; | ||
237 | spinlock_t rec_lock; | 242 | spinlock_t rec_lock; |
238 | spinlock_t hba_lock; | 243 | spinlock_t hba_lock; |
239 | spinlock_t san_lock; | 244 | spinlock_t san_lock; |
240 | spinlock_t scsi_lock; | 245 | spinlock_t scsi_lock; |
241 | struct zfcp_dbf_rec rec_buf; | 246 | struct zfcp_dbf_rec rec_buf; |
242 | struct zfcp_dbf_hba_record hba_buf; | 247 | struct zfcp_dbf_hba hba_buf; |
243 | struct zfcp_dbf_san san_buf; | 248 | struct zfcp_dbf_san san_buf; |
244 | struct zfcp_dbf_scsi_record scsi_buf; | 249 | struct zfcp_dbf_scsi_record scsi_buf; |
250 | struct zfcp_dbf_pay pay_buf; | ||
245 | struct zfcp_adapter *adapter; | 251 | struct zfcp_adapter *adapter; |
246 | }; | 252 | }; |
247 | 253 | ||
248 | static inline | 254 | static inline |
249 | void zfcp_dbf_hba_fsf_resp(const char *tag2, int level, | 255 | void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req) |
250 | struct zfcp_fsf_req *req, struct zfcp_dbf *dbf) | ||
251 | { | 256 | { |
252 | if (level <= dbf->hba->level) | 257 | if (level <= req->adapter->dbf->hba->level) |
253 | _zfcp_dbf_hba_fsf_response(tag2, level, req, dbf); | 258 | zfcp_dbf_hba_fsf_res(tag, req); |
254 | } | 259 | } |
255 | 260 | ||
256 | /** | 261 | /** |
257 | * zfcp_dbf_hba_fsf_response - trace event for request completion | 262 | * zfcp_dbf_hba_fsf_response - trace event for request completion |
258 | * @fsf_req: request that has been completed | 263 | * @fsf_req: request that has been completed |
259 | */ | 264 | */ |
260 | static inline void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) | 265 | static inline |
266 | void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) | ||
261 | { | 267 | { |
262 | struct zfcp_dbf *dbf = req->adapter->dbf; | ||
263 | struct fsf_qtcb *qtcb = req->qtcb; | 268 | struct fsf_qtcb *qtcb = req->qtcb; |
264 | 269 | ||
265 | if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && | 270 | if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && |
266 | (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { | 271 | (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { |
267 | zfcp_dbf_hba_fsf_resp("perr", 1, req, dbf); | 272 | zfcp_dbf_hba_fsf_resp("fs_perr", 1, req); |
268 | 273 | ||
269 | } else if (qtcb->header.fsf_status != FSF_GOOD) { | 274 | } else if (qtcb->header.fsf_status != FSF_GOOD) { |
270 | zfcp_dbf_hba_fsf_resp("ferr", 1, req, dbf); | 275 | zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req); |
271 | 276 | ||
272 | } else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || | 277 | } else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || |
273 | (req->fsf_command == FSF_QTCB_OPEN_LUN)) { | 278 | (req->fsf_command == FSF_QTCB_OPEN_LUN)) { |
274 | zfcp_dbf_hba_fsf_resp("open", 4, req, dbf); | 279 | zfcp_dbf_hba_fsf_resp("fs_open", 4, req); |
275 | 280 | ||
276 | } else if (qtcb->header.log_length) { | 281 | } else if (qtcb->header.log_length) { |
277 | zfcp_dbf_hba_fsf_resp("qtcb", 5, req, dbf); | 282 | zfcp_dbf_hba_fsf_resp("fs_qtcb", 5, req); |
278 | 283 | ||
279 | } else { | 284 | } else { |
280 | zfcp_dbf_hba_fsf_resp("norm", 6, req, dbf); | 285 | zfcp_dbf_hba_fsf_resp("fs_norm", 6, req); |
281 | } | 286 | } |
282 | } | ||
283 | |||
284 | /** | ||
285 | * zfcp_dbf_hba_fsf_unsol - trace event for an unsolicited status buffer | ||
286 | * @tag: tag indicating which kind of unsolicited status has been received | ||
287 | * @dbf: reference to dbf structure | ||
288 | * @status_buffer: buffer containing payload of unsolicited status | ||
289 | */ | ||
290 | static inline | ||
291 | void zfcp_dbf_hba_fsf_unsol(const char *tag, struct zfcp_dbf *dbf, | ||
292 | struct fsf_status_read_buffer *buf) | ||
293 | { | ||
294 | int level = 2; | ||
295 | |||
296 | if (level <= dbf->hba->level) | ||
297 | _zfcp_dbf_hba_fsf_unsol(tag, level, dbf, buf); | ||
298 | } | 287 | } |
299 | 288 | ||
300 | static inline | 289 | static inline |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index ff7effe55379..00875de2cb99 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -49,11 +49,9 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_dbf *); | |||
49 | extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *, | 49 | extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *, |
50 | struct zfcp_port *, struct scsi_device *, u8, u8); | 50 | struct zfcp_port *, struct scsi_device *, u8, u8); |
51 | extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *); | 51 | extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *); |
52 | extern void _zfcp_dbf_hba_fsf_response(const char *, int, struct zfcp_fsf_req *, | 52 | extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *); |
53 | struct zfcp_dbf *); | 53 | extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *); |
54 | extern void _zfcp_dbf_hba_fsf_unsol(const char *, int level, struct zfcp_dbf *, | 54 | extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *); |
55 | struct fsf_status_read_buffer *); | ||
56 | extern void zfcp_dbf_hba_qdio(struct zfcp_dbf *, unsigned int, int, int); | ||
57 | extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); | 55 | extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *); |
58 | extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); | 56 | extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32); |
59 | extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *); | 57 | extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *); |
@@ -141,6 +139,8 @@ extern int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *, struct zfcp_qdio_req *, | |||
141 | extern int zfcp_qdio_open(struct zfcp_qdio *); | 139 | extern int zfcp_qdio_open(struct zfcp_qdio *); |
142 | extern void zfcp_qdio_close(struct zfcp_qdio *); | 140 | extern void zfcp_qdio_close(struct zfcp_qdio *); |
143 | extern void zfcp_qdio_siosl(struct zfcp_adapter *); | 141 | extern void zfcp_qdio_siosl(struct zfcp_adapter *); |
142 | extern struct zfcp_fsf_req *zfcp_fsf_get_req(struct zfcp_qdio *, | ||
143 | struct qdio_buffer *); | ||
144 | 144 | ||
145 | /* zfcp_scsi.c */ | 145 | /* zfcp_scsi.c */ |
146 | extern struct zfcp_data zfcp_data; | 146 | extern struct zfcp_data zfcp_data; |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 6d805c50627f..9881ba947f11 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -211,13 +211,13 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
211 | struct fsf_status_read_buffer *sr_buf = req->data; | 211 | struct fsf_status_read_buffer *sr_buf = req->data; |
212 | 212 | ||
213 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 213 | if (req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
214 | zfcp_dbf_hba_fsf_unsol("dism", adapter->dbf, sr_buf); | 214 | zfcp_dbf_hba_fsf_uss("fssrh_1", req); |
215 | mempool_free(sr_buf, adapter->pool.status_read_data); | 215 | mempool_free(sr_buf, adapter->pool.status_read_data); |
216 | zfcp_fsf_req_free(req); | 216 | zfcp_fsf_req_free(req); |
217 | return; | 217 | return; |
218 | } | 218 | } |
219 | 219 | ||
220 | zfcp_dbf_hba_fsf_unsol("read", adapter->dbf, sr_buf); | 220 | zfcp_dbf_hba_fsf_uss("fssrh_2", req); |
221 | 221 | ||
222 | switch (sr_buf->status_type) { | 222 | switch (sr_buf->status_type) { |
223 | case FSF_STATUS_READ_PORT_CLOSED: | 223 | case FSF_STATUS_READ_PORT_CLOSED: |
@@ -232,7 +232,7 @@ static void zfcp_fsf_status_read_handler(struct zfcp_fsf_req *req) | |||
232 | dev_warn(&adapter->ccw_device->dev, | 232 | dev_warn(&adapter->ccw_device->dev, |
233 | "The error threshold for checksum statistics " | 233 | "The error threshold for checksum statistics " |
234 | "has been exceeded\n"); | 234 | "has been exceeded\n"); |
235 | zfcp_dbf_hba_berr(adapter->dbf, req); | 235 | zfcp_dbf_hba_bit_err("fssrh_3", req); |
236 | break; | 236 | break; |
237 | case FSF_STATUS_READ_LINK_DOWN: | 237 | case FSF_STATUS_READ_LINK_DOWN: |
238 | zfcp_fsf_status_read_link_down(req); | 238 | zfcp_fsf_status_read_link_down(req); |
@@ -754,10 +754,11 @@ int zfcp_fsf_status_read(struct zfcp_qdio *qdio) | |||
754 | goto out; | 754 | goto out; |
755 | 755 | ||
756 | failed_req_send: | 756 | failed_req_send: |
757 | req->data = NULL; | ||
757 | mempool_free(sr_buf, adapter->pool.status_read_data); | 758 | mempool_free(sr_buf, adapter->pool.status_read_data); |
758 | failed_buf: | 759 | failed_buf: |
760 | zfcp_dbf_hba_fsf_uss("fssr__1", req); | ||
759 | zfcp_fsf_req_free(req); | 761 | zfcp_fsf_req_free(req); |
760 | zfcp_dbf_hba_fsf_unsol("fail", adapter->dbf, NULL); | ||
761 | out: | 762 | out: |
762 | spin_unlock_irq(&qdio->req_q_lock); | 763 | spin_unlock_irq(&qdio->req_q_lock); |
763 | return retval; | 764 | return retval; |
@@ -2420,3 +2421,12 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) | |||
2420 | break; | 2421 | break; |
2421 | } | 2422 | } |
2422 | } | 2423 | } |
2424 | |||
2425 | struct zfcp_fsf_req *zfcp_fsf_get_req(struct zfcp_qdio *qdio, | ||
2426 | struct qdio_buffer *sbal) | ||
2427 | { | ||
2428 | struct qdio_buffer_element *sbale = &sbal->element[0]; | ||
2429 | u64 req_id = (unsigned long) sbale->addr; | ||
2430 | |||
2431 | return zfcp_reqlist_find(qdio->adapter->req_list, req_id); | ||
2432 | } | ||
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index a0554beb4179..434a33ba0509 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -74,7 +74,6 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, | |||
74 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; | 74 | struct zfcp_qdio *qdio = (struct zfcp_qdio *) parm; |
75 | 75 | ||
76 | if (unlikely(qdio_err)) { | 76 | if (unlikely(qdio_err)) { |
77 | zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count); | ||
78 | zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err); | 77 | zfcp_qdio_handler_error(qdio, "qdireq1", qdio_err); |
79 | return; | 78 | return; |
80 | } | 79 | } |
@@ -97,7 +96,6 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, | |||
97 | int sbal_idx, sbal_no; | 96 | int sbal_idx, sbal_no; |
98 | 97 | ||
99 | if (unlikely(qdio_err)) { | 98 | if (unlikely(qdio_err)) { |
100 | zfcp_dbf_hba_qdio(qdio->adapter->dbf, qdio_err, idx, count); | ||
101 | zfcp_qdio_handler_error(qdio, "qdires1", qdio_err); | 99 | zfcp_qdio_handler_error(qdio, "qdires1", qdio_err); |
102 | return; | 100 | return; |
103 | } | 101 | } |