1 From b9d5b89b487517cbd4cb4702da829e07ef9e4432 Mon Sep 17 00:00:00 2001
2 From: Tejun Heo <tj@kernel.org>
3 Date: Wed, 22 Oct 2008 00:46:36 +0900
4 Subject: [PATCH] sata_via: fix support for 5287
7 5287 used to be treated as vt6420 but it didn't work. It's new family
8 of controllers called vt8251 which hosts four SATA ports as M/S of the
9 two ATA ports. This configuration is rather peculiar in that although
10 the M/S devices are on the same port, each have its own SCR (or
11 equivalent link status/control) registers which screws up the
12 port-link-device hierarchy assumed by libata. Another controller
13 which falls into this category is ata_piix w/ SIDPR access.
15 libata now has facility to deal with this class of controllers named
16 slave_link. A low level driver for such controllers can just call
17 ata_slave_link_init() on the respective ports and libata will handle
18 all the difficult parts like following up with single SRST after
19 hardresetting both ports.
21 This patch creates new controller class vt8251, implements slave_link
22 aware init sequence and config space based SCR access for it and moves
23 5287 to the new class.
25 This patch is based on Joseph Chan's larger patch which was created
26 before slave_link was implemented in libata.
28 http://thread.gmane.org/gmane.linux.kernel.commits.mm/40640
30 Signed-off-by: Tejun Heo <tj@kernel.org>
31 Cc: Joseph Chan <JosephChan@via.com.tw>
32 Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
33 Signed-off-by: Tejun Heo <teheo@suse.de>
35 drivers/ata/sata_via.c | 155 ++++++++++++++++++++++++++++++++++++++++++++----
36 1 files changed, 143 insertions(+), 12 deletions(-)
38 diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
39 index 5b72e73..62367fe 100644
40 --- a/drivers/ata/sata_via.c
41 +++ b/drivers/ata/sata_via.c
43 #include <linux/libata.h>
45 #define DRV_NAME "sata_via"
46 -#define DRV_VERSION "2.3"
47 +#define DRV_VERSION "2.4"
50 + * vt8251 is different from other sata controllers of VIA. It has two
51 + * channels, each channel has both Master and Slave slot.
60 @@ -70,6 +75,8 @@ enum {
61 static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
62 static int svia_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
63 static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
64 +static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val);
65 +static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val);
66 static void svia_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
67 static void svia_noop_freeze(struct ata_port *ap);
68 static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
69 @@ -79,12 +86,12 @@ static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
71 static const struct pci_device_id svia_pci_tbl[] = {
72 { PCI_VDEVICE(VIA, 0x5337), vt6420 },
73 - { PCI_VDEVICE(VIA, 0x0591), vt6420 },
74 - { PCI_VDEVICE(VIA, 0x3149), vt6420 },
75 - { PCI_VDEVICE(VIA, 0x3249), vt6421 },
76 - { PCI_VDEVICE(VIA, 0x5287), vt6420 },
77 + { PCI_VDEVICE(VIA, 0x0591), vt6420 }, /* 2 sata chnls (Master) */
78 + { PCI_VDEVICE(VIA, 0x3149), vt6420 }, /* 2 sata chnls (Master) */
79 + { PCI_VDEVICE(VIA, 0x3249), vt6421 }, /* 2 sata chnls, 1 pata chnl */
80 { PCI_VDEVICE(VIA, 0x5372), vt6420 },
81 { PCI_VDEVICE(VIA, 0x7372), vt6420 },
82 + { PCI_VDEVICE(VIA, 0x5287), vt8251 }, /* 2 sata chnls (Master/Slave) */
84 { } /* terminate list */
86 @@ -128,6 +135,13 @@ static struct ata_port_operations vt6421_sata_ops = {
87 .scr_write = svia_scr_write,
90 +static struct ata_port_operations vt8251_ops = {
91 + .inherits = &svia_base_ops,
92 + .hardreset = sata_std_hardreset,
93 + .scr_read = vt8251_scr_read,
94 + .scr_write = vt8251_scr_write,
97 static const struct ata_port_info vt6420_port_info = {
98 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
100 @@ -152,6 +166,15 @@ static struct ata_port_info vt6421_pport_info = {
101 .port_ops = &vt6421_pata_ops,
104 +static struct ata_port_info vt8251_port_info = {
105 + .flags = ATA_FLAG_SATA | ATA_FLAG_SLAVE_POSS |
106 + ATA_FLAG_NO_LEGACY,
108 + .mwdma_mask = 0x07,
109 + .udma_mask = ATA_UDMA6,
110 + .port_ops = &vt8251_ops,
113 MODULE_AUTHOR("Jeff Garzik");
114 MODULE_DESCRIPTION("SCSI low-level driver for VIA SATA controllers");
115 MODULE_LICENSE("GPL");
116 @@ -174,6 +197,83 @@ static int svia_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
120 +static int vt8251_scr_read(struct ata_link *link, unsigned int scr, u32 *val)
122 + static const u8 ipm_tbl[] = { 1, 2, 6, 0 };
123 + struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
124 + int slot = 2 * link->ap->port_no + link->pmp;
130 + pci_read_config_byte(pdev, 0xA0 + slot, &raw);
132 + /* read the DET field, bit0 and 1 of the config byte */
135 + /* read the SPD field, bit4 of the configure byte */
136 + if (raw & (1 << 4))
141 + /* read the IPM field, bit2 and 3 of the config byte */
142 + v |= ipm_tbl[(raw >> 2) & 0x3];
146 + /* devices other than 5287 uses 0xA8 as base */
147 + WARN_ON(pdev->device != 0x5287);
148 + pci_read_config_dword(pdev, 0xB0 + slot * 4, &v);
152 + pci_read_config_byte(pdev, 0xA4 + slot, &raw);
154 + /* read the DET field, bit0 and bit1 */
155 + v |= ((raw & 0x02) << 1) | (raw & 0x01);
157 + /* read the IPM field, bit2 and bit3 */
158 + v |= ((raw >> 2) & 0x03) << 8;
169 +static int vt8251_scr_write(struct ata_link *link, unsigned int scr, u32 val)
171 + struct pci_dev *pdev = to_pci_dev(link->ap->host->dev);
172 + int slot = 2 * link->ap->port_no + link->pmp;
177 + /* devices other than 5287 uses 0xA8 as base */
178 + WARN_ON(pdev->device != 0x5287);
179 + pci_write_config_dword(pdev, 0xB0 + slot * 4, val);
183 + /* set the DET field */
184 + v |= ((val & 0x4) >> 1) | (val & 0x1);
186 + /* set the IPM field */
187 + v |= ((val >> 8) & 0x3) << 2;
189 + pci_write_config_byte(pdev, 0xA4 + slot, v);
198 * svia_tf_load - send taskfile registers to host controller
199 * @ap: Port to which output is sent
200 @@ -396,6 +496,30 @@ static int vt6421_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
204 +static int vt8251_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
206 + const struct ata_port_info *ppi[] = { &vt8251_port_info, NULL };
207 + struct ata_host *host;
210 + rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
215 + rc = pcim_iomap_regions(pdev, 1 << 5, DRV_NAME);
217 + dev_printk(KERN_ERR, &pdev->dev, "failed to iomap PCI BAR 5\n");
221 + /* 8251 hosts four sata ports as M/S of the two channels */
222 + for (i = 0; i < host->n_ports; i++)
223 + ata_slave_link_init(host->ports[i]);
228 static void svia_configure(struct pci_dev *pdev)
231 @@ -451,10 +575,10 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
235 - if (board_id == vt6420)
236 - bar_sizes = &svia_bar_sizes[0];
238 + if (board_id == vt6421)
239 bar_sizes = &vt6421_bar_sizes[0];
241 + bar_sizes = &svia_bar_sizes[0];
243 for (i = 0; i < ARRAY_SIZE(svia_bar_sizes); i++)
244 if ((pci_resource_start(pdev, i) == 0) ||
245 @@ -467,12 +591,19 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
249 - if (board_id == vt6420)
250 + switch (board_id) {
252 rc = vt6420_prepare_host(pdev, &host);
256 rc = vt6421_prepare_host(pdev, &host);
261 + rc = vt8251_prepare_host(pdev, &host);
267 svia_configure(pdev);