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.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 17620ecda33..9bba56b1683 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -1013,12 +1013,29 @@ skip_fsfstatus:
1013 send_ct->handler(send_ct->handler_data); 1013 send_ct->handler(send_ct->handler_data);
1014} 1014}
1015 1015
1016static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, 1016static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
1017 struct scatterlist *sg_req, 1017 struct scatterlist *sg_req,
1018 struct scatterlist *sg_resp, int max_sbals) 1018 struct scatterlist *sg_resp,
1019 int max_sbals)
1019{ 1020{
1021 struct qdio_buffer_element *sbale = zfcp_qdio_sbale_req(req);
1022 u32 feat = req->adapter->adapter_features;
1020 int bytes; 1023 int bytes;
1021 1024
1025 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
1026 if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE ||
1027 !sg_is_last(sg_req) || !sg_is_last(sg_resp))
1028 return -EOPNOTSUPP;
1029
1030 sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
1031 sbale[2].addr = sg_virt(sg_req);
1032 sbale[2].length = sg_req->length;
1033 sbale[3].addr = sg_virt(sg_resp);
1034 sbale[3].length = sg_resp->length;
1035 sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
1036 return 0;
1037 }
1038
1022 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ, 1039 bytes = zfcp_qdio_sbals_from_sg(req, SBAL_FLAGS0_TYPE_WRITE_READ,
1023 sg_req, max_sbals); 1040 sg_req, max_sbals);
1024 if (bytes <= 0) 1041 if (bytes <= 0)
@@ -1060,8 +1077,8 @@ int zfcp_fsf_send_ct(struct zfcp_send_ct *ct, mempool_t *pool,
1060 goto out; 1077 goto out;
1061 } 1078 }
1062 1079
1063 ret = zfcp_fsf_setup_sbals(req, ct->req, ct->resp, 1080 ret = zfcp_fsf_setup_ct_els_sbals(req, ct->req, ct->resp,
1064 FSF_MAX_SBALS_PER_REQ); 1081 FSF_MAX_SBALS_PER_REQ);
1065 if (ret) 1082 if (ret)
1066 goto failed_send; 1083 goto failed_send;
1067 1084
@@ -1171,7 +1188,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els)
1171 goto out; 1188 goto out;
1172 } 1189 }
1173 1190
1174 ret = zfcp_fsf_setup_sbals(req, els->req, els->resp, 2); 1191 ret = zfcp_fsf_setup_ct_els_sbals(req, els->req, els->resp, 2);
1175 1192
1176 if (ret) 1193 if (ret)
1177 goto failed_send; 1194 goto failed_send;
@@ -1440,7 +1457,8 @@ static void zfcp_fsf_open_port_handler(struct zfcp_fsf_req *req)
1440 * Alternately, an ADISC/PDISC ELS should suffice, as well. 1457 * Alternately, an ADISC/PDISC ELS should suffice, as well.
1441 */ 1458 */
1442 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els; 1459 plogi = (struct fsf_plogi *) req->qtcb->bottom.support.els;
1443 if (req->qtcb->bottom.support.els1_length >= sizeof(*plogi)) { 1460 if (req->qtcb->bottom.support.els1_length >=
1461 FSF_PLOGI_MIN_LEN) {
1444 if (plogi->serv_param.wwpn != port->wwpn) 1462 if (plogi->serv_param.wwpn != port->wwpn)
1445 port->d_id = 0; 1463 port->d_id = 0;
1446 else { 1464 else {