Commit bc93d425 authored by Sumit.Saxena@lsi.com's avatar Sumit.Saxena@lsi.com Committed by James Bottomley

[SCSI] megaraid_sas: Add support for Uneven Span PRL11

MegaRAID older Firmware does not support uneven span configuration for PRL11.
E.g User wants to create 34 Driver PRL11 config, it was not possible using old
firmware, since it was not supported configuration in old firmware

Old Firmware expect even number of Drives in each span and same number of
physical drives at each span.  Considering above design, 17 Drives at Span-0
and 17 drives at span-1 was not possible.

Now, using this new feature Firmware and Driver both required changes.  New
Firmware can allow user to create 16 Drives at span-0 and 18 Drives at
span-1. This will allow user to create 34 Drives Uneven span PRL11.

RAID map is interface between Driver and FW to fetch all required
fields(attributes) for each Virtual Drives.  Since legacy RAID map consider
Even Span design, there was no place to keep Uneven span information in
existing Raid map.  Because of this limitation, for Uneven span VD, driver can
not use RAID map.

This patch address the changes required in Driver to support Uneven span PRL11
support.

1. Driver will find if Firmware has UnevenSpanSupport or not by reading
   Controller Info.
2. If Firmware has UnvenSpan PRL11 support, then Driver will inform about its
   capability of handling UnevenSpan PRL11 to the firmware.
3. Driver will update its copy of span info on each time Raid map update is
   called.
4. Follow different IO path if it is Uneven Span. (For Uneven Span, Driver
   uses Span Set info to find relavent fields for that particular Virtual
   Disk)

More verbose prints will be available by setting "SPAN_DEBUG" to 1 at
compilation time.
Signed-off-by: default avatarSumit Saxena <sumit.saxena@lsi.com>
Signed-off-by: default avatarKashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent d46a3ad6
......@@ -189,6 +189,12 @@
#define MR_DCMD_CLUSTER_RESET_LD 0x08010200
#define MR_DCMD_PD_LIST_QUERY 0x02010100
/*
* Global functions
*/
extern u8 MR_ValidateMapInfo(struct megasas_instance *instance);
/*
* MFI command completion codes
*/
......@@ -729,8 +735,126 @@ struct megasas_ctrl_info {
*/
char package_version[0x60];
u8 pad[0x800 - 0x6a0];
/*
* If adapterOperations.supportMoreThan8Phys is set,
* and deviceInterface.portCount is greater than 8,
* SAS Addrs for first 8 ports shall be populated in
* deviceInterface.portAddr, and the rest shall be
* populated in deviceInterfacePortAddr2.
*/
u64 deviceInterfacePortAddr2[8]; /*6a0h */
u8 reserved3[128]; /*6e0h */
struct { /*760h */
u16 minPdRaidLevel_0:4;
u16 maxPdRaidLevel_0:12;
u16 minPdRaidLevel_1:4;
u16 maxPdRaidLevel_1:12;
u16 minPdRaidLevel_5:4;
u16 maxPdRaidLevel_5:12;
u16 minPdRaidLevel_1E:4;
u16 maxPdRaidLevel_1E:12;
u16 minPdRaidLevel_6:4;
u16 maxPdRaidLevel_6:12;
u16 minPdRaidLevel_10:4;
u16 maxPdRaidLevel_10:12;
u16 minPdRaidLevel_50:4;
u16 maxPdRaidLevel_50:12;
u16 minPdRaidLevel_60:4;
u16 maxPdRaidLevel_60:12;
u16 minPdRaidLevel_1E_RLQ0:4;
u16 maxPdRaidLevel_1E_RLQ0:12;
u16 minPdRaidLevel_1E0_RLQ0:4;
u16 maxPdRaidLevel_1E0_RLQ0:12;
u16 reserved[6];
} pdsForRaidLevels;
u16 maxPds; /*780h */
u16 maxDedHSPs; /*782h */
u16 maxGlobalHSPs; /*784h */
u16 ddfSize; /*786h */
u8 maxLdsPerArray; /*788h */
u8 partitionsInDDF; /*789h */
u8 lockKeyBinding; /*78ah */
u8 maxPITsPerLd; /*78bh */
u8 maxViewsPerLd; /*78ch */
u8 maxTargetId; /*78dh */
u16 maxBvlVdSize; /*78eh */
u16 maxConfigurableSSCSize; /*790h */
u16 currentSSCsize; /*792h */
char expanderFwVersion[12]; /*794h */
u16 PFKTrialTimeRemaining; /*7A0h */
u16 cacheMemorySize; /*7A2h */
struct { /*7A4h */
u32 supportPIcontroller:1;
u32 supportLdPIType1:1;
u32 supportLdPIType2:1;
u32 supportLdPIType3:1;
u32 supportLdBBMInfo:1;
u32 supportShieldState:1;
u32 blockSSDWriteCacheChange:1;
u32 supportSuspendResumeBGops:1;
u32 supportEmergencySpares:1;
u32 supportSetLinkSpeed:1;
u32 supportBootTimePFKChange:1;
u32 supportJBOD:1;
u32 disableOnlinePFKChange:1;
u32 supportPerfTuning:1;
u32 supportSSDPatrolRead:1;
u32 realTimeScheduler:1;
u32 supportResetNow:1;
u32 supportEmulatedDrives:1;
u32 headlessMode:1;
u32 dedicatedHotSparesLimited:1;
u32 supportUnevenSpans:1;
u32 reserved:11;
} adapterOperations2;
u8 driverVersion[32]; /*7A8h */
u8 maxDAPdCountSpinup60; /*7C8h */
u8 temperatureROC; /*7C9h */
u8 temperatureCtrl; /*7CAh */
u8 reserved4; /*7CBh */
u16 maxConfigurablePds; /*7CCh */
u8 reserved5[2]; /*0x7CDh */
/*
* HA cluster information
*/
struct {
u32 peerIsPresent:1;
u32 peerIsIncompatible:1;
u32 hwIncompatible:1;
u32 fwVersionMismatch:1;
u32 ctrlPropIncompatible:1;
u32 premiumFeatureMismatch:1;
u32 reserved:26;
} cluster;
char clusterId[16]; /*7D4h */
u8 pad[0x800-0x7E4]; /*7E4 */
} __packed;
/*
......@@ -1389,6 +1513,7 @@ struct megasas_instance {
u8 flag_ieee;
u8 issuepend_done;
u8 disableOnlineCtrlReset;
u8 UnevenSpanSupport;
u8 adprecovery;
unsigned long last_time;
u32 mfiStatus;
......
......@@ -171,8 +171,6 @@ megasas_sync_map_info(struct megasas_instance *instance);
int
wait_and_poll(struct megasas_instance *instance, struct megasas_cmd *cmd);
void megasas_reset_reply_desc(struct megasas_instance *instance);
u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo);
int megasas_reset_fusion(struct Scsi_Host *shost);
void megasas_fusion_ocr_wq(struct work_struct *work);
......@@ -2295,6 +2293,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
/* Check for LD map update */
if ((cmd->frame->dcmd.opcode == MR_DCMD_LD_MAP_GET_INFO) &&
(cmd->frame->dcmd.mbox.b[1] == 1)) {
fusion->fast_path_io = 0;
spin_lock_irqsave(instance->host->host_lock, flags);
if (cmd->frame->hdr.cmd_status != 0) {
if (cmd->frame->hdr.cmd_status !=
......@@ -2312,9 +2311,13 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
} else
instance->map_id++;
megasas_return_cmd(instance, cmd);
if (MR_ValidateMapInfo(
fusion->ld_map[(instance->map_id & 1)],
fusion->load_balance_info))
/*
* Set fast path IO to ZERO.
* Validate Map will set proper value.
* Meanwhile all IOs will go as LD IO.
*/
if (MR_ValidateMapInfo(instance))
fusion->fast_path_io = 1;
else
fusion->fast_path_io = 0;
......@@ -3661,6 +3664,18 @@ static int megasas_init_fw(struct megasas_instance *instance)
tmp_sectors = min_t(u32, max_sectors_1 , max_sectors_2);
instance->disableOnlineCtrlReset =
ctrl_info->properties.OnOffProperties.disableOnlineCtrlReset;
instance->UnevenSpanSupport =
ctrl_info->adapterOperations2.supportUnevenSpans;
if (instance->UnevenSpanSupport) {
struct fusion_context *fusion = instance->ctrl_context;
dev_info(&instance->pdev->dev, "FW supports: "
"UnevenSpanSupport=%x\n", instance->UnevenSpanSupport);
if (MR_ValidateMapInfo(instance))
fusion->fast_path_io = 1;
else
fusion->fast_path_io = 0;
}
}
instance->max_sectors_per_req = instance->max_num_sge *
......@@ -4202,6 +4217,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
instance->unload = 1;
instance->last_time = 0;
instance->disableOnlineCtrlReset = 1;
instance->UnevenSpanSupport = 0;
if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) ||
(instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
......
This diff is collapsed.
......@@ -86,8 +86,6 @@ u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map);
void
megasas_check_and_restore_queue_depth(struct megasas_instance *instance);
u8 MR_ValidateMapInfo(struct MR_FW_RAID_MAP_ALL *map,
struct LD_LOAD_BALANCE_INFO *lbInfo);
u16 get_updated_dev_handle(struct LD_LOAD_BALANCE_INFO *lbInfo,
struct IO_REQUEST_INFO *in_info);
int megasas_transition_to_ready(struct megasas_instance *instance, int ocr);
......@@ -782,8 +780,7 @@ megasas_get_map_info(struct megasas_instance *instance)
fusion->fast_path_io = 0;
if (!megasas_get_ld_map_info(instance)) {
if (MR_ValidateMapInfo(fusion->ld_map[(instance->map_id & 1)],
fusion->load_balance_info)) {
if (MR_ValidateMapInfo(instance)) {
fusion->fast_path_io = 1;
return 0;
}
......
......@@ -463,6 +463,7 @@ struct MPI2_IOC_INIT_REQUEST {
/* mrpriv defines */
#define MR_PD_INVALID 0xFFFF
#define MAX_SPAN_DEPTH 8
#define MAX_QUAD_DEPTH MAX_SPAN_DEPTH
#define MAX_RAIDMAP_SPAN_DEPTH (MAX_SPAN_DEPTH)
#define MAX_ROW_SIZE 32
#define MAX_RAIDMAP_ROW_SIZE (MAX_ROW_SIZE)
......@@ -504,7 +505,9 @@ struct MR_LD_SPAN {
u64 startBlk;
u64 numBlks;
u16 arrayRef;
u8 reserved[6];
u8 spanRowSize;
u8 spanRowDataSize;
u8 reserved[4];
};
struct MR_SPAN_BLOCK_INFO {
......@@ -590,6 +593,10 @@ struct IO_REQUEST_INFO {
u16 devHandle;
u64 pdBlock;
u8 fpOkForIo;
u8 IoforUnevenSpan;
u8 start_span;
u8 reserved;
u64 start_row;
};
struct MR_LD_TARGET_SYNC {
......@@ -651,6 +658,26 @@ struct LD_LOAD_BALANCE_INFO {
u64 last_accessed_block[2];
};
/* SPAN_SET is info caclulated from span info from Raid map per LD */
typedef struct _LD_SPAN_SET {
u64 log_start_lba;
u64 log_end_lba;
u64 span_row_start;
u64 span_row_end;
u64 data_strip_start;
u64 data_strip_end;
u64 data_row_start;
u64 data_row_end;
u8 strip_offset[MAX_SPAN_DEPTH];
u32 span_row_data_width;
u32 diff;
u32 reserved[2];
} LD_SPAN_SET, *PLD_SPAN_SET;
typedef struct LOG_BLOCK_SPAN_INFO {
LD_SPAN_SET span_set[MAX_SPAN_DEPTH];
} LD_SPAN_INFO, *PLD_SPAN_INFO;
struct MR_FW_RAID_MAP_ALL {
struct MR_FW_RAID_MAP raidMap;
struct MR_LD_SPAN_MAP ldSpanMap[MAX_LOGICAL_DRIVES - 1];
......@@ -695,6 +722,7 @@ struct fusion_context {
u32 map_sz;
u8 fast_path_io;
struct LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES];
LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES];
};
union desc_value {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment