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