1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22/*
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26
27#ifndef _AHCIVAR_H
28#define	_AHCIVAR_H
29
30#ifdef	__cplusplus
31extern "C" {
32#endif
33
34/*
35 * AHCI address qualifier flags (in qual field of ahci_addr struct).
36 */
37#define	AHCI_ADDR_NULL		0x00
38#define	AHCI_ADDR_PORT		0x01
39#define	AHCI_ADDR_PMPORT	0x02
40#define	AHCI_ADDR_PMULT		0x04
41#define	AHCI_ADDR_VALID		(AHCI_ADDR_PORT | \
42				AHCI_ADDR_PMULT | \
43				AHCI_ADDR_PMPORT)
44
45/*
46 * AHCI address structure.
47 */
48struct ahci_addr {
49
50	/* HBA port number */
51	uint8_t			aa_port;
52
53	/* Port multiplier port number */
54	uint8_t			aa_pmport;
55
56	/*
57	 * AHCI_ADDR_NULL
58	 * AHCI_ADDR_PORT
59	 * AHCI_ADDR_PMPORT
60	 * AHCI_ADDR_PMULT
61	 */
62	uint8_t			aa_qual;
63};
64typedef struct ahci_addr ahci_addr_t;
65
66_NOTE(SCHEME_PROTECTS_DATA("unshared data", ahci_addr))
67
68#define	AHCI_ADDR_IS_PORT(addrp)					\
69	((addrp)->aa_qual & AHCI_ADDR_PORT)
70#define	AHCI_ADDR_IS_PMPORT(addrp)					\
71	((addrp)->aa_qual & AHCI_ADDR_PMPORT)
72#define	AHCI_ADDR_IS_PMULT(addrp)					\
73	((addrp)->aa_qual & AHCI_ADDR_PMULT)
74#define	AHCI_ADDR_IS_VALID(addrp)					\
75	((addrp)->aa_port < SATA_MAX_CPORTS) &&				\
76	((addrp)->aa_pmport < SATA_MAX_PMPORTS) &&			\
77	((addrp)->aa_qual & AHCI_ADDR_VALID)
78
79#define	AHCI_ADDR_SET(addrp, port, pmport, qual)			\
80	{								\
81		(addrp)->aa_port = port;				\
82		(addrp)->aa_pmport = pmport;				\
83		(addrp)->aa_qual = qual;				\
84	}
85#define	AHCI_ADDR_SET_PORT(addrp, port)					\
86	AHCI_ADDR_SET(addrp, port, 0, AHCI_ADDR_PORT)
87#define	AHCI_ADDR_SET_PMPORT(addrp, port, pmport)			\
88	AHCI_ADDR_SET(addrp, port, pmport, AHCI_ADDR_PMPORT)
89#define	AHCI_ADDR_SET_PMULT(addrp, port)				\
90	AHCI_ADDR_SET(addrp, port, SATA_PMULT_HOSTPORT, AHCI_ADDR_PMULT)
91
92/* Type for argument of event handler */
93typedef	struct ahci_event_arg {
94	void		*ahciea_ctlp;
95	void		*ahciea_portp;
96	void		*ahciea_addrp;
97	uint32_t	ahciea_event;
98} ahci_event_arg_t;
99
100/* Warlock annotation */
101_NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_ctlp))
102_NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_portp))
103_NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_addrp))
104_NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_event))
105
106
107/*
108 * ahci_pmult_info stores the information of a port multiplier and its
109 * sub-devices in case a port multiplier is attached to an HBA port.
110 */
111struct ahci_pmult_info {
112
113	/* Number of the device ports */
114	int			ahcipmi_num_dev_ports;
115
116	/* Device type of the sub-devices of the port multipler */
117	uint8_t			ahcipmi_device_type[SATA_MAX_PMPORTS];
118
119	/* State of port multiplier port */
120	uint32_t		ahcipmi_port_state[SATA_MAX_PMPORTS];
121
122	/*
123	 * Port multiplier port on which there is outstanding NCQ
124	 * commands. Only make sense in command based switching mode.
125	 */
126	uint8_t			ahcipmi_ncq_pmport;
127
128	/* Pending asynchronous notification events tags */
129	uint32_t		ahcipmi_snotif_tags;
130};
131typedef struct ahci_pmult_info ahci_pmult_info_t;
132
133/*
134 * flags for ahciport_flags
135 *
136 * AHCI_PORT_FLAG_SPINUP: this flag will be set when a HBA which supports
137 * staggered spin-up needs to do a spin-up.
138 *
139 * AHCI_PORT_FLAG_MOPPING: this flag will be set when the HBA is stopped,
140 * and all the outstanding commands need to be aborted and sent to upper
141 * layers.
142 *
143 * AHCI_PORT_FLAG_POLLING: this flag will be set when the interrupt is
144 * disabled, and the command is executed in POLLING mode.
145 *
146 * AHCI_PORT_FLAG_RQSENSE: this flag will be set when a REQUEST SENSE which
147 * is used to retrieve sense data is being executed.
148 *
149 * AHCI_PORT_FLAG_STARTED: this flag will be set when the port is started,
150 * that is PxCMD.ST is set with '1', and be cleared when the port is put into
151 * idle, that is PxCMD.ST is changed from '1' to '0'.
152 *
153 * AHCI_PORT_FLAG_RDLOGEXT: this flag will be set when a READ LOG EXT which
154 * is used to retrieve NCQ failure context is being executed.
155 *
156 * AHCI_PORT_FLAG_NODEV: this flag will be set when a device is found gone
157 * during ahci_restart_port_wait_till_ready process.
158 *
159 * AHCI_PORT_FLAG_RDWR_PMULT: this flag will be set when a READ/WRITE
160 * PORTMULT command is being executed.
161 *
162 * AHCI_PORT_FLAG_IGNORE_IPMS: this flag will be set when enumerating a port
163 * multiplier. According AHCI spec, IPMS error should be ignore during
164 * enumeration of port multiplier.
165 *
166 * AHCI_PORT_FLAG_PMULT_SNTF: this flag will be set when the a asynchronous
167 * notification event on the port multiplier is being handled.
168 *
169 * AHCI_PORT_FLAG_HOTPLUG: this flag will be set when a hot plug event is
170 * being handled.
171 *
172 * AHCI_PORT_FLAG_ERRPRINT: this flag will be set when error recovery message
173 * will be printed. Note that, for INDENTIFY DEVICE command sent to ATAPI
174 * device or ATAPI PACKET command, this flag won't be set.
175 */
176#define	AHCI_PORT_FLAG_SPINUP		0x01
177#define	AHCI_PORT_FLAG_MOPPING		0x02
178#define	AHCI_PORT_FLAG_POLLING		0x04
179#define	AHCI_PORT_FLAG_RQSENSE		0x08
180#define	AHCI_PORT_FLAG_STARTED		0x10
181#define	AHCI_PORT_FLAG_RDLOGEXT		0x20
182#define	AHCI_PORT_FLAG_NODEV		0x40
183#define	AHCI_PORT_FLAG_RDWR_PMULT	0x80
184#define	AHCI_PORT_FLAG_IGNORE_IPMS	0x100
185#define	AHCI_PORT_FLAG_PMULT_SNTF	0x200
186#define	AHCI_PORT_FLAG_HOTPLUG		0x400
187#define	AHCI_PORT_FLAG_ERRPRINT		0x800
188
189typedef struct ahci_port {
190	/* The physical port number */
191	uint8_t			ahciport_port_num;
192
193	/* Type of the device attached to the port */
194	uint8_t			ahciport_device_type;
195	/* State of the port */
196	uint32_t		ahciport_port_state;
197
198	/* Port multiplier struct */
199	ahci_pmult_info_t	*ahciport_pmult_info;
200
201	/*
202	 * AHCI_PORT_FLAG_SPINUP
203	 * AHCI_PORT_FLAG_MOPPING
204	 * AHCI_PORT_FLAG_POLLING
205	 * AHCI_PORT_FLAG_RQSENSE
206	 * AHCI_PORT_FLAG_STARTED
207	 * AHCI_PORT_FLAG_RDLOGEXT
208	 * AHCI_PORT_FLAG_NODEV
209	 * AHCI_PORT_FLAG_RDWR_PMULT
210	 * AHCI_PORT_FLAG_IGNORE_IPMS
211	 * AHCI_PORT_FLAG_PMULT_SNTF
212	 * AHCI_PORT_FLAG_HOTPLUG
213	 * AHCI_PORT_FLAG_ERRPRINT
214	 */
215	int			ahciport_flags;
216
217	/* Pointer to received FIS structure */
218	ahci_rcvd_fis_t		*ahciport_rcvd_fis;
219	ddi_dma_handle_t	ahciport_rcvd_fis_dma_handle;
220	ddi_acc_handle_t	ahciport_rcvd_fis_acc_handle;
221	ddi_dma_cookie_t	ahciport_rcvd_fis_dma_cookie;
222
223	/* Pointer to command list structure */
224	ahci_cmd_header_t	*ahciport_cmd_list;
225	ddi_dma_handle_t	ahciport_cmd_list_dma_handle;
226	ddi_acc_handle_t	ahciport_cmd_list_acc_handle;
227	ddi_dma_cookie_t	ahciport_cmd_list_dma_cookie;
228
229	/* Pointer to cmmand table structure */
230	ahci_cmd_table_t	\
231			*ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS];
232	ddi_dma_handle_t	\
233			ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS];
234	ddi_acc_handle_t	\
235			ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS];
236
237	/* Condition variable used for sync mode commands */
238	kcondvar_t		ahciport_cv;
239
240	/* The whole mutex for the port structure */
241	kmutex_t		ahciport_mutex;
242
243	/* The maximum number of tags for native queuing command transfers */
244	int			ahciport_max_ncq_tags;
245
246	/* Keep the tags of all pending non-ncq commands */
247	uint32_t		ahciport_pending_tags;
248
249	/*
250	 * Keep the tags of all pending ncq commands
251	 * (READ/WRITE FPDMA QUEUED)
252	 */
253	uint32_t		ahciport_pending_ncq_tags;
254
255	/* Keep all the pending sata packets */
256	sata_pkt_t		*ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS];
257
258	/* Used to check whether corresponding packet is timeout */
259	int			ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS];
260
261	/* Queue of completed (done) sata packet */
262	sata_pkt_t		*ahciport_doneq;
263
264	/* Pointer of the tail of completed sata packet queue */
265	sata_pkt_t		**ahciport_doneqtail;
266
267	/* the length of the completed sata packet queue */
268	uint32_t		ahciport_doneq_len;
269
270	/* Keep the byte count of all PRD entries for every sata packet */
271	uint32_t		\
272			ahciport_prd_bytecounts[AHCI_PORT_MAX_CMD_SLOTS];
273
274	/* Keep the error retrieval sata packet */
275	sata_pkt_t		*ahciport_err_retri_pkt;
276
277	/* Keep the read/write port multiplier packet */
278	sata_pkt_t		*ahciport_rdwr_pmult_pkt;
279
280	/*
281	 * SATA HBA driver is supposed to remember and maintain device
282	 * reset state. While the reset is in progress, it doesn't accept
283	 * any more commands until receiving the command with
284	 * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE.
285	 */
286	int			ahciport_reset_in_progress;
287
288	/* Taskq for handling event */
289	ddi_taskq_t		*ahciport_event_taskq;
290
291	/* This is for error recovery handler */
292	ahci_event_arg_t	*ahciport_event_args;
293
294	/* This is to calculate how many mops are in progress */
295	int			ahciport_mop_in_progress;
296} ahci_port_t;
297
298/* Warlock annotation */
299_NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle))
300_NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle))
301_NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle))
302_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
303				    ahci_port_t::ahciport_device_type))
304_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
305				    ahci_port_t::ahciport_port_state))
306_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
307				    ahci_port_t::ahciport_flags))
308_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
309				    ahci_port_t::ahciport_pending_tags))
310_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
311				    ahci_port_t::ahciport_slot_pkts))
312_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
313				    ahci_port_t::ahciport_slot_timeout))
314_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
315				    ahci_port_t::ahciport_doneq))
316_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
317				    ahci_port_t::ahciport_doneqtail))
318_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
319				    ahci_port_t::ahciport_doneq_len))
320_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
321				    ahci_port_t::ahciport_reset_in_progress))
322_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
323				    ahci_port_t::ahciport_mop_in_progress))
324_NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
325				    ahci_port_t::ahciport_event_taskq))
326
327#define	AHCI_NUM_PORTS(ctlp)						\
328	(ctlp)->ahcictl_num_ports
329
330#define	AHCIPORT_NUM_PMPORTS(portp)					\
331	(portp)->ahciport_pmult_info->ahcipmi_num_dev_ports
332
333#define	AHCIPORT_NCQ_PMPORT(ahci_portp)					\
334	(ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport)
335
336#define	AHCIPORT_DEV_TYPE(portp, addrp)					\
337	(portp)->ahciport_device_type
338
339#define	AHCIPORT_PMDEV_TYPE(portp, addrp)				\
340	(portp)->ahciport_pmult_info->ahcipmi_device_type		\
341	[(addrp)->aa_pmport]
342
343#define	AHCIPORT_GET_DEV_TYPE(portp, addrp)				\
344	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
345	AHCIPORT_DEV_TYPE(portp, addrp) :				\
346	AHCIPORT_PMDEV_TYPE(portp, addrp))
347
348#define	AHCIPORT_SET_DEV_TYPE(portp, addrp, type)			\
349	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
350		AHCIPORT_DEV_TYPE(portp, addrp) = type;			\
351	else								\
352		AHCIPORT_PMDEV_TYPE(portp, addrp) = type;
353
354#define	AHCIPORT_STATE(portp, addrp)					\
355	(portp)->ahciport_port_state
356
357#define	AHCIPORT_PMSTATE(portp, addrp)					\
358	(portp)->ahciport_pmult_info->ahcipmi_port_state		\
359	[(addrp)->aa_pmport]
360
361#define	AHCIPORT_GET_STATE(portp, addrp)				\
362	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
363	AHCIPORT_STATE(portp, addrp) : AHCIPORT_PMSTATE(portp, addrp))
364
365#define	AHCIPORT_SET_STATE(portp, addrp, state)				\
366	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
367		AHCIPORT_STATE(portp, addrp) = state;			\
368	else								\
369		AHCIPORT_PMSTATE(portp, addrp) = state;
370
371typedef struct ahci_ctl {
372	dev_info_t		*ahcictl_dip;
373
374	ushort_t		ahcictl_venid;
375	ushort_t		ahcictl_devid;
376
377	/* To map port number to cport number */
378	uint8_t			ahcictl_port_to_cport[AHCI_MAX_PORTS];
379	/* To map cport number to port number */
380	uint8_t			ahcictl_cport_to_port[AHCI_MAX_PORTS];
381
382	/* Number of controller ports */
383	int			ahcictl_num_ports;
384	/* Number of command slots */
385	int			ahcictl_num_cmd_slots;
386	/* Number of implemented ports */
387	int			ahcictl_num_implemented_ports;
388	/* Bit map to indicate which port is implemented */
389	uint32_t		ahcictl_ports_implemented;
390	ahci_port_t		*ahcictl_ports[AHCI_MAX_PORTS];
391
392	int			ahcictl_flags;
393	int			ahcictl_power_level;
394	off_t			ahcictl_pmcsr_offset;
395
396	/*
397	 * AHCI_CAP_PIO_MDRQ
398	 * AHCI_CAP_NO_MCMDLIST_NONQUEUE
399	 * AHCI_CAP_NCQ
400	 * AHCI_CAP_PM
401	 * AHCI_CAP_BUF_32BIT_DMA
402	 * AHCI_CAP_SCLO
403	 * AHCI_CAP_COMMU_32BIT_DMA
404	 * AHCI_CAP_INIT_PORT_RESET
405	 * AHCI_CAP_SNTF
406	 * AHCI_CAP_PMULT_CBSS
407	 * AHCI_CAP_PMULT_FBSS
408	 * AHCI_CAP_SRST_NO_HOSTPORT
409	 */
410	int			ahcictl_cap;
411
412	/* Pci configuration space handle */
413	ddi_acc_handle_t	ahcictl_pci_conf_handle;
414
415	/* Mapping into bar 5 - AHCI base address */
416	ddi_acc_handle_t	ahcictl_ahci_acc_handle;
417	uintptr_t		ahcictl_ahci_addr;
418
419	/* Pointer used for sata hba framework registration */
420	struct sata_hba_tran	*ahcictl_sata_hba_tran;
421
422	/* DMA attributes for the data buffer */
423	ddi_dma_attr_t		ahcictl_buffer_dma_attr;
424	/* DMA attributes for the rcvd FIS */
425	ddi_dma_attr_t		ahcictl_rcvd_fis_dma_attr;
426	/* DMA attributes for the command list */
427	ddi_dma_attr_t		ahcictl_cmd_list_dma_attr;
428	/* DMA attributes for command tables */
429	ddi_dma_attr_t		ahcictl_cmd_table_dma_attr;
430
431	/* Used for watchdog handler */
432	timeout_id_t		ahcictl_timeout_id;
433
434	/* Per controller mutex */
435	kmutex_t		ahcictl_mutex;
436
437	/* Components for interrupt */
438	ddi_intr_handle_t	*ahcictl_intr_htable;   /* For array of intrs */
439	int			ahcictl_intr_type; /* What type of interrupt */
440	int			ahcictl_intr_cnt;  /* # of intrs returned */
441	size_t			ahcictl_intr_size; /* Size of intr array */
442	uint_t			ahcictl_intr_pri;  /* Intr priority */
443	int			ahcictl_intr_cap;  /* Intr capabilities */
444
445	/* FMA capabilities */
446	int			ahcictl_fm_cap;
447} ahci_ctl_t;
448
449/* Warlock annotation */
450_NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports))
451_NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port))
452_NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport))
453
454_NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
455					ahci_ctl_t::ahcictl_power_level))
456_NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
457					ahci_ctl_t::ahcictl_flags))
458_NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
459					ahci_ctl_t::ahcictl_timeout_id))
460
461#define	AHCI_SUCCESS	(0)  /* Successful return */
462#define	AHCI_TIMEOUT	(1)  /* Timed out */
463#define	AHCI_FAILURE	(-1) /* Unsuccessful return */
464
465/* Flags for ahcictl_flags */
466#define	AHCI_ATTACH		0x1
467#define	AHCI_DETACH		0x2
468#define	AHCI_SUSPEND		0x4
469
470/* Values for ahcictl_cap */
471/* PIO Multiple DRQ Block */
472#define	AHCI_CAP_PIO_MDRQ		0x1
473/*
474 * Multiple command slots in the command list cannot be used for
475 * non-queued commands
476 */
477#define	AHCI_CAP_NO_MCMDLIST_NONQUEUE	0x2
478/* Native Command Queuing (NCQ) */
479#define	AHCI_CAP_NCQ			0x4
480/* Power Management (PM) */
481#define	AHCI_CAP_PM			0x8
482/* 32-bit DMA addressing for buffer block */
483#define	AHCI_CAP_BUF_32BIT_DMA		0x10
484/* Supports Command List Override */
485#define	AHCI_CAP_SCLO			0x20
486/* 32-bit DMA addressing for communication memory descriptors */
487#define	AHCI_CAP_COMMU_32BIT_DMA	0x40
488/* Port reset is needed for initialization */
489#define	AHCI_CAP_INIT_PORT_RESET	0x80
490/* Port Asychronous Notification */
491#define	AHCI_CAP_SNTF			0x100
492/* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */
493#define	AHCI_CAP_PMULT_CBSS		0x200
494/* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */
495#define	AHCI_CAP_PMULT_FBSS		0x400
496/* Software Reset FIS cannot set pmport with 0xf for direct access device */
497#define	AHCI_CAP_SRST_NO_HOSTPORT	0x800
498
499/* Flags controlling the restart port behavior */
500#define	AHCI_PORT_RESET		0x0001	/* Reset the port */
501#define	AHCI_RESET_NO_EVENTS_UP	0x0002	/* Don't send reset events up */
502
503#define	ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)		\
504	(ahci_portp->ahciport_flags &			\
505	(AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
506
507#define	RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)		\
508	(ahci_portp->ahciport_flags &			\
509	AHCI_PORT_FLAG_RDWR_PMULT)
510
511#define	NON_NCQ_CMD_IN_PROGRESS(ahci_portp)		\
512	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
513	ahci_portp->ahciport_pending_tags != 0 &&	\
514	ahci_portp->ahciport_pending_ncq_tags == 0)
515
516#define	NCQ_CMD_IN_PROGRESS(ahci_portp)			\
517	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
518	ahci_portp->ahciport_pending_ncq_tags != 0)
519
520/* Command type for ahci_claim_free_slot routine */
521#define	AHCI_NON_NCQ_CMD	0x0
522#define	AHCI_NCQ_CMD		0x1
523#define	AHCI_ERR_RETRI_CMD	0x2
524#define	AHCI_RDWR_PMULT_CMD	0x4
525
526/* State values for ahci_attach */
527#define	AHCI_ATTACH_STATE_NONE			(0x1 << 0)
528#define	AHCI_ATTACH_STATE_STATEP_ALLOC		(0x1 << 1)
529#define	AHCI_ATTACH_STATE_FMA			(0x1 << 2)
530#define	AHCI_ATTACH_STATE_REG_MAP		(0x1 << 3)
531#define	AHCI_ATTACH_STATE_PCICFG_SETUP		(0x1 << 4)
532#define	AHCI_ATTACH_STATE_INTR_ADDED		(0x1 << 5)
533#define	AHCI_ATTACH_STATE_MUTEX_INIT		(0x1 << 6)
534#define	AHCI_ATTACH_STATE_PORT_ALLOC		(0x1 << 7)
535#define	AHCI_ATTACH_STATE_HW_INIT		(0x1 << 8)
536#define	AHCI_ATTACH_STATE_TIMEOUT_ENABLED	(0x1 << 9)
537
538/* Interval used for delay */
539#define	AHCI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 ms */
540#define	AHCI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 ms */
541#define	AHCI_100US_TICKS	(drv_usectohz(100))	/* ticks in 100 us */
542#define	AHCI_10MS_USECS		(10000)		/* microsecs in 10 millisec */
543#define	AHCI_1MS_USECS		(1000)		/* microsecs in 1 millisec */
544#define	AHCI_100US_USECS	(100)
545
546/*
547 * The following values are the numbers of times to retry polled requests.
548 */
549#define	AHCI_POLLRATE_HBA_RESET		100
550#define	AHCI_POLLRATE_PORT_SSTATUS	10
551#define	AHCI_POLLRATE_PORT_TFD_ERROR	1100
552#define	AHCI_POLLRATE_PORT_IDLE		50
553#define	AHCI_POLLRATE_PORT_SOFTRESET	100
554#define	AHCI_POLLRATE_GET_SPKT		100
555
556
557/* Clearing & setting the n'th bit in a given tag */
558#define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
559#define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
560
561
562#if DEBUG
563
564#define	AHCI_DEBUG		1
565
566#endif
567
568#define	AHCIDBG_INIT		0x0001
569#define	AHCIDBG_ENTRY		0x0002
570#define	AHCIDBG_PRDT		0x0004
571#define	AHCIDBG_EVENT		0x0008
572#define	AHCIDBG_POLL_LOOP	0x0010
573#define	AHCIDBG_PKTCOMP		0x0020
574#define	AHCIDBG_TIMEOUT		0x0040
575#define	AHCIDBG_INFO		0x0080
576#define	AHCIDBG_VERBOSE		0x0100
577#define	AHCIDBG_INTR		0x0200
578#define	AHCIDBG_ERRS		0x0400
579#define	AHCIDBG_ATACMD		0x0800
580#define	AHCIDBG_ATAPICMD	0x1000
581#define	AHCIDBG_SENSEDATA	0x2000
582#define	AHCIDBG_NCQ		0x4000
583#define	AHCIDBG_PM		0x8000
584#define	AHCIDBG_UNDERFLOW	0x10000
585#define	AHCIDBG_MSI		0x20000
586#define	AHCIDBG_PMULT		0x40000
587
588extern uint32_t ahci_debug_flags;
589
590#if DEBUG
591
592#define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
593	if (ahci_debug_flags & (flag)) {			\
594		ahci_log(ahci_ctlp, CE_WARN, fmt, ## args);	\
595		if (ahci_ctlp == NULL)				\
596			sata_trace_debug(NULL, fmt, ## args);	\
597		else						\
598			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
599			    fmt, ## args);			\
600	}
601
602#else
603
604#define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
605	if (ahci_debug_flags & (flag)) {			\
606		if (ahci_ctlp == NULL)				\
607			sata_trace_debug(NULL, fmt, ## args);	\
608		else						\
609			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
610			    fmt, ## args);			\
611	}
612
613#endif /* DEBUG */
614
615
616#ifdef	__cplusplus
617}
618#endif
619
620#endif /* _AHCIVAR_H */
621