12fcbc377Syt160523 /*
22fcbc377Syt160523  * CDDL HEADER START
32fcbc377Syt160523  *
42fcbc377Syt160523  * The contents of this file are subject to the terms of the
52fcbc377Syt160523  * Common Development and Distribution License (the "License").
62fcbc377Syt160523  * You may not use this file except in compliance with the License.
72fcbc377Syt160523  *
82fcbc377Syt160523  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92fcbc377Syt160523  * or http://www.opensolaris.org/os/licensing.
102fcbc377Syt160523  * See the License for the specific language governing permissions
112fcbc377Syt160523  * and limitations under the License.
122fcbc377Syt160523  *
132fcbc377Syt160523  * When distributing Covered Code, include this CDDL HEADER in each
142fcbc377Syt160523  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152fcbc377Syt160523  * If applicable, add the following below this CDDL HEADER, with the
162fcbc377Syt160523  * fields enclosed by brackets "[]" replaced with your own identifying
172fcbc377Syt160523  * information: Portions Copyright [yyyy] [name of copyright owner]
182fcbc377Syt160523  *
192fcbc377Syt160523  * CDDL HEADER END
202fcbc377Syt160523  */
212fcbc377Syt160523 
222fcbc377Syt160523 /*
23b22851f1SXiao-Yu Zhang  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
242ac30289SMarcel Telka  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
25fd6d41c5SRobert Mustacchi  * Copyright (c) 2018, Joyent, Inc.
26*33b27906SGarrett D'Amore  * Copyright 2021 RackTop Systems, Inc.
272fcbc377Syt160523  */
282fcbc377Syt160523 
292fcbc377Syt160523 
302fcbc377Syt160523 #ifndef _AHCIVAR_H
312fcbc377Syt160523 #define	_AHCIVAR_H
322fcbc377Syt160523 
332fcbc377Syt160523 #ifdef	__cplusplus
342fcbc377Syt160523 extern "C" {
352fcbc377Syt160523 #endif
362fcbc377Syt160523 
37fd6d41c5SRobert Mustacchi #include <sys/sata/adapters/ahci/ahciem.h>
38fd6d41c5SRobert Mustacchi 
398aa6aadbSXiao-Yu Zhang /*
408aa6aadbSXiao-Yu Zhang  * AHCI address qualifier flags (in qual field of ahci_addr struct).
418aa6aadbSXiao-Yu Zhang  */
428aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_NULL		0x00
438aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_PORT		0x01
448aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_PMPORT	0x02
458aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_PMULT		0x04
468aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_VALID		(AHCI_ADDR_PORT | \
478aa6aadbSXiao-Yu Zhang 				AHCI_ADDR_PMULT | \
488aa6aadbSXiao-Yu Zhang 				AHCI_ADDR_PMPORT)
498aa6aadbSXiao-Yu Zhang 
508aa6aadbSXiao-Yu Zhang /*
518aa6aadbSXiao-Yu Zhang  * AHCI address structure.
528aa6aadbSXiao-Yu Zhang  */
538aa6aadbSXiao-Yu Zhang struct ahci_addr {
548aa6aadbSXiao-Yu Zhang 
558aa6aadbSXiao-Yu Zhang 	/* HBA port number */
568aa6aadbSXiao-Yu Zhang 	uint8_t			aa_port;
578aa6aadbSXiao-Yu Zhang 
588aa6aadbSXiao-Yu Zhang 	/* Port multiplier port number */
598aa6aadbSXiao-Yu Zhang 	uint8_t			aa_pmport;
608aa6aadbSXiao-Yu Zhang 
618aa6aadbSXiao-Yu Zhang 	/*
628aa6aadbSXiao-Yu Zhang 	 * AHCI_ADDR_NULL
638aa6aadbSXiao-Yu Zhang 	 * AHCI_ADDR_PORT
648aa6aadbSXiao-Yu Zhang 	 * AHCI_ADDR_PMPORT
658aa6aadbSXiao-Yu Zhang 	 * AHCI_ADDR_PMULT
668aa6aadbSXiao-Yu Zhang 	 */
678aa6aadbSXiao-Yu Zhang 	uint8_t			aa_qual;
688aa6aadbSXiao-Yu Zhang };
698aa6aadbSXiao-Yu Zhang typedef struct ahci_addr ahci_addr_t;
708aa6aadbSXiao-Yu Zhang 
718aa6aadbSXiao-Yu Zhang _NOTE(SCHEME_PROTECTS_DATA("unshared data", ahci_addr))
728aa6aadbSXiao-Yu Zhang 
738aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_IS_PORT(addrp)					\
748aa6aadbSXiao-Yu Zhang 	((addrp)->aa_qual & AHCI_ADDR_PORT)
758aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_IS_PMPORT(addrp)					\
768aa6aadbSXiao-Yu Zhang 	((addrp)->aa_qual & AHCI_ADDR_PMPORT)
778aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_IS_PMULT(addrp)					\
788aa6aadbSXiao-Yu Zhang 	((addrp)->aa_qual & AHCI_ADDR_PMULT)
798aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_IS_VALID(addrp)					\
808aa6aadbSXiao-Yu Zhang 	((addrp)->aa_port < SATA_MAX_CPORTS) &&				\
818aa6aadbSXiao-Yu Zhang 	((addrp)->aa_pmport < SATA_MAX_PMPORTS) &&			\
828aa6aadbSXiao-Yu Zhang 	((addrp)->aa_qual & AHCI_ADDR_VALID)
838aa6aadbSXiao-Yu Zhang 
848aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_SET(addrp, port, pmport, qual)			\
858aa6aadbSXiao-Yu Zhang 	{								\
868aa6aadbSXiao-Yu Zhang 		(addrp)->aa_port = port;				\
878aa6aadbSXiao-Yu Zhang 		(addrp)->aa_pmport = pmport;				\
888aa6aadbSXiao-Yu Zhang 		(addrp)->aa_qual = qual;				\
898aa6aadbSXiao-Yu Zhang 	}
908aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_SET_PORT(addrp, port)					\
918aa6aadbSXiao-Yu Zhang 	AHCI_ADDR_SET(addrp, port, 0, AHCI_ADDR_PORT)
928aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_SET_PMPORT(addrp, port, pmport)			\
938aa6aadbSXiao-Yu Zhang 	AHCI_ADDR_SET(addrp, port, pmport, AHCI_ADDR_PMPORT)
948aa6aadbSXiao-Yu Zhang #define	AHCI_ADDR_SET_PMULT(addrp, port)				\
958aa6aadbSXiao-Yu Zhang 	AHCI_ADDR_SET(addrp, port, SATA_PMULT_HOSTPORT, AHCI_ADDR_PMULT)
968aa6aadbSXiao-Yu Zhang 
9768d33a25Syt160523 /* Type for argument of event handler */
9868d33a25Syt160523 typedef	struct ahci_event_arg {
9968d33a25Syt160523 	void		*ahciea_ctlp;
10068d33a25Syt160523 	void		*ahciea_portp;
1018aa6aadbSXiao-Yu Zhang 	void		*ahciea_addrp;
10268d33a25Syt160523 	uint32_t	ahciea_event;
10368d33a25Syt160523 } ahci_event_arg_t;
10468d33a25Syt160523 
10568d33a25Syt160523 /* Warlock annotation */
10668d33a25Syt160523 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_ctlp))
10768d33a25Syt160523 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_portp))
1088aa6aadbSXiao-Yu Zhang _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_addrp))
10968d33a25Syt160523 _NOTE(DATA_READABLE_WITHOUT_LOCK(ahci_event_arg_t::ahciea_event))
11068d33a25Syt160523 
1118aa6aadbSXiao-Yu Zhang 
1128aa6aadbSXiao-Yu Zhang /*
1138aa6aadbSXiao-Yu Zhang  * ahci_pmult_info stores the information of a port multiplier and its
1148aa6aadbSXiao-Yu Zhang  * sub-devices in case a port multiplier is attached to an HBA port.
1158aa6aadbSXiao-Yu Zhang  */
1168aa6aadbSXiao-Yu Zhang struct ahci_pmult_info {
1178aa6aadbSXiao-Yu Zhang 
1188aa6aadbSXiao-Yu Zhang 	/* Number of the device ports */
1198aa6aadbSXiao-Yu Zhang 	int			ahcipmi_num_dev_ports;
1208aa6aadbSXiao-Yu Zhang 
1218aa6aadbSXiao-Yu Zhang 	/* Device type of the sub-devices of the port multipler */
1228aa6aadbSXiao-Yu Zhang 	uint8_t			ahcipmi_device_type[SATA_MAX_PMPORTS];
1238aa6aadbSXiao-Yu Zhang 
1248aa6aadbSXiao-Yu Zhang 	/* State of port multiplier port */
1258aa6aadbSXiao-Yu Zhang 	uint32_t		ahcipmi_port_state[SATA_MAX_PMPORTS];
1268aa6aadbSXiao-Yu Zhang 
1278aa6aadbSXiao-Yu Zhang 	/*
1288aa6aadbSXiao-Yu Zhang 	 * Port multiplier port on which there is outstanding NCQ
1298aa6aadbSXiao-Yu Zhang 	 * commands. Only make sense in command based switching mode.
1308aa6aadbSXiao-Yu Zhang 	 */
1318aa6aadbSXiao-Yu Zhang 	uint8_t			ahcipmi_ncq_pmport;
1328aa6aadbSXiao-Yu Zhang 
1338aa6aadbSXiao-Yu Zhang 	/* Pending asynchronous notification events tags */
1348aa6aadbSXiao-Yu Zhang 	uint32_t		ahcipmi_snotif_tags;
1358aa6aadbSXiao-Yu Zhang };
1368aa6aadbSXiao-Yu Zhang typedef struct ahci_pmult_info ahci_pmult_info_t;
1378aa6aadbSXiao-Yu Zhang 
13868d33a25Syt160523 /*
13968d33a25Syt160523  * flags for ahciport_flags
14068d33a25Syt160523  *
14168d33a25Syt160523  * AHCI_PORT_FLAG_MOPPING: this flag will be set when the HBA is stopped,
14268d33a25Syt160523  * and all the outstanding commands need to be aborted and sent to upper
14368d33a25Syt160523  * layers.
14468d33a25Syt160523  *
14568d33a25Syt160523  * AHCI_PORT_FLAG_POLLING: this flag will be set when the interrupt is
14668d33a25Syt160523  * disabled, and the command is executed in POLLING mode.
14768d33a25Syt160523  *
14868d33a25Syt160523  * AHCI_PORT_FLAG_RQSENSE: this flag will be set when a REQUEST SENSE which
14968d33a25Syt160523  * is used to retrieve sense data is being executed.
15068d33a25Syt160523  *
15168d33a25Syt160523  * AHCI_PORT_FLAG_STARTED: this flag will be set when the port is started,
15268d33a25Syt160523  * that is PxCMD.ST is set with '1', and be cleared when the port is put into
15368d33a25Syt160523  * idle, that is PxCMD.ST is changed from '1' to '0'.
15482263d52Syt160523  *
15582263d52Syt160523  * AHCI_PORT_FLAG_RDLOGEXT: this flag will be set when a READ LOG EXT which
15682263d52Syt160523  * is used to retrieve NCQ failure context is being executed.
15782263d52Syt160523  *
15882263d52Syt160523  * AHCI_PORT_FLAG_NODEV: this flag will be set when a device is found gone
15982263d52Syt160523  * during ahci_restart_port_wait_till_ready process.
1608aa6aadbSXiao-Yu Zhang  *
1616b62a236Sying tian - Beijing China  * AHCI_PORT_FLAG_RDWR_PMULT: this flag will be set when a READ/WRITE
1628aa6aadbSXiao-Yu Zhang  * PORTMULT command is being executed.
1638aa6aadbSXiao-Yu Zhang  *
1646b62a236Sying tian - Beijing China  * AHCI_PORT_FLAG_IGNORE_IPMS: this flag will be set when enumerating a port
1658aa6aadbSXiao-Yu Zhang  * multiplier. According AHCI spec, IPMS error should be ignore during
1668aa6aadbSXiao-Yu Zhang  * enumeration of port multiplier.
1678aa6aadbSXiao-Yu Zhang  *
1686b62a236Sying tian - Beijing China  * AHCI_PORT_FLAG_PMULT_SNTF: this flag will be set when the a asynchronous
1698aa6aadbSXiao-Yu Zhang  * notification event on the port multiplier is being handled.
1708aa6aadbSXiao-Yu Zhang  *
1716b62a236Sying tian - Beijing China  * AHCI_PORT_FLAG_HOTPLUG: this flag will be set when a hot plug event is
1728aa6aadbSXiao-Yu Zhang  * being handled.
1733f022900Sying tian - Beijing China  *
1743f022900Sying tian - Beijing China  * AHCI_PORT_FLAG_ERRPRINT: this flag will be set when error recovery message
1753f022900Sying tian - Beijing China  * will be printed. Note that, for INDENTIFY DEVICE command sent to ATAPI
1763f022900Sying tian - Beijing China  * device or ATAPI PACKET command, this flag won't be set.
17768d33a25Syt160523  */
17868d33a25Syt160523 #define	AHCI_PORT_FLAG_MOPPING		0x02
17968d33a25Syt160523 #define	AHCI_PORT_FLAG_POLLING		0x04
18068d33a25Syt160523 #define	AHCI_PORT_FLAG_RQSENSE		0x08
18168d33a25Syt160523 #define	AHCI_PORT_FLAG_STARTED		0x10
18282263d52Syt160523 #define	AHCI_PORT_FLAG_RDLOGEXT		0x20
18382263d52Syt160523 #define	AHCI_PORT_FLAG_NODEV		0x40
1848aa6aadbSXiao-Yu Zhang #define	AHCI_PORT_FLAG_RDWR_PMULT	0x80
1858aa6aadbSXiao-Yu Zhang #define	AHCI_PORT_FLAG_IGNORE_IPMS	0x100
1868aa6aadbSXiao-Yu Zhang #define	AHCI_PORT_FLAG_PMULT_SNTF	0x200
1878aa6aadbSXiao-Yu Zhang #define	AHCI_PORT_FLAG_HOTPLUG		0x400
1883f022900Sying tian - Beijing China #define	AHCI_PORT_FLAG_ERRPRINT		0x800
18968d33a25Syt160523 
1902fcbc377Syt160523 typedef struct ahci_port {
19168d33a25Syt160523 	/* The physical port number */
1922fcbc377Syt160523 	uint8_t			ahciport_port_num;
19368d33a25Syt160523 
1942fcbc377Syt160523 	/* Type of the device attached to the port */
1952fcbc377Syt160523 	uint8_t			ahciport_device_type;
1962fcbc377Syt160523 	/* State of the port */
1972fcbc377Syt160523 	uint32_t		ahciport_port_state;
19868d33a25Syt160523 
1998aa6aadbSXiao-Yu Zhang 	/* Port multiplier struct */
2008aa6aadbSXiao-Yu Zhang 	ahci_pmult_info_t	*ahciport_pmult_info;
2018aa6aadbSXiao-Yu Zhang 
20268d33a25Syt160523 	/*
20368d33a25Syt160523 	 * AHCI_PORT_FLAG_MOPPING
20468d33a25Syt160523 	 * AHCI_PORT_FLAG_POLLING
20568d33a25Syt160523 	 * AHCI_PORT_FLAG_RQSENSE
20668d33a25Syt160523 	 * AHCI_PORT_FLAG_STARTED
20782263d52Syt160523 	 * AHCI_PORT_FLAG_RDLOGEXT
20882263d52Syt160523 	 * AHCI_PORT_FLAG_NODEV
2098aa6aadbSXiao-Yu Zhang 	 * AHCI_PORT_FLAG_RDWR_PMULT
2108aa6aadbSXiao-Yu Zhang 	 * AHCI_PORT_FLAG_IGNORE_IPMS
2118aa6aadbSXiao-Yu Zhang 	 * AHCI_PORT_FLAG_PMULT_SNTF
2128aa6aadbSXiao-Yu Zhang 	 * AHCI_PORT_FLAG_HOTPLUG
2133f022900Sying tian - Beijing China 	 * AHCI_PORT_FLAG_ERRPRINT
21468d33a25Syt160523 	 */
2152fcbc377Syt160523 	int			ahciport_flags;
2162fcbc377Syt160523 
2172fcbc377Syt160523 	/* Pointer to received FIS structure */
2182fcbc377Syt160523 	ahci_rcvd_fis_t		*ahciport_rcvd_fis;
2192fcbc377Syt160523 	ddi_dma_handle_t	ahciport_rcvd_fis_dma_handle;
2202fcbc377Syt160523 	ddi_acc_handle_t	ahciport_rcvd_fis_acc_handle;
22113bcbb7aSyt160523 	ddi_dma_cookie_t	ahciport_rcvd_fis_dma_cookie;
2222fcbc377Syt160523 
2232fcbc377Syt160523 	/* Pointer to command list structure */
2242fcbc377Syt160523 	ahci_cmd_header_t	*ahciport_cmd_list;
2252fcbc377Syt160523 	ddi_dma_handle_t	ahciport_cmd_list_dma_handle;
2262fcbc377Syt160523 	ddi_acc_handle_t	ahciport_cmd_list_acc_handle;
22713bcbb7aSyt160523 	ddi_dma_cookie_t	ahciport_cmd_list_dma_cookie;
2282fcbc377Syt160523 
2292fcbc377Syt160523 	/* Pointer to cmmand table structure */
2302fcbc377Syt160523 	ahci_cmd_table_t	\
2312fcbc377Syt160523 			*ahciport_cmd_tables[AHCI_PORT_MAX_CMD_SLOTS];
2322fcbc377Syt160523 	ddi_dma_handle_t	\
2332fcbc377Syt160523 			ahciport_cmd_tables_dma_handle[AHCI_PORT_MAX_CMD_SLOTS];
2342fcbc377Syt160523 	ddi_acc_handle_t	\
2352fcbc377Syt160523 			ahciport_cmd_tables_acc_handle[AHCI_PORT_MAX_CMD_SLOTS];
2362fcbc377Syt160523 
23768d33a25Syt160523 	/* Condition variable used for sync mode commands */
23868d33a25Syt160523 	kcondvar_t		ahciport_cv;
23968d33a25Syt160523 
24068d33a25Syt160523 	/* The whole mutex for the port structure */
2412fcbc377Syt160523 	kmutex_t		ahciport_mutex;
24268d33a25Syt160523 
24382263d52Syt160523 	/* The maximum number of tags for native queuing command transfers */
24482263d52Syt160523 	int			ahciport_max_ncq_tags;
24582263d52Syt160523 
24682263d52Syt160523 	/* Keep the tags of all pending non-ncq commands */
2472fcbc377Syt160523 	uint32_t		ahciport_pending_tags;
24868d33a25Syt160523 
24982263d52Syt160523 	/*
25082263d52Syt160523 	 * Keep the tags of all pending ncq commands
25182263d52Syt160523 	 * (READ/WRITE FPDMA QUEUED)
25282263d52Syt160523 	 */
25382263d52Syt160523 	uint32_t		ahciport_pending_ncq_tags;
25482263d52Syt160523 
25568d33a25Syt160523 	/* Keep all the pending sata packets */
2562fcbc377Syt160523 	sata_pkt_t		*ahciport_slot_pkts[AHCI_PORT_MAX_CMD_SLOTS];
2572fcbc377Syt160523 
2586b62a236Sying tian - Beijing China 	/* Used to check whether corresponding packet is timeout */
2596b62a236Sying tian - Beijing China 	int			ahciport_slot_timeout[AHCI_PORT_MAX_CMD_SLOTS];
2606b62a236Sying tian - Beijing China 
2616b62a236Sying tian - Beijing China 	/* Queue of completed (done) sata packet */
2626b62a236Sying tian - Beijing China 	sata_pkt_t		*ahciport_doneq;
2636b62a236Sying tian - Beijing China 
2646b62a236Sying tian - Beijing China 	/* Pointer of the tail of completed sata packet queue */
2656b62a236Sying tian - Beijing China 	sata_pkt_t		**ahciport_doneqtail;
2666b62a236Sying tian - Beijing China 
2676b62a236Sying tian - Beijing China 	/* the length of the completed sata packet queue */
2686b62a236Sying tian - Beijing China 	uint32_t		ahciport_doneq_len;
2696b62a236Sying tian - Beijing China 
27038547057Sying tian - Beijing China 	/* Keep the byte count of all PRD entries for every sata packet */
27138547057Sying tian - Beijing China 	uint32_t		\
27238547057Sying tian - Beijing China 			ahciport_prd_bytecounts[AHCI_PORT_MAX_CMD_SLOTS];
27338547057Sying tian - Beijing China 
27482263d52Syt160523 	/* Keep the error retrieval sata packet */
27582263d52Syt160523 	sata_pkt_t		*ahciport_err_retri_pkt;
27682263d52Syt160523 
2778aa6aadbSXiao-Yu Zhang 	/* Keep the read/write port multiplier packet */
2788aa6aadbSXiao-Yu Zhang 	sata_pkt_t		*ahciport_rdwr_pmult_pkt;
2798aa6aadbSXiao-Yu Zhang 
2802fcbc377Syt160523 	/*
2812fcbc377Syt160523 	 * SATA HBA driver is supposed to remember and maintain device
2822fcbc377Syt160523 	 * reset state. While the reset is in progress, it doesn't accept
2832fcbc377Syt160523 	 * any more commands until receiving the command with
2842fcbc377Syt160523 	 * SATA_CLEAR_DEV_RESET_STATE flag and SATA_IGNORE_DEV_RESET_STATE.
2852fcbc377Syt160523 	 */
2862fcbc377Syt160523 	int			ahciport_reset_in_progress;
2872fcbc377Syt160523 
288f8a673adSying tian - Beijing China 	/* Taskq for handling event */
289f8a673adSying tian - Beijing China 	ddi_taskq_t		*ahciport_event_taskq;
290f8a673adSying tian - Beijing China 
29168d33a25Syt160523 	/* This is for error recovery handler */
29268d33a25Syt160523 	ahci_event_arg_t	*ahciport_event_args;
29368d33a25Syt160523 
29468d33a25Syt160523 	/* This is to calculate how many mops are in progress */
29568d33a25Syt160523 	int			ahciport_mop_in_progress;
2962fcbc377Syt160523 } ahci_port_t;
2972fcbc377Syt160523 
2982fcbc377Syt160523 /* Warlock annotation */
2992fcbc377Syt160523 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_rcvd_fis_dma_handle))
3002fcbc377Syt160523 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_list_dma_handle))
3012fcbc377Syt160523 _NOTE(READ_ONLY_DATA(ahci_port_t::ahciport_cmd_tables_dma_handle))
3022fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3032fcbc377Syt160523 				    ahci_port_t::ahciport_device_type))
3042fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3052fcbc377Syt160523 				    ahci_port_t::ahciport_port_state))
3062fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3072fcbc377Syt160523 				    ahci_port_t::ahciport_flags))
3082fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3092fcbc377Syt160523 				    ahci_port_t::ahciport_pending_tags))
3102fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3112fcbc377Syt160523 				    ahci_port_t::ahciport_slot_pkts))
3122fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3136b62a236Sying tian - Beijing China 				    ahci_port_t::ahciport_slot_timeout))
3146b62a236Sying tian - Beijing China _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3156b62a236Sying tian - Beijing China 				    ahci_port_t::ahciport_doneq))
3166b62a236Sying tian - Beijing China _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3176b62a236Sying tian - Beijing China 				    ahci_port_t::ahciport_doneqtail))
3186b62a236Sying tian - Beijing China _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3196b62a236Sying tian - Beijing China 				    ahci_port_t::ahciport_doneq_len))
3206b62a236Sying tian - Beijing China _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
3212fcbc377Syt160523 				    ahci_port_t::ahciport_reset_in_progress))
32268d33a25Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
32368d33a25Syt160523 				    ahci_port_t::ahciport_mop_in_progress))
324f8a673adSying tian - Beijing China _NOTE(MUTEX_PROTECTS_DATA(ahci_port_t::ahciport_mutex,
325f8a673adSying tian - Beijing China 				    ahci_port_t::ahciport_event_taskq))
3262fcbc377Syt160523 
3278aa6aadbSXiao-Yu Zhang #define	AHCI_NUM_PORTS(ctlp)						\
3288aa6aadbSXiao-Yu Zhang 	(ctlp)->ahcictl_num_ports
3298aa6aadbSXiao-Yu Zhang 
3308aa6aadbSXiao-Yu Zhang #define	AHCIPORT_NUM_PMPORTS(portp)					\
3318aa6aadbSXiao-Yu Zhang 	(portp)->ahciport_pmult_info->ahcipmi_num_dev_ports
3328aa6aadbSXiao-Yu Zhang 
3338aa6aadbSXiao-Yu Zhang #define	AHCIPORT_NCQ_PMPORT(ahci_portp)					\
3348aa6aadbSXiao-Yu Zhang 	(ahci_portp->ahciport_pmult_info->ahcipmi_ncq_pmport)
3358aa6aadbSXiao-Yu Zhang 
3368aa6aadbSXiao-Yu Zhang #define	AHCIPORT_DEV_TYPE(portp, addrp)					\
3378aa6aadbSXiao-Yu Zhang 	(portp)->ahciport_device_type
3388aa6aadbSXiao-Yu Zhang 
3398aa6aadbSXiao-Yu Zhang #define	AHCIPORT_PMDEV_TYPE(portp, addrp)				\
3408aa6aadbSXiao-Yu Zhang 	(portp)->ahciport_pmult_info->ahcipmi_device_type		\
3418aa6aadbSXiao-Yu Zhang 	[(addrp)->aa_pmport]
3428aa6aadbSXiao-Yu Zhang 
3438aa6aadbSXiao-Yu Zhang #define	AHCIPORT_GET_DEV_TYPE(portp, addrp)				\
3448aa6aadbSXiao-Yu Zhang 	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
3458aa6aadbSXiao-Yu Zhang 	AHCIPORT_DEV_TYPE(portp, addrp) :				\
3468aa6aadbSXiao-Yu Zhang 	AHCIPORT_PMDEV_TYPE(portp, addrp))
3478aa6aadbSXiao-Yu Zhang 
3488aa6aadbSXiao-Yu Zhang #define	AHCIPORT_SET_DEV_TYPE(portp, addrp, type)			\
3498aa6aadbSXiao-Yu Zhang 	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
3508aa6aadbSXiao-Yu Zhang 		AHCIPORT_DEV_TYPE(portp, addrp) = type;			\
3518aa6aadbSXiao-Yu Zhang 	else								\
3528aa6aadbSXiao-Yu Zhang 		AHCIPORT_PMDEV_TYPE(portp, addrp) = type;
3538aa6aadbSXiao-Yu Zhang 
3548aa6aadbSXiao-Yu Zhang #define	AHCIPORT_STATE(portp, addrp)					\
3558aa6aadbSXiao-Yu Zhang 	(portp)->ahciport_port_state
3568aa6aadbSXiao-Yu Zhang 
3578aa6aadbSXiao-Yu Zhang #define	AHCIPORT_PMSTATE(portp, addrp)					\
3588aa6aadbSXiao-Yu Zhang 	(portp)->ahciport_pmult_info->ahcipmi_port_state		\
3598aa6aadbSXiao-Yu Zhang 	[(addrp)->aa_pmport]
3608aa6aadbSXiao-Yu Zhang 
3618aa6aadbSXiao-Yu Zhang #define	AHCIPORT_GET_STATE(portp, addrp)				\
3628aa6aadbSXiao-Yu Zhang 	(AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp) ?		\
3638aa6aadbSXiao-Yu Zhang 	AHCIPORT_STATE(portp, addrp) : AHCIPORT_PMSTATE(portp, addrp))
3648aa6aadbSXiao-Yu Zhang 
3658aa6aadbSXiao-Yu Zhang #define	AHCIPORT_SET_STATE(portp, addrp, state)				\
3668aa6aadbSXiao-Yu Zhang 	if (AHCI_ADDR_IS_PORT(addrp) | AHCI_ADDR_IS_PMULT(addrp))	\
3678aa6aadbSXiao-Yu Zhang 		AHCIPORT_STATE(portp, addrp) = state;			\
3688aa6aadbSXiao-Yu Zhang 	else								\
3698aa6aadbSXiao-Yu Zhang 		AHCIPORT_PMSTATE(portp, addrp) = state;
3708aa6aadbSXiao-Yu Zhang 
371fd6d41c5SRobert Mustacchi typedef enum ahci_em_flags {
372fd6d41c5SRobert Mustacchi 	AHCI_EM_PRESENT		= 1 << 0,
373fd6d41c5SRobert Mustacchi 	AHCI_EM_RESETTING	= 1 << 1,
374fd6d41c5SRobert Mustacchi 	AHCI_EM_TIMEOUT		= 1 << 2,
375fd6d41c5SRobert Mustacchi 	AHCI_EM_QUIESCE		= 1 << 3,
376fd6d41c5SRobert Mustacchi 	AHCI_EM_READY		= 1 << 4,
377fd6d41c5SRobert Mustacchi } ahci_em_flags_t;
378fd6d41c5SRobert Mustacchi 
379fd6d41c5SRobert Mustacchi #define	AHCI_EM_USABLE		(AHCI_EM_PRESENT | AHCI_EM_READY)
380fd6d41c5SRobert Mustacchi 
3812fcbc377Syt160523 typedef struct ahci_ctl {
3822fcbc377Syt160523 	dev_info_t		*ahcictl_dip;
38317ac46baSying tian - Beijing China 
38417ac46baSying tian - Beijing China 	ushort_t		ahcictl_venid;
38517ac46baSying tian - Beijing China 	ushort_t		ahcictl_devid;
38617ac46baSying tian - Beijing China 
3872fcbc377Syt160523 	/* To map port number to cport number */
3882fcbc377Syt160523 	uint8_t			ahcictl_port_to_cport[AHCI_MAX_PORTS];
3892fcbc377Syt160523 	/* To map cport number to port number */
3902fcbc377Syt160523 	uint8_t			ahcictl_cport_to_port[AHCI_MAX_PORTS];
3912fcbc377Syt160523 
3922fcbc377Syt160523 	/* Number of controller ports */
3932fcbc377Syt160523 	int			ahcictl_num_ports;
3942fcbc377Syt160523 	/* Number of command slots */
3952fcbc377Syt160523 	int			ahcictl_num_cmd_slots;
3962fcbc377Syt160523 	/* Number of implemented ports */
3972fcbc377Syt160523 	int			ahcictl_num_implemented_ports;
3982fcbc377Syt160523 	/* Bit map to indicate which port is implemented */
3992fcbc377Syt160523 	uint32_t		ahcictl_ports_implemented;
4002fcbc377Syt160523 	ahci_port_t		*ahcictl_ports[AHCI_MAX_PORTS];
4012fcbc377Syt160523 
4022fcbc377Syt160523 	int			ahcictl_flags;
4032fcbc377Syt160523 	int			ahcictl_power_level;
4042fcbc377Syt160523 	off_t			ahcictl_pmcsr_offset;
4052fcbc377Syt160523 
40668d33a25Syt160523 	/*
40768d33a25Syt160523 	 * AHCI_CAP_PIO_MDRQ
40882263d52Syt160523 	 * AHCI_CAP_NO_MCMDLIST_NONQUEUE
40982263d52Syt160523 	 * AHCI_CAP_NCQ
41013bcbb7aSyt160523 	 * AHCI_CAP_PM
41117ac46baSying tian - Beijing China 	 * AHCI_CAP_BUF_32BIT_DMA
4120a4c4cecSXiao-Yu Zhang 	 * AHCI_CAP_SCLO
41317ac46baSying tian - Beijing China 	 * AHCI_CAP_COMMU_32BIT_DMA
4148aa6aadbSXiao-Yu Zhang 	 * AHCI_CAP_INIT_PORT_RESET
4158aa6aadbSXiao-Yu Zhang 	 * AHCI_CAP_SNTF
4168aa6aadbSXiao-Yu Zhang 	 * AHCI_CAP_PMULT_CBSS
4178aa6aadbSXiao-Yu Zhang 	 * AHCI_CAP_PMULT_FBSS
41817ac46baSying tian - Beijing China 	 * AHCI_CAP_SRST_NO_HOSTPORT
41968d33a25Syt160523 	 */
42068d33a25Syt160523 	int			ahcictl_cap;
42168d33a25Syt160523 
4222fcbc377Syt160523 	/* Pci configuration space handle */
4232fcbc377Syt160523 	ddi_acc_handle_t	ahcictl_pci_conf_handle;
4242fcbc377Syt160523 
4252fcbc377Syt160523 	/* Mapping into bar 5 - AHCI base address */
4262fcbc377Syt160523 	ddi_acc_handle_t	ahcictl_ahci_acc_handle;
4272fcbc377Syt160523 	uintptr_t		ahcictl_ahci_addr;
4282fcbc377Syt160523 
4292fcbc377Syt160523 	/* Pointer used for sata hba framework registration */
4302fcbc377Syt160523 	struct sata_hba_tran	*ahcictl_sata_hba_tran;
4312fcbc377Syt160523 
4322fcbc377Syt160523 	/* DMA attributes for the data buffer */
4332fcbc377Syt160523 	ddi_dma_attr_t		ahcictl_buffer_dma_attr;
4342fcbc377Syt160523 	/* DMA attributes for the rcvd FIS */
4352fcbc377Syt160523 	ddi_dma_attr_t		ahcictl_rcvd_fis_dma_attr;
4362fcbc377Syt160523 	/* DMA attributes for the command list */
4372fcbc377Syt160523 	ddi_dma_attr_t		ahcictl_cmd_list_dma_attr;
4382fcbc377Syt160523 	/* DMA attributes for command tables */
4392fcbc377Syt160523 	ddi_dma_attr_t		ahcictl_cmd_table_dma_attr;
4402fcbc377Syt160523 
4412fcbc377Syt160523 	/* Used for watchdog handler */
4422fcbc377Syt160523 	timeout_id_t		ahcictl_timeout_id;
4432fcbc377Syt160523 
4442fcbc377Syt160523 	/* Per controller mutex */
4452fcbc377Syt160523 	kmutex_t		ahcictl_mutex;
4462fcbc377Syt160523 
4472fcbc377Syt160523 	/* Components for interrupt */
4482fcbc377Syt160523 	ddi_intr_handle_t	*ahcictl_intr_htable;   /* For array of intrs */
4492fcbc377Syt160523 	int			ahcictl_intr_type; /* What type of interrupt */
4502fcbc377Syt160523 	int			ahcictl_intr_cnt;  /* # of intrs returned */
4512fcbc377Syt160523 	size_t			ahcictl_intr_size; /* Size of intr array */
4522fcbc377Syt160523 	uint_t			ahcictl_intr_pri;  /* Intr priority */
4532fcbc377Syt160523 	int			ahcictl_intr_cap;  /* Intr capabilities */
454b22851f1SXiao-Yu Zhang 
455b22851f1SXiao-Yu Zhang 	/* FMA capabilities */
456b22851f1SXiao-Yu Zhang 	int			ahcictl_fm_cap;
457fd6d41c5SRobert Mustacchi 
458fd6d41c5SRobert Mustacchi 	/*
459fd6d41c5SRobert Mustacchi 	 * Enclosure information
460fd6d41c5SRobert Mustacchi 	 */
461fd6d41c5SRobert Mustacchi 	uint32_t		ahcictl_em_loc;
462fd6d41c5SRobert Mustacchi 	uint32_t		ahcictl_em_ctl;
463fd6d41c5SRobert Mustacchi 	uintptr_t		ahcictl_em_tx_off;
464fd6d41c5SRobert Mustacchi 	ahci_em_flags_t		ahcictl_em_flags;
465fd6d41c5SRobert Mustacchi 	ddi_taskq_t		*ahcictl_em_taskq;
466fd6d41c5SRobert Mustacchi 	ahci_em_led_state_t	ahcictl_em_state[AHCI_MAX_PORTS];
4672fcbc377Syt160523 } ahci_ctl_t;
4682fcbc377Syt160523 
4692fcbc377Syt160523 /* Warlock annotation */
4702fcbc377Syt160523 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports))
4712fcbc377Syt160523 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port))
4722fcbc377Syt160523 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport))
4732fcbc377Syt160523 
4742fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
4752fcbc377Syt160523 					ahci_ctl_t::ahcictl_power_level))
4762fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
4772fcbc377Syt160523 					ahci_ctl_t::ahcictl_flags))
4782fcbc377Syt160523 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
4792fcbc377Syt160523 					ahci_ctl_t::ahcictl_timeout_id))
4802fcbc377Syt160523 
4812fcbc377Syt160523 #define	AHCI_SUCCESS	(0)  /* Successful return */
4822fcbc377Syt160523 #define	AHCI_TIMEOUT	(1)  /* Timed out */
4832fcbc377Syt160523 #define	AHCI_FAILURE	(-1) /* Unsuccessful return */
4842fcbc377Syt160523 
4852fcbc377Syt160523 /* Flags for ahcictl_flags */
48613bcbb7aSyt160523 #define	AHCI_ATTACH		0x1
48713bcbb7aSyt160523 #define	AHCI_DETACH		0x2
48813bcbb7aSyt160523 #define	AHCI_SUSPEND		0x4
489265b5a40SMarcel Telka #define	AHCI_QUIESCE		0x8
49068d33a25Syt160523 
49168d33a25Syt160523 /* Values for ahcictl_cap */
4922fcbc377Syt160523 /* PIO Multiple DRQ Block */
49368d33a25Syt160523 #define	AHCI_CAP_PIO_MDRQ		0x1
49482263d52Syt160523 /*
49582263d52Syt160523  * Multiple command slots in the command list cannot be used for
49682263d52Syt160523  * non-queued commands
49782263d52Syt160523  */
49868d33a25Syt160523 #define	AHCI_CAP_NO_MCMDLIST_NONQUEUE	0x2
49982263d52Syt160523 /* Native Command Queuing (NCQ) */
50082263d52Syt160523 #define	AHCI_CAP_NCQ			0x4
50113bcbb7aSyt160523 /* Power Management (PM) */
50213bcbb7aSyt160523 #define	AHCI_CAP_PM			0x8
503259105bcSying tian - Beijing China /* 32-bit DMA addressing for buffer block */
504259105bcSying tian - Beijing China #define	AHCI_CAP_BUF_32BIT_DMA		0x10
5050a4c4cecSXiao-Yu Zhang /* Supports Command List Override */
5060a4c4cecSXiao-Yu Zhang #define	AHCI_CAP_SCLO			0x20
507259105bcSying tian - Beijing China /* 32-bit DMA addressing for communication memory descriptors */
508259105bcSying tian - Beijing China #define	AHCI_CAP_COMMU_32BIT_DMA	0x40
5097fb8b96eSying tian - Beijing China /* Port reset is needed for initialization */
5107fb8b96eSying tian - Beijing China #define	AHCI_CAP_INIT_PORT_RESET	0x80
5118aa6aadbSXiao-Yu Zhang /* Port Asychronous Notification */
5128aa6aadbSXiao-Yu Zhang #define	AHCI_CAP_SNTF			0x100
5138aa6aadbSXiao-Yu Zhang /* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */
5148aa6aadbSXiao-Yu Zhang #define	AHCI_CAP_PMULT_CBSS		0x200
5158aa6aadbSXiao-Yu Zhang /* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */
5168aa6aadbSXiao-Yu Zhang #define	AHCI_CAP_PMULT_FBSS		0x400
5175ce0c8ceSying tian - Beijing China /* Software Reset FIS cannot set pmport with 0xf for direct access device */
5185ce0c8ceSying tian - Beijing China #define	AHCI_CAP_SRST_NO_HOSTPORT	0x800
519fd6d41c5SRobert Mustacchi /* Enclosure Management Services available */
520fd6d41c5SRobert Mustacchi #define	AHCI_CAP_EMS			0x1000
521*33b27906SGarrett D'Amore /* DevSleep Supported */
522*33b27906SGarrett D'Amore #define	AHCI_CAP_SDS			0x2000
5232fcbc377Syt160523 
52468d33a25Syt160523 /* Flags controlling the restart port behavior */
5252fcbc377Syt160523 #define	AHCI_PORT_RESET		0x0001	/* Reset the port */
5260a4c4cecSXiao-Yu Zhang #define	AHCI_RESET_NO_EVENTS_UP	0x0002	/* Don't send reset events up */
5272fcbc377Syt160523 
52882263d52Syt160523 #define	ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)		\
52982263d52Syt160523 	(ahci_portp->ahciport_flags &			\
53082263d52Syt160523 	(AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
53182263d52Syt160523 
5328aa6aadbSXiao-Yu Zhang #define	RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)		\
5338aa6aadbSXiao-Yu Zhang 	(ahci_portp->ahciport_flags &			\
5348aa6aadbSXiao-Yu Zhang 	AHCI_PORT_FLAG_RDWR_PMULT)
5358aa6aadbSXiao-Yu Zhang 
53682263d52Syt160523 #define	NON_NCQ_CMD_IN_PROGRESS(ahci_portp)		\
53782263d52Syt160523 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
53882263d52Syt160523 	ahci_portp->ahciport_pending_tags != 0 &&	\
53982263d52Syt160523 	ahci_portp->ahciport_pending_ncq_tags == 0)
54082263d52Syt160523 
54182263d52Syt160523 #define	NCQ_CMD_IN_PROGRESS(ahci_portp)			\
54282263d52Syt160523 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
54382263d52Syt160523 	ahci_portp->ahciport_pending_ncq_tags != 0)
54482263d52Syt160523 
54582263d52Syt160523 /* Command type for ahci_claim_free_slot routine */
54682263d52Syt160523 #define	AHCI_NON_NCQ_CMD	0x0
54782263d52Syt160523 #define	AHCI_NCQ_CMD		0x1
54882263d52Syt160523 #define	AHCI_ERR_RETRI_CMD	0x2
5498aa6aadbSXiao-Yu Zhang #define	AHCI_RDWR_PMULT_CMD	0x4
55082263d52Syt160523 
5512fcbc377Syt160523 /* State values for ahci_attach */
5522fcbc377Syt160523 #define	AHCI_ATTACH_STATE_NONE			(0x1 << 0)
5532fcbc377Syt160523 #define	AHCI_ATTACH_STATE_STATEP_ALLOC		(0x1 << 1)
554b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_FMA			(0x1 << 2)
555b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_REG_MAP		(0x1 << 3)
556b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_PCICFG_SETUP		(0x1 << 4)
557b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_INTR_ADDED		(0x1 << 5)
558b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_MUTEX_INIT		(0x1 << 6)
559b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_PORT_ALLOC		(0x1 << 7)
560b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_HW_INIT		(0x1 << 8)
561b22851f1SXiao-Yu Zhang #define	AHCI_ATTACH_STATE_TIMEOUT_ENABLED	(0x1 << 9)
562fd6d41c5SRobert Mustacchi #define	AHCI_ATTACH_STATE_ENCLOSURE		(0x1 << 10)
5632fcbc377Syt160523 
5642fcbc377Syt160523 /* Interval used for delay */
565b2e3645aSying tian - Beijing China #define	AHCI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 ms */
566b2e3645aSying tian - Beijing China #define	AHCI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 ms */
567b2e3645aSying tian - Beijing China #define	AHCI_100US_TICKS	(drv_usectohz(100))	/* ticks in 100 us */
5680a4c4cecSXiao-Yu Zhang #define	AHCI_10MS_USECS		(10000)		/* microsecs in 10 millisec */
5690a4c4cecSXiao-Yu Zhang #define	AHCI_1MS_USECS		(1000)		/* microsecs in 1 millisec */
5700a4c4cecSXiao-Yu Zhang #define	AHCI_100US_USECS	(100)
5712fcbc377Syt160523 
5722fcbc377Syt160523 /*
5732fcbc377Syt160523  * The following values are the numbers of times to retry polled requests.
5742fcbc377Syt160523  */
5752fcbc377Syt160523 #define	AHCI_POLLRATE_HBA_RESET		100
5762fcbc377Syt160523 #define	AHCI_POLLRATE_PORT_SSTATUS	10
57768d33a25Syt160523 #define	AHCI_POLLRATE_PORT_TFD_ERROR	1100
5782fcbc377Syt160523 #define	AHCI_POLLRATE_PORT_IDLE		50
5792fcbc377Syt160523 #define	AHCI_POLLRATE_PORT_SOFTRESET	100
58068d33a25Syt160523 #define	AHCI_POLLRATE_GET_SPKT		100
5812ac30289SMarcel Telka #define	AHCI_POLLRATE_PORT_IDLE_FR	500
5822fcbc377Syt160523 
5832fcbc377Syt160523 
5842fcbc377Syt160523 /* Clearing & setting the n'th bit in a given tag */
5852fcbc377Syt160523 #define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
5862fcbc377Syt160523 #define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
5872fcbc377Syt160523 
5882fcbc377Syt160523 
5892fcbc377Syt160523 #if DEBUG
5902fcbc377Syt160523 
5912fcbc377Syt160523 #define	AHCI_DEBUG		1
5922fcbc377Syt160523 
593f5f2d263SFred Herard #endif
594f5f2d263SFred Herard 
5952fcbc377Syt160523 #define	AHCIDBG_INIT		0x0001
5962fcbc377Syt160523 #define	AHCIDBG_ENTRY		0x0002
59738547057Sying tian - Beijing China #define	AHCIDBG_PRDT		0x0004
5982fcbc377Syt160523 #define	AHCIDBG_EVENT		0x0008
5992fcbc377Syt160523 #define	AHCIDBG_POLL_LOOP	0x0010
6002fcbc377Syt160523 #define	AHCIDBG_PKTCOMP		0x0020
6012fcbc377Syt160523 #define	AHCIDBG_TIMEOUT		0x0040
6022fcbc377Syt160523 #define	AHCIDBG_INFO		0x0080
6032fcbc377Syt160523 #define	AHCIDBG_VERBOSE		0x0100
6042fcbc377Syt160523 #define	AHCIDBG_INTR		0x0200
6052fcbc377Syt160523 #define	AHCIDBG_ERRS		0x0400
60638547057Sying tian - Beijing China #define	AHCIDBG_ATACMD		0x0800
60738547057Sying tian - Beijing China #define	AHCIDBG_ATAPICMD	0x1000
60838547057Sying tian - Beijing China #define	AHCIDBG_SENSEDATA	0x2000
60938547057Sying tian - Beijing China #define	AHCIDBG_NCQ		0x4000
61038547057Sying tian - Beijing China #define	AHCIDBG_PM		0x8000
61138547057Sying tian - Beijing China #define	AHCIDBG_UNDERFLOW	0x10000
6122c742e1fSying tian - Beijing China #define	AHCIDBG_MSI		0x20000
6138aa6aadbSXiao-Yu Zhang #define	AHCIDBG_PMULT		0x40000
6142fcbc377Syt160523 
6150a4c4cecSXiao-Yu Zhang extern uint32_t ahci_debug_flags;
6162fcbc377Syt160523 
617f5f2d263SFred Herard #if DEBUG
618f5f2d263SFred Herard 
619f5f2d263SFred Herard #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
6202fcbc377Syt160523 	if (ahci_debug_flags & (flag)) {			\
621f5f2d263SFred Herard 		ahci_log(ahci_ctlp, CE_WARN, fmt, ## args);	\
622f5f2d263SFred Herard 		if (ahci_ctlp == NULL)				\
623f5f2d263SFred Herard 			sata_trace_debug(NULL, fmt, ## args);	\
624f5f2d263SFred Herard 		else						\
625f5f2d263SFred Herard 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
626f5f2d263SFred Herard 			    fmt, ## args);			\
6272fcbc377Syt160523 	}
6282fcbc377Syt160523 
6292fcbc377Syt160523 #else
6302fcbc377Syt160523 
631f5f2d263SFred Herard #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
632f5f2d263SFred Herard 	if (ahci_debug_flags & (flag)) {			\
633f5f2d263SFred Herard 		if (ahci_ctlp == NULL)				\
634f5f2d263SFred Herard 			sata_trace_debug(NULL, fmt, ## args);	\
635f5f2d263SFred Herard 		else						\
636f5f2d263SFred Herard 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
637f5f2d263SFred Herard 			    fmt, ## args);			\
638f5f2d263SFred Herard 	}
6392fcbc377Syt160523 
6402fcbc377Syt160523 #endif /* DEBUG */
6412fcbc377Syt160523 
642fd6d41c5SRobert Mustacchi /*
643fd6d41c5SRobert Mustacchi  * Minimum size required for the enclosure message buffer. This value is in
644fd6d41c5SRobert Mustacchi  * 4-byte quantities. So we need to multiply it by two.
645fd6d41c5SRobert Mustacchi  */
646fd6d41c5SRobert Mustacchi #define	AHCI_EM_BUFFER_MIN	2
647fd6d41c5SRobert Mustacchi 
648fd6d41c5SRobert Mustacchi /*
649fd6d41c5SRobert Mustacchi  * Enclosure Management LED message format values
650fd6d41c5SRobert Mustacchi  */
651fd6d41c5SRobert Mustacchi #define	AHCI_LED_OFF	0
652fd6d41c5SRobert Mustacchi #define	AHCI_LED_ON	1
653fd6d41c5SRobert Mustacchi 
654fd6d41c5SRobert Mustacchi #define	AHCI_LED_ACTIVITY_OFF	0
655fd6d41c5SRobert Mustacchi #define	AHCI_LED_IDENT_OFF	3
656fd6d41c5SRobert Mustacchi #define	AHCI_LED_FAULT_OFF	6
657fd6d41c5SRobert Mustacchi 
658fd6d41c5SRobert Mustacchi #define	AHCI_LED_MASK	0x7
659fd6d41c5SRobert Mustacchi 
660fd6d41c5SRobert Mustacchi #define	AHCI_EM_MSG_TYPE_LED	0
661fd6d41c5SRobert Mustacchi #define	AHCI_EM_MSG_TYPE_SAFTE	1
662fd6d41c5SRobert Mustacchi #define	AHCI_EM_MSG_TYPE_SES	2
663fd6d41c5SRobert Mustacchi #define	AHCI_EM_MSG_TYPE_SGPIO	3
664fd6d41c5SRobert Mustacchi 
665fd6d41c5SRobert Mustacchi #pragma pack(1)
666fd6d41c5SRobert Mustacchi typedef struct ahci_em_led_msg {
667fd6d41c5SRobert Mustacchi 	uint8_t		alm_hba;
668fd6d41c5SRobert Mustacchi 	uint8_t		alm_pminfo;
669fd6d41c5SRobert Mustacchi 	uint16_t	alm_value;
670fd6d41c5SRobert Mustacchi } ahci_em_led_msg_t;
671fd6d41c5SRobert Mustacchi 
672fd6d41c5SRobert Mustacchi typedef struct ahci_em_msg_hdr {
673fd6d41c5SRobert Mustacchi 	uint8_t		aemh_rsvd;
674fd6d41c5SRobert Mustacchi 	uint8_t		aemh_mlen;
675fd6d41c5SRobert Mustacchi 	uint8_t		aemh_dlen;
676fd6d41c5SRobert Mustacchi 	uint8_t		aemh_mtype;
677fd6d41c5SRobert Mustacchi } ahci_em_msg_hdr_t;
678fd6d41c5SRobert Mustacchi #pragma pack()
6792fcbc377Syt160523 
6802fcbc377Syt160523 #ifdef	__cplusplus
6812fcbc377Syt160523 }
6822fcbc377Syt160523 #endif
6832fcbc377Syt160523 
6842fcbc377Syt160523 #endif /* _AHCIVAR_H */
685