xref: /titanic_52/usr/src/uts/common/sys/sata/sata_hba.h (revision 0c6eaab480b44a0c790ad94e7cb6084792411de9)
166f9d5cbSmlf /*
266f9d5cbSmlf  * CDDL HEADER START
366f9d5cbSmlf  *
466f9d5cbSmlf  * The contents of this file are subject to the terms of the
566f9d5cbSmlf  * Common Development and Distribution License (the "License").
666f9d5cbSmlf  * You may not use this file except in compliance with the License.
766f9d5cbSmlf  *
866f9d5cbSmlf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
966f9d5cbSmlf  * or http://www.opensolaris.org/os/licensing.
1066f9d5cbSmlf  * See the License for the specific language governing permissions
1166f9d5cbSmlf  * and limitations under the License.
1266f9d5cbSmlf  *
1366f9d5cbSmlf  * When distributing Covered Code, include this CDDL HEADER in each
1466f9d5cbSmlf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1566f9d5cbSmlf  * If applicable, add the following below this CDDL HEADER, with the
1666f9d5cbSmlf  * fields enclosed by brackets "[]" replaced with your own identifying
1766f9d5cbSmlf  * information: Portions Copyright [yyyy] [name of copyright owner]
1866f9d5cbSmlf  *
1966f9d5cbSmlf  * CDDL HEADER END
2066f9d5cbSmlf  */
2166f9d5cbSmlf 
2266f9d5cbSmlf /*
23f5f2d263SFred Herard  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
2466f9d5cbSmlf  * Use is subject to license terms.
2566f9d5cbSmlf  */
26257c04ecSMarcel Telka /*
27*0c6eaab4SHans Rosenfeld  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
28257c04ecSMarcel Telka  */
2966f9d5cbSmlf 
3066f9d5cbSmlf #ifndef _SATA_HBA_H
3166f9d5cbSmlf #define	_SATA_HBA_H
3266f9d5cbSmlf 
3366f9d5cbSmlf #ifdef	__cplusplus
3466f9d5cbSmlf extern "C" {
3566f9d5cbSmlf #endif
3666f9d5cbSmlf 
3766f9d5cbSmlf #include <sys/sata/sata_defs.h>
3866f9d5cbSmlf 
3966f9d5cbSmlf /*
4066f9d5cbSmlf  * SATA Host Bus Adapter (HBA) driver transport definitions
4166f9d5cbSmlf  */
4266f9d5cbSmlf 
4366f9d5cbSmlf #include <sys/types.h>
4466f9d5cbSmlf 
4566f9d5cbSmlf #ifndef	TRUE
4666f9d5cbSmlf #define	TRUE	1
4766f9d5cbSmlf #define	FALSE	0
4866f9d5cbSmlf #endif
4966f9d5cbSmlf 
5066f9d5cbSmlf #define	SATA_SUCCESS	0
51a022fe3eSls24207 #define	SATA_RETRY	1
5266f9d5cbSmlf #define	SATA_FAILURE	-1
5366f9d5cbSmlf 
5466f9d5cbSmlf 
5566f9d5cbSmlf /* SATA Framework definitions */
5666f9d5cbSmlf 
5766f9d5cbSmlf #define	SATA_MAX_CPORTS		32	/* Max number of controller ports */
5866f9d5cbSmlf 					/* Multiplier (PMult) */
5966f9d5cbSmlf #define	SATA_MAX_PMPORTS	16	/* Maximum number of ports on PMult */
6066f9d5cbSmlf #define	SATA_PMULT_HOSTPORT	0xf	/* Port Multiplier host port number */
6166f9d5cbSmlf 
6266f9d5cbSmlf 
6366f9d5cbSmlf /*
6466f9d5cbSmlf  * SATA device address
6566f9d5cbSmlf  * Address qualifier flags are used to specify what is addressed (device
6666f9d5cbSmlf  * or port) and where (controller or port multiplier data port).
6766f9d5cbSmlf  */
6866f9d5cbSmlf struct sata_address {
6966f9d5cbSmlf 	uint8_t		cport;		/* Controller's SATA port number */
7066f9d5cbSmlf 	uint8_t 	pmport;		/* Port Multiplier SATA port number */
7166f9d5cbSmlf 	uint8_t		qual;		/* Address Qualifier flags */
7266f9d5cbSmlf 	uint8_t		pad;		/* Reserved */
7366f9d5cbSmlf };
7466f9d5cbSmlf 
7566f9d5cbSmlf typedef struct sata_address sata_address_t;
7666f9d5cbSmlf 
7766f9d5cbSmlf /*
7866f9d5cbSmlf  * SATA address Qualifier flags (in qual field of sata_address struct).
7966f9d5cbSmlf  * They are mutually exclusive.
8066f9d5cbSmlf  */
8166f9d5cbSmlf 
8266f9d5cbSmlf #define	SATA_ADDR_NULL		0x00	/* No address */
8366f9d5cbSmlf #define	SATA_ADDR_DCPORT	0x01	/* Device attched to controller port */
8466f9d5cbSmlf #define	SATA_ADDR_DPMPORT	0x02	/* Device attched to PM device port */
8566f9d5cbSmlf #define	SATA_ADDR_CPORT		0x04	/* Controller's device port */
8666f9d5cbSmlf #define	SATA_ADDR_PMPORT	0x08	/* Port Multiplier's device port */
8766f9d5cbSmlf #define	SATA_ADDR_CNTRL		0x10	/* Controller */
8866f9d5cbSmlf #define	SATA_ADDR_PMULT		0x20	/* Port Multiplier */
89918304a3SXiao-Yu Zhang #define	SATA_ADDR_PMULT_SPEC	0x40	/* Port Multiplier Specific */
9066f9d5cbSmlf 
9166f9d5cbSmlf /*
9266f9d5cbSmlf  * SATA port status and control register block.
9366f9d5cbSmlf  * The sstatus, serror, scontrol, sactive and snotific
9466f9d5cbSmlf  * are the copies of the SATA port status and control registers.
9566f9d5cbSmlf  * (Port SStatus, SError, SControl, SActive and SNotification are
9666f9d5cbSmlf  * defined by Serial ATA r1.0a sepc and Serial ATA II spec.
9766f9d5cbSmlf  */
9866f9d5cbSmlf 
9966f9d5cbSmlf struct sata_port_scr
10066f9d5cbSmlf {
10166f9d5cbSmlf 	uint32_t	sstatus;	/* Port SStatus register */
10266f9d5cbSmlf 	uint32_t	serror;		/* Port SError register */
10366f9d5cbSmlf 	uint32_t	scontrol;	/* Port SControl register */
10466f9d5cbSmlf 	uint32_t	sactive;	/* Port SActive register */
10566f9d5cbSmlf 	uint32_t	snotific; 	/* Port SNotification register */
10666f9d5cbSmlf };
10766f9d5cbSmlf 
10866f9d5cbSmlf typedef struct sata_port_scr sata_port_scr_t;
10966f9d5cbSmlf 
11066f9d5cbSmlf /*
1118aa6aadbSXiao-Yu Zhang  * SATA Port Multiplier general status and control register block.
1128aa6aadbSXiao-Yu Zhang  * The gscr0, gscr1, gscr2 are the copyies of the register on port multiplier.
1138aa6aadbSXiao-Yu Zhang  * GSCR[0], GSCR[1], GSCR[2] are defined in SATA defined by Port Multiplier
1148aa6aadbSXiao-Yu Zhang  * 1.0/1.1/1.2 spec.
1158aa6aadbSXiao-Yu Zhang  */
1168aa6aadbSXiao-Yu Zhang struct sata_pmult_gscr {
1178aa6aadbSXiao-Yu Zhang 	uint32_t	gscr0;		/* Product Identifier register */
1188aa6aadbSXiao-Yu Zhang 	uint32_t	gscr1;		/* Resrved Information register */
1198aa6aadbSXiao-Yu Zhang 	uint32_t	gscr2;		/* Port Information register */
1208aa6aadbSXiao-Yu Zhang 	uint32_t	gscr64;		/* Feature register */
121918304a3SXiao-Yu Zhang 	uint32_t	resv[4];	/* Reseved */
1228aa6aadbSXiao-Yu Zhang };
1238aa6aadbSXiao-Yu Zhang 
1248aa6aadbSXiao-Yu Zhang typedef struct sata_pmult_gscr sata_pmult_gscr_t;
1258aa6aadbSXiao-Yu Zhang 
1268aa6aadbSXiao-Yu Zhang /*
12766f9d5cbSmlf  * SATA Device Structure (rev 1)
12866f9d5cbSmlf  * Used to request/return state of the controller, port, port multiplier
12966f9d5cbSmlf  * or an attached drive:
13066f9d5cbSmlf  *  	The satadev_addr.cport, satadev_addr.pmport and satadev_addr.qual
13166f9d5cbSmlf  *  	fields are used to specify SATA address (see sata_address structure
13266f9d5cbSmlf  *  	description).
13366f9d5cbSmlf  * 	The satadev_scr structure is used to pass the content of a port
13466f9d5cbSmlf  *	status and control registers.
13566f9d5cbSmlf  *	The satadev_add_info field is used by SATA HBA driver to return an
13666f9d5cbSmlf  *	additional information, which type depends on the function using
13766f9d5cbSmlf  *	sata_device as argument. For example:
13866f9d5cbSmlf  *	- in case of sata_tran_probe_port() this field should contain
13966f9d5cbSmlf  *	a number of available Port Multiplier device ports;
14066f9d5cbSmlf  *	- in case of sata_hba_event_notify() this field may contain
14166f9d5cbSmlf  *	a value specific for a reported event.
14266f9d5cbSmlf  */
14366f9d5cbSmlf #define	SATA_DEVICE_REV_1	1
144918304a3SXiao-Yu Zhang #define	SATA_DEVICE_REV		SATA_DEVICE_REV_1
14566f9d5cbSmlf 
14666f9d5cbSmlf struct sata_device
14766f9d5cbSmlf {
14866f9d5cbSmlf 	int		satadev_rev;		/* structure  version */
14966f9d5cbSmlf 	struct sata_address satadev_addr;	/* sata port/device address */
15066f9d5cbSmlf 	uint32_t	satadev_state;		/* Port or device state */
15166f9d5cbSmlf 	uint32_t	satadev_type;		/* Attached device type */
15266f9d5cbSmlf 	struct sata_port_scr satadev_scr; 	/* Port status and ctrl regs */
15366f9d5cbSmlf 	uint32_t	satadev_add_info;	/* additional information, */
15466f9d5cbSmlf 						/* function specific */
15566f9d5cbSmlf };
15666f9d5cbSmlf 
15766f9d5cbSmlf typedef struct sata_device sata_device_t;
15866f9d5cbSmlf 
15966f9d5cbSmlf _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_device))
16066f9d5cbSmlf 
16166f9d5cbSmlf 
16266f9d5cbSmlf /*
16366f9d5cbSmlf  * satadev_state field of sata_device structure.
16466f9d5cbSmlf  * Common flags specifying current state of a port or an attached drive.
1654372d277Spawelw  * These states are mutually exclusive, obviously
16666f9d5cbSmlf  */
16766f9d5cbSmlf #define	SATA_STATE_UNKNOWN		0x000000
16866f9d5cbSmlf #define	SATA_STATE_READY		0x000010
16966f9d5cbSmlf 
17066f9d5cbSmlf /*
17166f9d5cbSmlf  * Attached drive specific states (satadev_state field of the sata_device
17266f9d5cbSmlf  * structure).
17366f9d5cbSmlf  * SATA_DSTATE_PWR_ACTIVE, SATA_DSTATE_PWR_IDLE and SATA_DSTATE_PWR_STANDBY
17466f9d5cbSmlf  * are mutually exclusive. All other states may be combined with each other
17566f9d5cbSmlf  * and with one of the power states.
17666f9d5cbSmlf  * These flags may be used only if the address qualifier (satadev_addr.qual) is
17766f9d5cbSmlf  * set to SATA_ADDR_DCPORT or SATA_ADDR_DPMPORT value.
17866f9d5cbSmlf  */
17966f9d5cbSmlf 
18066f9d5cbSmlf #define	SATA_DSTATE_PWR_ACTIVE		0x000100
18166f9d5cbSmlf #define	SATA_DSTATE_PWR_IDLE		0x000200
18266f9d5cbSmlf #define	SATA_DSTATE_PWR_STANDBY		0x000400
18366f9d5cbSmlf #define	SATA_DSTATE_RESET		0x001000
1848aa6aadbSXiao-Yu Zhang #define	SATA_DSTATE_PMULT_INIT		0x002000
18566f9d5cbSmlf #define	SATA_DSTATE_FAILED		0x008000
18666f9d5cbSmlf 
18766f9d5cbSmlf /* Mask for drive power states */
18866f9d5cbSmlf #define	SATA_DSTATE_PWR			(SATA_DSTATE_PWR_ACTIVE | \
18966f9d5cbSmlf 					SATA_DSTATE_PWR_IDLE | \
19066f9d5cbSmlf 					SATA_DSTATE_PWR_STANDBY)
19166f9d5cbSmlf /*
19266f9d5cbSmlf  * SATA Port specific states (satadev_state field of sata_device structure).
19366f9d5cbSmlf  * SATA_PSTATE_PWRON and SATA_PSTATE_PWROFF are mutually exclusive.
19466f9d5cbSmlf  * All other states may be combined with each other and with one of the power
19566f9d5cbSmlf  * level state.
19666f9d5cbSmlf  * These flags may be used only if the address qualifier (satadev_addr.qual) is
19766f9d5cbSmlf  * set to SATA_ADDR_CPORT or SATA_ADDR_PMPORT value.
19866f9d5cbSmlf  */
19966f9d5cbSmlf 
20066f9d5cbSmlf #define	SATA_PSTATE_PWRON		0x010000
20166f9d5cbSmlf #define	SATA_PSTATE_PWROFF		0X020000
20266f9d5cbSmlf #define	SATA_PSTATE_SHUTDOWN		0x040000
20366f9d5cbSmlf #define	SATA_PSTATE_FAILED		0x080000
20466f9d5cbSmlf 
20566f9d5cbSmlf /* Mask for the valid port-specific state flags */
20666f9d5cbSmlf #define	SATA_PSTATE_VALID		(SATA_PSTATE_PWRON | \
20766f9d5cbSmlf 					SATA_PSTATE_PWROFF | \
20866f9d5cbSmlf 					SATA_PSTATE_SHUTDOWN | \
20966f9d5cbSmlf 					SATA_PSTATE_FAILED)
21066f9d5cbSmlf 
21166f9d5cbSmlf /* Mask for a port power states */
21266f9d5cbSmlf #define	SATA_PSTATE_PWR			(SATA_PSTATE_PWRON | \
21366f9d5cbSmlf 					SATA_PSTATE_PWROFF)
21466f9d5cbSmlf /*
21566f9d5cbSmlf  * Device type (in satadev_type field of sata_device structure).
21666f9d5cbSmlf  * More device types may be added in the future.
21766f9d5cbSmlf  */
21866f9d5cbSmlf 
21966f9d5cbSmlf #define	SATA_DTYPE_NONE			0x00	/* No device attached */
22038547057Sying tian - Beijing China #define	SATA_DTYPE_ATADISK		0x01	/* ATA disk */
22138547057Sying tian - Beijing China #define	SATA_DTYPE_ATAPI		0x40	/* ATAPI device */
22238547057Sying tian - Beijing China #define	SATA_DTYPE_ATAPICD	\
22338547057Sying tian - Beijing China 	(SATA_DTYPE_ATAPI|0x02)			/* ATAPI CD/DVD device */
22438547057Sying tian - Beijing China #define	SATA_DTYPE_ATAPITAPE	\
22538547057Sying tian - Beijing China 	(SATA_DTYPE_ATAPI|0x04)			/* ATAPI tape */
22638547057Sying tian - Beijing China #define	SATA_DTYPE_ATAPIDISK	\
22738547057Sying tian - Beijing China 	(SATA_DTYPE_ATAPI|0x08)			/* ATAPI disk */
22866f9d5cbSmlf #define	SATA_DTYPE_PMULT		0x10	/* Port Multiplier */
22966f9d5cbSmlf #define	SATA_DTYPE_UNKNOWN		0x20	/* Device attached, unkown */
230257c04ecSMarcel Telka #define	SATA_DTYPE_ATAPIPROC	\
231257c04ecSMarcel Telka 	(SATA_DTYPE_ATAPI|0x80)			/* ATAPI processor */
23266f9d5cbSmlf 
23366f9d5cbSmlf 
23466f9d5cbSmlf /*
23566f9d5cbSmlf  * SATA cmd structure  (rev 1)
23666f9d5cbSmlf  *
23766f9d5cbSmlf  * SATA HBA framework always sets all fields except status_reg and error_reg.
23866f9d5cbSmlf  * SATA HBA driver action depends on the addressing type specified by
23966f9d5cbSmlf  * addr_type field:
24066f9d5cbSmlf  * If LBA48 addressing is indicated, SATA HBA driver has to load values from
24166f9d5cbSmlf  * satacmd_sec_count_msb_reg, satacmd_lba_low_msb_reg,
24266f9d5cbSmlf  * satacmd_lba_mid_msb_reg and satacmd_lba_hi_msb_reg
24366f9d5cbSmlf  * to appropriate registers prior to loading other registers.
24466f9d5cbSmlf  * For other addressing modes, SATA HBA driver should skip loading values
24566f9d5cbSmlf  * from satacmd_sec_count_msb_reg, satacmd_lba_low_msb_reg,
24666f9d5cbSmlf  * satacmd_lba_mid_msb_reg and satacmd_lba_hi_msb_reg
24766f9d5cbSmlf  * fields and load only remaining field values to corresponding registers.
24866f9d5cbSmlf  *
24966f9d5cbSmlf  * satacmd_sec_count_msb and satamcd_sec_count_lsb values are loaded into
25066f9d5cbSmlf  * sec_count register, satacmd_sec_count_msb loaded first (if LBA48
25166f9d5cbSmlf  * addressing is used).
25266f9d5cbSmlf  * satacmd_lba_low_msb and satacmd_lba_low_lsb values are loaded into the
25366f9d5cbSmlf  * lba_low register, satacmd_lba_low_msb loaded first (if LBA48 addressing
25466f9d5cbSmlf  * is used). The lba_low register is the newer name for the old
25566f9d5cbSmlf  * sector_number register.
25666f9d5cbSmlf  * satacmd_lba_mid_msb and satacmd_lba_mid_lsb values are loaded into lba_mid
25766f9d5cbSmlf  * register, satacmd_lba_mid_msb loaded first (if LBA48 addressing is used).
25866f9d5cbSmlf  * The lba_mid register is the newer name for the old cylinder_low register.
25966f9d5cbSmlf  * satacmd_lba_high_msb and satacmd_lba_high_lsb values are loaded into
26066f9d5cbSmlf  * the lba_high regster, satacmd_lba_high_msb loaded first (if LBA48
26166f9d5cbSmlf  * addressing is used). The lba_high register  is a newer name for the old
26266f9d5cbSmlf  * cylinder_high register.
26366f9d5cbSmlf  *
26466f9d5cbSmlf  * No addressing mode is selected when an ata command does not involve actual
26566f9d5cbSmlf  * reading/writing data from/to the media (for example IDENTIFY DEVICE or
26666f9d5cbSmlf  * SET FEATURE command), or the ATAPI PACKET command is sent.
26766f9d5cbSmlf  * If ATAPI PACKET command is sent and tagged commands are used,
26866f9d5cbSmlf  * SATA HBA driver has to provide and manage a tag value and
26966f9d5cbSmlf  * set it into the sector_count register.
27066f9d5cbSmlf  *
27166f9d5cbSmlf  * Device Control register is not specified in sata_cmd structure - SATA HBA
27266f9d5cbSmlf  * driver shall set it accordingly to current mode of operation (interrupt
27366f9d5cbSmlf  * enable/disable).
27466f9d5cbSmlf  *
27566f9d5cbSmlf  * Buffer structure's b_flags should be used to determine the
27666f9d5cbSmlf  * address type of b_un.b_addr. However, there is no need to allocate DMA
27766f9d5cbSmlf  * resources for the buffer in SATA HBA driver.
27866f9d5cbSmlf  * DMA resources for a buffer structure are allocated by the SATA HBA
27966f9d5cbSmlf  * framework. Scatter/gather list is to be used only for DMA transfers
28066f9d5cbSmlf  * and it should be based on the DMA cookies list.
28166f9d5cbSmlf  *
28266f9d5cbSmlf  * Upon completion of a command, SATA HBA driver has to update
28366f9d5cbSmlf  * satacmd_status_reg and satacmd_error_reg to reflect the contents of
28466f9d5cbSmlf  * the corresponding device status and error registers.
2856f9b9bf4Spawelw  * If the command completed successfully, satacmd_flags.sata_copy_xxx flags
2866f9b9bf4Spawelw  * specify what register fields should be updated in sata_cmd structure.
28766f9d5cbSmlf  * If the command completed with error, SATA HBA driver has to update
28866f9d5cbSmlf  * satacmd_sec_count_msb, satacmd_sec_count_lsb, satacmd_lba_low_msb,
28966f9d5cbSmlf  * satacmd_lba_low_lsb, satacmd_lba_mid_msb, satacmd_lba_mid_lsb,
29066f9d5cbSmlf  * satacmd_lba_high_msb and satacmd_lba_high_lsb to values read from the
29166f9d5cbSmlf  * corresponding device registers.
29266f9d5cbSmlf  * If an operation could not complete because of the port error, the
29366f9d5cbSmlf  * sata_pkt.satapkt_device.satadev_scr structure has to be updated.
29466f9d5cbSmlf  *
29566f9d5cbSmlf  * If ATAPI PACKET command was sent and command completed with error,
29666f9d5cbSmlf  * rqsense structure has to be filed by SATA HBA driver. The satacmd_arq_cdb
29766f9d5cbSmlf  * points to pre-set request sense cdb that may be used for issuing request
29866f9d5cbSmlf  * sense data from the device.
29966f9d5cbSmlf  *
3006f9b9bf4Spawelw  * The sata_max_queue_depth field specifies the maximum allowable queue depth
3016f9b9bf4Spawelw  * minus one, i.e. for maximum queue depth of 32, sata_max_queue_depth would
3026f9b9bf4Spawelw  * be set to value 0x1f.
30366f9d5cbSmlf  * If FPDMA-type command was sent and command completed with error, the HBA
30466f9d5cbSmlf  * driver may use pre-set command READ LOG EXTENDED command pointed to
30566f9d5cbSmlf  * by satacmd_rle_sata_cmd field to retrieve error data from a device.
30666f9d5cbSmlf  * Only ATA register fields of the sata_cmd are set-up for that purpose.
30766f9d5cbSmlf  *
30866f9d5cbSmlf  * If the READ MULTIPLIER command was specified in cmd_reg (command directed
30966f9d5cbSmlf  * to a port multiplier host port rather then to an attached device),
31066f9d5cbSmlf  * upon the command completion SATA HBA driver has to update_sector count
31166f9d5cbSmlf  * and lba fields of the sata_cmd structure to values returned via
31266f9d5cbSmlf  * command block registers (task file registers).
31366f9d5cbSmlf  */
31466f9d5cbSmlf #define	SATA_CMD_REV_1	1
315c03acfcaSls24207 #define	SATA_CMD_REV_2	2
3162038334aSUnknown #define	SATA_CMD_REV_3	3
3172038334aSUnknown #define	SATA_CMD_REV	SATA_CMD_REV_3
31866f9d5cbSmlf 
31966f9d5cbSmlf #define	SATA_ATAPI_MAX_CDB_LEN	16	/* Covers both 12 and 16 byte cdbs */
3202038334aSUnknown #define	SATA_ATAPI_RQSENSE_LEN	24	/* Allocated Request Sense data */
3212038334aSUnknown #define	SATA_ATAPI_MIN_RQSENSE_LEN 18	/* Min Fixed size Request Sense data */
3222038334aSUnknown #define	SATA_ATAPI_RQSENSE_CDB_LEN 6	/* Request Sense CDB length */
32366f9d5cbSmlf 
3246f9b9bf4Spawelw #define	SATA_MAX_QUEUE_DEPTH	32	/* Default max queue depth */
3256f9b9bf4Spawelw 
32666f9d5cbSmlf struct sata_cmd {
32766f9d5cbSmlf 	int		satacmd_rev;		/* version */
32866f9d5cbSmlf 	struct buf	*satacmd_bp;		/* ptr to buffer structure */
329c03acfcaSls24207 	struct sata_cmd_flags {
330c03acfcaSls24207 		uint32_t	sata_data_direction : 3;	 /* 0-2 */
331c03acfcaSls24207 		uint32_t	: 1;		/* reserved */	 /* 3 */
332c03acfcaSls24207 		uint32_t	sata_queue_stag : 1;		 /* 4 */
333c03acfcaSls24207 		uint32_t	sata_queue_otag : 1;		 /* 5 */
334c03acfcaSls24207 		uint32_t	: 2;		/* reserved */	 /* 6-7 */
335c03acfcaSls24207 		uint32_t	sata_queued : 1;		 /* 8 */
336c03acfcaSls24207 		uint32_t	: 3;		/* reserved */	 /* 9-11 */
337c03acfcaSls24207 		uint32_t	sata_ignore_dev_reset : 1;	 /* 12 */
338c03acfcaSls24207 		uint32_t	sata_clear_dev_reset : 1;	 /* 13 */
339c03acfcaSls24207 		uint32_t	: 2;		/* reserved */	 /* 14-15 */
340c03acfcaSls24207 		uint32_t	sata_special_regs : 1;		 /* 16 */
341c03acfcaSls24207 		uint32_t	sata_copy_out_sec_count_msb : 1; /* 17 */
342c03acfcaSls24207 		uint32_t	sata_copy_out_lba_low_msb : 1;	 /* 18 */
343c03acfcaSls24207 		uint32_t	sata_copy_out_lba_mid_msb : 1;	 /* 19 */
344c03acfcaSls24207 		uint32_t	sata_copy_out_lba_high_msb : 1;	 /* 20 */
345c03acfcaSls24207 		uint32_t	sata_copy_out_sec_count_lsb : 1; /* 21 */
346c03acfcaSls24207 		uint32_t	sata_copy_out_lba_low_lsb : 1;	 /* 22 */
347c03acfcaSls24207 		uint32_t	sata_copy_out_lba_mid_lsb : 1;	 /* 23 */
348c03acfcaSls24207 		uint32_t	sata_copy_out_lba_high_lsb : 1;	 /* 24 */
349c03acfcaSls24207 		uint32_t	sata_copy_out_device_reg : 1;	 /* 25 */
350c03acfcaSls24207 		uint32_t	sata_copy_out_error_reg : 1;	 /* 26 */
3512038334aSUnknown 		uint32_t	sata_max_queue_depth: 5;	 /* 27-31 */
352c03acfcaSls24207 	} satacmd_flags;
35366f9d5cbSmlf 	uint8_t 	satacmd_addr_type; 	/* addr type: LBA28, LBA48 */
35466f9d5cbSmlf 	uint8_t		satacmd_features_reg_ext; /* features reg extended */
35566f9d5cbSmlf 	uint8_t		satacmd_sec_count_msb;	/* sector count MSB (LBA48) */
35666f9d5cbSmlf 	uint8_t		satacmd_lba_low_msb; 	/* LBA Low MSB (LBA48) */
35766f9d5cbSmlf 	uint8_t		satacmd_lba_mid_msb;	/* LBA Mid MSB (LBA48) */
35866f9d5cbSmlf 	uint8_t		satacmd_lba_high_msb;	/* LBA High MSB (LBA48) */
35966f9d5cbSmlf 	uint8_t		satacmd_sec_count_lsb;	/* sector count LSB */
36066f9d5cbSmlf 	uint8_t		satacmd_lba_low_lsb;	/* LBA Low LSB */
36166f9d5cbSmlf 	uint8_t		satacmd_lba_mid_lsb;	/* LBA Mid LSB */
36266f9d5cbSmlf 	uint8_t		satacmd_lba_high_lsb;	/* LBA High LSB */
36366f9d5cbSmlf 	uint8_t		satacmd_device_reg;	/* ATA dev reg & LBA28 MSB */
36466f9d5cbSmlf 	uint8_t		satacmd_cmd_reg;	/* ata command code */
36566f9d5cbSmlf 	uint8_t		satacmd_features_reg;	/* ATA features register */
36666f9d5cbSmlf 	uint8_t		satacmd_status_reg;	/* ATA status register */
36766f9d5cbSmlf 	uint8_t		satacmd_error_reg;	/* ATA error register  */
36866f9d5cbSmlf 	uint8_t		satacmd_acdb_len;	/* ATAPI cdb length */
36966f9d5cbSmlf 	uint8_t		satacmd_acdb[SATA_ATAPI_MAX_CDB_LEN]; /* ATAPI cdb */
37066f9d5cbSmlf 
3712038334aSUnknown 						/* kept for binary compat. */
3722038334aSUnknown 	uint8_t		*pad1;			/* unused */
37366f9d5cbSmlf 
37466f9d5cbSmlf 	uint8_t 	satacmd_rqsense[SATA_ATAPI_RQSENSE_LEN];
37566f9d5cbSmlf 						/*
3762038334aSUnknown 						 * Error retrieval buffer
3772038334aSUnknown 						 * dma handle pointer
3782038334aSUnknown 						 * (for buffer DMA syncing)
3792038334aSUnknown 						 * Valid only in error
3802038334aSUnknown 						 * retrieval packet!
38166f9d5cbSmlf 						 */
3822038334aSUnknown 	ddi_dma_handle_t *satacmd_err_ret_buf_handle;
38366f9d5cbSmlf 
38466f9d5cbSmlf 	int		satacmd_num_dma_cookies; /* number of dma cookies */
38566f9d5cbSmlf 						/* ptr to dma cookie list */
38666f9d5cbSmlf 	ddi_dma_cookie_t *satacmd_dma_cookie_list;
38766f9d5cbSmlf };
38866f9d5cbSmlf 
38966f9d5cbSmlf typedef struct sata_cmd sata_cmd_t;
39066f9d5cbSmlf 
39166f9d5cbSmlf _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_cmd))
39266f9d5cbSmlf 
39366f9d5cbSmlf 
39466f9d5cbSmlf /* ATA address type (in satacmd_addr_type field */
39566f9d5cbSmlf #define	ATA_ADDR_LBA	0x1
39666f9d5cbSmlf #define	ATA_ADDR_LBA28	0x2
39766f9d5cbSmlf #define	ATA_ADDR_LBA48	0x4
39866f9d5cbSmlf 
39966f9d5cbSmlf /*
40066f9d5cbSmlf  * satacmd_flags : contain data transfer direction flags,
40166f9d5cbSmlf  * tagged queuing type flags, queued command flag, and reset state handling
40266f9d5cbSmlf  * flag.
40366f9d5cbSmlf  */
40466f9d5cbSmlf 
40566f9d5cbSmlf /*
406c03acfcaSls24207  * Data transfer direction flags (satacmd_flags.sata_data_direction)
40766f9d5cbSmlf  * Direction flags are mutually exclusive.
40866f9d5cbSmlf  */
40966f9d5cbSmlf #define	SATA_DIR_NODATA_XFER	0x0001	/* No data transfer */
41066f9d5cbSmlf #define	SATA_DIR_READ		0x0002	/* Reading data from a device */
41166f9d5cbSmlf #define	SATA_DIR_WRITE		0x0004	/* Writing data to a device */
41266f9d5cbSmlf 
41366f9d5cbSmlf /*
41437a077efSls24207  * Tagged Queuing type flags
41537a077efSls24207  * 	satacmd_flags.sata_queue_stag
41637a077efSls24207  * 	satacmd_flags.sata_queue_otag
41737a077efSls24207  *
41866f9d5cbSmlf  * These flags indicate how the SATA command should be queued.
41966f9d5cbSmlf  *
42037a077efSls24207  * sata_queue_stag
42166f9d5cbSmlf  * Simple-queue-tagged command. It may be executed out-of-order in respect
42266f9d5cbSmlf  * to other queued commands.
42337a077efSls24207  * sata_queue_otag
42466f9d5cbSmlf  * Ordered-queue-tagged command. It cannot be executed out-of-order in
42566f9d5cbSmlf  * respect to other commands, i.e. it should be executed in the order of
42666f9d5cbSmlf  * being transported to the HBA.
42766f9d5cbSmlf  *
42866f9d5cbSmlf  * Translated head-of-queue-tagged scsi commands and commands that are
42943fd86b4Sls24207  * to be put at the head of the queue are treated as sata_queue_otag
43066f9d5cbSmlf  * tagged commands.
43166f9d5cbSmlf  */
43266f9d5cbSmlf 
43366f9d5cbSmlf 
43466f9d5cbSmlf /*
43537a077efSls24207  * Queuing command set-up flag (satacmd_flags.sata_queued).
43666f9d5cbSmlf  * This flag indicates that sata_cmd was set-up for DMA Queued command
43766f9d5cbSmlf  * (either READ_DMA_QUEUED, READ_DMA_QUEUED_EXT, WRITE_DMA_QUEUED or
43866f9d5cbSmlf  * WRITE_DMA_QUEUED_EXT command) or one of the Native Command Queuing commands
43966f9d5cbSmlf  * (either READ_FPDMA_QUEUED or WRITE_FPDMA_QUEUED).
44066f9d5cbSmlf  * This flag will be used only if sata_tran_hba_flags indicates controller
44166f9d5cbSmlf  * support for queuing and the device for which sata_cmd is prepared supports
44266f9d5cbSmlf  * either legacy queuing (indicated by Device Identify data word 83 bit 2)
44366f9d5cbSmlf  * or NCQ (indicated by  word 76 of Device Identify data).
44466f9d5cbSmlf  */
44566f9d5cbSmlf 
44666f9d5cbSmlf /*
44737a077efSls24207  * Reset state handling
44837a077efSls24207  *	satacmd_flags.sata_ignore_dev_reset
44937a077efSls24207  *	satacmd_flags.sata_clear_dev_reset
45037a077efSls24207  *
45166f9d5cbSmlf  * SATA HBA device enters reset state if the device was subjected to
45266f9d5cbSmlf  * the Device Reset (may also enter this state if the device was reset
45366f9d5cbSmlf  * as a side effect of port reset). SATA HBA driver sets this state.
45466f9d5cbSmlf  * Device stays in this condition until explicit request from SATA HBA
45537a077efSls24207  * framework to clear the state.
45666f9d5cbSmlf  */
45766f9d5cbSmlf 
45866f9d5cbSmlf /*
45966f9d5cbSmlf  * SATA Packet structure (rev 1)
46066f9d5cbSmlf  * hba_driver_private is for a private use of the SATA HBA driver;
46166f9d5cbSmlf  * satapkt_framework_private is used only by SATA HBA framework;
46266f9d5cbSmlf  * satapkt_comp is a callback function to be called when packet
46366f9d5cbSmlf  * execution is completed (for any reason) if mode of operation is not
46466f9d5cbSmlf  * synchronous (SATA_OPMODE_SYNCH);
46566f9d5cbSmlf  * satapkt_reason specifies why the packet operation was completed
46666f9d5cbSmlf  *
46766f9d5cbSmlf  * NOTE: after the packet completion callback SATA HBA driver should not
46866f9d5cbSmlf  * attempt to access any sata_pkt fields because sata_pkt is not valid anymore
46966f9d5cbSmlf  * (it could have been destroyed).
47066f9d5cbSmlf  * Since satapkt_hba_driver_private field cannot be retrieved, any hba private
47166f9d5cbSmlf  * data respources allocated per packet and accessed via this pointer should
47266f9d5cbSmlf  * either be freed before the completion callback is done, or the pointer has
47366f9d5cbSmlf  * to be saved by the HBA driver before the completion callback.
47466f9d5cbSmlf  */
47566f9d5cbSmlf #define	SATA_PKT_REV_1	1
47666f9d5cbSmlf #define	SATA_PKT_REV	SATA_PKT_REV_1
47766f9d5cbSmlf 
47866f9d5cbSmlf struct sata_pkt {
47966f9d5cbSmlf 	int		satapkt_rev;		/* version */
48066f9d5cbSmlf 	struct sata_device satapkt_device;	/* Device address/type */
48166f9d5cbSmlf 
48266f9d5cbSmlf 						/* HBA driver private data */
48366f9d5cbSmlf 	void		*satapkt_hba_driver_private;
48466f9d5cbSmlf 
48566f9d5cbSmlf 						/* SATA framework priv data */
48666f9d5cbSmlf 	void		*satapkt_framework_private;
48766f9d5cbSmlf 
48866f9d5cbSmlf 						/* Rqsted mode of operation */
48966f9d5cbSmlf 	uint32_t	satapkt_op_mode;
49066f9d5cbSmlf 
49166f9d5cbSmlf 	struct sata_cmd	satapkt_cmd;		/* composite sata command */
49266f9d5cbSmlf 	int		satapkt_time;		/* time allotted to command */
49366f9d5cbSmlf 	void		(*satapkt_comp)(struct sata_pkt *); /* callback */
49466f9d5cbSmlf 	int		satapkt_reason; 	/* completion reason */
49566f9d5cbSmlf };
49666f9d5cbSmlf 
49766f9d5cbSmlf typedef struct sata_pkt sata_pkt_t;
49866f9d5cbSmlf 
49966f9d5cbSmlf _NOTE(SCHEME_PROTECTS_DATA("unshared data", sata_pkt))
50066f9d5cbSmlf 
50166f9d5cbSmlf 
50266f9d5cbSmlf /*
50366f9d5cbSmlf  * Operation mode flags (in satapkt_op_mode field of sata_pkt structure).
50466f9d5cbSmlf  * Use to specify what should be a mode of operation for specified command.
50566f9d5cbSmlf  * Default (000b) means use Interrupt and Asynchronous mode to
50666f9d5cbSmlf  * perform an operation.
50766f9d5cbSmlf  * Synchronous operation menas that the packet operation has to be completed
50866f9d5cbSmlf  * before the function called to initiate the operation returns.
50966f9d5cbSmlf  */
51066f9d5cbSmlf #define	SATA_OPMODE_INTERRUPTS	0 /* Use interrupts (hint) */
51166f9d5cbSmlf #define	SATA_OPMODE_POLLING	1 /* Use polling instead of interrupts */
51266f9d5cbSmlf #define	SATA_OPMODE_ASYNCH	0 /* Return immediately after accepting pkt */
51366f9d5cbSmlf #define	SATA_OPMODE_SYNCH	4 /* Perform synchronous operation */
51466f9d5cbSmlf 
51566f9d5cbSmlf /*
51666f9d5cbSmlf  * satapkt_reason values:
51766f9d5cbSmlf  *
51866f9d5cbSmlf  * SATA_PKT_QUEUE_FULL - cmd not sent because of queue full (detected
51966f9d5cbSmlf  * 	by the controller). If a device reject command for this reason, it
52066f9d5cbSmlf  * 	should be reported as SATA_PKT_DEV_ERROR
52166f9d5cbSmlf  *
52266f9d5cbSmlf  * SATA_PKT_CMD_NOT_SUPPORTED - command not supported by a controller
52366f9d5cbSmlf  *	Controller is unable to send such command to a device.
52466f9d5cbSmlf  *	If device rejects a command, it should be reported as
52566f9d5cbSmlf  *	SATA_PKT_DEV_ERROR.
52666f9d5cbSmlf  *
52766f9d5cbSmlf  * SATA_PKT_DEV_ERROR - cmd failed because of device reported an error.
52866f9d5cbSmlf  *	The content of status_reg (ERROR bit has to be set) and error_reg
52966f9d5cbSmlf  *	fields of the sata_cmd structure have to be set and will be used
53066f9d5cbSmlf  *	by SATA HBA Framework to determine the error cause.
53166f9d5cbSmlf  *
53266f9d5cbSmlf  * SATA_PKT_PORT_ERROR - cmd failed because of a link or a port error.
53366f9d5cbSmlf  *	Link failed / no communication with a device / communication error
53466f9d5cbSmlf  *	or other port related error was detected by a controller.
53566f9d5cbSmlf  *	sata_pkt.satapkt_device.satadev_scr.sXXXXXXX words have to be set.
53666f9d5cbSmlf  *
53766f9d5cbSmlf  * SATA_PKT_ABORTED - cmd execution was aborted by the request from the
53866f9d5cbSmlf  *	framework. Abort mechanism is HBA driver specific.
53966f9d5cbSmlf  *
54066f9d5cbSmlf  * SATA_PKT_TIMEOUT - cmd execution has timed-out. Timeout specified by
54166f9d5cbSmlf  *	 pkt_time was exceeded. The command was terminated by the SATA HBA
54266f9d5cbSmlf  *	driver.
54366f9d5cbSmlf  *
54466f9d5cbSmlf  * SATA_PKT_COMPLETED - this is a value returned when an operation
54566f9d5cbSmlf  *	completes without errors.
54666f9d5cbSmlf  *
54766f9d5cbSmlf  * SATA_PKT_BUSY - packet was not accepted for execution because the
54866f9d5cbSmlf  *      driver was busy performing some other operation(s).
54966f9d5cbSmlf  *
55066f9d5cbSmlf  * SATA_PKT_RESET - packet execution was aborted because of device
55166f9d5cbSmlf  * reset originated by either the HBA driver or the SATA framework.
55266f9d5cbSmlf  *
55366f9d5cbSmlf  */
55466f9d5cbSmlf 
55566f9d5cbSmlf #define	SATA_PKT_BUSY			-1	/* Not completed, busy */
55666f9d5cbSmlf #define	SATA_PKT_COMPLETED		0	/* No error */
55766f9d5cbSmlf #define	SATA_PKT_DEV_ERROR		1	/* Device reported error */
55866f9d5cbSmlf #define	SATA_PKT_QUEUE_FULL		2	/* Not accepted, queue full */
55966f9d5cbSmlf #define	SATA_PKT_PORT_ERROR		3	/* Not completed, port error */
56066f9d5cbSmlf #define	SATA_PKT_CMD_UNSUPPORTED	4	/* Cmd unsupported */
56166f9d5cbSmlf #define	SATA_PKT_ABORTED		5	/* Aborted by request */
56266f9d5cbSmlf #define	SATA_PKT_TIMEOUT		6	/* Operation timeut */
56366f9d5cbSmlf #define	SATA_PKT_RESET			7	/* Aborted by reset request */
56466f9d5cbSmlf 
56566f9d5cbSmlf /*
5662038334aSUnknown  * Error retrieval sata packet types
5672038334aSUnknown  */
5682038334aSUnknown #define	SATA_ERR_RETR_PKT_TYPE_NCQ	1
5692038334aSUnknown #define	SATA_ERR_RETR_PKT_TYPE_ATAPI	2
5702038334aSUnknown 
5712038334aSUnknown /*
5728aa6aadbSXiao-Yu Zhang  * Read/write port multiplier packet types
5738aa6aadbSXiao-Yu Zhang  */
5748aa6aadbSXiao-Yu Zhang #define	SATA_RDWR_PMULT_PKT_TYPE_READ	1
5758aa6aadbSXiao-Yu Zhang #define	SATA_RDWR_PMULT_PKT_TYPE_WRITE	2
5768aa6aadbSXiao-Yu Zhang 
5778aa6aadbSXiao-Yu Zhang /*
57866f9d5cbSmlf  * Hoplug functions vector structure (rev 1)
57966f9d5cbSmlf  */
58066f9d5cbSmlf #define	SATA_TRAN_HOTPLUG_OPS_REV_1	1
58166f9d5cbSmlf 
58266f9d5cbSmlf struct sata_tran_hotplug_ops {
58366f9d5cbSmlf 	int	sata_tran_hotplug_ops_rev; /* version */
58466f9d5cbSmlf 	int	(*sata_tran_port_activate)(dev_info_t  *, sata_device_t *);
58566f9d5cbSmlf 	int	(*sata_tran_port_deactivate)(dev_info_t  *, sata_device_t *);
58666f9d5cbSmlf };
58766f9d5cbSmlf 
58866f9d5cbSmlf typedef struct sata_tran_hotplug_ops sata_tran_hotplug_ops_t;
58966f9d5cbSmlf 
59066f9d5cbSmlf 
59166f9d5cbSmlf /*
59266f9d5cbSmlf  * Power management functions vector structure (rev 1)
59366f9d5cbSmlf  * The embedded function returns information about the controller's
59466f9d5cbSmlf  * power level.
59566f9d5cbSmlf  * Additional functions may be added in the future without changes to
59666f9d5cbSmlf  * sata_tran structure.
59766f9d5cbSmlf  */
59866f9d5cbSmlf #define	SATA_TRAN_PWRMGT_OPS_REV_1	1
59966f9d5cbSmlf 
60066f9d5cbSmlf struct sata_tran_pwrmgt_ops {
60166f9d5cbSmlf 	int	sata_tran_pwrmgt_ops_rev; /* version */
60266f9d5cbSmlf 	int	(*sata_tran_get_pwr_level)(dev_info_t  *, sata_device_t *);
60366f9d5cbSmlf };
60466f9d5cbSmlf 
60566f9d5cbSmlf typedef struct sata_tran_pwrmgt_ops sata_tran_pwrmgt_ops_t;
60666f9d5cbSmlf 
60766f9d5cbSmlf 
60866f9d5cbSmlf /*
60966f9d5cbSmlf  * SATA port PHY Power Level
61066f9d5cbSmlf  * These states correspond to the interface power management state as defined
61166f9d5cbSmlf  * in Serial ATA spec.
61266f9d5cbSmlf  */
61366f9d5cbSmlf #define	SATA_TRAN_PORTPWR_LEVEL1	1 /* Interface in active PM state */
61466f9d5cbSmlf #define	SATA_TRAN_PORTPWR_LEVEL2	2 /* Interface in PARTIAL PM state */
61566f9d5cbSmlf #define	SATA_TRAN_PORTPWR_LEVEL3	3 /* Interface in SLUMBER PM state */
61666f9d5cbSmlf 
61766f9d5cbSmlf /*
61866f9d5cbSmlf  * SATA HBA Tran structure (rev 1)
61966f9d5cbSmlf  * Registered with SATA Framework
62066f9d5cbSmlf  *
62166f9d5cbSmlf  * dma_attr is a pointer to data (buffer) dma attibutes of the controller
62266f9d5cbSmlf  * DMA engine.
62366f9d5cbSmlf  *
62466f9d5cbSmlf  * The qdepth field specifies number of commands that may be accepted by
62566f9d5cbSmlf  * the controller. Value range 1-32. A value greater than 1 indicates that
62666f9d5cbSmlf  * the controller supports queuing. Support for Native Command Queuing
62766f9d5cbSmlf  * indicated by SATA_CTLF_NCQ flag also requires qdepth set to a value
62866f9d5cbSmlf  * greater then 1.
62966f9d5cbSmlf  *
63066f9d5cbSmlf  */
63166f9d5cbSmlf #define	SATA_TRAN_HBA_REV_1	1
6322038334aSUnknown #define	SATA_TRAN_HBA_REV_2	2
6338aa6aadbSXiao-Yu Zhang #define	SATA_TRAN_HBA_REV_3	3
6348aa6aadbSXiao-Yu Zhang #define	SATA_TRAN_HBA_REV	SATA_TRAN_HBA_REV_3
63566f9d5cbSmlf 
63666f9d5cbSmlf struct sata_hba_tran {
63766f9d5cbSmlf 	int		sata_tran_hba_rev;	/* version */
63866f9d5cbSmlf 	dev_info_t	*sata_tran_hba_dip;	/* Controler dev info */
63966f9d5cbSmlf 	ddi_dma_attr_t	*sata_tran_hba_dma_attr; /* DMA attributes */
64066f9d5cbSmlf 	int		sata_tran_hba_num_cports; /* Num of HBA device ports */
64166f9d5cbSmlf 	uint16_t	sata_tran_hba_features_support; /* HBA features */
64266f9d5cbSmlf 	uint16_t	sata_tran_hba_qdepth;	/* HBA-supported queue depth */
64366f9d5cbSmlf 
64466f9d5cbSmlf 	int		(*sata_tran_probe_port)(dev_info_t *, sata_device_t *);
64566f9d5cbSmlf 	int		(*sata_tran_start)(dev_info_t *, sata_pkt_t *);
64666f9d5cbSmlf 	int		(*sata_tran_abort)(dev_info_t *, sata_pkt_t *, int);
64766f9d5cbSmlf 	int		(*sata_tran_reset_dport)(dev_info_t *,
64866f9d5cbSmlf 					sata_device_t *);
64966f9d5cbSmlf 	int		(*sata_tran_selftest)(dev_info_t *, sata_device_t *);
65066f9d5cbSmlf 
65166f9d5cbSmlf 						/* Hotplug vector */
65266f9d5cbSmlf 	struct sata_tran_hotplug_ops *sata_tran_hotplug_ops;
65366f9d5cbSmlf 
65466f9d5cbSmlf 						/* Power mgt vector */
65566f9d5cbSmlf 	struct sata_tran_pwrmgt_ops *sata_tran_pwrmgt_ops;
65666f9d5cbSmlf 
65766f9d5cbSmlf 	int		(*sata_tran_ioctl)(dev_info_t *, int, intptr_t);
65866f9d5cbSmlf };
65966f9d5cbSmlf 
66066f9d5cbSmlf typedef struct sata_hba_tran sata_hba_tran_t;
66166f9d5cbSmlf 
66266f9d5cbSmlf 
66366f9d5cbSmlf /*
66466f9d5cbSmlf  * Controller's features support flags (sata_tran_hba_features_support).
66566f9d5cbSmlf  * Note: SATA_CTLF_NCQ indicates that SATA controller supports NCQ in addition
66666f9d5cbSmlf  * to legacy queuing commands, indicated by SATA_CTLF_QCMD flag.
66766f9d5cbSmlf  */
66866f9d5cbSmlf 
66966f9d5cbSmlf #define	SATA_CTLF_ATAPI			0x001 /* ATAPI support */
67066f9d5cbSmlf #define	SATA_CTLF_PORT_MULTIPLIER 	0x010 /* Port Multiplier suport */
67166f9d5cbSmlf #define	SATA_CTLF_HOTPLUG		0x020 /* Hotplug support */
67266f9d5cbSmlf #define	SATA_CTLF_ASN			0x040 /* Asynchronous Event Support */
67366f9d5cbSmlf #define	SATA_CTLF_QCMD			0x080 /* Queued commands support */
67466f9d5cbSmlf #define	SATA_CTLF_NCQ			0x100 /* NCQ support */
6758aa6aadbSXiao-Yu Zhang #define	SATA_CTLF_PMULT_FBS		0x200 /* FIS-based switching support */
67666f9d5cbSmlf 
67766f9d5cbSmlf /*
67866f9d5cbSmlf  * sata_tran_start() return values.
67966f9d5cbSmlf  * When pkt is not accepted, the satapkt_reason has to be updated
68066f9d5cbSmlf  * before function returns - it should reflect the same reason for not being
68166f9d5cbSmlf  * executed as the return status of above functions.
68266f9d5cbSmlf  * If pkt was accepted and executed synchronously,
68366f9d5cbSmlf  * satapk_reason should indicate a completion status.
68466f9d5cbSmlf  */
68566f9d5cbSmlf #define	SATA_TRAN_ACCEPTED		0 /* accepted */
68666f9d5cbSmlf #define	SATA_TRAN_QUEUE_FULL		1 /* not accepted, queue full */
68766f9d5cbSmlf #define	SATA_TRAN_PORT_ERROR		2 /* not accepted, port error */
68866f9d5cbSmlf #define	SATA_TRAN_CMD_UNSUPPORTED	3 /* not accepted, cmd not supported */
68966f9d5cbSmlf #define	SATA_TRAN_BUSY			4 /* not accepted, busy */
69066f9d5cbSmlf 
69166f9d5cbSmlf 
69266f9d5cbSmlf /*
69366f9d5cbSmlf  * sata_tran_abort() abort type flag
69466f9d5cbSmlf  */
69566f9d5cbSmlf #define	SATA_ABORT_PACKET		0
69666f9d5cbSmlf #define	SATA_ABORT_ALL_PACKETS		1
69766f9d5cbSmlf 
69866f9d5cbSmlf 
69966f9d5cbSmlf /*
70066f9d5cbSmlf  * Events handled by SATA HBA Framework
70166f9d5cbSmlf  * More then one event may be reported at the same time
70266f9d5cbSmlf  *
70366f9d5cbSmlf  * SATA_EVNT__DEVICE_ATTACHED
70466f9d5cbSmlf  * HBA detected the presence of a device ( electrical connection with
70566f9d5cbSmlf  * a device was detected ).
70666f9d5cbSmlf  *
70766f9d5cbSmlf  * SATA_EVNT_DEVICE_DETACHED
70866f9d5cbSmlf  * HBA detected the detachment of a device (electrical connection with
70966f9d5cbSmlf  * a device was broken)
71066f9d5cbSmlf  *
71166f9d5cbSmlf  * SATA_EVNT_LINK_LOST
71266f9d5cbSmlf  * HBA lost link with an attached device
71366f9d5cbSmlf  *
71466f9d5cbSmlf  * SATA_EVNT_LINK_ESTABLISHED
71566f9d5cbSmlf  * HBA established a link with an attached device
71666f9d5cbSmlf  *
71766f9d5cbSmlf  * SATA_EVNT_PORT_FAILED
71866f9d5cbSmlf  * HBA has determined that the port failed and is unuseable
71966f9d5cbSmlf  *
72066f9d5cbSmlf  * SATA_EVENT_DEVICE_RESET
72166f9d5cbSmlf  * SATA device was reset, causing loss of the device setting
72266f9d5cbSmlf  *
72366f9d5cbSmlf  * SATA_EVNT_PWR_LEVEL_CHANGED
72466f9d5cbSmlf  * A port or entire SATA controller power level has changed
72566f9d5cbSmlf  *
7268aa6aadbSXiao-Yu Zhang  * SATA_EVNT_PMULT_LINK_CHANGED
7278aa6aadbSXiao-Yu Zhang  * Port multiplier detect change on a link of its device port
7288aa6aadbSXiao-Yu Zhang  *
72966f9d5cbSmlf  */
73066f9d5cbSmlf #define	SATA_EVNT_DEVICE_ATTACHED	0x01
73166f9d5cbSmlf #define	SATA_EVNT_DEVICE_DETACHED	0x02
73266f9d5cbSmlf #define	SATA_EVNT_LINK_LOST		0x04
73366f9d5cbSmlf #define	SATA_EVNT_LINK_ESTABLISHED	0x08
73466f9d5cbSmlf #define	SATA_EVNT_PORT_FAILED		0x10
73566f9d5cbSmlf #define	SATA_EVNT_DEVICE_RESET		0x20
73666f9d5cbSmlf #define	SATA_EVNT_PWR_LEVEL_CHANGED	0x40
7378aa6aadbSXiao-Yu Zhang #define	SATA_EVNT_PMULT_LINK_CHANGED	0x80
73866f9d5cbSmlf 
73966f9d5cbSmlf /*
74066f9d5cbSmlf  * SATA Framework interface entry points
74166f9d5cbSmlf  */
74266f9d5cbSmlf int 	sata_hba_init(struct modlinkage *);
74366f9d5cbSmlf int 	sata_hba_attach(dev_info_t *, sata_hba_tran_t *, ddi_attach_cmd_t);
74466f9d5cbSmlf int 	sata_hba_detach(dev_info_t *, ddi_detach_cmd_t);
74566f9d5cbSmlf void 	sata_hba_fini(struct modlinkage *);
74666f9d5cbSmlf void 	sata_hba_event_notify(dev_info_t *, sata_device_t *, int);
7472038334aSUnknown sata_pkt_t *sata_get_error_retrieval_pkt(dev_info_t *, sata_device_t *, int);
7482038334aSUnknown void	sata_free_error_retrieval_pkt(sata_pkt_t *);
7498aa6aadbSXiao-Yu Zhang sata_pkt_t *sata_get_rdwr_pmult_pkt(dev_info_t *, sata_device_t *, uint8_t,
7508aa6aadbSXiao-Yu Zhang     uint32_t, uint32_t);
7518aa6aadbSXiao-Yu Zhang void	sata_free_rdwr_pmult_pkt(sata_pkt_t *);
752918304a3SXiao-Yu Zhang void	sata_register_pmult(dev_info_t *, sata_device_t *, sata_pmult_gscr_t *);
753b5fc475bSap25164 void	sata_free_dma_resources(sata_pkt_t *);
754*0c6eaab4SHans Rosenfeld void	sata_split_model(char *, char **, char **);
75566f9d5cbSmlf 
756f5f2d263SFred Herard /*
757f5f2d263SFred Herard  * SATA trace ring buffer constants
758f5f2d263SFred Herard  */
759f5f2d263SFred Herard #define	DMSG_RING_SIZE		0x100000	/* 1MB */
760f5f2d263SFred Herard #define	DMSG_BUF_SIZE		256
761f5f2d263SFred Herard 
762f5f2d263SFred Herard /*
763f5f2d263SFred Herard  * SATA trace ring buffer content
764f5f2d263SFred Herard  */
765f5f2d263SFred Herard typedef struct sata_trace_dmsg {
766f5f2d263SFred Herard 	dev_info_t		*dip;
767f5f2d263SFred Herard 	timespec_t		timestamp;
768f5f2d263SFred Herard 	char			buf[DMSG_BUF_SIZE];
769f5f2d263SFred Herard 	struct sata_trace_dmsg	*next;
770f5f2d263SFred Herard } sata_trace_dmsg_t;
771f5f2d263SFred Herard 
772f5f2d263SFred Herard /*
773f5f2d263SFred Herard  * SATA trace ring buffer header
774f5f2d263SFred Herard  */
775f5f2d263SFred Herard typedef struct sata_trace_rbuf {
776f5f2d263SFred Herard 	kmutex_t		lock;		/* lock to avoid clutter */
777f5f2d263SFred Herard 	int			looped;		/* completed ring */
778f5f2d263SFred Herard 	int			allocfailed;	/* dmsg mem alloc failed */
779f5f2d263SFred Herard 	size_t			size;		/* current size */
780f5f2d263SFred Herard 	size_t			maxsize;	/* max size */
781f5f2d263SFred Herard 	sata_trace_dmsg_t	*dmsgh;		/* messages head */
782f5f2d263SFred Herard 	sata_trace_dmsg_t	*dmsgp;		/* ptr to last message */
783f5f2d263SFred Herard } sata_trace_rbuf_t;
784f5f2d263SFred Herard 
785f5f2d263SFred Herard /*
786f5f2d263SFred Herard  * SATA trace ring buffer interfaces
787f5f2d263SFred Herard  */
788f5f2d263SFred Herard void sata_trace_debug(dev_info_t *, const char *fmt, ...);
789f5f2d263SFred Herard void sata_vtrace_debug(dev_info_t *, const char *fmt, va_list);
79066f9d5cbSmlf 
79166f9d5cbSmlf #ifdef	__cplusplus
79266f9d5cbSmlf }
79366f9d5cbSmlf #endif
79466f9d5cbSmlf 
79566f9d5cbSmlf #endif /* _SATA_HBA_H */
796