blob: e476e7b9a44184bfe647738d5c918ee61b76b9e5 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * sata_sil.c - Silicon Image SATA
3 *
Tejun Heo8c3d3d42013-05-14 11:09:50 -07004 * Maintained by: Tejun Heo <tj@kernel.org>
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 * Please ALWAYS copy linux-ide@vger.kernel.org
6 * on emails.
7 *
Jeff Garzikaf36d7f2005-08-28 20:18:39 -04008 * Copyright 2003-2005 Red Hat, Inc.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 * Copyright 2003 Benjamin Herrenschmidt
10 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070011 *
Jeff Garzikaf36d7f2005-08-28 20:18:39 -040012 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; see the file COPYING. If not, write to
24 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 *
27 * libata documentation is available via 'make {ps|pdf}docs',
28 * as Documentation/DocBook/libata.*
Linus Torvalds1da177e2005-04-16 15:20:36 -070029 *
Jeff Garzik953d1132005-08-26 19:46:24 -040030 * Documentation for SiI 3112:
31 * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2
32 *
33 * Other errata and documentation available under NDA.
34 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 */
36
37#include <linux/kernel.h>
38#include <linux/module.h>
39#include <linux/pci.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070040#include <linux/blkdev.h>
41#include <linux/delay.h>
42#include <linux/interrupt.h>
Jeff Garzika9524a72005-10-30 14:39:11 -050043#include <linux/device.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070044#include <scsi/scsi_host.h>
45#include <linux/libata.h>
Alexander Beregalov1737ef72009-01-29 02:30:56 +030046#include <linux/dmi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070047
48#define DRV_NAME "sata_sil"
Robert Hancockc7e324f2008-12-24 19:06:06 -060049#define DRV_VERSION "2.4"
50
51#define SIL_DMA_BOUNDARY 0x7fffffffUL
Linus Torvalds1da177e2005-04-16 15:20:36 -070052
53enum {
Tejun Heo0d5ff562007-02-01 15:06:36 +090054 SIL_MMIO_BAR = 5,
55
Tejun Heoe653a1e2006-03-05 16:03:52 +090056 /*
57 * host flags
58 */
Tejun Heo201ce852006-06-26 21:23:52 +090059 SIL_FLAG_NO_SATA_IRQ = (1 << 28),
Tejun Heoe4e10e32006-02-25 13:52:30 +090060 SIL_FLAG_RERR_ON_DMA_ACT = (1 << 29),
Tejun Heoe4deec62005-08-23 07:27:25 +090061 SIL_FLAG_MOD15WRITE = (1 << 30),
Tejun Heo20888d82006-05-31 18:27:53 +090062
Sergei Shtylyov9cbe0562011-02-04 22:05:48 +030063 SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA,
Tejun Heoe4deec62005-08-23 07:27:25 +090064
Tejun Heoe653a1e2006-03-05 16:03:52 +090065 /*
66 * Controller IDs
67 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070068 sil_3112 = 0,
Tejun Heo201ce852006-06-26 21:23:52 +090069 sil_3112_no_sata_irq = 1,
70 sil_3512 = 2,
71 sil_3114 = 3,
Linus Torvalds1da177e2005-04-16 15:20:36 -070072
Tejun Heoe653a1e2006-03-05 16:03:52 +090073 /*
74 * Register offsets
75 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070076 SIL_SYSCFG = 0x48,
Tejun Heoe653a1e2006-03-05 16:03:52 +090077
78 /*
79 * Register bits
80 */
81 /* SYSCFG */
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 SIL_MASK_IDE0_INT = (1 << 22),
83 SIL_MASK_IDE1_INT = (1 << 23),
84 SIL_MASK_IDE2_INT = (1 << 24),
85 SIL_MASK_IDE3_INT = (1 << 25),
86 SIL_MASK_2PORT = SIL_MASK_IDE0_INT | SIL_MASK_IDE1_INT,
87 SIL_MASK_4PORT = SIL_MASK_2PORT |
88 SIL_MASK_IDE2_INT | SIL_MASK_IDE3_INT,
89
Tejun Heoe653a1e2006-03-05 16:03:52 +090090 /* BMDMA/BMDMA2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -070091 SIL_INTR_STEERING = (1 << 1),
Tejun Heoe653a1e2006-03-05 16:03:52 +090092
Tejun Heo20888d82006-05-31 18:27:53 +090093 SIL_DMA_ENABLE = (1 << 0), /* DMA run switch */
94 SIL_DMA_RDWR = (1 << 3), /* DMA Rd-Wr */
95 SIL_DMA_SATA_IRQ = (1 << 4), /* OR of all SATA IRQs */
96 SIL_DMA_ACTIVE = (1 << 16), /* DMA running */
97 SIL_DMA_ERROR = (1 << 17), /* PCI bus error */
98 SIL_DMA_COMPLETE = (1 << 18), /* cmd complete / IRQ pending */
99 SIL_DMA_N_SATA_IRQ = (1 << 6), /* SATA_IRQ for the next channel */
100 SIL_DMA_N_ACTIVE = (1 << 24), /* ACTIVE for the next channel */
101 SIL_DMA_N_ERROR = (1 << 25), /* ERROR for the next channel */
102 SIL_DMA_N_COMPLETE = (1 << 26), /* COMPLETE for the next channel */
103
104 /* SIEN */
105 SIL_SIEN_N = (1 << 16), /* triggered by SError.N */
106
Tejun Heoe653a1e2006-03-05 16:03:52 +0900107 /*
108 * Others
109 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 SIL_QUIRK_MOD15WRITE = (1 << 0),
111 SIL_QUIRK_UDMA5MAX = (1 << 1),
112};
113
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400114static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
Alexey Dobriyan281d4262006-08-14 22:49:30 -0700115#ifdef CONFIG_PM
Tejun Heoafb5a7c2006-07-03 16:07:27 +0900116static int sil_pci_device_resume(struct pci_dev *pdev);
Alexey Dobriyan281d4262006-08-14 22:49:30 -0700117#endif
Alancd0d3bb2007-03-02 00:56:15 +0000118static void sil_dev_config(struct ata_device *dev);
Tejun Heo82ef04f2008-07-31 17:02:40 +0900119static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val);
120static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val);
Tejun Heo02607312007-08-06 18:36:23 +0900121static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed);
Robert Hancockc7e324f2008-12-24 19:06:06 -0600122static void sil_qc_prep(struct ata_queued_cmd *qc);
123static void sil_bmdma_setup(struct ata_queued_cmd *qc);
124static void sil_bmdma_start(struct ata_queued_cmd *qc);
125static void sil_bmdma_stop(struct ata_queued_cmd *qc);
Tejun Heof6aae272006-05-15 20:58:27 +0900126static void sil_freeze(struct ata_port *ap);
127static void sil_thaw(struct ata_port *ap);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128
Jeff Garzik374b1872005-08-30 05:42:52 -0400129
Jeff Garzik3b7d6972005-11-10 11:04:11 -0500130static const struct pci_device_id sil_pci_tbl[] = {
Jeff Garzik54bb3a942006-09-27 22:20:11 -0400131 { PCI_VDEVICE(CMD, 0x3112), sil_3112 },
132 { PCI_VDEVICE(CMD, 0x0240), sil_3112 },
133 { PCI_VDEVICE(CMD, 0x3512), sil_3512 },
134 { PCI_VDEVICE(CMD, 0x3114), sil_3114 },
135 { PCI_VDEVICE(ATI, 0x436e), sil_3112 },
136 { PCI_VDEVICE(ATI, 0x4379), sil_3112_no_sata_irq },
137 { PCI_VDEVICE(ATI, 0x437a), sil_3112_no_sata_irq },
138
Linus Torvalds1da177e2005-04-16 15:20:36 -0700139 { } /* terminate list */
140};
141
142
143/* TODO firmware versions should be added - eric */
144static const struct sil_drivelist {
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400145 const char *product;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700146 unsigned int quirk;
147} sil_blacklist [] = {
148 { "ST320012AS", SIL_QUIRK_MOD15WRITE },
149 { "ST330013AS", SIL_QUIRK_MOD15WRITE },
150 { "ST340017AS", SIL_QUIRK_MOD15WRITE },
151 { "ST360015AS", SIL_QUIRK_MOD15WRITE },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700152 { "ST380023AS", SIL_QUIRK_MOD15WRITE },
153 { "ST3120023AS", SIL_QUIRK_MOD15WRITE },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700154 { "ST340014ASL", SIL_QUIRK_MOD15WRITE },
155 { "ST360014ASL", SIL_QUIRK_MOD15WRITE },
156 { "ST380011ASL", SIL_QUIRK_MOD15WRITE },
157 { "ST3120022ASL", SIL_QUIRK_MOD15WRITE },
158 { "ST3160021ASL", SIL_QUIRK_MOD15WRITE },
159 { "Maxtor 4D060H3", SIL_QUIRK_UDMA5MAX },
160 { }
161};
162
163static struct pci_driver sil_pci_driver = {
164 .name = DRV_NAME,
165 .id_table = sil_pci_tbl,
166 .probe = sil_init_one,
167 .remove = ata_pci_remove_one,
Alexey Dobriyan281d4262006-08-14 22:49:30 -0700168#ifdef CONFIG_PM
Tejun Heoafb5a7c2006-07-03 16:07:27 +0900169 .suspend = ata_pci_device_suspend,
170 .resume = sil_pci_device_resume,
Alexey Dobriyan281d4262006-08-14 22:49:30 -0700171#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700172};
173
Jeff Garzik193515d2005-11-07 00:59:37 -0500174static struct scsi_host_template sil_sht = {
Robert Hancockc7e324f2008-12-24 19:06:06 -0600175 ATA_BASE_SHT(DRV_NAME),
176 /** These controllers support Large Block Transfer which allows
177 transfer chunks up to 2GB and which cross 64KB boundaries,
178 therefore the DMA limits are more relaxed than standard ATA SFF. */
179 .dma_boundary = SIL_DMA_BOUNDARY,
180 .sg_tablesize = ATA_MAX_PRD
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181};
182
Tejun Heo029cfd62008-03-25 12:22:49 +0900183static struct ata_port_operations sil_ops = {
Robert Hancock31f80112009-04-13 22:57:28 -0600184 .inherits = &ata_bmdma32_port_ops,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700185 .dev_config = sil_dev_config,
Alan Cox9d2c7c72007-03-08 23:09:12 +0000186 .set_mode = sil_set_mode,
Robert Hancockc7e324f2008-12-24 19:06:06 -0600187 .bmdma_setup = sil_bmdma_setup,
188 .bmdma_start = sil_bmdma_start,
189 .bmdma_stop = sil_bmdma_stop,
190 .qc_prep = sil_qc_prep,
Tejun Heof6aae272006-05-15 20:58:27 +0900191 .freeze = sil_freeze,
192 .thaw = sil_thaw,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700193 .scr_read = sil_scr_read,
194 .scr_write = sil_scr_write,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195};
196
Arjan van de Ven98ac62d2005-11-28 10:06:23 +0100197static const struct ata_port_info sil_port_info[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700198 /* sil_3112 */
199 {
Jeff Garzikcca39742006-08-24 03:19:22 -0400200 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100201 .pio_mask = ATA_PIO4,
202 .mwdma_mask = ATA_MWDMA2,
Jeff Garzikbf6263a2007-07-09 12:16:50 -0400203 .udma_mask = ATA_UDMA5,
Tejun Heoe4deec62005-08-23 07:27:25 +0900204 .port_ops = &sil_ops,
Tejun Heo0ee304d2006-02-25 13:52:30 +0900205 },
Tejun Heo201ce852006-06-26 21:23:52 +0900206 /* sil_3112_no_sata_irq */
207 {
Jeff Garzikcca39742006-08-24 03:19:22 -0400208 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
Tejun Heo201ce852006-06-26 21:23:52 +0900209 SIL_FLAG_NO_SATA_IRQ,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100210 .pio_mask = ATA_PIO4,
211 .mwdma_mask = ATA_MWDMA2,
Jeff Garzikbf6263a2007-07-09 12:16:50 -0400212 .udma_mask = ATA_UDMA5,
Tejun Heo201ce852006-06-26 21:23:52 +0900213 .port_ops = &sil_ops,
214 },
Tejun Heo0ee304d2006-02-25 13:52:30 +0900215 /* sil_3512 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700216 {
Jeff Garzikcca39742006-08-24 03:19:22 -0400217 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100218 .pio_mask = ATA_PIO4,
219 .mwdma_mask = ATA_MWDMA2,
Jeff Garzikbf6263a2007-07-09 12:16:50 -0400220 .udma_mask = ATA_UDMA5,
Tejun Heo0ee304d2006-02-25 13:52:30 +0900221 .port_ops = &sil_ops,
222 },
223 /* sil_3114 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700224 {
Jeff Garzikcca39742006-08-24 03:19:22 -0400225 .flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
Erik Inge Bolsø14bdef92009-03-14 21:38:24 +0100226 .pio_mask = ATA_PIO4,
227 .mwdma_mask = ATA_MWDMA2,
Jeff Garzikbf6263a2007-07-09 12:16:50 -0400228 .udma_mask = ATA_UDMA5,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 .port_ops = &sil_ops,
230 },
231};
232
233/* per-port register offsets */
234/* TODO: we can probably calculate rather than use a table */
235static const struct {
236 unsigned long tf; /* ATA taskfile register block */
237 unsigned long ctl; /* ATA control/altstatus register block */
238 unsigned long bmdma; /* DMA register block */
Tejun Heo20888d82006-05-31 18:27:53 +0900239 unsigned long bmdma2; /* DMA register block #2 */
Tejun Heo48d4ef22006-03-05 16:03:52 +0900240 unsigned long fifo_cfg; /* FIFO Valid Byte Count and Control */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 unsigned long scr; /* SATA control register block */
242 unsigned long sien; /* SATA Interrupt Enable register */
243 unsigned long xfer_mode;/* data transfer mode register */
Tejun Heoe4e10e32006-02-25 13:52:30 +0900244 unsigned long sfis_cfg; /* SATA FIS reception config register */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700245} sil_port[] = {
246 /* port 0 ... */
Jeff Garzik5bcd7a002007-05-26 16:35:42 -0400247 /* tf ctl bmdma bmdma2 fifo scr sien mode sfis */
248 { 0x80, 0x8A, 0x0, 0x10, 0x40, 0x100, 0x148, 0xb4, 0x14c },
249 { 0xC0, 0xCA, 0x8, 0x18, 0x44, 0x180, 0x1c8, 0xf4, 0x1cc },
Tejun Heo20888d82006-05-31 18:27:53 +0900250 { 0x280, 0x28A, 0x200, 0x210, 0x240, 0x300, 0x348, 0x2b4, 0x34c },
251 { 0x2C0, 0x2CA, 0x208, 0x218, 0x244, 0x380, 0x3c8, 0x2f4, 0x3cc },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 /* ... port 3 */
253};
254
255MODULE_AUTHOR("Jeff Garzik");
256MODULE_DESCRIPTION("low-level driver for Silicon Image SATA controller");
257MODULE_LICENSE("GPL");
258MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
259MODULE_VERSION(DRV_VERSION);
260
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400261static int slow_down;
Jeff Garzik51e9f2f2006-01-27 16:50:27 -0500262module_param(slow_down, int, 0444);
263MODULE_PARM_DESC(slow_down, "Sledgehammer used to work around random problems, by limiting commands to 15 sectors (0=off, 1=on)");
264
Jeff Garzik374b1872005-08-30 05:42:52 -0400265
Robert Hancockc7e324f2008-12-24 19:06:06 -0600266static void sil_bmdma_stop(struct ata_queued_cmd *qc)
267{
268 struct ata_port *ap = qc->ap;
269 void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
270 void __iomem *bmdma2 = mmio_base + sil_port[ap->port_no].bmdma2;
271
272 /* clear start/stop bit - can safely always write 0 */
273 iowrite8(0, bmdma2);
274
275 /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
276 ata_sff_dma_pause(ap);
277}
278
279static void sil_bmdma_setup(struct ata_queued_cmd *qc)
280{
281 struct ata_port *ap = qc->ap;
282 void __iomem *bmdma = ap->ioaddr.bmdma_addr;
283
284 /* load PRD table addr. */
Tejun Heof60d7012010-05-10 21:41:41 +0200285 iowrite32(ap->bmdma_prd_dma, bmdma + ATA_DMA_TABLE_OFS);
Robert Hancockc7e324f2008-12-24 19:06:06 -0600286
287 /* issue r/w command */
288 ap->ops->sff_exec_command(ap, &qc->tf);
289}
290
291static void sil_bmdma_start(struct ata_queued_cmd *qc)
292{
293 unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
294 struct ata_port *ap = qc->ap;
295 void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
296 void __iomem *bmdma2 = mmio_base + sil_port[ap->port_no].bmdma2;
297 u8 dmactl = ATA_DMA_START;
298
299 /* set transfer direction, start host DMA transaction
300 Note: For Large Block Transfer to work, the DMA must be started
301 using the bmdma2 register. */
302 if (!rw)
303 dmactl |= ATA_DMA_WR;
304 iowrite8(dmactl, bmdma2);
305}
306
307/* The way God intended PCI IDE scatter/gather lists to look and behave... */
308static void sil_fill_sg(struct ata_queued_cmd *qc)
309{
310 struct scatterlist *sg;
311 struct ata_port *ap = qc->ap;
Tejun Heof60d7012010-05-10 21:41:41 +0200312 struct ata_bmdma_prd *prd, *last_prd = NULL;
Robert Hancockc7e324f2008-12-24 19:06:06 -0600313 unsigned int si;
314
Tejun Heof60d7012010-05-10 21:41:41 +0200315 prd = &ap->bmdma_prd[0];
Robert Hancockc7e324f2008-12-24 19:06:06 -0600316 for_each_sg(qc->sg, sg, qc->n_elem, si) {
317 /* Note h/w doesn't support 64-bit, so we unconditionally
318 * truncate dma_addr_t to u32.
319 */
320 u32 addr = (u32) sg_dma_address(sg);
321 u32 sg_len = sg_dma_len(sg);
322
323 prd->addr = cpu_to_le32(addr);
324 prd->flags_len = cpu_to_le32(sg_len);
Pasi Kärkkäinen41137aa2009-02-02 21:47:14 +0200325 VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", si, addr, sg_len);
Robert Hancockc7e324f2008-12-24 19:06:06 -0600326
327 last_prd = prd;
328 prd++;
329 }
330
331 if (likely(last_prd))
332 last_prd->flags_len |= cpu_to_le32(ATA_PRD_EOT);
333}
334
335static void sil_qc_prep(struct ata_queued_cmd *qc)
336{
337 if (!(qc->flags & ATA_QCFLAG_DMAMAP))
338 return;
339
340 sil_fill_sg(qc);
341}
342
Linus Torvalds1da177e2005-04-16 15:20:36 -0700343static unsigned char sil_get_device_cache_line(struct pci_dev *pdev)
344{
345 u8 cache_line = 0;
346 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &cache_line);
347 return cache_line;
348}
349
Alan Cox9d2c7c72007-03-08 23:09:12 +0000350/**
351 * sil_set_mode - wrap set_mode functions
Tejun Heo02607312007-08-06 18:36:23 +0900352 * @link: link to set up
Alan Cox9d2c7c72007-03-08 23:09:12 +0000353 * @r_failed: returned device when we fail
354 *
355 * Wrap the libata method for device setup as after the setup we need
356 * to inspect the results and do some configuration work
357 */
358
Tejun Heo02607312007-08-06 18:36:23 +0900359static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360{
Tejun Heo02607312007-08-06 18:36:23 +0900361 struct ata_port *ap = link->ap;
362 void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
Tejun Heo0d5ff562007-02-01 15:06:36 +0900363 void __iomem *addr = mmio_base + sil_port[ap->port_no].xfer_mode;
Tejun Heo02607312007-08-06 18:36:23 +0900364 struct ata_device *dev;
Tejun Heof58229f2007-08-06 18:36:23 +0900365 u32 tmp, dev_mode[2] = { };
Alan Cox9d2c7c72007-03-08 23:09:12 +0000366 int rc;
Jeff Garzika617c092007-05-21 20:14:23 -0400367
Tejun Heo02607312007-08-06 18:36:23 +0900368 rc = ata_do_set_mode(link, r_failed);
Alan Cox9d2c7c72007-03-08 23:09:12 +0000369 if (rc)
370 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Tejun Heo1eca4362008-11-03 20:03:17 +0900372 ata_for_each_dev(dev, link, ALL) {
Tejun Heoe1211e32006-04-01 01:38:18 +0900373 if (!ata_dev_enabled(dev))
Tejun Heof58229f2007-08-06 18:36:23 +0900374 dev_mode[dev->devno] = 0; /* PIO0/1/2 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 else if (dev->flags & ATA_DFLAG_PIO)
Tejun Heof58229f2007-08-06 18:36:23 +0900376 dev_mode[dev->devno] = 1; /* PIO3/4 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 else
Tejun Heof58229f2007-08-06 18:36:23 +0900378 dev_mode[dev->devno] = 3; /* UDMA */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379 /* value 2 indicates MDMA */
380 }
381
382 tmp = readl(addr);
383 tmp &= ~((1<<5) | (1<<4) | (1<<1) | (1<<0));
384 tmp |= dev_mode[0];
385 tmp |= (dev_mode[1] << 4);
386 writel(tmp, addr);
387 readl(addr); /* flush */
Alan Cox9d2c7c72007-03-08 23:09:12 +0000388 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389}
390
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400391static inline void __iomem *sil_scr_addr(struct ata_port *ap,
392 unsigned int sc_reg)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393{
Tejun Heo0d5ff562007-02-01 15:06:36 +0900394 void __iomem *offset = ap->ioaddr.scr_addr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
396 switch (sc_reg) {
397 case SCR_STATUS:
398 return offset + 4;
399 case SCR_ERROR:
400 return offset + 8;
401 case SCR_CONTROL:
402 return offset;
403 default:
404 /* do nothing */
405 break;
406 }
407
Randy Dunlap8d9db2d2007-02-16 01:40:06 -0800408 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409}
410
Tejun Heo82ef04f2008-07-31 17:02:40 +0900411static int sil_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700412{
Tejun Heo82ef04f2008-07-31 17:02:40 +0900413 void __iomem *mmio = sil_scr_addr(link->ap, sc_reg);
Tejun Heoda3dbb12007-07-16 14:29:40 +0900414
415 if (mmio) {
416 *val = readl(mmio);
417 return 0;
418 }
419 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420}
421
Tejun Heo82ef04f2008-07-31 17:02:40 +0900422static int sil_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423{
Tejun Heo82ef04f2008-07-31 17:02:40 +0900424 void __iomem *mmio = sil_scr_addr(link->ap, sc_reg);
Tejun Heoda3dbb12007-07-16 14:29:40 +0900425
426 if (mmio) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700427 writel(val, mmio);
Tejun Heoda3dbb12007-07-16 14:29:40 +0900428 return 0;
429 }
430 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700431}
432
Tejun Heocbe88fb2006-05-31 18:27:55 +0900433static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
434{
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900435 struct ata_eh_info *ehi = &ap->link.eh_info;
436 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
Tejun Heocbe88fb2006-05-31 18:27:55 +0900437 u8 status;
438
Tejun Heoe5738902006-05-31 18:28:16 +0900439 if (unlikely(bmdma2 & SIL_DMA_SATA_IRQ)) {
Jeff Garzikebd16992011-08-18 23:52:36 -0400440 u32 serror = 0xffffffff;
Tejun Heod4c85322006-06-12 18:45:55 +0900441
442 /* SIEN doesn't mask SATA IRQs on some 3112s. Those
443 * controllers continue to assert IRQ as long as
444 * SError bits are pending. Clear SError immediately.
445 */
Tejun Heo82ef04f2008-07-31 17:02:40 +0900446 sil_scr_read(&ap->link, SCR_ERROR, &serror);
447 sil_scr_write(&ap->link, SCR_ERROR, serror);
Tejun Heod4c85322006-06-12 18:45:55 +0900448
Tejun Heo8cf32ac2007-12-08 08:45:27 +0900449 /* Sometimes spurious interrupts occur, double check
450 * it's PHYRDY CHG.
Tejun Heod4c85322006-06-12 18:45:55 +0900451 */
Tejun Heo8cf32ac2007-12-08 08:45:27 +0900452 if (serror & SERR_PHYRDY_CHG) {
Tejun Heof7fe7ad42007-12-08 08:47:01 +0900453 ap->link.eh_info.serror |= serror;
Tejun Heo8cf32ac2007-12-08 08:45:27 +0900454 goto freeze;
Tejun Heod4c85322006-06-12 18:45:55 +0900455 }
456
Tejun Heo8cf32ac2007-12-08 08:45:27 +0900457 if (!(bmdma2 & SIL_DMA_COMPLETE))
458 return;
Tejun Heoe5738902006-05-31 18:28:16 +0900459 }
460
Tejun Heo8cf32ac2007-12-08 08:45:27 +0900461 if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
Tejun Heoe2f8fb72007-02-24 22:30:36 +0900462 /* this sometimes happens, just clear IRQ */
Tejun Heo5682ed32008-04-07 22:47:16 +0900463 ap->ops->sff_check_status(ap);
Tejun Heoe2f8fb72007-02-24 22:30:36 +0900464 return;
465 }
466
Tejun Heocbe88fb2006-05-31 18:27:55 +0900467 /* Check whether we are expecting interrupt in this state */
468 switch (ap->hsm_task_state) {
469 case HSM_ST_FIRST:
470 /* Some pre-ATAPI-4 devices assert INTRQ
471 * at this state when ready to receive CDB.
472 */
473
474 /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
Tejun Heo405e66b2007-11-27 19:28:53 +0900475 * The flag was turned on only for atapi devices. No
476 * need to check ata_is_atapi(qc->tf.protocol) again.
Tejun Heocbe88fb2006-05-31 18:27:55 +0900477 */
478 if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
479 goto err_hsm;
480 break;
481 case HSM_ST_LAST:
Tejun Heo405e66b2007-11-27 19:28:53 +0900482 if (ata_is_dma(qc->tf.protocol)) {
Tejun Heocbe88fb2006-05-31 18:27:55 +0900483 /* clear DMA-Start bit */
484 ap->ops->bmdma_stop(qc);
485
486 if (bmdma2 & SIL_DMA_ERROR) {
487 qc->err_mask |= AC_ERR_HOST_BUS;
488 ap->hsm_task_state = HSM_ST_ERR;
489 }
490 }
491 break;
492 case HSM_ST:
493 break;
494 default:
495 goto err_hsm;
496 }
497
498 /* check main status, clearing INTRQ */
Tejun Heo5682ed32008-04-07 22:47:16 +0900499 status = ap->ops->sff_check_status(ap);
Tejun Heocbe88fb2006-05-31 18:27:55 +0900500 if (unlikely(status & ATA_BUSY))
501 goto err_hsm;
502
503 /* ack bmdma irq events */
Tejun Heo37f65b82010-05-19 22:10:20 +0200504 ata_bmdma_irq_clear(ap);
Tejun Heocbe88fb2006-05-31 18:27:55 +0900505
506 /* kick HSM in the ass */
Tejun Heo9363c382008-04-07 22:47:16 +0900507 ata_sff_hsm_move(ap, qc, status, 0);
Tejun Heocbe88fb2006-05-31 18:27:55 +0900508
Tejun Heo405e66b2007-11-27 19:28:53 +0900509 if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
Tejun Heoea547632006-11-17 12:06:21 +0900510 ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
511
Tejun Heocbe88fb2006-05-31 18:27:55 +0900512 return;
513
514 err_hsm:
515 qc->err_mask |= AC_ERR_HSM;
516 freeze:
517 ata_port_freeze(ap);
518}
519
David Howells7d12e782006-10-05 14:55:46 +0100520static irqreturn_t sil_interrupt(int irq, void *dev_instance)
Tejun Heocbe88fb2006-05-31 18:27:55 +0900521{
Jeff Garzikcca39742006-08-24 03:19:22 -0400522 struct ata_host *host = dev_instance;
Tejun Heo0d5ff562007-02-01 15:06:36 +0900523 void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
Tejun Heocbe88fb2006-05-31 18:27:55 +0900524 int handled = 0;
525 int i;
526
Jeff Garzikcca39742006-08-24 03:19:22 -0400527 spin_lock(&host->lock);
Tejun Heocbe88fb2006-05-31 18:27:55 +0900528
Jeff Garzikcca39742006-08-24 03:19:22 -0400529 for (i = 0; i < host->n_ports; i++) {
530 struct ata_port *ap = host->ports[i];
Tejun Heocbe88fb2006-05-31 18:27:55 +0900531 u32 bmdma2 = readl(mmio_base + sil_port[ap->port_no].bmdma2);
532
Tejun Heo201ce852006-06-26 21:23:52 +0900533 /* turn off SATA_IRQ if not supported */
534 if (ap->flags & SIL_FLAG_NO_SATA_IRQ)
535 bmdma2 &= ~SIL_DMA_SATA_IRQ;
536
Tejun Heo23fa9612006-06-12 14:18:51 +0900537 if (bmdma2 == 0xffffffff ||
538 !(bmdma2 & (SIL_DMA_COMPLETE | SIL_DMA_SATA_IRQ)))
Tejun Heocbe88fb2006-05-31 18:27:55 +0900539 continue;
540
541 sil_host_intr(ap, bmdma2);
542 handled = 1;
543 }
544
Jeff Garzikcca39742006-08-24 03:19:22 -0400545 spin_unlock(&host->lock);
Tejun Heocbe88fb2006-05-31 18:27:55 +0900546
547 return IRQ_RETVAL(handled);
548}
549
Tejun Heof6aae272006-05-15 20:58:27 +0900550static void sil_freeze(struct ata_port *ap)
551{
Tejun Heo0d5ff562007-02-01 15:06:36 +0900552 void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
Tejun Heof6aae272006-05-15 20:58:27 +0900553 u32 tmp;
554
Tejun Heoe5738902006-05-31 18:28:16 +0900555 /* global IRQ mask doesn't block SATA IRQ, turn off explicitly */
556 writel(0, mmio_base + sil_port[ap->port_no].sien);
557
Tejun Heof6aae272006-05-15 20:58:27 +0900558 /* plug IRQ */
559 tmp = readl(mmio_base + SIL_SYSCFG);
560 tmp |= SIL_MASK_IDE0_INT << ap->port_no;
561 writel(tmp, mmio_base + SIL_SYSCFG);
562 readl(mmio_base + SIL_SYSCFG); /* flush */
Jeff Garzik2fc37ad2009-04-07 19:18:32 -0400563
564 /* Ensure DMA_ENABLE is off.
565 *
566 * This is because the controller will not give us access to the
567 * taskfile registers while a DMA is in progress
568 */
569 iowrite8(ioread8(ap->ioaddr.bmdma_addr) & ~SIL_DMA_ENABLE,
570 ap->ioaddr.bmdma_addr);
571
572 /* According to ata_bmdma_stop, an HDMA transition requires
573 * on PIO cycle. But we can't read a taskfile register.
574 */
575 ioread8(ap->ioaddr.bmdma_addr);
Tejun Heof6aae272006-05-15 20:58:27 +0900576}
577
578static void sil_thaw(struct ata_port *ap)
579{
Tejun Heo0d5ff562007-02-01 15:06:36 +0900580 void __iomem *mmio_base = ap->host->iomap[SIL_MMIO_BAR];
Tejun Heof6aae272006-05-15 20:58:27 +0900581 u32 tmp;
582
583 /* clear IRQ */
Tejun Heo5682ed32008-04-07 22:47:16 +0900584 ap->ops->sff_check_status(ap);
Tejun Heo37f65b82010-05-19 22:10:20 +0200585 ata_bmdma_irq_clear(ap);
Tejun Heof6aae272006-05-15 20:58:27 +0900586
Tejun Heo201ce852006-06-26 21:23:52 +0900587 /* turn on SATA IRQ if supported */
588 if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ))
589 writel(SIL_SIEN_N, mmio_base + sil_port[ap->port_no].sien);
Tejun Heoe5738902006-05-31 18:28:16 +0900590
Tejun Heof6aae272006-05-15 20:58:27 +0900591 /* turn on IRQ */
592 tmp = readl(mmio_base + SIL_SYSCFG);
593 tmp &= ~(SIL_MASK_IDE0_INT << ap->port_no);
594 writel(tmp, mmio_base + SIL_SYSCFG);
595}
596
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597/**
598 * sil_dev_config - Apply device/host-specific errata fixups
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 * @dev: Device to be examined
600 *
601 * After the IDENTIFY [PACKET] DEVICE step is complete, and a
602 * device is known to be present, this function is called.
603 * We apply two errata fixups which are specific to Silicon Image,
604 * a Seagate and a Maxtor fixup.
605 *
606 * For certain Seagate devices, we must limit the maximum sectors
607 * to under 8K.
608 *
609 * For certain Maxtor devices, we must not program the drive
610 * beyond udma5.
611 *
612 * Both fixups are unfairly pessimistic. As soon as I get more
613 * information on these errata, I will create a more exhaustive
614 * list, and apply the fixups to only the specific
615 * devices/hosts/firmwares that need it.
616 *
617 * 20040111 - Seagate drives affected by the Mod15Write bug are blacklisted
618 * The Maxtor quirk is in the blacklist, but I'm keeping the original
619 * pessimistic fix for the following reasons...
620 * - There seems to be less info on it, only one device gleaned off the
621 * Windows driver, maybe only one is affected. More info would be greatly
622 * appreciated.
623 * - But then again UDMA5 is hardly anything to complain about
624 */
Alancd0d3bb2007-03-02 00:56:15 +0000625static void sil_dev_config(struct ata_device *dev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626{
Tejun Heo9af5c9c2007-08-06 18:36:22 +0900627 struct ata_port *ap = dev->link->ap;
628 int print_info = ap->link.eh_context.i.flags & ATA_EHI_PRINTINFO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700629 unsigned int n, quirks = 0;
Tejun Heoa0cf7332007-01-02 20:18:49 +0900630 unsigned char model_num[ATA_ID_PROD_LEN + 1];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700631
Tejun Heoa0cf7332007-01-02 20:18:49 +0900632 ata_id_c_string(dev->id, model_num, ATA_ID_PROD, sizeof(model_num));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633
Jeff Garzik8a60a072005-07-31 13:13:24 -0400634 for (n = 0; sil_blacklist[n].product; n++)
Tejun Heo2e026712006-02-12 22:47:04 +0900635 if (!strcmp(sil_blacklist[n].product, model_num)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700636 quirks = sil_blacklist[n].quirk;
637 break;
638 }
Jeff Garzik8a60a072005-07-31 13:13:24 -0400639
Linus Torvalds1da177e2005-04-16 15:20:36 -0700640 /* limit requests to 15 sectors */
Jeff Garzik51e9f2f2006-01-27 16:50:27 -0500641 if (slow_down ||
642 ((ap->flags & SIL_FLAG_MOD15WRITE) &&
643 (quirks & SIL_QUIRK_MOD15WRITE))) {
Tejun Heoefdaedc2006-11-01 18:38:52 +0900644 if (print_info)
Joe Perchesa9a79df2011-04-15 15:51:59 -0700645 ata_dev_info(dev,
646 "applying Seagate errata fix (mod15write workaround)\n");
Tejun Heob00eec12006-02-12 23:32:59 +0900647 dev->max_sectors = 15;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 return;
649 }
650
651 /* limit to udma5 */
652 if (quirks & SIL_QUIRK_UDMA5MAX) {
Tejun Heoefdaedc2006-11-01 18:38:52 +0900653 if (print_info)
Joe Perchesa9a79df2011-04-15 15:51:59 -0700654 ata_dev_info(dev, "applying Maxtor errata fix %s\n",
655 model_num);
Tejun Heo5a529132006-03-24 14:07:50 +0900656 dev->udma_mask &= ATA_UDMA5;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700657 return;
658 }
659}
660
Tejun Heo4447d352007-04-17 23:44:08 +0900661static void sil_init_controller(struct ata_host *host)
Tejun Heo3d8ec912006-07-03 16:07:27 +0900662{
Tejun Heo4447d352007-04-17 23:44:08 +0900663 struct pci_dev *pdev = to_pci_dev(host->dev);
664 void __iomem *mmio_base = host->iomap[SIL_MMIO_BAR];
Tejun Heo3d8ec912006-07-03 16:07:27 +0900665 u8 cls;
666 u32 tmp;
667 int i;
668
669 /* Initialize FIFO PCI bus arbitration */
670 cls = sil_get_device_cache_line(pdev);
671 if (cls) {
672 cls >>= 3;
673 cls++; /* cls = (line_size/8)+1 */
Tejun Heo4447d352007-04-17 23:44:08 +0900674 for (i = 0; i < host->n_ports; i++)
Tejun Heo3d8ec912006-07-03 16:07:27 +0900675 writew(cls << 8 | cls,
676 mmio_base + sil_port[i].fifo_cfg);
677 } else
Joe Perchesa44fec12011-04-15 15:51:58 -0700678 dev_warn(&pdev->dev,
679 "cache line size not set. Driver may not function\n");
Tejun Heo3d8ec912006-07-03 16:07:27 +0900680
681 /* Apply R_ERR on DMA activate FIS errata workaround */
Tejun Heo4447d352007-04-17 23:44:08 +0900682 if (host->ports[0]->flags & SIL_FLAG_RERR_ON_DMA_ACT) {
Tejun Heo3d8ec912006-07-03 16:07:27 +0900683 int cnt;
684
Tejun Heo4447d352007-04-17 23:44:08 +0900685 for (i = 0, cnt = 0; i < host->n_ports; i++) {
Tejun Heo3d8ec912006-07-03 16:07:27 +0900686 tmp = readl(mmio_base + sil_port[i].sfis_cfg);
687 if ((tmp & 0x3) != 0x01)
688 continue;
689 if (!cnt)
Joe Perchesa44fec12011-04-15 15:51:58 -0700690 dev_info(&pdev->dev,
691 "Applying R_ERR on DMA activate FIS errata fix\n");
Tejun Heo3d8ec912006-07-03 16:07:27 +0900692 writel(tmp & ~0x3, mmio_base + sil_port[i].sfis_cfg);
693 cnt++;
694 }
695 }
696
Tejun Heo4447d352007-04-17 23:44:08 +0900697 if (host->n_ports == 4) {
Tejun Heo3d8ec912006-07-03 16:07:27 +0900698 /* flip the magic "make 4 ports work" bit */
699 tmp = readl(mmio_base + sil_port[2].bmdma);
700 if ((tmp & SIL_INTR_STEERING) == 0)
701 writel(tmp | SIL_INTR_STEERING,
702 mmio_base + sil_port[2].bmdma);
703 }
704}
705
Rafael J. Wysockie57db7b2009-01-19 20:58:29 +0100706static bool sil_broken_system_poweroff(struct pci_dev *pdev)
707{
708 static const struct dmi_system_id broken_systems[] = {
709 {
710 .ident = "HP Compaq nx6325",
711 .matches = {
712 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
713 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
714 },
715 /* PCI slot number of the controller */
716 .driver_data = (void *)0x12UL,
717 },
718
719 { } /* terminate list */
720 };
721 const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
722
723 if (dmi) {
724 unsigned long slot = (unsigned long)dmi->driver_data;
725 /* apply the quirk only to on-board controllers */
726 return slot == PCI_SLOT(pdev->devfn);
727 }
728
729 return false;
730}
731
Jeff Garzik5796d1c2007-10-26 00:03:37 -0400732static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733{
Tejun Heo4447d352007-04-17 23:44:08 +0900734 int board_id = ent->driver_data;
Rafael J. Wysockie57db7b2009-01-19 20:58:29 +0100735 struct ata_port_info pi = sil_port_info[board_id];
736 const struct ata_port_info *ppi[] = { &pi, NULL };
Tejun Heo4447d352007-04-17 23:44:08 +0900737 struct ata_host *host;
Jeff Garzikea6ba102005-08-30 05:18:18 -0400738 void __iomem *mmio_base;
Tejun Heo4447d352007-04-17 23:44:08 +0900739 int n_ports, rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 unsigned int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741
Joe Perches06296a12011-04-15 15:52:00 -0700742 ata_print_version_once(&pdev->dev, DRV_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700743
Tejun Heo4447d352007-04-17 23:44:08 +0900744 /* allocate host */
745 n_ports = 2;
746 if (board_id == sil_3114)
747 n_ports = 4;
748
Rafael J. Wysockie57db7b2009-01-19 20:58:29 +0100749 if (sil_broken_system_poweroff(pdev)) {
750 pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN |
751 ATA_FLAG_NO_HIBERNATE_SPINDOWN;
752 dev_info(&pdev->dev, "quirky BIOS, skipping spindown "
753 "on poweroff and hibernation\n");
754 }
755
Tejun Heo4447d352007-04-17 23:44:08 +0900756 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
757 if (!host)
758 return -ENOMEM;
759
760 /* acquire resources and fill host */
Tejun Heo24dc5f32007-01-20 16:00:28 +0900761 rc = pcim_enable_device(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762 if (rc)
763 return rc;
764
Tejun Heo0d5ff562007-02-01 15:06:36 +0900765 rc = pcim_iomap_regions(pdev, 1 << SIL_MMIO_BAR, DRV_NAME);
766 if (rc == -EBUSY)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900767 pcim_pin_device(pdev);
Tejun Heo0d5ff562007-02-01 15:06:36 +0900768 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900769 return rc;
Tejun Heo4447d352007-04-17 23:44:08 +0900770 host->iomap = pcim_iomap_table(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700771
772 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
773 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900774 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
776 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +0900777 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778
Tejun Heo4447d352007-04-17 23:44:08 +0900779 mmio_base = host->iomap[SIL_MMIO_BAR];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780
Tejun Heo4447d352007-04-17 23:44:08 +0900781 for (i = 0; i < host->n_ports; i++) {
Tejun Heocbcdd872007-08-18 13:14:55 +0900782 struct ata_port *ap = host->ports[i];
783 struct ata_ioports *ioaddr = &ap->ioaddr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
Tejun Heo4447d352007-04-17 23:44:08 +0900785 ioaddr->cmd_addr = mmio_base + sil_port[i].tf;
786 ioaddr->altstatus_addr =
787 ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
788 ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
789 ioaddr->scr_addr = mmio_base + sil_port[i].scr;
Tejun Heo9363c382008-04-07 22:47:16 +0900790 ata_sff_std_ports(ioaddr);
Tejun Heocbcdd872007-08-18 13:14:55 +0900791
792 ata_port_pbar_desc(ap, SIL_MMIO_BAR, -1, "mmio");
793 ata_port_pbar_desc(ap, SIL_MMIO_BAR, sil_port[i].tf, "tf");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794 }
795
Tejun Heo4447d352007-04-17 23:44:08 +0900796 /* initialize and activate */
797 sil_init_controller(host);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700798
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799 pci_set_master(pdev);
Tejun Heo4447d352007-04-17 23:44:08 +0900800 return ata_host_activate(host, pdev->irq, sil_interrupt, IRQF_SHARED,
801 &sil_sht);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802}
803
Alexey Dobriyan281d4262006-08-14 22:49:30 -0700804#ifdef CONFIG_PM
Tejun Heoafb5a7c2006-07-03 16:07:27 +0900805static int sil_pci_device_resume(struct pci_dev *pdev)
806{
Jingoo Han0a86e1c2013-06-03 14:05:36 +0900807 struct ata_host *host = pci_get_drvdata(pdev);
Tejun Heo553c4aa2006-12-26 19:39:50 +0900808 int rc;
Tejun Heoafb5a7c2006-07-03 16:07:27 +0900809
Tejun Heo553c4aa2006-12-26 19:39:50 +0900810 rc = ata_pci_device_do_resume(pdev);
811 if (rc)
812 return rc;
813
Tejun Heo4447d352007-04-17 23:44:08 +0900814 sil_init_controller(host);
Jeff Garzikcca39742006-08-24 03:19:22 -0400815 ata_host_resume(host);
Tejun Heoafb5a7c2006-07-03 16:07:27 +0900816
817 return 0;
818}
Alexey Dobriyan281d4262006-08-14 22:49:30 -0700819#endif
Tejun Heoafb5a7c2006-07-03 16:07:27 +0900820
Axel Lin2fc75da2012-04-19 13:43:05 +0800821module_pci_driver(sil_pci_driver);