xref: /illumos-gate/usr/src/uts/common/sys/sata/adapters/ahci/ahcivar.h (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
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  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
25  * Copyright (c) 2018, Joyent, Inc.
26  */
27 
28 
29 #ifndef _AHCIVAR_H
30 #define	_AHCIVAR_H
31 
32 #ifdef	__cplusplus
33 extern "C" {
34 #endif
35 
36 #include <sys/sata/adapters/ahci/ahciem.h>
37 
38 /*
39  * AHCI address qualifier flags (in qual field of ahci_addr struct).
40  */
41 #define	AHCI_ADDR_NULL		0x00
42 #define	AHCI_ADDR_PORT		0x01
43 #define	AHCI_ADDR_PMPORT	0x02
44 #define	AHCI_ADDR_PMULT		0x04
45 #define	AHCI_ADDR_VALID		(AHCI_ADDR_PORT | \
46 				AHCI_ADDR_PMULT | \
47 				AHCI_ADDR_PMPORT)
48 
49 /*
50  * AHCI address structure.
51  */
52 struct ahci_addr {
53 
54 	/* HBA port number */
55 	uint8_t			aa_port;
56 
57 	/* Port multiplier port number */
58 	uint8_t			aa_pmport;
59 
60 	/*
61 	 * AHCI_ADDR_NULL
62 	 * AHCI_ADDR_PORT
63 	 * AHCI_ADDR_PMPORT
64 	 * AHCI_ADDR_PMULT
65 	 */
66 	uint8_t			aa_qual;
67 };
68 typedef struct ahci_addr ahci_addr_t;
69 
70 _NOTE(SCHEME_PROTECTS_DATA("unshared data", ahci_addr))
71 
72 #define	AHCI_ADDR_IS_PORT(addrp)					\
73 	((addrp)->aa_qual & AHCI_ADDR_PORT)
74 #define	AHCI_ADDR_IS_PMPORT(addrp)					\
75 	((addrp)->aa_qual & AHCI_ADDR_PMPORT)
76 #define	AHCI_ADDR_IS_PMULT(addrp)					\
77 	((addrp)->aa_qual & AHCI_ADDR_PMULT)
78 #define	AHCI_ADDR_IS_VALID(addrp)					\
79 	((addrp)->aa_port < SATA_MAX_CPORTS) &&				\
80 	((addrp)->aa_pmport < SATA_MAX_PMPORTS) &&			\
81 	((addrp)->aa_qual & AHCI_ADDR_VALID)
82 
83 #define	AHCI_ADDR_SET(addrp, port, pmport, qual)			\
84 	{								\
85 		(addrp)->aa_port = port;				\
86 		(addrp)->aa_pmport = pmport;				\
87 		(addrp)->aa_qual = qual;				\
88 	}
89 #define	AHCI_ADDR_SET_PORT(addrp, port)					\
90 	AHCI_ADDR_SET(addrp, port, 0, AHCI_ADDR_PORT)
91 #define	AHCI_ADDR_SET_PMPORT(addrp, port, pmport)			\
92 	AHCI_ADDR_SET(addrp, port, pmport, AHCI_ADDR_PMPORT)
93 #define	AHCI_ADDR_SET_PMULT(addrp, port)				\
94 	AHCI_ADDR_SET(addrp, port, SATA_PMULT_HOSTPORT, AHCI_ADDR_PMULT)
95 
96 /* Type for argument of event handler */
97 typedef	struct ahci_event_arg {
98 	void		*ahciea_ctlp;
99 	void		*ahciea_portp;
100 	void		*ahciea_addrp;
101 	uint32_t	ahciea_event;
102 } ahci_event_arg_t;
103 
104 /* Warlock annotation */
105 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_ctlp))
106 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_portp))
107 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_addrp))
108 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_event))
109 
110 
111 /*
112  * ahci_pmult_info stores the information of a port multiplier and its
113  * sub-devices in case a port multiplier is attached to an HBA port.
114  */
115 struct ahci_pmult_info {
116 
117 	/* Number of the device ports */
118 	int			ahcipmi_num_dev_ports;
119 
120 	/* Device type of the sub-devices of the port multipler */
121 	uint8_t			ahcipmi_device_type[SATA_MAX_PMPORTS];
122 
123 	/* State of port multiplier port */
124 	uint32_t		ahcipmi_port_state[SATA_MAX_PMPORTS];
125 
126 	/*
127 	 * Port multiplier port on which there is outstanding NCQ
128 	 * commands. Only make sense in command based switching mode.
129 	 */
130 	uint8_t			ahcipmi_ncq_pmport;
131 
132 	/* Pending asynchronous notification events tags */
133 	uint32_t		ahcipmi_snotif_tags;
134 };
135 typedef struct ahci_pmult_info ahci_pmult_info_t;
136 
137 /*
138  * flags for ahciport_flags
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 flag will be set when a READ/WRITE
161  * PORTMULT command is being executed.
162  *
163  * AHCI_PORT_FLAG_IGNORE_IPMS: this flag 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 flag will be set when the a asynchronous
168  * notification event on the port multiplier is being handled.
169  *
170  * AHCI_PORT_FLAG_HOTPLUG: this flag will be set when a hot plug event is
171  * being handled.
172  *
173  * AHCI_PORT_FLAG_ERRPRINT: this flag will be set when error recovery message
174  * will be printed. Note that, for INDENTIFY DEVICE command sent to ATAPI
175  * device or ATAPI PACKET command, this flag won't be set.
176  */
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 
189 typedef 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_MOPPING
203 	 * AHCI_PORT_FLAG_POLLING
204 	 * AHCI_PORT_FLAG_RQSENSE
205 	 * AHCI_PORT_FLAG_STARTED
206 	 * AHCI_PORT_FLAG_RDLOGEXT
207 	 * AHCI_PORT_FLAG_NODEV
208 	 * AHCI_PORT_FLAG_RDWR_PMULT
209 	 * AHCI_PORT_FLAG_IGNORE_IPMS
210 	 * AHCI_PORT_FLAG_PMULT_SNTF
211 	 * AHCI_PORT_FLAG_HOTPLUG
212 	 * AHCI_PORT_FLAG_ERRPRINT
213 	 */
214 	int			ahciport_flags;
215 
216 	/* Pointer to received FIS structure */
217 	ahci_rcvd_fis_t		*ahciport_rcvd_fis;
218 	ddi_dma_handle_t	ahciport_rcvd_fis_dma_handle;
219 	ddi_acc_handle_t	ahciport_rcvd_fis_acc_handle;
220 	ddi_dma_cookie_t	ahciport_rcvd_fis_dma_cookie;
221 
222 	/* Pointer to command list structure */
223 	ahci_cmd_header_t	*ahciport_cmd_list;
224 	ddi_dma_handle_t	ahciport_cmd_list_dma_handle;
225 	ddi_acc_handle_t	ahciport_cmd_list_acc_handle;
226 	ddi_dma_cookie_t	ahciport_cmd_list_dma_cookie;
227 
228 	/* Pointer to cmmand table structure */
229 	ahci_cmd_table_t	\
230 			*ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS];
231 	ddi_dma_handle_t	\
232 			ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS];
233 	ddi_acc_handle_t	\
234 			ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS];
235 
236 	/* Condition variable used for sync mode commands */
237 	kcondvar_t		ahciport_cv;
238 
239 	/* The whole mutex for the port structure */
240 	kmutex_t		ahciport_mutex;
241 
242 	/* The maximum number of tags for native queuing command transfers */
243 	int			ahciport_max_ncq_tags;
244 
245 	/* Keep the tags of all pending non-ncq commands */
246 	uint32_t		ahciport_pending_tags;
247 
248 	/*
249 	 * Keep the tags of all pending ncq commands
250 	 * (READ/WRITE FPDMA QUEUED)
251 	 */
252 	uint32_t		ahciport_pending_ncq_tags;
253 
254 	/* Keep all the pending sata packets */
255 	sata_pkt_t		*ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS];
256 
257 	/* Used to check whether corresponding packet is timeout */
258 	int			ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS];
259 
260 	/* Queue of completed (done) sata packet */
261 	sata_pkt_t		*ahciport_doneq;
262 
263 	/* Pointer of the tail of completed sata packet queue */
264 	sata_pkt_t		**ahciport_doneqtail;
265 
266 	/* the length of the completed sata packet queue */
267 	uint32_t		ahciport_doneq_len;
268 
269 	/* Keep the byte count of all PRD entries for every sata packet */
270 	uint32_t		\
271 			ahciport_prd_bytecounts[AHCI_PORT_MAX_CMD_SLOTS];
272 
273 	/* Keep the error retrieval sata packet */
274 	sata_pkt_t		*ahciport_err_retri_pkt;
275 
276 	/* Keep the read/write port multiplier packet */
277 	sata_pkt_t		*ahciport_rdwr_pmult_pkt;
278 
279 	/*
280 	 * SATA HBA driver is supposed to remember and maintain device
281 	 * reset state. While the reset is in progress, it doesn't accept
282 	 * any more commands until receiving the command with
283 	 * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE.
284 	 */
285 	int			ahciport_reset_in_progress;
286 
287 	/* Taskq for handling event */
288 	ddi_taskq_t		*ahciport_event_taskq;
289 
290 	/* This is for error recovery handler */
291 	ahci_event_arg_t	*ahciport_event_args;
292 
293 	/* This is to calculate how many mops are in progress */
294 	int			ahciport_mop_in_progress;
295 } ahci_port_t;
296 
297 /* Warlock annotation */
298 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle))
299 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle))
300 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle))
301 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
302 				    ahci_port_t::ahciport_device_type))
303 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
304 				    ahci_port_t::ahciport_port_state))
305 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
306 				    ahci_port_t::ahciport_flags))
307 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
308 				    ahci_port_t::ahciport_pending_tags))
309 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
310 				    ahci_port_t::ahciport_slot_pkts))
311 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
312 				    ahci_port_t::ahciport_slot_timeout))
313 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
314 				    ahci_port_t::ahciport_doneq))
315 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
316 				    ahci_port_t::ahciport_doneqtail))
317 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
318 				    ahci_port_t::ahciport_doneq_len))
319 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
320 				    ahci_port_t::ahciport_reset_in_progress))
321 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
322 				    ahci_port_t::ahciport_mop_in_progress))
323 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
324 				    ahci_port_t::ahciport_event_taskq))
325 
326 #define	AHCI_NUM_PORTS(ctlp)						\
327 	(ctlp)->ahcictl_num_ports
328 
329 #define	AHCIPORT_NUM_PMPORTS(portp)					\
330 	(portp)->ahciport_pmult_info->ahcipmi_num_dev_ports
331 
332 #define	AHCIPORT_NCQ_PMPORT(ahci_portp)					\
333 	(ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport)
334 
335 #define	AHCIPORT_DEV_TYPE(portp, addrp)					\
336 	(portp)->ahciport_device_type
337 
338 #define	AHCIPORT_PMDEV_TYPE(portp, addrp)				\
339 	(portp)->ahciport_pmult_info->ahcipmi_device_type		\
340 	[(addrp)->aa_pmport]
341 
342 #define	AHCIPORT_GET_DEV_TYPE(portp, addrp)				\
343 	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
344 	AHCIPORT_DEV_TYPE(portp, addrp) :				\
345 	AHCIPORT_PMDEV_TYPE(portp, addrp))
346 
347 #define	AHCIPORT_SET_DEV_TYPE(portp, addrp, type)			\
348 	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
349 		AHCIPORT_DEV_TYPE(portp, addrp) = type;			\
350 	else								\
351 		AHCIPORT_PMDEV_TYPE(portp, addrp) = type;
352 
353 #define	AHCIPORT_STATE(portp, addrp)					\
354 	(portp)->ahciport_port_state
355 
356 #define	AHCIPORT_PMSTATE(portp, addrp)					\
357 	(portp)->ahciport_pmult_info->ahcipmi_port_state		\
358 	[(addrp)->aa_pmport]
359 
360 #define	AHCIPORT_GET_STATE(portp, addrp)				\
361 	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
362 	AHCIPORT_STATE(portp, addrp) : AHCIPORT_PMSTATE(portp, addrp))
363 
364 #define	AHCIPORT_SET_STATE(portp, addrp, state)				\
365 	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
366 		AHCIPORT_STATE(portp, addrp) = state;			\
367 	else								\
368 		AHCIPORT_PMSTATE(portp, addrp) = state;
369 
370 typedef enum ahci_em_flags {
371 	AHCI_EM_PRESENT		= 1 << 0,
372 	AHCI_EM_RESETTING	= 1 << 1,
373 	AHCI_EM_TIMEOUT		= 1 << 2,
374 	AHCI_EM_QUIESCE		= 1 << 3,
375 	AHCI_EM_READY		= 1 << 4,
376 } ahci_em_flags_t;
377 
378 #define	AHCI_EM_USABLE		(AHCI_EM_PRESENT | AHCI_EM_READY)
379 
380 typedef struct ahci_ctl {
381 	dev_info_t		*ahcictl_dip;
382 
383 	ushort_t		ahcictl_venid;
384 	ushort_t		ahcictl_devid;
385 
386 	/* To map port number to cport number */
387 	uint8_t			ahcictl_port_to_cport[AHCI_MAX_PORTS];
388 	/* To map cport number to port number */
389 	uint8_t			ahcictl_cport_to_port[AHCI_MAX_PORTS];
390 
391 	/* Number of controller ports */
392 	int			ahcictl_num_ports;
393 	/* Number of command slots */
394 	int			ahcictl_num_cmd_slots;
395 	/* Number of implemented ports */
396 	int			ahcictl_num_implemented_ports;
397 	/* Bit map to indicate which port is implemented */
398 	uint32_t		ahcictl_ports_implemented;
399 	ahci_port_t		*ahcictl_ports[AHCI_MAX_PORTS];
400 
401 	int			ahcictl_flags;
402 	int			ahcictl_power_level;
403 	off_t			ahcictl_pmcsr_offset;
404 
405 	/*
406 	 * AHCI_CAP_PIO_MDRQ
407 	 * AHCI_CAP_NO_MCMDLIST_NONQUEUE
408 	 * AHCI_CAP_NCQ
409 	 * AHCI_CAP_PM
410 	 * AHCI_CAP_BUF_32BIT_DMA
411 	 * AHCI_CAP_SCLO
412 	 * AHCI_CAP_COMMU_32BIT_DMA
413 	 * AHCI_CAP_INIT_PORT_RESET
414 	 * AHCI_CAP_SNTF
415 	 * AHCI_CAP_PMULT_CBSS
416 	 * AHCI_CAP_PMULT_FBSS
417 	 * AHCI_CAP_SRST_NO_HOSTPORT
418 	 */
419 	int			ahcictl_cap;
420 
421 	/* Pci configuration space handle */
422 	ddi_acc_handle_t	ahcictl_pci_conf_handle;
423 
424 	/* Mapping into bar 5 - AHCI base address */
425 	ddi_acc_handle_t	ahcictl_ahci_acc_handle;
426 	uintptr_t		ahcictl_ahci_addr;
427 
428 	/* Pointer used for sata hba framework registration */
429 	struct sata_hba_tran	*ahcictl_sata_hba_tran;
430 
431 	/* DMA attributes for the data buffer */
432 	ddi_dma_attr_t		ahcictl_buffer_dma_attr;
433 	/* DMA attributes for the rcvd FIS */
434 	ddi_dma_attr_t		ahcictl_rcvd_fis_dma_attr;
435 	/* DMA attributes for the command list */
436 	ddi_dma_attr_t		ahcictl_cmd_list_dma_attr;
437 	/* DMA attributes for command tables */
438 	ddi_dma_attr_t		ahcictl_cmd_table_dma_attr;
439 
440 	/* Used for watchdog handler */
441 	timeout_id_t		ahcictl_timeout_id;
442 
443 	/* Per controller mutex */
444 	kmutex_t		ahcictl_mutex;
445 
446 	/* Components for interrupt */
447 	ddi_intr_handle_t	*ahcictl_intr_htable;   /* For array of intrs */
448 	int			ahcictl_intr_type; /* What type of interrupt */
449 	int			ahcictl_intr_cnt;  /* # of intrs returned */
450 	size_t			ahcictl_intr_size; /* Size of intr array */
451 	uint_t			ahcictl_intr_pri;  /* Intr priority */
452 	int			ahcictl_intr_cap;  /* Intr capabilities */
453 
454 	/* FMA capabilities */
455 	int			ahcictl_fm_cap;
456 
457 	/*
458 	 * Enclosure information
459 	 */
460 	uint32_t		ahcictl_em_loc;
461 	uint32_t		ahcictl_em_ctl;
462 	uintptr_t		ahcictl_em_tx_off;
463 	ahci_em_flags_t		ahcictl_em_flags;
464 	ddi_taskq_t		*ahcictl_em_taskq;
465 	ahci_em_led_state_t	ahcictl_em_state[AHCI_MAX_PORTS];
466 } ahci_ctl_t;
467 
468 /* Warlock annotation */
469 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports))
470 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port))
471 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport))
472 
473 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
474 					ahci_ctl_t::ahcictl_power_level))
475 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
476 					ahci_ctl_t::ahcictl_flags))
477 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
478 					ahci_ctl_t::ahcictl_timeout_id))
479 
480 #define	AHCI_SUCCESS	(0)  /* Successful return */
481 #define	AHCI_TIMEOUT	(1)  /* Timed out */
482 #define	AHCI_FAILURE	(-1) /* Unsuccessful return */
483 
484 /* Flags for ahcictl_flags */
485 #define	AHCI_ATTACH		0x1
486 #define	AHCI_DETACH		0x2
487 #define	AHCI_SUSPEND		0x4
488 #define	AHCI_QUIESCE		0x8
489 
490 /* Values for ahcictl_cap */
491 /* PIO Multiple DRQ Block */
492 #define	AHCI_CAP_PIO_MDRQ		0x1
493 /*
494  * Multiple command slots in the command list cannot be used for
495  * non-queued commands
496  */
497 #define	AHCI_CAP_NO_MCMDLIST_NONQUEUE	0x2
498 /* Native Command Queuing (NCQ) */
499 #define	AHCI_CAP_NCQ			0x4
500 /* Power Management (PM) */
501 #define	AHCI_CAP_PM			0x8
502 /* 32-bit DMA addressing for buffer block */
503 #define	AHCI_CAP_BUF_32BIT_DMA		0x10
504 /* Supports Command List Override */
505 #define	AHCI_CAP_SCLO			0x20
506 /* 32-bit DMA addressing for communication memory descriptors */
507 #define	AHCI_CAP_COMMU_32BIT_DMA	0x40
508 /* Port reset is needed for initialization */
509 #define	AHCI_CAP_INIT_PORT_RESET	0x80
510 /* Port Asychronous Notification */
511 #define	AHCI_CAP_SNTF			0x100
512 /* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */
513 #define	AHCI_CAP_PMULT_CBSS		0x200
514 /* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */
515 #define	AHCI_CAP_PMULT_FBSS		0x400
516 /* Software Reset FIS cannot set pmport with 0xf for direct access device */
517 #define	AHCI_CAP_SRST_NO_HOSTPORT	0x800
518 /* Enclosure Management Services available */
519 #define	AHCI_CAP_EMS			0x1000
520 
521 /* Flags controlling the restart port behavior */
522 #define	AHCI_PORT_RESET		0x0001	/* Reset the port */
523 #define	AHCI_RESET_NO_EVENTS_UP	0x0002	/* Don't send reset events up */
524 
525 #define	ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)		\
526 	(ahci_portp->ahciport_flags &			\
527 	(AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
528 
529 #define	RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)		\
530 	(ahci_portp->ahciport_flags &			\
531 	AHCI_PORT_FLAG_RDWR_PMULT)
532 
533 #define	NON_NCQ_CMD_IN_PROGRESS(ahci_portp)		\
534 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
535 	ahci_portp->ahciport_pending_tags != 0 &&	\
536 	ahci_portp->ahciport_pending_ncq_tags == 0)
537 
538 #define	NCQ_CMD_IN_PROGRESS(ahci_portp)			\
539 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
540 	ahci_portp->ahciport_pending_ncq_tags != 0)
541 
542 /* Command type for ahci_claim_free_slot routine */
543 #define	AHCI_NON_NCQ_CMD	0x0
544 #define	AHCI_NCQ_CMD		0x1
545 #define	AHCI_ERR_RETRI_CMD	0x2
546 #define	AHCI_RDWR_PMULT_CMD	0x4
547 
548 /* State values for ahci_attach */
549 #define	AHCI_ATTACH_STATE_NONE			(0x1 << 0)
550 #define	AHCI_ATTACH_STATE_STATEP_ALLOC		(0x1 << 1)
551 #define	AHCI_ATTACH_STATE_FMA			(0x1 << 2)
552 #define	AHCI_ATTACH_STATE_REG_MAP		(0x1 << 3)
553 #define	AHCI_ATTACH_STATE_PCICFG_SETUP		(0x1 << 4)
554 #define	AHCI_ATTACH_STATE_INTR_ADDED		(0x1 << 5)
555 #define	AHCI_ATTACH_STATE_MUTEX_INIT		(0x1 << 6)
556 #define	AHCI_ATTACH_STATE_PORT_ALLOC		(0x1 << 7)
557 #define	AHCI_ATTACH_STATE_HW_INIT		(0x1 << 8)
558 #define	AHCI_ATTACH_STATE_TIMEOUT_ENABLED	(0x1 << 9)
559 #define	AHCI_ATTACH_STATE_ENCLOSURE		(0x1 << 10)
560 
561 /* Interval used for delay */
562 #define	AHCI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 ms */
563 #define	AHCI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 ms */
564 #define	AHCI_100US_TICKS	(drv_usectohz(100))	/* ticks in 100 us */
565 #define	AHCI_10MS_USECS		(10000)		/* microsecs in 10 millisec */
566 #define	AHCI_1MS_USECS		(1000)		/* microsecs in 1 millisec */
567 #define	AHCI_100US_USECS	(100)
568 
569 /*
570  * The following values are the numbers of times to retry polled requests.
571  */
572 #define	AHCI_POLLRATE_HBA_RESET		100
573 #define	AHCI_POLLRATE_PORT_SSTATUS	10
574 #define	AHCI_POLLRATE_PORT_TFD_ERROR	1100
575 #define	AHCI_POLLRATE_PORT_IDLE		50
576 #define	AHCI_POLLRATE_PORT_SOFTRESET	100
577 #define	AHCI_POLLRATE_GET_SPKT		100
578 #define	AHCI_POLLRATE_PORT_IDLE_FR	500
579 
580 
581 /* Clearing & setting the n'th bit in a given tag */
582 #define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
583 #define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
584 
585 
586 #if DEBUG
587 
588 #define	AHCI_DEBUG		1
589 
590 #endif
591 
592 #define	AHCIDBG_INIT		0x0001
593 #define	AHCIDBG_ENTRY		0x0002
594 #define	AHCIDBG_PRDT		0x0004
595 #define	AHCIDBG_EVENT		0x0008
596 #define	AHCIDBG_POLL_LOOP	0x0010
597 #define	AHCIDBG_PKTCOMP		0x0020
598 #define	AHCIDBG_TIMEOUT		0x0040
599 #define	AHCIDBG_INFO		0x0080
600 #define	AHCIDBG_VERBOSE		0x0100
601 #define	AHCIDBG_INTR		0x0200
602 #define	AHCIDBG_ERRS		0x0400
603 #define	AHCIDBG_ATACMD		0x0800
604 #define	AHCIDBG_ATAPICMD	0x1000
605 #define	AHCIDBG_SENSEDATA	0x2000
606 #define	AHCIDBG_NCQ		0x4000
607 #define	AHCIDBG_PM		0x8000
608 #define	AHCIDBG_UNDERFLOW	0x10000
609 #define	AHCIDBG_MSI		0x20000
610 #define	AHCIDBG_PMULT		0x40000
611 
612 extern uint32_t ahci_debug_flags;
613 
614 #if DEBUG
615 
616 #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
617 	if (ahci_debug_flags & (flag)) {			\
618 		ahci_log(ahci_ctlp, CE_WARN, fmt, ## args);	\
619 		if (ahci_ctlp == NULL)				\
620 			sata_trace_debug(NULL, fmt, ## args);	\
621 		else						\
622 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
623 			    fmt, ## args);			\
624 	}
625 
626 #else
627 
628 #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
629 	if (ahci_debug_flags & (flag)) {			\
630 		if (ahci_ctlp == NULL)				\
631 			sata_trace_debug(NULL, fmt, ## args);	\
632 		else						\
633 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
634 			    fmt, ## args);			\
635 	}
636 
637 #endif /* DEBUG */
638 
639 /*
640  * Minimum size required for the enclosure message buffer. This value is in
641  * 4-byte quantities. So we need to multiply it by two.
642  */
643 #define	AHCI_EM_BUFFER_MIN	2
644 
645 /*
646  * Enclosure Management LED message format values
647  */
648 #define	AHCI_LED_OFF	0
649 #define	AHCI_LED_ON	1
650 
651 #define	AHCI_LED_ACTIVITY_OFF	0
652 #define	AHCI_LED_IDENT_OFF	3
653 #define	AHCI_LED_FAULT_OFF	6
654 
655 #define	AHCI_LED_MASK	0x7
656 
657 #define	AHCI_EM_MSG_TYPE_LED	0
658 #define	AHCI_EM_MSG_TYPE_SAFTE	1
659 #define	AHCI_EM_MSG_TYPE_SES	2
660 #define	AHCI_EM_MSG_TYPE_SGPIO	3
661 
662 #pragma pack(1)
663 typedef struct ahci_em_led_msg {
664 	uint8_t		alm_hba;
665 	uint8_t		alm_pminfo;
666 	uint16_t	alm_value;
667 } ahci_em_led_msg_t;
668 
669 typedef struct ahci_em_msg_hdr {
670 	uint8_t		aemh_rsvd;
671 	uint8_t		aemh_mlen;
672 	uint8_t		aemh_dlen;
673 	uint8_t		aemh_mtype;
674 } ahci_em_msg_hdr_t;
675 #pragma pack()
676 
677 #ifdef	__cplusplus
678 }
679 #endif
680 
681 #endif /* _AHCIVAR_H */
682