]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.arch/s390-15-04-zfcp-unchained-sbals.patch
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / s390-15-04-zfcp-unchained-sbals.patch
CommitLineData
2cb7cef9
BS
1From: Gerald Schaefer <geraldsc@de.ibm.com>
2Subject: zfcp: Use only single SBAL commands from recovery
3References: bnc#518291,LTC#54462
4
5Symptom: Issuing an ELS request might not detect a stalled
6 outbound queue
7Problem: zfcp uses chained SBALs for ELS requests leading to the
8 situation that the ELS request gets one free SBAL, but
9 not the following ones. In this situation the ELS request
10 fails but does not trigger the error handling for the
11 stalled queue.
12Solution: Use unchained SBALs where possible, especially for
13 commands from the erp. This guarantees that each erp
14 command will get the required SBAL or trigger queue
15 recovery.
16
17Acked-by: John Jolly <jjolly@suse.de>
18---
19 drivers/s390/scsi/zfcp_fsf.c | 33 +++++++++++++++++++++++++--------
20 1 file changed, 25 insertions(+), 8 deletions(-)
21
22--- a/drivers/s390/scsi/zfcp_fsf.c 2009-07-01 12:26:28.000000000 +0200
23+++ b/drivers/s390/scsi/zfcp_fsf.c 2009-07-01 12:28:43.000000000 +0200
24@@ -1012,6 +1012,23 @@ skip_fsfstatus:
25 send_ct->handler(send_ct->handler_data);
26 }
27
28+static void zfcp_fsf_setup_ct_els_unchained(struct qdio_buffer_element *sbale,
29+ struct scatterlist *sg_req,
30+ struct scatterlist *sg_resp)
31+{
32+ sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
33+ sbale[2].addr = sg_virt(sg_req);
34+ sbale[2].length = sg_req->length;
35+ sbale[3].addr = sg_virt(sg_resp);
36+ sbale[3].length = sg_resp->length;
37+ sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
38+}
39+
40+static int zfcp_fsf_one_sbal(struct scatterlist *sg)
41+{
42+ return sg_is_last(sg) && sg->length <= PAGE_SIZE;
43+}
44+
45 static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
46 struct scatterlist *sg_req,
47 struct scatterlist *sg_resp,
48@@ -1022,16 +1039,16 @@ static int zfcp_fsf_setup_ct_els_sbals(s
49 int bytes;
50
51 if (!(feat & FSF_FEATURE_ELS_CT_CHAINED_SBALS)) {
52- if (sg_req->length > PAGE_SIZE || sg_resp->length > PAGE_SIZE ||
53- !sg_is_last(sg_req) || !sg_is_last(sg_resp))
54+ if (!zfcp_fsf_one_sbal(sg_req) || !zfcp_fsf_one_sbal(sg_resp))
55 return -EOPNOTSUPP;
56
57- sbale[0].flags |= SBAL_FLAGS0_TYPE_WRITE_READ;
58- sbale[2].addr = sg_virt(sg_req);
59- sbale[2].length = sg_req->length;
60- sbale[3].addr = sg_virt(sg_resp);
61- sbale[3].length = sg_resp->length;
62- sbale[3].flags |= SBAL_FLAGS_LAST_ENTRY;
63+ zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);
64+ return 0;
65+ }
66+
67+ /* use single, unchained SBAL if it can hold the request */
68+ if (zfcp_fsf_one_sbal(sg_req) && zfcp_fsf_one_sbal(sg_resp)) {
69+ zfcp_fsf_setup_ct_els_unchained(sbale, sg_req, sg_resp);
70 return 0;
71 }
72