aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/scsi/zfcp_fsf.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index c57658f3d34..47795fbf081 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -670,8 +670,11 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter)
670 zfcp_fsf_sbal_check(adapter), 5 * HZ); 670 zfcp_fsf_sbal_check(adapter), 5 * HZ);
671 if (ret > 0) 671 if (ret > 0)
672 return 0; 672 return 0;
673 if (!ret) 673 if (!ret) {
674 atomic_inc(&adapter->qdio_outb_full); 674 atomic_inc(&adapter->qdio_outb_full);
675 /* assume hanging outbound queue, try queue recovery */
676 zfcp_erp_adapter_reopen(adapter, 0, "fsrsg_1", NULL);
677 }
675 678
676 spin_lock_bh(&adapter->req_q_lock); 679 spin_lock_bh(&adapter->req_q_lock);
677 return -EIO; 680 return -EIO;
@@ -722,7 +725,7 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_adapter *adapter,
722 req = zfcp_fsf_alloc_qtcb(pool); 725 req = zfcp_fsf_alloc_qtcb(pool);
723 726
724 if (unlikely(!req)) 727 if (unlikely(!req))
725 return ERR_PTR(-EIO); 728 return ERR_PTR(-ENOMEM);
726 729
727 if (adapter->req_no == 0) 730 if (adapter->req_no == 0)
728 adapter->req_no++; 731 adapter->req_no++;
@@ -1010,6 +1013,23 @@ skip_fsfstatus:
1010 send_ct->handler(send_ct->handler_data); 1013 send_ct->handler(send_ct->handler_data);
1011} 1014}
1012 1015
1016static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale,
1017 struct scatterlist *sg_req,
1018 struct scatterlist *sg_resp)
1019{
1020 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
1021 sbale[2].addr = sg_virt(sg_req);
1022 sbale[2].length = sg_req->length;
1023 sbale[3].addr = sg_virt(sg_resp);
1024 sbale[3].length = sg_resp->length;
1025 sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
1026}
1027
1028static int zfcp_fsf_one_sbal(struct scatterlist *sg)
1029{
1030 return sg_is_last(sg) && sg->length <= PAGE_SIZE;
1031}
1032
1013static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req, 1033static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1014 struct scatterlist *sg_req, 1034 struct scatterlist *sg_req,
1015 struct scatterlist *sg_resp, 1035 struct scatterlist *sg_resp,
@@ -1020,30 +1040,30 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1020 int bytes; 1040 int bytes;
1021 1041
1022 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) { 1042 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
1023 if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE || 1043 if (!zfcp_fsf_one_sbal(sg_req) || !zfcp_fsf_one_sbal(sg_resp))
1024 !sg_is_last(sg_req) || !sg_is_last(sg_resp))
1025 return -EOPNOTSUPP; 1044 return -EOPNOTSUPP;
1026 1045
1027 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ; 1046 zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);
1028 sbale[2].addr = sg_virt(sg_req); 1047 return 0;
1029 sbale[2].length = sg_req->length; 1048 }
1030 sbale[3].addr = sg_virt(sg_resp); 1049
1031 sbale[3].length = sg_resp->length; 1050 /* use single, unchained SBAL if it can hold the request */
1032 sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY; 1051 if (zfcp_fsf_one_sbal(sg_req) && zfcp_fsf_one_sbal(sg_resp)) {
1052 zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);
1033 return 0; 1053 return 0;
1034 } 1054 }
1035 1055
1036 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, 1056 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
1037 sg_req, max_sbals); 1057 sg_req, max_sbals);
1038 if (bytes <= 0) 1058 if (bytes <= 0)
1039 return -ENOMEM; 1059 return -EIO;
1040 req->qtcb->bottom.support.req_buf_length = bytes; 1060 req->qtcb->bottom.support.req_buf_length = bytes;
1041 req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL; 1061 req->sbale_curr = ZFCP_LAST_SBALE_PER_SBAL;
1042 1062
1043 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, 1063 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
1044 sg_resp, max_sbals); 1064 sg_resp, max_sbals);
1045 if (bytes <= 0) 1065 if (bytes <= 0)
1046 return -ENOMEM; 1066 return -EIO;
1047 req->qtcb->bottom.support.resp_buf_length = bytes; 1067 req->qtcb->bottom.support.resp_buf_length = bytes;
1048 1068
1049 return 0; 1069 return 0;
@@ -1607,10 +1627,10 @@ static void zfcp_fsf_open_wka_port_handler(struct zfcp_fsf_req *req)
1607 case FSF_ACCESS_DENIED: 1627 case FSF_ACCESS_DENIED:
1608 wka_port->status = ZFCP_WKA_PORT_OFFLINE; 1628 wka_port->status = ZFCP_WKA_PORT_OFFLINE;
1609 break; 1629 break;
1610 case FSF_PORT_ALREADY_OPEN:
1611 break;
1612 case FSF_GOOD: 1630 case FSF_GOOD:
1613 wka_port->handle = header->port_handle; 1631 wka_port->handle = header->port_handle;
1632 /* fall through */
1633 case FSF_PORT_ALREADY_OPEN:
1614 wka_port->status = ZFCP_WKA_PORT_ONLINE; 1634 wka_port->status = ZFCP_WKA_PORT_ONLINE;
1615 } 1635 }
1616out: 1636out:
@@ -1731,15 +1751,16 @@ static void zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *req)
1731 zfcp_fsf_access_denied_port(req, port); 1751 zfcp_fsf_access_denied_port(req, port);
1732 break; 1752 break;
1733 case FSF_PORT_BOXED: 1753 case FSF_PORT_BOXED:
1734 zfcp_erp_port_boxed(port, "fscpph2", req);
1735 req->status |= ZFCP_STATUS_FSFREQ_ERROR |
1736 ZFCP_STATUS_FSFREQ_RETRY;
1737 /* can't use generic zfcp_erp_modify_port_status because 1754 /* can't use generic zfcp_erp_modify_port_status because
1738 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */ 1755 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
1739 atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status); 1756 atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
1740 list_for_each_entry(unit, &port->unit_list_head, list) 1757 list_for_each_entry(unit, &port->unit_list_head, list)
1741 atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN, 1758 atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
1742 &unit->status); 1759 &unit->status);
1760 zfcp_erp_port_boxed(port, "fscpph2", req);
1761 req->status |= ZFCP_STATUS_FSFREQ_ERROR |
1762 ZFCP_STATUS_FSFREQ_RETRY;
1763
1743 break; 1764 break;
1744 case FSF_ADAPTER_STATUS_AVAILABLE: 1765 case FSF_ADAPTER_STATUS_AVAILABLE:
1745 switch (header->fsf_status_qual.word[0]) { 1766 switch (header->fsf_status_qual.word[0]) {
@@ -2541,7 +2562,6 @@ struct zfcp_fsf_req *zfcp_fsf_control_file(struct zfcp_adapter *adapter,
2541 bytes = zfcp_qdio_sbals_from_sg(req, direction, fsf_cfdc->sg, 2562 bytes = zfcp_qdio_sbals_from_sg(req, direction, fsf_cfdc->sg,
2542 FSF_MAX_SBALS_PER_REQ); 2563 FSF_MAX_SBALS_PER_REQ);
2543 if (bytes != ZFCP_CFDC_MAX_SIZE) { 2564 if (bytes != ZFCP_CFDC_MAX_SIZE) {
2544 retval = -ENOMEM;
2545 zfcp_fsf_req_free(req); 2565 zfcp_fsf_req_free(req);
2546 goto out; 2566 goto out;
2547 } 2567 }