]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/libata-ata_piix-use-slave_link
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / libata-ata_piix-use-slave_link
1 From be77e43abb433c2d6f2fc69352289e34dcbf040a Mon Sep 17 00:00:00 2001
2 From: Tejun Heo <tj@kernel.org>
3 Date: Thu, 31 Jul 2008 17:02:44 +0900
4 Subject: [PATCH] ata_piix: drop merged SCR access and use slave_link instead
5 References: bnc#441420
6
7 Now that libata has slave_link, there's no need to keep ugly merged
8 SCR access. Drop it and use slave_link instead. This results in
9 simpler code and much better separate link handling for master and
10 slave.
11
12 Signed-off-by: Tejun Heo <tj@kernel.org>
13 Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
14 Signed-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 */