16029a2d8Ssusans /*
26029a2d8Ssusans  * megaraid_sas.h: header for mega_sas
36029a2d8Ssusans  *
46029a2d8Ssusans  * Solaris MegaRAID driver for SAS controllers
56029a2d8Ssusans  * Copyright (c) 2004-2008, LSI Logic Corporation.
66029a2d8Ssusans  * All rights reserved.
76029a2d8Ssusans  *
86029a2d8Ssusans  * Redistribution and use in source and binary forms, with or without
96029a2d8Ssusans  * modification, are permitted provided that the following conditions are met:
106029a2d8Ssusans  *
116029a2d8Ssusans  * 1. Redistributions of source code must retain the above copyright notice,
126029a2d8Ssusans  *    this list of conditions and the following disclaimer.
136029a2d8Ssusans  *
146029a2d8Ssusans  * 2. Redistributions in binary form must reproduce the above copyright notice,
156029a2d8Ssusans  *    this list of conditions and the following disclaimer in the documentation
166029a2d8Ssusans  *    and/or other materials provided with the distribution.
176029a2d8Ssusans  *
186029a2d8Ssusans  * 3. Neither the name of the author nor the names of its contributors may be
196029a2d8Ssusans  *    used to endorse or promote products derived from this software without
206029a2d8Ssusans  *    specific prior written permission.
216029a2d8Ssusans  *
226029a2d8Ssusans  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
236029a2d8Ssusans  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
246029a2d8Ssusans  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
256029a2d8Ssusans  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
266029a2d8Ssusans  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
276029a2d8Ssusans  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
286029a2d8Ssusans  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
296029a2d8Ssusans  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
306029a2d8Ssusans  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
316029a2d8Ssusans  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
326029a2d8Ssusans  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
336029a2d8Ssusans  * DAMAGE.
346029a2d8Ssusans  */
356029a2d8Ssusans 
366029a2d8Ssusans /*
376029a2d8Ssusans  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
386029a2d8Ssusans  * Use is subject to license terms.
396029a2d8Ssusans  */
406029a2d8Ssusans 
416029a2d8Ssusans #ifndef	_MEGARAID_SAS_H_
426029a2d8Ssusans #define	_MEGARAID_SAS_H_
436029a2d8Ssusans 
446029a2d8Ssusans #ifdef	__cplusplus
456029a2d8Ssusans extern "C" {
466029a2d8Ssusans #endif
476029a2d8Ssusans 
486029a2d8Ssusans #include <sys/scsi/scsi.h>
496029a2d8Ssusans #include "list.h"
506029a2d8Ssusans 
516029a2d8Ssusans /*
526029a2d8Ssusans  * MegaRAID SAS Driver meta data
536029a2d8Ssusans  */
54*14cd9973SSusan Scheufele #define	MEGASAS_VERSION				"LSIv1.28"
55*14cd9973SSusan Scheufele #define	MEGASAS_RELDATE				"Dec 4, 2008"
566029a2d8Ssusans 
576029a2d8Ssusans #define	MEGASAS_TRUE				1
586029a2d8Ssusans #define	MEGASAS_FALSE				0
596029a2d8Ssusans 
606029a2d8Ssusans /*
616029a2d8Ssusans  * MegaRAID device id conversion definitions.
626029a2d8Ssusans  */
636029a2d8Ssusans #define	INST2LSIRDCTL(x)		((x) << INST_MINOR_SHIFT)
646029a2d8Ssusans 
656029a2d8Ssusans /*
666029a2d8Ssusans  * MegaRAID SAS supported controllers
676029a2d8Ssusans  */
686029a2d8Ssusans #define	PCI_DEVICE_ID_LSI_1064			0x0411
696029a2d8Ssusans #define	PCI_DEVICE_ID_LSI_1078			0x0060
70ea20eddaSsusans #define	PCI_DEVICE_ID_LSI_1078DE		0x007C
716029a2d8Ssusans 
726029a2d8Ssusans #define	PCI_DEVICE_ID_DELL_PERC5		0x0015
736029a2d8Ssusans #define	PCI_DEVICE_ID_DELL_SAS5			0x0054
746029a2d8Ssusans 
756029a2d8Ssusans #define	PCI_SUBSYSTEM_DELL_PERC5E		0x1F01
766029a2d8Ssusans #define	PCI_SUBSYSTEM_DELL_PERC5I		0x1F02
776029a2d8Ssusans #define	PCI_SUBSYSTEM_DELL_PERC5I_INTEGRATED	0x1F03
786029a2d8Ssusans #define	PCI_SUBSYSTEM_DELL_SAS5I		0x1F05
796029a2d8Ssusans #define	PCI_SUBSYSTEM_DELL_SAS5I_INTEGRATED	0x1F06
806029a2d8Ssusans 
816029a2d8Ssusans #define	PCI_SUB_DEVICEID_FSC			0x1081
826029a2d8Ssusans #define	PCI_SUB_VENDORID_FSC			0x1734
836029a2d8Ssusans 
846029a2d8Ssusans #define	REGISTER_SET_IO				(1)
856029a2d8Ssusans 
866029a2d8Ssusans #define	MEGASAS_MAX_SGE_CNT			0x50
876029a2d8Ssusans 
886029a2d8Ssusans #define	MEGASAS_IOCTL_DRIVER			0x12341234
896029a2d8Ssusans #define	MEGASAS_IOCTL_FIRMWARE			0x12345678
906029a2d8Ssusans #define	MEGASAS_IOCTL_AEN			0x87654321
916029a2d8Ssusans 
926029a2d8Ssusans #define	MEGASAS_1_SECOND			1000000
936029a2d8Ssusans /*
946029a2d8Ssusans  * =====================================
956029a2d8Ssusans  * MegaRAID SAS MFI firmware definitions
966029a2d8Ssusans  * =====================================
976029a2d8Ssusans  */
986029a2d8Ssusans /*
996029a2d8Ssusans  * MFI stands for  MegaRAID SAS FW Interface. This is just a moniker for
1006029a2d8Ssusans  * protocol between the software and firmware. Commands are issued using
1016029a2d8Ssusans  * "message frames"
1026029a2d8Ssusans  */
1036029a2d8Ssusans 
1046029a2d8Ssusans /*
1056029a2d8Ssusans  * FW posts its state in upper 4 bits of outbound_msg_0 register
1066029a2d8Ssusans  */
1076029a2d8Ssusans #define	MFI_STATE_MASK				0xF0000000
1086029a2d8Ssusans #define	MFI_STATE_UNDEFINED			0x00000000
1096029a2d8Ssusans #define	MFI_STATE_BB_INIT			0x10000000
1106029a2d8Ssusans #define	MFI_STATE_FW_INIT			0x40000000
1116029a2d8Ssusans #define	MFI_STATE_WAIT_HANDSHAKE		0x60000000
1126029a2d8Ssusans #define	MFI_STATE_FW_INIT_2			0x70000000
1136029a2d8Ssusans #define	MFI_STATE_DEVICE_SCAN			0x80000000
1146029a2d8Ssusans #define	MFI_STATE_BOOT_MESSAGE_PENDING		0x90000000
1156029a2d8Ssusans #define	MFI_STATE_FLUSH_CACHE			0xA0000000
1166029a2d8Ssusans #define	MFI_STATE_READY				0xB0000000
1176029a2d8Ssusans #define	MFI_STATE_OPERATIONAL			0xC0000000
1186029a2d8Ssusans #define	MFI_STATE_FAULT				0xF0000000
1196029a2d8Ssusans 
1206029a2d8Ssusans #define	MEGAMFI_FRAME_SIZE			64
1216029a2d8Ssusans 
1226029a2d8Ssusans /*
1236029a2d8Ssusans  * During FW init, clear pending cmds & reset state using inbound_msg_0
1246029a2d8Ssusans  *
1256029a2d8Ssusans  * ABORT	: Abort all pending cmds
1266029a2d8Ssusans  * READY	: Move from OPERATIONAL to READY state; discard queue info
1276029a2d8Ssusans  * MFIMODE	: Discard (possible) low MFA posted in 64-bit mode (??)
1286029a2d8Ssusans  * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver
1296029a2d8Ssusans  */
1306029a2d8Ssusans #define	MFI_INIT_ABORT				0x00000001
1316029a2d8Ssusans #define	MFI_INIT_READY				0x00000002
1326029a2d8Ssusans #define	MFI_INIT_MFIMODE			0x00000004
1336029a2d8Ssusans #define	MFI_INIT_CLEAR_HANDSHAKE		0x00000008
1346029a2d8Ssusans #define	MFI_INIT_HOTPLUG			0x00000010
1356029a2d8Ssusans #define	MFI_STOP_ADP				0x00000020
1366029a2d8Ssusans #define	MFI_RESET_FLAGS		MFI_INIT_READY|MFI_INIT_MFIMODE|MFI_INIT_ABORT
1376029a2d8Ssusans 
1386029a2d8Ssusans /*
1396029a2d8Ssusans  * MFI frame flags
1406029a2d8Ssusans  */
1416029a2d8Ssusans #define	MFI_FRAME_POST_IN_REPLY_QUEUE		0x0000
1426029a2d8Ssusans #define	MFI_FRAME_DONT_POST_IN_REPLY_QUEUE	0x0001
1436029a2d8Ssusans #define	MFI_FRAME_SGL32				0x0000
1446029a2d8Ssusans #define	MFI_FRAME_SGL64				0x0002
1456029a2d8Ssusans #define	MFI_FRAME_SENSE32			0x0000
1466029a2d8Ssusans #define	MFI_FRAME_SENSE64			0x0004
1476029a2d8Ssusans #define	MFI_FRAME_DIR_NONE			0x0000
1486029a2d8Ssusans #define	MFI_FRAME_DIR_WRITE			0x0008
1496029a2d8Ssusans #define	MFI_FRAME_DIR_READ			0x0010
1506029a2d8Ssusans #define	MFI_FRAME_DIR_BOTH			0x0018
1516029a2d8Ssusans 
1526029a2d8Ssusans /*
1536029a2d8Ssusans  * Definition for cmd_status
1546029a2d8Ssusans  */
1556029a2d8Ssusans #define	MFI_CMD_STATUS_POLL_MODE		0xFF
1567ddfa2acSSusan Scheufele #define	MFI_CMD_STATUS_SYNC_MODE		0xFF
1576029a2d8Ssusans 
1586029a2d8Ssusans /*
1596029a2d8Ssusans  * MFI command opcodes
1606029a2d8Ssusans  */
1616029a2d8Ssusans #define	MFI_CMD_OP_INIT				0x00
1626029a2d8Ssusans #define	MFI_CMD_OP_LD_READ			0x01
1636029a2d8Ssusans #define	MFI_CMD_OP_LD_WRITE			0x02
1646029a2d8Ssusans #define	MFI_CMD_OP_LD_SCSI			0x03
1656029a2d8Ssusans #define	MFI_CMD_OP_PD_SCSI			0x04
1666029a2d8Ssusans #define	MFI_CMD_OP_DCMD				0x05
1676029a2d8Ssusans #define	MFI_CMD_OP_ABORT			0x06
1686029a2d8Ssusans #define	MFI_CMD_OP_SMP				0x07
1696029a2d8Ssusans #define	MFI_CMD_OP_STP				0x08
1706029a2d8Ssusans 
1716029a2d8Ssusans #define	MR_DCMD_CTRL_GET_INFO			0x01010000
1726029a2d8Ssusans 
1736029a2d8Ssusans #define	MR_DCMD_CTRL_CACHE_FLUSH		0x01101000
1746029a2d8Ssusans #define	MR_FLUSH_CTRL_CACHE			0x01
1756029a2d8Ssusans #define	MR_FLUSH_DISK_CACHE			0x02
1766029a2d8Ssusans 
1776029a2d8Ssusans #define	MR_DCMD_CTRL_SHUTDOWN			0x01050000
1786029a2d8Ssusans #define	MR_ENABLE_DRIVE_SPINDOWN		0x01
1796029a2d8Ssusans 
1806029a2d8Ssusans #define	MR_DCMD_CTRL_EVENT_GET_INFO		0x01040100
1816029a2d8Ssusans #define	MR_DCMD_CTRL_EVENT_GET			0x01040300
1826029a2d8Ssusans #define	MR_DCMD_CTRL_EVENT_WAIT			0x01040500
1836029a2d8Ssusans #define	MR_DCMD_LD_GET_PROPERTIES		0x03030000
1846029a2d8Ssusans 
1856029a2d8Ssusans /*
1866029a2d8Ssusans  * Solaris Specific MAX values
1876029a2d8Ssusans  */
1886029a2d8Ssusans #define	MAX_SGL					24
1896029a2d8Ssusans /*
1906029a2d8Ssusans  * MFI command completion codes
1916029a2d8Ssusans  */
1926029a2d8Ssusans enum MFI_STAT {
1936029a2d8Ssusans 	MFI_STAT_OK				= 0x00,
1946029a2d8Ssusans 	MFI_STAT_INVALID_CMD			= 0x01,
1956029a2d8Ssusans 	MFI_STAT_INVALID_DCMD			= 0x02,
1966029a2d8Ssusans 	MFI_STAT_INVALID_PARAMETER		= 0x03,
1976029a2d8Ssusans 	MFI_STAT_INVALID_SEQUENCE_NUMBER	= 0x04,
1986029a2d8Ssusans 	MFI_STAT_ABORT_NOT_POSSIBLE		= 0x05,
1996029a2d8Ssusans 	MFI_STAT_APP_HOST_CODE_NOT_FOUND	= 0x06,
2006029a2d8Ssusans 	MFI_STAT_APP_IN_USE			= 0x07,
2016029a2d8Ssusans 	MFI_STAT_APP_NOT_INITIALIZED		= 0x08,
2026029a2d8Ssusans 	MFI_STAT_ARRAY_INDEX_INVALID		= 0x09,
2036029a2d8Ssusans 	MFI_STAT_ARRAY_ROW_NOT_EMPTY		= 0x0a,
2046029a2d8Ssusans 	MFI_STAT_CONFIG_RESOURCE_CONFLICT	= 0x0b,
2056029a2d8Ssusans 	MFI_STAT_DEVICE_NOT_FOUND		= 0x0c,
2066029a2d8Ssusans 	MFI_STAT_DRIVE_TOO_SMALL		= 0x0d,
2076029a2d8Ssusans 	MFI_STAT_FLASH_ALLOC_FAIL		= 0x0e,
2086029a2d8Ssusans 	MFI_STAT_FLASH_BUSY			= 0x0f,
2096029a2d8Ssusans 	MFI_STAT_FLASH_ERROR			= 0x10,
2106029a2d8Ssusans 	MFI_STAT_FLASH_IMAGE_BAD		= 0x11,
2116029a2d8Ssusans 	MFI_STAT_FLASH_IMAGE_INCOMPLETE		= 0x12,
2126029a2d8Ssusans 	MFI_STAT_FLASH_NOT_OPEN			= 0x13,
2136029a2d8Ssusans 	MFI_STAT_FLASH_NOT_STARTED		= 0x14,
2146029a2d8Ssusans 	MFI_STAT_FLUSH_FAILED			= 0x15,
2156029a2d8Ssusans 	MFI_STAT_HOST_CODE_NOT_FOUNT		= 0x16,
2166029a2d8Ssusans 	MFI_STAT_LD_CC_IN_PROGRESS		= 0x17,
2176029a2d8Ssusans 	MFI_STAT_LD_INIT_IN_PROGRESS		= 0x18,
2186029a2d8Ssusans 	MFI_STAT_LD_LBA_OUT_OF_RANGE		= 0x19,
2196029a2d8Ssusans 	MFI_STAT_LD_MAX_CONFIGURED		= 0x1a,
2206029a2d8Ssusans 	MFI_STAT_LD_NOT_OPTIMAL			= 0x1b,
2216029a2d8Ssusans 	MFI_STAT_LD_RBLD_IN_PROGRESS		= 0x1c,
2226029a2d8Ssusans 	MFI_STAT_LD_RECON_IN_PROGRESS		= 0x1d,
2236029a2d8Ssusans 	MFI_STAT_LD_WRONG_RAID_LEVEL		= 0x1e,
2246029a2d8Ssusans 	MFI_STAT_MAX_SPARES_EXCEEDED		= 0x1f,
2256029a2d8Ssusans 	MFI_STAT_MEMORY_NOT_AVAILABLE		= 0x20,
2266029a2d8Ssusans 	MFI_STAT_MFC_HW_ERROR			= 0x21,
2276029a2d8Ssusans 	MFI_STAT_NO_HW_PRESENT			= 0x22,
2286029a2d8Ssusans 	MFI_STAT_NOT_FOUND			= 0x23,
2296029a2d8Ssusans 	MFI_STAT_NOT_IN_ENCL			= 0x24,
2306029a2d8Ssusans 	MFI_STAT_PD_CLEAR_IN_PROGRESS		= 0x25,
2316029a2d8Ssusans 	MFI_STAT_PD_TYPE_WRONG			= 0x26,
2326029a2d8Ssusans 	MFI_STAT_PR_DISABLED			= 0x27,
2336029a2d8Ssusans 	MFI_STAT_ROW_INDEX_INVALID		= 0x28,
2346029a2d8Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_ACTION	= 0x29,
2356029a2d8Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_DATA	= 0x2a,
2366029a2d8Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_PAGE	= 0x2b,
2376029a2d8Ssusans 	MFI_STAT_SAS_CONFIG_INVALID_TYPE	= 0x2c,
2386029a2d8Ssusans 	MFI_STAT_SCSI_DONE_WITH_ERROR		= 0x2d,
2396029a2d8Ssusans 	MFI_STAT_SCSI_IO_FAILED			= 0x2e,
2406029a2d8Ssusans 	MFI_STAT_SCSI_RESERVATION_CONFLICT	= 0x2f,
2416029a2d8Ssusans 	MFI_STAT_SHUTDOWN_FAILED		= 0x30,
2426029a2d8Ssusans 	MFI_STAT_TIME_NOT_SET			= 0x31,
2436029a2d8Ssusans 	MFI_STAT_WRONG_STATE			= 0x32,
2443ddf1763Syw 	MFI_STAT_LD_OFFLINE			= 0x33,
2456029a2d8Ssusans 	MFI_STAT_INVALID_STATUS			= 0xFF
2466029a2d8Ssusans };
2476029a2d8Ssusans 
2486029a2d8Ssusans enum MR_EVT_CLASS {
2496029a2d8Ssusans 	MR_EVT_CLASS_DEBUG		= -2,
2506029a2d8Ssusans 	MR_EVT_CLASS_PROGRESS		= -1,
2516029a2d8Ssusans 	MR_EVT_CLASS_INFO		=  0,
2526029a2d8Ssusans 	MR_EVT_CLASS_WARNING		=  1,
2536029a2d8Ssusans 	MR_EVT_CLASS_CRITICAL		=  2,
2546029a2d8Ssusans 	MR_EVT_CLASS_FATAL		=  3,
2556029a2d8Ssusans 	MR_EVT_CLASS_DEAD		=  4
2566029a2d8Ssusans };
2576029a2d8Ssusans 
2586029a2d8Ssusans enum MR_EVT_LOCALE {
2596029a2d8Ssusans 	MR_EVT_LOCALE_LD		= 0x0001,
2606029a2d8Ssusans 	MR_EVT_LOCALE_PD		= 0x0002,
2616029a2d8Ssusans 	MR_EVT_LOCALE_ENCL		= 0x0004,
2626029a2d8Ssusans 	MR_EVT_LOCALE_BBU		= 0x0008,
2636029a2d8Ssusans 	MR_EVT_LOCALE_SAS		= 0x0010,
2646029a2d8Ssusans 	MR_EVT_LOCALE_CTRL		= 0x0020,
2656029a2d8Ssusans 	MR_EVT_LOCALE_CONFIG		= 0x0040,
2666029a2d8Ssusans 	MR_EVT_LOCALE_CLUSTER		= 0x0080,
2676029a2d8Ssusans 	MR_EVT_LOCALE_ALL		= 0xffff
2686029a2d8Ssusans };
2696029a2d8Ssusans 
2706029a2d8Ssusans enum MR_EVT_ARGS {
2716029a2d8Ssusans 	MR_EVT_ARGS_NONE,
2726029a2d8Ssusans 	MR_EVT_ARGS_CDB_SENSE,
2736029a2d8Ssusans 	MR_EVT_ARGS_LD,
2746029a2d8Ssusans 	MR_EVT_ARGS_LD_COUNT,
2756029a2d8Ssusans 	MR_EVT_ARGS_LD_LBA,
2766029a2d8Ssusans 	MR_EVT_ARGS_LD_OWNER,
2776029a2d8Ssusans 	MR_EVT_ARGS_LD_LBA_PD_LBA,
2786029a2d8Ssusans 	MR_EVT_ARGS_LD_PROG,
2796029a2d8Ssusans 	MR_EVT_ARGS_LD_STATE,
2806029a2d8Ssusans 	MR_EVT_ARGS_LD_STRIP,
2816029a2d8Ssusans 	MR_EVT_ARGS_PD,
2826029a2d8Ssusans 	MR_EVT_ARGS_PD_ERR,
2836029a2d8Ssusans 	MR_EVT_ARGS_PD_LBA,
2846029a2d8Ssusans 	MR_EVT_ARGS_PD_LBA_LD,
2856029a2d8Ssusans 	MR_EVT_ARGS_PD_PROG,
2866029a2d8Ssusans 	MR_EVT_ARGS_PD_STATE,
2876029a2d8Ssusans 	MR_EVT_ARGS_PCI,
2886029a2d8Ssusans 	MR_EVT_ARGS_RATE,
2896029a2d8Ssusans 	MR_EVT_ARGS_STR,
2906029a2d8Ssusans 	MR_EVT_ARGS_TIME,
2916029a2d8Ssusans 	MR_EVT_ARGS_ECC
2926029a2d8Ssusans };
2936029a2d8Ssusans 
2947ddfa2acSSusan Scheufele #pragma pack(1)
2957ddfa2acSSusan Scheufele 
2966029a2d8Ssusans /*
2976029a2d8Ssusans  * SAS controller properties
2986029a2d8Ssusans  */
2996029a2d8Ssusans struct megasas_ctrl_prop {
3006029a2d8Ssusans 	uint16_t	seq_num;
3016029a2d8Ssusans 	uint16_t	pred_fail_poll_interval;
3026029a2d8Ssusans 	uint16_t	intr_throttle_count;
3036029a2d8Ssusans 	uint16_t	intr_throttle_timeouts;
3046029a2d8Ssusans 
3056029a2d8Ssusans 	uint8_t		rebuild_rate;
3066029a2d8Ssusans 	uint8_t		patrol_read_rate;
3076029a2d8Ssusans 	uint8_t		bgi_rate;
3086029a2d8Ssusans 	uint8_t		cc_rate;
3096029a2d8Ssusans 	uint8_t		recon_rate;
3106029a2d8Ssusans 
3116029a2d8Ssusans 	uint8_t		cache_flush_interval;
3126029a2d8Ssusans 
3136029a2d8Ssusans 	uint8_t		spinup_drv_count;
3146029a2d8Ssusans 	uint8_t		spinup_delay;
3156029a2d8Ssusans 
3166029a2d8Ssusans 	uint8_t		cluster_enable;
3176029a2d8Ssusans 	uint8_t		coercion_mode;
3186029a2d8Ssusans 	uint8_t		disk_write_cache_disable;
3196029a2d8Ssusans 	uint8_t		alarm_enable;
3206029a2d8Ssusans 
3216029a2d8Ssusans 	uint8_t		reserved[44];
3226029a2d8Ssusans };
3236029a2d8Ssusans 
3246029a2d8Ssusans /*
3256029a2d8Ssusans  * SAS controller information
3266029a2d8Ssusans  */
3276029a2d8Ssusans struct megasas_ctrl_info {
3286029a2d8Ssusans 	/* PCI device information */
3296029a2d8Ssusans 	struct {
3306029a2d8Ssusans 		uint16_t	vendor_id;
3316029a2d8Ssusans 		uint16_t	device_id;
3326029a2d8Ssusans 		uint16_t	sub_vendor_id;
3336029a2d8Ssusans 		uint16_t	sub_device_id;
3346029a2d8Ssusans 		uint8_t	reserved[24];
3356029a2d8Ssusans 	} pci;
3366029a2d8Ssusans 
3376029a2d8Ssusans 	/* Host interface information */
3386029a2d8Ssusans 	struct {
3396029a2d8Ssusans 		uint8_t	PCIX		: 1;
3406029a2d8Ssusans 		uint8_t	PCIE		: 1;
3416029a2d8Ssusans 		uint8_t	iSCSI		: 1;
3426029a2d8Ssusans 		uint8_t	SAS_3G		: 1;
3436029a2d8Ssusans 		uint8_t	reserved_0	: 4;
3446029a2d8Ssusans 		uint8_t	reserved_1[6];
3456029a2d8Ssusans 		uint8_t	port_count;
3466029a2d8Ssusans 		uint64_t	port_addr[8];
3476029a2d8Ssusans 	} host_interface;
3486029a2d8Ssusans 
3496029a2d8Ssusans 	/* Device (backend) interface information */
3506029a2d8Ssusans 	struct {
3516029a2d8Ssusans 		uint8_t	SPI		: 1;
3526029a2d8Ssusans 		uint8_t	SAS_3G		: 1;
3536029a2d8Ssusans 		uint8_t	SATA_1_5G	: 1;
3546029a2d8Ssusans 		uint8_t	SATA_3G		: 1;
3556029a2d8Ssusans 		uint8_t	reserved_0	: 4;
3566029a2d8Ssusans 		uint8_t	reserved_1[6];
3576029a2d8Ssusans 		uint8_t	port_count;
3586029a2d8Ssusans 		uint64_t	port_addr[8];
3596029a2d8Ssusans 	} device_interface;
3606029a2d8Ssusans 
3616029a2d8Ssusans 	/* List of components residing in flash. All str are null terminated */
3626029a2d8Ssusans 	uint32_t	image_check_word;
3636029a2d8Ssusans 	uint32_t	image_component_count;
3646029a2d8Ssusans 
3656029a2d8Ssusans 	struct {
3666029a2d8Ssusans 		char	name[8];
3676029a2d8Ssusans 		char	version[32];
3686029a2d8Ssusans 		char	build_date[16];
3696029a2d8Ssusans 		char	built_time[16];
3706029a2d8Ssusans 	} image_component[8];
3716029a2d8Ssusans 
3726029a2d8Ssusans 	/*
3736029a2d8Ssusans 	 * List of flash components that have been flashed on the card, but
3746029a2d8Ssusans 	 * are not in use, pending reset of the adapter. This list will be
3756029a2d8Ssusans 	 * empty if a flash operation has not occurred. All stings are null
3766029a2d8Ssusans 	 * terminated
3776029a2d8Ssusans 	 */
3786029a2d8Ssusans 	uint32_t	pending_image_component_count;
3796029a2d8Ssusans 
3806029a2d8Ssusans 	struct {
3816029a2d8Ssusans 		char	name[8];
3826029a2d8Ssusans 		char	version[32];
3836029a2d8Ssusans 		char	build_date[16];
3846029a2d8Ssusans 		char	build_time[16];
3856029a2d8Ssusans 	} pending_image_component[8];
3866029a2d8Ssusans 
3876029a2d8Ssusans 	uint8_t		max_arms;
3886029a2d8Ssusans 	uint8_t		max_spans;
3896029a2d8Ssusans 	uint8_t		max_arrays;
3906029a2d8Ssusans 	uint8_t		max_lds;
3916029a2d8Ssusans 
3926029a2d8Ssusans 	char		product_name[80];
3936029a2d8Ssusans 	char		serial_no[32];
3946029a2d8Ssusans 
3956029a2d8Ssusans 	/*
3966029a2d8Ssusans 	 * Other physical/controller/operation information. Indicates the
3976029a2d8Ssusans 	 * presence of the hardware
3986029a2d8Ssusans 	 */
3996029a2d8Ssusans 	struct {
4006029a2d8Ssusans 		uint32_t	bbu		: 1;
4016029a2d8Ssusans 		uint32_t	alarm		: 1;
4026029a2d8Ssusans 		uint32_t	nvram		: 1;
4036029a2d8Ssusans 		uint32_t	uart		: 1;
4046029a2d8Ssusans 		uint32_t	reserved	: 28;
4056029a2d8Ssusans 	} hw_present;
4066029a2d8Ssusans 
4076029a2d8Ssusans 	uint32_t	current_fw_time;
4086029a2d8Ssusans 
4096029a2d8Ssusans 	/* Maximum data transfer sizes */
4106029a2d8Ssusans 	uint16_t		max_concurrent_cmds;
4116029a2d8Ssusans 	uint16_t		max_sge_count;
4126029a2d8Ssusans 	uint32_t		max_request_size;
4136029a2d8Ssusans 
4146029a2d8Ssusans 	/* Logical and physical device counts */
4156029a2d8Ssusans 	uint16_t		ld_present_count;
4166029a2d8Ssusans 	uint16_t		ld_degraded_count;
4176029a2d8Ssusans 	uint16_t		ld_offline_count;
4186029a2d8Ssusans 
4196029a2d8Ssusans 	uint16_t		pd_present_count;
4206029a2d8Ssusans 	uint16_t		pd_disk_present_count;
4216029a2d8Ssusans 	uint16_t		pd_disk_pred_failure_count;
4226029a2d8Ssusans 	uint16_t		pd_disk_failed_count;
4236029a2d8Ssusans 
4246029a2d8Ssusans 	/* Memory size information */
4256029a2d8Ssusans 	uint16_t		nvram_size;
4266029a2d8Ssusans 	uint16_t		memory_size;
4276029a2d8Ssusans 	uint16_t		flash_size;
4286029a2d8Ssusans 
4296029a2d8Ssusans 	/* Error counters */
4306029a2d8Ssusans 	uint16_t		mem_correctable_error_count;
4316029a2d8Ssusans 	uint16_t		mem_uncorrectable_error_count;
4326029a2d8Ssusans 
4336029a2d8Ssusans 	/* Cluster information */
4346029a2d8Ssusans 	uint8_t		cluster_permitted;
4356029a2d8Ssusans 	uint8_t		cluster_active;
4366029a2d8Ssusans 	uint8_t		reserved_1[2];
4376029a2d8Ssusans 
4386029a2d8Ssusans 	/* Controller capabilities structures */
4396029a2d8Ssusans 	struct {
4406029a2d8Ssusans 		uint32_t	raid_level_0	: 1;
4416029a2d8Ssusans 		uint32_t	raid_level_1	: 1;
4426029a2d8Ssusans 		uint32_t	raid_level_5	: 1;
4436029a2d8Ssusans 		uint32_t	raid_level_1E	: 1;
4446029a2d8Ssusans 		uint32_t	reserved	: 28;
4456029a2d8Ssusans 	} raid_levels;
4466029a2d8Ssusans 
4476029a2d8Ssusans 	struct {
4486029a2d8Ssusans 		uint32_t	rbld_rate		: 1;
4496029a2d8Ssusans 		uint32_t	cc_rate			: 1;
4506029a2d8Ssusans 		uint32_t	bgi_rate		: 1;
4516029a2d8Ssusans 		uint32_t	recon_rate		: 1;
4526029a2d8Ssusans 		uint32_t	patrol_rate		: 1;
4536029a2d8Ssusans 		uint32_t	alarm_control		: 1;
4546029a2d8Ssusans 		uint32_t	cluster_supported	: 1;
4556029a2d8Ssusans 		uint32_t	bbu			: 1;
4566029a2d8Ssusans 		uint32_t	spanning_allowed	: 1;
4576029a2d8Ssusans 		uint32_t	dedicated_hotspares	: 1;
4586029a2d8Ssusans 		uint32_t	revertible_hotspares	: 1;
4596029a2d8Ssusans 		uint32_t	foreign_config_import	: 1;
4606029a2d8Ssusans 		uint32_t	self_diagnostic		: 1;
4616029a2d8Ssusans 		uint32_t	reserved		: 19;
4626029a2d8Ssusans 	} adapter_operations;
4636029a2d8Ssusans 
4646029a2d8Ssusans 	struct {
4656029a2d8Ssusans 		uint32_t	read_policy	: 1;
4666029a2d8Ssusans 		uint32_t	write_policy	: 1;
4676029a2d8Ssusans 		uint32_t	io_policy	: 1;
4686029a2d8Ssusans 		uint32_t	access_policy	: 1;
4696029a2d8Ssusans 		uint32_t	reserved	: 28;
4706029a2d8Ssusans 	} ld_operations;
4716029a2d8Ssusans 
4726029a2d8Ssusans 	struct {
4736029a2d8Ssusans 		uint8_t	min;
4746029a2d8Ssusans 		uint8_t	max;
4756029a2d8Ssusans 		uint8_t	reserved[2];
4766029a2d8Ssusans 	} stripe_size_operations;
4776029a2d8Ssusans 
4786029a2d8Ssusans 	struct {
4796029a2d8Ssusans 		uint32_t	force_online	: 1;
4806029a2d8Ssusans 		uint32_t	force_offline	: 1;
4816029a2d8Ssusans 		uint32_t	force_rebuild	: 1;
4826029a2d8Ssusans 		uint32_t	reserved	: 29;
4836029a2d8Ssusans 	} pd_operations;
4846029a2d8Ssusans 
4856029a2d8Ssusans 	struct {
4866029a2d8Ssusans 		uint32_t	ctrl_supports_sas	: 1;
4876029a2d8Ssusans 		uint32_t	ctrl_supports_sata	: 1;
4886029a2d8Ssusans 		uint32_t	allow_mix_in_encl	: 1;
4896029a2d8Ssusans 		uint32_t	allow_mix_in_ld		: 1;
4906029a2d8Ssusans 		uint32_t	allow_sata_in_cluster	: 1;
4916029a2d8Ssusans 		uint32_t	reserved		: 27;
4926029a2d8Ssusans 	} pd_mix_support;
4936029a2d8Ssusans 
4946029a2d8Ssusans 	/* Include the controller properties (changeable items) */
4956029a2d8Ssusans 	uint8_t				reserved_2[12];
4966029a2d8Ssusans 	struct megasas_ctrl_prop	properties;
4976029a2d8Ssusans 
4986029a2d8Ssusans 	uint8_t				pad[0x800 - 0x640];
4996029a2d8Ssusans };
5006029a2d8Ssusans 
5016029a2d8Ssusans /*
5026029a2d8Ssusans  * ===============================
5036029a2d8Ssusans  * MegaRAID SAS driver definitions
5046029a2d8Ssusans  * ===============================
5056029a2d8Ssusans  */
5066029a2d8Ssusans #define	MEGADRV_MAX_NUM_CMD			1024
5076029a2d8Ssusans 
5086029a2d8Ssusans #define	MEGADRV_MAX_PD_CHANNELS			2
5096029a2d8Ssusans #define	MEGADRV_MAX_LD_CHANNELS			2
5106029a2d8Ssusans #define	MEGADRV_MAX_CHANNELS			(MEGADRV_MAX_PD_CHANNELS + \
5116029a2d8Ssusans 						MEGADRV_MAX_LD_CHANNELS)
5126029a2d8Ssusans #define	MEGADRV_MAX_DEV_PER_CHANNEL		128
5136029a2d8Ssusans #define	MEGADRV_DEFAULT_INIT_ID			-1
5146029a2d8Ssusans #define	MEGADRV_MAX_CMD_PER_LUN			1000
5156029a2d8Ssusans #define	MEGADRV_MAX_LUN				8
5166029a2d8Ssusans #define	MEGADRV_MAX_LD				64
5176029a2d8Ssusans 
5186029a2d8Ssusans #define	MEGADRV_RESET_WAIT_TIME			300
5196029a2d8Ssusans #define	MEGADRV_RESET_NOTICE_INTERVAL		5
5206029a2d8Ssusans 
5216029a2d8Ssusans #define	MEGASAS_IOCTL_CMD			0
5226029a2d8Ssusans 
5236029a2d8Ssusans /*
5246029a2d8Ssusans  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit
5256029a2d8Ssusans  * SGLs based on the size of dma_addr_t
5266029a2d8Ssusans  */
5276029a2d8Ssusans #define	IS_DMA64		(sizeof (dma_addr_t) == 8)
5286029a2d8Ssusans 
5297ddfa2acSSusan Scheufele #define	IB_MSG_0_OFF			0x10	/* XScale */
5307ddfa2acSSusan Scheufele #define	OB_MSG_0_OFF			0x18	/* XScale */
5317ddfa2acSSusan Scheufele #define	IB_DOORBELL_OFF			0x20	/* XScale & ROC */
5327ddfa2acSSusan Scheufele #define	OB_INTR_STATUS_OFF		0x30	/* XScale & ROC */
5337ddfa2acSSusan Scheufele #define	OB_INTR_MASK_OFF		0x34	/* XScale & ROC */
5347ddfa2acSSusan Scheufele #define	IB_QPORT_OFF			0x40	/* XScale & ROC */
5357ddfa2acSSusan Scheufele #define	OB_DOORBELL_CLEAR_OFF		0xA0	/* ROC */
5367ddfa2acSSusan Scheufele #define	OB_SCRATCH_PAD_0_OFF		0xB0	/* ROC */
5377ddfa2acSSusan Scheufele #define	OB_INTR_MASK			0xFFFFFFFF
5387ddfa2acSSusan Scheufele #define	OB_DOORBELL_CLEAR_MASK		0xFFFFFFFF
5397ddfa2acSSusan Scheufele 
5406029a2d8Ssusans /*
5416029a2d8Ssusans  * All MFI register set macros accept megasas_register_set*
5426029a2d8Ssusans  */
5436029a2d8Ssusans #define	WR_IB_MSG_0(v, instance) 	ddi_put32((instance)->regmap_handle, \
5447ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_MSG_0_OFF), (v))
5456029a2d8Ssusans 
5466029a2d8Ssusans #define	RD_OB_MSG_0(instance) 		ddi_get32((instance)->regmap_handle, \
5477ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_MSG_0_OFF))
5486029a2d8Ssusans 
5496029a2d8Ssusans #define	WR_IB_DOORBELL(v, instance)	ddi_put32((instance)->regmap_handle, \
5507ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF), (v))
5516029a2d8Ssusans 
5526029a2d8Ssusans #define	RD_IB_DOORBELL(instance)	ddi_get32((instance)->regmap_handle, \
5537ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF))
5546029a2d8Ssusans 
5556029a2d8Ssusans #define	WR_OB_INTR_STATUS(v, instance) 	ddi_put32((instance)->regmap_handle, \
5567ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF), (v))
5576029a2d8Ssusans 
5586029a2d8Ssusans #define	RD_OB_INTR_STATUS(instance) 	ddi_get32((instance)->regmap_handle, \
5597ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF))
5606029a2d8Ssusans 
5616029a2d8Ssusans #define	WR_OB_INTR_MASK(v, instance) 	ddi_put32((instance)->regmap_handle, \
5627ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), (v))
5636029a2d8Ssusans 
5646029a2d8Ssusans #define	RD_OB_INTR_MASK(instance) 	ddi_get32((instance)->regmap_handle, \
5657ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF))
5666029a2d8Ssusans 
5676029a2d8Ssusans #define	WR_IB_QPORT(v, instance) 	ddi_put32((instance)->regmap_handle, \
5687ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + IB_QPORT_OFF), (v))
5696029a2d8Ssusans 
5706029a2d8Ssusans #define	WR_OB_DOORBELL_CLEAR(v, instance) ddi_put32((instance)->regmap_handle, \
5717ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_CLEAR_OFF), \
5727ddfa2acSSusan Scheufele 	(v))
5736029a2d8Ssusans 
5746029a2d8Ssusans #define	RD_OB_SCRATCH_PAD_0(instance) 	ddi_get32((instance)->regmap_handle, \
5757ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_0_OFF))
5766029a2d8Ssusans 
5776029a2d8Ssusans /*
5786029a2d8Ssusans  * When FW is in MFI_STATE_READY or MFI_STATE_OPERATIONAL, the state data
5796029a2d8Ssusans  * of Outbound Msg Reg 0 indicates max concurrent cmds supported, max SGEs
5806029a2d8Ssusans  * supported per cmd and if 64-bit MFAs (M64) is enabled or disabled.
5816029a2d8Ssusans  */
5826029a2d8Ssusans #define	MFI_OB_INTR_STATUS_MASK		0x00000002
5836029a2d8Ssusans 
5846029a2d8Ssusans /*
5856029a2d8Ssusans  * This MFI_REPLY_1078_MESSAGE_INTR flag is used also
5866029a2d8Ssusans  * in enable_intr_pcc also. Hence bit 2, i.e. 0x4 has
5876029a2d8Ssusans  * been set in this flag along with bit 31.
5886029a2d8Ssusans  */
5896029a2d8Ssusans #define	MFI_REPLY_1078_MESSAGE_INTR	0x80000004
5906029a2d8Ssusans 
5916029a2d8Ssusans #define	MFI_POLL_TIMEOUT_SECS		60
5926029a2d8Ssusans 
5936029a2d8Ssusans #define	MFI_ENABLE_INTR(instance)  ddi_put32((instance)->regmap_handle, \
5946ec0e308SSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), 1)
5956029a2d8Ssusans #define	MFI_DISABLE_INTR(instance)					\
5966029a2d8Ssusans {									\
5976029a2d8Ssusans 	uint32_t disable = 1;						\
5986029a2d8Ssusans 	uint32_t mask =  ddi_get32((instance)->regmap_handle, 		\
5997ddfa2acSSusan Scheufele 	(uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF));\
6006029a2d8Ssusans 	mask &= ~disable;						\
6017ddfa2acSSusan Scheufele 	ddi_put32((instance)->regmap_handle, (uint32_t *)		\
6027ddfa2acSSusan Scheufele 	    (uintptr_t)((instance)->regmap + OB_INTR_MASK_OFF), mask);	\
6036029a2d8Ssusans }
6046029a2d8Ssusans 
6057ddfa2acSSusan Scheufele /* By default, the firmware programs for 8 Kbytes of memory */
6067ddfa2acSSusan Scheufele #define	DEFAULT_MFI_MEM_SZ	8192
6077ddfa2acSSusan Scheufele #define	MINIMUM_MFI_MEM_SZ	4096
6087ddfa2acSSusan Scheufele 
6097ddfa2acSSusan Scheufele /* DCMD Message Frame MAILBOX0-11 */
6107ddfa2acSSusan Scheufele #define	DCMD_MBOX_SZ		12
6117ddfa2acSSusan Scheufele 
6126029a2d8Ssusans 
6136029a2d8Ssusans struct megasas_register_set {
6146029a2d8Ssusans 	uint32_t	reserved_0[4];			/* 0000h */
6156029a2d8Ssusans 
6166029a2d8Ssusans 	uint32_t	inbound_msg_0;			/* 0010h */
6176029a2d8Ssusans 	uint32_t	inbound_msg_1;			/* 0014h */
6186029a2d8Ssusans 	uint32_t	outbound_msg_0;			/* 0018h */
6196029a2d8Ssusans 	uint32_t	outbound_msg_1;			/* 001Ch */
6206029a2d8Ssusans 
6216029a2d8Ssusans 	uint32_t	inbound_doorbell;		/* 0020h */
6226029a2d8Ssusans 	uint32_t	inbound_intr_status;		/* 0024h */
6236029a2d8Ssusans 	uint32_t	inbound_intr_mask;		/* 0028h */
6246029a2d8Ssusans 
6256029a2d8Ssusans 	uint32_t	outbound_doorbell;		/* 002Ch */
6266029a2d8Ssusans 	uint32_t	outbound_intr_status;		/* 0030h */
6276029a2d8Ssusans 	uint32_t	outbound_intr_mask;		/* 0034h */
6286029a2d8Ssusans 
6296029a2d8Ssusans 	uint32_t	reserved_1[2];			/* 0038h */
6306029a2d8Ssusans 
6316029a2d8Ssusans 	uint32_t	inbound_queue_port;		/* 0040h */
6326029a2d8Ssusans 	uint32_t	outbound_queue_port;		/* 0044h */
6336029a2d8Ssusans 
6346029a2d8Ssusans 	uint32_t 	reserved_2[22];			/* 0048h */
6356029a2d8Ssusans 
6366029a2d8Ssusans 	uint32_t 	outbound_doorbell_clear;	/* 00A0h */
6376029a2d8Ssusans 
6386029a2d8Ssusans 	uint32_t 	reserved_3[3];			/* 00A4h */
6396029a2d8Ssusans 
6406029a2d8Ssusans 	uint32_t 	outbound_scratch_pad;		/* 00B0h */
6416029a2d8Ssusans 
6426029a2d8Ssusans 	uint32_t 	reserved_4[3];			/* 00B4h */
6436029a2d8Ssusans 
6446029a2d8Ssusans 	uint32_t 	inbound_low_queue_port;		/* 00C0h */
6456029a2d8Ssusans 
6466029a2d8Ssusans 	uint32_t 	inbound_high_queue_port;	/* 00C4h */
6476029a2d8Ssusans 
6486029a2d8Ssusans 	uint32_t 	reserved_5;			/* 00C8h */
6496029a2d8Ssusans 	uint32_t 	index_registers[820];		/* 00CCh */
6506029a2d8Ssusans };
6516029a2d8Ssusans 
6526029a2d8Ssusans struct megasas_sge32 {
6536029a2d8Ssusans 	uint32_t	phys_addr;
6546029a2d8Ssusans 	uint32_t	length;
6556029a2d8Ssusans };
6566029a2d8Ssusans 
6576029a2d8Ssusans struct megasas_sge64 {
6586029a2d8Ssusans 	uint64_t	phys_addr;
6596029a2d8Ssusans 	uint32_t	length;
6606029a2d8Ssusans };
6616029a2d8Ssusans 
6626029a2d8Ssusans union megasas_sgl {
6636029a2d8Ssusans 	struct megasas_sge32	sge32[1];
6646029a2d8Ssusans 	struct megasas_sge64	sge64[1];
6656029a2d8Ssusans };
6666029a2d8Ssusans 
6676029a2d8Ssusans struct megasas_header {
6686029a2d8Ssusans 	uint8_t		cmd;				/* 00h */
6696029a2d8Ssusans 	uint8_t		sense_len;			/* 01h */
6706029a2d8Ssusans 	uint8_t		cmd_status;			/* 02h */
6716029a2d8Ssusans 	uint8_t		scsi_status;			/* 03h */
6726029a2d8Ssusans 
6736029a2d8Ssusans 	uint8_t		target_id;			/* 04h */
6746029a2d8Ssusans 	uint8_t		lun;				/* 05h */
6756029a2d8Ssusans 	uint8_t		cdb_len;			/* 06h */
6766029a2d8Ssusans 	uint8_t		sge_count;			/* 07h */
6776029a2d8Ssusans 
6786029a2d8Ssusans 	uint32_t	context;			/* 08h */
6796029a2d8Ssusans 	uint32_t	pad_0;				/* 0Ch */
6806029a2d8Ssusans 
6816029a2d8Ssusans 	uint16_t	flags;				/* 10h */
6826029a2d8Ssusans 	uint16_t	timeout;			/* 12h */
6836029a2d8Ssusans 	uint32_t	data_xferlen;			/* 14h */
6846029a2d8Ssusans };
6856029a2d8Ssusans 
6866029a2d8Ssusans union megasas_sgl_frame {
6876029a2d8Ssusans 	struct megasas_sge32	sge32[8];
6886029a2d8Ssusans 	struct megasas_sge64	sge64[5];
6896029a2d8Ssusans };
6906029a2d8Ssusans 
6916029a2d8Ssusans struct megasas_init_frame {
6926029a2d8Ssusans 	uint8_t		cmd;				/* 00h */
6936029a2d8Ssusans 	uint8_t		reserved_0;			/* 01h */
6946029a2d8Ssusans 	uint8_t		cmd_status;			/* 02h */
6956029a2d8Ssusans 
6966029a2d8Ssusans 	uint8_t		reserved_1;			/* 03h */
6976029a2d8Ssusans 	uint32_t	reserved_2;			/* 04h */
6986029a2d8Ssusans 
6996029a2d8Ssusans 	uint32_t	context;			/* 08h */
7006029a2d8Ssusans 	uint32_t	pad_0;				/* 0Ch */
7016029a2d8Ssusans 
7026029a2d8Ssusans 	uint16_t	flags;				/* 10h */
7036029a2d8Ssusans 	uint16_t	reserved_3;			/* 12h */
7046029a2d8Ssusans 	uint32_t	data_xfer_len;			/* 14h */
7056029a2d8Ssusans 
7066029a2d8Ssusans 	uint32_t	queue_info_new_phys_addr_lo;	/* 18h */
7076029a2d8Ssusans 	uint32_t	queue_info_new_phys_addr_hi;	/* 1Ch */
7086029a2d8Ssusans 	uint32_t	queue_info_old_phys_addr_lo;	/* 20h */
7096029a2d8Ssusans 	uint32_t	queue_info_old_phys_addr_hi;	/* 24h */
7106029a2d8Ssusans 
7116029a2d8Ssusans 	uint32_t	reserved_4[6];			/* 28h */
7126029a2d8Ssusans };
7136029a2d8Ssusans 
7146029a2d8Ssusans struct megasas_init_queue_info {
7156029a2d8Ssusans 	uint32_t		init_flags;			/* 00h */
7166029a2d8Ssusans 	uint32_t		reply_queue_entries;		/* 04h */
7176029a2d8Ssusans 
7186029a2d8Ssusans 	uint32_t		reply_queue_start_phys_addr_lo;	/* 08h */
7196029a2d8Ssusans 	uint32_t		reply_queue_start_phys_addr_hi;	/* 0Ch */
7206029a2d8Ssusans 	uint32_t		producer_index_phys_addr_lo;	/* 10h */
7216029a2d8Ssusans 	uint32_t		producer_index_phys_addr_hi;	/* 14h */
7226029a2d8Ssusans 	uint32_t		consumer_index_phys_addr_lo;	/* 18h */
7236029a2d8Ssusans 	uint32_t		consumer_index_phys_addr_hi;	/* 1Ch */
7246029a2d8Ssusans };
7256029a2d8Ssusans 
7266029a2d8Ssusans struct megasas_io_frame {
7276029a2d8Ssusans 	uint8_t			cmd;			/* 00h */
7286029a2d8Ssusans 	uint8_t			sense_len;		/* 01h */
7296029a2d8Ssusans 	uint8_t			cmd_status;		/* 02h */
7306029a2d8Ssusans 	uint8_t			scsi_status;		/* 03h */
7316029a2d8Ssusans 
7326029a2d8Ssusans 	uint8_t			target_id;		/* 04h */
7336029a2d8Ssusans 	uint8_t			access_byte;		/* 05h */
7346029a2d8Ssusans 	uint8_t			reserved_0;		/* 06h */
7356029a2d8Ssusans 	uint8_t			sge_count;		/* 07h */
7366029a2d8Ssusans 
7376029a2d8Ssusans 	uint32_t		context;		/* 08h */
7386029a2d8Ssusans 	uint32_t		pad_0;			/* 0Ch */
7396029a2d8Ssusans 
7406029a2d8Ssusans 	uint16_t		flags;			/* 10h */
7416029a2d8Ssusans 	uint16_t		timeout;		/* 12h */
7426029a2d8Ssusans 	uint32_t		lba_count;		/* 14h */
7436029a2d8Ssusans 
7446029a2d8Ssusans 	uint32_t		sense_buf_phys_addr_lo;	/* 18h */
7456029a2d8Ssusans 	uint32_t		sense_buf_phys_addr_hi;	/* 1Ch */
7466029a2d8Ssusans 
7476029a2d8Ssusans 	uint32_t		start_lba_lo;		/* 20h */
7486029a2d8Ssusans 	uint32_t		start_lba_hi;		/* 24h */
7496029a2d8Ssusans 
7506029a2d8Ssusans 	union megasas_sgl	sgl;			/* 28h */
7516029a2d8Ssusans };
7526029a2d8Ssusans 
7536029a2d8Ssusans struct megasas_pthru_frame {
7546029a2d8Ssusans 	uint8_t			cmd;			/* 00h */
7556029a2d8Ssusans 	uint8_t			sense_len;		/* 01h */
7566029a2d8Ssusans 	uint8_t			cmd_status;		/* 02h */
7576029a2d8Ssusans 	uint8_t			scsi_status;		/* 03h */
7586029a2d8Ssusans 
7596029a2d8Ssusans 	uint8_t			target_id;		/* 04h */
7606029a2d8Ssusans 	uint8_t			lun;			/* 05h */
7616029a2d8Ssusans 	uint8_t			cdb_len;		/* 06h */
7626029a2d8Ssusans 	uint8_t			sge_count;		/* 07h */
7636029a2d8Ssusans 
7646029a2d8Ssusans 	uint32_t		context;		/* 08h */
7656029a2d8Ssusans 	uint32_t		pad_0;			/* 0Ch */
7666029a2d8Ssusans 
7676029a2d8Ssusans 	uint16_t		flags;			/* 10h */
7686029a2d8Ssusans 	uint16_t		timeout;		/* 12h */
7696029a2d8Ssusans 	uint32_t		data_xfer_len;		/* 14h */
7706029a2d8Ssusans 
7716029a2d8Ssusans 	uint32_t		sense_buf_phys_addr_lo;	/* 18h */
7726029a2d8Ssusans 	uint32_t		sense_buf_phys_addr_hi;	/* 1Ch */
7736029a2d8Ssusans 
7746029a2d8Ssusans 	uint8_t			cdb[16];		/* 20h */
7756029a2d8Ssusans 	union megasas_sgl	sgl;			/* 30h */
7766029a2d8Ssusans };
7776029a2d8Ssusans 
7786029a2d8Ssusans struct megasas_dcmd_frame {
7796029a2d8Ssusans 	uint8_t			cmd;			/* 00h */
7806029a2d8Ssusans 	uint8_t			reserved_0;		/* 01h */
7816029a2d8Ssusans 	uint8_t			cmd_status;		/* 02h */
7826029a2d8Ssusans 	uint8_t			reserved_1[4];		/* 03h */
7836029a2d8Ssusans 	uint8_t			sge_count;		/* 07h */
7846029a2d8Ssusans 
7856029a2d8Ssusans 	uint32_t		context;		/* 08h */
7866029a2d8Ssusans 	uint32_t		pad_0;			/* 0Ch */
7876029a2d8Ssusans 
7886029a2d8Ssusans 	uint16_t		flags;			/* 10h */
7896029a2d8Ssusans 	uint16_t		timeout;		/* 12h */
7906029a2d8Ssusans 
7916029a2d8Ssusans 	uint32_t		data_xfer_len;		/* 14h */
7926029a2d8Ssusans 	uint32_t		opcode;			/* 18h */
7936029a2d8Ssusans 
7947ddfa2acSSusan Scheufele 	/* uint8_t		mbox[DCMD_MBOX_SZ]; */	/* 1Ch */
7956029a2d8Ssusans 	union {						/* 1Ch */
7967ddfa2acSSusan Scheufele 		uint8_t b[DCMD_MBOX_SZ];
7976029a2d8Ssusans 		uint16_t s[6];
7986029a2d8Ssusans 		uint32_t w[3];
7996029a2d8Ssusans 	} mbox;
8006029a2d8Ssusans 
8016029a2d8Ssusans 	union megasas_sgl	sgl;			/* 28h */
8026029a2d8Ssusans };
8036029a2d8Ssusans 
8046029a2d8Ssusans struct megasas_abort_frame {
8056029a2d8Ssusans 	uint8_t		cmd;				/* 00h */
8066029a2d8Ssusans 	uint8_t		reserved_0;			/* 01h */
8076029a2d8Ssusans 	uint8_t		cmd_status;			/* 02h */
8086029a2d8Ssusans 
8096029a2d8Ssusans 	uint8_t		reserved_1;			/* 03h */
8106029a2d8Ssusans 	uint32_t	reserved_2;			/* 04h */
8116029a2d8Ssusans 
8126029a2d8Ssusans 	uint32_t	context;			/* 08h */
8136029a2d8Ssusans 	uint32_t	pad_0;				/* 0Ch */
8146029a2d8Ssusans 
8156029a2d8Ssusans 	uint16_t	flags;				/* 10h */
8166029a2d8Ssusans 	uint16_t	reserved_3;			/* 12h */
8176029a2d8Ssusans 	uint32_t	reserved_4;			/* 14h */
8186029a2d8Ssusans 
8196029a2d8Ssusans 	uint32_t	abort_context;			/* 18h */
8206029a2d8Ssusans 	uint32_t	pad_1;				/* 1Ch */
8216029a2d8Ssusans 
8226029a2d8Ssusans 	uint32_t	abort_mfi_phys_addr_lo;		/* 20h */
8236029a2d8Ssusans 	uint32_t	abort_mfi_phys_addr_hi;		/* 24h */
8246029a2d8Ssusans 
8256029a2d8Ssusans 	uint32_t	reserved_5[6];			/* 28h */
8266029a2d8Ssusans };
8276029a2d8Ssusans 
8286029a2d8Ssusans struct megasas_smp_frame {
8296029a2d8Ssusans 	uint8_t		cmd;				/* 00h */
8306029a2d8Ssusans 	uint8_t		reserved_1;			/* 01h */
8316029a2d8Ssusans 	uint8_t		cmd_status;			/* 02h */
8326029a2d8Ssusans 	uint8_t		connection_status;		/* 03h */
8336029a2d8Ssusans 
8346029a2d8Ssusans 	uint8_t		reserved_2[3];			/* 04h */
8356029a2d8Ssusans 	uint8_t		sge_count;			/* 07h */
8366029a2d8Ssusans 
8376029a2d8Ssusans 	uint32_t	context;			/* 08h */
8386029a2d8Ssusans 	uint32_t	pad_0;				/* 0Ch */
8396029a2d8Ssusans 
8406029a2d8Ssusans 	uint16_t	flags;				/* 10h */
8416029a2d8Ssusans 	uint16_t	timeout;			/* 12h */
8426029a2d8Ssusans 
8436029a2d8Ssusans 	uint32_t	data_xfer_len;			/* 14h */
8446029a2d8Ssusans 
8456029a2d8Ssusans 	uint64_t	sas_addr;			/* 20h */
8466029a2d8Ssusans 
8476029a2d8Ssusans 	union megasas_sgl	sgl[2];			/* 28h */
8486029a2d8Ssusans };
8496029a2d8Ssusans 
8506029a2d8Ssusans struct megasas_stp_frame {
8516029a2d8Ssusans 	uint8_t		cmd;				/* 00h */
8526029a2d8Ssusans 	uint8_t		reserved_1;			/* 01h */
8536029a2d8Ssusans 	uint8_t		cmd_status;			/* 02h */
8546029a2d8Ssusans 	uint8_t		connection_status;		/* 03h */
8556029a2d8Ssusans 
8566029a2d8Ssusans 	uint8_t		target_id;			/* 04h */
8576029a2d8Ssusans 	uint8_t		reserved_2[2];			/* 04h */
8586029a2d8Ssusans 	uint8_t		sge_count;			/* 07h */
8596029a2d8Ssusans 
8606029a2d8Ssusans 	uint32_t	context;			/* 08h */
8616029a2d8Ssusans 	uint32_t	pad_0;				/* 0Ch */
8626029a2d8Ssusans 
8636029a2d8Ssusans 	uint16_t	flags;				/* 10h */
8646029a2d8Ssusans 	uint16_t	timeout;			/* 12h */
8656029a2d8Ssusans 
8666029a2d8Ssusans 	uint32_t	data_xfer_len;			/* 14h */
8676029a2d8Ssusans 
8686029a2d8Ssusans 	uint16_t	fis[10];			/* 28h */
8696029a2d8Ssusans 	uint32_t	stp_flags;			/* 3C */
8706029a2d8Ssusans 	union megasas_sgl	sgl;			/* 40 */
8716029a2d8Ssusans };
8726029a2d8Ssusans 
8736029a2d8Ssusans union megasas_frame {
8746029a2d8Ssusans 	struct megasas_header		hdr;
8756029a2d8Ssusans 	struct megasas_init_frame	init;
8766029a2d8Ssusans 	struct megasas_io_frame		io;
8776029a2d8Ssusans 	struct megasas_pthru_frame	pthru;
8786029a2d8Ssusans 	struct megasas_dcmd_frame	dcmd;
8796029a2d8Ssusans 	struct megasas_abort_frame	abort;
8806029a2d8Ssusans 	struct megasas_smp_frame	smp;
8816029a2d8Ssusans 	struct megasas_stp_frame	stp;
8826029a2d8Ssusans 
8836029a2d8Ssusans 	uint8_t		raw_bytes[64];
8846029a2d8Ssusans };
8856029a2d8Ssusans 
8866029a2d8Ssusans union megasas_evt_class_locale {
8876029a2d8Ssusans 	struct {
8886029a2d8Ssusans 		uint16_t	locale;
8896029a2d8Ssusans 		uint8_t		reserved;
8906029a2d8Ssusans 		int8_t		class;
8916029a2d8Ssusans 	} members;
8926029a2d8Ssusans 
8936029a2d8Ssusans 	uint32_t	word;
8946029a2d8Ssusans };
8956029a2d8Ssusans 
8966029a2d8Ssusans struct megasas_evt_log_info {
8976029a2d8Ssusans 	uint32_t	newest_seq_num;
8986029a2d8Ssusans 	uint32_t	oldest_seq_num;
8996029a2d8Ssusans 	uint32_t	clear_seq_num;
9006029a2d8Ssusans 	uint32_t	shutdown_seq_num;
9016029a2d8Ssusans 	uint32_t	boot_seq_num;
9026029a2d8Ssusans };
9036029a2d8Ssusans 
9046029a2d8Ssusans struct megasas_progress {
9056029a2d8Ssusans 	uint16_t	progress;
9066029a2d8Ssusans 	uint16_t	elapsed_seconds;
9076029a2d8Ssusans };
9086029a2d8Ssusans 
9096029a2d8Ssusans struct megasas_evtarg_ld {
9106029a2d8Ssusans 	uint16_t	target_id;
9116029a2d8Ssusans 	uint8_t		ld_index;
9126029a2d8Ssusans 	uint8_t		reserved;
9136029a2d8Ssusans };
9146029a2d8Ssusans 
9156029a2d8Ssusans struct megasas_evtarg_pd {
9166029a2d8Ssusans 	uint16_t	device_id;
9176029a2d8Ssusans 	uint8_t		encl_index;
9186029a2d8Ssusans 	uint8_t		slot_number;
9196029a2d8Ssusans };
9206029a2d8Ssusans 
9216029a2d8Ssusans struct megasas_evt_detail {
9226029a2d8Ssusans 	uint32_t	seq_num;
9236029a2d8Ssusans 	uint32_t	time_stamp;
9246029a2d8Ssusans 	uint32_t	code;
9256029a2d8Ssusans 	union megasas_evt_class_locale	cl;
9266029a2d8Ssusans 	uint8_t		arg_type;
9276029a2d8Ssusans 	uint8_t		reserved1[15];
9286029a2d8Ssusans 
9296029a2d8Ssusans 	union {
9306029a2d8Ssusans 		struct {
9316029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
9326029a2d8Ssusans 			uint8_t				cdb_length;
9336029a2d8Ssusans 			uint8_t				sense_length;
9346029a2d8Ssusans 			uint8_t				reserved[2];
9356029a2d8Ssusans 			uint8_t				cdb[16];
9366029a2d8Ssusans 			uint8_t				sense[64];
9376029a2d8Ssusans 		} cdbSense;
9386029a2d8Ssusans 
9396029a2d8Ssusans 		struct megasas_evtarg_ld		ld;
9406029a2d8Ssusans 
9416029a2d8Ssusans 		struct {
9426029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9436029a2d8Ssusans 			uint64_t			count;
9446029a2d8Ssusans 		} ld_count;
9456029a2d8Ssusans 
9466029a2d8Ssusans 		struct {
9476029a2d8Ssusans 			uint64_t			lba;
9486029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9496029a2d8Ssusans 		} ld_lba;
9506029a2d8Ssusans 
9516029a2d8Ssusans 		struct {
9526029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9536029a2d8Ssusans 			uint32_t			prevOwner;
9546029a2d8Ssusans 			uint32_t			newOwner;
9556029a2d8Ssusans 		} ld_owner;
9566029a2d8Ssusans 
9576029a2d8Ssusans 		struct {
9586029a2d8Ssusans 			uint64_t			ld_lba;
9596029a2d8Ssusans 			uint64_t			pd_lba;
9606029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9616029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
9626029a2d8Ssusans 		} ld_lba_pd_lba;
9636029a2d8Ssusans 
9646029a2d8Ssusans 		struct {
9656029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9666029a2d8Ssusans 			struct megasas_progress		prog;
9676029a2d8Ssusans 		} ld_prog;
9686029a2d8Ssusans 
9696029a2d8Ssusans 		struct {
9706029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9716029a2d8Ssusans 			uint32_t			prev_state;
9726029a2d8Ssusans 			uint32_t			new_state;
9736029a2d8Ssusans 		} ld_state;
9746029a2d8Ssusans 
9756029a2d8Ssusans 		struct {
9766029a2d8Ssusans 			uint64_t			strip;
9776029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9786029a2d8Ssusans 		} ld_strip;
9796029a2d8Ssusans 
9806029a2d8Ssusans 		struct megasas_evtarg_pd	pd;
9816029a2d8Ssusans 
9826029a2d8Ssusans 		struct {
9836029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
9846029a2d8Ssusans 			uint32_t			err;
9856029a2d8Ssusans 		} pd_err;
9866029a2d8Ssusans 
9876029a2d8Ssusans 		struct {
9886029a2d8Ssusans 			uint64_t			lba;
9896029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
9906029a2d8Ssusans 		} pd_lba;
9916029a2d8Ssusans 
9926029a2d8Ssusans 		struct {
9936029a2d8Ssusans 			uint64_t			lba;
9946029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
9956029a2d8Ssusans 			struct megasas_evtarg_ld	ld;
9966029a2d8Ssusans 		} pd_lba_ld;
9976029a2d8Ssusans 
9986029a2d8Ssusans 		struct {
9996029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
10006029a2d8Ssusans 			struct megasas_progress		prog;
10016029a2d8Ssusans 		} pd_prog;
10026029a2d8Ssusans 
10036029a2d8Ssusans 		struct {
10046029a2d8Ssusans 			struct megasas_evtarg_pd	pd;
10056029a2d8Ssusans 			uint32_t			prevState;
10066029a2d8Ssusans 			uint32_t			newState;
10076029a2d8Ssusans 		} pd_state;
10086029a2d8Ssusans 
10096029a2d8Ssusans 		struct {
10106029a2d8Ssusans 			uint16_t	vendorId;
10116029a2d8Ssusans 			uint16_t	deviceId;
10126029a2d8Ssusans 			uint16_t	subVendorId;
10136029a2d8Ssusans 			uint16_t	subDeviceId;
10146029a2d8Ssusans 		} pci;
10156029a2d8Ssusans 
10166029a2d8Ssusans 		uint32_t	rate;
10176029a2d8Ssusans 		char		str[96];
10186029a2d8Ssusans 
10196029a2d8Ssusans 		struct {
10206029a2d8Ssusans 			uint32_t	rtc;
10216029a2d8Ssusans 			uint32_t	elapsedSeconds;
10226029a2d8Ssusans 		} time;
10236029a2d8Ssusans 
10246029a2d8Ssusans 		struct {
10256029a2d8Ssusans 			uint32_t	ecar;
10266029a2d8Ssusans 			uint32_t	elog;
10276029a2d8Ssusans 			char		str[64];
10286029a2d8Ssusans 		} ecc;
10296029a2d8Ssusans 
10306029a2d8Ssusans 		uint8_t		b[96];
10316029a2d8Ssusans 		uint16_t	s[48];
10326029a2d8Ssusans 		uint32_t	w[24];
10336029a2d8Ssusans 		uint64_t	d[12];
10346029a2d8Ssusans 	} args;
10356029a2d8Ssusans 
10366029a2d8Ssusans 	char	description[128];
10376029a2d8Ssusans 
10386029a2d8Ssusans };
10396029a2d8Ssusans 
10406029a2d8Ssusans /* only 63 are usable by the application */
10416029a2d8Ssusans #define	MAX_LOGICAL_DRIVES			64
10426029a2d8Ssusans /* only 255 physical devices may be used */
10436029a2d8Ssusans #define	MAX_PHYSICAL_DEVICES			256
10446029a2d8Ssusans #define	MAX_PD_PER_ENCLOSURE			64
10456029a2d8Ssusans /* maximum disks per array */
10466029a2d8Ssusans #define	MAX_ROW_SIZE				32
10476029a2d8Ssusans /* maximum spans per logical drive */
10486029a2d8Ssusans #define	MAX_SPAN_DEPTH				8
10496029a2d8Ssusans /* maximum number of arrays a hot spare may be dedicated to */
10506029a2d8Ssusans #define	MAX_ARRAYS_DEDICATED			16
10516029a2d8Ssusans /* maximum number of arrays which may exist */
10526029a2d8Ssusans #define	MAX_ARRAYS				128
10536029a2d8Ssusans /* maximum number of foreign configs that may ha managed at once */
10546029a2d8Ssusans #define	MAX_FOREIGN_CONFIGS			8
10556029a2d8Ssusans /* maximum spares (global and dedicated combined) */
10566029a2d8Ssusans #define	MAX_SPARES_FOR_THE_CONTROLLER		MAX_PHYSICAL_DEVICES
10576029a2d8Ssusans /* maximum possible Target IDs (i.e. 0 to 63) */
10586029a2d8Ssusans #define	MAX_TARGET_ID				63
10596029a2d8Ssusans /* maximum number of supported enclosures */
10606029a2d8Ssusans #define	MAX_ENCLOSURES				32
10616029a2d8Ssusans /* maximum number of PHYs per controller */
10626029a2d8Ssusans #define	MAX_PHYS_PER_CONTROLLER			16
10636029a2d8Ssusans /* maximum number of LDs per array (due to DDF limitations) */
10646029a2d8Ssusans #define	MAX_LDS_PER_ARRAY			16
10656029a2d8Ssusans 
10666029a2d8Ssusans /*
10676029a2d8Ssusans  * -----------------------------------------------------------------------------
10686029a2d8Ssusans  * -----------------------------------------------------------------------------
10696029a2d8Ssusans  *
10706029a2d8Ssusans  * Logical Drive commands
10716029a2d8Ssusans  *
10726029a2d8Ssusans  * -----------------------------------------------------------------------------
10736029a2d8Ssusans  * -----------------------------------------------------------------------------
10746029a2d8Ssusans  */
10756029a2d8Ssusans #define	MR_DCMD_LD	0x03000000,	/* Logical Device (LD) opcodes */
10766029a2d8Ssusans 
10776029a2d8Ssusans /*
10786029a2d8Ssusans  * Input:	dcmd.opcode	- MR_DCMD_LD_GET_LIST
10796029a2d8Ssusans  *		dcmd.mbox	- reserved
10806029a2d8Ssusans  *		dcmd.sge IN	- ptr to returned MR_LD_LIST structure
10816029a2d8Ssusans  * Desc:	Return the logical drive list structure
10826029a2d8Ssusans  * Status:	No error
10836029a2d8Ssusans  */
10846029a2d8Ssusans 
10856029a2d8Ssusans /*
10866029a2d8Ssusans  * defines the logical drive reference structure
10876029a2d8Ssusans  */
10886029a2d8Ssusans typedef	union _MR_LD_REF {	/* LD reference structure */
10896029a2d8Ssusans 	struct {
10906029a2d8Ssusans 		uint8_t	targetId; /* LD target id (0 to MAX_TARGET_ID) */
10916029a2d8Ssusans 		uint8_t	reserved; /* reserved to make in line with MR_PD_REF */
10926029a2d8Ssusans 		uint16_t seqNum;  /* Sequence Number */
10936029a2d8Ssusans 	} ld_ref;
10946029a2d8Ssusans 	uint32_t ref;		/* shorthand reference to full 32-bits */
10956029a2d8Ssusans } MR_LD_REF;			/* 4 bytes */
10966029a2d8Ssusans 
10976029a2d8Ssusans /*
10986029a2d8Ssusans  * defines the logical drive list structure
10996029a2d8Ssusans  */
11006029a2d8Ssusans typedef struct _MR_LD_LIST {
11016029a2d8Ssusans 	uint32_t	ldCount;	/* number of LDs */
11026029a2d8Ssusans 	uint32_t	reserved;	/* pad to 8-byte boundary */
11036029a2d8Ssusans 	struct {
11046029a2d8Ssusans 		MR_LD_REF ref;		/* LD reference */
11056029a2d8Ssusans 		uint8_t	state;		/* current LD state (MR_LD_STATE) */
11066029a2d8Ssusans 		uint8_t	reserved[3];	/* pad to 8-byte boundary */
11076029a2d8Ssusans 		uint64_t size;		/* LD size */
11086029a2d8Ssusans 	} ldList[MAX_LOGICAL_DRIVES];
11096029a2d8Ssusans } MR_LD_LIST;
11106029a2d8Ssusans /* 4 + 4 + (MAX_LOGICAL_DRIVES * 16), for 40LD it is = 648 bytes */
11116029a2d8Ssusans 
11127ddfa2acSSusan Scheufele #pragma pack()
11137ddfa2acSSusan Scheufele 
11146029a2d8Ssusans #define	DMA_OBJ_ALLOCATED	1
11156029a2d8Ssusans #define	DMA_OBJ_REALLOCATED	2
11166029a2d8Ssusans #define	DMA_OBJ_FREED		3
11176029a2d8Ssusans 
11186029a2d8Ssusans /*
11196029a2d8Ssusans  * dma_obj_t	- Our DMA object
11206029a2d8Ssusans  * @param buffer	: kernel virtual address
11216029a2d8Ssusans  * @param size		: size of the data to be allocated
11226029a2d8Ssusans  * @param acc_handle	: access handle
11236029a2d8Ssusans  * @param dma_handle	: dma handle
11246029a2d8Ssusans  * @param dma_cookie	: scatter-gather list
11256029a2d8Ssusans  * @param dma_attr	: dma attributes for this buffer
11266029a2d8Ssusans  *
11276029a2d8Ssusans  * Our DMA object. The caller must initialize the size and dma attributes
11286029a2d8Ssusans  * (dma_attr) fields before allocating the resources.
11296029a2d8Ssusans  */
11306029a2d8Ssusans typedef struct {
11316029a2d8Ssusans 	caddr_t			buffer;
11326029a2d8Ssusans 	uint32_t		size;
11336029a2d8Ssusans 	ddi_acc_handle_t	acc_handle;
11346029a2d8Ssusans 	ddi_dma_handle_t	dma_handle;
11356029a2d8Ssusans 	ddi_dma_cookie_t	dma_cookie[MEGASAS_MAX_SGE_CNT];
11366029a2d8Ssusans 	ddi_dma_attr_t		dma_attr;
11376029a2d8Ssusans 	uint8_t			status;
11386029a2d8Ssusans } dma_obj_t;
11396029a2d8Ssusans 
11406029a2d8Ssusans struct megasas_instance {
11416029a2d8Ssusans 	uint32_t	*producer;
11426029a2d8Ssusans 	uint32_t	*consumer;
11436029a2d8Ssusans 
11446029a2d8Ssusans 	uint32_t	*reply_queue;
11456029a2d8Ssusans 	dma_obj_t	mfi_internal_dma_obj;
11466029a2d8Ssusans 
11476029a2d8Ssusans 	uint8_t		init_id;
11486029a2d8Ssusans 	uint8_t		reserved[3];
11496029a2d8Ssusans 
11506029a2d8Ssusans 	uint16_t	max_num_sge;
11516029a2d8Ssusans 	uint16_t	max_fw_cmds;
11526029a2d8Ssusans 	uint32_t	max_sectors_per_req;
11536029a2d8Ssusans 
11546029a2d8Ssusans 	struct megasas_cmd	**cmd_list;
11556029a2d8Ssusans 
11566029a2d8Ssusans 	mlist_t		cmd_pool_list;
11576029a2d8Ssusans 	kmutex_t	cmd_pool_mtx;
11586029a2d8Ssusans 
11596029a2d8Ssusans 	mlist_t		cmd_pend_list;
11606029a2d8Ssusans 	kmutex_t	cmd_pend_mtx;
11616029a2d8Ssusans 
11626029a2d8Ssusans 	dma_obj_t	mfi_evt_detail_obj;
11636029a2d8Ssusans 	struct megasas_cmd	*aen_cmd;
11646029a2d8Ssusans 
11656029a2d8Ssusans 	uint32_t	aen_seq_num;
11666029a2d8Ssusans 	uint32_t	aen_class_locale_word;
11676029a2d8Ssusans 
11686029a2d8Ssusans 	scsi_hba_tran_t		*tran;
11696029a2d8Ssusans 
11706029a2d8Ssusans 	kcondvar_t	int_cmd_cv;
11716029a2d8Ssusans 	kmutex_t	int_cmd_mtx;
11726029a2d8Ssusans 
11736029a2d8Ssusans 	kcondvar_t	aen_cmd_cv;
11746029a2d8Ssusans 	kmutex_t	aen_cmd_mtx;
11756029a2d8Ssusans 
11766029a2d8Ssusans 	kcondvar_t	abort_cmd_cv;
11776029a2d8Ssusans 	kmutex_t	abort_cmd_mtx;
11786029a2d8Ssusans 
11796029a2d8Ssusans 	dev_info_t		*dip;
11806029a2d8Ssusans 	ddi_acc_handle_t	pci_handle;
11816029a2d8Ssusans 
11826029a2d8Ssusans 	timeout_id_t	timeout_id;
11836029a2d8Ssusans 	uint32_t	unique_id;
11846029a2d8Ssusans 	uint16_t	fw_outstanding;
11856029a2d8Ssusans 	caddr_t		regmap;
11866029a2d8Ssusans 	ddi_acc_handle_t	regmap_handle;
11876029a2d8Ssusans 	uint8_t		isr_level;
11886029a2d8Ssusans 	ddi_iblock_cookie_t	iblock_cookie;
11896029a2d8Ssusans 	ddi_iblock_cookie_t	soft_iblock_cookie;
11906029a2d8Ssusans 	ddi_softintr_t		soft_intr_id;
11916029a2d8Ssusans 	uint8_t		softint_running;
11926029a2d8Ssusans 	kmutex_t	completed_pool_mtx;
11936029a2d8Ssusans 	mlist_t		completed_pool_list;
11946029a2d8Ssusans 
11956029a2d8Ssusans 	caddr_t		internal_buf;
11966029a2d8Ssusans 	uint32_t	internal_buf_dmac_add;
11976029a2d8Ssusans 	uint32_t	internal_buf_size;
11986029a2d8Ssusans 
11996029a2d8Ssusans 	uint16_t	vendor_id;
12006029a2d8Ssusans 	uint16_t	device_id;
12016029a2d8Ssusans 	uint16_t	subsysvid;
12026029a2d8Ssusans 	uint16_t	subsysid;
12036029a2d8Ssusans 	int		baseaddress;
12046029a2d8Ssusans 	char		iocnode[16];
12056029a2d8Ssusans 
12062fa451d9SYu Wu - Sun Microsystems - Beijing China 	int		fm_capabilities;
12072fa451d9SYu Wu - Sun Microsystems - Beijing China 
12086029a2d8Ssusans 	struct megasas_func_ptr	*func_ptr;
12096029a2d8Ssusans };
12106029a2d8Ssusans 
12116029a2d8Ssusans struct megasas_func_ptr {
12126029a2d8Ssusans 	int (*read_fw_status_reg)(struct megasas_instance *);
12136029a2d8Ssusans 	void (*issue_cmd)(struct megasas_cmd *, struct megasas_instance *);
12146029a2d8Ssusans 	int (*issue_cmd_in_sync_mode)(struct megasas_instance *,
12156029a2d8Ssusans 	    struct megasas_cmd *);
12166029a2d8Ssusans 	int (*issue_cmd_in_poll_mode)(struct megasas_instance *,
12176029a2d8Ssusans 	    struct megasas_cmd *);
12186029a2d8Ssusans 	void (*enable_intr)(struct megasas_instance *);
12196029a2d8Ssusans 	void (*disable_intr)(struct megasas_instance *);
12206029a2d8Ssusans 	int (*intr_ack)(struct megasas_instance *);
12216029a2d8Ssusans };
12226029a2d8Ssusans 
12236029a2d8Ssusans /*
12246029a2d8Ssusans  * ### Helper routines ###
12256029a2d8Ssusans  */
12266029a2d8Ssusans 
12276029a2d8Ssusans /*
12286029a2d8Ssusans  * con_log() - console log routine
12296029a2d8Ssusans  * @param level		: indicates the severity of the message.
12306029a2d8Ssusans  * @fparam mt		: format string
12316029a2d8Ssusans  *
12326029a2d8Ssusans  * con_log displays the error messages on the console based on the current
12336029a2d8Ssusans  * debug level. Also it attaches the appropriate kernel severity level with
12346029a2d8Ssusans  * the message.
12356029a2d8Ssusans  *
12366029a2d8Ssusans  *
12377ddfa2acSSusan Scheufele  * console messages debug levels
12386029a2d8Ssusans  */
12396029a2d8Ssusans #define	CL_ANN		0	/* print unconditionally, announcements */
12406029a2d8Ssusans #define	CL_ANN1		1	/* No o/p  */
12416029a2d8Ssusans #define	CL_DLEVEL1	2	/* debug level 1, informative */
12426029a2d8Ssusans #define	CL_DLEVEL2	3	/* debug level 2, verbose */
12436029a2d8Ssusans #define	CL_DLEVEL3	4	/* debug level 3, very verbose */
12446029a2d8Ssusans 
12456029a2d8Ssusans #ifdef __SUNPRO_C
12466029a2d8Ssusans #define	__func__ ""
12476029a2d8Ssusans #endif
12486029a2d8Ssusans 
12496029a2d8Ssusans #if DEBUG
12506029a2d8Ssusans #define	con_log(level, fmt) { if (debug_level_g >= level) cmn_err fmt; }
12516029a2d8Ssusans #else
12526029a2d8Ssusans #define	con_log(level, fmt)
12536029a2d8Ssusans #endif /* DEBUG */
12546029a2d8Ssusans 
12556029a2d8Ssusans /* byte-ordering macros */
12566029a2d8Ssusans #ifdef __sparc
12576029a2d8Ssusans #define	host_to_le16(s) ((s) & 0xFF) << 8 | ((s) & 0xFF00) >> 8
12586029a2d8Ssusans #else
12596029a2d8Ssusans #define	host_to_le16(s) (s)
12606029a2d8Ssusans #endif
12616029a2d8Ssusans 
12626029a2d8Ssusans #ifdef __sparc
12636029a2d8Ssusans #define	host_to_le32(l) (((l) & 0xFF) << 24 | ((l) & 0xFF00) << 8 | \
12646029a2d8Ssusans 		((l) & 0xFF0000) >> 8 | ((l) & 0xFF000000) >> 24)
12656029a2d8Ssusans #else
12666029a2d8Ssusans #define	host_to_le32(l) (l)
12676029a2d8Ssusans #endif
12686029a2d8Ssusans 
12696029a2d8Ssusans #ifdef __sparc
12706029a2d8Ssusans #define	host_to_le64(ull) ((host_to_le32(((ull) & 0xFFFFFFFF)) << 32) | \
12716029a2d8Ssusans 		(host_to_le32((((ull) & 0xFFFFFFFF00000000) >> 32))))
12726029a2d8Ssusans #else
12736029a2d8Ssusans #define	host_to_le64(ull) (ull)
12746029a2d8Ssusans #endif
12756029a2d8Ssusans 
12766029a2d8Ssusans /*
12776029a2d8Ssusans  * ### SCSA definitions ###
12786029a2d8Ssusans  */
12796029a2d8Ssusans #define	PKT2TGT(pkt)	((pkt)->pkt_address.a_target)
12806029a2d8Ssusans #define	PKT2LUN(pkt)	((pkt)->pkt_address.a_lun)
12816029a2d8Ssusans #define	PKT2TRAN(pkt)	((pkt)->pkt_adress.a_hba_tran)
12826029a2d8Ssusans #define	ADDR2TRAN(ap)	((ap)->a_hba_tran)
12836029a2d8Ssusans 
12846029a2d8Ssusans #define	TRAN2MEGA(tran)	(struct megasas_instance *)(tran)->tran_hba_private)
12856029a2d8Ssusans #define	ADDR2MEGA(ap)	(TRAN2MEGA(ADDR2TRAN(ap))
12866029a2d8Ssusans 
12876029a2d8Ssusans #define	PKT2CMD(pkt)	((struct scsa_cmd *)(pkt)->pkt_ha_private)
12886029a2d8Ssusans #define	CMD2PKT(sp)	((sp)->cmd_pkt)
12896029a2d8Ssusans #define	PKT2REQ(pkt)	(&(PKT2CMD(pkt)->request))
12906029a2d8Ssusans 
12916029a2d8Ssusans #define	CMD2ADDR(cmd)	(&CMD2PKT(cmd)->pkt_address)
12926029a2d8Ssusans #define	CMD2TRAN(cmd)	(CMD2PKT(cmd)->pkt_address.a_hba_tran)
12936029a2d8Ssusans #define	CMD2MEGA(cmd)	(TRAN2MEGA(CMD2TRAN(cmd)))
12946029a2d8Ssusans 
12956029a2d8Ssusans #define	CFLAG_DMAVALID		0x0001	/* requires a dma operation */
12966029a2d8Ssusans #define	CFLAG_DMASEND		0x0002	/* Transfer from the device */
12976029a2d8Ssusans #define	CFLAG_CONSISTENT	0x0040	/* consistent data transfer */
12986029a2d8Ssusans 
12996029a2d8Ssusans /*
13006029a2d8Ssusans  * ### Data structures for ioctl inteface and internal commands ###
13016029a2d8Ssusans  */
13026029a2d8Ssusans 
13036029a2d8Ssusans /*
13046029a2d8Ssusans  * Data direction flags
13056029a2d8Ssusans  */
13066029a2d8Ssusans #define	UIOC_RD		0x00001
13076029a2d8Ssusans #define	UIOC_WR		0x00002
13086029a2d8Ssusans 
13096029a2d8Ssusans #define	SCP2HOST(scp)		(scp)->device->host	/* to host */
13106029a2d8Ssusans #define	SCP2HOSTDATA(scp)	SCP2HOST(scp)->hostdata	/* to soft state */
13116029a2d8Ssusans #define	SCP2CHANNEL(scp)	(scp)->device->channel	/* to channel */
13126029a2d8Ssusans #define	SCP2TARGET(scp)		(scp)->device->id	/* to target */
13136029a2d8Ssusans #define	SCP2LUN(scp)		(scp)->device->lun	/* to LUN */
13146029a2d8Ssusans 
13156029a2d8Ssusans #define	SCSIHOST2ADAP(host)	(((caddr_t *)(host->hostdata))[0])
13166029a2d8Ssusans #define	SCP2ADAPTER(scp)				\
13176029a2d8Ssusans 	(struct megasas_instance *)SCSIHOST2ADAP(SCP2HOST(scp))
13186029a2d8Ssusans 
13196029a2d8Ssusans #define	MEGADRV_IS_LOGICAL_SCSA(instance, acmd)		\
13206029a2d8Ssusans 	(acmd->device_id < MEGADRV_MAX_LD) ? 1 : 0
13216029a2d8Ssusans #define	MEGADRV_IS_LOGICAL(ap)				\
13226029a2d8Ssusans 	(ap->a_target < MEGADRV_MAX_LD) ? 1 : 0
13236029a2d8Ssusans #define	MAP_DEVICE_ID(instance, ap)			\
13246029a2d8Ssusans 	(ap->a_target % MEGADRV_MAX_LD)
13256029a2d8Ssusans /*
13266029a2d8Ssusans  * #define MAP_DEVICE_ID(instance,ap)			\
13276029a2d8Ssusans  *       (ap->a_target)
13286029a2d8Ssusans  */
13296029a2d8Ssusans 
13306029a2d8Ssusans #define	HIGH_LEVEL_INTR			1
13316029a2d8Ssusans #define	NORMAL_LEVEL_INTR		0
13326029a2d8Ssusans 
13336029a2d8Ssusans /*
13346029a2d8Ssusans  * scsa_cmd  - Per-command mega private data
13356029a2d8Ssusans  * @param cmd_dmahandle		:  dma handle
13366029a2d8Ssusans  * @param cmd_dmacookies	: current dma cookies
13376029a2d8Ssusans  * @param cmd_pkt		:  scsi_pkt reference
13386029a2d8Ssusans  * @param cmd_dmacount		:  dma count
13396029a2d8Ssusans  * @param cmd_cookie		:  next cookie
13406029a2d8Ssusans  * @param cmd_ncookies		:  cookies per window
13416029a2d8Ssusans  * @param cmd_cookiecnt		:  cookies per sub-win
13426029a2d8Ssusans  * @param cmd_nwin		:  number of dma windows
13436029a2d8Ssusans  * @param cmd_curwin		:  current dma window
13446029a2d8Ssusans  * @param cmd_dma_offset	:  current window offset
13456029a2d8Ssusans  * @param cmd_dma_len		:  current window length
13466029a2d8Ssusans  * @param cmd_flags		:  private flags
13476029a2d8Ssusans  * @param cmd_cdblen		:  length of cdb
13486029a2d8Ssusans  * @param cmd_scblen		:  length of scb
13496029a2d8Ssusans  * @param cmd_buf		:  command buffer
13506029a2d8Ssusans  * @param channel		:  channel for scsi sub-system
13516029a2d8Ssusans  * @param target		:  target for scsi sub-system
13526029a2d8Ssusans  * @param lun			:  LUN for scsi sub-system
13536029a2d8Ssusans  *
13546029a2d8Ssusans  * - Allocated at same time as scsi_pkt by scsi_hba_pkt_alloc(9E)
13556029a2d8Ssusans  * - Pointed to by pkt_ha_private field in scsi_pkt
13566029a2d8Ssusans  */
13576029a2d8Ssusans struct scsa_cmd {
13586029a2d8Ssusans 	ddi_dma_handle_t	cmd_dmahandle;
13596029a2d8Ssusans 	ddi_dma_cookie_t	cmd_dmacookies[MEGASAS_MAX_SGE_CNT];
13606029a2d8Ssusans 	struct scsi_pkt		*cmd_pkt;
13616029a2d8Ssusans 	ulong_t			cmd_dmacount;
13626029a2d8Ssusans 	uint_t			cmd_cookie;
13636029a2d8Ssusans 	uint_t			cmd_ncookies;
13646029a2d8Ssusans 	uint_t			cmd_cookiecnt;
13656029a2d8Ssusans 	uint_t			cmd_nwin;
13666029a2d8Ssusans 	uint_t			cmd_curwin;
13676029a2d8Ssusans 	off_t			cmd_dma_offset;
13686029a2d8Ssusans 	ulong_t			cmd_dma_len;
13696029a2d8Ssusans 	ulong_t			cmd_flags;
13706029a2d8Ssusans 	uint_t			cmd_cdblen;
13716029a2d8Ssusans 	uint_t			cmd_scblen;
13726029a2d8Ssusans 	struct buf		*cmd_buf;
13736029a2d8Ssusans 	ushort_t		device_id;
13746029a2d8Ssusans 	uchar_t			islogical;
13756029a2d8Ssusans 	uchar_t			lun;
13766029a2d8Ssusans };
13776029a2d8Ssusans 
13786029a2d8Ssusans 
13796029a2d8Ssusans struct megasas_cmd {
13806029a2d8Ssusans 	union megasas_frame	*frame;
13816029a2d8Ssusans 	uint32_t		frame_phys_addr;
13826029a2d8Ssusans 	uint8_t			*sense;
13836029a2d8Ssusans 	uint32_t		sense_phys_addr;
13846029a2d8Ssusans 	dma_obj_t		frame_dma_obj;
13856029a2d8Ssusans 	uint8_t			frame_dma_obj_status;
13866029a2d8Ssusans 
13876029a2d8Ssusans 	uint32_t		index;
13886029a2d8Ssusans 	uint8_t			sync_cmd;
13896029a2d8Ssusans 	uint8_t			cmd_status;
13906029a2d8Ssusans 	uint16_t		abort_aen;
13916029a2d8Ssusans 	mlist_t			list;
13926029a2d8Ssusans 	uint32_t		frame_count;
13936029a2d8Ssusans 	struct scsa_cmd		*cmd;
13946029a2d8Ssusans 	struct scsi_pkt		*pkt;
13956029a2d8Ssusans };
13966029a2d8Ssusans 
13976029a2d8Ssusans #define	MAX_MGMT_ADAPTERS			1024
13986029a2d8Ssusans #define	IOC_SIGNATURE				"MEGA-SAS"
13996029a2d8Ssusans 
14006029a2d8Ssusans #define	IOC_CMD_FIRMWARE			0x0
14016029a2d8Ssusans #define	MR_DRIVER_IOCTL_COMMON			0xF0010000
14026029a2d8Ssusans #define	MR_DRIVER_IOCTL_DRIVER_VERSION		0xF0010100
14036029a2d8Ssusans #define	MR_DRIVER_IOCTL_PCI_INFORMATION		0xF0010200
14046029a2d8Ssusans #define	MR_DRIVER_IOCTL_MEGARAID_STATISTICS	0xF0010300
14056029a2d8Ssusans 
14066029a2d8Ssusans 
14076029a2d8Ssusans #define	MR_MAX_SENSE_LENGTH			32
14086029a2d8Ssusans 
14096029a2d8Ssusans struct megasas_mgmt_info {
14106029a2d8Ssusans 
14116029a2d8Ssusans 	uint16_t			count;
14126029a2d8Ssusans 	struct megasas_instance		*instance[MAX_MGMT_ADAPTERS];
14136029a2d8Ssusans 	uint16_t			map[MAX_MGMT_ADAPTERS];
14146029a2d8Ssusans 	int				max_index;
14156029a2d8Ssusans };
14166029a2d8Ssusans 
14176029a2d8Ssusans #pragma pack(1)
14186029a2d8Ssusans 
14196029a2d8Ssusans struct megasas_drv_ver {
14206029a2d8Ssusans 	uint8_t	signature[12];
14216029a2d8Ssusans 	uint8_t	os_name[16];
14226029a2d8Ssusans 	uint8_t	os_ver[12];
14236029a2d8Ssusans 	uint8_t	drv_name[20];
14246029a2d8Ssusans 	uint8_t	drv_ver[32];
14256029a2d8Ssusans 	uint8_t	drv_rel_date[20];
14266029a2d8Ssusans };
14276029a2d8Ssusans 
14286029a2d8Ssusans #define	PCI_TYPE0_ADDRESSES		6
14296029a2d8Ssusans #define	PCI_TYPE1_ADDRESSES		2
14306029a2d8Ssusans #define	PCI_TYPE2_ADDRESSES		5
14316029a2d8Ssusans 
14326029a2d8Ssusans struct megasas_pci_common_header {
14336029a2d8Ssusans 	uint16_t	vendorID;		/* (ro) */
14346029a2d8Ssusans 	uint16_t	deviceID;		/* (ro) */
14356029a2d8Ssusans 	uint16_t	command;		/* Device control */
14366029a2d8Ssusans 	uint16_t	status;
14376029a2d8Ssusans 	uint8_t		revisionID;		/* (ro) */
14386029a2d8Ssusans 	uint8_t		progIf;			/* (ro) */
14396029a2d8Ssusans 	uint8_t		subClass;		/* (ro) */
14406029a2d8Ssusans 	uint8_t		baseClass;		/* (ro) */
14416029a2d8Ssusans 	uint8_t		cacheLineSize;		/* (ro+) */
14426029a2d8Ssusans 	uint8_t		latencyTimer;		/* (ro+) */
14436029a2d8Ssusans 	uint8_t		headerType;		/* (ro) */
14446029a2d8Ssusans 	uint8_t		bist;			/* Built in self test */
14456029a2d8Ssusans 
14466029a2d8Ssusans 	union {
14476029a2d8Ssusans 	    struct {
14486029a2d8Ssusans 		uint32_t	baseAddresses[PCI_TYPE0_ADDRESSES];
14496029a2d8Ssusans 		uint32_t	cis;
14506029a2d8Ssusans 		uint16_t	subVendorID;
14516029a2d8Ssusans 		uint16_t	subSystemID;
14526029a2d8Ssusans 		uint32_t	romBaseAddress;
14536029a2d8Ssusans 		uint8_t		capabilitiesPtr;
14546029a2d8Ssusans 		uint8_t		reserved1[3];
14556029a2d8Ssusans 		uint32_t	reserved2;
14566029a2d8Ssusans 		uint8_t		interruptLine;
14576029a2d8Ssusans 		uint8_t		interruptPin;	/* (ro) */
14586029a2d8Ssusans 		uint8_t		minimumGrant;	/* (ro) */
14596029a2d8Ssusans 		uint8_t		maximumLatency;	/* (ro) */
14606029a2d8Ssusans 	    } type_0;
14616029a2d8Ssusans 
14626029a2d8Ssusans 	    struct {
14636029a2d8Ssusans 		uint32_t	baseAddresses[PCI_TYPE1_ADDRESSES];
14646029a2d8Ssusans 		uint8_t		primaryBus;
14656029a2d8Ssusans 		uint8_t		secondaryBus;
14666029a2d8Ssusans 		uint8_t		subordinateBus;
14676029a2d8Ssusans 		uint8_t		secondaryLatency;
14686029a2d8Ssusans 		uint8_t		ioBase;
14696029a2d8Ssusans 		uint8_t		ioLimit;
14706029a2d8Ssusans 		uint16_t	secondaryStatus;
14716029a2d8Ssusans 		uint16_t	memoryBase;
14726029a2d8Ssusans 		uint16_t	memoryLimit;
14736029a2d8Ssusans 		uint16_t	prefetchBase;
14746029a2d8Ssusans 		uint16_t	prefetchLimit;
14756029a2d8Ssusans 		uint32_t	prefetchBaseUpper32;
14766029a2d8Ssusans 		uint32_t	prefetchLimitUpper32;
14776029a2d8Ssusans 		uint16_t	ioBaseUpper16;
14786029a2d8Ssusans 		uint16_t	ioLimitUpper16;
14796029a2d8Ssusans 		uint8_t		capabilitiesPtr;
14806029a2d8Ssusans 		uint8_t		reserved1[3];
14816029a2d8Ssusans 		uint32_t	romBaseAddress;
14826029a2d8Ssusans 		uint8_t		interruptLine;
14836029a2d8Ssusans 		uint8_t		interruptPin;
14846029a2d8Ssusans 		uint16_t	bridgeControl;
14856029a2d8Ssusans 	    } type_1;
14866029a2d8Ssusans 
14876029a2d8Ssusans 	    struct {
14886029a2d8Ssusans 		uint32_t	socketRegistersBaseAddress;
14896029a2d8Ssusans 		uint8_t		capabilitiesPtr;
14906029a2d8Ssusans 		uint8_t		reserved;
14916029a2d8Ssusans 		uint16_t	secondaryStatus;
14926029a2d8Ssusans 		uint8_t		primaryBus;
14936029a2d8Ssusans 		uint8_t		secondaryBus;
14946029a2d8Ssusans 		uint8_t		subordinateBus;
14956029a2d8Ssusans 		uint8_t		secondaryLatency;
14966029a2d8Ssusans 		struct {
14976029a2d8Ssusans 			uint32_t	base;
14986029a2d8Ssusans 			uint32_t	limit;
14996029a2d8Ssusans 		} range[PCI_TYPE2_ADDRESSES-1];
15006029a2d8Ssusans 		uint8_t		interruptLine;
15016029a2d8Ssusans 		uint8_t		interruptPin;
15026029a2d8Ssusans 		uint16_t	bridgeControl;
15036029a2d8Ssusans 	    } type_2;
15046029a2d8Ssusans 	} header;
15056029a2d8Ssusans };
15066029a2d8Ssusans 
15076029a2d8Ssusans struct megasas_pci_link_capability {
15086029a2d8Ssusans 	union {
15096029a2d8Ssusans 	    struct {
15106029a2d8Ssusans 		uint32_t linkSpeed		:4;
15116029a2d8Ssusans 		uint32_t linkWidth		:6;
15126029a2d8Ssusans 		uint32_t aspmSupport		:2;
15136029a2d8Ssusans 		uint32_t losExitLatency		:3;
15146029a2d8Ssusans 		uint32_t l1ExitLatency		:3;
15156029a2d8Ssusans 		uint32_t rsvdp			:6;
15166029a2d8Ssusans 		uint32_t portNumber		:8;
15176029a2d8Ssusans 	    } bits;
15186029a2d8Ssusans 
15196029a2d8Ssusans 	    uint32_t asUlong;
15206029a2d8Ssusans 	} cap;
15216029a2d8Ssusans 
15226029a2d8Ssusans };
15236029a2d8Ssusans 
15246029a2d8Ssusans struct megasas_pci_link_status_capability {
15256029a2d8Ssusans 	union {
15266029a2d8Ssusans 	    struct {
15276029a2d8Ssusans 		uint16_t linkSpeed		:4;
15286029a2d8Ssusans 		uint16_t negotiatedLinkWidth	:6;
15296029a2d8Ssusans 		uint16_t linkTrainingError	:1;
15306029a2d8Ssusans 		uint16_t linkTraning		:1;
15316029a2d8Ssusans 		uint16_t slotClockConfig	:1;
15326029a2d8Ssusans 		uint16_t rsvdZ			:3;
15336029a2d8Ssusans 	    } bits;
15346029a2d8Ssusans 
15356029a2d8Ssusans 	    uint16_t asUshort;
15366029a2d8Ssusans 	} stat_cap;
15376029a2d8Ssusans 
15386029a2d8Ssusans 	uint16_t reserved;
15396029a2d8Ssusans 
15406029a2d8Ssusans };
15416029a2d8Ssusans 
15426029a2d8Ssusans struct megasas_pci_capabilities {
15436029a2d8Ssusans 	struct megasas_pci_link_capability	linkCapability;
15446029a2d8Ssusans 	struct megasas_pci_link_status_capability linkStatusCapability;
15456029a2d8Ssusans };
15466029a2d8Ssusans 
15476029a2d8Ssusans struct megasas_pci_information
15486029a2d8Ssusans {
15496029a2d8Ssusans 	uint32_t		busNumber;
15506029a2d8Ssusans 	uint8_t			deviceNumber;
15516029a2d8Ssusans 	uint8_t			functionNumber;
15526029a2d8Ssusans 	uint8_t			interruptVector;
15536029a2d8Ssusans 	uint8_t			reserved;
15546029a2d8Ssusans 	struct megasas_pci_common_header pciHeaderInfo;
15556029a2d8Ssusans 	struct megasas_pci_capabilities capability;
15566029a2d8Ssusans 	uint8_t			reserved2[32];
15576029a2d8Ssusans };
15586029a2d8Ssusans 
15596029a2d8Ssusans struct megasas_ioctl {
15606029a2d8Ssusans 	uint16_t	version;
15616029a2d8Ssusans 	uint16_t	controller_id;
15626029a2d8Ssusans 	uint8_t		signature[8];
15636029a2d8Ssusans 	uint32_t	reserved_1;
15646029a2d8Ssusans 	uint32_t	control_code;
15656029a2d8Ssusans 	uint32_t	reserved_2[2];
15666029a2d8Ssusans 	uint8_t		frame[64];
15676029a2d8Ssusans 	union megasas_sgl_frame	sgl_frame;
15686029a2d8Ssusans 	uint8_t		sense_buff[MR_MAX_SENSE_LENGTH];
15696029a2d8Ssusans 	uint8_t		data[1];
15706029a2d8Ssusans };
15716029a2d8Ssusans 
15726029a2d8Ssusans struct megasas_aen {
15736029a2d8Ssusans 	uint16_t	host_no;
15746029a2d8Ssusans 	uint16_t	cmd_status;
15756029a2d8Ssusans 	uint32_t	seq_num;
15766029a2d8Ssusans 	uint32_t	class_locale_word;
15776029a2d8Ssusans };
15786029a2d8Ssusans 
15796029a2d8Ssusans #pragma pack()
15806029a2d8Ssusans 
15816029a2d8Ssusans #ifndef	DDI_VENDOR_LSI
15826029a2d8Ssusans #define	DDI_VENDOR_LSI		"LSI"
15836029a2d8Ssusans #endif /* DDI_VENDOR_LSI */
15846029a2d8Ssusans 
15856029a2d8Ssusans static int	megasas_getinfo(dev_info_t *, ddi_info_cmd_t,  void *, void **);
15866029a2d8Ssusans static int	megasas_attach(dev_info_t *, ddi_attach_cmd_t);
15876029a2d8Ssusans static int	megasas_reset(dev_info_t *, ddi_reset_cmd_t);
15886029a2d8Ssusans static int	megasas_detach(dev_info_t *, ddi_detach_cmd_t);
15896029a2d8Ssusans static int	megasas_open(dev_t *, int, int, cred_t *);
15906029a2d8Ssusans static int	megasas_close(dev_t, int, int, cred_t *);
15916029a2d8Ssusans static int	megasas_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
15926029a2d8Ssusans 
15936029a2d8Ssusans static int	megasas_tran_tgt_init(dev_info_t *, dev_info_t *,
15946029a2d8Ssusans 		    scsi_hba_tran_t *, struct scsi_device *);
15956029a2d8Ssusans static struct scsi_pkt *megasas_tran_init_pkt(struct scsi_address *, register
15966029a2d8Ssusans 		    struct scsi_pkt *, struct buf *, int, int, int, int,
15976029a2d8Ssusans 		    int (*)(), caddr_t);
15986029a2d8Ssusans static int	megasas_tran_start(struct scsi_address *,
15996029a2d8Ssusans 		    register struct scsi_pkt *);
16006029a2d8Ssusans static int	megasas_tran_abort(struct scsi_address *, struct scsi_pkt *);
16016029a2d8Ssusans static int	megasas_tran_reset(struct scsi_address *, int);
16026029a2d8Ssusans static int	megasas_tran_bus_reset(dev_info_t *, int);
16036029a2d8Ssusans static int	megasas_tran_getcap(struct scsi_address *, char *, int);
16046029a2d8Ssusans static int	megasas_tran_setcap(struct scsi_address *, char *, int, int);
16056029a2d8Ssusans static void	megasas_tran_destroy_pkt(struct scsi_address *,
16066029a2d8Ssusans 		    struct scsi_pkt *);
16076029a2d8Ssusans static void	megasas_tran_dmafree(struct scsi_address *, struct scsi_pkt *);
16086029a2d8Ssusans static void	megasas_tran_sync_pkt(struct scsi_address *, struct scsi_pkt *);
16096029a2d8Ssusans static int	megasas_tran_quiesce(dev_info_t *dip);
16106029a2d8Ssusans static int	megasas_tran_unquiesce(dev_info_t *dip);
16117ddfa2acSSusan Scheufele static uint_t	megasas_isr();
16127ddfa2acSSusan Scheufele static uint_t	megasas_softintr();
16136029a2d8Ssusans 
16146029a2d8Ssusans static int	init_mfi(struct megasas_instance *);
16152fa451d9SYu Wu - Sun Microsystems - Beijing China static int	mega_free_dma_obj(struct megasas_instance *, dma_obj_t);
16166029a2d8Ssusans static int	mega_alloc_dma_obj(struct megasas_instance *, dma_obj_t *);
16176029a2d8Ssusans static struct megasas_cmd *get_mfi_pkt(struct megasas_instance *);
16186029a2d8Ssusans static void	return_mfi_pkt(struct megasas_instance *,
16196029a2d8Ssusans 		    struct megasas_cmd *);
16207ddfa2acSSusan Scheufele 
16216029a2d8Ssusans static void	free_space_for_mfi(struct megasas_instance *);
16226029a2d8Ssusans static void	free_additional_dma_buffer(struct megasas_instance *);
16236029a2d8Ssusans static int	alloc_additional_dma_buffer(struct megasas_instance *);
16246029a2d8Ssusans static int	read_fw_status_reg_xscale(struct megasas_instance *);
16256029a2d8Ssusans static int	read_fw_status_reg_ppc(struct megasas_instance *);
16266029a2d8Ssusans static void	issue_cmd_xscale(struct megasas_cmd *,
16276029a2d8Ssusans 		    struct megasas_instance *);
16286029a2d8Ssusans static void	issue_cmd_ppc(struct megasas_cmd *, struct megasas_instance *);
16296029a2d8Ssusans static int	issue_cmd_in_poll_mode_xscale(struct megasas_instance *,
16306029a2d8Ssusans 		    struct megasas_cmd *);
16316029a2d8Ssusans static int	issue_cmd_in_poll_mode_ppc(struct megasas_instance *,
16326029a2d8Ssusans 		    struct megasas_cmd *);
16336029a2d8Ssusans static int	issue_cmd_in_sync_mode_xscale(struct megasas_instance *,
16346029a2d8Ssusans 		    struct megasas_cmd *);
16356029a2d8Ssusans static int	issue_cmd_in_sync_mode_ppc(struct megasas_instance *,
16366029a2d8Ssusans 		    struct megasas_cmd *);
16376029a2d8Ssusans static void	enable_intr_xscale(struct megasas_instance *);
16386029a2d8Ssusans static void	enable_intr_ppc(struct megasas_instance *);
16396029a2d8Ssusans static void	disable_intr_xscale(struct megasas_instance *);
16406029a2d8Ssusans static void	disable_intr_ppc(struct megasas_instance *);
16416029a2d8Ssusans static int	intr_ack_xscale(struct megasas_instance *);
16426029a2d8Ssusans static int	intr_ack_ppc(struct megasas_instance *);
16436029a2d8Ssusans static int	mfi_state_transition_to_ready(struct megasas_instance *);
16446029a2d8Ssusans static void	destroy_mfi_frame_pool(struct megasas_instance *);
16456029a2d8Ssusans static int	create_mfi_frame_pool(struct megasas_instance *);
16466029a2d8Ssusans static int	megasas_dma_alloc(struct megasas_instance *, struct scsi_pkt *,
16476029a2d8Ssusans 		    struct buf *, int, int (*)());
16486029a2d8Ssusans static int	megasas_dma_move(struct megasas_instance *,
16496029a2d8Ssusans 			struct scsi_pkt *, struct buf *);
16506029a2d8Ssusans static void	flush_cache(struct megasas_instance *instance);
16516029a2d8Ssusans static void	display_scsi_inquiry(caddr_t);
16526029a2d8Ssusans static int	start_mfi_aen(struct megasas_instance *instance);
16536029a2d8Ssusans static int	handle_drv_ioctl(struct megasas_instance *instance,
16546029a2d8Ssusans 		    struct megasas_ioctl *ioctl, int mode);
16556029a2d8Ssusans static int	handle_mfi_ioctl(struct megasas_instance *instance,
16566029a2d8Ssusans 		    struct megasas_ioctl *ioctl, int mode);
16576029a2d8Ssusans static int	handle_mfi_aen(struct megasas_instance *instance,
16586029a2d8Ssusans 		    struct megasas_aen *aen);
16596029a2d8Ssusans static void	fill_up_drv_ver(struct megasas_drv_ver *dv);
16606029a2d8Ssusans static struct megasas_cmd *build_cmd(struct megasas_instance *instance,
16616029a2d8Ssusans 		    struct scsi_address *ap, struct scsi_pkt *pkt,
16626029a2d8Ssusans 		    uchar_t *cmd_done);
16636029a2d8Ssusans static int	wait_for_outstanding(struct megasas_instance *instance);
16646029a2d8Ssusans static int	register_mfi_aen(struct megasas_instance *instance,
16656029a2d8Ssusans 		    uint32_t seq_num, uint32_t class_locale_word);
16666029a2d8Ssusans static int	issue_mfi_pthru(struct megasas_instance *instance, struct
16676029a2d8Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16686029a2d8Ssusans static int	issue_mfi_dcmd(struct megasas_instance *instance, struct
16696029a2d8Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16706029a2d8Ssusans static int	issue_mfi_smp(struct megasas_instance *instance, struct
16716029a2d8Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16726029a2d8Ssusans static int	issue_mfi_stp(struct megasas_instance *instance, struct
16736029a2d8Ssusans 		    megasas_ioctl *ioctl, struct megasas_cmd *cmd, int mode);
16746029a2d8Ssusans static int	abort_aen_cmd(struct megasas_instance *instance,
16756029a2d8Ssusans 		    struct megasas_cmd *cmd_to_abort);
16766029a2d8Ssusans 
16772fa451d9SYu Wu - Sun Microsystems - Beijing China static int	megasas_common_check(struct megasas_instance *instance,
16782fa451d9SYu Wu - Sun Microsystems - Beijing China 		    struct  megasas_cmd *cmd);
16792fa451d9SYu Wu - Sun Microsystems - Beijing China static void	megasas_fm_init(struct megasas_instance *instance);
16802fa451d9SYu Wu - Sun Microsystems - Beijing China static void	megasas_fm_fini(struct megasas_instance *instance);
16812fa451d9SYu Wu - Sun Microsystems - Beijing China static int	megasas_fm_error_cb(dev_info_t *, ddi_fm_error_t *,
16822fa451d9SYu Wu - Sun Microsystems - Beijing China 		    const void *);
16832fa451d9SYu Wu - Sun Microsystems - Beijing China static void	megasas_fm_ereport(struct megasas_instance *instance,
16842fa451d9SYu Wu - Sun Microsystems - Beijing China 		    char *detail);
16852fa451d9SYu Wu - Sun Microsystems - Beijing China static int	megasas_check_dma_handle(ddi_dma_handle_t handle);
16862fa451d9SYu Wu - Sun Microsystems - Beijing China static int	megasas_check_acc_handle(ddi_acc_handle_t handle);
16872fa451d9SYu Wu - Sun Microsystems - Beijing China 
16886029a2d8Ssusans #ifdef	__cplusplus
16896029a2d8Ssusans }
16906029a2d8Ssusans #endif
16916029a2d8Ssusans 
16926029a2d8Ssusans #endif /* _MEGARAID_SAS_H_ */
1693