Home | History | Annotate | Download | only in ahci
      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
     32 extern "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  */
     49 struct 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 };
     65 typedef 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 */
     94 typedef	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  */
    112 struct 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 };
    132 typedef 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 
    185 typedef 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 
    346 typedef struct ahci_ctl {
    347 	dev_info_t		*ahcictl_dip;
    348 
    349 	ushort_t		ahcictl_venid;
    350 	ushort_t		ahcictl_devid;
    351 
    352 	/* To map port number to cport number */
    353 	uint8_t			ahcictl_port_to_cport[AHCI_MAX_PORTS];
    354 	/* To map cport number to port number */
    355 	uint8_t			ahcictl_cport_to_port[AHCI_MAX_PORTS];
    356 
    357 	/* Number of controller ports */
    358 	int			ahcictl_num_ports;
    359 	/* Number of command slots */
    360 	int			ahcictl_num_cmd_slots;
    361 	/* Number of implemented ports */
    362 	int			ahcictl_num_implemented_ports;
    363 	/* Bit map to indicate which port is implemented */
    364 	uint32_t		ahcictl_ports_implemented;
    365 	ahci_port_t		*ahcictl_ports[AHCI_MAX_PORTS];
    366 
    367 	int			ahcictl_flags;
    368 	int			ahcictl_power_level;
    369 	off_t			ahcictl_pmcsr_offset;
    370 
    371 	/*
    372 	 * AHCI_CAP_PIO_MDRQ
    373 	 * AHCI_CAP_NO_MCMDLIST_NONQUEUE
    374 	 * AHCI_CAP_NCQ
    375 	 * AHCI_CAP_PM
    376 	 * AHCI_CAP_BUF_32BIT_DMA
    377 	 * AHCI_CAP_SCLO
    378 	 * AHCI_CAP_COMMU_32BIT_DMA
    379 	 * AHCI_CAP_INIT_PORT_RESET
    380 	 * AHCI_CAP_SNTF
    381 	 * AHCI_CAP_PMULT_CBSS
    382 	 * AHCI_CAP_PMULT_FBSS
    383 	 * AHCI_CAP_SRST_NO_HOSTPORT
    384 	 */
    385 	int			ahcictl_cap;
    386 
    387 	/* Pci configuration space handle */
    388 	ddi_acc_handle_t	ahcictl_pci_conf_handle;
    389 
    390 	/* Mapping into bar 5 - AHCI base address */
    391 	ddi_acc_handle_t	ahcictl_ahci_acc_handle;
    392 	uintptr_t		ahcictl_ahci_addr;
    393 
    394 	/* Pointer used for sata hba framework registration */
    395 	struct sata_hba_tran	*ahcictl_sata_hba_tran;
    396 
    397 	/* DMA attributes for the data buffer */
    398 	ddi_dma_attr_t		ahcictl_buffer_dma_attr;
    399 	/* DMA attributes for the rcvd FIS */
    400 	ddi_dma_attr_t		ahcictl_rcvd_fis_dma_attr;
    401 	/* DMA attributes for the command list */
    402 	ddi_dma_attr_t		ahcictl_cmd_list_dma_attr;
    403 	/* DMA attributes for command tables */
    404 	ddi_dma_attr_t		ahcictl_cmd_table_dma_attr;
    405 
    406 	/* Used for watchdog handler */
    407 	timeout_id_t		ahcictl_timeout_id;
    408 
    409 	/* Per controller mutex */
    410 	kmutex_t		ahcictl_mutex;
    411 
    412 	/* Components for interrupt */
    413 	ddi_intr_handle_t	*ahcictl_intr_htable;   /* For array of intrs */
    414 	int			ahcictl_intr_type; /* What type of interrupt */
    415 	int			ahcictl_intr_cnt;  /* # of intrs returned */
    416 	size_t			ahcictl_intr_size; /* Size of intr array */
    417 	uint_t			ahcictl_intr_pri;  /* Intr priority */
    418 	int			ahcictl_intr_cap;  /* Intr capabilities */
    419 } ahci_ctl_t;
    420 
    421 /* Warlock annotation */
    422 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_ports))
    423 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_cport_to_port))
    424 _NOTE(READ_ONLY_DATA(ahci_ctl_t::ahcictl_port_to_cport))
    425 
    426 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
    427 					ahci_ctl_t::ahcictl_power_level))
    428 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
    429 					ahci_ctl_t::ahcictl_flags))
    430 _NOTE(MUTEX_PROTECTS_DATA(ahci_ctl_t::ahcictl_mutex,
    431 					ahci_ctl_t::ahcictl_timeout_id))
    432 
    433 #define	AHCI_SUCCESS	(0)  /* Successful return */
    434 #define	AHCI_TIMEOUT	(1)  /* Timed out */
    435 #define	AHCI_FAILURE	(-1) /* Unsuccessful return */
    436 
    437 /* Flags for ahcictl_flags */
    438 #define	AHCI_ATTACH		0x1
    439 #define	AHCI_DETACH		0x2
    440 #define	AHCI_SUSPEND		0x4
    441 
    442 /* Values for ahcictl_cap */
    443 /* PIO Multiple DRQ Block */
    444 #define	AHCI_CAP_PIO_MDRQ		0x1
    445 /*
    446  * Multiple command slots in the command list cannot be used for
    447  * non-queued commands
    448  */
    449 #define	AHCI_CAP_NO_MCMDLIST_NONQUEUE	0x2
    450 /* Native Command Queuing (NCQ) */
    451 #define	AHCI_CAP_NCQ			0x4
    452 /* Power Management (PM) */
    453 #define	AHCI_CAP_PM			0x8
    454 /* 32-bit DMA addressing for buffer block */
    455 #define	AHCI_CAP_BUF_32BIT_DMA		0x10
    456 /* Supports Command List Override */
    457 #define	AHCI_CAP_SCLO			0x20
    458 /* 32-bit DMA addressing for communication memory descriptors */
    459 #define	AHCI_CAP_COMMU_32BIT_DMA	0x40
    460 /* Port reset is needed for initialization */
    461 #define	AHCI_CAP_INIT_PORT_RESET	0x80
    462 /* Port Asychronous Notification */
    463 #define	AHCI_CAP_SNTF			0x100
    464 /* Port Multiplier Command-Based Switching Support (PMULT_CBSS) */
    465 #define	AHCI_CAP_PMULT_CBSS		0x200
    466 /* Port Multiplier FIS-Based Switching Support (PMULT_FBSS) */
    467 #define	AHCI_CAP_PMULT_FBSS		0x400
    468 /* Software Reset FIS cannot set pmport with 0xf for direct access device */
    469 #define	AHCI_CAP_SRST_NO_HOSTPORT	0x800
    470 
    471 /* Flags controlling the restart port behavior */
    472 #define	AHCI_PORT_RESET		0x0001	/* Reset the port */
    473 #define	AHCI_RESET_NO_EVENTS_UP	0x0002	/* Don't send reset events up */
    474 
    475 #define	ERR_RETRI_CMD_IN_PROGRESS(ahci_portp)		\
    476 	(ahci_portp->ahciport_flags &			\
    477 	(AHCI_PORT_FLAG_RQSENSE|AHCI_PORT_FLAG_RDLOGEXT))
    478 
    479 #define	RDWR_PMULT_CMD_IN_PROGRESS(ahci_portp)		\
    480 	(ahci_portp->ahciport_flags &			\
    481 	AHCI_PORT_FLAG_RDWR_PMULT)
    482 
    483 #define	NON_NCQ_CMD_IN_PROGRESS(ahci_portp)		\
    484 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
    485 	ahci_portp->ahciport_pending_tags != 0 &&	\
    486 	ahci_portp->ahciport_pending_ncq_tags == 0)
    487 
    488 #define	NCQ_CMD_IN_PROGRESS(ahci_portp)			\
    489 	(!ERR_RETRI_CMD_IN_PROGRESS(ahci_portp) &&	\
    490 	ahci_portp->ahciport_pending_ncq_tags != 0)
    491 
    492 /* Command type for ahci_claim_free_slot routine */
    493 #define	AHCI_NON_NCQ_CMD	0x0
    494 #define	AHCI_NCQ_CMD		0x1
    495 #define	AHCI_ERR_RETRI_CMD	0x2
    496 #define	AHCI_RDWR_PMULT_CMD	0x4
    497 
    498 /* State values for ahci_attach */
    499 #define	AHCI_ATTACH_STATE_NONE			(0x1 << 0)
    500 #define	AHCI_ATTACH_STATE_STATEP_ALLOC		(0x1 << 1)
    501 #define	AHCI_ATTACH_STATE_REG_MAP		(0x1 << 2)
    502 #define	AHCI_ATTACH_STATE_PCICFG_SETUP		(0x1 << 3)
    503 #define	AHCI_ATTACH_STATE_INTR_ADDED		(0x1 << 4)
    504 #define	AHCI_ATTACH_STATE_MUTEX_INIT		(0x1 << 5)
    505 #define	AHCI_ATTACH_STATE_PORT_ALLOC		(0x1 << 6)
    506 #define	AHCI_ATTACH_STATE_HW_INIT		(0x1 << 7)
    507 #define	AHCI_ATTACH_STATE_TIMEOUT_ENABLED	(0x1 << 8)
    508 
    509 /* Interval used for delay */
    510 #define	AHCI_10MS_TICKS	(drv_usectohz(10000))	/* ticks in 10 ms */
    511 #define	AHCI_1MS_TICKS	(drv_usectohz(1000))	/* ticks in 1 ms */
    512 #define	AHCI_100US_TICKS	(drv_usectohz(100))	/* ticks in 100 us */
    513 #define	AHCI_10MS_USECS		(10000)		/* microsecs in 10 millisec */
    514 #define	AHCI_1MS_USECS		(1000)		/* microsecs in 1 millisec */
    515 #define	AHCI_100US_USECS	(100)
    516 
    517 /*
    518  * The following values are the numbers of times to retry polled requests.
    519  */
    520 #define	AHCI_POLLRATE_HBA_RESET		100
    521 #define	AHCI_POLLRATE_PORT_SSTATUS	10
    522 #define	AHCI_POLLRATE_PORT_TFD_ERROR	1100
    523 #define	AHCI_POLLRATE_PORT_IDLE		50
    524 #define	AHCI_POLLRATE_PORT_SOFTRESET	100
    525 #define	AHCI_POLLRATE_GET_SPKT		100
    526 
    527 
    528 /* Clearing & setting the n'th bit in a given tag */
    529 #define	CLEAR_BIT(tag, bit)	(tag &= ~(0x1<<bit))
    530 #define	SET_BIT(tag, bit)	(tag |= (0x1<<bit))
    531 
    532 
    533 #if DEBUG
    534 
    535 #define	AHCI_DEBUG		1
    536 
    537 #endif
    538 
    539 #define	AHCIDBG_INIT		0x0001
    540 #define	AHCIDBG_ENTRY		0x0002
    541 #define	AHCIDBG_PRDT		0x0004
    542 #define	AHCIDBG_EVENT		0x0008
    543 #define	AHCIDBG_POLL_LOOP	0x0010
    544 #define	AHCIDBG_PKTCOMP		0x0020
    545 #define	AHCIDBG_TIMEOUT		0x0040
    546 #define	AHCIDBG_INFO		0x0080
    547 #define	AHCIDBG_VERBOSE		0x0100
    548 #define	AHCIDBG_INTR		0x0200
    549 #define	AHCIDBG_ERRS		0x0400
    550 #define	AHCIDBG_ATACMD		0x0800
    551 #define	AHCIDBG_ATAPICMD	0x1000
    552 #define	AHCIDBG_SENSEDATA	0x2000
    553 #define	AHCIDBG_NCQ		0x4000
    554 #define	AHCIDBG_PM		0x8000
    555 #define	AHCIDBG_UNDERFLOW	0x10000
    556 #define	AHCIDBG_MSI		0x20000
    557 #define	AHCIDBG_PMULT		0x40000
    558 
    559 extern uint32_t ahci_debug_flags;
    560 
    561 #if DEBUG
    562 
    563 #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
    564 	if (ahci_debug_flags & (flag)) {			\
    565 		ahci_log(ahci_ctlp, CE_WARN, fmt, ## args);	\
    566 		if (ahci_ctlp == NULL)				\
    567 			sata_trace_debug(NULL, fmt, ## args);	\
    568 		else						\
    569 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
    570 			    fmt, ## args);			\
    571 	}
    572 
    573 #else
    574 
    575 #define	AHCIDBG(flag, ahci_ctlp, fmt, args ...)			\
    576 	if (ahci_debug_flags & (flag)) {			\
    577 		if (ahci_ctlp == NULL)				\
    578 			sata_trace_debug(NULL, fmt, ## args);	\
    579 		else						\
    580 			sata_trace_debug(ahci_ctlp->ahcictl_dip,\
    581 			    fmt, ## args);			\
    582 	}
    583 
    584 #endif /* DEBUG */
    585 
    586 
    587 #ifdef	__cplusplus
    588 }
    589 #endif
    590 
    591 #endif /* _AHCIVAR_H */
    592