xref: /onnv-gate/usr/src/uts/common/io/mega_sas/megaraid_sas.h (revision 8312:4a514ecf60e2)
16447Ssusans /*
26447Ssusans  * megaraid_sas.h: header for mega_sas
36447Ssusans  *
46447Ssusans  * Solaris MegaRAID driver for SAS controllers
56447Ssusans  * Copyright (c) 2004-2008, LSI Logic Corporation.
66447Ssusans  * All rights reserved.
76447Ssusans  *
86447Ssusans  * Redistribution and use in source and binary forms, with or without
96447Ssusans  * modification, are permitted provided that the following conditions are met:
106447Ssusans  *
116447Ssusans  * 1. Redistributions of source code must retain the above copyright notice,
126447Ssusans  *    this list of conditions and the following disclaimer.
136447Ssusans  *
146447Ssusans  * 2. Redistributions in binary form must reproduce the above copyright notice,
156447Ssusans  *    this list of conditions and the following disclaimer in the documentation
166447Ssusans  *    and/or other materials provided with the distribution.
176447Ssusans  *
186447Ssusans  * 3. Neither the name of the author nor the names of its contributors may be
196447Ssusans  *    used to endorse or promote products derived from this software without
206447Ssusans  *    specific prior written permission.
216447Ssusans  *
226447Ssusans  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
236447Ssusans  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
246447Ssusans  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
256447Ssusans  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
266447Ssusans  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
276447Ssusans  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
286447Ssusans  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
296447Ssusans  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
306447Ssusans  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
316447Ssusans  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
326447Ssusans  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
336447Ssusans  * DAMAGE.
346447Ssusans  */
356447Ssusans 
366447Ssusans /*
376447Ssusans  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
386447Ssusans  * Use is subject to license terms.
396447Ssusans  */
406447Ssusans 
416447Ssusans #ifndef	_MEGARAID_SAS_H_
426447Ssusans #define	_MEGARAID_SAS_H_
436447Ssusans 
446447Ssusans #ifdef	__cplusplus
456447Ssusans extern "C" {
466447Ssusans #endif
476447Ssusans 
486447Ssusans #include <sys/scsi/scsi.h>
496447Ssusans #include "list.h"
506447Ssusans 
516447Ssusans /*
526447Ssusans  * MegaRAID SAS Driver meta data
536447Ssusans  */
54*8312SSusan.Scheufele@Sun.COM #define	MEGASAS_VERSION				"LSIv1.28"
55*8312SSusan.Scheufele@Sun.COM #define	MEGASAS_RELDATE				"Dec 4, 2008"
566447Ssusans 
576447Ssusans #define	MEGASAS_TRUE				1
586447Ssusans #define	MEGASAS_FALSE				0
596447Ssusans 
606447Ssusans /*
616447Ssusans  * MegaRAID device id conversion definitions.
626447Ssusans  */
636447Ssusans #define	INST2LSIRDCTL(x)		((x) << INST_MINOR_SHIFT)
646447Ssusans 
656447Ssusans /*
666447Ssusans  * MegaRAID SAS supported controllers
676447Ssusans  */
686447Ssusans #define	PCI_DEVICE_ID_LSI_1064			0x0411
696447Ssusans #define	PCI_DEVICE_ID_LSI_1078			0x0060
706599Ssusans #define	PCI_DEVICE_ID_LSI_1078DE		0x007C
716447Ssusans 
726447Ssusans #define	PCI_DEVICE_ID_DELL_PERC5		0x0015
736447Ssusans #define	PCI_DEVICE_ID_DELL_SAS5			0x0054
746447Ssusans 
756447Ssusans #define	PCI_SUBSYSTEM_DELL_PERC5E		0x1F01
766447Ssusans #define	PCI_SUBSYSTEM_DELL_PERC5I		0x1F02
776447Ssusans #define	PCI_SUBSYSTEM_DELL_PERC5I_INTEGRATED	0x1F03
786447Ssusans #define	PCI_SUBSYSTEM_DELL_SAS5I		0x1F05
796447Ssusans #define	PCI_SUBSYSTEM_DELL_SAS5I_INTEGRATED	0x1F06
806447Ssusans 
816447Ssusans #define	PCI_SUB_DEVICEID_FSC			0x1081
826447Ssusans #define	PCI_SUB_VENDORID_FSC			0x1734
836447Ssusans 
846447Ssusans #define	REGISTER_SET_IO				(1)
856447Ssusans 
866447Ssusans #define	MEGASAS_MAX_SGE_CNT			0x50
876447Ssusans 
886447Ssusans #define	MEGASAS_IOCTL_DRIVER			0x12341234
896447Ssusans #define	MEGASAS_IOCTL_FIRMWARE			0x12345678
906447Ssusans #define	MEGASAS_IOCTL_AEN			0x87654321
916447Ssusans 
926447Ssusans #define	MEGASAS_1_SECOND			1000000
936447Ssusans /*
946447Ssusans  * =====================================
956447Ssusans  * MegaRAID SAS MFI firmware definitions
966447Ssusans  * =====================================
976447Ssusans  */
986447Ssusans /*
996447Ssusans  * MFI stands for  MegaRAID SAS FW Interface. This is just a moniker for
1006447Ssusans  * protocol between the software and firmware. Commands are issued using
1016447Ssusans  * "message frames"
1026447Ssusans  */
1036447Ssusans 
1046447Ssusans /*
1056447Ssusans  * FW posts its state in upper 4 bits of outbound_msg_0 register
1066447Ssusans  */
1076447Ssusans #define	MFI_STATE_MASK				0xF0000000
1086447Ssusans #define	MFI_STATE_UNDEFINED			0x00000000
1096447Ssusans #define	MFI_STATE_BB_INIT			0x10000000
1106447Ssusans #define	MFI_STATE_FW_INIT			0x40000000
1116447Ssusans #define	MFI_STATE_WAIT_HANDSHAKE		0x60000000
1126447Ssusans #define	MFI_STATE_FW_INIT_2			0x70000000
1136447Ssusans #define	MFI_STATE_DEVICE_SCAN			0x80000000
1146447Ssusans #define	MFI_STATE_BOOT_MESSAGE_PENDING		0x90000000
1156447Ssusans #define	MFI_STATE_FLUSH_CACHE			0xA0000000
1166447Ssusans #define	MFI_STATE_READY				0xB0000000
1176447Ssusans #define	MFI_STATE_OPERATIONAL			0xC0000000
1186447Ssusans #define	MFI_STATE_FAULT				0xF0000000
1196447Ssusans 
1206447Ssusans #define	MEGAMFI_FRAME_SIZE			64
1216447Ssusans 
1226447Ssusans /*
1236447Ssusans  * During FW init, clear pending cmds & reset state using inbound_msg_0
1246447Ssusans  *
1256447Ssusans  * ABORT	: Abort all pending cmds
1266447Ssusans  * READY	: Move from OPERATIONAL to READY state; discard queue info
1276447Ssusans  * MFIMODE	: Discard (possible) low MFA posted in 64-bit mode (??)
1286447Ssusans  * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
1296447Ssusans  */
1306447Ssusans #define	MFI_INIT_ABORT				0x00000001
1316447Ssusans #define	MFI_INIT_READY				0x00000002
1326447Ssusans #define	MFI_INIT_MFIMODE			0x00000004
1336447Ssusans #define	MFI_INIT_CLEAR_HANDSHAKE		0x00000008
1346447Ssusans #define	MFI_INIT_HOTPLUG			0x00000010
1356447Ssusans #define	MFI_STOP_ADP				0x00000020
1366447Ssusans #define	MFI_RESET_FLAGS		MFI_INIT_READY|MFI_INIT_MFIMODE|MFI_INIT_ABORT
1376447Ssusans 
1386447Ssusans /*
1396447Ssusans  * MFI frame flags
1406447Ssusans  */
1416447Ssusans #define	MFI_FRAME_POST_IN_REPLY_QUEUE		0x0000
1426447Ssusans #define	MFI_FRAME_DONT_POST_IN_REPLY_QUEUE	0x0001
1436447Ssusans #define	MFI_FRAME_SGL32				0x0000
1446447Ssusans #define	MFI_FRAME_SGL64				0x0002
1456447Ssusans #define	MFI_FRAME_SENSE32			0x0000
1466447Ssusans #define	MFI_FRAME_SENSE64			0x0004
1476447Ssusans #define	MFI_FRAME_DIR_NONE			0x0000
1486447Ssusans #define	MFI_FRAME_DIR_WRITE			0x0008
1496447Ssusans #define	MFI_FRAME_DIR_READ			0x0010
1506447Ssusans #define	MFI_FRAME_DIR_BOTH			0x0018
1516447Ssusans 
1526447Ssusans /*
1536447Ssusans  * Definition for cmd_status
1546447Ssusans  */
1556447Ssusans #define	MFI_CMD_STATUS_POLL_MODE		0xFF
1567562SSusan.Scheufele@Sun.COM #define	MFI_CMD_STATUS_SYNC_MODE		0xFF
1576447Ssusans 
1586447Ssusans /*
1596447Ssusans  * MFI command opcodes
1606447Ssusans  */
1616447Ssusans #define	MFI_CMD_OP_INIT				0x00
1626447Ssusans #define	MFI_CMD_OP_LD_READ			0x01
1636447Ssusans #define	MFI_CMD_OP_LD_WRITE			0x02
1646447Ssusans #define	MFI_CMD_OP_LD_SCSI			0x03
1656447Ssusans #define	MFI_CMD_OP_PD_SCSI			0x04
1666447Ssusans #define	MFI_CMD_OP_DCMD				0x05
1676447Ssusans #define	MFI_CMD_OP_ABORT			0x06
1686447Ssusans #define	MFI_CMD_OP_SMP				0x07
1696447Ssusans #define	MFI_CMD_OP_STP				0x08
1706447Ssusans 
1716447Ssusans #define	MR_DCMD_CTRL_GET_INFO			0x01010000
1726447Ssusans 
1736447Ssusans #define	MR_DCMD_CTRL_CACHE_FLUSH		0x01101000
1746447Ssusans #define	MR_FLUSH_CTRL_CACHE			0x01
1756447Ssusans #define	MR_FLUSH_DISK_CACHE			0x02
1766447Ssusans 
1776447Ssusans #define	MR_DCMD_CTRL_SHUTDOWN			0x01050000
1786447Ssusans #define	MR_ENABLE_DRIVE_SPINDOWN		0x01
1796447Ssusans 
1806447Ssusans #define	MR_DCMD_CTRL_EVENT_GET_INFO		0x01040100
1816447Ssusans #define	MR_DCMD_CTRL_EVENT_GET			0x01040300
1826447Ssusans #define	MR_DCMD_CTRL_EVENT_WAIT			0x01040500
1836447Ssusans #define	MR_DCMD_LD_GET_PROPERTIES		0x03030000
1846447Ssusans 
1856447Ssusans /*
1866447Ssusans  * Solaris Specific MAX values
1876447Ssusans  */
1886447Ssusans #define	MAX_SGL					24
1896447Ssusans /*
1906447Ssusans  * MFI command completion codes
1916447Ssusans  */
1926447Ssusans enum MFI_STAT {
1936447Ssusans 	MFI_STAT_OK				= 0x00,
1946447Ssusans 	MFI_STAT_INVALID_CMD			= 0x01,
1956447Ssusans 	MFI_STAT_INVALID_DCMD			= 0x02,
1966447Ssusans 	MFI_STAT_INVALID_PARAMETER		= 0x03,
1976447Ssusans 	MFI_STAT_INVALID_SEQUENCE_NUMBER	= 0x04,
1986447Ssusans 	MFI_STAT_ABORT_NOT_POSSIBLE		= 0x05,
1996447Ssusans 	MFI_STAT_APP_HOST_CODE_NOT_FOUND	= 0x06,
2006447Ssusans 	MFI_STAT_APP_IN_USE			= 0x07,
2016447Ssusans 	MFI_STAT_APP_NOT_INITIALIZED		= 0x08,
2026447Ssusans 	MFI_STAT_ARRAY_INDEX_INVALID		= 0x09,
2036447Ssusans 	MFI_STAT_ARRAY_ROW_NOT_EMPTY		= 0x0a,
2046447Ssusans 	MFI_STAT_CONFIG_RESOURCE_CONFLICT	= 0x0b,
2056447Ssusans 	MFI_STAT_DEVICE_NOT_FOUND		= 0x0c,
2066447Ssusans 	MFI_STAT_DRIVE_TOO_SMALL		= 0x0d,
2076447Ssusans 	MFI_STAT_FLASH_ALLOC_FAIL		= 0x0e,
2086447Ssusans 	MFI_STAT_FLASH_BUSY			= 0x0f,
2096447Ssusans 	MFI_STAT_FLASH_ERROR			= 0x10,
2106447Ssusans 	MFI_STAT_FLASH_IMAGE_BAD		= 0x11,
2116447Ssusans 	MFI_STAT_FLASH_IMAGE_INCOMPLETE		= 0x12,
2126447Ssusans 	MFI_STAT_FLASH_NOT_OPEN			= 0x13,
2136447Ssusans 	MFI_STAT_FLASH_NOT_STARTED		= 0x14,
2146447Ssusans 	MFI_STAT_FLUSH_FAILED			= 0x15,
2156447Ssusans 	MFI_STAT_HOST_CODE_NOT_FOUNT		= 0x16,
2166447Ssusans 	MFI_STAT_LD_CC_IN_PROGRESS		= 0x17,
2176447Ssusans 	MFI_STAT_LD_INIT_IN_PROGRESS		= 0x18,
2186447Ssusans 	MFI_STAT_LD_LBA_OUT_OF_RANGE		= 0x19,
2196447Ssusans 	MFI_STAT_LD_MAX_CONFIGURED		= 0x1a,
2206447Ssusans 	MFI_STAT_LD_NOT_OPTIMAL			= 0x1b,
2216447Ssusans 	MFI_STAT_LD_RBLD_IN_PROGRESS		= 0x1c,
2226447Ssusans 	MFI_STAT_LD_RECON_IN_PROGRESS		= 0x1d,
2236447Ssusans 	MFI_STAT_LD_WRONG_RAID_LEVEL		= 0x1e,
2246447Ssusans 	MFI_STAT_MAX_SPARES_EXCEEDED		= 0x1f,
2256447Ssusans 	MFI_STAT_MEMORY_NOT_AVAILABLE		= 0x20,
2266447Ssusans 	MFI_STAT_MFC_HW_ERROR			= 0x21,
2276447Ssusans 	MFI_STAT_NO_HW_PRESENT			= 0x22,
2286447Ssusans 	MFI_STAT_NOT_FOUND			= 0x23,
2296447Ssusans 	MFI_STAT_NOT_IN_ENCL			= 0x24,
2306447Ssusans 	MFI_STAT_PD_CLEAR_IN_PROGRESS		= 0x25,
2316447Ssusans 	MFI_STAT_PD_TYPE_WRONG			= 0x26,
2326447Ssusans 	MFI_STAT_PR_DISABLED			= 0x27,
2336447Ssusans 	MFI_STAT_ROW_INDEX_INVALID		= 0x28,
2346447Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_ACTION	= 0x29,
2356447Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_DATA	= 0x2a,
2366447Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_PAGE	= 0x2b,
2376447Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_TYPE	= 0x2c,
2386447Ssusans 	MFI_STAT_SCSI_DONE_WITH_ERROR		= 0x2d,
2396447Ssusans 	MFI_STAT_SCSI_IO_FAILED			= 0x2e,
2406447Ssusans 	MFI_STAT_SCSI_RESERVATION_CONFLICT	= 0x2f,
2416447Ssusans 	MFI_STAT_SHUTDOWN_FAILED		= 0x30,
2426447Ssusans 	MFI_STAT_TIME_NOT_SET			= 0x31,
2436447Ssusans 	MFI_STAT_WRONG_STATE			= 0x32,
2447193Syw209021 	MFI_STAT_LD_OFFLINE			= 0x33,
2456447Ssusans 	MFI_STAT_INVALID_STATUS			= 0xFF
2466447Ssusans };
2476447Ssusans 
2486447Ssusans enum MR_EVT_CLASS {
2496447Ssusans 	MR_EVT_CLASS_DEBUG		= -2,
2506447Ssusans 	MR_EVT_CLASS_PROGRESS		= -1,
2516447Ssusans 	MR_EVT_CLASS_INFO		=  0,
2526447Ssusans 	MR_EVT_CLASS_WARNING		=  1,
2536447Ssusans 	MR_EVT_CLASS_CRITICAL		=  2,
2546447Ssusans 	MR_EVT_CLASS_FATAL		=  3,
2556447Ssusans 	MR_EVT_CLASS_DEAD		=  4
2566447Ssusans };
2576447Ssusans 
2586447Ssusans enum MR_EVT_LOCALE {
2596447Ssusans 	MR_EVT_LOCALE_LD		= 0x0001,
2606447Ssusans 	MR_EVT_LOCALE_PD		= 0x0002,
2616447Ssusans 	MR_EVT_LOCALE_ENCL		= 0x0004,
2626447Ssusans 	MR_EVT_LOCALE_BBU		= 0x0008,
2636447Ssusans 	MR_EVT_LOCALE_SAS		= 0x0010,
2646447Ssusans 	MR_EVT_LOCALE_CTRL		= 0x0020,
2656447Ssusans 	MR_EVT_LOCALE_CONFIG		= 0x0040,
2666447Ssusans 	MR_EVT_LOCALE_CLUSTER		= 0x0080,
2676447Ssusans 	MR_EVT_LOCALE_ALL		= 0xffff
2686447Ssusans };
2696447Ssusans 
2706447Ssusans enum MR_EVT_ARGS {
2716447Ssusans 	MR_EVT_ARGS_NONE,
2726447Ssusans 	MR_EVT_ARGS_CDB_SENSE,
2736447Ssusans 	MR_EVT_ARGS_LD,
2746447Ssusans 	MR_EVT_ARGS_LD_COUNT,
2756447Ssusans 	MR_EVT_ARGS_LD_LBA,
2766447Ssusans 	MR_EVT_ARGS_LD_OWNER,
2776447Ssusans 	MR_EVT_ARGS_LD_LBA_PD_LBA,
2786447Ssusans 	MR_EVT_ARGS_LD_PROG,
2796447Ssusans 	MR_EVT_ARGS_LD_STATE,
2806447Ssusans 	MR_EVT_ARGS_LD_STRIP,
2816447Ssusans 	MR_EVT_ARGS_PD,
2826447Ssusans 	MR_EVT_ARGS_PD_ERR,
2836447Ssusans 	MR_EVT_ARGS_PD_LBA,
2846447Ssusans 	MR_EVT_ARGS_PD_LBA_LD,
2856447Ssusans 	MR_EVT_ARGS_PD_PROG,
2866447Ssusans 	MR_EVT_ARGS_PD_STATE,
2876447Ssusans 	MR_EVT_ARGS_PCI,
2886447Ssusans 	MR_EVT_ARGS_RATE,
2896447Ssusans 	MR_EVT_ARGS_STR,
2906447Ssusans 	MR_EVT_ARGS_TIME,
2916447Ssusans 	MR_EVT_ARGS_ECC
2926447Ssusans };
2936447Ssusans 
2947562SSusan.Scheufele@Sun.COM #pragma pack(1)
2957562SSusan.Scheufele@Sun.COM 
2966447Ssusans /*
2976447Ssusans  * SAS controller properties
2986447Ssusans  */
2996447Ssusans struct megasas_ctrl_prop {
3006447Ssusans 	uint16_t	seq_num;
3016447Ssusans 	uint16_t	pred_fail_poll_interval;
3026447Ssusans 	uint16_t	intr_throttle_count;
3036447Ssusans 	uint16_t	intr_throttle_timeouts;
3046447Ssusans 
3056447Ssusans 	uint8_t		rebuild_rate;
3066447Ssusans 	uint8_t		patrol_read_rate;
3076447Ssusans 	uint8_t		bgi_rate;
3086447Ssusans 	uint8_t		cc_rate;
3096447Ssusans 	uint8_t		recon_rate;
3106447Ssusans 
3116447Ssusans 	uint8_t		cache_flush_interval;
3126447Ssusans 
3136447Ssusans 	uint8_t		spinup_drv_count;
3146447Ssusans 	uint8_t		spinup_delay;
3156447Ssusans 
3166447Ssusans 	uint8_t		cluster_enable;
3176447Ssusans 	uint8_t		coercion_mode;
3186447Ssusans 	uint8_t		disk_write_cache_disable;
3196447Ssusans 	uint8_t		alarm_enable;
3206447Ssusans 
3216447Ssusans 	uint8_t		reserved[44];
3226447Ssusans };
3236447Ssusans 
3246447Ssusans /*
3256447Ssusans  * SAS controller information
3266447Ssusans  */
3276447Ssusans struct megasas_ctrl_info {
3286447Ssusans 	/* PCI device information */
3296447Ssusans 	struct {
3306447Ssusans 		uint16_t	vendor_id;
3316447Ssusans 		uint16_t	device_id;
3326447Ssusans 		uint16_t	sub_vendor_id;
3336447Ssusans 		uint16_t	sub_device_id;
3346447Ssusans 		uint8_t	reserved[24];
3356447Ssusans 	} pci;
3366447Ssusans 
3376447Ssusans 	/* Host interface information */
3386447Ssusans 	struct {
3396447Ssusans 		uint8_t	PCIX		: 1;
3406447Ssusans 		uint8_t	PCIE		: 1;
3416447Ssusans 		uint8_t	iSCSI		: 1;
3426447Ssusans 		uint8_t	SAS_3G		: 1;
3436447Ssusans 		uint8_t	reserved_0	: 4;
3446447Ssusans 		uint8_t	reserved_1[6];
3456447Ssusans 		uint8_t	port_count;
3466447Ssusans 		uint64_t	port_addr[8];
3476447Ssusans 	} host_interface;
3486447Ssusans 
3496447Ssusans 	/* Device (backend) interface information */
3506447Ssusans 	struct {
3516447Ssusans 		uint8_t	SPI		: 1;
3526447Ssusans 		uint8_t	SAS_3G		: 1;
3536447Ssusans 		uint8_t	SATA_1_5G	: 1;
3546447Ssusans 		uint8_t	SATA_3G		: 1;
3556447Ssusans 		uint8_t	reserved_0	: 4;
3566447Ssusans 		uint8_t	reserved_1[6];
3576447Ssusans 		uint8_t	port_count;
3586447Ssusans 		uint64_t	port_addr[8];
3596447Ssusans 	} device_interface;
3606447Ssusans 
3616447Ssusans 	/* List of components residing in flash. All str are null terminated */
3626447Ssusans 	uint32_t	image_check_word;
3636447Ssusans 	uint32_t	image_component_count;
3646447Ssusans 
3656447Ssusans 	struct {
3666447Ssusans 		char	name[8];
3676447Ssusans 		char	version[32];
3686447Ssusans 		char	build_date[16];
3696447Ssusans 		char	built_time[16];
3706447Ssusans 	} image_component[8];
3716447Ssusans 
3726447Ssusans 	/*
3736447Ssusans 	 * List of flash components that have been flashed on the card, but
3746447Ssusans 	 * are not in use, pending reset of the adapter. This list will be
3756447Ssusans 	 * empty if a flash operation has not occurred. All stings are null
3766447Ssusans 	 * terminated
3776447Ssusans 	 */
3786447Ssusans 	uint32_t	pending_image_component_count;
3796447Ssusans 
3806447Ssusans 	struct {
3816447Ssusans 		char	name[8];
3826447Ssusans 		char	version[32];
3836447Ssusans 		char	build_date[16];
3846447Ssusans 		char	build_time[16];
3856447Ssusans 	} pending_image_component[8];
3866447Ssusans 
3876447Ssusans 	uint8_t		max_arms;
3886447Ssusans 	uint8_t		max_spans;
3896447Ssusans 	uint8_t		max_arrays;
3906447Ssusans 	uint8_t		max_lds;
3916447Ssusans 
3926447Ssusans 	char		product_name[80];
3936447Ssusans 	char		serial_no[32];
3946447Ssusans 
3956447Ssusans 	/*
3966447Ssusans 	 * Other physical/controller/operation information. Indicates the
3976447Ssusans 	 * presence of the hardware
3986447Ssusans 	 */
3996447Ssusans 	struct {
4006447Ssusans 		uint32_t	bbu		: 1;
4016447Ssusans 		uint32_t	alarm		: 1;
4026447Ssusans 		uint32_t	nvram		: 1;
4036447Ssusans 		uint32_t	uart		: 1;
4046447Ssusans 		uint32_t	reserved	: 28;
4056447Ssusans 	} hw_present;
4066447Ssusans 
4076447Ssusans 	uint32_t	current_fw_time;
4086447Ssusans 
4096447Ssusans 	/* Maximum data transfer sizes */
4106447Ssusans 	uint16_t		max_concurrent_cmds;
4116447Ssusans 	uint16_t		max_sge_count;
4126447Ssusans 	uint32_t		max_request_size;
4136447Ssusans 
4146447Ssusans 	/* Logical and physical device counts */
4156447Ssusans 	uint16_t		ld_present_count;
4166447Ssusans 	uint16_t		ld_degraded_count;
4176447Ssusans 	uint16_t		ld_offline_count;
4186447Ssusans 
4196447Ssusans 	uint16_t		pd_present_count;
4206447Ssusans 	uint16_t		pd_disk_present_count;
4216447Ssusans 	uint16_t		pd_disk_pred_failure_count;
4226447Ssusans 	uint16_t		pd_disk_failed_count;
4236447Ssusans 
4246447Ssusans 	/* Memory size information */
4256447Ssusans 	uint16_t		nvram_size;
4266447Ssusans 	uint16_t		memory_size;
4276447Ssusans 	uint16_t		flash_size;
4286447Ssusans 
4296447Ssusans 	/* Error counters */
4306447Ssusans 	uint16_t		mem_correctable_error_count;
4316447Ssusans 	uint16_t		mem_uncorrectable_error_count;
4326447Ssusans 
4336447Ssusans 	/* Cluster information */
4346447Ssusans 	uint8_t		cluster_permitted;
4356447Ssusans 	uint8_t		cluster_active;
4366447Ssusans 	uint8_t		reserved_1[2];
4376447Ssusans 
4386447Ssusans 	/* Controller capabilities structures */
4396447Ssusans 	struct {
4406447Ssusans 		uint32_t	raid_level_0	: 1;
4416447Ssusans 		uint32_t	raid_level_1	: 1;
4426447Ssusans 		uint32_t	raid_level_5	: 1;
4436447Ssusans 		uint32_t	raid_level_1E	: 1;
4446447Ssusans 		uint32_t	reserved	: 28;
4456447Ssusans 	} raid_levels;
4466447Ssusans 
4476447Ssusans 	struct {
4486447Ssusans 		uint32_t	rbld_rate		: 1;
4496447Ssusans 		uint32_t	cc_rate			: 1;
4506447Ssusans 		uint32_t	bgi_rate		: 1;
4516447Ssusans 		uint32_t	recon_rate		: 1;
4526447Ssusans 		uint32_t	patrol_rate		: 1;
4536447Ssusans 		uint32_t	alarm_control		: 1;
4546447Ssusans 		uint32_t	cluster_supported	: 1;
4556447Ssusans 		uint32_t	bbu			: 1;
4566447Ssusans 		uint32_t	spanning_allowed	: 1;
4576447Ssusans 		uint32_t	dedicated_hotspares	: 1;
4586447Ssusans 		uint32_t	revertible_hotspares	: 1;
4596447Ssusans 		uint32_t	foreign_config_import	: 1;
4606447Ssusans 		uint32_t	self_diagnostic		: 1;
4616447Ssusans 		uint32_t	reserved		: 19;
4626447Ssusans 	} adapter_operations;
4636447Ssusans 
4646447Ssusans 	struct {
4656447Ssusans 		uint32_t	read_policy	: 1;
4666447Ssusans 		uint32_t	write_policy	: 1;
4676447Ssusans 		uint32_t	io_policy	: 1;
4686447Ssusans 		uint32_t	access_policy	: 1;
4696447Ssusans 		uint32_t	reserved	: 28;
4706447Ssusans 	} ld_operations;
4716447Ssusans 
4726447Ssusans 	struct {
4736447Ssusans 		uint8_t	min;
4746447Ssusans 		uint8_t	max;
4756447Ssusans 		uint8_t	reserved[2];
4766447Ssusans 	} stripe_size_operations;
4776447Ssusans 
4786447Ssusans 	struct {
4796447Ssusans 		uint32_t	force_online	: 1;
4806447Ssusans 		uint32_t	force_offline	: 1;
4816447Ssusans 		uint32_t	force_rebuild	: 1;
4826447Ssusans 		uint32_t	reserved	: 29;
4836447Ssusans 	} pd_operations;
4846447Ssusans 
4856447Ssusans 	struct {
4866447Ssusans 		uint32_t	ctrl_supports_sas	: 1;
4876447Ssusans 		uint32_t	ctrl_supports_sata	: 1;
4886447Ssusans 		uint32_t	allow_mix_in_encl	: 1;
4896447Ssusans 		uint32_t	allow_mix_in_ld		: 1;
4906447Ssusans 		uint32_t	allow_sata_in_cluster	: 1;
4916447Ssusans 		uint32_t	reserved		: 27;
4926447Ssusans 	} pd_mix_support;
4936447Ssusans 
4946447Ssusans 	/* Include the controller properties (changeable items) */
4956447Ssusans 	uint8_t				reserved_2[12];
4966447Ssusans 	struct megasas_ctrl_prop	properties;
4976447Ssusans 
4986447Ssusans 	uint8_t				pad[0x800 - 0x640];
4996447Ssusans };
5006447Ssusans 
5016447Ssusans /*
5026447Ssusans  * ===============================
5036447Ssusans  * MegaRAID SAS driver definitions
5046447Ssusans  * ===============================
5056447Ssusans  */
5066447Ssusans #define	MEGADRV_MAX_NUM_CMD			1024
5076447Ssusans 
5086447Ssusans #define	MEGADRV_MAX_PD_CHANNELS			2
5096447Ssusans #define	MEGADRV_MAX_LD_CHANNELS			2
5106447Ssusans #define	MEGADRV_MAX_CHANNELS			(MEGADRV_MAX_PD_CHANNELS + \
5116447Ssusans 						MEGADRV_MAX_LD_CHANNELS)
5126447Ssusans #define	MEGADRV_MAX_DEV_PER_CHANNEL		128
5136447Ssusans #define	MEGADRV_DEFAULT_INIT_ID			-1
5146447Ssusans #define	MEGADRV_MAX_CMD_PER_LUN			1000
5156447Ssusans #define	MEGADRV_MAX_LUN				8
5166447Ssusans #define	MEGADRV_MAX_LD				64
5176447Ssusans 
5186447Ssusans #define	MEGADRV_RESET_WAIT_TIME			300
5196447Ssusans #define	MEGADRV_RESET_NOTICE_INTERVAL		5
5206447Ssusans 
5216447Ssusans #define	MEGASAS_IOCTL_CMD			0
5226447Ssusans 
5236447Ssusans /*
5246447Ssusans  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
5256447Ssusans  * SGLs based on the size of dma_addr_t
5266447Ssusans  */
5276447Ssusans #define	IS_DMA64		(sizeof (dma_addr_t) == 8)
5286447Ssusans 
5297562SSusan.Scheufele@Sun.COM #define	IB_MSG_0_OFF			0x10	/* XScale */
5307562SSusan.Scheufele@Sun.COM #define	OB_MSG_0_OFF			0x18	/* XScale */
5317562SSusan.Scheufele@Sun.COM #define	IB_DOORBELL_OFF			0x20	/* XScale & ROC */
5327562SSusan.Scheufele@Sun.COM #define	OB_INTR_STATUS_OFF		0x30	/* XScale & ROC */
5337562SSusan.Scheufele@Sun.COM #define	OB_INTR_MASK_OFF		0x34	/* XScale & ROC */
5347562SSusan.Scheufele@Sun.COM #define	IB_QPORT_OFF			0x40	/* XScale & ROC */
5357562SSusan.Scheufele@Sun.COM #define	OB_DOORBELL_CLEAR_OFF		0xA0	/* ROC */
5367562SSusan.Scheufele@Sun.COM #define	OB_SCRATCH_PAD_0_OFF		0xB0	/* ROC */
5377562SSusan.Scheufele@Sun.COM #define	OB_INTR_MASK			0xFFFFFFFF
5387562SSusan.Scheufele@Sun.COM #define	OB_DOORBELL_CLEAR_MASK		0xFFFFFFFF
5397562SSusan.Scheufele@Sun.COM 
5406447Ssusans /*
5416447Ssusans  * All MFI register set macros accept megasas_register_set*
5426447Ssusans  */
5436447Ssusans #define	WR_IB_MSG_0(v, instance) 	ddi_put32((instance)->regmap_handle, \
5447562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_MSG_0_OFF), (v))
5456447Ssusans 
5466447Ssusans #define	RD_OB_MSG_0(instance) 		ddi_get32((instance)->regmap_handle, \
5477562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_MSG_0_OFF))
5486447Ssusans 
5496447Ssusans #define	WR_IB_DOORBELL(v, instance)	ddi_put32((instance)->regmap_handle, \
5507562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF), (v))
5516447Ssusans 
5526447Ssusans #define	RD_IB_DOORBELL(instance)	ddi_get32((instance)->regmap_handle, \
5537562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF))
5546447Ssusans 
5556447Ssusans #define	WR_OB_INTR_STATUS(v, instance) 	ddi_put32((instance)->regmap_handle, \
5567562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF), (v))
5576447Ssusans 
5586447Ssusans #define	RD_OB_INTR_STATUS(instance) 	ddi_get32((instance)->regmap_handle, \
5597562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF))
5606447Ssusans 
5616447Ssusans #define	WR_OB_INTR_MASK(v, instance) 	ddi_put32((instance)->regmap_handle, \
5627562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), (v))
5636447Ssusans 
5646447Ssusans #define	RD_OB_INTR_MASK(instance) 	ddi_get32((instance)->regmap_handle, \
5657562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF))
5666447Ssusans 
5676447Ssusans #define	WR_IB_QPORT(v, instance) 	ddi_put32((instance)->regmap_handle, \
5687562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_QPORT_OFF), (v))
5696447Ssusans 
5706447Ssusans #define	WR_OB_DOORBELL_CLEAR(v, instance) ddi_put32((instance)->regmap_handle, \
5717562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_CLEAR_OFF), \
5727562SSusan.Scheufele@Sun.COM 	(v))
5736447Ssusans 
5746447Ssusans #define	RD_OB_SCRATCH_PAD_0(instance) 	ddi_get32((instance)->regmap_handle, \
5757562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_0_OFF))
5766447Ssusans 
5776447Ssusans /*
5786447Ssusans  * When FW is in MFI_STATE_READY or MFI_STATE_OPERATIONAL, the state data
5796447Ssusans  * of Outbound Msg Reg 0 indicates max concurrent cmds supported, max SGEs
5806447Ssusans  * supported per cmd and if 64-bit MFAs (M64) is enabled or disabled.
5816447Ssusans  */
5826447Ssusans #define	MFI_OB_INTR_STATUS_MASK		0x00000002
5836447Ssusans 
5846447Ssusans /*
5856447Ssusans  * This MFI_REPLY_1078_MESSAGE_INTR flag is used also
5866447Ssusans  * in enable_intr_pcc also. Hence bit 2, i.e. 0x4 has
5876447Ssusans  * been set in this flag along with bit 31.
5886447Ssusans  */
5896447Ssusans #define	MFI_REPLY_1078_MESSAGE_INTR	0x80000004
5906447Ssusans 
5916447Ssusans #define	MFI_POLL_TIMEOUT_SECS		60
5926447Ssusans 
5936447Ssusans #define	MFI_ENABLE_INTR(instance)  ddi_put32((instance)->regmap_handle, \
5947698SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), 1)
5956447Ssusans #define	MFI_DISABLE_INTR(instance)					\
5966447Ssusans {									\
5976447Ssusans 	uint32_t disable = 1;						\
5986447Ssusans 	uint32_t mask =  ddi_get32((instance)->regmap_handle, 		\
5997562SSusan.Scheufele@Sun.COM 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF));\
6006447Ssusans 	mask &= ~disable;						\
6017562SSusan.Scheufele@Sun.COM 	ddi_put32((instance)->regmap_handle, (uint32_t *)		\
6027562SSusan.Scheufele@Sun.COM 	    (uintptr_t)((instance)->regmap + OB_INTR_MASK_OFF), mask);	\
6036447Ssusans }
6046447Ssusans 
6057562SSusan.Scheufele@Sun.COM /* By default, the firmware programs for 8 Kbytes of memory */
6067562SSusan.Scheufele@Sun.COM #define	DEFAULT_MFI_MEM_SZ	8192
6077562SSusan.Scheufele@Sun.COM #define	MINIMUM_MFI_MEM_SZ	4096
6087562SSusan.Scheufele@Sun.COM 
6097562SSusan.Scheufele@Sun.COM /* DCMD Message Frame MAILBOX0-11 */
6107562SSusan.Scheufele@Sun.COM #define	DCMD_MBOX_SZ		12
6117562SSusan.Scheufele@Sun.COM 
6126447Ssusans 
6136447Ssusans struct megasas_register_set {
6146447Ssusans 	uint32_t	reserved_0[4];			/* 0000h */
6156447Ssusans 
6166447Ssusans 	uint32_t	inbound_msg_0;			/* 0010h */
6176447Ssusans 	uint32_t	inbound_msg_1;			/* 0014h */
6186447Ssusans 	uint32_t	outbound_msg_0;			/* 0018h */
6196447Ssusans 	uint32_t	outbound_msg_1;			/* 001Ch */
6206447Ssusans 
6216447Ssusans 	uint32_t	inbound_doorbell;		/* 0020h */
6226447Ssusans 	uint32_t	inbound_intr_status;		/* 0024h */
6236447Ssusans 	uint32_t	inbound_intr_mask;		/* 0028h */
6246447Ssusans 
6256447Ssusans 	uint32_t	outbound_doorbell;		/* 002Ch */
6266447Ssusans 	uint32_t	outbound_intr_status;		/* 0030h */
6276447Ssusans 	uint32_t	outbound_intr_mask;		/* 0034h */
6286447Ssusans 
6296447Ssusans 	uint32_t	reserved_1[2];			/* 0038h */
6306447Ssusans 
6316447Ssusans 	uint32_t	inbound_queue_port;		/* 0040h */
6326447Ssusans 	uint32_t	outbound_queue_port;		/* 0044h */
6336447Ssusans 
6346447Ssusans 	uint32_t 	reserved_2[22];			/* 0048h */
6356447Ssusans 
6366447Ssusans 	uint32_t 	outbound_doorbell_clear;	/* 00A0h */
6376447Ssusans 
6386447Ssusans 	uint32_t 	reserved_3[3];			/* 00A4h */
6396447Ssusans 
6406447Ssusans 	uint32_t 	outbound_scratch_pad;		/* 00B0h */
6416447Ssusans 
6426447Ssusans 	uint32_t 	reserved_4[3];			/* 00B4h */
6436447Ssusans 
6446447Ssusans 	uint32_t 	inbound_low_queue_port;		/* 00C0h */
6456447Ssusans 
6466447Ssusans 	uint32_t 	inbound_high_queue_port;	/* 00C4h */
6476447Ssusans 
6486447Ssusans 	uint32_t 	reserved_5;			/* 00C8h */
6496447Ssusans 	uint32_t 	index_registers[820];		/* 00CCh */
6506447Ssusans };
6516447Ssusans 
6526447Ssusans struct megasas_sge32 {
6536447Ssusans 	uint32_t	phys_addr;
6546447Ssusans 	uint32_t	length;
6556447Ssusans };
6566447Ssusans 
6576447Ssusans struct megasas_sge64 {
6586447Ssusans 	uint64_t	phys_addr;
6596447Ssusans 	uint32_t	length;
6606447Ssusans };
6616447Ssusans 
6626447Ssusans union megasas_sgl {
6636447Ssusans 	struct megasas_sge32	sge32[1];
6646447Ssusans 	struct megasas_sge64	sge64[1];
6656447Ssusans };
6666447Ssusans 
6676447Ssusans struct megasas_header {
6686447Ssusans 	uint8_t		cmd;				/* 00h */
6696447Ssusans 	uint8_t		sense_len;			/* 01h */
6706447Ssusans 	uint8_t		cmd_status;			/* 02h */
6716447Ssusans 	uint8_t		scsi_status;			/* 03h */
6726447Ssusans 
6736447Ssusans 	uint8_t		target_id;			/* 04h */
6746447Ssusans 	uint8_t		lun;				/* 05h */
6756447Ssusans 	uint8_t		cdb_len;			/* 06h */
6766447Ssusans 	uint8_t		sge_count;			/* 07h */
6776447Ssusans 
6786447Ssusans 	uint32_t	context;			/* 08h */
6796447Ssusans 	uint32_t	pad_0;				/* 0Ch */
6806447Ssusans 
6816447Ssusans 	uint16_t	flags;				/* 10h */
6826447Ssusans 	uint16_t	timeout;			/* 12h */
6836447Ssusans 	uint32_t	data_xferlen;			/* 14h */
6846447Ssusans };
6856447Ssusans 
6866447Ssusans union megasas_sgl_frame {
6876447Ssusans 	struct megasas_sge32	sge32[8];
6886447Ssusans 	struct megasas_sge64	sge64[5];
6896447Ssusans };
6906447Ssusans 
6916447Ssusans struct megasas_init_frame {
6926447Ssusans 	uint8_t		cmd;				/* 00h */
6936447Ssusans 	uint8_t		reserved_0;			/* 01h */
6946447Ssusans 	uint8_t		cmd_status;			/* 02h */
6956447Ssusans 
6966447Ssusans 	uint8_t		reserved_1;			/* 03h */
6976447Ssusans 	uint32_t	reserved_2;			/* 04h */
6986447Ssusans 
6996447Ssusans 	uint32_t	context;			/* 08h */
7006447Ssusans 	uint32_t	pad_0;				/* 0Ch */
7016447Ssusans 
7026447Ssusans 	uint16_t	flags;				/* 10h */
7036447Ssusans 	uint16_t	reserved_3;			/* 12h */
7046447Ssusans 	uint32_t	data_xfer_len;			/* 14h */
7056447Ssusans 
7066447Ssusans 	uint32_t	queue_info_new_phys_addr_lo;	/* 18h */
7076447Ssusans 	uint32_t	queue_info_new_phys_addr_hi;	/* 1Ch */
7086447Ssusans 	uint32_t	queue_info_old_phys_addr_lo;	/* 20h */
7096447Ssusans 	uint32_t	queue_info_old_phys_addr_hi;	/* 24h */
7106447Ssusans 
7116447Ssusans 	uint32_t	reserved_4[6];			/* 28h */
7126447Ssusans };
7136447Ssusans 
7146447Ssusans struct megasas_init_queue_info {
7156447Ssusans 	uint32_t		init_flags;			/* 00h */
7166447Ssusans 	uint32_t		reply_queue_entries;		/* 04h */
7176447Ssusans 
7186447Ssusans 	uint32_t		reply_queue_start_phys_addr_lo;	/* 08h */
7196447Ssusans 	uint32_t		reply_queue_start_phys_addr_hi;	/* 0Ch */
7206447Ssusans 	uint32_t		producer_index_phys_addr_lo;	/* 10h */
7216447Ssusans 	uint32_t		producer_index_phys_addr_hi;	/* 14h */
7226447Ssusans 	uint32_t		consumer_index_phys_addr_lo;	/* 18h */
7236447Ssusans 	uint32_t		consumer_index_phys_addr_hi;	/* 1Ch */
7246447Ssusans };
7256447Ssusans 
7266447Ssusans struct megasas_io_frame {
7276447Ssusans 	uint8_t			cmd;			/* 00h */
7286447Ssusans 	uint8_t			sense_len;		/* 01h */
7296447Ssusans 	uint8_t			cmd_status;		/* 02h */
7306447Ssusans 	uint8_t			scsi_status;		/* 03h */
7316447Ssusans 
7326447Ssusans 	uint8_t			target_id;		/* 04h */
7336447Ssusans 	uint8_t			access_byte;		/* 05h */
7346447Ssusans 	uint8_t			reserved_0;		/* 06h */
7356447Ssusans 	uint8_t			sge_count;		/* 07h */
7366447Ssusans 
7376447Ssusans 	uint32_t		context;		/* 08h */
7386447Ssusans 	uint32_t		pad_0;			/* 0Ch */
7396447Ssusans 
7406447Ssusans 	uint16_t		flags;			/* 10h */
7416447Ssusans 	uint16_t		timeout;		/* 12h */
7426447Ssusans 	uint32_t		lba_count;		/* 14h */
7436447Ssusans 
7446447Ssusans 	uint32_t		sense_buf_phys_addr_lo;	/* 18h */
7456447Ssusans 	uint32_t		sense_buf_phys_addr_hi;	/* 1Ch */
7466447Ssusans 
7476447Ssusans 	uint32_t		start_lba_lo;		/* 20h */
7486447Ssusans 	uint32_t		start_lba_hi;		/* 24h */
7496447Ssusans 
7506447Ssusans 	union megasas_sgl	sgl;			/* 28h */
7516447Ssusans };
7526447Ssusans 
7536447Ssusans struct megasas_pthru_frame {
7546447Ssusans 	uint8_t			cmd;			/* 00h */
7556447Ssusans 	uint8_t			sense_len;		/* 01h */
7566447Ssusans 	uint8_t			cmd_status;		/* 02h */
7576447Ssusans 	uint8_t			scsi_status;		/* 03h */
7586447Ssusans 
7596447Ssusans 	uint8_t			target_id;		/* 04h */
7606447Ssusans 	uint8_t			lun;			/* 05h */
7616447Ssusans 	uint8_t			cdb_len;		/* 06h */
7626447Ssusans 	uint8_t			sge_count;		/* 07h */
7636447Ssusans 
7646447Ssusans 	uint32_t		context;		/* 08h */
7656447Ssusans 	uint32_t		pad_0;			/* 0Ch */
7666447Ssusans 
7676447Ssusans 	uint16_t		flags;			/* 10h */
7686447Ssusans 	uint16_t		timeout;		/* 12h */
7696447Ssusans 	uint32_t		data_xfer_len;		/* 14h */
7706447Ssusans 
7716447Ssusans 	uint32_t		sense_buf_phys_addr_lo;	/* 18h */
7726447Ssusans 	uint32_t		sense_buf_phys_addr_hi;	/* 1Ch */
7736447Ssusans 
7746447Ssusans 	uint8_t			cdb[16];		/* 20h */
7756447Ssusans 	union megasas_sgl	sgl;			/* 30h */
7766447Ssusans };
7776447Ssusans 
7786447Ssusans struct megasas_dcmd_frame {
7796447Ssusans 	uint8_t			cmd;			/* 00h */
7806447Ssusans 	uint8_t			reserved_0;		/* 01h */
7816447Ssusans 	uint8_t			cmd_status;		/* 02h */
7826447Ssusans 	uint8_t			reserved_1[4];		/* 03h */
7836447Ssusans 	uint8_t			sge_count;		/* 07h */
7846447Ssusans 
7856447Ssusans 	uint32_t		context;		/* 08h */
7866447Ssusans 	uint32_t		pad_0;			/* 0Ch */
7876447Ssusans 
7886447Ssusans 	uint16_t		flags;			/* 10h */
7896447Ssusans 	uint16_t		timeout;		/* 12h */
7906447Ssusans 
7916447Ssusans 	uint32_t		data_xfer_len;		/* 14h */
7926447Ssusans 	uint32_t		opcode;			/* 18h */
7936447Ssusans 
7947562SSusan.Scheufele@Sun.COM 	/* uint8_t		mbox[DCMD_MBOX_SZ]; */	/* 1Ch */
7956447Ssusans 	union {						/* 1Ch */
7967562SSusan.Scheufele@Sun.COM 		uint8_t b[DCMD_MBOX_SZ];
7976447Ssusans 		uint16_t s[6];
7986447Ssusans 		uint32_t w[3];
7996447Ssusans 	} mbox;
8006447Ssusans 
8016447Ssusans 	union megasas_sgl	sgl;			/* 28h */
8026447Ssusans };
8036447Ssusans 
8046447Ssusans struct megasas_abort_frame {
8056447Ssusans 	uint8_t		cmd;				/* 00h */
8066447Ssusans 	uint8_t		reserved_0;			/* 01h */
8076447Ssusans 	uint8_t		cmd_status;			/* 02h */
8086447Ssusans 
8096447Ssusans 	uint8_t		reserved_1;			/* 03h */
8106447Ssusans 	uint32_t	reserved_2;			/* 04h */
8116447Ssusans 
8126447Ssusans 	uint32_t	context;			/* 08h */
8136447Ssusans 	uint32_t	pad_0;				/* 0Ch */
8146447Ssusans 
8156447Ssusans 	uint16_t	flags;				/* 10h */
8166447Ssusans 	uint16_t	reserved_3;			/* 12h */
8176447Ssusans 	uint32_t	reserved_4;			/* 14h */
8186447Ssusans 
8196447Ssusans 	uint32_t	abort_context;			/* 18h */
8206447Ssusans 	uint32_t	pad_1;				/* 1Ch */
8216447Ssusans 
8226447Ssusans 	uint32_t	abort_mfi_phys_addr_lo;		/* 20h */
8236447Ssusans 	uint32_t	abort_mfi_phys_addr_hi;		/* 24h */
8246447Ssusans 
8256447Ssusans 	uint32_t	reserved_5[6];			/* 28h */
8266447Ssusans };
8276447Ssusans 
8286447Ssusans struct megasas_smp_frame {
8296447Ssusans 	uint8_t		cmd;				/* 00h */
8306447Ssusans 	uint8_t		reserved_1;			/* 01h */
8316447Ssusans 	uint8_t		cmd_status;			/* 02h */
8326447Ssusans 	uint8_t		connection_status;		/* 03h */
8336447Ssusans 
8346447Ssusans 	uint8_t		reserved_2[3];			/* 04h */
8356447Ssusans 	uint8_t		sge_count;			/* 07h */
8366447Ssusans 
8376447Ssusans 	uint32_t	context;			/* 08h */
8386447Ssusans 	uint32_t	pad_0;				/* 0Ch */
8396447Ssusans 
8406447Ssusans 	uint16_t	flags;				/* 10h */
8416447Ssusans 	uint16_t	timeout;			/* 12h */
8426447Ssusans 
8436447Ssusans 	uint32_t	data_xfer_len;			/* 14h */
8446447Ssusans 
8456447Ssusans 	uint64_t	sas_addr;			/* 20h */
8466447Ssusans 
8476447Ssusans 	union megasas_sgl	sgl[2];			/* 28h */
8486447Ssusans };
8496447Ssusans 
8506447Ssusans struct megasas_stp_frame {
8516447Ssusans 	uint8_t		cmd;				/* 00h */
8526447Ssusans 	uint8_t		reserved_1;			/* 01h */
8536447Ssusans 	uint8_t		cmd_status;			/* 02h */
8546447Ssusans 	uint8_t		connection_status;		/* 03h */
8556447Ssusans 
8566447Ssusans 	uint8_t		target_id;			/* 04h */
8576447Ssusans 	uint8_t		reserved_2[2];			/* 04h */
8586447Ssusans 	uint8_t		sge_count;			/* 07h */
8596447Ssusans 
8606447Ssusans 	uint32_t	context;			/* 08h */
8616447Ssusans 	uint32_t	pad_0;				/* 0Ch */
8626447Ssusans 
8636447Ssusans 	uint16_t	flags;				/* 10h */
8646447Ssusans 	uint16_t	timeout;			/* 12h */
8656447Ssusans 
8666447Ssusans 	uint32_t	data_xfer_len;			/* 14h */
8676447Ssusans 
8686447Ssusans 	uint16_t	fis[10];			/* 28h */
8696447Ssusans 	uint32_t	stp_flags;			/* 3C */
8706447Ssusans 	union megasas_sgl	sgl;			/* 40 */
8716447Ssusans };
8726447Ssusans 
8736447Ssusans union megasas_frame {
8746447Ssusans 	struct megasas_header		hdr;
8756447Ssusans 	struct megasas_init_frame	init;
8766447Ssusans 	struct megasas_io_frame		io;
8776447Ssusans 	struct megasas_pthru_frame	pthru;
8786447Ssusans 	struct megasas_dcmd_frame	dcmd;
8796447Ssusans 	struct megasas_abort_frame	abort;
8806447Ssusans 	struct megasas_smp_frame	smp;
8816447Ssusans 	struct megasas_stp_frame	stp;
8826447Ssusans 
8836447Ssusans 	uint8_t		raw_bytes[64];
8846447Ssusans };
8856447Ssusans 
8866447Ssusans union megasas_evt_class_locale {
8876447Ssusans 	struct {
8886447Ssusans 		uint16_t	locale;
8896447Ssusans 		uint8_t		reserved;
8906447Ssusans 		int8_t		class;
8916447Ssusans 	} members;
8926447Ssusans 
8936447Ssusans 	uint32_t	word;
8946447Ssusans };
8956447Ssusans 
8966447Ssusans struct megasas_evt_log_info {
8976447Ssusans 	uint32_t	newest_seq_num;
8986447Ssusans 	uint32_t	oldest_seq_num;
8996447Ssusans 	uint32_t	clear_seq_num;
9006447Ssusans 	uint32_t	shutdown_seq_num;
9016447Ssusans 	uint32_t	boot_seq_num;
9026447Ssusans };
9036447Ssusans 
9046447Ssusans struct megasas_progress {
9056447Ssusans 	uint16_t	progress;
9066447Ssusans 	uint16_t	elapsed_seconds;
9076447Ssusans };
9086447Ssusans 
9096447Ssusans struct megasas_evtarg_ld {
9106447Ssusans 	uint16_t	target_id;
9116447Ssusans 	uint8_t		ld_index;
9126447Ssusans 	uint8_t		reserved;
9136447Ssusans };
9146447Ssusans 
9156447Ssusans struct megasas_evtarg_pd {
9166447Ssusans 	uint16_t	device_id;
9176447Ssusans 	uint8_t		encl_index;
9186447Ssusans 	uint8_t		slot_number;
9196447Ssusans };
9206447Ssusans 
9216447Ssusans struct megasas_evt_detail {
9226447Ssusans 	uint32_t	seq_num;
9236447Ssusans 	uint32_t	time_stamp;
9246447Ssusans 	uint32_t	code;
9256447Ssusans 	union megasas_evt_class_locale	cl;
9266447Ssusans 	uint8_t		arg_type;
9276447Ssusans 	uint8_t		reserved1[15];
9286447Ssusans 
9296447Ssusans 	union {
9306447Ssusans 		struct {
9316447Ssusans 			struct megasas_evtarg_pd	pd;
9326447Ssusans 			uint8_t				cdb_length;
9336447Ssusans 			uint8_t				sense_length;
9346447Ssusans 			uint8_t				reserved[2];
9356447Ssusans 			uint8_t				cdb[16];
9366447Ssusans 			uint8_t				sense[64];
9376447Ssusans 		} cdbSense;
9386447Ssusans 
9396447Ssusans 		struct megasas_evtarg_ld		ld;
9406447Ssusans 
9416447Ssusans 		struct {
9426447Ssusans 			struct megasas_evtarg_ld	ld;
9436447Ssusans 			uint64_t			count;
9446447Ssusans 		} ld_count;
9456447Ssusans 
9466447Ssusans 		struct {
9476447Ssusans 			uint64_t			lba;
9486447Ssusans 			struct megasas_evtarg_ld	ld;
9496447Ssusans 		} ld_lba;
9506447Ssusans 
9516447Ssusans 		struct {
9526447Ssusans 			struct megasas_evtarg_ld	ld;
9536447Ssusans 			uint32_t			prevOwner;
9546447Ssusans 			uint32_t			newOwner;
9556447Ssusans 		} ld_owner;
9566447Ssusans 
9576447Ssusans 		struct {
9586447Ssusans 			uint64_t			ld_lba;
9596447Ssusans 			uint64_t			pd_lba;
9606447Ssusans 			struct megasas_evtarg_ld	ld;
9616447Ssusans 			struct megasas_evtarg_pd	pd;
9626447Ssusans 		} ld_lba_pd_lba;
9636447Ssusans 
9646447Ssusans 		struct {
9656447Ssusans 			struct megasas_evtarg_ld	ld;
9666447Ssusans 			struct megasas_progress		prog;
9676447Ssusans 		} ld_prog;
9686447Ssusans 
9696447Ssusans 		struct {
9706447Ssusans 			struct megasas_evtarg_ld	ld;
9716447Ssusans 			uint32_t			prev_state;
9726447Ssusans 			uint32_t			new_state;
9736447Ssusans 		} ld_state;
9746447Ssusans 
9756447Ssusans 		struct {
9766447Ssusans 			uint64_t			strip;
9776447Ssusans 			struct megasas_evtarg_ld	ld;
9786447Ssusans 		} ld_strip;
9796447Ssusans 
9806447Ssusans 		struct megasas_evtarg_pd	pd;
9816447Ssusans 
9826447Ssusans 		struct {
9836447Ssusans 			struct megasas_evtarg_pd	pd;
9846447Ssusans 			uint32_t			err;
9856447Ssusans 		} pd_err;
9866447Ssusans 
9876447Ssusans 		struct {
9886447Ssusans 			uint64_t			lba;
9896447Ssusans 			struct megasas_evtarg_pd	pd;
9906447Ssusans 		} pd_lba;
9916447Ssusans 
9926447Ssusans 		struct {
9936447Ssusans 			uint64_t			lba;
9946447Ssusans 			struct megasas_evtarg_pd	pd;
9956447Ssusans 			struct megasas_evtarg_ld	ld;
9966447Ssusans 		} pd_lba_ld;
9976447Ssusans 
9986447Ssusans 		struct {
9996447Ssusans 			struct megasas_evtarg_pd	pd;
10006447Ssusans 			struct megasas_progress		prog;
10016447Ssusans 		} pd_prog;
10026447Ssusans 
10036447Ssusans 		struct {
10046447Ssusans 			struct megasas_evtarg_pd	pd;
10056447Ssusans 			uint32_t			prevState;
10066447Ssusans 			uint32_t			newState;
10076447Ssusans 		} pd_state;
10086447Ssusans 
10096447Ssusans 		struct {
10106447Ssusans 			uint16_t	vendorId;
10116447Ssusans 			uint16_t	deviceId;
10126447Ssusans 			uint16_t	subVendorId;
10136447Ssusans 			uint16_t	subDeviceId;
10146447Ssusans 		} pci;
10156447Ssusans 
10166447Ssusans 		uint32_t	rate;
10176447Ssusans 		char		str[96];
10186447Ssusans 
10196447Ssusans 		struct {
10206447Ssusans 			uint32_t	rtc;
10216447Ssusans 			uint32_t	elapsedSeconds;
10226447Ssusans 		} time;
10236447Ssusans 
10246447Ssusans 		struct {
10256447Ssusans 			uint32_t	ecar;
10266447Ssusans 			uint32_t	elog;
10276447Ssusans 			char		str[64];
10286447Ssusans 		} ecc;
10296447Ssusans 
10306447Ssusans 		uint8_t		b[96];
10316447Ssusans 		uint16_t	s[48];
10326447Ssusans 		uint32_t	w[24];
10336447Ssusans 		uint64_t	d[12];
10346447Ssusans 	} args;
10356447Ssusans 
10366447Ssusans 	char	description[128];
10376447Ssusans 
10386447Ssusans };
10396447Ssusans 
10406447Ssusans /* only 63 are usable by the application */
10416447Ssusans #define	MAX_LOGICAL_DRIVES			64
10426447Ssusans /* only 255 physical devices may be used */
10436447Ssusans #define	MAX_PHYSICAL_DEVICES			256
10446447Ssusans #define	MAX_PD_PER_ENCLOSURE			64
10456447Ssusans /* maximum disks per array */
10466447Ssusans #define	MAX_ROW_SIZE				32
10476447Ssusans /* maximum spans per logical drive */
10486447Ssusans #define	MAX_SPAN_DEPTH				8
10496447Ssusans /* maximum number of arrays a hot spare may be dedicated to */
10506447Ssusans #define	MAX_ARRAYS_DEDICATED			16
10516447Ssusans /* maximum number of arrays which may exist */
10526447Ssusans #define	MAX_ARRAYS				128
10536447Ssusans /* maximum number of foreign configs that may ha managed at once */
10546447Ssusans #define	MAX_FOREIGN_CONFIGS			8
10556447Ssusans /* maximum spares (global and dedicated combined) */
10566447Ssusans #define	MAX_SPARES_FOR_THE_CONTROLLER		MAX_PHYSICAL_DEVICES
10576447Ssusans /* maximum possible Target IDs (i.e. 0 to 63) */
10586447Ssusans #define	MAX_TARGET_ID				63
10596447Ssusans /* maximum number of supported enclosures */
10606447Ssusans #define	MAX_ENCLOSURES				32
10616447Ssusans /* maximum number of PHYs per controller */
10626447Ssusans #define	MAX_PHYS_PER_CONTROLLER			16
10636447Ssusans /* maximum number of LDs per array (due to DDF limitations) */
10646447Ssusans #define	MAX_LDS_PER_ARRAY			16
10656447Ssusans 
10666447Ssusans /*
10676447Ssusans  * -----------------------------------------------------------------------------
10686447Ssusans  * -----------------------------------------------------------------------------
10696447Ssusans  *
10706447Ssusans  * Logical Drive commands
10716447Ssusans  *
10726447Ssusans  * -----------------------------------------------------------------------------
10736447Ssusans  * -----------------------------------------------------------------------------
10746447Ssusans  */
10756447Ssusans #define	MR_DCMD_LD	0x03000000,	/* Logical Device (LD) opcodes */
10766447Ssusans 
10776447Ssusans /*
10786447Ssusans  * Input:	dcmd.opcode	- MR_DCMD_LD_GET_LIST
10796447Ssusans  *		dcmd.mbox	- reserved
10806447Ssusans  *		dcmd.sge IN	- ptr to returned MR_LD_LIST structure
10816447Ssusans  * Desc:	Return the logical drive list structure
10826447Ssusans  * Status:	No error
10836447Ssusans  */
10846447Ssusans 
10856447Ssusans /*
10866447Ssusans  * defines the logical drive reference structure
10876447Ssusans  */
10886447Ssusans typedef	union _MR_LD_REF {	/* LD reference structure */
10896447Ssusans 	struct {
10906447Ssusans 		uint8_t	targetId; /* LD target id (0 to MAX_TARGET_ID) */
10916447Ssusans 		uint8_t	reserved; /* reserved to make in line with MR_PD_REF */
10926447Ssusans 		uint16_t seqNum;  /* Sequence Number */
10936447Ssusans 	} ld_ref;
10946447Ssusans 	uint32_t ref;		/* shorthand reference to full 32-bits */
10956447Ssusans } MR_LD_REF;			/* 4 bytes */
10966447Ssusans 
10976447Ssusans /*
10986447Ssusans  * defines the logical drive list structure
10996447Ssusans  */
11006447Ssusans typedef struct _MR_LD_LIST {
11016447Ssusans 	uint32_t	ldCount;	/* number of LDs */
11026447Ssusans 	uint32_t	reserved;	/* pad to 8-byte boundary */
11036447Ssusans 	struct {
11046447Ssusans 		MR_LD_REF ref;		/* LD reference */
11056447Ssusans 		uint8_t	state;		/* current LD state (MR_LD_STATE) */
11066447Ssusans 		uint8_t	reserved[3];	/* pad to 8-byte boundary */
11076447Ssusans 		uint64_t size;		/* LD size */
11086447Ssusans 	} ldList[MAX_LOGICAL_DRIVES];
11096447Ssusans } MR_LD_LIST;
11106447Ssusans /* 4 + 4 + (MAX_LOGICAL_DRIVES * 16), for 40LD it is = 648 bytes */
11116447Ssusans 
11127562SSusan.Scheufele@Sun.COM #pragma pack()
11137562SSusan.Scheufele@Sun.COM 
11146447Ssusans #define	DMA_OBJ_ALLOCATED	1
11156447Ssusans #define	DMA_OBJ_REALLOCATED	2
11166447Ssusans #define	DMA_OBJ_FREED		3
11176447Ssusans 
11186447Ssusans /*
11196447Ssusans  * dma_obj_t	- Our DMA object
11206447Ssusans  * @param buffer	: kernel virtual address
11216447Ssusans  * @param size		: size of the data to be allocated
11226447Ssusans  * @param acc_handle	: access handle
11236447Ssusans  * @param dma_handle	: dma handle
11246447Ssusans  * @param dma_cookie	: scatter-gather list
11256447Ssusans  * @param dma_attr	: dma attributes for this buffer
11266447Ssusans  *
11276447Ssusans  * Our DMA object. The caller must initialize the size and dma attributes
11286447Ssusans  * (dma_attr) fields before allocating the resources.
11296447Ssusans  */
11306447Ssusans typedef struct {
11316447Ssusans 	caddr_t			buffer;
11326447Ssusans 	uint32_t		size;
11336447Ssusans 	ddi_acc_handle_t	acc_handle;
11346447Ssusans 	ddi_dma_handle_t	dma_handle;
11356447Ssusans 	ddi_dma_cookie_t	dma_cookie[MEGASAS_MAX_SGE_CNT];
11366447Ssusans 	ddi_dma_attr_t		dma_attr;
11376447Ssusans 	uint8_t			status;
11386447Ssusans } dma_obj_t;
11396447Ssusans 
11406447Ssusans struct megasas_instance {
11416447Ssusans 	uint32_t	*producer;
11426447Ssusans 	uint32_t	*consumer;
11436447Ssusans 
11446447Ssusans 	uint32_t	*reply_queue;
11456447Ssusans 	dma_obj_t	mfi_internal_dma_obj;
11466447Ssusans 
11476447Ssusans 	uint8_t		init_id;
11486447Ssusans 	uint8_t		reserved[3];
11496447Ssusans 
11506447Ssusans 	uint16_t	max_num_sge;
11516447Ssusans 	uint16_t	max_fw_cmds;
11526447Ssusans 	uint32_t	max_sectors_per_req;
11536447Ssusans 
11546447Ssusans 	struct megasas_cmd	**cmd_list;
11556447Ssusans 
11566447Ssusans 	mlist_t		cmd_pool_list;
11576447Ssusans 	kmutex_t	cmd_pool_mtx;
11586447Ssusans 
11596447Ssusans 	mlist_t		cmd_pend_list;
11606447Ssusans 	kmutex_t	cmd_pend_mtx;
11616447Ssusans 
11626447Ssusans 	dma_obj_t	mfi_evt_detail_obj;
11636447Ssusans 	struct megasas_cmd	*aen_cmd;
11646447Ssusans 
11656447Ssusans 	uint32_t	aen_seq_num;
11666447Ssusans 	uint32_t	aen_class_locale_word;
11676447Ssusans 
11686447Ssusans 	scsi_hba_tran_t		*tran;
11696447Ssusans 
11706447Ssusans 	kcondvar_t	int_cmd_cv;
11716447Ssusans 	kmutex_t	int_cmd_mtx;
11726447Ssusans 
11736447Ssusans 	kcondvar_t	aen_cmd_cv;
11746447Ssusans 	kmutex_t	aen_cmd_mtx;
11756447Ssusans 
11766447Ssusans 	kcondvar_t	abort_cmd_cv;
11776447Ssusans 	kmutex_t	abort_cmd_mtx;
11786447Ssusans 
11796447Ssusans 	dev_info_t		*dip;
11806447Ssusans 	ddi_acc_handle_t	pci_handle;
11816447Ssusans 
11826447Ssusans 	timeout_id_t	timeout_id;
11836447Ssusans 	uint32_t	unique_id;
11846447Ssusans 	uint16_t	fw_outstanding;
11856447Ssusans 	caddr_t		regmap;
11866447Ssusans 	ddi_acc_handle_t	regmap_handle;
11876447Ssusans 	uint8_t		isr_level;
11886447Ssusans 	ddi_iblock_cookie_t	iblock_cookie;
11896447Ssusans 	ddi_iblock_cookie_t	soft_iblock_cookie;
11906447Ssusans 	ddi_softintr_t		soft_intr_id;
11916447Ssusans 	uint8_t		softint_running;
11926447Ssusans 	kmutex_t	completed_pool_mtx;
11936447Ssusans 	mlist_t		completed_pool_list;
11946447Ssusans 
11956447Ssusans 	caddr_t		internal_buf;
11966447Ssusans 	uint32_t	internal_buf_dmac_add;
11976447Ssusans 	uint32_t	internal_buf_size;
11986447Ssusans 
11996447Ssusans 	uint16_t	vendor_id;
12006447Ssusans 	uint16_t	device_id;
12016447Ssusans 	uint16_t	subsysvid;
12026447Ssusans 	uint16_t	subsysid;
12036447Ssusans 	int		baseaddress;
12046447Ssusans 	char		iocnode[16];
12056447Ssusans 
12067533SYu.Wu@Sun.COM 	int		fm_capabilities;
12077533SYu.Wu@Sun.COM 
12086447Ssusans 	struct megasas_func_ptr	*func_ptr;
12096447Ssusans };
12106447Ssusans 
12116447Ssusans struct megasas_func_ptr {
12126447Ssusans 	int (*read_fw_status_reg)(struct megasas_instance *);
12136447Ssusans 	void (*issue_cmd)(struct megasas_cmd *, struct megasas_instance *);
12146447Ssusans 	int (*issue_cmd_in_sync_mode)(struct megasas_instance *,
12156447Ssusans 	    struct megasas_cmd *);
12166447Ssusans 	int (*issue_cmd_in_poll_mode)(struct megasas_instance *,
12176447Ssusans 	    struct megasas_cmd *);
12186447Ssusans 	void (*enable_intr)(struct megasas_instance *);
12196447Ssusans 	void (*disable_intr)(struct megasas_instance *);
12206447Ssusans 	int (*intr_ack)(struct megasas_instance *);
12216447Ssusans };
12226447Ssusans 
12236447Ssusans /*
12246447Ssusans  * ### Helper routines ###
12256447Ssusans  */
12266447Ssusans 
12276447Ssusans /*
12286447Ssusans  * con_log() - console log routine
12296447Ssusans  * @param level		: indicates the severity of the message.
12306447Ssusans  * @fparam mt		: format string
12316447Ssusans  *
12326447Ssusans  * con_log displays the error messages on the console based on the current
12336447Ssusans  * debug level. Also it attaches the appropriate kernel severity level with
12346447Ssusans  * the message.
12356447Ssusans  *
12366447Ssusans  *
12377562SSusan.Scheufele@Sun.COM  * console messages debug levels
12386447Ssusans  */
12396447Ssusans #define	CL_ANN		0	/* print unconditionally, announcements */
12406447Ssusans #define	CL_ANN1		1	/* No o/p  */
12416447Ssusans #define	CL_DLEVEL1	2	/* debug level 1, informative */
12426447Ssusans #define	CL_DLEVEL2	3	/* debug level 2, verbose */
12436447Ssusans #define	CL_DLEVEL3	4	/* debug level 3, very verbose */
12446447Ssusans 
12456447Ssusans #ifdef __SUNPRO_C
12466447Ssusans #define	__func__ ""
12476447Ssusans #endif
12486447Ssusans 
12496447Ssusans #if DEBUG
12506447Ssusans #define	con_log(level, fmt) { if (debug_level_g >= level) cmn_err fmt; }
12516447Ssusans #else
12526447Ssusans #define	con_log(level, fmt)
12536447Ssusans #endif /* DEBUG */
12546447Ssusans 
12556447Ssusans /* byte-ordering macros */
12566447Ssusans #ifdef __sparc
12576447Ssusans #define	host_to_le16(s) ((s) & 0xFF) << 8 | ((s) & 0xFF00) >> 8
12586447Ssusans #else
12596447Ssusans #define	host_to_le16(s) (s)
12606447Ssusans #endif
12616447Ssusans 
12626447Ssusans #ifdef __sparc
12636447Ssusans #define	host_to_le32(l) (((l) & 0xFF) << 24 | ((l) & 0xFF00) << 8 | \
12646447Ssusans 		((l) & 0xFF0000) >> 8 | ((l) & 0xFF000000) >> 24)
12656447Ssusans #else
12666447Ssusans #define	host_to_le32(l) (l)
12676447Ssusans #endif
12686447Ssusans 
12696447Ssusans #ifdef __sparc
12706447Ssusans #define	host_to_le64(ull) ((host_to_le32(((ull) & 0xFFFFFFFF)) << 32) | \
12716447Ssusans 		(host_to_le32((((ull) & 0xFFFFFFFF00000000) >> 32))))
12726447Ssusans #else
12736447Ssusans #define	host_to_le64(ull) (ull)
12746447Ssusans #endif
12756447Ssusans 
12766447Ssusans /*
12776447Ssusans  * ### SCSA definitions ###
12786447Ssusans  */
12796447Ssusans #define	PKT2TGT(pkt)	((pkt)->pkt_address.a_target)
12806447Ssusans #define	PKT2LUN(pkt)	((pkt)->pkt_address.a_lun)
12816447Ssusans #define	PKT2TRAN(pkt)	((pkt)->pkt_adress.a_hba_tran)
12826447Ssusans #define	ADDR2TRAN(ap)	((ap)->a_hba_tran)
12836447Ssusans 
12846447Ssusans #define	TRAN2MEGA(tran)	(struct megasas_instance *)(tran)->tran_hba_private)
12856447Ssusans #define	ADDR2MEGA(ap)	(TRAN2MEGA(ADDR2TRAN(ap))
12866447Ssusans 
12876447Ssusans #define	PKT2CMD(pkt)	((struct scsa_cmd *)(pkt)->pkt_ha_private)
12886447Ssusans #define	CMD2PKT(sp)	((sp)->cmd_pkt)
12896447Ssusans #define	PKT2REQ(pkt)	(&(PKT2CMD(pkt)->request))
12906447Ssusans 
12916447Ssusans #define	CMD2ADDR(cmd)	(&CMD2PKT(cmd)->pkt_address)
12926447Ssusans #define	CMD2TRAN(cmd)	(CMD2PKT(cmd)->pkt_address.a_hba_tran)
12936447Ssusans #define	CMD2MEGA(cmd)	(TRAN2MEGA(CMD2TRAN(cmd)))
12946447Ssusans 
12956447Ssusans #define	CFLAG_DMAVALID		0x0001	/* requires a dma operation */
12966447Ssusans #define	CFLAG_DMASEND		0x0002	/* Transfer from the device */
12976447Ssusans #define	CFLAG_CONSISTENT	0x0040	/* consistent data transfer */
12986447Ssusans 
12996447Ssusans /*
13006447Ssusans  * ### Data structures for ioctl inteface and internal commands ###
13016447Ssusans  */
13026447Ssusans 
13036447Ssusans /*
13046447Ssusans  * Data direction flags
13056447Ssusans  */
13066447Ssusans #define	UIOC_RD		0x00001
13076447Ssusans #define	UIOC_WR		0x00002
13086447Ssusans 
13096447Ssusans #define	SCP2HOST(scp)		(scp)->device->host	/* to host */
13106447Ssusans #define	SCP2HOSTDATA(scp)	SCP2HOST(scp)->hostdata	/* to soft state */
13116447Ssusans #define	SCP2CHANNEL(scp)	(scp)->device->channel	/* to channel */
13126447Ssusans #define	SCP2TARGET(scp)		(scp)->device->id	/* to target */
13136447Ssusans #define	SCP2LUN(scp)		(scp)->device->lun	/* to LUN */
13146447Ssusans 
13156447Ssusans #define	SCSIHOST2ADAP(host)	(((caddr_t *)(host->hostdata))[0])
13166447Ssusans #define	SCP2ADAPTER(scp)				\
13176447Ssusans 	(struct megasas_instance *)SCSIHOST2ADAP(SCP2HOST(scp))
13186447Ssusans 
13196447Ssusans #define	MEGADRV_IS_LOGICAL_SCSA(instance, acmd)		\
13206447Ssusans 	(acmd->device_id < MEGADRV_MAX_LD) ? 1 : 0
13216447Ssusans #define	MEGADRV_IS_LOGICAL(ap)				\
13226447Ssusans 	(ap->a_target < MEGADRV_MAX_LD) ? 1 : 0
13236447Ssusans #define	MAP_DEVICE_ID(instance, ap)			\
13246447Ssusans 	(ap->a_target % MEGADRV_MAX_LD)
13256447Ssusans /*
13266447Ssusans  * #define MAP_DEVICE_ID(instance,ap)			\
13276447Ssusans  *       (ap->a_target)
13286447Ssusans  */
13296447Ssusans 
13306447Ssusans #define	HIGH_LEVEL_INTR			1
13316447Ssusans #define	NORMAL_LEVEL_INTR		0
13326447Ssusans 
13336447Ssusans /*
13346447Ssusans  * scsa_cmd  - Per-command mega private data
13356447Ssusans  * @param cmd_dmahandle		:  dma handle
13366447Ssusans  * @param cmd_dmacookies	: current dma cookies
13376447Ssusans  * @param cmd_pkt		:  scsi_pkt reference
13386447Ssusans  * @param cmd_dmacount		:  dma count
13396447Ssusans  * @param cmd_cookie		:  next cookie
13406447Ssusans  * @param cmd_ncookies		:  cookies per window
13416447Ssusans  * @param cmd_cookiecnt		:  cookies per sub-win
13426447Ssusans  * @param cmd_nwin		:  number of dma windows
13436447Ssusans  * @param cmd_curwin		:  current dma window
13446447Ssusans  * @param cmd_dma_offset	:  current window offset
13456447Ssusans  * @param cmd_dma_len		:  current window length
13466447Ssusans  * @param cmd_flags		:  private flags
13476447Ssusans  * @param cmd_cdblen		:  length of cdb
13486447Ssusans  * @param cmd_scblen		:  length of scb
13496447Ssusans  * @param cmd_buf		:  command buffer
13506447Ssusans  * @param channel		:  channel for scsi sub-system
13516447Ssusans  * @param target		:  target for scsi sub-system
13526447Ssusans  * @param lun			:  LUN for scsi sub-system
13536447Ssusans  *
13546447Ssusans  * - Allocated at same time as scsi_pkt by scsi_hba_pkt_alloc(9E)
13556447Ssusans  * - Pointed to by pkt_ha_private field in scsi_pkt
13566447Ssusans  */
13576447Ssusans struct scsa_cmd {
13586447Ssusans 	ddi_dma_handle_t	cmd_dmahandle;
13596447Ssusans 	ddi_dma_cookie_t	cmd_dmacookies[MEGASAS_MAX_SGE_CNT];
13606447Ssusans 	struct scsi_pkt		*cmd_pkt;
13616447Ssusans 	ulong_t			cmd_dmacount;
13626447Ssusans 	uint_t			cmd_cookie;
13636447Ssusans 	uint_t			cmd_ncookies;
13646447Ssusans 	uint_t			cmd_cookiecnt;
13656447Ssusans 	uint_t			cmd_nwin;
13666447Ssusans 	uint_t			cmd_curwin;
13676447Ssusans 	off_t			cmd_dma_offset;
13686447Ssusans 	ulong_t			cmd_dma_len;
13696447Ssusans 	ulong_t			cmd_flags;
13706447Ssusans 	uint_t			cmd_cdblen;
13716447Ssusans 	uint_t			cmd_scblen;
13726447Ssusans 	struct buf		*cmd_buf;
13736447Ssusans 	ushort_t		device_id;
13746447Ssusans 	uchar_t			islogical;
13756447Ssusans 	uchar_t			lun;
13766447Ssusans };
13776447Ssusans 
13786447Ssusans 
13796447Ssusans struct megasas_cmd {
13806447Ssusans 	union megasas_frame	*frame;
13816447Ssusans 	uint32_t		frame_phys_addr;
13826447Ssusans 	uint8_t			*sense;
13836447Ssusans 	uint32_t		sense_phys_addr;
13846447Ssusans 	dma_obj_t		frame_dma_obj;
13856447Ssusans 	uint8_t			frame_dma_obj_status;
13866447Ssusans 
13876447Ssusans 	uint32_t		index;
13886447Ssusans 	uint8_t			sync_cmd;
13896447Ssusans 	uint8_t			cmd_status;
13906447Ssusans 	uint16_t		abort_aen;
13916447Ssusans 	mlist_t			list;
13926447Ssusans 	uint32_t		frame_count;
13936447Ssusans 	struct scsa_cmd		*cmd;
13946447Ssusans 	struct scsi_pkt		*pkt;
13956447Ssusans };
13966447Ssusans 
13976447Ssusans #define	MAX_MGMT_ADAPTERS			1024
13986447Ssusans #define	IOC_SIGNATURE				"MEGA-SAS"
13996447Ssusans 
14006447Ssusans #define	IOC_CMD_FIRMWARE			0x0
14016447Ssusans #define	MR_DRIVER_IOCTL_COMMON			0xF0010000
14026447Ssusans #define	MR_DRIVER_IOCTL_DRIVER_VERSION		0xF0010100
14036447Ssusans #define	MR_DRIVER_IOCTL_PCI_INFORMATION		0xF0010200
14046447Ssusans #define	MR_DRIVER_IOCTL_MEGARAID_STATISTICS	0xF0010300
14056447Ssusans 
14066447Ssusans 
14076447Ssusans #define	MR_MAX_SENSE_LENGTH			32
14086447Ssusans 
14096447Ssusans struct megasas_mgmt_info {
14106447Ssusans 
14116447Ssusans 	uint16_t			count;
14126447Ssusans 	struct megasas_instance		*instance[MAX_MGMT_ADAPTERS];
14136447Ssusans 	uint16_t			map[MAX_MGMT_ADAPTERS];
14146447Ssusans 	int				max_index;
14156447Ssusans };
14166447Ssusans 
14176447Ssusans #pragma pack(1)
14186447Ssusans 
14196447Ssusans struct megasas_drv_ver {
14206447Ssusans 	uint8_t	signature[12];
14216447Ssusans 	uint8_t	os_name[16];
14226447Ssusans 	uint8_t	os_ver[12];
14236447Ssusans 	uint8_t	drv_name[20];
14246447Ssusans 	uint8_t	drv_ver[32];
14256447Ssusans 	uint8_t	drv_rel_date[20];
14266447Ssusans };
14276447Ssusans 
14286447Ssusans #define	PCI_TYPE0_ADDRESSES		6
14296447Ssusans #define	PCI_TYPE1_ADDRESSES		2
14306447Ssusans #define	PCI_TYPE2_ADDRESSES		5
14316447Ssusans 
14326447Ssusans struct megasas_pci_common_header {
14336447Ssusans 	uint16_t	vendorID;		/* (ro) */
14346447Ssusans 	uint16_t	deviceID;		/* (ro) */
14356447Ssusans 	uint16_t	command;		/* Device control */
14366447Ssusans 	uint16_t	status;
14376447Ssusans 	uint8_t		revisionID;		/* (ro) */
14386447Ssusans 	uint8_t		progIf;			/* (ro) */
14396447Ssusans 	uint8_t		subClass;		/* (ro) */
14406447Ssusans 	uint8_t		baseClass;		/* (ro) */
14416447Ssusans 	uint8_t		cacheLineSize;		/* (ro+) */
14426447Ssusans 	uint8_t		latencyTimer;		/* (ro+) */
14436447Ssusans 	uint8_t		headerType;		/* (ro) */
14446447Ssusans 	uint8_t		bist;			/* Built in self test */
14456447Ssusans 
14466447Ssusans 	union {
14476447Ssusans 	    struct {
14486447Ssusans 		uint32_t	baseAddresses[PCI_TYPE0_ADDRESSES];
14496447Ssusans 		uint32_t	cis;
14506447Ssusans 		uint16_t	subVendorID;
14516447Ssusans 		uint16_t	subSystemID;
14526447Ssusans 		uint32_t	romBaseAddress;
14536447Ssusans 		uint8_t		capabilitiesPtr;
14546447Ssusans 		uint8_t		reserved1[3];
14556447Ssusans 		uint32_t	reserved2;
14566447Ssusans 		uint8_t		interruptLine;
14576447Ssusans 		uint8_t		interruptPin;	/* (ro) */
14586447Ssusans 		uint8_t		minimumGrant;	/* (ro) */
14596447Ssusans 		uint8_t		maximumLatency;	/* (ro) */
14606447Ssusans 	    } type_0;
14616447Ssusans 
14626447Ssusans 	    struct {
14636447Ssusans 		uint32_t	baseAddresses[PCI_TYPE1_ADDRESSES];
14646447Ssusans 		uint8_t		primaryBus;
14656447Ssusans 		uint8_t		secondaryBus;
14666447Ssusans 		uint8_t		subordinateBus;
14676447Ssusans 		uint8_t		secondaryLatency;
14686447Ssusans 		uint8_t		ioBase;
14696447Ssusans 		uint8_t		ioLimit;
14706447Ssusans 		uint16_t	secondaryStatus;
14716447Ssusans 		uint16_t	memoryBase;
14726447Ssusans 		uint16_t	memoryLimit;
14736447Ssusans 		uint16_t	prefetchBase;
14746447Ssusans 		uint16_t	prefetchLimit;
14756447Ssusans 		uint32_t	prefetchBaseUpper32;
14766447Ssusans 		uint32_t	prefetchLimitUpper32;
14776447Ssusans 		uint16_t	ioBaseUpper16;
14786447Ssusans 		uint16_t	ioLimitUpper16;
14796447Ssusans 		uint8_t		capabilitiesPtr;
14806447Ssusans 		uint8_t		reserved1[3];
14816447Ssusans 		uint32_t	romBaseAddress;
14826447Ssusans 		uint8_t		interruptLine;
14836447Ssusans 		uint8_t		interruptPin;
14846447Ssusans 		uint16_t	bridgeControl;
14856447Ssusans 	    } type_1;
14866447Ssusans 
14876447Ssusans 	    struct {
14886447Ssusans 		uint32_t	socketRegistersBaseAddress;
14896447Ssusans 		uint8_t		capabilitiesPtr;
14906447Ssusans 		uint8_t		reserved;
14916447Ssusans 		uint16_t	secondaryStatus;
14926447Ssusans 		uint8_t		primaryBus;
14936447Ssusans 		uint8_t		secondaryBus;
14946447Ssusans 		uint8_t		subordinateBus;
14956447Ssusans 		uint8_t		secondaryLatency;
14966447Ssusans 		struct {
14976447Ssusans 			uint32_t	base;
14986447Ssusans 			uint32_t	limit;
14996447Ssusans 		} range[PCI_TYPE2_ADDRESSES-1];
15006447Ssusans 		uint8_t		interruptLine;
15016447Ssusans 		uint8_t		interruptPin;
15026447Ssusans 		uint16_t	bridgeControl;
15036447Ssusans 	    } type_2;
15046447Ssusans 	} header;
15056447Ssusans };
15066447Ssusans 
15076447Ssusans struct megasas_pci_link_capability {
15086447Ssusans 	union {
15096447Ssusans 	    struct {
15106447Ssusans 		uint32_t linkSpeed		:4;
15116447Ssusans 		uint32_t linkWidth		:6;
15126447Ssusans 		uint32_t aspmSupport		:2;
15136447Ssusans 		uint32_t losExitLatency		:3;
15146447Ssusans 		uint32_t l1ExitLatency		:3;
15156447Ssusans 		uint32_t rsvdp			:6;
15166447Ssusans 		uint32_t portNumber		:8;
15176447Ssusans 	    } bits;
15186447Ssusans 
15196447Ssusans 	    uint32_t asUlong;
15206447Ssusans 	} cap;
15216447Ssusans 
15226447Ssusans };
15236447Ssusans 
15246447Ssusans struct megasas_pci_link_status_capability {
15256447Ssusans 	union {
15266447Ssusans 	    struct {
15276447Ssusans 		uint16_t linkSpeed		:4;
15286447Ssusans 		uint16_t negotiatedLinkWidth	:6;
15296447Ssusans 		uint16_t linkTrainingError	:1;
15306447Ssusans 		uint16_t linkTraning		:1;
15316447Ssusans 		uint16_t slotClockConfig	:1;
15326447Ssusans 		uint16_t rsvdZ			:3;
15336447Ssusans 	    } bits;
15346447Ssusans 
15356447Ssusans 	    uint16_t asUshort;
15366447Ssusans 	} stat_cap;
15376447Ssusans 
15386447Ssusans 	uint16_t reserved;
15396447Ssusans 
15406447Ssusans };
15416447Ssusans 
15426447Ssusans struct megasas_pci_capabilities {
15436447Ssusans 	struct megasas_pci_link_capability	linkCapability;
15446447Ssusans 	struct megasas_pci_link_status_capability linkStatusCapability;
15456447Ssusans };
15466447Ssusans 
15476447Ssusans struct megasas_pci_information
15486447Ssusans {
15496447Ssusans 	uint32_t		busNumber;
15506447Ssusans 	uint8_t			deviceNumber;
15516447Ssusans 	uint8_t			functionNumber;
15526447Ssusans 	uint8_t			interruptVector;
15536447Ssusans 	uint8_t			reserved;
15546447Ssusans 	struct megasas_pci_common_header pciHeaderInfo;
15556447Ssusans 	struct megasas_pci_capabilities capability;
15566447Ssusans 	uint8_t			reserved2[32];
15576447Ssusans };
15586447Ssusans 
15596447Ssusans struct megasas_ioctl {
15606447Ssusans 	uint16_t	version;
15616447Ssusans 	uint16_t	controller_id;
15626447Ssusans 	uint8_t		signature[8];
15636447Ssusans 	uint32_t	reserved_1;
15646447Ssusans 	uint32_t	control_code;
15656447Ssusans 	uint32_t	reserved_2[2];
15666447Ssusans 	uint8_t		frame[64];
15676447Ssusans 	union megasas_sgl_frame	sgl_frame;
15686447Ssusans 	uint8_t		sense_buff[MR_MAX_SENSE_LENGTH];
15696447Ssusans 	uint8_t		data[1];
15706447Ssusans };
15716447Ssusans 
15726447Ssusans struct megasas_aen {
15736447Ssusans 	uint16_t	host_no;
15746447Ssusans 	uint16_t	cmd_status;
15756447Ssusans 	uint32_t	seq_num;
15766447Ssusans 	uint32_t	class_locale_word;
15776447Ssusans };
15786447Ssusans 
15796447Ssusans #pragma pack()
15806447Ssusans 
15816447Ssusans #ifndef	DDI_VENDOR_LSI
15826447Ssusans #define	DDI_VENDOR_LSI		"LSI"
15836447Ssusans #endif /* DDI_VENDOR_LSI */
15846447Ssusans 
15856447Ssusans static int	megasas_getinfo(dev_info_t *, ddi_info_cmd_t,  void *, void **);
15866447Ssusans static int	megasas_attach(dev_info_t *, ddi_attach_cmd_t);
15876447Ssusans static int	megasas_reset(dev_info_t *, ddi_reset_cmd_t);
15886447Ssusans static int	megasas_detach(dev_info_t *, ddi_detach_cmd_t);
15896447Ssusans static int	megasas_open(dev_t *, int, int, cred_t *);
15906447Ssusans static int	megasas_close(dev_t, int, int, cred_t *);
15916447Ssusans static int	megasas_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
15926447Ssusans 
15936447Ssusans static int	megasas_tran_tgt_init(dev_info_t *, dev_info_t *,
15946447Ssusans 		    scsi_hba_tran_t *, struct scsi_device *);
15956447Ssusans static struct scsi_pkt *megasas_tran_init_pkt(struct scsi_address *, register
15966447Ssusans 		    struct scsi_pkt *, struct buf *, int, int, int, int,
15976447Ssusans 		    int (*)(), caddr_t);
15986447Ssusans static int	megasas_tran_start(struct scsi_address *,
15996447Ssusans 		    register struct scsi_pkt *);
16006447Ssusans static int	megasas_tran_abort(struct scsi_address *, struct scsi_pkt *);
16016447Ssusans static int	megasas_tran_reset(struct scsi_address *, int);
16026447Ssusans static int	megasas_tran_bus_reset(dev_info_t *, int);
16036447Ssusans static int	megasas_tran_getcap(struct scsi_address *, char *, int);
16046447Ssusans static int	megasas_tran_setcap(struct scsi_address *, char *, int, int);
16056447Ssusans static void	megasas_tran_destroy_pkt(struct scsi_address *,
16066447Ssusans 		    struct scsi_pkt *);
16076447Ssusans static void	megasas_tran_dmafree(struct scsi_address *, struct scsi_pkt *);
16086447Ssusans static void	megasas_tran_sync_pkt(struct scsi_address *, struct scsi_pkt *);
16096447Ssusans static int	megasas_tran_quiesce(dev_info_t *dip);
16106447Ssusans static int	megasas_tran_unquiesce(dev_info_t *dip);
16117562SSusan.Scheufele@Sun.COM static uint_t	megasas_isr();
16127562SSusan.Scheufele@Sun.COM static uint_t	megasas_softintr();
16136447Ssusans 
16146447Ssusans static int	init_mfi(struct megasas_instance *);
16157533SYu.Wu@Sun.COM static int	mega_free_dma_obj(struct megasas_instance *, dma_obj_t);
16166447Ssusans static int	mega_alloc_dma_obj(struct megasas_instance *, dma_obj_t *);
16176447Ssusans static struct megasas_cmd *get_mfi_pkt(struct megasas_instance *);
16186447Ssusans static void	return_mfi_pkt(struct megasas_instance *,
16196447Ssusans 		    struct megasas_cmd *);
16207562SSusan.Scheufele@Sun.COM 
16216447Ssusans static void	free_space_for_mfi(struct megasas_instance *);
16226447Ssusans static void	free_additional_dma_buffer(struct megasas_instance *);
16236447Ssusans static int	alloc_additional_dma_buffer(struct megasas_instance *);
16246447Ssusans static int	read_fw_status_reg_xscale(struct megasas_instance *);
16256447Ssusans static int	read_fw_status_reg_ppc(struct megasas_instance *);
16266447Ssusans static void	issue_cmd_xscale(struct megasas_cmd *,
16276447Ssusans 		    struct megasas_instance *);
16286447Ssusans static void	issue_cmd_ppc(struct megasas_cmd *, struct megasas_instance *);
16296447Ssusans static int	issue_cmd_in_poll_mode_xscale(struct megasas_instance *,
16306447Ssusans 		    struct megasas_cmd *);
16316447Ssusans static int	issue_cmd_in_poll_mode_ppc(struct megasas_instance *,
16326447Ssusans 		    struct megasas_cmd *);
16336447Ssusans static int	issue_cmd_in_sync_mode_xscale(struct megasas_instance *,
16346447Ssusans 		    struct megasas_cmd *);
16356447Ssusans static int	issue_cmd_in_sync_mode_ppc(struct megasas_instance *,
16366447Ssusans 		    struct megasas_cmd *);
16376447Ssusans static void	enable_intr_xscale(struct megasas_instance *);
16386447Ssusans static void	enable_intr_ppc(struct megasas_instance *);
16396447Ssusans static void	disable_intr_xscale(struct megasas_instance *);
16406447Ssusans static void	disable_intr_ppc(struct megasas_instance *);
16416447Ssusans static int	intr_ack_xscale(struct megasas_instance *);
16426447Ssusans static int	intr_ack_ppc(struct megasas_instance *);
16436447Ssusans static int	mfi_state_transition_to_ready(struct megasas_instance *);
16446447Ssusans static void	destroy_mfi_frame_pool(struct megasas_instance *);
16456447Ssusans static int	create_mfi_frame_pool(struct megasas_instance *);
16466447Ssusans static int	megasas_dma_alloc(struct megasas_instance *, struct scsi_pkt *,
16476447Ssusans 		    struct buf *, int, int (*)());
16486447Ssusans static int	megasas_dma_move(struct megasas_instance *,
16496447Ssusans 			struct scsi_pkt *, struct buf *);
16506447Ssusans static void	flush_cache(struct megasas_instance *instance);
16516447Ssusans static void	display_scsi_inquiry(caddr_t);
16526447Ssusans static int	start_mfi_aen(struct megasas_instance *instance);
16536447Ssusans static int	handle_drv_ioctl(struct megasas_instance *instance,
16546447Ssusans 		    struct megasas_ioctl *ioctl, int mode);
16556447Ssusans static int	handle_mfi_ioctl(struct megasas_instance *instance,
16566447Ssusans 		    struct megasas_ioctl *ioctl, int mode);
16576447Ssusans static int	handle_mfi_aen(struct megasas_instance *instance,
16586447Ssusans 		    struct megasas_aen *aen);
16596447Ssusans static void	fill_up_drv_ver(struct megasas_drv_ver *dv);
16606447Ssusans static struct megasas_cmd *build_cmd(struct megasas_instance *instance,
16616447Ssusans 		    struct scsi_address *ap, struct scsi_pkt *pkt,
16626447Ssusans 		    uchar_t *cmd_done);
16636447Ssusans static int	wait_for_outstanding(struct megasas_instance *instance);
16646447Ssusans static int	register_mfi_aen(struct megasas_instance *instance,
16656447Ssusans 		    uint32_t seq_num, uint32_t class_locale_word);
16666447Ssusans static int	issue_mfi_pthru(struct megasas_instance *instance, struct
16676447Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16686447Ssusans static int	issue_mfi_dcmd(struct megasas_instance *instance, struct
16696447Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16706447Ssusans static int	issue_mfi_smp(struct megasas_instance *instance, struct
16716447Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16726447Ssusans static int	issue_mfi_stp(struct megasas_instance *instance, struct
16736447Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16746447Ssusans static int	abort_aen_cmd(struct megasas_instance *instance,
16756447Ssusans 		    struct megasas_cmd *cmd_to_abort);
16766447Ssusans 
16777533SYu.Wu@Sun.COM static int	megasas_common_check(struct megasas_instance *instance,
16787533SYu.Wu@Sun.COM 		    struct  megasas_cmd *cmd);
16797533SYu.Wu@Sun.COM static void	megasas_fm_init(struct megasas_instance *instance);
16807533SYu.Wu@Sun.COM static void	megasas_fm_fini(struct megasas_instance *instance);
16817533SYu.Wu@Sun.COM static int	megasas_fm_error_cb(dev_info_t *, ddi_fm_error_t *,
16827533SYu.Wu@Sun.COM 		    const void *);
16837533SYu.Wu@Sun.COM static void	megasas_fm_ereport(struct megasas_instance *instance,
16847533SYu.Wu@Sun.COM 		    char *detail);
16857533SYu.Wu@Sun.COM static int	megasas_check_dma_handle(ddi_dma_handle_t handle);
16867533SYu.Wu@Sun.COM static int	megasas_check_acc_handle(ddi_acc_handle_t handle);
16877533SYu.Wu@Sun.COM 
16886447Ssusans #ifdef	__cplusplus
16896447Ssusans }
16906447Ssusans #endif
16916447Ssusans 
16926447Ssusans #endif /* _MEGARAID_SAS_H_ */
1693