| /* |
| * mr_sas.h: header for mr_sas |
| * |
| * Solaris MegaRAID driver for SAS2.0 controllers |
| * Copyright (c) 2008-2012, LSI Logic Corporation. |
| * All rights reserved. |
| * |
| * Version: |
| * Author: |
| * Swaminathan K S |
| * Arun Chandrashekhar |
| * Manju R |
| * Rasheed |
| * Shakeel Bukhari |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, |
| * this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation |
| * and/or other materials provided with the distribution. |
| * |
| * 3. Neither the name of the author nor the names of its contributors may be |
| * used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
| * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
| * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
| * DAMAGE. |
| */ |
| |
| /* |
| * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. |
| * Copyright 2013 Nexenta Systems, Inc. All rights reserved. |
| * Copyright 2015 Garrett D'Amore <garrett@damore.org> |
| * Copyright 2017 Citrus IT Limited. All rights reserved. |
| */ |
| |
| #ifndef _MR_SAS_H_ |
| #define _MR_SAS_H_ |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| #include <sys/scsi/scsi.h> |
| #include "mr_sas_list.h" |
| #include "ld_pd_map.h" |
| |
| /* |
| * MegaRAID SAS2.0 Driver meta data |
| */ |
| #define MRSAS_VERSION "6.503.00.00ILLUMOS-20170524" |
| #define MRSAS_RELDATE "May 24, 2017" |
| |
| #define MRSAS_TRUE 1 |
| #define MRSAS_FALSE 0 |
| |
| #define ADAPTER_RESET_NOT_REQUIRED 0 |
| #define ADAPTER_RESET_REQUIRED 1 |
| |
| /* |
| * MegaRAID SAS2.0 device id conversion definitions. |
| */ |
| #define INST2LSIRDCTL(x) ((x) << INST_MINOR_SHIFT) |
| #define MRSAS_GET_BOUNDARY_ALIGNED_LEN(len, new_len, boundary_len) { \ |
| int rem; \ |
| rem = (len / boundary_len); \ |
| if ((rem * boundary_len) != len) { \ |
| new_len = len + ((rem + 1) * boundary_len - len); \ |
| } else { \ |
| new_len = len; \ |
| } \ |
| } |
| |
| |
| /* |
| * MegaRAID SAS2.0 supported controllers |
| */ |
| |
| /* Skinny */ |
| #define PCI_DEVICE_ID_LSI_SKINNY 0x0071 |
| #define PCI_DEVICE_ID_LSI_SKINNY_NEW 0x0073 |
| /* Liberator series (Gen2) */ |
| #define PCI_DEVICE_ID_LSI_2108VDE 0x0078 |
| #define PCI_DEVICE_ID_LSI_2108V 0x0079 |
| /* Thunderbolt series */ |
| #define PCI_DEVICE_ID_LSI_TBOLT 0x005b |
| /* Invader series (Gen3) */ |
| #define PCI_DEVICE_ID_LSI_INVADER 0x005d |
| #define PCI_DEVICE_ID_LSI_FURY 0x005f |
| #define PCI_DEVICE_ID_LSI_INTRUDER 0x00ce |
| #define PCI_DEVICE_ID_LSI_INTRUDER_24 0x00cf |
| #define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052 |
| #define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053 |
| /* Ventura series not yet supported */ |
| |
| /* |
| * Register Index for 2108 Controllers. |
| */ |
| #define REGISTER_SET_IO_2108 (2) |
| |
| #define MRSAS_MAX_SGE_CNT 0x50 |
| #define MRSAS_APP_RESERVED_CMDS 32 |
| #define MRSAS_APP_MIN_RESERVED_CMDS 4 |
| |
| #define MRSAS_IOCTL_DRIVER 0x12341234 |
| #define MRSAS_IOCTL_FIRMWARE 0x12345678 |
| #define MRSAS_IOCTL_AEN 0x87654321 |
| |
| #define MRSAS_1_SECOND 1000000 |
| |
| #define UNCONFIGURED_GOOD 0x0 |
| #define PD_SYSTEM 0x40 |
| #define MR_EVT_PD_STATE_CHANGE 0x0072 |
| #define MR_EVT_PD_REMOVED_EXT 0x00f8 |
| #define MR_EVT_PD_INSERTED_EXT 0x00f7 |
| #define MR_DCMD_PD_GET_INFO 0x02020000 |
| #define MRSAS_TBOLT_PD_LUN 1 |
| #define MRSAS_TBOLT_PD_TGT_MAX 255 |
| #define MRSAS_TBOLT_GET_PD_MAX(s) ((s)->mr_tbolt_pd_max) |
| |
| /* Raid Context Flags */ |
| #define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT 0x4 |
| #define MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_MASK 0x30 |
| typedef enum MR_RAID_FLAGS_IO_SUB_TYPE { |
| MR_RAID_FLAGS_IO_SUB_TYPE_NONE = 0, |
| MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD = 1 |
| } MR_RAID_FLAGS_IO_SUB_TYPE; |
| |
| /* Dynamic Enumeration Flags */ |
| #define MRSAS_LD_LUN 0 |
| #define WWN_STRLEN 17 |
| #define LD_SYNC_BIT 1 |
| #define LD_SYNC_SHIFT 14 |
| /* ThunderBolt (TB) specific */ |
| #define MRSAS_THUNDERBOLT_MSG_SIZE 256 |
| #define MRSAS_THUNDERBOLT_MAX_COMMANDS 1024 |
| #define MRSAS_THUNDERBOLT_MAX_REPLY_COUNT 1024 |
| #define MRSAS_THUNDERBOLT_REPLY_SIZE 8 |
| #define MRSAS_THUNDERBOLT_MAX_CHAIN_COUNT 1 |
| |
| #define MPI2_FUNCTION_PASSTHRU_IO_REQUEST 0xF0 |
| #define MPI2_FUNCTION_LD_IO_REQUEST 0xF1 |
| |
| #define MR_EVT_LD_FAST_PATH_IO_STATUS_CHANGED (0xFFFF) |
| |
| #define MR_INTERNAL_MFI_FRAMES_SMID 1 |
| #define MR_CTRL_EVENT_WAIT_SMID 2 |
| #define MR_INTERNAL_DRIVER_RESET_SMID 3 |
| |
| |
| /* |
| * ===================================== |
| * MegaRAID SAS2.0 MFI firmware definitions |
| * ===================================== |
| */ |
| /* |
| * MFI stands for MegaRAID SAS2.0 FW Interface. This is just a moniker for |
| * protocol between the software and firmware. Commands are issued using |
| * "message frames" |
| */ |
| |
| /* |
| * FW posts its state in upper 4 bits of outbound_msg_0 register |
| */ |
| #define MFI_STATE_MASK 0xF0000000 |
| #define MFI_STATE_UNDEFINED 0x00000000 |
| #define MFI_STATE_BB_INIT 0x10000000 |
| #define MFI_STATE_FW_INIT 0x40000000 |
| #define MFI_STATE_WAIT_HANDSHAKE 0x60000000 |
| #define MFI_STATE_FW_INIT_2 0x70000000 |
| #define MFI_STATE_DEVICE_SCAN 0x80000000 |
| #define MFI_STATE_BOOT_MESSAGE_PENDING 0x90000000 |
| #define MFI_STATE_FLUSH_CACHE 0xA0000000 |
| #define MFI_STATE_READY 0xB0000000 |
| #define MFI_STATE_OPERATIONAL 0xC0000000 |
| #define MFI_STATE_FAULT 0xF0000000 |
| |
| #define MRMFI_FRAME_SIZE 64 |
| |
| /* |
| * During FW init, clear pending cmds & reset state using inbound_msg_0 |
| * |
| * ABORT : Abort all pending cmds |
| * READY : Move from OPERATIONAL to READY state; discard queue info |
| * MFIMODE : Discard (possible) low MFA posted in 64-bit mode (??) |
| * CLR_HANDSHAKE: FW is waiting for HANDSHAKE from BIOS or Driver |
| */ |
| #define MFI_INIT_ABORT 0x00000001 |
| #define MFI_INIT_READY 0x00000002 |
| #define MFI_INIT_MFIMODE 0x00000004 |
| #define MFI_INIT_CLEAR_HANDSHAKE 0x00000008 |
| #define MFI_INIT_HOTPLUG 0x00000010 |
| #define MFI_STOP_ADP 0x00000020 |
| #define MFI_RESET_FLAGS MFI_INIT_READY|MFI_INIT_MFIMODE|MFI_INIT_ABORT |
| |
| /* |
| * MFI frame flags |
| */ |
| #define MFI_FRAME_POST_IN_REPLY_QUEUE 0x0000 |
| #define MFI_FRAME_DONT_POST_IN_REPLY_QUEUE 0x0001 |
| #define MFI_FRAME_SGL32 0x0000 |
| #define MFI_FRAME_SGL64 0x0002 |
| #define MFI_FRAME_SENSE32 0x0000 |
| #define MFI_FRAME_SENSE64 0x0004 |
| #define MFI_FRAME_DIR_NONE 0x0000 |
| #define MFI_FRAME_DIR_WRITE 0x0008 |
| #define MFI_FRAME_DIR_READ 0x0010 |
| #define MFI_FRAME_DIR_BOTH 0x0018 |
| #define MFI_FRAME_IEEE 0x0020 |
| |
| /* |
| * Definition for cmd_status |
| */ |
| #define MFI_CMD_STATUS_POLL_MODE 0xFF |
| #define MFI_CMD_STATUS_SYNC_MODE 0xFF |
| |
| /* |
| * MFI command opcodes |
| */ |
| #define MFI_CMD_OP_INIT 0x00 |
| #define MFI_CMD_OP_LD_READ 0x01 |
| #define MFI_CMD_OP_LD_WRITE 0x02 |
| #define MFI_CMD_OP_LD_SCSI 0x03 |
| #define MFI_CMD_OP_PD_SCSI 0x04 |
| #define MFI_CMD_OP_DCMD 0x05 |
| #define MFI_CMD_OP_ABORT 0x06 |
| #define MFI_CMD_OP_SMP 0x07 |
| #define MFI_CMD_OP_STP 0x08 |
| |
| #define MR_DCMD_CTRL_GET_INFO 0x01010000 |
| |
| #define MR_DCMD_CTRL_CACHE_FLUSH 0x01101000 |
| #define MR_FLUSH_CTRL_CACHE 0x01 |
| #define MR_FLUSH_DISK_CACHE 0x02 |
| |
| #define MR_DCMD_CTRL_SHUTDOWN 0x01050000 |
| #define MRSAS_ENABLE_DRIVE_SPINDOWN 0x01 |
| |
| #define MR_DCMD_CTRL_EVENT_GET_INFO 0x01040100 |
| #define MR_DCMD_CTRL_EVENT_GET 0x01040300 |
| #define MR_DCMD_CTRL_EVENT_WAIT 0x01040500 |
| #define MR_DCMD_LD_GET_PROPERTIES 0x03030000 |
| |
| /* |
| * Solaris Specific MAX values |
| */ |
| #define MAX_SGL 24 |
| |
| /* |
| * MFI command completion codes |
| */ |
| enum MFI_STAT { |
| MFI_STAT_OK = 0x00, |
| MFI_STAT_INVALID_CMD = 0x01, |
| MFI_STAT_INVALID_DCMD = 0x02, |
| MFI_STAT_INVALID_PARAMETER = 0x03, |
| MFI_STAT_INVALID_SEQUENCE_NUMBER = 0x04, |
| MFI_STAT_ABORT_NOT_POSSIBLE = 0x05, |
| MFI_STAT_APP_HOST_CODE_NOT_FOUND = 0x06, |
| MFI_STAT_APP_IN_USE = 0x07, |
| MFI_STAT_APP_NOT_INITIALIZED = 0x08, |
| MFI_STAT_ARRAY_INDEX_INVALID = 0x09, |
| MFI_STAT_ARRAY_ROW_NOT_EMPTY = 0x0a, |
| MFI_STAT_CONFIG_RESOURCE_CONFLICT = 0x0b, |
| MFI_STAT_DEVICE_NOT_FOUND = 0x0c, |
| MFI_STAT_DRIVE_TOO_SMALL = 0x0d, |
| MFI_STAT_FLASH_ALLOC_FAIL = 0x0e, |
| MFI_STAT_FLASH_BUSY = 0x0f, |
| MFI_STAT_FLASH_ERROR = 0x10, |
| MFI_STAT_FLASH_IMAGE_BAD = 0x11, |
| MFI_STAT_FLASH_IMAGE_INCOMPLETE = 0x12, |
| MFI_STAT_FLASH_NOT_OPEN = 0x13, |
| MFI_STAT_FLASH_NOT_STARTED = 0x14, |
| MFI_STAT_FLUSH_FAILED = 0x15, |
| MFI_STAT_HOST_CODE_NOT_FOUNT = 0x16, |
| MFI_STAT_LD_CC_IN_PROGRESS = 0x17, |
| MFI_STAT_LD_INIT_IN_PROGRESS = 0x18, |
| MFI_STAT_LD_LBA_OUT_OF_RANGE = 0x19, |
| MFI_STAT_LD_MAX_CONFIGURED = 0x1a, |
| MFI_STAT_LD_NOT_OPTIMAL = 0x1b, |
| MFI_STAT_LD_RBLD_IN_PROGRESS = 0x1c, |
| MFI_STAT_LD_RECON_IN_PROGRESS = 0x1d, |
| MFI_STAT_LD_WRONG_RAID_LEVEL = 0x1e, |
| MFI_STAT_MAX_SPARES_EXCEEDED = 0x1f, |
| MFI_STAT_MEMORY_NOT_AVAILABLE = 0x20, |
| MFI_STAT_MFC_HW_ERROR = 0x21, |
| MFI_STAT_NO_HW_PRESENT = 0x22, |
| MFI_STAT_NOT_FOUND = 0x23, |
| MFI_STAT_NOT_IN_ENCL = 0x24, |
| MFI_STAT_PD_CLEAR_IN_PROGRESS = 0x25, |
| MFI_STAT_PD_TYPE_WRONG = 0x26, |
| MFI_STAT_PR_DISABLED = 0x27, |
| MFI_STAT_ROW_INDEX_INVALID = 0x28, |
| MFI_STAT_SAS_CONFIG_INVALID_ACTION = 0x29, |
| MFI_STAT_SAS_CONFIG_INVALID_DATA = 0x2a, |
| MFI_STAT_SAS_CONFIG_INVALID_PAGE = 0x2b, |
| MFI_STAT_SAS_CONFIG_INVALID_TYPE = 0x2c, |
| MFI_STAT_SCSI_DONE_WITH_ERROR = 0x2d, |
| MFI_STAT_SCSI_IO_FAILED = 0x2e, |
| MFI_STAT_SCSI_RESERVATION_CONFLICT = 0x2f, |
| MFI_STAT_SHUTDOWN_FAILED = 0x30, |
| MFI_STAT_TIME_NOT_SET = 0x31, |
| MFI_STAT_WRONG_STATE = 0x32, |
| MFI_STAT_LD_OFFLINE = 0x33, |
| MFI_STAT_INVALID_STATUS = 0xFF |
| }; |
| |
| enum MR_EVT_CLASS { |
| MR_EVT_CLASS_DEBUG = -2, |
| MR_EVT_CLASS_PROGRESS = -1, |
| MR_EVT_CLASS_INFO = 0, |
| MR_EVT_CLASS_WARNING = 1, |
| MR_EVT_CLASS_CRITICAL = 2, |
| MR_EVT_CLASS_FATAL = 3, |
| MR_EVT_CLASS_DEAD = 4 |
| }; |
| |
| enum MR_EVT_LOCALE { |
| MR_EVT_LOCALE_LD = 0x0001, |
| MR_EVT_LOCALE_PD = 0x0002, |
| MR_EVT_LOCALE_ENCL = 0x0004, |
| MR_EVT_LOCALE_BBU = 0x0008, |
| MR_EVT_LOCALE_SAS = 0x0010, |
| MR_EVT_LOCALE_CTRL = 0x0020, |
| MR_EVT_LOCALE_CONFIG = 0x0040, |
| MR_EVT_LOCALE_CLUSTER = 0x0080, |
| MR_EVT_LOCALE_ALL = 0xffff |
| }; |
| |
| enum MR_EVT_ARGS { |
| MR_EVT_ARGS_NONE, |
| MR_EVT_ARGS_CDB_SENSE, |
| MR_EVT_ARGS_LD, |
| MR_EVT_ARGS_LD_COUNT, |
| MR_EVT_ARGS_LD_LBA, |
| MR_EVT_ARGS_LD_OWNER, |
| MR_EVT_ARGS_LD_LBA_PD_LBA, |
| MR_EVT_ARGS_LD_PROG, |
| MR_EVT_ARGS_LD_STATE, |
| MR_EVT_ARGS_LD_STRIP, |
| MR_EVT_ARGS_PD, |
| MR_EVT_ARGS_PD_ERR, |
| MR_EVT_ARGS_PD_LBA, |
| MR_EVT_ARGS_PD_LBA_LD, |
| MR_EVT_ARGS_PD_PROG, |
| MR_EVT_ARGS_PD_STATE, |
| MR_EVT_ARGS_PCI, |
| MR_EVT_ARGS_RATE, |
| MR_EVT_ARGS_STR, |
| MR_EVT_ARGS_TIME, |
| MR_EVT_ARGS_ECC |
| }; |
| |
| #define MR_EVT_CFG_CLEARED 0x0004 |
| #define MR_EVT_LD_CREATED 0x008a |
| #define MR_EVT_LD_DELETED 0x008b |
| #define MR_EVT_CFG_FP_CHANGE 0x017B |
| |
| enum LD_STATE { |
| LD_OFFLINE = 0, |
| LD_PARTIALLY_DEGRADED = 1, |
| LD_DEGRADED = 2, |
| LD_OPTIMAL = 3, |
| LD_INVALID = 0xFF |
| }; |
| |
| enum MRSAS_EVT { |
| MRSAS_EVT_CONFIG_TGT = 0, |
| MRSAS_EVT_UNCONFIG_TGT = 1, |
| MRSAS_EVT_UNCONFIG_SMP = 2 |
| }; |
| |
| #define DMA_OBJ_ALLOCATED 1 |
| #define DMA_OBJ_REALLOCATED 2 |
| #define DMA_OBJ_FREED 3 |
| |
| /* |
| * dma_obj_t - Our DMA object |
| * @param buffer : kernel virtual address |
| * @param size : size of the data to be allocated |
| * @param acc_handle : access handle |
| * @param dma_handle : dma handle |
| * @param dma_cookie : scatter-gather list |
| * @param dma_attr : dma attributes for this buffer |
| * |
| * Our DMA object. The caller must initialize the size and dma attributes |
| * (dma_attr) fields before allocating the resources. |
| */ |
| typedef struct { |
| caddr_t buffer; |
| uint32_t size; |
| ddi_acc_handle_t acc_handle; |
| ddi_dma_handle_t dma_handle; |
| ddi_dma_cookie_t dma_cookie[MRSAS_MAX_SGE_CNT]; |
| ddi_dma_attr_t dma_attr; |
| uint8_t status; |
| uint8_t reserved[3]; |
| } dma_obj_t; |
| |
| struct mrsas_eventinfo { |
| struct mrsas_instance *instance; |
| int tgt; |
| int lun; |
| int event; |
| uint64_t wwn; |
| }; |
| |
| struct mrsas_ld { |
| dev_info_t *dip; |
| uint8_t lun_type; |
| uint8_t flag; |
| uint8_t reserved[2]; |
| }; |
| |
| |
| struct mrsas_tbolt_pd { |
| dev_info_t *dip; |
| uint8_t lun_type; |
| uint8_t dev_id; |
| uint8_t flag; |
| uint8_t reserved; |
| }; |
| struct mrsas_tbolt_pd_info { |
| uint16_t deviceId; |
| uint16_t seqNum; |
| uint8_t inquiryData[96]; |
| uint8_t vpdPage83[64]; |
| uint8_t notSupported; |
| uint8_t scsiDevType; |
| uint8_t a; |
| uint8_t device_speed; |
| uint32_t mediaerrcnt; |
| uint32_t other; |
| uint32_t pred; |
| uint32_t lastpred; |
| uint16_t fwState; |
| uint8_t disabled; |
| uint8_t linkspwwd; |
| uint32_t ddfType; |
| struct { |
| uint8_t count; |
| uint8_t isPathBroken; |
| uint8_t connectorIndex[2]; |
| uint8_t reserved[4]; |
| uint64_t sasAddr[2]; |
| uint8_t reserved2[16]; |
| } pathInfo; |
| }; |
| |
| typedef struct mrsas_instance { |
| uint32_t *producer; |
| uint32_t *consumer; |
| |
| uint32_t *reply_queue; |
| dma_obj_t mfi_internal_dma_obj; |
| uint16_t adapterresetinprogress; |
| uint16_t deadadapter; |
| /* ThunderBolt (TB) specific */ |
| dma_obj_t mpi2_frame_pool_dma_obj; |
| dma_obj_t request_desc_dma_obj; |
| dma_obj_t reply_desc_dma_obj; |
| dma_obj_t ld_map_obj[2]; |
| |
| uint8_t init_id; |
| uint8_t flag_ieee; |
| uint8_t disable_online_ctrl_reset; |
| uint8_t fw_fault_count_after_ocr; |
| |
| uint16_t max_num_sge; |
| uint16_t max_fw_cmds; |
| uint32_t max_sectors_per_req; |
| |
| struct mrsas_cmd **cmd_list; |
| |
| mlist_t cmd_pool_list; |
| kmutex_t cmd_pool_mtx; |
| kmutex_t sync_map_mtx; |
| |
| mlist_t app_cmd_pool_list; |
| kmutex_t app_cmd_pool_mtx; |
| mlist_t cmd_app_pool_list; |
| kmutex_t cmd_app_pool_mtx; |
| |
| |
| mlist_t cmd_pend_list; |
| kmutex_t cmd_pend_mtx; |
| |
| dma_obj_t mfi_evt_detail_obj; |
| struct mrsas_cmd *aen_cmd; |
| |
| uint32_t aen_seq_num; |
| uint32_t aen_class_locale_word; |
| |
| scsi_hba_tran_t *tran; |
| |
| kcondvar_t int_cmd_cv; |
| kmutex_t int_cmd_mtx; |
| |
| kcondvar_t aen_cmd_cv; |
| kmutex_t aen_cmd_mtx; |
| |
| kcondvar_t abort_cmd_cv; |
| kmutex_t abort_cmd_mtx; |
| |
| kmutex_t reg_write_mtx; |
| kmutex_t chip_mtx; |
| |
| dev_info_t *dip; |
| ddi_acc_handle_t pci_handle; |
| |
| timeout_id_t timeout_id; |
| uint32_t unique_id; |
| uint16_t fw_outstanding; |
| caddr_t regmap; |
| ddi_acc_handle_t regmap_handle; |
| uint8_t isr_level; |
| ddi_iblock_cookie_t iblock_cookie; |
| ddi_iblock_cookie_t soft_iblock_cookie; |
| ddi_softintr_t soft_intr_id; |
| uint8_t softint_running; |
| uint8_t tbolt_softint_running; |
| kmutex_t completed_pool_mtx; |
| mlist_t completed_pool_list; |
| |
| caddr_t internal_buf; |
| uint32_t internal_buf_dmac_add; |
| uint32_t internal_buf_size; |
| |
| uint16_t vendor_id; |
| uint16_t device_id; |
| uint16_t subsysvid; |
| uint16_t subsysid; |
| int instance; |
| int baseaddress; |
| char iocnode[16]; |
| |
| int fm_capabilities; |
| /* |
| * Driver resources unroll flags. The flag is set for resources that |
| * are needed to be free'd at detach() time. |
| */ |
| struct _unroll { |
| uint8_t softs; /* The software state was allocated. */ |
| uint8_t regs; /* Controller registers mapped. */ |
| uint8_t intr; /* Interrupt handler added. */ |
| uint8_t reqs; /* Request structs allocated. */ |
| uint8_t mutexs; /* Mutex's allocated. */ |
| uint8_t taskq; /* Task q's created. */ |
| uint8_t tran; /* Tran struct allocated */ |
| uint8_t tranSetup; /* Tran attached to the ddi. */ |
| uint8_t devctl; /* Device nodes for cfgadm created. */ |
| uint8_t scsictl; /* Device nodes for cfgadm created. */ |
| uint8_t ioctl; /* Device nodes for ioctl's created. */ |
| uint8_t timer; /* Timer started. */ |
| uint8_t aenPend; /* AEN cmd pending f/w. */ |
| uint8_t mapUpdate_pend; /* LD MAP update cmd pending f/w. */ |
| uint8_t soft_isr; /* Soft interrupt handler allocated. */ |
| uint8_t ldlist_buff; /* Logical disk list allocated. */ |
| uint8_t pdlist_buff; /* Physical disk list allocated. */ |
| uint8_t syncCmd; /* Sync map command allocated. */ |
| uint8_t verBuff; /* 2108 MFI buffer allocated. */ |
| uint8_t alloc_space_mfi; /* Allocated space for 2108 MFI. */ |
| uint8_t alloc_space_mpi2; /* Allocated space for 2208 MPI2. */ |
| } unroll; |
| |
| |
| /* function template pointer */ |
| struct mrsas_function_template *func_ptr; |
| |
| |
| /* MSI interrupts specific */ |
| ddi_intr_handle_t *intr_htable; /* Interrupt handle array */ |
| size_t intr_htable_size; /* Int. handle array size */ |
| int intr_type; |
| int intr_cnt; |
| uint_t intr_pri; |
| int intr_cap; |
| |
| ddi_taskq_t *taskq; |
| struct mrsas_ld *mr_ld_list; |
| kmutex_t config_dev_mtx; |
| /* ThunderBolt (TB) specific */ |
| ddi_softintr_t tbolt_soft_intr_id; |
| |
| uint32_t mr_tbolt_pd_max; |
| struct mrsas_tbolt_pd *mr_tbolt_pd_list; |
| |
| uint8_t fast_path_io; |
| |
| uint8_t skinny; |
| uint8_t tbolt; |
| uint8_t gen3; |
| uint16_t reply_read_index; |
| uint16_t reply_size; /* Single Reply struct size */ |
| uint16_t raid_io_msg_size; /* Single message size */ |
| uint32_t io_request_frames_phy; |
| uint8_t *io_request_frames; |
| /* Virtual address of request desc frame pool */ |
| MRSAS_REQUEST_DESCRIPTOR_UNION *request_message_pool; |
| /* Physical address of request desc frame pool */ |
| uint32_t request_message_pool_phy; |
| /* Virtual address of reply Frame */ |
| MPI2_REPLY_DESCRIPTORS_UNION *reply_frame_pool; |
| /* Physical address of reply Frame */ |
| uint32_t reply_frame_pool_phy; |
| uint8_t *reply_pool_limit; /* Last reply frame address */ |
| /* Physical address of Last reply frame */ |
| uint32_t reply_pool_limit_phy; |
| uint32_t reply_q_depth; /* Reply Queue Depth */ |
| uint8_t max_sge_in_main_msg; |
| uint8_t max_sge_in_chain; |
| uint8_t chain_offset_io_req; |
| uint8_t chain_offset_mpt_msg; |
| MR_FW_RAID_MAP_ALL *ld_map[2]; |
| uint32_t ld_map_phy[2]; |
| uint32_t size_map_info; |
| uint64_t map_id; |
| LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES]; |
| struct mrsas_cmd *map_update_cmd; |
| uint32_t SyncRequired; |
| kmutex_t ocr_flags_mtx; |
| dma_obj_t drv_ver_dma_obj; |
| } mrsas_t; |
| |
| |
| /* |
| * Function templates for various controller specific functions |
| */ |
| struct mrsas_function_template { |
| uint32_t (*read_fw_status_reg)(struct mrsas_instance *); |
| void (*issue_cmd)(struct mrsas_cmd *, struct mrsas_instance *); |
| int (*issue_cmd_in_sync_mode)(struct mrsas_instance *, |
| struct mrsas_cmd *); |
| int (*issue_cmd_in_poll_mode)(struct mrsas_instance *, |
| struct mrsas_cmd *); |
| void (*enable_intr)(struct mrsas_instance *); |
| void (*disable_intr)(struct mrsas_instance *); |
| int (*intr_ack)(struct mrsas_instance *); |
| int (*init_adapter)(struct mrsas_instance *); |
| /* int (*reset_adapter)(struct mrsas_instance *); */ |
| }; |
| |
| /* |
| * ### Helper routines ### |
| */ |
| |
| /* |
| * con_log() - console log routine |
| * @param level : indicates the severity of the message. |
| * @fparam mt : format string |
| * |
| * con_log displays the error messages on the console based on the current |
| * debug level. Also it attaches the appropriate kernel severity level with |
| * the message. |
| * |
| * |
| * console messages debug levels |
| */ |
| #define CL_NONE 0 /* No debug information */ |
| #define CL_ANN 1 /* print unconditionally, announcements */ |
| #define CL_ANN1 2 /* No-op */ |
| #define CL_DLEVEL1 3 /* debug level 1, informative */ |
| #define CL_DLEVEL2 4 /* debug level 2, verbose */ |
| #define CL_DLEVEL3 5 /* debug level 3, very verbose */ |
| |
| #ifdef __SUNPRO_C |
| #define __func__ "" |
| #endif |
| |
| #define con_log(level, fmt) { if (debug_level_g >= level) cmn_err fmt; } |
| |
| /* |
| * ### SCSA definitions ### |
| */ |
| #define PKT2TGT(pkt) ((pkt)->pkt_address.a_target) |
| #define PKT2LUN(pkt) ((pkt)->pkt_address.a_lun) |
| #define PKT2TRAN(pkt) ((pkt)->pkt_adress.a_hba_tran) |
| #define ADDR2TRAN(ap) ((ap)->a_hba_tran) |
| |
| #define TRAN2MR(tran) (struct mrsas_instance *)(tran)->tran_hba_private) |
| #define ADDR2MR(ap) (TRAN2MR(ADDR2TRAN(ap)) |
| |
| #define PKT2CMD(pkt) ((struct scsa_cmd *)(pkt)->pkt_ha_private) |
| #define CMD2PKT(sp) ((sp)->cmd_pkt) |
| #define PKT2REQ(pkt) (&(PKT2CMD(pkt)->request)) |
| |
| #define CMD2ADDR(cmd) (&CMD2PKT(cmd)->pkt_address) |
| #define CMD2TRAN(cmd) (CMD2PKT(cmd)->pkt_address.a_hba_tran) |
| #define CMD2MR(cmd) (TRAN2MR(CMD2TRAN(cmd))) |
| |
| #define CFLAG_DMAVALID 0x0001 /* requires a dma operation */ |
| #define CFLAG_DMASEND 0x0002 /* Transfer from the device */ |
| #define CFLAG_CONSISTENT 0x0040 /* consistent data transfer */ |
| |
| /* |
| * ### Data structures for ioctl inteface and internal commands ### |
| */ |
| |
| /* |
| * Data direction flags |
| */ |
| #define UIOC_RD 0x00001 |
| #define UIOC_WR 0x00002 |
| |
| #define SCP2HOST(scp) (scp)->device->host /* to host */ |
| #define SCP2HOSTDATA(scp) SCP2HOST(scp)->hostdata /* to soft state */ |
| #define SCP2CHANNEL(scp) (scp)->device->channel /* to channel */ |
| #define SCP2TARGET(scp) (scp)->device->id /* to target */ |
| #define SCP2LUN(scp) (scp)->device->lun /* to LUN */ |
| |
| #define SCSIHOST2ADAP(host) (((caddr_t *)(host->hostdata))[0]) |
| #define SCP2ADAPTER(scp) \ |
| (struct mrsas_instance *)SCSIHOST2ADAP(SCP2HOST(scp)) |
| |
| #define MRDRV_IS_LOGICAL_SCSA(instance, acmd) \ |
| (acmd->device_id < MRDRV_MAX_LD) ? 1 : 0 |
| #define MRDRV_IS_LOGICAL(ap) \ |
| ((ap->a_target < MRDRV_MAX_LD) && (ap->a_lun == 0)) ? 1 : 0 |
| #define MAP_DEVICE_ID(instance, ap) \ |
| (ap->a_target) |
| |
| #define HIGH_LEVEL_INTR 1 |
| #define NORMAL_LEVEL_INTR 0 |
| |
| #define IO_TIMEOUT_VAL 0 |
| #define IO_RETRY_COUNT 3 |
| #define MAX_FW_RESET_COUNT 3 |
| /* |
| * scsa_cmd - Per-command mr private data |
| * @param cmd_dmahandle : dma handle |
| * @param cmd_dmacookies : current dma cookies |
| * @param cmd_pkt : scsi_pkt reference |
| * @param cmd_dmacount : dma count |
| * @param cmd_cookie : next cookie |
| * @param cmd_ncookies : cookies per window |
| * @param cmd_cookiecnt : cookies per sub-win |
| * @param cmd_nwin : number of dma windows |
| * @param cmd_curwin : current dma window |
| * @param cmd_dma_offset : current window offset |
| * @param cmd_dma_len : current window length |
| * @param cmd_flags : private flags |
| * @param cmd_cdblen : length of cdb |
| * @param cmd_scblen : length of scb |
| * @param cmd_buf : command buffer |
| * @param channel : channel for scsi sub-system |
| * @param target : target for scsi sub-system |
| * @param lun : LUN for scsi sub-system |
| * |
| * - Allocated at same time as scsi_pkt by scsi_hba_pkt_alloc(9E) |
| * - Pointed to by pkt_ha_private field in scsi_pkt |
| */ |
| struct scsa_cmd { |
| ddi_dma_handle_t cmd_dmahandle; |
| ddi_dma_cookie_t cmd_dmacookies[MRSAS_MAX_SGE_CNT]; |
| struct scsi_pkt *cmd_pkt; |
| ulong_t cmd_dmacount; |
| uint_t cmd_cookie; |
| uint_t cmd_ncookies; |
| uint_t cmd_cookiecnt; |
| uint_t cmd_nwin; |
| uint_t cmd_curwin; |
| off_t cmd_dma_offset; |
| ulong_t cmd_dma_len; |
| ulong_t cmd_flags; |
| uint_t cmd_cdblen; |
| uint_t cmd_scblen; |
| struct buf *cmd_buf; |
| ushort_t device_id; |
| uchar_t islogical; |
| uchar_t lun; |
| struct mrsas_device *mrsas_dev; |
| }; |
| |
| |
| struct mrsas_cmd { |
| /* |
| * ThunderBolt(TB) We would be needing to have a placeholder |
| * for RAID_MSG_IO_REQUEST inside this structure. We are |
| * supposed to embed the mr_frame inside the RAID_MSG and post |
| * it down to the firmware. |
| */ |
| union mrsas_frame *frame; |
| uint32_t frame_phys_addr; |
| uint8_t *sense; |
| uint8_t *sense1; |
| uint32_t sense_phys_addr; |
| uint32_t sense_phys_addr1; |
| dma_obj_t frame_dma_obj; |
| uint8_t frame_dma_obj_status; |
| uint32_t index; |
| uint8_t sync_cmd; |
| uint8_t cmd_status; |
| uint16_t abort_aen; |
| mlist_t list; |
| uint32_t frame_count; |
| struct scsa_cmd *cmd; |
| struct scsi_pkt *pkt; |
| Mpi2RaidSCSIIORequest_t *scsi_io_request; |
| Mpi2SGEIOUnion_t *sgl; |
| uint32_t sgl_phys_addr; |
| uint32_t scsi_io_request_phys_addr; |
| MRSAS_REQUEST_DESCRIPTOR_UNION *request_desc; |
| uint16_t SMID; |
| uint16_t retry_count_for_ocr; |
| uint16_t drv_pkt_time; |
| uint16_t load_balance_flag; |
| |
| }; |
| |
| #define MAX_MGMT_ADAPTERS 1024 |
| #define IOC_SIGNATURE "MR-SAS" |
| |
| #define IOC_CMD_FIRMWARE 0x0 |
| #define MRSAS_DRIVER_IOCTL_COMMON 0xF0010000 |
| #define MRSAS_DRIVER_IOCTL_DRIVER_VERSION 0xF0010100 |
| #define MRSAS_DRIVER_IOCTL_PCI_INFORMATION 0xF0010200 |
| #define MRSAS_DRIVER_IOCTL_MRRAID_STATISTICS 0xF0010300 |
| |
| |
| #define MRSAS_MAX_SENSE_LENGTH 32 |
| |
| struct mrsas_mgmt_info { |
| |
| uint16_t count; |
| struct mrsas_instance *instance[MAX_MGMT_ADAPTERS]; |
| uint16_t map[MAX_MGMT_ADAPTERS]; |
| int max_index; |
| }; |
| |
| |
| #pragma pack(1) |
| /* |
| * SAS controller properties |
| */ |
| struct mrsas_ctrl_prop { |
| uint16_t seq_num; |
| uint16_t pred_fail_poll_interval; |
| uint16_t intr_throttle_count; |
| uint16_t intr_throttle_timeouts; |
| |
| uint8_t rebuild_rate; |
| uint8_t patrol_read_rate; |
| uint8_t bgi_rate; |
| uint8_t cc_rate; |
| uint8_t recon_rate; |
| |
| uint8_t cache_flush_interval; |
| |
| uint8_t spinup_drv_count; |
| uint8_t spinup_delay; |
| |
| uint8_t cluster_enable; |
| uint8_t coercion_mode; |
| uint8_t alarm_enable; |
| |
| uint8_t reserved_1[13]; |
| uint32_t on_off_properties; |
| uint8_t reserved_4[28]; |
| }; |
| |
| |
| /* |
| * SAS controller information |
| */ |
| struct mrsas_ctrl_info { |
| /* PCI device information */ |
| struct { |
| uint16_t vendor_id; |
| uint16_t device_id; |
| uint16_t sub_vendor_id; |
| uint16_t sub_device_id; |
| uint8_t reserved[24]; |
| } pci; |
| |
| /* Host interface information */ |
| struct { |
| uint8_t PCIX : 1; |
| uint8_t PCIE : 1; |
| uint8_t iSCSI : 1; |
| uint8_t SAS_3G : 1; |
| uint8_t reserved_0 : 4; |
| uint8_t reserved_1[6]; |
| uint8_t port_count; |
| uint64_t port_addr[8]; |
| } host_interface; |
| |
| /* Device (backend) interface information */ |
| struct { |
| uint8_t SPI : 1; |
| uint8_t SAS_3G : 1; |
| uint8_t SATA_1_5G : 1; |
| uint8_t SATA_3G : 1; |
| uint8_t reserved_0 : 4; |
| uint8_t reserved_1[6]; |
| uint8_t port_count; |
| uint64_t port_addr[8]; |
| } device_interface; |
| |
| /* List of components residing in flash. All str are null terminated */ |
| uint32_t image_check_word; |
| uint32_t image_component_count; |
| |
| struct { |
| char name[8]; |
| char version[32]; |
| char build_date[16]; |
| char built_time[16]; |
| } image_component[8]; |
| |
| /* |
| * List of flash components that have been flashed on the card, but |
| * are not in use, pending reset of the adapter. This list will be |
| * empty if a flash operation has not occurred. All stings are null |
| * terminated |
| */ |
| uint32_t pending_image_component_count; |
| |
| struct { |
| char name[8]; |
| char version[32]; |
| char build_date[16]; |
| char build_time[16]; |
| } pending_image_component[8]; |
| |
| uint8_t max_arms; |
| uint8_t max_spans; |
| uint8_t max_arrays; |
| uint8_t max_lds; |
| |
| char product_name[80]; |
| char serial_no[32]; |
| |
| /* |
| * Other physical/controller/operation information. Indicates the |
| * presence of the hardware |
| */ |
| struct { |
| uint32_t bbu : 1; |
| uint32_t alarm : 1; |
| uint32_t nvram : 1; |
| uint32_t uart : 1; |
| uint32_t reserved : 28; |
| } hw_present; |
| |
| uint32_t current_fw_time; |
| |
| /* Maximum data transfer sizes */ |
| uint16_t max_concurrent_cmds; |
| uint16_t max_sge_count; |
| uint32_t max_request_size; |
| |
| /* Logical and physical device counts */ |
| uint16_t ld_present_count; |
| uint16_t ld_degraded_count; |
| uint16_t ld_offline_count; |
| |
| uint16_t pd_present_count; |
| uint16_t pd_disk_present_count; |
| uint16_t pd_disk_pred_failure_count; |
| uint16_t pd_disk_failed_count; |
| |
| /* Memory size information */ |
| uint16_t nvram_size; |
| uint16_t memory_size; |
| uint16_t flash_size; |
| |
| /* Error counters */ |
| uint16_t mem_correctable_error_count; |
| uint16_t mem_uncorrectable_error_count; |
| |
| /* Cluster information */ |
| uint8_t cluster_permitted; |
| uint8_t cluster_active; |
| uint8_t reserved_1[2]; |
| |
| /* Controller capabilities structures */ |
| struct { |
| uint32_t raid_level_0 : 1; |
| uint32_t raid_level_1 : 1; |
| uint32_t raid_level_5 : 1; |
| uint32_t raid_level_1E : 1; |
| uint32_t reserved : 28; |
| } raid_levels; |
| |
| struct { |
| uint32_t rbld_rate : 1; |
| uint32_t cc_rate : 1; |
| uint32_t bgi_rate : 1; |
| uint32_t recon_rate : 1; |
| uint32_t patrol_rate : 1; |
| uint32_t alarm_control : 1; |
| uint32_t cluster_supported : 1; |
| uint32_t bbu : 1; |
| uint32_t spanning_allowed : 1; |
| uint32_t dedicated_hotspares : 1; |
| uint32_t revertible_hotspares : 1; |
| uint32_t foreign_config_import : 1; |
| uint32_t self_diagnostic : 1; |
| uint32_t reserved : 19; |
| } adapter_operations; |
| |
| struct { |
| uint32_t read_policy : 1; |
| uint32_t write_policy : 1; |
| uint32_t io_policy : 1; |
| uint32_t access_policy : 1; |
| uint32_t reserved : 28; |
| } ld_operations; |
| |
| struct { |
| uint8_t min; |
| uint8_t max; |
| uint8_t reserved[2]; |
| } stripe_size_operations; |
| |
| struct { |
| uint32_t force_online : 1; |
| uint32_t force_offline : 1; |
| uint32_t force_rebuild : 1; |
| uint32_t reserved : 29; |
| } pd_operations; |
| |
| struct { |
| uint32_t ctrl_supports_sas : 1; |
| uint32_t ctrl_supports_sata : 1; |
| uint32_t allow_mix_in_encl : 1; |
| uint32_t allow_mix_in_ld : 1; |
| uint32_t allow_sata_in_cluster : 1; |
| uint32_t reserved : 27; |
| } pd_mix_support; |
| |
| /* Include the controller properties (changeable items) */ |
| uint8_t reserved_2[12]; |
| struct mrsas_ctrl_prop properties; |
| |
| uint8_t pad[0x800 - 0x640]; |
| }; |
| |
| /* |
| * ================================== |
| * MegaRAID SAS2.0 driver definitions |
| * ================================== |
| */ |
| #define MRDRV_MAX_NUM_CMD 1024 |
| |
| #define MRDRV_MAX_PD_CHANNELS 2 |
| #define MRDRV_MAX_LD_CHANNELS 2 |
| #define MRDRV_MAX_CHANNELS (MRDRV_MAX_PD_CHANNELS + \ |
| MRDRV_MAX_LD_CHANNELS) |
| #define MRDRV_MAX_DEV_PER_CHANNEL 128 |
| #define MRDRV_DEFAULT_INIT_ID -1 |
| #define MRDRV_MAX_CMD_PER_LUN 1000 |
| #define MRDRV_MAX_LUN 1 |
| #define MRDRV_MAX_LD 64 |
| |
| #define MRDRV_RESET_WAIT_TIME 300 |
| #define MRDRV_RESET_NOTICE_INTERVAL 5 |
| |
| #define MRSAS_IOCTL_CMD 0 |
| |
| #define MRDRV_TGT_VALID 1 |
| |
| /* |
| * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit |
| * SGLs based on the size of dma_addr_t |
| */ |
| #define IS_DMA64 (sizeof (dma_addr_t) == 8) |
| |
| #define RESERVED0_REGISTER 0x00 /* XScale */ |
| #define IB_MSG_0_OFF 0x10 /* XScale */ |
| #define OB_MSG_0_OFF 0x18 /* XScale */ |
| #define IB_DOORBELL_OFF 0x20 /* XScale & ROC */ |
| #define OB_INTR_STATUS_OFF 0x30 /* XScale & ROC */ |
| #define OB_INTR_MASK_OFF 0x34 /* XScale & ROC */ |
| #define IB_QPORT_OFF 0x40 /* XScale & ROC */ |
| #define OB_DOORBELL_CLEAR_OFF 0xA0 /* ROC */ |
| #define OB_SCRATCH_PAD_0_OFF 0xB0 /* ROC */ |
| #define OB_INTR_MASK 0xFFFFFFFF |
| #define OB_DOORBELL_CLEAR_MASK 0xFFFFFFFF |
| #define SYSTOIOP_INTERRUPT_MASK 0x80000000 |
| #define OB_SCRATCH_PAD_2_OFF 0xB4 |
| #define WRITE_TBOLT_SEQ_OFF 0x00000004 |
| #define DIAG_TBOLT_RESET_ADAPTER 0x00000004 |
| #define HOST_TBOLT_DIAG_OFF 0x00000008 |
| #define RESET_TBOLT_STATUS_OFF 0x000003C3 |
| #define WRITE_SEQ_OFF 0x000000FC |
| #define HOST_DIAG_OFF 0x000000F8 |
| #define DIAG_RESET_ADAPTER 0x00000004 |
| #define DIAG_WRITE_ENABLE 0x00000080 |
| #define SYSTOIOP_INTERRUPT_MASK 0x80000000 |
| |
| #define WR_IB_WRITE_SEQ(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + WRITE_SEQ_OFF), (v)) |
| |
| #define RD_OB_DRWE(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + HOST_DIAG_OFF)) |
| |
| #define WR_IB_DRWE(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + HOST_DIAG_OFF), (v)) |
| |
| #define IB_LOW_QPORT 0xC0 |
| #define IB_HIGH_QPORT 0xC4 |
| #define OB_DOORBELL_REGISTER 0x9C /* 1078 implementation */ |
| |
| /* |
| * All MFI register set macros accept mrsas_register_set* |
| */ |
| #define WR_IB_MSG_0(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + IB_MSG_0_OFF), (v)) |
| |
| #define RD_OB_MSG_0(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_MSG_0_OFF)) |
| |
| #define WR_IB_DOORBELL(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF), (v)) |
| |
| #define RD_IB_DOORBELL(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + IB_DOORBELL_OFF)) |
| |
| #define WR_OB_INTR_STATUS(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF), (v)) |
| |
| #define RD_OB_INTR_STATUS(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_STATUS_OFF)) |
| |
| #define WR_OB_INTR_MASK(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), (v)) |
| |
| #define RD_OB_INTR_MASK(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF)) |
| |
| #define WR_IB_QPORT(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + IB_QPORT_OFF), (v)) |
| |
| #define WR_OB_DOORBELL_CLEAR(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_CLEAR_OFF), \ |
| (v)) |
| |
| #define RD_OB_SCRATCH_PAD_0(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_0_OFF)) |
| |
| /* Thunderbolt specific registers */ |
| #define RD_OB_SCRATCH_PAD_2(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_SCRATCH_PAD_2_OFF)) |
| |
| #define WR_TBOLT_IB_WRITE_SEQ(v, instance) \ |
| ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + WRITE_TBOLT_SEQ_OFF), (v)) |
| |
| #define RD_TBOLT_HOST_DIAG(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + HOST_TBOLT_DIAG_OFF)) |
| |
| #define WR_TBOLT_HOST_DIAG(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + HOST_TBOLT_DIAG_OFF), (v)) |
| |
| #define RD_TBOLT_RESET_STAT(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + RESET_TBOLT_STATUS_OFF)) |
| |
| |
| #define WR_MPI2_REPLY_POST_INDEX(v, instance)\ |
| ddi_put32((instance)->regmap_handle,\ |
| (uint32_t *)\ |
| ((uintptr_t)(instance)->regmap + MPI2_REPLY_POST_HOST_INDEX_OFFSET),\ |
| (v)) |
| |
| |
| #define RD_MPI2_REPLY_POST_INDEX(instance)\ |
| ddi_get32((instance)->regmap_handle,\ |
| (uint32_t *)\ |
| ((uintptr_t)(instance)->regmap + MPI2_REPLY_POST_HOST_INDEX_OFFSET)) |
| |
| #define WR_IB_LOW_QPORT(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + IB_LOW_QPORT), (v)) |
| |
| #define WR_IB_HIGH_QPORT(v, instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + IB_HIGH_QPORT), (v)) |
| |
| #define WR_OB_DOORBELL_REGISTER_CLEAR(v, instance)\ |
| ddi_put32((instance)->regmap_handle,\ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_DOORBELL_REGISTER), \ |
| (v)) |
| |
| #define WR_RESERVED0_REGISTER(v, instance) ddi_put32((instance)->regmap_handle,\ |
| (uint32_t *)((uintptr_t)(instance)->regmap + RESERVED0_REGISTER), \ |
| (v)) |
| |
| #define RD_RESERVED0_REGISTER(instance) ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + RESERVED0_REGISTER)) |
| |
| |
| |
| /* |
| * When FW is in MFI_STATE_READY or MFI_STATE_OPERATIONAL, the state data |
| * of Outbound Msg Reg 0 indicates max concurrent cmds supported, max SGEs |
| * supported per cmd and if 64-bit MFAs (M64) is enabled or disabled. |
| */ |
| #define MFI_OB_INTR_STATUS_MASK 0x00000002 |
| |
| /* |
| * This MFI_REPLY_2108_MESSAGE_INTR flag is used also |
| * in enable_intr_ppc also. Hence bit 2, i.e. 0x4 has |
| * been set in this flag along with bit 1. |
| */ |
| #define MFI_REPLY_2108_MESSAGE_INTR 0x00000001 |
| #define MFI_REPLY_2108_MESSAGE_INTR_MASK 0x00000005 |
| |
| /* Fusion interrupt mask */ |
| #define MFI_FUSION_ENABLE_INTERRUPT_MASK (0x00000008) |
| |
| #define MFI_POLL_TIMEOUT_SECS 60 |
| |
| #define MFI_ENABLE_INTR(instance) ddi_put32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF), 1) |
| #define MFI_DISABLE_INTR(instance) \ |
| { \ |
| uint32_t disable = 1; \ |
| uint32_t mask = ddi_get32((instance)->regmap_handle, \ |
| (uint32_t *)((uintptr_t)(instance)->regmap + OB_INTR_MASK_OFF));\ |
| mask &= ~disable; \ |
| ddi_put32((instance)->regmap_handle, (uint32_t *) \ |
| (uintptr_t)((instance)->regmap + OB_INTR_MASK_OFF), mask); \ |
| } |
| |
| /* By default, the firmware programs for 8 Kbytes of memory */ |
| #define DEFAULT_MFI_MEM_SZ 8192 |
| #define MINIMUM_MFI_MEM_SZ 4096 |
| |
| /* DCMD Message Frame MAILBOX0-11 */ |
| #define DCMD_MBOX_SZ 12 |
| |
| /* |
| * on_off_property of mrsas_ctrl_prop |
| * bit0-9, 11-31 are reserved |
| */ |
| #define DISABLE_OCR_PROP_FLAG 0x00000400 /* bit 10 */ |
| |
| struct mrsas_register_set { |
| uint32_t reserved_0[4]; /* 0000h */ |
| |
| uint32_t inbound_msg_0; /* 0010h */ |
| uint32_t inbound_msg_1; /* 0014h */ |
| uint32_t outbound_msg_0; /* 0018h */ |
| uint32_t outbound_msg_1; /* 001Ch */ |
| |
| uint32_t inbound_doorbell; /* 0020h */ |
| uint32_t inbound_intr_status; /* 0024h */ |
| uint32_t inbound_intr_mask; /* 0028h */ |
| |
| uint32_t outbound_doorbell; /* 002Ch */ |
| uint32_t outbound_intr_status; /* 0030h */ |
| uint32_t outbound_intr_mask; /* 0034h */ |
| |
| uint32_t reserved_1[2]; /* 0038h */ |
| |
| uint32_t inbound_queue_port; /* 0040h */ |
| uint32_t outbound_queue_port; /* 0044h */ |
| |
| uint32_t reserved_2[22]; /* 0048h */ |
| |
| uint32_t outbound_doorbell_clear; /* 00A0h */ |
| |
| uint32_t reserved_3[3]; /* 00A4h */ |
| |
| uint32_t outbound_scratch_pad; /* 00B0h */ |
| |
| uint32_t reserved_4[3]; /* 00B4h */ |
| |
| uint32_t inbound_low_queue_port; /* 00C0h */ |
| |
| uint32_t inbound_high_queue_port; /* 00C4h */ |
| |
| uint32_t reserved_5; /* 00C8h */ |
| uint32_t index_registers[820]; /* 00CCh */ |
| }; |
| |
| struct mrsas_sge32 { |
| uint32_t phys_addr; |
| uint32_t length; |
| }; |
| |
| struct mrsas_sge64 { |
| uint64_t phys_addr; |
| uint32_t length; |
| }; |
| |
| struct mrsas_sge_ieee { |
| uint64_t phys_addr; |
| uint32_t length; |
| uint32_t flag; |
| }; |
| |
| union mrsas_sgl { |
| struct mrsas_sge32 sge32[1]; |
| struct mrsas_sge64 sge64[1]; |
| struct mrsas_sge_ieee sge_ieee[1]; |
| }; |
| |
| struct mrsas_header { |
| uint8_t cmd; /* 00h */ |
| uint8_t sense_len; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| uint8_t scsi_status; /* 03h */ |
| |
| uint8_t target_id; /* 04h */ |
| uint8_t lun; /* 05h */ |
| uint8_t cdb_len; /* 06h */ |
| uint8_t sge_count; /* 07h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t timeout; /* 12h */ |
| uint32_t data_xferlen; /* 14h */ |
| }; |
| |
| union mrsas_sgl_frame { |
| struct mrsas_sge32 sge32[8]; |
| struct mrsas_sge64 sge64[5]; |
| }; |
| |
| struct mrsas_init_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t reserved_0; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| |
| uint8_t reserved_1; /* 03h */ |
| uint32_t reserved_2; /* 04h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t reserved_3; /* 12h */ |
| uint32_t data_xfer_len; /* 14h */ |
| |
| uint32_t queue_info_new_phys_addr_lo; /* 18h */ |
| uint32_t queue_info_new_phys_addr_hi; /* 1Ch */ |
| uint32_t queue_info_old_phys_addr_lo; /* 20h */ |
| uint32_t queue_info_old_phys_addr_hi; /* 24h */ |
| uint64_t driverversion; /* 28h */ |
| uint32_t reserved_4[4]; /* 30h */ |
| }; |
| |
| struct mrsas_init_queue_info { |
| uint32_t init_flags; /* 00h */ |
| uint32_t reply_queue_entries; /* 04h */ |
| |
| uint32_t reply_queue_start_phys_addr_lo; /* 08h */ |
| uint32_t reply_queue_start_phys_addr_hi; /* 0Ch */ |
| uint32_t producer_index_phys_addr_lo; /* 10h */ |
| uint32_t producer_index_phys_addr_hi; /* 14h */ |
| uint32_t consumer_index_phys_addr_lo; /* 18h */ |
| uint32_t consumer_index_phys_addr_hi; /* 1Ch */ |
| }; |
| |
| struct mrsas_io_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t sense_len; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| uint8_t scsi_status; /* 03h */ |
| |
| uint8_t target_id; /* 04h */ |
| uint8_t access_byte; /* 05h */ |
| uint8_t reserved_0; /* 06h */ |
| uint8_t sge_count; /* 07h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t timeout; /* 12h */ |
| uint32_t lba_count; /* 14h */ |
| |
| uint32_t sense_buf_phys_addr_lo; /* 18h */ |
| uint32_t sense_buf_phys_addr_hi; /* 1Ch */ |
| |
| uint32_t start_lba_lo; /* 20h */ |
| uint32_t start_lba_hi; /* 24h */ |
| |
| union mrsas_sgl sgl; /* 28h */ |
| }; |
| |
| struct mrsas_pthru_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t sense_len; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| uint8_t scsi_status; /* 03h */ |
| |
| uint8_t target_id; /* 04h */ |
| uint8_t lun; /* 05h */ |
| uint8_t cdb_len; /* 06h */ |
| uint8_t sge_count; /* 07h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t timeout; /* 12h */ |
| uint32_t data_xfer_len; /* 14h */ |
| |
| uint32_t sense_buf_phys_addr_lo; /* 18h */ |
| uint32_t sense_buf_phys_addr_hi; /* 1Ch */ |
| |
| uint8_t cdb[16]; /* 20h */ |
| union mrsas_sgl sgl; /* 30h */ |
| }; |
| |
| struct mrsas_dcmd_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t reserved_0; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| uint8_t reserved_1[4]; /* 03h */ |
| uint8_t sge_count; /* 07h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t timeout; /* 12h */ |
| |
| uint32_t data_xfer_len; /* 14h */ |
| uint32_t opcode; /* 18h */ |
| |
| /* uint8_t mbox[DCMD_MBOX_SZ]; */ /* 1Ch */ |
| union { /* 1Ch */ |
| uint8_t b[DCMD_MBOX_SZ]; |
| uint16_t s[6]; |
| uint32_t w[3]; |
| } mbox; |
| |
| union mrsas_sgl sgl; /* 28h */ |
| }; |
| |
| struct mrsas_abort_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t reserved_0; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| |
| uint8_t reserved_1; /* 03h */ |
| uint32_t reserved_2; /* 04h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t reserved_3; /* 12h */ |
| uint32_t reserved_4; /* 14h */ |
| |
| uint32_t abort_context; /* 18h */ |
| uint32_t pad_1; /* 1Ch */ |
| |
| uint32_t abort_mfi_phys_addr_lo; /* 20h */ |
| uint32_t abort_mfi_phys_addr_hi; /* 24h */ |
| |
| uint32_t reserved_5[6]; /* 28h */ |
| }; |
| |
| struct mrsas_smp_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t reserved_1; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| uint8_t connection_status; /* 03h */ |
| |
| uint8_t reserved_2[3]; /* 04h */ |
| uint8_t sge_count; /* 07h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t timeout; /* 12h */ |
| |
| uint32_t data_xfer_len; /* 14h */ |
| |
| uint64_t sas_addr; /* 20h */ |
| |
| union mrsas_sgl sgl[2]; /* 28h */ |
| }; |
| |
| struct mrsas_stp_frame { |
| uint8_t cmd; /* 00h */ |
| uint8_t reserved_1; /* 01h */ |
| uint8_t cmd_status; /* 02h */ |
| uint8_t connection_status; /* 03h */ |
| |
| uint8_t target_id; /* 04h */ |
| uint8_t reserved_2[2]; /* 04h */ |
| uint8_t sge_count; /* 07h */ |
| |
| uint32_t context; /* 08h */ |
| uint8_t req_id; /* 0Ch */ |
| uint8_t msgvector; /* 0Dh */ |
| uint16_t pad_0; /* 0Eh */ |
| |
| uint16_t flags; /* 10h */ |
| uint16_t timeout; /* 12h */ |
| |
| uint32_t data_xfer_len; /* 14h */ |
| |
| uint16_t fis[10]; /* 28h */ |
| uint32_t stp_flags; /* 3C */ |
| union mrsas_sgl sgl; /* 40 */ |
| }; |
| |
| union mrsas_frame { |
| struct mrsas_header hdr; |
| struct mrsas_init_frame init; |
| struct mrsas_io_frame io; |
| struct mrsas_pthru_frame pthru; |
| struct mrsas_dcmd_frame dcmd; |
| struct mrsas_abort_frame abort; |
| struct mrsas_smp_frame smp; |
| struct mrsas_stp_frame stp; |
| |
| uint8_t raw_bytes[64]; |
| }; |
| |
| typedef struct mrsas_pd_address { |
| uint16_t device_id; |
| uint16_t encl_id; |
| |
| union { |
| struct { |
| uint8_t encl_index; |
| uint8_t slot_number; |
| } pd_address; |
| struct { |
| uint8_t encl_position; |
| uint8_t encl_connector_index; |
| } encl_address; |
| }address; |
| |
| uint8_t scsi_dev_type; |
| |
| union { |
| uint8_t port_bitmap; |
| uint8_t port_numbers; |
| } connected; |
| |
| uint64_t sas_addr[2]; |
| } mrsas_pd_address_t; |
| |
| union mrsas_evt_class_locale { |
| struct { |
| uint16_t locale; |
| uint8_t reserved; |
| int8_t class; |
| } members; |
| |
| uint32_t word; |
| }; |
| |
| struct mrsas_evt_log_info { |
| uint32_t newest_seq_num; |
| uint32_t oldest_seq_num; |
| uint32_t clear_seq_num; |
| uint32_t shutdown_seq_num; |
| uint32_t boot_seq_num; |
| }; |
| |
| struct mrsas_progress { |
| uint16_t progress; |
| uint16_t elapsed_seconds; |
| }; |
| |
| struct mrsas_evtarg_ld { |
| uint16_t target_id; |
| uint8_t ld_index; |
| uint8_t reserved; |
| }; |
| |
| struct mrsas_evtarg_pd { |
| uint16_t device_id; |
| uint8_t encl_index; |
| uint8_t slot_number; |
| }; |
| |
| struct mrsas_evt_detail { |
| uint32_t seq_num; |
| uint32_t time_stamp; |
| uint32_t code; |
| union mrsas_evt_class_locale cl; |
| uint8_t arg_type; |
| uint8_t reserved1[15]; |
| |
| union { |
| struct { |
| struct mrsas_evtarg_pd pd; |
| uint8_t cdb_length; |
| uint8_t sense_length; |
| uint8_t reserved[2]; |
| uint8_t cdb[16]; |
| uint8_t sense[64]; |
| } cdbSense; |
| |
| struct mrsas_evtarg_ld ld; |
| |
| struct { |
| struct mrsas_evtarg_ld ld; |
| uint64_t count; |
| } ld_count; |
| |
| struct { |
| uint64_t lba; |
| struct mrsas_evtarg_ld ld; |
| } ld_lba; |
| |
| struct { |
| struct mrsas_evtarg_ld ld; |
| uint32_t prevOwner; |
| uint32_t newOwner; |
| } ld_owner; |
| |
| struct { |
| uint64_t ld_lba; |
| uint64_t pd_lba; |
| struct mrsas_evtarg_ld ld; |
| struct mrsas_evtarg_pd pd; |
| } ld_lba_pd_lba; |
| |
| struct { |
| struct mrsas_evtarg_ld ld; |
| struct mrsas_progress prog; |
| } ld_prog; |
| |
| struct { |
| struct mrsas_evtarg_ld ld; |
| uint32_t prev_state; |
| uint32_t new_state; |
| } ld_state; |
| |
| struct { |
| uint64_t strip; |
| struct mrsas_evtarg_ld ld; |
| } ld_strip; |
| |
| struct mrsas_evtarg_pd pd; |
| |
| struct { |
| struct mrsas_evtarg_pd pd; |
| uint32_t err; |
| } pd_err; |
| |
| struct { |
| uint64_t lba; |
| struct mrsas_evtarg_pd pd; |
| } pd_lba; |
| |
| struct { |
| uint64_t lba; |
| struct mrsas_evtarg_pd pd; |
| struct mrsas_evtarg_ld ld; |
| } pd_lba_ld; |
| |
| struct { |
| struct mrsas_evtarg_pd pd; |
| struct mrsas_progress prog; |
| } pd_prog; |
| |
| struct { |
| struct mrsas_evtarg_pd pd; |
| uint32_t prevState; |
| uint32_t newState; |
| } pd_state; |
| |
| struct { |
| uint16_t vendorId; |
| uint16_t deviceId; |
| uint16_t subVendorId; |
| uint16_t subDeviceId; |
| } pci; |
| |
| uint32_t rate; |
| char str[96]; |
| |
| struct { |
| uint32_t rtc; |
| uint32_t elapsedSeconds; |
| } time; |
| |
| struct { |
| uint32_t ecar; |
| uint32_t elog; |
| char str[64]; |
| } ecc; |
| |
| mrsas_pd_address_t pd_addr; |
| |
| uint8_t b[96]; |
| uint16_t s[48]; |
| uint32_t w[24]; |
| uint64_t d[12]; |
| } args; |
| |
| char description[128]; |
| |
| }; |
| |
| /* only 63 are usable by the application */ |
| #define MAX_LOGICAL_DRIVES 64 |
| /* only 255 physical devices may be used */ |
| #define MAX_PHYSICAL_DEVICES 256 |
| #define MAX_PD_PER_ENCLOSURE 64 |
| /* maximum disks per array */ |
| #define MAX_ROW_SIZE 32 |
| /* maximum spans per logical drive */ |
| #define MAX_SPAN_DEPTH 8 |
| /* maximum number of arrays a hot spare may be dedicated to */ |
| #define MAX_ARRAYS_DEDICATED 16 |
| /* maximum number of arrays which may exist */ |
| #define MAX_ARRAYS 128 |
| /* maximum number of foreign configs that may ha managed at once */ |
| #define MAX_FOREIGN_CONFIGS 8 |
| /* maximum spares (global and dedicated combined) */ |
| #define MAX_SPARES_FOR_THE_CONTROLLER MAX_PHYSICAL_DEVICES |
| /* maximum possible Target IDs (i.e. 0 to 63) */ |
| #define MAX_TARGET_ID 63 |
| /* maximum number of supported enclosures */ |
| #define MAX_ENCLOSURES 32 |
| /* maximum number of PHYs per controller */ |
| #define MAX_PHYS_PER_CONTROLLER 16 |
| /* maximum number of LDs per array (due to DDF limitations) */ |
| #define MAX_LDS_PER_ARRAY 16 |
| |
| /* |
| * ----------------------------------------------------------------------------- |
| * ----------------------------------------------------------------------------- |
| * |
| * Logical Drive commands |
| * |
| * ----------------------------------------------------------------------------- |
| * ----------------------------------------------------------------------------- |
| */ |
| #define MR_DCMD_LD 0x03000000, /* Logical Device (LD) opcodes */ |
| |
| /* |
| * Input: dcmd.opcode - MR_DCMD_LD_GET_LIST |
| * dcmd.mbox - reserved |
| * dcmd.sge IN - ptr to returned MR_LD_LIST structure |
| * Desc: Return the logical drive list structure |
| * Status: No error |
| */ |
| |
| /* |
| * defines the logical drive reference structure |
| */ |
| typedef union _MR_LD_REF { /* LD reference structure */ |
| struct { |
| uint8_t targetId; /* LD target id (0 to MAX_TARGET_ID) */ |
| uint8_t reserved; /* reserved for in line with MR_PD_REF */ |
| uint16_t seqNum; /* Sequence Number */ |
| } ld_ref; |
| uint32_t ref; /* shorthand reference to full 32-bits */ |
| } MR_LD_REF; /* 4 bytes */ |
| |
| /* |
| * defines the logical drive list structure |
| */ |
| typedef struct _MR_LD_LIST { |
| uint32_t ldCount; /* number of LDs */ |
| uint32_t reserved; /* pad to 8-byte boundary */ |
| struct { |
| MR_LD_REF ref; /* LD reference */ |
| uint8_t state; /* current LD state (MR_LD_STATE) */ |
| uint8_t reserved[3]; /* pad to 8-byte boundary */ |
| uint64_t size; /* LD size */ |
| } ldList[MAX_LOGICAL_DRIVES]; |
| } MR_LD_LIST; |
| |
| struct mrsas_drv_ver { |
| uint8_t signature[12]; |
| uint8_t os_name[16]; |
| uint8_t os_ver[12]; |
| uint8_t drv_name[20]; |
| uint8_t drv_ver[32]; |
| uint8_t drv_rel_date[20]; |
| }; |
| |
| #define PCI_TYPE0_ADDRESSES 6 |
| #define PCI_TYPE1_ADDRESSES 2 |
| #define PCI_TYPE2_ADDRESSES 5 |
| |
| struct mrsas_pci_common_header { |
| uint16_t vendorID; /* (ro) */ |
| uint16_t deviceID; /* (ro) */ |
| uint16_t command; /* Device control */ |
| uint16_t status; |
| uint8_t revisionID; /* (ro) */ |
| uint8_t progIf; /* (ro) */ |
| uint8_t subClass; /* (ro) */ |
| uint8_t baseClass; /* (ro) */ |
| uint8_t cacheLineSize; /* (ro+) */ |
| uint8_t latencyTimer; /* (ro+) */ |
| uint8_t headerType; /* (ro) */ |
| uint8_t bist; /* Built in self test */ |
| |
| union { |
| struct { |
| uint32_t baseAddresses[PCI_TYPE0_ADDRESSES]; |
| uint32_t cis; |
| uint16_t subVendorID; |
| uint16_t subSystemID; |
| uint32_t romBaseAddress; |
| uint8_t capabilitiesPtr; |
| uint8_t reserved1[3]; |
| uint32_t reserved2; |
| uint8_t interruptLine; |
| uint8_t interruptPin; /* (ro) */ |
| uint8_t minimumGrant; /* (ro) */ |
| uint8_t maximumLatency; /* (ro) */ |
| } type_0; |
| |
| struct { |
| uint32_t baseAddresses[PCI_TYPE1_ADDRESSES]; |
| uint8_t primaryBus; |
| uint8_t secondaryBus; |
| uint8_t subordinateBus; |
| uint8_t secondaryLatency; |
| uint8_t ioBase; |
| uint8_t ioLimit; |
| uint16_t secondaryStatus; |
| uint16_t memoryBase; |
| uint16_t memoryLimit; |
| uint16_t prefetchBase; |
| uint16_t prefetchLimit; |
| uint32_t prefetchBaseUpper32; |
| uint32_t prefetchLimitUpper32; |
| uint16_t ioBaseUpper16; |
| uint16_t ioLimitUpper16; |
| uint8_t capabilitiesPtr; |
| uint8_t reserved1[3]; |
| uint32_t romBaseAddress; |
| uint8_t interruptLine; |
| uint8_t interruptPin; |
| uint16_t bridgeControl; |
| } type_1; |
| |
| struct { |
| uint32_t socketRegistersBaseAddress; |
| uint8_t capabilitiesPtr; |
| uint8_t reserved; |
| uint16_t secondaryStatus; |
| uint8_t primaryBus; |
| uint8_t secondaryBus; |
| uint8_t subordinateBus; |
| uint8_t secondaryLatency; |
| struct { |
| uint32_t base; |
| uint32_t limit; |
| } range[PCI_TYPE2_ADDRESSES-1]; |
| uint8_t interruptLine; |
| uint8_t interruptPin; |
| uint16_t bridgeControl; |
| } type_2; |
| } header; |
| }; |
| |
| struct mrsas_pci_link_capability { |
| union { |
| struct { |
| uint32_t linkSpeed :4; |
| uint32_t linkWidth :6; |
| uint32_t aspmSupport :2; |
| uint32_t losExitLatency :3; |
| uint32_t l1ExitLatency :3; |
| uint32_t rsvdp :6; |
| uint32_t portNumber :8; |
| } bits; |
| |
| uint32_t asUlong; |
| } cap; |
| |
| }; |
| |
| struct mrsas_pci_link_status_capability { |
| union { |
| struct { |
| uint16_t linkSpeed :4; |
| uint16_t negotiatedLinkWidth :6; |
| uint16_t linkTrainingError :1; |
| uint16_t linkTraning :1; |
| uint16_t slotClockConfig :1; |
| uint16_t rsvdZ :3; |
| } bits; |
| |
| uint16_t asUshort; |
| } stat_cap; |
| |
| uint16_t reserved; |
| |
| }; |
| |
| struct mrsas_pci_capabilities { |
| struct mrsas_pci_link_capability linkCapability; |
| struct mrsas_pci_link_status_capability linkStatusCapability; |
| }; |
| |
| struct mrsas_pci_information |
| { |
| uint32_t busNumber; |
| uint8_t deviceNumber; |
| uint8_t functionNumber; |
| uint8_t interruptVector; |
| uint8_t reserved; |
| struct mrsas_pci_common_header pciHeaderInfo; |
| struct mrsas_pci_capabilities capability; |
| uint8_t reserved2[32]; |
| }; |
| |
| struct mrsas_ioctl { |
| uint16_t version; |
| uint16_t controller_id; |
| uint8_t signature[8]; |
| uint32_t reserved_1; |
| uint32_t control_code; |
| uint32_t reserved_2[2]; |
| uint8_t frame[64]; |
| union mrsas_sgl_frame sgl_frame; |
| uint8_t sense_buff[MRSAS_MAX_SENSE_LENGTH]; |
| uint8_t data[1]; |
| }; |
| |
| struct mrsas_aen { |
| uint16_t host_no; |
| uint16_t cmd_status; |
| uint32_t seq_num; |
| uint32_t class_locale_word; |
| }; |
| |
| #pragma pack() |
| |
| #ifndef DDI_VENDOR_LSI |
| #define DDI_VENDOR_LSI "LSI" |
| #endif /* DDI_VENDOR_LSI */ |
| |
| int mrsas_config_scsi_device(struct mrsas_instance *, |
| struct scsi_device *, dev_info_t **); |
| |
| int mrsas_tbolt_config_pd(struct mrsas_instance *, uint16_t, |
| uint8_t, dev_info_t **); |
| |
| dev_info_t *mrsas_find_child(struct mrsas_instance *, uint16_t, uint8_t); |
| int mrsas_service_evt(struct mrsas_instance *, int, int, int, uint64_t); |
| void return_raid_msg_pkt(struct mrsas_instance *, struct mrsas_cmd *); |
| struct mrsas_cmd *get_raid_msg_mfi_pkt(struct mrsas_instance *); |
| void return_raid_msg_mfi_pkt(struct mrsas_instance *, struct mrsas_cmd *); |
| |
| int alloc_space_for_mpi2(struct mrsas_instance *); |
| void fill_up_drv_ver(struct mrsas_drv_ver *dv); |
| |
| int mrsas_issue_init_mpi2(struct mrsas_instance *); |
| struct scsi_pkt *mrsas_tbolt_tran_init_pkt(struct scsi_address *, register |
| struct scsi_pkt *, struct buf *, int, int, int, int, |
| int (*)(), caddr_t); |
| int mrsas_tbolt_tran_start(struct scsi_address *, |
| register struct scsi_pkt *); |
| uint32_t tbolt_read_fw_status_reg(struct mrsas_instance *); |
| void tbolt_issue_cmd(struct mrsas_cmd *, struct mrsas_instance *); |
| int tbolt_issue_cmd_in_poll_mode(struct mrsas_instance *, |
| struct mrsas_cmd *); |
| int tbolt_issue_cmd_in_sync_mode(struct mrsas_instance *, |
| struct mrsas_cmd *); |
| void tbolt_enable_intr(struct mrsas_instance *); |
| void tbolt_disable_intr(struct mrsas_instance *); |
| int tbolt_intr_ack(struct mrsas_instance *); |
| uint_t mr_sas_tbolt_process_outstanding_cmd(struct mrsas_instance *); |
| uint_t tbolt_softintr(); |
| int mrsas_tbolt_dma(struct mrsas_instance *, uint32_t, int, int (*)()); |
| int mrsas_check_dma_handle(ddi_dma_handle_t handle); |
| int mrsas_check_acc_handle(ddi_acc_handle_t handle); |
| int mrsas_dma_alloc(struct mrsas_instance *, struct scsi_pkt *, |
| struct buf *, int, int (*)()); |
| int mrsas_dma_move(struct mrsas_instance *, |
| struct scsi_pkt *, struct buf *); |
| int mrsas_alloc_dma_obj(struct mrsas_instance *, dma_obj_t *, |
| uchar_t); |
| void mr_sas_tbolt_build_mfi_cmd(struct mrsas_instance *, struct mrsas_cmd *); |
| int mrsas_dma_alloc_dmd(struct mrsas_instance *, dma_obj_t *); |
| void tbolt_complete_cmd_in_sync_mode(struct mrsas_instance *, |
| struct mrsas_cmd *); |
| int alloc_req_rep_desc(struct mrsas_instance *); |
| int mrsas_mode_sense_build(struct scsi_pkt *); |
| void push_pending_mfi_pkt(struct mrsas_instance *, |
| struct mrsas_cmd *); |
| int mrsas_issue_pending_cmds(struct mrsas_instance *); |
| int mrsas_print_pending_cmds(struct mrsas_instance *); |
| int mrsas_complete_pending_cmds(struct mrsas_instance *); |
| |
| int create_mfi_frame_pool(struct mrsas_instance *); |
| void destroy_mfi_frame_pool(struct mrsas_instance *); |
| int create_mfi_mpi_frame_pool(struct mrsas_instance *); |
| void destroy_mfi_mpi_frame_pool(struct mrsas_instance *); |
| int create_mpi2_frame_pool(struct mrsas_instance *); |
| void destroy_mpi2_frame_pool(struct mrsas_instance *); |
| int mrsas_free_dma_obj(struct mrsas_instance *, dma_obj_t); |
| void mrsas_tbolt_free_additional_dma_buffer(struct mrsas_instance *); |
| void free_req_desc_pool(struct mrsas_instance *); |
| void free_space_for_mpi2(struct mrsas_instance *); |
| void mrsas_dump_reply_desc(struct mrsas_instance *); |
| void tbolt_complete_cmd(struct mrsas_instance *, struct mrsas_cmd *); |
| void display_scsi_inquiry(caddr_t); |
| void service_mfi_aen(struct mrsas_instance *, struct mrsas_cmd *); |
| int mrsas_mode_sense_build(struct scsi_pkt *); |
| int mrsas_tbolt_get_ld_map_info(struct mrsas_instance *); |
| struct mrsas_cmd *mrsas_tbolt_build_poll_cmd(struct mrsas_instance *, |
| struct scsi_address *, struct scsi_pkt *, uchar_t *); |
| int mrsas_tbolt_reset_ppc(struct mrsas_instance *instance); |
| void mrsas_tbolt_kill_adapter(struct mrsas_instance *instance); |
| int abort_syncmap_cmd(struct mrsas_instance *, struct mrsas_cmd *); |
| void mrsas_tbolt_prepare_cdb(struct mrsas_instance *instance, U8 cdb[], |
| struct IO_REQUEST_INFO *, Mpi2RaidSCSIIORequest_t *, U32); |
| |
| |
| int mrsas_init_adapter_ppc(struct mrsas_instance *instance); |
| int mrsas_init_adapter_tbolt(struct mrsas_instance *instance); |
| int mrsas_init_adapter(struct mrsas_instance *instance); |
| |
| int mrsas_alloc_cmd_pool(struct mrsas_instance *instance); |
| void mrsas_free_cmd_pool(struct mrsas_instance *instance); |
| |
| void mrsas_print_cmd_details(struct mrsas_instance *, struct mrsas_cmd *, int); |
| struct mrsas_cmd *get_raid_msg_pkt(struct mrsas_instance *); |
| |
| int mfi_state_transition_to_ready(struct mrsas_instance *); |
| |
| struct mrsas_cmd *mrsas_get_mfi_pkt(struct mrsas_instance *); |
| void mrsas_return_mfi_pkt(struct mrsas_instance *, struct mrsas_cmd *); |
| |
| |
| /* FMA functions. */ |
| int mrsas_common_check(struct mrsas_instance *, struct mrsas_cmd *); |
| void mrsas_fm_ereport(struct mrsas_instance *, char *); |
| |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _MR_SAS_H_ */ |