]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.drivers/libata-ata_piix-use-slave_link
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / libata-ata_piix-use-slave_link
CommitLineData
00e5a55c
BS
1From be77e43abb433c2d6f2fc69352289e34dcbf040a Mon Sep 17 00:00:00 2001
2From: Tejun Heo <tj@kernel.org>
3Date: Thu, 31 Jul 2008 17:02:44 +0900
4Subject: [PATCH] ata_piix: drop merged SCR access and use slave_link instead
5References: bnc#441420
6
7Now that libata has slave_link, there's no need to keep ugly merged
8SCR access. Drop it and use slave_link instead. This results in
9simpler code and much better separate link handling for master and
10slave.
11
12Signed-off-by: Tejun Heo <tj@kernel.org>
13Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
14Signed-off-by: Tejun Heo <teheo@suse.de>
15---
16 drivers/ata/ata_piix.c | 168 +++++++++++--------------------------------------
17 1 file changed, 41 insertions(+), 127 deletions(-)
18
19--- a/drivers/ata/ata_piix.c
20+++ b/drivers/ata/ata_piix.c
21@@ -887,23 +887,9 @@ static void ich_set_dmamode(struct ata_p
22 * Serial ATA Index/Data Pair Superset Registers access
23 *
24 * Beginning from ICH8, there's a sane way to access SCRs using index
25- * and data register pair located at BAR5. This creates an
26- * interesting problem of mapping two SCRs to one port.
27- *
28- * Although they have separate SCRs, the master and slave aren't
29- * independent enough to be treated as separate links - e.g. softreset
30- * resets both. Also, there's no protocol defined for hard resetting
31- * singled device sharing the virtual port (no defined way to acquire
32- * device signature). This is worked around by merging the SCR values
33- * into one sensible value and requesting follow-up SRST after
34- * hardreset.
35- *
36- * SCR merging is perfomed in nibbles which is the unit contents in
37- * SCRs are organized. If two values are equal, the value is used.
38- * When they differ, merge table which lists precedence of possible
39- * values is consulted and the first match or the last entry when
40- * nothing matches is used. When there's no merge table for the
41- * specific nibble, value from the first port is used.
42+ * and data register pair located at BAR5 which means that we have
43+ * separate SCRs for master and slave. This is handled using libata
44+ * slave_link facility.
45 */
46 static const int piix_sidx_map[] = {
47 [SCR_STATUS] = 0,
48@@ -911,125 +897,38 @@ static const int piix_sidx_map[] = {
49 [SCR_CONTROL] = 1,
50 };
51
52-static void piix_sidpr_sel(struct ata_device *dev, unsigned int reg)
53+static void piix_sidpr_sel(struct ata_link *link, unsigned int reg)
54 {
55- struct ata_port *ap = dev->link->ap;
56+ struct ata_port *ap = link->ap;
57 struct piix_host_priv *hpriv = ap->host->private_data;
58
59- iowrite32(((ap->port_no * 2 + dev->devno) << 8) | piix_sidx_map[reg],
60+ iowrite32(((ap->port_no * 2 + link->pmp) << 8) | piix_sidx_map[reg],
61 hpriv->sidpr + PIIX_SIDPR_IDX);
62 }
63
64-static int piix_sidpr_read(struct ata_device *dev, unsigned int reg)
65-{
66- struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
67-
68- piix_sidpr_sel(dev, reg);
69- return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
70-}
71-
72-static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val)
73-{
74- struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
75-
76- piix_sidpr_sel(dev, reg);
77- iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
78-}
79-
80-static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
81-{
82- u32 val = 0;
83- int i, mi;
84-
85- for (i = 0, mi = 0; i < 32 / 4; i++) {
86- u8 c0 = (val0 >> (i * 4)) & 0xf;
87- u8 c1 = (val1 >> (i * 4)) & 0xf;
88- u8 merged = c0;
89- const int *cur;
90-
91- /* if no merge preference, assume the first value */
92- cur = merge_tbl[mi];
93- if (!cur)
94- goto done;
95- mi++;
96-
97- /* if two values equal, use it */
98- if (c0 == c1)
99- goto done;
100-
101- /* choose the first match or the last from the merge table */
102- while (*cur != -1) {
103- if (c0 == *cur || c1 == *cur)
104- break;
105- cur++;
106- }
107- if (*cur == -1)
108- cur--;
109- merged = *cur;
110- done:
111- val |= merged << (i * 4);
112- }
113-
114- return val;
115-}
116-
117 static int piix_sidpr_scr_read(struct ata_link *link,
118 unsigned int reg, u32 *val)
119 {
120- struct ata_port *ap = link->ap;
121- const int * const sstatus_merge_tbl[] = {
122- /* DET */ (const int []){ 1, 3, 0, 4, 3, -1 },
123- /* SPD */ (const int []){ 2, 1, 0, -1 },
124- /* IPM */ (const int []){ 6, 2, 1, 0, -1 },
125- NULL,
126- };
127- const int * const scontrol_merge_tbl[] = {
128- /* DET */ (const int []){ 1, 0, 4, 0, -1 },
129- /* SPD */ (const int []){ 0, 2, 1, 0, -1 },
130- /* IPM */ (const int []){ 0, 1, 2, 3, 0, -1 },
131- NULL,
132- };
133- u32 v0, v1;
134+ struct piix_host_priv *hpriv = link->ap->host->private_data;
135
136 if (reg >= ARRAY_SIZE(piix_sidx_map))
137 return -EINVAL;
138
139- if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) {
140- *val = piix_sidpr_read(&ap->link.device[0], reg);
141- return 0;
142- }
143-
144- v0 = piix_sidpr_read(&ap->link.device[0], reg);
145- v1 = piix_sidpr_read(&ap->link.device[1], reg);
146-
147- switch (reg) {
148- case SCR_STATUS:
149- *val = piix_merge_scr(v0, v1, sstatus_merge_tbl);
150- break;
151- case SCR_ERROR:
152- *val = v0 | v1;
153- break;
154- case SCR_CONTROL:
155- *val = piix_merge_scr(v0, v1, scontrol_merge_tbl);
156- break;
157- }
158-
159+ piix_sidpr_sel(link, reg);
160+ *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
161 return 0;
162 }
163
164 static int piix_sidpr_scr_write(struct ata_link *link,
165 unsigned int reg, u32 val)
166 {
167- struct ata_port *ap = link->ap;
168+ struct piix_host_priv *hpriv = link->ap->host->private_data;
169
170 if (reg >= ARRAY_SIZE(piix_sidx_map))
171 return -EINVAL;
172
173- piix_sidpr_write(&ap->link.device[0], reg, val);
174-
175- if (ap->flags & ATA_FLAG_SLAVE_POSS)
176- piix_sidpr_write(&ap->link.device[1], reg, val);
177-
178+ piix_sidpr_sel(link, reg);
179+ iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
180 return 0;
181 }
182
183@@ -1403,32 +1302,33 @@ static bool piix_no_sidpr(struct ata_hos
184 return false;
185 }
186
187-static void __devinit piix_init_sidpr(struct ata_host *host)
188+static int __devinit piix_init_sidpr(struct ata_host *host)
189 {
190 struct pci_dev *pdev = to_pci_dev(host->dev);
191 struct piix_host_priv *hpriv = host->private_data;
192- struct ata_device *dev0 = &host->ports[0]->link.device[0];
193+ struct ata_link *link0 = &host->ports[0]->link;
194 u32 scontrol;
195 int i;
196+ int rc;
197
198 /* check for availability */
199 for (i = 0; i < 4; i++)
200 if (hpriv->map[i] == IDE)
201- return;
202+ return 0;
203
204 /* is it blacklisted? */
205 if (piix_no_sidpr(host))
206- return;
207+ return 0;
208
209 if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
210- return;
211+ return 0;
212
213 if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
214 pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
215- return;
216+ return 0;
217
218 if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
219- return;
220+ return 0;
221
222 hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
223
224@@ -1436,7 +1336,7 @@ static void __devinit piix_init_sidpr(st
225 * Give it a test drive by inhibiting power save modes which
226 * we'll do anyway.
227 */
228- scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
229+ piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
230
231 /* if IPM is already 3, SCR access is probably working. Don't
232 * un-inhibit power save modes as BIOS might have inhibited
233@@ -1444,18 +1344,30 @@ static void __devinit piix_init_sidpr(st
234 */
235 if ((scontrol & 0xf00) != 0x300) {
236 scontrol |= 0x300;
237- piix_sidpr_write(dev0, SCR_CONTROL, scontrol);
238- scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
239+ piix_sidpr_scr_write(link0, SCR_CONTROL, scontrol);
240+ piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
241
242 if ((scontrol & 0xf00) != 0x300) {
243 dev_printk(KERN_INFO, host->dev, "SCR access via "
244 "SIDPR is available but doesn't work\n");
245- return;
246+ return 0;
247 }
248 }
249
250- host->ports[0]->ops = &piix_sidpr_sata_ops;
251- host->ports[1]->ops = &piix_sidpr_sata_ops;
252+ /* okay, SCRs available, set ops and ask libata for slave_link */
253+ for (i = 0; i < 2; i++) {
254+ struct ata_port *ap = host->ports[i];
255+
256+ ap->ops = &piix_sidpr_sata_ops;
257+
258+ if (ap->flags & ATA_FLAG_SLAVE_POSS) {
259+ rc = ata_slave_link_init(ap);
260+ if (rc)
261+ return rc;
262+ }
263+ }
264+
265+ return 0;
266 }
267
268 static void piix_iocfg_bit18_quirk(struct pci_dev *pdev)
269@@ -1565,7 +1477,9 @@ static int __devinit piix_init_one(struc
270 /* initialize controller */
271 if (port_flags & ATA_FLAG_SATA) {
272 piix_init_pcs(host, piix_map_db_table[ent->driver_data]);
273- piix_init_sidpr(host);
274+ rc = piix_init_sidpr(host);
275+ if (rc)
276+ return rc;
277 }
278
279 /* apply IOCFG bit18 quirk */