ahci_pci.c revision 222039
1145519Sdarrenr/*-
2145510Sdarrenr * Copyright (c) 2009 Alexander Motin <mav@FreeBSD.org>
3170268Sdarrenr * All rights reserved.
4255332Scy *
5170268Sdarrenr * Redistribution and use in source and binary forms, with or without
6170268Sdarrenr * modification, are permitted provided that the following conditions
7170268Sdarrenr * are met:
8145510Sdarrenr * 1. Redistributions of source code must retain the above copyright
9145510Sdarrenr *    notice, this list of conditions and the following disclaimer,
10145510Sdarrenr *    without modification, immediately at the beginning of the file.
11145510Sdarrenr * 2. Redistributions in binary form must reproduce the above copyright
12145510Sdarrenr *    notice, this list of conditions and the following disclaimer in the
13145510Sdarrenr *    documentation and/or other materials provided with the distribution.
14145510Sdarrenr *
15145510Sdarrenr * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16145510Sdarrenr * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17145510Sdarrenr * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18145510Sdarrenr * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19145510Sdarrenr * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20145510Sdarrenr * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21145510Sdarrenr * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22145510Sdarrenr * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23145510Sdarrenr * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24145510Sdarrenr * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25145510Sdarrenr */
26145510Sdarrenr
27145510Sdarrenr#include <sys/cdefs.h>
28145510Sdarrenr__FBSDID("$FreeBSD: head/sys/dev/ahci/ahci.c 222039 2011-05-17 22:07:45Z mav $");
29145510Sdarrenr
30145510Sdarrenr#include <sys/param.h>
31145510Sdarrenr#include <sys/module.h>
32145510Sdarrenr#include <sys/systm.h>
33145510Sdarrenr#include <sys/kernel.h>
34145510Sdarrenr#include <sys/ata.h>
35145510Sdarrenr#include <sys/bus.h>
36145510Sdarrenr#include <sys/conf.h>
37145510Sdarrenr#include <sys/endian.h>
38255332Scy#include <sys/malloc.h>
39145510Sdarrenr#include <sys/lock.h>
40145510Sdarrenr#include <sys/mutex.h>
41145510Sdarrenr#include <sys/sema.h>
42145510Sdarrenr#include <sys/taskqueue.h>
43170268Sdarrenr#include <vm/uma.h>
44145510Sdarrenr#include <machine/stdarg.h>
45145510Sdarrenr#include <machine/resource.h>
46145510Sdarrenr#include <machine/bus.h>
47145510Sdarrenr#include <sys/rman.h>
48145510Sdarrenr#include <dev/led/led.h>
49145510Sdarrenr#include <dev/pci/pcivar.h>
50145510Sdarrenr#include <dev/pci/pcireg.h>
51145510Sdarrenr#include "ahci.h"
52255332Scy
53145510Sdarrenr#include <cam/cam.h>
54145510Sdarrenr#include <cam/cam_ccb.h>
55145510Sdarrenr#include <cam/cam_sim.h>
56170268Sdarrenr#include <cam/cam_xpt_sim.h>
57170268Sdarrenr#include <cam/cam_debug.h>
58255332Scy
59255332Scy/* local prototypes */
60170268Sdarrenrstatic int ahci_setup_interrupt(device_t dev);
61145510Sdarrenrstatic void ahci_intr(void *data);
62145510Sdarrenrstatic void ahci_intr_one(void *data);
63145510Sdarrenrstatic int ahci_suspend(device_t dev);
64145510Sdarrenrstatic int ahci_resume(device_t dev);
65145510Sdarrenrstatic int ahci_ch_init(device_t dev);
66255332Scystatic int ahci_ch_deinit(device_t dev);
67145510Sdarrenrstatic int ahci_ch_suspend(device_t dev);
68255332Scystatic int ahci_ch_resume(device_t dev);
69145510Sdarrenrstatic void ahci_ch_pm(void *arg);
70145510Sdarrenrstatic void ahci_ch_intr_locked(void *data);
71255332Scystatic void ahci_ch_intr(void *data);
72255332Scystatic void ahci_ch_led(void *priv, int onoff);
73255332Scystatic int ahci_ctlr_reset(device_t dev);
74145510Sdarrenrstatic int ahci_ctlr_setup(device_t dev);
75145510Sdarrenrstatic void ahci_begin_transaction(device_t dev, union ccb *ccb);
76255332Scystatic void ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error);
77255332Scystatic void ahci_execute_transaction(struct ahci_slot *slot);
78255332Scystatic void ahci_timeout(struct ahci_slot *slot);
79255332Scystatic void ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et);
80255332Scystatic int ahci_setup_fis(device_t dev, struct ahci_cmd_tab *ctp, union ccb *ccb, int tag);
81255332Scystatic void ahci_dmainit(device_t dev);
82255332Scystatic void ahci_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error);
83255332Scystatic void ahci_dmafini(device_t dev);
84145510Sdarrenrstatic void ahci_slotsalloc(device_t dev);
85255332Scystatic void ahci_slotsfree(device_t dev);
86255332Scystatic void ahci_reset(device_t dev);
87255332Scystatic void ahci_start(device_t dev, int fbs);
88255332Scystatic void ahci_stop(device_t dev);
89255332Scystatic void ahci_clo(device_t dev);
90145510Sdarrenrstatic void ahci_start_fr(device_t dev);
91145510Sdarrenrstatic void ahci_stop_fr(device_t dev);
92145510Sdarrenr
93145510Sdarrenrstatic int ahci_sata_connect(struct ahci_channel *ch);
94255332Scystatic int ahci_sata_phy_reset(device_t dev);
95255332Scystatic int ahci_wait_ready(device_t dev, int t, int t0);
96255332Scy
97255332Scystatic void ahci_issue_recovery(device_t dev);
98145510Sdarrenrstatic void ahci_process_read_log(device_t dev, union ccb *ccb);
99145510Sdarrenrstatic void ahci_process_request_sense(device_t dev, union ccb *ccb);
100145510Sdarrenr
101145510Sdarrenrstatic void ahciaction(struct cam_sim *sim, union ccb *ccb);
102145510Sdarrenrstatic void ahcipoll(struct cam_sim *sim);
103145510Sdarrenr
104145510SdarrenrMALLOC_DEFINE(M_AHCI, "AHCI driver", "AHCI driver data buffers");
105145510Sdarrenr
106255332Scystatic struct {
107255332Scy	uint32_t	id;
108145510Sdarrenr	uint8_t		rev;
109145510Sdarrenr	const char	*name;
110255332Scy	int		quirks;
111255332Scy#define AHCI_Q_NOFORCE	1
112255332Scy#define AHCI_Q_NOPMP	2
113255332Scy#define AHCI_Q_NONCQ	4
114145510Sdarrenr#define AHCI_Q_1CH	8
115255332Scy#define AHCI_Q_2CH	16
116145510Sdarrenr#define AHCI_Q_4CH	32
117255332Scy#define AHCI_Q_EDGEIS	64
118255332Scy#define AHCI_Q_SATA2	128
119145510Sdarrenr#define AHCI_Q_NOBSYRES	256
120145510Sdarrenr#define AHCI_Q_NOAA	512
121255332Scy#define AHCI_Q_NOCOUNT	1024
122255332Scy} ahci_ids[] = {
123255332Scy	{0x43801002, 0x00, "ATI IXP600",	0},
124255332Scy	{0x43901002, 0x00, "ATI IXP700",	0},
125145510Sdarrenr	{0x43911002, 0x00, "ATI IXP700",	0},
126255332Scy	{0x43921002, 0x00, "ATI IXP700",	0},
127145510Sdarrenr	{0x43931002, 0x00, "ATI IXP700",	0},
128145510Sdarrenr	{0x43941002, 0x00, "ATI IXP800",	0},
129255332Scy	{0x43951002, 0x00, "ATI IXP800",	0},
130255332Scy	{0x26528086, 0x00, "Intel ICH6",	AHCI_Q_NOFORCE},
131145510Sdarrenr	{0x26538086, 0x00, "Intel ICH6M",	AHCI_Q_NOFORCE},
132145510Sdarrenr	{0x26818086, 0x00, "Intel ESB2",	0},
133145510Sdarrenr	{0x26828086, 0x00, "Intel ESB2",	0},
134145510Sdarrenr	{0x26838086, 0x00, "Intel ESB2",	0},
135255332Scy	{0x27c18086, 0x00, "Intel ICH7",	0},
136255332Scy	{0x27c38086, 0x00, "Intel ICH7",	0},
137255332Scy	{0x27c58086, 0x00, "Intel ICH7M",	0},
138255332Scy	{0x27c68086, 0x00, "Intel ICH7M",	0},
139145510Sdarrenr	{0x28218086, 0x00, "Intel ICH8",	0},
140255332Scy	{0x28228086, 0x00, "Intel ICH8",	0},
141145510Sdarrenr	{0x28248086, 0x00, "Intel ICH8",	0},
142145510Sdarrenr	{0x28298086, 0x00, "Intel ICH8M",	0},
143255332Scy	{0x282a8086, 0x00, "Intel ICH8M",	0},
144145510Sdarrenr	{0x29228086, 0x00, "Intel ICH9",	0},
145145510Sdarrenr	{0x29238086, 0x00, "Intel ICH9",	0},
146145510Sdarrenr	{0x29248086, 0x00, "Intel ICH9",	0},
147145510Sdarrenr	{0x29258086, 0x00, "Intel ICH9",	0},
148145510Sdarrenr	{0x29278086, 0x00, "Intel ICH9",	0},
149145510Sdarrenr	{0x29298086, 0x00, "Intel ICH9M",	0},
150145510Sdarrenr	{0x292a8086, 0x00, "Intel ICH9M",	0},
151145510Sdarrenr	{0x292b8086, 0x00, "Intel ICH9M",	0},
152145510Sdarrenr	{0x292c8086, 0x00, "Intel ICH9M",	0},
153170268Sdarrenr	{0x292f8086, 0x00, "Intel ICH9M",	0},
154145510Sdarrenr	{0x294d8086, 0x00, "Intel ICH9",	0},
155145510Sdarrenr	{0x294e8086, 0x00, "Intel ICH9M",	0},
156145510Sdarrenr	{0x3a058086, 0x00, "Intel ICH10",	0},
157145510Sdarrenr	{0x3a228086, 0x00, "Intel ICH10",	0},
158145510Sdarrenr	{0x3a258086, 0x00, "Intel ICH10",	0},
159145510Sdarrenr	{0x3b228086, 0x00, "Intel 5 Series/3400 Series",	0},
160145510Sdarrenr	{0x3b238086, 0x00, "Intel 5 Series/3400 Series",	0},
161145510Sdarrenr	{0x3b258086, 0x00, "Intel 5 Series/3400 Series",	0},
162145510Sdarrenr	{0x3b298086, 0x00, "Intel 5 Series/3400 Series",	0},
163145510Sdarrenr	{0x3b2c8086, 0x00, "Intel 5 Series/3400 Series",	0},
164255332Scy	{0x3b2f8086, 0x00, "Intel 5 Series/3400 Series",	0},
165145510Sdarrenr	{0x1c028086, 0x00, "Intel Cougar Point",	0},
166145510Sdarrenr	{0x1c038086, 0x00, "Intel Cougar Point",	0},
167145510Sdarrenr	{0x1c048086, 0x00, "Intel Cougar Point",	0},
168145510Sdarrenr	{0x1c058086, 0x00, "Intel Cougar Point",	0},
169145510Sdarrenr	{0x1d028086, 0x00, "Intel Patsburg",	0},
170145510Sdarrenr	{0x1d048086, 0x00, "Intel Patsburg",	0},
171145510Sdarrenr	{0x1d068086, 0x00, "Intel Patsburg",	0},
172145510Sdarrenr	{0x1e028086, 0x00, "Intel Panther Point",	0},
173145510Sdarrenr	{0x1e038086, 0x00, "Intel Panther Point",	0},
174145510Sdarrenr	{0x1e048086, 0x00, "Intel Panther Point",	0},
175145510Sdarrenr	{0x1e058086, 0x00, "Intel Panther Point",	0},
176145510Sdarrenr	{0x1e068086, 0x00, "Intel Panther Point",	0},
177145510Sdarrenr	{0x1e078086, 0x00, "Intel Panther Point",	0},
178145510Sdarrenr	{0x1e0e8086, 0x00, "Intel Panther Point",	0},
179145510Sdarrenr	{0x1e0f8086, 0x00, "Intel Panther Point",	0},
180145510Sdarrenr	{0x23238086, 0x00, "Intel DH89xxCC",	0},
181145510Sdarrenr	{0x2361197b, 0x00, "JMicron JMB361",	AHCI_Q_NOFORCE},
182145510Sdarrenr	{0x2363197b, 0x00, "JMicron JMB363",	AHCI_Q_NOFORCE},
183255332Scy	{0x2365197b, 0x00, "JMicron JMB365",	AHCI_Q_NOFORCE},
184255332Scy	{0x2366197b, 0x00, "JMicron JMB366",	AHCI_Q_NOFORCE},
185145510Sdarrenr	{0x2368197b, 0x00, "JMicron JMB368",	AHCI_Q_NOFORCE},
186145510Sdarrenr	{0x611111ab, 0x00, "Marvell 88SX6111",	AHCI_Q_NOFORCE | AHCI_Q_1CH |
187255332Scy	    AHCI_Q_EDGEIS},
188255332Scy	{0x612111ab, 0x00, "Marvell 88SX6121",	AHCI_Q_NOFORCE | AHCI_Q_2CH |
189255332Scy	    AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
190255332Scy	{0x614111ab, 0x00, "Marvell 88SX6141",	AHCI_Q_NOFORCE | AHCI_Q_4CH |
191255332Scy	    AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
192255332Scy	{0x614511ab, 0x00, "Marvell 88SX6145",	AHCI_Q_NOFORCE | AHCI_Q_4CH |
193255332Scy	    AHCI_Q_EDGEIS | AHCI_Q_NONCQ | AHCI_Q_NOCOUNT},
194145510Sdarrenr	{0x91201b4b, 0x00, "Marvell 88SE912x",	AHCI_Q_EDGEIS|AHCI_Q_NOBSYRES},
195145510Sdarrenr	{0x91231b4b, 0x11, "Marvell 88SE912x",	AHCI_Q_NOBSYRES},
196145510Sdarrenr	{0x91231b4b, 0x00, "Marvell 88SE912x",	AHCI_Q_EDGEIS|AHCI_Q_SATA2|AHCI_Q_NOBSYRES},
197145510Sdarrenr	{0x91821b4b, 0x00, "Marvell 88SE9182",	AHCI_Q_NOBSYRES},
198145510Sdarrenr	{0x06201103, 0x00, "HighPoint RocketRAID 620",	AHCI_Q_NOBSYRES},
199145510Sdarrenr	{0x06201b4b, 0x00, "HighPoint RocketRAID 620",	AHCI_Q_NOBSYRES},
200145510Sdarrenr	{0x06221103, 0x00, "HighPoint RocketRAID 622",	AHCI_Q_NOBSYRES},
201145510Sdarrenr	{0x06221b4b, 0x00, "HighPoint RocketRAID 622",	AHCI_Q_NOBSYRES},
202145510Sdarrenr	{0x06401103, 0x00, "HighPoint RocketRAID 640",	AHCI_Q_NOBSYRES},
203145510Sdarrenr	{0x06401b4b, 0x00, "HighPoint RocketRAID 640",	AHCI_Q_NOBSYRES},
204145510Sdarrenr	{0x06441103, 0x00, "HighPoint RocketRAID 644",	AHCI_Q_NOBSYRES},
205145510Sdarrenr	{0x06441b4b, 0x00, "HighPoint RocketRAID 644",	AHCI_Q_NOBSYRES},
206145510Sdarrenr	{0x044c10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
207145510Sdarrenr	{0x044d10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
208145510Sdarrenr	{0x044e10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
209145510Sdarrenr	{0x044f10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
210145510Sdarrenr	{0x045c10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
211145510Sdarrenr	{0x045d10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
212145510Sdarrenr	{0x045e10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
213145510Sdarrenr	{0x045f10de, 0x00, "NVIDIA MCP65",	AHCI_Q_NOAA},
214145510Sdarrenr	{0x055010de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
215145510Sdarrenr	{0x055110de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
216145510Sdarrenr	{0x055210de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
217145510Sdarrenr	{0x055310de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
218145510Sdarrenr	{0x055410de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
219145510Sdarrenr	{0x055510de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
220255332Scy	{0x055610de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
221145510Sdarrenr	{0x055710de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
222255332Scy	{0x055810de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
223255332Scy	{0x055910de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
224145510Sdarrenr	{0x055A10de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
225145510Sdarrenr	{0x055B10de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
226145510Sdarrenr	{0x058410de, 0x00, "NVIDIA MCP67",	AHCI_Q_NOAA},
227145510Sdarrenr	{0x07f010de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
228145510Sdarrenr	{0x07f110de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
229255332Scy	{0x07f210de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
230255332Scy	{0x07f310de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
231255332Scy	{0x07f410de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
232255332Scy	{0x07f510de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
233255332Scy	{0x07f610de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
234255332Scy	{0x07f710de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
235145510Sdarrenr	{0x07f810de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
236145510Sdarrenr	{0x07f910de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
237145510Sdarrenr	{0x07fa10de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
238145510Sdarrenr	{0x07fb10de, 0x00, "NVIDIA MCP73",	AHCI_Q_NOAA},
239145510Sdarrenr	{0x0ad010de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
240145510Sdarrenr	{0x0ad110de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
241145510Sdarrenr	{0x0ad210de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
242255332Scy	{0x0ad310de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
243145510Sdarrenr	{0x0ad410de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
244145510Sdarrenr	{0x0ad510de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
245145510Sdarrenr	{0x0ad610de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
246145510Sdarrenr	{0x0ad710de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
247145510Sdarrenr	{0x0ad810de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
248145510Sdarrenr	{0x0ad910de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
249145510Sdarrenr	{0x0ada10de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
250145510Sdarrenr	{0x0adb10de, 0x00, "NVIDIA MCP77",	AHCI_Q_NOAA},
251145510Sdarrenr	{0x0ab410de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
252145510Sdarrenr	{0x0ab510de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
253145510Sdarrenr	{0x0ab610de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
254145510Sdarrenr	{0x0ab710de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
255145510Sdarrenr	{0x0ab810de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
256145510Sdarrenr	{0x0ab910de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
257255332Scy	{0x0aba10de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
258255332Scy	{0x0abb10de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
259255332Scy	{0x0abc10de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
260255332Scy	{0x0abd10de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
261255332Scy	{0x0abe10de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
262255332Scy	{0x0abf10de, 0x00, "NVIDIA MCP79",	AHCI_Q_NOAA},
263145510Sdarrenr	{0x0d8410de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
264145510Sdarrenr	{0x0d8510de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
265145510Sdarrenr	{0x0d8610de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
266145510Sdarrenr	{0x0d8710de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
267255332Scy	{0x0d8810de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
268145510Sdarrenr	{0x0d8910de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
269145510Sdarrenr	{0x0d8a10de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
270255332Scy	{0x0d8b10de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
271255332Scy	{0x0d8c10de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
272255332Scy	{0x0d8d10de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
273145510Sdarrenr	{0x0d8e10de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
274145510Sdarrenr	{0x0d8f10de, 0x00, "NVIDIA MCP89",	AHCI_Q_NOAA},
275145510Sdarrenr	{0x33491106, 0x00, "VIA VT8251",	AHCI_Q_NOPMP|AHCI_Q_NONCQ},
276145510Sdarrenr	{0x62871106, 0x00, "VIA VT8251",	AHCI_Q_NOPMP|AHCI_Q_NONCQ},
277255332Scy	{0x11841039, 0x00, "SiS 966",		0},
278255332Scy	{0x11851039, 0x00, "SiS 968",		0},
279255332Scy	{0x01861039, 0x00, "SiS 968",		0},
280255332Scy	{0x00000000, 0x00, NULL,		0}
281255332Scy};
282255332Scy
283255332Scy#define recovery_type		spriv_field0
284255332Scy#define RECOVERY_NONE		0
285145510Sdarrenr#define RECOVERY_READ_LOG	1
286255332Scy#define RECOVERY_REQUEST_SENSE	2
287255332Scy#define recovery_slot		spriv_field1
288255332Scy
289145510Sdarrenrstatic int
290145510Sdarrenrahci_probe(device_t dev)
291145510Sdarrenr{
292255332Scy	char buf[64];
293145510Sdarrenr	int i, valid = 0;
294145510Sdarrenr	uint32_t devid = pci_get_devid(dev);
295145510Sdarrenr	uint8_t revid = pci_get_revid(dev);
296145510Sdarrenr
297145510Sdarrenr	/* Is this a possible AHCI candidate? */
298145510Sdarrenr	if (pci_get_class(dev) == PCIC_STORAGE &&
299255332Scy	    pci_get_subclass(dev) == PCIS_STORAGE_SATA &&
300255332Scy	    pci_get_progif(dev) == PCIP_STORAGE_SATA_AHCI_1_0)
301145510Sdarrenr		valid = 1;
302145510Sdarrenr	/* Is this a known AHCI chip? */
303255332Scy	for (i = 0; ahci_ids[i].id != 0; i++) {
304255332Scy		if (ahci_ids[i].id == devid &&
305255332Scy		    ahci_ids[i].rev <= revid &&
306255332Scy		    (valid || !(ahci_ids[i].quirks & AHCI_Q_NOFORCE))) {
307255332Scy			/* Do not attach JMicrons with single PCI function. */
308255332Scy			if (pci_get_vendor(dev) == 0x197b &&
309145510Sdarrenr			    (pci_read_config(dev, 0xdf, 1) & 0x40) == 0)
310145510Sdarrenr				return (ENXIO);
311145510Sdarrenr			snprintf(buf, sizeof(buf), "%s AHCI SATA controller",
312145510Sdarrenr			    ahci_ids[i].name);
313255332Scy			device_set_desc_copy(dev, buf);
314255332Scy			return (BUS_PROBE_VENDOR);
315255332Scy		}
316255332Scy	}
317255332Scy	if (!valid)
318255332Scy		return (ENXIO);
319255332Scy	device_set_desc_copy(dev, "AHCI SATA controller");
320255332Scy	return (BUS_PROBE_VENDOR);
321255332Scy}
322255332Scy
323255332Scystatic int
324255332Scyahci_ata_probe(device_t dev)
325255332Scy{
326255332Scy	char buf[64];
327255332Scy	int i;
328255332Scy	uint32_t devid = pci_get_devid(dev);
329255332Scy	uint8_t revid = pci_get_revid(dev);
330145510Sdarrenr
331145510Sdarrenr	if ((intptr_t)device_get_ivars(dev) >= 0)
332255332Scy		return (ENXIO);
333145510Sdarrenr	/* Is this a known AHCI chip? */
334145510Sdarrenr	for (i = 0; ahci_ids[i].id != 0; i++) {
335145510Sdarrenr		if (ahci_ids[i].id == devid &&
336145510Sdarrenr		    ahci_ids[i].rev <= revid) {
337145510Sdarrenr			snprintf(buf, sizeof(buf), "%s AHCI SATA controller",
338255332Scy			    ahci_ids[i].name);
339255332Scy			device_set_desc_copy(dev, buf);
340255332Scy			return (BUS_PROBE_VENDOR);
341255332Scy		}
342255332Scy	}
343255332Scy	device_set_desc_copy(dev, "AHCI SATA controller");
344255332Scy	return (BUS_PROBE_VENDOR);
345255332Scy}
346255332Scy
347255332Scystatic int
348255332Scyahci_attach(device_t dev)
349255332Scy{
350255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
351145510Sdarrenr	device_t child;
352145510Sdarrenr	int	error, unit, speed, i;
353145510Sdarrenr	uint32_t devid = pci_get_devid(dev);
354255332Scy	uint8_t revid = pci_get_revid(dev);
355255332Scy	u_int32_t version;
356255332Scy
357255332Scy	ctlr->dev = dev;
358145510Sdarrenr	i = 0;
359255332Scy	while (ahci_ids[i].id != 0 &&
360255332Scy	    (ahci_ids[i].id != devid ||
361255332Scy	     ahci_ids[i].rev > revid))
362255332Scy		i++;
363255332Scy	ctlr->quirks = ahci_ids[i].quirks;
364255332Scy	resource_int_value(device_get_name(dev),
365255332Scy	    device_get_unit(dev), "ccc", &ctlr->ccc);
366255332Scy	/* if we have a memory BAR(5) we are likely on an AHCI part */
367255332Scy	ctlr->r_rid = PCIR_BAR(5);
368255332Scy	if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
369255332Scy	    &ctlr->r_rid, RF_ACTIVE)))
370145510Sdarrenr		return ENXIO;
371145510Sdarrenr	/* Setup our own memory management for channels. */
372145510Sdarrenr	ctlr->sc_iomem.rm_start = rman_get_start(ctlr->r_mem);
373255332Scy	ctlr->sc_iomem.rm_end = rman_get_end(ctlr->r_mem);
374255332Scy	ctlr->sc_iomem.rm_type = RMAN_ARRAY;
375255332Scy	ctlr->sc_iomem.rm_descr = "I/O memory addresses";
376255332Scy	if ((error = rman_init(&ctlr->sc_iomem)) != 0) {
377255332Scy		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
378255332Scy		return (error);
379255332Scy	}
380255332Scy	if ((error = rman_manage_region(&ctlr->sc_iomem,
381255332Scy	    rman_get_start(ctlr->r_mem), rman_get_end(ctlr->r_mem))) != 0) {
382255332Scy		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
383255332Scy		rman_fini(&ctlr->sc_iomem);
384255332Scy		return (error);
385255332Scy	}
386255332Scy	pci_enable_busmaster(dev);
387255332Scy	/* Reset controller */
388145510Sdarrenr	if ((error = ahci_ctlr_reset(dev)) != 0) {
389145510Sdarrenr		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
390255332Scy		rman_fini(&ctlr->sc_iomem);
391255332Scy		return (error);
392255332Scy	};
393255332Scy	/* Get the HW capabilities */
394255332Scy	version = ATA_INL(ctlr->r_mem, AHCI_VS);
395255332Scy	ctlr->caps = ATA_INL(ctlr->r_mem, AHCI_CAP);
396255332Scy	if (version >= 0x00010020)
397255332Scy		ctlr->caps2 = ATA_INL(ctlr->r_mem, AHCI_CAP2);
398255332Scy	if (ctlr->caps & AHCI_CAP_EMS)
399255332Scy		ctlr->capsem = ATA_INL(ctlr->r_mem, AHCI_EM_CTL);
400255332Scy	ctlr->ichannels = ATA_INL(ctlr->r_mem, AHCI_PI);
401255332Scy	if (ctlr->quirks & AHCI_Q_1CH) {
402255332Scy		ctlr->caps &= ~AHCI_CAP_NPMASK;
403255332Scy		ctlr->ichannels &= 0x01;
404255332Scy	}
405255332Scy	if (ctlr->quirks & AHCI_Q_2CH) {
406255332Scy		ctlr->caps &= ~AHCI_CAP_NPMASK;
407145510Sdarrenr		ctlr->caps |= 1;
408145510Sdarrenr		ctlr->ichannels &= 0x03;
409255332Scy	}
410145510Sdarrenr	if (ctlr->quirks & AHCI_Q_4CH) {
411145510Sdarrenr		ctlr->caps &= ~AHCI_CAP_NPMASK;
412255332Scy		ctlr->caps |= 3;
413145510Sdarrenr		ctlr->ichannels &= 0x0f;
414145510Sdarrenr	}
415145510Sdarrenr	ctlr->channels = MAX(flsl(ctlr->ichannels),
416145510Sdarrenr	    (ctlr->caps & AHCI_CAP_NPMASK) + 1);
417145510Sdarrenr	if (ctlr->quirks & AHCI_Q_NOPMP)
418145510Sdarrenr		ctlr->caps &= ~AHCI_CAP_SPM;
419145510Sdarrenr	if (ctlr->quirks & AHCI_Q_NONCQ)
420145510Sdarrenr		ctlr->caps &= ~AHCI_CAP_SNCQ;
421145510Sdarrenr	if ((ctlr->caps & AHCI_CAP_CCCS) == 0)
422145510Sdarrenr		ctlr->ccc = 0;
423145510Sdarrenr	mtx_init(&ctlr->em_mtx, "AHCI EM lock", NULL, MTX_DEF);
424255332Scy	ctlr->emloc = ATA_INL(ctlr->r_mem, AHCI_EM_LOC);
425255332Scy	ahci_ctlr_setup(dev);
426255332Scy	/* Setup interrupts. */
427255332Scy	if (ahci_setup_interrupt(dev)) {
428255332Scy		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
429255332Scy		rman_fini(&ctlr->sc_iomem);
430255332Scy		return ENXIO;
431255332Scy	}
432255332Scy	/* Announce HW capabilities. */
433255332Scy	speed = (ctlr->caps & AHCI_CAP_ISS) >> AHCI_CAP_ISS_SHIFT;
434255332Scy	device_printf(dev,
435255332Scy		    "AHCI v%x.%02x with %d %sGbps ports, Port Multiplier %s%s\n",
436255332Scy		    ((version >> 20) & 0xf0) + ((version >> 16) & 0x0f),
437255332Scy		    ((version >> 4) & 0xf0) + (version & 0x0f),
438255332Scy		    (ctlr->caps & AHCI_CAP_NPMASK) + 1,
439255332Scy		    ((speed == 1) ? "1.5":((speed == 2) ? "3":
440255332Scy		    ((speed == 3) ? "6":"?"))),
441255332Scy		    (ctlr->caps & AHCI_CAP_SPM) ?
442255332Scy		    "supported" : "not supported",
443255332Scy		    (ctlr->caps & AHCI_CAP_FBSS) ?
444255332Scy		    " with FBS" : "");
445255332Scy	if (bootverbose) {
446255332Scy		device_printf(dev, "Caps:%s%s%s%s%s%s%s%s %sGbps",
447255332Scy		    (ctlr->caps & AHCI_CAP_64BIT) ? " 64bit":"",
448255332Scy		    (ctlr->caps & AHCI_CAP_SNCQ) ? " NCQ":"",
449255332Scy		    (ctlr->caps & AHCI_CAP_SSNTF) ? " SNTF":"",
450255332Scy		    (ctlr->caps & AHCI_CAP_SMPS) ? " MPS":"",
451255332Scy		    (ctlr->caps & AHCI_CAP_SSS) ? " SS":"",
452255332Scy		    (ctlr->caps & AHCI_CAP_SALP) ? " ALP":"",
453255332Scy		    (ctlr->caps & AHCI_CAP_SAL) ? " AL":"",
454255332Scy		    (ctlr->caps & AHCI_CAP_SCLO) ? " CLO":"",
455255332Scy		    ((speed == 1) ? "1.5":((speed == 2) ? "3":
456255332Scy		    ((speed == 3) ? "6":"?"))));
457255332Scy		printf("%s%s%s%s%s%s %dcmd%s%s%s %dports\n",
458255332Scy		    (ctlr->caps & AHCI_CAP_SAM) ? " AM":"",
459255332Scy		    (ctlr->caps & AHCI_CAP_SPM) ? " PM":"",
460255332Scy		    (ctlr->caps & AHCI_CAP_FBSS) ? " FBS":"",
461255332Scy		    (ctlr->caps & AHCI_CAP_PMD) ? " PMD":"",
462255332Scy		    (ctlr->caps & AHCI_CAP_SSC) ? " SSC":"",
463255332Scy		    (ctlr->caps & AHCI_CAP_PSC) ? " PSC":"",
464255332Scy		    ((ctlr->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1,
465255332Scy		    (ctlr->caps & AHCI_CAP_CCCS) ? " CCC":"",
466255332Scy		    (ctlr->caps & AHCI_CAP_EMS) ? " EM":"",
467255332Scy		    (ctlr->caps & AHCI_CAP_SXS) ? " eSATA":"",
468255332Scy		    (ctlr->caps & AHCI_CAP_NPMASK) + 1);
469255332Scy	}
470255332Scy	if (bootverbose && version >= 0x00010020) {
471255332Scy		device_printf(dev, "Caps2:%s%s%s\n",
472255332Scy		    (ctlr->caps2 & AHCI_CAP2_APST) ? " APST":"",
473255332Scy		    (ctlr->caps2 & AHCI_CAP2_NVMP) ? " NVMP":"",
474255332Scy		    (ctlr->caps2 & AHCI_CAP2_BOH) ? " BOH":"");
475255332Scy	}
476255332Scy	if (bootverbose && (ctlr->caps & AHCI_CAP_EMS)) {
477255332Scy		device_printf(dev, "EM Caps:%s%s%s%s%s%s%s%s\n",
478255332Scy		    (ctlr->capsem & AHCI_EM_PM) ? " PM":"",
479255332Scy		    (ctlr->capsem & AHCI_EM_ALHD) ? " ALHD":"",
480255332Scy		    (ctlr->capsem & AHCI_EM_XMT) ? " XMT":"",
481255332Scy		    (ctlr->capsem & AHCI_EM_SMB) ? " SMB":"",
482255332Scy		    (ctlr->capsem & AHCI_EM_SGPIO) ? " SGPIO":"",
483255332Scy		    (ctlr->capsem & AHCI_EM_SES2) ? " SES-2":"",
484255332Scy		    (ctlr->capsem & AHCI_EM_SAFTE) ? " SAF-TE":"",
485255332Scy		    (ctlr->capsem & AHCI_EM_LED) ? " LED":"");
486255332Scy	}
487255332Scy	/* Attach all channels on this controller */
488255332Scy	for (unit = 0; unit < ctlr->channels; unit++) {
489255332Scy		if ((ctlr->ichannels & (1 << unit)) == 0)
490255332Scy			continue;
491255332Scy		child = device_add_child(dev, "ahcich", -1);
492255332Scy		if (child == NULL)
493255332Scy			device_printf(dev, "failed to add channel device\n");
494255332Scy		else
495255332Scy			device_set_ivars(child, (void *)(intptr_t)unit);
496255332Scy	}
497255332Scy	bus_generic_attach(dev);
498255332Scy	return 0;
499255332Scy}
500255332Scy
501255332Scystatic int
502255332Scyahci_detach(device_t dev)
503255332Scy{
504255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
505255332Scy	device_t *children;
506255332Scy	int nchildren, i;
507255332Scy
508255332Scy	/* Detach & delete all children */
509255332Scy	if (!device_get_children(dev, &children, &nchildren)) {
510255332Scy		for (i = 0; i < nchildren; i++)
511255332Scy			device_delete_child(dev, children[i]);
512255332Scy		free(children, M_TEMP);
513255332Scy	}
514255332Scy	/* Free interrupts. */
515255332Scy	for (i = 0; i < ctlr->numirqs; i++) {
516255332Scy		if (ctlr->irqs[i].r_irq) {
517255332Scy			bus_teardown_intr(dev, ctlr->irqs[i].r_irq,
518255332Scy			    ctlr->irqs[i].handle);
519255332Scy			bus_release_resource(dev, SYS_RES_IRQ,
520255332Scy			    ctlr->irqs[i].r_irq_rid, ctlr->irqs[i].r_irq);
521255332Scy		}
522255332Scy	}
523255332Scy	pci_release_msi(dev);
524255332Scy	/* Free memory. */
525255332Scy	rman_fini(&ctlr->sc_iomem);
526255332Scy	if (ctlr->r_mem)
527255332Scy		bus_release_resource(dev, SYS_RES_MEMORY, ctlr->r_rid, ctlr->r_mem);
528255332Scy	mtx_destroy(&ctlr->em_mtx);
529255332Scy	return (0);
530255332Scy}
531255332Scy
532255332Scystatic int
533255332Scyahci_ctlr_reset(device_t dev)
534255332Scy{
535255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
536255332Scy	int timeout;
537255332Scy
538255332Scy	if (pci_read_config(dev, 0x00, 4) == 0x28298086 &&
539255332Scy	    (pci_read_config(dev, 0x92, 1) & 0xfe) == 0x04)
540255332Scy		pci_write_config(dev, 0x92, 0x01, 1);
541255332Scy	/* Enable AHCI mode */
542255332Scy	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
543255332Scy	/* Reset AHCI controller */
544255332Scy	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE|AHCI_GHC_HR);
545255332Scy	for (timeout = 1000; timeout > 0; timeout--) {
546255332Scy		DELAY(1000);
547255332Scy		if ((ATA_INL(ctlr->r_mem, AHCI_GHC) & AHCI_GHC_HR) == 0)
548255332Scy			break;
549255332Scy	}
550255332Scy	if (timeout == 0) {
551255332Scy		device_printf(dev, "AHCI controller reset failure\n");
552255332Scy		return ENXIO;
553255332Scy	}
554255332Scy	/* Reenable AHCI mode */
555255332Scy	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
556255332Scy	return (0);
557255332Scy}
558255332Scy
559255332Scystatic int
560255332Scyahci_ctlr_setup(device_t dev)
561255332Scy{
562255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
563255332Scy	/* Clear interrupts */
564255332Scy	ATA_OUTL(ctlr->r_mem, AHCI_IS, ATA_INL(ctlr->r_mem, AHCI_IS));
565255332Scy	/* Configure CCC */
566145510Sdarrenr	if (ctlr->ccc) {
567145510Sdarrenr		ATA_OUTL(ctlr->r_mem, AHCI_CCCP, ATA_INL(ctlr->r_mem, AHCI_PI));
568255332Scy		ATA_OUTL(ctlr->r_mem, AHCI_CCCC,
569255332Scy		    (ctlr->ccc << AHCI_CCCC_TV_SHIFT) |
570255332Scy		    (4 << AHCI_CCCC_CC_SHIFT) |
571255332Scy		    AHCI_CCCC_EN);
572255332Scy		ctlr->cccv = (ATA_INL(ctlr->r_mem, AHCI_CCCC) &
573255332Scy		    AHCI_CCCC_INT_MASK) >> AHCI_CCCC_INT_SHIFT;
574255332Scy		if (bootverbose) {
575255332Scy			device_printf(dev,
576255332Scy			    "CCC with %dms/4cmd enabled on vector %d\n",
577255332Scy			    ctlr->ccc, ctlr->cccv);
578255332Scy		}
579255332Scy	}
580255332Scy	/* Enable AHCI interrupts */
581255332Scy	ATA_OUTL(ctlr->r_mem, AHCI_GHC,
582255332Scy	    ATA_INL(ctlr->r_mem, AHCI_GHC) | AHCI_GHC_IE);
583255332Scy	return (0);
584255332Scy}
585255332Scy
586255332Scystatic int
587255332Scyahci_suspend(device_t dev)
588255332Scy{
589255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
590255332Scy
591255332Scy	bus_generic_suspend(dev);
592255332Scy	/* Disable interupts, so the state change(s) doesn't trigger */
593255332Scy	ATA_OUTL(ctlr->r_mem, AHCI_GHC,
594255332Scy	     ATA_INL(ctlr->r_mem, AHCI_GHC) & (~AHCI_GHC_IE));
595255332Scy	return 0;
596255332Scy}
597255332Scy
598145510Sdarrenrstatic int
599145510Sdarrenrahci_resume(device_t dev)
600145510Sdarrenr{
601145510Sdarrenr	int res;
602145510Sdarrenr
603145510Sdarrenr	if ((res = ahci_ctlr_reset(dev)) != 0)
604145510Sdarrenr		return (res);
605145510Sdarrenr	ahci_ctlr_setup(dev);
606145510Sdarrenr	return (bus_generic_resume(dev));
607145510Sdarrenr}
608145510Sdarrenr
609145510Sdarrenrstatic int
610145510Sdarrenrahci_setup_interrupt(device_t dev)
611145510Sdarrenr{
612145510Sdarrenr	struct ahci_controller *ctlr = device_get_softc(dev);
613145510Sdarrenr	int i, msi = 1;
614145510Sdarrenr
615145510Sdarrenr	/* Process hints. */
616145510Sdarrenr	resource_int_value(device_get_name(dev),
617145510Sdarrenr	    device_get_unit(dev), "msi", &msi);
618145510Sdarrenr	if (msi < 0)
619145510Sdarrenr		msi = 0;
620145510Sdarrenr	else if (msi == 1)
621145510Sdarrenr		msi = min(1, pci_msi_count(dev));
622145510Sdarrenr	else if (msi > 1)
623145510Sdarrenr		msi = pci_msi_count(dev);
624145510Sdarrenr	/* Allocate MSI if needed/present. */
625145510Sdarrenr	if (msi && pci_alloc_msi(dev, &msi) == 0) {
626145510Sdarrenr		ctlr->numirqs = msi;
627145510Sdarrenr	} else {
628145510Sdarrenr		msi = 0;
629145510Sdarrenr		ctlr->numirqs = 1;
630145510Sdarrenr	}
631145510Sdarrenr	/* Check for single MSI vector fallback. */
632145510Sdarrenr	if (ctlr->numirqs > 1 &&
633145510Sdarrenr	    (ATA_INL(ctlr->r_mem, AHCI_GHC) & AHCI_GHC_MRSM) != 0) {
634145510Sdarrenr		device_printf(dev, "Falling back to one MSI\n");
635145510Sdarrenr		ctlr->numirqs = 1;
636145510Sdarrenr	}
637145510Sdarrenr	/* Allocate all IRQs. */
638145510Sdarrenr	for (i = 0; i < ctlr->numirqs; i++) {
639145510Sdarrenr		ctlr->irqs[i].ctlr = ctlr;
640145510Sdarrenr		ctlr->irqs[i].r_irq_rid = i + (msi ? 1 : 0);
641145510Sdarrenr		if (ctlr->numirqs == 1 || i >= ctlr->channels ||
642145510Sdarrenr		    (ctlr->ccc && i == ctlr->cccv))
643145510Sdarrenr			ctlr->irqs[i].mode = AHCI_IRQ_MODE_ALL;
644145510Sdarrenr		else if (i == ctlr->numirqs - 1)
645145510Sdarrenr			ctlr->irqs[i].mode = AHCI_IRQ_MODE_AFTER;
646145510Sdarrenr		else
647145510Sdarrenr			ctlr->irqs[i].mode = AHCI_IRQ_MODE_ONE;
648145510Sdarrenr		if (!(ctlr->irqs[i].r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
649145510Sdarrenr		    &ctlr->irqs[i].r_irq_rid, RF_SHAREABLE | RF_ACTIVE))) {
650145510Sdarrenr			device_printf(dev, "unable to map interrupt\n");
651145510Sdarrenr			return ENXIO;
652145510Sdarrenr		}
653145510Sdarrenr		if ((bus_setup_intr(dev, ctlr->irqs[i].r_irq, ATA_INTR_FLAGS, NULL,
654145510Sdarrenr		    (ctlr->irqs[i].mode == AHCI_IRQ_MODE_ONE) ? ahci_intr_one : ahci_intr,
655145510Sdarrenr		    &ctlr->irqs[i], &ctlr->irqs[i].handle))) {
656145510Sdarrenr			/* SOS XXX release r_irq */
657145510Sdarrenr			device_printf(dev, "unable to setup interrupt\n");
658145510Sdarrenr			return ENXIO;
659145510Sdarrenr		}
660145510Sdarrenr		if (ctlr->numirqs > 1) {
661145510Sdarrenr			bus_describe_intr(dev, ctlr->irqs[i].r_irq,
662145510Sdarrenr			    ctlr->irqs[i].handle,
663145510Sdarrenr			    ctlr->irqs[i].mode == AHCI_IRQ_MODE_ONE ?
664145510Sdarrenr			    "ch%d" : "%d", i);
665170268Sdarrenr		}
666170268Sdarrenr	}
667170268Sdarrenr	return (0);
668170268Sdarrenr}
669170268Sdarrenr
670170268Sdarrenr/*
671170268Sdarrenr * Common case interrupt handler.
672170268Sdarrenr */
673170268Sdarrenrstatic void
674170268Sdarrenrahci_intr(void *data)
675170268Sdarrenr{
676170268Sdarrenr	struct ahci_controller_irq *irq = data;
677170268Sdarrenr	struct ahci_controller *ctlr = irq->ctlr;
678170268Sdarrenr	u_int32_t is, ise = 0;
679170268Sdarrenr	void *arg;
680170268Sdarrenr	int unit;
681170268Sdarrenr
682170268Sdarrenr	if (irq->mode == AHCI_IRQ_MODE_ALL) {
683255332Scy		unit = 0;
684170268Sdarrenr		if (ctlr->ccc)
685255332Scy			is = ctlr->ichannels;
686170268Sdarrenr		else
687170268Sdarrenr			is = ATA_INL(ctlr->r_mem, AHCI_IS);
688170268Sdarrenr	} else {	/* AHCI_IRQ_MODE_AFTER */
689170268Sdarrenr		unit = irq->r_irq_rid - 1;
690170268Sdarrenr		is = ATA_INL(ctlr->r_mem, AHCI_IS);
691170268Sdarrenr	}
692170268Sdarrenr	/* CCC interrupt is edge triggered. */
693170268Sdarrenr	if (ctlr->ccc)
694170268Sdarrenr		ise = 1 << ctlr->cccv;
695170268Sdarrenr	/* Some controllers have edge triggered IS. */
696255332Scy	if (ctlr->quirks & AHCI_Q_EDGEIS)
697255332Scy		ise |= is;
698255332Scy	if (ise != 0)
699170268Sdarrenr		ATA_OUTL(ctlr->r_mem, AHCI_IS, ise);
700170268Sdarrenr	for (; unit < ctlr->channels; unit++) {
701170268Sdarrenr		if ((is & (1 << unit)) != 0 &&
702170268Sdarrenr		    (arg = ctlr->interrupt[unit].argument)) {
703170268Sdarrenr				ctlr->interrupt[unit].function(arg);
704170268Sdarrenr		}
705170268Sdarrenr	}
706170268Sdarrenr	/* AHCI declares level triggered IS. */
707170268Sdarrenr	if (!(ctlr->quirks & AHCI_Q_EDGEIS))
708170268Sdarrenr		ATA_OUTL(ctlr->r_mem, AHCI_IS, is);
709170268Sdarrenr}
710170268Sdarrenr
711170268Sdarrenr/*
712170268Sdarrenr * Simplified interrupt handler for multivector MSI mode.
713170268Sdarrenr */
714170268Sdarrenrstatic void
715170268Sdarrenrahci_intr_one(void *data)
716170268Sdarrenr{
717170268Sdarrenr	struct ahci_controller_irq *irq = data;
718170268Sdarrenr	struct ahci_controller *ctlr = irq->ctlr;
719170268Sdarrenr	void *arg;
720170268Sdarrenr	int unit;
721170268Sdarrenr
722170268Sdarrenr	unit = irq->r_irq_rid - 1;
723170268Sdarrenr	/* Some controllers have edge triggered IS. */
724170268Sdarrenr	if (ctlr->quirks & AHCI_Q_EDGEIS)
725170268Sdarrenr		ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
726170268Sdarrenr	if ((arg = ctlr->interrupt[unit].argument))
727170268Sdarrenr	    ctlr->interrupt[unit].function(arg);
728170268Sdarrenr	/* AHCI declares level triggered IS. */
729255332Scy	if (!(ctlr->quirks & AHCI_Q_EDGEIS))
730170268Sdarrenr		ATA_OUTL(ctlr->r_mem, AHCI_IS, 1 << unit);
731255332Scy}
732170268Sdarrenr
733170268Sdarrenrstatic struct resource *
734170268Sdarrenrahci_alloc_resource(device_t dev, device_t child, int type, int *rid,
735170268Sdarrenr		       u_long start, u_long end, u_long count, u_int flags)
736170268Sdarrenr{
737170268Sdarrenr	struct ahci_controller *ctlr = device_get_softc(dev);
738170268Sdarrenr	int unit = ((struct ahci_channel *)device_get_softc(child))->unit;
739170268Sdarrenr	struct resource *res = NULL;
740170268Sdarrenr	int offset = AHCI_OFFSET + (unit << 7);
741255332Scy	long st;
742170268Sdarrenr
743255332Scy	switch (type) {
744255332Scy	case SYS_RES_MEMORY:
745255332Scy		st = rman_get_start(ctlr->r_mem);
746255332Scy		res = rman_reserve_resource(&ctlr->sc_iomem, st + offset,
747255332Scy		    st + offset + 127, 128, RF_ACTIVE, child);
748255332Scy		if (res) {
749255332Scy			bus_space_handle_t bsh;
750255332Scy			bus_space_tag_t bst;
751255332Scy			bsh = rman_get_bushandle(ctlr->r_mem);
752170268Sdarrenr			bst = rman_get_bustag(ctlr->r_mem);
753255332Scy			bus_space_subregion(bst, bsh, offset, 128, &bsh);
754170268Sdarrenr			rman_set_bushandle(res, bsh);
755170268Sdarrenr			rman_set_bustag(res, bst);
756170268Sdarrenr		}
757170268Sdarrenr		break;
758170268Sdarrenr	case SYS_RES_IRQ:
759170268Sdarrenr		if (*rid == ATA_IRQ_RID)
760170268Sdarrenr			res = ctlr->irqs[0].r_irq;
761170268Sdarrenr		break;
762170268Sdarrenr	}
763170268Sdarrenr	return (res);
764170268Sdarrenr}
765170268Sdarrenr
766255332Scystatic int
767255332Scyahci_release_resource(device_t dev, device_t child, int type, int rid,
768255332Scy			 struct resource *r)
769255332Scy{
770255332Scy
771255332Scy	switch (type) {
772255332Scy	case SYS_RES_MEMORY:
773255332Scy		rman_release_resource(r);
774255332Scy		return (0);
775255332Scy	case SYS_RES_IRQ:
776255332Scy		if (rid != ATA_IRQ_RID)
777255332Scy			return ENOENT;
778255332Scy		return (0);
779255332Scy	}
780255332Scy	return (EINVAL);
781255332Scy}
782255332Scy
783255332Scystatic int
784255332Scyahci_setup_intr(device_t dev, device_t child, struct resource *irq,
785255332Scy		   int flags, driver_filter_t *filter, driver_intr_t *function,
786255332Scy		   void *argument, void **cookiep)
787255332Scy{
788255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
789255332Scy	int unit = (intptr_t)device_get_ivars(child);
790255332Scy
791255332Scy	if (filter != NULL) {
792255332Scy		printf("ahci.c: we cannot use a filter here\n");
793255332Scy		return (EINVAL);
794255332Scy	}
795255332Scy	ctlr->interrupt[unit].function = function;
796255332Scy	ctlr->interrupt[unit].argument = argument;
797255332Scy	return (0);
798255332Scy}
799255332Scy
800255332Scystatic int
801255332Scyahci_teardown_intr(device_t dev, device_t child, struct resource *irq,
802255332Scy		      void *cookie)
803255332Scy{
804255332Scy	struct ahci_controller *ctlr = device_get_softc(dev);
805255332Scy	int unit = (intptr_t)device_get_ivars(child);
806255332Scy
807255332Scy	ctlr->interrupt[unit].function = NULL;
808255332Scy	ctlr->interrupt[unit].argument = NULL;
809255332Scy	return (0);
810255332Scy}
811255332Scy
812255332Scystatic int
813255332Scyahci_print_child(device_t dev, device_t child)
814255332Scy{
815255332Scy	int retval;
816255332Scy
817255332Scy	retval = bus_print_child_header(dev, child);
818255332Scy	retval += printf(" at channel %d",
819255332Scy	    (int)(intptr_t)device_get_ivars(child));
820255332Scy	retval += bus_print_child_footer(dev, child);
821255332Scy
822	return (retval);
823}
824
825static int
826ahci_child_location_str(device_t dev, device_t child, char *buf,
827    size_t buflen)
828{
829
830	snprintf(buf, buflen, "channel=%d",
831	    (int)(intptr_t)device_get_ivars(child));
832	return (0);
833}
834
835devclass_t ahci_devclass;
836static device_method_t ahci_methods[] = {
837	DEVMETHOD(device_probe,     ahci_probe),
838	DEVMETHOD(device_attach,    ahci_attach),
839	DEVMETHOD(device_detach,    ahci_detach),
840	DEVMETHOD(device_suspend,   ahci_suspend),
841	DEVMETHOD(device_resume,    ahci_resume),
842	DEVMETHOD(bus_print_child,  ahci_print_child),
843	DEVMETHOD(bus_alloc_resource,       ahci_alloc_resource),
844	DEVMETHOD(bus_release_resource,     ahci_release_resource),
845	DEVMETHOD(bus_setup_intr,   ahci_setup_intr),
846	DEVMETHOD(bus_teardown_intr,ahci_teardown_intr),
847	DEVMETHOD(bus_child_location_str, ahci_child_location_str),
848	{ 0, 0 }
849};
850static driver_t ahci_driver = {
851        "ahci",
852        ahci_methods,
853        sizeof(struct ahci_controller)
854};
855DRIVER_MODULE(ahci, pci, ahci_driver, ahci_devclass, 0, 0);
856static device_method_t ahci_ata_methods[] = {
857	DEVMETHOD(device_probe,     ahci_ata_probe),
858	DEVMETHOD(device_attach,    ahci_attach),
859	DEVMETHOD(device_detach,    ahci_detach),
860	DEVMETHOD(device_suspend,   ahci_suspend),
861	DEVMETHOD(device_resume,    ahci_resume),
862	DEVMETHOD(bus_print_child,  ahci_print_child),
863	DEVMETHOD(bus_alloc_resource,       ahci_alloc_resource),
864	DEVMETHOD(bus_release_resource,     ahci_release_resource),
865	DEVMETHOD(bus_setup_intr,   ahci_setup_intr),
866	DEVMETHOD(bus_teardown_intr,ahci_teardown_intr),
867	DEVMETHOD(bus_child_location_str, ahci_child_location_str),
868	{ 0, 0 }
869};
870static driver_t ahci_ata_driver = {
871        "ahci",
872        ahci_ata_methods,
873        sizeof(struct ahci_controller)
874};
875DRIVER_MODULE(ahci, atapci, ahci_ata_driver, ahci_devclass, 0, 0);
876MODULE_VERSION(ahci, 1);
877MODULE_DEPEND(ahci, cam, 1, 1, 1);
878
879static int
880ahci_ch_probe(device_t dev)
881{
882
883	device_set_desc_copy(dev, "AHCI channel");
884	return (0);
885}
886
887static int
888ahci_ch_attach(device_t dev)
889{
890	struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
891	struct ahci_channel *ch = device_get_softc(dev);
892	struct cam_devq *devq;
893	int rid, error, i, sata_rev = 0;
894	u_int32_t version;
895	char buf[32];
896
897	ch->dev = dev;
898	ch->unit = (intptr_t)device_get_ivars(dev);
899	ch->caps = ctlr->caps;
900	ch->caps2 = ctlr->caps2;
901	ch->quirks = ctlr->quirks;
902	ch->numslots = ((ch->caps & AHCI_CAP_NCS) >> AHCI_CAP_NCS_SHIFT) + 1;
903	mtx_init(&ch->mtx, "AHCI channel lock", NULL, MTX_DEF);
904	resource_int_value(device_get_name(dev),
905	    device_get_unit(dev), "pm_level", &ch->pm_level);
906	if (ch->pm_level > 3)
907		callout_init_mtx(&ch->pm_timer, &ch->mtx, 0);
908	callout_init_mtx(&ch->reset_timer, &ch->mtx, 0);
909	/* Limit speed for my onboard JMicron external port.
910	 * It is not eSATA really. */
911	if (pci_get_devid(ctlr->dev) == 0x2363197b &&
912	    pci_get_subvendor(ctlr->dev) == 0x1043 &&
913	    pci_get_subdevice(ctlr->dev) == 0x81e4 &&
914	    ch->unit == 0)
915		sata_rev = 1;
916	if (ch->quirks & AHCI_Q_SATA2)
917		sata_rev = 2;
918	resource_int_value(device_get_name(dev),
919	    device_get_unit(dev), "sata_rev", &sata_rev);
920	for (i = 0; i < 16; i++) {
921		ch->user[i].revision = sata_rev;
922		ch->user[i].mode = 0;
923		ch->user[i].bytecount = 8192;
924		ch->user[i].tags = ch->numslots;
925		ch->user[i].caps = 0;
926		ch->curr[i] = ch->user[i];
927		if (ch->pm_level) {
928			ch->user[i].caps = CTS_SATA_CAPS_H_PMREQ |
929			    CTS_SATA_CAPS_H_APST |
930			    CTS_SATA_CAPS_D_PMREQ | CTS_SATA_CAPS_D_APST;
931		}
932		ch->user[i].caps |= CTS_SATA_CAPS_H_DMAAA |
933		    CTS_SATA_CAPS_H_AN;
934	}
935	rid = ch->unit;
936	if (!(ch->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
937	    &rid, RF_ACTIVE)))
938		return (ENXIO);
939	ahci_dmainit(dev);
940	ahci_slotsalloc(dev);
941	ahci_ch_init(dev);
942	mtx_lock(&ch->mtx);
943	rid = ATA_IRQ_RID;
944	if (!(ch->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
945	    &rid, RF_SHAREABLE | RF_ACTIVE))) {
946		device_printf(dev, "Unable to map interrupt\n");
947		error = ENXIO;
948		goto err0;
949	}
950	if ((bus_setup_intr(dev, ch->r_irq, ATA_INTR_FLAGS, NULL,
951	    ahci_ch_intr_locked, dev, &ch->ih))) {
952		device_printf(dev, "Unable to setup interrupt\n");
953		error = ENXIO;
954		goto err1;
955	}
956	ch->chcaps = ATA_INL(ch->r_mem, AHCI_P_CMD);
957	version = ATA_INL(ctlr->r_mem, AHCI_VS);
958	if (version < 0x00010020 && (ctlr->caps & AHCI_CAP_FBSS))
959		ch->chcaps |= AHCI_P_CMD_FBSCP;
960	if (bootverbose) {
961		device_printf(dev, "Caps:%s%s%s%s%s\n",
962		    (ch->chcaps & AHCI_P_CMD_HPCP) ? " HPCP":"",
963		    (ch->chcaps & AHCI_P_CMD_MPSP) ? " MPSP":"",
964		    (ch->chcaps & AHCI_P_CMD_CPD) ? " CPD":"",
965		    (ch->chcaps & AHCI_P_CMD_ESP) ? " ESP":"",
966		    (ch->chcaps & AHCI_P_CMD_FBSCP) ? " FBSCP":"");
967	}
968	/* Create the device queue for our SIM. */
969	devq = cam_simq_alloc(ch->numslots);
970	if (devq == NULL) {
971		device_printf(dev, "Unable to allocate simq\n");
972		error = ENOMEM;
973		goto err1;
974	}
975	/* Construct SIM entry */
976	ch->sim = cam_sim_alloc(ahciaction, ahcipoll, "ahcich", ch,
977	    device_get_unit(dev), &ch->mtx,
978	    min(2, ch->numslots),
979	    (ch->caps & AHCI_CAP_SNCQ) ? ch->numslots : 0,
980	    devq);
981	if (ch->sim == NULL) {
982		cam_simq_free(devq);
983		device_printf(dev, "unable to allocate sim\n");
984		error = ENOMEM;
985		goto err1;
986	}
987	if (xpt_bus_register(ch->sim, dev, 0) != CAM_SUCCESS) {
988		device_printf(dev, "unable to register xpt bus\n");
989		error = ENXIO;
990		goto err2;
991	}
992	if (xpt_create_path(&ch->path, /*periph*/NULL, cam_sim_path(ch->sim),
993	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
994		device_printf(dev, "unable to create path\n");
995		error = ENXIO;
996		goto err3;
997	}
998	if (ch->pm_level > 3) {
999		callout_reset(&ch->pm_timer,
1000		    (ch->pm_level == 4) ? hz / 1000 : hz / 8,
1001		    ahci_ch_pm, dev);
1002	}
1003	mtx_unlock(&ch->mtx);
1004	if ((ch->caps & AHCI_CAP_EMS) &&
1005	    (ctlr->capsem & AHCI_EM_LED)) {
1006		for (i = 0; i < AHCI_NUM_LEDS; i++) {
1007			ch->leds[i].dev = dev;
1008			ch->leds[i].num = i;
1009		}
1010		if ((ctlr->capsem & AHCI_EM_ALHD) == 0) {
1011			snprintf(buf, sizeof(buf), "%s.act",
1012			    device_get_nameunit(dev));
1013			ch->leds[0].led = led_create(ahci_ch_led,
1014			    &ch->leds[0], buf);
1015		}
1016		snprintf(buf, sizeof(buf), "%s.locate",
1017		    device_get_nameunit(dev));
1018		ch->leds[1].led = led_create(ahci_ch_led, &ch->leds[1], buf);
1019		snprintf(buf, sizeof(buf), "%s.fault",
1020		    device_get_nameunit(dev));
1021		ch->leds[2].led = led_create(ahci_ch_led, &ch->leds[2], buf);
1022	}
1023	return (0);
1024
1025err3:
1026	xpt_bus_deregister(cam_sim_path(ch->sim));
1027err2:
1028	cam_sim_free(ch->sim, /*free_devq*/TRUE);
1029err1:
1030	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
1031err0:
1032	bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
1033	mtx_unlock(&ch->mtx);
1034	mtx_destroy(&ch->mtx);
1035	return (error);
1036}
1037
1038static int
1039ahci_ch_detach(device_t dev)
1040{
1041	struct ahci_channel *ch = device_get_softc(dev);
1042	int i;
1043
1044	for (i = 0; i < AHCI_NUM_LEDS; i++) {
1045		if (ch->leds[i].led)
1046			led_destroy(ch->leds[i].led);
1047	}
1048	mtx_lock(&ch->mtx);
1049	xpt_async(AC_LOST_DEVICE, ch->path, NULL);
1050	/* Forget about reset. */
1051	if (ch->resetting) {
1052		ch->resetting = 0;
1053		xpt_release_simq(ch->sim, TRUE);
1054	}
1055	xpt_free_path(ch->path);
1056	xpt_bus_deregister(cam_sim_path(ch->sim));
1057	cam_sim_free(ch->sim, /*free_devq*/TRUE);
1058	mtx_unlock(&ch->mtx);
1059
1060	if (ch->pm_level > 3)
1061		callout_drain(&ch->pm_timer);
1062	callout_drain(&ch->reset_timer);
1063	bus_teardown_intr(dev, ch->r_irq, ch->ih);
1064	bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ch->r_irq);
1065
1066	ahci_ch_deinit(dev);
1067	ahci_slotsfree(dev);
1068	ahci_dmafini(dev);
1069
1070	bus_release_resource(dev, SYS_RES_MEMORY, ch->unit, ch->r_mem);
1071	mtx_destroy(&ch->mtx);
1072	return (0);
1073}
1074
1075static int
1076ahci_ch_init(device_t dev)
1077{
1078	struct ahci_channel *ch = device_get_softc(dev);
1079	uint64_t work;
1080
1081	/* Disable port interrupts */
1082	ATA_OUTL(ch->r_mem, AHCI_P_IE, 0);
1083	/* Setup work areas */
1084	work = ch->dma.work_bus + AHCI_CL_OFFSET;
1085	ATA_OUTL(ch->r_mem, AHCI_P_CLB, work & 0xffffffff);
1086	ATA_OUTL(ch->r_mem, AHCI_P_CLBU, work >> 32);
1087	work = ch->dma.rfis_bus;
1088	ATA_OUTL(ch->r_mem, AHCI_P_FB, work & 0xffffffff);
1089	ATA_OUTL(ch->r_mem, AHCI_P_FBU, work >> 32);
1090	/* Activate the channel and power/spin up device */
1091	ATA_OUTL(ch->r_mem, AHCI_P_CMD,
1092	     (AHCI_P_CMD_ACTIVE | AHCI_P_CMD_POD | AHCI_P_CMD_SUD |
1093	     ((ch->pm_level == 2 || ch->pm_level == 3) ? AHCI_P_CMD_ALPE : 0) |
1094	     ((ch->pm_level > 2) ? AHCI_P_CMD_ASP : 0 )));
1095	ahci_start_fr(dev);
1096	ahci_start(dev, 1);
1097	return (0);
1098}
1099
1100static int
1101ahci_ch_deinit(device_t dev)
1102{
1103	struct ahci_channel *ch = device_get_softc(dev);
1104
1105	/* Disable port interrupts. */
1106	ATA_OUTL(ch->r_mem, AHCI_P_IE, 0);
1107	/* Reset command register. */
1108	ahci_stop(dev);
1109	ahci_stop_fr(dev);
1110	ATA_OUTL(ch->r_mem, AHCI_P_CMD, 0);
1111	/* Allow everything, including partial and slumber modes. */
1112	ATA_OUTL(ch->r_mem, AHCI_P_SCTL, 0);
1113	/* Request slumber mode transition and give some time to get there. */
1114	ATA_OUTL(ch->r_mem, AHCI_P_CMD, AHCI_P_CMD_SLUMBER);
1115	DELAY(100);
1116	/* Disable PHY. */
1117	ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE);
1118	return (0);
1119}
1120
1121static int
1122ahci_ch_suspend(device_t dev)
1123{
1124	struct ahci_channel *ch = device_get_softc(dev);
1125
1126	mtx_lock(&ch->mtx);
1127	xpt_freeze_simq(ch->sim, 1);
1128	/* Forget about reset. */
1129	if (ch->resetting) {
1130		ch->resetting = 0;
1131		callout_stop(&ch->reset_timer);
1132		xpt_release_simq(ch->sim, TRUE);
1133	}
1134	while (ch->oslots)
1135		msleep(ch, &ch->mtx, PRIBIO, "ahcisusp", hz/100);
1136	ahci_ch_deinit(dev);
1137	mtx_unlock(&ch->mtx);
1138	return (0);
1139}
1140
1141static int
1142ahci_ch_resume(device_t dev)
1143{
1144	struct ahci_channel *ch = device_get_softc(dev);
1145
1146	mtx_lock(&ch->mtx);
1147	ahci_ch_init(dev);
1148	ahci_reset(dev);
1149	xpt_release_simq(ch->sim, TRUE);
1150	mtx_unlock(&ch->mtx);
1151	return (0);
1152}
1153
1154devclass_t ahcich_devclass;
1155static device_method_t ahcich_methods[] = {
1156	DEVMETHOD(device_probe,     ahci_ch_probe),
1157	DEVMETHOD(device_attach,    ahci_ch_attach),
1158	DEVMETHOD(device_detach,    ahci_ch_detach),
1159	DEVMETHOD(device_suspend,   ahci_ch_suspend),
1160	DEVMETHOD(device_resume,    ahci_ch_resume),
1161	{ 0, 0 }
1162};
1163static driver_t ahcich_driver = {
1164        "ahcich",
1165        ahcich_methods,
1166        sizeof(struct ahci_channel)
1167};
1168DRIVER_MODULE(ahcich, ahci, ahcich_driver, ahcich_devclass, 0, 0);
1169
1170static void
1171ahci_ch_setleds(device_t dev)
1172{
1173	struct ahci_channel *ch;
1174	struct ahci_controller *ctlr;
1175	size_t buf;
1176	int i, timeout;
1177	int16_t val;
1178
1179	ctlr = device_get_softc(device_get_parent(dev));
1180	ch = device_get_softc(dev);
1181
1182	val = 0;
1183	for (i = 0; i < AHCI_NUM_LEDS; i++)
1184		val |= ch->leds[i].state << (i * 3);
1185
1186	buf = (ctlr->emloc & 0xffff0000) >> 14;
1187	mtx_lock(&ctlr->em_mtx);
1188	timeout = 1000;
1189	while (ATA_INL(ctlr->r_mem, AHCI_EM_CTL) & (AHCI_EM_TM | AHCI_EM_RST) &&
1190	    --timeout > 0)
1191		DELAY(1000);
1192	if (timeout == 0)
1193		device_printf(dev, "EM timeout\n");
1194	ATA_OUTL(ctlr->r_mem, buf, (1 << 8) | (0 << 16) | (0 << 24));
1195	ATA_OUTL(ctlr->r_mem, buf + 4, ch->unit | (val << 16));
1196	ATA_OUTL(ctlr->r_mem, AHCI_EM_CTL, AHCI_EM_TM);
1197	mtx_unlock(&ctlr->em_mtx);
1198}
1199
1200static void
1201ahci_ch_led(void *priv, int onoff)
1202{
1203	struct ahci_led *led;
1204
1205	led = (struct ahci_led *)priv;
1206
1207	led->state = onoff;
1208	ahci_ch_setleds(led->dev);
1209}
1210
1211struct ahci_dc_cb_args {
1212	bus_addr_t maddr;
1213	int error;
1214};
1215
1216static void
1217ahci_dmainit(device_t dev)
1218{
1219	struct ahci_channel *ch = device_get_softc(dev);
1220	struct ahci_dc_cb_args dcba;
1221	size_t rfsize;
1222
1223	if (ch->caps & AHCI_CAP_64BIT)
1224		ch->dma.max_address = BUS_SPACE_MAXADDR;
1225	else
1226		ch->dma.max_address = BUS_SPACE_MAXADDR_32BIT;
1227	/* Command area. */
1228	if (bus_dma_tag_create(bus_get_dma_tag(dev), 1024, 0,
1229	    ch->dma.max_address, BUS_SPACE_MAXADDR,
1230	    NULL, NULL, AHCI_WORK_SIZE, 1, AHCI_WORK_SIZE,
1231	    0, NULL, NULL, &ch->dma.work_tag))
1232		goto error;
1233	if (bus_dmamem_alloc(ch->dma.work_tag, (void **)&ch->dma.work, 0,
1234	    &ch->dma.work_map))
1235		goto error;
1236	if (bus_dmamap_load(ch->dma.work_tag, ch->dma.work_map, ch->dma.work,
1237	    AHCI_WORK_SIZE, ahci_dmasetupc_cb, &dcba, 0) || dcba.error) {
1238		bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
1239		goto error;
1240	}
1241	ch->dma.work_bus = dcba.maddr;
1242	/* FIS receive area. */
1243	if (ch->chcaps & AHCI_P_CMD_FBSCP)
1244	    rfsize = 4096;
1245	else
1246	    rfsize = 256;
1247	if (bus_dma_tag_create(bus_get_dma_tag(dev), rfsize, 0,
1248	    ch->dma.max_address, BUS_SPACE_MAXADDR,
1249	    NULL, NULL, rfsize, 1, rfsize,
1250	    0, NULL, NULL, &ch->dma.rfis_tag))
1251		goto error;
1252	if (bus_dmamem_alloc(ch->dma.rfis_tag, (void **)&ch->dma.rfis, 0,
1253	    &ch->dma.rfis_map))
1254		goto error;
1255	if (bus_dmamap_load(ch->dma.rfis_tag, ch->dma.rfis_map, ch->dma.rfis,
1256	    rfsize, ahci_dmasetupc_cb, &dcba, 0) || dcba.error) {
1257		bus_dmamem_free(ch->dma.rfis_tag, ch->dma.rfis, ch->dma.rfis_map);
1258		goto error;
1259	}
1260	ch->dma.rfis_bus = dcba.maddr;
1261	/* Data area. */
1262	if (bus_dma_tag_create(bus_get_dma_tag(dev), 2, 0,
1263	    ch->dma.max_address, BUS_SPACE_MAXADDR,
1264	    NULL, NULL,
1265	    AHCI_SG_ENTRIES * PAGE_SIZE * ch->numslots,
1266	    AHCI_SG_ENTRIES, AHCI_PRD_MAX,
1267	    0, busdma_lock_mutex, &ch->mtx, &ch->dma.data_tag)) {
1268		goto error;
1269	}
1270	return;
1271
1272error:
1273	device_printf(dev, "WARNING - DMA initialization failed\n");
1274	ahci_dmafini(dev);
1275}
1276
1277static void
1278ahci_dmasetupc_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int error)
1279{
1280	struct ahci_dc_cb_args *dcba = (struct ahci_dc_cb_args *)xsc;
1281
1282	if (!(dcba->error = error))
1283		dcba->maddr = segs[0].ds_addr;
1284}
1285
1286static void
1287ahci_dmafini(device_t dev)
1288{
1289	struct ahci_channel *ch = device_get_softc(dev);
1290
1291	if (ch->dma.data_tag) {
1292		bus_dma_tag_destroy(ch->dma.data_tag);
1293		ch->dma.data_tag = NULL;
1294	}
1295	if (ch->dma.rfis_bus) {
1296		bus_dmamap_unload(ch->dma.rfis_tag, ch->dma.rfis_map);
1297		bus_dmamem_free(ch->dma.rfis_tag, ch->dma.rfis, ch->dma.rfis_map);
1298		ch->dma.rfis_bus = 0;
1299		ch->dma.rfis_map = NULL;
1300		ch->dma.rfis = NULL;
1301	}
1302	if (ch->dma.work_bus) {
1303		bus_dmamap_unload(ch->dma.work_tag, ch->dma.work_map);
1304		bus_dmamem_free(ch->dma.work_tag, ch->dma.work, ch->dma.work_map);
1305		ch->dma.work_bus = 0;
1306		ch->dma.work_map = NULL;
1307		ch->dma.work = NULL;
1308	}
1309	if (ch->dma.work_tag) {
1310		bus_dma_tag_destroy(ch->dma.work_tag);
1311		ch->dma.work_tag = NULL;
1312	}
1313}
1314
1315static void
1316ahci_slotsalloc(device_t dev)
1317{
1318	struct ahci_channel *ch = device_get_softc(dev);
1319	int i;
1320
1321	/* Alloc and setup command/dma slots */
1322	bzero(ch->slot, sizeof(ch->slot));
1323	for (i = 0; i < ch->numslots; i++) {
1324		struct ahci_slot *slot = &ch->slot[i];
1325
1326		slot->dev = dev;
1327		slot->slot = i;
1328		slot->state = AHCI_SLOT_EMPTY;
1329		slot->ccb = NULL;
1330		callout_init_mtx(&slot->timeout, &ch->mtx, 0);
1331
1332		if (bus_dmamap_create(ch->dma.data_tag, 0, &slot->dma.data_map))
1333			device_printf(ch->dev, "FAILURE - create data_map\n");
1334	}
1335}
1336
1337static void
1338ahci_slotsfree(device_t dev)
1339{
1340	struct ahci_channel *ch = device_get_softc(dev);
1341	int i;
1342
1343	/* Free all dma slots */
1344	for (i = 0; i < ch->numslots; i++) {
1345		struct ahci_slot *slot = &ch->slot[i];
1346
1347		callout_drain(&slot->timeout);
1348		if (slot->dma.data_map) {
1349			bus_dmamap_destroy(ch->dma.data_tag, slot->dma.data_map);
1350			slot->dma.data_map = NULL;
1351		}
1352	}
1353}
1354
1355static int
1356ahci_phy_check_events(device_t dev, u_int32_t serr)
1357{
1358	struct ahci_channel *ch = device_get_softc(dev);
1359
1360	if (((ch->pm_level == 0) && (serr & ATA_SE_PHY_CHANGED)) ||
1361	    ((ch->pm_level != 0 || ch->listening) && (serr & ATA_SE_EXCHANGED))) {
1362		u_int32_t status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
1363		union ccb *ccb;
1364
1365		if (bootverbose) {
1366			if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE)
1367				device_printf(dev, "CONNECT requested\n");
1368			else
1369				device_printf(dev, "DISCONNECT requested\n");
1370		}
1371		ahci_reset(dev);
1372		if ((ccb = xpt_alloc_ccb_nowait()) == NULL)
1373			return (0);
1374		if (xpt_create_path(&ccb->ccb_h.path, NULL,
1375		    cam_sim_path(ch->sim),
1376		    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1377			xpt_free_ccb(ccb);
1378			return (0);
1379		}
1380		xpt_rescan(ccb);
1381		return (1);
1382	}
1383	return (0);
1384}
1385
1386static void
1387ahci_cpd_check_events(device_t dev)
1388{
1389	struct ahci_channel *ch = device_get_softc(dev);
1390	u_int32_t status;
1391	union ccb *ccb;
1392
1393	if (ch->pm_level == 0)
1394		return;
1395
1396	status = ATA_INL(ch->r_mem, AHCI_P_CMD);
1397	if ((status & AHCI_P_CMD_CPD) == 0)
1398		return;
1399
1400	if (bootverbose) {
1401		if (status & AHCI_P_CMD_CPS) {
1402			device_printf(dev, "COLD CONNECT requested\n");
1403		} else
1404			device_printf(dev, "COLD DISCONNECT requested\n");
1405	}
1406	ahci_reset(dev);
1407	if ((ccb = xpt_alloc_ccb_nowait()) == NULL)
1408		return;
1409	if (xpt_create_path(&ccb->ccb_h.path, NULL, cam_sim_path(ch->sim),
1410	    CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
1411		xpt_free_ccb(ccb);
1412		return;
1413	}
1414	xpt_rescan(ccb);
1415}
1416
1417static void
1418ahci_notify_events(device_t dev, u_int32_t status)
1419{
1420	struct ahci_channel *ch = device_get_softc(dev);
1421	struct cam_path *dpath;
1422	int i;
1423
1424	if (ch->caps & AHCI_CAP_SSNTF)
1425		ATA_OUTL(ch->r_mem, AHCI_P_SNTF, status);
1426	if (bootverbose)
1427		device_printf(dev, "SNTF 0x%04x\n", status);
1428	for (i = 0; i < 16; i++) {
1429		if ((status & (1 << i)) == 0)
1430			continue;
1431		if (xpt_create_path(&dpath, NULL,
1432		    xpt_path_path_id(ch->path), i, 0) == CAM_REQ_CMP) {
1433			xpt_async(AC_SCSI_AEN, dpath, NULL);
1434			xpt_free_path(dpath);
1435		}
1436	}
1437}
1438
1439static void
1440ahci_ch_intr_locked(void *data)
1441{
1442	device_t dev = (device_t)data;
1443	struct ahci_channel *ch = device_get_softc(dev);
1444
1445	mtx_lock(&ch->mtx);
1446	ahci_ch_intr(data);
1447	mtx_unlock(&ch->mtx);
1448}
1449
1450static void
1451ahci_ch_pm(void *arg)
1452{
1453	device_t dev = (device_t)arg;
1454	struct ahci_channel *ch = device_get_softc(dev);
1455	uint32_t work;
1456
1457	if (ch->numrslots != 0)
1458		return;
1459	work = ATA_INL(ch->r_mem, AHCI_P_CMD);
1460	if (ch->pm_level == 4)
1461		work |= AHCI_P_CMD_PARTIAL;
1462	else
1463		work |= AHCI_P_CMD_SLUMBER;
1464	ATA_OUTL(ch->r_mem, AHCI_P_CMD, work);
1465}
1466
1467static void
1468ahci_ch_intr(void *data)
1469{
1470	device_t dev = (device_t)data;
1471	struct ahci_channel *ch = device_get_softc(dev);
1472	uint32_t istatus, sstatus, cstatus, serr = 0, sntf = 0, ok, err;
1473	enum ahci_err_type et;
1474	int i, ccs, port, reset = 0;
1475
1476	/* Read and clear interrupt statuses. */
1477	istatus = ATA_INL(ch->r_mem, AHCI_P_IS);
1478	if (istatus == 0)
1479		return;
1480	ATA_OUTL(ch->r_mem, AHCI_P_IS, istatus);
1481	/* Read command statuses. */
1482	sstatus = ATA_INL(ch->r_mem, AHCI_P_SACT);
1483	cstatus = ATA_INL(ch->r_mem, AHCI_P_CI);
1484	if (istatus & AHCI_P_IX_SDB) {
1485		if (ch->caps & AHCI_CAP_SSNTF)
1486			sntf = ATA_INL(ch->r_mem, AHCI_P_SNTF);
1487		else if (ch->fbs_enabled) {
1488			u_int8_t *fis = ch->dma.rfis + 0x58;
1489
1490			for (i = 0; i < 16; i++) {
1491				if (fis[1] & 0x80) {
1492					fis[1] &= 0x7f;
1493	    				sntf |= 1 << i;
1494	    			}
1495	    			fis += 256;
1496	    		}
1497		} else {
1498			u_int8_t *fis = ch->dma.rfis + 0x58;
1499
1500			if (fis[1] & 0x80)
1501				sntf = (1 << (fis[1] & 0x0f));
1502		}
1503	}
1504	/* Process PHY events */
1505	if (istatus & (AHCI_P_IX_PC | AHCI_P_IX_PRC | AHCI_P_IX_OF |
1506	    AHCI_P_IX_IF | AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
1507		serr = ATA_INL(ch->r_mem, AHCI_P_SERR);
1508		if (serr) {
1509			ATA_OUTL(ch->r_mem, AHCI_P_SERR, serr);
1510			reset = ahci_phy_check_events(dev, serr);
1511		}
1512	}
1513	/* Process cold presence detection events */
1514	if ((istatus & AHCI_P_IX_CPD) && !reset)
1515		ahci_cpd_check_events(dev);
1516	/* Process command errors */
1517	if (istatus & (AHCI_P_IX_OF | AHCI_P_IX_IF |
1518	    AHCI_P_IX_HBD | AHCI_P_IX_HBF | AHCI_P_IX_TFE)) {
1519		ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
1520		    >> AHCI_P_CMD_CCS_SHIFT;
1521//device_printf(dev, "%s ERROR is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x fbs %08x ccs %d\n",
1522//    __func__, istatus, cstatus, sstatus, ch->rslots, ATA_INL(ch->r_mem, AHCI_P_TFD),
1523//    serr, ATA_INL(ch->r_mem, AHCI_P_FBS), ccs);
1524		port = -1;
1525		if (ch->fbs_enabled) {
1526			uint32_t fbs = ATA_INL(ch->r_mem, AHCI_P_FBS);
1527			if (fbs & AHCI_P_FBS_SDE) {
1528				port = (fbs & AHCI_P_FBS_DWE)
1529				    >> AHCI_P_FBS_DWE_SHIFT;
1530			} else {
1531				for (i = 0; i < 16; i++) {
1532					if (ch->numrslotspd[i] == 0)
1533						continue;
1534					if (port == -1)
1535						port = i;
1536					else if (port != i) {
1537						port = -2;
1538						break;
1539					}
1540				}
1541			}
1542		}
1543		err = ch->rslots & (cstatus | sstatus);
1544	} else {
1545		ccs = 0;
1546		err = 0;
1547		port = -1;
1548	}
1549	/* Complete all successfull commands. */
1550	ok = ch->rslots & ~(cstatus | sstatus);
1551	for (i = 0; i < ch->numslots; i++) {
1552		if ((ok >> i) & 1)
1553			ahci_end_transaction(&ch->slot[i], AHCI_ERR_NONE);
1554	}
1555	/* On error, complete the rest of commands with error statuses. */
1556	if (err) {
1557		if (ch->frozen) {
1558			union ccb *fccb = ch->frozen;
1559			ch->frozen = NULL;
1560			fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
1561			if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
1562				xpt_freeze_devq(fccb->ccb_h.path, 1);
1563				fccb->ccb_h.status |= CAM_DEV_QFRZN;
1564			}
1565			xpt_done(fccb);
1566		}
1567		for (i = 0; i < ch->numslots; i++) {
1568			/* XXX: reqests in loading state. */
1569			if (((err >> i) & 1) == 0)
1570				continue;
1571			if (port >= 0 &&
1572			    ch->slot[i].ccb->ccb_h.target_id != port)
1573				continue;
1574			if (istatus & AHCI_P_IX_TFE) {
1575			    if (port != -2) {
1576				/* Task File Error */
1577				if (ch->numtslotspd[
1578				    ch->slot[i].ccb->ccb_h.target_id] == 0) {
1579					/* Untagged operation. */
1580					if (i == ccs)
1581						et = AHCI_ERR_TFE;
1582					else
1583						et = AHCI_ERR_INNOCENT;
1584				} else {
1585					/* Tagged operation. */
1586					et = AHCI_ERR_NCQ;
1587				}
1588			    } else {
1589				et = AHCI_ERR_TFE;
1590				ch->fatalerr = 1;
1591			    }
1592			} else if (istatus & AHCI_P_IX_IF) {
1593				if (ch->numtslots == 0 && i != ccs && port != -2)
1594					et = AHCI_ERR_INNOCENT;
1595				else
1596					et = AHCI_ERR_SATA;
1597			} else
1598				et = AHCI_ERR_INVALID;
1599			ahci_end_transaction(&ch->slot[i], et);
1600		}
1601		/*
1602		 * We can't reinit port if there are some other
1603		 * commands active, use resume to complete them.
1604		 */
1605		if (ch->rslots != 0 && !ch->recoverycmd)
1606			ATA_OUTL(ch->r_mem, AHCI_P_FBS, AHCI_P_FBS_EN | AHCI_P_FBS_DEC);
1607	}
1608	/* Process NOTIFY events */
1609	if (sntf)
1610		ahci_notify_events(dev, sntf);
1611}
1612
1613/* Must be called with channel locked. */
1614static int
1615ahci_check_collision(device_t dev, union ccb *ccb)
1616{
1617	struct ahci_channel *ch = device_get_softc(dev);
1618	int t = ccb->ccb_h.target_id;
1619
1620	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1621	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1622		/* Tagged command while we have no supported tag free. */
1623		if (((~ch->oslots) & (0xffffffff >> (32 -
1624		    ch->curr[t].tags))) == 0)
1625			return (1);
1626		/* If we have FBS */
1627		if (ch->fbs_enabled) {
1628			/* Tagged command while untagged are active. */
1629			if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] == 0)
1630				return (1);
1631		} else {
1632			/* Tagged command while untagged are active. */
1633			if (ch->numrslots != 0 && ch->numtslots == 0)
1634				return (1);
1635			/* Tagged command while tagged to other target is active. */
1636			if (ch->numtslots != 0 &&
1637			    ch->taggedtarget != ccb->ccb_h.target_id)
1638				return (1);
1639		}
1640	} else {
1641		/* If we have FBS */
1642		if (ch->fbs_enabled) {
1643			/* Untagged command while tagged are active. */
1644			if (ch->numrslotspd[t] != 0 && ch->numtslotspd[t] != 0)
1645				return (1);
1646		} else {
1647			/* Untagged command while tagged are active. */
1648			if (ch->numrslots != 0 && ch->numtslots != 0)
1649				return (1);
1650		}
1651	}
1652	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1653	    (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT))) {
1654		/* Atomic command while anything active. */
1655		if (ch->numrslots != 0)
1656			return (1);
1657	}
1658       /* We have some atomic command running. */
1659       if (ch->aslots != 0)
1660               return (1);
1661	return (0);
1662}
1663
1664/* Must be called with channel locked. */
1665static void
1666ahci_begin_transaction(device_t dev, union ccb *ccb)
1667{
1668	struct ahci_channel *ch = device_get_softc(dev);
1669	struct ahci_slot *slot;
1670	int tag, tags;
1671
1672	/* Choose empty slot. */
1673	tags = ch->numslots;
1674	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1675	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA))
1676		tags = ch->curr[ccb->ccb_h.target_id].tags;
1677	tag = ch->lastslot;
1678	while (1) {
1679		if (tag >= tags)
1680			tag = 0;
1681		if (ch->slot[tag].state == AHCI_SLOT_EMPTY)
1682			break;
1683		tag++;
1684	};
1685	ch->lastslot = tag;
1686	/* Occupy chosen slot. */
1687	slot = &ch->slot[tag];
1688	slot->ccb = ccb;
1689	/* Stop PM timer. */
1690	if (ch->numrslots == 0 && ch->pm_level > 3)
1691		callout_stop(&ch->pm_timer);
1692	/* Update channel stats. */
1693	ch->oslots |= (1 << slot->slot);
1694	ch->numrslots++;
1695	ch->numrslotspd[ccb->ccb_h.target_id]++;
1696	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1697	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1698		ch->numtslots++;
1699		ch->numtslotspd[ccb->ccb_h.target_id]++;
1700		ch->taggedtarget = ccb->ccb_h.target_id;
1701	}
1702	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1703	    (ccb->ataio.cmd.flags & (CAM_ATAIO_CONTROL | CAM_ATAIO_NEEDRESULT)))
1704		ch->aslots |= (1 << slot->slot);
1705	slot->dma.nsegs = 0;
1706	/* If request moves data, setup and load SG list */
1707	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
1708		void *buf;
1709		bus_size_t size;
1710
1711		slot->state = AHCI_SLOT_LOADING;
1712		if (ccb->ccb_h.func_code == XPT_ATA_IO) {
1713			buf = ccb->ataio.data_ptr;
1714			size = ccb->ataio.dxfer_len;
1715		} else {
1716			buf = ccb->csio.data_ptr;
1717			size = ccb->csio.dxfer_len;
1718		}
1719		bus_dmamap_load(ch->dma.data_tag, slot->dma.data_map,
1720		    buf, size, ahci_dmasetprd, slot, 0);
1721	} else
1722		ahci_execute_transaction(slot);
1723}
1724
1725/* Locked by busdma engine. */
1726static void
1727ahci_dmasetprd(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
1728{
1729	struct ahci_slot *slot = arg;
1730	struct ahci_channel *ch = device_get_softc(slot->dev);
1731	struct ahci_cmd_tab *ctp;
1732	struct ahci_dma_prd *prd;
1733	int i;
1734
1735	if (error) {
1736		device_printf(slot->dev, "DMA load error\n");
1737		ahci_end_transaction(slot, AHCI_ERR_INVALID);
1738		return;
1739	}
1740	KASSERT(nsegs <= AHCI_SG_ENTRIES, ("too many DMA segment entries\n"));
1741	/* Get a piece of the workspace for this request */
1742	ctp = (struct ahci_cmd_tab *)
1743		(ch->dma.work + AHCI_CT_OFFSET + (AHCI_CT_SIZE * slot->slot));
1744	/* Fill S/G table */
1745	prd = &ctp->prd_tab[0];
1746	for (i = 0; i < nsegs; i++) {
1747		prd[i].dba = htole64(segs[i].ds_addr);
1748		prd[i].dbc = htole32((segs[i].ds_len - 1) & AHCI_PRD_MASK);
1749	}
1750	slot->dma.nsegs = nsegs;
1751	bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map,
1752	    ((slot->ccb->ccb_h.flags & CAM_DIR_IN) ?
1753	    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE));
1754	ahci_execute_transaction(slot);
1755}
1756
1757/* Must be called with channel locked. */
1758static void
1759ahci_execute_transaction(struct ahci_slot *slot)
1760{
1761	device_t dev = slot->dev;
1762	struct ahci_channel *ch = device_get_softc(dev);
1763	struct ahci_cmd_tab *ctp;
1764	struct ahci_cmd_list *clp;
1765	union ccb *ccb = slot->ccb;
1766	int port = ccb->ccb_h.target_id & 0x0f;
1767	int fis_size, i;
1768	uint8_t *fis = ch->dma.rfis + 0x40;
1769	uint8_t val;
1770
1771	/* Get a piece of the workspace for this request */
1772	ctp = (struct ahci_cmd_tab *)
1773		(ch->dma.work + AHCI_CT_OFFSET + (AHCI_CT_SIZE * slot->slot));
1774	/* Setup the FIS for this request */
1775	if (!(fis_size = ahci_setup_fis(dev, ctp, ccb, slot->slot))) {
1776		device_printf(ch->dev, "Setting up SATA FIS failed\n");
1777		ahci_end_transaction(slot, AHCI_ERR_INVALID);
1778		return;
1779	}
1780	/* Setup the command list entry */
1781	clp = (struct ahci_cmd_list *)
1782	    (ch->dma.work + AHCI_CL_OFFSET + (AHCI_CL_SIZE * slot->slot));
1783	clp->cmd_flags = htole16(
1784		    (ccb->ccb_h.flags & CAM_DIR_OUT ? AHCI_CMD_WRITE : 0) |
1785		    (ccb->ccb_h.func_code == XPT_SCSI_IO ?
1786		     (AHCI_CMD_ATAPI | AHCI_CMD_PREFETCH) : 0) |
1787		    (fis_size / sizeof(u_int32_t)) |
1788		    (port << 12));
1789	clp->prd_length = htole16(slot->dma.nsegs);
1790	/* Special handling for Soft Reset command. */
1791	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1792	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL)) {
1793		if (ccb->ataio.cmd.control & ATA_A_RESET) {
1794			/* Kick controller into sane state */
1795			ahci_stop(dev);
1796			ahci_clo(dev);
1797			ahci_start(dev, 0);
1798			clp->cmd_flags |= AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY;
1799		} else {
1800			/* Prepare FIS receive area for check. */
1801			for (i = 0; i < 20; i++)
1802				fis[i] = 0xff;
1803		}
1804	}
1805	clp->bytecount = 0;
1806	clp->cmd_table_phys = htole64(ch->dma.work_bus + AHCI_CT_OFFSET +
1807				  (AHCI_CT_SIZE * slot->slot));
1808	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
1809	    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1810	bus_dmamap_sync(ch->dma.rfis_tag, ch->dma.rfis_map,
1811	    BUS_DMASYNC_PREREAD);
1812	/* Set ACTIVE bit for NCQ commands. */
1813	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1814	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
1815		ATA_OUTL(ch->r_mem, AHCI_P_SACT, 1 << slot->slot);
1816	}
1817	/* If FBS is enabled, set PMP port. */
1818	if (ch->fbs_enabled) {
1819		ATA_OUTL(ch->r_mem, AHCI_P_FBS, AHCI_P_FBS_EN |
1820		    (port << AHCI_P_FBS_DEV_SHIFT));
1821	}
1822	/* Issue command to the controller. */
1823	slot->state = AHCI_SLOT_RUNNING;
1824	ch->rslots |= (1 << slot->slot);
1825	ATA_OUTL(ch->r_mem, AHCI_P_CI, (1 << slot->slot));
1826	/* Device reset commands doesn't interrupt. Poll them. */
1827	if (ccb->ccb_h.func_code == XPT_ATA_IO &&
1828	    (ccb->ataio.cmd.command == ATA_DEVICE_RESET ||
1829	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL))) {
1830		int count, timeout = ccb->ccb_h.timeout * 100;
1831		enum ahci_err_type et = AHCI_ERR_NONE;
1832
1833		for (count = 0; count < timeout; count++) {
1834			DELAY(10);
1835			if (!(ATA_INL(ch->r_mem, AHCI_P_CI) & (1 << slot->slot)))
1836				break;
1837			if (ATA_INL(ch->r_mem, AHCI_P_TFD) & ATA_S_ERROR) {
1838				device_printf(ch->dev,
1839				    "Poll error on slot %d, TFD: %04x\n",
1840				    slot->slot, ATA_INL(ch->r_mem, AHCI_P_TFD));
1841				et = AHCI_ERR_TFE;
1842				break;
1843			}
1844			/* Workaround for ATI SB600/SB700 chipsets. */
1845			if (ccb->ccb_h.target_id == 15 &&
1846			    pci_get_vendor(device_get_parent(dev)) == 0x1002 &&
1847			    (ATA_INL(ch->r_mem, AHCI_P_IS) & AHCI_P_IX_IPM)) {
1848				et = AHCI_ERR_TIMEOUT;
1849				break;
1850			}
1851		}
1852		if (timeout && (count >= timeout)) {
1853			device_printf(ch->dev,
1854			    "Poll timeout on slot %d\n", slot->slot);
1855			device_printf(dev, "is %08x cs %08x ss %08x "
1856			    "rs %08x tfd %02x serr %08x\n",
1857			    ATA_INL(ch->r_mem, AHCI_P_IS),
1858			    ATA_INL(ch->r_mem, AHCI_P_CI),
1859			    ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots,
1860			    ATA_INL(ch->r_mem, AHCI_P_TFD),
1861			    ATA_INL(ch->r_mem, AHCI_P_SERR));
1862			et = AHCI_ERR_TIMEOUT;
1863		}
1864		/* Marvell controllers do not wait for readyness. */
1865		if ((ch->quirks & AHCI_Q_NOBSYRES) &&
1866		    (ccb->ccb_h.func_code == XPT_ATA_IO) &&
1867		    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
1868		    (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
1869			while ((val = fis[2]) & (ATA_S_BUSY | ATA_S_DRQ)) {
1870				DELAY(10);
1871				if (count++ >= timeout) {
1872					device_printf(dev, "device is not "
1873					    "ready after soft-reset: "
1874					    "tfd = %08x\n", val);
1875	    				et = AHCI_ERR_TIMEOUT;
1876	    				break;
1877				}
1878			}
1879		}
1880		ahci_end_transaction(slot, et);
1881		/* Kick controller into sane state and enable FBS. */
1882		if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
1883		    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
1884		    (ccb->ataio.cmd.control & ATA_A_RESET) == 0) {
1885			ahci_stop(ch->dev);
1886			ahci_start(ch->dev, 1);
1887		}
1888		return;
1889	}
1890	/* Start command execution timeout */
1891	callout_reset(&slot->timeout, (int)ccb->ccb_h.timeout * hz / 2000,
1892	    (timeout_t*)ahci_timeout, slot);
1893	return;
1894}
1895
1896/* Must be called with channel locked. */
1897static void
1898ahci_process_timeout(device_t dev)
1899{
1900	struct ahci_channel *ch = device_get_softc(dev);
1901	int i;
1902
1903	mtx_assert(&ch->mtx, MA_OWNED);
1904	/* Handle the rest of commands. */
1905	for (i = 0; i < ch->numslots; i++) {
1906		/* Do we have a running request on slot? */
1907		if (ch->slot[i].state < AHCI_SLOT_RUNNING)
1908			continue;
1909		ahci_end_transaction(&ch->slot[i], AHCI_ERR_TIMEOUT);
1910	}
1911}
1912
1913/* Must be called with channel locked. */
1914static void
1915ahci_rearm_timeout(device_t dev)
1916{
1917	struct ahci_channel *ch = device_get_softc(dev);
1918	int i;
1919
1920	mtx_assert(&ch->mtx, MA_OWNED);
1921	for (i = 0; i < ch->numslots; i++) {
1922		struct ahci_slot *slot = &ch->slot[i];
1923
1924		/* Do we have a running request on slot? */
1925		if (slot->state < AHCI_SLOT_RUNNING)
1926			continue;
1927		if ((ch->toslots & (1 << i)) == 0)
1928			continue;
1929		callout_reset(&slot->timeout,
1930		    (int)slot->ccb->ccb_h.timeout * hz / 2000,
1931		    (timeout_t*)ahci_timeout, slot);
1932	}
1933}
1934
1935/* Locked by callout mechanism. */
1936static void
1937ahci_timeout(struct ahci_slot *slot)
1938{
1939	device_t dev = slot->dev;
1940	struct ahci_channel *ch = device_get_softc(dev);
1941	uint32_t sstatus;
1942	int ccs;
1943	int i;
1944
1945	/* Check for stale timeout. */
1946	if (slot->state < AHCI_SLOT_RUNNING)
1947		return;
1948
1949	/* Check if slot was not being executed last time we checked. */
1950	if (slot->state < AHCI_SLOT_EXECUTING) {
1951		/* Check if slot started executing. */
1952		sstatus = ATA_INL(ch->r_mem, AHCI_P_SACT);
1953		ccs = (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CCS_MASK)
1954		    >> AHCI_P_CMD_CCS_SHIFT;
1955		if ((sstatus & (1 << slot->slot)) != 0 || ccs == slot->slot ||
1956		    ch->fbs_enabled)
1957			slot->state = AHCI_SLOT_EXECUTING;
1958
1959		callout_reset(&slot->timeout,
1960		    (int)slot->ccb->ccb_h.timeout * hz / 2000,
1961		    (timeout_t*)ahci_timeout, slot);
1962		return;
1963	}
1964
1965	device_printf(dev, "Timeout on slot %d\n", slot->slot);
1966	device_printf(dev, "is %08x cs %08x ss %08x rs %08x tfd %02x serr %08x\n",
1967	    ATA_INL(ch->r_mem, AHCI_P_IS), ATA_INL(ch->r_mem, AHCI_P_CI),
1968	    ATA_INL(ch->r_mem, AHCI_P_SACT), ch->rslots,
1969	    ATA_INL(ch->r_mem, AHCI_P_TFD), ATA_INL(ch->r_mem, AHCI_P_SERR));
1970
1971	/* Handle frozen command. */
1972	if (ch->frozen) {
1973		union ccb *fccb = ch->frozen;
1974		ch->frozen = NULL;
1975		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
1976		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
1977			xpt_freeze_devq(fccb->ccb_h.path, 1);
1978			fccb->ccb_h.status |= CAM_DEV_QFRZN;
1979		}
1980		xpt_done(fccb);
1981	}
1982	if (!ch->fbs_enabled) {
1983		/* Without FBS we know real timeout source. */
1984		ch->fatalerr = 1;
1985		/* Handle command with timeout. */
1986		ahci_end_transaction(&ch->slot[slot->slot], AHCI_ERR_TIMEOUT);
1987		/* Handle the rest of commands. */
1988		for (i = 0; i < ch->numslots; i++) {
1989			/* Do we have a running request on slot? */
1990			if (ch->slot[i].state < AHCI_SLOT_RUNNING)
1991				continue;
1992			ahci_end_transaction(&ch->slot[i], AHCI_ERR_INNOCENT);
1993		}
1994	} else {
1995		/* With FBS we wait for other commands timeout and pray. */
1996		if (ch->toslots == 0)
1997			xpt_freeze_simq(ch->sim, 1);
1998		ch->toslots |= (1 << slot->slot);
1999		if ((ch->rslots & ~ch->toslots) == 0)
2000			ahci_process_timeout(dev);
2001		else
2002			device_printf(dev, " ... waiting for slots %08x\n",
2003			    ch->rslots & ~ch->toslots);
2004	}
2005}
2006
2007/* Must be called with channel locked. */
2008static void
2009ahci_end_transaction(struct ahci_slot *slot, enum ahci_err_type et)
2010{
2011	device_t dev = slot->dev;
2012	struct ahci_channel *ch = device_get_softc(dev);
2013	union ccb *ccb = slot->ccb;
2014	struct ahci_cmd_list *clp;
2015	int lastto;
2016
2017	bus_dmamap_sync(ch->dma.work_tag, ch->dma.work_map,
2018	    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
2019	clp = (struct ahci_cmd_list *)
2020	    (ch->dma.work + AHCI_CL_OFFSET + (AHCI_CL_SIZE * slot->slot));
2021	/* Read result registers to the result struct
2022	 * May be incorrect if several commands finished same time,
2023	 * so read only when sure or have to.
2024	 */
2025	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
2026		struct ata_res *res = &ccb->ataio.res;
2027
2028		if ((et == AHCI_ERR_TFE) ||
2029		    (ccb->ataio.cmd.flags & CAM_ATAIO_NEEDRESULT)) {
2030			u_int8_t *fis = ch->dma.rfis + 0x40;
2031
2032			bus_dmamap_sync(ch->dma.rfis_tag, ch->dma.rfis_map,
2033			    BUS_DMASYNC_POSTREAD);
2034			if (ch->fbs_enabled) {
2035				fis += ccb->ccb_h.target_id * 256;
2036				res->status = fis[2];
2037				res->error = fis[3];
2038			} else {
2039				uint16_t tfd = ATA_INL(ch->r_mem, AHCI_P_TFD);
2040
2041				res->status = tfd;
2042				res->error = tfd >> 8;
2043			}
2044			res->lba_low = fis[4];
2045			res->lba_mid = fis[5];
2046			res->lba_high = fis[6];
2047			res->device = fis[7];
2048			res->lba_low_exp = fis[8];
2049			res->lba_mid_exp = fis[9];
2050			res->lba_high_exp = fis[10];
2051			res->sector_count = fis[12];
2052			res->sector_count_exp = fis[13];
2053		} else
2054			bzero(res, sizeof(*res));
2055		if ((ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) == 0 &&
2056		    (ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
2057		    (ch->quirks & AHCI_Q_NOCOUNT) == 0) {
2058			ccb->ataio.resid =
2059			    ccb->ataio.dxfer_len - le32toh(clp->bytecount);
2060		}
2061	} else {
2062		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
2063		    (ch->quirks & AHCI_Q_NOCOUNT) == 0) {
2064			ccb->csio.resid =
2065			    ccb->csio.dxfer_len - le32toh(clp->bytecount);
2066		}
2067	}
2068	if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
2069		bus_dmamap_sync(ch->dma.data_tag, slot->dma.data_map,
2070		    (ccb->ccb_h.flags & CAM_DIR_IN) ?
2071		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
2072		bus_dmamap_unload(ch->dma.data_tag, slot->dma.data_map);
2073	}
2074	if (et != AHCI_ERR_NONE)
2075		ch->eslots |= (1 << slot->slot);
2076	/* In case of error, freeze device for proper recovery. */
2077	if ((et != AHCI_ERR_NONE) && (!ch->recoverycmd) &&
2078	    !(ccb->ccb_h.status & CAM_DEV_QFRZN)) {
2079		xpt_freeze_devq(ccb->ccb_h.path, 1);
2080		ccb->ccb_h.status |= CAM_DEV_QFRZN;
2081	}
2082	/* Set proper result status. */
2083	ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2084	switch (et) {
2085	case AHCI_ERR_NONE:
2086		ccb->ccb_h.status |= CAM_REQ_CMP;
2087		if (ccb->ccb_h.func_code == XPT_SCSI_IO)
2088			ccb->csio.scsi_status = SCSI_STATUS_OK;
2089		break;
2090	case AHCI_ERR_INVALID:
2091		ch->fatalerr = 1;
2092		ccb->ccb_h.status |= CAM_REQ_INVALID;
2093		break;
2094	case AHCI_ERR_INNOCENT:
2095		ccb->ccb_h.status |= CAM_REQUEUE_REQ;
2096		break;
2097	case AHCI_ERR_TFE:
2098	case AHCI_ERR_NCQ:
2099		if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
2100			ccb->ccb_h.status |= CAM_SCSI_STATUS_ERROR;
2101			ccb->csio.scsi_status = SCSI_STATUS_CHECK_COND;
2102		} else {
2103			ccb->ccb_h.status |= CAM_ATA_STATUS_ERROR;
2104		}
2105		break;
2106	case AHCI_ERR_SATA:
2107		ch->fatalerr = 1;
2108		if (!ch->recoverycmd) {
2109			xpt_freeze_simq(ch->sim, 1);
2110			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2111			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
2112		}
2113		ccb->ccb_h.status |= CAM_UNCOR_PARITY;
2114		break;
2115	case AHCI_ERR_TIMEOUT:
2116		if (!ch->recoverycmd) {
2117			xpt_freeze_simq(ch->sim, 1);
2118			ccb->ccb_h.status &= ~CAM_STATUS_MASK;
2119			ccb->ccb_h.status |= CAM_RELEASE_SIMQ;
2120		}
2121		ccb->ccb_h.status |= CAM_CMD_TIMEOUT;
2122		break;
2123	default:
2124		ch->fatalerr = 1;
2125		ccb->ccb_h.status |= CAM_REQ_CMP_ERR;
2126	}
2127	/* Free slot. */
2128	ch->oslots &= ~(1 << slot->slot);
2129	ch->rslots &= ~(1 << slot->slot);
2130	ch->aslots &= ~(1 << slot->slot);
2131	slot->state = AHCI_SLOT_EMPTY;
2132	slot->ccb = NULL;
2133	/* Update channel stats. */
2134	ch->numrslots--;
2135	ch->numrslotspd[ccb->ccb_h.target_id]--;
2136	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
2137	    (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA)) {
2138		ch->numtslots--;
2139		ch->numtslotspd[ccb->ccb_h.target_id]--;
2140	}
2141	/* Cancel timeout state if request completed normally. */
2142	if (et != AHCI_ERR_TIMEOUT) {
2143		lastto = (ch->toslots == (1 << slot->slot));
2144		ch->toslots &= ~(1 << slot->slot);
2145		if (lastto)
2146			xpt_release_simq(ch->sim, TRUE);
2147	}
2148	/* If it was first request of reset sequence and there is no error,
2149	 * proceed to second request. */
2150	if ((ccb->ccb_h.func_code == XPT_ATA_IO) &&
2151	    (ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) &&
2152	    (ccb->ataio.cmd.control & ATA_A_RESET) &&
2153	    et == AHCI_ERR_NONE) {
2154		ccb->ataio.cmd.control &= ~ATA_A_RESET;
2155		ahci_begin_transaction(dev, ccb);
2156		return;
2157	}
2158	/* If it was our READ LOG command - process it. */
2159	if (ccb->ccb_h.recovery_type == RECOVERY_READ_LOG) {
2160		ahci_process_read_log(dev, ccb);
2161	/* If it was our REQUEST SENSE command - process it. */
2162	} else if (ccb->ccb_h.recovery_type == RECOVERY_REQUEST_SENSE) {
2163		ahci_process_request_sense(dev, ccb);
2164	/* If it was NCQ or ATAPI command error, put result on hold. */
2165	} else if (et == AHCI_ERR_NCQ ||
2166	    ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_SCSI_STATUS_ERROR &&
2167	     (ccb->ccb_h.flags & CAM_DIS_AUTOSENSE) == 0)) {
2168		ch->hold[slot->slot] = ccb;
2169		ch->numhslots++;
2170	} else
2171		xpt_done(ccb);
2172	/* Unfreeze frozen command. */
2173	if (ch->frozen && !ahci_check_collision(dev, ch->frozen)) {
2174		union ccb *fccb = ch->frozen;
2175		ch->frozen = NULL;
2176		ahci_begin_transaction(dev, fccb);
2177		xpt_release_simq(ch->sim, TRUE);
2178	}
2179	/* If we have no other active commands, ... */
2180	if (ch->rslots == 0) {
2181		/* if there was fatal error - reset port. */
2182		if (ch->toslots != 0 || ch->fatalerr) {
2183			ahci_reset(dev);
2184		} else {
2185			/* if we have slots in error, we can reinit port. */
2186			if (ch->eslots != 0) {
2187				ahci_stop(dev);
2188				ahci_start(dev, 1);
2189			}
2190			/* if there commands on hold, we can do READ LOG. */
2191			if (!ch->recoverycmd && ch->numhslots)
2192				ahci_issue_recovery(dev);
2193		}
2194	/* If all the rest of commands are in timeout - give them chance. */
2195	} else if ((ch->rslots & ~ch->toslots) == 0 &&
2196	    et != AHCI_ERR_TIMEOUT)
2197		ahci_rearm_timeout(dev);
2198	/* Start PM timer. */
2199	if (ch->numrslots == 0 && ch->pm_level > 3 &&
2200	    (ch->curr[ch->pm_present ? 15 : 0].caps & CTS_SATA_CAPS_D_PMREQ)) {
2201		callout_schedule(&ch->pm_timer,
2202		    (ch->pm_level == 4) ? hz / 1000 : hz / 8);
2203	}
2204}
2205
2206static void
2207ahci_issue_recovery(device_t dev)
2208{
2209	struct ahci_channel *ch = device_get_softc(dev);
2210	union ccb *ccb;
2211	struct ccb_ataio *ataio;
2212	struct ccb_scsiio *csio;
2213	int i;
2214
2215	/* Find some held command. */
2216	for (i = 0; i < ch->numslots; i++) {
2217		if (ch->hold[i])
2218			break;
2219	}
2220	ccb = xpt_alloc_ccb_nowait();
2221	if (ccb == NULL) {
2222		device_printf(dev, "Unable to allocate recovery command\n");
2223completeall:
2224		/* We can't do anything -- complete held commands. */
2225		for (i = 0; i < ch->numslots; i++) {
2226			if (ch->hold[i] == NULL)
2227				continue;
2228			ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
2229			ch->hold[i]->ccb_h.status |= CAM_RESRC_UNAVAIL;
2230			xpt_done(ch->hold[i]);
2231			ch->hold[i] = NULL;
2232			ch->numhslots--;
2233		}
2234		ahci_reset(dev);
2235		return;
2236	}
2237	ccb->ccb_h = ch->hold[i]->ccb_h;	/* Reuse old header. */
2238	if (ccb->ccb_h.func_code == XPT_ATA_IO) {
2239		/* READ LOG */
2240		ccb->ccb_h.recovery_type = RECOVERY_READ_LOG;
2241		ccb->ccb_h.func_code = XPT_ATA_IO;
2242		ccb->ccb_h.flags = CAM_DIR_IN;
2243		ccb->ccb_h.timeout = 1000;	/* 1s should be enough. */
2244		ataio = &ccb->ataio;
2245		ataio->data_ptr = malloc(512, M_AHCI, M_NOWAIT);
2246		if (ataio->data_ptr == NULL) {
2247			xpt_free_ccb(ccb);
2248			device_printf(dev,
2249			    "Unable to allocate memory for READ LOG command\n");
2250			goto completeall;
2251		}
2252		ataio->dxfer_len = 512;
2253		bzero(&ataio->cmd, sizeof(ataio->cmd));
2254		ataio->cmd.flags = CAM_ATAIO_48BIT;
2255		ataio->cmd.command = 0x2F;	/* READ LOG EXT */
2256		ataio->cmd.sector_count = 1;
2257		ataio->cmd.sector_count_exp = 0;
2258		ataio->cmd.lba_low = 0x10;
2259		ataio->cmd.lba_mid = 0;
2260		ataio->cmd.lba_mid_exp = 0;
2261	} else {
2262		/* REQUEST SENSE */
2263		ccb->ccb_h.recovery_type = RECOVERY_REQUEST_SENSE;
2264		ccb->ccb_h.recovery_slot = i;
2265		ccb->ccb_h.func_code = XPT_SCSI_IO;
2266		ccb->ccb_h.flags = CAM_DIR_IN;
2267		ccb->ccb_h.status = 0;
2268		ccb->ccb_h.timeout = 1000;	/* 1s should be enough. */
2269		csio = &ccb->csio;
2270		csio->data_ptr = (void *)&ch->hold[i]->csio.sense_data;
2271		csio->dxfer_len = ch->hold[i]->csio.sense_len;
2272		csio->cdb_len = 6;
2273		bzero(&csio->cdb_io, sizeof(csio->cdb_io));
2274		csio->cdb_io.cdb_bytes[0] = 0x03;
2275		csio->cdb_io.cdb_bytes[4] = csio->dxfer_len;
2276	}
2277	/* Freeze SIM while doing recovery. */
2278	ch->recoverycmd = 1;
2279	xpt_freeze_simq(ch->sim, 1);
2280	ahci_begin_transaction(dev, ccb);
2281}
2282
2283static void
2284ahci_process_read_log(device_t dev, union ccb *ccb)
2285{
2286	struct ahci_channel *ch = device_get_softc(dev);
2287	uint8_t *data;
2288	struct ata_res *res;
2289	int i;
2290
2291	ch->recoverycmd = 0;
2292
2293	data = ccb->ataio.data_ptr;
2294	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP &&
2295	    (data[0] & 0x80) == 0) {
2296		for (i = 0; i < ch->numslots; i++) {
2297			if (!ch->hold[i])
2298				continue;
2299			if (ch->hold[i]->ccb_h.func_code != XPT_ATA_IO)
2300				continue;
2301			if ((data[0] & 0x1F) == i) {
2302				res = &ch->hold[i]->ataio.res;
2303				res->status = data[2];
2304				res->error = data[3];
2305				res->lba_low = data[4];
2306				res->lba_mid = data[5];
2307				res->lba_high = data[6];
2308				res->device = data[7];
2309				res->lba_low_exp = data[8];
2310				res->lba_mid_exp = data[9];
2311				res->lba_high_exp = data[10];
2312				res->sector_count = data[12];
2313				res->sector_count_exp = data[13];
2314			} else {
2315				ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
2316				ch->hold[i]->ccb_h.status |= CAM_REQUEUE_REQ;
2317			}
2318			xpt_done(ch->hold[i]);
2319			ch->hold[i] = NULL;
2320			ch->numhslots--;
2321		}
2322	} else {
2323		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
2324			device_printf(dev, "Error while READ LOG EXT\n");
2325		else if ((data[0] & 0x80) == 0) {
2326			device_printf(dev, "Non-queued command error in READ LOG EXT\n");
2327		}
2328		for (i = 0; i < ch->numslots; i++) {
2329			if (!ch->hold[i])
2330				continue;
2331			if (ch->hold[i]->ccb_h.func_code != XPT_ATA_IO)
2332				continue;
2333			xpt_done(ch->hold[i]);
2334			ch->hold[i] = NULL;
2335			ch->numhslots--;
2336		}
2337	}
2338	free(ccb->ataio.data_ptr, M_AHCI);
2339	xpt_free_ccb(ccb);
2340	xpt_release_simq(ch->sim, TRUE);
2341}
2342
2343static void
2344ahci_process_request_sense(device_t dev, union ccb *ccb)
2345{
2346	struct ahci_channel *ch = device_get_softc(dev);
2347	int i;
2348
2349	ch->recoverycmd = 0;
2350
2351	i = ccb->ccb_h.recovery_slot;
2352	if ((ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
2353		ch->hold[i]->ccb_h.status |= CAM_AUTOSNS_VALID;
2354	} else {
2355		ch->hold[i]->ccb_h.status &= ~CAM_STATUS_MASK;
2356		ch->hold[i]->ccb_h.status |= CAM_AUTOSENSE_FAIL;
2357	}
2358	xpt_done(ch->hold[i]);
2359	ch->hold[i] = NULL;
2360	ch->numhslots--;
2361	xpt_free_ccb(ccb);
2362	xpt_release_simq(ch->sim, TRUE);
2363}
2364
2365static void
2366ahci_start(device_t dev, int fbs)
2367{
2368	struct ahci_channel *ch = device_get_softc(dev);
2369	u_int32_t cmd;
2370
2371	/* Clear SATA error register */
2372	ATA_OUTL(ch->r_mem, AHCI_P_SERR, 0xFFFFFFFF);
2373	/* Clear any interrupts pending on this channel */
2374	ATA_OUTL(ch->r_mem, AHCI_P_IS, 0xFFFFFFFF);
2375	/* Configure FIS-based switching if supported. */
2376	if (ch->chcaps & AHCI_P_CMD_FBSCP) {
2377		ch->fbs_enabled = (fbs && ch->pm_present) ? 1 : 0;
2378		ATA_OUTL(ch->r_mem, AHCI_P_FBS,
2379		    ch->fbs_enabled ? AHCI_P_FBS_EN : 0);
2380	}
2381	/* Start operations on this channel */
2382	cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
2383	cmd &= ~AHCI_P_CMD_PMA;
2384	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_ST |
2385	    (ch->pm_present ? AHCI_P_CMD_PMA : 0));
2386}
2387
2388static void
2389ahci_stop(device_t dev)
2390{
2391	struct ahci_channel *ch = device_get_softc(dev);
2392	u_int32_t cmd;
2393	int timeout;
2394
2395	/* Kill all activity on this channel */
2396	cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
2397	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_ST);
2398	/* Wait for activity stop. */
2399	timeout = 0;
2400	do {
2401		DELAY(10);
2402		if (timeout++ > 50000) {
2403			device_printf(dev, "stopping AHCI engine failed\n");
2404			break;
2405		}
2406	} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CR);
2407	ch->eslots = 0;
2408}
2409
2410static void
2411ahci_clo(device_t dev)
2412{
2413	struct ahci_channel *ch = device_get_softc(dev);
2414	u_int32_t cmd;
2415	int timeout;
2416
2417	/* Issue Command List Override if supported */
2418	if (ch->caps & AHCI_CAP_SCLO) {
2419		cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
2420		cmd |= AHCI_P_CMD_CLO;
2421		ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd);
2422		timeout = 0;
2423		do {
2424			DELAY(10);
2425			if (timeout++ > 50000) {
2426			    device_printf(dev, "executing CLO failed\n");
2427			    break;
2428			}
2429		} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_CLO);
2430	}
2431}
2432
2433static void
2434ahci_stop_fr(device_t dev)
2435{
2436	struct ahci_channel *ch = device_get_softc(dev);
2437	u_int32_t cmd;
2438	int timeout;
2439
2440	/* Kill all FIS reception on this channel */
2441	cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
2442	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd & ~AHCI_P_CMD_FRE);
2443	/* Wait for FIS reception stop. */
2444	timeout = 0;
2445	do {
2446		DELAY(10);
2447		if (timeout++ > 50000) {
2448			device_printf(dev, "stopping AHCI FR engine failed\n");
2449			break;
2450		}
2451	} while (ATA_INL(ch->r_mem, AHCI_P_CMD) & AHCI_P_CMD_FR);
2452}
2453
2454static void
2455ahci_start_fr(device_t dev)
2456{
2457	struct ahci_channel *ch = device_get_softc(dev);
2458	u_int32_t cmd;
2459
2460	/* Start FIS reception on this channel */
2461	cmd = ATA_INL(ch->r_mem, AHCI_P_CMD);
2462	ATA_OUTL(ch->r_mem, AHCI_P_CMD, cmd | AHCI_P_CMD_FRE);
2463}
2464
2465static int
2466ahci_wait_ready(device_t dev, int t, int t0)
2467{
2468	struct ahci_channel *ch = device_get_softc(dev);
2469	int timeout = 0;
2470	uint32_t val;
2471
2472	while ((val = ATA_INL(ch->r_mem, AHCI_P_TFD)) &
2473	    (ATA_S_BUSY | ATA_S_DRQ)) {
2474		if (timeout > t) {
2475			if (t != 0) {
2476				device_printf(dev,
2477				    "AHCI reset: device not ready after %dms "
2478				    "(tfd = %08x)\n",
2479				    MAX(t, 0) + t0, val);
2480			}
2481			return (EBUSY);
2482		}
2483		DELAY(1000);
2484		timeout++;
2485	}
2486	if (bootverbose)
2487		device_printf(dev, "AHCI reset: device ready after %dms\n",
2488		    timeout + t0);
2489	return (0);
2490}
2491
2492static void
2493ahci_reset_to(void *arg)
2494{
2495	device_t dev = arg;
2496	struct ahci_channel *ch = device_get_softc(dev);
2497
2498	if (ch->resetting == 0)
2499		return;
2500	ch->resetting--;
2501	if (ahci_wait_ready(dev, ch->resetting == 0 ? -1 : 0,
2502	    (310 - ch->resetting) * 100) == 0) {
2503		ch->resetting = 0;
2504		ahci_start(dev, 1);
2505		xpt_release_simq(ch->sim, TRUE);
2506		return;
2507	}
2508	if (ch->resetting == 0) {
2509		ahci_clo(dev);
2510		ahci_start(dev, 1);
2511		xpt_release_simq(ch->sim, TRUE);
2512		return;
2513	}
2514	callout_schedule(&ch->reset_timer, hz / 10);
2515}
2516
2517static void
2518ahci_reset(device_t dev)
2519{
2520	struct ahci_channel *ch = device_get_softc(dev);
2521	struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
2522	int i;
2523
2524	xpt_freeze_simq(ch->sim, 1);
2525	if (bootverbose)
2526		device_printf(dev, "AHCI reset...\n");
2527	/* Forget about previous reset. */
2528	if (ch->resetting) {
2529		ch->resetting = 0;
2530		callout_stop(&ch->reset_timer);
2531		xpt_release_simq(ch->sim, TRUE);
2532	}
2533	/* Requeue freezed command. */
2534	if (ch->frozen) {
2535		union ccb *fccb = ch->frozen;
2536		ch->frozen = NULL;
2537		fccb->ccb_h.status = CAM_REQUEUE_REQ | CAM_RELEASE_SIMQ;
2538		if (!(fccb->ccb_h.status & CAM_DEV_QFRZN)) {
2539			xpt_freeze_devq(fccb->ccb_h.path, 1);
2540			fccb->ccb_h.status |= CAM_DEV_QFRZN;
2541		}
2542		xpt_done(fccb);
2543	}
2544	/* Kill the engine and requeue all running commands. */
2545	ahci_stop(dev);
2546	for (i = 0; i < ch->numslots; i++) {
2547		/* Do we have a running request on slot? */
2548		if (ch->slot[i].state < AHCI_SLOT_RUNNING)
2549			continue;
2550		/* XXX; Commands in loading state. */
2551		ahci_end_transaction(&ch->slot[i], AHCI_ERR_INNOCENT);
2552	}
2553	for (i = 0; i < ch->numslots; i++) {
2554		if (!ch->hold[i])
2555			continue;
2556		xpt_done(ch->hold[i]);
2557		ch->hold[i] = NULL;
2558		ch->numhslots--;
2559	}
2560	if (ch->toslots != 0)
2561		xpt_release_simq(ch->sim, TRUE);
2562	ch->eslots = 0;
2563	ch->toslots = 0;
2564	ch->fatalerr = 0;
2565	/* Tell the XPT about the event */
2566	xpt_async(AC_BUS_RESET, ch->path, NULL);
2567	/* Disable port interrupts */
2568	ATA_OUTL(ch->r_mem, AHCI_P_IE, 0);
2569	/* Reset and reconnect PHY, */
2570	if (!ahci_sata_phy_reset(dev)) {
2571		if (bootverbose)
2572			device_printf(dev,
2573			    "AHCI reset: device not found\n");
2574		ch->devices = 0;
2575		/* Enable wanted port interrupts */
2576		ATA_OUTL(ch->r_mem, AHCI_P_IE,
2577		    (((ch->pm_level != 0) ? AHCI_P_IX_CPD | AHCI_P_IX_MP : 0) |
2578		     AHCI_P_IX_PRC | AHCI_P_IX_PC));
2579		xpt_release_simq(ch->sim, TRUE);
2580		return;
2581	}
2582	if (bootverbose)
2583		device_printf(dev, "AHCI reset: device found\n");
2584	/* Wait for clearing busy status. */
2585	if (ahci_wait_ready(dev, dumping ? 31000 : 0, 0)) {
2586		if (dumping)
2587			ahci_clo(dev);
2588		else
2589			ch->resetting = 310;
2590	}
2591	ch->devices = 1;
2592	/* Enable wanted port interrupts */
2593	ATA_OUTL(ch->r_mem, AHCI_P_IE,
2594	     (((ch->pm_level != 0) ? AHCI_P_IX_CPD | AHCI_P_IX_MP : 0) |
2595	      AHCI_P_IX_TFE | AHCI_P_IX_HBF |
2596	      AHCI_P_IX_HBD | AHCI_P_IX_IF | AHCI_P_IX_OF |
2597	      ((ch->pm_level == 0) ? AHCI_P_IX_PRC : 0) | AHCI_P_IX_PC |
2598	      AHCI_P_IX_DP | AHCI_P_IX_UF | (ctlr->ccc ? 0 : AHCI_P_IX_SDB) |
2599	      AHCI_P_IX_DS | AHCI_P_IX_PS | (ctlr->ccc ? 0 : AHCI_P_IX_DHR)));
2600	if (ch->resetting)
2601		callout_reset(&ch->reset_timer, hz / 10, ahci_reset_to, dev);
2602	else {
2603		ahci_start(dev, 1);
2604		xpt_release_simq(ch->sim, TRUE);
2605	}
2606}
2607
2608static int
2609ahci_setup_fis(device_t dev, struct ahci_cmd_tab *ctp, union ccb *ccb, int tag)
2610{
2611	struct ahci_channel *ch = device_get_softc(dev);
2612	u_int8_t *fis = &ctp->cfis[0];
2613
2614	bzero(ctp->cfis, 64);
2615	fis[0] = 0x27;  		/* host to device */
2616	fis[1] = (ccb->ccb_h.target_id & 0x0f);
2617	if (ccb->ccb_h.func_code == XPT_SCSI_IO) {
2618		fis[1] |= 0x80;
2619		fis[2] = ATA_PACKET_CMD;
2620		if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE &&
2621		    ch->curr[ccb->ccb_h.target_id].mode >= ATA_DMA)
2622			fis[3] = ATA_F_DMA;
2623		else {
2624			fis[5] = ccb->csio.dxfer_len;
2625		        fis[6] = ccb->csio.dxfer_len >> 8;
2626		}
2627		fis[7] = ATA_D_LBA;
2628		fis[15] = ATA_A_4BIT;
2629		bzero(ctp->acmd, 32);
2630		bcopy((ccb->ccb_h.flags & CAM_CDB_POINTER) ?
2631		    ccb->csio.cdb_io.cdb_ptr : ccb->csio.cdb_io.cdb_bytes,
2632		    ctp->acmd, ccb->csio.cdb_len);
2633	} else if ((ccb->ataio.cmd.flags & CAM_ATAIO_CONTROL) == 0) {
2634		fis[1] |= 0x80;
2635		fis[2] = ccb->ataio.cmd.command;
2636		fis[3] = ccb->ataio.cmd.features;
2637		fis[4] = ccb->ataio.cmd.lba_low;
2638		fis[5] = ccb->ataio.cmd.lba_mid;
2639		fis[6] = ccb->ataio.cmd.lba_high;
2640		fis[7] = ccb->ataio.cmd.device;
2641		fis[8] = ccb->ataio.cmd.lba_low_exp;
2642		fis[9] = ccb->ataio.cmd.lba_mid_exp;
2643		fis[10] = ccb->ataio.cmd.lba_high_exp;
2644		fis[11] = ccb->ataio.cmd.features_exp;
2645		if (ccb->ataio.cmd.flags & CAM_ATAIO_FPDMA) {
2646			fis[12] = tag << 3;
2647			fis[13] = 0;
2648		} else {
2649			fis[12] = ccb->ataio.cmd.sector_count;
2650			fis[13] = ccb->ataio.cmd.sector_count_exp;
2651		}
2652		fis[15] = ATA_A_4BIT;
2653	} else {
2654		fis[15] = ccb->ataio.cmd.control;
2655	}
2656	return (20);
2657}
2658
2659static int
2660ahci_sata_connect(struct ahci_channel *ch)
2661{
2662	u_int32_t status;
2663	int timeout, found = 0;
2664
2665	/* Wait up to 100ms for "connect well" */
2666	for (timeout = 0; timeout < 1000 ; timeout++) {
2667		status = ATA_INL(ch->r_mem, AHCI_P_SSTS);
2668		if ((status & ATA_SS_DET_MASK) != ATA_SS_DET_NO_DEVICE)
2669			found = 1;
2670		if (((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_ONLINE) &&
2671		    ((status & ATA_SS_SPD_MASK) != ATA_SS_SPD_NO_SPEED) &&
2672		    ((status & ATA_SS_IPM_MASK) == ATA_SS_IPM_ACTIVE))
2673			break;
2674		if ((status & ATA_SS_DET_MASK) == ATA_SS_DET_PHY_OFFLINE) {
2675			if (bootverbose) {
2676				device_printf(ch->dev, "SATA offline status=%08x\n",
2677				    status);
2678			}
2679			return (0);
2680		}
2681		if (found == 0 && timeout >= 100)
2682			break;
2683		DELAY(100);
2684	}
2685	if (timeout >= 1000 || !found) {
2686		if (bootverbose) {
2687			device_printf(ch->dev,
2688			    "SATA connect timeout time=%dus status=%08x\n",
2689			    timeout * 100, status);
2690		}
2691		return (0);
2692	}
2693	if (bootverbose) {
2694		device_printf(ch->dev, "SATA connect time=%dus status=%08x\n",
2695		    timeout * 100, status);
2696	}
2697	/* Clear SATA error register */
2698	ATA_OUTL(ch->r_mem, AHCI_P_SERR, 0xffffffff);
2699	return (1);
2700}
2701
2702static int
2703ahci_sata_phy_reset(device_t dev)
2704{
2705	struct ahci_channel *ch = device_get_softc(dev);
2706	int sata_rev;
2707	uint32_t val;
2708
2709	if (ch->listening) {
2710		val = ATA_INL(ch->r_mem, AHCI_P_CMD);
2711		val |= AHCI_P_CMD_SUD;
2712		ATA_OUTL(ch->r_mem, AHCI_P_CMD, val);
2713		ch->listening = 0;
2714	}
2715	sata_rev = ch->user[ch->pm_present ? 15 : 0].revision;
2716	if (sata_rev == 1)
2717		val = ATA_SC_SPD_SPEED_GEN1;
2718	else if (sata_rev == 2)
2719		val = ATA_SC_SPD_SPEED_GEN2;
2720	else if (sata_rev == 3)
2721		val = ATA_SC_SPD_SPEED_GEN3;
2722	else
2723		val = 0;
2724	ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
2725	    ATA_SC_DET_RESET | val |
2726	    ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER);
2727	DELAY(1000);
2728	ATA_OUTL(ch->r_mem, AHCI_P_SCTL,
2729	    ATA_SC_DET_IDLE | val | ((ch->pm_level > 0) ? 0 :
2730	    (ATA_SC_IPM_DIS_PARTIAL | ATA_SC_IPM_DIS_SLUMBER)));
2731	if (!ahci_sata_connect(ch)) {
2732		if (ch->caps & AHCI_CAP_SSS) {
2733			val = ATA_INL(ch->r_mem, AHCI_P_CMD);
2734			val &= ~AHCI_P_CMD_SUD;
2735			ATA_OUTL(ch->r_mem, AHCI_P_CMD, val);
2736			ch->listening = 1;
2737		} else if (ch->pm_level > 0)
2738			ATA_OUTL(ch->r_mem, AHCI_P_SCTL, ATA_SC_DET_DISABLE);
2739		return (0);
2740	}
2741	return (1);
2742}
2743
2744static int
2745ahci_check_ids(device_t dev, union ccb *ccb)
2746{
2747	struct ahci_channel *ch = device_get_softc(dev);
2748
2749	if (ccb->ccb_h.target_id > ((ch->caps & AHCI_CAP_SPM) ? 15 : 0)) {
2750		ccb->ccb_h.status = CAM_TID_INVALID;
2751		xpt_done(ccb);
2752		return (-1);
2753	}
2754	if (ccb->ccb_h.target_lun != 0) {
2755		ccb->ccb_h.status = CAM_LUN_INVALID;
2756		xpt_done(ccb);
2757		return (-1);
2758	}
2759	return (0);
2760}
2761
2762static void
2763ahciaction(struct cam_sim *sim, union ccb *ccb)
2764{
2765	device_t dev, parent;
2766	struct ahci_channel *ch;
2767
2768	CAM_DEBUG(ccb->ccb_h.path, CAM_DEBUG_TRACE, ("ahciaction func_code=%x\n",
2769	    ccb->ccb_h.func_code));
2770
2771	ch = (struct ahci_channel *)cam_sim_softc(sim);
2772	dev = ch->dev;
2773	switch (ccb->ccb_h.func_code) {
2774	/* Common cases first */
2775	case XPT_ATA_IO:	/* Execute the requested I/O operation */
2776	case XPT_SCSI_IO:
2777		if (ahci_check_ids(dev, ccb))
2778			return;
2779		if (ch->devices == 0 ||
2780		    (ch->pm_present == 0 &&
2781		     ccb->ccb_h.target_id > 0 && ccb->ccb_h.target_id < 15)) {
2782			ccb->ccb_h.status = CAM_SEL_TIMEOUT;
2783			break;
2784		}
2785		ccb->ccb_h.recovery_type = RECOVERY_NONE;
2786		/* Check for command collision. */
2787		if (ahci_check_collision(dev, ccb)) {
2788			/* Freeze command. */
2789			ch->frozen = ccb;
2790			/* We have only one frozen slot, so freeze simq also. */
2791			xpt_freeze_simq(ch->sim, 1);
2792			return;
2793		}
2794		ahci_begin_transaction(dev, ccb);
2795		return;
2796	case XPT_EN_LUN:		/* Enable LUN as a target */
2797	case XPT_TARGET_IO:		/* Execute target I/O request */
2798	case XPT_ACCEPT_TARGET_IO:	/* Accept Host Target Mode CDB */
2799	case XPT_CONT_TARGET_IO:	/* Continue Host Target I/O Connection*/
2800	case XPT_ABORT:			/* Abort the specified CCB */
2801		/* XXX Implement */
2802		ccb->ccb_h.status = CAM_REQ_INVALID;
2803		break;
2804	case XPT_SET_TRAN_SETTINGS:
2805	{
2806		struct	ccb_trans_settings *cts = &ccb->cts;
2807		struct	ahci_device *d;
2808
2809		if (ahci_check_ids(dev, ccb))
2810			return;
2811		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
2812			d = &ch->curr[ccb->ccb_h.target_id];
2813		else
2814			d = &ch->user[ccb->ccb_h.target_id];
2815		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_REVISION)
2816			d->revision = cts->xport_specific.sata.revision;
2817		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_MODE)
2818			d->mode = cts->xport_specific.sata.mode;
2819		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_BYTECOUNT)
2820			d->bytecount = min(8192, cts->xport_specific.sata.bytecount);
2821		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_TAGS)
2822			d->tags = min(ch->numslots, cts->xport_specific.sata.tags);
2823		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_PM)
2824			ch->pm_present = cts->xport_specific.sata.pm_present;
2825		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_ATAPI)
2826			d->atapi = cts->xport_specific.sata.atapi;
2827		if (cts->xport_specific.sata.valid & CTS_SATA_VALID_CAPS)
2828			d->caps = cts->xport_specific.sata.caps;
2829		ccb->ccb_h.status = CAM_REQ_CMP;
2830		break;
2831	}
2832	case XPT_GET_TRAN_SETTINGS:
2833	/* Get default/user set transfer settings for the target */
2834	{
2835		struct	ccb_trans_settings *cts = &ccb->cts;
2836		struct  ahci_device *d;
2837		uint32_t status;
2838
2839		if (ahci_check_ids(dev, ccb))
2840			return;
2841		if (cts->type == CTS_TYPE_CURRENT_SETTINGS)
2842			d = &ch->curr[ccb->ccb_h.target_id];
2843		else
2844			d = &ch->user[ccb->ccb_h.target_id];
2845		cts->protocol = PROTO_ATA;
2846		cts->protocol_version = PROTO_VERSION_UNSPECIFIED;
2847		cts->transport = XPORT_SATA;
2848		cts->transport_version = XPORT_VERSION_UNSPECIFIED;
2849		cts->proto_specific.valid = 0;
2850		cts->xport_specific.sata.valid = 0;
2851		if (cts->type == CTS_TYPE_CURRENT_SETTINGS &&
2852		    (ccb->ccb_h.target_id == 15 ||
2853		    (ccb->ccb_h.target_id == 0 && !ch->pm_present))) {
2854			status = ATA_INL(ch->r_mem, AHCI_P_SSTS) & ATA_SS_SPD_MASK;
2855			if (status & 0x0f0) {
2856				cts->xport_specific.sata.revision =
2857				    (status & 0x0f0) >> 4;
2858				cts->xport_specific.sata.valid |=
2859				    CTS_SATA_VALID_REVISION;
2860			}
2861			cts->xport_specific.sata.caps = d->caps & CTS_SATA_CAPS_D;
2862			if (ch->pm_level) {
2863				if (ch->caps & (AHCI_CAP_PSC | AHCI_CAP_SSC))
2864					cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_PMREQ;
2865				if (ch->caps2 & AHCI_CAP2_APST)
2866					cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_APST;
2867			}
2868			if ((ch->caps & AHCI_CAP_SNCQ) &&
2869			    (ch->quirks & AHCI_Q_NOAA) == 0)
2870				cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_DMAAA;
2871			cts->xport_specific.sata.caps |= CTS_SATA_CAPS_H_AN;
2872			cts->xport_specific.sata.caps &=
2873			    ch->user[ccb->ccb_h.target_id].caps;
2874			cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
2875		} else {
2876			cts->xport_specific.sata.revision = d->revision;
2877			cts->xport_specific.sata.valid |= CTS_SATA_VALID_REVISION;
2878			cts->xport_specific.sata.caps = d->caps;
2879			cts->xport_specific.sata.valid |= CTS_SATA_VALID_CAPS;
2880		}
2881		cts->xport_specific.sata.mode = d->mode;
2882		cts->xport_specific.sata.valid |= CTS_SATA_VALID_MODE;
2883		cts->xport_specific.sata.bytecount = d->bytecount;
2884		cts->xport_specific.sata.valid |= CTS_SATA_VALID_BYTECOUNT;
2885		cts->xport_specific.sata.pm_present = ch->pm_present;
2886		cts->xport_specific.sata.valid |= CTS_SATA_VALID_PM;
2887		cts->xport_specific.sata.tags = d->tags;
2888		cts->xport_specific.sata.valid |= CTS_SATA_VALID_TAGS;
2889		cts->xport_specific.sata.atapi = d->atapi;
2890		cts->xport_specific.sata.valid |= CTS_SATA_VALID_ATAPI;
2891		ccb->ccb_h.status = CAM_REQ_CMP;
2892		break;
2893	}
2894	case XPT_RESET_BUS:		/* Reset the specified SCSI bus */
2895	case XPT_RESET_DEV:	/* Bus Device Reset the specified SCSI device */
2896		ahci_reset(dev);
2897		ccb->ccb_h.status = CAM_REQ_CMP;
2898		break;
2899	case XPT_TERM_IO:		/* Terminate the I/O process */
2900		/* XXX Implement */
2901		ccb->ccb_h.status = CAM_REQ_INVALID;
2902		break;
2903	case XPT_PATH_INQ:		/* Path routing inquiry */
2904	{
2905		struct ccb_pathinq *cpi = &ccb->cpi;
2906
2907		parent = device_get_parent(dev);
2908		cpi->version_num = 1; /* XXX??? */
2909		cpi->hba_inquiry = PI_SDTR_ABLE;
2910		if (ch->caps & AHCI_CAP_SNCQ)
2911			cpi->hba_inquiry |= PI_TAG_ABLE;
2912		if (ch->caps & AHCI_CAP_SPM)
2913			cpi->hba_inquiry |= PI_SATAPM;
2914		cpi->target_sprt = 0;
2915		cpi->hba_misc = PIM_SEQSCAN;
2916		cpi->hba_eng_cnt = 0;
2917		if (ch->caps & AHCI_CAP_SPM)
2918			cpi->max_target = 15;
2919		else
2920			cpi->max_target = 0;
2921		cpi->max_lun = 0;
2922		cpi->initiator_id = 0;
2923		cpi->bus_id = cam_sim_bus(sim);
2924		cpi->base_transfer_speed = 150000;
2925		strncpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN);
2926		strncpy(cpi->hba_vid, "AHCI", HBA_IDLEN);
2927		strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
2928		cpi->unit_number = cam_sim_unit(sim);
2929		cpi->transport = XPORT_SATA;
2930		cpi->transport_version = XPORT_VERSION_UNSPECIFIED;
2931		cpi->protocol = PROTO_ATA;
2932		cpi->protocol_version = PROTO_VERSION_UNSPECIFIED;
2933		cpi->maxio = MAXPHYS;
2934		/* ATI SB600 can't handle 256 sectors with FPDMA (NCQ). */
2935		if (pci_get_devid(parent) == 0x43801002)
2936			cpi->maxio = min(cpi->maxio, 128 * 512);
2937		cpi->hba_vendor = pci_get_vendor(parent);
2938		cpi->hba_device = pci_get_device(parent);
2939		cpi->hba_subvendor = pci_get_subvendor(parent);
2940		cpi->hba_subdevice = pci_get_subdevice(parent);
2941		cpi->ccb_h.status = CAM_REQ_CMP;
2942		break;
2943	}
2944	default:
2945		ccb->ccb_h.status = CAM_REQ_INVALID;
2946		break;
2947	}
2948	xpt_done(ccb);
2949}
2950
2951static void
2952ahcipoll(struct cam_sim *sim)
2953{
2954	struct ahci_channel *ch = (struct ahci_channel *)cam_sim_softc(sim);
2955
2956	ahci_ch_intr(ch->dev);
2957	if (ch->resetting != 0 &&
2958	    (--ch->resetpolldiv <= 0 || !callout_pending(&ch->reset_timer))) {
2959		ch->resetpolldiv = 1000;
2960		ahci_reset_to(ch->dev);
2961	}
2962}
2963