1 /* 2 * This file is part of the zfcp device driver for 3 * FCP adapters for IBM System z9 and zSeries. 4 * 5 * (C) Copyright IBM Corp. 2002, 2006 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 */ 21 22 #include <linux/ctype.h> 23 #include <asm/debug.h> 24 #include "zfcp_ext.h" 25 26 static u32 dbfsize = 4; 27 28 module_param(dbfsize, uint, 0400); 29 MODULE_PARM_DESC(dbfsize, 30 "number of pages for each debug feature area (default 4)"); 31 32 #define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER 33 34 static int 35 zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck) 36 { 37 unsigned long long sec; 38 struct timespec dbftime; 39 int len = 0; 40 41 stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096); 42 sec = stck >> 12; 43 do_div(sec, 1000000); 44 dbftime.tv_sec = sec; 45 stck -= (sec * 1000000) << 12; 46 dbftime.tv_nsec = ((stck * 1000) >> 12); 47 len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n", 48 label, dbftime.tv_sec, dbftime.tv_nsec); 49 50 return len; 51 } 52 53 static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag) 54 { 55 int len = 0, i; 56 57 len += sprintf(out_buf + len, "%-24s", label); 58 for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++) 59 len += sprintf(out_buf + len, "%c", tag[i]); 60 len += sprintf(out_buf + len, "\n"); 61 62 return len; 63 } 64 65 static int 66 zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...) 67 { 68 va_list arg; 69 int len = 0; 70 71 len += sprintf(out_buf + len, "%-24s", label); 72 va_start(arg, format); 73 len += vsprintf(out_buf + len, format, arg); 74 va_end(arg); 75 len += sprintf(out_buf + len, "\n"); 76 77 return len; 78 } 79 80 static int 81 zfcp_dbf_view_dump(char *out_buf, const char *label, 82 char *buffer, int buflen, int offset, int total_size) 83 { 84 int len = 0; 85 86 if (offset == 0) 87 len += sprintf(out_buf + len, "%-24s ", label); 88 89 while (buflen--) { 90 if (offset > 0) { 91 if ((offset % 32) == 0) 92 len += sprintf(out_buf + len, "\n%-24c ", ' '); 93 else if ((offset % 4) == 0) 94 len += sprintf(out_buf + len, " "); 95 } 96 len += sprintf(out_buf + len, "%02x", *buffer++); 97 if (++offset == total_size) { 98 len += sprintf(out_buf + len, "\n"); 99 break; 100 } 101 } 102 103 if (total_size == 0) 104 len += sprintf(out_buf + len, "\n"); 105 106 return len; 107 } 108 109 static int 110 zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area, 111 debug_entry_t * entry, char *out_buf) 112 { 113 struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry); 114 int len = 0; 115 116 if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) { 117 len += zfcp_dbf_stck(out_buf + len, "timestamp", 118 entry->id.stck); 119 len += zfcp_dbf_view(out_buf + len, "cpu", "%02i", 120 entry->id.fields.cpuid); 121 } else { 122 len += zfcp_dbf_view_dump(out_buf + len, NULL, 123 dump->data, 124 dump->size, 125 dump->offset, dump->total_size); 126 if ((dump->offset + dump->size) == dump->total_size) 127 len += sprintf(out_buf + len, "\n"); 128 } 129 130 return len; 131 } 132 133 void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req) 134 { 135 struct zfcp_adapter *adapter = fsf_req->adapter; 136 struct fsf_qtcb *qtcb = fsf_req->qtcb; 137 union fsf_prot_status_qual *prot_status_qual = 138 &qtcb->prefix.prot_status_qual; 139 union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual; 140 struct scsi_cmnd *scsi_cmnd; 141 struct zfcp_port *port; 142 struct zfcp_unit *unit; 143 struct zfcp_send_els *send_els; 144 struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; 145 struct zfcp_hba_dbf_record_response *response = &rec->type.response; 146 int level; 147 unsigned long flags; 148 149 spin_lock_irqsave(&adapter->hba_dbf_lock, flags); 150 memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); 151 strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE); 152 153 if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && 154 (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { 155 strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE); 156 level = 1; 157 } else if (qtcb->header.fsf_status != FSF_GOOD) { 158 strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE); 159 level = 1; 160 } else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || 161 (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) { 162 strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE); 163 level = 4; 164 } else { 165 strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE); 166 level = 6; 167 } 168 169 response->fsf_command = fsf_req->fsf_command; 170 response->fsf_reqid = (unsigned long)fsf_req; 171 response->fsf_seqno = fsf_req->seq_no; 172 response->fsf_issued = fsf_req->issued; 173 response->fsf_prot_status = qtcb->prefix.prot_status; 174 response->fsf_status = qtcb->header.fsf_status; 175 memcpy(response->fsf_prot_status_qual, 176 prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE); 177 memcpy(response->fsf_status_qual, 178 fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE); 179 response->fsf_req_status = fsf_req->status; 180 response->sbal_first = fsf_req->sbal_first; 181 response->sbal_curr = fsf_req->sbal_curr; 182 response->sbal_last = fsf_req->sbal_last; 183 response->pool = fsf_req->pool != NULL; 184 response->erp_action = (unsigned long)fsf_req->erp_action; 185 186 switch (fsf_req->fsf_command) { 187 case FSF_QTCB_FCP_CMND: 188 if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) 189 break; 190 scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; 191 if (scsi_cmnd != NULL) { 192 response->data.send_fcp.scsi_cmnd 193 = (unsigned long)scsi_cmnd; 194 response->data.send_fcp.scsi_serial 195 = scsi_cmnd->serial_number; 196 } 197 break; 198 199 case FSF_QTCB_OPEN_PORT_WITH_DID: 200 case FSF_QTCB_CLOSE_PORT: 201 case FSF_QTCB_CLOSE_PHYSICAL_PORT: 202 port = (struct zfcp_port *)fsf_req->data; 203 response->data.port.wwpn = port->wwpn; 204 response->data.port.d_id = port->d_id; 205 response->data.port.port_handle = qtcb->header.port_handle; 206 break; 207 208 case FSF_QTCB_OPEN_LUN: 209 case FSF_QTCB_CLOSE_LUN: 210 unit = (struct zfcp_unit *)fsf_req->data; 211 port = unit->port; 212 response->data.unit.wwpn = port->wwpn; 213 response->data.unit.fcp_lun = unit->fcp_lun; 214 response->data.unit.port_handle = qtcb->header.port_handle; 215 response->data.unit.lun_handle = qtcb->header.lun_handle; 216 break; 217 218 case FSF_QTCB_SEND_ELS: 219 send_els = (struct zfcp_send_els *)fsf_req->data; 220 response->data.send_els.d_id = qtcb->bottom.support.d_id; 221 response->data.send_els.ls_code = send_els->ls_code >> 24; 222 break; 223 224 case FSF_QTCB_ABORT_FCP_CMND: 225 case FSF_QTCB_SEND_GENERIC: 226 case FSF_QTCB_EXCHANGE_CONFIG_DATA: 227 case FSF_QTCB_EXCHANGE_PORT_DATA: 228 case FSF_QTCB_DOWNLOAD_CONTROL_FILE: 229 case FSF_QTCB_UPLOAD_CONTROL_FILE: 230 break; 231 } 232 233 debug_event(adapter->hba_dbf, level, 234 rec, sizeof(struct zfcp_hba_dbf_record)); 235 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); 236 } 237 238 void 239 zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter, 240 struct fsf_status_read_buffer *status_buffer) 241 { 242 struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; 243 unsigned long flags; 244 245 spin_lock_irqsave(&adapter->hba_dbf_lock, flags); 246 memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); 247 strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE); 248 strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE); 249 250 rec->type.status.failed = adapter->status_read_failed; 251 if (status_buffer != NULL) { 252 rec->type.status.status_type = status_buffer->status_type; 253 rec->type.status.status_subtype = status_buffer->status_subtype; 254 memcpy(&rec->type.status.queue_designator, 255 &status_buffer->queue_designator, 256 sizeof(struct fsf_queue_designator)); 257 258 switch (status_buffer->status_type) { 259 case FSF_STATUS_READ_SENSE_DATA_AVAIL: 260 rec->type.status.payload_size = 261 ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL; 262 break; 263 264 case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: 265 rec->type.status.payload_size = 266 ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD; 267 break; 268 269 case FSF_STATUS_READ_LINK_DOWN: 270 switch (status_buffer->status_subtype) { 271 case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: 272 case FSF_STATUS_READ_SUB_FDISC_FAILED: 273 rec->type.status.payload_size = 274 sizeof(struct fsf_link_down_info); 275 } 276 break; 277 278 case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: 279 rec->type.status.payload_size = 280 ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT; 281 break; 282 } 283 memcpy(&rec->type.status.payload, 284 &status_buffer->payload, rec->type.status.payload_size); 285 } 286 287 debug_event(adapter->hba_dbf, 2, 288 rec, sizeof(struct zfcp_hba_dbf_record)); 289 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); 290 } 291 292 void 293 zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status, 294 unsigned int qdio_error, unsigned int siga_error, 295 int sbal_index, int sbal_count) 296 { 297 struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf; 298 unsigned long flags; 299 300 spin_lock_irqsave(&adapter->hba_dbf_lock, flags); 301 memset(rec, 0, sizeof(struct zfcp_hba_dbf_record)); 302 strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE); 303 rec->type.qdio.status = status; 304 rec->type.qdio.qdio_error = qdio_error; 305 rec->type.qdio.siga_error = siga_error; 306 rec->type.qdio.sbal_index = sbal_index; 307 rec->type.qdio.sbal_count = sbal_count; 308 debug_event(adapter->hba_dbf, 0, 309 rec, sizeof(struct zfcp_hba_dbf_record)); 310 spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags); 311 } 312 313 static int 314 zfcp_hba_dbf_view_response(char *out_buf, 315 struct zfcp_hba_dbf_record_response *rec) 316 { 317 int len = 0; 318 319 len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x", 320 rec->fsf_command); 321 len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", 322 rec->fsf_reqid); 323 len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", 324 rec->fsf_seqno); 325 len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); 326 len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x", 327 rec->fsf_prot_status); 328 len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x", 329 rec->fsf_status); 330 len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual", 331 rec->fsf_prot_status_qual, 332 FSF_PROT_STATUS_QUAL_SIZE, 333 0, FSF_PROT_STATUS_QUAL_SIZE); 334 len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual", 335 rec->fsf_status_qual, 336 FSF_STATUS_QUALIFIER_SIZE, 337 0, FSF_STATUS_QUALIFIER_SIZE); 338 len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x", 339 rec->fsf_req_status); 340 len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x", 341 rec->sbal_first); 342 len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x", 343 rec->sbal_curr); 344 len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x", 345 rec->sbal_last); 346 len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool); 347 348 switch (rec->fsf_command) { 349 case FSF_QTCB_FCP_CMND: 350 if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT) 351 break; 352 len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", 353 rec->data.send_fcp.scsi_cmnd); 354 len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", 355 rec->data.send_fcp.scsi_serial); 356 break; 357 358 case FSF_QTCB_OPEN_PORT_WITH_DID: 359 case FSF_QTCB_CLOSE_PORT: 360 case FSF_QTCB_CLOSE_PHYSICAL_PORT: 361 len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", 362 rec->data.port.wwpn); 363 len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", 364 rec->data.port.d_id); 365 len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", 366 rec->data.port.port_handle); 367 break; 368 369 case FSF_QTCB_OPEN_LUN: 370 case FSF_QTCB_CLOSE_LUN: 371 len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx", 372 rec->data.unit.wwpn); 373 len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx", 374 rec->data.unit.fcp_lun); 375 len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x", 376 rec->data.unit.port_handle); 377 len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x", 378 rec->data.unit.lun_handle); 379 break; 380 381 case FSF_QTCB_SEND_ELS: 382 len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", 383 rec->data.send_els.d_id); 384 len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", 385 rec->data.send_els.ls_code); 386 break; 387 388 case FSF_QTCB_ABORT_FCP_CMND: 389 case FSF_QTCB_SEND_GENERIC: 390 case FSF_QTCB_EXCHANGE_CONFIG_DATA: 391 case FSF_QTCB_EXCHANGE_PORT_DATA: 392 case FSF_QTCB_DOWNLOAD_CONTROL_FILE: 393 case FSF_QTCB_UPLOAD_CONTROL_FILE: 394 break; 395 } 396 397 return len; 398 } 399 400 static int 401 zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec) 402 { 403 int len = 0; 404 405 len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed); 406 len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x", 407 rec->status_type); 408 len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x", 409 rec->status_subtype); 410 len += zfcp_dbf_view_dump(out_buf + len, "queue_designator", 411 (char *)&rec->queue_designator, 412 sizeof(struct fsf_queue_designator), 413 0, sizeof(struct fsf_queue_designator)); 414 len += zfcp_dbf_view_dump(out_buf + len, "payload", 415 (char *)&rec->payload, 416 rec->payload_size, 0, rec->payload_size); 417 418 return len; 419 } 420 421 static int 422 zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec) 423 { 424 int len = 0; 425 426 len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status); 427 len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x", 428 rec->qdio_error); 429 len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x", 430 rec->siga_error); 431 len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x", 432 rec->sbal_index); 433 len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x", 434 rec->sbal_count); 435 436 return len; 437 } 438 439 static int 440 zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view, 441 char *out_buf, const char *in_buf) 442 { 443 struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf; 444 int len = 0; 445 446 if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) 447 return 0; 448 449 len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); 450 if (isalpha(rec->tag2[0])) 451 len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); 452 if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0) 453 len += zfcp_hba_dbf_view_response(out_buf + len, 454 &rec->type.response); 455 else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0) 456 len += zfcp_hba_dbf_view_status(out_buf + len, 457 &rec->type.status); 458 else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0) 459 len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio); 460 461 len += sprintf(out_buf + len, "\n"); 462 463 return len; 464 } 465 466 static struct debug_view zfcp_hba_dbf_view = { 467 "structured", 468 NULL, 469 &zfcp_dbf_view_header, 470 &zfcp_hba_dbf_view_format, 471 NULL, 472 NULL 473 }; 474 475 static void 476 _zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req, 477 u32 s_id, u32 d_id, void *buffer, int buflen) 478 { 479 struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data; 480 struct zfcp_port *port = send_ct->port; 481 struct zfcp_adapter *adapter = port->adapter; 482 struct ct_hdr *header = (struct ct_hdr *)buffer; 483 struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; 484 struct zfcp_san_dbf_record_ct *ct = &rec->type.ct; 485 unsigned long flags; 486 487 spin_lock_irqsave(&adapter->san_dbf_lock, flags); 488 memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); 489 strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); 490 rec->fsf_reqid = (unsigned long)fsf_req; 491 rec->fsf_seqno = fsf_req->seq_no; 492 rec->s_id = s_id; 493 rec->d_id = d_id; 494 if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { 495 ct->type.request.cmd_req_code = header->cmd_rsp_code; 496 ct->type.request.revision = header->revision; 497 ct->type.request.gs_type = header->gs_type; 498 ct->type.request.gs_subtype = header->gs_subtype; 499 ct->type.request.options = header->options; 500 ct->type.request.max_res_size = header->max_res_size; 501 } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { 502 ct->type.response.cmd_rsp_code = header->cmd_rsp_code; 503 ct->type.response.revision = header->revision; 504 ct->type.response.reason_code = header->reason_code; 505 ct->type.response.reason_code_expl = header->reason_code_expl; 506 ct->type.response.vendor_unique = header->vendor_unique; 507 } 508 ct->payload_size = 509 min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD); 510 memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size); 511 debug_event(adapter->san_dbf, 3, 512 rec, sizeof(struct zfcp_san_dbf_record)); 513 spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); 514 } 515 516 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req) 517 { 518 struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; 519 struct zfcp_port *port = ct->port; 520 struct zfcp_adapter *adapter = port->adapter; 521 522 _zfcp_san_dbf_event_common_ct("octc", fsf_req, 523 fc_host_port_id(adapter->scsi_host), 524 port->d_id, zfcp_sg_to_address(ct->req), 525 ct->req->length); 526 } 527 528 void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req) 529 { 530 struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data; 531 struct zfcp_port *port = ct->port; 532 struct zfcp_adapter *adapter = port->adapter; 533 534 _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id, 535 fc_host_port_id(adapter->scsi_host), 536 zfcp_sg_to_address(ct->resp), 537 ct->resp->length); 538 } 539 540 static void 541 _zfcp_san_dbf_event_common_els(const char *tag, int level, 542 struct zfcp_fsf_req *fsf_req, u32 s_id, 543 u32 d_id, u8 ls_code, void *buffer, int buflen) 544 { 545 struct zfcp_adapter *adapter = fsf_req->adapter; 546 struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf; 547 struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; 548 unsigned long flags; 549 int offset = 0; 550 551 spin_lock_irqsave(&adapter->san_dbf_lock, flags); 552 do { 553 memset(rec, 0, sizeof(struct zfcp_san_dbf_record)); 554 if (offset == 0) { 555 strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); 556 rec->fsf_reqid = (unsigned long)fsf_req; 557 rec->fsf_seqno = fsf_req->seq_no; 558 rec->s_id = s_id; 559 rec->d_id = d_id; 560 rec->type.els.ls_code = ls_code; 561 buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD); 562 rec->type.els.payload_size = buflen; 563 memcpy(rec->type.els.payload, 564 buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD)); 565 offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD); 566 } else { 567 strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); 568 dump->total_size = buflen; 569 dump->offset = offset; 570 dump->size = min(buflen - offset, 571 (int)sizeof(struct zfcp_san_dbf_record) 572 - (int)sizeof(struct zfcp_dbf_dump)); 573 memcpy(dump->data, buffer + offset, dump->size); 574 offset += dump->size; 575 } 576 debug_event(adapter->san_dbf, level, 577 rec, sizeof(struct zfcp_san_dbf_record)); 578 } while (offset < buflen); 579 spin_unlock_irqrestore(&adapter->san_dbf_lock, flags); 580 } 581 582 void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req) 583 { 584 struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; 585 586 _zfcp_san_dbf_event_common_els("oels", 2, fsf_req, 587 fc_host_port_id(els->adapter->scsi_host), 588 els->d_id, 589 *(u8 *) zfcp_sg_to_address(els->req), 590 zfcp_sg_to_address(els->req), 591 els->req->length); 592 } 593 594 void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req) 595 { 596 struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data; 597 598 _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id, 599 fc_host_port_id(els->adapter->scsi_host), 600 *(u8 *) zfcp_sg_to_address(els->req), 601 zfcp_sg_to_address(els->resp), 602 els->resp->length); 603 } 604 605 void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req) 606 { 607 struct zfcp_adapter *adapter = fsf_req->adapter; 608 struct fsf_status_read_buffer *status_buffer = 609 (struct fsf_status_read_buffer *)fsf_req->data; 610 int length = (int)status_buffer->length - 611 (int)((void *)&status_buffer->payload - (void *)status_buffer); 612 613 _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id, 614 fc_host_port_id(adapter->scsi_host), 615 *(u8 *) status_buffer->payload, 616 (void *)status_buffer->payload, length); 617 } 618 619 static int 620 zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view, 621 char *out_buf, const char *in_buf) 622 { 623 struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf; 624 char *buffer = NULL; 625 int buflen = 0, total = 0; 626 int len = 0; 627 628 if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) 629 return 0; 630 631 len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); 632 len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", 633 rec->fsf_reqid); 634 len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", 635 rec->fsf_seqno); 636 len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id); 637 len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id); 638 639 if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) { 640 len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x", 641 rec->type.ct.type.request.cmd_req_code); 642 len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", 643 rec->type.ct.type.request.revision); 644 len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x", 645 rec->type.ct.type.request.gs_type); 646 len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x", 647 rec->type.ct.type.request.gs_subtype); 648 len += zfcp_dbf_view(out_buf + len, "options", "0x%02x", 649 rec->type.ct.type.request.options); 650 len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x", 651 rec->type.ct.type.request.max_res_size); 652 total = rec->type.ct.payload_size; 653 buffer = rec->type.ct.payload; 654 buflen = min(total, ZFCP_DBF_CT_PAYLOAD); 655 } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) { 656 len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x", 657 rec->type.ct.type.response.cmd_rsp_code); 658 len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x", 659 rec->type.ct.type.response.revision); 660 len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x", 661 rec->type.ct.type.response.reason_code); 662 len += 663 zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x", 664 rec->type.ct.type.response.reason_code_expl); 665 len += 666 zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x", 667 rec->type.ct.type.response.vendor_unique); 668 total = rec->type.ct.payload_size; 669 buffer = rec->type.ct.payload; 670 buflen = min(total, ZFCP_DBF_CT_PAYLOAD); 671 } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 || 672 strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 || 673 strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) { 674 len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x", 675 rec->type.els.ls_code); 676 total = rec->type.els.payload_size; 677 buffer = rec->type.els.payload; 678 buflen = min(total, ZFCP_DBF_ELS_PAYLOAD); 679 } 680 681 len += zfcp_dbf_view_dump(out_buf + len, "payload", 682 buffer, buflen, 0, total); 683 684 if (buflen == total) 685 len += sprintf(out_buf + len, "\n"); 686 687 return len; 688 } 689 690 static struct debug_view zfcp_san_dbf_view = { 691 "structured", 692 NULL, 693 &zfcp_dbf_view_header, 694 &zfcp_san_dbf_view_format, 695 NULL, 696 NULL 697 }; 698 699 static void 700 _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level, 701 struct zfcp_adapter *adapter, 702 struct scsi_cmnd *scsi_cmnd, 703 struct zfcp_fsf_req *fsf_req, 704 unsigned long old_req_id) 705 { 706 struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf; 707 struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec; 708 unsigned long flags; 709 struct fcp_rsp_iu *fcp_rsp; 710 char *fcp_rsp_info = NULL, *fcp_sns_info = NULL; 711 int offset = 0, buflen = 0; 712 713 spin_lock_irqsave(&adapter->scsi_dbf_lock, flags); 714 do { 715 memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record)); 716 if (offset == 0) { 717 strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE); 718 strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE); 719 if (scsi_cmnd != NULL) { 720 if (scsi_cmnd->device) { 721 rec->scsi_id = scsi_cmnd->device->id; 722 rec->scsi_lun = scsi_cmnd->device->lun; 723 } 724 rec->scsi_result = scsi_cmnd->result; 725 rec->scsi_cmnd = (unsigned long)scsi_cmnd; 726 rec->scsi_serial = scsi_cmnd->serial_number; 727 memcpy(rec->scsi_opcode, &scsi_cmnd->cmnd, 728 min((int)scsi_cmnd->cmd_len, 729 ZFCP_DBF_SCSI_OPCODE)); 730 rec->scsi_retries = scsi_cmnd->retries; 731 rec->scsi_allowed = scsi_cmnd->allowed; 732 } 733 if (fsf_req != NULL) { 734 fcp_rsp = (struct fcp_rsp_iu *) 735 &(fsf_req->qtcb->bottom.io.fcp_rsp); 736 fcp_rsp_info = 737 zfcp_get_fcp_rsp_info_ptr(fcp_rsp); 738 fcp_sns_info = 739 zfcp_get_fcp_sns_info_ptr(fcp_rsp); 740 741 rec->type.fcp.rsp_validity = 742 fcp_rsp->validity.value; 743 rec->type.fcp.rsp_scsi_status = 744 fcp_rsp->scsi_status; 745 rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid; 746 if (fcp_rsp->validity.bits.fcp_rsp_len_valid) 747 rec->type.fcp.rsp_code = 748 *(fcp_rsp_info + 3); 749 if (fcp_rsp->validity.bits.fcp_sns_len_valid) { 750 buflen = min((int)fcp_rsp->fcp_sns_len, 751 ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO); 752 rec->type.fcp.sns_info_len = buflen; 753 memcpy(rec->type.fcp.sns_info, 754 fcp_sns_info, 755 min(buflen, 756 ZFCP_DBF_SCSI_FCP_SNS_INFO)); 757 offset += min(buflen, 758 ZFCP_DBF_SCSI_FCP_SNS_INFO); 759 } 760 761 rec->fsf_reqid = (unsigned long)fsf_req; 762 rec->fsf_seqno = fsf_req->seq_no; 763 rec->fsf_issued = fsf_req->issued; 764 } 765 rec->type.old_fsf_reqid = old_req_id; 766 } else { 767 strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE); 768 dump->total_size = buflen; 769 dump->offset = offset; 770 dump->size = min(buflen - offset, 771 (int)sizeof(struct 772 zfcp_scsi_dbf_record) - 773 (int)sizeof(struct zfcp_dbf_dump)); 774 memcpy(dump->data, fcp_sns_info + offset, dump->size); 775 offset += dump->size; 776 } 777 debug_event(adapter->scsi_dbf, level, 778 rec, sizeof(struct zfcp_scsi_dbf_record)); 779 } while (offset < buflen); 780 spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags); 781 } 782 783 void 784 zfcp_scsi_dbf_event_result(const char *tag, int level, 785 struct zfcp_adapter *adapter, 786 struct scsi_cmnd *scsi_cmnd, 787 struct zfcp_fsf_req *fsf_req) 788 { 789 _zfcp_scsi_dbf_event_common("rslt", tag, level, 790 adapter, scsi_cmnd, fsf_req, 0); 791 } 792 793 void 794 zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter, 795 struct scsi_cmnd *scsi_cmnd, 796 struct zfcp_fsf_req *new_fsf_req, 797 unsigned long old_req_id) 798 { 799 _zfcp_scsi_dbf_event_common("abrt", tag, 1, 800 adapter, scsi_cmnd, new_fsf_req, old_req_id); 801 } 802 803 void 804 zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit, 805 struct scsi_cmnd *scsi_cmnd) 806 { 807 struct zfcp_adapter *adapter = unit->port->adapter; 808 809 _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst", 810 tag, 1, adapter, scsi_cmnd, NULL, 0); 811 } 812 813 static int 814 zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view, 815 char *out_buf, const char *in_buf) 816 { 817 struct zfcp_scsi_dbf_record *rec = 818 (struct zfcp_scsi_dbf_record *)in_buf; 819 int len = 0; 820 821 if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0) 822 return 0; 823 824 len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag); 825 len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2); 826 len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id); 827 len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x", 828 rec->scsi_lun); 829 len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x", 830 rec->scsi_result); 831 len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx", 832 rec->scsi_cmnd); 833 len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx", 834 rec->scsi_serial); 835 len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode", 836 rec->scsi_opcode, 837 ZFCP_DBF_SCSI_OPCODE, 838 0, ZFCP_DBF_SCSI_OPCODE); 839 len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x", 840 rec->scsi_retries); 841 len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x", 842 rec->scsi_allowed); 843 if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) { 844 len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx", 845 rec->type.old_fsf_reqid); 846 } 847 len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx", 848 rec->fsf_reqid); 849 len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x", 850 rec->fsf_seqno); 851 len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued); 852 if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) { 853 len += 854 zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x", 855 rec->type.fcp.rsp_validity); 856 len += 857 zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status", 858 "0x%02x", rec->type.fcp.rsp_scsi_status); 859 len += 860 zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x", 861 rec->type.fcp.rsp_resid); 862 len += 863 zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x", 864 rec->type.fcp.rsp_code); 865 len += 866 zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x", 867 rec->type.fcp.sns_info_len); 868 len += 869 zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info", 870 rec->type.fcp.sns_info, 871 min((int)rec->type.fcp.sns_info_len, 872 ZFCP_DBF_SCSI_FCP_SNS_INFO), 0, 873 rec->type.fcp.sns_info_len); 874 } 875 876 len += sprintf(out_buf + len, "\n"); 877 878 return len; 879 } 880 881 static struct debug_view zfcp_scsi_dbf_view = { 882 "structured", 883 NULL, 884 &zfcp_dbf_view_header, 885 &zfcp_scsi_dbf_view_format, 886 NULL, 887 NULL 888 }; 889 890 /** 891 * zfcp_adapter_debug_register - registers debug feature for an adapter 892 * @adapter: pointer to adapter for which debug features should be registered 893 * return: -ENOMEM on error, 0 otherwise 894 */ 895 int zfcp_adapter_debug_register(struct zfcp_adapter *adapter) 896 { 897 char dbf_name[DEBUG_MAX_NAME_LEN]; 898 899 /* debug feature area which records recovery activity */ 900 sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter)); 901 adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2, 902 sizeof(struct zfcp_erp_dbf_record)); 903 if (!adapter->erp_dbf) 904 goto failed; 905 debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view); 906 debug_set_level(adapter->erp_dbf, 3); 907 908 /* debug feature area which records HBA (FSF and QDIO) conditions */ 909 sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter)); 910 adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1, 911 sizeof(struct zfcp_hba_dbf_record)); 912 if (!adapter->hba_dbf) 913 goto failed; 914 debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view); 915 debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view); 916 debug_set_level(adapter->hba_dbf, 3); 917 918 /* debug feature area which records SAN command failures and recovery */ 919 sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter)); 920 adapter->san_dbf = debug_register(dbf_name, dbfsize, 1, 921 sizeof(struct zfcp_san_dbf_record)); 922 if (!adapter->san_dbf) 923 goto failed; 924 debug_register_view(adapter->san_dbf, &debug_hex_ascii_view); 925 debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view); 926 debug_set_level(adapter->san_dbf, 6); 927 928 /* debug feature area which records SCSI command failures and recovery */ 929 sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter)); 930 adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1, 931 sizeof(struct zfcp_scsi_dbf_record)); 932 if (!adapter->scsi_dbf) 933 goto failed; 934 debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view); 935 debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view); 936 debug_set_level(adapter->scsi_dbf, 3); 937 938 return 0; 939 940 failed: 941 zfcp_adapter_debug_unregister(adapter); 942 943 return -ENOMEM; 944 } 945 946 /** 947 * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter 948 * @adapter: pointer to adapter for which debug features should be unregistered 949 */ 950 void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter) 951 { 952 debug_unregister(adapter->scsi_dbf); 953 debug_unregister(adapter->san_dbf); 954 debug_unregister(adapter->hba_dbf); 955 debug_unregister(adapter->erp_dbf); 956 adapter->scsi_dbf = NULL; 957 adapter->san_dbf = NULL; 958 adapter->hba_dbf = NULL; 959 adapter->erp_dbf = NULL; 960 } 961 962 #undef ZFCP_LOG_AREA 963