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
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
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>
16 drivers/ata/ata_piix.c | 168 +++++++++++--------------------------------------
17 1 file changed, 41 insertions(+), 127 deletions(-)
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
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.
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
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.
46 static const int piix_sidx_map[] = {
48 @@ -911,125 +897,38 @@ static const int piix_sidx_map[] = {
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)
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;
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);
64 -static int piix_sidpr_read(struct ata_device *dev, unsigned int reg)
66 - struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
68 - piix_sidpr_sel(dev, reg);
69 - return ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
72 -static void piix_sidpr_write(struct ata_device *dev, unsigned int reg, u32 val)
74 - struct piix_host_priv *hpriv = dev->link->ap->host->private_data;
76 - piix_sidpr_sel(dev, reg);
77 - iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
80 -static u32 piix_merge_scr(u32 val0, u32 val1, const int * const *merge_tbl)
85 - for (i = 0, mi = 0; i < 32 / 4; i++) {
86 - u8 c0 = (val0 >> (i * 4)) & 0xf;
87 - u8 c1 = (val1 >> (i * 4)) & 0xf;
91 - /* if no merge preference, assume the first value */
92 - cur = merge_tbl[mi];
97 - /* if two values equal, use it */
101 - /* choose the first match or the last from the merge table */
102 - while (*cur != -1) {
103 - if (c0 == *cur || c1 == *cur)
111 - val |= merged << (i * 4);
117 static int piix_sidpr_scr_read(struct ata_link *link,
118 unsigned int reg, u32 *val)
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 },
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 },
134 + struct piix_host_priv *hpriv = link->ap->host->private_data;
136 if (reg >= ARRAY_SIZE(piix_sidx_map))
139 - if (!(ap->flags & ATA_FLAG_SLAVE_POSS)) {
140 - *val = piix_sidpr_read(&ap->link.device[0], reg);
144 - v0 = piix_sidpr_read(&ap->link.device[0], reg);
145 - v1 = piix_sidpr_read(&ap->link.device[1], reg);
149 - *val = piix_merge_scr(v0, v1, sstatus_merge_tbl);
155 - *val = piix_merge_scr(v0, v1, scontrol_merge_tbl);
159 + piix_sidpr_sel(link, reg);
160 + *val = ioread32(hpriv->sidpr + PIIX_SIDPR_DATA);
164 static int piix_sidpr_scr_write(struct ata_link *link,
165 unsigned int reg, u32 val)
167 - struct ata_port *ap = link->ap;
168 + struct piix_host_priv *hpriv = link->ap->host->private_data;
170 if (reg >= ARRAY_SIZE(piix_sidx_map))
173 - piix_sidpr_write(&ap->link.device[0], reg, val);
175 - if (ap->flags & ATA_FLAG_SLAVE_POSS)
176 - piix_sidpr_write(&ap->link.device[1], reg, val);
178 + piix_sidpr_sel(link, reg);
179 + iowrite32(val, hpriv->sidpr + PIIX_SIDPR_DATA);
183 @@ -1403,32 +1302,33 @@ static bool piix_no_sidpr(struct ata_hos
187 -static void __devinit piix_init_sidpr(struct ata_host *host)
188 +static int __devinit piix_init_sidpr(struct ata_host *host)
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;
198 /* check for availability */
199 for (i = 0; i < 4; i++)
200 if (hpriv->map[i] == IDE)
204 /* is it blacklisted? */
205 if (piix_no_sidpr(host))
209 if (!(host->ports[0]->flags & PIIX_FLAG_SIDPR))
213 if (pci_resource_start(pdev, PIIX_SIDPR_BAR) == 0 ||
214 pci_resource_len(pdev, PIIX_SIDPR_BAR) != PIIX_SIDPR_LEN)
218 if (pcim_iomap_regions(pdev, 1 << PIIX_SIDPR_BAR, DRV_NAME))
222 hpriv->sidpr = pcim_iomap_table(pdev)[PIIX_SIDPR_BAR];
224 @@ -1436,7 +1336,7 @@ static void __devinit piix_init_sidpr(st
225 * Give it a test drive by inhibiting power save modes which
228 - scontrol = piix_sidpr_read(dev0, SCR_CONTROL);
229 + piix_sidpr_scr_read(link0, SCR_CONTROL, &scontrol);
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
235 if ((scontrol & 0xf00) != 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);
242 if ((scontrol & 0xf00) != 0x300) {
243 dev_printk(KERN_INFO, host->dev, "SCR access via "
244 "SIDPR is available but doesn't work\n");
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];
256 + ap->ops = &piix_sidpr_sata_ops;
258 + if (ap->flags & ATA_FLAG_SLAVE_POSS) {
259 + rc = ata_slave_link_init(ap);
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);
279 /* apply IOCFG bit18 quirk */