#ifndef iprlib_h #define iprlib_h /** * IBM IPR adapter utility library * * (C) Copyright 2000, 2004 * International Business Machines Corporation and others. * All Rights Reserved. This program and the accompanying * materials are made available under the terms of the * Common Public License v1.0 which accompanies this distribution. * */ /* * $Header: /cvsroot/iprdd/iprutils/iprlib.h,v 1.107 2009/06/30 23:32:40 wboyer Exp $ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; #define IPR_DASD_UCODE_USRLIB 0 #define IPR_DASD_UCODE_ETC 1 #define IPR_DASD_UCODE_NOT_FOUND -1 #define IPR_DASD_UCODE_NO_HDR 1 #define IPR_DASD_UCODE_HDR 2 #define UCODE_BASE_DIR "/usr/lib/microcode" #define LINUX_UCODE_BASE_DIR "/lib/firmware" #define FIRMWARE_HOTPLUG_DIR_TAG "FIRMWARE_DIR" #define FIRMWARE_HOTPLUG_CONFIG_FILE "/etc/hotplug/firmware.agent" #define FIRMWARE_HOTPLUG_DEFAULT_DIR LINUX_UCODE_BASE_DIR #define IPRDUMP_DIR "/var/log/" #define IPR_JBOD_BLOCK_SIZE 512 #define IPR_DEFAULT_AF_BLOCK_SIZE 522 #define IPR_JBOD_4K_BLOCK_SIZE 4096 #define IPR_AF_4K_BLOCK_SIZE 4224 #define IOCTL_BUFFER_SIZE 512 #define IPR_MAX_NUM_BUSES 4 #define IPR_VENDOR_ID_LEN 8 #define IPR_PROD_ID_LEN 16 #define IPR_SERIAL_NUM_LEN 8 #define ESM_SERIAL_NUM_LEN 12 #define YL_SERIAL_NUM_LEN 12 #define IPR_DESCRIPTION_LEN 16 #define IPR_VPD_PLANT_CODE_LEN 4 #define IPR_VPD_CACHE_SIZE_LEN 3 #define IPR_VPD_DRAM_SIZE_LEN 3 #define IPR_VPD_PART_NUM_LEN 12 #define IPR_CCB_CDB_LEN 16 #define IPR_QAC_BUFFER_SIZE 200000 #define IPR_SIS32_QAC_BUFFER_SIZE 16000 #define IPR_INVALID_ARRAY_ID 0xFF #define IPR_IOA_RESOURCE_HANDLE 0xffffffff #define IPR_RECLAIM_NUM_BLOCKS_MULTIPLIER 256 #define IPR_SDB_CHECK_AND_QUIESCE 0x00 #define IPR_SDB_CHECK_ONLY 0x40 #define IPR_SDB_CHECK_AND_QUIESCE_ENC 0x0e #define IPR_RDB_UNQUIESCE_AND_REBALANCE 0x20 #define IPR_MAX_NUM_SUPP_INQ_PAGES 36 #define SES_MAX_NUM_SUPP_INQ_PAGES 7 #define IPR_DUMP_TRACE_ENTRY_SIZE 8192 #define IPR_MODE_SENSE_LENGTH 255 #define IPR_DEFECT_LIST_HDR_LEN 4 #define IPR_FORMAT_DATA 0x10 #define IPR_FORMAT_IMMED 2 #define IPR_ARRAY_CMD_TIMEOUT (2 * 60) /* 2 minutes */ #define IPR_INTERNAL_DEV_TIMEOUT (2 * 60) /* 2 minutes */ #define IPR_FORMAT_UNIT_TIMEOUT (3 * 60 * 60) /* 3 hours */ #define IPR_INTERNAL_TIMEOUT (30) /* 30 seconds */ #define IPR_SUSPEND_DEV_BUS_TIMEOUT (35) /* 35 seconds */ #define IPR_EVALUATE_DEVICE_TIMEOUT (2 * 60) /* 2 minutes */ #define IPR_WRITE_BUFFER_TIMEOUT (8 * 60) /* 8 minutes */ #define IPR_CACHE_RECLAIM_TIMEOUT (10 * 60) /* 10 minutes */ #define SET_DASD_TIMEOUTS_TIMEOUT (2 * 60) #define IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES 50 #define IPR_DRIVE_ELEM_STATUS_EMPTY 5 #define IPR_DRIVE_ELEM_STATUS_POPULATED 1 #define IPR_DRIVE_ELEM_STATUS_UNSUPP 0 #define IPR_DRIVE_ELEM_STATUS_NO_ACCESS 8 #define IPR_TIMEOUT_SECOND_RADIX 0x0000 #define IPR_TIMEOUT_MINUTE_RADIX 0x4000 #define IPR_TIMEOUT_RADIX_MASK 0xC000 #define IPR_TIMEOUT_RADIX_IS_MINUTE(to) \ (((to) & IPR_TIMEOUT_RADIX_MASK) == IPR_TIMEOUT_MINUTE_RADIX) #define IPR_TIMEOUT_RADIX_IS_SECONDS(to) \ (((to) & IPR_TIMEOUT_RADIX_MASK) == IPR_TIMEOUT_SECOND_RADIX) #define IPR_TIMEOUT_MASK 0x3FFF #define IPR_IOA_DEBUG 0xDDu #define IPR_IOA_DEBUG_READ_IOA_MEM 0x00u #define IPR_IOA_DEBUG_WRITE_IOA_MEM 0x01u #define IPR_IOA_DEBUG_READ_FLIT 0x03u #define IPR_IOA_DEBUG_ENABLE_DBG_FUNC 0x0Au #define IPR_IOA_DEBUG_DISABLE_DBG_FUNC 0x0Bu #define IPR_STD_INQ_Z0_TERM_LEN 8 #define IPR_STD_INQ_Z1_TERM_LEN 12 #define IPR_STD_INQ_Z2_TERM_LEN 4 #define IPR_STD_INQ_Z3_TERM_LEN 5 #define IPR_STD_INQ_Z4_TERM_LEN 4 #define IPR_STD_INQ_Z5_TERM_LEN 2 #define IPR_STD_INQ_Z6_TERM_LEN 10 #define IPR_STD_INQ_PART_NUM_LEN 12 #define IPR_STD_INQ_EC_LEVEL_LEN 10 #define IPR_STD_INQ_FRU_NUM_LEN 12 #define IPR_START_STOP_STOP 0x00 #define IPR_START_STOP_START 0x01 #define IPR_READ_CAPACITY_16 0x10 #define IPR_SERVICE_ACTION_IN 0x9E #define IPR_MAINTENANCE_IN 0xA3 #define IPR_QUERY_MULTI_ADAPTER_STATUS 0x01 #define IPR_MAINTENANCE_OUT 0xA4 #define IPR_CHANGE_MULTI_ADAPTER_ASSIGNMENT 0x02 #define IPR_QUERY_RESOURCE_STATE 0xC2 #define IPR_QUERY_COMMAND_STATUS 0xCB #define IPR_SUSPEND_DEV_BUS 0xC8 #define IPR_RESUME_DEV_BUS 0xC9 #define IPR_IOA_SERVICE_ACTION 0xD2 #define IPR_QUERY_RES_ADDR_ALIASES 0x10 #define IPR_QUERY_RES_PATH_ALIASES 0x20 #define IPR_DISRUPT_DEVICE 0x11 #define IPR_QUERY_SAS_EXPANDER_INFO 0x12 #define IPR_QUERY_RES_REDUNDANCY_INFO 0x13 #define IPR_QUERY_RES_REDUNDANCY_INFO64 0x23 #define IPR_CHANGE_CACHE_PARAMETERS 0x14 #define IPR_QUERY_CACHE_PARAMETERS 0x16 #define IPR_LIVE_DUMP 0x31 #define IPR_QUERY_IOA_DEV_PORT 0x32 #define IPR_EVALUATE_DEVICE 0xE4 #define SKIP_READ 0xE8 #define SKIP_WRITE 0xEA #define QUERY_DASD_TIMEOUTS 0xEB #define SET_DASD_TIMEOUTS 0xEC #define IPR_MIGRATE_ARRAY_PROTECTION 0xEF #define IPR_QUERY_ARRAY_CONFIG 0xF0 #define IPR_START_ARRAY_PROTECTION 0xF1 #define IPR_STOP_ARRAY_PROTECTION 0xF2 #define IPR_RESYNC_ARRAY_PROTECTION 0xF3 #define IPR_ADD_ARRAY_DEVICE 0xF4 #define IPR_REMOVE_ARRAY_DEVICE 0xF5 #define IPR_REBUILD_DEVICE_DATA 0xF6 #define IPR_RECLAIM_CACHE_STORE 0xF8 #define IPR_SET_ARRAY_ASYMMETRIC_ACCESS 0xFA #define IPR_RECLAIM_ACTION 0x68 #define IPR_RECLAIM_PERFORM 0x00 #define IPR_RECLAIM_RESET_BATTERY_ERROR 0x08 #define IPR_RECLAIM_EXTENDED_INFO 0x10 #define IPR_RECLAIM_QUERY 0x20 #define IPR_RECLAIM_RESET 0x40 #define IPR_RECLAIM_FORCE_BATTERY_ERROR 0x60 #define IPR_RECLAIM_UNKNOWN_PERM 0x80 #define SET_SUPPORTED_DEVICES 0xFB #define IPR_STD_INQUIRY 0xFF #ifndef REPORT_LUNS #define REPORT_LUNS 0xA0 #endif #define IPR_XLATE_DEV_FMT_RC(rc) ((((rc) & 127) == 51) ? -EIO : 0) #define IPR_TYPE_AF_DISK 0xC #define IPR_TYPE_ADAPTER 0x1f #define IPR_TYPE_ARRAY 0x1f #define IPR_TYPE_EMPTY_SLOT 0xff #define IPR_ACTIVE_OPTIMIZED 0x0 #define IPR_ACTIVE_NON_OPTIMIZED 0x1 #define IPR_ACTIVE_STANDBY 0x2 #define IPR_CLEAR_ASYMMETRIC_STATE 0x0 #define IPR_PRESERVE_ASYMMETRIC_STATE 0x80 #define IPR_IOA_CACHING_DUAL_FAILURE_DISABLED 0x0 #define IPR_IOA_CACHING_DUAL_FAILURE_ENABLED 0x1 #define IPR_IOA_REQUESTED_CACHING_DEFAULT 0x0 #define IPR_IOA_REQUESTED_CACHING_DISABLED 0x1 #define IPR_IOA_CACHING_DEFAULT_DUAL_ENABLED 0x2 #define IPR_IOA_CACHING_DISABLED_DUAL_ENABLED 0x3 #define IPR_IOA_VSET_CACHE_ENABLED 0x4 #define IPR_IOA_SET_CACHING_DEFAULT 0x0 #define IPR_IOA_SET_CACHING_DISABLED 0x10 #define IPR_IOA_SET_CACHING_DUAL_DISABLED 0x20 #define IPR_IOA_SET_CACHING_DUAL_ENABLED 0x30 #define IPR_IOA_SET_VSET_CACHE_ENABLED 0x40 #define IPR_IOA_SET_VSET_CACHE_DISABLED 0x50 #define PHYSICAL_LOCATION_LENGTH 1024 #define IPR_HDD 0x0 #define IPR_SSD 0x1 #define IPR_BLK_DEV_CLASS_4K 0x4 #define IPR_RI 0x1 #define IPR_ARRAY_VIRTUAL_BUS 0x1 #define IPR_VSET_VIRTUAL_BUS 0x2 #define IPR_IOAFP_VIRTUAL_BUS 0x3 #define IPR_SAS_STD_INQ_UCODE_ID 12 #define IPR_SAS_STD_INQ_VENDOR_UNIQ 40 #define IPR_SAS_STD_INQ_PLANT_MAN 4 #define IPR_SAS_STD_INQ_DATE_MAN 5 #define IPR_SAS_STD_INQ_FRU_COUNT 4 #define IPR_SAS_STD_INQ_FRU_FIELD_LEN 2 #define IPR_SAS_STD_INQ_FRU_PN 12 #define IPR_SAS_STD_INQ_ASM_EC_LVL 10 #define IPR_SAS_STD_INQ_ASM_PART_NUM 12 #define IPR_SAS_STD_INQ_FRU_ASM_EC 10 #define IPR_SAS_INQ_BYTES_WARRANTY_LEN 3 /* Device write cache policies. */ enum {IPR_DEV_CACHE_WRITE_THROUGH = 0, IPR_DEV_CACHE_WRITE_BACK}; /* System P Operating modes */ enum system_p_mode {POWER_VM, POWER_KVM, POWER_BAREMETAL} ; #define IPR_IS_DASD_DEVICE(std_inq_data) \ ((((std_inq_data).peri_dev_type) == TYPE_DISK) && !((std_inq_data).removeable_medium)) #define IPR_SET_MODE(change_mask, cur_val, new_val) \ { \ int mod_bits = (cur_val ^ new_val); \ if ((change_mask & mod_bits) == mod_bits) \ { \ cur_val = new_val; \ } \ } #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) #define IPR_RECORD_ID_SUPPORTED_ARRAYS __constant_be16_to_cpu((u16)0) #define IPR_RECORD_ID_COMP_RECORD __constant_be16_to_cpu((u16)3) #define IPR_RECORD_ID_ARRAY_RECORD __constant_be16_to_cpu((u16)4) #define IPR_RECORD_ID_DEVICE_RECORD __constant_be16_to_cpu((u16)5) #define IPR_RECORD_ID_ARRAY_RECORD_3 __constant_be16_to_cpu((u16)6) #define IPR_RECORD_ID_VSET_RECORD_3 __constant_be16_to_cpu((u16)7) #define IPR_RECORD_ID_DEVICE_RECORD_3 __constant_be16_to_cpu((u16)8) extern struct ipr_array_query_data *ipr_array_query_data; extern int num_ioas; extern struct ipr_ioa *ipr_ioa_head; extern struct ipr_ioa *ipr_ioa_tail; extern int runtime; extern void (*exit_func) (void); extern int daemonize; extern int ipr_debug; extern int ipr_force; extern int ipr_sg_required; extern int polling_mode; extern int ipr_fast; extern int format_done; extern char *tool_name; extern struct sysfs_dev *head_zdev; extern struct sysfs_dev *tail_zdev; extern enum system_p_mode power_cur_mode; extern int tool_init_retry; struct sysfs_dev { u64 device_id; char ioa_pci_addr[16]; struct sysfs_dev *next, *prev; }; struct ipr_phy { #if defined (__BIG_ENDIAN_BITFIELD) u8 box:3; u8 phy:5; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 phy:5; u8 box:3; #endif }; struct ipr_phy_2bit_hop { #if defined (__BIG_ENDIAN_BITFIELD) u8 box:2; u8 phy:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 phy:6; u8 box:2; #endif }; struct ipr_res_addr { u8 host; u8 bus; union { u8 target; struct ipr_phy phy; struct ipr_phy_2bit_hop phy_2bit_hop; }; u8 lun; #define IPR_GET_PHYSICAL_LOCATOR(res_addr) \ (((res_addr)->bus << 16) | ((res_addr)->target << 8) | (res_addr)->lun) }; struct ipr_res_path { u8 res_path_bytes[8]; }; struct ipr_std_inq_vpids { u8 vendor_id[IPR_VENDOR_ID_LEN]; /* Vendor ID */ u8 product_id[IPR_PROD_ID_LEN]; /* Product ID */ }; struct ipr_common_record { u16 record_id; u16 record_len; }; struct ipr_vset_res_state { u16 stripe_size; u8 prot_level; u8 num_devices_in_vset; u32 reserved6; u32 ilid; u32 failing_dev_ioasc; struct ipr_res_addr failing_dev_res_addr; u32 failing_dev_res_handle; u8 prot_level_str[8]; }; struct ipr_dasd_res_state { u32 data_path_width; /* bits */ u32 data_xfer_rate; /* 100 KBytes/second */ u32 ilid; u32 failing_dev_ioasc; struct ipr_res_addr failing_dev_res_addr; u32 failing_dev_res_handle; }; struct ipr_gscsi_res_state { u32 data_path_width; /* bits */ u32 data_xfer_rate; /* 100 KBytes/second */ }; struct ipr_supported_device { u16 data_length; u8 reserved; u8 num_records; struct ipr_std_inq_vpids vpids; u8 reserved2[16]; }; struct ipr_mode_page_hdr { #if defined (__BIG_ENDIAN_BITFIELD) u8 parms_saveable:1; u8 reserved1:1; u8 page_code:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 page_code:6; u8 reserved1:1; u8 parms_saveable:1; #endif u8 page_length; }; struct ipr_vendor_mode_page { /* Mode page 0x00 */ struct ipr_mode_page_hdr hdr; #if defined (__BIG_ENDIAN_BITFIELD) u8 qpe:1; u8 uqe:1; u8 dwd:1; u8 reserved1:4; u8 arhes:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 arhes:1; u8 reserved1:4; u8 dwd:1; u8 uqe:1; u8 qpe:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 asdpe:1; u8 reserved2:1; u8 cmdac:1; u8 rpfae:1; u8 dotf:1; u8 reserved3:1; u8 rrnde:1; u8 cpe:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 cpe:1; u8 rrnde:1; u8 reserved3:1; u8 dotf:1; u8 rpfae:1; u8 cmdac:1; u8 reserved2:1; u8 asdpe:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved4:6; u8 dwlro:1; u8 dlro:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 dlro:1; u8 dwlro:1; u8 reserved4:6; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved5:2; u8 dsn:1; u8 frdd:1; u8 dpsdp:1; u8 wpen:1; u8 caen:1; u8 ovple:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 ovple:1; u8 caen:1; u8 wpen:1; u8 dpsdp:1; u8 frdd:1; u8 dsn:1; u8 reserved5:2; #endif u8 reserved7[2]; #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved8:1; u8 adc:1; u8 qemc:1; u8 drd:1; u8 led_mode:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 led_mode:4; u8 drd:1; u8 qemc:1; u8 adc:1; u8 reserved8:1; #endif u8 temp_threshold; u8 cmd_aging_limit_hi; u8 cmd_aging_limit_lo; u8 qpe_read_threshold; u8 reserved10; #if defined (__BIG_ENDIAN_BITFIELD) u8 drrt:1; u8 dnr:1; u8 reserved11:1; u8 rarr:1; u8 ffmt:1; u8 reserved12:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved12:3; u8 ffmt:1; u8 rarr:1; u8 reserved11:1; u8 dnr:1; u8 drrt:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 rtp:1; u8 rrc:1; u8 fcert:1; u8 reserved13:1; u8 drpdv:1; u8 dsf:1; u8 irt:1; u8 ivr:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 ivr:1; u8 irt:1; u8 dsf:1; u8 drpdv:1; u8 reserved13:1; u8 fcert:1; u8 rrc:1; u8 rtp:1; #endif }; struct ipr_caching_parameters_page { /* Mode page 0x08 */ struct ipr_mode_page_hdr hdr; #if defined (__BIG_ENDIAN_BITFIELD) u8 ic:1; u8 abpf:1; u8 cap:1; u8 disc:1; u8 size:1; u8 wce:1; u8 mf:1; u8 rcd:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 rcd:1; u8 mf:1; u8 wce:1; u8 size:1; u8 disc:1; u8 cap:1; u8 abpf:1; u8 ic:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 demand_read_retention_priority:4; u8 write_retention_priority:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 write_retention_priority:4; u8 demand_read_retention_priority:4; #endif u16 disable_prefetch_transfer_length; u16 minimum_prefetch; u16 maximum_prefetch; u16 maximum_prefetch_ceiling; #if defined (__BIG_ENDIAN_BITFIELD) u8 fsw:1; u8 lbcss:1; u8 dra:1; u8 reserved:5; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved:5; u8 dra:1; u8 lbcss:1; u8 fsw:1; #endif u8 cache_segments; u16 cache_segment_size; u8 reserved1; u8 non_cache_segment_size[3]; }; struct ipr_control_mode_page { /* Mode page 0x0A */ struct ipr_mode_page_hdr hdr; #if defined (__BIG_ENDIAN_BITFIELD) u8 tst:3; u8 reserved1:3; u8 gltsd:1; u8 rlec:1; u8 queue_algorithm_modifier:4; u8 reserved2:1; u8 qerr:2; u8 dque:1; u8 reserved3:1; u8 rac:1; u8 reserved4:2; u8 swp:1; u8 raerp:1; u8 uaaerp:1; u8 eaerp:1; u8 ato:1; u8 tas:1; u8 reserved5:3; u8 autoload_mode:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 rlec:1; u8 gltsd:1; u8 reserved1:3; u8 tst:3; u8 dque:1; u8 qerr:2; u8 reserved2:1; u8 queue_algorithm_modifier:4; u8 eaerp:1; u8 uaaerp:1; u8 raerp:1; u8 swp:1; u8 reserved4:2; u8 rac:1; u8 reserved3:1; u8 autoload_mode:3; u8 reserved5:3; u8 tas:1; u8 ato:1; #endif u16 ready_aen_holdoff_period; u16 busy_timeout_period; u16 reserved6; }; struct ipr_rw_err_mode_page { /* Page code 0x01 */ struct ipr_mode_page_hdr hdr; #if defined (__BIG_ENDIAN_BITFIELD) u8 awre:1; u8 arre:1; u8 tb:1; u8 rc:1; u8 eer:1; u8 per:1; u8 dte:1; u8 dcr:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 dcr:1; u8 dte:1; u8 per:1; u8 eer:1; u8 rc:1; u8 tb:1; u8 arre:1; u8 awre:1; #endif u8 read_retry_count; u8 correction_span; u8 head_offset_count; u8 data_strobe_offset_count; u8 reserved1; u8 write_retry_count; u8 reserved2; u16 recovery_time_limit; }; struct ipr_reclaim_query_data { u8 action_status; #define IPR_ACTION_SUCCESSFUL 0 #define IPR_ACTION_NOT_REQUIRED 1 #define IPR_ACTION_NOT_PERFORMED 2 #if defined (__BIG_ENDIAN_BITFIELD) u8 reclaim_known_needed:1; u8 reclaim_unknown_needed:1; u8 reserved2:2; u8 reclaim_known_performed:1; u8 reclaim_unknown_performed:1; u8 reserved3:1; u8 num_blocks_needs_multiplier:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 num_blocks_needs_multiplier:1; u8 reserved3:1; u8 reclaim_unknown_performed:1; u8 reclaim_known_performed:1; u8 reserved2:2; u8 reclaim_unknown_needed:1; u8 reclaim_known_needed:1; #endif u16 num_blocks; u8 rechargeable_battery_type; #define IPR_BATTERY_TYPE_NO_BATTERY 0 #define IPR_BATTERY_TYPE_NICD 1 #define IPR_BATTERY_TYPE_NIMH 2 #define IPR_BATTERY_TYPE_LIION 3 u8 rechargeable_battery_error_state; #define IPR_BATTERY_NO_ERROR_STATE 0 #define IPR_BATTERY_WARNING_STATE 1 #define IPR_BATTERY_ERROR_STATE 2 #if defined (__BIG_ENDIAN_BITFIELD) u8 conc_maint_battery:1; u8 battery_replace_allowed:1; u8 reserved4:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved4:6; u8 battery_replace_allowed:1; u8 conc_maint_battery:1; #endif u8 reserved5; u16 raw_power_on_time; u16 adjusted_power_on_time; u16 estimated_time_to_battery_warning; u16 estimated_time_to_battery_failure; u8 reserved6[240]; }; struct ipr_sdt_entry { u32 bar_str_offset; u32 end_offset; u8 entry_byte; u8 reserved[3]; #if defined (__BIG_ENDIAN_BITFIELD) u8 endian:1; u8 reserved1:1; u8 valid_entry:1; u8 reserved2:5; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:5; u8 valid_entry:1; u8 reserved1:1; u8 endian:1; #endif u8 resv; u16 priority; }; struct ipr_query_res_state { #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved1:1; u8 not_oper:1; u8 not_ready:1; u8 not_func:1; u8 reserved2:4; u8 read_write_prot:1; u8 reserved3:7; u8 prot_dev_failed:1; u8 prot_suspended:1; u8 prot_resuming:1; u8 degraded_oper:1; u8 service_req:1; u8 reserved4:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:4; u8 not_func:1; u8 not_ready:1; u8 not_oper:1; u8 reserved1:1; u8 reserved3:7; u8 read_write_prot:1; u8 reserved4:3; u8 service_req:1; u8 degraded_oper:1; u8 prot_resuming:1; u8 prot_suspended:1; u8 prot_dev_failed:1; #endif u8 reserved5; union { struct ipr_vset_res_state vset; struct ipr_dasd_res_state dasd; struct ipr_gscsi_res_state gscsi; }; }; struct ipr_query_io_port { u32 length; #define IOA_DEV_PORT_ACTIVE 0x0 #define IOA_DEV_PORT_SUSPEND 0x1 #define IOA_DEV_PORT_PARTIAL_SUSPEND 0x2 #define IOA_DEV_PORT_UNKNOWN 0xFF u8 port_state; u8 reserved1; u8 reserved2; u8 reserved3; }; struct ipr_res_addr_aliases { u32 length; struct ipr_res_addr res_addr[10]; }; #define for_each_ra_alias(ra, aliases) \ for (ra = (aliases)->res_addr; \ ra < ((aliases)->res_addr + (ntohl((aliases)->length) / sizeof(struct ipr_res_addr))) && \ ra < ((aliases)->res_addr + ARRAY_SIZE((aliases)->res_addr)); \ ra++) struct ipr_res_path_aliases { u32 length; u32 reserved1; struct ipr_res_path res_path[10]; }; #define for_each_rp_alias(rp, aliases) \ for (rp = (aliases)->res_path; \ rp < ((aliases)->res_path + ((ntohl((aliases)->length)- 4) / sizeof(struct ipr_res_path))) && \ rp < ((aliases)->res_path + ARRAY_SIZE((aliases)->res_path)); \ rp++) struct ipr_array_cap_entry { u8 prot_level; #define IPR_DEFAULT_RAID_LVL "5" #if defined (__BIG_ENDIAN_BITFIELD) u8 include_allowed:1; u8 reserved:5; u8 format_overlay_type:2; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 format_overlay_type:2; u8 reserved:5; u8 include_allowed:1; #endif #define IPR_FORMAT_ADD_DEVICES 1 #define IPR_FORMAT_REMOVE_DEVICES 2 u16 reserved2; u8 reserved3; u8 max_num_array_devices; u8 min_num_array_devices; u8 min_mult_array_devices; u8 min_num_per_tier; u8 reserved4; u16 supported_stripe_sizes; u16 reserved5; u16 recommended_stripe_size; u8 prot_level_str[8]; }; #define for_each_cap_entry(cap, supp) \ for (cap = (supp)->entry; \ (unsigned long)cap < ((unsigned long)((supp)->entry) + (ntohs((supp)->num_entries) * ntohs((supp)->entry_length))); \ cap = (struct ipr_array_cap_entry *)((unsigned long)cap + ntohs((supp)->entry_length))) struct ipr_array_record { struct ipr_common_record common; #if defined (__BIG_ENDIAN_BITFIELD) u8 issue_cmd:1; u8 known_zeroed:1; u8 reserved1:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved1:6; u8 known_zeroed:1; u8 issue_cmd:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 saved_asym_access_state:4; u8 current_asym_access_state:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 current_asym_access_state:4; u8 saved_asym_access_state:4; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 established:1; u8 exposed:1; u8 non_func:1; u8 high_avail:1; u8 no_config_entry:1; u8 reserved3:3; u8 start_cand:1; u8 stop_cand:1; u8 resync_cand:1; u8 migrate_cand:1; u8 asym_access_cand:1; u8 reserved4:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved3:3; u8 no_config_entry:1; u8 high_avail:1; u8 non_func:1; u8 exposed:1; u8 established:1; u8 reserved4:3; u8 asym_access_cand:1; u8 migrate_cand:1; u8 resync_cand:1; u8 stop_cand:1; u8 start_cand:1; #endif union { struct { u16 stripe_size; u8 raid_level; u8 array_id; u32 resource_handle; struct ipr_res_addr resource_addr; struct ipr_res_addr last_resource_addr; u8 vendor_id[IPR_VENDOR_ID_LEN]; u8 product_id[IPR_PROD_ID_LEN]; u8 serial_number[8]; #if defined (__BIG_ENDIAN_BITFIELD) u8 block_dev_class:3; u8 reserved51:1; u8 read_intensive:1; u8 reserved5:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved5:3; u8 read_intensive:1; u8 reserved51:1; u8 block_dev_class:3; #endif u8 reserved6; u8 reserved7; u8 reserved8; }__attribute__((packed, aligned (4))) type2; struct { u8 reserved5; u8 raid_level; u16 stripe_size; u8 reserved6[4]; u8 reserved7[16]; u8 last_func_res_path[8]; u8 reserved8[2]; u8 array_id; #if defined (__BIG_ENDIAN_BITFIELD) u8 block_dev_class:3; u8 reserved91:1; u8 read_intensive:1; u8 reserved9:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved9:3; u8 read_intensive:1; u8 reserved91:1; u8 block_dev_class:3; #endif u32 resource_handle; u8 dev_id[8]; u8 lun[8]; u8 wwn[16]; u8 res_path[8]; u8 vendor_id[IPR_VENDOR_ID_LEN]; u8 product_id[IPR_PROD_ID_LEN]; u8 serial_number[IPR_SERIAL_NUM_LEN]; u8 desc[IPR_DESCRIPTION_LEN]; u8 total_arr_size[8]; u8 total_size_inuse[8]; u8 max_size_to_use[8]; u8 total_size_enc[8]; u8 total_inuse_enc[8]; u8 max_size_enc[8]; }__attribute__((packed, aligned (4))) type3; }; }__attribute__((packed, aligned (4))); struct ipr_dev_record { struct ipr_common_record common; #if defined (__BIG_ENDIAN_BITFIELD) u8 issue_cmd:1; u8 known_zeroed:1; u8 reserved:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved:6; u8 known_zeroed:1; u8 issue_cmd:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 saved_asym_access_state:4; u8 current_asym_access_state:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 current_asym_access_state:4; u8 saved_asym_access_state:4; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 array_member:1; u8 has_parity:1; u8 is_exposed_device:1; u8 is_hot_spare:1; u8 no_cfgte_vol:1; u8 no_cfgte_dev:1; u8 reserved2:2; u8 start_cand:1; u8 parity_cand:1; u8 stop_cand:1; u8 resync_cand:1; u8 include_cand:1; u8 exclude_cand:1; u8 rebuild_cand:1; u8 zero_cand:1; u8 add_hot_spare_cand:1; u8 rmv_hot_spare_cand:1; u8 migrate_array_prot_cand:1; u8 reserved3:5; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:2; u8 no_cfgte_dev:1; u8 no_cfgte_vol:1; u8 is_hot_spare:1; u8 is_exposed_device:1; u8 has_parity:1; u8 array_member:1; u8 zero_cand:1; u8 rebuild_cand:1; u8 exclude_cand:1; u8 include_cand:1; u8 resync_cand:1; u8 stop_cand:1; u8 parity_cand:1; u8 start_cand:1; u8 reserved3:5; u8 migrate_array_prot_cand:1; u8 rmv_hot_spare_cand:1; u8 add_hot_spare_cand:1; #endif union { struct { u8 reserved4[2]; u8 array_id; u32 resource_handle; struct ipr_res_addr resource_addr; struct ipr_res_addr last_resource_addr; u8 vendor_id[IPR_VENDOR_ID_LEN]; u8 product_id[IPR_PROD_ID_LEN]; u8 serial_number[IPR_SERIAL_NUM_LEN]; #if defined (__BIG_ENDIAN_BITFIELD) u8 block_dev_class:3; u8 reserved51:1; u8 read_intensive:1; u8 reserved5:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved5:3; u8 read_intensive:1; u8 reserved51:1; u8 block_dev_class:3; #endif u8 reserved6; u8 reserved7; u8 reserved8; }__attribute__((packed, aligned (4))) type2; struct { u8 reserved4[3]; u8 reserved5[4]; u8 reserved6[16]; u8 last_func_res_path[8]; u8 reserved7[2]; u8 array_id; #if defined (__BIG_ENDIAN_BITFIELD) u8 block_dev_class:3; u8 reserved81:1; u8 read_intensive:1; u8 reserved8:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved8:3; u8 read_intensive:1; u8 reserved81:1; u8 block_dev_class:3; #endif u32 resource_handle; u8 dev_id[8]; u8 lun[8]; u8 wwn[16]; u8 res_path[8]; u8 vendor_id[IPR_VENDOR_ID_LEN]; u8 product_id[IPR_PROD_ID_LEN]; u8 serial_number[IPR_SERIAL_NUM_LEN]; u8 desc[IPR_DESCRIPTION_LEN]; u8 reserved9[8]; u8 reserved10[2]; u8 reserved11[6]; u8 reserved12[8]; }__attribute__((packed, aligned (4))) type3; }; }__attribute__((packed, aligned (4))); #define __for_each_qac_entry(rcd, qac, type) \ if ((qac)->num_records) \ for (rcd = (type *)(qac)->data; \ ((unsigned long)rcd) < ((unsigned long)((qac)->u.buf + (qac)->resp_len)) && \ ((unsigned long)rcd) < ((unsigned long)((qac)->u.buf + IPR_QAC_BUFFER_SIZE)); \ rcd = (type *)((unsigned long)rcd + ntohs(((struct ipr_common_record *)rcd)->record_len))) #define for_each_supported_arrays_rcd(rcd, qac) \ __for_each_qac_entry(rcd, qac, struct ipr_supported_arrays) \ if (rcd->common.record_id == IPR_RECORD_ID_SUPPORTED_ARRAYS) #define for_each_qac_entry(rcd, qac) \ __for_each_qac_entry(rcd, qac, struct ipr_common_record) #define for_each_dev_rcd(rcd, qac) \ __for_each_qac_entry(rcd, qac, struct ipr_dev_record) \ if (ipr_is_device_record(rcd->common.record_id)) #define for_each_array_rcd(rcd, qac) \ __for_each_qac_entry(rcd, qac, struct ipr_array_record) \ if (ipr_is_array_record(rcd->common.record_id)) struct ipr_std_inq_data { #if defined (__BIG_ENDIAN_BITFIELD) u8 peri_qual:3; u8 peri_dev_type:5; u8 removeable_medium:1; u8 reserved1:7; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 peri_dev_type:5; u8 peri_qual:3; u8 reserved1:7; u8 removeable_medium:1; #endif u8 version; #if defined (__BIG_ENDIAN_BITFIELD) u8 aen:1; u8 obsolete1:1; u8 norm_aca:1; u8 hi_sup:1; u8 resp_data_fmt:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 resp_data_fmt:4; u8 hi_sup:1; u8 norm_aca:1; u8 obsolete1:1; u8 aen:1; #endif u8 additional_len; #if defined (__BIG_ENDIAN_BITFIELD) u8 sccs:1; u8 reserved2:7; u8 bque:1; u8 enc_serv:1; u8 vs:1; u8 multi_port:1; u8 mchngr:1; u8 obsolete2:2; u8 addr16:1; u8 rel_adr:1; u8 obsolete3:1; u8 wbus16:1; u8 sync:1; u8 linked:1; u8 trans_dis:1; u8 cmd_que:1; u8 vs2:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:7; u8 sccs:1; u8 addr16:1; u8 obsolete2:2; u8 mchngr:1; u8 multi_port:1; u8 vs:1; u8 enc_serv:1; u8 bque:1; u8 vs2:1; u8 cmd_que:1; u8 trans_dis:1; u8 linked:1; u8 sync:1; u8 wbus16:1; u8 obsolete3:1; u8 rel_adr:1; #endif struct ipr_std_inq_vpids vpids; u8 ros_rsvd_ram_rsvd[4]; u8 serial_num[IPR_SERIAL_NUM_LEN]; }; struct ipr_std_inq_data_long { struct ipr_std_inq_data std_inq_data; u8 z1_term[IPR_STD_INQ_Z1_TERM_LEN]; #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved:4; u8 clocking:2; u8 qas:1; u8 ius:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 ius:1; u8 qas:1; u8 clocking:2; u8 reserved:4; #endif u8 reserved1[41]; u8 z2_term[IPR_STD_INQ_Z2_TERM_LEN]; u8 z3_term[IPR_STD_INQ_Z3_TERM_LEN]; u8 as400_service_level; u8 z4_term[IPR_STD_INQ_Z4_TERM_LEN]; u8 z5_term[IPR_STD_INQ_Z5_TERM_LEN]; u8 fru_number[IPR_STD_INQ_FRU_NUM_LEN]; u8 ec_level[IPR_STD_INQ_EC_LEVEL_LEN]; u8 part_number[IPR_STD_INQ_PART_NUM_LEN]; u8 z6_term[IPR_STD_INQ_Z6_TERM_LEN]; }; struct ipr_sas_std_inq_data { struct ipr_std_inq_data std_inq_data; u8 microcode_id[IPR_SAS_STD_INQ_UCODE_ID]; u8 reserved1; u8 vendor_unique[IPR_SAS_STD_INQ_VENDOR_UNIQ]; #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved2:5; u8 is_ssd:1; u8 near_line:1; u8 unlock:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 unlock:1; u8 near_line:1; u8 is_ssd:1; u8 reserved2:5; #endif u8 plant_manufacture[IPR_SAS_STD_INQ_PLANT_MAN]; u8 date_manufacture[IPR_SAS_STD_INQ_DATE_MAN]; u8 vendor_unique_pn; u8 fru_count[IPR_SAS_STD_INQ_FRU_COUNT]; u8 fru_field_len[IPR_SAS_STD_INQ_FRU_FIELD_LEN]; u8 fru_pn[IPR_SAS_STD_INQ_FRU_PN]; u8 asm_ec_level[IPR_SAS_STD_INQ_ASM_EC_LVL]; u8 asm_part_num[IPR_SAS_STD_INQ_ASM_PART_NUM]; u8 fru_asm_ec[IPR_SAS_STD_INQ_FRU_ASM_EC]; u8 reserved3[6]; }; struct ipr_mode_page_28_scsi_dev_bus_attr { struct ipr_res_addr res_addr; #if defined (__BIG_ENDIAN_BITFIELD) u8 qas_capability:2; u8 enable_target_mode:1; u8 term_power_absent:1; u8 target_mode_supported:1; u8 lvd_to_se_transition_not_allowed:1; u8 reserved2:2; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:2; u8 lvd_to_se_transition_not_allowed:1; u8 target_mode_supported:1; u8 term_power_absent:1; u8 enable_target_mode:1; u8 qas_capability:2; #endif #define IPR_MODEPAGE28_QAS_CAPABILITY_NO_CHANGE 0 #define IPR_MODEPAGE28_QAS_CAPABILITY_DISABLE_ALL 1 #define IPR_MODEPAGE28_QAS_CAPABILITY_ENABLE_ALL 2 /* NOTE: Due to current operation conditions QAS should never be enabled so the change mask will be set to 0 */ #define IPR_MODEPAGE28_QAS_CAPABILITY_CHANGE_MASK 0 u8 scsi_id; #define IPR_MODEPAGE28_SCSI_ID_NO_CHANGE 0x80u #define IPR_MODEPAGE28_SCSI_ID_NO_ID 0xFFu u8 bus_width; #define IPR_MODEPAGE28_BUS_WIDTH_NO_CHANGE 0 u8 extended_reset_delay; #define IPR_EXTENDED_RESET_DELAY 7 u32 max_xfer_rate; #define IPR_MODEPAGE28_MAX_XFR_RATE_NO_CHANGE 0 u8 min_time_delay; #define IPR_DEFAULT_SPINUP_DELAY 0xFFu #define IPR_INIT_SPINUP_DELAY 5 u8 reserved3; u16 reserved4; }; #define IPR_BUS_XFER_RATE_TO_THRUPUT(rate, width) \ (((rate) * ((width) / 8)) / 10) #define IPR_BUS_THRUPUT_TO_XFER_RATE(thruput, width) \ (((thruput) * 10) / ((width) / 8)) #define IPR_CONFIG_DIR "/etc/ipr/" #define IPR_CATEGORY_IOA "Adapter" #define IPR_GSCSI_HA_ONLY "JBOD_ONLY_HA" #define IPR_DUAL_ADAPTER_ACTIVE_ACTIVE "DUAL_ADAPTER_ACTIVE_ACTIVE" #define IPR_ARRAY_REBUILD_RATE "ARRAY_REBUILD_RATE" #define IPR_ARRAY_DISABLE_REBUILD_VERIFY "DISABLE_ARRAY_REBUILD_VERIFY" #define IPR_CATEGORY_BUS "Bus" #define IPR_QAS_CAPABILITY "QAS_CAPABILITY" #define IPR_HOST_SCSI_ID "HOST_SCSI_ID" #define IPR_BUS_WIDTH "BUS_WIDTH" #define IPR_MAX_XFER_RATE_STR "MAX_BUS_SPEED" #define IPR_MIN_TIME_DELAY "MIN_TIME_DELAY" /* Disk is the old format which is only here for backwards compatibility */ #define IPR_CATEGORY_DISK "Disk" /* Device is the new format which should be used for all new attributes */ #define IPR_CATEGORY_DEVICE "Device" #define IPR_QUEUE_DEPTH "QUEUE_DEPTH" #define IPR_TCQ_ENABLED "TCQ_ENABLED" #define IPR_FORMAT_TIMEOUT "FORMAT_UNIT_TIMEOUT" #define IPR_WRITE_CACHE_POLICY "WRITE_CACHE_POLICY" #define IPR_MAX_XFER_RATE 320 #define IPR_SAFE_XFER_RATE 160 #define IPR_JBOD_SYSFS_UNBIND 0 #define IPR_JBOD_SYSFS_BIND 1 /* Internal return codes */ #define RC_SUCCESS 0 #define RC_FAILED -1 #define RC_NOOP -2 #define RC_NOT_PERFORMED -3 #define RC_IN_USE -4 #define RC_CANCEL 12 #define RC_REFRESH 1 #define RC_EXIT 3 struct scsi_dev_data { int host; int channel; union { u8 id; struct ipr_phy phy; struct ipr_phy_2bit_hop phy_2bit_hop; }; int lun; int type; int opens; int qdepth; int busy; int online; u32 handle; char vendor_id[IPR_VENDOR_ID_LEN + 1]; char product_id[IPR_PROD_ID_LEN + 1]; char sysfs_device_name[PATH_MAX]; char dev_name[64]; char gen_name[64]; #define IPR_MAX_RES_PATH_LEN 24 char res_path[IPR_MAX_RES_PATH_LEN]; u64 device_id; }; struct ipr_path_entry { u8 state; #define IPR_PATH_FUNCTIONAL 0 #define IPR_PATH_NOT_FUNCTIONAL 1 u8 local_bus_num; u8 remote_bus_num; u8 reserved; u8 local_connection_id[8]; u8 remote_connection_id[8]; }; struct ipr_path_entries { u32 num_path_entries; struct ipr_path_entry path[0]; /* variable length */ }; struct ipr_dual_ioa_entry { u32 length; u8 link_state; #define IPR_IOA_LINK_STATE_NOT_OPER 0 #define IPR_IOA_LINK_STATE_OPER 1 u8 cur_state; #define IPR_IOA_STATE_NO_CHANGE 0 #define IPR_IOA_STATE_PRIMARY 2 #define IPR_IOA_STATE_SECONDARY 3 #define IPR_IOA_STATE_NO_PREFERENCE 4 u8 fmt; u8 multi_adapter_type; #define IPR_IOA_MA_TYPE_UNDEFINED 0 #define IPR_IOA_MA_TYPE_DUAL_IOA 1 #define IPR_IOA_MA_TYPE_AUX_CACHE 2 u8 reserved[2]; u16 add_len; union { struct { u8 remote_vendor_id[IPR_VENDOR_ID_LEN]; u8 remote_prod_id[IPR_PROD_ID_LEN]; u8 remote_sn[IPR_SERIAL_NUM_LEN]; } fmt0; struct { u8 remote_vendor_id[IPR_VENDOR_ID_LEN]; u8 remote_prod_id[IPR_PROD_ID_LEN]; u8 remote_sn[IPR_SERIAL_NUM_LEN]; u8 wwid[8]; } fmt1; }; }; struct ipr_phys_bus_entry { u8 bus_num; u8 reserved[3]; u8 conn_id[8]; }; struct ipr_ioa_cap_entry { u32 length; u8 reserved; u8 preferred_role; u8 token; u8 reserved2[4]; u8 num_bus_entries; struct ipr_phys_bus_entry bus[0]; }; struct ipr_multi_ioa_status { u32 length; u32 num_entries; struct ipr_ioa_cap_entry cap; u8 buf[16 * 1024]; /* * struct ipr_dual_ioa_entry ioa[0]; */ }; struct ipr_disk_attr { int queue_depth; int tcq_enabled; int format_timeout; int write_cache_policy; }; struct ipr_vset_attr { int queue_depth; }; struct ipr_ioa_attr { int preferred_primary; int gscsi_only_ha; int active_active; int caching; int rebuild_rate; int disable_rebuild_verify; int vset_write_cache; }; #define IPR_DEV_MAX_PATHS 2 struct ipr_dev { char dev_name[64]; char gen_name[64]; char prot_level_str[8]; u8 *vendor_id; u8 *product_id; u8 *serial_number; u8 array_id; u8 raid_level; u16 stripe_size; u32 resource_handle; u8 block_dev_class; u8 read_intensive; u32 is_reclaim_cand:1; u32 should_init:1; u32 init_not_allowed:1; u32 local_flag:1; u32 rescan:1; u8 active_suspend; u32 is_suspend_cand:1; u32 is_resume_cand:1; u8 supports_4k:1; u8 supports_5xx:1; u8 read_c7:1; u8 locked:1; int lock_fd; u32 format_timeout; struct scsi_dev_data *scsi_dev_data; struct ipr_dev *ses[IPR_DEV_MAX_PATHS]; struct ipr_res_addr res_addr[IPR_DEV_MAX_PATHS]; struct ipr_res_path res_path[IPR_DEV_MAX_PATHS]; char res_path_name[IPR_MAX_RES_PATH_LEN]; struct ipr_disk_attr attr; char physical_location[PHYSICAL_LOCATION_LENGTH]; union { struct ipr_common_record *qac_entry; struct ipr_dev_record *dev_rcd; struct ipr_array_record *array_rcd; }; struct ipr_dev *alt_path; struct ipr_ioa *ioa; }; #define for_each_ra(ra, dev) \ for(ra = (dev)->res_addr; \ (ra - ((dev)->res_addr)) < IPR_DEV_MAX_PATHS; ra++) #define for_each_rp(rp, dev) \ for(rp = (dev)->res_path; \ (rp - ((dev)->res_path)) < IPR_DEV_MAX_PATHS; rp++) enum ipr_tcq_mode { IPR_TCQ_DISABLE = 0, IPR_TCQ_FROZEN = 1, IPR_TCQ_NACA = 2 }; #define IPR_MAX_IOA_DEVICES (IPR_MAX_NUM_BUSES * 45 * 2 + 1) struct ipr_ioa { struct ipr_dev ioa; u16 ccin; u16 af_block_size; u32 host_addr; u32 num_raid_cmds; u32 msl; u16 num_devices; u8 ioa_dead:1; u8 nr_ioa_microcode:1; u8 scsi_id_changeable:1; u8 dual_raid_support:1; u8 is_secondary:1; u8 should_init:1; u8 is_aux_cache:1; u8 protect_last_bus:1; u8 gscsi_only_ha:1; u8 in_gscsi_only_ha:1; u8 asymmetric_access:1; u8 asymmetric_access_enabled:1; u8 has_cache:1; u8 sis64:1; u8 rebuild_rate:4; u8 disable_rebuild_verify:1; u8 configure_rebuild_verify:1; u8 has_vset_write_cache:1; u8 vset_write_cache:1; #define IPR_SIS32 0x00 #define IPR_SIS64 0x01 u8 support_4k:1; int can_queue; enum ipr_tcq_mode tcq_mode; u16 pci_vendor; u16 pci_device; u16 subsystem_vendor; u16 subsystem_device; u16 hop_count; #define IPR_NOHOP 0x00 #define IPR_2BIT_HOP 0x01 #define IPR_3BIT_HOP 0x02 char dual_state[16]; char preferred_dual_state[16]; int host_num; char pci_address[16]; char host_name[16]; char physical_location[1024]; u8 yl_serial_num[YL_SERIAL_NUM_LEN]; struct ipr_dev dev[IPR_MAX_IOA_DEVICES]; struct ipr_multi_ioa_status ioa_status; struct ipr_array_query_data *qac_data; struct ipr_array_record *start_array_qac_entry; struct ipr_supported_arrays *supported_arrays; struct ipr_reclaim_query_data *reclaim_data; struct ipr_ioa *next; struct ipr_ioa *cmd_next; }; #define __for_each_ioa(ioa, head) for (ioa = head; ioa; ioa = ioa->next) #define for_each_ioa(ioa) __for_each_ioa(ioa, ipr_ioa_head) #define for_each_primary_ioa(ioa) \ __for_each_ioa(ioa, ipr_ioa_head) \ if (!ioa->is_secondary) #define for_each_secondary_ioa(ioa) \ __for_each_ioa(ioa, ipr_ioa_head) \ if (ioa->is_secondary) #define for_each_sas_ioa(ioa) \ __for_each_ioa(ioa, ipr_ioa_head) \ if (!__ioa_is_spi(ioa)) #define for_each_dev(i, d) for (d = (i)->dev; (d - (i)->dev) < (i)->num_devices; d++) #define for_ioa_and_each_dev(i, d) for (d = &((i)->ioa); \ (d == &((i)->ioa)) || ((d - (i)->dev) < (i)->num_devices); \ d = (d == &((i)->ioa)) ? (i)->dev : d + 1) #define for_each_hotplug_dev(i, d) \ for_each_dev(i, d) \ if (ipr_is_af_dasd_device(d) || ipr_is_gscsi(d)) #define for_each_af_dasd(i, d) \ for_each_dev(i, d) \ if (ipr_is_af_dasd_device(d)) #define for_each_dev_in_vset(v, d) \ for_each_af_dasd((v)->ioa, d) \ if (ipr_is_array_member(d) && d->array_id == (v)->array_id) #define for_each_vset(i, d) \ for_each_dev(i, d) \ if (ipr_is_volume_set(d) && !d->array_rcd->start_cand) #define for_each_array(i, d) \ for_each_dev(i, d) \ if (ipr_is_array(d) && !d->array_rcd->start_cand) #define for_each_dvd_tape(i, d) \ for_each_dev(i, d) \ if (d->scsi_dev_data && (d->scsi_dev_data->type == TYPE_ROM || \ d->scsi_dev_data->type == TYPE_TAPE)) #define for_each_ses(i, d) \ for_each_dev(i, d) \ if (d->scsi_dev_data && d->scsi_dev_data->type == TYPE_ENCLOSURE) #define for_each_hot_spare(i, d) \ for_each_dev(i, d) \ if (ipr_is_hot_spare(d)) #define for_each_disk(i, d) \ for_each_dev(i, d) \ if ((d)->scsi_dev_data && (ipr_is_af_dasd_device(d) || ipr_is_gscsi(d))) #define __for_each_disk(i, d) \ for_each_dev(i, d) \ if ((d)->scsi_dev_data && ((d)->scsi_dev_data->type == TYPE_DISK || \ (d)->scsi_dev_data->type == IPR_TYPE_AF_DISK)) #define for_each_standalone_disk(i, d) \ for_each_disk(i, d) \ if (!ipr_is_hot_spare(d) && !ipr_is_array_member(d)) #define __for_each_standalone_disk(i, d) \ __for_each_disk(i, d) \ if (!ipr_is_hot_spare(d) && !ipr_is_volume_set(d) && \ !ipr_is_array_member(d)) #define for_each_standalone_af_disk(i, d) \ for_each_standalone_disk(i, d) \ if (ipr_is_af_dasd_device(d)) #define for_each_jbod_disk(i, d) \ for_each_disk(i, d) \ if (ipr_is_gscsi(d)) struct ipr_dasd_inquiry_page3 { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_len; u8 reserved2[3]; u8 load_id[4]; u8 release_level[4]; u8 ptf_number[4]; u8 patch_number[4]; }; struct ipr_array_query32_data { u16 resp_len; u8 reserved; u8 num_records; u8 data[0]; }; struct ipr_array_query64_data { u32 resp_len; u32 num_records; u8 data[0]; }; struct ipr_array_query_data { u32 resp_len; u32 num_records; u32 hdr_len; u8 *data; union { u8 buf[IPR_QAC_BUFFER_SIZE]; struct ipr_array_query32_data buf32; struct ipr_array_query64_data buf64; } u; }; struct ipr_block_desc { u8 num_blocks[4]; u8 density_code; u8 block_length[3]; }; struct ipr_mode_parm_hdr { u8 length; u8 medium_type; u8 device_spec_parms; u8 block_desc_len; }; struct ipr_mode_pages { struct ipr_mode_parm_hdr hdr; u8 data[255 - sizeof(struct ipr_mode_parm_hdr)]; }; struct sense_data_t { u8 error_code; u8 segment_numb; u8 sense_key; u8 info[4]; u8 add_sense_len; u8 cmd_spec_info[4]; u8 add_sense_code; u8 add_sense_code_qual; u8 field_rep_unit_code; u8 sense_key_spec[3]; u8 add_sense_bytes[0]; }; struct ipr_ioa_mode_page { struct ipr_mode_page_hdr hdr; u8 reserved; u8 max_tcq_depth; #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved1:1; u8 format_completed:1; u8 reserved2:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:6; u8 format_completed:1; u8 reserved1:1; #endif }; struct ipr_mode_page24 { struct ipr_mode_page_hdr hdr; #if defined (__BIG_ENDIAN_BITFIELD) u8 dual_adapter_af:2; u8 reserved:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved:6; u8 dual_adapter_af:2; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 rebuild_without_verify:1; u8 reserved1:3; u8 rebuild_rate:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 rebuild_rate:4; u8 reserved1:3; u8 rebuild_without_verify:1; #endif #define MIN_ARRAY_REBUILD_RATE 0x02 #define DISABLE_DUAL_IOA_AF 0x00 #define ENABLE_DUAL_IOA_AF 0x02 #define ENABLE_DUAL_IOA_ACTIVE_ACTIVE 0x03 }; struct ipr_config_term_hdr { u8 term_id; u8 len; }; struct ipr_subsys_config_term { struct ipr_config_term_hdr hdr; #define IPR_SUBSYS_CONFIG_TERM_ID 0x02 u8 config; #define IPR_AFDASD_SUBSYS 0x00 #define IPR_GSCSI_ONLY_HA_SUBSYS 0x01 u8 reserved; }; struct ipr_mode_page25 { struct ipr_mode_page_hdr hdr; u8 reserved[2]; struct ipr_config_term_hdr term; u8 data[256]; }; #define for_each_page25_term(hdr, page) \ for (hdr = &(page)->term; \ (char *)hdr < ((char *)(page) + (page)->hdr.page_length + sizeof((page)->hdr)); \ hdr = (struct ipr_config_term_hdr *)((char *)hdr + (hdr)->len + sizeof(*hdr))) struct ipr_mode_page_28_header { struct ipr_mode_page_hdr header; u8 num_dev_entries; u8 dev_entry_length; }; struct ipr_mode_page_28 { struct ipr_mode_page_28_header page_hdr; struct ipr_mode_page_28_scsi_dev_bus_attr attr[0]; }; #define for_each_bus_attr(ptr, page28, i) \ for (i = 0, ptr = page28->attr; i < page_28->page_hdr.num_dev_entries; \ i++, ptr = (struct ipr_mode_page_28_scsi_dev_bus_attr *) \ ((u8 *)ptr + page_28->page_hdr.dev_entry_length)) struct ipr_scsi_bus_attr { u32 max_xfer_rate; u8 qas_capability; u8 scsi_id; u8 bus_width; u8 extended_reset_delay; u8 min_time_delay; }; struct ipr_scsi_buses { int num_buses; struct ipr_scsi_bus_attr bus[IPR_MAX_NUM_BUSES]; }; struct ipr_dasd_timeout_record { u8 op_code; u8 reserved; u16 timeout; }; struct ipr_query_dasd_timeouts { u32 length; struct ipr_dasd_timeout_record record[100]; }; struct ipr_supported_arrays { struct ipr_common_record common; u16 num_entries; u16 entry_length; struct ipr_array_cap_entry entry[0]; }; struct ipr_read_cap { u32 max_user_lba; u32 block_length; }; struct ipr_read_cap16 { u32 max_user_lba_hi; u32 max_user_lba_lo; u32 block_length; }; /* Struct for disks that are unsupported or require a minimum microcode level prior to formatting to 522-byte sectors. */ struct unsupported_af_dasd { char vendor_id[IPR_VENDOR_ID_LEN + 1]; char compare_vendor_id_byte[IPR_VENDOR_ID_LEN]; char product_id[IPR_PROD_ID_LEN + 1]; char compare_product_id_byte[IPR_PROD_ID_LEN]; char lid[5]; /* Load ID - Bytes 8-11 of Inquiry Page 3 */ char lid_mask[4]; /* Mask for certain bytes of the LID */ uint supported_with_min_ucode_level; char min_ucode_level[5]; char min_ucode_mask[4]; /* used to mask don't cares in the ucode level */ }; struct unsupported_dasd { char vendor_id[IPR_VENDOR_ID_LEN + 1]; char compare_vendor_id_byte[IPR_VENDOR_ID_LEN]; char product_id[IPR_PROD_ID_LEN + 1]; char compare_product_id_byte[IPR_PROD_ID_LEN]; }; struct ipr_cmd_status_record { u16 reserved1; u16 length; u8 array_id; u8 command_code; u8 status; #define IPR_CMD_STATUS_SUCCESSFUL 0 #define IPR_CMD_STATUS_IN_PROGRESS 2 #define IPR_CMD_STATUS_ATTRIB_CHANGE 3 #define IPR_CMD_STATUS_FAILED 4 #define IPR_CMD_STATUS_INSUFF_DATA_MOVED 5 #define IPR_CMD_STATUS_MIXED_BLK_DEV_CLASESS 6 #define IPR_CMD_STATUS_MIXED_LOG_BLK_SIZE 7 #define IPR_CMD_STATUS_UNSUPT_REQ_BLK_DEV_CLASS 8 u8 percent_complete; struct ipr_res_addr failing_dev_res_addr; u32 failing_dev_res_handle; u32 failing_dev_ioasc; u32 ilid; u32 resource_handle; u8 vset_id; u8 flags; u16 reserved; u8 failing_dev_res_path[8]; }; struct ipr_cmd_status { u16 resp_len; u16 num_records; struct ipr_cmd_status_record record[250]; }; #define for_each_cmd_status(r, s) for (r = (s)->record; (unsigned long)(r) < ((unsigned long)((s)->record) + ntohs((s)->resp_len) - 4); r = (void *)(r) + ntohs((r)->length)) struct ipr_inquiry_page0 { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 supported_page_codes[IPR_MAX_NUM_SUPP_INQ_PAGES]; }; struct ipr_inquiry_page3 { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_len; u8 reserved2[3]; u8 load_id[4]; u8 major_release; u8 card_type; u8 minor_release[2]; u8 ptf_number[4]; u8 patch_number[4]; }; struct ipr_inquiry_ioa_cap { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_len; u8 reserved2; u8 sis_version[2]; #if defined (__BIG_ENDIAN_BITFIELD) u8 dual_ioa_raid:1; u8 dual_ioa_wcache:1; u8 dual_ioa_asymmetric_access:1; u8 reserved:2; u8 disable_array_rebuild_verify:1; u8 reserved7:2; u8 can_attach_to_aux_cache:1; u8 is_aux_cache:1; u8 is_dual_wide:1; u8 gscsi_only_ha:1; u8 reserved3:4; u8 reserved4:1; u8 af_4k_support:1; u8 reserved5:6; u8 reserved6:3; u8 ra_id_encoding:3; u8 sis_format:2; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved7:2; u8 disable_array_rebuild_verify:1; u8 reserved:2; u8 dual_ioa_asymmetric_access:1; u8 dual_ioa_wcache:1; u8 dual_ioa_raid:1; u8 reserved3:4; u8 gscsi_only_ha:1; u8 is_dual_wide:1; u8 is_aux_cache:1; u8 can_attach_to_aux_cache:1; u8 reserved4:6; u8 af_4k_support:1; u8 reserved5:1; u8 sis_format:2; u8 ra_id_encoding:3; u8 reserved6:3; #endif u16 af_block_size; u16 af_ext_cap; u16 vset_ext_cap; u16 gscsi_ext_cap; }; struct ipr_dasd_ucode_header { u8 length[3]; u8 load_id[4]; u8 modification_level[4]; u8 ptf_number[4]; u8 patch_number[4]; }; struct ipr_ioa_ucode_img_desc { #define IPR_IOAF_STR "IOAF" #define IPR_FPGA_STR "FPGA" #define IPR_DRAM_STR "AGIG" char fw_type[4]; #define IPR_IOAF 0 #define IPR_FPGA 1 #define IPR_DRAM 2 u8 reserved[16]; }; struct ipr_ioa_ucode_ext_header { char eyecatcher[8]; /* EXTDLIMG */ u32 image_length; u32 flags; char fw_level[8]; u8 reserved[12]; u32 img_desc_offset; }; struct ipr_ioa_ucode_header { u32 header_length; u32 lid_table_offset; u32 rev_level; #define LINUX_HEADER_RESERVED_BYTES 20 u8 reserved[LINUX_HEADER_RESERVED_BYTES]; char eyecatcher[16]; /* IBMAS400 CCIN */ u32 num_lids; }; struct ipr_fw_images { char file[100]; u32 version; int has_header; char date[20]; }; struct ipr_ioa_vpd { struct ipr_std_inq_data std_inq_data; u8 ascii_part_num[IPR_VPD_PART_NUM_LEN]; u8 reserved[40]; u8 ascii_plant_code[IPR_VPD_PLANT_CODE_LEN]; }; struct ipr_cfc_vpd { u8 peri_dev_type; u8 page_code; u8 reserved1; u8 add_page_len; u8 ascii_len; u8 cache_size[IPR_VPD_CACHE_SIZE_LEN]; struct ipr_std_inq_vpids vpids; u8 revision_level[4]; u8 serial_num[IPR_SERIAL_NUM_LEN]; u8 ascii_part_num[12]; u8 reserved3[40]; u8 ascii_plant_code[IPR_VPD_PLANT_CODE_LEN]; }; struct ipr_dram_vpd { u8 peri_dev_type; u8 page_code; u8 reserved1; u8 add_page_len; u8 ascii_len; u8 dram_size[IPR_VPD_DRAM_SIZE_LEN]; }; struct ipr_cache_cap_vpd { #define IPR_CACHE_CAP_VSET_WRITE_CACHE 0x08000000 u8 peri_dev_type; u8 page_code; u8 reserved1; u8 add_page_len; u32 cache_cap; u32 data_store_size; u32 write_cache_size; u32 comp_write_cache_size; u32 read_cache_size; u32 comp_read_cache_size; }; struct ipr_dev_identify_vpd { u8 peri_dev_type; u8 page_code; u16 add_page_len; u8 reserved[80]; u8 dev_identify_contxt[40]; }; #define IPR_IOA_MAX_SUPP_LOG_PAGES 64 struct ipr_supp_log_pages { u8 page_code; u8 reserved; u16 length; u8 page[IPR_IOA_MAX_SUPP_LOG_PAGES]; }; struct ipr_sas_phy_log_desc { u8 reserved; u8 phy; u8 reserved2[2]; #if defined (__BIG_ENDIAN_BITFIELD) u8 reseved3:1; u8 attached_dev_type:3; u8 reserved4:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved4:4; u8 attached_dev_type:3; u8 reseved3:1; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved5:4; u8 link_rate:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 link_rate:4; u8 reserved5:4; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved6:4; u8 attached_ssp_initiator_port:1; u8 attached_stp_initiator_port:1; u8 attached_smp_initiator_port:1; u8 reserved7:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved7:1; u8 attached_smp_initiator_port:1; u8 attached_stp_initiator_port:1; u8 attached_ssp_initiator_port:1; u8 reserved6:4; #endif #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved8:4; u8 attached_ssp_target_port:1; u8 attached_stp_target_port:1; u8 attached_smp_target_port:1; u8 reserved9:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved9:1; u8 attached_smp_target_port:1; u8 attached_stp_target_port:1; u8 attached_ssp_target_port:1; u8 reserved8:4; #endif u8 sas_addr[8]; u8 attached_sas_addr[8]; u8 attached_phy_id; u8 reserved10[7]; u32 invalid_dword_count; u32 running_disparity_error_count; u32 loss_of_dword_sync_count; u32 phy_reset_problem_count; }; struct ipr_sas_port_log_desc { u16 port_num; #if defined (__BIG_ENDIAN_BITFIELD) u8 du:1; u8 ds:1; u8 tsd:1; u8 etc:1; u8 tmc:2; u8 lbin:1; u8 lp:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 lp:1; u8 lbin:1; u8 tmc:2; u8 etc:1; u8 tsd:1; u8 ds:1; u8 du:1; #endif u8 length; u8 proto_id; #define IPR_SAS_PROTOCOL_ID 0x06 u8 reserved[2]; u8 num_phys; #define IPR_IOA_MAX_PHYS 4 struct ipr_sas_phy_log_desc phy[IPR_IOA_MAX_PHYS]; }; #define IPR_SAS_LINK_RATE_NOT_PROGRAMMABLE 0 #define IPR_SAS_LINK_RATE_1_5_Gbps 8 #define IPR_SAS_LINK_RATE_3_0_Gbps 9 #define IPR_SAS_ROUTING_DIRECT 0 #define IPR_SAS_ROUTING_SUB_OR_DIRECT 1 #define IPR_SAS_ROUTING_TABLE_OR_DIRECT 2 struct ipr_sas_phy_info { u32 len; u8 bus; u8 cascade; u8 phy_num; u8 reserved; struct ipr_sas_phy_log_desc phy_log; #if defined (__BIG_ENDIAN_BITFIELD) u8 prog_min_link_rate:4; u8 hw_min_link_rate:4; u8 prog_max_link_rate:4; u8 hw_max_link_rate:4; u8 virtual_phy:1; u8 reserved2:7; u8 reserved3:4; u8 routing_attr:4; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 hw_min_link_rate:4; u8 prog_min_link_rate:4; u8 hw_max_link_rate:4; u8 prog_max_link_rate:4; u8 reserved2:7; u8 virtual_phy:1; u8 routing_attr:4; u8 reserved3:4; #endif }; struct ipr_sas_expander_info { u32 len; u8 bus; u8 cascade; u8 reserved; #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved2:7; u8 sas_1_1_fmt:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 sas_1_1_fmt:1; u8 reserved2:7; #endif struct ipr_std_inq_vpids vpids; u8 prod_rev_level[4]; u8 component_vendor_id[8]; u8 component_id[2]; u8 component_rev_id; u8 reserved3; u8 vendor_spec[8]; u8 enclosure_logical_id[8]; u8 reserved4[3]; u8 num_phys; struct ipr_sas_phy_info phy[1]; }; struct ipr_query_sas_expander_info { u32 len; u8 reserved[3]; u8 num_expanders; struct ipr_sas_expander_info exp[1]; }; struct ipr_global_cache_params_term { #define IPR_CACHE_PARAM_TERM_ID 0x10 u8 term_id; u8 len; #if defined (__BIG_ENDIAN_BITFIELD) u8 enable_caching_dual_ioa_failure:1; u8 disable_caching_requested:1; u8 reserved1:2; u8 vset_write_cache_enabled:1; u8 reserved2:3; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved2:3; u8 vset_write_cache_enabled:1; u8 reserved1:2; u8 disable_caching_requested:1; u8 enable_caching_dual_ioa_failure:1; #endif u8 reserved3; }; struct log_parameter_hdr { u8 parameter_code[2]; #if defined (__BIG_ENDIAN_BITFIELD) u8 du:1; u8 reserved1:1; u8 tsd:1; u8 etc:1; u8 tmc:2; u8 lbin:1; u8 lp:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 lp:1; u8 lbin:1; u8 tmc:2; u8 etc:1; u8 tsd:1; u8 reserved1:1; u8 du:1; #endif u8 length; }; /* Log Parameter: Log Page = 0x34. Attribute template */ struct ipr_sas_log_smart_attr { struct log_parameter_hdr hdr; u8 norm_threshold_val; int8_t norm_worst_val; u8 raw_data[10]; }; /* Log Parameter: Log Page = 0x2F. Attribute Code = 0x0 */ struct ipr_sas_log_inf_except_attr { struct log_parameter_hdr param_hdr; u8 inf_except_add_sense_code; u8 inf_except_add_sense_code_qual; u8 last_temp_read; }; struct ipr_sas_log_write_err_cnt_attr { struct log_parameter_hdr param_hdr; u8 counter; }; struct ipr_sas_log_page { #if defined (__BIG_ENDIAN_BITFIELD) u8 reserved1:2; u8 page_code:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 page_code:6; u8 reserved1:2; #endif u8 reserved2; u8 page_length[2]; #define IPR_SAS_LOG_MAX_ENTRIES 256 u8 raw_data[IPR_SAS_LOG_MAX_ENTRIES]; }; struct ipr_query_ioa_caching_info { u16 len; u8 reserved[2]; #define IPR_MAX_TERMS 512 struct ipr_global_cache_params_term term[IPR_MAX_TERMS]; }; #define for_each_cache_term(term, info) \ for (term = (info)->term; \ ((unsigned long)term) < ((unsigned long)((unsigned long)(info) + ntohs((info)->len)) + 2) && \ ((unsigned long)term + term->len + 2 - (unsigned long)(info)->term) < sizeof((info)->term); \ term = (struct ipr_global_cache_params_term *)(((unsigned long)term) + term->len + 2)) struct ipr_log_page18 { u8 page_code; u8 reserved; u16 length; #define IPR_IOA_MAX_PORTS 32 struct ipr_sas_port_log_desc port[IPR_IOA_MAX_PORTS]; }; #define for_each_port(port, log) \ for (port = (log)->port; \ (unsigned long)port < ((unsigned long)((log)->port) + ntohs(port->length)); \ port = (struct ipr_sas_port_log_desc *)((unsigned long)(&port->length) + port->length + 1)) #define for_each_phy(phy, port) \ for (phy = (port)->phy; \ (phy < ((port)->phy + (port)->num_phys)) && \ (phy < ((port)->phy + IPR_IOA_MAX_PORTS)); phy++) struct ipr_dasd_perf_counters_log_page30 { u8 page_code; u8 reserved1; u16 length; u8 reserved2[3]; u8 param_length; u16 dev_no_seeks; u16 dev_seeks_2_3; u16 dev_seeks_1_3; u16 dev_seeks_1_6; u16 dev_seeks_1_12; u16 dev_seeks_0; u32 reserved3; u16 dev_read_buf_overruns; u16 dev_write_buf_underruns; u32 dev_cache_read_hits; u32 dev_cache_partial_read_hits; u32 dev_cache_write_hits; u32 dev_cache_fast_write_hits; u32 reserved4; u32 reserved5; u32 ioa_dev_read_ops; u32 ioa_dev_write_ops; u32 ioa_cache_read_hits; u32 ioa_cache_partial_read_hits; u32 ioa_cache_write_hits; u32 ioa_cache_fast_write_hits; u32 ioa_cache_emu_read_hits; u32 ioa_idle_loop_count[2]; u32 ioa_idle_count_value; u8 ioa_idle_units; u8 reserved6[3]; }; struct ipr_fabric_config_element { u8 type_status; #define IPR_PATH_CFG_TYPE_MASK 0xF0 #define IPR_PATH_CFG_NOT_EXIST 0x00 #define IPR_PATH_CFG_IOA_PORT 0x10 #define IPR_PATH_CFG_EXP_PORT 0x20 #define IPR_PATH_CFG_DEVICE_PORT 0x30 #define IPR_PATH_CFG_DEVICE_LUN 0x40 #define IPR_PATH_CFG_STATUS_MASK 0x0F #define IPR_PATH_CFG_NO_PROB 0x00 #define IPR_PATH_CFG_DEGRADED 0x01 #define IPR_PATH_CFG_FAILED 0x02 #define IPR_PATH_CFG_SUSPECT 0x03 #define IPR_PATH_NOT_DETECTED 0x04 #define IPR_PATH_INCORRECT_CONN 0x05 u8 cascaded_expander; u8 phy; u8 link_rate; #define IPR_PHY_LINK_RATE_MASK 0x0F u32 wwid[2]; }; struct ipr_fabric_descriptor { u16 length; u8 ioa_port; u8 cascaded_expander; u8 phy; u8 path_state; #define IPR_PATH_ACTIVE_MASK 0xC0 #define IPR_PATH_NO_INFO 0x00 #define IPR_PATH_ACTIVE 0x40 #define IPR_PATH_NOT_ACTIVE 0x80 #define IPR_PATH_STATE_MASK 0x0F #define IPR_PATH_STATE_NO_INFO 0x00 #define IPR_PATH_HEALTHY 0x01 #define IPR_PATH_DEGRADED 0x02 #define IPR_PATH_FAILED 0x03 u16 num_entries; struct ipr_fabric_config_element elem[1]; }; struct ipr_fabric_config_element64 { u16 length; #if defined (__BIG_ENDIAN_BITFIELD) u8 cfg_elem_id:2; u8 reserved1:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved1:6; u8 cfg_elem_id:2; #endif u8 reserved2; u8 type_status; u8 reserved3[2]; u8 link_rate; u8 res_path[8]; u32 wwid[4]; }; struct ipr_fabric_descriptor64 { u16 length; #if defined (__BIG_ENDIAN_BITFIELD) u8 fabric_id:2; u8 reserved1:6; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 reserved1:6; u8 fabric_id:2; #endif u8 reserved2[2]; u8 path_state; u8 reserved3; u8 res_path[8]; u32 reserved4; u8 reserved5[2]; u16 num_entries; struct ipr_fabric_config_element64 elem[1]; }; #define for_each_fabric_cfg(fabric, cfg) \ for (cfg = (fabric)->elem; \ cfg < ((fabric)->elem + ntohs((fabric)->num_entries)); \ cfg++) #define for_each_fabric_desc(fabric, info) \ for (fabric = (info)->u.fabric; \ ((unsigned long)fabric) < (((unsigned long)(info)) + ntohl((info)->len) + sizeof((info)->len)); \ fabric = (struct ipr_fabric_descriptor *)(((unsigned long)fabric) + ntohs(fabric->length))) #define for_each_fabric_desc64(fabric, info) \ for (fabric = (info)->u.fabric64; \ ((unsigned long)fabric) < (((unsigned long)(info)) + ntohl((info)->len) + sizeof((info)->len)); \ fabric = (struct ipr_fabric_descriptor64 *)(((unsigned long)fabric) + ntohs(fabric->length))) struct ipr_res_redundancy_info { u32 len; u8 possibly_redundant_paths; u8 healthy_paths; u8 degraded_paths; u8 failed_paths; u8 active_paths; u8 reserved[2]; u8 fabric_descriptors; union { struct ipr_fabric_descriptor fabric[1]; struct ipr_fabric_descriptor64 fabric64[1]; } u; u8 data[16384]; }; struct ses_inquiry_page0 { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 supported_vpd_page[SES_MAX_NUM_SUPP_INQ_PAGES]; }; struct ses_serial_num_vpd { u8 peri_dev_type; u8 page_code; u8 reserved1; u8 add_page_len; u8 ascii_len; u8 serial_num_head[3]; u8 feature_code[4]; u8 ascii_dash; u8 count[3]; u8 ascii_space; u8 ses_serial_num[7]; }; struct esm_serial_num_vpd { u8 peri_dev_type; u8 page_code; u8 reserved1; u8 page_len; u8 ascii_len; u8 fru_part_number[3]; u8 frb_number[8]; u8 reserved2; u8 serial_num_head[3]; u8 esm_serial_num[12]; u8 reserved3; u8 model_num_head[3]; u8 model_num[4]; u8 reserved4; u8 frb_label_head[3]; u8 frb_label[5]; u8 reserved5; }; struct drive_elem_desc { u8 reserved1[2]; u8 desc_length[2]; u8 reserved2; #define DISK_PHY_LOC_LENGTH 9 u8 disk_physical_loc[DISK_PHY_LOC_LENGTH]; u8 reserved3[2]; u8 form_facter; u8 slot_height; u8 slot_bus; u8 phy_speed; }; struct drive_elem_desc_pg { u8 page_code; u8 reserved1; u16 page_length; u8 reserved2[6]; u16 desc_length; #define DEVICE_ELEM_NUMBER 50 struct drive_elem_desc dev_elem[DEVICE_ELEM_NUMBER]; }; struct ipr_ses_type_desc { u8 elem_type; #define IPR_SES_DEVICE_ELEM 0x01 #define IPR_SES_ESM_ELEM 0x07 #define IPR_SES_ENCLOSURE_ELEM 0x0E u8 num_elems; u8 subenclosure_id; u8 text_len; }; struct ipr_drive_elem_status { #if defined (__BIG_ENDIAN_BITFIELD) u8 select:1; u8 predictive_fault:1; u8 reserved:1; u8 swap:1; u8 status:4; u8 reserved2:1; u8 device_environment:2; u8 slot_id:5; u8 reserved3:4; u8 insert:1; u8 remove:1; u8 identify:1; u8 reserved4:1; u8 reserved5:1; u8 fault_requested:1; u8 fault_sensed:1; u8 reserved6:1; u8 enable_byp:2; u8 reserved7:1; u8 disable_resets:1; #elif defined (__LITTLE_ENDIAN_BITFIELD) u8 status:4; u8 swap:1; u8 reserved:1; u8 predictive_fault:1; u8 select:1; u8 slot_id:5; u8 device_environment:2; u8 reserved2:1; u8 reserved4:1; u8 identify:1; u8 remove:1; u8 insert:1; u8 reserved3:4; u8 disable_resets:1; u8 reserved7:1; u8 enable_byp:2; u8 reserved6:1; u8 fault_sensed:1; u8 fault_requested:1; u8 reserved5:1; #endif }; struct ipr_encl_status_ctl_pg { u8 page_code; u8 health_status; u16 byte_count; u8 reserved1[4]; struct ipr_drive_elem_status elem_status[IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES]; u8 reserved2[468]; /*rest of page 2*/ }; struct ipr_ses_config_pg { u8 buf[2048]; }; struct ipr_ses_inquiry_pageC3 { u8 perif_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_length; u8 mode_keyword[3]; u8 mode[4]; u8 reserved2; }; /* Page 12h - Get Time */ struct ipr_ses_diag_page12 { u8 page_code; u8 reserved1; u8 page_length[2]; u8 timestamp_origin; u8 reserved2; u8 timestamp[6]; }; /* Page 13h - Set Time */ struct ipr_ses_diag_ctrl_page13 { u8 page_code; u8 reserved1; u8 page_length[2]; u8 timestamp[6]; u8 reserved[2]; }; struct ipr_sas_inquiry_pageC4 { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; #define IPR_SAS_ENDURANCE_HIGH_HDD 0x20 #define IPR_SAS_ENDURANCE_LOW_EZ 0x31 #define IPR_SAS_ENDURANCE_LOW3 0x32 #define IPR_SAS_ENDURANCE_LOW1 0x33 u8 endurance; u8 reserved[6]; u8 revision; u8 serial_num_11s[8]; u8 serial_num_supplier[8]; u8 master_drive_part[12]; }; struct ipr_sas_inquiry_pageC7 { u8 peri_qual_dev_type; u8 page_code; u8 reserved1; u8 page_length; u8 ascii_len; u8 reserved2[38]; u8 format_timeout_hi; /* in minutes */ u8 format_timeout_lo; u8 reserved3[63]; u8 support_4k_modes; #define ONLY_5XX_SUPPORTED 0 #define BOTH_5XXe_OR_4K_SUPPORTED 1 #define ONLY_4K_SUPPORTED 2 u8 reserved4[5]; u8 total_bytes_warranty[IPR_SAS_INQ_BYTES_WARRANTY_LEN]; u8 reserved5[43]; }; static inline int ipr_elem_offset(struct ipr_ses_config_pg *ses_cfg, u8 type) { int i, off; struct ipr_ses_type_desc *desc; u8 *diag = ses_cfg->buf; desc = (struct ipr_ses_type_desc *)&diag[12+diag[11]]; for (i = 0, off = 1; i < diag[10]; off += (desc->num_elems + 1), i++, desc++) if (desc->elem_type == type) return off; return 1; } static inline int ipr_dev_elem_offset(struct ipr_ses_config_pg *ses_cfg) { return ipr_elem_offset(ses_cfg, IPR_SES_DEVICE_ELEM); } static inline int ipr_ses_elem_offset(struct ipr_ses_config_pg *ses_cfg) { return ipr_elem_offset(ses_cfg, IPR_SES_ENCLOSURE_ELEM); } static inline int ipr_esm_elem_offset(struct ipr_ses_config_pg *ses_cfg) { return ipr_elem_offset(ses_cfg, IPR_SES_ESM_ELEM); } static inline struct ipr_drive_elem_status * ipr_get_overall_elem(struct ipr_encl_status_ctl_pg *ses_data, struct ipr_ses_config_pg *ses_cfg) { return &(ses_data->elem_status[ipr_dev_elem_offset(ses_cfg) - 1]); } static inline struct ipr_ses_type_desc *ipr_get_elem(struct ipr_ses_config_pg *ses_cfg, u8 type) { int i; struct ipr_ses_type_desc *desc; u8 *diag = ses_cfg->buf; desc = (struct ipr_ses_type_desc *)&diag[12+diag[11]]; for (i = 0; i < diag[10]; i++, desc++) if (desc->elem_type == type) return desc; return NULL; } static inline struct ipr_ses_type_desc *ipr_get_dev_elem(struct ipr_ses_config_pg *ses_cfg) { return ipr_get_elem(ses_cfg, IPR_SES_DEVICE_ELEM); } static inline struct ipr_drive_elem_status * ipr_get_enclosure_elem(struct ipr_encl_status_ctl_pg *ses_data, struct ipr_ses_config_pg *ses_cfg) { return &(ses_data->elem_status[ipr_ses_elem_offset(ses_cfg) - 1]); } static inline struct ipr_drive_elem_status * ipr_get_esm_elem(struct ipr_encl_status_ctl_pg *ses_data, struct ipr_ses_config_pg *ses_cfg) { return &(ses_data->elem_status[ipr_esm_elem_offset(ses_cfg) - 1]); } static inline int ipr_max_dev_elems(struct ipr_ses_config_pg *ses_cfg) { struct ipr_ses_type_desc *desc = ipr_get_dev_elem(ses_cfg); if (desc && desc->num_elems < IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES) return desc->num_elems; return IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES; } #define for_each_elem_status(elem, sd, sc) \ for (elem = &((sd)->elem_status[ipr_dev_elem_offset(sc)]); \ elem < &((sd)->elem_status[(ntohs((sd)->byte_count)-4)/sizeof((sd)->elem_status[0])]) && \ elem < &((sd)->elem_status[ipr_dev_elem_offset(sc) + ipr_max_dev_elems(sc)]) && \ elem < &((sd)->elem_status[IPR_NUM_DRIVE_ELEM_STATUS_ENTRIES]); elem++) int sg_ioctl(int, u8 *, void *, u32, u32, struct sense_data_t *, u32); int sg_ioctl_noretry(int, u8 *, void *, u32, u32, struct sense_data_t *, u32); int ipr_change_multi_adapter_assignment(struct ipr_ioa *, int, int); int set_ha_mode(struct ipr_ioa *, int); int set_preferred_primary(struct ipr_ioa *, int); void check_current_config(bool); void __check_current_config(bool, bool); int num_device_opens(int, int, int, int); int open_and_lock(char *); int tool_init(int); void exit_on_error(char *, ...); bool is_af_blocked(struct ipr_dev *, int); int ipr_query_array_config(struct ipr_ioa *, bool, bool, bool, int, struct ipr_array_query_data *); int __ipr_query_array_config(struct ipr_ioa *, int, bool, bool, bool, int, struct ipr_array_query_data *); int ipr_query_command_status(struct ipr_dev *, void *); int ipr_query_io_dev_port(struct ipr_dev *, struct ipr_query_io_port *); int ipr_mode_sense(struct ipr_dev *, u8, void *); int ipr_mode_select(struct ipr_dev *, void *, int); int ipr_log_sense(struct ipr_dev *, u8, void *, u16); int ipr_is_log_page_supported(struct ipr_dev *, u8); void *ipr_sas_log_get_param(const struct ipr_sas_log_page *page, u32 param, int *entries_cnt); int ipr_reset_device(struct ipr_dev *); int ipr_re_read_partition(struct ipr_dev *); int ipr_read_capacity(struct ipr_dev *, void *); int ipr_read_capacity_16(struct ipr_dev *, void *); int ipr_query_resource_state(struct ipr_dev *, void *); void ipr_allow_restart(struct ipr_dev *, int); int ipr_get_logical_block_size(struct ipr_dev *); bool ipr_is_af_blk_size(struct ipr_ioa *, int); void ipr_set_manage_start_stop(struct ipr_dev *); int ipr_start_stop_start(struct ipr_dev *); int ipr_start_stop_stop(struct ipr_dev *); int ipr_stop_array_protection(struct ipr_ioa *); int ipr_remove_hot_spare(struct ipr_ioa *); int ipr_start_array_protection(struct ipr_ioa *, int, int); int ipr_migrate_array_protection(struct ipr_ioa *, struct ipr_array_query_data *, int, int, int); int ipr_set_array_asym_access(struct ipr_ioa *); int ipr_add_hot_spare(struct ipr_ioa *); int ipr_rebuild_device_data(struct ipr_ioa *); int ipr_resync_array(struct ipr_ioa *); int ipr_test_unit_ready(struct ipr_dev *, struct sense_data_t *); int ipr_format_unit(struct ipr_dev *); void ipr_format_res_path(u8 *, char *, int); void ipr_format_res_path_wo_hyphen(u8 *, char *, int); int ipr_add_array_device(struct ipr_ioa *, int, struct ipr_array_query_data *); int ipr_reclaim_cache_store(struct ipr_ioa *, int, void *); int ipr_evaluate_device(struct ipr_dev *, u32); int ipr_query_res_redundancy_info(struct ipr_dev *, struct ipr_res_redundancy_info *); int ipr_query_sas_expander_info(struct ipr_ioa *, struct ipr_query_sas_expander_info *); int ipr_query_cache_parameters(struct ipr_ioa *, void *, int); int ipr_disrupt_device(struct ipr_dev *); int ipr_inquiry(struct ipr_dev *, u8, void *, u8); int ipr_query_res_addr_aliases(struct ipr_ioa *, struct ipr_res_addr *, struct ipr_res_addr_aliases *); int ipr_query_res_path_aliases(struct ipr_ioa *, struct ipr_res_path *, struct ipr_res_path_aliases *); void ipr_convert_res_path_to_bytes(struct ipr_dev *); void ipr_format_res_path(u8 *, char *, int); void ipr_reset_adapter(struct ipr_ioa *); void ipr_scan(struct ipr_ioa *, int, int, int); int ipr_read_host_attr(struct ipr_ioa *, char *, void *, size_t); int ipr_write_host_attr(struct ipr_ioa *, char *, void *, size_t); int ipr_read_dev_attr(struct ipr_dev *, char *, char *, size_t); int ipr_write_dev_attr(struct ipr_dev *, char *, char *); int ipr_suspend_device_bus(struct ipr_dev *, struct ipr_res_addr *, u8); int ipr_resume_device_bus(struct ipr_dev *, struct ipr_res_addr *); int ipr_can_remove_device(struct ipr_dev *); int ipr_receive_diagnostics(struct ipr_dev *, u8, void *, int); int ipr_send_diagnostics(struct ipr_dev *, void *, int); int ipr_get_bus_attr(struct ipr_ioa *, struct ipr_scsi_buses *); void ipr_modify_bus_attr(struct ipr_ioa *, struct ipr_scsi_buses *); int ipr_set_bus_attr(struct ipr_ioa *, struct ipr_scsi_buses *, int); int ipr_write_buffer(struct ipr_dev *, void *, int); int enable_af(struct ipr_dev *); int get_max_bus_speed(struct ipr_ioa *, int); int ipr_get_ioa_attr(struct ipr_ioa *, struct ipr_ioa_attr *); int ipr_get_dev_attr(struct ipr_dev *, struct ipr_disk_attr *); int ipr_modify_dev_attr(struct ipr_dev *, struct ipr_disk_attr *); int ipr_set_ioa_attr(struct ipr_ioa *, struct ipr_ioa_attr *, int); int ipr_modify_ioa_attr(struct ipr_ioa *, struct ipr_ioa_attr *); int ipr_set_dev_attr(struct ipr_dev *, struct ipr_disk_attr *, int); int set_active_active_mode(struct ipr_ioa *, int); int ipr_set_format_completed_bit(struct ipr_dev *); int ipr_set_ses_mode(struct ipr_dev *, int); int get_ioa_caching(struct ipr_ioa *); int ipr_change_cache_parameters(struct ipr_ioa *, int); int ipr_query_dasd_timeouts(struct ipr_dev *, struct ipr_query_dasd_timeouts *); int get_ioa_firmware_image_list(struct ipr_ioa *, struct ipr_fw_images **); int get_dasd_firmware_image_list(struct ipr_dev *, struct ipr_fw_images **); int get_ses_firmware_image_list(struct ipr_dev *, struct ipr_fw_images **); int get_latest_fw_image_version(struct ipr_dev *); struct ipr_fw_images *get_latest_fw_image(struct ipr_dev *); int ipr_update_ioa_fw(struct ipr_ioa *, struct ipr_fw_images *, int); int ipr_update_disk_fw(struct ipr_dev *, struct ipr_fw_images *, int); int ipr_init_dev(struct ipr_dev *); int ipr_init_new_dev(struct ipr_dev *); int ipr_init_ioa(struct ipr_ioa *); int device_supported(struct ipr_dev *); struct ipr_dev *get_dev_from_addr(struct ipr_res_addr *res_addr); struct ipr_dev *get_dev_from_handle(struct ipr_ioa *ioa, u32 res_handle); void ipr_daemonize(); struct unsupported_af_dasd *get_unsupp_af(struct ipr_std_inq_data *, struct ipr_dasd_inquiry_page3 *); bool disk_needs_msl(struct unsupported_af_dasd *, struct ipr_std_inq_data *); void ipr_add_zeroed_dev(struct ipr_dev *); void ipr_update_qac_with_zeroed_devs(struct ipr_ioa *); void ipr_cleanup_zeroed_devs(); void ipr_del_zeroed_dev(struct ipr_dev *); int ipr_device_is_zeroed(struct ipr_dev *); struct ipr_array_cap_entry *get_raid_cap_entry(struct ipr_supported_arrays *, u8 ); char *get_prot_level_str(struct ipr_supported_arrays *, int); u32 get_fw_version(struct ipr_dev *); int ipr_disable_qerr(struct ipr_dev *); void ipr_log_ucode_error(struct ipr_ioa *); u32 get_dasd_ucode_version(char *, int); u32 get_ses_ucode_version(char *ucode_file); const char *get_bus_desc(struct ipr_ioa *); const char *get_ioa_desc(struct ipr_ioa *); int ioa_is_spi(struct ipr_ioa *); int __ioa_is_spi(struct ipr_ioa *); int page0x0a_setup(struct ipr_dev *); int handle_events(void (*) (void), int, void (*) (char *)); struct ipr_ioa *find_ioa(int); int parse_option(char *); struct ipr_dev *find_blk_dev(char *); struct ipr_dev *find_gen_dev(char *); struct ipr_dev *find_dev(char *); int ipr_cmds_per_lun(struct ipr_ioa *); void scsi_host_kevent(char *, int (*)(struct ipr_ioa *)); void scsi_dev_kevent(char *, struct ipr_dev *(*)(char *), int (*)(struct ipr_dev *)); int format_req(struct ipr_dev *); struct ipr_dev *get_vset_from_array(struct ipr_ioa *, struct ipr_dev *); struct ipr_dev *get_array_from_vset(struct ipr_ioa *, struct ipr_dev *); struct sysfs_dev * ipr_find_sysfs_dev(struct ipr_dev *, struct sysfs_dev *); void ipr_add_sysfs_dev(struct ipr_dev *, struct sysfs_dev **, struct sysfs_dev **); void ipr_del_sysfs_dev(struct ipr_dev *, struct sysfs_dev **, struct sysfs_dev **); struct ipr_dev *ipr_sysfs_dev_to_dev(struct sysfs_dev *); struct ipr_array_cap_entry *get_cap_entry(struct ipr_supported_arrays *, char *); int ipr_get_blk_size(struct ipr_dev *); u32 get_ioa_ucode_version(char *); int ipr_improper_device_type(struct ipr_dev *); int ipr_get_fw_version(struct ipr_dev *, u8 release_level[4]); int ipr_get_live_dump(struct ipr_ioa *); int ipr_jbod_sysfs_bind(struct ipr_dev *, u8); int ipr_max_queue_depth(struct ipr_ioa *ioa, int num_devs, int num_ssd_devs); void ipr_count_devices_in_vset(struct ipr_dev *, int *num_devs, int *ssd_num_devs); int ipr_known_zeroed_is_saved(struct ipr_dev *); int get_sg_name(struct scsi_dev_data *); int ipr_sg_inquiry(struct scsi_dev_data *, u8, void *, u8); int get_scsi_dev_data(struct scsi_dev_data **scsi_dev_ref); int ipr_device_lock(struct ipr_dev *dev); void ipr_device_unlock(struct ipr_dev *dev); int check_sg_module(); static inline u32 ipr_get_dev_res_handle(struct ipr_ioa *ioa, struct ipr_dev_record *dev_rcd) { if (ioa->sis64) return dev_rcd->type3.resource_handle; else return dev_rcd->type2.resource_handle; } static inline u32 ipr_get_arr_res_handle(struct ipr_ioa *ioa, struct ipr_array_record *array_rcd) { if (ioa->sis64) return array_rcd->type3.resource_handle; else return array_rcd->type2.resource_handle; } static inline int ipr_is_device_record(int record_id) { if ((record_id == IPR_RECORD_ID_DEVICE_RECORD) || (record_id == IPR_RECORD_ID_DEVICE_RECORD_3)) return 1; else return 0; } static inline int ipr_is_vset_record(int record_id) { if ((record_id == IPR_RECORD_ID_ARRAY_RECORD) || (record_id == IPR_RECORD_ID_VSET_RECORD_3)) return 1; else return 0; } static inline int ipr_is_array_record(int record_id) { if ((record_id == IPR_RECORD_ID_ARRAY_RECORD) || (record_id == IPR_RECORD_ID_ARRAY_RECORD_3)) return 1; else return 0; } static inline int ipr_is_ioa(struct ipr_dev *device) { if (device->ioa && device->ioa->ioa.scsi_dev_data && device->scsi_dev_data == device->ioa->ioa.scsi_dev_data) return 1; else return 0; } static inline int ipr_is_af_dasd_device(struct ipr_dev *device) { if ((device->qac_entry != NULL) && (ipr_is_device_record(device->qac_entry->record_id))) return 1; else return 0; } static inline int ipr_is_remote_af_dasd_device(struct ipr_dev *device) { if ((device->qac_entry != NULL) && (ipr_is_device_record(device->qac_entry->record_id) && device->dev_rcd->current_asym_access_state == IPR_ACTIVE_NON_OPTIMIZED)) return 1; else return 0; } static inline int ipr_is_volume_set(struct ipr_dev *device) { if ((device->qac_entry != NULL) && (ipr_is_vset_record(device->qac_entry->record_id))) return 1; else return 0; } static inline int ipr_is_array(struct ipr_dev *device) { if ((device->qac_entry != NULL) && (ipr_is_array_record(device->qac_entry->record_id))) return 1; else return 0; } static inline int ipr_is_hidden(struct ipr_dev *device) { if (ipr_is_af_dasd_device(device) || ((device->scsi_dev_data) && (device->scsi_dev_data->type == 3))) //FIXME SES type. return 1; else return 0;} static inline int ipr_is_hot_spare(struct ipr_dev *device) { struct ipr_dev_record *dev_record = (struct ipr_dev_record *)device->qac_entry; if ((dev_record != NULL) && (ipr_is_device_record(dev_record->common.record_id)) && (dev_record->is_hot_spare)) return 1; else return 0; } static inline int ipr_is_array_member(struct ipr_dev *device) { struct ipr_dev_record *dev_record = (struct ipr_dev_record *)device->qac_entry; if ((dev_record != NULL) && (dev_record->array_member)) return 1; else return 0; } static inline int ipr_is_af(struct ipr_dev *device) { if (device->qac_entry != NULL) return 1; else return 0; } static inline int ipr_is_gscsi(struct ipr_dev *dev) { if (!dev->qac_entry && dev->scsi_dev_data && dev->scsi_dev_data->type == TYPE_DISK) return 1; else return 0; } static inline int ipr_is_ses(struct ipr_dev *dev) { if (dev->scsi_dev_data && dev->scsi_dev_data->type == TYPE_ENCLOSURE) return 1; else return 0; } static inline void ipr_strncpy_0(char *dest, char *source, int length) { memcpy(dest, source, length); dest[length] = '\0'; } static inline void ipr_strncpy_0n(char *dest, char *source, int length) { char *ch; memcpy(dest, source, length); dest[length] = '\0'; ch = strchr(dest, '\n'); if (ch) *ch = '\0'; } #define dprintf(...) \ do { \ if (ipr_debug) \ fprintf(stderr, __VA_ARGS__);\ } while(0) #define ENTER dprintf("Entering %s\n", __FUNCTION__); #define LEAVE dprintf("Leaving %s\n", __FUNCTION__); #define syslog_dbg(...) \ do { \ if (ipr_debug) \ syslog(LOG_ERR, __VA_ARGS__);\ } while(0) #define ra_dbg(ra, fmt, ...) \ syslog_dbg("%d:%d:%d:%d: " fmt, (ra)->host, (ra)->bus, \ (ra)->target, (ra)->lun, ##__VA_ARGS__); \ #define scsi_log(level, dev, fmt, ...) \ do { \ if (dev->scsi_dev_data && !dev->ioa->ioa_dead) { \ syslog(level, "%d:%d:%d:%d: " fmt, dev->ioa->host_num, \ dev->scsi_dev_data->channel, dev->scsi_dev_data->id, \ dev->scsi_dev_data->lun, ##__VA_ARGS__); \ } \ } while (0) #define scsi_dbg(dev, fmt, ...) \ do { \ if ((dev)->scsi_dev_data) { \ syslog_dbg("%d:%d:%d:%d: " fmt, (dev)->ioa->host_num, \ (dev)->scsi_dev_data->channel, (dev)->scsi_dev_data->id, \ (dev)->scsi_dev_data->lun, ##__VA_ARGS__); \ } \ } while (0) #define scsi_info(dev, fmt, ...) \ scsi_log(LOG_NOTICE, dev, fmt, ##__VA_ARGS__) #define scsi_err(dev, fmt, ...) \ scsi_log(LOG_ERR, dev, fmt, ##__VA_ARGS__) #define scsi_warn(dev, fmt, ...) \ scsi_log(LOG_WARNING, dev, fmt, ##__VA_ARGS__) #define scsi_cmd_err(dev, sense, cmd, rc) \ do { \ if ((((sense)->error_code & 0x7F) != 0x70) || \ (((sense)->sense_key & 0x0F) != 0x05) || ipr_debug) { \ scsi_err(dev, "%s failed. rc=%d, SK: %X ASC: %X ASCQ: %X\n",\ cmd, rc, (sense)->sense_key & 0x0f, (sense)->add_sense_code, \ (sense)->add_sense_code_qual); \ } \ } while (0) #define scsi_cmd_dbg(dev, sense, cmd, rc) \ do { \ if (rc && ipr_debug) { \ scsi_err(dev, "%s failed. rc=%d, SK: %X ASC: %X ASCQ: %X\n",\ cmd, rc, (sense)->sense_key & 0x0f, (sense)->add_sense_code, \ (sense)->add_sense_code_qual); \ } \ } while (0) #define ioa_log(level, ioa, fmt, ...) \ syslog(level, "%s: " fmt, ioa->pci_address, ##__VA_ARGS__) #define ioa_info(ioa, fmt, ...) \ ioa_log(LOG_NOTICE, ioa, fmt, ##__VA_ARGS__) #define ioa_err(ioa, fmt, ...) \ ioa_log(LOG_ERR, ioa, fmt, ##__VA_ARGS__) #define ioa_dbg(ioa, fmt, ...) \ syslog_dbg("%s: " fmt, ioa->pci_address, ##__VA_ARGS__) #define ioa_cmd_err(ioa, sense, cmd, rc) \ do { \ if (!ioa->ioa_dead) { \ if ((((sense)->error_code & 0x7F) != 0x70) || \ (((sense)->sense_key & 0x0F) != 0x05) || ipr_debug) { \ ioa_err(ioa, "%s failed. rc=%d, SK: %X ASC: %X ASCQ: %X\n",\ cmd, rc, (sense)->sense_key & 0x0f, (sense)->add_sense_code, \ (sense)->add_sense_code_qual); \ } \ } \ } while (0) #endif /* iprlib_h */