mirror of
https://github.com/AuxXxilium/arc-modules.git
synced 2024-11-23 14:51:01 +07:00
Merge pull request #289 from maluueu/dev
Patch hpsa to support HBA/IT mode Signed-off-by: AuxXxilium <info@auxxxilium.tech>
This commit is contained in:
parent
be63d62534
commit
c3a2e6440b
@ -90,6 +90,11 @@ module_param(hpsa_simple_mode, int, S_IRUGO|S_IWUSR);
|
|||||||
MODULE_PARM_DESC(hpsa_simple_mode,
|
MODULE_PARM_DESC(hpsa_simple_mode,
|
||||||
"Use 'simple mode' rather than 'performant mode'");
|
"Use 'simple mode' rather than 'performant mode'");
|
||||||
|
|
||||||
|
static bool hpsa_use_nvram_hba_flag;
|
||||||
|
module_param(hpsa_use_nvram_hba_flag, bool, 0444);
|
||||||
|
MODULE_PARM_DESC(hpsa_use_nvram_hba_flag,
|
||||||
|
"Use flag from NVRAM to enable HBA mode");
|
||||||
|
|
||||||
/* define the PCI info for the cards we can control */
|
/* define the PCI info for the cards we can control */
|
||||||
static const struct pci_device_id hpsa_pci_device_id[] = {
|
static const struct pci_device_id hpsa_pci_device_id[] = {
|
||||||
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241},
|
{PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3241},
|
||||||
@ -1454,6 +1459,14 @@ static inline int device_updated(struct hpsa_scsi_dev_t *dev1,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool device_expose_changed(struct hpsa_scsi_dev_t *dev1,
|
||||||
|
struct hpsa_scsi_dev_t *dev2)
|
||||||
|
{
|
||||||
|
if (dev1->expose_device != dev2->expose_device)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find needle in haystack. If exact match found, return DEVICE_SAME,
|
/* Find needle in haystack. If exact match found, return DEVICE_SAME,
|
||||||
* and return needle location in *index. If scsi3addr matches, but not
|
* and return needle location in *index. If scsi3addr matches, but not
|
||||||
* vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle
|
* vendor, model, serial num, etc. return DEVICE_CHANGED, and return needle
|
||||||
@ -1480,6 +1493,8 @@ static int hpsa_scsi_find_entry(struct hpsa_scsi_dev_t *needle,
|
|||||||
if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) {
|
if (SCSI3ADDR_EQ(needle->scsi3addr, haystack[i]->scsi3addr)) {
|
||||||
*index = i;
|
*index = i;
|
||||||
if (device_is_the_same(needle, haystack[i])) {
|
if (device_is_the_same(needle, haystack[i])) {
|
||||||
|
if (device_expose_changed(needle, haystack[i]))
|
||||||
|
return DEVICE_CHANGED;
|
||||||
if (device_updated(needle, haystack[i]))
|
if (device_updated(needle, haystack[i]))
|
||||||
return DEVICE_UPDATED;
|
return DEVICE_UPDATED;
|
||||||
return DEVICE_SAME;
|
return DEVICE_SAME;
|
||||||
@ -2815,6 +2830,37 @@ out:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int hpsa_bmic_ctrl_mode_sense(struct ctlr_info *h,
|
||||||
|
struct bmic_controller_parameters *buf)
|
||||||
|
{
|
||||||
|
int rc = IO_OK;
|
||||||
|
struct CommandList *c;
|
||||||
|
struct ErrorInfo *ei;
|
||||||
|
|
||||||
|
c = cmd_alloc(h);
|
||||||
|
|
||||||
|
if (fill_cmd(c, BMIC_SENSE_CONTROLLER_PARAMETERS, h, buf, sizeof(*buf),
|
||||||
|
0, RAID_CTLR_LUNID, TYPE_CMD)) {
|
||||||
|
rc = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = hpsa_scsi_do_simple_cmd_with_retry(h, c, PCI_DMA_FROMDEVICE,
|
||||||
|
NO_TIMEOUT);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
ei = c->err_info;
|
||||||
|
if (ei->CommandStatus != 0 && ei->CommandStatus != CMD_DATA_UNDERRUN) {
|
||||||
|
hpsa_scsi_interpret_error(h, c);
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
cmd_free(h, c);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
|
static int hpsa_send_reset(struct ctlr_info *h, unsigned char *scsi3addr,
|
||||||
u8 reset_type, int reply_queue)
|
u8 reset_type, int reply_queue)
|
||||||
{
|
{
|
||||||
@ -3992,6 +4038,66 @@ static bool hpsa_skip_device(struct ctlr_info *h, u8 *lunaddrbytes,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_hba_supported(const struct bmic_identify_controller *id_ctlr)
|
||||||
|
{
|
||||||
|
return le32_to_cpu(id_ctlr->yet_more_controller_flags) &
|
||||||
|
YET_MORE_CTLR_FLAG_HBA_MODE_SUPP;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hpsa_nvram_hba_flag_enabled(struct ctlr_info *h, bool *flag_enabled)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
struct bmic_controller_parameters *ctlr_params;
|
||||||
|
|
||||||
|
ctlr_params = kzalloc(sizeof(*ctlr_params), GFP_KERNEL);
|
||||||
|
if (!ctlr_params) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = hpsa_bmic_ctrl_mode_sense(h, ctlr_params);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
*flag_enabled = ctlr_params->nvram_flags & HPSA_NVRAM_FLAG_HBA;
|
||||||
|
|
||||||
|
out:
|
||||||
|
kfree(ctlr_params);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hpsa_update_nvram_hba_mode(struct ctlr_info *h, u32 nlogicals,
|
||||||
|
const struct bmic_identify_controller *id_ctlr)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
bool flag_enabled;
|
||||||
|
bool ignore;
|
||||||
|
|
||||||
|
if (!hpsa_use_nvram_hba_flag)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!is_hba_supported(id_ctlr)) {
|
||||||
|
dev_info(&h->pdev->dev, "NVRAM HBA flag: not supported\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = hpsa_nvram_hba_flag_enabled(h, &flag_enabled);
|
||||||
|
if (rc == -ENOMEM)
|
||||||
|
dev_warn(&h->pdev->dev, "Out of memory.\n");
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
ignore = flag_enabled && nlogicals;
|
||||||
|
|
||||||
|
dev_info(&h->pdev->dev, "NVRAM HBA flag: %s%s\n",
|
||||||
|
flag_enabled ? "enabled" : "disabled",
|
||||||
|
ignore ? " (ignored because of existing logical devices)" : "");
|
||||||
|
|
||||||
|
h->nvram_hba_mode_enabled = flag_enabled && !ignore;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
||||||
{
|
{
|
||||||
/* the idea here is we could get notified
|
/* the idea here is we could get notified
|
||||||
@ -4048,6 +4154,11 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
|||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hpsa_update_nvram_hba_mode(h, nlogicals, id_ctlr)) {
|
||||||
|
h->drv_req_rescan = 1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
/* We might see up to the maximum number of logical and physical disks
|
/* We might see up to the maximum number of logical and physical disks
|
||||||
* plus external target devices, and a device for the local RAID
|
* plus external target devices, and a device for the local RAID
|
||||||
* controller.
|
* controller.
|
||||||
@ -4144,11 +4255,15 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h)
|
|||||||
* Expose all devices except for physical devices that
|
* Expose all devices except for physical devices that
|
||||||
* are masked.
|
* are masked.
|
||||||
*/
|
*/
|
||||||
if (MASKED_DEVICE(lunaddrbytes) && this_device->physical_device)
|
if (MASKED_DEVICE(lunaddrbytes) &&
|
||||||
this_device->expose_device = 0;
|
this_device->physical_device) {
|
||||||
else
|
if (h->nvram_hba_mode_enabled)
|
||||||
this_device->expose_device = 1;
|
this_device->expose_device = 1;
|
||||||
|
else
|
||||||
|
this_device->expose_device = 0;
|
||||||
|
} else {
|
||||||
|
this_device->expose_device = 1;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Get the SAS address for physical devices that are exposed.
|
* Get the SAS address for physical devices that are exposed.
|
||||||
*/
|
*/
|
||||||
|
@ -153,6 +153,8 @@ struct bmic_controller_parameters {
|
|||||||
};
|
};
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
#define HPSA_NVRAM_FLAG_HBA (1 << 3)
|
||||||
|
|
||||||
struct ctlr_info {
|
struct ctlr_info {
|
||||||
int ctlr;
|
int ctlr;
|
||||||
char devname[8];
|
char devname[8];
|
||||||
@ -178,6 +180,7 @@ struct ctlr_info {
|
|||||||
unsigned int msi_vector;
|
unsigned int msi_vector;
|
||||||
int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
|
int intr_mode; /* either PERF_MODE_INT or SIMPLE_MODE_INT */
|
||||||
struct access_method access;
|
struct access_method access;
|
||||||
|
bool nvram_hba_mode_enabled;
|
||||||
|
|
||||||
/* queue and queue Info */
|
/* queue and queue Info */
|
||||||
unsigned int Qdepth;
|
unsigned int Qdepth;
|
||||||
|
@ -687,13 +687,120 @@ struct hpsa_pci_info {
|
|||||||
|
|
||||||
struct bmic_identify_controller {
|
struct bmic_identify_controller {
|
||||||
u8 configured_logical_drive_count; /* offset 0 */
|
u8 configured_logical_drive_count; /* offset 0 */
|
||||||
u8 pad1[153];
|
__le32 signature;
|
||||||
|
char running_firm_rev[4];
|
||||||
|
char rom_firm_rev[4];
|
||||||
|
u8 hardware_rev;
|
||||||
|
u8 reserved_1[4];
|
||||||
|
__le32 drive_present_bit_map;
|
||||||
|
__le32 external_drive_bit_map;
|
||||||
|
__le32 board_id;
|
||||||
|
u8 reserved_2;
|
||||||
|
__le32 non_disk_map;
|
||||||
|
u8 reserved_3[5];
|
||||||
|
u8 marketing_revision;
|
||||||
|
u8 controller_flags;
|
||||||
|
u8 host_flags;
|
||||||
|
u8 expand_disable_code;
|
||||||
|
u8 scsi_chip_count;
|
||||||
|
u8 reserved_4[4];
|
||||||
|
__le32 ctlr_clock;
|
||||||
|
u8 drives_per_scsi_bus;
|
||||||
|
__le16 big_drive_present_map[8];
|
||||||
|
__le16 big_ext_drive_map[8];
|
||||||
|
__le16 big_non_disk_map[8];
|
||||||
|
|
||||||
|
/* used for FW debugging */
|
||||||
|
__le16 task_flags;
|
||||||
|
/* Bitmap used for ICL between controllers */
|
||||||
|
u8 icl_bus_map;
|
||||||
|
/* See REDUNDANT MODE VALUES */
|
||||||
|
u8 redund_ctlr_modes_support;
|
||||||
|
/* See REDUNDANT MODE VALUES */
|
||||||
|
u8 curr_redund_ctlr_mode;
|
||||||
|
/* See REDUNDANT STATUS FLAG */
|
||||||
|
u8 redund_ctlr_status;
|
||||||
|
/* See REDUNDANT FAILURE VALUES */
|
||||||
|
u8 redund_op_failure_code;
|
||||||
|
u8 unsupported_nile_bus;
|
||||||
|
u8 host_i2c_autorev;
|
||||||
|
u8 cpld_revision;
|
||||||
|
u8 fibre_chip_count;
|
||||||
|
u8 daughterboard_type;
|
||||||
|
u8 reserved_5[2];
|
||||||
|
|
||||||
|
u8 access_module_status;
|
||||||
|
u8 features_supported[12];
|
||||||
|
/* Recovery ROM inactive f/w revision */
|
||||||
|
char rec_rom_inactive_rev[4];
|
||||||
|
/* Recovery ROM flags */
|
||||||
|
u8 rec_rom_flags;
|
||||||
|
u8 pci_to_pci_bridge_status;
|
||||||
|
/* Reserved for future use */
|
||||||
|
u8 reserved_6[4];
|
||||||
|
/* Percent of memory allocated to write cache */
|
||||||
|
u8 percent_write_cache;
|
||||||
|
/* Total cache board size */
|
||||||
|
__le16 daughter_board_cache_size;
|
||||||
|
/* Number of cache batteries */
|
||||||
|
u8 cache_battery_count;
|
||||||
|
/* Total size (MB) of atttached memory */
|
||||||
|
__le16 total_memory_size;
|
||||||
|
/* Additional controller flags byte */
|
||||||
|
u8 more_controller_flags;
|
||||||
|
/* 2nd byte of 3 byte autorev field */
|
||||||
|
u8 x_board_host_i2c_autorev;
|
||||||
|
/* BBWC PIC revision */
|
||||||
|
u8 battery_pic_rev;
|
||||||
|
/* DDFF update engine version */
|
||||||
|
u8 ddff_version[4];
|
||||||
|
/* Maximum logical units supported */
|
||||||
|
__le16 max_logical_units;
|
||||||
|
/* Big num configured logical units */
|
||||||
__le16 extended_logical_unit_count; /* offset 154 */
|
__le16 extended_logical_unit_count; /* offset 154 */
|
||||||
u8 pad2[136];
|
/* Maximum physical devices supported */
|
||||||
|
__le16 max_physical_devices;
|
||||||
|
/* Max physical drive per logical unit */
|
||||||
|
__le16 max_phy_drv_per_logical_unit;
|
||||||
|
/* Number of attached enclosures */
|
||||||
|
u8 enclosure_count;
|
||||||
|
/* Number of expanders detected */
|
||||||
|
u8 expander_count;
|
||||||
|
/* Offset to extended drive present map*/
|
||||||
|
__le16 offset_to_edp_bitmap;
|
||||||
|
/* Offset to extended external drive present map */
|
||||||
|
__le16 offset_to_eedp_bitmap;
|
||||||
|
/* Offset to extended non-disk map */
|
||||||
|
__le16 offset_to_end_bitmap;
|
||||||
|
/* Internal port status bytes */
|
||||||
|
u8 internal_port_status[8];
|
||||||
|
/* External port status bytes */
|
||||||
|
u8 external_port_status[8];
|
||||||
|
/* Yet More Controller flags */
|
||||||
|
__le32 yet_more_controller_flags;
|
||||||
|
/* Last lockup code */
|
||||||
|
u8 last_lockup;
|
||||||
|
/* PCI slot according to option ROM*/
|
||||||
|
u8 pci_slot;
|
||||||
|
/* Build number */
|
||||||
|
__le16 build_num;
|
||||||
|
/* Maximum safe full stripe size */
|
||||||
|
__le32 max_safe_full_stripe_size;
|
||||||
|
/* Total structure length */
|
||||||
|
__le32 total_length;
|
||||||
|
/* Vendor ID */
|
||||||
|
char vendor_id[8];
|
||||||
|
/* Product ID */
|
||||||
|
char product_id[16];
|
||||||
|
u8 reserved_7[68];
|
||||||
u8 controller_mode; /* offset 292 */
|
u8 controller_mode; /* offset 292 */
|
||||||
u8 pad3[32];
|
u8 reserved_8[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ssacli calls this bit "Hba Mode Supported". */
|
||||||
|
#define YET_MORE_CTLR_FLAG_HBA_MODE_SUPP (1 << 25)
|
||||||
|
|
||||||
|
|
||||||
struct bmic_identify_physical_device {
|
struct bmic_identify_physical_device {
|
||||||
u8 scsi_bus; /* SCSI Bus number on controller */
|
u8 scsi_bus; /* SCSI Bus number on controller */
|
||||||
u8 scsi_id; /* SCSI ID on this bus */
|
u8 scsi_id; /* SCSI ID on this bus */
|
||||||
|
Loading…
Reference in New Issue
Block a user