diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 769 |
1 files changed, 354 insertions, 415 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index c007b6424e74..3b0fc1163f5f 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -59,6 +59,8 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *, struct timer_list *); | |||
59 | static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *); | 59 | static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *); |
60 | static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *); | 60 | static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *); |
61 | static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *); | 61 | static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *); |
62 | static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *, | ||
63 | struct fsf_link_down_info *); | ||
62 | static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); | 64 | static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *); |
63 | static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *); | 65 | static void zfcp_fsf_req_dismiss(struct zfcp_fsf_req *); |
64 | 66 | ||
@@ -285,51 +287,51 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
285 | { | 287 | { |
286 | int retval = 0; | 288 | int retval = 0; |
287 | struct zfcp_adapter *adapter = fsf_req->adapter; | 289 | struct zfcp_adapter *adapter = fsf_req->adapter; |
290 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | ||
291 | union fsf_prot_status_qual *prot_status_qual = | ||
292 | &qtcb->prefix.prot_status_qual; | ||
288 | 293 | ||
289 | ZFCP_LOG_DEBUG("QTCB is at %p\n", fsf_req->qtcb); | 294 | zfcp_hba_dbf_event_fsf_response(fsf_req); |
290 | 295 | ||
291 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 296 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
292 | ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n", | 297 | ZFCP_LOG_DEBUG("fsf_req 0x%lx has been dismissed\n", |
293 | (unsigned long) fsf_req); | 298 | (unsigned long) fsf_req); |
294 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | | 299 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR | |
295 | ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ | 300 | ZFCP_STATUS_FSFREQ_RETRY; /* only for SCSI cmnds. */ |
296 | zfcp_cmd_dbf_event_fsf("dismiss", fsf_req, NULL, 0); | ||
297 | goto skip_protstatus; | 301 | goto skip_protstatus; |
298 | } | 302 | } |
299 | 303 | ||
300 | /* log additional information provided by FSF (if any) */ | 304 | /* log additional information provided by FSF (if any) */ |
301 | if (unlikely(fsf_req->qtcb->header.log_length)) { | 305 | if (unlikely(qtcb->header.log_length)) { |
302 | /* do not trust them ;-) */ | 306 | /* do not trust them ;-) */ |
303 | if (fsf_req->qtcb->header.log_start > sizeof(struct fsf_qtcb)) { | 307 | if (qtcb->header.log_start > sizeof(struct fsf_qtcb)) { |
304 | ZFCP_LOG_NORMAL | 308 | ZFCP_LOG_NORMAL |
305 | ("bug: ULP (FSF logging) log data starts " | 309 | ("bug: ULP (FSF logging) log data starts " |
306 | "beyond end of packet header. Ignored. " | 310 | "beyond end of packet header. Ignored. " |
307 | "(start=%i, size=%li)\n", | 311 | "(start=%i, size=%li)\n", |
308 | fsf_req->qtcb->header.log_start, | 312 | qtcb->header.log_start, |
309 | sizeof(struct fsf_qtcb)); | 313 | sizeof(struct fsf_qtcb)); |
310 | goto forget_log; | 314 | goto forget_log; |
311 | } | 315 | } |
312 | if ((size_t) (fsf_req->qtcb->header.log_start + | 316 | if ((size_t) (qtcb->header.log_start + qtcb->header.log_length) |
313 | fsf_req->qtcb->header.log_length) | ||
314 | > sizeof(struct fsf_qtcb)) { | 317 | > sizeof(struct fsf_qtcb)) { |
315 | ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " | 318 | ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends " |
316 | "beyond end of packet header. Ignored. " | 319 | "beyond end of packet header. Ignored. " |
317 | "(start=%i, length=%i, size=%li)\n", | 320 | "(start=%i, length=%i, size=%li)\n", |
318 | fsf_req->qtcb->header.log_start, | 321 | qtcb->header.log_start, |
319 | fsf_req->qtcb->header.log_length, | 322 | qtcb->header.log_length, |
320 | sizeof(struct fsf_qtcb)); | 323 | sizeof(struct fsf_qtcb)); |
321 | goto forget_log; | 324 | goto forget_log; |
322 | } | 325 | } |
323 | ZFCP_LOG_TRACE("ULP log data: \n"); | 326 | ZFCP_LOG_TRACE("ULP log data: \n"); |
324 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, | 327 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, |
325 | (char *) fsf_req->qtcb + | 328 | (char *) qtcb + qtcb->header.log_start, |
326 | fsf_req->qtcb->header.log_start, | 329 | qtcb->header.log_length); |
327 | fsf_req->qtcb->header.log_length); | ||
328 | } | 330 | } |
329 | forget_log: | 331 | forget_log: |
330 | 332 | ||
331 | /* evaluate FSF Protocol Status */ | 333 | /* evaluate FSF Protocol Status */ |
332 | switch (fsf_req->qtcb->prefix.prot_status) { | 334 | switch (qtcb->prefix.prot_status) { |
333 | 335 | ||
334 | case FSF_PROT_GOOD: | 336 | case FSF_PROT_GOOD: |
335 | case FSF_PROT_FSF_STATUS_PRESENTED: | 337 | case FSF_PROT_FSF_STATUS_PRESENTED: |
@@ -340,14 +342,9 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
340 | "microcode of version 0x%x, the device driver " | 342 | "microcode of version 0x%x, the device driver " |
341 | "only supports 0x%x. Aborting.\n", | 343 | "only supports 0x%x. Aborting.\n", |
342 | zfcp_get_busid_by_adapter(adapter), | 344 | zfcp_get_busid_by_adapter(adapter), |
343 | fsf_req->qtcb->prefix.prot_status_qual. | 345 | prot_status_qual->version_error.fsf_version, |
344 | version_error.fsf_version, ZFCP_QTCB_VERSION); | 346 | ZFCP_QTCB_VERSION); |
345 | /* stop operation for this adapter */ | ||
346 | debug_text_exception(adapter->erp_dbf, 0, "prot_ver_err"); | ||
347 | zfcp_erp_adapter_shutdown(adapter, 0); | 347 | zfcp_erp_adapter_shutdown(adapter, 0); |
348 | zfcp_cmd_dbf_event_fsf("qverserr", fsf_req, | ||
349 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
350 | sizeof (union fsf_prot_status_qual)); | ||
351 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 348 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
352 | break; | 349 | break; |
353 | 350 | ||
@@ -355,16 +352,10 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
355 | ZFCP_LOG_NORMAL("bug: Sequence number mismatch between " | 352 | ZFCP_LOG_NORMAL("bug: Sequence number mismatch between " |
356 | "driver (0x%x) and adapter %s (0x%x). " | 353 | "driver (0x%x) and adapter %s (0x%x). " |
357 | "Restarting all operations on this adapter.\n", | 354 | "Restarting all operations on this adapter.\n", |
358 | fsf_req->qtcb->prefix.req_seq_no, | 355 | qtcb->prefix.req_seq_no, |
359 | zfcp_get_busid_by_adapter(adapter), | 356 | zfcp_get_busid_by_adapter(adapter), |
360 | fsf_req->qtcb->prefix.prot_status_qual. | 357 | prot_status_qual->sequence_error.exp_req_seq_no); |
361 | sequence_error.exp_req_seq_no); | ||
362 | debug_text_exception(adapter->erp_dbf, 0, "prot_seq_err"); | ||
363 | /* restart operation on this adapter */ | ||
364 | zfcp_erp_adapter_reopen(adapter, 0); | 358 | zfcp_erp_adapter_reopen(adapter, 0); |
365 | zfcp_cmd_dbf_event_fsf("seqnoerr", fsf_req, | ||
366 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
367 | sizeof (union fsf_prot_status_qual)); | ||
368 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 359 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; |
369 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 360 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
370 | break; | 361 | break; |
@@ -375,116 +366,35 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
375 | "that used on adapter %s. " | 366 | "that used on adapter %s. " |
376 | "Stopping all operations on this adapter.\n", | 367 | "Stopping all operations on this adapter.\n", |
377 | zfcp_get_busid_by_adapter(adapter)); | 368 | zfcp_get_busid_by_adapter(adapter)); |
378 | debug_text_exception(adapter->erp_dbf, 0, "prot_unsup_qtcb"); | ||
379 | zfcp_erp_adapter_shutdown(adapter, 0); | 369 | zfcp_erp_adapter_shutdown(adapter, 0); |
380 | zfcp_cmd_dbf_event_fsf("unsqtcbt", fsf_req, | ||
381 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
382 | sizeof (union fsf_prot_status_qual)); | ||
383 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 370 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
384 | break; | 371 | break; |
385 | 372 | ||
386 | case FSF_PROT_HOST_CONNECTION_INITIALIZING: | 373 | case FSF_PROT_HOST_CONNECTION_INITIALIZING: |
387 | zfcp_cmd_dbf_event_fsf("hconinit", fsf_req, | ||
388 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
389 | sizeof (union fsf_prot_status_qual)); | ||
390 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 374 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
391 | atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, | 375 | atomic_set_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT, |
392 | &(adapter->status)); | 376 | &(adapter->status)); |
393 | debug_text_event(adapter->erp_dbf, 3, "prot_con_init"); | ||
394 | break; | 377 | break; |
395 | 378 | ||
396 | case FSF_PROT_DUPLICATE_REQUEST_ID: | 379 | case FSF_PROT_DUPLICATE_REQUEST_ID: |
397 | if (fsf_req->qtcb) { | ||
398 | ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx " | 380 | ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx " |
399 | "to the adapter %s is ambiguous. " | 381 | "to the adapter %s is ambiguous. " |
400 | "Stopping all operations on this " | 382 | "Stopping all operations on this adapter.\n", |
401 | "adapter.\n", | 383 | *(unsigned long long*) |
402 | *(unsigned long long *) | 384 | (&qtcb->bottom.support.req_handle), |
403 | (&fsf_req->qtcb->bottom.support. | ||
404 | req_handle), | ||
405 | zfcp_get_busid_by_adapter(adapter)); | ||
406 | } else { | ||
407 | ZFCP_LOG_NORMAL("bug: The request identifier %p " | ||
408 | "to the adapter %s is ambiguous. " | ||
409 | "Stopping all operations on this " | ||
410 | "adapter. " | ||
411 | "(bug: got this for an unsolicited " | ||
412 | "status read request)\n", | ||
413 | fsf_req, | ||
414 | zfcp_get_busid_by_adapter(adapter)); | 385 | zfcp_get_busid_by_adapter(adapter)); |
415 | } | ||
416 | debug_text_exception(adapter->erp_dbf, 0, "prot_dup_id"); | ||
417 | zfcp_erp_adapter_shutdown(adapter, 0); | 386 | zfcp_erp_adapter_shutdown(adapter, 0); |
418 | zfcp_cmd_dbf_event_fsf("dupreqid", fsf_req, | ||
419 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
420 | sizeof (union fsf_prot_status_qual)); | ||
421 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 387 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
422 | break; | 388 | break; |
423 | 389 | ||
424 | case FSF_PROT_LINK_DOWN: | 390 | case FSF_PROT_LINK_DOWN: |
425 | /* | 391 | zfcp_fsf_link_down_info_eval(adapter, |
426 | * 'test and set' is not atomic here - | 392 | &prot_status_qual->link_down_info); |
427 | * it's ok as long as calls to our response queue handler | ||
428 | * (and thus execution of this code here) are serialized | ||
429 | * by the qdio module | ||
430 | */ | ||
431 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
432 | &adapter->status)) { | ||
433 | switch (fsf_req->qtcb->prefix.prot_status_qual. | ||
434 | locallink_error.code) { | ||
435 | case FSF_PSQ_LINK_NOLIGHT: | ||
436 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
437 | "is down (no light detected).\n", | ||
438 | zfcp_get_busid_by_adapter( | ||
439 | adapter)); | ||
440 | break; | ||
441 | case FSF_PSQ_LINK_WRAPPLUG: | ||
442 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
443 | "is down (wrap plug detected).\n", | ||
444 | zfcp_get_busid_by_adapter( | ||
445 | adapter)); | ||
446 | break; | ||
447 | case FSF_PSQ_LINK_NOFCP: | ||
448 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
449 | "is down (adjacent node on " | ||
450 | "link does not support FCP).\n", | ||
451 | zfcp_get_busid_by_adapter( | ||
452 | adapter)); | ||
453 | break; | ||
454 | default: | ||
455 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
456 | "is down " | ||
457 | "(warning: unknown reason " | ||
458 | "code).\n", | ||
459 | zfcp_get_busid_by_adapter( | ||
460 | adapter)); | ||
461 | break; | ||
462 | |||
463 | } | ||
464 | /* | ||
465 | * Due to the 'erp failed' flag the adapter won't | ||
466 | * be recovered but will be just set to 'blocked' | ||
467 | * state. All subordinary devices will have state | ||
468 | * 'blocked' and 'erp failed', too. | ||
469 | * Thus the adapter is still able to provide | ||
470 | * 'link up' status without being flooded with | ||
471 | * requests. | ||
472 | * (note: even 'close port' is not permitted) | ||
473 | */ | ||
474 | ZFCP_LOG_INFO("Stopping all operations for adapter " | ||
475 | "%s.\n", | ||
476 | zfcp_get_busid_by_adapter(adapter)); | ||
477 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | | ||
478 | ZFCP_STATUS_COMMON_ERP_FAILED, | ||
479 | &adapter->status); | ||
480 | zfcp_erp_adapter_reopen(adapter, 0); | ||
481 | } | ||
482 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 393 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
483 | break; | 394 | break; |
484 | 395 | ||
485 | case FSF_PROT_REEST_QUEUE: | 396 | case FSF_PROT_REEST_QUEUE: |
486 | debug_text_event(adapter->erp_dbf, 1, "prot_reest_queue"); | 397 | ZFCP_LOG_NORMAL("The local link to adapter with " |
487 | ZFCP_LOG_INFO("The local link to adapter with " | ||
488 | "%s was re-plugged. " | 398 | "%s was re-plugged. " |
489 | "Re-starting operations on this adapter.\n", | 399 | "Re-starting operations on this adapter.\n", |
490 | zfcp_get_busid_by_adapter(adapter)); | 400 | zfcp_get_busid_by_adapter(adapter)); |
@@ -495,9 +405,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
495 | zfcp_erp_adapter_reopen(adapter, | 405 | zfcp_erp_adapter_reopen(adapter, |
496 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | 406 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
497 | | ZFCP_STATUS_COMMON_ERP_FAILED); | 407 | | ZFCP_STATUS_COMMON_ERP_FAILED); |
498 | zfcp_cmd_dbf_event_fsf("reestque", fsf_req, | ||
499 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
500 | sizeof (union fsf_prot_status_qual)); | ||
501 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 408 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
502 | break; | 409 | break; |
503 | 410 | ||
@@ -507,12 +414,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
507 | "Restarting all operations on this " | 414 | "Restarting all operations on this " |
508 | "adapter.\n", | 415 | "adapter.\n", |
509 | zfcp_get_busid_by_adapter(adapter)); | 416 | zfcp_get_busid_by_adapter(adapter)); |
510 | debug_text_event(adapter->erp_dbf, 0, "prot_err_sta"); | ||
511 | /* restart operation on this adapter */ | ||
512 | zfcp_erp_adapter_reopen(adapter, 0); | 417 | zfcp_erp_adapter_reopen(adapter, 0); |
513 | zfcp_cmd_dbf_event_fsf("proterrs", fsf_req, | ||
514 | &fsf_req->qtcb->prefix.prot_status_qual, | ||
515 | sizeof (union fsf_prot_status_qual)); | ||
516 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; | 418 | fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY; |
517 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 419 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
518 | break; | 420 | break; |
@@ -524,11 +426,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
524 | "Stopping all operations on this adapter. " | 426 | "Stopping all operations on this adapter. " |
525 | "(debug info 0x%x).\n", | 427 | "(debug info 0x%x).\n", |
526 | zfcp_get_busid_by_adapter(adapter), | 428 | zfcp_get_busid_by_adapter(adapter), |
527 | fsf_req->qtcb->prefix.prot_status); | 429 | qtcb->prefix.prot_status); |
528 | debug_text_event(adapter->erp_dbf, 0, "prot_inval:"); | ||
529 | debug_exception(adapter->erp_dbf, 0, | ||
530 | &fsf_req->qtcb->prefix.prot_status, | ||
531 | sizeof (u32)); | ||
532 | zfcp_erp_adapter_shutdown(adapter, 0); | 430 | zfcp_erp_adapter_shutdown(adapter, 0); |
533 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 431 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
534 | } | 432 | } |
@@ -568,28 +466,18 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
568 | "(debug info 0x%x).\n", | 466 | "(debug info 0x%x).\n", |
569 | zfcp_get_busid_by_adapter(fsf_req->adapter), | 467 | zfcp_get_busid_by_adapter(fsf_req->adapter), |
570 | fsf_req->qtcb->header.fsf_command); | 468 | fsf_req->qtcb->header.fsf_command); |
571 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
572 | "fsf_s_unknown"); | ||
573 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); | 469 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); |
574 | zfcp_cmd_dbf_event_fsf("unknownc", fsf_req, | ||
575 | &fsf_req->qtcb->header.fsf_status_qual, | ||
576 | sizeof (union fsf_status_qual)); | ||
577 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 470 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
578 | break; | 471 | break; |
579 | 472 | ||
580 | case FSF_FCP_RSP_AVAILABLE: | 473 | case FSF_FCP_RSP_AVAILABLE: |
581 | ZFCP_LOG_DEBUG("FCP Sense data will be presented to the " | 474 | ZFCP_LOG_DEBUG("FCP Sense data will be presented to the " |
582 | "SCSI stack.\n"); | 475 | "SCSI stack.\n"); |
583 | debug_text_event(fsf_req->adapter->erp_dbf, 3, "fsf_s_rsp"); | ||
584 | break; | 476 | break; |
585 | 477 | ||
586 | case FSF_ADAPTER_STATUS_AVAILABLE: | 478 | case FSF_ADAPTER_STATUS_AVAILABLE: |
587 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_astatus"); | ||
588 | zfcp_fsf_fsfstatus_qual_eval(fsf_req); | 479 | zfcp_fsf_fsfstatus_qual_eval(fsf_req); |
589 | break; | 480 | break; |
590 | |||
591 | default: | ||
592 | break; | ||
593 | } | 481 | } |
594 | 482 | ||
595 | skip_fsfstatus: | 483 | skip_fsfstatus: |
@@ -617,44 +505,28 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
617 | 505 | ||
618 | switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { | 506 | switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) { |
619 | case FSF_SQ_FCP_RSP_AVAILABLE: | 507 | case FSF_SQ_FCP_RSP_AVAILABLE: |
620 | debug_text_event(fsf_req->adapter->erp_dbf, 4, "fsf_sq_rsp"); | ||
621 | break; | 508 | break; |
622 | case FSF_SQ_RETRY_IF_POSSIBLE: | 509 | case FSF_SQ_RETRY_IF_POSSIBLE: |
623 | /* The SCSI-stack may now issue retries or escalate */ | 510 | /* The SCSI-stack may now issue retries or escalate */ |
624 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_retry"); | ||
625 | zfcp_cmd_dbf_event_fsf("sqretry", fsf_req, | ||
626 | &fsf_req->qtcb->header.fsf_status_qual, | ||
627 | sizeof (union fsf_status_qual)); | ||
628 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 511 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
629 | break; | 512 | break; |
630 | case FSF_SQ_COMMAND_ABORTED: | 513 | case FSF_SQ_COMMAND_ABORTED: |
631 | /* Carry the aborted state on to upper layer */ | 514 | /* Carry the aborted state on to upper layer */ |
632 | debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_sq_abort"); | ||
633 | zfcp_cmd_dbf_event_fsf("sqabort", fsf_req, | ||
634 | &fsf_req->qtcb->header.fsf_status_qual, | ||
635 | sizeof (union fsf_status_qual)); | ||
636 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED; | 515 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTED; |
637 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 516 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
638 | break; | 517 | break; |
639 | case FSF_SQ_NO_RECOM: | 518 | case FSF_SQ_NO_RECOM: |
640 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
641 | "fsf_sq_no_rec"); | ||
642 | ZFCP_LOG_NORMAL("bug: No recommendation could be given for a" | 519 | ZFCP_LOG_NORMAL("bug: No recommendation could be given for a" |
643 | "problem on the adapter %s " | 520 | "problem on the adapter %s " |
644 | "Stopping all operations on this adapter. ", | 521 | "Stopping all operations on this adapter. ", |
645 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 522 | zfcp_get_busid_by_adapter(fsf_req->adapter)); |
646 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); | 523 | zfcp_erp_adapter_shutdown(fsf_req->adapter, 0); |
647 | zfcp_cmd_dbf_event_fsf("sqnrecom", fsf_req, | ||
648 | &fsf_req->qtcb->header.fsf_status_qual, | ||
649 | sizeof (union fsf_status_qual)); | ||
650 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 524 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
651 | break; | 525 | break; |
652 | case FSF_SQ_ULP_PROGRAMMING_ERROR: | 526 | case FSF_SQ_ULP_PROGRAMMING_ERROR: |
653 | ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer " | 527 | ZFCP_LOG_NORMAL("error: not enough SBALs for data transfer " |
654 | "(adapter %s)\n", | 528 | "(adapter %s)\n", |
655 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 529 | zfcp_get_busid_by_adapter(fsf_req->adapter)); |
656 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | ||
657 | "fsf_sq_ulp_err"); | ||
658 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 530 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
659 | break; | 531 | break; |
660 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: | 532 | case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE: |
@@ -668,13 +540,6 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
668 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | 540 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, |
669 | (char *) &fsf_req->qtcb->header.fsf_status_qual, | 541 | (char *) &fsf_req->qtcb->header.fsf_status_qual, |
670 | sizeof (union fsf_status_qual)); | 542 | sizeof (union fsf_status_qual)); |
671 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_sq_inval:"); | ||
672 | debug_exception(fsf_req->adapter->erp_dbf, 0, | ||
673 | &fsf_req->qtcb->header.fsf_status_qual.word[0], | ||
674 | sizeof (u32)); | ||
675 | zfcp_cmd_dbf_event_fsf("squndef", fsf_req, | ||
676 | &fsf_req->qtcb->header.fsf_status_qual, | ||
677 | sizeof (union fsf_status_qual)); | ||
678 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 543 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
679 | break; | 544 | break; |
680 | } | 545 | } |
@@ -682,6 +547,110 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
682 | return retval; | 547 | return retval; |
683 | } | 548 | } |
684 | 549 | ||
550 | /** | ||
551 | * zfcp_fsf_link_down_info_eval - evaluate link down information block | ||
552 | */ | ||
553 | static void | ||
554 | zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter, | ||
555 | struct fsf_link_down_info *link_down) | ||
556 | { | ||
557 | switch (link_down->error_code) { | ||
558 | case FSF_PSQ_LINK_NO_LIGHT: | ||
559 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
560 | "(no light detected)\n", | ||
561 | zfcp_get_busid_by_adapter(adapter)); | ||
562 | break; | ||
563 | case FSF_PSQ_LINK_WRAP_PLUG: | ||
564 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
565 | "(wrap plug detected)\n", | ||
566 | zfcp_get_busid_by_adapter(adapter)); | ||
567 | break; | ||
568 | case FSF_PSQ_LINK_NO_FCP: | ||
569 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
570 | "(adjacent node on link does not support FCP)\n", | ||
571 | zfcp_get_busid_by_adapter(adapter)); | ||
572 | break; | ||
573 | case FSF_PSQ_LINK_FIRMWARE_UPDATE: | ||
574 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
575 | "(firmware update in progress)\n", | ||
576 | zfcp_get_busid_by_adapter(adapter)); | ||
577 | break; | ||
578 | case FSF_PSQ_LINK_INVALID_WWPN: | ||
579 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
580 | "(duplicate or invalid WWPN detected)\n", | ||
581 | zfcp_get_busid_by_adapter(adapter)); | ||
582 | break; | ||
583 | case FSF_PSQ_LINK_NO_NPIV_SUPPORT: | ||
584 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
585 | "(no support for NPIV by Fabric)\n", | ||
586 | zfcp_get_busid_by_adapter(adapter)); | ||
587 | break; | ||
588 | case FSF_PSQ_LINK_NO_FCP_RESOURCES: | ||
589 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
590 | "(out of resource in FCP daughtercard)\n", | ||
591 | zfcp_get_busid_by_adapter(adapter)); | ||
592 | break; | ||
593 | case FSF_PSQ_LINK_NO_FABRIC_RESOURCES: | ||
594 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
595 | "(out of resource in Fabric)\n", | ||
596 | zfcp_get_busid_by_adapter(adapter)); | ||
597 | break; | ||
598 | case FSF_PSQ_LINK_FABRIC_LOGIN_UNABLE: | ||
599 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
600 | "(unable to Fabric login)\n", | ||
601 | zfcp_get_busid_by_adapter(adapter)); | ||
602 | break; | ||
603 | case FSF_PSQ_LINK_WWPN_ASSIGNMENT_CORRUPTED: | ||
604 | ZFCP_LOG_NORMAL("WWPN assignment file corrupted on adapter %s\n", | ||
605 | zfcp_get_busid_by_adapter(adapter)); | ||
606 | break; | ||
607 | case FSF_PSQ_LINK_MODE_TABLE_CURRUPTED: | ||
608 | ZFCP_LOG_NORMAL("Mode table corrupted on adapter %s\n", | ||
609 | zfcp_get_busid_by_adapter(adapter)); | ||
610 | break; | ||
611 | case FSF_PSQ_LINK_NO_WWPN_ASSIGNMENT: | ||
612 | ZFCP_LOG_NORMAL("No WWPN for assignment table on adapter %s\n", | ||
613 | zfcp_get_busid_by_adapter(adapter)); | ||
614 | break; | ||
615 | default: | ||
616 | ZFCP_LOG_NORMAL("The local link to adapter %s is down " | ||
617 | "(warning: unknown reason code %d)\n", | ||
618 | zfcp_get_busid_by_adapter(adapter), | ||
619 | link_down->error_code); | ||
620 | } | ||
621 | |||
622 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) | ||
623 | ZFCP_LOG_DEBUG("Debug information to link down: " | ||
624 | "primary_status=0x%02x " | ||
625 | "ioerr_code=0x%02x " | ||
626 | "action_code=0x%02x " | ||
627 | "reason_code=0x%02x " | ||
628 | "explanation_code=0x%02x " | ||
629 | "vendor_specific_code=0x%02x\n", | ||
630 | link_down->primary_status, | ||
631 | link_down->ioerr_code, | ||
632 | link_down->action_code, | ||
633 | link_down->reason_code, | ||
634 | link_down->explanation_code, | ||
635 | link_down->vendor_specific_code); | ||
636 | |||
637 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
638 | &adapter->status)) { | ||
639 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
640 | &adapter->status); | ||
641 | switch (link_down->error_code) { | ||
642 | case FSF_PSQ_LINK_NO_LIGHT: | ||
643 | case FSF_PSQ_LINK_WRAP_PLUG: | ||
644 | case FSF_PSQ_LINK_NO_FCP: | ||
645 | case FSF_PSQ_LINK_FIRMWARE_UPDATE: | ||
646 | zfcp_erp_adapter_reopen(adapter, 0); | ||
647 | break; | ||
648 | default: | ||
649 | zfcp_erp_adapter_failed(adapter); | ||
650 | } | ||
651 | } | ||
652 | } | ||
653 | |||
685 | /* | 654 | /* |
686 | * function: zfcp_fsf_req_dispatch | 655 | * function: zfcp_fsf_req_dispatch |
687 | * | 656 | * |
@@ -696,11 +665,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | |||
696 | struct zfcp_adapter *adapter = fsf_req->adapter; | 665 | struct zfcp_adapter *adapter = fsf_req->adapter; |
697 | int retval = 0; | 666 | int retval = 0; |
698 | 667 | ||
699 | if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | ||
700 | ZFCP_LOG_TRACE("fsf_req=%p, QTCB=%p\n", fsf_req, fsf_req->qtcb); | ||
701 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, | ||
702 | (char *) fsf_req->qtcb, sizeof(struct fsf_qtcb)); | ||
703 | } | ||
704 | 668 | ||
705 | switch (fsf_req->fsf_command) { | 669 | switch (fsf_req->fsf_command) { |
706 | 670 | ||
@@ -760,13 +724,13 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | |||
760 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 724 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
761 | ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " | 725 | ZFCP_LOG_NORMAL("bug: Command issued by the device driver is " |
762 | "not supported by the adapter %s\n", | 726 | "not supported by the adapter %s\n", |
763 | zfcp_get_busid_by_adapter(fsf_req->adapter)); | 727 | zfcp_get_busid_by_adapter(adapter)); |
764 | if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command) | 728 | if (fsf_req->fsf_command != fsf_req->qtcb->header.fsf_command) |
765 | ZFCP_LOG_NORMAL | 729 | ZFCP_LOG_NORMAL |
766 | ("bug: Command issued by the device driver differs " | 730 | ("bug: Command issued by the device driver differs " |
767 | "from the command returned by the adapter %s " | 731 | "from the command returned by the adapter %s " |
768 | "(debug info 0x%x, 0x%x).\n", | 732 | "(debug info 0x%x, 0x%x).\n", |
769 | zfcp_get_busid_by_adapter(fsf_req->adapter), | 733 | zfcp_get_busid_by_adapter(adapter), |
770 | fsf_req->fsf_command, | 734 | fsf_req->fsf_command, |
771 | fsf_req->qtcb->header.fsf_command); | 735 | fsf_req->qtcb->header.fsf_command); |
772 | } | 736 | } |
@@ -774,8 +738,6 @@ zfcp_fsf_req_dispatch(struct zfcp_fsf_req *fsf_req) | |||
774 | if (!erp_action) | 738 | if (!erp_action) |
775 | return retval; | 739 | return retval; |
776 | 740 | ||
777 | debug_text_event(adapter->erp_dbf, 3, "a_frh"); | ||
778 | debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int)); | ||
779 | zfcp_erp_async_handler(erp_action, 0); | 741 | zfcp_erp_async_handler(erp_action, 0); |
780 | 742 | ||
781 | return retval; | 743 | return retval; |
@@ -821,7 +783,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) | |||
821 | goto failed_buf; | 783 | goto failed_buf; |
822 | } | 784 | } |
823 | memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer)); | 785 | memset(status_buffer, 0, sizeof (struct fsf_status_read_buffer)); |
824 | fsf_req->data.status_read.buffer = status_buffer; | 786 | fsf_req->data = (unsigned long) status_buffer; |
825 | 787 | ||
826 | /* insert pointer to respective buffer */ | 788 | /* insert pointer to respective buffer */ |
827 | sbale = zfcp_qdio_sbale_curr(fsf_req); | 789 | sbale = zfcp_qdio_sbale_curr(fsf_req); |
@@ -846,6 +808,7 @@ zfcp_fsf_status_read(struct zfcp_adapter *adapter, int req_flags) | |||
846 | failed_buf: | 808 | failed_buf: |
847 | zfcp_fsf_req_free(fsf_req); | 809 | zfcp_fsf_req_free(fsf_req); |
848 | failed_req_create: | 810 | failed_req_create: |
811 | zfcp_hba_dbf_event_fsf_unsol("fail", adapter, NULL); | ||
849 | out: | 812 | out: |
850 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); | 813 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, lock_flags); |
851 | return retval; | 814 | return retval; |
@@ -859,7 +822,7 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req) | |||
859 | struct zfcp_port *port; | 822 | struct zfcp_port *port; |
860 | unsigned long flags; | 823 | unsigned long flags; |
861 | 824 | ||
862 | status_buffer = fsf_req->data.status_read.buffer; | 825 | status_buffer = (struct fsf_status_read_buffer *) fsf_req->data; |
863 | adapter = fsf_req->adapter; | 826 | adapter = fsf_req->adapter; |
864 | 827 | ||
865 | read_lock_irqsave(&zfcp_data.config_lock, flags); | 828 | read_lock_irqsave(&zfcp_data.config_lock, flags); |
@@ -918,38 +881,33 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
918 | int retval = 0; | 881 | int retval = 0; |
919 | struct zfcp_adapter *adapter = fsf_req->adapter; | 882 | struct zfcp_adapter *adapter = fsf_req->adapter; |
920 | struct fsf_status_read_buffer *status_buffer = | 883 | struct fsf_status_read_buffer *status_buffer = |
921 | fsf_req->data.status_read.buffer; | 884 | (struct fsf_status_read_buffer *) fsf_req->data; |
922 | 885 | ||
923 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { | 886 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_DISMISSED) { |
887 | zfcp_hba_dbf_event_fsf_unsol("dism", adapter, status_buffer); | ||
924 | mempool_free(status_buffer, adapter->pool.data_status_read); | 888 | mempool_free(status_buffer, adapter->pool.data_status_read); |
925 | zfcp_fsf_req_free(fsf_req); | 889 | zfcp_fsf_req_free(fsf_req); |
926 | goto out; | 890 | goto out; |
927 | } | 891 | } |
928 | 892 | ||
893 | zfcp_hba_dbf_event_fsf_unsol("read", adapter, status_buffer); | ||
894 | |||
929 | switch (status_buffer->status_type) { | 895 | switch (status_buffer->status_type) { |
930 | 896 | ||
931 | case FSF_STATUS_READ_PORT_CLOSED: | 897 | case FSF_STATUS_READ_PORT_CLOSED: |
932 | debug_text_event(adapter->erp_dbf, 3, "unsol_pclosed:"); | ||
933 | debug_event(adapter->erp_dbf, 3, | ||
934 | &status_buffer->d_id, sizeof (u32)); | ||
935 | zfcp_fsf_status_read_port_closed(fsf_req); | 898 | zfcp_fsf_status_read_port_closed(fsf_req); |
936 | break; | 899 | break; |
937 | 900 | ||
938 | case FSF_STATUS_READ_INCOMING_ELS: | 901 | case FSF_STATUS_READ_INCOMING_ELS: |
939 | debug_text_event(adapter->erp_dbf, 3, "unsol_els:"); | ||
940 | zfcp_fsf_incoming_els(fsf_req); | 902 | zfcp_fsf_incoming_els(fsf_req); |
941 | break; | 903 | break; |
942 | 904 | ||
943 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: | 905 | case FSF_STATUS_READ_SENSE_DATA_AVAIL: |
944 | debug_text_event(adapter->erp_dbf, 3, "unsol_sense:"); | ||
945 | ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n", | 906 | ZFCP_LOG_INFO("unsolicited sense data received (adapter %s)\n", |
946 | zfcp_get_busid_by_adapter(adapter)); | 907 | zfcp_get_busid_by_adapter(adapter)); |
947 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, (char *) status_buffer, | ||
948 | sizeof(struct fsf_status_read_buffer)); | ||
949 | break; | 908 | break; |
950 | 909 | ||
951 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: | 910 | case FSF_STATUS_READ_BIT_ERROR_THRESHOLD: |
952 | debug_text_event(adapter->erp_dbf, 3, "unsol_bit_err:"); | ||
953 | ZFCP_LOG_NORMAL("Bit error threshold data received:\n"); | 911 | ZFCP_LOG_NORMAL("Bit error threshold data received:\n"); |
954 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, | 912 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL, |
955 | (char *) status_buffer, | 913 | (char *) status_buffer, |
@@ -957,17 +915,32 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
957 | break; | 915 | break; |
958 | 916 | ||
959 | case FSF_STATUS_READ_LINK_DOWN: | 917 | case FSF_STATUS_READ_LINK_DOWN: |
960 | debug_text_event(adapter->erp_dbf, 0, "unsol_link_down:"); | 918 | switch (status_buffer->status_subtype) { |
961 | ZFCP_LOG_INFO("Local link to adapter %s is down\n", | 919 | case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK: |
920 | ZFCP_LOG_INFO("Physical link to adapter %s is down\n", | ||
921 | zfcp_get_busid_by_adapter(adapter)); | ||
922 | break; | ||
923 | case FSF_STATUS_READ_SUB_FDISC_FAILED: | ||
924 | ZFCP_LOG_INFO("Local link to adapter %s is down " | ||
925 | "due to failed FDISC login\n", | ||
962 | zfcp_get_busid_by_adapter(adapter)); | 926 | zfcp_get_busid_by_adapter(adapter)); |
963 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 927 | break; |
964 | &adapter->status); | 928 | case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: |
965 | zfcp_erp_adapter_failed(adapter); | 929 | ZFCP_LOG_INFO("Local link to adapter %s is down " |
930 | "due to firmware update on adapter\n", | ||
931 | zfcp_get_busid_by_adapter(adapter)); | ||
932 | break; | ||
933 | default: | ||
934 | ZFCP_LOG_INFO("Local link to adapter %s is down " | ||
935 | "due to unknown reason\n", | ||
936 | zfcp_get_busid_by_adapter(adapter)); | ||
937 | }; | ||
938 | zfcp_fsf_link_down_info_eval(adapter, | ||
939 | (struct fsf_link_down_info *) &status_buffer->payload); | ||
966 | break; | 940 | break; |
967 | 941 | ||
968 | case FSF_STATUS_READ_LINK_UP: | 942 | case FSF_STATUS_READ_LINK_UP: |
969 | debug_text_event(adapter->erp_dbf, 2, "unsol_link_up:"); | 943 | ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. " |
970 | ZFCP_LOG_INFO("Local link to adapter %s was replugged. " | ||
971 | "Restarting operations on this adapter\n", | 944 | "Restarting operations on this adapter\n", |
972 | zfcp_get_busid_by_adapter(adapter)); | 945 | zfcp_get_busid_by_adapter(adapter)); |
973 | /* All ports should be marked as ready to run again */ | 946 | /* All ports should be marked as ready to run again */ |
@@ -980,35 +953,40 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
980 | break; | 953 | break; |
981 | 954 | ||
982 | case FSF_STATUS_READ_CFDC_UPDATED: | 955 | case FSF_STATUS_READ_CFDC_UPDATED: |
983 | debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_update:"); | 956 | ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n", |
984 | ZFCP_LOG_INFO("CFDC has been updated on the adapter %s\n", | ||
985 | zfcp_get_busid_by_adapter(adapter)); | 957 | zfcp_get_busid_by_adapter(adapter)); |
986 | zfcp_erp_adapter_access_changed(adapter); | 958 | zfcp_erp_adapter_access_changed(adapter); |
987 | break; | 959 | break; |
988 | 960 | ||
989 | case FSF_STATUS_READ_CFDC_HARDENED: | 961 | case FSF_STATUS_READ_CFDC_HARDENED: |
990 | debug_text_event(adapter->erp_dbf, 2, "unsol_cfdc_harden:"); | ||
991 | switch (status_buffer->status_subtype) { | 962 | switch (status_buffer->status_subtype) { |
992 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE: | 963 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE: |
993 | ZFCP_LOG_INFO("CFDC of adapter %s saved on SE\n", | 964 | ZFCP_LOG_NORMAL("CFDC of adapter %s saved on SE\n", |
994 | zfcp_get_busid_by_adapter(adapter)); | 965 | zfcp_get_busid_by_adapter(adapter)); |
995 | break; | 966 | break; |
996 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2: | 967 | case FSF_STATUS_READ_SUB_CFDC_HARDENED_ON_SE2: |
997 | ZFCP_LOG_INFO("CFDC of adapter %s has been copied " | 968 | ZFCP_LOG_NORMAL("CFDC of adapter %s has been copied " |
998 | "to the secondary SE\n", | 969 | "to the secondary SE\n", |
999 | zfcp_get_busid_by_adapter(adapter)); | 970 | zfcp_get_busid_by_adapter(adapter)); |
1000 | break; | 971 | break; |
1001 | default: | 972 | default: |
1002 | ZFCP_LOG_INFO("CFDC of adapter %s has been hardened\n", | 973 | ZFCP_LOG_NORMAL("CFDC of adapter %s has been hardened\n", |
1003 | zfcp_get_busid_by_adapter(adapter)); | 974 | zfcp_get_busid_by_adapter(adapter)); |
1004 | } | 975 | } |
1005 | break; | 976 | break; |
1006 | 977 | ||
978 | case FSF_STATUS_READ_FEATURE_UPDATE_ALERT: | ||
979 | debug_text_event(adapter->erp_dbf, 2, "unsol_features:"); | ||
980 | ZFCP_LOG_INFO("List of supported features on adapter %s has " | ||
981 | "been changed from 0x%08X to 0x%08X\n", | ||
982 | zfcp_get_busid_by_adapter(adapter), | ||
983 | *(u32*) (status_buffer->payload + 4), | ||
984 | *(u32*) (status_buffer->payload)); | ||
985 | adapter->adapter_features = *(u32*) status_buffer->payload; | ||
986 | break; | ||
987 | |||
1007 | default: | 988 | default: |
1008 | debug_text_event(adapter->erp_dbf, 0, "unsol_unknown:"); | 989 | ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown " |
1009 | debug_exception(adapter->erp_dbf, 0, | ||
1010 | &status_buffer->status_type, sizeof (u32)); | ||
1011 | ZFCP_LOG_NORMAL("bug: An unsolicited status packet of unknown " | ||
1012 | "type was received (debug info 0x%x)\n", | 990 | "type was received (debug info 0x%x)\n", |
1013 | status_buffer->status_type); | 991 | status_buffer->status_type); |
1014 | ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n", | 992 | ZFCP_LOG_DEBUG("Dump of status_read_buffer %p:\n", |
@@ -1093,7 +1071,7 @@ zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
1093 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | 1071 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; |
1094 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 1072 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
1095 | 1073 | ||
1096 | fsf_req->data.abort_fcp_command.unit = unit; | 1074 | fsf_req->data = (unsigned long) unit; |
1097 | 1075 | ||
1098 | /* set handles of unit and its parent port in QTCB */ | 1076 | /* set handles of unit and its parent port in QTCB */ |
1099 | fsf_req->qtcb->header.lun_handle = unit->handle; | 1077 | fsf_req->qtcb->header.lun_handle = unit->handle; |
@@ -1139,7 +1117,7 @@ static int | |||
1139 | zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | 1117 | zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) |
1140 | { | 1118 | { |
1141 | int retval = -EINVAL; | 1119 | int retval = -EINVAL; |
1142 | struct zfcp_unit *unit = new_fsf_req->data.abort_fcp_command.unit; | 1120 | struct zfcp_unit *unit; |
1143 | unsigned char status_qual = | 1121 | unsigned char status_qual = |
1144 | new_fsf_req->qtcb->header.fsf_status_qual.word[0]; | 1122 | new_fsf_req->qtcb->header.fsf_status_qual.word[0]; |
1145 | 1123 | ||
@@ -1150,6 +1128,8 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req) | |||
1150 | goto skip_fsfstatus; | 1128 | goto skip_fsfstatus; |
1151 | } | 1129 | } |
1152 | 1130 | ||
1131 | unit = (struct zfcp_unit *) new_fsf_req->data; | ||
1132 | |||
1153 | /* evaluate FSF status in QTCB */ | 1133 | /* evaluate FSF status in QTCB */ |
1154 | switch (new_fsf_req->qtcb->header.fsf_status) { | 1134 | switch (new_fsf_req->qtcb->header.fsf_status) { |
1155 | 1135 | ||
@@ -1364,7 +1344,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
1364 | sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]); | 1344 | sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]); |
1365 | sbale[3].length = ct->resp[0].length; | 1345 | sbale[3].length = ct->resp[0].length; |
1366 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; | 1346 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; |
1367 | } else if (adapter->supported_features & | 1347 | } else if (adapter->adapter_features & |
1368 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { | 1348 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { |
1369 | /* try to use chained SBALs */ | 1349 | /* try to use chained SBALs */ |
1370 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, | 1350 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, |
@@ -1414,7 +1394,9 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
1414 | fsf_req->qtcb->header.port_handle = port->handle; | 1394 | fsf_req->qtcb->header.port_handle = port->handle; |
1415 | fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class; | 1395 | fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class; |
1416 | fsf_req->qtcb->bottom.support.timeout = ct->timeout; | 1396 | fsf_req->qtcb->bottom.support.timeout = ct->timeout; |
1417 | fsf_req->data.send_ct = ct; | 1397 | fsf_req->data = (unsigned long) ct; |
1398 | |||
1399 | zfcp_san_dbf_event_ct_request(fsf_req); | ||
1418 | 1400 | ||
1419 | /* start QDIO request for this FSF request */ | 1401 | /* start QDIO request for this FSF request */ |
1420 | ret = zfcp_fsf_req_send(fsf_req, ct->timer); | 1402 | ret = zfcp_fsf_req_send(fsf_req, ct->timer); |
@@ -1445,10 +1427,10 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
1445 | * zfcp_fsf_send_ct_handler - handler for Generic Service requests | 1427 | * zfcp_fsf_send_ct_handler - handler for Generic Service requests |
1446 | * @fsf_req: pointer to struct zfcp_fsf_req | 1428 | * @fsf_req: pointer to struct zfcp_fsf_req |
1447 | * | 1429 | * |
1448 | * Data specific for the Generic Service request is passed by | 1430 | * Data specific for the Generic Service request is passed using |
1449 | * fsf_req->data.send_ct | 1431 | * fsf_req->data. There we find the pointer to struct zfcp_send_ct. |
1450 | * Usually a specific handler for the request is called via | 1432 | * Usually a specific handler for the CT request is called which is |
1451 | * fsf_req->data.send_ct->handler at end of this function. | 1433 | * found in this structure. |
1452 | */ | 1434 | */ |
1453 | static int | 1435 | static int |
1454 | zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | 1436 | zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) |
@@ -1462,7 +1444,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1462 | u16 subtable, rule, counter; | 1444 | u16 subtable, rule, counter; |
1463 | 1445 | ||
1464 | adapter = fsf_req->adapter; | 1446 | adapter = fsf_req->adapter; |
1465 | send_ct = fsf_req->data.send_ct; | 1447 | send_ct = (struct zfcp_send_ct *) fsf_req->data; |
1466 | port = send_ct->port; | 1448 | port = send_ct->port; |
1467 | header = &fsf_req->qtcb->header; | 1449 | header = &fsf_req->qtcb->header; |
1468 | bottom = &fsf_req->qtcb->bottom.support; | 1450 | bottom = &fsf_req->qtcb->bottom.support; |
@@ -1474,6 +1456,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req) | |||
1474 | switch (header->fsf_status) { | 1456 | switch (header->fsf_status) { |
1475 | 1457 | ||
1476 | case FSF_GOOD: | 1458 | case FSF_GOOD: |
1459 | zfcp_san_dbf_event_ct_response(fsf_req); | ||
1477 | retval = 0; | 1460 | retval = 0; |
1478 | break; | 1461 | break; |
1479 | 1462 | ||
@@ -1634,7 +1617,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1634 | { | 1617 | { |
1635 | volatile struct qdio_buffer_element *sbale; | 1618 | volatile struct qdio_buffer_element *sbale; |
1636 | struct zfcp_fsf_req *fsf_req; | 1619 | struct zfcp_fsf_req *fsf_req; |
1637 | fc_id_t d_id; | 1620 | u32 d_id; |
1638 | struct zfcp_adapter *adapter; | 1621 | struct zfcp_adapter *adapter; |
1639 | unsigned long lock_flags; | 1622 | unsigned long lock_flags; |
1640 | int bytes; | 1623 | int bytes; |
@@ -1664,7 +1647,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1664 | sbale[3].addr = zfcp_sg_to_address(&els->resp[0]); | 1647 | sbale[3].addr = zfcp_sg_to_address(&els->resp[0]); |
1665 | sbale[3].length = els->resp[0].length; | 1648 | sbale[3].length = els->resp[0].length; |
1666 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; | 1649 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; |
1667 | } else if (adapter->supported_features & | 1650 | } else if (adapter->adapter_features & |
1668 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { | 1651 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { |
1669 | /* try to use chained SBALs */ | 1652 | /* try to use chained SBALs */ |
1670 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, | 1653 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, |
@@ -1714,10 +1697,12 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1714 | fsf_req->qtcb->bottom.support.d_id = d_id; | 1697 | fsf_req->qtcb->bottom.support.d_id = d_id; |
1715 | fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class; | 1698 | fsf_req->qtcb->bottom.support.service_class = adapter->fc_service_class; |
1716 | fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT; | 1699 | fsf_req->qtcb->bottom.support.timeout = ZFCP_ELS_TIMEOUT; |
1717 | fsf_req->data.send_els = els; | 1700 | fsf_req->data = (unsigned long) els; |
1718 | 1701 | ||
1719 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | 1702 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); |
1720 | 1703 | ||
1704 | zfcp_san_dbf_event_els_request(fsf_req); | ||
1705 | |||
1721 | /* start QDIO request for this FSF request */ | 1706 | /* start QDIO request for this FSF request */ |
1722 | ret = zfcp_fsf_req_send(fsf_req, els->timer); | 1707 | ret = zfcp_fsf_req_send(fsf_req, els->timer); |
1723 | if (ret) { | 1708 | if (ret) { |
@@ -1746,23 +1731,23 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1746 | * zfcp_fsf_send_els_handler - handler for ELS commands | 1731 | * zfcp_fsf_send_els_handler - handler for ELS commands |
1747 | * @fsf_req: pointer to struct zfcp_fsf_req | 1732 | * @fsf_req: pointer to struct zfcp_fsf_req |
1748 | * | 1733 | * |
1749 | * Data specific for the ELS command is passed by | 1734 | * Data specific for the ELS command is passed using |
1750 | * fsf_req->data.send_els | 1735 | * fsf_req->data. There we find the pointer to struct zfcp_send_els. |
1751 | * Usually a specific handler for the command is called via | 1736 | * Usually a specific handler for the ELS command is called which is |
1752 | * fsf_req->data.send_els->handler at end of this function. | 1737 | * found in this structure. |
1753 | */ | 1738 | */ |
1754 | static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | 1739 | static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) |
1755 | { | 1740 | { |
1756 | struct zfcp_adapter *adapter; | 1741 | struct zfcp_adapter *adapter; |
1757 | struct zfcp_port *port; | 1742 | struct zfcp_port *port; |
1758 | fc_id_t d_id; | 1743 | u32 d_id; |
1759 | struct fsf_qtcb_header *header; | 1744 | struct fsf_qtcb_header *header; |
1760 | struct fsf_qtcb_bottom_support *bottom; | 1745 | struct fsf_qtcb_bottom_support *bottom; |
1761 | struct zfcp_send_els *send_els; | 1746 | struct zfcp_send_els *send_els; |
1762 | int retval = -EINVAL; | 1747 | int retval = -EINVAL; |
1763 | u16 subtable, rule, counter; | 1748 | u16 subtable, rule, counter; |
1764 | 1749 | ||
1765 | send_els = fsf_req->data.send_els; | 1750 | send_els = (struct zfcp_send_els *) fsf_req->data; |
1766 | adapter = send_els->adapter; | 1751 | adapter = send_els->adapter; |
1767 | port = send_els->port; | 1752 | port = send_els->port; |
1768 | d_id = send_els->d_id; | 1753 | d_id = send_els->d_id; |
@@ -1775,6 +1760,7 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req) | |||
1775 | switch (header->fsf_status) { | 1760 | switch (header->fsf_status) { |
1776 | 1761 | ||
1777 | case FSF_GOOD: | 1762 | case FSF_GOOD: |
1763 | zfcp_san_dbf_event_els_response(fsf_req); | ||
1778 | retval = 0; | 1764 | retval = 0; |
1779 | break; | 1765 | break; |
1780 | 1766 | ||
@@ -1954,7 +1940,9 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1954 | 1940 | ||
1955 | erp_action->fsf_req->erp_action = erp_action; | 1941 | erp_action->fsf_req->erp_action = erp_action; |
1956 | erp_action->fsf_req->qtcb->bottom.config.feature_selection = | 1942 | erp_action->fsf_req->qtcb->bottom.config.feature_selection = |
1957 | (FSF_FEATURE_CFDC | FSF_FEATURE_LUN_SHARING); | 1943 | FSF_FEATURE_CFDC | |
1944 | FSF_FEATURE_LUN_SHARING | | ||
1945 | FSF_FEATURE_UPDATE_ALERT; | ||
1958 | 1946 | ||
1959 | /* start QDIO request for this FSF request */ | 1947 | /* start QDIO request for this FSF request */ |
1960 | retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer); | 1948 | retval = zfcp_fsf_req_send(erp_action->fsf_req, &erp_action->timer); |
@@ -1990,29 +1978,36 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
1990 | { | 1978 | { |
1991 | struct fsf_qtcb_bottom_config *bottom; | 1979 | struct fsf_qtcb_bottom_config *bottom; |
1992 | struct zfcp_adapter *adapter = fsf_req->adapter; | 1980 | struct zfcp_adapter *adapter = fsf_req->adapter; |
1981 | struct Scsi_Host *shost = adapter->scsi_host; | ||
1993 | 1982 | ||
1994 | bottom = &fsf_req->qtcb->bottom.config; | 1983 | bottom = &fsf_req->qtcb->bottom.config; |
1995 | ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n", | 1984 | ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n", |
1996 | bottom->low_qtcb_version, bottom->high_qtcb_version); | 1985 | bottom->low_qtcb_version, bottom->high_qtcb_version); |
1997 | adapter->fsf_lic_version = bottom->lic_version; | 1986 | adapter->fsf_lic_version = bottom->lic_version; |
1998 | adapter->supported_features = bottom->supported_features; | 1987 | adapter->adapter_features = bottom->adapter_features; |
1988 | adapter->connection_features = bottom->connection_features; | ||
1999 | adapter->peer_wwpn = 0; | 1989 | adapter->peer_wwpn = 0; |
2000 | adapter->peer_wwnn = 0; | 1990 | adapter->peer_wwnn = 0; |
2001 | adapter->peer_d_id = 0; | 1991 | adapter->peer_d_id = 0; |
2002 | 1992 | ||
2003 | if (xchg_ok) { | 1993 | if (xchg_ok) { |
2004 | adapter->wwnn = bottom->nport_serv_param.wwnn; | 1994 | fc_host_node_name(shost) = bottom->nport_serv_param.wwnn; |
2005 | adapter->wwpn = bottom->nport_serv_param.wwpn; | 1995 | fc_host_port_name(shost) = bottom->nport_serv_param.wwpn; |
2006 | adapter->s_id = bottom->s_id & ZFCP_DID_MASK; | 1996 | fc_host_port_id(shost) = bottom->s_id & ZFCP_DID_MASK; |
1997 | fc_host_speed(shost) = bottom->fc_link_speed; | ||
1998 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; | ||
2007 | adapter->fc_topology = bottom->fc_topology; | 1999 | adapter->fc_topology = bottom->fc_topology; |
2008 | adapter->fc_link_speed = bottom->fc_link_speed; | ||
2009 | adapter->hydra_version = bottom->adapter_type; | 2000 | adapter->hydra_version = bottom->adapter_type; |
2001 | if (adapter->physical_wwpn == 0) | ||
2002 | adapter->physical_wwpn = fc_host_port_name(shost); | ||
2003 | if (adapter->physical_s_id == 0) | ||
2004 | adapter->physical_s_id = fc_host_port_id(shost); | ||
2010 | } else { | 2005 | } else { |
2011 | adapter->wwnn = 0; | 2006 | fc_host_node_name(shost) = 0; |
2012 | adapter->wwpn = 0; | 2007 | fc_host_port_name(shost) = 0; |
2013 | adapter->s_id = 0; | 2008 | fc_host_port_id(shost) = 0; |
2009 | fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; | ||
2014 | adapter->fc_topology = 0; | 2010 | adapter->fc_topology = 0; |
2015 | adapter->fc_link_speed = 0; | ||
2016 | adapter->hydra_version = 0; | 2011 | adapter->hydra_version = 0; |
2017 | } | 2012 | } |
2018 | 2013 | ||
@@ -2022,26 +2017,28 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2022 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; | 2017 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; |
2023 | } | 2018 | } |
2024 | 2019 | ||
2025 | if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){ | 2020 | if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { |
2026 | adapter->hardware_version = bottom->hardware_version; | 2021 | adapter->hardware_version = bottom->hardware_version; |
2027 | memcpy(adapter->serial_number, bottom->serial_number, 17); | 2022 | memcpy(fc_host_serial_number(shost), bottom->serial_number, |
2028 | EBCASC(adapter->serial_number, sizeof(adapter->serial_number)); | 2023 | min(FC_SERIAL_NUMBER_SIZE, 17)); |
2024 | EBCASC(fc_host_serial_number(shost), | ||
2025 | min(FC_SERIAL_NUMBER_SIZE, 17)); | ||
2029 | } | 2026 | } |
2030 | 2027 | ||
2031 | ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" | 2028 | ZFCP_LOG_NORMAL("The adapter %s reported the following characteristics:\n" |
2032 | "WWNN 0x%016Lx, " | 2029 | "WWNN 0x%016Lx, " |
2033 | "WWPN 0x%016Lx, " | 2030 | "WWPN 0x%016Lx, " |
2034 | "S_ID 0x%08x,\n" | 2031 | "S_ID 0x%08x,\n" |
2035 | "adapter version 0x%x, " | 2032 | "adapter version 0x%x, " |
2036 | "LIC version 0x%x, " | 2033 | "LIC version 0x%x, " |
2037 | "FC link speed %d Gb/s\n", | 2034 | "FC link speed %d Gb/s\n", |
2038 | zfcp_get_busid_by_adapter(adapter), | 2035 | zfcp_get_busid_by_adapter(adapter), |
2039 | adapter->wwnn, | 2036 | (wwn_t) fc_host_node_name(shost), |
2040 | adapter->wwpn, | 2037 | (wwn_t) fc_host_port_name(shost), |
2041 | (unsigned int) adapter->s_id, | 2038 | fc_host_port_id(shost), |
2042 | adapter->hydra_version, | 2039 | adapter->hydra_version, |
2043 | adapter->fsf_lic_version, | 2040 | adapter->fsf_lic_version, |
2044 | adapter->fc_link_speed); | 2041 | fc_host_speed(shost)); |
2045 | if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) { | 2042 | if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) { |
2046 | ZFCP_LOG_NORMAL("error: the adapter %s " | 2043 | ZFCP_LOG_NORMAL("error: the adapter %s " |
2047 | "only supports newer control block " | 2044 | "only supports newer control block " |
@@ -2062,7 +2059,6 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2062 | zfcp_erp_adapter_shutdown(adapter, 0); | 2059 | zfcp_erp_adapter_shutdown(adapter, 0); |
2063 | return -EIO; | 2060 | return -EIO; |
2064 | } | 2061 | } |
2065 | zfcp_set_fc_host_attrs(adapter); | ||
2066 | return 0; | 2062 | return 0; |
2067 | } | 2063 | } |
2068 | 2064 | ||
@@ -2078,11 +2074,12 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2078 | { | 2074 | { |
2079 | struct fsf_qtcb_bottom_config *bottom; | 2075 | struct fsf_qtcb_bottom_config *bottom; |
2080 | struct zfcp_adapter *adapter = fsf_req->adapter; | 2076 | struct zfcp_adapter *adapter = fsf_req->adapter; |
2077 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | ||
2081 | 2078 | ||
2082 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2079 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2083 | return -EIO; | 2080 | return -EIO; |
2084 | 2081 | ||
2085 | switch (fsf_req->qtcb->header.fsf_status) { | 2082 | switch (qtcb->header.fsf_status) { |
2086 | 2083 | ||
2087 | case FSF_GOOD: | 2084 | case FSF_GOOD: |
2088 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) | 2085 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) |
@@ -2112,7 +2109,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2112 | zfcp_erp_adapter_shutdown(adapter, 0); | 2109 | zfcp_erp_adapter_shutdown(adapter, 0); |
2113 | return -EIO; | 2110 | return -EIO; |
2114 | case FSF_TOPO_FABRIC: | 2111 | case FSF_TOPO_FABRIC: |
2115 | ZFCP_LOG_INFO("Switched fabric fibrechannel " | 2112 | ZFCP_LOG_NORMAL("Switched fabric fibrechannel " |
2116 | "network detected at adapter %s.\n", | 2113 | "network detected at adapter %s.\n", |
2117 | zfcp_get_busid_by_adapter(adapter)); | 2114 | zfcp_get_busid_by_adapter(adapter)); |
2118 | break; | 2115 | break; |
@@ -2130,7 +2127,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2130 | zfcp_erp_adapter_shutdown(adapter, 0); | 2127 | zfcp_erp_adapter_shutdown(adapter, 0); |
2131 | return -EIO; | 2128 | return -EIO; |
2132 | } | 2129 | } |
2133 | bottom = &fsf_req->qtcb->bottom.config; | 2130 | bottom = &qtcb->bottom.config; |
2134 | if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { | 2131 | if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { |
2135 | ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) " | 2132 | ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) " |
2136 | "allowed by the adapter %s " | 2133 | "allowed by the adapter %s " |
@@ -2155,12 +2152,10 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2155 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) | 2152 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) |
2156 | return -EIO; | 2153 | return -EIO; |
2157 | 2154 | ||
2158 | ZFCP_LOG_INFO("Local link to adapter %s is down\n", | 2155 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); |
2159 | zfcp_get_busid_by_adapter(adapter)); | 2156 | |
2160 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | | 2157 | zfcp_fsf_link_down_info_eval(adapter, |
2161 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2158 | &qtcb->header.fsf_status_qual.link_down_info); |
2162 | &adapter->status); | ||
2163 | zfcp_erp_adapter_failed(adapter); | ||
2164 | break; | 2159 | break; |
2165 | default: | 2160 | default: |
2166 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); | 2161 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); |
@@ -2174,11 +2169,13 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2174 | 2169 | ||
2175 | /** | 2170 | /** |
2176 | * zfcp_fsf_exchange_port_data - request information about local port | 2171 | * zfcp_fsf_exchange_port_data - request information about local port |
2172 | * @erp_action: ERP action for the adapter for which port data is requested | ||
2177 | * @adapter: for which port data is requested | 2173 | * @adapter: for which port data is requested |
2178 | * @data: response to exchange port data request | 2174 | * @data: response to exchange port data request |
2179 | */ | 2175 | */ |
2180 | int | 2176 | int |
2181 | zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | 2177 | zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, |
2178 | struct zfcp_adapter *adapter, | ||
2182 | struct fsf_qtcb_bottom_port *data) | 2179 | struct fsf_qtcb_bottom_port *data) |
2183 | { | 2180 | { |
2184 | volatile struct qdio_buffer_element *sbale; | 2181 | volatile struct qdio_buffer_element *sbale; |
@@ -2187,7 +2184,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2187 | struct zfcp_fsf_req *fsf_req; | 2184 | struct zfcp_fsf_req *fsf_req; |
2188 | struct timer_list *timer; | 2185 | struct timer_list *timer; |
2189 | 2186 | ||
2190 | if(!(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT)){ | 2187 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { |
2191 | ZFCP_LOG_INFO("error: exchange port data " | 2188 | ZFCP_LOG_INFO("error: exchange port data " |
2192 | "command not supported by adapter %s\n", | 2189 | "command not supported by adapter %s\n", |
2193 | zfcp_get_busid_by_adapter(adapter)); | 2190 | zfcp_get_busid_by_adapter(adapter)); |
@@ -2211,12 +2208,18 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2211 | goto out; | 2208 | goto out; |
2212 | } | 2209 | } |
2213 | 2210 | ||
2211 | if (erp_action) { | ||
2212 | erp_action->fsf_req = fsf_req; | ||
2213 | fsf_req->erp_action = erp_action; | ||
2214 | } | ||
2215 | |||
2216 | if (data) | ||
2217 | fsf_req->data = (unsigned long) data; | ||
2218 | |||
2214 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | 2219 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); |
2215 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; | 2220 | sbale[0].flags |= SBAL_FLAGS0_TYPE_READ; |
2216 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 2221 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
2217 | 2222 | ||
2218 | fsf_req->data.port_data = data; | ||
2219 | |||
2220 | init_timer(timer); | 2223 | init_timer(timer); |
2221 | timer->function = zfcp_fsf_request_timeout_handler; | 2224 | timer->function = zfcp_fsf_request_timeout_handler; |
2222 | timer->data = (unsigned long) adapter; | 2225 | timer->data = (unsigned long) adapter; |
@@ -2228,6 +2231,8 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2228 | "command on the adapter %s\n", | 2231 | "command on the adapter %s\n", |
2229 | zfcp_get_busid_by_adapter(adapter)); | 2232 | zfcp_get_busid_by_adapter(adapter)); |
2230 | zfcp_fsf_req_free(fsf_req); | 2233 | zfcp_fsf_req_free(fsf_req); |
2234 | if (erp_action) | ||
2235 | erp_action->fsf_req = NULL; | ||
2231 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | 2236 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
2232 | lock_flags); | 2237 | lock_flags); |
2233 | goto out; | 2238 | goto out; |
@@ -2256,21 +2261,42 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2256 | static void | 2261 | static void |
2257 | zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) | 2262 | zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) |
2258 | { | 2263 | { |
2259 | struct fsf_qtcb_bottom_port *bottom; | 2264 | struct zfcp_adapter *adapter = fsf_req->adapter; |
2260 | struct fsf_qtcb_bottom_port *data = fsf_req->data.port_data; | 2265 | struct Scsi_Host *shost = adapter->scsi_host; |
2266 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | ||
2267 | struct fsf_qtcb_bottom_port *bottom, *data; | ||
2261 | 2268 | ||
2262 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2269 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2263 | return; | 2270 | return; |
2264 | 2271 | ||
2265 | switch (fsf_req->qtcb->header.fsf_status) { | 2272 | switch (qtcb->header.fsf_status) { |
2266 | case FSF_GOOD: | 2273 | case FSF_GOOD: |
2267 | bottom = &fsf_req->qtcb->bottom.port; | 2274 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2268 | memcpy(data, bottom, sizeof(*data)); | 2275 | |
2276 | bottom = &qtcb->bottom.port; | ||
2277 | data = (struct fsf_qtcb_bottom_port*) fsf_req->data; | ||
2278 | if (data) | ||
2279 | memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); | ||
2280 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) { | ||
2281 | adapter->physical_wwpn = bottom->wwpn; | ||
2282 | adapter->physical_s_id = bottom->fc_port_id; | ||
2283 | } else { | ||
2284 | adapter->physical_wwpn = fc_host_port_name(shost); | ||
2285 | adapter->physical_s_id = fc_host_port_id(shost); | ||
2286 | } | ||
2287 | fc_host_maxframe_size(shost) = bottom->maximum_frame_size; | ||
2288 | break; | ||
2289 | |||
2290 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: | ||
2291 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | ||
2292 | |||
2293 | zfcp_fsf_link_down_info_eval(adapter, | ||
2294 | &qtcb->header.fsf_status_qual.link_down_info); | ||
2269 | break; | 2295 | break; |
2270 | 2296 | ||
2271 | default: | 2297 | default: |
2272 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "xchg-port-ng"); | 2298 | debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng"); |
2273 | debug_event(fsf_req->adapter->erp_dbf, 0, | 2299 | debug_event(adapter->erp_dbf, 0, |
2274 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); | 2300 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); |
2275 | } | 2301 | } |
2276 | } | 2302 | } |
@@ -2312,7 +2338,7 @@ zfcp_fsf_open_port(struct zfcp_erp_action *erp_action) | |||
2312 | 2338 | ||
2313 | erp_action->fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id; | 2339 | erp_action->fsf_req->qtcb->bottom.support.d_id = erp_action->port->d_id; |
2314 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status); | 2340 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->port->status); |
2315 | erp_action->fsf_req->data.open_port.port = erp_action->port; | 2341 | erp_action->fsf_req->data = (unsigned long) erp_action->port; |
2316 | erp_action->fsf_req->erp_action = erp_action; | 2342 | erp_action->fsf_req->erp_action = erp_action; |
2317 | 2343 | ||
2318 | /* start QDIO request for this FSF request */ | 2344 | /* start QDIO request for this FSF request */ |
@@ -2353,7 +2379,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2353 | struct fsf_qtcb_header *header; | 2379 | struct fsf_qtcb_header *header; |
2354 | u16 subtable, rule, counter; | 2380 | u16 subtable, rule, counter; |
2355 | 2381 | ||
2356 | port = fsf_req->data.open_port.port; | 2382 | port = (struct zfcp_port *) fsf_req->data; |
2357 | header = &fsf_req->qtcb->header; | 2383 | header = &fsf_req->qtcb->header; |
2358 | 2384 | ||
2359 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 2385 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
@@ -2566,7 +2592,7 @@ zfcp_fsf_close_port(struct zfcp_erp_action *erp_action) | |||
2566 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; | 2592 | sbale[1].flags |= SBAL_FLAGS_LAST_ENTRY; |
2567 | 2593 | ||
2568 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status); | 2594 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->port->status); |
2569 | erp_action->fsf_req->data.close_port.port = erp_action->port; | 2595 | erp_action->fsf_req->data = (unsigned long) erp_action->port; |
2570 | erp_action->fsf_req->erp_action = erp_action; | 2596 | erp_action->fsf_req->erp_action = erp_action; |
2571 | erp_action->fsf_req->qtcb->header.port_handle = | 2597 | erp_action->fsf_req->qtcb->header.port_handle = |
2572 | erp_action->port->handle; | 2598 | erp_action->port->handle; |
@@ -2606,7 +2632,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2606 | int retval = -EINVAL; | 2632 | int retval = -EINVAL; |
2607 | struct zfcp_port *port; | 2633 | struct zfcp_port *port; |
2608 | 2634 | ||
2609 | port = fsf_req->data.close_port.port; | 2635 | port = (struct zfcp_port *) fsf_req->data; |
2610 | 2636 | ||
2611 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 2637 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
2612 | /* don't change port status in our bookkeeping */ | 2638 | /* don't change port status in our bookkeeping */ |
@@ -2703,8 +2729,8 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) | |||
2703 | atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, | 2729 | atomic_set_mask(ZFCP_STATUS_PORT_PHYS_CLOSING, |
2704 | &erp_action->port->status); | 2730 | &erp_action->port->status); |
2705 | /* save a pointer to this port */ | 2731 | /* save a pointer to this port */ |
2706 | erp_action->fsf_req->data.close_physical_port.port = erp_action->port; | 2732 | erp_action->fsf_req->data = (unsigned long) erp_action->port; |
2707 | /* port to be closeed */ | 2733 | /* port to be closed */ |
2708 | erp_action->fsf_req->qtcb->header.port_handle = | 2734 | erp_action->fsf_req->qtcb->header.port_handle = |
2709 | erp_action->port->handle; | 2735 | erp_action->port->handle; |
2710 | erp_action->fsf_req->erp_action = erp_action; | 2736 | erp_action->fsf_req->erp_action = erp_action; |
@@ -2747,7 +2773,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req) | |||
2747 | struct fsf_qtcb_header *header; | 2773 | struct fsf_qtcb_header *header; |
2748 | u16 subtable, rule, counter; | 2774 | u16 subtable, rule, counter; |
2749 | 2775 | ||
2750 | port = fsf_req->data.close_physical_port.port; | 2776 | port = (struct zfcp_port *) fsf_req->data; |
2751 | header = &fsf_req->qtcb->header; | 2777 | header = &fsf_req->qtcb->header; |
2752 | 2778 | ||
2753 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 2779 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
@@ -2908,10 +2934,11 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
2908 | erp_action->port->handle; | 2934 | erp_action->port->handle; |
2909 | erp_action->fsf_req->qtcb->bottom.support.fcp_lun = | 2935 | erp_action->fsf_req->qtcb->bottom.support.fcp_lun = |
2910 | erp_action->unit->fcp_lun; | 2936 | erp_action->unit->fcp_lun; |
2937 | if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE)) | ||
2911 | erp_action->fsf_req->qtcb->bottom.support.option = | 2938 | erp_action->fsf_req->qtcb->bottom.support.option = |
2912 | FSF_OPEN_LUN_SUPPRESS_BOXING; | 2939 | FSF_OPEN_LUN_SUPPRESS_BOXING; |
2913 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); | 2940 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); |
2914 | erp_action->fsf_req->data.open_unit.unit = erp_action->unit; | 2941 | erp_action->fsf_req->data = (unsigned long) erp_action->unit; |
2915 | erp_action->fsf_req->erp_action = erp_action; | 2942 | erp_action->fsf_req->erp_action = erp_action; |
2916 | 2943 | ||
2917 | /* start QDIO request for this FSF request */ | 2944 | /* start QDIO request for this FSF request */ |
@@ -2955,9 +2982,9 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
2955 | struct fsf_qtcb_bottom_support *bottom; | 2982 | struct fsf_qtcb_bottom_support *bottom; |
2956 | struct fsf_queue_designator *queue_designator; | 2983 | struct fsf_queue_designator *queue_designator; |
2957 | u16 subtable, rule, counter; | 2984 | u16 subtable, rule, counter; |
2958 | u32 allowed, exclusive, readwrite; | 2985 | int exclusive, readwrite; |
2959 | 2986 | ||
2960 | unit = fsf_req->data.open_unit.unit; | 2987 | unit = (struct zfcp_unit *) fsf_req->data; |
2961 | 2988 | ||
2962 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 2989 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
2963 | /* don't change unit status in our bookkeeping */ | 2990 | /* don't change unit status in our bookkeeping */ |
@@ -2969,10 +2996,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
2969 | bottom = &fsf_req->qtcb->bottom.support; | 2996 | bottom = &fsf_req->qtcb->bottom.support; |
2970 | queue_designator = &header->fsf_status_qual.fsf_queue_designator; | 2997 | queue_designator = &header->fsf_status_qual.fsf_queue_designator; |
2971 | 2998 | ||
2972 | allowed = bottom->lun_access_info & FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED; | ||
2973 | exclusive = bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE; | ||
2974 | readwrite = bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER; | ||
2975 | |||
2976 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 2999 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
2977 | ZFCP_STATUS_UNIT_SHARED | | 3000 | ZFCP_STATUS_UNIT_SHARED | |
2978 | ZFCP_STATUS_UNIT_READONLY, | 3001 | ZFCP_STATUS_UNIT_READONLY, |
@@ -3146,10 +3169,15 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3146 | unit->handle); | 3169 | unit->handle); |
3147 | /* mark unit as open */ | 3170 | /* mark unit as open */ |
3148 | atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); | 3171 | atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); |
3149 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 3172 | |
3150 | ZFCP_STATUS_COMMON_ACCESS_BOXED, | 3173 | if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) && |
3151 | &unit->status); | 3174 | (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) && |
3152 | if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){ | 3175 | (adapter->ccw_device->id.dev_model != ZFCP_DEVICE_MODEL_PRIV)) { |
3176 | exclusive = (bottom->lun_access_info & | ||
3177 | FSF_UNIT_ACCESS_EXCLUSIVE); | ||
3178 | readwrite = (bottom->lun_access_info & | ||
3179 | FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); | ||
3180 | |||
3153 | if (!exclusive) | 3181 | if (!exclusive) |
3154 | atomic_set_mask(ZFCP_STATUS_UNIT_SHARED, | 3182 | atomic_set_mask(ZFCP_STATUS_UNIT_SHARED, |
3155 | &unit->status); | 3183 | &unit->status); |
@@ -3242,7 +3270,7 @@ zfcp_fsf_close_unit(struct zfcp_erp_action *erp_action) | |||
3242 | erp_action->port->handle; | 3270 | erp_action->port->handle; |
3243 | erp_action->fsf_req->qtcb->header.lun_handle = erp_action->unit->handle; | 3271 | erp_action->fsf_req->qtcb->header.lun_handle = erp_action->unit->handle; |
3244 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status); | 3272 | atomic_set_mask(ZFCP_STATUS_COMMON_CLOSING, &erp_action->unit->status); |
3245 | erp_action->fsf_req->data.close_unit.unit = erp_action->unit; | 3273 | erp_action->fsf_req->data = (unsigned long) erp_action->unit; |
3246 | erp_action->fsf_req->erp_action = erp_action; | 3274 | erp_action->fsf_req->erp_action = erp_action; |
3247 | 3275 | ||
3248 | /* start QDIO request for this FSF request */ | 3276 | /* start QDIO request for this FSF request */ |
@@ -3281,7 +3309,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3281 | int retval = -EINVAL; | 3309 | int retval = -EINVAL; |
3282 | struct zfcp_unit *unit; | 3310 | struct zfcp_unit *unit; |
3283 | 3311 | ||
3284 | unit = fsf_req->data.close_unit.unit; /* restore unit */ | 3312 | unit = (struct zfcp_unit *) fsf_req->data; |
3285 | 3313 | ||
3286 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 3314 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
3287 | /* don't change unit status in our bookkeeping */ | 3315 | /* don't change unit status in our bookkeeping */ |
@@ -3305,9 +3333,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3305 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3333 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
3306 | "fsf_s_phand_nv"); | 3334 | "fsf_s_phand_nv"); |
3307 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | 3335 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); |
3308 | zfcp_cmd_dbf_event_fsf("porthinv", fsf_req, | ||
3309 | &fsf_req->qtcb->header.fsf_status_qual, | ||
3310 | sizeof (union fsf_status_qual)); | ||
3311 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3336 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3312 | break; | 3337 | break; |
3313 | 3338 | ||
@@ -3326,9 +3351,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3326 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3351 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
3327 | "fsf_s_lhand_nv"); | 3352 | "fsf_s_lhand_nv"); |
3328 | zfcp_erp_port_reopen(unit->port, 0); | 3353 | zfcp_erp_port_reopen(unit->port, 0); |
3329 | zfcp_cmd_dbf_event_fsf("lunhinv", fsf_req, | ||
3330 | &fsf_req->qtcb->header.fsf_status_qual, | ||
3331 | sizeof (union fsf_status_qual)); | ||
3332 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3354 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3333 | break; | 3355 | break; |
3334 | 3356 | ||
@@ -3436,21 +3458,14 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
3436 | goto failed_req_create; | 3458 | goto failed_req_create; |
3437 | } | 3459 | } |
3438 | 3460 | ||
3439 | /* | 3461 | zfcp_unit_get(unit); |
3440 | * associate FSF request with SCSI request | 3462 | fsf_req->unit = unit; |
3441 | * (need this for look up on abort) | ||
3442 | */ | ||
3443 | fsf_req->data.send_fcp_command_task.fsf_req = fsf_req; | ||
3444 | scsi_cmnd->host_scribble = (char *) &(fsf_req->data); | ||
3445 | 3463 | ||
3446 | /* | 3464 | /* associate FSF request with SCSI request (for look up on abort) */ |
3447 | * associate SCSI command with FSF request | 3465 | scsi_cmnd->host_scribble = (char *) fsf_req; |
3448 | * (need this for look up on normal command completion) | 3466 | |
3449 | */ | 3467 | /* associate SCSI command with FSF request */ |
3450 | fsf_req->data.send_fcp_command_task.scsi_cmnd = scsi_cmnd; | 3468 | fsf_req->data = (unsigned long) scsi_cmnd; |
3451 | fsf_req->data.send_fcp_command_task.start_jiffies = jiffies; | ||
3452 | fsf_req->data.send_fcp_command_task.unit = unit; | ||
3453 | ZFCP_LOG_DEBUG("unit=%p, fcp_lun=0x%016Lx\n", unit, unit->fcp_lun); | ||
3454 | 3469 | ||
3455 | /* set handles of unit and its parent port in QTCB */ | 3470 | /* set handles of unit and its parent port in QTCB */ |
3456 | fsf_req->qtcb->header.lun_handle = unit->handle; | 3471 | fsf_req->qtcb->header.lun_handle = unit->handle; |
@@ -3584,6 +3599,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
3584 | send_failed: | 3599 | send_failed: |
3585 | no_fit: | 3600 | no_fit: |
3586 | failed_scsi_cmnd: | 3601 | failed_scsi_cmnd: |
3602 | zfcp_unit_put(unit); | ||
3587 | zfcp_fsf_req_free(fsf_req); | 3603 | zfcp_fsf_req_free(fsf_req); |
3588 | fsf_req = NULL; | 3604 | fsf_req = NULL; |
3589 | scsi_cmnd->host_scribble = NULL; | 3605 | scsi_cmnd->host_scribble = NULL; |
@@ -3640,7 +3656,7 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter, | |||
3640 | * hold a pointer to the unit being target of this | 3656 | * hold a pointer to the unit being target of this |
3641 | * task management request | 3657 | * task management request |
3642 | */ | 3658 | */ |
3643 | fsf_req->data.send_fcp_command_task_management.unit = unit; | 3659 | fsf_req->data = (unsigned long) unit; |
3644 | 3660 | ||
3645 | /* set FSF related fields in QTCB */ | 3661 | /* set FSF related fields in QTCB */ |
3646 | fsf_req->qtcb->header.lun_handle = unit->handle; | 3662 | fsf_req->qtcb->header.lun_handle = unit->handle; |
@@ -3706,9 +3722,9 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3706 | header = &fsf_req->qtcb->header; | 3722 | header = &fsf_req->qtcb->header; |
3707 | 3723 | ||
3708 | if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)) | 3724 | if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)) |
3709 | unit = fsf_req->data.send_fcp_command_task_management.unit; | 3725 | unit = (struct zfcp_unit *) fsf_req->data; |
3710 | else | 3726 | else |
3711 | unit = fsf_req->data.send_fcp_command_task.unit; | 3727 | unit = fsf_req->unit; |
3712 | 3728 | ||
3713 | if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | 3729 | if (unlikely(fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)) { |
3714 | /* go directly to calls of special handlers */ | 3730 | /* go directly to calls of special handlers */ |
@@ -3765,10 +3781,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3765 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3781 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
3766 | "fsf_s_hand_mis"); | 3782 | "fsf_s_hand_mis"); |
3767 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); | 3783 | zfcp_erp_adapter_reopen(unit->port->adapter, 0); |
3768 | zfcp_cmd_dbf_event_fsf("handmism", | ||
3769 | fsf_req, | ||
3770 | &header->fsf_status_qual, | ||
3771 | sizeof (union fsf_status_qual)); | ||
3772 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3784 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3773 | break; | 3785 | break; |
3774 | 3786 | ||
@@ -3789,10 +3801,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3789 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, | 3801 | debug_text_exception(fsf_req->adapter->erp_dbf, 0, |
3790 | "fsf_s_class_nsup"); | 3802 | "fsf_s_class_nsup"); |
3791 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | 3803 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); |
3792 | zfcp_cmd_dbf_event_fsf("unsclass", | ||
3793 | fsf_req, | ||
3794 | &header->fsf_status_qual, | ||
3795 | sizeof (union fsf_status_qual)); | ||
3796 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3804 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3797 | break; | 3805 | break; |
3798 | 3806 | ||
@@ -3811,10 +3819,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3811 | debug_text_event(fsf_req->adapter->erp_dbf, 1, | 3819 | debug_text_event(fsf_req->adapter->erp_dbf, 1, |
3812 | "fsf_s_fcp_lun_nv"); | 3820 | "fsf_s_fcp_lun_nv"); |
3813 | zfcp_erp_port_reopen(unit->port, 0); | 3821 | zfcp_erp_port_reopen(unit->port, 0); |
3814 | zfcp_cmd_dbf_event_fsf("fluninv", | ||
3815 | fsf_req, | ||
3816 | &header->fsf_status_qual, | ||
3817 | sizeof (union fsf_status_qual)); | ||
3818 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3822 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3819 | break; | 3823 | break; |
3820 | 3824 | ||
@@ -3853,10 +3857,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3853 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 3857 | debug_text_event(fsf_req->adapter->erp_dbf, 0, |
3854 | "fsf_s_dir_ind_nv"); | 3858 | "fsf_s_dir_ind_nv"); |
3855 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | 3859 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); |
3856 | zfcp_cmd_dbf_event_fsf("dirinv", | ||
3857 | fsf_req, | ||
3858 | &header->fsf_status_qual, | ||
3859 | sizeof (union fsf_status_qual)); | ||
3860 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3860 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3861 | break; | 3861 | break; |
3862 | 3862 | ||
@@ -3872,10 +3872,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3872 | debug_text_event(fsf_req->adapter->erp_dbf, 0, | 3872 | debug_text_event(fsf_req->adapter->erp_dbf, 0, |
3873 | "fsf_s_cmd_len_nv"); | 3873 | "fsf_s_cmd_len_nv"); |
3874 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); | 3874 | zfcp_erp_adapter_shutdown(unit->port->adapter, 0); |
3875 | zfcp_cmd_dbf_event_fsf("cleninv", | ||
3876 | fsf_req, | ||
3877 | &header->fsf_status_qual, | ||
3878 | sizeof (union fsf_status_qual)); | ||
3879 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 3875 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
3880 | break; | 3876 | break; |
3881 | 3877 | ||
@@ -3947,6 +3943,8 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req) | |||
3947 | zfcp_fsf_send_fcp_command_task_management_handler(fsf_req); | 3943 | zfcp_fsf_send_fcp_command_task_management_handler(fsf_req); |
3948 | } else { | 3944 | } else { |
3949 | retval = zfcp_fsf_send_fcp_command_task_handler(fsf_req); | 3945 | retval = zfcp_fsf_send_fcp_command_task_handler(fsf_req); |
3946 | fsf_req->unit = NULL; | ||
3947 | zfcp_unit_put(unit); | ||
3950 | } | 3948 | } |
3951 | return retval; | 3949 | return retval; |
3952 | } | 3950 | } |
@@ -3970,10 +3968,10 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
3970 | u32 sns_len; | 3968 | u32 sns_len; |
3971 | char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); | 3969 | char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); |
3972 | unsigned long flags; | 3970 | unsigned long flags; |
3973 | struct zfcp_unit *unit = fsf_req->data.send_fcp_command_task.unit; | 3971 | struct zfcp_unit *unit = fsf_req->unit; |
3974 | 3972 | ||
3975 | read_lock_irqsave(&fsf_req->adapter->abort_lock, flags); | 3973 | read_lock_irqsave(&fsf_req->adapter->abort_lock, flags); |
3976 | scpnt = fsf_req->data.send_fcp_command_task.scsi_cmnd; | 3974 | scpnt = (struct scsi_cmnd *) fsf_req->data; |
3977 | if (unlikely(!scpnt)) { | 3975 | if (unlikely(!scpnt)) { |
3978 | ZFCP_LOG_DEBUG | 3976 | ZFCP_LOG_DEBUG |
3979 | ("Command with fsf_req %p is not associated to " | 3977 | ("Command with fsf_req %p is not associated to " |
@@ -4043,7 +4041,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4043 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 4041 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
4044 | (char *) &fsf_req->qtcb-> | 4042 | (char *) &fsf_req->qtcb-> |
4045 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 4043 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
4046 | zfcp_cmd_dbf_event_fsf("clenmis", fsf_req, NULL, 0); | ||
4047 | set_host_byte(&scpnt->result, DID_ERROR); | 4044 | set_host_byte(&scpnt->result, DID_ERROR); |
4048 | goto skip_fsfstatus; | 4045 | goto skip_fsfstatus; |
4049 | case RSP_CODE_FIELD_INVALID: | 4046 | case RSP_CODE_FIELD_INVALID: |
@@ -4062,7 +4059,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4062 | (char *) &fsf_req->qtcb-> | 4059 | (char *) &fsf_req->qtcb-> |
4063 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 4060 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
4064 | set_host_byte(&scpnt->result, DID_ERROR); | 4061 | set_host_byte(&scpnt->result, DID_ERROR); |
4065 | zfcp_cmd_dbf_event_fsf("codeinv", fsf_req, NULL, 0); | ||
4066 | goto skip_fsfstatus; | 4062 | goto skip_fsfstatus; |
4067 | case RSP_CODE_RO_MISMATCH: | 4063 | case RSP_CODE_RO_MISMATCH: |
4068 | /* hardware bug */ | 4064 | /* hardware bug */ |
@@ -4079,7 +4075,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4079 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 4075 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
4080 | (char *) &fsf_req->qtcb-> | 4076 | (char *) &fsf_req->qtcb-> |
4081 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 4077 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
4082 | zfcp_cmd_dbf_event_fsf("codemism", fsf_req, NULL, 0); | ||
4083 | set_host_byte(&scpnt->result, DID_ERROR); | 4078 | set_host_byte(&scpnt->result, DID_ERROR); |
4084 | goto skip_fsfstatus; | 4079 | goto skip_fsfstatus; |
4085 | default: | 4080 | default: |
@@ -4096,7 +4091,6 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4096 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, | 4091 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG, |
4097 | (char *) &fsf_req->qtcb-> | 4092 | (char *) &fsf_req->qtcb-> |
4098 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); | 4093 | bottom.io.fcp_cmnd, FSF_FCP_CMND_SIZE); |
4099 | zfcp_cmd_dbf_event_fsf("undeffcp", fsf_req, NULL, 0); | ||
4100 | set_host_byte(&scpnt->result, DID_ERROR); | 4094 | set_host_byte(&scpnt->result, DID_ERROR); |
4101 | goto skip_fsfstatus; | 4095 | goto skip_fsfstatus; |
4102 | } | 4096 | } |
@@ -4158,19 +4152,17 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req) | |||
4158 | skip_fsfstatus: | 4152 | skip_fsfstatus: |
4159 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); | 4153 | ZFCP_LOG_DEBUG("scpnt->result =0x%x\n", scpnt->result); |
4160 | 4154 | ||
4161 | zfcp_cmd_dbf_event_scsi("response", scpnt); | 4155 | if (scpnt->result != 0) |
4156 | zfcp_scsi_dbf_event_result("erro", 3, fsf_req->adapter, scpnt); | ||
4157 | else if (scpnt->retries > 0) | ||
4158 | zfcp_scsi_dbf_event_result("retr", 4, fsf_req->adapter, scpnt); | ||
4159 | else | ||
4160 | zfcp_scsi_dbf_event_result("norm", 6, fsf_req->adapter, scpnt); | ||
4162 | 4161 | ||
4163 | /* cleanup pointer (need this especially for abort) */ | 4162 | /* cleanup pointer (need this especially for abort) */ |
4164 | scpnt->host_scribble = NULL; | 4163 | scpnt->host_scribble = NULL; |
4165 | 4164 | ||
4166 | /* | ||
4167 | * NOTE: | ||
4168 | * according to the outcome of a discussion on linux-scsi we | ||
4169 | * don't need to grab the io_request_lock here since we use | ||
4170 | * the new eh | ||
4171 | */ | ||
4172 | /* always call back */ | 4165 | /* always call back */ |
4173 | |||
4174 | (scpnt->scsi_done) (scpnt); | 4166 | (scpnt->scsi_done) (scpnt); |
4175 | 4167 | ||
4176 | /* | 4168 | /* |
@@ -4198,8 +4190,7 @@ zfcp_fsf_send_fcp_command_task_management_handler(struct zfcp_fsf_req *fsf_req) | |||
4198 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) | 4190 | struct fcp_rsp_iu *fcp_rsp_iu = (struct fcp_rsp_iu *) |
4199 | &(fsf_req->qtcb->bottom.io.fcp_rsp); | 4191 | &(fsf_req->qtcb->bottom.io.fcp_rsp); |
4200 | char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); | 4192 | char *fcp_rsp_info = zfcp_get_fcp_rsp_info_ptr(fcp_rsp_iu); |
4201 | struct zfcp_unit *unit = | 4193 | struct zfcp_unit *unit = (struct zfcp_unit *) fsf_req->data; |
4202 | fsf_req->data.send_fcp_command_task_management.unit; | ||
4203 | 4194 | ||
4204 | del_timer(&fsf_req->adapter->scsi_er_timer); | 4195 | del_timer(&fsf_req->adapter->scsi_er_timer); |
4205 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { | 4196 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) { |
@@ -4276,7 +4267,7 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter, | |||
4276 | int direction; | 4267 | int direction; |
4277 | int retval = 0; | 4268 | int retval = 0; |
4278 | 4269 | ||
4279 | if (!(adapter->supported_features & FSF_FEATURE_CFDC)) { | 4270 | if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) { |
4280 | ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n", | 4271 | ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n", |
4281 | zfcp_get_busid_by_adapter(adapter)); | 4272 | zfcp_get_busid_by_adapter(adapter)); |
4282 | retval = -EOPNOTSUPP; | 4273 | retval = -EOPNOTSUPP; |
@@ -4549,52 +4540,6 @@ skip_fsfstatus: | |||
4549 | return retval; | 4540 | return retval; |
4550 | } | 4541 | } |
4551 | 4542 | ||
4552 | |||
4553 | /* | ||
4554 | * function: zfcp_fsf_req_wait_and_cleanup | ||
4555 | * | ||
4556 | * purpose: | ||
4557 | * | ||
4558 | * FIXME(design): signal seems to be <0 !!! | ||
4559 | * returns: 0 - request completed (*status is valid), cleanup succ. | ||
4560 | * <0 - request completed (*status is valid), cleanup failed | ||
4561 | * >0 - signal which interrupted waiting (*status invalid), | ||
4562 | * request not completed, no cleanup | ||
4563 | * | ||
4564 | * *status is a copy of status of completed fsf_req | ||
4565 | */ | ||
4566 | int | ||
4567 | zfcp_fsf_req_wait_and_cleanup(struct zfcp_fsf_req *fsf_req, | ||
4568 | int interruptible, u32 * status) | ||
4569 | { | ||
4570 | int retval = 0; | ||
4571 | int signal = 0; | ||
4572 | |||
4573 | if (interruptible) { | ||
4574 | __wait_event_interruptible(fsf_req->completion_wq, | ||
4575 | fsf_req->status & | ||
4576 | ZFCP_STATUS_FSFREQ_COMPLETED, | ||
4577 | signal); | ||
4578 | if (signal) { | ||
4579 | ZFCP_LOG_DEBUG("Caught signal %i while waiting for the " | ||
4580 | "completion of the request at %p\n", | ||
4581 | signal, fsf_req); | ||
4582 | retval = signal; | ||
4583 | goto out; | ||
4584 | } | ||
4585 | } else { | ||
4586 | __wait_event(fsf_req->completion_wq, | ||
4587 | fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED); | ||
4588 | } | ||
4589 | |||
4590 | *status = fsf_req->status; | ||
4591 | |||
4592 | /* cleanup request */ | ||
4593 | zfcp_fsf_req_free(fsf_req); | ||
4594 | out: | ||
4595 | return retval; | ||
4596 | } | ||
4597 | |||
4598 | static inline int | 4543 | static inline int |
4599 | zfcp_fsf_req_sbal_check(unsigned long *flags, | 4544 | zfcp_fsf_req_sbal_check(unsigned long *flags, |
4600 | struct zfcp_qdio_queue *queue, int needed) | 4545 | struct zfcp_qdio_queue *queue, int needed) |
@@ -4610,15 +4555,16 @@ zfcp_fsf_req_sbal_check(unsigned long *flags, | |||
4610 | * set qtcb pointer in fsf_req and initialize QTCB | 4555 | * set qtcb pointer in fsf_req and initialize QTCB |
4611 | */ | 4556 | */ |
4612 | static inline void | 4557 | static inline void |
4613 | zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req, u32 fsf_cmd) | 4558 | zfcp_fsf_req_qtcb_init(struct zfcp_fsf_req *fsf_req) |
4614 | { | 4559 | { |
4615 | if (likely(fsf_req->qtcb != NULL)) { | 4560 | if (likely(fsf_req->qtcb != NULL)) { |
4561 | fsf_req->qtcb->prefix.req_seq_no = fsf_req->adapter->fsf_req_seq_no; | ||
4616 | fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req; | 4562 | fsf_req->qtcb->prefix.req_id = (unsigned long)fsf_req; |
4617 | fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; | 4563 | fsf_req->qtcb->prefix.ulp_info = ZFCP_ULP_INFO_VERSION; |
4618 | fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_cmd]; | 4564 | fsf_req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_req->fsf_command]; |
4619 | fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; | 4565 | fsf_req->qtcb->prefix.qtcb_version = ZFCP_QTCB_VERSION; |
4620 | fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req; | 4566 | fsf_req->qtcb->header.req_handle = (unsigned long)fsf_req; |
4621 | fsf_req->qtcb->header.fsf_command = fsf_cmd; | 4567 | fsf_req->qtcb->header.fsf_command = fsf_req->fsf_command; |
4622 | } | 4568 | } |
4623 | } | 4569 | } |
4624 | 4570 | ||
@@ -4686,7 +4632,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
4686 | goto failed_fsf_req; | 4632 | goto failed_fsf_req; |
4687 | } | 4633 | } |
4688 | 4634 | ||
4689 | zfcp_fsf_req_qtcb_init(fsf_req, fsf_cmd); | 4635 | fsf_req->adapter = adapter; |
4636 | fsf_req->fsf_command = fsf_cmd; | ||
4637 | |||
4638 | zfcp_fsf_req_qtcb_init(fsf_req); | ||
4690 | 4639 | ||
4691 | /* initialize waitqueue which may be used to wait on | 4640 | /* initialize waitqueue which may be used to wait on |
4692 | this request completion */ | 4641 | this request completion */ |
@@ -4708,8 +4657,10 @@ zfcp_fsf_req_create(struct zfcp_adapter *adapter, u32 fsf_cmd, int req_flags, | |||
4708 | goto failed_sbals; | 4657 | goto failed_sbals; |
4709 | } | 4658 | } |
4710 | 4659 | ||
4711 | fsf_req->adapter = adapter; /* pointer to "parent" adapter */ | 4660 | if (fsf_req->qtcb) { |
4712 | fsf_req->fsf_command = fsf_cmd; | 4661 | fsf_req->seq_no = adapter->fsf_req_seq_no; |
4662 | fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; | ||
4663 | } | ||
4713 | fsf_req->sbal_number = 1; | 4664 | fsf_req->sbal_number = 1; |
4714 | fsf_req->sbal_first = req_queue->free_index; | 4665 | fsf_req->sbal_first = req_queue->free_index; |
4715 | fsf_req->sbal_curr = req_queue->free_index; | 4666 | fsf_req->sbal_curr = req_queue->free_index; |
@@ -4760,9 +4711,9 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
4760 | struct zfcp_adapter *adapter; | 4711 | struct zfcp_adapter *adapter; |
4761 | struct zfcp_qdio_queue *req_queue; | 4712 | struct zfcp_qdio_queue *req_queue; |
4762 | volatile struct qdio_buffer_element *sbale; | 4713 | volatile struct qdio_buffer_element *sbale; |
4714 | int inc_seq_no; | ||
4763 | int new_distance_from_int; | 4715 | int new_distance_from_int; |
4764 | unsigned long flags; | 4716 | unsigned long flags; |
4765 | int inc_seq_no = 1; | ||
4766 | int retval = 0; | 4717 | int retval = 0; |
4767 | 4718 | ||
4768 | adapter = fsf_req->adapter; | 4719 | adapter = fsf_req->adapter; |
@@ -4776,23 +4727,13 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
4776 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, | 4727 | ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE, (char *) sbale[1].addr, |
4777 | sbale[1].length); | 4728 | sbale[1].length); |
4778 | 4729 | ||
4779 | /* set sequence counter in QTCB */ | ||
4780 | if (likely(fsf_req->qtcb)) { | ||
4781 | fsf_req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; | ||
4782 | fsf_req->seq_no = adapter->fsf_req_seq_no; | ||
4783 | ZFCP_LOG_TRACE("FSF request %p of adapter %s gets " | ||
4784 | "FSF sequence counter value of %i\n", | ||
4785 | fsf_req, | ||
4786 | zfcp_get_busid_by_adapter(adapter), | ||
4787 | fsf_req->qtcb->prefix.req_seq_no); | ||
4788 | } else | ||
4789 | inc_seq_no = 0; | ||
4790 | |||
4791 | /* put allocated FSF request at list tail */ | 4730 | /* put allocated FSF request at list tail */ |
4792 | spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); | 4731 | spin_lock_irqsave(&adapter->fsf_req_list_lock, flags); |
4793 | list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); | 4732 | list_add_tail(&fsf_req->list, &adapter->fsf_req_list_head); |
4794 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); | 4733 | spin_unlock_irqrestore(&adapter->fsf_req_list_lock, flags); |
4795 | 4734 | ||
4735 | inc_seq_no = (fsf_req->qtcb != NULL); | ||
4736 | |||
4796 | /* figure out expiration time of timeout and start timeout */ | 4737 | /* figure out expiration time of timeout and start timeout */ |
4797 | if (unlikely(timer)) { | 4738 | if (unlikely(timer)) { |
4798 | timer->expires += jiffies; | 4739 | timer->expires += jiffies; |
@@ -4822,6 +4763,8 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
4822 | req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */ | 4763 | req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap if needed */ |
4823 | new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req); | 4764 | new_distance_from_int = zfcp_qdio_determine_pci(req_queue, fsf_req); |
4824 | 4765 | ||
4766 | fsf_req->issued = get_clock(); | ||
4767 | |||
4825 | retval = do_QDIO(adapter->ccw_device, | 4768 | retval = do_QDIO(adapter->ccw_device, |
4826 | QDIO_FLAG_SYNC_OUTPUT, | 4769 | QDIO_FLAG_SYNC_OUTPUT, |
4827 | 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); | 4770 | 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL); |
@@ -4860,15 +4803,11 @@ zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req, struct timer_list *timer) | |||
4860 | * routines resulting in missing sequence counter values | 4803 | * routines resulting in missing sequence counter values |
4861 | * otherwise, | 4804 | * otherwise, |
4862 | */ | 4805 | */ |
4806 | |||
4863 | /* Don't increase for unsolicited status */ | 4807 | /* Don't increase for unsolicited status */ |
4864 | if (likely(inc_seq_no)) { | 4808 | if (inc_seq_no) |
4865 | adapter->fsf_req_seq_no++; | 4809 | adapter->fsf_req_seq_no++; |
4866 | ZFCP_LOG_TRACE | 4810 | |
4867 | ("FSF sequence counter value of adapter %s " | ||
4868 | "increased to %i\n", | ||
4869 | zfcp_get_busid_by_adapter(adapter), | ||
4870 | adapter->fsf_req_seq_no); | ||
4871 | } | ||
4872 | /* count FSF requests pending */ | 4811 | /* count FSF requests pending */ |
4873 | atomic_inc(&adapter->fsf_reqs_active); | 4812 | atomic_inc(&adapter->fsf_reqs_active); |
4874 | } | 4813 | } |