diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2008-12-19 10:57:01 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-12-29 12:38:28 -0500 |
commit | 39eb7e9aca2a582330ddb6f1167272268e6b3965 (patch) | |
tree | 59045a1bdcb5d48286f244dc700482495973a018 /drivers/s390/scsi/zfcp_fsf.c | |
parent | b225cf9b8040849e16add4da8e84a72a3548ada8 (diff) |
[SCSI] zfcp: Add support for unchained FSF requests
Add the support to send CT and ELS requests as unchained FSF requests. This is
required for older hardware and was somehow omitted during the cleanup of the
FSF layer. The req_count and resp_count attributes are unused, so remove them
instead of adding a special case for setting them. Also add debug data and a
warning, when the ct request hits a limit.
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Acked-by: Martin Petermann <martin@linux.vnet.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 17620ecda335..9bba56b16831 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 | ||
1016 | static int zfcp_fsf_setup_sbals(struct zfcp_fsf_req *req, | 1016 | static 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 { |