blob: 546a3692774f8d3819ef76d9bcc656ef1af1c99d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * ahci.c - AHCI SATA support
3 *
Tejun Heo8c3d3d42013-05-14 11:09:50 -07004 * Maintained by: Tejun Heo <tj@kernel.org>
Jeff Garzikaf36d7f2005-08-28 20:18:39 -04005 * Please ALWAYS copy linux-ide@vger.kernel.org
6 * on emails.
Linus Torvalds1da177e2005-04-16 15:20:36 -07007 *
Jeff Garzikaf36d7f2005-08-28 20:18:39 -04008 * Copyright 2004-2005 Red Hat, Inc.
Linus Torvalds1da177e2005-04-16 15:20:36 -07009 *
Linus Torvalds1da177e2005-04-16 15:20:36 -070010 *
Jeff Garzikaf36d7f2005-08-28 20:18:39 -040011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2, or (at your option)
14 * any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; see the file COPYING. If not, write to
23 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 *
26 * libata documentation is available via 'make {ps|pdf}docs',
27 * as Documentation/DocBook/libata.*
28 *
29 * AHCI hardware documentation:
Linus Torvalds1da177e2005-04-16 15:20:36 -070030 * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
Jeff Garzikaf36d7f2005-08-28 20:18:39 -040031 * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
Linus Torvalds1da177e2005-04-16 15:20:36 -070032 *
33 */
34
35#include <linux/kernel.h>
36#include <linux/module.h>
37#include <linux/pci.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <linux/blkdev.h>
39#include <linux/delay.h>
40#include <linux/interrupt.h>
domen@coderock.org87507cf2005-04-08 09:53:06 +020041#include <linux/dma-mapping.h>
Jeff Garzika9524a72005-10-30 14:39:11 -050042#include <linux/device.h>
Tejun Heoedc93052007-10-25 14:59:16 +090043#include <linux/dmi.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090044#include <linux/gfp.h>
Robert Richteree2aad42015-06-05 19:49:25 +020045#include <linux/msi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070046#include <scsi/scsi_host.h>
Jeff Garzik193515d2005-11-07 00:59:37 -050047#include <scsi/scsi_cmnd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070048#include <linux/libata.h>
Anton Vorontsov365cfa12010-03-28 00:22:14 -040049#include "ahci.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
51#define DRV_NAME "ahci"
Tejun Heo7d50b602007-09-23 13:19:54 +090052#define DRV_VERSION "3.0"
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Linus Torvalds1da177e2005-04-16 15:20:36 -070054enum {
Alessandro Rubini318893e2012-01-06 13:33:39 +010055 AHCI_PCI_BAR_STA2X11 = 0,
Robert Richterb7ae1282015-06-05 19:49:26 +020056 AHCI_PCI_BAR_CAVIUM = 0,
Hugh Daschbach7f9c9f82013-01-04 14:39:09 -080057 AHCI_PCI_BAR_ENMOTUS = 2,
Alessandro Rubini318893e2012-01-06 13:33:39 +010058 AHCI_PCI_BAR_STANDARD = 5,
Tejun Heo441577e2010-03-29 10:32:39 +090059};
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Tejun Heo441577e2010-03-29 10:32:39 +090061enum board_ids {
62 /* board IDs by feature in alphabetical order */
63 board_ahci,
64 board_ahci_ign_iferr,
Tejun Heo66a7cbc2014-10-27 10:22:56 -040065 board_ahci_nomsi,
Levente Kurusa67809f82014-02-18 10:22:17 -050066 board_ahci_noncq,
Tejun Heo441577e2010-03-29 10:32:39 +090067 board_ahci_nosntf,
Tejun Heo5f173102010-07-24 16:53:48 +020068 board_ahci_yes_fbs,
Tejun Heo441577e2010-03-29 10:32:39 +090069
70 /* board IDs for specific chipsets in alphabetical order */
Dan Williamsdbfe8ef2015-05-08 15:23:55 -040071 board_ahci_avn,
Tejun Heo441577e2010-03-29 10:32:39 +090072 board_ahci_mcp65,
Tejun Heo83f2b962010-03-30 10:28:32 +090073 board_ahci_mcp77,
74 board_ahci_mcp89,
Tejun Heo441577e2010-03-29 10:32:39 +090075 board_ahci_mv,
76 board_ahci_sb600,
77 board_ahci_sb700, /* for SB700 and SB800 */
78 board_ahci_vt8251,
79
80 /* aliases */
81 board_ahci_mcp_linux = board_ahci_mcp65,
82 board_ahci_mcp67 = board_ahci_mcp65,
83 board_ahci_mcp73 = board_ahci_mcp65,
Tejun Heo83f2b962010-03-30 10:28:32 +090084 board_ahci_mcp79 = board_ahci_mcp77,
Linus Torvalds1da177e2005-04-16 15:20:36 -070085};
86
Jeff Garzik2dcb4072007-10-19 06:42:56 -040087static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
Tejun Heoa1efdab2008-03-25 12:22:50 +090088static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
89 unsigned long deadline);
Dan Williamsdbfe8ef2015-05-08 15:23:55 -040090static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
91 unsigned long deadline);
James Lairdcb856962013-11-19 11:06:38 +110092static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
93static bool is_mcp89_apple(struct pci_dev *pdev);
Tejun Heoa1efdab2008-03-25 12:22:50 +090094static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
95 unsigned long deadline);
Tejun Heo438ac6d2007-03-02 17:31:26 +090096#ifdef CONFIG_PM
Tejun Heoc1332872006-07-26 15:59:26 +090097static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
98static int ahci_pci_device_resume(struct pci_dev *pdev);
Tejun Heo438ac6d2007-03-02 17:31:26 +090099#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Tejun Heofad16e72010-09-21 09:25:48 +0200101static struct scsi_host_template ahci_sht = {
102 AHCI_SHT("ahci"),
103};
104
Tejun Heo029cfd62008-03-25 12:22:49 +0900105static struct ata_port_operations ahci_vt8251_ops = {
106 .inherits = &ahci_ops,
Tejun Heoa1efdab2008-03-25 12:22:50 +0900107 .hardreset = ahci_vt8251_hardreset,
Tejun Heoad616ff2006-11-01 18:00:24 +0900108};
109
Tejun Heo029cfd62008-03-25 12:22:49 +0900110static struct ata_port_operations ahci_p5wdh_ops = {
111 .inherits = &ahci_ops,
Tejun Heoa1efdab2008-03-25 12:22:50 +0900112 .hardreset = ahci_p5wdh_hardreset,
Tejun Heoedc93052007-10-25 14:59:16 +0900113};
114
Dan Williamsdbfe8ef2015-05-08 15:23:55 -0400115static struct ata_port_operations ahci_avn_ops = {
116 .inherits = &ahci_ops,
117 .hardreset = ahci_avn_hardreset,
118};
119
Arjan van de Ven98ac62d2005-11-28 10:06:23 +0100120static const struct ata_port_info ahci_port_info[] = {
Tejun Heo441577e2010-03-29 10:32:39 +0900121 /* by features */
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530122 [board_ahci] = {
Tejun Heo1188c0d2007-04-23 02:41:05 +0900123 .flags = AHCI_FLAG_COMMON,
Erik Inge Bolsø14bdef982009-03-14 21:38:24 +0100124 .pio_mask = ATA_PIO4,
Jeff Garzik469248a2007-07-08 01:13:16 -0400125 .udma_mask = ATA_UDMA6,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700126 .port_ops = &ahci_ops,
127 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530128 [board_ahci_ign_iferr] = {
Tejun Heo417a1a62007-09-23 13:19:55 +0900129 AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
130 .flags = AHCI_FLAG_COMMON,
Erik Inge Bolsø14bdef982009-03-14 21:38:24 +0100131 .pio_mask = ATA_PIO4,
Jeff Garzik469248a2007-07-08 01:13:16 -0400132 .udma_mask = ATA_UDMA6,
Tejun Heo41669552006-11-29 11:33:14 +0900133 .port_ops = &ahci_ops,
134 },
Tejun Heo66a7cbc2014-10-27 10:22:56 -0400135 [board_ahci_nomsi] = {
136 AHCI_HFLAGS (AHCI_HFLAG_NO_MSI),
137 .flags = AHCI_FLAG_COMMON,
138 .pio_mask = ATA_PIO4,
139 .udma_mask = ATA_UDMA6,
140 .port_ops = &ahci_ops,
141 },
Levente Kurusa67809f82014-02-18 10:22:17 -0500142 [board_ahci_noncq] = {
143 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ),
144 .flags = AHCI_FLAG_COMMON,
145 .pio_mask = ATA_PIO4,
146 .udma_mask = ATA_UDMA6,
147 .port_ops = &ahci_ops,
148 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530149 [board_ahci_nosntf] = {
Tejun Heo441577e2010-03-29 10:32:39 +0900150 AHCI_HFLAGS (AHCI_HFLAG_NO_SNTF),
151 .flags = AHCI_FLAG_COMMON,
152 .pio_mask = ATA_PIO4,
153 .udma_mask = ATA_UDMA6,
154 .port_ops = &ahci_ops,
155 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530156 [board_ahci_yes_fbs] = {
Tejun Heo5f173102010-07-24 16:53:48 +0200157 AHCI_HFLAGS (AHCI_HFLAG_YES_FBS),
158 .flags = AHCI_FLAG_COMMON,
159 .pio_mask = ATA_PIO4,
160 .udma_mask = ATA_UDMA6,
161 .port_ops = &ahci_ops,
162 },
Tejun Heo441577e2010-03-29 10:32:39 +0900163 /* by chipsets */
Dan Williamsdbfe8ef2015-05-08 15:23:55 -0400164 [board_ahci_avn] = {
165 .flags = AHCI_FLAG_COMMON,
166 .pio_mask = ATA_PIO4,
167 .udma_mask = ATA_UDMA6,
168 .port_ops = &ahci_avn_ops,
169 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530170 [board_ahci_mcp65] = {
Tejun Heo83f2b962010-03-30 10:28:32 +0900171 AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
172 AHCI_HFLAG_YES_NCQ),
Tejun Heoae01b242011-03-16 11:14:55 +0100173 .flags = AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
Tejun Heo83f2b962010-03-30 10:28:32 +0900174 .pio_mask = ATA_PIO4,
175 .udma_mask = ATA_UDMA6,
176 .port_ops = &ahci_ops,
177 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530178 [board_ahci_mcp77] = {
Tejun Heo83f2b962010-03-30 10:28:32 +0900179 AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP),
180 .flags = AHCI_FLAG_COMMON,
181 .pio_mask = ATA_PIO4,
182 .udma_mask = ATA_UDMA6,
183 .port_ops = &ahci_ops,
184 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530185 [board_ahci_mcp89] = {
Tejun Heo83f2b962010-03-30 10:28:32 +0900186 AHCI_HFLAGS (AHCI_HFLAG_NO_FPDMA_AA),
Tejun Heo441577e2010-03-29 10:32:39 +0900187 .flags = AHCI_FLAG_COMMON,
188 .pio_mask = ATA_PIO4,
189 .udma_mask = ATA_UDMA6,
190 .port_ops = &ahci_ops,
191 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530192 [board_ahci_mv] = {
Tejun Heo441577e2010-03-29 10:32:39 +0900193 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
194 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
Sergei Shtylyov9cbe0562011-02-04 22:05:48 +0300195 .flags = ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
Tejun Heo441577e2010-03-29 10:32:39 +0900196 .pio_mask = ATA_PIO4,
197 .udma_mask = ATA_UDMA6,
198 .port_ops = &ahci_ops,
199 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530200 [board_ahci_sb600] = {
Tejun Heo417a1a62007-09-23 13:19:55 +0900201 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
Tejun Heo2fcad9d2009-10-03 18:27:29 +0900202 AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 |
203 AHCI_HFLAG_32BIT_ONLY),
Tejun Heo417a1a62007-09-23 13:19:55 +0900204 .flags = AHCI_FLAG_COMMON,
Erik Inge Bolsø14bdef982009-03-14 21:38:24 +0100205 .pio_mask = ATA_PIO4,
Jeff Garzik469248a2007-07-08 01:13:16 -0400206 .udma_mask = ATA_UDMA6,
Yuan-Hsin Chen345347c2011-06-21 17:17:38 +0800207 .port_ops = &ahci_pmp_retry_srst_ops,
Conke Hu55a61602007-03-27 18:33:05 +0800208 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530209 [board_ahci_sb700] = { /* for SB700 and SB800 */
Shane Huangbd172432008-06-10 15:52:04 +0800210 AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL),
Shane Huange39fc8c2008-02-22 05:00:31 -0800211 .flags = AHCI_FLAG_COMMON,
Erik Inge Bolsø14bdef982009-03-14 21:38:24 +0100212 .pio_mask = ATA_PIO4,
Shane Huange39fc8c2008-02-22 05:00:31 -0800213 .udma_mask = ATA_UDMA6,
Yuan-Hsin Chen345347c2011-06-21 17:17:38 +0800214 .port_ops = &ahci_pmp_retry_srst_ops,
Shane Huange39fc8c2008-02-22 05:00:31 -0800215 },
Jeffrin Josefacb8fa2012-06-05 01:33:37 +0530216 [board_ahci_vt8251] = {
Tejun Heo441577e2010-03-29 10:32:39 +0900217 AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
Tejun Heoe297d992008-06-10 00:13:04 +0900218 .flags = AHCI_FLAG_COMMON,
Erik Inge Bolsø14bdef982009-03-14 21:38:24 +0100219 .pio_mask = ATA_PIO4,
Tejun Heoe297d992008-06-10 00:13:04 +0900220 .udma_mask = ATA_UDMA6,
Tejun Heo441577e2010-03-29 10:32:39 +0900221 .port_ops = &ahci_vt8251_ops,
Shaohua Li1b677af2009-11-16 09:56:05 +0800222 },
Linus Torvalds1da177e2005-04-16 15:20:36 -0700223};
224
Jeff Garzik3b7d6972005-11-10 11:04:11 -0500225static const struct pci_device_id ahci_pci_tbl[] = {
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400226 /* Intel */
Jeff Garzik54bb3a942006-09-27 22:20:11 -0400227 { PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
228 { PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
229 { PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
230 { PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
231 { PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
Tejun Heo82490c02007-01-23 15:13:39 +0900232 { PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */
Jeff Garzik54bb3a942006-09-27 22:20:11 -0400233 { PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
234 { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
235 { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
236 { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
Tejun Heo7a234af2007-09-03 12:44:57 +0900237 { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
Shaohua Li1b677af2009-11-16 09:56:05 +0800238 { PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8 */
Tejun Heo7a234af2007-09-03 12:44:57 +0900239 { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
240 { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
241 { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
242 { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
243 { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
244 { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
245 { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
246 { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
247 { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
248 { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
249 { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
250 { PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */
251 { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
252 { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
253 { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
Jason Gastond4155e62007-09-20 17:35:00 -0400254 { PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
255 { PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
Jason Gaston16ad1ad2008-01-28 17:34:14 -0800256 { PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
Mark Goodwinb2dde6a2009-06-26 10:44:11 -0500257 { PCI_VDEVICE(INTEL, 0x3a22), board_ahci }, /* ICH10 */
Jason Gaston16ad1ad2008-01-28 17:34:14 -0800258 { PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
David Milburnc1f57d92009-07-22 15:15:56 -0500259 { PCI_VDEVICE(INTEL, 0x3b22), board_ahci }, /* PCH AHCI */
260 { PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
Seth Heasleyadcb5302008-08-11 17:03:09 -0700261 { PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
Seth Heasley8e48b6b2008-08-27 16:47:22 -0700262 { PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
David Milburnc1f57d92009-07-22 15:15:56 -0500263 { PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */
Seth Heasleyadcb5302008-08-11 17:03:09 -0700264 { PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
Seth Heasley8e48b6b2008-08-27 16:47:22 -0700265 { PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
David Milburnc1f57d92009-07-22 15:15:56 -0500266 { PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
Alexandra Yates342decf2016-02-05 15:27:49 -0800267 { PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
268 { PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
269 { PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */
270 { PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */
271 { PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */
272 { PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */
273 { PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */
274 { PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */
275 { PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */
276 { PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */
277 { PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */
278 { PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */
279 { PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */
280 { PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */
281 { PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */
282 { PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */
283 { PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */
284 { PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */
285 { PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
286 { PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
Seth Heasley5623cab2010-01-12 17:00:18 -0800287 { PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
288 { PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
289 { PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
290 { PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
291 { PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
292 { PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
Seth Heasley992b3fb2010-09-09 09:44:56 -0700293 { PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
294 { PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */
295 { PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */
Seth Heasley64a39032011-03-11 11:57:42 -0800296 { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
Seth Heasleya4a461a2011-01-10 12:57:17 -0800297 { PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
Seth Heasley181e3ce2011-04-20 08:45:20 -0700298 { PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
299 { PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
300 { PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
301 { PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
302 { PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
303 { PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
Seth Heasley2cab7a42011-07-14 16:50:49 -0700304 { PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
Seth Heasleyea4ace62012-01-23 16:27:30 -0800305 { PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
306 { PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
307 { PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
308 { PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
309 { PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
310 { PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
311 { PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
312 { PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
James Ralston77b12bc92012-08-09 09:02:31 -0700313 { PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
314 { PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
315 { PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
316 { PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */
317 { PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */
318 { PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
319 { PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
320 { PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
Seth Heasley29e674d2013-01-25 12:01:05 -0800321 { PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
322 { PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
323 { PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
324 { PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */
325 { PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */
326 { PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
327 { PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
328 { PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
Dan Williamsdbfe8ef2015-05-08 15:23:55 -0400329 { PCI_VDEVICE(INTEL, 0x1f32), board_ahci_avn }, /* Avoton AHCI */
330 { PCI_VDEVICE(INTEL, 0x1f33), board_ahci_avn }, /* Avoton AHCI */
331 { PCI_VDEVICE(INTEL, 0x1f34), board_ahci_avn }, /* Avoton RAID */
332 { PCI_VDEVICE(INTEL, 0x1f35), board_ahci_avn }, /* Avoton RAID */
333 { PCI_VDEVICE(INTEL, 0x1f36), board_ahci_avn }, /* Avoton RAID */
334 { PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */
335 { PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */
336 { PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */
James Ralstonefda3322013-02-21 11:08:51 -0800337 { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
338 { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
James Ralston151743fd82013-02-08 17:34:47 -0800339 { PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
340 { PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
341 { PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
342 { PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
343 { PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
344 { PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
345 { PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
346 { PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
Seth Heasley1cfc7df2013-06-19 16:36:45 -0700347 { PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
James Ralston9f961a52013-11-04 09:24:58 -0800348 { PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
349 { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
350 { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
351 { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
James Ralston1b071a02014-08-27 14:29:07 -0700352 { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
353 { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
354 { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
355 { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
356 { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
357 { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
358 { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
359 { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
Devin Ryles249cd0a2014-11-07 17:59:05 -0500360 { PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
361 { PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
362 { PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
Charles_Rose@Dell.comc5967b72015-11-06 14:18:56 -0600363 { PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
James Ralston690000b2014-10-13 15:16:38 -0700364 { PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
James Ralston690000b2014-10-13 15:16:38 -0700365 { PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
Charles_Rose@Dell.comc5967b72015-11-06 14:18:56 -0600366 { PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
James Ralston690000b2014-10-13 15:16:38 -0700367 { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
368 { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
Alexandra Yates4d92f002015-11-16 11:22:16 -0500369 { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
370 { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
371 { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
372 { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
373 { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
374 { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
375 { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
376 { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
377 { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
378 { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400379
Tejun Heoe34bb372007-02-26 20:24:03 +0900380 /* JMicron 360/1/3/5/6, match class to avoid IDE function */
381 { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
382 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
Ben Hutchings1fefb8f2012-09-10 01:09:04 +0100383 /* JMicron 362B and 362C have an AHCI function with IDE class code */
384 { PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
385 { PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
Zhang Rui91f15fb2015-08-24 15:27:11 -0500386 /* May need to update quirk_jmicron_async_suspend() for additions */
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400387
388 /* ATI */
Conke Huc65ec1c2007-04-11 18:23:14 +0800389 { PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
Shane Huange39fc8c2008-02-22 05:00:31 -0800390 { PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700 }, /* ATI SB700/800 */
391 { PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700 }, /* ATI SB700/800 */
392 { PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700 }, /* ATI SB700/800 */
393 { PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700 }, /* ATI SB700/800 */
394 { PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */
395 { PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400396
Shane Huange2dd90b2009-07-29 11:34:49 +0800397 /* AMD */
Shane Huang5deab532009-10-13 11:14:00 +0800398 { PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
Shane Huangfafe5c3d82013-06-03 18:24:10 +0800399 { PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
Shane Huange2dd90b2009-07-29 11:34:49 +0800400 /* AMD is using RAID class only for ahci controllers */
401 { PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
402 PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
403
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400404 /* VIA */
Jeff Garzik54bb3a942006-09-27 22:20:11 -0400405 { PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
Tejun Heobf335542007-04-11 17:27:14 +0900406 { PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400407
408 /* NVIDIA */
Tejun Heoe297d992008-06-10 00:13:04 +0900409 { PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 }, /* MCP65 */
410 { PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 }, /* MCP65 */
411 { PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 }, /* MCP65 */
412 { PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 }, /* MCP65 */
413 { PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 }, /* MCP65 */
414 { PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 }, /* MCP65 */
415 { PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 }, /* MCP65 */
416 { PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 }, /* MCP65 */
Tejun Heo441577e2010-03-29 10:32:39 +0900417 { PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_mcp67 }, /* MCP67 */
418 { PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_mcp67 }, /* MCP67 */
419 { PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_mcp67 }, /* MCP67 */
420 { PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_mcp67 }, /* MCP67 */
421 { PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_mcp67 }, /* MCP67 */
422 { PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_mcp67 }, /* MCP67 */
423 { PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_mcp67 }, /* MCP67 */
424 { PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_mcp67 }, /* MCP67 */
425 { PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_mcp67 }, /* MCP67 */
426 { PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_mcp67 }, /* MCP67 */
427 { PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_mcp67 }, /* MCP67 */
428 { PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_mcp67 }, /* MCP67 */
429 { PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_mcp_linux }, /* Linux ID */
430 { PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_mcp_linux }, /* Linux ID */
431 { PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_mcp_linux }, /* Linux ID */
432 { PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_mcp_linux }, /* Linux ID */
433 { PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_mcp_linux }, /* Linux ID */
434 { PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_mcp_linux }, /* Linux ID */
435 { PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_mcp_linux }, /* Linux ID */
436 { PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_mcp_linux }, /* Linux ID */
437 { PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_mcp_linux }, /* Linux ID */
438 { PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_mcp_linux }, /* Linux ID */
439 { PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_mcp_linux }, /* Linux ID */
440 { PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_mcp_linux }, /* Linux ID */
441 { PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_mcp_linux }, /* Linux ID */
442 { PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_mcp_linux }, /* Linux ID */
443 { PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_mcp_linux }, /* Linux ID */
444 { PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_mcp_linux }, /* Linux ID */
445 { PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_mcp73 }, /* MCP73 */
446 { PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_mcp73 }, /* MCP73 */
447 { PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_mcp73 }, /* MCP73 */
448 { PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_mcp73 }, /* MCP73 */
449 { PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_mcp73 }, /* MCP73 */
450 { PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_mcp73 }, /* MCP73 */
451 { PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_mcp73 }, /* MCP73 */
452 { PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_mcp73 }, /* MCP73 */
453 { PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_mcp73 }, /* MCP73 */
454 { PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_mcp73 }, /* MCP73 */
455 { PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_mcp73 }, /* MCP73 */
456 { PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_mcp73 }, /* MCP73 */
457 { PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci_mcp77 }, /* MCP77 */
458 { PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci_mcp77 }, /* MCP77 */
459 { PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci_mcp77 }, /* MCP77 */
460 { PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci_mcp77 }, /* MCP77 */
461 { PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci_mcp77 }, /* MCP77 */
462 { PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci_mcp77 }, /* MCP77 */
463 { PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci_mcp77 }, /* MCP77 */
464 { PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci_mcp77 }, /* MCP77 */
465 { PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci_mcp77 }, /* MCP77 */
466 { PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci_mcp77 }, /* MCP77 */
467 { PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci_mcp77 }, /* MCP77 */
468 { PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci_mcp77 }, /* MCP77 */
469 { PCI_VDEVICE(NVIDIA, 0x0ab4), board_ahci_mcp79 }, /* MCP79 */
470 { PCI_VDEVICE(NVIDIA, 0x0ab5), board_ahci_mcp79 }, /* MCP79 */
471 { PCI_VDEVICE(NVIDIA, 0x0ab6), board_ahci_mcp79 }, /* MCP79 */
472 { PCI_VDEVICE(NVIDIA, 0x0ab7), board_ahci_mcp79 }, /* MCP79 */
473 { PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci_mcp79 }, /* MCP79 */
474 { PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci_mcp79 }, /* MCP79 */
475 { PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci_mcp79 }, /* MCP79 */
476 { PCI_VDEVICE(NVIDIA, 0x0abb), board_ahci_mcp79 }, /* MCP79 */
477 { PCI_VDEVICE(NVIDIA, 0x0abc), board_ahci_mcp79 }, /* MCP79 */
478 { PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci_mcp79 }, /* MCP79 */
479 { PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci_mcp79 }, /* MCP79 */
480 { PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci_mcp79 }, /* MCP79 */
481 { PCI_VDEVICE(NVIDIA, 0x0d84), board_ahci_mcp89 }, /* MCP89 */
482 { PCI_VDEVICE(NVIDIA, 0x0d85), board_ahci_mcp89 }, /* MCP89 */
483 { PCI_VDEVICE(NVIDIA, 0x0d86), board_ahci_mcp89 }, /* MCP89 */
484 { PCI_VDEVICE(NVIDIA, 0x0d87), board_ahci_mcp89 }, /* MCP89 */
485 { PCI_VDEVICE(NVIDIA, 0x0d88), board_ahci_mcp89 }, /* MCP89 */
486 { PCI_VDEVICE(NVIDIA, 0x0d89), board_ahci_mcp89 }, /* MCP89 */
487 { PCI_VDEVICE(NVIDIA, 0x0d8a), board_ahci_mcp89 }, /* MCP89 */
488 { PCI_VDEVICE(NVIDIA, 0x0d8b), board_ahci_mcp89 }, /* MCP89 */
489 { PCI_VDEVICE(NVIDIA, 0x0d8c), board_ahci_mcp89 }, /* MCP89 */
490 { PCI_VDEVICE(NVIDIA, 0x0d8d), board_ahci_mcp89 }, /* MCP89 */
491 { PCI_VDEVICE(NVIDIA, 0x0d8e), board_ahci_mcp89 }, /* MCP89 */
492 { PCI_VDEVICE(NVIDIA, 0x0d8f), board_ahci_mcp89 }, /* MCP89 */
Jeff Garzikfe7fa312006-06-22 23:05:36 -0400493
Jeff Garzik95916ed2006-07-29 04:10:14 -0400494 /* SiS */
Tejun Heo20e2de42008-08-01 12:51:43 +0900495 { PCI_VDEVICE(SI, 0x1184), board_ahci }, /* SiS 966 */
496 { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 968 */
497 { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
Jeff Garzik95916ed2006-07-29 04:10:14 -0400498
Alessandro Rubini318893e2012-01-06 13:33:39 +0100499 /* ST Microelectronics */
500 { PCI_VDEVICE(STMICRO, 0xCC06), board_ahci }, /* ST ConneXt */
501
Jeff Garzikcd70c262007-07-08 02:29:42 -0400502 /* Marvell */
503 { PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv }, /* 6145 */
Jose Alberto Regueroc40e7cb2008-03-13 23:22:24 +0100504 { PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv }, /* 6121 */
Myron Stowe69fd3152013-04-08 11:32:49 -0600505 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9123),
Anssi Hannula10aca062011-01-18 20:03:26 -0500506 .class = PCI_CLASS_STORAGE_SATA_AHCI,
507 .class_mask = 0xffffff,
Tejun Heo5f173102010-07-24 16:53:48 +0200508 .driver_data = board_ahci_yes_fbs }, /* 88se9128 */
Myron Stowe69fd3152013-04-08 11:32:49 -0600509 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9125),
Per Jessen467b41c2011-02-08 13:54:32 +0100510 .driver_data = board_ahci_yes_fbs }, /* 88se9125 */
Simon Guinote098f5c2013-12-23 13:24:35 +0100511 { PCI_DEVICE_SUB(PCI_VENDOR_ID_MARVELL_EXT, 0x9178,
512 PCI_VENDOR_ID_MARVELL_EXT, 0x9170),
513 .driver_data = board_ahci_yes_fbs }, /* 88se9170 */
Myron Stowe69fd3152013-04-08 11:32:49 -0600514 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
Matt Johnson642d8922012-04-27 01:42:30 -0500515 .driver_data = board_ahci_yes_fbs }, /* 88se9172 */
George Spelvinfcce9a32013-05-29 10:20:35 +0900516 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
Murali Karicheric5edfff2014-09-05 13:21:00 -0400517 .driver_data = board_ahci_yes_fbs }, /* 88se9182 */
518 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9182),
George Spelvinfcce9a32013-05-29 10:20:35 +0900519 .driver_data = board_ahci_yes_fbs }, /* 88se9172 */
Myron Stowe69fd3152013-04-08 11:32:49 -0600520 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
Alan Cox17c60c62012-09-04 16:07:18 +0100521 .driver_data = board_ahci_yes_fbs }, /* 88se9172 on some Gigabyte */
Andreas Schrägle754a2922014-05-24 16:35:43 +0200522 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0),
523 .driver_data = board_ahci_yes_fbs },
Johannes Thumshirna40cf3f2015-10-20 09:31:22 +0200524 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a2), /* 88se91a2 */
525 .driver_data = board_ahci_yes_fbs },
Myron Stowe69fd3152013-04-08 11:32:49 -0600526 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
Tejun Heo50be5e32010-11-29 15:57:14 +0100527 .driver_data = board_ahci_yes_fbs },
Samir Benmendil6d5278a2013-11-17 23:56:17 +0100528 { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
529 .driver_data = board_ahci_yes_fbs },
Jérôme Carreterod2518362014-06-03 14:56:25 -0400530 { PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
531 .driver_data = board_ahci_yes_fbs },
Jeff Garzikcd70c262007-07-08 02:29:42 -0400532
Mark Nelsonc77a0362008-10-23 14:08:16 +1100533 /* Promise */
534 { PCI_VDEVICE(PROMISE, 0x3f20), board_ahci }, /* PDC42819 */
Romain Degezb32bfc02014-07-11 18:08:13 +0200535 { PCI_VDEVICE(PROMISE, 0x3781), board_ahci }, /* FastTrak TX8660 ahci-mode */
Mark Nelsonc77a0362008-10-23 14:08:16 +1100536
Keng-Yu Linc9703762011-11-09 01:47:36 -0500537 /* Asmedia */
Alan Cox7b4f6ec2012-09-04 16:25:25 +0100538 { PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci }, /* ASM1060 */
539 { PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci }, /* ASM1060 */
540 { PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci }, /* ASM1061 */
541 { PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci }, /* ASM1062 */
Keng-Yu Linc9703762011-11-09 01:47:36 -0500542
Levente Kurusa67809f82014-02-18 10:22:17 -0500543 /*
Tejun Heo66a7cbc2014-10-27 10:22:56 -0400544 * Samsung SSDs found on some macbooks. NCQ times out if MSI is
545 * enabled. https://bugzilla.kernel.org/show_bug.cgi?id=60731
Levente Kurusa67809f82014-02-18 10:22:17 -0500546 */
Tejun Heo66a7cbc2014-10-27 10:22:56 -0400547 { PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi },
Tejun Heo2b21ef02014-12-04 13:13:28 -0500548 { PCI_VDEVICE(SAMSUNG, 0xa800), board_ahci_nomsi },
Levente Kurusa67809f82014-02-18 10:22:17 -0500549
Hugh Daschbach7f9c9f82013-01-04 14:39:09 -0800550 /* Enmotus */
551 { PCI_DEVICE(0x1c44, 0x8000), board_ahci },
552
Jeff Garzik415ae2b2006-11-01 05:10:42 -0500553 /* Generic, PCI class code for AHCI */
554 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
Conke Huc9f89472007-01-09 05:32:51 -0500555 PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
Jeff Garzik415ae2b2006-11-01 05:10:42 -0500556
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 { } /* terminate list */
558};
559
560
561static struct pci_driver ahci_pci_driver = {
562 .name = DRV_NAME,
563 .id_table = ahci_pci_tbl,
564 .probe = ahci_init_one,
Tejun Heo24dc5f32007-01-20 16:00:28 +0900565 .remove = ata_pci_remove_one,
Tejun Heo438ac6d2007-03-02 17:31:26 +0900566#ifdef CONFIG_PM
Tejun Heoc1332872006-07-26 15:59:26 +0900567 .suspend = ahci_pci_device_suspend,
568 .resume = ahci_pci_device_resume,
Tejun Heo438ac6d2007-03-02 17:31:26 +0900569#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570};
571
Alan Cox5b66c822008-09-03 14:48:34 +0100572#if defined(CONFIG_PATA_MARVELL) || defined(CONFIG_PATA_MARVELL_MODULE)
573static int marvell_enable;
574#else
575static int marvell_enable = 1;
576#endif
577module_param(marvell_enable, int, 0644);
578MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
579
580
Anton Vorontsov394d6e52010-03-03 20:17:36 +0300581static void ahci_pci_save_initial_config(struct pci_dev *pdev,
582 struct ahci_host_priv *hpriv)
583{
Anton Vorontsov394d6e52010-03-03 20:17:36 +0300584 if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
585 dev_info(&pdev->dev, "JMB361 has only one port\n");
Antoine Tenart9a23c1d2014-11-03 09:56:11 +0100586 hpriv->force_port_map = 1;
Anton Vorontsov394d6e52010-03-03 20:17:36 +0300587 }
588
589 /*
590 * Temporary Marvell 6145 hack: PATA port presence
591 * is asserted through the standard AHCI port
592 * presence register, as bit 4 (counting from 0)
593 */
594 if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
595 if (pdev->device == 0x6121)
Antoine Tenart9a23c1d2014-11-03 09:56:11 +0100596 hpriv->mask_port_map = 0x3;
Anton Vorontsov394d6e52010-03-03 20:17:36 +0300597 else
Antoine Tenart9a23c1d2014-11-03 09:56:11 +0100598 hpriv->mask_port_map = 0xf;
Anton Vorontsov394d6e52010-03-03 20:17:36 +0300599 dev_info(&pdev->dev,
600 "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.\n");
601 }
602
Antoine Ténart725c7b52014-07-30 20:13:56 +0200603 ahci_save_initial_config(&pdev->dev, hpriv);
Anton Vorontsov394d6e52010-03-03 20:17:36 +0300604}
605
Anton Vorontsov33030402010-03-03 20:17:39 +0300606static int ahci_pci_reset_controller(struct ata_host *host)
607{
608 struct pci_dev *pdev = to_pci_dev(host->dev);
609
610 ahci_reset_controller(host);
611
Tejun Heod91542c2006-07-26 15:59:26 +0900612 if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
Anton Vorontsov33030402010-03-03 20:17:39 +0300613 struct ahci_host_priv *hpriv = host->private_data;
Tejun Heod91542c2006-07-26 15:59:26 +0900614 u16 tmp16;
615
616 /* configure PCS */
617 pci_read_config_word(pdev, 0x92, &tmp16);
Tejun Heo49f29092007-11-19 16:03:44 +0900618 if ((tmp16 & hpriv->port_map) != hpriv->port_map) {
619 tmp16 |= hpriv->port_map;
620 pci_write_config_word(pdev, 0x92, tmp16);
621 }
Tejun Heod91542c2006-07-26 15:59:26 +0900622 }
623
624 return 0;
625}
626
Anton Vorontsov781d6552010-03-03 20:17:42 +0300627static void ahci_pci_init_controller(struct ata_host *host)
628{
629 struct ahci_host_priv *hpriv = host->private_data;
630 struct pci_dev *pdev = to_pci_dev(host->dev);
631 void __iomem *port_mmio;
632 u32 tmp;
Jose Alberto Regueroc40e7cb2008-03-13 23:22:24 +0100633 int mv;
Tejun Heod91542c2006-07-26 15:59:26 +0900634
Tejun Heo417a1a62007-09-23 13:19:55 +0900635 if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
Jose Alberto Regueroc40e7cb2008-03-13 23:22:24 +0100636 if (pdev->device == 0x6121)
637 mv = 2;
638 else
639 mv = 4;
640 port_mmio = __ahci_port_base(host, mv);
Jeff Garzikcd70c262007-07-08 02:29:42 -0400641
642 writel(0, port_mmio + PORT_IRQ_MASK);
643
644 /* clear port IRQ */
645 tmp = readl(port_mmio + PORT_IRQ_STAT);
646 VPRINTK("PORT_IRQ_STAT 0x%x\n", tmp);
647 if (tmp)
648 writel(tmp, port_mmio + PORT_IRQ_STAT);
649 }
650
Anton Vorontsov781d6552010-03-03 20:17:42 +0300651 ahci_init_controller(host);
Tejun Heod91542c2006-07-26 15:59:26 +0900652}
653
Tejun Heocc0680a2007-08-06 18:36:23 +0900654static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
Tejun Heod4b2bab2007-02-02 16:50:52 +0900655 unsigned long deadline)
Tejun Heoad616ff2006-11-01 18:00:24 +0900656{
Tejun Heocc0680a2007-08-06 18:36:23 +0900657 struct ata_port *ap = link->ap;
Hans de Goede039ece32014-02-22 16:53:30 +0100658 struct ahci_host_priv *hpriv = ap->host->private_data;
Tejun Heo9dadd452008-04-07 22:47:19 +0900659 bool online;
Tejun Heoad616ff2006-11-01 18:00:24 +0900660 int rc;
661
662 DPRINTK("ENTER\n");
663
Tejun Heo4447d352007-04-17 23:44:08 +0900664 ahci_stop_engine(ap);
Tejun Heoad616ff2006-11-01 18:00:24 +0900665
Tejun Heocc0680a2007-08-06 18:36:23 +0900666 rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
Tejun Heo9dadd452008-04-07 22:47:19 +0900667 deadline, &online, NULL);
Tejun Heoad616ff2006-11-01 18:00:24 +0900668
Hans de Goede039ece32014-02-22 16:53:30 +0100669 hpriv->start_engine(ap);
Tejun Heoad616ff2006-11-01 18:00:24 +0900670
671 DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
672
673 /* vt8251 doesn't clear BSY on signature FIS reception,
674 * request follow-up softreset.
675 */
Tejun Heo9dadd452008-04-07 22:47:19 +0900676 return online ? -EAGAIN : rc;
Tejun Heoad616ff2006-11-01 18:00:24 +0900677}
678
Tejun Heoedc93052007-10-25 14:59:16 +0900679static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
680 unsigned long deadline)
681{
682 struct ata_port *ap = link->ap;
683 struct ahci_port_priv *pp = ap->private_data;
Hans de Goede039ece32014-02-22 16:53:30 +0100684 struct ahci_host_priv *hpriv = ap->host->private_data;
Tejun Heoedc93052007-10-25 14:59:16 +0900685 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
686 struct ata_taskfile tf;
Tejun Heo9dadd452008-04-07 22:47:19 +0900687 bool online;
Tejun Heoedc93052007-10-25 14:59:16 +0900688 int rc;
689
690 ahci_stop_engine(ap);
691
692 /* clear D2H reception area to properly wait for D2H FIS */
693 ata_tf_init(link->device, &tf);
Sergei Shtylyov9bbb1b02013-06-23 01:39:39 +0400694 tf.command = ATA_BUSY;
Tejun Heoedc93052007-10-25 14:59:16 +0900695 ata_tf_to_fis(&tf, 0, 0, d2h_fis);
696
697 rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
Tejun Heo9dadd452008-04-07 22:47:19 +0900698 deadline, &online, NULL);
Tejun Heoedc93052007-10-25 14:59:16 +0900699
Hans de Goede039ece32014-02-22 16:53:30 +0100700 hpriv->start_engine(ap);
Tejun Heoedc93052007-10-25 14:59:16 +0900701
Tejun Heoedc93052007-10-25 14:59:16 +0900702 /* The pseudo configuration device on SIMG4726 attached to
703 * ASUS P5W-DH Deluxe doesn't send signature FIS after
704 * hardreset if no device is attached to the first downstream
705 * port && the pseudo device locks up on SRST w/ PMP==0. To
706 * work around this, wait for !BSY only briefly. If BSY isn't
707 * cleared, perform CLO and proceed to IDENTIFY (achieved by
708 * ATA_LFLAG_NO_SRST and ATA_LFLAG_ASSUME_ATA).
709 *
710 * Wait for two seconds. Devices attached to downstream port
711 * which can't process the following IDENTIFY after this will
712 * have to be reset again. For most cases, this should
713 * suffice while making probing snappish enough.
714 */
Tejun Heo9dadd452008-04-07 22:47:19 +0900715 if (online) {
716 rc = ata_wait_after_reset(link, jiffies + 2 * HZ,
717 ahci_check_ready);
718 if (rc)
Shane Huang78d5ae32009-08-07 15:05:52 +0800719 ahci_kick_engine(ap);
Tejun Heo9dadd452008-04-07 22:47:19 +0900720 }
Tejun Heo9dadd452008-04-07 22:47:19 +0900721 return rc;
Tejun Heoedc93052007-10-25 14:59:16 +0900722}
723
Dan Williamsdbfe8ef2015-05-08 15:23:55 -0400724/*
725 * ahci_avn_hardreset - attempt more aggressive recovery of Avoton ports.
726 *
727 * It has been observed with some SSDs that the timing of events in the
728 * link synchronization phase can leave the port in a state that can not
729 * be recovered by a SATA-hard-reset alone. The failing signature is
730 * SStatus.DET stuck at 1 ("Device presence detected but Phy
731 * communication not established"). It was found that unloading and
732 * reloading the driver when this problem occurs allows the drive
733 * connection to be recovered (DET advanced to 0x3). The critical
734 * component of reloading the driver is that the port state machines are
735 * reset by bouncing "port enable" in the AHCI PCS configuration
736 * register. So, reproduce that effect by bouncing a port whenever we
737 * see DET==1 after a reset.
738 */
739static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
740 unsigned long deadline)
741{
742 const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
743 struct ata_port *ap = link->ap;
744 struct ahci_port_priv *pp = ap->private_data;
745 struct ahci_host_priv *hpriv = ap->host->private_data;
746 u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
747 unsigned long tmo = deadline - jiffies;
748 struct ata_taskfile tf;
749 bool online;
750 int rc, i;
751
752 DPRINTK("ENTER\n");
753
754 ahci_stop_engine(ap);
755
756 for (i = 0; i < 2; i++) {
757 u16 val;
758 u32 sstatus;
759 int port = ap->port_no;
760 struct ata_host *host = ap->host;
761 struct pci_dev *pdev = to_pci_dev(host->dev);
762
763 /* clear D2H reception area to properly wait for D2H FIS */
764 ata_tf_init(link->device, &tf);
765 tf.command = ATA_BUSY;
766 ata_tf_to_fis(&tf, 0, 0, d2h_fis);
767
768 rc = sata_link_hardreset(link, timing, deadline, &online,
769 ahci_check_ready);
770
771 if (sata_scr_read(link, SCR_STATUS, &sstatus) != 0 ||
772 (sstatus & 0xf) != 1)
773 break;
774
775 ata_link_printk(link, KERN_INFO, "avn bounce port%d\n",
776 port);
777
778 pci_read_config_word(pdev, 0x92, &val);
779 val &= ~(1 << port);
780 pci_write_config_word(pdev, 0x92, val);
781 ata_msleep(ap, 1000);
782 val |= 1 << port;
783 pci_write_config_word(pdev, 0x92, val);
784 deadline += tmo;
785 }
786
787 hpriv->start_engine(ap);
788
789 if (online)
790 *class = ahci_dev_classify(ap);
791
792 DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
793 return rc;
794}
795
796
Tejun Heo438ac6d2007-03-02 17:31:26 +0900797#ifdef CONFIG_PM
Tejun Heoc1332872006-07-26 15:59:26 +0900798static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg)
799{
Jingoo Han0a86e1c2013-06-03 14:05:36 +0900800 struct ata_host *host = pci_get_drvdata(pdev);
Tejun Heo9b10ae82009-05-30 20:50:12 +0900801 struct ahci_host_priv *hpriv = host->private_data;
Anton Vorontsovd8993342010-03-03 20:17:34 +0300802 void __iomem *mmio = hpriv->mmio;
Tejun Heoc1332872006-07-26 15:59:26 +0900803 u32 ctl;
804
Tejun Heo9b10ae82009-05-30 20:50:12 +0900805 if (mesg.event & PM_EVENT_SUSPEND &&
806 hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
Joe Perchesa44fec12011-04-15 15:51:58 -0700807 dev_err(&pdev->dev,
808 "BIOS update required for suspend/resume\n");
Tejun Heo9b10ae82009-05-30 20:50:12 +0900809 return -EIO;
810 }
811
Rafael J. Wysocki3a2d5b72008-02-23 19:13:25 +0100812 if (mesg.event & PM_EVENT_SLEEP) {
Tejun Heoc1332872006-07-26 15:59:26 +0900813 /* AHCI spec rev1.1 section 8.3.3:
814 * Software must disable interrupts prior to requesting a
815 * transition of the HBA to D3 state.
816 */
817 ctl = readl(mmio + HOST_CTL);
818 ctl &= ~HOST_IRQ_EN;
819 writel(ctl, mmio + HOST_CTL);
820 readl(mmio + HOST_CTL); /* flush */
821 }
822
823 return ata_pci_device_suspend(pdev, mesg);
824}
825
826static int ahci_pci_device_resume(struct pci_dev *pdev)
827{
Jingoo Han0a86e1c2013-06-03 14:05:36 +0900828 struct ata_host *host = pci_get_drvdata(pdev);
Tejun Heoc1332872006-07-26 15:59:26 +0900829 int rc;
830
Tejun Heo553c4aa2006-12-26 19:39:50 +0900831 rc = ata_pci_device_do_resume(pdev);
832 if (rc)
833 return rc;
Tejun Heoc1332872006-07-26 15:59:26 +0900834
James Lairdcb856962013-11-19 11:06:38 +1100835 /* Apple BIOS helpfully mangles the registers on resume */
836 if (is_mcp89_apple(pdev))
837 ahci_mcp89_apple_enable(pdev);
838
Tejun Heoc1332872006-07-26 15:59:26 +0900839 if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
Anton Vorontsov33030402010-03-03 20:17:39 +0300840 rc = ahci_pci_reset_controller(host);
Tejun Heoc1332872006-07-26 15:59:26 +0900841 if (rc)
842 return rc;
843
Anton Vorontsov781d6552010-03-03 20:17:42 +0300844 ahci_pci_init_controller(host);
Tejun Heoc1332872006-07-26 15:59:26 +0900845 }
846
Jeff Garzikcca39742006-08-24 03:19:22 -0400847 ata_host_resume(host);
Tejun Heoc1332872006-07-26 15:59:26 +0900848
849 return 0;
850}
Tejun Heo438ac6d2007-03-02 17:31:26 +0900851#endif
Tejun Heoc1332872006-07-26 15:59:26 +0900852
Tejun Heo4447d352007-04-17 23:44:08 +0900853static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 int rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
Alessandro Rubini318893e2012-01-06 13:33:39 +0100857 /*
858 * If the device fixup already set the dma_mask to some non-standard
859 * value, don't extend it here. This happens on STA2X11, for example.
860 */
861 if (pdev->dma_mask && pdev->dma_mask < DMA_BIT_MASK(32))
862 return 0;
863
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 if (using_dac &&
Quentin Lambertc54c7192015-04-08 14:34:10 +0200865 !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
866 rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 if (rc) {
Quentin Lambertc54c7192015-04-08 14:34:10 +0200868 rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 if (rc) {
Joe Perchesa44fec12011-04-15 15:51:58 -0700870 dev_err(&pdev->dev,
871 "64-bit DMA enable failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872 return rc;
873 }
874 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700875 } else {
Quentin Lambertc54c7192015-04-08 14:34:10 +0200876 rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700877 if (rc) {
Joe Perchesa44fec12011-04-15 15:51:58 -0700878 dev_err(&pdev->dev, "32-bit DMA enable failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 return rc;
880 }
Quentin Lambertc54c7192015-04-08 14:34:10 +0200881 rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700882 if (rc) {
Joe Perchesa44fec12011-04-15 15:51:58 -0700883 dev_err(&pdev->dev,
884 "32-bit consistent DMA enable failed\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700885 return rc;
886 }
887 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700888 return 0;
889}
890
Anton Vorontsov439fcae2010-03-03 20:17:43 +0300891static void ahci_pci_print_info(struct ata_host *host)
892{
893 struct pci_dev *pdev = to_pci_dev(host->dev);
894 u16 cc;
895 const char *scc_s;
896
897 pci_read_config_word(pdev, 0x0a, &cc);
898 if (cc == PCI_CLASS_STORAGE_IDE)
899 scc_s = "IDE";
900 else if (cc == PCI_CLASS_STORAGE_SATA)
901 scc_s = "SATA";
902 else if (cc == PCI_CLASS_STORAGE_RAID)
903 scc_s = "RAID";
904 else
905 scc_s = "unknown";
906
907 ahci_print_info(host, scc_s);
908}
909
Tejun Heoedc93052007-10-25 14:59:16 +0900910/* On ASUS P5W DH Deluxe, the second port of PCI device 00:1f.2 is
911 * hardwired to on-board SIMG 4726. The chipset is ICH8 and doesn't
912 * support PMP and the 4726 either directly exports the device
913 * attached to the first downstream port or acts as a hardware storage
914 * controller and emulate a single ATA device (can be RAID 0/1 or some
915 * other configuration).
916 *
917 * When there's no device attached to the first downstream port of the
918 * 4726, "Config Disk" appears, which is a pseudo ATA device to
919 * configure the 4726. However, ATA emulation of the device is very
920 * lame. It doesn't send signature D2H Reg FIS after the initial
921 * hardreset, pukes on SRST w/ PMP==0 and has bunch of other issues.
922 *
923 * The following function works around the problem by always using
924 * hardreset on the port and not depending on receiving signature FIS
925 * afterward. If signature FIS isn't received soon, ATA class is
926 * assumed without follow-up softreset.
927 */
928static void ahci_p5wdh_workaround(struct ata_host *host)
929{
Mathias Krause1bd06862014-08-31 10:57:09 +0200930 static const struct dmi_system_id sysids[] = {
Tejun Heoedc93052007-10-25 14:59:16 +0900931 {
932 .ident = "P5W DH Deluxe",
933 .matches = {
934 DMI_MATCH(DMI_SYS_VENDOR,
935 "ASUSTEK COMPUTER INC"),
936 DMI_MATCH(DMI_PRODUCT_NAME, "P5W DH Deluxe"),
937 },
938 },
939 { }
940 };
941 struct pci_dev *pdev = to_pci_dev(host->dev);
942
943 if (pdev->bus->number == 0 && pdev->devfn == PCI_DEVFN(0x1f, 2) &&
944 dmi_check_system(sysids)) {
945 struct ata_port *ap = host->ports[1];
946
Joe Perchesa44fec12011-04-15 15:51:58 -0700947 dev_info(&pdev->dev,
948 "enabling ASUS P5W DH Deluxe on-board SIMG4726 workaround\n");
Tejun Heoedc93052007-10-25 14:59:16 +0900949
950 ap->ops = &ahci_p5wdh_ops;
951 ap->link.flags |= ATA_LFLAG_NO_SRST | ATA_LFLAG_ASSUME_ATA;
952 }
953}
954
James Lairdcb856962013-11-19 11:06:38 +1100955/*
956 * Macbook7,1 firmware forcibly disables MCP89 AHCI and changes PCI ID when
957 * booting in BIOS compatibility mode. We restore the registers but not ID.
958 */
959static void ahci_mcp89_apple_enable(struct pci_dev *pdev)
960{
961 u32 val;
962
963 printk(KERN_INFO "ahci: enabling MCP89 AHCI mode\n");
964
965 pci_read_config_dword(pdev, 0xf8, &val);
966 val |= 1 << 0x1b;
967 /* the following changes the device ID, but appears not to affect function */
968 /* val = (val & ~0xf0000000) | 0x80000000; */
969 pci_write_config_dword(pdev, 0xf8, val);
970
971 pci_read_config_dword(pdev, 0x54c, &val);
972 val |= 1 << 0xc;
973 pci_write_config_dword(pdev, 0x54c, val);
974
975 pci_read_config_dword(pdev, 0x4a4, &val);
976 val &= 0xff;
977 val |= 0x01060100;
978 pci_write_config_dword(pdev, 0x4a4, val);
979
980 pci_read_config_dword(pdev, 0x54c, &val);
981 val &= ~(1 << 0xc);
982 pci_write_config_dword(pdev, 0x54c, val);
983
984 pci_read_config_dword(pdev, 0xf8, &val);
985 val &= ~(1 << 0x1b);
986 pci_write_config_dword(pdev, 0xf8, val);
987}
988
989static bool is_mcp89_apple(struct pci_dev *pdev)
990{
991 return pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
992 pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA &&
993 pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
994 pdev->subsystem_device == 0xcb89;
995}
996
Tejun Heo2fcad9d2009-10-03 18:27:29 +0900997/* only some SB600 ahci controllers can do 64bit DMA */
998static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
Shane Huang58a09b32009-05-27 15:04:43 +0800999{
1000 static const struct dmi_system_id sysids[] = {
Tejun Heo03d783b2009-08-16 21:04:02 +09001001 /*
1002 * The oldest version known to be broken is 0901 and
1003 * working is 1501 which was released on 2007-10-26.
Tejun Heo2fcad9d2009-10-03 18:27:29 +09001004 * Enable 64bit DMA on 1501 and anything newer.
1005 *
Tejun Heo03d783b2009-08-16 21:04:02 +09001006 * Please read bko#9412 for more info.
1007 */
Shane Huang58a09b32009-05-27 15:04:43 +08001008 {
1009 .ident = "ASUS M2A-VM",
1010 .matches = {
1011 DMI_MATCH(DMI_BOARD_VENDOR,
1012 "ASUSTeK Computer INC."),
1013 DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"),
1014 },
Tejun Heo03d783b2009-08-16 21:04:02 +09001015 .driver_data = "20071026", /* yyyymmdd */
Shane Huang58a09b32009-05-27 15:04:43 +08001016 },
Mark Nelsone65cc192009-11-03 20:06:48 +11001017 /*
1018 * All BIOS versions for the MSI K9A2 Platinum (MS-7376)
1019 * support 64bit DMA.
1020 *
1021 * BIOS versions earlier than 1.5 had the Manufacturer DMI
1022 * fields as "MICRO-STAR INTERANTIONAL CO.,LTD".
1023 * This spelling mistake was fixed in BIOS version 1.5, so
1024 * 1.5 and later have the Manufacturer as
1025 * "MICRO-STAR INTERNATIONAL CO.,LTD".
1026 * So try to match on DMI_BOARD_VENDOR of "MICRO-STAR INTER".
1027 *
1028 * BIOS versions earlier than 1.9 had a Board Product Name
1029 * DMI field of "MS-7376". This was changed to be
1030 * "K9A2 Platinum (MS-7376)" in version 1.9, but we can still
1031 * match on DMI_BOARD_NAME of "MS-7376".
1032 */
1033 {
1034 .ident = "MSI K9A2 Platinum",
1035 .matches = {
1036 DMI_MATCH(DMI_BOARD_VENDOR,
1037 "MICRO-STAR INTER"),
1038 DMI_MATCH(DMI_BOARD_NAME, "MS-7376"),
1039 },
1040 },
Mark Nelson3c4aa912011-06-27 16:33:44 +10001041 /*
Mark Nelsonff0173c2012-06-28 12:32:14 +10001042 * All BIOS versions for the MSI K9AGM2 (MS-7327) support
1043 * 64bit DMA.
1044 *
1045 * This board also had the typo mentioned above in the
1046 * Manufacturer DMI field (fixed in BIOS version 1.5), so
1047 * match on DMI_BOARD_VENDOR of "MICRO-STAR INTER" again.
1048 */
1049 {
1050 .ident = "MSI K9AGM2",
1051 .matches = {
1052 DMI_MATCH(DMI_BOARD_VENDOR,
1053 "MICRO-STAR INTER"),
1054 DMI_MATCH(DMI_BOARD_NAME, "MS-7327"),
1055 },
1056 },
1057 /*
Mark Nelson3c4aa912011-06-27 16:33:44 +10001058 * All BIOS versions for the Asus M3A support 64bit DMA.
1059 * (all release versions from 0301 to 1206 were tested)
1060 */
1061 {
1062 .ident = "ASUS M3A",
1063 .matches = {
1064 DMI_MATCH(DMI_BOARD_VENDOR,
1065 "ASUSTeK Computer INC."),
1066 DMI_MATCH(DMI_BOARD_NAME, "M3A"),
1067 },
1068 },
Shane Huang58a09b32009-05-27 15:04:43 +08001069 { }
1070 };
Tejun Heo03d783b2009-08-16 21:04:02 +09001071 const struct dmi_system_id *match;
Tejun Heo2fcad9d2009-10-03 18:27:29 +09001072 int year, month, date;
1073 char buf[9];
Shane Huang58a09b32009-05-27 15:04:43 +08001074
Tejun Heo03d783b2009-08-16 21:04:02 +09001075 match = dmi_first_match(sysids);
Shane Huang58a09b32009-05-27 15:04:43 +08001076 if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
Tejun Heo03d783b2009-08-16 21:04:02 +09001077 !match)
Shane Huang58a09b32009-05-27 15:04:43 +08001078 return false;
1079
Mark Nelsone65cc192009-11-03 20:06:48 +11001080 if (!match->driver_data)
1081 goto enable_64bit;
1082
Tejun Heo2fcad9d2009-10-03 18:27:29 +09001083 dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
1084 snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
Shane Huang58a09b32009-05-27 15:04:43 +08001085
Mark Nelsone65cc192009-11-03 20:06:48 +11001086 if (strcmp(buf, match->driver_data) >= 0)
1087 goto enable_64bit;
1088 else {
Joe Perchesa44fec12011-04-15 15:51:58 -07001089 dev_warn(&pdev->dev,
1090 "%s: BIOS too old, forcing 32bit DMA, update BIOS\n",
1091 match->ident);
Tejun Heo2fcad9d2009-10-03 18:27:29 +09001092 return false;
1093 }
Mark Nelsone65cc192009-11-03 20:06:48 +11001094
1095enable_64bit:
Joe Perchesa44fec12011-04-15 15:51:58 -07001096 dev_warn(&pdev->dev, "%s: enabling 64bit DMA\n", match->ident);
Mark Nelsone65cc192009-11-03 20:06:48 +11001097 return true;
Shane Huang58a09b32009-05-27 15:04:43 +08001098}
1099
Rafael J. Wysocki1fd68432009-01-19 20:57:36 +01001100static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
1101{
1102 static const struct dmi_system_id broken_systems[] = {
1103 {
1104 .ident = "HP Compaq nx6310",
1105 .matches = {
1106 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1107 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"),
1108 },
1109 /* PCI slot number of the controller */
1110 .driver_data = (void *)0x1FUL,
1111 },
Maciej Ruteckid2f9c062009-03-20 00:06:46 +01001112 {
1113 .ident = "HP Compaq 6720s",
1114 .matches = {
1115 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1116 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"),
1117 },
1118 /* PCI slot number of the controller */
1119 .driver_data = (void *)0x1FUL,
1120 },
Rafael J. Wysocki1fd68432009-01-19 20:57:36 +01001121
1122 { } /* terminate list */
1123 };
1124 const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
1125
1126 if (dmi) {
1127 unsigned long slot = (unsigned long)dmi->driver_data;
1128 /* apply the quirk only to on-board controllers */
1129 return slot == PCI_SLOT(pdev->devfn);
1130 }
1131
1132 return false;
1133}
1134
Tejun Heo9b10ae82009-05-30 20:50:12 +09001135static bool ahci_broken_suspend(struct pci_dev *pdev)
1136{
1137 static const struct dmi_system_id sysids[] = {
1138 /*
1139 * On HP dv[4-6] and HDX18 with earlier BIOSen, link
1140 * to the harddisk doesn't become online after
1141 * resuming from STR. Warn and fail suspend.
Tejun Heo9deb3432010-03-16 09:50:26 +09001142 *
1143 * http://bugzilla.kernel.org/show_bug.cgi?id=12276
1144 *
1145 * Use dates instead of versions to match as HP is
1146 * apparently recycling both product and version
1147 * strings.
1148 *
1149 * http://bugzilla.kernel.org/show_bug.cgi?id=15462
Tejun Heo9b10ae82009-05-30 20:50:12 +09001150 */
1151 {
1152 .ident = "dv4",
1153 .matches = {
1154 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1155 DMI_MATCH(DMI_PRODUCT_NAME,
1156 "HP Pavilion dv4 Notebook PC"),
1157 },
Tejun Heo9deb3432010-03-16 09:50:26 +09001158 .driver_data = "20090105", /* F.30 */
Tejun Heo9b10ae82009-05-30 20:50:12 +09001159 },
1160 {
1161 .ident = "dv5",
1162 .matches = {
1163 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1164 DMI_MATCH(DMI_PRODUCT_NAME,
1165 "HP Pavilion dv5 Notebook PC"),
1166 },
Tejun Heo9deb3432010-03-16 09:50:26 +09001167 .driver_data = "20090506", /* F.16 */
Tejun Heo9b10ae82009-05-30 20:50:12 +09001168 },
1169 {
1170 .ident = "dv6",
1171 .matches = {
1172 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1173 DMI_MATCH(DMI_PRODUCT_NAME,
1174 "HP Pavilion dv6 Notebook PC"),
1175 },
Tejun Heo9deb3432010-03-16 09:50:26 +09001176 .driver_data = "20090423", /* F.21 */
Tejun Heo9b10ae82009-05-30 20:50:12 +09001177 },
1178 {
1179 .ident = "HDX18",
1180 .matches = {
1181 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
1182 DMI_MATCH(DMI_PRODUCT_NAME,
1183 "HP HDX18 Notebook PC"),
1184 },
Tejun Heo9deb3432010-03-16 09:50:26 +09001185 .driver_data = "20090430", /* F.23 */
Tejun Heo9b10ae82009-05-30 20:50:12 +09001186 },
Tejun Heocedc9bf2010-01-28 16:04:15 +09001187 /*
1188 * Acer eMachines G725 has the same problem. BIOS
1189 * V1.03 is known to be broken. V3.04 is known to
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001190 * work. Between, there are V1.06, V2.06 and V3.03
Tejun Heocedc9bf2010-01-28 16:04:15 +09001191 * that we don't have much idea about. For now,
1192 * blacklist anything older than V3.04.
Tejun Heo9deb3432010-03-16 09:50:26 +09001193 *
1194 * http://bugzilla.kernel.org/show_bug.cgi?id=15104
Tejun Heocedc9bf2010-01-28 16:04:15 +09001195 */
1196 {
1197 .ident = "G725",
1198 .matches = {
1199 DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
1200 DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
1201 },
Tejun Heo9deb3432010-03-16 09:50:26 +09001202 .driver_data = "20091216", /* V3.04 */
Tejun Heocedc9bf2010-01-28 16:04:15 +09001203 },
Tejun Heo9b10ae82009-05-30 20:50:12 +09001204 { } /* terminate list */
1205 };
1206 const struct dmi_system_id *dmi = dmi_first_match(sysids);
Tejun Heo9deb3432010-03-16 09:50:26 +09001207 int year, month, date;
1208 char buf[9];
Tejun Heo9b10ae82009-05-30 20:50:12 +09001209
1210 if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
1211 return false;
1212
Tejun Heo9deb3432010-03-16 09:50:26 +09001213 dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
1214 snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
Tejun Heo9b10ae82009-05-30 20:50:12 +09001215
Tejun Heo9deb3432010-03-16 09:50:26 +09001216 return strcmp(buf, dmi->driver_data) < 0;
Tejun Heo9b10ae82009-05-30 20:50:12 +09001217}
1218
Tejun Heo55946392009-08-04 14:30:08 +09001219static bool ahci_broken_online(struct pci_dev *pdev)
1220{
1221#define ENCODE_BUSDEVFN(bus, slot, func) \
1222 (void *)(unsigned long)(((bus) << 8) | PCI_DEVFN((slot), (func)))
1223 static const struct dmi_system_id sysids[] = {
1224 /*
1225 * There are several gigabyte boards which use
1226 * SIMG5723s configured as hardware RAID. Certain
1227 * 5723 firmware revisions shipped there keep the link
1228 * online but fail to answer properly to SRST or
1229 * IDENTIFY when no device is attached downstream
1230 * causing libata to retry quite a few times leading
1231 * to excessive detection delay.
1232 *
1233 * As these firmwares respond to the second reset try
1234 * with invalid device signature, considering unknown
1235 * sig as offline works around the problem acceptably.
1236 */
1237 {
1238 .ident = "EP45-DQ6",
1239 .matches = {
1240 DMI_MATCH(DMI_BOARD_VENDOR,
1241 "Gigabyte Technology Co., Ltd."),
1242 DMI_MATCH(DMI_BOARD_NAME, "EP45-DQ6"),
1243 },
1244 .driver_data = ENCODE_BUSDEVFN(0x0a, 0x00, 0),
1245 },
1246 {
1247 .ident = "EP45-DS5",
1248 .matches = {
1249 DMI_MATCH(DMI_BOARD_VENDOR,
1250 "Gigabyte Technology Co., Ltd."),
1251 DMI_MATCH(DMI_BOARD_NAME, "EP45-DS5"),
1252 },
1253 .driver_data = ENCODE_BUSDEVFN(0x03, 0x00, 0),
1254 },
1255 { } /* terminate list */
1256 };
1257#undef ENCODE_BUSDEVFN
1258 const struct dmi_system_id *dmi = dmi_first_match(sysids);
1259 unsigned int val;
1260
1261 if (!dmi)
1262 return false;
1263
1264 val = (unsigned long)dmi->driver_data;
1265
1266 return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
1267}
1268
Jacob Pan0cf4a7d2014-04-15 22:27:11 -07001269static bool ahci_broken_devslp(struct pci_dev *pdev)
1270{
1271 /* device with broken DEVSLP but still showing SDS capability */
1272 static const struct pci_device_id ids[] = {
1273 { PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */
1274 {}
1275 };
1276
1277 return pci_match_id(ids, pdev);
1278}
1279
Markus Trippelsdorf8e513212009-10-09 05:41:47 +02001280#ifdef CONFIG_ATA_ACPI
Tejun Heof80ae7e2009-09-16 04:18:03 +09001281static void ahci_gtf_filter_workaround(struct ata_host *host)
1282{
1283 static const struct dmi_system_id sysids[] = {
1284 /*
1285 * Aspire 3810T issues a bunch of SATA enable commands
1286 * via _GTF including an invalid one and one which is
1287 * rejected by the device. Among the successful ones
1288 * is FPDMA non-zero offset enable which when enabled
1289 * only on the drive side leads to NCQ command
1290 * failures. Filter it out.
1291 */
1292 {
1293 .ident = "Aspire 3810T",
1294 .matches = {
1295 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
1296 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3810T"),
1297 },
1298 .driver_data = (void *)ATA_ACPI_FILTER_FPDMA_OFFSET,
1299 },
1300 { }
1301 };
1302 const struct dmi_system_id *dmi = dmi_first_match(sysids);
1303 unsigned int filter;
1304 int i;
1305
1306 if (!dmi)
1307 return;
1308
1309 filter = (unsigned long)dmi->driver_data;
Joe Perchesa44fec12011-04-15 15:51:58 -07001310 dev_info(host->dev, "applying extra ACPI _GTF filter 0x%x for %s\n",
1311 filter, dmi->ident);
Tejun Heof80ae7e2009-09-16 04:18:03 +09001312
1313 for (i = 0; i < host->n_ports; i++) {
1314 struct ata_port *ap = host->ports[i];
1315 struct ata_link *link;
1316 struct ata_device *dev;
1317
1318 ata_for_each_link(link, ap, EDGE)
1319 ata_for_each_dev(dev, link, ALL)
1320 dev->gtf_filter |= filter;
1321 }
1322}
Markus Trippelsdorf8e513212009-10-09 05:41:47 +02001323#else
1324static inline void ahci_gtf_filter_workaround(struct ata_host *host)
1325{}
1326#endif
Tejun Heof80ae7e2009-09-16 04:18:03 +09001327
Robert Richteree2aad42015-06-05 19:49:25 +02001328/*
Dan Williamsd684a902015-11-11 16:27:33 -08001329 * ahci_init_msix() - optionally enable per-port MSI-X otherwise defer
1330 * to single msi.
Robert Richteree2aad42015-06-05 19:49:25 +02001331 */
1332static int ahci_init_msix(struct pci_dev *pdev, unsigned int n_ports,
Dan Williamsd684a902015-11-11 16:27:33 -08001333 struct ahci_host_priv *hpriv, unsigned long flags)
Robert Richteree2aad42015-06-05 19:49:25 +02001334{
Dan Williamsd684a902015-11-11 16:27:33 -08001335 int nvec, i, rc;
Robert Richteree2aad42015-06-05 19:49:25 +02001336
1337 /* Do not init MSI-X if MSI is disabled for the device */
1338 if (hpriv->flags & AHCI_HFLAG_NO_MSI)
1339 return -ENODEV;
1340
1341 nvec = pci_msix_vec_count(pdev);
1342 if (nvec < 0)
1343 return nvec;
1344
Dan Williamsd684a902015-11-11 16:27:33 -08001345 /*
1346 * Proper MSI-X implementations will have a vector per-port.
1347 * Barring that, we prefer single-MSI over single-MSIX. If this
1348 * check fails (not enough MSI-X vectors for all ports) we will
1349 * be called again with the flag clear iff ahci_init_msi()
1350 * fails.
1351 */
1352 if (flags & AHCI_HFLAG_MULTI_MSIX) {
1353 if (nvec < n_ports)
1354 return -ENODEV;
1355 nvec = n_ports;
1356 } else if (nvec) {
1357 nvec = 1;
1358 } else {
1359 /*
1360 * Emit dev_err() since this was the non-legacy irq
1361 * method of last resort.
1362 */
Robert Richteree2aad42015-06-05 19:49:25 +02001363 rc = -ENODEV;
1364 goto fail;
1365 }
1366
Dan Williamsd684a902015-11-11 16:27:33 -08001367 for (i = 0; i < nvec; i++)
1368 hpriv->msix[i].entry = i;
1369 rc = pci_enable_msix_exact(pdev, hpriv->msix, nvec);
Robert Richteree2aad42015-06-05 19:49:25 +02001370 if (rc < 0)
1371 goto fail;
1372
Dan Williamsd684a902015-11-11 16:27:33 -08001373 if (nvec > 1)
1374 hpriv->flags |= AHCI_HFLAG_MULTI_MSIX;
1375 hpriv->irq = hpriv->msix[0].vector; /* for single msi-x */
Robert Richteree2aad42015-06-05 19:49:25 +02001376
Dan Williamsd684a902015-11-11 16:27:33 -08001377 return nvec;
Robert Richteree2aad42015-06-05 19:49:25 +02001378fail:
1379 dev_err(&pdev->dev,
1380 "failed to enable MSI-X with error %d, # of vectors: %d\n",
1381 rc, nvec);
1382
1383 return rc;
1384}
1385
Robert Richtera1c8231172015-05-31 13:55:17 +02001386static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
1387 struct ahci_host_priv *hpriv)
Alexander Gordeev5ca72c42012-11-19 16:02:48 +01001388{
Alexander Gordeevccf8f532014-04-17 14:13:50 +02001389 int rc, nvec;
Alexander Gordeev5ca72c42012-11-19 16:02:48 +01001390
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001391 if (hpriv->flags & AHCI_HFLAG_NO_MSI)
Robert Richtera1c8231172015-05-31 13:55:17 +02001392 return -ENODEV;
Alexander Gordeev5ca72c42012-11-19 16:02:48 +01001393
Alexander Gordeevfc061d92014-01-29 14:19:43 -07001394 nvec = pci_msi_vec_count(pdev);
1395 if (nvec < 0)
Robert Richtera1c8231172015-05-31 13:55:17 +02001396 return nvec;
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001397
1398 /*
1399 * If number of MSIs is less than number of ports then Sharing Last
1400 * Message mode could be enforced. In this case assume that advantage
1401 * of multipe MSIs is negated and use single MSI mode instead.
1402 */
Alexander Gordeevfc061d92014-01-29 14:19:43 -07001403 if (nvec < n_ports)
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001404 goto single_msi;
1405
Alexander Gordeevccf8f532014-04-17 14:13:50 +02001406 rc = pci_enable_msi_exact(pdev, nvec);
1407 if (rc == -ENOSPC)
Alexander Gordeevfc403632014-02-14 14:27:19 -07001408 goto single_msi;
Robert Richtera1c8231172015-05-31 13:55:17 +02001409 if (rc < 0)
1410 return rc;
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001411
Alexander Gordeevab0f9e72014-04-17 14:13:49 +02001412 /* fallback to single MSI mode if the controller enforced MRSM mode */
1413 if (readl(hpriv->mmio + HOST_CTL) & HOST_MRSM) {
1414 pci_disable_msi(pdev);
1415 printk(KERN_INFO "ahci: MRSM is on, fallback to single MSI\n");
1416 goto single_msi;
1417 }
1418
Alexander Gordeevc3ebd6a2014-09-25 15:13:21 +02001419 if (nvec > 1)
1420 hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
1421
Robert Richter21bfd1a2015-05-31 13:55:18 +02001422 goto out;
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001423
1424single_msi:
Robert Richter21bfd1a2015-05-31 13:55:18 +02001425 nvec = 1;
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001426
Robert Richtera1c8231172015-05-31 13:55:17 +02001427 rc = pci_enable_msi(pdev);
1428 if (rc < 0)
1429 return rc;
Robert Richter21bfd1a2015-05-31 13:55:18 +02001430out:
1431 hpriv->irq = pdev->irq;
Alexander Gordeev7b92b4f2013-12-30 08:28:14 +01001432
Robert Richter21bfd1a2015-05-31 13:55:18 +02001433 return nvec;
Robert Richtera1c8231172015-05-31 13:55:17 +02001434}
1435
1436static int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports,
1437 struct ahci_host_priv *hpriv)
1438{
1439 int nvec;
1440
Dan Williamsd684a902015-11-11 16:27:33 -08001441 /*
1442 * Try to enable per-port MSI-X. If the host is not capable
1443 * fall back to single MSI before finally attempting single
1444 * MSI-X.
1445 */
1446 nvec = ahci_init_msix(pdev, n_ports, hpriv, AHCI_HFLAG_MULTI_MSIX);
1447 if (nvec >= 0)
1448 return nvec;
1449
Robert Richtera1c8231172015-05-31 13:55:17 +02001450 nvec = ahci_init_msi(pdev, n_ports, hpriv);
1451 if (nvec >= 0)
1452 return nvec;
1453
Dan Williamsd684a902015-11-11 16:27:33 -08001454 /* try single-msix */
1455 nvec = ahci_init_msix(pdev, n_ports, hpriv, 0);
Robert Richteree2aad42015-06-05 19:49:25 +02001456 if (nvec >= 0)
1457 return nvec;
1458
Dan Williamsd684a902015-11-11 16:27:33 -08001459 /* legacy intx interrupts */
Alexander Gordeev5ca72c42012-11-19 16:02:48 +01001460 pci_intx(pdev, 1);
Robert Richter21bfd1a2015-05-31 13:55:18 +02001461 hpriv->irq = pdev->irq;
Robert Richtera1c8231172015-05-31 13:55:17 +02001462
Alexander Gordeev5ca72c42012-11-19 16:02:48 +01001463 return 0;
1464}
1465
Tejun Heo24dc5f32007-01-20 16:00:28 +09001466static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467{
Tejun Heoe297d992008-06-10 00:13:04 +09001468 unsigned int board_id = ent->driver_data;
1469 struct ata_port_info pi = ahci_port_info[board_id];
Tejun Heo4447d352007-04-17 23:44:08 +09001470 const struct ata_port_info *ppi[] = { &pi, NULL };
Tejun Heo24dc5f32007-01-20 16:00:28 +09001471 struct device *dev = &pdev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001472 struct ahci_host_priv *hpriv;
Tejun Heo4447d352007-04-17 23:44:08 +09001473 struct ata_host *host;
Alexander Gordeevc3ebd6a2014-09-25 15:13:21 +02001474 int n_ports, i, rc;
Alessandro Rubini318893e2012-01-06 13:33:39 +01001475 int ahci_pci_bar = AHCI_PCI_BAR_STANDARD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476
1477 VPRINTK("ENTER\n");
1478
Justin P. Mattockb429dd52010-07-03 07:29:25 -07001479 WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS);
Tejun Heo12fad3f2006-05-15 21:03:55 +09001480
Joe Perches06296a12011-04-15 15:52:00 -07001481 ata_print_version_once(&pdev->dev, DRV_VERSION);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482
Alan Cox5b66c822008-09-03 14:48:34 +01001483 /* The AHCI driver can only drive the SATA ports, the PATA driver
1484 can drive them all so if both drivers are selected make sure
1485 AHCI stays out of the way */
1486 if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
1487 return -ENODEV;
1488
James Lairdcb856962013-11-19 11:06:38 +11001489 /* Apple BIOS on MCP89 prevents us using AHCI */
1490 if (is_mcp89_apple(pdev))
1491 ahci_mcp89_apple_enable(pdev);
Tejun Heoc6353b42010-06-17 11:42:22 +02001492
Mark Nelson7a022672009-11-22 12:07:41 +11001493 /* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode.
1494 * At the moment, we can only use the AHCI mode. Let the users know
1495 * that for SAS drives they're out of luck.
1496 */
1497 if (pdev->vendor == PCI_VENDOR_ID_PROMISE)
Joe Perchesa44fec12011-04-15 15:51:58 -07001498 dev_info(&pdev->dev,
1499 "PDC42819 can only drive SATA devices with this driver\n");
Mark Nelson7a022672009-11-22 12:07:41 +11001500
Robert Richterb7ae1282015-06-05 19:49:26 +02001501 /* Some devices use non-standard BARs */
Alessandro Rubini318893e2012-01-06 13:33:39 +01001502 if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06)
1503 ahci_pci_bar = AHCI_PCI_BAR_STA2X11;
Hugh Daschbach7f9c9f82013-01-04 14:39:09 -08001504 else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000)
1505 ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS;
Robert Richterb7ae1282015-06-05 19:49:26 +02001506 else if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
1507 ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
Alessandro Rubini318893e2012-01-06 13:33:39 +01001508
Tejun Heo4447d352007-04-17 23:44:08 +09001509 /* acquire resources */
Tejun Heo24dc5f32007-01-20 16:00:28 +09001510 rc = pcim_enable_device(pdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 if (rc)
1512 return rc;
1513
Tejun Heoc4f77922007-12-06 15:09:43 +09001514 if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
1515 (pdev->device == 0x2652 || pdev->device == 0x2653)) {
1516 u8 map;
1517
1518 /* ICH6s share the same PCI ID for both piix and ahci
1519 * modes. Enabling ahci mode while MAP indicates
1520 * combined mode is a bad idea. Yield to ata_piix.
1521 */
1522 pci_read_config_byte(pdev, ICH_MAP, &map);
1523 if (map & 0x3) {
Joe Perchesa44fec12011-04-15 15:51:58 -07001524 dev_info(&pdev->dev,
1525 "controller is in combined mode, can't enable AHCI mode\n");
Tejun Heoc4f77922007-12-06 15:09:43 +09001526 return -ENODEV;
1527 }
1528 }
1529
Paul Bolle6fec8872013-12-16 11:34:21 +01001530 /* AHCI controllers often implement SFF compatible interface.
1531 * Grab all PCI BARs just in case.
1532 */
1533 rc = pcim_iomap_regions_request_all(pdev, 1 << ahci_pci_bar, DRV_NAME);
1534 if (rc == -EBUSY)
1535 pcim_pin_device(pdev);
1536 if (rc)
1537 return rc;
1538
Tejun Heo24dc5f32007-01-20 16:00:28 +09001539 hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
1540 if (!hpriv)
1541 return -ENOMEM;
Tejun Heo417a1a62007-09-23 13:19:55 +09001542 hpriv->flags |= (unsigned long)pi.private_data;
1543
Tejun Heoe297d992008-06-10 00:13:04 +09001544 /* MCP65 revision A1 and A2 can't do MSI */
1545 if (board_id == board_ahci_mcp65 &&
1546 (pdev->revision == 0xa1 || pdev->revision == 0xa2))
1547 hpriv->flags |= AHCI_HFLAG_NO_MSI;
1548
Shane Huange427fe02008-12-30 10:53:41 +08001549 /* SB800 does NOT need the workaround to ignore SERR_INTERNAL */
1550 if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
1551 hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
1552
Tejun Heo2fcad9d2009-10-03 18:27:29 +09001553 /* only some SB600s can do 64bit DMA */
1554 if (ahci_sb600_enable_64bit(pdev))
1555 hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY;
Shane Huang58a09b32009-05-27 15:04:43 +08001556
Alessandro Rubini318893e2012-01-06 13:33:39 +01001557 hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
Anton Vorontsovd8993342010-03-03 20:17:34 +03001558
Jacob Pan0cf4a7d2014-04-15 22:27:11 -07001559 /* must set flag prior to save config in order to take effect */
1560 if (ahci_broken_devslp(pdev))
1561 hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
1562
Tejun Heo4447d352007-04-17 23:44:08 +09001563 /* save initial config */
Anton Vorontsov394d6e52010-03-03 20:17:36 +03001564 ahci_pci_save_initial_config(pdev, hpriv);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
Tejun Heo4447d352007-04-17 23:44:08 +09001566 /* prepare host */
Robert Hancock453d3132010-01-26 22:33:23 -06001567 if (hpriv->cap & HOST_CAP_NCQ) {
1568 pi.flags |= ATA_FLAG_NCQ;
Tejun Heo83f2b962010-03-30 10:28:32 +09001569 /*
1570 * Auto-activate optimization is supposed to be
1571 * supported on all AHCI controllers indicating NCQ
1572 * capability, but it seems to be broken on some
1573 * chipsets including NVIDIAs.
1574 */
1575 if (!(hpriv->flags & AHCI_HFLAG_NO_FPDMA_AA))
Robert Hancock453d3132010-01-26 22:33:23 -06001576 pi.flags |= ATA_FLAG_FPDMA_AA;
Marc Carino40fb59e2013-08-24 23:22:49 -07001577
1578 /*
1579 * All AHCI controllers should be forward-compatible
1580 * with the new auxiliary field. This code should be
1581 * conditionalized if any buggy AHCI controllers are
1582 * encountered.
1583 */
1584 pi.flags |= ATA_FLAG_FPDMA_AUX;
Robert Hancock453d3132010-01-26 22:33:23 -06001585 }
Tejun Heo4447d352007-04-17 23:44:08 +09001586
Tejun Heo7d50b602007-09-23 13:19:54 +09001587 if (hpriv->cap & HOST_CAP_PMP)
1588 pi.flags |= ATA_FLAG_PMP;
1589
Anton Vorontsov0cbb0e72010-03-03 20:17:45 +03001590 ahci_set_em_messages(hpriv, &pi);
Kristen Carlson Accardi18f7ba42008-06-03 10:33:55 -07001591
Rafael J. Wysocki1fd68432009-01-19 20:57:36 +01001592 if (ahci_broken_system_poweroff(pdev)) {
1593 pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN;
1594 dev_info(&pdev->dev,
1595 "quirky BIOS, skipping spindown on poweroff\n");
1596 }
1597
Tejun Heo9b10ae82009-05-30 20:50:12 +09001598 if (ahci_broken_suspend(pdev)) {
1599 hpriv->flags |= AHCI_HFLAG_NO_SUSPEND;
Joe Perchesa44fec12011-04-15 15:51:58 -07001600 dev_warn(&pdev->dev,
1601 "BIOS update required for suspend/resume\n");
Tejun Heo9b10ae82009-05-30 20:50:12 +09001602 }
1603
Tejun Heo55946392009-08-04 14:30:08 +09001604 if (ahci_broken_online(pdev)) {
1605 hpriv->flags |= AHCI_HFLAG_SRST_TOUT_IS_OFFLINE;
1606 dev_info(&pdev->dev,
1607 "online status unreliable, applying workaround\n");
1608 }
1609
Tejun Heo837f5f82008-02-06 15:13:51 +09001610 /* CAP.NP sometimes indicate the index of the last enabled
1611 * port, at other times, that of the last possible port, so
1612 * determining the maximum port number requires looking at
1613 * both CAP.NP and port_map.
1614 */
1615 n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
1616
1617 host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
Tejun Heo4447d352007-04-17 23:44:08 +09001618 if (!host)
1619 return -ENOMEM;
Tejun Heo4447d352007-04-17 23:44:08 +09001620 host->private_data = hpriv;
Dan Williamsd684a902015-11-11 16:27:33 -08001621 hpriv->msix = devm_kzalloc(&pdev->dev,
1622 sizeof(struct msix_entry) * n_ports, GFP_KERNEL);
1623 if (!hpriv->msix)
1624 return -ENOMEM;
Robert Richter21bfd1a2015-05-31 13:55:18 +02001625 ahci_init_interrupts(pdev, n_ports, hpriv);
1626
Arjan van de Venf3d7f232009-01-26 02:05:44 -08001627 if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
Arjan van de Ven886ad092009-01-09 15:54:07 -08001628 host->flags |= ATA_HOST_PARALLEL_SCAN;
Arjan van de Venf3d7f232009-01-26 02:05:44 -08001629 else
Jingoo Hand2782d92013-10-05 09:15:16 +09001630 dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled\n");
Arjan van de Ven886ad092009-01-09 15:54:07 -08001631
Kristen Carlson Accardi18f7ba42008-06-03 10:33:55 -07001632 if (pi.flags & ATA_FLAG_EM)
1633 ahci_reset_em(host);
1634
Tejun Heo4447d352007-04-17 23:44:08 +09001635 for (i = 0; i < host->n_ports; i++) {
Jeff Garzikdab632e2007-05-28 08:33:01 -04001636 struct ata_port *ap = host->ports[i];
Tejun Heo4447d352007-04-17 23:44:08 +09001637
Alessandro Rubini318893e2012-01-06 13:33:39 +01001638 ata_port_pbar_desc(ap, ahci_pci_bar, -1, "abar");
1639 ata_port_pbar_desc(ap, ahci_pci_bar,
Tejun Heocbcdd872007-08-18 13:14:55 +09001640 0x100 + ap->port_no * 0x80, "port");
1641
Kristen Carlson Accardi18f7ba42008-06-03 10:33:55 -07001642 /* set enclosure management message type */
1643 if (ap->flags & ATA_FLAG_EM)
Harry Zhang008dbd62010-04-23 17:27:19 +08001644 ap->em_message_type = hpriv->em_msg_type;
Kristen Carlson Accardi18f7ba42008-06-03 10:33:55 -07001645
1646
Jeff Garzikdab632e2007-05-28 08:33:01 -04001647 /* disabled/not-implemented port */
Tejun Heo350756f2008-04-07 22:47:21 +09001648 if (!(hpriv->port_map & (1 << i)))
Jeff Garzikdab632e2007-05-28 08:33:01 -04001649 ap->ops = &ata_dummy_port_ops;
Tejun Heo4447d352007-04-17 23:44:08 +09001650 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001651
Tejun Heoedc93052007-10-25 14:59:16 +09001652 /* apply workaround for ASUS P5W DH Deluxe mainboard */
1653 ahci_p5wdh_workaround(host);
1654
Tejun Heof80ae7e2009-09-16 04:18:03 +09001655 /* apply gtf filter quirk */
1656 ahci_gtf_filter_workaround(host);
1657
Linus Torvalds1da177e2005-04-16 15:20:36 -07001658 /* initialize adapter */
Tejun Heo4447d352007-04-17 23:44:08 +09001659 rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001660 if (rc)
Tejun Heo24dc5f32007-01-20 16:00:28 +09001661 return rc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662
Anton Vorontsov33030402010-03-03 20:17:39 +03001663 rc = ahci_pci_reset_controller(host);
Tejun Heo4447d352007-04-17 23:44:08 +09001664 if (rc)
1665 return rc;
Tejun Heo12fad3f2006-05-15 21:03:55 +09001666
Anton Vorontsov781d6552010-03-03 20:17:42 +03001667 ahci_pci_init_controller(host);
Anton Vorontsov439fcae2010-03-03 20:17:43 +03001668 ahci_pci_print_info(host);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669
Tejun Heo4447d352007-04-17 23:44:08 +09001670 pci_set_master(pdev);
Alexander Gordeev5ca72c42012-11-19 16:02:48 +01001671
Robert Richter21bfd1a2015-05-31 13:55:18 +02001672 return ahci_host_activate(host, &ahci_sht);
Jeff Garzik907f4672005-05-12 15:03:42 -04001673}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001674
Axel Lin2fc75da2012-04-19 13:43:05 +08001675module_pci_driver(ahci_pci_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676
1677MODULE_AUTHOR("Jeff Garzik");
1678MODULE_DESCRIPTION("AHCI SATA low-level driver");
1679MODULE_LICENSE("GPL");
1680MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
Jeff Garzik68854332005-08-23 02:53:51 -04001681MODULE_VERSION(DRV_VERSION);