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