xref: /illumos-gate/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h (revision 3e95bd4ab92abca814bd28e854607d1975c7dc88)
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
31 extern "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  */
48 struct 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 };
64 typedef 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 */
93 typedef	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  */
111 struct 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 };
131 typedef 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 #define	AHCI_PORT_FLAG_SPINUP		0x01
173 #define	AHCI_PORT_FLAG_MOPPING		0x02
174 #define	AHCI_PORT_FLAG_POLLING		0x04
175 #define	AHCI_PORT_FLAG_RQSENSE		0x08
176 #define	AHCI_PORT_FLAG_STARTED		0x10
177 #define	AHCI_PORT_FLAG_RDLOGEXT		0x20
178 #define	AHCI_PORT_FLAG_NODEV		0x40
179 #define	AHCI_PORT_FLAG_RDWR_PMULT	0x80
180 #define	AHCI_PORT_FLAG_IGNORE_IPMS	0x100
181 #define	AHCI_PORT_FLAG_PMULT_SNTF	0x200
182 #define	AHCI_PORT_FLAG_HOTPLUG		0x400
183 
184 typedef struct ahci_port {
185 	/* The physical port number */
186 	uint8_t			ahciport_port_num;
187 
188 	/* Type of the device attached to the port */
189 	uint8_t			ahciport_device_type;
190 	/* State of the port */
191 	uint32_t		ahciport_port_state;
192 
193 	/* Port multiplier struct */
194 	ahci_pmult_info_t	*ahciport_pmult_info;
195 
196 	/*
197 	 * AHCI_PORT_FLAG_SPINUP
198 	 * AHCI_PORT_FLAG_MOPPING
199 	 * AHCI_PORT_FLAG_POLLING
200 	 * AHCI_PORT_FLAG_RQSENSE
201 	 * AHCI_PORT_FLAG_STARTED
202 	 * AHCI_PORT_FLAG_RDLOGEXT
203 	 * AHCI_PORT_FLAG_NODEV
204 	 * AHCI_PORT_FLAG_RDWR_PMULT
205 	 * AHCI_PORT_FLAG_IGNORE_IPMS
206 	 * AHCI_PORT_FLAG_PMULT_SNTF
207 	 * AHCI_PORT_FLAG_HOTPLUG
208 	 */
209 	int			ahciport_flags;
210 
211 	/* Pointer to received FIS structure */
212 	ahci_rcvd_fis_t		*ahciport_rcvd_fis;
213 	ddi_dma_handle_t	ahciport_rcvd_fis_dma_handle;
214 	ddi_acc_handle_t	ahciport_rcvd_fis_acc_handle;
215 	ddi_dma_cookie_t	ahciport_rcvd_fis_dma_cookie;
216 
217 	/* Pointer to command list structure */
218 	ahci_cmd_header_t	*ahciport_cmd_list;
219 	ddi_dma_handle_t	ahciport_cmd_list_dma_handle;
220 	ddi_acc_handle_t	ahciport_cmd_list_acc_handle;
221 	ddi_dma_cookie_t	ahciport_cmd_list_dma_cookie;
222 
223 	/* Pointer to cmmand table structure */
224 	ahci_cmd_table_t	\
225 			*ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS];
226 	ddi_dma_handle_t	\
227 			ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS];
228 	ddi_acc_handle_t	\
229 			ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS];
230 
231 	/* Condition variable used for sync mode commands */
232 	kcondvar_t		ahciport_cv;
233 
234 	/* The whole mutex for the port structure */
235 	kmutex_t		ahciport_mutex;
236 
237 	/* The maximum number of tags for native queuing command transfers */
238 	int			ahciport_max_ncq_tags;
239 
240 	/* Keep the tags of all pending non-ncq commands */
241 	uint32_t		ahciport_pending_tags;
242 
243 	/*
244 	 * Keep the tags of all pending ncq commands
245 	 * (READ/WRITE FPDMA QUEUED)
246 	 */
247 	uint32_t		ahciport_pending_ncq_tags;
248 
249 	/* Keep all the pending sata packets */
250 	sata_pkt_t		*ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS];
251 
252 	/* Used to check whether corresponding packet is timeout */
253 	int			ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS];
254 
255 	/* Queue of completed (done) sata packet */
256 	sata_pkt_t		*ahciport_doneq;
257 
258 	/* Pointer of the tail of completed sata packet queue */
259 	sata_pkt_t		**ahciport_doneqtail;
260 
261 	/* the length of the completed sata packet queue */
262 	uint32_t		ahciport_doneq_len;
263 
264 	/* Keep the byte count of all PRD entries for every sata packet */
265 	uint32_t		\
266 			ahciport_prd_bytecounts[AHCI_PORT_MAX_CMD_SLOTS];
267 
268 	/* Keep the error retrieval sata packet */
269 	sata_pkt_t		*ahciport_err_retri_pkt;
270 
271 	/* Keep the read/write port multiplier packet */
272 	sata_pkt_t		*ahciport_rdwr_pmult_pkt;
273 
274 	/*
275 	 * SATA HBA driver is supposed to remember and maintain device
276 	 * reset state. While the reset is in progress, it doesn't accept
277 	 * any more commands until receiving the command with
278 	 * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE.
279 	 */
280 	int			ahciport_reset_in_progress;
281 
282 	/* Taskq for handling event */
283 	ddi_taskq_t		*ahciport_event_taskq;
284 
285 	/* This is for error recovery handler */
286 	ahci_event_arg_t	*ahciport_event_args;
287 
288 	/* This is to calculate how many mops are in progress */
289 	int			ahciport_mop_in_progress;
290 } ahci_port_t;
291 
292 /* Warlock annotation */
293 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle))
294 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle))
295 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle))
296 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
297 				    ahci_port_t::ahciport_device_type))
298 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
299 				    ahci_port_t::ahciport_port_state))
300 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
301 				    ahci_port_t::ahciport_flags))
302 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
303 				    ahci_port_t::ahciport_pending_tags))
304 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
305 				    ahci_port_t::ahciport_slot_pkts))
306 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
307 				    ahci_port_t::ahciport_slot_timeout))
308 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
309 				    ahci_port_t::ahciport_doneq))
310 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
311 				    ahci_port_t::ahciport_doneqtail))
312 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
313 				    ahci_port_t::ahciport_doneq_len))
314 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
315 				    ahci_port_t::ahciport_reset_in_progress))
316 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
317 				    ahci_port_t::ahciport_mop_in_progress))
318 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
319 				    ahci_port_t::ahciport_event_taskq))
320 
321 #define	AHCI_NUM_PORTS(ctlp)						\
322 	(ctlp)->ahcictl_num_ports
323 
324 #define	AHCIPORT_NUM_PMPORTS(portp)					\
325 	(portp)->ahciport_pmult_info->ahcipmi_num_dev_ports
326 
327 #define	AHCIPORT_NCQ_PMPORT(ahci_portp)					\
328 	(ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport)
329 
330 #define	AHCIPORT_DEV_TYPE(portp, addrp)					\
331 	(portp)->ahciport_device_type
332 
333 #define	AHCIPORT_PMDEV_TYPE(portp, addrp)				\
334 	(portp)->ahciport_pmult_info->ahcipmi_device_type		\
335 	[(addrp)->aa_pmport]
336 
337 #define	AHCIPORT_GET_DEV_TYPE(portp, addrp)				\
338 	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
339 	AHCIPORT_DEV_TYPE(portp, addrp) :				\
340 	AHCIPORT_PMDEV_TYPE(portp, addrp))
341 
342 #define	AHCIPORT_SET_DEV_TYPE(portp, addrp, type)			\
343 	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
344 		AHCIPORT_DEV_TYPE(portp, addrp) = type;			\
345 	else								\
346 		AHCIPORT_PMDEV_TYPE(portp, addrp) = type;
347 
348 #define	AHCIPORT_STATE(portp, addrp)					\
349 	(portp)->ahciport_port_state
350 
351 #define	AHCIPORT_PMSTATE(portp, addrp)					\
352 	(portp)->ahciport_pmult_info->ahcipmi_port_state		\
353 	[(addrp)->aa_pmport]
354 
355 #define	AHCIPORT_GET_STATE(portp, addrp)				\
356 	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
357 	AHCIPORT_STATE(portp, addrp) : AHCIPORT_PMSTATE(portp, addrp))
358 
359 #define	AHCIPORT_SET_STATE(portp, addrp, state)				\
360 	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
361 		AHCIPORT_STATE(portp, addrp) = state;			\
362 	else								\
363 		AHCIPORT_PMSTATE(portp, addrp) = state;
364 
365 typedef struct ahci_ctl {
366 	dev_info_t		*ahcictl_dip;
367 
368 	ushort_t		ahcictl_venid;
369 	ushort_t		ahcictl_devid;
370 
371 	/* To map port number to cport number */
372 	uint8_t			ahcictl_port_to_cport[AHCI_MAX_PORTS];
373 	/* To map cport number to port number */
374 	uint8_t			ahcictl_cport_to_port[AHCI_MAX_PORTS];
375 
376 	/* Number of controller ports */
377 	int			ahcictl_num_ports;
378 	/* Number of command slots */
379 	int			ahcictl_num_cmd_slots;
380 	/* Number of implemented ports */
381 	int			ahcictl_num_implemented_ports;
382 	/* Bit map to indicate which port is implemented */
383 	uint32_t		ahcictl_ports_implemented;
384 	ahci_port_t		*ahcictl_ports[AHCI_MAX_PORTS];
385 
386 	int			ahcictl_flags;
387 	int			ahcictl_power_level;
388 	off_t			ahcictl_pmcsr_offset;
389 
390 	/*
391 	 * AHCI_CAP_PIO_MDRQ
392 	 * AHCI_CAP_NO_MCMDLIST_NONQUEUE
393 	 * AHCI_CAP_NCQ
394 	 * AHCI_CAP_PM
395 	 * AHCI_CAP_BUF_32BIT_DMA
396 	 * AHCI_CAP_SCLO
397 	 * AHCI_CAP_COMMU_32BIT_DMA
398 	 * AHCI_CAP_INIT_PORT_RESET
399 	 * AHCI_CAP_SNTF
400 	 * AHCI_CAP_PMULT_CBSS
401 	 * AHCI_CAP_PMULT_FBSS
402 	 * AHCI_CAP_SRST_NO_HOSTPORT
403 	 */
404 	int			ahcictl_cap;
405 
406 	/* Pci configuration space handle */
407 	ddi_acc_handle_t	ahcictl_pci_conf_handle;
408 
409 	/* Mapping into bar 5 - AHCI base address */
410 	ddi_acc_handle_t	ahcictl_ahci_acc_handle;
411 	uintptr_t		ahcictl_ahci_addr;
412 
413 	/* Pointer used for sata hba framework registration */
414 	struct sata_hba_tran	*ahcictl_sata_hba_tran;
415 
416 	/* DMA attributes for the data buffer */
417 	ddi_dma_attr_t		ahcictl_buffer_dma_attr;
418 	/* DMA attributes for the rcvd FIS */
419 	ddi_dma_attr_t		ahcictl_rcvd_fis_dma_attr;
420 	/* DMA attributes for the command list */
421 	ddi_dma_attr_t		ahcictl_cmd_list_dma_attr;
422 	/* DMA attributes for command tables */
423 	ddi_dma_attr_t		ahcictl_cmd_table_dma_attr;
424 
425 	/* Used for watchdog handler */
426 	timeout_id_t		ahcictl_timeout_id;
427 
428 	/* Per controller mutex */
429 	kmutex_t		ahcictl_mutex;
430 
431 	/* Components for interrupt */
432 	ddi_intr_handle_t	*ahcictl_intr_htable;   /* For array of intrs */
433 	int			ahcictl_intr_type; /* What type of interrupt */
434 	int			ahcictl_intr_cnt;  /* # of intrs returned */
435 	size_t			ahcictl_intr_size; /* Size of intr array */
436 	uint_t			ahcictl_intr_pri;  /* Intr priority */
437 	int			ahcictl_intr_cap;  /* Intr capabilities */
438 
439 	/* FMA capabilities */
440 	int			ahcictl_fm_cap;
441 } ahci_ctl_t;
442 
443 /* Warlock annotation */
444 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports))
445 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port))
446 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport))
447 
448 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
449 					ahci_ctl_t::ahcictl_power_level))
450 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
451 					ahci_ctl_t::ahcictl_flags))
452 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
453 					ahci_ctl_t::ahcictl_timeout_id))
454 
455 #define	AHCI_SUCCESS	(0)  /* Successful return */
456 #define	AHCI_TIMEOUT	(1)  /* Timed out */
457 #define	AHCI_FAILURE	(-1) /* Unsuccessful return */
458 
459 /* Flags for ahcictl_flags */
460 #define	AHCI_ATTACH		0x1
461 #define	AHCI_DETACH		0x2
462 #define	AHCI_SUSPEND		0x4
463 
464 /* Values for ahcictl_cap */
465 /* PIO Multiple DRQ Block */
466 #define	AHCI_CAP_PIO_MDRQ		0x1
467 /*
468  * Multiple command slots in the command list cannot be used for
469  * non-queued commands
470  */
471 #define	AHCI_CAP_NO_MCMDLIST_NONQUEUE	0x2
472 /* Native Command Queuing (NCQ) */
473 #define	AHCI_CAP_NCQ			0x4
474 /* Power Management (PM) */
475 #define	AHCI_CAP_PM			0x8
476 /* 32-bit DMA addressing for buffer block */
477 #define	AHCI_CAP_BUF_32BIT_DMA		0x10
478 /* Supports Command List Override */
479 #define	AHCI_CAP_SCLO			0x20
480 /* 32-bit DMA addressing for communication memory descriptors */
481 #define	AHCI_CAP_COMMU_32BIT_DMA	0x40
482 /* Port reset is needed for initialization */
483 #define	AHCI_CAP_INIT_PORT_RESET	0x80
484 /* Port Asychronous Notification */
485 #define	AHCI_CAP_SNTF			0x100
486 /* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */
487 #define	AHCI_CAP_PMULT_CBSS		0x200
488 /* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */
489 #define	AHCI_CAP_PMULT_FBSS		0x400
490 /* Software Reset FIS cannot set pmport with 0xf for direct access device */
491 #define	AHCI_CAP_SRST_NO_HOSTPORT	0x800
492 
493 /* Flags controlling the restart port behavior */
494 #define	AHCI_PORT_RESET		0x0001	/* Reset the port */
495 #define	AHCI_RESET_NO_EVENTS_UP	0x0002	/* Don't send reset events up */
496 
497 #define	ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)		\
498 	(ahci_portp->ahciport_flags &			\
499 	(AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
500 
501 #define	RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)		\
502 	(ahci_portp->ahciport_flags &			\
503 	AHCI_PORT_FLAG_RDWR_PMULT)
504 
505 #define	NON_NCQ_CMD_IN_PROGRESS(ahci_portp)		\
506 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
507 	ahci_portp->ahciport_pending_tags != 0 &&	\
508 	ahci_portp->ahciport_pending_ncq_tags == 0)
509 
510 #define	NCQ_CMD_IN_PROGRESS(ahci_portp)			\
511 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
512 	ahci_portp->ahciport_pending_ncq_tags != 0)
513 
514 /* Command type for ahci_claim_free_slot routine */
515 #define	AHCI_NON_NCQ_CMD	0x0
516 #define	AHCI_NCQ_CMD		0x1
517 #define	AHCI_ERR_RETRI_CMD	0x2
518 #define	AHCI_RDWR_PMULT_CMD	0x4
519 
520 /* State values for ahci_attach */
521 #define	AHCI_ATTACH_STATE_NONE			(0x1 << 0)
522 #define	AHCI_ATTACH_STATE_STATEP_ALLOC		(0x1 << 1)
523 #define	AHCI_ATTACH_STATE_FMA			(0x1 << 2)
524 #define	AHCI_ATTACH_STATE_REG_MAP		(0x1 << 3)
525 #define	AHCI_ATTACH_STATE_PCICFG_SETUP		(0x1 << 4)
526 #define	AHCI_ATTACH_STATE_INTR_ADDED		(0x1 << 5)
527 #define	AHCI_ATTACH_STATE_MUTEX_INIT		(0x1 << 6)
528 #define	AHCI_ATTACH_STATE_PORT_ALLOC		(0x1 << 7)
529 #define	AHCI_ATTACH_STATE_HW_INIT		(0x1 << 8)
530 #define	AHCI_ATTACH_STATE_TIMEOUT_ENABLED	(0x1 << 9)
531 
532 /* Interval used for delay */
533 #define	AHCI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 ms */
534 #define	AHCI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 ms */
535 #define	AHCI_100US_TICKS	(drv_usectohz(100))	/* ticks in 100 us */
536 #define	AHCI_10MS_USECS		(10000)		/* microsecs in 10 millisec */
537 #define	AHCI_1MS_USECS		(1000)		/* microsecs in 1 millisec */
538 #define	AHCI_100US_USECS	(100)
539 
540 /*
541  * The following values are the numbers of times to retry polled requests.
542  */
543 #define	AHCI_POLLRATE_HBA_RESET		100
544 #define	AHCI_POLLRATE_PORT_SSTATUS	10
545 #define	AHCI_POLLRATE_PORT_TFD_ERROR	1100
546 #define	AHCI_POLLRATE_PORT_IDLE		50
547 #define	AHCI_POLLRATE_PORT_SOFTRESET	100
548 #define	AHCI_POLLRATE_GET_SPKT		100
549 
550 
551 /* Clearing & setting the n'th bit in a given tag */
552 #define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
553 #define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
554 
555 
556 #if DEBUG
557 
558 #define	AHCI_DEBUG		1
559 
560 #endif
561 
562 #define	AHCIDBG_INIT		0x0001
563 #define	AHCIDBG_ENTRY		0x0002
564 #define	AHCIDBG_PRDT		0x0004
565 #define	AHCIDBG_EVENT		0x0008
566 #define	AHCIDBG_POLL_LOOP	0x0010
567 #define	AHCIDBG_PKTCOMP		0x0020
568 #define	AHCIDBG_TIMEOUT		0x0040
569 #define	AHCIDBG_INFO		0x0080
570 #define	AHCIDBG_VERBOSE		0x0100
571 #define	AHCIDBG_INTR		0x0200
572 #define	AHCIDBG_ERRS		0x0400
573 #define	AHCIDBG_ATACMD		0x0800
574 #define	AHCIDBG_ATAPICMD	0x1000
575 #define	AHCIDBG_SENSEDATA	0x2000
576 #define	AHCIDBG_NCQ		0x4000
577 #define	AHCIDBG_PM		0x8000
578 #define	AHCIDBG_UNDERFLOW	0x10000
579 #define	AHCIDBG_MSI		0x20000
580 #define	AHCIDBG_PMULT		0x40000
581 
582 extern uint32_t ahci_debug_flags;
583 
584 #if DEBUG
585 
586 #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
587 	if (ahci_debug_flags & (flag)) {			\
588 		ahci_log(ahci_ctlp, CE_WARN, fmt, ## args);	\
589 		if (ahci_ctlp == NULL)				\
590 			sata_trace_debug(NULL, fmt, ## args);	\
591 		else						\
592 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
593 			    fmt, ## args);			\
594 	}
595 
596 #else
597 
598 #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
599 	if (ahci_debug_flags & (flag)) {			\
600 		if (ahci_ctlp == NULL)				\
601 			sata_trace_debug(NULL, fmt, ## args);	\
602 		else						\
603 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
604 			    fmt, ## args);			\
605 	}
606 
607 #endif /* DEBUG */
608 
609 
610 #ifdef	__cplusplus
611 }
612 #endif
613 
614 #endif /* _AHCIVAR_H */
615