1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * pmcraid.h -- PMC Sierra MaxRAID controller driver header file 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Written By: Anil Ravindranath<anil_ravindranath@pmc-sierra.com> 6*4882a593Smuzhiyun * PMC-Sierra Inc 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * Copyright (C) 2008, 2009 PMC Sierra Inc. 9*4882a593Smuzhiyun */ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #ifndef _PMCRAID_H 12*4882a593Smuzhiyun #define _PMCRAID_H 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include <linux/types.h> 15*4882a593Smuzhiyun #include <linux/completion.h> 16*4882a593Smuzhiyun #include <linux/list.h> 17*4882a593Smuzhiyun #include <scsi/scsi.h> 18*4882a593Smuzhiyun #include <scsi/scsi_cmnd.h> 19*4882a593Smuzhiyun #include <linux/cdev.h> 20*4882a593Smuzhiyun #include <net/netlink.h> 21*4882a593Smuzhiyun #include <net/genetlink.h> 22*4882a593Smuzhiyun #include <linux/connector.h> 23*4882a593Smuzhiyun /* 24*4882a593Smuzhiyun * Driver name : string representing the driver name 25*4882a593Smuzhiyun * Device file : /dev file to be used for management interfaces 26*4882a593Smuzhiyun * Driver version: version string in major_version.minor_version.patch format 27*4882a593Smuzhiyun * Driver date : date information in "Mon dd yyyy" format 28*4882a593Smuzhiyun */ 29*4882a593Smuzhiyun #define PMCRAID_DRIVER_NAME "PMC MaxRAID" 30*4882a593Smuzhiyun #define PMCRAID_DEVFILE "pmcsas" 31*4882a593Smuzhiyun #define PMCRAID_DRIVER_VERSION "1.0.3" 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun #define PMCRAID_FW_VERSION_1 0x002 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun /* Maximum number of adapters supported by current version of the driver */ 36*4882a593Smuzhiyun #define PMCRAID_MAX_ADAPTERS 1024 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* Bit definitions as per firmware, bit position [0][1][2].....[31] */ 39*4882a593Smuzhiyun #define PMC_BIT8(n) (1 << (7-n)) 40*4882a593Smuzhiyun #define PMC_BIT16(n) (1 << (15-n)) 41*4882a593Smuzhiyun #define PMC_BIT32(n) (1 << (31-n)) 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun /* PMC PCI vendor ID and device ID values */ 44*4882a593Smuzhiyun #define PCI_VENDOR_ID_PMC 0x11F8 45*4882a593Smuzhiyun #define PCI_DEVICE_ID_PMC_MAXRAID 0x5220 46*4882a593Smuzhiyun 47*4882a593Smuzhiyun /* 48*4882a593Smuzhiyun * MAX_CMD : maximum commands that can be outstanding with IOA 49*4882a593Smuzhiyun * MAX_IO_CMD : command blocks available for IO commands 50*4882a593Smuzhiyun * MAX_HCAM_CMD : command blocks avaibale for HCAMS 51*4882a593Smuzhiyun * MAX_INTERNAL_CMD : command blocks avaible for internal commands like reset 52*4882a593Smuzhiyun */ 53*4882a593Smuzhiyun #define PMCRAID_MAX_CMD 1024 54*4882a593Smuzhiyun #define PMCRAID_MAX_IO_CMD 1020 55*4882a593Smuzhiyun #define PMCRAID_MAX_HCAM_CMD 2 56*4882a593Smuzhiyun #define PMCRAID_MAX_INTERNAL_CMD 2 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* MAX_IOADLS : max number of scatter-gather lists supported by IOA 59*4882a593Smuzhiyun * IOADLS_INTERNAL : number of ioadls included as part of IOARCB. 60*4882a593Smuzhiyun * IOADLS_EXTERNAL : number of ioadls allocated external to IOARCB 61*4882a593Smuzhiyun */ 62*4882a593Smuzhiyun #define PMCRAID_IOADLS_INTERNAL 27 63*4882a593Smuzhiyun #define PMCRAID_IOADLS_EXTERNAL 37 64*4882a593Smuzhiyun #define PMCRAID_MAX_IOADLS PMCRAID_IOADLS_INTERNAL 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun /* HRRQ_ENTRY_SIZE : size of hrrq buffer 67*4882a593Smuzhiyun * IOARCB_ALIGNMENT : alignment required for IOARCB 68*4882a593Smuzhiyun * IOADL_ALIGNMENT : alignment requirement for IOADLs 69*4882a593Smuzhiyun * MSIX_VECTORS : number of MSIX vectors supported 70*4882a593Smuzhiyun */ 71*4882a593Smuzhiyun #define HRRQ_ENTRY_SIZE sizeof(__le32) 72*4882a593Smuzhiyun #define PMCRAID_IOARCB_ALIGNMENT 32 73*4882a593Smuzhiyun #define PMCRAID_IOADL_ALIGNMENT 16 74*4882a593Smuzhiyun #define PMCRAID_IOASA_ALIGNMENT 4 75*4882a593Smuzhiyun #define PMCRAID_NUM_MSIX_VECTORS 16 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* various other limits */ 78*4882a593Smuzhiyun #define PMCRAID_VENDOR_ID_LEN 8 79*4882a593Smuzhiyun #define PMCRAID_PRODUCT_ID_LEN 16 80*4882a593Smuzhiyun #define PMCRAID_SERIAL_NUM_LEN 8 81*4882a593Smuzhiyun #define PMCRAID_LUN_LEN 8 82*4882a593Smuzhiyun #define PMCRAID_MAX_CDB_LEN 16 83*4882a593Smuzhiyun #define PMCRAID_DEVICE_ID_LEN 8 84*4882a593Smuzhiyun #define PMCRAID_SENSE_DATA_LEN 256 85*4882a593Smuzhiyun #define PMCRAID_ADD_CMD_PARAM_LEN 48 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun #define PMCRAID_MAX_BUS_TO_SCAN 1 88*4882a593Smuzhiyun #define PMCRAID_MAX_NUM_TARGETS_PER_BUS 256 89*4882a593Smuzhiyun #define PMCRAID_MAX_NUM_LUNS_PER_TARGET 8 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /* IOA bus/target/lun number of IOA resources */ 92*4882a593Smuzhiyun #define PMCRAID_IOA_BUS_ID 0xfe 93*4882a593Smuzhiyun #define PMCRAID_IOA_TARGET_ID 0xff 94*4882a593Smuzhiyun #define PMCRAID_IOA_LUN_ID 0xff 95*4882a593Smuzhiyun #define PMCRAID_VSET_BUS_ID 0x1 96*4882a593Smuzhiyun #define PMCRAID_VSET_LUN_ID 0x0 97*4882a593Smuzhiyun #define PMCRAID_PHYS_BUS_ID 0x0 98*4882a593Smuzhiyun #define PMCRAID_VIRTUAL_ENCL_BUS_ID 0x8 99*4882a593Smuzhiyun #define PMCRAID_MAX_VSET_TARGETS 0x7F 100*4882a593Smuzhiyun #define PMCRAID_MAX_VSET_LUNS_PER_TARGET 8 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun #define PMCRAID_IOA_MAX_SECTORS 32767 103*4882a593Smuzhiyun #define PMCRAID_VSET_MAX_SECTORS 512 104*4882a593Smuzhiyun #define PMCRAID_MAX_CMD_PER_LUN 254 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /* Number of configuration table entries (resources), includes 1 FP, 107*4882a593Smuzhiyun * 1 Enclosure device 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun #define PMCRAID_MAX_RESOURCES 256 110*4882a593Smuzhiyun 111*4882a593Smuzhiyun /* Adapter Commands used by driver */ 112*4882a593Smuzhiyun #define PMCRAID_QUERY_RESOURCE_STATE 0xC2 113*4882a593Smuzhiyun #define PMCRAID_RESET_DEVICE 0xC3 114*4882a593Smuzhiyun /* options to select reset target */ 115*4882a593Smuzhiyun #define ENABLE_RESET_MODIFIER 0x80 116*4882a593Smuzhiyun #define RESET_DEVICE_LUN 0x40 117*4882a593Smuzhiyun #define RESET_DEVICE_TARGET 0x20 118*4882a593Smuzhiyun #define RESET_DEVICE_BUS 0x10 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun #define PMCRAID_IDENTIFY_HRRQ 0xC4 121*4882a593Smuzhiyun #define PMCRAID_QUERY_IOA_CONFIG 0xC5 122*4882a593Smuzhiyun #define PMCRAID_QUERY_CMD_STATUS 0xCB 123*4882a593Smuzhiyun #define PMCRAID_ABORT_CMD 0xC7 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun /* CANCEL ALL command, provides option for setting SYNC_COMPLETE 126*4882a593Smuzhiyun * on the target resources for which commands got cancelled 127*4882a593Smuzhiyun */ 128*4882a593Smuzhiyun #define PMCRAID_CANCEL_ALL_REQUESTS 0xCE 129*4882a593Smuzhiyun #define PMCRAID_SYNC_COMPLETE_AFTER_CANCEL PMC_BIT8(0) 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun /* HCAM command and types of HCAM supported by IOA */ 132*4882a593Smuzhiyun #define PMCRAID_HOST_CONTROLLED_ASYNC 0xCF 133*4882a593Smuzhiyun #define PMCRAID_HCAM_CODE_CONFIG_CHANGE 0x01 134*4882a593Smuzhiyun #define PMCRAID_HCAM_CODE_LOG_DATA 0x02 135*4882a593Smuzhiyun 136*4882a593Smuzhiyun /* IOA shutdown command and various shutdown types */ 137*4882a593Smuzhiyun #define PMCRAID_IOA_SHUTDOWN 0xF7 138*4882a593Smuzhiyun #define PMCRAID_SHUTDOWN_NORMAL 0x00 139*4882a593Smuzhiyun #define PMCRAID_SHUTDOWN_PREPARE_FOR_NORMAL 0x40 140*4882a593Smuzhiyun #define PMCRAID_SHUTDOWN_NONE 0x100 141*4882a593Smuzhiyun #define PMCRAID_SHUTDOWN_ABBREV 0x80 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* SET SUPPORTED DEVICES command and the option to select all the 144*4882a593Smuzhiyun * devices to be supported 145*4882a593Smuzhiyun */ 146*4882a593Smuzhiyun #define PMCRAID_SET_SUPPORTED_DEVICES 0xFB 147*4882a593Smuzhiyun #define ALL_DEVICES_SUPPORTED PMC_BIT8(0) 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun /* This option is used with SCSI WRITE_BUFFER command */ 150*4882a593Smuzhiyun #define PMCRAID_WR_BUF_DOWNLOAD_AND_SAVE 0x05 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun /* IOASC Codes used by driver */ 153*4882a593Smuzhiyun #define PMCRAID_IOASC_SENSE_MASK 0xFFFFFF00 154*4882a593Smuzhiyun #define PMCRAID_IOASC_SENSE_KEY(ioasc) ((ioasc) >> 24) 155*4882a593Smuzhiyun #define PMCRAID_IOASC_SENSE_CODE(ioasc) (((ioasc) & 0x00ff0000) >> 16) 156*4882a593Smuzhiyun #define PMCRAID_IOASC_SENSE_QUAL(ioasc) (((ioasc) & 0x0000ff00) >> 8) 157*4882a593Smuzhiyun #define PMCRAID_IOASC_SENSE_STATUS(ioasc) ((ioasc) & 0x000000ff) 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun #define PMCRAID_IOASC_GOOD_COMPLETION 0x00000000 160*4882a593Smuzhiyun #define PMCRAID_IOASC_GC_IOARCB_NOTFOUND 0x005A0000 161*4882a593Smuzhiyun #define PMCRAID_IOASC_NR_INIT_CMD_REQUIRED 0x02040200 162*4882a593Smuzhiyun #define PMCRAID_IOASC_NR_IOA_RESET_REQUIRED 0x02048000 163*4882a593Smuzhiyun #define PMCRAID_IOASC_NR_SYNC_REQUIRED 0x023F0000 164*4882a593Smuzhiyun #define PMCRAID_IOASC_ME_READ_ERROR_NO_REALLOC 0x03110C00 165*4882a593Smuzhiyun #define PMCRAID_IOASC_HW_CANNOT_COMMUNICATE 0x04050000 166*4882a593Smuzhiyun #define PMCRAID_IOASC_HW_DEVICE_TIMEOUT 0x04080100 167*4882a593Smuzhiyun #define PMCRAID_IOASC_HW_DEVICE_BUS_STATUS_ERROR 0x04448500 168*4882a593Smuzhiyun #define PMCRAID_IOASC_HW_IOA_RESET_REQUIRED 0x04448600 169*4882a593Smuzhiyun #define PMCRAID_IOASC_IR_INVALID_RESOURCE_HANDLE 0x05250000 170*4882a593Smuzhiyun #define PMCRAID_IOASC_AC_TERMINATED_BY_HOST 0x0B5A0000 171*4882a593Smuzhiyun #define PMCRAID_IOASC_UA_BUS_WAS_RESET 0x06290000 172*4882a593Smuzhiyun #define PMCRAID_IOASC_TIME_STAMP_OUT_OF_SYNC 0x06908B00 173*4882a593Smuzhiyun #define PMCRAID_IOASC_UA_BUS_WAS_RESET_BY_OTHER 0x06298000 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun /* Driver defined IOASCs */ 176*4882a593Smuzhiyun #define PMCRAID_IOASC_IOA_WAS_RESET 0x10000001 177*4882a593Smuzhiyun #define PMCRAID_IOASC_PCI_ACCESS_ERROR 0x10000002 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun /* Various timeout values (in milliseconds) used. If any of these are chip 180*4882a593Smuzhiyun * specific, move them to pmcraid_chip_details structure. 181*4882a593Smuzhiyun */ 182*4882a593Smuzhiyun #define PMCRAID_PCI_DEASSERT_TIMEOUT 2000 183*4882a593Smuzhiyun #define PMCRAID_BIST_TIMEOUT 2000 184*4882a593Smuzhiyun #define PMCRAID_AENWAIT_TIMEOUT 5000 185*4882a593Smuzhiyun #define PMCRAID_TRANSOP_TIMEOUT 60000 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun #define PMCRAID_RESET_TIMEOUT (2 * HZ) 188*4882a593Smuzhiyun #define PMCRAID_CHECK_FOR_RESET_TIMEOUT ((HZ / 10)) 189*4882a593Smuzhiyun #define PMCRAID_VSET_IO_TIMEOUT (60 * HZ) 190*4882a593Smuzhiyun #define PMCRAID_INTERNAL_TIMEOUT (60 * HZ) 191*4882a593Smuzhiyun #define PMCRAID_SHUTDOWN_TIMEOUT (150 * HZ) 192*4882a593Smuzhiyun #define PMCRAID_RESET_BUS_TIMEOUT (60 * HZ) 193*4882a593Smuzhiyun #define PMCRAID_RESET_HOST_TIMEOUT (150 * HZ) 194*4882a593Smuzhiyun #define PMCRAID_REQUEST_SENSE_TIMEOUT (30 * HZ) 195*4882a593Smuzhiyun #define PMCRAID_SET_SUP_DEV_TIMEOUT (2 * 60 * HZ) 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun /* structure to represent a scatter-gather element (IOADL descriptor) */ 198*4882a593Smuzhiyun struct pmcraid_ioadl_desc { 199*4882a593Smuzhiyun __le64 address; 200*4882a593Smuzhiyun __le32 data_len; 201*4882a593Smuzhiyun __u8 reserved[3]; 202*4882a593Smuzhiyun __u8 flags; 203*4882a593Smuzhiyun } __attribute__((packed, aligned(PMCRAID_IOADL_ALIGNMENT))); 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /* pmcraid_ioadl_desc.flags values */ 206*4882a593Smuzhiyun #define IOADL_FLAGS_CHAINED PMC_BIT8(0) 207*4882a593Smuzhiyun #define IOADL_FLAGS_LAST_DESC PMC_BIT8(1) 208*4882a593Smuzhiyun #define IOADL_FLAGS_READ_LAST PMC_BIT8(1) 209*4882a593Smuzhiyun #define IOADL_FLAGS_WRITE_LAST PMC_BIT8(1) 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun /* additional IOARCB data which can be CDB or additional request parameters 213*4882a593Smuzhiyun * or list of IOADLs. Firmware supports max of 512 bytes for IOARCB, hence then 214*4882a593Smuzhiyun * number of IOADLs are limted to 27. In case they are more than 27, they will 215*4882a593Smuzhiyun * be used in chained form 216*4882a593Smuzhiyun */ 217*4882a593Smuzhiyun struct pmcraid_ioarcb_add_data { 218*4882a593Smuzhiyun union { 219*4882a593Smuzhiyun struct pmcraid_ioadl_desc ioadl[PMCRAID_IOADLS_INTERNAL]; 220*4882a593Smuzhiyun __u8 add_cmd_params[PMCRAID_ADD_CMD_PARAM_LEN]; 221*4882a593Smuzhiyun } u; 222*4882a593Smuzhiyun }; 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun /* 225*4882a593Smuzhiyun * IOA Request Control Block 226*4882a593Smuzhiyun */ 227*4882a593Smuzhiyun struct pmcraid_ioarcb { 228*4882a593Smuzhiyun __le64 ioarcb_bus_addr; 229*4882a593Smuzhiyun __le32 resource_handle; 230*4882a593Smuzhiyun __le32 response_handle; 231*4882a593Smuzhiyun __le64 ioadl_bus_addr; 232*4882a593Smuzhiyun __le32 ioadl_length; 233*4882a593Smuzhiyun __le32 data_transfer_length; 234*4882a593Smuzhiyun __le64 ioasa_bus_addr; 235*4882a593Smuzhiyun __le16 ioasa_len; 236*4882a593Smuzhiyun __le16 cmd_timeout; 237*4882a593Smuzhiyun __le16 add_cmd_param_offset; 238*4882a593Smuzhiyun __le16 add_cmd_param_length; 239*4882a593Smuzhiyun __le32 reserved1[2]; 240*4882a593Smuzhiyun __le32 reserved2; 241*4882a593Smuzhiyun __u8 request_type; 242*4882a593Smuzhiyun __u8 request_flags0; 243*4882a593Smuzhiyun __u8 request_flags1; 244*4882a593Smuzhiyun __u8 hrrq_id; 245*4882a593Smuzhiyun __u8 cdb[PMCRAID_MAX_CDB_LEN]; 246*4882a593Smuzhiyun struct pmcraid_ioarcb_add_data add_data; 247*4882a593Smuzhiyun } __attribute__((packed, aligned(PMCRAID_IOARCB_ALIGNMENT))); 248*4882a593Smuzhiyun 249*4882a593Smuzhiyun /* well known resource handle values */ 250*4882a593Smuzhiyun #define PMCRAID_IOA_RES_HANDLE 0xffffffff 251*4882a593Smuzhiyun #define PMCRAID_INVALID_RES_HANDLE 0 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun /* pmcraid_ioarcb.request_type values */ 254*4882a593Smuzhiyun #define REQ_TYPE_SCSI 0x00 255*4882a593Smuzhiyun #define REQ_TYPE_IOACMD 0x01 256*4882a593Smuzhiyun #define REQ_TYPE_HCAM 0x02 257*4882a593Smuzhiyun 258*4882a593Smuzhiyun /* pmcraid_ioarcb.flags0 values */ 259*4882a593Smuzhiyun #define TRANSFER_DIR_WRITE PMC_BIT8(0) 260*4882a593Smuzhiyun #define INHIBIT_UL_CHECK PMC_BIT8(2) 261*4882a593Smuzhiyun #define SYNC_OVERRIDE PMC_BIT8(3) 262*4882a593Smuzhiyun #define SYNC_COMPLETE PMC_BIT8(4) 263*4882a593Smuzhiyun #define NO_LINK_DESCS PMC_BIT8(5) 264*4882a593Smuzhiyun 265*4882a593Smuzhiyun /* pmcraid_ioarcb.flags1 values */ 266*4882a593Smuzhiyun #define DELAY_AFTER_RESET PMC_BIT8(0) 267*4882a593Smuzhiyun #define TASK_TAG_SIMPLE 0x10 268*4882a593Smuzhiyun #define TASK_TAG_ORDERED 0x20 269*4882a593Smuzhiyun #define TASK_TAG_QUEUE_HEAD 0x30 270*4882a593Smuzhiyun 271*4882a593Smuzhiyun /* toggle bit offset in response handle */ 272*4882a593Smuzhiyun #define HRRQ_TOGGLE_BIT 0x01 273*4882a593Smuzhiyun #define HRRQ_RESPONSE_BIT 0x02 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun /* IOA Status Area */ 276*4882a593Smuzhiyun struct pmcraid_ioasa_vset { 277*4882a593Smuzhiyun __le32 failing_lba_hi; 278*4882a593Smuzhiyun __le32 failing_lba_lo; 279*4882a593Smuzhiyun __le32 reserved; 280*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 281*4882a593Smuzhiyun 282*4882a593Smuzhiyun struct pmcraid_ioasa { 283*4882a593Smuzhiyun __le32 ioasc; 284*4882a593Smuzhiyun __le16 returned_status_length; 285*4882a593Smuzhiyun __le16 available_status_length; 286*4882a593Smuzhiyun __le32 residual_data_length; 287*4882a593Smuzhiyun __le32 ilid; 288*4882a593Smuzhiyun __le32 fd_ioasc; 289*4882a593Smuzhiyun __le32 fd_res_address; 290*4882a593Smuzhiyun __le32 fd_res_handle; 291*4882a593Smuzhiyun __le32 reserved; 292*4882a593Smuzhiyun 293*4882a593Smuzhiyun /* resource specific sense information */ 294*4882a593Smuzhiyun union { 295*4882a593Smuzhiyun struct pmcraid_ioasa_vset vset; 296*4882a593Smuzhiyun } u; 297*4882a593Smuzhiyun 298*4882a593Smuzhiyun /* IOA autosense data */ 299*4882a593Smuzhiyun __le16 auto_sense_length; 300*4882a593Smuzhiyun __le16 error_data_length; 301*4882a593Smuzhiyun __u8 sense_data[PMCRAID_SENSE_DATA_LEN]; 302*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun #define PMCRAID_DRIVER_ILID 0xffffffff 305*4882a593Smuzhiyun 306*4882a593Smuzhiyun /* Config Table Entry per Resource */ 307*4882a593Smuzhiyun struct pmcraid_config_table_entry { 308*4882a593Smuzhiyun __u8 resource_type; 309*4882a593Smuzhiyun __u8 bus_protocol; 310*4882a593Smuzhiyun __le16 array_id; 311*4882a593Smuzhiyun __u8 common_flags0; 312*4882a593Smuzhiyun __u8 common_flags1; 313*4882a593Smuzhiyun __u8 unique_flags0; 314*4882a593Smuzhiyun __u8 unique_flags1; /*also used as vset target_id */ 315*4882a593Smuzhiyun __le32 resource_handle; 316*4882a593Smuzhiyun __le32 resource_address; 317*4882a593Smuzhiyun __u8 device_id[PMCRAID_DEVICE_ID_LEN]; 318*4882a593Smuzhiyun __u8 lun[PMCRAID_LUN_LEN]; 319*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun /* extended configuration table sizes are also of 32 bytes in size */ 322*4882a593Smuzhiyun struct pmcraid_config_table_entry_ext { 323*4882a593Smuzhiyun struct pmcraid_config_table_entry cfgte; 324*4882a593Smuzhiyun }; 325*4882a593Smuzhiyun 326*4882a593Smuzhiyun /* resource types (config_table_entry.resource_type values) */ 327*4882a593Smuzhiyun #define RES_TYPE_AF_DASD 0x00 328*4882a593Smuzhiyun #define RES_TYPE_GSCSI 0x01 329*4882a593Smuzhiyun #define RES_TYPE_VSET 0x02 330*4882a593Smuzhiyun #define RES_TYPE_IOA_FP 0xFF 331*4882a593Smuzhiyun 332*4882a593Smuzhiyun #define RES_IS_IOA(res) ((res).resource_type == RES_TYPE_IOA_FP) 333*4882a593Smuzhiyun #define RES_IS_GSCSI(res) ((res).resource_type == RES_TYPE_GSCSI) 334*4882a593Smuzhiyun #define RES_IS_VSET(res) ((res).resource_type == RES_TYPE_VSET) 335*4882a593Smuzhiyun #define RES_IS_AFDASD(res) ((res).resource_type == RES_TYPE_AF_DASD) 336*4882a593Smuzhiyun 337*4882a593Smuzhiyun /* bus_protocol values used by driver */ 338*4882a593Smuzhiyun #define RES_TYPE_VENCLOSURE 0x8 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun /* config_table_entry.common_flags0 */ 341*4882a593Smuzhiyun #define MULTIPATH_RESOURCE PMC_BIT32(0) 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun /* unique_flags1 */ 344*4882a593Smuzhiyun #define IMPORT_MODE_MANUAL PMC_BIT8(0) 345*4882a593Smuzhiyun 346*4882a593Smuzhiyun /* well known resource handle values */ 347*4882a593Smuzhiyun #define RES_HANDLE_IOA 0xFFFFFFFF 348*4882a593Smuzhiyun #define RES_HANDLE_NONE 0x00000000 349*4882a593Smuzhiyun 350*4882a593Smuzhiyun /* well known resource address values */ 351*4882a593Smuzhiyun #define RES_ADDRESS_IOAFP 0xFEFFFFFF 352*4882a593Smuzhiyun #define RES_ADDRESS_INVALID 0xFFFFFFFF 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun /* BUS/TARGET/LUN values from resource_addrr */ 355*4882a593Smuzhiyun #define RES_BUS(res_addr) (le32_to_cpu(res_addr) & 0xFF) 356*4882a593Smuzhiyun #define RES_TARGET(res_addr) ((le32_to_cpu(res_addr) >> 16) & 0xFF) 357*4882a593Smuzhiyun #define RES_LUN(res_addr) 0x0 358*4882a593Smuzhiyun 359*4882a593Smuzhiyun /* configuration table structure */ 360*4882a593Smuzhiyun struct pmcraid_config_table { 361*4882a593Smuzhiyun __le16 num_entries; 362*4882a593Smuzhiyun __u8 table_format; 363*4882a593Smuzhiyun __u8 reserved1; 364*4882a593Smuzhiyun __u8 flags; 365*4882a593Smuzhiyun __u8 reserved2[11]; 366*4882a593Smuzhiyun union { 367*4882a593Smuzhiyun struct pmcraid_config_table_entry 368*4882a593Smuzhiyun entries[PMCRAID_MAX_RESOURCES]; 369*4882a593Smuzhiyun struct pmcraid_config_table_entry_ext 370*4882a593Smuzhiyun entries_ext[PMCRAID_MAX_RESOURCES]; 371*4882a593Smuzhiyun }; 372*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 373*4882a593Smuzhiyun 374*4882a593Smuzhiyun /* config_table.flags value */ 375*4882a593Smuzhiyun #define MICROCODE_UPDATE_REQUIRED PMC_BIT32(0) 376*4882a593Smuzhiyun 377*4882a593Smuzhiyun /* 378*4882a593Smuzhiyun * HCAM format 379*4882a593Smuzhiyun */ 380*4882a593Smuzhiyun #define PMCRAID_HOSTRCB_LDNSIZE 4056 381*4882a593Smuzhiyun 382*4882a593Smuzhiyun /* Error log notification format */ 383*4882a593Smuzhiyun struct pmcraid_hostrcb_error { 384*4882a593Smuzhiyun __le32 fd_ioasc; 385*4882a593Smuzhiyun __le32 fd_ra; 386*4882a593Smuzhiyun __le32 fd_rh; 387*4882a593Smuzhiyun __le32 prc; 388*4882a593Smuzhiyun union { 389*4882a593Smuzhiyun __u8 data[PMCRAID_HOSTRCB_LDNSIZE]; 390*4882a593Smuzhiyun } u; 391*4882a593Smuzhiyun } __attribute__ ((packed, aligned(4))); 392*4882a593Smuzhiyun 393*4882a593Smuzhiyun struct pmcraid_hcam_hdr { 394*4882a593Smuzhiyun __u8 op_code; 395*4882a593Smuzhiyun __u8 notification_type; 396*4882a593Smuzhiyun __u8 notification_lost; 397*4882a593Smuzhiyun __u8 flags; 398*4882a593Smuzhiyun __u8 overlay_id; 399*4882a593Smuzhiyun __u8 reserved1[3]; 400*4882a593Smuzhiyun __le32 ilid; 401*4882a593Smuzhiyun __le32 timestamp1; 402*4882a593Smuzhiyun __le32 timestamp2; 403*4882a593Smuzhiyun __le32 data_len; 404*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 405*4882a593Smuzhiyun 406*4882a593Smuzhiyun #define PMCRAID_AEN_GROUP 0x3 407*4882a593Smuzhiyun 408*4882a593Smuzhiyun struct pmcraid_hcam_ccn { 409*4882a593Smuzhiyun struct pmcraid_hcam_hdr header; 410*4882a593Smuzhiyun struct pmcraid_config_table_entry cfg_entry; 411*4882a593Smuzhiyun struct pmcraid_config_table_entry cfg_entry_old; 412*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 413*4882a593Smuzhiyun 414*4882a593Smuzhiyun #define PMCRAID_CCN_EXT_SIZE 3944 415*4882a593Smuzhiyun struct pmcraid_hcam_ccn_ext { 416*4882a593Smuzhiyun struct pmcraid_hcam_hdr header; 417*4882a593Smuzhiyun struct pmcraid_config_table_entry_ext cfg_entry; 418*4882a593Smuzhiyun struct pmcraid_config_table_entry_ext cfg_entry_old; 419*4882a593Smuzhiyun __u8 reserved[PMCRAID_CCN_EXT_SIZE]; 420*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 421*4882a593Smuzhiyun 422*4882a593Smuzhiyun struct pmcraid_hcam_ldn { 423*4882a593Smuzhiyun struct pmcraid_hcam_hdr header; 424*4882a593Smuzhiyun struct pmcraid_hostrcb_error error_log; 425*4882a593Smuzhiyun } __attribute__((packed, aligned(4))); 426*4882a593Smuzhiyun 427*4882a593Smuzhiyun /* pmcraid_hcam.op_code values */ 428*4882a593Smuzhiyun #define HOSTRCB_TYPE_CCN 0xE1 429*4882a593Smuzhiyun #define HOSTRCB_TYPE_LDN 0xE2 430*4882a593Smuzhiyun 431*4882a593Smuzhiyun /* pmcraid_hcam.notification_type values */ 432*4882a593Smuzhiyun #define NOTIFICATION_TYPE_ENTRY_CHANGED 0x0 433*4882a593Smuzhiyun #define NOTIFICATION_TYPE_ENTRY_NEW 0x1 434*4882a593Smuzhiyun #define NOTIFICATION_TYPE_ENTRY_DELETED 0x2 435*4882a593Smuzhiyun #define NOTIFICATION_TYPE_STATE_CHANGE 0x3 436*4882a593Smuzhiyun #define NOTIFICATION_TYPE_ENTRY_STATECHANGED 0x4 437*4882a593Smuzhiyun #define NOTIFICATION_TYPE_ERROR_LOG 0x10 438*4882a593Smuzhiyun #define NOTIFICATION_TYPE_INFORMATION_LOG 0x11 439*4882a593Smuzhiyun 440*4882a593Smuzhiyun #define HOSTRCB_NOTIFICATIONS_LOST PMC_BIT8(0) 441*4882a593Smuzhiyun 442*4882a593Smuzhiyun /* pmcraid_hcam.flags values */ 443*4882a593Smuzhiyun #define HOSTRCB_INTERNAL_OP_ERROR PMC_BIT8(0) 444*4882a593Smuzhiyun #define HOSTRCB_ERROR_RESPONSE_SENT PMC_BIT8(1) 445*4882a593Smuzhiyun 446*4882a593Smuzhiyun /* pmcraid_hcam.overlay_id values */ 447*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_08 0x08 448*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_09 0x09 449*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_11 0x11 450*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_12 0x12 451*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_13 0x13 452*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_14 0x14 453*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_16 0x16 454*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_17 0x17 455*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_20 0x20 456*4882a593Smuzhiyun #define HOSTRCB_OVERLAY_ID_FF 0xFF 457*4882a593Smuzhiyun 458*4882a593Smuzhiyun /* Implementation specific card details */ 459*4882a593Smuzhiyun struct pmcraid_chip_details { 460*4882a593Smuzhiyun /* hardware register offsets */ 461*4882a593Smuzhiyun unsigned long ioastatus; 462*4882a593Smuzhiyun unsigned long ioarrin; 463*4882a593Smuzhiyun unsigned long mailbox; 464*4882a593Smuzhiyun unsigned long global_intr_mask; 465*4882a593Smuzhiyun unsigned long ioa_host_intr; 466*4882a593Smuzhiyun unsigned long ioa_host_msix_intr; 467*4882a593Smuzhiyun unsigned long ioa_host_intr_clr; 468*4882a593Smuzhiyun unsigned long ioa_host_mask; 469*4882a593Smuzhiyun unsigned long ioa_host_mask_clr; 470*4882a593Smuzhiyun unsigned long host_ioa_intr; 471*4882a593Smuzhiyun unsigned long host_ioa_intr_clr; 472*4882a593Smuzhiyun 473*4882a593Smuzhiyun /* timeout used during transitional to operational state */ 474*4882a593Smuzhiyun unsigned long transop_timeout; 475*4882a593Smuzhiyun }; 476*4882a593Smuzhiyun 477*4882a593Smuzhiyun /* IOA to HOST doorbells (interrupts) */ 478*4882a593Smuzhiyun #define INTRS_TRANSITION_TO_OPERATIONAL PMC_BIT32(0) 479*4882a593Smuzhiyun #define INTRS_IOARCB_TRANSFER_FAILED PMC_BIT32(3) 480*4882a593Smuzhiyun #define INTRS_IOA_UNIT_CHECK PMC_BIT32(4) 481*4882a593Smuzhiyun #define INTRS_NO_HRRQ_FOR_CMD_RESPONSE PMC_BIT32(5) 482*4882a593Smuzhiyun #define INTRS_CRITICAL_OP_IN_PROGRESS PMC_BIT32(6) 483*4882a593Smuzhiyun #define INTRS_IO_DEBUG_ACK PMC_BIT32(7) 484*4882a593Smuzhiyun #define INTRS_IOARRIN_LOST PMC_BIT32(27) 485*4882a593Smuzhiyun #define INTRS_SYSTEM_BUS_MMIO_ERROR PMC_BIT32(28) 486*4882a593Smuzhiyun #define INTRS_IOA_PROCESSOR_ERROR PMC_BIT32(29) 487*4882a593Smuzhiyun #define INTRS_HRRQ_VALID PMC_BIT32(30) 488*4882a593Smuzhiyun #define INTRS_OPERATIONAL_STATUS PMC_BIT32(0) 489*4882a593Smuzhiyun #define INTRS_ALLOW_MSIX_VECTOR0 PMC_BIT32(31) 490*4882a593Smuzhiyun 491*4882a593Smuzhiyun /* Host to IOA Doorbells */ 492*4882a593Smuzhiyun #define DOORBELL_RUNTIME_RESET PMC_BIT32(1) 493*4882a593Smuzhiyun #define DOORBELL_IOA_RESET_ALERT PMC_BIT32(7) 494*4882a593Smuzhiyun #define DOORBELL_IOA_DEBUG_ALERT PMC_BIT32(9) 495*4882a593Smuzhiyun #define DOORBELL_ENABLE_DESTRUCTIVE_DIAGS PMC_BIT32(8) 496*4882a593Smuzhiyun #define DOORBELL_IOA_START_BIST PMC_BIT32(23) 497*4882a593Smuzhiyun #define DOORBELL_INTR_MODE_MSIX PMC_BIT32(25) 498*4882a593Smuzhiyun #define DOORBELL_INTR_MSIX_CLR PMC_BIT32(26) 499*4882a593Smuzhiyun #define DOORBELL_RESET_IOA PMC_BIT32(31) 500*4882a593Smuzhiyun 501*4882a593Smuzhiyun /* Global interrupt mask register value */ 502*4882a593Smuzhiyun #define GLOBAL_INTERRUPT_MASK 0x5ULL 503*4882a593Smuzhiyun 504*4882a593Smuzhiyun #define PMCRAID_ERROR_INTERRUPTS (INTRS_IOARCB_TRANSFER_FAILED | \ 505*4882a593Smuzhiyun INTRS_IOA_UNIT_CHECK | \ 506*4882a593Smuzhiyun INTRS_NO_HRRQ_FOR_CMD_RESPONSE | \ 507*4882a593Smuzhiyun INTRS_IOARRIN_LOST | \ 508*4882a593Smuzhiyun INTRS_SYSTEM_BUS_MMIO_ERROR | \ 509*4882a593Smuzhiyun INTRS_IOA_PROCESSOR_ERROR) 510*4882a593Smuzhiyun 511*4882a593Smuzhiyun #define PMCRAID_PCI_INTERRUPTS (PMCRAID_ERROR_INTERRUPTS | \ 512*4882a593Smuzhiyun INTRS_HRRQ_VALID | \ 513*4882a593Smuzhiyun INTRS_TRANSITION_TO_OPERATIONAL |\ 514*4882a593Smuzhiyun INTRS_ALLOW_MSIX_VECTOR0) 515*4882a593Smuzhiyun 516*4882a593Smuzhiyun /* control_block, associated with each of the commands contains IOARCB, IOADLs 517*4882a593Smuzhiyun * memory for IOASA. Additional 3 * 16 bytes are allocated in order to support 518*4882a593Smuzhiyun * additional request parameters (of max size 48) any command. 519*4882a593Smuzhiyun */ 520*4882a593Smuzhiyun struct pmcraid_control_block { 521*4882a593Smuzhiyun struct pmcraid_ioarcb ioarcb; 522*4882a593Smuzhiyun struct pmcraid_ioadl_desc ioadl[PMCRAID_IOADLS_EXTERNAL + 3]; 523*4882a593Smuzhiyun struct pmcraid_ioasa ioasa; 524*4882a593Smuzhiyun } __attribute__ ((packed, aligned(PMCRAID_IOARCB_ALIGNMENT))); 525*4882a593Smuzhiyun 526*4882a593Smuzhiyun /* pmcraid_sglist - Scatter-gather list allocated for passthrough ioctls 527*4882a593Smuzhiyun */ 528*4882a593Smuzhiyun struct pmcraid_sglist { 529*4882a593Smuzhiyun u32 order; 530*4882a593Smuzhiyun u32 num_sg; 531*4882a593Smuzhiyun u32 num_dma_sg; 532*4882a593Smuzhiyun struct scatterlist *scatterlist; 533*4882a593Smuzhiyun }; 534*4882a593Smuzhiyun 535*4882a593Smuzhiyun /* page D0 inquiry data of focal point resource */ 536*4882a593Smuzhiyun struct pmcraid_inquiry_data { 537*4882a593Smuzhiyun __u8 ph_dev_type; 538*4882a593Smuzhiyun __u8 page_code; 539*4882a593Smuzhiyun __u8 reserved1; 540*4882a593Smuzhiyun __u8 add_page_len; 541*4882a593Smuzhiyun __u8 length; 542*4882a593Smuzhiyun __u8 reserved2; 543*4882a593Smuzhiyun __be16 fw_version; 544*4882a593Smuzhiyun __u8 reserved3[16]; 545*4882a593Smuzhiyun }; 546*4882a593Smuzhiyun 547*4882a593Smuzhiyun #define PMCRAID_TIMESTAMP_LEN 12 548*4882a593Smuzhiyun #define PMCRAID_REQ_TM_STR_LEN 6 549*4882a593Smuzhiyun #define PMCRAID_SCSI_SET_TIMESTAMP 0xA4 550*4882a593Smuzhiyun #define PMCRAID_SCSI_SERVICE_ACTION 0x0F 551*4882a593Smuzhiyun 552*4882a593Smuzhiyun struct pmcraid_timestamp_data { 553*4882a593Smuzhiyun __u8 reserved1[4]; 554*4882a593Smuzhiyun __u8 timestamp[PMCRAID_REQ_TM_STR_LEN]; /* current time value */ 555*4882a593Smuzhiyun __u8 reserved2[2]; 556*4882a593Smuzhiyun }; 557*4882a593Smuzhiyun 558*4882a593Smuzhiyun /* pmcraid_cmd - LLD representation of SCSI command */ 559*4882a593Smuzhiyun struct pmcraid_cmd { 560*4882a593Smuzhiyun 561*4882a593Smuzhiyun /* Ptr and bus address of DMA.able control block for this command */ 562*4882a593Smuzhiyun struct pmcraid_control_block *ioa_cb; 563*4882a593Smuzhiyun dma_addr_t ioa_cb_bus_addr; 564*4882a593Smuzhiyun dma_addr_t dma_handle; 565*4882a593Smuzhiyun 566*4882a593Smuzhiyun /* pointer to mid layer structure of SCSI commands */ 567*4882a593Smuzhiyun struct scsi_cmnd *scsi_cmd; 568*4882a593Smuzhiyun 569*4882a593Smuzhiyun struct list_head free_list; 570*4882a593Smuzhiyun struct completion wait_for_completion; 571*4882a593Smuzhiyun struct timer_list timer; /* needed for internal commands */ 572*4882a593Smuzhiyun u32 timeout; /* current timeout value */ 573*4882a593Smuzhiyun u32 index; /* index into the command list */ 574*4882a593Smuzhiyun u8 completion_req; /* for handling internal commands */ 575*4882a593Smuzhiyun u8 release; /* for handling completions */ 576*4882a593Smuzhiyun 577*4882a593Smuzhiyun void (*cmd_done) (struct pmcraid_cmd *); 578*4882a593Smuzhiyun struct pmcraid_instance *drv_inst; 579*4882a593Smuzhiyun 580*4882a593Smuzhiyun struct pmcraid_sglist *sglist; /* used for passthrough IOCTLs */ 581*4882a593Smuzhiyun 582*4882a593Smuzhiyun /* scratch used */ 583*4882a593Smuzhiyun union { 584*4882a593Smuzhiyun /* during reset sequence */ 585*4882a593Smuzhiyun unsigned long time_left; 586*4882a593Smuzhiyun struct pmcraid_resource_entry *res; 587*4882a593Smuzhiyun int hrrq_index; 588*4882a593Smuzhiyun 589*4882a593Smuzhiyun /* used during IO command error handling. Sense buffer 590*4882a593Smuzhiyun * for REQUEST SENSE command if firmware is not sending 591*4882a593Smuzhiyun * auto sense data 592*4882a593Smuzhiyun */ 593*4882a593Smuzhiyun struct { 594*4882a593Smuzhiyun u8 *sense_buffer; 595*4882a593Smuzhiyun dma_addr_t sense_buffer_dma; 596*4882a593Smuzhiyun }; 597*4882a593Smuzhiyun }; 598*4882a593Smuzhiyun }; 599*4882a593Smuzhiyun 600*4882a593Smuzhiyun /* 601*4882a593Smuzhiyun * Interrupt registers of IOA 602*4882a593Smuzhiyun */ 603*4882a593Smuzhiyun struct pmcraid_interrupts { 604*4882a593Smuzhiyun void __iomem *ioa_host_interrupt_reg; 605*4882a593Smuzhiyun void __iomem *ioa_host_msix_interrupt_reg; 606*4882a593Smuzhiyun void __iomem *ioa_host_interrupt_clr_reg; 607*4882a593Smuzhiyun void __iomem *ioa_host_interrupt_mask_reg; 608*4882a593Smuzhiyun void __iomem *ioa_host_interrupt_mask_clr_reg; 609*4882a593Smuzhiyun void __iomem *global_interrupt_mask_reg; 610*4882a593Smuzhiyun void __iomem *host_ioa_interrupt_reg; 611*4882a593Smuzhiyun void __iomem *host_ioa_interrupt_clr_reg; 612*4882a593Smuzhiyun }; 613*4882a593Smuzhiyun 614*4882a593Smuzhiyun /* ISR parameters LLD allocates (one for each MSI-X if enabled) vectors */ 615*4882a593Smuzhiyun struct pmcraid_isr_param { 616*4882a593Smuzhiyun struct pmcraid_instance *drv_inst; 617*4882a593Smuzhiyun u8 hrrq_id; /* hrrq entry index */ 618*4882a593Smuzhiyun }; 619*4882a593Smuzhiyun 620*4882a593Smuzhiyun 621*4882a593Smuzhiyun /* AEN message header sent as part of event data to applications */ 622*4882a593Smuzhiyun struct pmcraid_aen_msg { 623*4882a593Smuzhiyun u32 hostno; 624*4882a593Smuzhiyun u32 length; 625*4882a593Smuzhiyun u8 reserved[8]; 626*4882a593Smuzhiyun u8 data[]; 627*4882a593Smuzhiyun }; 628*4882a593Smuzhiyun 629*4882a593Smuzhiyun /* Controller state event message type */ 630*4882a593Smuzhiyun struct pmcraid_state_msg { 631*4882a593Smuzhiyun struct pmcraid_aen_msg msg; 632*4882a593Smuzhiyun u32 ioa_state; 633*4882a593Smuzhiyun }; 634*4882a593Smuzhiyun 635*4882a593Smuzhiyun #define PMC_DEVICE_EVENT_RESET_START 0x11000000 636*4882a593Smuzhiyun #define PMC_DEVICE_EVENT_RESET_SUCCESS 0x11000001 637*4882a593Smuzhiyun #define PMC_DEVICE_EVENT_RESET_FAILED 0x11000002 638*4882a593Smuzhiyun #define PMC_DEVICE_EVENT_SHUTDOWN_START 0x11000003 639*4882a593Smuzhiyun #define PMC_DEVICE_EVENT_SHUTDOWN_SUCCESS 0x11000004 640*4882a593Smuzhiyun #define PMC_DEVICE_EVENT_SHUTDOWN_FAILED 0x11000005 641*4882a593Smuzhiyun 642*4882a593Smuzhiyun struct pmcraid_hostrcb { 643*4882a593Smuzhiyun struct pmcraid_instance *drv_inst; 644*4882a593Smuzhiyun struct pmcraid_aen_msg *msg; 645*4882a593Smuzhiyun struct pmcraid_hcam_hdr *hcam; /* pointer to hcam buffer */ 646*4882a593Smuzhiyun struct pmcraid_cmd *cmd; /* pointer to command block used */ 647*4882a593Smuzhiyun dma_addr_t baddr; /* system address of hcam buffer */ 648*4882a593Smuzhiyun atomic_t ignore; /* process HCAM response ? */ 649*4882a593Smuzhiyun }; 650*4882a593Smuzhiyun 651*4882a593Smuzhiyun #define PMCRAID_AEN_HDR_SIZE sizeof(struct pmcraid_aen_msg) 652*4882a593Smuzhiyun 653*4882a593Smuzhiyun 654*4882a593Smuzhiyun 655*4882a593Smuzhiyun /* 656*4882a593Smuzhiyun * Per adapter structure maintained by LLD 657*4882a593Smuzhiyun */ 658*4882a593Smuzhiyun struct pmcraid_instance { 659*4882a593Smuzhiyun /* Array of allowed-to-be-exposed resources, initialized from 660*4882a593Smuzhiyun * Configutation Table, later updated with CCNs 661*4882a593Smuzhiyun */ 662*4882a593Smuzhiyun struct pmcraid_resource_entry *res_entries; 663*4882a593Smuzhiyun 664*4882a593Smuzhiyun struct list_head free_res_q; /* res_entries lists for easy lookup */ 665*4882a593Smuzhiyun struct list_head used_res_q; /* List of to be exposed resources */ 666*4882a593Smuzhiyun spinlock_t resource_lock; /* spinlock to protect resource list */ 667*4882a593Smuzhiyun 668*4882a593Smuzhiyun void __iomem *mapped_dma_addr; 669*4882a593Smuzhiyun void __iomem *ioa_status; /* Iomapped IOA status register */ 670*4882a593Smuzhiyun void __iomem *mailbox; /* Iomapped mailbox register */ 671*4882a593Smuzhiyun void __iomem *ioarrin; /* IOmapped IOARR IN register */ 672*4882a593Smuzhiyun 673*4882a593Smuzhiyun struct pmcraid_interrupts int_regs; 674*4882a593Smuzhiyun struct pmcraid_chip_details *chip_cfg; 675*4882a593Smuzhiyun 676*4882a593Smuzhiyun /* HostRCBs needed for HCAM */ 677*4882a593Smuzhiyun struct pmcraid_hostrcb ldn; 678*4882a593Smuzhiyun struct pmcraid_hostrcb ccn; 679*4882a593Smuzhiyun struct pmcraid_state_msg scn; /* controller state change msg */ 680*4882a593Smuzhiyun 681*4882a593Smuzhiyun 682*4882a593Smuzhiyun /* Bus address of start of HRRQ */ 683*4882a593Smuzhiyun dma_addr_t hrrq_start_bus_addr[PMCRAID_NUM_MSIX_VECTORS]; 684*4882a593Smuzhiyun 685*4882a593Smuzhiyun /* Pointer to 1st entry of HRRQ */ 686*4882a593Smuzhiyun __le32 *hrrq_start[PMCRAID_NUM_MSIX_VECTORS]; 687*4882a593Smuzhiyun 688*4882a593Smuzhiyun /* Pointer to last entry of HRRQ */ 689*4882a593Smuzhiyun __le32 *hrrq_end[PMCRAID_NUM_MSIX_VECTORS]; 690*4882a593Smuzhiyun 691*4882a593Smuzhiyun /* Pointer to current pointer of hrrq */ 692*4882a593Smuzhiyun __le32 *hrrq_curr[PMCRAID_NUM_MSIX_VECTORS]; 693*4882a593Smuzhiyun 694*4882a593Smuzhiyun /* Lock for HRRQ access */ 695*4882a593Smuzhiyun spinlock_t hrrq_lock[PMCRAID_NUM_MSIX_VECTORS]; 696*4882a593Smuzhiyun 697*4882a593Smuzhiyun struct pmcraid_inquiry_data *inq_data; 698*4882a593Smuzhiyun dma_addr_t inq_data_baddr; 699*4882a593Smuzhiyun 700*4882a593Smuzhiyun struct pmcraid_timestamp_data *timestamp_data; 701*4882a593Smuzhiyun dma_addr_t timestamp_data_baddr; 702*4882a593Smuzhiyun 703*4882a593Smuzhiyun /* size of configuration table entry, varies based on the firmware */ 704*4882a593Smuzhiyun u32 config_table_entry_size; 705*4882a593Smuzhiyun 706*4882a593Smuzhiyun /* Expected toggle bit at host */ 707*4882a593Smuzhiyun u8 host_toggle_bit[PMCRAID_NUM_MSIX_VECTORS]; 708*4882a593Smuzhiyun 709*4882a593Smuzhiyun 710*4882a593Smuzhiyun /* Wait Q for threads to wait for Reset IOA completion */ 711*4882a593Smuzhiyun wait_queue_head_t reset_wait_q; 712*4882a593Smuzhiyun struct pmcraid_cmd *reset_cmd; 713*4882a593Smuzhiyun 714*4882a593Smuzhiyun /* structures for supporting SIGIO based AEN. */ 715*4882a593Smuzhiyun struct fasync_struct *aen_queue; 716*4882a593Smuzhiyun struct mutex aen_queue_lock; /* lock for aen subscribers list */ 717*4882a593Smuzhiyun struct cdev cdev; 718*4882a593Smuzhiyun 719*4882a593Smuzhiyun struct Scsi_Host *host; /* mid layer interface structure handle */ 720*4882a593Smuzhiyun struct pci_dev *pdev; /* PCI device structure handle */ 721*4882a593Smuzhiyun 722*4882a593Smuzhiyun /* No of Reset IOA retries . IOA marked dead if threshold exceeds */ 723*4882a593Smuzhiyun u8 ioa_reset_attempts; 724*4882a593Smuzhiyun #define PMCRAID_RESET_ATTEMPTS 3 725*4882a593Smuzhiyun 726*4882a593Smuzhiyun u8 current_log_level; /* default level for logging IOASC errors */ 727*4882a593Smuzhiyun 728*4882a593Smuzhiyun u8 num_hrrq; /* Number of interrupt vectors allocated */ 729*4882a593Smuzhiyun u8 interrupt_mode; /* current interrupt mode legacy or msix */ 730*4882a593Smuzhiyun dev_t dev; /* Major-Minor numbers for Char device */ 731*4882a593Smuzhiyun 732*4882a593Smuzhiyun /* Used as ISR handler argument */ 733*4882a593Smuzhiyun struct pmcraid_isr_param hrrq_vector[PMCRAID_NUM_MSIX_VECTORS]; 734*4882a593Smuzhiyun 735*4882a593Smuzhiyun /* Message id as filled in last fired IOARCB, used to identify HRRQ */ 736*4882a593Smuzhiyun atomic_t last_message_id; 737*4882a593Smuzhiyun 738*4882a593Smuzhiyun /* configuration table */ 739*4882a593Smuzhiyun struct pmcraid_config_table *cfg_table; 740*4882a593Smuzhiyun dma_addr_t cfg_table_bus_addr; 741*4882a593Smuzhiyun 742*4882a593Smuzhiyun /* structures related to command blocks */ 743*4882a593Smuzhiyun struct kmem_cache *cmd_cachep; /* cache for cmd blocks */ 744*4882a593Smuzhiyun struct dma_pool *control_pool; /* pool for control blocks */ 745*4882a593Smuzhiyun char cmd_pool_name[64]; /* name of cmd cache */ 746*4882a593Smuzhiyun char ctl_pool_name[64]; /* name of control cache */ 747*4882a593Smuzhiyun 748*4882a593Smuzhiyun struct pmcraid_cmd *cmd_list[PMCRAID_MAX_CMD]; 749*4882a593Smuzhiyun 750*4882a593Smuzhiyun struct list_head free_cmd_pool; 751*4882a593Smuzhiyun struct list_head pending_cmd_pool; 752*4882a593Smuzhiyun spinlock_t free_pool_lock; /* free pool lock */ 753*4882a593Smuzhiyun spinlock_t pending_pool_lock; /* pending pool lock */ 754*4882a593Smuzhiyun 755*4882a593Smuzhiyun /* Tasklet to handle deferred processing */ 756*4882a593Smuzhiyun struct tasklet_struct isr_tasklet[PMCRAID_NUM_MSIX_VECTORS]; 757*4882a593Smuzhiyun 758*4882a593Smuzhiyun /* Work-queue (Shared) for deferred reset processing */ 759*4882a593Smuzhiyun struct work_struct worker_q; 760*4882a593Smuzhiyun 761*4882a593Smuzhiyun /* No of IO commands pending with FW */ 762*4882a593Smuzhiyun atomic_t outstanding_cmds; 763*4882a593Smuzhiyun 764*4882a593Smuzhiyun /* should add/delete resources to mid-layer now ?*/ 765*4882a593Smuzhiyun atomic_t expose_resources; 766*4882a593Smuzhiyun 767*4882a593Smuzhiyun 768*4882a593Smuzhiyun 769*4882a593Smuzhiyun u32 ioa_state:4; /* For IOA Reset sequence FSM */ 770*4882a593Smuzhiyun #define IOA_STATE_OPERATIONAL 0x0 771*4882a593Smuzhiyun #define IOA_STATE_UNKNOWN 0x1 772*4882a593Smuzhiyun #define IOA_STATE_DEAD 0x2 773*4882a593Smuzhiyun #define IOA_STATE_IN_SOFT_RESET 0x3 774*4882a593Smuzhiyun #define IOA_STATE_IN_HARD_RESET 0x4 775*4882a593Smuzhiyun #define IOA_STATE_IN_RESET_ALERT 0x5 776*4882a593Smuzhiyun #define IOA_STATE_IN_BRINGDOWN 0x6 777*4882a593Smuzhiyun #define IOA_STATE_IN_BRINGUP 0x7 778*4882a593Smuzhiyun 779*4882a593Smuzhiyun u32 ioa_reset_in_progress:1; /* true if IOA reset is in progress */ 780*4882a593Smuzhiyun u32 ioa_hard_reset:1; /* TRUE if Hard Reset is needed */ 781*4882a593Smuzhiyun u32 ioa_unit_check:1; /* Indicates Unit Check condition */ 782*4882a593Smuzhiyun u32 ioa_bringdown:1; /* whether IOA needs to be brought down */ 783*4882a593Smuzhiyun u32 force_ioa_reset:1; /* force adapter reset ? */ 784*4882a593Smuzhiyun u32 reinit_cfg_table:1; /* reinit config table due to lost CCN */ 785*4882a593Smuzhiyun u32 ioa_shutdown_type:2;/* shutdown type used during reset */ 786*4882a593Smuzhiyun #define SHUTDOWN_NONE 0x0 787*4882a593Smuzhiyun #define SHUTDOWN_NORMAL 0x1 788*4882a593Smuzhiyun #define SHUTDOWN_ABBREV 0x2 789*4882a593Smuzhiyun u32 timestamp_error:1; /* indicate set timestamp for out of sync */ 790*4882a593Smuzhiyun 791*4882a593Smuzhiyun }; 792*4882a593Smuzhiyun 793*4882a593Smuzhiyun /* LLD maintained resource entry structure */ 794*4882a593Smuzhiyun struct pmcraid_resource_entry { 795*4882a593Smuzhiyun struct list_head queue; /* link to "to be exposed" resources */ 796*4882a593Smuzhiyun union { 797*4882a593Smuzhiyun struct pmcraid_config_table_entry cfg_entry; 798*4882a593Smuzhiyun struct pmcraid_config_table_entry_ext cfg_entry_ext; 799*4882a593Smuzhiyun }; 800*4882a593Smuzhiyun struct scsi_device *scsi_dev; /* Link scsi_device structure */ 801*4882a593Smuzhiyun atomic_t read_failures; /* count of failed READ commands */ 802*4882a593Smuzhiyun atomic_t write_failures; /* count of failed WRITE commands */ 803*4882a593Smuzhiyun 804*4882a593Smuzhiyun /* To indicate add/delete/modify during CCN */ 805*4882a593Smuzhiyun u8 change_detected; 806*4882a593Smuzhiyun #define RES_CHANGE_ADD 0x1 /* add this to mid-layer */ 807*4882a593Smuzhiyun #define RES_CHANGE_DEL 0x2 /* remove this from mid-layer */ 808*4882a593Smuzhiyun 809*4882a593Smuzhiyun u8 reset_progress; /* Device is resetting */ 810*4882a593Smuzhiyun 811*4882a593Smuzhiyun /* 812*4882a593Smuzhiyun * When IOA asks for sync (i.e. IOASC = Not Ready, Sync Required), this 813*4882a593Smuzhiyun * flag will be set, mid layer will be asked to retry. In the next 814*4882a593Smuzhiyun * attempt, this flag will be checked in queuecommand() to set 815*4882a593Smuzhiyun * SYNC_COMPLETE flag in IOARCB (flag_0). 816*4882a593Smuzhiyun */ 817*4882a593Smuzhiyun u8 sync_reqd; 818*4882a593Smuzhiyun 819*4882a593Smuzhiyun /* target indicates the mapped target_id assigned to this resource if 820*4882a593Smuzhiyun * this is VSET resource. For non-VSET resources this will be un-used 821*4882a593Smuzhiyun * or zero 822*4882a593Smuzhiyun */ 823*4882a593Smuzhiyun u8 target; 824*4882a593Smuzhiyun }; 825*4882a593Smuzhiyun 826*4882a593Smuzhiyun /* Data structures used in IOASC error code logging */ 827*4882a593Smuzhiyun struct pmcraid_ioasc_error { 828*4882a593Smuzhiyun u32 ioasc_code; /* IOASC code */ 829*4882a593Smuzhiyun u8 log_level; /* default log level assignment. */ 830*4882a593Smuzhiyun char *error_string; 831*4882a593Smuzhiyun }; 832*4882a593Smuzhiyun 833*4882a593Smuzhiyun /* Initial log_level assignments for various IOASCs */ 834*4882a593Smuzhiyun #define IOASC_LOG_LEVEL_NONE 0x0 /* no logging */ 835*4882a593Smuzhiyun #define IOASC_LOG_LEVEL_MUST 0x1 /* must log: all high-severity errors */ 836*4882a593Smuzhiyun #define IOASC_LOG_LEVEL_HARD 0x2 /* optional – low severity errors */ 837*4882a593Smuzhiyun 838*4882a593Smuzhiyun /* Error information maintained by LLD. LLD initializes the pmcraid_error_table 839*4882a593Smuzhiyun * statically. 840*4882a593Smuzhiyun */ 841*4882a593Smuzhiyun static struct pmcraid_ioasc_error pmcraid_ioasc_error_table[] = { 842*4882a593Smuzhiyun {0x01180600, IOASC_LOG_LEVEL_HARD, 843*4882a593Smuzhiyun "Recovered Error, soft media error, sector reassignment suggested"}, 844*4882a593Smuzhiyun {0x015D0000, IOASC_LOG_LEVEL_HARD, 845*4882a593Smuzhiyun "Recovered Error, failure prediction threshold exceeded"}, 846*4882a593Smuzhiyun {0x015D9200, IOASC_LOG_LEVEL_HARD, 847*4882a593Smuzhiyun "Recovered Error, soft Cache Card Battery error threshold"}, 848*4882a593Smuzhiyun {0x015D9200, IOASC_LOG_LEVEL_HARD, 849*4882a593Smuzhiyun "Recovered Error, soft Cache Card Battery error threshold"}, 850*4882a593Smuzhiyun {0x02048000, IOASC_LOG_LEVEL_HARD, 851*4882a593Smuzhiyun "Not Ready, IOA Reset Required"}, 852*4882a593Smuzhiyun {0x02408500, IOASC_LOG_LEVEL_HARD, 853*4882a593Smuzhiyun "Not Ready, IOA microcode download required"}, 854*4882a593Smuzhiyun {0x03110B00, IOASC_LOG_LEVEL_HARD, 855*4882a593Smuzhiyun "Medium Error, data unreadable, reassignment suggested"}, 856*4882a593Smuzhiyun {0x03110C00, IOASC_LOG_LEVEL_MUST, 857*4882a593Smuzhiyun "Medium Error, data unreadable do not reassign"}, 858*4882a593Smuzhiyun {0x03310000, IOASC_LOG_LEVEL_HARD, 859*4882a593Smuzhiyun "Medium Error, media corrupted"}, 860*4882a593Smuzhiyun {0x04050000, IOASC_LOG_LEVEL_HARD, 861*4882a593Smuzhiyun "Hardware Error, IOA can't communicate with device"}, 862*4882a593Smuzhiyun {0x04080000, IOASC_LOG_LEVEL_MUST, 863*4882a593Smuzhiyun "Hardware Error, device bus error"}, 864*4882a593Smuzhiyun {0x04088000, IOASC_LOG_LEVEL_MUST, 865*4882a593Smuzhiyun "Hardware Error, device bus is not functioning"}, 866*4882a593Smuzhiyun {0x04118000, IOASC_LOG_LEVEL_HARD, 867*4882a593Smuzhiyun "Hardware Error, IOA reserved area data check"}, 868*4882a593Smuzhiyun {0x04118100, IOASC_LOG_LEVEL_HARD, 869*4882a593Smuzhiyun "Hardware Error, IOA reserved area invalid data pattern"}, 870*4882a593Smuzhiyun {0x04118200, IOASC_LOG_LEVEL_HARD, 871*4882a593Smuzhiyun "Hardware Error, IOA reserved area LRC error"}, 872*4882a593Smuzhiyun {0x04320000, IOASC_LOG_LEVEL_HARD, 873*4882a593Smuzhiyun "Hardware Error, reassignment space exhausted"}, 874*4882a593Smuzhiyun {0x04330000, IOASC_LOG_LEVEL_HARD, 875*4882a593Smuzhiyun "Hardware Error, data transfer underlength error"}, 876*4882a593Smuzhiyun {0x04330000, IOASC_LOG_LEVEL_HARD, 877*4882a593Smuzhiyun "Hardware Error, data transfer overlength error"}, 878*4882a593Smuzhiyun {0x04418000, IOASC_LOG_LEVEL_MUST, 879*4882a593Smuzhiyun "Hardware Error, PCI bus error"}, 880*4882a593Smuzhiyun {0x04440000, IOASC_LOG_LEVEL_HARD, 881*4882a593Smuzhiyun "Hardware Error, device error"}, 882*4882a593Smuzhiyun {0x04448200, IOASC_LOG_LEVEL_MUST, 883*4882a593Smuzhiyun "Hardware Error, IOA error"}, 884*4882a593Smuzhiyun {0x04448300, IOASC_LOG_LEVEL_HARD, 885*4882a593Smuzhiyun "Hardware Error, undefined device response"}, 886*4882a593Smuzhiyun {0x04448400, IOASC_LOG_LEVEL_HARD, 887*4882a593Smuzhiyun "Hardware Error, IOA microcode error"}, 888*4882a593Smuzhiyun {0x04448600, IOASC_LOG_LEVEL_HARD, 889*4882a593Smuzhiyun "Hardware Error, IOA reset required"}, 890*4882a593Smuzhiyun {0x04449200, IOASC_LOG_LEVEL_HARD, 891*4882a593Smuzhiyun "Hardware Error, hard Cache Fearuee Card Battery error"}, 892*4882a593Smuzhiyun {0x0444A000, IOASC_LOG_LEVEL_HARD, 893*4882a593Smuzhiyun "Hardware Error, failed device altered"}, 894*4882a593Smuzhiyun {0x0444A200, IOASC_LOG_LEVEL_HARD, 895*4882a593Smuzhiyun "Hardware Error, data check after reassignment"}, 896*4882a593Smuzhiyun {0x0444A300, IOASC_LOG_LEVEL_HARD, 897*4882a593Smuzhiyun "Hardware Error, LRC error after reassignment"}, 898*4882a593Smuzhiyun {0x044A0000, IOASC_LOG_LEVEL_HARD, 899*4882a593Smuzhiyun "Hardware Error, device bus error (msg/cmd phase)"}, 900*4882a593Smuzhiyun {0x04670400, IOASC_LOG_LEVEL_HARD, 901*4882a593Smuzhiyun "Hardware Error, new device can't be used"}, 902*4882a593Smuzhiyun {0x04678000, IOASC_LOG_LEVEL_HARD, 903*4882a593Smuzhiyun "Hardware Error, invalid multiadapter configuration"}, 904*4882a593Smuzhiyun {0x04678100, IOASC_LOG_LEVEL_HARD, 905*4882a593Smuzhiyun "Hardware Error, incorrect connection between enclosures"}, 906*4882a593Smuzhiyun {0x04678200, IOASC_LOG_LEVEL_HARD, 907*4882a593Smuzhiyun "Hardware Error, connections exceed IOA design limits"}, 908*4882a593Smuzhiyun {0x04678300, IOASC_LOG_LEVEL_HARD, 909*4882a593Smuzhiyun "Hardware Error, incorrect multipath connection"}, 910*4882a593Smuzhiyun {0x04679000, IOASC_LOG_LEVEL_HARD, 911*4882a593Smuzhiyun "Hardware Error, command to LUN failed"}, 912*4882a593Smuzhiyun {0x064C8000, IOASC_LOG_LEVEL_HARD, 913*4882a593Smuzhiyun "Unit Attention, cache exists for missing/failed device"}, 914*4882a593Smuzhiyun {0x06670100, IOASC_LOG_LEVEL_HARD, 915*4882a593Smuzhiyun "Unit Attention, incompatible exposed mode device"}, 916*4882a593Smuzhiyun {0x06670600, IOASC_LOG_LEVEL_HARD, 917*4882a593Smuzhiyun "Unit Attention, attachment of logical unit failed"}, 918*4882a593Smuzhiyun {0x06678000, IOASC_LOG_LEVEL_HARD, 919*4882a593Smuzhiyun "Unit Attention, cables exceed connective design limit"}, 920*4882a593Smuzhiyun {0x06678300, IOASC_LOG_LEVEL_HARD, 921*4882a593Smuzhiyun "Unit Attention, incomplete multipath connection between" \ 922*4882a593Smuzhiyun "IOA and enclosure"}, 923*4882a593Smuzhiyun {0x06678400, IOASC_LOG_LEVEL_HARD, 924*4882a593Smuzhiyun "Unit Attention, incomplete multipath connection between" \ 925*4882a593Smuzhiyun "device and enclosure"}, 926*4882a593Smuzhiyun {0x06678500, IOASC_LOG_LEVEL_HARD, 927*4882a593Smuzhiyun "Unit Attention, incomplete multipath connection between" \ 928*4882a593Smuzhiyun "IOA and remote IOA"}, 929*4882a593Smuzhiyun {0x06678600, IOASC_LOG_LEVEL_HARD, 930*4882a593Smuzhiyun "Unit Attention, missing remote IOA"}, 931*4882a593Smuzhiyun {0x06679100, IOASC_LOG_LEVEL_HARD, 932*4882a593Smuzhiyun "Unit Attention, enclosure doesn't support required multipath" \ 933*4882a593Smuzhiyun "function"}, 934*4882a593Smuzhiyun {0x06698200, IOASC_LOG_LEVEL_HARD, 935*4882a593Smuzhiyun "Unit Attention, corrupt array parity detected on device"}, 936*4882a593Smuzhiyun {0x066B0200, IOASC_LOG_LEVEL_HARD, 937*4882a593Smuzhiyun "Unit Attention, array exposed"}, 938*4882a593Smuzhiyun {0x066B8200, IOASC_LOG_LEVEL_HARD, 939*4882a593Smuzhiyun "Unit Attention, exposed array is still protected"}, 940*4882a593Smuzhiyun {0x066B9200, IOASC_LOG_LEVEL_HARD, 941*4882a593Smuzhiyun "Unit Attention, Multipath redundancy level got worse"}, 942*4882a593Smuzhiyun {0x07270000, IOASC_LOG_LEVEL_HARD, 943*4882a593Smuzhiyun "Data Protect, device is read/write protected by IOA"}, 944*4882a593Smuzhiyun {0x07278000, IOASC_LOG_LEVEL_HARD, 945*4882a593Smuzhiyun "Data Protect, IOA doesn't support device attribute"}, 946*4882a593Smuzhiyun {0x07278100, IOASC_LOG_LEVEL_HARD, 947*4882a593Smuzhiyun "Data Protect, NVRAM mirroring prohibited"}, 948*4882a593Smuzhiyun {0x07278400, IOASC_LOG_LEVEL_HARD, 949*4882a593Smuzhiyun "Data Protect, array is short 2 or more devices"}, 950*4882a593Smuzhiyun {0x07278600, IOASC_LOG_LEVEL_HARD, 951*4882a593Smuzhiyun "Data Protect, exposed array is short a required device"}, 952*4882a593Smuzhiyun {0x07278700, IOASC_LOG_LEVEL_HARD, 953*4882a593Smuzhiyun "Data Protect, array members not at required addresses"}, 954*4882a593Smuzhiyun {0x07278800, IOASC_LOG_LEVEL_HARD, 955*4882a593Smuzhiyun "Data Protect, exposed mode device resource address conflict"}, 956*4882a593Smuzhiyun {0x07278900, IOASC_LOG_LEVEL_HARD, 957*4882a593Smuzhiyun "Data Protect, incorrect resource address of exposed mode device"}, 958*4882a593Smuzhiyun {0x07278A00, IOASC_LOG_LEVEL_HARD, 959*4882a593Smuzhiyun "Data Protect, Array is missing a device and parity is out of sync"}, 960*4882a593Smuzhiyun {0x07278B00, IOASC_LOG_LEVEL_HARD, 961*4882a593Smuzhiyun "Data Protect, maximum number of arrays already exist"}, 962*4882a593Smuzhiyun {0x07278C00, IOASC_LOG_LEVEL_HARD, 963*4882a593Smuzhiyun "Data Protect, cannot locate cache data for device"}, 964*4882a593Smuzhiyun {0x07278D00, IOASC_LOG_LEVEL_HARD, 965*4882a593Smuzhiyun "Data Protect, cache data exits for a changed device"}, 966*4882a593Smuzhiyun {0x07279100, IOASC_LOG_LEVEL_HARD, 967*4882a593Smuzhiyun "Data Protect, detection of a device requiring format"}, 968*4882a593Smuzhiyun {0x07279200, IOASC_LOG_LEVEL_HARD, 969*4882a593Smuzhiyun "Data Protect, IOA exceeds maximum number of devices"}, 970*4882a593Smuzhiyun {0x07279600, IOASC_LOG_LEVEL_HARD, 971*4882a593Smuzhiyun "Data Protect, missing array, volume set is not functional"}, 972*4882a593Smuzhiyun {0x07279700, IOASC_LOG_LEVEL_HARD, 973*4882a593Smuzhiyun "Data Protect, single device for a volume set"}, 974*4882a593Smuzhiyun {0x07279800, IOASC_LOG_LEVEL_HARD, 975*4882a593Smuzhiyun "Data Protect, missing multiple devices for a volume set"}, 976*4882a593Smuzhiyun {0x07279900, IOASC_LOG_LEVEL_HARD, 977*4882a593Smuzhiyun "Data Protect, maximum number of volument sets already exists"}, 978*4882a593Smuzhiyun {0x07279A00, IOASC_LOG_LEVEL_HARD, 979*4882a593Smuzhiyun "Data Protect, other volume set problem"}, 980*4882a593Smuzhiyun }; 981*4882a593Smuzhiyun 982*4882a593Smuzhiyun /* macros to help in debugging */ 983*4882a593Smuzhiyun #define pmcraid_err(...) \ 984*4882a593Smuzhiyun printk(KERN_ERR "MaxRAID: "__VA_ARGS__) 985*4882a593Smuzhiyun 986*4882a593Smuzhiyun #define pmcraid_info(...) \ 987*4882a593Smuzhiyun if (pmcraid_debug_log) \ 988*4882a593Smuzhiyun printk(KERN_INFO "MaxRAID: "__VA_ARGS__) 989*4882a593Smuzhiyun 990*4882a593Smuzhiyun /* check if given command is a SCSI READ or SCSI WRITE command */ 991*4882a593Smuzhiyun #define SCSI_READ_CMD 0x1 /* any of SCSI READ commands */ 992*4882a593Smuzhiyun #define SCSI_WRITE_CMD 0x2 /* any of SCSI WRITE commands */ 993*4882a593Smuzhiyun #define SCSI_CMD_TYPE(opcode) \ 994*4882a593Smuzhiyun ({ u8 op = opcode; u8 __type = 0;\ 995*4882a593Smuzhiyun if (op == READ_6 || op == READ_10 || op == READ_12 || op == READ_16)\ 996*4882a593Smuzhiyun __type = SCSI_READ_CMD;\ 997*4882a593Smuzhiyun else if (op == WRITE_6 || op == WRITE_10 || op == WRITE_12 || \ 998*4882a593Smuzhiyun op == WRITE_16)\ 999*4882a593Smuzhiyun __type = SCSI_WRITE_CMD;\ 1000*4882a593Smuzhiyun __type;\ 1001*4882a593Smuzhiyun }) 1002*4882a593Smuzhiyun 1003*4882a593Smuzhiyun #define IS_SCSI_READ_WRITE(opcode) \ 1004*4882a593Smuzhiyun ({ u8 __type = SCSI_CMD_TYPE(opcode); \ 1005*4882a593Smuzhiyun (__type == SCSI_READ_CMD || __type == SCSI_WRITE_CMD) ? 1 : 0;\ 1006*4882a593Smuzhiyun }) 1007*4882a593Smuzhiyun 1008*4882a593Smuzhiyun 1009*4882a593Smuzhiyun /* 1010*4882a593Smuzhiyun * pmcraid_ioctl_header - definition of header structure that precedes all the 1011*4882a593Smuzhiyun * buffers given as ioctl arguments. 1012*4882a593Smuzhiyun * 1013*4882a593Smuzhiyun * .signature : always ASCII string, "PMCRAID" 1014*4882a593Smuzhiyun * .reserved : not used 1015*4882a593Smuzhiyun * .buffer_length : length of the buffer following the header 1016*4882a593Smuzhiyun */ 1017*4882a593Smuzhiyun struct pmcraid_ioctl_header { 1018*4882a593Smuzhiyun u8 signature[8]; 1019*4882a593Smuzhiyun u32 reserved; 1020*4882a593Smuzhiyun u32 buffer_length; 1021*4882a593Smuzhiyun }; 1022*4882a593Smuzhiyun 1023*4882a593Smuzhiyun #define PMCRAID_IOCTL_SIGNATURE "PMCRAID" 1024*4882a593Smuzhiyun 1025*4882a593Smuzhiyun /* 1026*4882a593Smuzhiyun * pmcraid_passthrough_ioctl_buffer - structure given as argument to 1027*4882a593Smuzhiyun * passthrough(or firmware handled) IOCTL commands. Note that ioarcb requires 1028*4882a593Smuzhiyun * 32-byte alignment so, it is necessary to pack this structure to avoid any 1029*4882a593Smuzhiyun * holes between ioctl_header and passthrough buffer 1030*4882a593Smuzhiyun * 1031*4882a593Smuzhiyun * .ioactl_header : ioctl header 1032*4882a593Smuzhiyun * .ioarcb : filled-up ioarcb buffer, driver always reads this buffer 1033*4882a593Smuzhiyun * .ioasa : buffer for ioasa, driver fills this with IOASA from firmware 1034*4882a593Smuzhiyun * .request_buffer: The I/O buffer (flat), driver reads/writes to this based on 1035*4882a593Smuzhiyun * the transfer directions passed in ioarcb.flags0. Contents 1036*4882a593Smuzhiyun * of this buffer are valid only when ioarcb.data_transfer_len 1037*4882a593Smuzhiyun * is not zero. 1038*4882a593Smuzhiyun */ 1039*4882a593Smuzhiyun struct pmcraid_passthrough_ioctl_buffer { 1040*4882a593Smuzhiyun struct pmcraid_ioctl_header ioctl_header; 1041*4882a593Smuzhiyun struct pmcraid_ioarcb ioarcb; 1042*4882a593Smuzhiyun struct pmcraid_ioasa ioasa; 1043*4882a593Smuzhiyun u8 request_buffer[1]; 1044*4882a593Smuzhiyun } __attribute__ ((packed)); 1045*4882a593Smuzhiyun 1046*4882a593Smuzhiyun /* 1047*4882a593Smuzhiyun * keys to differentiate between driver handled IOCTLs and passthrough 1048*4882a593Smuzhiyun * IOCTLs passed to IOA. driver determines the ioctl type using macro 1049*4882a593Smuzhiyun * _IOC_TYPE 1050*4882a593Smuzhiyun */ 1051*4882a593Smuzhiyun #define PMCRAID_DRIVER_IOCTL 'D' 1052*4882a593Smuzhiyun #define PMCRAID_PASSTHROUGH_IOCTL 'F' 1053*4882a593Smuzhiyun 1054*4882a593Smuzhiyun #define DRV_IOCTL(n, size) \ 1055*4882a593Smuzhiyun _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_DRIVER_IOCTL, (n), (size)) 1056*4882a593Smuzhiyun 1057*4882a593Smuzhiyun #define FMW_IOCTL(n, size) \ 1058*4882a593Smuzhiyun _IOC(_IOC_READ|_IOC_WRITE, PMCRAID_PASSTHROUGH_IOCTL, (n), (size)) 1059*4882a593Smuzhiyun 1060*4882a593Smuzhiyun /* 1061*4882a593Smuzhiyun * _ARGSIZE: macro that gives size of the argument type passed to an IOCTL cmd. 1062*4882a593Smuzhiyun * This is to facilitate applications avoiding un-necessary memory allocations. 1063*4882a593Smuzhiyun * For example, most of driver handled ioctls do not require ioarcb, ioasa. 1064*4882a593Smuzhiyun */ 1065*4882a593Smuzhiyun #define _ARGSIZE(arg) (sizeof(struct pmcraid_ioctl_header) + sizeof(arg)) 1066*4882a593Smuzhiyun 1067*4882a593Smuzhiyun /* Driver handled IOCTL command definitions */ 1068*4882a593Smuzhiyun 1069*4882a593Smuzhiyun #define PMCRAID_IOCTL_RESET_ADAPTER \ 1070*4882a593Smuzhiyun DRV_IOCTL(5, sizeof(struct pmcraid_ioctl_header)) 1071*4882a593Smuzhiyun 1072*4882a593Smuzhiyun /* passthrough/firmware handled commands */ 1073*4882a593Smuzhiyun #define PMCRAID_IOCTL_PASSTHROUGH_COMMAND \ 1074*4882a593Smuzhiyun FMW_IOCTL(1, sizeof(struct pmcraid_passthrough_ioctl_buffer)) 1075*4882a593Smuzhiyun 1076*4882a593Smuzhiyun #define PMCRAID_IOCTL_DOWNLOAD_MICROCODE \ 1077*4882a593Smuzhiyun FMW_IOCTL(2, sizeof(struct pmcraid_passthrough_ioctl_buffer)) 1078*4882a593Smuzhiyun 1079*4882a593Smuzhiyun 1080*4882a593Smuzhiyun #endif /* _PMCRAID_H */ 1081