aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2014-02-21 17:25:15 -0500
committerJames Bottomley <JBottomley@Parallels.com>2014-03-15 13:19:23 -0400
commit316b221a37802b6abe26067f2c6f2d7bb79069e5 (patch)
tree6925287735d55108d37a0458477a6148c2d59e53
parentc14c5891ddbd20cffbc4e35bfba8b7fbac9d5ada (diff)
[SCSI] hpsa: Add hba mode to the hpsa driver
This allows exposing physical disks behind Smart Array controllers to the OS (if the controller has the right firmware and is in "hba" mode) Signed-off-by: Joe Handzik <joseph.t.handzik@hp.com> Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/hpsa.c93
-rw-r--r--drivers/scsi/hpsa.h41
-rw-r--r--drivers/scsi/hpsa_cmd.h1
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
2131static 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 }
2157out:
2158 cmd_special_free(h, c);
2159 return rc;
2160 }
2161
2131static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr, 2162static 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
2963static 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
2932static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno) 2981static 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)
68struct 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
67struct ctlr_info { 107struct 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 */
262union SCSI3Addr { 263union SCSI3Addr {