diff options
-rw-r--r-- | drivers/scsi/hpsa.c | 93 | ||||
-rw-r--r-- | drivers/scsi/hpsa.h | 41 | ||||
-rw-r--r-- | drivers/scsi/hpsa_cmd.h | 1 |
3 files changed, 131 insertions, 4 deletions
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 388e229cdcec..eb23eeacf592 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -2128,6 +2128,37 @@ out: | |||
2128 | return rc; | 2128 | return rc; |
2129 | } | 2129 | } |
2130 | 2130 | ||
2131 | static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h, | ||
2132 | unsigned char *scsi3addr, unsigned char page, | ||
2133 | struct bmic_controller_parameters *buf, size_t bufsize) | ||
2134 | { | ||
2135 | int rc = IO_OK; | ||
2136 | struct CommandList *c; | ||
2137 | struct ErrorInfo *ei; | ||
2138 | |||
2139 | c = cmd_special_alloc(h); | ||
2140 | |||
2141 | if (c == NULL) { /* trouble... */ | ||
2142 | dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); | ||
2143 | return -ENOMEM; | ||
2144 | } | ||
2145 | |||
2146 | if (fill_cmd(c, BMIC_SENSE_CONTROLLER_PARAMETERS, h, buf, bufsize, | ||
2147 | page, scsi3addr, TYPE_CMD)) { | ||
2148 | rc = -1; | ||
2149 | goto out; | ||
2150 | } | ||
2151 | hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE); | ||
2152 | ei = c->err_info; | ||
2153 | if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) { | ||
2154 | hpsa_scsi_interpret_error(h, c); | ||
2155 | rc = -1; | ||
2156 | } | ||
2157 | out: | ||
2158 | cmd_special_free(h, c); | ||
2159 | return rc; | ||
2160 | } | ||
2161 | |||
2131 | static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr, | 2162 | static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr, |
2132 | u8 reset_type) | 2163 | u8 reset_type) |
2133 | { | 2164 | { |
@@ -2929,6 +2960,24 @@ u8 *figure_lunaddrbytes(struct ctlr_info *h, int raid_ctlr_position, int i, | |||
2929 | return NULL; | 2960 | return NULL; |
2930 | } | 2961 | } |
2931 | 2962 | ||
2963 | static int hpsa_hba_mode_enabled(struct ctlr_info *h) | ||
2964 | { | ||
2965 | int rc; | ||
2966 | struct bmic_controller_parameters *ctlr_params; | ||
2967 | ctlr_params = kzalloc(sizeof(struct bmic_controller_parameters), | ||
2968 | GFP_KERNEL); | ||
2969 | |||
2970 | if (!ctlr_params) | ||
2971 | return 0; | ||
2972 | rc = hpsa_bmic_ctrl_mode_sense(h, RAID_CTLR_LUNID, 0, ctlr_params, | ||
2973 | sizeof(struct bmic_controller_parameters)); | ||
2974 | if (rc != 0) { | ||
2975 | kfree(ctlr_params); | ||
2976 | return 0; | ||
2977 | } | ||
2978 | return ctlr_params->nvram_flags & (1 << 3) ? 1 : 0; | ||
2979 | } | ||
2980 | |||
2932 | static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | 2981 | static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) |
2933 | { | 2982 | { |
2934 | /* the idea here is we could get notified | 2983 | /* the idea here is we could get notified |
@@ -2952,6 +3001,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
2952 | int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 24; | 3001 | int reportlunsize = sizeof(*physdev_list) + HPSA_MAX_PHYS_LUN * 24; |
2953 | int i, n_ext_target_devs, ndevs_to_allocate; | 3002 | int i, n_ext_target_devs, ndevs_to_allocate; |
2954 | int raid_ctlr_position; | 3003 | int raid_ctlr_position; |
3004 | u8 rescan_hba_mode; | ||
2955 | DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS); | 3005 | DECLARE_BITMAP(lunzerobits, MAX_EXT_TARGETS); |
2956 | 3006 | ||
2957 | currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL); | 3007 | currentsd = kzalloc(sizeof(*currentsd) * HPSA_MAX_DEVICES, GFP_KERNEL); |
@@ -2965,6 +3015,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
2965 | } | 3015 | } |
2966 | memset(lunzerobits, 0, sizeof(lunzerobits)); | 3016 | memset(lunzerobits, 0, sizeof(lunzerobits)); |
2967 | 3017 | ||
3018 | rescan_hba_mode = hpsa_hba_mode_enabled(h); | ||
3019 | |||
3020 | if (!h->hba_mode_enabled && rescan_hba_mode) | ||
3021 | dev_warn(&h->pdev->dev, "HBA mode enabled\n"); | ||
3022 | else if (h->hba_mode_enabled && !rescan_hba_mode) | ||
3023 | dev_warn(&h->pdev->dev, "HBA mode disabled\n"); | ||
3024 | |||
3025 | h->hba_mode_enabled = rescan_hba_mode; | ||
3026 | |||
2968 | if (hpsa_gather_lun_info(h, reportlunsize, | 3027 | if (hpsa_gather_lun_info(h, reportlunsize, |
2969 | (struct ReportLUNdata *) physdev_list, &nphysicals, | 3028 | (struct ReportLUNdata *) physdev_list, &nphysicals, |
2970 | &physical_mode, logdev_list, &nlogicals)) | 3029 | &physical_mode, logdev_list, &nlogicals)) |
@@ -3048,7 +3107,19 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) | |||
3048 | ncurrent++; | 3107 | ncurrent++; |
3049 | break; | 3108 | break; |
3050 | case TYPE_DISK: | 3109 | case TYPE_DISK: |
3051 | if (i >= nphysicals) { | 3110 | if (h->hba_mode_enabled) { |
3111 | /* never use raid mapper in HBA mode */ | ||
3112 | this_device->offload_enabled = 0; | ||
3113 | ncurrent++; | ||
3114 | break; | ||
3115 | } else if (h->acciopath_status) { | ||
3116 | if (i >= nphysicals) { | ||
3117 | ncurrent++; | ||
3118 | break; | ||
3119 | } | ||
3120 | } else { | ||
3121 | if (i < nphysicals) | ||
3122 | break; | ||
3052 | ncurrent++; | 3123 | ncurrent++; |
3053 | break; | 3124 | break; |
3054 | } | 3125 | } |
@@ -4116,7 +4187,10 @@ static int hpsa_register_scsi(struct ctlr_info *h) | |||
4116 | sh->max_lun = HPSA_MAX_LUN; | 4187 | sh->max_lun = HPSA_MAX_LUN; |
4117 | sh->max_id = HPSA_MAX_LUN; | 4188 | sh->max_id = HPSA_MAX_LUN; |
4118 | sh->can_queue = h->nr_cmds; | 4189 | sh->can_queue = h->nr_cmds; |
4119 | sh->cmd_per_lun = h->nr_cmds; | 4190 | if (h->hba_mode_enabled) |
4191 | sh->cmd_per_lun = 7; | ||
4192 | else | ||
4193 | sh->cmd_per_lun = h->nr_cmds; | ||
4120 | sh->sg_tablesize = h->maxsgentries; | 4194 | sh->sg_tablesize = h->maxsgentries; |
4121 | h->scsi_host = sh; | 4195 | h->scsi_host = sh; |
4122 | sh->hostdata[0] = (unsigned long) h; | 4196 | sh->hostdata[0] = (unsigned long) h; |
@@ -5261,6 +5335,16 @@ static int fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, | |||
5261 | c->Request.CDB[8] = (size >> 8) & 0xFF; | 5335 | c->Request.CDB[8] = (size >> 8) & 0xFF; |
5262 | c->Request.CDB[9] = size & 0xFF; | 5336 | c->Request.CDB[9] = size & 0xFF; |
5263 | break; | 5337 | break; |
5338 | case BMIC_SENSE_CONTROLLER_PARAMETERS: | ||
5339 | c->Request.CDBLen = 10; | ||
5340 | c->Request.Type.Attribute = ATTR_SIMPLE; | ||
5341 | c->Request.Type.Direction = XFER_READ; | ||
5342 | c->Request.Timeout = 0; | ||
5343 | c->Request.CDB[0] = BMIC_READ; | ||
5344 | c->Request.CDB[6] = BMIC_SENSE_CONTROLLER_PARAMETERS; | ||
5345 | c->Request.CDB[7] = (size >> 16) & 0xFF; | ||
5346 | c->Request.CDB[8] = (size >> 8) & 0xFF; | ||
5347 | break; | ||
5264 | default: | 5348 | default: |
5265 | dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); | 5349 | dev_warn(&h->pdev->dev, "unknown command 0x%c\n", cmd); |
5266 | BUG(); | 5350 | BUG(); |
@@ -6885,6 +6969,7 @@ reinit_after_soft_reset: | |||
6885 | 6969 | ||
6886 | pci_set_drvdata(pdev, h); | 6970 | pci_set_drvdata(pdev, h); |
6887 | h->ndevices = 0; | 6971 | h->ndevices = 0; |
6972 | h->hba_mode_enabled = 0; | ||
6888 | h->scsi_host = NULL; | 6973 | h->scsi_host = NULL; |
6889 | spin_lock_init(&h->devlock); | 6974 | spin_lock_init(&h->devlock); |
6890 | hpsa_put_ctlr_into_performant_mode(h); | 6975 | hpsa_put_ctlr_into_performant_mode(h); |
@@ -6944,8 +7029,8 @@ reinit_after_soft_reset: | |||
6944 | goto reinit_after_soft_reset; | 7029 | goto reinit_after_soft_reset; |
6945 | } | 7030 | } |
6946 | 7031 | ||
6947 | /* Enable Accelerated IO path at driver layer */ | 7032 | /* Enable Accelerated IO path at driver layer */ |
6948 | h->acciopath_status = 1; | 7033 | h->acciopath_status = 1; |
6949 | 7034 | ||
6950 | h->drv_req_rescan = 0; | 7035 | h->drv_req_rescan = 0; |
6951 | 7036 | ||
diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h index ae8c592df8d3..44235a27e1b6 100644 --- a/drivers/scsi/hpsa.h +++ b/drivers/scsi/hpsa.h | |||
@@ -64,6 +64,46 @@ struct reply_pool { | |||
64 | u32 current_entry; | 64 | u32 current_entry; |
65 | }; | 65 | }; |
66 | 66 | ||
67 | #pragma pack(1) | ||
68 | struct bmic_controller_parameters { | ||
69 | u8 led_flags; | ||
70 | u8 enable_command_list_verification; | ||
71 | u8 backed_out_write_drives; | ||
72 | u16 stripes_for_parity; | ||
73 | u8 parity_distribution_mode_flags; | ||
74 | u16 max_driver_requests; | ||
75 | u16 elevator_trend_count; | ||
76 | u8 disable_elevator; | ||
77 | u8 force_scan_complete; | ||
78 | u8 scsi_transfer_mode; | ||
79 | u8 force_narrow; | ||
80 | u8 rebuild_priority; | ||
81 | u8 expand_priority; | ||
82 | u8 host_sdb_asic_fix; | ||
83 | u8 pdpi_burst_from_host_disabled; | ||
84 | char software_name[64]; | ||
85 | char hardware_name[32]; | ||
86 | u8 bridge_revision; | ||
87 | u8 snapshot_priority; | ||
88 | u32 os_specific; | ||
89 | u8 post_prompt_timeout; | ||
90 | u8 automatic_drive_slamming; | ||
91 | u8 reserved1; | ||
92 | u8 nvram_flags; | ||
93 | u8 cache_nvram_flags; | ||
94 | u8 drive_config_flags; | ||
95 | u16 reserved2; | ||
96 | u8 temp_warning_level; | ||
97 | u8 temp_shutdown_level; | ||
98 | u8 temp_condition_reset; | ||
99 | u8 max_coalesce_commands; | ||
100 | u32 max_coalesce_delay; | ||
101 | u8 orca_password[4]; | ||
102 | u8 access_id[16]; | ||
103 | u8 reserved[356]; | ||
104 | }; | ||
105 | #pragma pack() | ||
106 | |||
67 | struct ctlr_info { | 107 | struct ctlr_info { |
68 | int ctlr; | 108 | int ctlr; |
69 | char devname[8]; | 109 | char devname[8]; |
@@ -89,6 +129,7 @@ struct ctlr_info { | |||
89 | unsigned int msi_vector; | 129 | unsigned int msi_vector; |
90 | int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */ | 130 | int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */ |
91 | struct access_method access; | 131 | struct access_method access; |
132 | char hba_mode_enabled; | ||
92 | 133 | ||
93 | /* queue and queue Info */ | 134 | /* queue and queue Info */ |
94 | struct list_head reqQ; | 135 | struct list_head reqQ; |
diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index 50388f133ac9..b5cc7052339f 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h | |||
@@ -257,6 +257,7 @@ struct SenseSubsystem_info { | |||
257 | #define BMIC_CACHE_FLUSH 0xc2 | 257 | #define BMIC_CACHE_FLUSH 0xc2 |
258 | #define HPSA_CACHE_FLUSH 0x01 /* C2 was already being used by HPSA */ | 258 | #define HPSA_CACHE_FLUSH 0x01 /* C2 was already being used by HPSA */ |
259 | #define BMIC_FLASH_FIRMWARE 0xF7 | 259 | #define BMIC_FLASH_FIRMWARE 0xF7 |
260 | #define BMIC_SENSE_CONTROLLER_PARAMETERS 0x64 | ||
260 | 261 | ||
261 | /* Command List Structure */ | 262 | /* Command List Structure */ |
262 | union SCSI3Addr { | 263 | union SCSI3Addr { |