]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.39/patches.arch/s390-15-04-zfcp-unchained-sbals.patch
Fix oinkmaster patch.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.arch / s390-15-04-zfcp-unchained-sbals.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: zfcp: Use only single SBAL commands from recovery
3 References: bnc#518291,LTC#54462
4
5 Symptom: Issuing an ELS request might not detect a stalled
6 outbound queue
7 Problem: 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.
12 Solution: 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
17 Acked-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