Blame view

drivers/ata/ahci.c 54.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
  /*
   *  ahci.c - AHCI SATA support
   *
8c3d3d4b1   Tejun Heo   libata: update "M...
4
   *  Maintained by:  Tejun Heo <tj@kernel.org>
af36d7f0d   Jeff Garzik   [libata] license ...
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
   *    		    Please ALWAYS copy linux-ide@vger.kernel.org
   *		    on emails.
   *
   *  Copyright 2004-2005 Red Hat, Inc.
   *
   *
   *  This program is free software; you can redistribute it and/or modify
   *  it under the terms of the GNU General Public License as published by
   *  the Free Software Foundation; either version 2, or (at your option)
   *  any later version.
   *
   *  This program is distributed in the hope that it will be useful,
   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   *  GNU General Public License for more details.
   *
   *  You should have received a copy of the GNU General Public License
   *  along with this program; see the file COPYING.  If not, write to
   *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
   *
   *
   * libata documentation is available via 'make {ps|pdf}docs',
   * as Documentation/DocBook/libata.*
   *
   * AHCI hardware documentation:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
30
   * http://www.intel.com/technology/serialata/pdf/rev1_0.pdf
af36d7f0d   Jeff Garzik   [libata] license ...
31
   * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
32
33
34
35
36
37
   *
   */
  
  #include <linux/kernel.h>
  #include <linux/module.h>
  #include <linux/pci.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
  #include <linux/blkdev.h>
  #include <linux/delay.h>
  #include <linux/interrupt.h>
87507cfdd   Domen Puncer   [PATCH] drivers/s...
41
  #include <linux/dma-mapping.h>
a9524a76f   Jeff Garzik   [libata] use dev_...
42
  #include <linux/device.h>
edc930528   Tejun Heo   ahci: ahci: imple...
43
  #include <linux/dmi.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
44
  #include <linux/gfp.h>
ee2aad42e   Robert Richter   ahci: Add generic...
45
  #include <linux/msi.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
  #include <scsi/scsi_host.h>
193515d51   Jeff Garzik   [libata] eliminat...
47
  #include <scsi/scsi_cmnd.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
48
  #include <linux/libata.h>
365cfa1ed   Anton Vorontsov   ahci: Move generi...
49
  #include "ahci.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
  
  #define DRV_NAME	"ahci"
7d50b60b5   Tejun Heo   ahci: implement P...
52
  #define DRV_VERSION	"3.0"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
53

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
54
  enum {
318893e14   Alessandro Rubini   ahci: support the...
55
  	AHCI_PCI_BAR_STA2X11	= 0,
b7ae128d7   Robert Richter   ahci: Add support...
56
  	AHCI_PCI_BAR_CAVIUM	= 0,
7f9c9f8e2   Hugh Daschbach   [libata] ahci: Ad...
57
  	AHCI_PCI_BAR_ENMOTUS	= 2,
318893e14   Alessandro Rubini   ahci: support the...
58
  	AHCI_PCI_BAR_STANDARD	= 5,
441577efa   Tejun Heo   ahci: clean up bo...
59
60
61
62
63
64
  };
  
  enum board_ids {
  	/* board IDs by feature in alphabetical order */
  	board_ahci,
  	board_ahci_ign_iferr,
66a7cbc30   Tejun Heo   ahci: disable MSI...
65
  	board_ahci_nomsi,
67809f85d   Levente Kurusa   ahci: disable NCQ...
66
  	board_ahci_noncq,
441577efa   Tejun Heo   ahci: clean up bo...
67
  	board_ahci_nosntf,
5f173107e   Tejun Heo   ahci: add HFLAG_Y...
68
  	board_ahci_yes_fbs,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
69

441577efa   Tejun Heo   ahci: clean up bo...
70
  	/* board IDs for specific chipsets in alphabetical order */
dbfe8ef55   Dan Williams   ahci: avoton port...
71
  	board_ahci_avn,
441577efa   Tejun Heo   ahci: clean up bo...
72
  	board_ahci_mcp65,
83f2b9630   Tejun Heo   ahci: implement A...
73
74
  	board_ahci_mcp77,
  	board_ahci_mcp89,
441577efa   Tejun Heo   ahci: clean up bo...
75
76
77
78
79
80
81
82
83
  	board_ahci_mv,
  	board_ahci_sb600,
  	board_ahci_sb700,	/* for SB700 and SB800 */
  	board_ahci_vt8251,
  
  	/* aliases */
  	board_ahci_mcp_linux	= board_ahci_mcp65,
  	board_ahci_mcp67	= board_ahci_mcp65,
  	board_ahci_mcp73	= board_ahci_mcp65,
83f2b9630   Tejun Heo   ahci: implement A...
84
  	board_ahci_mcp79	= board_ahci_mcp77,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
85
  };
2dcb407e6   Jeff Garzik   [libata] checkpat...
86
  static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
02e53293e   Mika Westerberg   ahci: Add runtime...
87
  static void ahci_remove_one(struct pci_dev *dev);
a1efdaba2   Tejun Heo   libata: make rese...
88
89
  static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
  				 unsigned long deadline);
dbfe8ef55   Dan Williams   ahci: avoton port...
90
91
  static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
  			      unsigned long deadline);
cb85696d7   James Laird   ahci: mcp89: ente...
92
93
  static void ahci_mcp89_apple_enable(struct pci_dev *pdev);
  static bool is_mcp89_apple(struct pci_dev *pdev);
a1efdaba2   Tejun Heo   libata: make rese...
94
95
  static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
  				unsigned long deadline);
02e53293e   Mika Westerberg   ahci: Add runtime...
96
97
98
  #ifdef CONFIG_PM
  static int ahci_pci_device_runtime_suspend(struct device *dev);
  static int ahci_pci_device_runtime_resume(struct device *dev);
f1d848f9f   Mika Westerberg   ahci: Convert dri...
99
100
101
  #ifdef CONFIG_PM_SLEEP
  static int ahci_pci_device_suspend(struct device *dev);
  static int ahci_pci_device_resume(struct device *dev);
438ac6d5e   Tejun Heo   libata: add missi...
102
  #endif
02e53293e   Mika Westerberg   ahci: Add runtime...
103
  #endif /* CONFIG_PM */
ad616ffbd   Tejun Heo   [PATCH] ahci: upd...
104

fad16e7a7   Tejun Heo   ahci: fix module ...
105
106
107
  static struct scsi_host_template ahci_sht = {
  	AHCI_SHT("ahci"),
  };
029cfd6b7   Tejun Heo   libata: implement...
108
109
  static struct ata_port_operations ahci_vt8251_ops = {
  	.inherits		= &ahci_ops,
a1efdaba2   Tejun Heo   libata: make rese...
110
  	.hardreset		= ahci_vt8251_hardreset,
029cfd6b7   Tejun Heo   libata: implement...
111
  };
edc930528   Tejun Heo   ahci: ahci: imple...
112

029cfd6b7   Tejun Heo   libata: implement...
113
114
  static struct ata_port_operations ahci_p5wdh_ops = {
  	.inherits		= &ahci_ops,
a1efdaba2   Tejun Heo   libata: make rese...
115
  	.hardreset		= ahci_p5wdh_hardreset,
edc930528   Tejun Heo   ahci: ahci: imple...
116
  };
dbfe8ef55   Dan Williams   ahci: avoton port...
117
118
119
120
  static struct ata_port_operations ahci_avn_ops = {
  	.inherits		= &ahci_ops,
  	.hardreset		= ahci_avn_hardreset,
  };
98ac62def   Arjan van de Ven   [PATCH] mark seve...
121
  static const struct ata_port_info ahci_port_info[] = {
441577efa   Tejun Heo   ahci: clean up bo...
122
  	/* by features */
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
123
  	[board_ahci] = {
1188c0d83   Tejun Heo   ahci: consolidate...
124
  		.flags		= AHCI_FLAG_COMMON,
14bdef982   Erik Inge Bolsø   [libata] convert ...
125
  		.pio_mask	= ATA_PIO4,
469248abf   Jeff Garzik   [libata] Clean up...
126
  		.udma_mask	= ATA_UDMA6,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
127
128
  		.port_ops	= &ahci_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
129
  	[board_ahci_ign_iferr] = {
441577efa   Tejun Heo   ahci: clean up bo...
130
  		AHCI_HFLAGS	(AHCI_HFLAG_IGN_IRQ_IF_ERR),
417a1a6d3   Tejun Heo   ahci: move host f...
131
  		.flags		= AHCI_FLAG_COMMON,
14bdef982   Erik Inge Bolsø   [libata] convert ...
132
  		.pio_mask	= ATA_PIO4,
469248abf   Jeff Garzik   [libata] Clean up...
133
  		.udma_mask	= ATA_UDMA6,
441577efa   Tejun Heo   ahci: clean up bo...
134
  		.port_ops	= &ahci_ops,
bf2af2a20   Bastiaan Jacques   [PATCH] ahci: add...
135
  	},
66a7cbc30   Tejun Heo   ahci: disable MSI...
136
137
138
139
140
141
142
  	[board_ahci_nomsi] = {
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_MSI),
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_ops,
  	},
67809f85d   Levente Kurusa   ahci: disable NCQ...
143
144
145
146
147
148
149
  	[board_ahci_noncq] = {
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ),
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
150
  	[board_ahci_nosntf] = {
441577efa   Tejun Heo   ahci: clean up bo...
151
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_SNTF),
417a1a6d3   Tejun Heo   ahci: move host f...
152
  		.flags		= AHCI_FLAG_COMMON,
14bdef982   Erik Inge Bolsø   [libata] convert ...
153
  		.pio_mask	= ATA_PIO4,
469248abf   Jeff Garzik   [libata] Clean up...
154
  		.udma_mask	= ATA_UDMA6,
416695533   Tejun Heo   [PATCH] ahci: ign...
155
156
  		.port_ops	= &ahci_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
157
  	[board_ahci_yes_fbs] = {
5f173107e   Tejun Heo   ahci: add HFLAG_Y...
158
159
160
161
162
163
  		AHCI_HFLAGS	(AHCI_HFLAG_YES_FBS),
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_ops,
  	},
441577efa   Tejun Heo   ahci: clean up bo...
164
  	/* by chipsets */
dbfe8ef55   Dan Williams   ahci: avoton port...
165
166
167
168
169
170
  	[board_ahci_avn] = {
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_avn_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
171
  	[board_ahci_mcp65] = {
83f2b9630   Tejun Heo   ahci: implement A...
172
173
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP |
  				 AHCI_HFLAG_YES_NCQ),
ae01b2493   Tejun Heo   libata: Implement...
174
  		.flags		= AHCI_FLAG_COMMON | ATA_FLAG_NO_DIPM,
83f2b9630   Tejun Heo   ahci: implement A...
175
176
177
178
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
179
  	[board_ahci_mcp77] = {
83f2b9630   Tejun Heo   ahci: implement A...
180
181
182
183
184
185
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_FPDMA_AA | AHCI_HFLAG_NO_PMP),
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
186
  	[board_ahci_mcp89] = {
83f2b9630   Tejun Heo   ahci: implement A...
187
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_FPDMA_AA),
417a1a6d3   Tejun Heo   ahci: move host f...
188
  		.flags		= AHCI_FLAG_COMMON,
14bdef982   Erik Inge Bolsø   [libata] convert ...
189
  		.pio_mask	= ATA_PIO4,
469248abf   Jeff Garzik   [libata] Clean up...
190
  		.udma_mask	= ATA_UDMA6,
441577efa   Tejun Heo   ahci: clean up bo...
191
  		.port_ops	= &ahci_ops,
55a61604c   Conke Hu   ahci.c: walkaroun...
192
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
193
  	[board_ahci_mv] = {
417a1a6d3   Tejun Heo   ahci: move host f...
194
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI |
17248461c   Tejun Heo   ahci: disable PMP...
195
  				 AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP),
9cbe056f6   Sergei Shtylyov   libata: remove AT...
196
  		.flags		= ATA_FLAG_SATA | ATA_FLAG_PIO_DMA,
14bdef982   Erik Inge Bolsø   [libata] convert ...
197
  		.pio_mask	= ATA_PIO4,
cd70c2661   Jeff Garzik   [libata] AHCI: Ad...
198
199
200
  		.udma_mask	= ATA_UDMA6,
  		.port_ops	= &ahci_ops,
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
201
  	[board_ahci_sb600] = {
441577efa   Tejun Heo   ahci: clean up bo...
202
203
204
  		AHCI_HFLAGS	(AHCI_HFLAG_IGN_SERR_INTERNAL |
  				 AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255 |
  				 AHCI_HFLAG_32BIT_ONLY),
e39fc8c9f   Shane Huang   [libata] ahci: AM...
205
  		.flags		= AHCI_FLAG_COMMON,
14bdef982   Erik Inge Bolsø   [libata] convert ...
206
  		.pio_mask	= ATA_PIO4,
e39fc8c9f   Shane Huang   [libata] ahci: AM...
207
  		.udma_mask	= ATA_UDMA6,
345347c5d   Yuan-Hsin Chen   ahci: move ahci_s...
208
  		.port_ops	= &ahci_pmp_retry_srst_ops,
e39fc8c9f   Shane Huang   [libata] ahci: AM...
209
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
210
  	[board_ahci_sb700] = {	/* for SB700 and SB800 */
441577efa   Tejun Heo   ahci: clean up bo...
211
  		AHCI_HFLAGS	(AHCI_HFLAG_IGN_SERR_INTERNAL),
aa431dd39   Tejun Heo   ahci: force CAP_N...
212
213
214
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
345347c5d   Yuan-Hsin Chen   ahci: move ahci_s...
215
  		.port_ops	= &ahci_pmp_retry_srst_ops,
aa431dd39   Tejun Heo   ahci: force CAP_N...
216
  	},
facb8fa6c   Jeffrin Jose   ahci, trivial: fi...
217
  	[board_ahci_vt8251] = {
441577efa   Tejun Heo   ahci: clean up bo...
218
  		AHCI_HFLAGS	(AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
1b677afda   Shaohua Li   ahci: disable SNo...
219
220
221
  		.flags		= AHCI_FLAG_COMMON,
  		.pio_mask	= ATA_PIO4,
  		.udma_mask	= ATA_UDMA6,
441577efa   Tejun Heo   ahci: clean up bo...
222
  		.port_ops	= &ahci_vt8251_ops,
1b677afda   Shaohua Li   ahci: disable SNo...
223
  	},
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
224
  };
3b7d697df   Jeff Garzik   [libata] constify...
225
  static const struct pci_device_id ahci_pci_tbl[] = {
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
226
  	/* Intel */
54bb3a94b   Jeff Garzik   [libata] Use new ...
227
228
229
230
231
  	{ PCI_VDEVICE(INTEL, 0x2652), board_ahci }, /* ICH6 */
  	{ PCI_VDEVICE(INTEL, 0x2653), board_ahci }, /* ICH6M */
  	{ PCI_VDEVICE(INTEL, 0x27c1), board_ahci }, /* ICH7 */
  	{ PCI_VDEVICE(INTEL, 0x27c5), board_ahci }, /* ICH7M */
  	{ PCI_VDEVICE(INTEL, 0x27c3), board_ahci }, /* ICH7R */
82490c093   Tejun Heo   ahci: make ULi M5...
232
  	{ PCI_VDEVICE(AL, 0x5288), board_ahci_ign_iferr }, /* ULi M5288 */
54bb3a94b   Jeff Garzik   [libata] Use new ...
233
234
235
236
  	{ PCI_VDEVICE(INTEL, 0x2681), board_ahci }, /* ESB2 */
  	{ PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
  	{ PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
  	{ PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
7a234aff3   Tejun Heo   ahci: reimplement...
237
  	{ PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */
1b677afda   Shaohua Li   ahci: disable SNo...
238
  	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci_nosntf }, /* ICH8 */
7a234aff3   Tejun Heo   ahci: reimplement...
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
  	{ PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */
  	{ PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */
  	{ PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */
  	{ PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */
  	{ PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */
  	{ PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */
  	{ PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */
  	{ PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */
  	{ PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */
  	{ PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */
  	{ PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */
  	{ PCI_VDEVICE(INTEL, 0x292c), board_ahci }, /* ICH9M */
  	{ PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */
  	{ PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */
  	{ PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */
d4155e6f1   Jason Gaston   ahci: RAID mode S...
254
255
  	{ PCI_VDEVICE(INTEL, 0x502a), board_ahci }, /* Tolapai */
  	{ PCI_VDEVICE(INTEL, 0x502b), board_ahci }, /* Tolapai */
16ad1ad9c   Jason Gaston   ahci: RAID mode S...
256
  	{ PCI_VDEVICE(INTEL, 0x3a05), board_ahci }, /* ICH10 */
b2dde6afe   Mark Goodwin   ahci: add device ...
257
  	{ PCI_VDEVICE(INTEL, 0x3a22), board_ahci }, /* ICH10 */
16ad1ad9c   Jason Gaston   ahci: RAID mode S...
258
  	{ PCI_VDEVICE(INTEL, 0x3a25), board_ahci }, /* ICH10 */
c1f57d9b9   David Milburn   ahci: add device ...
259
260
  	{ PCI_VDEVICE(INTEL, 0x3b22), board_ahci }, /* PCH AHCI */
  	{ PCI_VDEVICE(INTEL, 0x3b23), board_ahci }, /* PCH AHCI */
adcb5308d   Seth Heasley   ahci: RAID mode S...
261
  	{ PCI_VDEVICE(INTEL, 0x3b24), board_ahci }, /* PCH RAID */
8e48b6b30   Seth Heasley   ahci: RAID mode S...
262
  	{ PCI_VDEVICE(INTEL, 0x3b25), board_ahci }, /* PCH RAID */
c1f57d9b9   David Milburn   ahci: add device ...
263
  	{ PCI_VDEVICE(INTEL, 0x3b29), board_ahci }, /* PCH AHCI */
adcb5308d   Seth Heasley   ahci: RAID mode S...
264
  	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
8e48b6b30   Seth Heasley   ahci: RAID mode S...
265
  	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
c1f57d9b9   David Milburn   ahci: add device ...
266
  	{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
342decff2   Alexandra Yates   ahci: Intel DNV d...
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  	{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
  	{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
5623cab83   Seth Heasley   ahci: AHCI and RA...
287
288
289
290
291
292
  	{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
  	{ PCI_VDEVICE(INTEL, 0x1c05), board_ahci }, /* CPT RAID */
  	{ PCI_VDEVICE(INTEL, 0x1c06), board_ahci }, /* CPT RAID */
  	{ PCI_VDEVICE(INTEL, 0x1c07), board_ahci }, /* CPT RAID */
992b3fb9b   Seth Heasley   ahci: AHCI and RA...
293
294
295
  	{ PCI_VDEVICE(INTEL, 0x1d02), board_ahci }, /* PBG AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1d04), board_ahci }, /* PBG RAID */
  	{ PCI_VDEVICE(INTEL, 0x1d06), board_ahci }, /* PBG RAID */
64a3903d0   Seth Heasley   ahci: AHCI mode S...
296
  	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* PBG RAID */
a4a461a6d   Seth Heasley   ahci: AHCI mode S...
297
  	{ PCI_VDEVICE(INTEL, 0x2323), board_ahci }, /* DH89xxCC AHCI */
181e3ceab   Seth Heasley   ahci: AHCI-mode S...
298
299
300
301
302
303
  	{ PCI_VDEVICE(INTEL, 0x1e02), board_ahci }, /* Panther Point AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1e03), board_ahci }, /* Panther Point AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1e04), board_ahci }, /* Panther Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x1e05), board_ahci }, /* Panther Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x1e06), board_ahci }, /* Panther Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x1e07), board_ahci }, /* Panther Point RAID */
2cab7a4c5   Seth Heasley   ahci: RAID-mode S...
304
  	{ PCI_VDEVICE(INTEL, 0x1e0e), board_ahci }, /* Panther Point RAID */
ea4ace667   Seth Heasley   ahci: AHCI-mode S...
305
306
307
308
309
310
311
312
  	{ PCI_VDEVICE(INTEL, 0x8c02), board_ahci }, /* Lynx Point AHCI */
  	{ PCI_VDEVICE(INTEL, 0x8c03), board_ahci }, /* Lynx Point AHCI */
  	{ PCI_VDEVICE(INTEL, 0x8c04), board_ahci }, /* Lynx Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c05), board_ahci }, /* Lynx Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c06), board_ahci }, /* Lynx Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c07), board_ahci }, /* Lynx Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c0e), board_ahci }, /* Lynx Point RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c0f), board_ahci }, /* Lynx Point RAID */
77b12bc9c   James Ralston   ahci: Add Device ...
313
314
315
316
317
318
319
320
  	{ PCI_VDEVICE(INTEL, 0x9c02), board_ahci }, /* Lynx Point-LP AHCI */
  	{ PCI_VDEVICE(INTEL, 0x9c03), board_ahci }, /* Lynx Point-LP AHCI */
  	{ PCI_VDEVICE(INTEL, 0x9c04), board_ahci }, /* Lynx Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c05), board_ahci }, /* Lynx Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c06), board_ahci }, /* Lynx Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c07), board_ahci }, /* Lynx Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c0e), board_ahci }, /* Lynx Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c0f), board_ahci }, /* Lynx Point-LP RAID */
29e674dd5   Seth Heasley   ahci: AHCI-mode S...
321
322
323
324
325
326
327
328
  	{ PCI_VDEVICE(INTEL, 0x1f22), board_ahci }, /* Avoton AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1f23), board_ahci }, /* Avoton AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1f24), board_ahci }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f25), board_ahci }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f26), board_ahci }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f27), board_ahci }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f2e), board_ahci }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f2f), board_ahci }, /* Avoton RAID */
dbfe8ef55   Dan Williams   ahci: avoton port...
329
330
331
332
333
334
335
336
  	{ PCI_VDEVICE(INTEL, 0x1f32), board_ahci_avn }, /* Avoton AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1f33), board_ahci_avn }, /* Avoton AHCI */
  	{ PCI_VDEVICE(INTEL, 0x1f34), board_ahci_avn }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f35), board_ahci_avn }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f36), board_ahci_avn }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f37), board_ahci_avn }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f3e), board_ahci_avn }, /* Avoton RAID */
  	{ PCI_VDEVICE(INTEL, 0x1f3f), board_ahci_avn }, /* Avoton RAID */
efda332cb   James Ralston   ahci: Add Device ...
337
338
  	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Wellsburg RAID */
  	{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Wellsburg RAID */
151743fd8   James Ralston   ahci: Add Device ...
339
340
341
342
343
344
345
346
  	{ PCI_VDEVICE(INTEL, 0x8d02), board_ahci }, /* Wellsburg AHCI */
  	{ PCI_VDEVICE(INTEL, 0x8d04), board_ahci }, /* Wellsburg RAID */
  	{ PCI_VDEVICE(INTEL, 0x8d06), board_ahci }, /* Wellsburg RAID */
  	{ PCI_VDEVICE(INTEL, 0x8d0e), board_ahci }, /* Wellsburg RAID */
  	{ PCI_VDEVICE(INTEL, 0x8d62), board_ahci }, /* Wellsburg AHCI */
  	{ PCI_VDEVICE(INTEL, 0x8d64), board_ahci }, /* Wellsburg RAID */
  	{ PCI_VDEVICE(INTEL, 0x8d66), board_ahci }, /* Wellsburg RAID */
  	{ PCI_VDEVICE(INTEL, 0x8d6e), board_ahci }, /* Wellsburg RAID */
1cfc7df3d   Seth Heasley   ahci: AHCI-mode S...
347
  	{ PCI_VDEVICE(INTEL, 0x23a3), board_ahci }, /* Coleto Creek AHCI */
9f961a5f6   James Ralston   ahci: Add Device ...
348
349
350
351
  	{ PCI_VDEVICE(INTEL, 0x9c83), board_ahci }, /* Wildcat Point-LP AHCI */
  	{ PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
1b071a094   James Ralston   ahci: Add Device ...
352
353
354
355
356
357
358
359
  	{ PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
  	{ PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
  	{ PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
  	{ PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
249cd0a18   Devin Ryles   AHCI: Add DeviceI...
360
361
362
  	{ PCI_VDEVICE(INTEL, 0x9d03), board_ahci }, /* Sunrise Point-LP AHCI */
  	{ PCI_VDEVICE(INTEL, 0x9d05), board_ahci }, /* Sunrise Point-LP RAID */
  	{ PCI_VDEVICE(INTEL, 0x9d07), board_ahci }, /* Sunrise Point-LP RAID */
c5967b79e   Charles_Rose@Dell.com   ahci: Add Device ...
363
  	{ PCI_VDEVICE(INTEL, 0xa102), board_ahci }, /* Sunrise Point-H AHCI */
690000b93   James Ralston   ahci: Add Device ...
364
  	{ PCI_VDEVICE(INTEL, 0xa103), board_ahci }, /* Sunrise Point-H AHCI */
690000b93   James Ralston   ahci: Add Device ...
365
  	{ PCI_VDEVICE(INTEL, 0xa105), board_ahci }, /* Sunrise Point-H RAID */
c5967b79e   Charles_Rose@Dell.com   ahci: Add Device ...
366
  	{ PCI_VDEVICE(INTEL, 0xa106), board_ahci }, /* Sunrise Point-H RAID */
690000b93   James Ralston   ahci: Add Device ...
367
368
  	{ PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
  	{ PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
4d92f0099   Alexandra Yates   ahci: Order SATA ...
369
  	{ PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
f5bdd66c7   Alexandra Yates   Adding Intel Lewi...
370
  	{ PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
4d92f0099   Alexandra Yates   ahci: Order SATA ...
371
  	{ PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
f5bdd66c7   Alexandra Yates   Adding Intel Lewi...
372
  	{ PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/
4d92f0099   Alexandra Yates   ahci: Order SATA ...
373
  	{ PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
4d92f0099   Alexandra Yates   ahci: Order SATA ...
374
  	{ PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
f5bdd66c7   Alexandra Yates   Adding Intel Lewi...
375
376
  	{ PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/
  	{ PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/
4d92f0099   Alexandra Yates   ahci: Order SATA ...
377
  	{ PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
4d92f0099   Alexandra Yates   ahci: Order SATA ...
378
  	{ PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
f5bdd66c7   Alexandra Yates   Adding Intel Lewi...
379
380
  	{ PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
  	{ PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
381

e34bb370d   Tejun Heo   ahci/pata_jmicron...
382
383
384
  	/* JMicron 360/1/3/5/6, match class to avoid IDE function */
  	{ PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
  	  PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci_ign_iferr },
1fefb8fdc   Ben Hutchings   ahci: Add JMicron...
385
386
387
  	/* JMicron 362B and 362C have an AHCI function with IDE class code */
  	{ PCI_VDEVICE(JMICRON, 0x2362), board_ahci_ign_iferr },
  	{ PCI_VDEVICE(JMICRON, 0x236f), board_ahci_ign_iferr },
91f15fb30   Zhang Rui   PCI: Disable asyn...
388
  	/* May need to update quirk_jmicron_async_suspend() for additions */
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
389
390
  
  	/* ATI */
c65ec1c25   Conke Hu   ahci.c: remove no...
391
  	{ PCI_VDEVICE(ATI, 0x4380), board_ahci_sb600 }, /* ATI SB600 */
e39fc8c9f   Shane Huang   [libata] ahci: AM...
392
393
394
395
396
397
  	{ PCI_VDEVICE(ATI, 0x4390), board_ahci_sb700 }, /* ATI SB700/800 */
  	{ PCI_VDEVICE(ATI, 0x4391), board_ahci_sb700 }, /* ATI SB700/800 */
  	{ PCI_VDEVICE(ATI, 0x4392), board_ahci_sb700 }, /* ATI SB700/800 */
  	{ PCI_VDEVICE(ATI, 0x4393), board_ahci_sb700 }, /* ATI SB700/800 */
  	{ PCI_VDEVICE(ATI, 0x4394), board_ahci_sb700 }, /* ATI SB700/800 */
  	{ PCI_VDEVICE(ATI, 0x4395), board_ahci_sb700 }, /* ATI SB700/800 */
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
398

e2dd90b1a   Shane Huang   ahci: Add AMD SB9...
399
  	/* AMD */
5deab5366   Shane Huang   ahci / atiixp / p...
400
  	{ PCI_VDEVICE(AMD, 0x7800), board_ahci }, /* AMD Hudson-2 */
fafe5c3d8   Shane Huang   ahci: Add AMD CZ ...
401
  	{ PCI_VDEVICE(AMD, 0x7900), board_ahci }, /* AMD CZ */
e2dd90b1a   Shane Huang   ahci: Add AMD SB9...
402
403
404
  	/* AMD is using RAID class only for ahci controllers */
  	{ PCI_VENDOR_ID_AMD, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
  	  PCI_CLASS_STORAGE_RAID << 8, 0xffffff, board_ahci },
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
405
  	/* VIA */
54bb3a94b   Jeff Garzik   [libata] Use new ...
406
  	{ PCI_VDEVICE(VIA, 0x3349), board_ahci_vt8251 }, /* VIA VT8251 */
bf3355429   Tejun Heo   ahci: add PCI ID ...
407
  	{ PCI_VDEVICE(VIA, 0x6287), board_ahci_vt8251 }, /* VIA VT8251 */
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
408
409
  
  	/* NVIDIA */
e297d99e1   Tejun Heo   ahci: workarounds...
410
411
412
413
414
415
416
417
  	{ PCI_VDEVICE(NVIDIA, 0x044c), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x044d), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x044e), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x044f), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x045c), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x045d), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x045e), board_ahci_mcp65 },	/* MCP65 */
  	{ PCI_VDEVICE(NVIDIA, 0x045f), board_ahci_mcp65 },	/* MCP65 */
441577efa   Tejun Heo   ahci: clean up bo...
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
  	{ PCI_VDEVICE(NVIDIA, 0x0550), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0551), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0552), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0553), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0554), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0555), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0556), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0557), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0558), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0559), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x055a), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x055b), board_ahci_mcp67 },	/* MCP67 */
  	{ PCI_VDEVICE(NVIDIA, 0x0580), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0581), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0582), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0583), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0584), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0585), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0586), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0587), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0588), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x0589), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x058a), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x058b), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x058c), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x058d), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x058e), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x058f), board_ahci_mcp_linux },	/* Linux ID */
  	{ PCI_VDEVICE(NVIDIA, 0x07f0), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f1), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f2), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f3), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f4), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f5), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f6), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f7), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f8), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07f9), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07fa), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x07fb), board_ahci_mcp73 },	/* MCP73 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad0), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad1), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad2), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad3), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad4), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad5), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad6), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad7), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad8), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ad9), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ada), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0adb), board_ahci_mcp77 },	/* MCP77 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ab4), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ab5), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ab6), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ab7), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ab8), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0ab9), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0aba), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0abb), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0abc), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0abd), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0abe), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0abf), board_ahci_mcp79 },	/* MCP79 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d84), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d85), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d86), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d87), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d88), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d89), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d8a), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d8b), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d8c), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d8d), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d8e), board_ahci_mcp89 },	/* MCP89 */
  	{ PCI_VDEVICE(NVIDIA, 0x0d8f), board_ahci_mcp89 },	/* MCP89 */
fe7fa31aa   Jeff Garzik   [libata] ahci: Ad...
494

95916edd0   Jeff Garzik   [libata] ahci: ad...
495
  	/* SiS */
20e2de4a5   Tejun Heo   ahci: sis control...
496
497
498
  	{ PCI_VDEVICE(SI, 0x1184), board_ahci },		/* SiS 966 */
  	{ PCI_VDEVICE(SI, 0x1185), board_ahci },		/* SiS 968 */
  	{ PCI_VDEVICE(SI, 0x0186), board_ahci },		/* SiS 968 */
95916edd0   Jeff Garzik   [libata] ahci: ad...
499

318893e14   Alessandro Rubini   ahci: support the...
500
501
  	/* ST Microelectronics */
  	{ PCI_VDEVICE(STMICRO, 0xCC06), board_ahci },		/* ST ConneXt */
cd70c2661   Jeff Garzik   [libata] AHCI: Ad...
502
503
  	/* Marvell */
  	{ PCI_VDEVICE(MARVELL, 0x6145), board_ahci_mv },	/* 6145 */
c40e7cb89   Jose Alberto Reguero   ahci: Add Marvell...
504
  	{ PCI_VDEVICE(MARVELL, 0x6121), board_ahci_mv },	/* 6121 */
69fd31573   Myron Stowe   ahci: Use PCI_VEN...
505
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9123),
10aca06c8   Anssi Hannula   ahci: add HFLAG_Y...
506
507
  	  .class = PCI_CLASS_STORAGE_SATA_AHCI,
  	  .class_mask = 0xffffff,
5f173107e   Tejun Heo   ahci: add HFLAG_Y...
508
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9128 */
69fd31573   Myron Stowe   ahci: Use PCI_VEN...
509
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9125),
467b41c68   Per Jessen   ahci: recognize M...
510
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9125 */
e098f5cbe   Simon Guinot   ahci: add PCI ID ...
511
512
513
  	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_MARVELL_EXT, 0x9178,
  			 PCI_VENDOR_ID_MARVELL_EXT, 0x9170),
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9170 */
69fd31573   Myron Stowe   ahci: Use PCI_VEN...
514
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
642d89252   Matt Johnson   ahci: Detect Marv...
515
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */
fcce9a35f   George Spelvin   ahci: add an obse...
516
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
c5edfff9d   Murali Karicheri   ahci: add pcid fo...
517
518
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9182 */
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9182),
fcce9a35f   George Spelvin   ahci: add an obse...
519
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 */
69fd31573   Myron Stowe   ahci: Use PCI_VEN...
520
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
17c60c6b7   Alan Cox   ahci: Add alterna...
521
  	  .driver_data = board_ahci_yes_fbs },			/* 88se9172 on some Gigabyte */
754a292fe   Andreas Schrägle   ahci: add PCI ID ...
522
523
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a0),
  	  .driver_data = board_ahci_yes_fbs },
a40cf3f38   Johannes Thumshirn   ahci: Add Marvell...
524
525
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a2), 	/* 88se91a2 */
  	  .driver_data = board_ahci_yes_fbs },
69fd31573   Myron Stowe   ahci: Use PCI_VEN...
526
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x91a3),
50be5e365   Tejun Heo   ahci: add another...
527
  	  .driver_data = board_ahci_yes_fbs },
6d5278a68   Samir Benmendil   ahci: add Marvell...
528
529
  	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9230),
  	  .driver_data = board_ahci_yes_fbs },
d25183650   Jérôme Carretero   ahci: Add Device ...
530
531
  	{ PCI_DEVICE(PCI_VENDOR_ID_TTI, 0x0642),
  	  .driver_data = board_ahci_yes_fbs },
cd70c2661   Jeff Garzik   [libata] AHCI: Ad...
532

c77a036be   Mark Nelson   ahci: Add support...
533
534
  	/* Promise */
  	{ PCI_VDEVICE(PROMISE, 0x3f20), board_ahci },	/* PDC42819 */
b32bfc06a   Romain Degez   ahci: add support...
535
  	{ PCI_VDEVICE(PROMISE, 0x3781), board_ahci },   /* FastTrak TX8660 ahci-mode */
c77a036be   Mark Nelson   ahci: Add support...
536

c9703765f   Keng-Yu Lin   [libata] ahci: Ad...
537
  	/* Asmedia */
7b4f6ecac   Alan Cox   ahci: Add identif...
538
539
540
541
  	{ PCI_VDEVICE(ASMEDIA, 0x0601), board_ahci },	/* ASM1060 */
  	{ PCI_VDEVICE(ASMEDIA, 0x0602), board_ahci },	/* ASM1060 */
  	{ PCI_VDEVICE(ASMEDIA, 0x0611), board_ahci },	/* ASM1061 */
  	{ PCI_VDEVICE(ASMEDIA, 0x0612), board_ahci },	/* ASM1062 */
c9703765f   Keng-Yu Lin   [libata] ahci: Ad...
542

67809f85d   Levente Kurusa   ahci: disable NCQ...
543
  	/*
66a7cbc30   Tejun Heo   ahci: disable MSI...
544
545
  	 * Samsung SSDs found on some macbooks.  NCQ times out if MSI is
  	 * enabled.  https://bugzilla.kernel.org/show_bug.cgi?id=60731
67809f85d   Levente Kurusa   ahci: disable NCQ...
546
  	 */
66a7cbc30   Tejun Heo   ahci: disable MSI...
547
  	{ PCI_VDEVICE(SAMSUNG, 0x1600), board_ahci_nomsi },
2b21ef0aa   Tejun Heo   ahci: disable MSI...
548
  	{ PCI_VDEVICE(SAMSUNG, 0xa800), board_ahci_nomsi },
67809f85d   Levente Kurusa   ahci: disable NCQ...
549

7f9c9f8e2   Hugh Daschbach   [libata] ahci: Ad...
550
551
  	/* Enmotus */
  	{ PCI_DEVICE(0x1c44, 0x8000), board_ahci },
415ae2b5c   Jeff Garzik   [libata] ahci: Ma...
552
553
  	/* Generic, PCI class code for AHCI */
  	{ PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
c9f89475a   Conke Hu   Add pci class cod...
554
  	  PCI_CLASS_STORAGE_SATA_AHCI, 0xffffff, board_ahci },
415ae2b5c   Jeff Garzik   [libata] ahci: Ma...
555

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
556
557
  	{ }	/* terminate list */
  };
f1d848f9f   Mika Westerberg   ahci: Convert dri...
558
559
  static const struct dev_pm_ops ahci_pci_pm_ops = {
  	SET_SYSTEM_SLEEP_PM_OPS(ahci_pci_device_suspend, ahci_pci_device_resume)
02e53293e   Mika Westerberg   ahci: Add runtime...
560
561
  	SET_RUNTIME_PM_OPS(ahci_pci_device_runtime_suspend,
  			   ahci_pci_device_runtime_resume, NULL)
f1d848f9f   Mika Westerberg   ahci: Convert dri...
562
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
564
565
566
567
  
  static struct pci_driver ahci_pci_driver = {
  	.name			= DRV_NAME,
  	.id_table		= ahci_pci_tbl,
  	.probe			= ahci_init_one,
02e53293e   Mika Westerberg   ahci: Add runtime...
568
  	.remove			= ahci_remove_one,
f1d848f9f   Mika Westerberg   ahci: Convert dri...
569
570
571
  	.driver = {
  		.pm		= &ahci_pci_pm_ops,
  	},
365cfa1ed   Anton Vorontsov   ahci: Move generi...
572
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573

5219d6530   Javier Martinez Canillas   ata: Use IS_ENABL...
574
  #if IS_ENABLED(CONFIG_PATA_MARVELL)
365cfa1ed   Anton Vorontsov   ahci: Move generi...
575
576
577
578
579
580
  static int marvell_enable;
  #else
  static int marvell_enable = 1;
  #endif
  module_param(marvell_enable, int, 0644);
  MODULE_PARM_DESC(marvell_enable, "Marvell SATA via AHCI (1 = enabled)");
d28f87aa8   Tejun Heo   ahci: give anothe...
581

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582

365cfa1ed   Anton Vorontsov   ahci: Move generi...
583
584
585
  static void ahci_pci_save_initial_config(struct pci_dev *pdev,
  					 struct ahci_host_priv *hpriv)
  {
365cfa1ed   Anton Vorontsov   ahci: Move generi...
586
587
588
  	if (pdev->vendor == PCI_VENDOR_ID_JMICRON && pdev->device == 0x2361) {
  		dev_info(&pdev->dev, "JMB361 has only one port
  ");
9a23c1d6f   Antoine Tenart   ahci: fix AHCI pa...
589
  		hpriv->force_port_map = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  	}
365cfa1ed   Anton Vorontsov   ahci: Move generi...
591
592
593
594
  	/*
  	 * Temporary Marvell 6145 hack: PATA port presence
  	 * is asserted through the standard AHCI port
  	 * presence register, as bit 4 (counting from 0)
d28f87aa8   Tejun Heo   ahci: give anothe...
595
  	 */
365cfa1ed   Anton Vorontsov   ahci: Move generi...
596
597
  	if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
  		if (pdev->device == 0x6121)
9a23c1d6f   Antoine Tenart   ahci: fix AHCI pa...
598
  			hpriv->mask_port_map = 0x3;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
599
  		else
9a23c1d6f   Antoine Tenart   ahci: fix AHCI pa...
600
  			hpriv->mask_port_map = 0xf;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
601
602
603
604
  		dev_info(&pdev->dev,
  			  "Disabling your PATA port. Use the boot option 'ahci.marvell_enable=0' to avoid this.
  ");
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
605

725c7b570   Antoine Ténart   ata: libahci_plat...
606
  	ahci_save_initial_config(&pdev->dev, hpriv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607
  }
365cfa1ed   Anton Vorontsov   ahci: Move generi...
608
  static int ahci_pci_reset_controller(struct ata_host *host)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
609
  {
365cfa1ed   Anton Vorontsov   ahci: Move generi...
610
  	struct pci_dev *pdev = to_pci_dev(host->dev);
7d50b60b5   Tejun Heo   ahci: implement P...
611

365cfa1ed   Anton Vorontsov   ahci: Move generi...
612
  	ahci_reset_controller(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
613

365cfa1ed   Anton Vorontsov   ahci: Move generi...
614
615
616
  	if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
  		struct ahci_host_priv *hpriv = host->private_data;
  		u16 tmp16;
d6ef31539   Shane Huang   ahci: Implement S...
617

365cfa1ed   Anton Vorontsov   ahci: Move generi...
618
619
620
621
622
623
  		/* configure PCS */
  		pci_read_config_word(pdev, 0x92, &tmp16);
  		if ((tmp16 & hpriv->port_map) != hpriv->port_map) {
  			tmp16 |= hpriv->port_map;
  			pci_write_config_word(pdev, 0x92, tmp16);
  		}
d6ef31539   Shane Huang   ahci: Implement S...
624
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625
626
  	return 0;
  }
365cfa1ed   Anton Vorontsov   ahci: Move generi...
627
  static void ahci_pci_init_controller(struct ata_host *host)
78cd52d02   Tejun Heo   [PATCH] ahci: con...
628
  {
365cfa1ed   Anton Vorontsov   ahci: Move generi...
629
630
631
  	struct ahci_host_priv *hpriv = host->private_data;
  	struct pci_dev *pdev = to_pci_dev(host->dev);
  	void __iomem *port_mmio;
78cd52d02   Tejun Heo   [PATCH] ahci: con...
632
  	u32 tmp;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
633
  	int mv;
78cd52d02   Tejun Heo   [PATCH] ahci: con...
634

365cfa1ed   Anton Vorontsov   ahci: Move generi...
635
636
637
638
639
640
  	if (hpriv->flags & AHCI_HFLAG_MV_PATA) {
  		if (pdev->device == 0x6121)
  			mv = 2;
  		else
  			mv = 4;
  		port_mmio = __ahci_port_base(host, mv);
78cd52d02   Tejun Heo   [PATCH] ahci: con...
641

365cfa1ed   Anton Vorontsov   ahci: Move generi...
642
  		writel(0, port_mmio + PORT_IRQ_MASK);
78cd52d02   Tejun Heo   [PATCH] ahci: con...
643

365cfa1ed   Anton Vorontsov   ahci: Move generi...
644
645
646
647
648
649
  		/* clear port IRQ */
  		tmp = readl(port_mmio + PORT_IRQ_STAT);
  		VPRINTK("PORT_IRQ_STAT 0x%x
  ", tmp);
  		if (tmp)
  			writel(tmp, port_mmio + PORT_IRQ_STAT);
78cd52d02   Tejun Heo   [PATCH] ahci: con...
650
  	}
365cfa1ed   Anton Vorontsov   ahci: Move generi...
651
  	ahci_init_controller(host);
edc930528   Tejun Heo   ahci: ahci: imple...
652
  }
365cfa1ed   Anton Vorontsov   ahci: Move generi...
653
654
  static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
  				 unsigned long deadline)
d6ef31539   Shane Huang   ahci: Implement S...
655
  {
365cfa1ed   Anton Vorontsov   ahci: Move generi...
656
  	struct ata_port *ap = link->ap;
039ece38d   Hans de Goede   libahci: Allow dr...
657
  	struct ahci_host_priv *hpriv = ap->host->private_data;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
658
  	bool online;
d6ef31539   Shane Huang   ahci: Implement S...
659
  	int rc;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
660
661
  	DPRINTK("ENTER
  ");
d6ef31539   Shane Huang   ahci: Implement S...
662

365cfa1ed   Anton Vorontsov   ahci: Move generi...
663
  	ahci_stop_engine(ap);
d6ef31539   Shane Huang   ahci: Implement S...
664

365cfa1ed   Anton Vorontsov   ahci: Move generi...
665
666
  	rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  				 deadline, &online, NULL);
d6ef31539   Shane Huang   ahci: Implement S...
667

039ece38d   Hans de Goede   libahci: Allow dr...
668
  	hpriv->start_engine(ap);
d6ef31539   Shane Huang   ahci: Implement S...
669

365cfa1ed   Anton Vorontsov   ahci: Move generi...
670
671
  	DPRINTK("EXIT, rc=%d, class=%u
  ", rc, *class);
d6ef31539   Shane Huang   ahci: Implement S...
672

365cfa1ed   Anton Vorontsov   ahci: Move generi...
673
674
675
676
  	/* vt8251 doesn't clear BSY on signature FIS reception,
  	 * request follow-up softreset.
  	 */
  	return online ? -EAGAIN : rc;
7d50b60b5   Tejun Heo   ahci: implement P...
677
  }
365cfa1ed   Anton Vorontsov   ahci: Move generi...
678
679
  static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
  				unsigned long deadline)
7d50b60b5   Tejun Heo   ahci: implement P...
680
  {
365cfa1ed   Anton Vorontsov   ahci: Move generi...
681
  	struct ata_port *ap = link->ap;
1c954a4d9   Tejun Heo   ahci: clean up PO...
682
  	struct ahci_port_priv *pp = ap->private_data;
039ece38d   Hans de Goede   libahci: Allow dr...
683
  	struct ahci_host_priv *hpriv = ap->host->private_data;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
684
685
686
687
  	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  	struct ata_taskfile tf;
  	bool online;
  	int rc;
7d50b60b5   Tejun Heo   ahci: implement P...
688

365cfa1ed   Anton Vorontsov   ahci: Move generi...
689
  	ahci_stop_engine(ap);
028a25963   Alexey Dobriyan   ahci.c: fix CONFI...
690

365cfa1ed   Anton Vorontsov   ahci: Move generi...
691
692
  	/* clear D2H reception area to properly wait for D2H FIS */
  	ata_tf_init(link->device, &tf);
9bbb1b0e2   Sergei Shtylyov   AHCI: use ATA_BUSY
693
  	tf.command = ATA_BUSY;
365cfa1ed   Anton Vorontsov   ahci: Move generi...
694
  	ata_tf_to_fis(&tf, 0, 0, d2h_fis);
7d50b60b5   Tejun Heo   ahci: implement P...
695

365cfa1ed   Anton Vorontsov   ahci: Move generi...
696
697
  	rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
  				 deadline, &online, NULL);
028a25963   Alexey Dobriyan   ahci.c: fix CONFI...
698

039ece38d   Hans de Goede   libahci: Allow dr...
699
  	hpriv->start_engine(ap);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
700

365cfa1ed   Anton Vorontsov   ahci: Move generi...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
  	/* The pseudo configuration device on SIMG4726 attached to
  	 * ASUS P5W-DH Deluxe doesn't send signature FIS after
  	 * hardreset if no device is attached to the first downstream
  	 * port && the pseudo device locks up on SRST w/ PMP==0.  To
  	 * work around this, wait for !BSY only briefly.  If BSY isn't
  	 * cleared, perform CLO and proceed to IDENTIFY (achieved by
  	 * ATA_LFLAG_NO_SRST and ATA_LFLAG_ASSUME_ATA).
  	 *
  	 * Wait for two seconds.  Devices attached to downstream port
  	 * which can't process the following IDENTIFY after this will
  	 * have to be reset again.  For most cases, this should
  	 * suffice while making probing snappish enough.
  	 */
  	if (online) {
  		rc = ata_wait_after_reset(link, jiffies + 2 * HZ,
  					  ahci_check_ready);
  		if (rc)
  			ahci_kick_engine(ap);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
719
  	}
c1332875c   Tejun Heo   [PATCH] ahci: imp...
720
721
  	return rc;
  }
dbfe8ef55   Dan Williams   ahci: avoton port...
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
  /*
   * ahci_avn_hardreset - attempt more aggressive recovery of Avoton ports.
   *
   * It has been observed with some SSDs that the timing of events in the
   * link synchronization phase can leave the port in a state that can not
   * be recovered by a SATA-hard-reset alone.  The failing signature is
   * SStatus.DET stuck at 1 ("Device presence detected but Phy
   * communication not established").  It was found that unloading and
   * reloading the driver when this problem occurs allows the drive
   * connection to be recovered (DET advanced to 0x3).  The critical
   * component of reloading the driver is that the port state machines are
   * reset by bouncing "port enable" in the AHCI PCS configuration
   * register.  So, reproduce that effect by bouncing a port whenever we
   * see DET==1 after a reset.
   */
  static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
  			      unsigned long deadline)
  {
  	const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
  	struct ata_port *ap = link->ap;
  	struct ahci_port_priv *pp = ap->private_data;
  	struct ahci_host_priv *hpriv = ap->host->private_data;
  	u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
  	unsigned long tmo = deadline - jiffies;
  	struct ata_taskfile tf;
  	bool online;
  	int rc, i;
  
  	DPRINTK("ENTER
  ");
  
  	ahci_stop_engine(ap);
  
  	for (i = 0; i < 2; i++) {
  		u16 val;
  		u32 sstatus;
  		int port = ap->port_no;
  		struct ata_host *host = ap->host;
  		struct pci_dev *pdev = to_pci_dev(host->dev);
  
  		/* clear D2H reception area to properly wait for D2H FIS */
  		ata_tf_init(link->device, &tf);
  		tf.command = ATA_BUSY;
  		ata_tf_to_fis(&tf, 0, 0, d2h_fis);
  
  		rc = sata_link_hardreset(link, timing, deadline, &online,
  				ahci_check_ready);
  
  		if (sata_scr_read(link, SCR_STATUS, &sstatus) != 0 ||
  				(sstatus & 0xf) != 1)
  			break;
  
  		ata_link_printk(link, KERN_INFO, "avn bounce port%d
  ",
  				port);
  
  		pci_read_config_word(pdev, 0x92, &val);
  		val &= ~(1 << port);
  		pci_write_config_word(pdev, 0x92, val);
  		ata_msleep(ap, 1000);
  		val |= 1 << port;
  		pci_write_config_word(pdev, 0x92, val);
  		deadline += tmo;
  	}
  
  	hpriv->start_engine(ap);
  
  	if (online)
  		*class = ahci_dev_classify(ap);
  
  	DPRINTK("EXIT, rc=%d, class=%u
  ", rc, *class);
  	return rc;
  }
02e53293e   Mika Westerberg   ahci: Add runtime...
796
797
  #ifdef CONFIG_PM
  static void ahci_pci_disable_interrupts(struct ata_host *host)
c1332875c   Tejun Heo   [PATCH] ahci: imp...
798
  {
9b10ae86d   Tejun Heo   ahci: add warning...
799
  	struct ahci_host_priv *hpriv = host->private_data;
d89933497   Anton Vorontsov   ahci: Get rid of ...
800
  	void __iomem *mmio = hpriv->mmio;
c1332875c   Tejun Heo   [PATCH] ahci: imp...
801
  	u32 ctl;
f1d848f9f   Mika Westerberg   ahci: Convert dri...
802
803
804
805
806
807
808
809
  	/* AHCI spec rev1.1 section 8.3.3:
  	 * Software must disable interrupts prior to requesting a
  	 * transition of the HBA to D3 state.
  	 */
  	ctl = readl(mmio + HOST_CTL);
  	ctl &= ~HOST_IRQ_EN;
  	writel(ctl, mmio + HOST_CTL);
  	readl(mmio + HOST_CTL); /* flush */
02e53293e   Mika Westerberg   ahci: Add runtime...
810
811
812
813
814
815
  }
  
  static int ahci_pci_device_runtime_suspend(struct device *dev)
  {
  	struct pci_dev *pdev = to_pci_dev(dev);
  	struct ata_host *host = pci_get_drvdata(pdev);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
816

02e53293e   Mika Westerberg   ahci: Add runtime...
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
  	ahci_pci_disable_interrupts(host);
  	return 0;
  }
  
  static int ahci_pci_device_runtime_resume(struct device *dev)
  {
  	struct pci_dev *pdev = to_pci_dev(dev);
  	struct ata_host *host = pci_get_drvdata(pdev);
  	int rc;
  
  	rc = ahci_pci_reset_controller(host);
  	if (rc)
  		return rc;
  	ahci_pci_init_controller(host);
  	return 0;
  }
  
  #ifdef CONFIG_PM_SLEEP
  static int ahci_pci_device_suspend(struct device *dev)
  {
  	struct pci_dev *pdev = to_pci_dev(dev);
  	struct ata_host *host = pci_get_drvdata(pdev);
  	struct ahci_host_priv *hpriv = host->private_data;
  
  	if (hpriv->flags & AHCI_HFLAG_NO_SUSPEND) {
  		dev_err(&pdev->dev,
  			"BIOS update required for suspend/resume
  ");
  		return -EIO;
  	}
  
  	ahci_pci_disable_interrupts(host);
f1d848f9f   Mika Westerberg   ahci: Convert dri...
849
  	return ata_host_suspend(host, PMSG_SUSPEND);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
850
  }
f1d848f9f   Mika Westerberg   ahci: Convert dri...
851
  static int ahci_pci_device_resume(struct device *dev)
c1332875c   Tejun Heo   [PATCH] ahci: imp...
852
  {
f1d848f9f   Mika Westerberg   ahci: Convert dri...
853
  	struct pci_dev *pdev = to_pci_dev(dev);
0a86e1c85   Jingoo Han   ata: use pci_get_...
854
  	struct ata_host *host = pci_get_drvdata(pdev);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
855
  	int rc;
cb85696d7   James Laird   ahci: mcp89: ente...
856
857
858
  	/* Apple BIOS helpfully mangles the registers on resume */
  	if (is_mcp89_apple(pdev))
  		ahci_mcp89_apple_enable(pdev);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
859
  	if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
3303040d8   Anton Vorontsov   ahci: Factor out ...
860
  		rc = ahci_pci_reset_controller(host);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
861
862
  		if (rc)
  			return rc;
781d65508   Anton Vorontsov   ahci: Factor out ...
863
  		ahci_pci_init_controller(host);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
864
  	}
cca3974e4   Jeff Garzik   libata: Grand ren...
865
  	ata_host_resume(host);
c1332875c   Tejun Heo   [PATCH] ahci: imp...
866
867
868
  
  	return 0;
  }
438ac6d5e   Tejun Heo   libata: add missi...
869
  #endif
c1332875c   Tejun Heo   [PATCH] ahci: imp...
870

02e53293e   Mika Westerberg   ahci: Add runtime...
871
  #endif /* CONFIG_PM */
4447d3515   Tejun Heo   libata: convert t...
872
  static int ahci_configure_dma_masks(struct pci_dev *pdev, int using_dac)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
875

318893e14   Alessandro Rubini   ahci: support the...
876
877
878
879
880
881
  	/*
  	 * If the device fixup already set the dma_mask to some non-standard
  	 * value, don't extend it here. This happens on STA2X11, for example.
  	 */
  	if (pdev->dma_mask && pdev->dma_mask < DMA_BIT_MASK(32))
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
882
  	if (using_dac &&
c54c719b5   Quentin Lambert   ata: remove depre...
883
884
  	    !dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
  		rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(64));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
  		if (rc) {
c54c719b5   Quentin Lambert   ata: remove depre...
886
  			rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
887
  			if (rc) {
a44fec1fc   Joe Perches   ata: Convert dev_...
888
889
890
  				dev_err(&pdev->dev,
  					"64-bit DMA enable failed
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
892
893
  				return rc;
  			}
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894
  	} else {
c54c719b5   Quentin Lambert   ata: remove depre...
895
  		rc = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
  		if (rc) {
a44fec1fc   Joe Perches   ata: Convert dev_...
897
898
  			dev_err(&pdev->dev, "32-bit DMA enable failed
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
899
900
  			return rc;
  		}
c54c719b5   Quentin Lambert   ata: remove depre...
901
  		rc = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
902
  		if (rc) {
a44fec1fc   Joe Perches   ata: Convert dev_...
903
904
905
  			dev_err(&pdev->dev,
  				"32-bit consistent DMA enable failed
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
906
907
908
  			return rc;
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
  	return 0;
  }
439fcaec1   Anton Vorontsov   ahci: Factor out ...
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
  static void ahci_pci_print_info(struct ata_host *host)
  {
  	struct pci_dev *pdev = to_pci_dev(host->dev);
  	u16 cc;
  	const char *scc_s;
  
  	pci_read_config_word(pdev, 0x0a, &cc);
  	if (cc == PCI_CLASS_STORAGE_IDE)
  		scc_s = "IDE";
  	else if (cc == PCI_CLASS_STORAGE_SATA)
  		scc_s = "SATA";
  	else if (cc == PCI_CLASS_STORAGE_RAID)
  		scc_s = "RAID";
  	else
  		scc_s = "unknown";
  
  	ahci_print_info(host, scc_s);
  }
edc930528   Tejun Heo   ahci: ahci: imple...
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
  /* On ASUS P5W DH Deluxe, the second port of PCI device 00:1f.2 is
   * hardwired to on-board SIMG 4726.  The chipset is ICH8 and doesn't
   * support PMP and the 4726 either directly exports the device
   * attached to the first downstream port or acts as a hardware storage
   * controller and emulate a single ATA device (can be RAID 0/1 or some
   * other configuration).
   *
   * When there's no device attached to the first downstream port of the
   * 4726, "Config Disk" appears, which is a pseudo ATA device to
   * configure the 4726.  However, ATA emulation of the device is very
   * lame.  It doesn't send signature D2H Reg FIS after the initial
   * hardreset, pukes on SRST w/ PMP==0 and has bunch of other issues.
   *
   * The following function works around the problem by always using
   * hardreset on the port and not depending on receiving signature FIS
   * afterward.  If signature FIS isn't received soon, ATA class is
   * assumed without follow-up softreset.
   */
  static void ahci_p5wdh_workaround(struct ata_host *host)
  {
1bd06867f   Mathias Krause   ahci: ahci_p5wdh_...
949
  	static const struct dmi_system_id sysids[] = {
edc930528   Tejun Heo   ahci: ahci: imple...
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
  		{
  			.ident = "P5W DH Deluxe",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR,
  					  "ASUSTEK COMPUTER INC"),
  				DMI_MATCH(DMI_PRODUCT_NAME, "P5W DH Deluxe"),
  			},
  		},
  		{ }
  	};
  	struct pci_dev *pdev = to_pci_dev(host->dev);
  
  	if (pdev->bus->number == 0 && pdev->devfn == PCI_DEVFN(0x1f, 2) &&
  	    dmi_check_system(sysids)) {
  		struct ata_port *ap = host->ports[1];
a44fec1fc   Joe Perches   ata: Convert dev_...
965
966
967
  		dev_info(&pdev->dev,
  			 "enabling ASUS P5W DH Deluxe on-board SIMG4726 workaround
  ");
edc930528   Tejun Heo   ahci: ahci: imple...
968
969
970
971
972
  
  		ap->ops = &ahci_p5wdh_ops;
  		ap->link.flags |= ATA_LFLAG_NO_SRST | ATA_LFLAG_ASSUME_ATA;
  	}
  }
cb85696d7   James Laird   ahci: mcp89: ente...
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
  /*
   * Macbook7,1 firmware forcibly disables MCP89 AHCI and changes PCI ID when
   * booting in BIOS compatibility mode.  We restore the registers but not ID.
   */
  static void ahci_mcp89_apple_enable(struct pci_dev *pdev)
  {
  	u32 val;
  
  	printk(KERN_INFO "ahci: enabling MCP89 AHCI mode
  ");
  
  	pci_read_config_dword(pdev, 0xf8, &val);
  	val |= 1 << 0x1b;
  	/* the following changes the device ID, but appears not to affect function */
  	/* val = (val & ~0xf0000000) | 0x80000000; */
  	pci_write_config_dword(pdev, 0xf8, val);
  
  	pci_read_config_dword(pdev, 0x54c, &val);
  	val |= 1 << 0xc;
  	pci_write_config_dword(pdev, 0x54c, val);
  
  	pci_read_config_dword(pdev, 0x4a4, &val);
  	val &= 0xff;
  	val |= 0x01060100;
  	pci_write_config_dword(pdev, 0x4a4, val);
  
  	pci_read_config_dword(pdev, 0x54c, &val);
  	val &= ~(1 << 0xc);
  	pci_write_config_dword(pdev, 0x54c, val);
  
  	pci_read_config_dword(pdev, 0xf8, &val);
  	val &= ~(1 << 0x1b);
  	pci_write_config_dword(pdev, 0xf8, val);
  }
  
  static bool is_mcp89_apple(struct pci_dev *pdev)
  {
  	return pdev->vendor == PCI_VENDOR_ID_NVIDIA &&
  		pdev->device == PCI_DEVICE_ID_NVIDIA_NFORCE_MCP89_SATA &&
  		pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE &&
  		pdev->subsystem_device == 0xcb89;
  }
2fcad9d27   Tejun Heo   ahci: disable 64b...
1015
1016
  /* only some SB600 ahci controllers can do 64bit DMA */
  static bool ahci_sb600_enable_64bit(struct pci_dev *pdev)
58a09b38c   Shane Huang   [libata] ahci: Re...
1017
1018
  {
  	static const struct dmi_system_id sysids[] = {
03d783bf5   Tejun Heo   ahci: make ahci_a...
1019
1020
1021
  		/*
  		 * The oldest version known to be broken is 0901 and
  		 * working is 1501 which was released on 2007-10-26.
2fcad9d27   Tejun Heo   ahci: disable 64b...
1022
1023
  		 * Enable 64bit DMA on 1501 and anything newer.
  		 *
03d783bf5   Tejun Heo   ahci: make ahci_a...
1024
1025
  		 * Please read bko#9412 for more info.
  		 */
58a09b38c   Shane Huang   [libata] ahci: Re...
1026
1027
1028
1029
1030
1031
1032
  		{
  			.ident = "ASUS M2A-VM",
  			.matches = {
  				DMI_MATCH(DMI_BOARD_VENDOR,
  					  "ASUSTeK Computer INC."),
  				DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"),
  			},
03d783bf5   Tejun Heo   ahci: make ahci_a...
1033
  			.driver_data = "20071026",	/* yyyymmdd */
58a09b38c   Shane Huang   [libata] ahci: Re...
1034
  		},
e65cc194f   Mark Nelson   ahci: Enable SB60...
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
  		/*
  		 * All BIOS versions for the MSI K9A2 Platinum (MS-7376)
  		 * support 64bit DMA.
  		 *
  		 * BIOS versions earlier than 1.5 had the Manufacturer DMI
  		 * fields as "MICRO-STAR INTERANTIONAL CO.,LTD".
  		 * This spelling mistake was fixed in BIOS version 1.5, so
  		 * 1.5 and later have the Manufacturer as
  		 * "MICRO-STAR INTERNATIONAL CO.,LTD".
  		 * So try to match on DMI_BOARD_VENDOR of "MICRO-STAR INTER".
  		 *
  		 * BIOS versions earlier than 1.9 had a Board Product Name
  		 * DMI field of "MS-7376". This was changed to be
  		 * "K9A2 Platinum (MS-7376)" in version 1.9, but we can still
  		 * match on DMI_BOARD_NAME of "MS-7376".
  		 */
  		{
  			.ident = "MSI K9A2 Platinum",
  			.matches = {
  				DMI_MATCH(DMI_BOARD_VENDOR,
  					  "MICRO-STAR INTER"),
  				DMI_MATCH(DMI_BOARD_NAME, "MS-7376"),
  			},
  		},
3c4aa91f2   Mark Nelson   ahci: Enable SB60...
1059
  		/*
ff0173c1a   Mark Nelson   ahci: Enable SB60...
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
  		 * All BIOS versions for the MSI K9AGM2 (MS-7327) support
  		 * 64bit DMA.
  		 *
  		 * This board also had the typo mentioned above in the
  		 * Manufacturer DMI field (fixed in BIOS version 1.5), so
  		 * match on DMI_BOARD_VENDOR of "MICRO-STAR INTER" again.
  		 */
  		{
  			.ident = "MSI K9AGM2",
  			.matches = {
  				DMI_MATCH(DMI_BOARD_VENDOR,
  					  "MICRO-STAR INTER"),
  				DMI_MATCH(DMI_BOARD_NAME, "MS-7327"),
  			},
  		},
  		/*
3c4aa91f2   Mark Nelson   ahci: Enable SB60...
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
  		 * All BIOS versions for the Asus M3A support 64bit DMA.
  		 * (all release versions from 0301 to 1206 were tested)
  		 */
  		{
  			.ident = "ASUS M3A",
  			.matches = {
  				DMI_MATCH(DMI_BOARD_VENDOR,
  					  "ASUSTeK Computer INC."),
  				DMI_MATCH(DMI_BOARD_NAME, "M3A"),
  			},
  		},
58a09b38c   Shane Huang   [libata] ahci: Re...
1087
1088
  		{ }
  	};
03d783bf5   Tejun Heo   ahci: make ahci_a...
1089
  	const struct dmi_system_id *match;
2fcad9d27   Tejun Heo   ahci: disable 64b...
1090
1091
  	int year, month, date;
  	char buf[9];
58a09b38c   Shane Huang   [libata] ahci: Re...
1092

03d783bf5   Tejun Heo   ahci: make ahci_a...
1093
  	match = dmi_first_match(sysids);
58a09b38c   Shane Huang   [libata] ahci: Re...
1094
  	if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) ||
03d783bf5   Tejun Heo   ahci: make ahci_a...
1095
  	    !match)
58a09b38c   Shane Huang   [libata] ahci: Re...
1096
  		return false;
e65cc194f   Mark Nelson   ahci: Enable SB60...
1097
1098
  	if (!match->driver_data)
  		goto enable_64bit;
2fcad9d27   Tejun Heo   ahci: disable 64b...
1099
1100
  	dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
  	snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
03d783bf5   Tejun Heo   ahci: make ahci_a...
1101

e65cc194f   Mark Nelson   ahci: Enable SB60...
1102
1103
1104
  	if (strcmp(buf, match->driver_data) >= 0)
  		goto enable_64bit;
  	else {
a44fec1fc   Joe Perches   ata: Convert dev_...
1105
1106
1107
1108
  		dev_warn(&pdev->dev,
  			 "%s: BIOS too old, forcing 32bit DMA, update BIOS
  ",
  			 match->ident);
2fcad9d27   Tejun Heo   ahci: disable 64b...
1109
1110
  		return false;
  	}
e65cc194f   Mark Nelson   ahci: Enable SB60...
1111
1112
  
  enable_64bit:
a44fec1fc   Joe Perches   ata: Convert dev_...
1113
1114
  	dev_warn(&pdev->dev, "%s: enabling 64bit DMA
  ", match->ident);
e65cc194f   Mark Nelson   ahci: Enable SB60...
1115
  	return true;
58a09b38c   Shane Huang   [libata] ahci: Re...
1116
  }
1fd684346   Rafael J. Wysocki   SATA AHCI: Blackl...
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
  static bool ahci_broken_system_poweroff(struct pci_dev *pdev)
  {
  	static const struct dmi_system_id broken_systems[] = {
  		{
  			.ident = "HP Compaq nx6310",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  				DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6310"),
  			},
  			/* PCI slot number of the controller */
  			.driver_data = (void *)0x1FUL,
  		},
d2f9c0614   Maciej Rutecki   ahci: Blacklist H...
1129
1130
1131
1132
1133
1134
1135
1136
1137
  		{
  			.ident = "HP Compaq 6720s",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  				DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq 6720s"),
  			},
  			/* PCI slot number of the controller */
  			.driver_data = (void *)0x1FUL,
  		},
1fd684346   Rafael J. Wysocki   SATA AHCI: Blackl...
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
  
  		{ }	/* terminate list */
  	};
  	const struct dmi_system_id *dmi = dmi_first_match(broken_systems);
  
  	if (dmi) {
  		unsigned long slot = (unsigned long)dmi->driver_data;
  		/* apply the quirk only to on-board controllers */
  		return slot == PCI_SLOT(pdev->devfn);
  	}
  
  	return false;
  }
9b10ae86d   Tejun Heo   ahci: add warning...
1151
1152
1153
1154
1155
1156
1157
  static bool ahci_broken_suspend(struct pci_dev *pdev)
  {
  	static const struct dmi_system_id sysids[] = {
  		/*
  		 * On HP dv[4-6] and HDX18 with earlier BIOSen, link
  		 * to the harddisk doesn't become online after
  		 * resuming from STR.  Warn and fail suspend.
9deb34318   Tejun Heo   ahci: use BIOS da...
1158
1159
1160
1161
1162
1163
1164
1165
  		 *
  		 * http://bugzilla.kernel.org/show_bug.cgi?id=12276
  		 *
  		 * Use dates instead of versions to match as HP is
  		 * apparently recycling both product and version
  		 * strings.
  		 *
  		 * http://bugzilla.kernel.org/show_bug.cgi?id=15462
9b10ae86d   Tejun Heo   ahci: add warning...
1166
1167
1168
1169
1170
1171
1172
1173
  		 */
  		{
  			.ident = "dv4",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  				DMI_MATCH(DMI_PRODUCT_NAME,
  					  "HP Pavilion dv4 Notebook PC"),
  			},
9deb34318   Tejun Heo   ahci: use BIOS da...
1174
  			.driver_data = "20090105",	/* F.30 */
9b10ae86d   Tejun Heo   ahci: add warning...
1175
1176
1177
1178
1179
1180
1181
1182
  		},
  		{
  			.ident = "dv5",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  				DMI_MATCH(DMI_PRODUCT_NAME,
  					  "HP Pavilion dv5 Notebook PC"),
  			},
9deb34318   Tejun Heo   ahci: use BIOS da...
1183
  			.driver_data = "20090506",	/* F.16 */
9b10ae86d   Tejun Heo   ahci: add warning...
1184
1185
1186
1187
1188
1189
1190
1191
  		},
  		{
  			.ident = "dv6",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  				DMI_MATCH(DMI_PRODUCT_NAME,
  					  "HP Pavilion dv6 Notebook PC"),
  			},
9deb34318   Tejun Heo   ahci: use BIOS da...
1192
  			.driver_data = "20090423",	/* F.21 */
9b10ae86d   Tejun Heo   ahci: add warning...
1193
1194
1195
1196
1197
1198
1199
1200
  		},
  		{
  			.ident = "HDX18",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
  				DMI_MATCH(DMI_PRODUCT_NAME,
  					  "HP HDX18 Notebook PC"),
  			},
9deb34318   Tejun Heo   ahci: use BIOS da...
1201
  			.driver_data = "20090430",	/* F.23 */
9b10ae86d   Tejun Heo   ahci: add warning...
1202
  		},
cedc9bf90   Tejun Heo   ahci: add Acer G7...
1203
1204
1205
  		/*
  		 * Acer eMachines G725 has the same problem.  BIOS
  		 * V1.03 is known to be broken.  V3.04 is known to
25985edce   Lucas De Marchi   Fix common misspe...
1206
  		 * work.  Between, there are V1.06, V2.06 and V3.03
cedc9bf90   Tejun Heo   ahci: add Acer G7...
1207
1208
  		 * that we don't have much idea about.  For now,
  		 * blacklist anything older than V3.04.
9deb34318   Tejun Heo   ahci: use BIOS da...
1209
1210
  		 *
  		 * http://bugzilla.kernel.org/show_bug.cgi?id=15104
cedc9bf90   Tejun Heo   ahci: add Acer G7...
1211
1212
1213
1214
1215
1216
1217
  		 */
  		{
  			.ident = "G725",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "eMachines"),
  				DMI_MATCH(DMI_PRODUCT_NAME, "eMachines G725"),
  			},
9deb34318   Tejun Heo   ahci: use BIOS da...
1218
  			.driver_data = "20091216",	/* V3.04 */
cedc9bf90   Tejun Heo   ahci: add Acer G7...
1219
  		},
9b10ae86d   Tejun Heo   ahci: add warning...
1220
1221
1222
  		{ }	/* terminate list */
  	};
  	const struct dmi_system_id *dmi = dmi_first_match(sysids);
9deb34318   Tejun Heo   ahci: use BIOS da...
1223
1224
  	int year, month, date;
  	char buf[9];
9b10ae86d   Tejun Heo   ahci: add warning...
1225
1226
1227
  
  	if (!dmi || pdev->bus->number || pdev->devfn != PCI_DEVFN(0x1f, 2))
  		return false;
9deb34318   Tejun Heo   ahci: use BIOS da...
1228
1229
  	dmi_get_date(DMI_BIOS_DATE, &year, &month, &date);
  	snprintf(buf, sizeof(buf), "%04d%02d%02d", year, month, date);
9b10ae86d   Tejun Heo   ahci: add warning...
1230

9deb34318   Tejun Heo   ahci: use BIOS da...
1231
  	return strcmp(buf, dmi->driver_data) < 0;
9b10ae86d   Tejun Heo   ahci: add warning...
1232
  }
5594639aa   Tejun Heo   ahci: add workaro...
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
  static bool ahci_broken_online(struct pci_dev *pdev)
  {
  #define ENCODE_BUSDEVFN(bus, slot, func)			\
  	(void *)(unsigned long)(((bus) << 8) | PCI_DEVFN((slot), (func)))
  	static const struct dmi_system_id sysids[] = {
  		/*
  		 * There are several gigabyte boards which use
  		 * SIMG5723s configured as hardware RAID.  Certain
  		 * 5723 firmware revisions shipped there keep the link
  		 * online but fail to answer properly to SRST or
  		 * IDENTIFY when no device is attached downstream
  		 * causing libata to retry quite a few times leading
  		 * to excessive detection delay.
  		 *
  		 * As these firmwares respond to the second reset try
  		 * with invalid device signature, considering unknown
  		 * sig as offline works around the problem acceptably.
  		 */
  		{
  			.ident = "EP45-DQ6",
  			.matches = {
  				DMI_MATCH(DMI_BOARD_VENDOR,
  					  "Gigabyte Technology Co., Ltd."),
  				DMI_MATCH(DMI_BOARD_NAME, "EP45-DQ6"),
  			},
  			.driver_data = ENCODE_BUSDEVFN(0x0a, 0x00, 0),
  		},
  		{
  			.ident = "EP45-DS5",
  			.matches = {
  				DMI_MATCH(DMI_BOARD_VENDOR,
  					  "Gigabyte Technology Co., Ltd."),
  				DMI_MATCH(DMI_BOARD_NAME, "EP45-DS5"),
  			},
  			.driver_data = ENCODE_BUSDEVFN(0x03, 0x00, 0),
  		},
  		{ }	/* terminate list */
  	};
  #undef ENCODE_BUSDEVFN
  	const struct dmi_system_id *dmi = dmi_first_match(sysids);
  	unsigned int val;
  
  	if (!dmi)
  		return false;
  
  	val = (unsigned long)dmi->driver_data;
  
  	return pdev->bus->number == (val >> 8) && pdev->devfn == (val & 0xff);
  }
0cf4a7d6c   Jacob Pan   ahci: disable DEV...
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
  static bool ahci_broken_devslp(struct pci_dev *pdev)
  {
  	/* device with broken DEVSLP but still showing SDS capability */
  	static const struct pci_device_id ids[] = {
  		{ PCI_VDEVICE(INTEL, 0x0f23)}, /* Valleyview SoC */
  		{}
  	};
  
  	return pci_match_id(ids, pdev);
  }
8e5132175   Markus Trippelsdorf   ahci: Add ifdef w...
1292
  #ifdef CONFIG_ATA_ACPI
f80ae7e45   Tejun Heo   ahci: filter FPDM...
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
  static void ahci_gtf_filter_workaround(struct ata_host *host)
  {
  	static const struct dmi_system_id sysids[] = {
  		/*
  		 * Aspire 3810T issues a bunch of SATA enable commands
  		 * via _GTF including an invalid one and one which is
  		 * rejected by the device.  Among the successful ones
  		 * is FPDMA non-zero offset enable which when enabled
  		 * only on the drive side leads to NCQ command
  		 * failures.  Filter it out.
  		 */
  		{
  			.ident = "Aspire 3810T",
  			.matches = {
  				DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
  				DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3810T"),
  			},
  			.driver_data = (void *)ATA_ACPI_FILTER_FPDMA_OFFSET,
  		},
  		{ }
  	};
  	const struct dmi_system_id *dmi = dmi_first_match(sysids);
  	unsigned int filter;
  	int i;
  
  	if (!dmi)
  		return;
  
  	filter = (unsigned long)dmi->driver_data;
a44fec1fc   Joe Perches   ata: Convert dev_...
1322
1323
1324
  	dev_info(host->dev, "applying extra ACPI _GTF filter 0x%x for %s
  ",
  		 filter, dmi->ident);
f80ae7e45   Tejun Heo   ahci: filter FPDM...
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
  
  	for (i = 0; i < host->n_ports; i++) {
  		struct ata_port *ap = host->ports[i];
  		struct ata_link *link;
  		struct ata_device *dev;
  
  		ata_for_each_link(link, ap, EDGE)
  			ata_for_each_dev(dev, link, ALL)
  				dev->gtf_filter |= filter;
  	}
  }
8e5132175   Markus Trippelsdorf   ahci: Add ifdef w...
1336
1337
1338
1339
  #else
  static inline void ahci_gtf_filter_workaround(struct ata_host *host)
  {}
  #endif
f80ae7e45   Tejun Heo   ahci: filter FPDM...
1340

d243bed32   Tirumalesh Chalamarla   ahci: Workaround ...
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
  #ifdef CONFIG_ARM64
  /*
   * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently.
   * Workaround is to make sure all pending IRQs are served before leaving
   * handler.
   */
  static irqreturn_t ahci_thunderx_irq_handler(int irq, void *dev_instance)
  {
  	struct ata_host *host = dev_instance;
  	struct ahci_host_priv *hpriv;
  	unsigned int rc = 0;
  	void __iomem *mmio;
  	u32 irq_stat, irq_masked;
  	unsigned int handled = 1;
  
  	VPRINTK("ENTER
  ");
  	hpriv = host->private_data;
  	mmio = hpriv->mmio;
  	irq_stat = readl(mmio + HOST_IRQ_STAT);
  	if (!irq_stat)
  		return IRQ_NONE;
  
  	do {
  		irq_masked = irq_stat & hpriv->port_map;
  		spin_lock(&host->lock);
  		rc = ahci_handle_port_intr(host, irq_masked);
  		if (!rc)
  			handled = 0;
  		writel(irq_stat, mmio + HOST_IRQ_STAT);
  		irq_stat = readl(mmio + HOST_IRQ_STAT);
  		spin_unlock(&host->lock);
  	} while (irq_stat);
  	VPRINTK("EXIT
  ");
  
  	return IRQ_RETVAL(handled);
  }
  #endif
0b9e2988a   Christoph Hellwig   ahci: use pci_all...
1380
  static int ahci_get_irq_vector(struct ata_host *host, int port)
5ca72c4f7   Alexander Gordeev   AHCI: Support mul...
1381
  {
0b9e2988a   Christoph Hellwig   ahci: use pci_all...
1382
  	return pci_irq_vector(to_pci_dev(host->dev), port);
ee2aad42e   Robert Richter   ahci: Add generic...
1383
  }
a1c823117   Robert Richter   ahci: Move interr...
1384
1385
  static int ahci_init_msi(struct pci_dev *pdev, unsigned int n_ports,
  			struct ahci_host_priv *hpriv)
5ca72c4f7   Alexander Gordeev   AHCI: Support mul...
1386
  {
0b9e2988a   Christoph Hellwig   ahci: use pci_all...
1387
  	int nvec;
5ca72c4f7   Alexander Gordeev   AHCI: Support mul...
1388

7b92b4f61   Alexander Gordeev   PCI/MSI: Remove p...
1389
  	if (hpriv->flags & AHCI_HFLAG_NO_MSI)
a1c823117   Robert Richter   ahci: Move interr...
1390
  		return -ENODEV;
7b92b4f61   Alexander Gordeev   PCI/MSI: Remove p...
1391

7b92b4f61   Alexander Gordeev   PCI/MSI: Remove p...
1392
1393
1394
1395
1396
  	/*
  	 * If number of MSIs is less than number of ports then Sharing Last
  	 * Message mode could be enforced. In this case assume that advantage
  	 * of multipe MSIs is negated and use single MSI mode instead.
  	 */
17a51f12c   Christoph Hellwig   ahci: only try to...
1397
1398
1399
1400
1401
1402
1403
1404
1405
  	if (n_ports > 1) {
  		nvec = pci_alloc_irq_vectors(pdev, n_ports, INT_MAX,
  				PCI_IRQ_MSIX | PCI_IRQ_MSI);
  		if (nvec > 0) {
  			if (!(readl(hpriv->mmio + HOST_CTL) & HOST_MRSM)) {
  				hpriv->get_irq_vector = ahci_get_irq_vector;
  				hpriv->flags |= AHCI_HFLAG_MULTI_MSI;
  				return nvec;
  			}
5ca72c4f7   Alexander Gordeev   AHCI: Support mul...
1406

17a51f12c   Christoph Hellwig   ahci: only try to...
1407
1408
1409
1410
1411
1412
1413
1414
1415
  			/*
  			 * Fallback to single MSI mode if the controller
  			 * enforced MRSM mode.
  			 */
  			printk(KERN_INFO
  				"ahci: MRSM is on, fallback to single MSI
  ");
  			pci_free_irq_vectors(pdev);
  		}
a478b0974   Christoph Hellwig   ahci: fix nvec check
1416
  	}
d684a90d3   Dan Williams   ahci: per-port ms...
1417

0b9e2988a   Christoph Hellwig   ahci: use pci_all...
1418
1419
1420
1421
1422
1423
  	/*
  	 * If the host is not capable of supporting per-port vectors, fall
  	 * back to single MSI before finally attempting single MSI-X.
  	 */
  	nvec = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSI);
  	if (nvec == 1)
ee2aad42e   Robert Richter   ahci: Add generic...
1424
  		return nvec;
0b9e2988a   Christoph Hellwig   ahci: use pci_all...
1425
  	return pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_MSIX);
5ca72c4f7   Alexander Gordeev   AHCI: Support mul...
1426
  }
24dc5f33e   Tejun Heo   libata: update li...
1427
  static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1428
  {
e297d99e1   Tejun Heo   ahci: workarounds...
1429
1430
  	unsigned int board_id = ent->driver_data;
  	struct ata_port_info pi = ahci_port_info[board_id];
4447d3515   Tejun Heo   libata: convert t...
1431
  	const struct ata_port_info *ppi[] = { &pi, NULL };
24dc5f33e   Tejun Heo   libata: update li...
1432
  	struct device *dev = &pdev->dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1433
  	struct ahci_host_priv *hpriv;
4447d3515   Tejun Heo   libata: convert t...
1434
  	struct ata_host *host;
c3ebd6a9b   Alexander Gordeev   AHCI: Cleanup che...
1435
  	int n_ports, i, rc;
318893e14   Alessandro Rubini   ahci: support the...
1436
  	int ahci_pci_bar = AHCI_PCI_BAR_STANDARD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1437
1438
1439
  
  	VPRINTK("ENTER
  ");
b429dd599   Justin P. Mattock   [libata] ahci: Fi...
1440
  	WARN_ON((int)ATA_MAX_QUEUE > AHCI_MAX_CMDS);
12fad3f96   Tejun Heo   [PATCH] ahci: imp...
1441

06296a1e6   Joe Perches   ata: Add and use ...
1442
  	ata_print_version_once(&pdev->dev, DRV_VERSION);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1443

5b66c829b   Alan Cox   ahci, pata_marvel...
1444
1445
1446
1447
1448
  	/* The AHCI driver can only drive the SATA ports, the PATA driver
  	   can drive them all so if both drivers are selected make sure
  	   AHCI stays out of the way */
  	if (pdev->vendor == PCI_VENDOR_ID_MARVELL && !marvell_enable)
  		return -ENODEV;
cb85696d7   James Laird   ahci: mcp89: ente...
1449
1450
1451
  	/* Apple BIOS on MCP89 prevents us using AHCI */
  	if (is_mcp89_apple(pdev))
  		ahci_mcp89_apple_enable(pdev);
c6353b452   Tejun Heo   ahci,ata_generic:...
1452

7a02267e0   Mark Nelson   ahci: let users k...
1453
1454
1455
1456
1457
  	/* Promise's PDC42819 is a SAS/SATA controller that has an AHCI mode.
  	 * At the moment, we can only use the AHCI mode. Let the users know
  	 * that for SAS drives they're out of luck.
  	 */
  	if (pdev->vendor == PCI_VENDOR_ID_PROMISE)
a44fec1fc   Joe Perches   ata: Convert dev_...
1458
1459
1460
  		dev_info(&pdev->dev,
  			 "PDC42819 can only drive SATA devices with this driver
  ");
7a02267e0   Mark Nelson   ahci: let users k...
1461

b7ae128d7   Robert Richter   ahci: Add support...
1462
  	/* Some devices use non-standard BARs */
318893e14   Alessandro Rubini   ahci: support the...
1463
1464
  	if (pdev->vendor == PCI_VENDOR_ID_STMICRO && pdev->device == 0xCC06)
  		ahci_pci_bar = AHCI_PCI_BAR_STA2X11;
7f9c9f8e2   Hugh Daschbach   [libata] ahci: Ad...
1465
1466
  	else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000)
  		ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS;
b7ae128d7   Robert Richter   ahci: Add support...
1467
1468
  	else if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
  		ahci_pci_bar = AHCI_PCI_BAR_CAVIUM;
318893e14   Alessandro Rubini   ahci: support the...
1469

4447d3515   Tejun Heo   libata: convert t...
1470
  	/* acquire resources */
24dc5f33e   Tejun Heo   libata: update li...
1471
  	rc = pcim_enable_device(pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1472
1473
  	if (rc)
  		return rc;
c4f7792c0   Tejun Heo   ahci: don't attac...
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
  	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
  	    (pdev->device == 0x2652 || pdev->device == 0x2653)) {
  		u8 map;
  
  		/* ICH6s share the same PCI ID for both piix and ahci
  		 * modes.  Enabling ahci mode while MAP indicates
  		 * combined mode is a bad idea.  Yield to ata_piix.
  		 */
  		pci_read_config_byte(pdev, ICH_MAP, &map);
  		if (map & 0x3) {
a44fec1fc   Joe Perches   ata: Convert dev_...
1484
1485
1486
  			dev_info(&pdev->dev,
  				 "controller is in combined mode, can't enable AHCI mode
  ");
c4f7792c0   Tejun Heo   ahci: don't attac...
1487
1488
1489
  			return -ENODEV;
  		}
  	}
6fec88712   Paul Bolle   ahci: bail out on...
1490
1491
1492
1493
1494
1495
1496
1497
  	/* AHCI controllers often implement SFF compatible interface.
  	 * Grab all PCI BARs just in case.
  	 */
  	rc = pcim_iomap_regions_request_all(pdev, 1 << ahci_pci_bar, DRV_NAME);
  	if (rc == -EBUSY)
  		pcim_pin_device(pdev);
  	if (rc)
  		return rc;
24dc5f33e   Tejun Heo   libata: update li...
1498
1499
1500
  	hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
  	if (!hpriv)
  		return -ENOMEM;
417a1a6d3   Tejun Heo   ahci: move host f...
1501
  	hpriv->flags |= (unsigned long)pi.private_data;
e297d99e1   Tejun Heo   ahci: workarounds...
1502
1503
1504
1505
  	/* MCP65 revision A1 and A2 can't do MSI */
  	if (board_id == board_ahci_mcp65 &&
  	    (pdev->revision == 0xa1 || pdev->revision == 0xa2))
  		hpriv->flags |= AHCI_HFLAG_NO_MSI;
e427fe042   Shane Huang   [libata] ahci: Wi...
1506
1507
1508
  	/* SB800 does NOT need the workaround to ignore SERR_INTERNAL */
  	if (board_id == board_ahci_sb700 && pdev->revision >= 0x40)
  		hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL;
2fcad9d27   Tejun Heo   ahci: disable 64b...
1509
1510
1511
  	/* only some SB600s can do 64bit DMA */
  	if (ahci_sb600_enable_64bit(pdev))
  		hpriv->flags &= ~AHCI_HFLAG_32BIT_ONLY;
58a09b38c   Shane Huang   [libata] ahci: Re...
1512

318893e14   Alessandro Rubini   ahci: support the...
1513
  	hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar];
d89933497   Anton Vorontsov   ahci: Get rid of ...
1514

0cf4a7d6c   Jacob Pan   ahci: disable DEV...
1515
1516
1517
  	/* must set flag prior to save config in order to take effect */
  	if (ahci_broken_devslp(pdev))
  		hpriv->flags |= AHCI_HFLAG_NO_DEVSLP;
d243bed32   Tirumalesh Chalamarla   ahci: Workaround ...
1518
1519
1520
1521
  #ifdef CONFIG_ARM64
  	if (pdev->vendor == 0x177d && pdev->device == 0xa01c)
  		hpriv->irq_handler = ahci_thunderx_irq_handler;
  #endif
4447d3515   Tejun Heo   libata: convert t...
1522
  	/* save initial config */
394d6e535   Anton Vorontsov   ahci: Factor out ...
1523
  	ahci_pci_save_initial_config(pdev, hpriv);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1524

4447d3515   Tejun Heo   libata: convert t...
1525
  	/* prepare host */
453d3131e   Robert Hancock   ahci: disable FPD...
1526
1527
  	if (hpriv->cap & HOST_CAP_NCQ) {
  		pi.flags |= ATA_FLAG_NCQ;
83f2b9630   Tejun Heo   ahci: implement A...
1528
1529
1530
1531
1532
1533
1534
  		/*
  		 * Auto-activate optimization is supposed to be
  		 * supported on all AHCI controllers indicating NCQ
  		 * capability, but it seems to be broken on some
  		 * chipsets including NVIDIAs.
  		 */
  		if (!(hpriv->flags & AHCI_HFLAG_NO_FPDMA_AA))
453d3131e   Robert Hancock   ahci: disable FPD...
1535
  			pi.flags |= ATA_FLAG_FPDMA_AA;
40fb59e75   Marc Carino   libata: Add H2D F...
1536
1537
1538
1539
1540
1541
1542
1543
  
  		/*
  		 * All AHCI controllers should be forward-compatible
  		 * with the new auxiliary field. This code should be
  		 * conditionalized if any buggy AHCI controllers are
  		 * encountered.
  		 */
  		pi.flags |= ATA_FLAG_FPDMA_AUX;
453d3131e   Robert Hancock   ahci: disable FPD...
1544
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1545

7d50b60b5   Tejun Heo   ahci: implement P...
1546
1547
  	if (hpriv->cap & HOST_CAP_PMP)
  		pi.flags |= ATA_FLAG_PMP;
0cbb0e774   Anton Vorontsov   ahci: Introduce a...
1548
  	ahci_set_em_messages(hpriv, &pi);
18f7ba4c2   Kristen Carlson Accardi   libata/ahci: encl...
1549

1fd684346   Rafael J. Wysocki   SATA AHCI: Blackl...
1550
1551
1552
1553
1554
1555
  	if (ahci_broken_system_poweroff(pdev)) {
  		pi.flags |= ATA_FLAG_NO_POWEROFF_SPINDOWN;
  		dev_info(&pdev->dev,
  			"quirky BIOS, skipping spindown on poweroff
  ");
  	}
9b10ae86d   Tejun Heo   ahci: add warning...
1556
1557
  	if (ahci_broken_suspend(pdev)) {
  		hpriv->flags |= AHCI_HFLAG_NO_SUSPEND;
a44fec1fc   Joe Perches   ata: Convert dev_...
1558
1559
1560
  		dev_warn(&pdev->dev,
  			 "BIOS update required for suspend/resume
  ");
9b10ae86d   Tejun Heo   ahci: add warning...
1561
  	}
5594639aa   Tejun Heo   ahci: add workaro...
1562
1563
1564
1565
1566
1567
  	if (ahci_broken_online(pdev)) {
  		hpriv->flags |= AHCI_HFLAG_SRST_TOUT_IS_OFFLINE;
  		dev_info(&pdev->dev,
  			 "online status unreliable, applying workaround
  ");
  	}
837f5f8fb   Tejun Heo   ahci: fix CAP.NP ...
1568
1569
1570
1571
1572
1573
1574
1575
  	/* CAP.NP sometimes indicate the index of the last enabled
  	 * port, at other times, that of the last possible port, so
  	 * determining the maximum port number requires looking at
  	 * both CAP.NP and port_map.
  	 */
  	n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map));
  
  	host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports);
4447d3515   Tejun Heo   libata: convert t...
1576
1577
  	if (!host)
  		return -ENOMEM;
4447d3515   Tejun Heo   libata: convert t...
1578
  	host->private_data = hpriv;
0b9e2988a   Christoph Hellwig   ahci: use pci_all...
1579
1580
1581
1582
1583
  
  	if (ahci_init_msi(pdev, n_ports, hpriv) < 0) {
  		/* legacy intx interrupts */
  		pci_intx(pdev, 1);
  	}
0ce57f8af   Christoph Hellwig   ahci: fix the sin...
1584
  	hpriv->irq = pci_irq_vector(pdev, 0);
21bfd1aa9   Robert Richter   ahci: Store irq n...
1585

f3d7f23f8   Arjan van de Ven   ahci: add a modul...
1586
  	if (!(hpriv->cap & HOST_CAP_SSS) || ahci_ignore_sss)
886ad09fc   Arjan van de Ven   libata: Add a per...
1587
  		host->flags |= ATA_HOST_PARALLEL_SCAN;
f3d7f23f8   Arjan van de Ven   ahci: add a modul...
1588
  	else
d2782d96f   Jingoo Han   ahci: use dev_inf...
1589
1590
  		dev_info(&pdev->dev, "SSS flag set, parallel bus scan disabled
  ");
886ad09fc   Arjan van de Ven   libata: Add a per...
1591

18f7ba4c2   Kristen Carlson Accardi   libata/ahci: encl...
1592
1593
  	if (pi.flags & ATA_FLAG_EM)
  		ahci_reset_em(host);
4447d3515   Tejun Heo   libata: convert t...
1594
  	for (i = 0; i < host->n_ports; i++) {
dab632e8c   Jeff Garzik   [libata] ahci: mi...
1595
  		struct ata_port *ap = host->ports[i];
4447d3515   Tejun Heo   libata: convert t...
1596

318893e14   Alessandro Rubini   ahci: support the...
1597
1598
  		ata_port_pbar_desc(ap, ahci_pci_bar, -1, "abar");
  		ata_port_pbar_desc(ap, ahci_pci_bar,
cbcdd8759   Tejun Heo   libata: implement...
1599
  				   0x100 + ap->port_no * 0x80, "port");
18f7ba4c2   Kristen Carlson Accardi   libata/ahci: encl...
1600
1601
  		/* set enclosure management message type */
  		if (ap->flags & ATA_FLAG_EM)
008dbd61e   Harry Zhang   ahci: EM message ...
1602
  			ap->em_message_type = hpriv->em_msg_type;
18f7ba4c2   Kristen Carlson Accardi   libata/ahci: encl...
1603

dab632e8c   Jeff Garzik   [libata] ahci: mi...
1604
  		/* disabled/not-implemented port */
350756f6d   Tejun Heo   libata: don't use...
1605
  		if (!(hpriv->port_map & (1 << i)))
dab632e8c   Jeff Garzik   [libata] ahci: mi...
1606
  			ap->ops = &ata_dummy_port_ops;
4447d3515   Tejun Heo   libata: convert t...
1607
  	}
d447df140   Tejun Heo   ahci: implement a...
1608

edc930528   Tejun Heo   ahci: ahci: imple...
1609
1610
  	/* apply workaround for ASUS P5W DH Deluxe mainboard */
  	ahci_p5wdh_workaround(host);
f80ae7e45   Tejun Heo   ahci: filter FPDM...
1611
1612
  	/* apply gtf filter quirk */
  	ahci_gtf_filter_workaround(host);
4447d3515   Tejun Heo   libata: convert t...
1613
1614
  	/* initialize adapter */
  	rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1615
  	if (rc)
24dc5f33e   Tejun Heo   libata: update li...
1616
  		return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1617

3303040d8   Anton Vorontsov   ahci: Factor out ...
1618
  	rc = ahci_pci_reset_controller(host);
4447d3515   Tejun Heo   libata: convert t...
1619
1620
  	if (rc)
  		return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1621

781d65508   Anton Vorontsov   ahci: Factor out ...
1622
  	ahci_pci_init_controller(host);
439fcaec1   Anton Vorontsov   ahci: Factor out ...
1623
  	ahci_pci_print_info(host);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1624

4447d3515   Tejun Heo   libata: convert t...
1625
  	pci_set_master(pdev);
5ca72c4f7   Alexander Gordeev   AHCI: Support mul...
1626

02e53293e   Mika Westerberg   ahci: Add runtime...
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
  	rc = ahci_host_activate(host, &ahci_sht);
  	if (rc)
  		return rc;
  
  	pm_runtime_put_noidle(&pdev->dev);
  	return 0;
  }
  
  static void ahci_remove_one(struct pci_dev *pdev)
  {
  	pm_runtime_get_noresume(&pdev->dev);
  	ata_pci_remove_one(pdev);
907f4678c   Jeff Garzik   [libata ahci] sup...
1639
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1640

2fc75da0c   Axel Lin   ata: use module_p...
1641
  module_pci_driver(ahci_pci_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1642
1643
1644
1645
1646
  
  MODULE_AUTHOR("Jeff Garzik");
  MODULE_DESCRIPTION("AHCI SATA low-level driver");
  MODULE_LICENSE("GPL");
  MODULE_DEVICE_TABLE(pci, ahci_pci_tbl);
6885433c2   Jeff Garzik   libata: release p...
1647
  MODULE_VERSION(DRV_VERSION);