diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 330 |
1 files changed, 214 insertions, 116 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 80ab721ddfff..f994f453e2d2 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 | ||
@@ -375,87 +377,19 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req) | |||
375 | break; | 377 | break; |
376 | 378 | ||
377 | case FSF_PROT_DUPLICATE_REQUEST_ID: | 379 | case FSF_PROT_DUPLICATE_REQUEST_ID: |
378 | if (fsf_req->qtcb) { | ||
379 | ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx " | 380 | ZFCP_LOG_NORMAL("bug: The request identifier 0x%Lx " |
380 | "to the adapter %s is ambiguous. " | 381 | "to the adapter %s is ambiguous. " |
381 | "Stopping all operations on this " | 382 | "Stopping all operations on this adapter.\n", |
382 | "adapter.\n", | 383 | *(unsigned long long*) |
383 | *(unsigned long long *) | 384 | (&qtcb->bottom.support.req_handle), |
384 | (&fsf_req->qtcb->bottom.support. | ||
385 | req_handle), | ||
386 | zfcp_get_busid_by_adapter(adapter)); | ||
387 | } else { | ||
388 | ZFCP_LOG_NORMAL("bug: The request identifier %p " | ||
389 | "to the adapter %s is ambiguous. " | ||
390 | "Stopping all operations on this " | ||
391 | "adapter. " | ||
392 | "(bug: got this for an unsolicited " | ||
393 | "status read request)\n", | ||
394 | fsf_req, | ||
395 | zfcp_get_busid_by_adapter(adapter)); | 385 | zfcp_get_busid_by_adapter(adapter)); |
396 | } | ||
397 | zfcp_erp_adapter_shutdown(adapter, 0); | 386 | zfcp_erp_adapter_shutdown(adapter, 0); |
398 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 387 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
399 | break; | 388 | break; |
400 | 389 | ||
401 | case FSF_PROT_LINK_DOWN: | 390 | case FSF_PROT_LINK_DOWN: |
402 | /* | 391 | zfcp_fsf_link_down_info_eval(adapter, |
403 | * 'test and set' is not atomic here - | 392 | &prot_status_qual->link_down_info); |
404 | * it's ok as long as calls to our response queue handler | ||
405 | * (and thus execution of this code here) are serialized | ||
406 | * by the qdio module | ||
407 | */ | ||
408 | if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | ||
409 | &adapter->status)) { | ||
410 | switch (fsf_req->qtcb->prefix.prot_status_qual. | ||
411 | locallink_error.code) { | ||
412 | case FSF_PSQ_LINK_NOLIGHT: | ||
413 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
414 | "is down (no light detected).\n", | ||
415 | zfcp_get_busid_by_adapter( | ||
416 | adapter)); | ||
417 | break; | ||
418 | case FSF_PSQ_LINK_WRAPPLUG: | ||
419 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
420 | "is down (wrap plug detected).\n", | ||
421 | zfcp_get_busid_by_adapter( | ||
422 | adapter)); | ||
423 | break; | ||
424 | case FSF_PSQ_LINK_NOFCP: | ||
425 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
426 | "is down (adjacent node on " | ||
427 | "link does not support FCP).\n", | ||
428 | zfcp_get_busid_by_adapter( | ||
429 | adapter)); | ||
430 | break; | ||
431 | default: | ||
432 | ZFCP_LOG_INFO("The local link to adapter %s " | ||
433 | "is down " | ||
434 | "(warning: unknown reason " | ||
435 | "code).\n", | ||
436 | zfcp_get_busid_by_adapter( | ||
437 | adapter)); | ||
438 | break; | ||
439 | |||
440 | } | ||
441 | /* | ||
442 | * Due to the 'erp failed' flag the adapter won't | ||
443 | * be recovered but will be just set to 'blocked' | ||
444 | * state. All subordinary devices will have state | ||
445 | * 'blocked' and 'erp failed', too. | ||
446 | * Thus the adapter is still able to provide | ||
447 | * 'link up' status without being flooded with | ||
448 | * requests. | ||
449 | * (note: even 'close port' is not permitted) | ||
450 | */ | ||
451 | ZFCP_LOG_INFO("Stopping all operations for adapter " | ||
452 | "%s.\n", | ||
453 | zfcp_get_busid_by_adapter(adapter)); | ||
454 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | | ||
455 | ZFCP_STATUS_COMMON_ERP_FAILED, | ||
456 | &adapter->status); | ||
457 | zfcp_erp_adapter_reopen(adapter, 0); | ||
458 | } | ||
459 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; | 393 | fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR; |
460 | break; | 394 | break; |
461 | 395 | ||
@@ -613,6 +547,110 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req) | |||
613 | return retval; | 547 | return retval; |
614 | } | 548 | } |
615 | 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 | |||
616 | /* | 654 | /* |
617 | * function: zfcp_fsf_req_dispatch | 655 | * function: zfcp_fsf_req_dispatch |
618 | * | 656 | * |
@@ -877,17 +915,32 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
877 | break; | 915 | break; |
878 | 916 | ||
879 | case FSF_STATUS_READ_LINK_DOWN: | 917 | case FSF_STATUS_READ_LINK_DOWN: |
880 | debug_text_event(adapter->erp_dbf, 0, "unsol_link_down:"); | 918 | switch (status_buffer->status_subtype) { |
881 | 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", | ||
882 | zfcp_get_busid_by_adapter(adapter)); | 926 | zfcp_get_busid_by_adapter(adapter)); |
883 | atomic_set_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 927 | break; |
884 | &adapter->status); | 928 | case FSF_STATUS_READ_SUB_FIRMWARE_UPDATE: |
885 | 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); | ||
886 | break; | 940 | break; |
887 | 941 | ||
888 | case FSF_STATUS_READ_LINK_UP: | 942 | case FSF_STATUS_READ_LINK_UP: |
889 | debug_text_event(adapter->erp_dbf, 2, "unsol_link_up:"); | 943 | ZFCP_LOG_NORMAL("Local link to adapter %s was replugged. " |
890 | ZFCP_LOG_INFO("Local link to adapter %s was replugged. " | ||
891 | "Restarting operations on this adapter\n", | 944 | "Restarting operations on this adapter\n", |
892 | zfcp_get_busid_by_adapter(adapter)); | 945 | zfcp_get_busid_by_adapter(adapter)); |
893 | /* All ports should be marked as ready to run again */ | 946 | /* All ports should be marked as ready to run again */ |
@@ -922,6 +975,16 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req) | |||
922 | } | 975 | } |
923 | break; | 976 | break; |
924 | 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 | |||
925 | default: | 988 | default: |
926 | ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown " | 989 | ZFCP_LOG_NORMAL("warning: An unsolicited status packet of unknown " |
927 | "type was received (debug info 0x%x)\n", | 990 | "type was received (debug info 0x%x)\n", |
@@ -1281,7 +1344,7 @@ zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool, | |||
1281 | sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]); | 1344 | sbale[3].addr = zfcp_sg_to_address(&ct->resp[0]); |
1282 | sbale[3].length = ct->resp[0].length; | 1345 | sbale[3].length = ct->resp[0].length; |
1283 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; | 1346 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; |
1284 | } else if (adapter->supported_features & | 1347 | } else if (adapter->adapter_features & |
1285 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { | 1348 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { |
1286 | /* try to use chained SBALs */ | 1349 | /* try to use chained SBALs */ |
1287 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, | 1350 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, |
@@ -1584,7 +1647,7 @@ zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1584 | sbale[3].addr = zfcp_sg_to_address(&els->resp[0]); | 1647 | sbale[3].addr = zfcp_sg_to_address(&els->resp[0]); |
1585 | sbale[3].length = els->resp[0].length; | 1648 | sbale[3].length = els->resp[0].length; |
1586 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; | 1649 | sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; |
1587 | } else if (adapter->supported_features & | 1650 | } else if (adapter->adapter_features & |
1588 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { | 1651 | FSF_FEATURE_ELS_CT_CHAINED_SBALS) { |
1589 | /* try to use chained SBALs */ | 1652 | /* try to use chained SBALs */ |
1590 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, | 1653 | bytes = zfcp_qdio_sbals_from_sg(fsf_req, |
@@ -1877,7 +1940,9 @@ zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1877 | 1940 | ||
1878 | erp_action->fsf_req->erp_action = erp_action; | 1941 | erp_action->fsf_req->erp_action = erp_action; |
1879 | erp_action->fsf_req->qtcb->bottom.config.feature_selection = | 1942 | erp_action->fsf_req->qtcb->bottom.config.feature_selection = |
1880 | (FSF_FEATURE_CFDC | FSF_FEATURE_LUN_SHARING); | 1943 | FSF_FEATURE_CFDC | |
1944 | FSF_FEATURE_LUN_SHARING | | ||
1945 | FSF_FEATURE_UPDATE_ALERT; | ||
1881 | 1946 | ||
1882 | /* start QDIO request for this FSF request */ | 1947 | /* start QDIO request for this FSF request */ |
1883 | 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); |
@@ -1918,7 +1983,8 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
1918 | ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n", | 1983 | ZFCP_LOG_DEBUG("low/high QTCB version 0x%x/0x%x of FSF\n", |
1919 | bottom->low_qtcb_version, bottom->high_qtcb_version); | 1984 | bottom->low_qtcb_version, bottom->high_qtcb_version); |
1920 | adapter->fsf_lic_version = bottom->lic_version; | 1985 | adapter->fsf_lic_version = bottom->lic_version; |
1921 | adapter->supported_features = bottom->supported_features; | 1986 | adapter->adapter_features = bottom->adapter_features; |
1987 | adapter->connection_features = bottom->connection_features; | ||
1922 | adapter->peer_wwpn = 0; | 1988 | adapter->peer_wwpn = 0; |
1923 | adapter->peer_wwnn = 0; | 1989 | adapter->peer_wwnn = 0; |
1924 | adapter->peer_d_id = 0; | 1990 | adapter->peer_d_id = 0; |
@@ -1930,6 +1996,10 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
1930 | adapter->fc_topology = bottom->fc_topology; | 1996 | adapter->fc_topology = bottom->fc_topology; |
1931 | adapter->fc_link_speed = bottom->fc_link_speed; | 1997 | adapter->fc_link_speed = bottom->fc_link_speed; |
1932 | adapter->hydra_version = bottom->adapter_type; | 1998 | adapter->hydra_version = bottom->adapter_type; |
1999 | if (adapter->physical_wwpn == 0) | ||
2000 | adapter->physical_wwpn = adapter->wwpn; | ||
2001 | if (adapter->physical_s_id == 0) | ||
2002 | adapter->physical_s_id = adapter->s_id; | ||
1933 | } else { | 2003 | } else { |
1934 | adapter->wwnn = 0; | 2004 | adapter->wwnn = 0; |
1935 | adapter->wwpn = 0; | 2005 | adapter->wwpn = 0; |
@@ -1945,7 +2015,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
1945 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; | 2015 | adapter->peer_wwnn = bottom->plogi_payload.wwnn; |
1946 | } | 2016 | } |
1947 | 2017 | ||
1948 | if(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT){ | 2018 | if (adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT) { |
1949 | adapter->hardware_version = bottom->hardware_version; | 2019 | adapter->hardware_version = bottom->hardware_version; |
1950 | memcpy(adapter->serial_number, bottom->serial_number, 17); | 2020 | memcpy(adapter->serial_number, bottom->serial_number, 17); |
1951 | EBCASC(adapter->serial_number, sizeof(adapter->serial_number)); | 2021 | EBCASC(adapter->serial_number, sizeof(adapter->serial_number)); |
@@ -2001,11 +2071,12 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2001 | { | 2071 | { |
2002 | struct fsf_qtcb_bottom_config *bottom; | 2072 | struct fsf_qtcb_bottom_config *bottom; |
2003 | struct zfcp_adapter *adapter = fsf_req->adapter; | 2073 | struct zfcp_adapter *adapter = fsf_req->adapter; |
2074 | struct fsf_qtcb *qtcb = fsf_req->qtcb; | ||
2004 | 2075 | ||
2005 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2076 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2006 | return -EIO; | 2077 | return -EIO; |
2007 | 2078 | ||
2008 | switch (fsf_req->qtcb->header.fsf_status) { | 2079 | switch (qtcb->header.fsf_status) { |
2009 | 2080 | ||
2010 | case FSF_GOOD: | 2081 | case FSF_GOOD: |
2011 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) | 2082 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 1)) |
@@ -2035,7 +2106,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2035 | zfcp_erp_adapter_shutdown(adapter, 0); | 2106 | zfcp_erp_adapter_shutdown(adapter, 0); |
2036 | return -EIO; | 2107 | return -EIO; |
2037 | case FSF_TOPO_FABRIC: | 2108 | case FSF_TOPO_FABRIC: |
2038 | ZFCP_LOG_INFO("Switched fabric fibrechannel " | 2109 | ZFCP_LOG_NORMAL("Switched fabric fibrechannel " |
2039 | "network detected at adapter %s.\n", | 2110 | "network detected at adapter %s.\n", |
2040 | zfcp_get_busid_by_adapter(adapter)); | 2111 | zfcp_get_busid_by_adapter(adapter)); |
2041 | break; | 2112 | break; |
@@ -2053,7 +2124,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2053 | zfcp_erp_adapter_shutdown(adapter, 0); | 2124 | zfcp_erp_adapter_shutdown(adapter, 0); |
2054 | return -EIO; | 2125 | return -EIO; |
2055 | } | 2126 | } |
2056 | bottom = &fsf_req->qtcb->bottom.config; | 2127 | bottom = &qtcb->bottom.config; |
2057 | if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { | 2128 | if (bottom->max_qtcb_size < sizeof(struct fsf_qtcb)) { |
2058 | ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) " | 2129 | ZFCP_LOG_NORMAL("bug: Maximum QTCB size (%d bytes) " |
2059 | "allowed by the adapter %s " | 2130 | "allowed by the adapter %s " |
@@ -2078,12 +2149,10 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2078 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) | 2149 | if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0)) |
2079 | return -EIO; | 2150 | return -EIO; |
2080 | 2151 | ||
2081 | ZFCP_LOG_INFO("Local link to adapter %s is down\n", | 2152 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK, &adapter->status); |
2082 | zfcp_get_busid_by_adapter(adapter)); | 2153 | |
2083 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK | | 2154 | zfcp_fsf_link_down_info_eval(adapter, |
2084 | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, | 2155 | &qtcb->header.fsf_status_qual.link_down_info); |
2085 | &adapter->status); | ||
2086 | zfcp_erp_adapter_failed(adapter); | ||
2087 | break; | 2156 | break; |
2088 | default: | 2157 | default: |
2089 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); | 2158 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng"); |
@@ -2097,11 +2166,13 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req) | |||
2097 | 2166 | ||
2098 | /** | 2167 | /** |
2099 | * zfcp_fsf_exchange_port_data - request information about local port | 2168 | * zfcp_fsf_exchange_port_data - request information about local port |
2169 | * @erp_action: ERP action for the adapter for which port data is requested | ||
2100 | * @adapter: for which port data is requested | 2170 | * @adapter: for which port data is requested |
2101 | * @data: response to exchange port data request | 2171 | * @data: response to exchange port data request |
2102 | */ | 2172 | */ |
2103 | int | 2173 | int |
2104 | zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | 2174 | zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action, |
2175 | struct zfcp_adapter *adapter, | ||
2105 | struct fsf_qtcb_bottom_port *data) | 2176 | struct fsf_qtcb_bottom_port *data) |
2106 | { | 2177 | { |
2107 | volatile struct qdio_buffer_element *sbale; | 2178 | volatile struct qdio_buffer_element *sbale; |
@@ -2110,7 +2181,7 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2110 | struct zfcp_fsf_req *fsf_req; | 2181 | struct zfcp_fsf_req *fsf_req; |
2111 | struct timer_list *timer; | 2182 | struct timer_list *timer; |
2112 | 2183 | ||
2113 | if(!(adapter->supported_features & FSF_FEATURE_HBAAPI_MANAGEMENT)){ | 2184 | if (!(adapter->adapter_features & FSF_FEATURE_HBAAPI_MANAGEMENT)) { |
2114 | ZFCP_LOG_INFO("error: exchange port data " | 2185 | ZFCP_LOG_INFO("error: exchange port data " |
2115 | "command not supported by adapter %s\n", | 2186 | "command not supported by adapter %s\n", |
2116 | zfcp_get_busid_by_adapter(adapter)); | 2187 | zfcp_get_busid_by_adapter(adapter)); |
@@ -2134,6 +2205,12 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2134 | goto out; | 2205 | goto out; |
2135 | } | 2206 | } |
2136 | 2207 | ||
2208 | if (erp_action) { | ||
2209 | erp_action->fsf_req = fsf_req; | ||
2210 | fsf_req->erp_action = erp_action; | ||
2211 | } | ||
2212 | |||
2213 | if (data) | ||
2137 | fsf_req->data = (unsigned long) data; | 2214 | fsf_req->data = (unsigned long) data; |
2138 | 2215 | ||
2139 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); | 2216 | sbale = zfcp_qdio_sbale_req(fsf_req, fsf_req->sbal_curr, 0); |
@@ -2151,6 +2228,8 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2151 | "command on the adapter %s\n", | 2228 | "command on the adapter %s\n", |
2152 | zfcp_get_busid_by_adapter(adapter)); | 2229 | zfcp_get_busid_by_adapter(adapter)); |
2153 | zfcp_fsf_req_free(fsf_req); | 2230 | zfcp_fsf_req_free(fsf_req); |
2231 | if (erp_action) | ||
2232 | erp_action->fsf_req = NULL; | ||
2154 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, | 2233 | write_unlock_irqrestore(&adapter->request_queue.queue_lock, |
2155 | lock_flags); | 2234 | lock_flags); |
2156 | goto out; | 2235 | goto out; |
@@ -2179,23 +2258,40 @@ zfcp_fsf_exchange_port_data(struct zfcp_adapter *adapter, | |||
2179 | static void | 2258 | static void |
2180 | zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) | 2259 | zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req) |
2181 | { | 2260 | { |
2182 | struct fsf_qtcb_bottom_port *bottom; | 2261 | struct zfcp_adapter *adapter = fsf_req->adapter; |
2183 | struct fsf_qtcb_bottom_port *data; | 2262 | struct fsf_qtcb *qtcb = fsf_req->qtcb; |
2184 | 2263 | struct fsf_qtcb_bottom_port *bottom, *data; | |
2185 | data = (struct fsf_qtcb_bottom_port*) fsf_req->data; | ||
2186 | 2264 | ||
2187 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | 2265 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) |
2188 | return; | 2266 | return; |
2189 | 2267 | ||
2190 | switch (fsf_req->qtcb->header.fsf_status) { | 2268 | switch (qtcb->header.fsf_status) { |
2191 | case FSF_GOOD: | 2269 | case FSF_GOOD: |
2192 | bottom = &fsf_req->qtcb->bottom.port; | 2270 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); |
2193 | memcpy(data, bottom, sizeof(*data)); | 2271 | |
2272 | bottom = &qtcb->bottom.port; | ||
2273 | data = (struct fsf_qtcb_bottom_port*) fsf_req->data; | ||
2274 | if (data) | ||
2275 | memcpy(data, bottom, sizeof(struct fsf_qtcb_bottom_port)); | ||
2276 | if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) { | ||
2277 | adapter->physical_wwpn = bottom->wwpn; | ||
2278 | adapter->physical_s_id = bottom->fc_port_id; | ||
2279 | } else { | ||
2280 | adapter->physical_wwpn = adapter->wwpn; | ||
2281 | adapter->physical_s_id = adapter->s_id; | ||
2282 | } | ||
2283 | break; | ||
2284 | |||
2285 | case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE: | ||
2286 | atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status); | ||
2287 | |||
2288 | zfcp_fsf_link_down_info_eval(adapter, | ||
2289 | &qtcb->header.fsf_status_qual.link_down_info); | ||
2194 | break; | 2290 | break; |
2195 | 2291 | ||
2196 | default: | 2292 | default: |
2197 | debug_text_event(fsf_req->adapter->erp_dbf, 0, "xchg-port-ng"); | 2293 | debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng"); |
2198 | debug_event(fsf_req->adapter->erp_dbf, 0, | 2294 | debug_event(adapter->erp_dbf, 0, |
2199 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); | 2295 | &fsf_req->qtcb->header.fsf_status, sizeof(u32)); |
2200 | } | 2296 | } |
2201 | } | 2297 | } |
@@ -2629,7 +2725,7 @@ zfcp_fsf_close_physical_port(struct zfcp_erp_action *erp_action) | |||
2629 | &erp_action->port->status); | 2725 | &erp_action->port->status); |
2630 | /* save a pointer to this port */ | 2726 | /* save a pointer to this port */ |
2631 | erp_action->fsf_req->data = (unsigned long) erp_action->port; | 2727 | erp_action->fsf_req->data = (unsigned long) erp_action->port; |
2632 | /* port to be closeed */ | 2728 | /* port to be closed */ |
2633 | erp_action->fsf_req->qtcb->header.port_handle = | 2729 | erp_action->fsf_req->qtcb->header.port_handle = |
2634 | erp_action->port->handle; | 2730 | erp_action->port->handle; |
2635 | erp_action->fsf_req->erp_action = erp_action; | 2731 | erp_action->fsf_req->erp_action = erp_action; |
@@ -2833,6 +2929,7 @@ zfcp_fsf_open_unit(struct zfcp_erp_action *erp_action) | |||
2833 | erp_action->port->handle; | 2929 | erp_action->port->handle; |
2834 | erp_action->fsf_req->qtcb->bottom.support.fcp_lun = | 2930 | erp_action->fsf_req->qtcb->bottom.support.fcp_lun = |
2835 | erp_action->unit->fcp_lun; | 2931 | erp_action->unit->fcp_lun; |
2932 | if (!(erp_action->adapter->connection_features & FSF_FEATURE_NPIV_MODE)) | ||
2836 | erp_action->fsf_req->qtcb->bottom.support.option = | 2933 | erp_action->fsf_req->qtcb->bottom.support.option = |
2837 | FSF_OPEN_LUN_SUPPRESS_BOXING; | 2934 | FSF_OPEN_LUN_SUPPRESS_BOXING; |
2838 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); | 2935 | atomic_set_mask(ZFCP_STATUS_COMMON_OPENING, &erp_action->unit->status); |
@@ -2880,7 +2977,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
2880 | struct fsf_qtcb_bottom_support *bottom; | 2977 | struct fsf_qtcb_bottom_support *bottom; |
2881 | struct fsf_queue_designator *queue_designator; | 2978 | struct fsf_queue_designator *queue_designator; |
2882 | u16 subtable, rule, counter; | 2979 | u16 subtable, rule, counter; |
2883 | u32 allowed, exclusive, readwrite; | 2980 | int exclusive, readwrite; |
2884 | 2981 | ||
2885 | unit = (struct zfcp_unit *) fsf_req->data; | 2982 | unit = (struct zfcp_unit *) fsf_req->data; |
2886 | 2983 | ||
@@ -2894,10 +2991,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
2894 | bottom = &fsf_req->qtcb->bottom.support; | 2991 | bottom = &fsf_req->qtcb->bottom.support; |
2895 | queue_designator = &header->fsf_status_qual.fsf_queue_designator; | 2992 | queue_designator = &header->fsf_status_qual.fsf_queue_designator; |
2896 | 2993 | ||
2897 | allowed = bottom->lun_access_info & FSF_UNIT_ACCESS_OPEN_LUN_ALLOWED; | ||
2898 | exclusive = bottom->lun_access_info & FSF_UNIT_ACCESS_EXCLUSIVE; | ||
2899 | readwrite = bottom->lun_access_info & FSF_UNIT_ACCESS_OUTBOUND_TRANSFER; | ||
2900 | |||
2901 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 2994 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | |
2902 | ZFCP_STATUS_UNIT_SHARED | | 2995 | ZFCP_STATUS_UNIT_SHARED | |
2903 | ZFCP_STATUS_UNIT_READONLY, | 2996 | ZFCP_STATUS_UNIT_READONLY, |
@@ -3071,10 +3164,15 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req) | |||
3071 | unit->handle); | 3164 | unit->handle); |
3072 | /* mark unit as open */ | 3165 | /* mark unit as open */ |
3073 | atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); | 3166 | atomic_set_mask(ZFCP_STATUS_COMMON_OPEN, &unit->status); |
3074 | atomic_clear_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED | | 3167 | |
3075 | ZFCP_STATUS_COMMON_ACCESS_BOXED, | 3168 | if (!(adapter->connection_features & FSF_FEATURE_NPIV_MODE) && |
3076 | &unit->status); | 3169 | (adapter->adapter_features & FSF_FEATURE_LUN_SHARING) && |
3077 | if (adapter->supported_features & FSF_FEATURE_LUN_SHARING){ | 3170 | (adapter->ccw_device->id.dev_model != ZFCP_DEVICE_MODEL_PRIV)) { |
3171 | exclusive = (bottom->lun_access_info & | ||
3172 | FSF_UNIT_ACCESS_EXCLUSIVE); | ||
3173 | readwrite = (bottom->lun_access_info & | ||
3174 | FSF_UNIT_ACCESS_OUTBOUND_TRANSFER); | ||
3175 | |||
3078 | if (!exclusive) | 3176 | if (!exclusive) |
3079 | atomic_set_mask(ZFCP_STATUS_UNIT_SHARED, | 3177 | atomic_set_mask(ZFCP_STATUS_UNIT_SHARED, |
3080 | &unit->status); | 3178 | &unit->status); |
@@ -4164,7 +4262,7 @@ zfcp_fsf_control_file(struct zfcp_adapter *adapter, | |||
4164 | int direction; | 4262 | int direction; |
4165 | int retval = 0; | 4263 | int retval = 0; |
4166 | 4264 | ||
4167 | if (!(adapter->supported_features & FSF_FEATURE_CFDC)) { | 4265 | if (!(adapter->adapter_features & FSF_FEATURE_CFDC)) { |
4168 | ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n", | 4266 | ZFCP_LOG_INFO("cfdc not supported (adapter %s)\n", |
4169 | zfcp_get_busid_by_adapter(adapter)); | 4267 | zfcp_get_busid_by_adapter(adapter)); |
4170 | retval = -EOPNOTSUPP; | 4268 | retval = -EOPNOTSUPP; |