mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-25 18:12:57 +01:00
9fac68fc38
It includes: 1)Newly added TMF feature. 2)Added newly Huawei & Inspur PCI ID's 3)Fixed smartpqi driver hangs in Z-Pool while running on FreeBSD12.1 4)Fixed flooding dmesg in kernel while the controller is offline during in ioctls. 5)Avoided unnecessary host memory allocation for rcb sg buffers. 6)Fixed race conditions while accessing internal rcb structure. 7)Fixed where Logical volumes exposing two different names to the OS it's due to the system memory is overwritten with DMA stale data. 8)Fixed dynamically unloading a smartpqi driver. 9)Added device_shutdown callback instead of deprecated shutdown_final kernel event in smartpqi driver. 10)Fixed where Os is crashed during physical drive hot removal during heavy IO. 11)Fixed OS crash during controller lockup/offline during heavy IO. 12)Fixed coverity issues in smartpqi driver 13)Fixed system crash while creating and deleting logical volume in a continuous loop. 14)Fixed where the volume size is not exposing to OS when it expands. 15)Added HC3 pci id's. Reviewed by: Scott Benesh (microsemi), Murthy Bhat (microsemi), imp Differential Revision: https://reviews.freebsd.org/D30182 Sponsored by: Netflix
1171 lines
39 KiB
C
1171 lines
39 KiB
C
/*-
|
|
* Copyright 2016-2021 Microchip Technology, Inc. and/or its subsidiaries.
|
|
*
|
|
* 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.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
|
*/
|
|
|
|
/* $FreeBSD$ */
|
|
|
|
#ifndef _PQI_DEFINES_H
|
|
#define _PQI_DEFINES_H
|
|
|
|
#define PQI_STATUS_FAILURE -1
|
|
#define PQI_STATUS_TIMEOUT -2
|
|
#define PQI_STATUS_QFULL -3
|
|
#define PQI_STATUS_SUCCESS 0
|
|
|
|
/* Maximum timeout for internal command completion */
|
|
#define TIMEOUT_INFINITE ((uint32_t) (-1))
|
|
#define PQISRC_CMD_TIMEOUT TIMEOUT_INFINITE
|
|
#define PQISRC_PASSTHROUGH_CMD_TIMEOUT PQISRC_CMD_TIMEOUT
|
|
/* Delay in milli seconds */
|
|
#define PQISRC_TMF_TIMEOUT (OS_TMF_TIMEOUT_SEC * 1000)
|
|
/* Delay in micro seconds */
|
|
#define PQISRC_PENDING_IO_TIMEOUT_USEC 30000000 /* 30 seconds */
|
|
|
|
/* If want to disable atomic operations on device active io, then set to zero */
|
|
#define PQISRC_DEVICE_IO_COUNTER 1
|
|
|
|
#define INVALID_ELEM 0xffff
|
|
#ifndef MIN
|
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
#endif
|
|
|
|
#ifndef MAX
|
|
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
|
#endif
|
|
|
|
#define PQISRC_ROUNDUP(x, y) (((x) + (y) - 1) / (y) * (y))
|
|
#define PQISRC_DIV_ROUND_UP(x, y) (((x) + (y) - 1) / (y))
|
|
|
|
#define ALIGN_BOUNDARY(a, n) { \
|
|
if (a % n) \
|
|
a = a + (n - a % n); \
|
|
}
|
|
|
|
/* Busy wait timeout on a condition */
|
|
#define COND_BUSYWAIT(cond, timeout /* in millisecond */) { \
|
|
if (!(cond)) { \
|
|
while (timeout) { \
|
|
OS_BUSYWAIT(1000); \
|
|
if (cond) \
|
|
break; \
|
|
timeout--; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
/* Wait timeout on a condition*/
|
|
#define COND_WAIT(cond, timeout /* in millisecond */) { \
|
|
if (!(cond)) { \
|
|
while (timeout) { \
|
|
OS_SLEEP(1000); \
|
|
if (cond) \
|
|
break; \
|
|
timeout--; \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define FILL_QUEUE_ARRAY_ADDR(q,virt,dma) { \
|
|
q->array_virt_addr = virt; \
|
|
q->array_dma_addr = dma; \
|
|
}
|
|
|
|
#define true 1
|
|
#define false 0
|
|
|
|
enum INTR_TYPE {
|
|
LOCK_INTR,
|
|
LOCK_SLEEP
|
|
};
|
|
|
|
#define LOCKNAME_SIZE 32
|
|
|
|
#define INTR_TYPE_NONE 0x0
|
|
#define INTR_TYPE_FIXED 0x1
|
|
#define INTR_TYPE_MSI 0x2
|
|
#define INTR_TYPE_MSIX 0x4
|
|
#define SIS_ENABLE_MSIX 0x40
|
|
#define SIS_ENABLE_INTX 0x80
|
|
#define PQISRC_LEGACY_INTX_MASK 0x1
|
|
|
|
#define DMA_TO_VIRT(mem) ((mem)->virt_addr)
|
|
#define DMA_PHYS_LOW(mem) (((mem)->dma_addr) & 0x00000000ffffffff)
|
|
#define DMA_PHYS_HIGH(mem) ((((mem)->dma_addr) & 0xffffffff00000000) >> 32)
|
|
|
|
|
|
typedef enum REQUEST_STATUS {
|
|
REQUEST_SUCCESS = 0,
|
|
REQUEST_PENDING = -1,
|
|
REQUEST_FAILED = -2,
|
|
}REQUEST_STATUS_T;
|
|
typedef enum IO_PATH {
|
|
AIO_PATH,
|
|
RAID_PATH
|
|
}IO_PATH_T;
|
|
|
|
typedef enum device_type
|
|
{
|
|
DISK_DEVICE,
|
|
TAPE_DEVICE,
|
|
ROM_DEVICE = 5,
|
|
SES_DEVICE,
|
|
CONTROLLER_DEVICE,
|
|
MEDIUM_CHANGER_DEVICE,
|
|
RAID_DEVICE = 0x0c,
|
|
ENCLOSURE_DEVICE,
|
|
ZBC_DEVICE = 0x14
|
|
} device_type_t;
|
|
|
|
typedef enum controller_state {
|
|
PQI_UP_RUNNING,
|
|
PQI_BUS_RESET,
|
|
}controller_state_t;
|
|
|
|
|
|
#define PQISRC_MAX_MSIX_SUPPORTED 64
|
|
|
|
/* SIS Specific */
|
|
#define PQISRC_INIT_STRUCT_REVISION 9
|
|
#define PQISRC_SECTOR_SIZE 512
|
|
#define PQISRC_BLK_SIZE PQISRC_SECTOR_SIZE
|
|
#define PQISRC_DEFAULT_DMA_ALIGN 4
|
|
#define PQISRC_DMA_ALIGN_MASK (PQISRC_DEFAULT_DMA_ALIGN - 1)
|
|
#define PQISRC_ERR_BUF_DMA_ALIGN 32
|
|
#define PQISRC_ERR_BUF_ELEM_SIZE MAX(sizeof(raid_path_error_info_elem_t),sizeof(aio_path_error_info_elem_t))
|
|
#define PQISRC_INIT_STRUCT_DMA_ALIGN 16
|
|
|
|
#define SIS_CMD_GET_ADAPTER_PROPERTIES 0x19
|
|
#define SIS_CMD_GET_COMM_PREFERRED_SETTINGS 0x26
|
|
#define SIS_CMD_GET_PQI_CAPABILITIES 0x3000
|
|
#define SIS_CMD_INIT_BASE_STRUCT_ADDRESS 0x1b
|
|
|
|
#define SIS_SUPPORT_EXT_OPT 0x00800000
|
|
#define SIS_SUPPORT_PQI 0x00000004
|
|
#define SIS_SUPPORT_PQI_RESET_QUIESCE 0x00000008
|
|
|
|
#define SIS_PQI_RESET_QUIESCE 0x1000000
|
|
|
|
#define SIS_STATUS_OK_TIMEOUT 120000 /* in milli sec, 5 sec */
|
|
|
|
#define SIS_CMD_COMPLETE_TIMEOUT 30000 /* in milli sec, 30 secs */
|
|
#define SIS_POLL_START_WAIT_TIME 20000 /* in micro sec, 20 milli sec */
|
|
#define SIS_DB_BIT_CLEAR_TIMEOUT_CNT 120000 /* 500usec * 120000 = 60 sec */
|
|
|
|
#define SIS_ENABLE_TIMEOUT 3000
|
|
#define REENABLE_SIS 0x1
|
|
#define TRIGGER_NMI_SIS 0x800000
|
|
/*SIS Register status defines */
|
|
|
|
#define PQI_CTRL_KERNEL_UP_AND_RUNNING 0x80
|
|
#define PQI_CTRL_KERNEL_PANIC 0x100
|
|
|
|
#define SIS_CTL_TO_HOST_DB_DISABLE_ALL 0xFFFFFFFF
|
|
#define SIS_CTL_TO_HOST_DB_CLEAR 0x00001000
|
|
#define SIS_CMD_SUBMIT 0x00000200 /* Bit 9 */
|
|
#define SIS_CMD_COMPLETE 0x00001000 /* Bit 12 */
|
|
#define SIS_CMD_STATUS_SUCCESS 0x1
|
|
|
|
/* PQI specific */
|
|
|
|
/* defines */
|
|
#define PQISRC_PQI_REG_OFFSET 0x4000
|
|
#define PQISRC_MAX_OUTSTANDING_REQ 4096
|
|
#define PQISRC_MAX_ADMIN_IB_QUEUE_ELEM_NUM 16
|
|
#define PQISRC_MAX_ADMIN_OB_QUEUE_ELEM_NUM 16
|
|
|
|
|
|
|
|
#define PQI_MIN_OP_IB_QUEUE_ID 1
|
|
#define PQI_OP_EVENT_QUEUE_ID 1
|
|
#define PQI_MIN_OP_OB_QUEUE_ID 2
|
|
|
|
#define PQISRC_MAX_SUPPORTED_OP_IB_Q 128
|
|
#define PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q (PQISRC_MAX_SUPPORTED_OP_IB_Q / 2)
|
|
#define PQISRC_MAX_SUPPORTED_OP_AIO_IB_Q (PQISRC_MAX_SUPPORTED_OP_RAID_IB_Q)
|
|
#define PQISRC_MAX_OP_IB_QUEUE_ELEM_NUM (PQISRC_MAX_OUTSTANDING_REQ / PQISRC_MAX_SUPPORTED_OP_IB_Q)
|
|
#define PQISRC_MAX_OP_OB_QUEUE_ELEM_NUM PQISRC_MAX_OUTSTANDING_REQ
|
|
#define PQISRC_MIN_OP_OB_QUEUE_ELEM_NUM 2
|
|
#define PQISRC_MAX_SUPPORTED_OP_OB_Q 64
|
|
#define PQISRC_OP_MAX_IBQ_ELEM_SIZE 8 /* 8 * 16 = 128 bytes */
|
|
#define PQISRC_OP_MIN_IBQ_ELEM_SIZE 2 /* 2 * 16 = 32 bytes */
|
|
#define PQISRC_OP_OBQ_ELEM_SIZE 1 /* 16 bytes */
|
|
#define PQISRC_ADMIN_IBQ_ELEM_SIZE 2 /* 2 * 16 = 32 bytes */
|
|
#define PQISRC_INTR_COALSC_GRAN 0
|
|
#define PQISRC_PROTO_BIT_MASK 0
|
|
#define PQISRC_SGL_SUPPORTED_BIT_MASK 0
|
|
|
|
#define PQISRC_NUM_EVENT_Q_ELEM 32
|
|
#define PQISRC_EVENT_Q_ELEM_SIZE 32
|
|
|
|
/* PQI Registers state status */
|
|
|
|
#define PQI_RESET_ACTION_RESET 0x1
|
|
#define PQI_RESET_ACTION_COMPLETED 0x2
|
|
#define PQI_RESET_TYPE_NO_RESET 0x0
|
|
#define PQI_RESET_TYPE_SOFT_RESET 0x1
|
|
#define PQI_RESET_TYPE_FIRM_RESET 0x2
|
|
#define PQI_RESET_TYPE_HARD_RESET 0x3
|
|
|
|
#define PQI_RESET_POLL_INTERVAL 100000 /*100 msec*/
|
|
|
|
enum pqisrc_ctrl_mode{
|
|
CTRL_SIS_MODE = 0,
|
|
CTRL_PQI_MODE
|
|
};
|
|
|
|
/* PQI device performing internal initialization (e.g., POST). */
|
|
#define PQI_DEV_STATE_POWER_ON_AND_RESET 0x0
|
|
/* Upon entry to this state PQI device initialization begins. */
|
|
#define PQI_DEV_STATE_PQI_STATUS_AVAILABLE 0x1
|
|
/* PQI device Standard registers are available to the driver. */
|
|
#define PQI_DEV_STATE_ALL_REGISTERS_READY 0x2
|
|
/* PQI device is initialized and ready to process any PCI transactions. */
|
|
#define PQI_DEV_STATE_ADMIN_QUEUE_PAIR_READY 0x3
|
|
/* The PQI Device Error register indicates the error. */
|
|
#define PQI_DEV_STATE_ERROR 0x4
|
|
|
|
#define PQI_DEV_STATE_AT_INIT ( PQI_DEV_STATE_PQI_STATUS_AVAILABLE | \
|
|
PQI_DEV_STATE_ALL_REGISTERS_READY | \
|
|
PQI_DEV_STATE_ADMIN_QUEUE_PAIR_READY )
|
|
|
|
#define PQISRC_PQI_DEVICE_SIGNATURE "PQI DREG"
|
|
#define PQI_ADMINQ_ELEM_ARRAY_ALIGN 64
|
|
#define PQI_ADMINQ_CI_PI_ALIGN 64
|
|
#define PQI_OPQ_ELEM_ARRAY_ALIGN 64
|
|
#define PQI_OPQ_CI_PI_ALIGN 4
|
|
#define PQI_ADDR_ALIGN_MASK_64 0x3F /* lsb 6 bits */
|
|
#define PQI_ADDR_ALIGN_MASK_4 0x3 /* lsb 2 bits */
|
|
|
|
#define PQISRC_PQIMODE_READY_TIMEOUT (30 * 1000 ) /* 30 secs */
|
|
#define PQISRC_MODE_READY_POLL_INTERVAL 1000 /* 1 msec */
|
|
|
|
#define PRINT_PQI_SIGNATURE(sign) { int i = 0; \
|
|
char si[9]; \
|
|
for(i=0;i<8;i++) \
|
|
si[i] = *((char *)&(sign)+i); \
|
|
si[i] = '\0'; \
|
|
DBG_INFO("Signature is %s",si); \
|
|
}
|
|
#define PQI_CONF_TABLE_MAX_LEN ((uint16_t)~0)
|
|
#define PQI_CONF_TABLE_SIGNATURE "CFGTABLE"
|
|
|
|
/* PQI configuration table section IDs */
|
|
#define PQI_CONF_TABLE_ALL_SECTIONS (-1)
|
|
#define PQI_CONF_TABLE_SECTION_GENERAL_INFO 0
|
|
#define PQI_CONF_TABLE_SECTION_FIRMWARE_FEATURES 1
|
|
#define PQI_CONF_TABLE_SECTION_FIRMWARE_ERRATA 2
|
|
#define PQI_CONF_TABLE_SECTION_DEBUG 3
|
|
#define PQI_CONF_TABLE_SECTION_HEARTBEAT 4
|
|
|
|
|
|
#define PQI_FIRMWARE_FEATURE_OFA 0
|
|
#define PQI_FIRMWARE_FEATURE_SMP 1
|
|
#define PQI_FIRMWARE_FEATURE_MAX_KNOWN 2
|
|
#define PQI_FIRMWARE_FEATURE_AIO_READ_RAID_0 3
|
|
#define PQI_FIRMWARE_FEATURE_AIO_READ_RAID_1_10 4
|
|
#define PQI_FIRMWARE_FEATURE_AIO_READ_RAID_5_50 5
|
|
#define PQI_FIRMWARE_FEATURE_AIO_READ_RAID_6_60 6
|
|
#define PQI_FIRMWARE_FEATURE_AIO_WRITE_RAID_0 7
|
|
#define PQI_FIRMWARE_FEATURE_AIO_WRITE_RAID_1_10 8
|
|
#define PQI_FIRMWARE_FEATURE_AIO_WRITE_RAID_5_50 9
|
|
#define PQI_FIRMWARE_FEATURE_AIO_WRITE_RAID_6_60 10
|
|
#define PQI_FIRMWARE_FEATURE_SOFT_RESET_HANDSHAKE 11
|
|
#define PQI_FIRMWARE_FEATURE_SATA_WWN_FOR_DEV_UNIQUE_ID 12
|
|
#define PQI_FIRMWARE_FEATURE_TIMEOUT_IN_RAID_IU_SUPPORT 13
|
|
#define PQI_FIRMWARE_FEATURE_TIMEOUT_IN_TMF_IU_SUPPORT 14
|
|
#define PQI_FIRMWARE_FEATURE_MAXIMUM 14
|
|
|
|
#define CTRLR_HEARTBEAT_CNT(softs) \
|
|
LE_64(PCI_MEM_GET64(softs, softs->heartbeat_counter_abs_addr, softs->heartbeat_counter_off))
|
|
#define PQI_HEARTBEAT_TIMEOUT_SEC (10) /* 10 sec interval */
|
|
#define PQI_HOST_WELLNESS_TIMEOUT_SEC (24*3600)
|
|
|
|
/* pqi-2r00a table 36 */
|
|
#define PQI_ADMIN_QUEUE_MSIX_DISABLE (0x80000000)
|
|
#define PQI_ADMIN_QUEUE_MSIX_ENABLE (0 << 31)
|
|
|
|
#define PQI_ADMIN_QUEUE_CONF_FUNC_CREATE_Q_PAIR 0x01
|
|
#define PQI_ADMIN_QUEUE_CONF_FUNC_DEL_Q_PAIR 0x02
|
|
#define PQI_ADMIN_QUEUE_CONF_FUNC_STATUS_IDLE 0x00
|
|
#define PQISRC_ADMIN_QUEUE_CREATE_TIMEOUT 1000 /* in miLLI sec, 1 sec, 100 ms is standard */
|
|
#define PQISRC_ADMIN_QUEUE_DELETE_TIMEOUT 100 /* 100 ms is standard */
|
|
#define PQISRC_ADMIN_CMD_RESP_TIMEOUT 3000 /* 3 sec */
|
|
#define PQISRC_RAIDPATH_CMD_TIMEOUT 30000 /* 30 sec */
|
|
|
|
#define REPORT_PQI_DEV_CAP_DATA_BUF_SIZE sizeof(pqi_dev_cap_t)
|
|
#define REPORT_MANUFACTURER_INFO_DATA_BUF_SIZE 0x80 /* Data buffer size specified in bytes 0-1 of data buffer. 128 bytes. */
|
|
/* PQI IUs */
|
|
/* Admin IU request length not including header. */
|
|
#define PQI_STANDARD_IU_LENGTH 0x003C /* 60 bytes. */
|
|
#define PQI_IU_TYPE_GENERAL_ADMIN_REQUEST 0x60
|
|
#define PQI_IU_TYPE_GENERAL_ADMIN_RESPONSE 0xe0
|
|
|
|
/* PQI / Vendor specific IU */
|
|
#define PQI_FUNCTION_REPORT_DEV_CAP 0x00
|
|
#define PQI_REQUEST_IU_RAID_TASK_MANAGEMENT 0x13
|
|
#define PQI_IU_TYPE_RAID_PATH_IO_REQUEST 0x14
|
|
#define PQI_IU_TYPE_AIO_PATH_IO_REQUEST 0x15
|
|
#define PQI_REQUEST_IU_AIO_TASK_MANAGEMENT 0x16
|
|
#define PQI_REQUEST_IU_GENERAL_ADMIN 0x60
|
|
#define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG 0x72
|
|
#define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG 0x73
|
|
#define PQI_REQUEST_IU_VENDOR_GENERAL 0x75
|
|
#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81
|
|
#define PQI_RESPONSE_IU_TASK_MANAGEMENT 0x93
|
|
#define PQI_RESPONSE_IU_GENERAL_ADMIN 0xe0
|
|
|
|
#define PQI_RESPONSE_IU_RAID_PATH_IO_SUCCESS 0xf0
|
|
#define PQI_RESPONSE_IU_AIO_PATH_IO_SUCCESS 0xf1
|
|
#define PQI_RESPONSE_IU_RAID_PATH_IO_ERROR 0xf2
|
|
#define PQI_RESPONSE_IU_AIO_PATH_IO_ERROR 0xf3
|
|
#define PQI_RESPONSE_IU_AIO_PATH_IS_OFF 0xf4
|
|
#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6
|
|
#define PQI_RESPONSE_IU_VENDOR_GENERAL 0xf7
|
|
#define PQI_REQUEST_HEADER_LENGTH 4
|
|
#define PQI_FUNCTION_CREATE_OPERATIONAL_IQ 0x10
|
|
#define PQI_FUNCTION_CREATE_OPERATIONAL_OQ 0x11
|
|
#define PQI_FUNCTION_DELETE_OPERATIONAL_IQ 0x12
|
|
#define PQI_FUNCTION_DELETE_OPERATIONAL_OQ 0x13
|
|
#define PQI_FUNCTION_CHANGE_OPERATIONAL_IQ_PROP 0x14
|
|
#define PQI_CHANGE_OP_IQ_PROP_ASSIGN_AIO 1
|
|
|
|
#define PQI_DEFAULT_IB_QUEUE 0
|
|
#define PQI_VENDOR_GENERAL_CONFIG_TABLE_UPDATE 0
|
|
|
|
#define PQI_VENDOR_RESPONSE_IU_SUCCESS 0
|
|
#define PQI_VENDOR_RESPONSE_IU_UNSUCCESS 1
|
|
#define PQI_VENDOR_RESPONSE_IU_INVALID_PARAM 2
|
|
#define PQI_VENDOR_RESPONSE_IU_INSUFF_RESRC 3
|
|
|
|
/* Interface macros */
|
|
|
|
#define GET_FW_STATUS(softs) \
|
|
(PCI_MEM_GET32(softs, &softs->ioa_reg->scratchpad3_fw_status, LEGACY_SIS_OMR))
|
|
|
|
#define SIS_IS_KERNEL_PANIC(softs) \
|
|
(GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_PANIC)
|
|
|
|
#define SIS_IS_KERNEL_UP(softs) \
|
|
(GET_FW_STATUS(softs) & PQI_CTRL_KERNEL_UP_AND_RUNNING)
|
|
|
|
#define PQI_GET_CTRL_MODE(softs) \
|
|
(PCI_MEM_GET32(softs, &softs->ioa_reg->scratchpad0, LEGACY_SIS_SCR0))
|
|
|
|
#define PQI_SAVE_CTRL_MODE(softs, mode) \
|
|
PCI_MEM_PUT32(softs, &softs->ioa_reg->scratchpad0, LEGACY_SIS_SCR0, mode)
|
|
|
|
#define PQISRC_MAX_TARGETID 1024
|
|
#define PQISRC_MAX_TARGETLUN 64
|
|
|
|
/* Vendor specific IU Type for Event config Cmds */
|
|
#define PQI_REQUEST_IU_REPORT_EVENT_CONFIG 0x72
|
|
#define PQI_REQUEST_IU_SET_EVENT_CONFIG 0x73
|
|
#define PQI_REQUEST_IU_ACKNOWLEDGE_VENDOR_EVENT 0xf6
|
|
|
|
#define PQI_RESPONSE_IU_GENERAL_MANAGEMENT 0x81
|
|
#define PQI_MANAGEMENT_CMD_RESP_TIMEOUT 3000
|
|
#define PQISRC_EVENT_ACK_RESP_TIMEOUT 1000
|
|
|
|
|
|
/* Supported Event types by controller */
|
|
|
|
#define PQI_NUM_SUPPORTED_EVENTS 6
|
|
|
|
#define PQI_EVENT_TYPE_HOTPLUG 0x1
|
|
#define PQI_EVENT_TYPE_HARDWARE 0x2
|
|
#define PQI_EVENT_TYPE_PHYSICAL_DEVICE 0x4
|
|
#define PQI_EVENT_TYPE_LOGICAL_DEVICE 0x5
|
|
#define PQI_EVENT_TYPE_AIO_STATE_CHANGE 0xfd
|
|
#define PQI_EVENT_TYPE_AIO_CONFIG_CHANGE 0xfe
|
|
|
|
/* for indexing into the pending_events[] field of struct pqisrc_softstate */
|
|
#define PQI_EVENT_HOTPLUG 0
|
|
#define PQI_EVENT_HARDWARE 1
|
|
#define PQI_EVENT_PHYSICAL_DEVICE 2
|
|
#define PQI_EVENT_LOGICAL_DEVICE 3
|
|
#define PQI_EVENT_AIO_STATE_CHANGE 4
|
|
#define PQI_EVENT_AIO_CONFIG_CHANGE 5
|
|
|
|
|
|
|
|
/* Device flags */
|
|
#define PQISRC_DFLAG_VALID (1 << 0)
|
|
#define PQISRC_DFLAG_CONFIGURING (1 << 1)
|
|
|
|
#define MAX_EMBEDDED_SG_IN_FIRST_IU 4
|
|
#define MAX_EMBEDDED_SG_IN_IU 8
|
|
#define SG_FLAG_LAST 0x40000000
|
|
#define SG_FLAG_CHAIN 0x80000000
|
|
|
|
#define IN_PQI_RESET(softs) (softs->ctlr_state & PQI_BUS_RESET)
|
|
#define DEV_GONE(dev) (!dev || (dev->invalid == true))
|
|
#define IS_AIO_PATH(dev) (dev->aio_enabled)
|
|
#define IS_RAID_PATH(dev) (!dev->aio_enabled)
|
|
|
|
#define DEVICE_RESET(dvp) (dvp->reset_in_progress)
|
|
|
|
/* SOP data direction flags */
|
|
#define SOP_DATA_DIR_NONE 0x00
|
|
#define SOP_DATA_DIR_FROM_DEVICE 0x01
|
|
#define SOP_DATA_DIR_TO_DEVICE 0x02
|
|
#define SOP_DATA_DIR_BIDIRECTIONAL 0x03
|
|
#define SOP_PARTIAL_DATA_BUFFER 0x04
|
|
|
|
#define PQISRC_DMA_VALID (1 << 0)
|
|
#define PQISRC_CMD_NO_INTR (1 << 1)
|
|
|
|
#define SOP_TASK_ATTRIBUTE_SIMPLE 0
|
|
#define SOP_TASK_ATTRIBUTE_HEAD_OF_QUEUE 1
|
|
#define SOP_TASK_ATTRIBUTE_ORDERED 2
|
|
#define SOP_TASK_ATTRIBUTE_ACA 4
|
|
|
|
#define SOP_TASK_MANAGEMENT_FUNCTION_COMPLETE 0x0
|
|
#define SOP_TASK_MANAGEMENT_FUNCTION_REJECTED 0x4
|
|
#define SOP_TASK_MANAGEMENT_FUNCTION_FAILED 0x5
|
|
#define SOP_TASK_MANAGEMENT_FUNCTION_SUCCEEDED 0x8
|
|
#define SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK 0x01
|
|
#define SOP_TASK_MANAGEMENT_FUNCTION_ABORT_TASK_SET 0x02
|
|
#define SOP_TASK_MANAGEMENT_LUN_RESET 0x8
|
|
|
|
|
|
/* Additional CDB bytes */
|
|
#define PQI_ADDITIONAL_CDB_BYTES_0 0 /* 16 byte CDB */
|
|
#define PQI_ADDITIONAL_CDB_BYTES_4 1 /* 20 byte CDB */
|
|
#define PQI_ADDITIONAL_CDB_BYTES_8 2 /* 24 byte CDB */
|
|
#define PQI_ADDITIONAL_CDB_BYTES_12 3 /* 28 byte CDB */
|
|
#define PQI_ADDITIONAL_CDB_BYTES_16 4 /* 32 byte CDB */
|
|
|
|
#define PQI_PROTOCOL_SOP 0x0
|
|
|
|
#define PQI_AIO_STATUS_GOOD 0x0
|
|
#define PQI_AIO_STATUS_CHECK_CONDITION 0x2
|
|
#define PQI_AIO_STATUS_CONDITION_MET 0x4
|
|
#define PQI_AIO_STATUS_DEVICE_BUSY 0x8
|
|
#define PQI_AIO_STATUS_INT_GOOD 0x10
|
|
#define PQI_AIO_STATUS_INT_COND_MET 0x14
|
|
#define PQI_AIO_STATUS_RESERV_CONFLICT 0x18
|
|
#define PQI_AIO_STATUS_CMD_TERMINATED 0x22
|
|
#define PQI_AIO_STATUS_QUEUE_FULL 0x28
|
|
#define PQI_AIO_STATUS_TASK_ABORTED 0x40
|
|
#define PQI_AIO_STATUS_UNDERRUN 0x51
|
|
#define PQI_AIO_STATUS_OVERRUN 0x75
|
|
/* Status when Target Failure */
|
|
#define PQI_AIO_STATUS_IO_ERROR 0x1
|
|
#define PQI_AIO_STATUS_IO_ABORTED 0x2
|
|
#define PQI_AIO_STATUS_IO_NO_DEVICE 0x3
|
|
#define PQI_AIO_STATUS_INVALID_DEVICE 0x4
|
|
#define PQI_AIO_STATUS_AIO_PATH_DISABLED 0xe
|
|
|
|
/* Service Response */
|
|
#define PQI_AIO_SERV_RESPONSE_COMPLETE 0
|
|
#define PQI_AIO_SERV_RESPONSE_FAILURE 1
|
|
#define PQI_AIO_SERV_RESPONSE_TMF_COMPLETE 2
|
|
#define PQI_AIO_SERV_RESPONSE_TMF_SUCCEEDED 3
|
|
#define PQI_AIO_SERV_RESPONSE_TMF_REJECTED 4
|
|
#define PQI_AIO_SERV_RESPONSE_TMF_INCORRECT_LUN 5
|
|
|
|
#define PQI_TMF_WAIT_DELAY 10000000 /* 10 seconds */
|
|
|
|
#define PQI_RAID_STATUS_GOOD PQI_AIO_STATUS_GOOD
|
|
#define PQI_RAID_STATUS_CHECK_CONDITION PQI_AIO_STATUS_CHECK_CONDITION
|
|
#define PQI_RAID_STATUS_CONDITION_MET PQI_AIO_STATUS_CONDITION_MET
|
|
#define PQI_RAID_STATUS_DEVICE_BUSY PQI_AIO_STATUS_DEVICE_BUSY
|
|
#define PQI_RAID_STATUS_INT_GOOD PQI_AIO_STATUS_INT_GOOD
|
|
#define PQI_RAID_STATUS_INT_COND_MET PQI_AIO_STATUS_INT_COND_MET
|
|
#define PQI_RAID_STATUS_RESERV_CONFLICT PQI_AIO_STATUS_RESERV_CONFLICT
|
|
#define PQI_RAID_STATUS_CMD_TERMINATED PQI_AIO_STATUS_CMD_TERMINATED
|
|
#define PQI_RAID_STATUS_QUEUE_FULL PQI_AIO_STATUS_QUEUE_FULL
|
|
#define PQI_RAID_STATUS_TASK_ABORTED PQI_AIO_STATUS_TASK_ABORTED
|
|
#define PQI_RAID_STATUS_UNDERRUN PQI_AIO_STATUS_UNDERRUN
|
|
#define PQI_RAID_STATUS_OVERRUN PQI_AIO_STATUS_OVERRUN
|
|
|
|
/* VPD inquiry pages */
|
|
#define SCSI_VPD_SUPPORTED_PAGES 0x0 /* standard page */
|
|
#define SCSI_VPD_DEVICE_ID 0x83 /* standard page */
|
|
#define SA_VPD_PHYS_DEVICE_ID 0xc0 /* vendor-specific page */
|
|
#define SA_VPD_LV_DEVICE_GEOMETRY 0xc1 /* vendor-specific page */
|
|
#define SA_VPD_LV_IOACCEL_STATUS 0xc2 /* vendor-specific page */
|
|
#define SA_VPD_LV_STATUS 0xc3 /* vendor-specific page */
|
|
|
|
#define VPD_PAGE (1 << 8)
|
|
|
|
|
|
/* logical volume states */
|
|
#define SA_LV_OK 0x0
|
|
#define SA_LV_FAILED 0x1
|
|
#define SA_LV_NOT_CONFIGURED 0x2
|
|
#define SA_LV_DEGRADED 0x3
|
|
#define SA_LV_READY_FOR_RECOVERY 0x4
|
|
#define SA_LV_UNDERGOING_RECOVERY 0x5
|
|
#define SA_LV_WRONG_PHYSICAL_DRIVE_REPLACED 0x6
|
|
#define SA_LV_PHYSICAL_DRIVE_CONNECTION_PROBLEM 0x7
|
|
#define SA_LV_HARDWARE_OVERHEATING 0x8
|
|
#define SA_LV_HARDWARE_HAS_OVERHEATED 0x9
|
|
#define SA_LV_UNDERGOING_EXPANSION 0xA
|
|
#define SA_LV_NOT_AVAILABLE 0xb
|
|
#define SA_LV_QUEUED_FOR_EXPANSION 0xc
|
|
#define SA_LV_DISABLED_SCSI_ID_CONFLICT 0xd
|
|
#define SA_LV_EJECTED 0xe
|
|
#define SA_LV_UNDERGOING_ERASE 0xf
|
|
#define SA_LV_UNDERGOING_RPI 0x12
|
|
#define SA_LV_PENDING_RPI 0x13
|
|
#define SA_LV_ENCRYPTED_NO_KEY 0x14
|
|
#define SA_LV_PLAINTEXT_IN_ENCRYPT_ONLY_CONTROLLER 0x15
|
|
#define SA_LV_UNDERGOING_ENCRYPTION 0x16
|
|
#define SA_LV_UNDERGOING_ENCRYPTION_REKEYING 0x17
|
|
#define SA_LV_ENCRYPTED_IN_NON_ENCRYPTED_CONTROLLER 0x18
|
|
#define SA_LV_PENDING_ENCRYPTION 0x19
|
|
#define SA_LV_PENDING_ENCRYPTION_REKEYING 0x1a
|
|
#define SA_LV_STATUS_VPD_UNSUPPORTED 0xff
|
|
|
|
|
|
/* constants for flags field of ciss_vpd_logical_volume_status */
|
|
#define SA_LV_FLAGS_NO_HOST_IO 0x1 /* volume not available for */
|
|
|
|
/*
|
|
* assume worst case: SATA queue depth of 31 minus 4 internal firmware commands
|
|
*/
|
|
#define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH 27
|
|
|
|
/* 0 = no limit */
|
|
#define PQI_LOGICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH 0
|
|
#define PQI_LOG_EXT_QUEUE_DEPTH_ENABLED 0x20
|
|
#define PQI_LOG_EXT_QUEUE_ENABLE 0x56
|
|
#define MAX_RAW_M256_QDEPTH 32512
|
|
#define MAX_RAW_M16_QDEPTH 2032
|
|
#define PQI_PTRAID_UPDATE_ON_RESCAN_LUNS 0x80000000
|
|
|
|
#define RAID_CTLR_LUNID "\0\0\0\0\0\0\0\0"
|
|
|
|
#define SA_CACHE_FLUSH 0x1
|
|
#define PQISRC_INQUIRY_TIMEOUT 30
|
|
#define SA_INQUIRY 0x12
|
|
#define SA_REPORT_LOG 0xc2 /* Report Logical LUNs */
|
|
#define SA_REPORT_PHYS 0xc3 /* Report Physical LUNs */
|
|
#define SA_CISS_READ 0xc0
|
|
#define SA_GET_RAID_MAP 0xc8
|
|
|
|
#define SCSI_SENSE_RESPONSE_70 0x70
|
|
#define SCSI_SENSE_RESPONSE_71 0x71
|
|
#define SCSI_SENSE_RESPONSE_72 0x72
|
|
#define SCSI_SENSE_RESPONSE_73 0x73
|
|
|
|
#define SA_REPORT_LOG_EXTENDED 0x1
|
|
#define SA_REPORT_PHYS_EXTENDED 0x2
|
|
|
|
#define SA_CACHE_FLUSH_BUF_LEN 4
|
|
|
|
#define GET_SCSI_SNO(cmd) (cmd->cmdId.serialNumber)
|
|
|
|
#define REPORT_LUN_DEV_FLAG_AIO_ENABLED 0x8
|
|
#define PQI_MAX_TRANSFER_SIZE (4 * 1024U * 1024U)
|
|
#define RAID_MAP_MAX_ENTRIES 1024
|
|
#define RAID_MAP_ENCRYPTION_ENABLED 0x1
|
|
#define PQI_PHYSICAL_DISK_DEFAULT_MAX_QUEUE_DEPTH 27
|
|
|
|
#define ASC_LUN_NOT_READY 0x4
|
|
#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS 0x4
|
|
#define ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ 0x2
|
|
|
|
|
|
#define OBDR_SIG_OFFSET 43
|
|
#define OBDR_TAPE_SIG "$DR-10"
|
|
#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1)
|
|
#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN)
|
|
|
|
|
|
#define IOACCEL_STATUS_BYTE 4
|
|
#define OFFLOAD_CONFIGURED_BIT 0x1
|
|
#define OFFLOAD_ENABLED_BIT 0x2
|
|
|
|
#define PQI_RAID_DATA_IN_OUT_GOOD 0x0
|
|
#define PQI_RAID_DATA_IN_OUT_UNDERFLOW 0x1
|
|
#define PQI_RAID_DATA_IN_OUT_BUFFER_ERROR 0x40
|
|
#define PQI_RAID_DATA_IN_OUT_BUFFER_OVERFLOW 0x41
|
|
#define PQI_RAID_DATA_IN_OUT_BUFFER_OVERFLOW_DESCRIPTOR_AREA 0x42
|
|
#define PQI_RAID_DATA_IN_OUT_BUFFER_OVERFLOW_BRIDGE 0x43
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_FABRIC_ERROR 0x60
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_COMPLETION_TIMEOUT 0x61
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_COMPLETER_ABORT_RECEIVED 0x62
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_POISONED_MEMORY_READ 0x63
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_ECRC_CHECK_FAILED 0x64
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_UNSUPPORTED_REQUEST 0x65
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_ACS_VIOLATION 0x66
|
|
#define PQI_RAID_DATA_IN_OUT_PCIE_TLP_PREFIX_BLOCKED 0x67
|
|
#define PQI_RAID_DATA_IN_OUT_ERROR 0xf0
|
|
#define PQI_RAID_DATA_IN_OUT_PROTOCOL_ERROR 0xf1
|
|
#define PQI_RAID_DATA_IN_OUT_HARDWARE_ERROR 0xf2
|
|
#define PQI_RAID_DATA_IN_OUT_UNSOLICITED_ABORT 0xf3
|
|
#define PQI_RAID_DATA_IN_OUT_ABORTED 0xf4
|
|
#define PQI_RAID_DATA_IN_OUT_TIMEOUT 0xf5
|
|
|
|
|
|
#define PQI_PHYSICAL_DEVICE_BUS 0
|
|
#define PQI_RAID_VOLUME_BUS 1
|
|
#define PQI_HBA_BUS 2
|
|
#define PQI_EXTERNAL_RAID_VOLUME_BUS 3
|
|
#define PQI_MAX_BUS PQI_EXTERNAL_RAID_VOLUME_BUS
|
|
|
|
#define TEST_UNIT_READY 0x00
|
|
#define SCSI_VPD_HEADER_LENGTH 64
|
|
|
|
|
|
#define PQI_MAX_MULTILUN 256
|
|
#define PQI_MAX_LOGICALS 64
|
|
#define PQI_MAX_PHYSICALS 1024
|
|
#define PQI_MAX_DEVICES (PQI_MAX_LOGICALS + PQI_MAX_PHYSICALS + 1) /* 1 for controller device entry */
|
|
#define PQI_MAX_EXT_TARGETS 32
|
|
|
|
#define PQI_CTLR_INDEX (PQI_MAX_DEVICES - 1)
|
|
#define PQI_PD_INDEX(t) (t + PQI_MAX_LOGICALS)
|
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
#define MAX_TARGET_DEVICES 1024
|
|
|
|
#define PQI_NO_MEM 2
|
|
|
|
typedef enum pqisrc_device_status {
|
|
DEVICE_NOT_FOUND,
|
|
DEVICE_CHANGED,
|
|
DEVICE_UNCHANGED,
|
|
} device_status_t;
|
|
|
|
#define SA_RAID_0 0
|
|
#define SA_RAID_4 1
|
|
#define SA_RAID_1 2 /* also used for RAID 10 */
|
|
#define SA_RAID_5 3 /* also used for RAID 50 */
|
|
#define SA_RAID_51 4
|
|
#define SA_RAID_6 5 /* also used for RAID 60 */
|
|
#define SA_RAID_ADM 6 /* also used for RAID 1+0 ADM */
|
|
#define SA_RAID_MAX SA_RAID_ADM
|
|
#define SA_RAID_UNKNOWN 0xff
|
|
|
|
#define BIT0 (1 << 0)
|
|
#define BIT1 (1 << 1)
|
|
#define BIT2 (1 << 2)
|
|
#define BIT3 (1 << 3)
|
|
|
|
#define BITS_PER_BYTE 8
|
|
/* BMIC commands */
|
|
#define BMIC_IDENTIFY_CONTROLLER 0x11
|
|
#define BMIC_IDENTIFY_PHYSICAL_DEVICE 0x15
|
|
#define BMIC_READ 0x26
|
|
#define BMIC_WRITE 0x27
|
|
#define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64
|
|
#define BMIC_SENSE_SUBSYSTEM_INFORMATION 0x66
|
|
#define BMIC_CACHE_FLUSH 0xc2
|
|
#define BMIC_FLASH_FIRMWARE 0xf7
|
|
#define BMIC_WRITE_HOST_WELLNESS 0xa5
|
|
#define BMIC_SET_DIAGS_OPTIONS 0xf4
|
|
#define BMIC_SENSE_DIAGS_OPTIONS 0xf5
|
|
|
|
|
|
#define MASKED_DEVICE(lunid) ((lunid)[3] & 0xC0)
|
|
#define BMIC_GET_LEVEL_2_BUS(lunid) ((lunid)[7] & 0x3F)
|
|
#define BMIC_GET_LEVEL_TWO_TARGET(lunid) ((lunid)[6])
|
|
#define BMIC_GET_DRIVE_NUMBER(lunid) \
|
|
(((BMIC_GET_LEVEL_2_BUS((lunid)) - 1) << 8) + \
|
|
BMIC_GET_LEVEL_TWO_TARGET((lunid)))
|
|
#define NON_DISK_PHYS_DEV(rle) \
|
|
(((reportlun_ext_entry_t *)(rle))->device_flags & 0x1)
|
|
|
|
#define NO_TIMEOUT ((unsigned long) -1)
|
|
|
|
#define BMIC_DEVICE_TYPE_SATA 0x1
|
|
|
|
/* No of IO slots required for internal requests */
|
|
#define PQI_RESERVED_IO_SLOTS_SYNC_REQUESTS 3
|
|
#define PQI_RESERVED_IO_SLOTS_TMF 1
|
|
#define PQI_RESERVED_IO_SLOTS_CNT (PQI_NUM_SUPPORTED_EVENTS + \
|
|
PQI_RESERVED_IO_SLOTS_TMF + \
|
|
PQI_RESERVED_IO_SLOTS_SYNC_REQUESTS)
|
|
|
|
/* Defines for print flags */
|
|
#define PRINT_FLAG_HDR_COLUMN 0x0001
|
|
|
|
|
|
static inline uint16_t GET_LE16(const uint8_t *p)
|
|
{
|
|
return p[0] | p[1] << 8;
|
|
}
|
|
|
|
static inline uint32_t GET_LE32(const uint8_t *p)
|
|
{
|
|
return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
|
|
}
|
|
|
|
static inline uint64_t GET_LE64(const uint8_t *p)
|
|
{
|
|
return (((uint64_t)GET_LE32(p + 4) << 32) |
|
|
GET_LE32(p));
|
|
}
|
|
|
|
static inline uint16_t GET_BE16(const uint8_t *p)
|
|
{
|
|
return p[0] << 8 | p[1];
|
|
}
|
|
|
|
static inline uint32_t GET_BE32(const uint8_t *p)
|
|
{
|
|
return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
|
|
}
|
|
|
|
static inline uint64_t GET_BE64(const uint8_t *p)
|
|
{
|
|
return (((uint64_t)GET_BE32(p) << 32) |
|
|
GET_BE32(p + 4));
|
|
}
|
|
|
|
static inline void PUT_BE16(uint16_t val, uint8_t *p)
|
|
{
|
|
*p++ = val >> 8;
|
|
*p++ = val;
|
|
}
|
|
|
|
static inline void PUT_BE32(uint32_t val, uint8_t *p)
|
|
{
|
|
PUT_BE16(val >> 16, p);
|
|
PUT_BE16(val, p + 2);
|
|
}
|
|
|
|
static inline void PUT_BE64(uint64_t val, uint8_t *p)
|
|
{
|
|
PUT_BE32(val >> 32, p);
|
|
PUT_BE32(val, p + 4);
|
|
}
|
|
|
|
#define OS_FREEBSD
|
|
#define SIS_POLL_WAIT
|
|
|
|
#define OS_ATTRIBUTE_PACKED __attribute__((__packed__))
|
|
#define OS_ATTRIBUTE_ALIGNED(n) __attribute__((aligned(n)))
|
|
|
|
|
|
/* Management Interface */
|
|
#define CCISS_IOC_MAGIC 'C'
|
|
#define SMARTPQI_IOCTL_BASE 'M'
|
|
#define CCISS_GETDRIVVER _IOWR(SMARTPQI_IOCTL_BASE, 0, driver_info)
|
|
#define CCISS_GETPCIINFO _IOWR(SMARTPQI_IOCTL_BASE, 1, pqi_pci_info_t)
|
|
#define SMARTPQI_PASS_THRU _IOWR(SMARTPQI_IOCTL_BASE, 2, IOCTL_Command_struct)
|
|
#define CCISS_PASSTHRU _IOWR('C', 210, IOCTL_Command_struct)
|
|
#define CCISS_REGNEWD _IO(CCISS_IOC_MAGIC, 14)
|
|
|
|
/*IOCTL pci_info structure */
|
|
typedef struct pqi_pci_info
|
|
{
|
|
unsigned char bus;
|
|
unsigned char dev_fn;
|
|
unsigned short domain;
|
|
uint32_t board_id;
|
|
uint32_t chip_id;
|
|
}pqi_pci_info_t;
|
|
|
|
typedef struct _driver_info
|
|
{
|
|
unsigned char major_version;
|
|
unsigned long minor_version;
|
|
unsigned char release_version;
|
|
unsigned long build_revision;
|
|
unsigned long max_targets;
|
|
unsigned long max_io;
|
|
unsigned long max_transfer_length;
|
|
}driver_info, *pdriver_info;
|
|
|
|
typedef uint8_t *passthru_buf_type_t;
|
|
|
|
|
|
#define PQISRC_OS_VERSION 1
|
|
#define PQISRC_FEATURE_VERSION 4014
|
|
#define PQISRC_PATCH_VERSION 0
|
|
#define PQISRC_BUILD_VERSION 105
|
|
|
|
#define STR(s) # s
|
|
#define PQISRC_VERSION(a, b, c, d) STR(a.b.c.d)
|
|
#define PQISRC_DRIVER_VERSION PQISRC_VERSION(PQISRC_OS_VERSION, \
|
|
PQISRC_FEATURE_VERSION, \
|
|
PQISRC_PATCH_VERSION, \
|
|
PQISRC_BUILD_VERSION)
|
|
|
|
/* End Management interface */
|
|
|
|
#ifdef ASSERT
|
|
#undef ASSERT
|
|
#endif
|
|
|
|
/*
|
|
*os_atomic64_cas--
|
|
*
|
|
*Atomically read, compare, and conditionally write.
|
|
*i.e. compare and swap.
|
|
*retval True On Success
|
|
*retval False On Failure
|
|
*
|
|
*/
|
|
static inline boolean_t
|
|
os_atomic64_cas(volatile uint64_t* var, uint64_t old_val, uint64_t new_val)
|
|
{
|
|
return (atomic_cmpset_64(var, old_val, new_val));
|
|
}
|
|
|
|
#define ASSERT(cond) {\
|
|
if (!(cond)) { \
|
|
printf("Assertion failed at file %s line %d\n",__FILE__,__LINE__); \
|
|
} \
|
|
}
|
|
|
|
/* Atomic */
|
|
typedef volatile uint64_t OS_ATOMIC64_T;
|
|
#define OS_ATOMIC64_READ(p) atomic_load_acq_64(p)
|
|
#define OS_ATOMIC64_INIT(p,val) atomic_store_rel_64(p, val)
|
|
|
|
/* 64-bit post atomic increment and decrement operations on value in pointer.*/
|
|
#define OS_ATOMIC64_DEC(p) (atomic_fetchadd_64(p, -1) - 1)
|
|
#define OS_ATOMIC64_INC(p) (atomic_fetchadd_64(p, 1) + 1)
|
|
|
|
|
|
#define PQI_MAX_MSIX 64 /* vectors */
|
|
#define PQI_MSI_CTX_SIZE sizeof(pqi_intr_ctx)+1
|
|
#define IS_POLLING_REQUIRED(softs) if (cold) {\
|
|
pqisrc_process_event_intr_src(softs, 0);\
|
|
pqisrc_process_response_queue(softs, 1);\
|
|
}
|
|
|
|
#define OS_GET_TASK_ATTR(rcb) os_get_task_attr(rcb)
|
|
#define OS_FW_HEARTBEAT_TIMER_INTERVAL (5)
|
|
|
|
typedef struct PCI_ACC_HANDLE {
|
|
bus_space_tag_t pqi_btag;
|
|
bus_space_handle_t pqi_bhandle;
|
|
} PCI_ACC_HANDLE_T;
|
|
|
|
/*
|
|
* Legacy SIS Register definitions for the Adaptec PMC SRC/SRCv/smartraid adapters.
|
|
*/
|
|
/* accessible via BAR0 */
|
|
#define LEGACY_SIS_IOAR 0x18 /* IOA->host interrupt register */
|
|
#define LEGACY_SIS_IDBR 0x20 /* inbound doorbell register */
|
|
#define LEGACY_SIS_IISR 0x24 /* inbound interrupt status register */
|
|
#define LEGACY_SIS_OIMR 0x34 /* outbound interrupt mask register */
|
|
#define LEGACY_SIS_ODBR_R 0x9c /* outbound doorbell register read */
|
|
#define LEGACY_SIS_ODBR_C 0xa0 /* outbound doorbell register clear */
|
|
|
|
#define LEGACY_SIS_SCR0 0xb0 /* scratchpad 0 */
|
|
#define LEGACY_SIS_OMR 0xbc /* outbound message register */
|
|
#define LEGACY_SIS_IQUE64_L 0xc0 /* inbound queue address 64-bit (low) */
|
|
#define LEGACY_SIS_IQUE64_H 0xc4 /* inbound queue address 64-bit (high)*/
|
|
#define LEGACY_SIS_ODBR_MSI 0xc8 /* MSI register for sync./AIF */
|
|
#define LEGACY_SIS_IQN_L 0xd0 /* inbound queue native mode (low) */
|
|
#define LEGACY_SIS_IQN_H 0xd4 /* inbound queue native mode (high)*/
|
|
#define LEGACY_SIS_MAILBOX 0x7fc60 /* mailbox (20 bytes) */
|
|
#define LEGACY_SIS_SRCV_MAILBOX 0x1000 /* mailbox (20 bytes) */
|
|
#define LEGACY_SIS_SRCV_OFFSET_MAILBOX_7 0x101C /* mailbox 7 register offset */
|
|
|
|
|
|
#define LEGACY_SIS_ODR_SHIFT 12 /* outbound doorbell shift */
|
|
#define LEGACY_SIS_IDR_SHIFT 9 /* inbound doorbell shift */
|
|
|
|
|
|
/*
|
|
* PQI Register definitions for the smartraid adapters
|
|
*/
|
|
/* accessible via BAR0 */
|
|
#define PQI_SIGNATURE 0x4000
|
|
#define PQI_ADMINQ_CONFIG 0x4008
|
|
#define PQI_ADMINQ_CAP 0x4010
|
|
#define PQI_LEGACY_INTR_STATUS 0x4018
|
|
#define PQI_LEGACY_INTR_MASK_SET 0x401C
|
|
#define PQI_LEGACY_INTR_MASK_CLR 0x4020
|
|
#define PQI_DEV_STATUS 0x4040
|
|
#define PQI_ADMIN_IBQ_PI_OFFSET 0x4048
|
|
#define PQI_ADMIN_OBQ_CI_OFFSET 0x4050
|
|
#define PQI_ADMIN_IBQ_ELEM_ARRAY_ADDR 0x4058
|
|
#define PQI_ADMIN_OBQ_ELEM_ARRAY_ADDR 0x4060
|
|
#define PQI_ADMIN_IBQ_CI_ADDR 0x4068
|
|
#define PQI_ADMIN_OBQ_PI_ADDR 0x4070
|
|
#define PQI_ADMINQ_PARAM 0x4078
|
|
#define PQI_DEV_ERR 0x4080
|
|
#define PQI_DEV_ERR_DETAILS 0x4088
|
|
#define PQI_DEV_RESET 0x4090
|
|
#define PQI_POWER_ACTION 0x4094
|
|
|
|
/* Busy wait micro seconds */
|
|
#define OS_BUSYWAIT(x) DELAY(x)
|
|
#define OS_SLEEP(timeout) \
|
|
DELAY(timeout);
|
|
|
|
/* TMF request timeout is 600 Sec */
|
|
#define OS_TMF_TIMEOUT_SEC (10 * 60)
|
|
|
|
#define LE_16(x) htole16(x)
|
|
#define LE_32(x) htole32(x)
|
|
#define LE_64(x) htole64(x)
|
|
#define BE_16(x) htobe16(x)
|
|
#define BE_32(x) htobe32(x)
|
|
#define BE_64(x) htobe64(x)
|
|
|
|
#define PQI_HWIF_SRCV 0
|
|
#define PQI_HWIF_UNKNOWN -1
|
|
|
|
|
|
#define SMART_STATE_SUSPEND (1<<0)
|
|
#define SMART_STATE_UNUSED0 (1<<1)
|
|
#define SMART_STATE_INTERRUPTS_ON (1<<2)
|
|
#define SMART_STATE_AIF_SLEEPER (1<<3)
|
|
#define SMART_STATE_RESET (1<<4)
|
|
|
|
#define PQI_FLAG_BUSY (1<<0)
|
|
#define PQI_MSI_ENABLED (1<<1)
|
|
#define PQI_SIM_REGISTERED (1<<2)
|
|
#define PQI_MTX_INIT (1<<3)
|
|
|
|
|
|
#define PQI_CMD_MAPPED (1<<2)
|
|
|
|
/* Interrupt context to get oq_id */
|
|
typedef struct pqi_intr_ctx {
|
|
int oq_id;
|
|
device_t pqi_dev;
|
|
}pqi_intr_ctx_t;
|
|
|
|
typedef uint8_t os_dev_info_t;
|
|
|
|
typedef struct OS_SPECIFIC {
|
|
device_t pqi_dev;
|
|
struct resource *pqi_regs_res0; /* reg. if. window */
|
|
int pqi_regs_rid0; /* resource ID */
|
|
bus_dma_tag_t pqi_parent_dmat; /* parent DMA tag */
|
|
bus_dma_tag_t pqi_buffer_dmat;
|
|
|
|
/* controller hardware interface */
|
|
int pqi_hwif;
|
|
struct resource *pqi_irq[PQI_MAX_MSIX]; /* interrupt */
|
|
int pqi_irq_rid[PQI_MAX_MSIX];
|
|
void *intrcookie[PQI_MAX_MSIX];
|
|
bool intr_registered[PQI_MAX_MSIX];
|
|
bool msi_enabled; /* MSI/MSI-X enabled */
|
|
pqi_intr_ctx_t *msi_ctx;
|
|
int oq_id;
|
|
int pqi_state;
|
|
uint32_t pqi_flags;
|
|
struct mtx cam_lock;
|
|
struct mtx map_lock;
|
|
int mtx_init;
|
|
int sim_registered;
|
|
struct cam_devq *devq;
|
|
struct cam_sim *sim;
|
|
struct cam_path *path;
|
|
struct task event_task;
|
|
struct cdev *cdev;
|
|
struct callout wellness_periodic; /* periodic event handling */
|
|
struct callout heartbeat_timeout_id; /* heart beat event handling */
|
|
} OS_SPECIFIC_T;
|
|
|
|
typedef bus_addr_t dma_addr_t;
|
|
|
|
|
|
/* Register access macros */
|
|
#define PCI_MEM_GET32( _softs, _absaddr, _offset ) \
|
|
bus_space_read_4(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset)
|
|
|
|
|
|
#if defined(__i386__)
|
|
#define PCI_MEM_GET64( _softs, _absaddr, _offset ) ({ \
|
|
(uint64_t)bus_space_read_4(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset) + \
|
|
((uint64_t)bus_space_read_4(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset + 4) << 32); \
|
|
})
|
|
#else
|
|
#define PCI_MEM_GET64(_softs, _absaddr, _offset ) \
|
|
bus_space_read_8(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset)
|
|
#endif
|
|
|
|
#define PCI_MEM_PUT32( _softs, _absaddr, _offset, _val ) \
|
|
bus_space_write_4(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset, _val)
|
|
|
|
#if defined(__i386__)
|
|
#define PCI_MEM_PUT64( _softs, _absaddr, _offset, _val ) \
|
|
bus_space_write_4(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset, _val); \
|
|
bus_space_write_4(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset + 4, _val >> 32);
|
|
#else
|
|
#define PCI_MEM_PUT64( _softs, _absaddr, _offset, _val ) \
|
|
bus_space_write_8(_softs->pci_mem_handle.pqi_btag, \
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset, _val)
|
|
#endif
|
|
|
|
|
|
#define PCI_MEM_GET_BUF(_softs, _absaddr, _offset, buf, size) \
|
|
bus_space_read_region_1(_softs->pci_mem_handle.pqi_btag,\
|
|
_softs->pci_mem_handle.pqi_bhandle, _offset, buf, size)
|
|
|
|
/* Lock */
|
|
typedef struct mtx OS_LOCK_T;
|
|
typedef struct sema OS_SEMA_LOCK_T;
|
|
|
|
#define OS_PQILOCK_T OS_LOCK_T
|
|
|
|
#define OS_ACQUIRE_SPINLOCK(_lock) mtx_lock_spin(_lock)
|
|
#define OS_RELEASE_SPINLOCK(_lock) mtx_unlock_spin(_lock)
|
|
|
|
#define OS_INIT_PQILOCK(_softs,_lock,_lockname) os_init_spinlock(_softs,_lock,_lockname)
|
|
#define OS_UNINIT_PQILOCK(_lock) os_uninit_spinlock(_lock)
|
|
|
|
#define PQI_LOCK(_lock) OS_ACQUIRE_SPINLOCK(_lock)
|
|
#define PQI_UNLOCK(_lock) OS_RELEASE_SPINLOCK(_lock)
|
|
|
|
#define OS_GET_CDBP(rcb) \
|
|
((rcb->cm_ccb->ccb_h.flags & CAM_CDB_POINTER) ? rcb->cm_ccb->csio.cdb_io.cdb_ptr : rcb->cm_ccb->csio.cdb_io.cdb_bytes)
|
|
#define GET_SCSI_BUFFLEN(rcb) (rcb->cm_ccb->csio.dxfer_len)
|
|
#define IS_OS_SCSICMD(rcb) (rcb && !rcb->tm_req && rcb->cm_ccb)
|
|
|
|
#define OS_GET_IO_QINDEX(softs,rcb) curcpu % softs->num_op_obq
|
|
#define OS_GET_IO_RESP_QID(softs,rcb) (softs->op_ob_q[(OS_GET_IO_QINDEX(softs,rcb))].q_id)
|
|
#define OS_GET_IO_REQ_QINDEX(softs,rcb) OS_GET_IO_QINDEX(softs,rcb)
|
|
#define OS_GET_TMF_RESP_QID OS_GET_IO_RESP_QID
|
|
#define OS_GET_TMF_REQ_QINDEX OS_GET_IO_REQ_QINDEX
|
|
|
|
/* check request type */
|
|
#define is_internal_req(rcb) (!(rcb->cm_ccb))
|
|
|
|
#define os_io_memcpy(dest, src, len) memcpy(dest, src, len)
|
|
|
|
/* sg elements addr, len, flags */
|
|
#define OS_GET_IO_SG_COUNT(rcb) rcb->nseg
|
|
#define OS_GET_IO_SG_ADDR(rcb,i) rcb->sgt[i].addr
|
|
#define OS_GET_IO_SG_LEN(rcb,i) rcb->sgt[i].len
|
|
|
|
/* scsi commands used in pqilib for RAID bypass*/
|
|
#define SCMD_READ_6 READ_6
|
|
#define SCMD_WRITE_6 WRITE_6
|
|
#define SCMD_READ_10 READ_10
|
|
#define SCMD_WRITE_10 WRITE_10
|
|
#define SCMD_READ_12 READ_12
|
|
#define SCMD_WRITE_12 WRITE_12
|
|
#define SCMD_READ_16 READ_16
|
|
#define SCMD_WRITE_16 WRITE_16
|
|
|
|
/* FreeBSD status macros */
|
|
#define BSD_SUCCESS 0
|
|
|
|
|
|
/* Debug facility */
|
|
|
|
#define PQISRC_LOG_LEVEL 0x60
|
|
|
|
static int logging_level = PQISRC_LOG_LEVEL;
|
|
|
|
#define PQISRC_FLAGS_MASK 0x0000ffff
|
|
#define PQISRC_FLAGS_INIT 0x00000001
|
|
#define PQISRC_FLAGS_INFO 0x00000002
|
|
#define PQISRC_FLAGS_FUNC 0x00000004
|
|
#define PQISRC_FLAGS_TRACEIO 0x00000008
|
|
#define PQISRC_FLAGS_DISC 0x00000010
|
|
#define PQISRC_FLAGS_WARN 0x00000020
|
|
#define PQISRC_FLAGS_ERROR 0x00000040
|
|
#define PQISRC_FLAGS_NOTE 0x00000080
|
|
|
|
|
|
#define DBG_INIT(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_INIT) { \
|
|
printf("[INIT]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_INFO(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_INFO) { \
|
|
printf("[INFO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_FUNC(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_FUNC) { \
|
|
printf("[FUNC]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_TRACEIO(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_TRACEIO) { \
|
|
printf("[TRACEIO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_DISC(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_DISC) { \
|
|
printf("[DISC]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_WARN(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_WARN) { \
|
|
printf("[WARN]:[%u:%u.%u][CPU %d][%s][%d]:"fmt,softs->bus_id,softs->device_id,softs->func_id,curcpu,__func__,__LINE__,##args);\
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_ERR(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_ERROR) { \
|
|
printf("[ERROR]::[%u:%u.%u][CPU %d][%s][%d]:"fmt,softs->bus_id,softs->device_id,softs->func_id,curcpu,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
#define DBG_IO(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_TRACEIO) { \
|
|
printf("[IO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_ERR_BTL(device,fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_ERROR) { \
|
|
printf("[ERROR]::[%u:%u.%u][%u,%u,%u][CPU %d][%s][%d]:"fmt, softs->bus_id, softs->device_id, softs->func_id, device->bus, device->target, device->lun,curcpu,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_WARN_BTL(device,fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_WARN) { \
|
|
printf("[WARN]:[%u:%u.%u][%u,%u,%u][CPU %d][%s][%d]:"fmt, softs->bus_id, softs->device_id, softs->func_id, device->bus, device->target, device->lun,curcpu,__func__,__LINE__,##args);\
|
|
} \
|
|
}while(0);
|
|
|
|
#define DBG_NOTE(fmt,args...) \
|
|
do { \
|
|
if (logging_level & PQISRC_FLAGS_NOTE) { \
|
|
printf("[INFO]:[ %s ] [ %d ]"fmt,__func__,__LINE__,##args); \
|
|
} \
|
|
}while(0);
|
|
|
|
#endif /* _PQI_DEFINES_H */
|