summaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0035-libsas-fix-taskfile-corruption-in-sas_ata_qc_fill_rt.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0035-libsas-fix-taskfile-corruption-in-sas_ata_qc_fill_rt.patch')
-rw-r--r--recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0035-libsas-fix-taskfile-corruption-in-sas_ata_qc_fill_rt.patch116
1 files changed, 116 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0035-libsas-fix-taskfile-corruption-in-sas_ata_qc_fill_rt.patch b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0035-libsas-fix-taskfile-corruption-in-sas_ata_qc_fill_rt.patch
new file mode 100644
index 00000000..88c76273
--- /dev/null
+++ b/recipes-kernel/linux/linux-ti33x-psp-3.2/3.2.24/0035-libsas-fix-taskfile-corruption-in-sas_ata_qc_fill_rt.patch
@@ -0,0 +1,116 @@
1From 65719aa5de077d1ccbfe535e9b934d6e91d11601 Mon Sep 17 00:00:00 2001
2From: Dan Williams <dan.j.williams@intel.com>
3Date: Fri, 22 Jun 2012 10:52:34 -0700
4Subject: [PATCH 035/109] libsas: fix taskfile corruption in
5 sas_ata_qc_fill_rtf
6
7commit 6ef1b512f4e6f936d89aa20be3d97a7ec7c290ac upstream.
8
9fill_result_tf() grabs the taskfile flags from the originating qc which
10sas_ata_qc_fill_rtf() promptly overwrites. The presence of an
11ata_taskfile in the sata_device makes it tempting to just copy the full
12contents in sas_ata_qc_fill_rtf(). However, libata really only wants
13the fis contents and expects the other portions of the taskfile to not
14be touched by ->qc_fill_rtf. To that end store a fis buffer in the
15sata_device and use ata_tf_from_fis() like every other ->qc_fill_rtf()
16implementation.
17
18Reported-by: Praveen Murali <pmurali@logicube.com>
19Tested-by: Praveen Murali <pmurali@logicube.com>
20Signed-off-by: Dan Williams <dan.j.williams@intel.com>
21Signed-off-by: James Bottomley <JBottomley@Parallels.com>
22[bwh: Backported to 3.2: adjust context]
23Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
24---
25 drivers/scsi/aic94xx/aic94xx_task.c | 2 +-
26 drivers/scsi/libsas/sas_ata.c | 12 ++++++------
27 include/scsi/libsas.h | 6 ++++--
28 3 files changed, 11 insertions(+), 9 deletions(-)
29
30diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
31index 532d212..393e7ce 100644
32--- a/drivers/scsi/aic94xx/aic94xx_task.c
33+++ b/drivers/scsi/aic94xx/aic94xx_task.c
34@@ -201,7 +201,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb,
35
36 if (SAS_STATUS_BUF_SIZE >= sizeof(*resp)) {
37 resp->frame_len = le16_to_cpu(*(__le16 *)(r+6));
38- memcpy(&resp->ending_fis[0], r+16, 24);
39+ memcpy(&resp->ending_fis[0], r+16, ATA_RESP_FIS_SIZE);
40 ts->buf_valid_size = sizeof(*resp);
41 }
42 }
43diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
44index db9238f..4868fc9 100644
45--- a/drivers/scsi/libsas/sas_ata.c
46+++ b/drivers/scsi/libsas/sas_ata.c
47@@ -112,12 +112,12 @@ static void sas_ata_task_done(struct sas_task *task)
48 if (stat->stat == SAS_PROTO_RESPONSE || stat->stat == SAM_STAT_GOOD ||
49 ((stat->stat == SAM_STAT_CHECK_CONDITION &&
50 dev->sata_dev.command_set == ATAPI_COMMAND_SET))) {
51- ata_tf_from_fis(resp->ending_fis, &dev->sata_dev.tf);
52+ memcpy(dev->sata_dev.fis, resp->ending_fis, ATA_RESP_FIS_SIZE);
53
54 if (!link->sactive) {
55- qc->err_mask |= ac_err_mask(dev->sata_dev.tf.command);
56+ qc->err_mask |= ac_err_mask(dev->sata_dev.fis[2]);
57 } else {
58- link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.tf.command);
59+ link->eh_info.err_mask |= ac_err_mask(dev->sata_dev.fis[2]);
60 if (unlikely(link->eh_info.err_mask))
61 qc->flags |= ATA_QCFLAG_FAILED;
62 }
63@@ -138,8 +138,8 @@ static void sas_ata_task_done(struct sas_task *task)
64 qc->flags |= ATA_QCFLAG_FAILED;
65 }
66
67- dev->sata_dev.tf.feature = 0x04; /* status err */
68- dev->sata_dev.tf.command = ATA_ERR;
69+ dev->sata_dev.fis[3] = 0x04; /* status err */
70+ dev->sata_dev.fis[2] = ATA_ERR;
71 }
72 }
73
74@@ -252,7 +252,7 @@ static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc)
75 {
76 struct domain_device *dev = qc->ap->private_data;
77
78- memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf));
79+ ata_tf_from_fis(dev->sata_dev.fis, &qc->result_tf);
80 return true;
81 }
82
83diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
84index 6a308d4..1e100c6 100644
85--- a/include/scsi/libsas.h
86+++ b/include/scsi/libsas.h
87@@ -159,6 +159,8 @@ enum ata_command_set {
88 ATAPI_COMMAND_SET = 1,
89 };
90
91+#define ATA_RESP_FIS_SIZE 24
92+
93 struct sata_device {
94 enum ata_command_set command_set;
95 struct smp_resp rps_resp; /* report_phy_sata_resp */
96@@ -170,7 +172,7 @@ struct sata_device {
97
98 struct ata_port *ap;
99 struct ata_host ata_host;
100- struct ata_taskfile tf;
101+ u8 fis[ATA_RESP_FIS_SIZE];
102 u32 sstatus;
103 u32 serror;
104 u32 scontrol;
105@@ -486,7 +488,7 @@ enum exec_status {
106 */
107 struct ata_task_resp {
108 u16 frame_len;
109- u8 ending_fis[24]; /* dev to host or data-in */
110+ u8 ending_fis[ATA_RESP_FIS_SIZE]; /* dev to host or data-in */
111 u32 sstatus;
112 u32 serror;
113 u32 scontrol;
114--
1151.7.7.6
116