diff options
author | Maxim Shchetynin <maxim@de.ibm.com> | 2005-09-13 15:51:16 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.(none)> | 2005-09-19 14:03:45 -0400 |
commit | aef4a983090fa590481a86d9690dc3fa6bb121fa (patch) | |
tree | 12b78b227102dc2f41dda227fe83f34a8838e015 /drivers/s390/scsi/zfcp_fsf.c | |
parent | 8a36e4532ea10471f0a8605207d071361d7be2c3 (diff) |
[SCSI] zfcp: provide support for NPIV
N_Port ID Virtualization (NPIV) allows a single FCP port to appear as
multiple, distinct ports providing separate port identification. NPIV
is supported by FC HBAs on System z9. zfcp was adapted to support this
new feature.
Signed-off-by: Andreas Herrmann <aherrman@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
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; |