diff options
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.patch | 116 |
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 @@ | |||
1 | From 65719aa5de077d1ccbfe535e9b934d6e91d11601 Mon Sep 17 00:00:00 2001 | ||
2 | From: Dan Williams <dan.j.williams@intel.com> | ||
3 | Date: Fri, 22 Jun 2012 10:52:34 -0700 | ||
4 | Subject: [PATCH 035/109] libsas: fix taskfile corruption in | ||
5 | sas_ata_qc_fill_rtf | ||
6 | |||
7 | commit 6ef1b512f4e6f936d89aa20be3d97a7ec7c290ac upstream. | ||
8 | |||
9 | fill_result_tf() grabs the taskfile flags from the originating qc which | ||
10 | sas_ata_qc_fill_rtf() promptly overwrites. The presence of an | ||
11 | ata_taskfile in the sata_device makes it tempting to just copy the full | ||
12 | contents in sas_ata_qc_fill_rtf(). However, libata really only wants | ||
13 | the fis contents and expects the other portions of the taskfile to not | ||
14 | be touched by ->qc_fill_rtf. To that end store a fis buffer in the | ||
15 | sata_device and use ata_tf_from_fis() like every other ->qc_fill_rtf() | ||
16 | implementation. | ||
17 | |||
18 | Reported-by: Praveen Murali <pmurali@logicube.com> | ||
19 | Tested-by: Praveen Murali <pmurali@logicube.com> | ||
20 | Signed-off-by: Dan Williams <dan.j.williams@intel.com> | ||
21 | Signed-off-by: James Bottomley <JBottomley@Parallels.com> | ||
22 | [bwh: Backported to 3.2: adjust context] | ||
23 | Signed-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 | |||
30 | diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c | ||
31 | index 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 | } | ||
43 | diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c | ||
44 | index 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 | |||
83 | diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h | ||
84 | index 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 | -- | ||
115 | 1.7.7.6 | ||
116 | |||