Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 51087a86 authored by Sumit.Saxena@avagotech.com's avatar Sumit.Saxena@avagotech.com Committed by Christoph Hellwig
Browse files

megaraid_sas : Extended VD support



Resending the patch. Addressed the review comments from Tomas Henzl.
reserved1 field(part of union) of Raid map struct was not required so it is removed.

Current MegaRAID firmware and hence the driver only supported 64VDs.
E.g: If the user wants to create more than 64VD on a controller,
    it is not possible on current firmware/driver.

New feature and requirement to support upto 256VD, firmware/driver/apps need changes.
In addition to that there must be a backward compatibility of the new driver with the
older firmware and vice versa.

RAID map is the interface between Driver and FW to fetch all required
fields(attributes) for each Virtual Drives.
In the earlier design driver was using the FW copy of RAID map where as
in the new design the Driver will keep the RAID map copy of its own; on which
it will operate for any raid map access in fast path.

Local driver raid map copy will provide ease of access through out the code
and provide generic interface for future FW raid map changes.

For the backward compatibility driver will notify FW that it supports 256VD
to the FW in driver capability field.
Based on the controller properly returned by the FW, the Driver will know
whether it supports 256VD or not and will copy the RAID map accordingly.

At any given time, driver will always have old or new Raid map.
So with this changes, driver can also work in host lock less mode. Please
see next patch which enable host lock less mode for megaraid_sas driver.

Signed-off-by: default avatarSumit Saxena <sumit.saxena@avagotech.com>
Signed-off-by: default avatarKashyap Desai <kashyap.desai@avagotech.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
parent fc62b3fc
Loading
Loading
Loading
Loading
+55 −18
Original line number Diff line number Diff line
@@ -390,7 +390,6 @@ enum MR_LD_QUERY_TYPE {
#define MR_EVT_FOREIGN_CFG_IMPORTED                     0x00db
#define MR_EVT_LD_OFFLINE                               0x00fc
#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED             0x0152
#define MAX_LOGICAL_DRIVES				64

enum MR_PD_STATE {
	MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
@@ -468,14 +467,14 @@ struct MR_LD_LIST {
		u8          state;
		u8          reserved[3];
		u64         size;
	} ldList[MAX_LOGICAL_DRIVES];
	} ldList[MAX_LOGICAL_DRIVES_EXT];
} __packed;

struct MR_LD_TARGETID_LIST {
	u32	size;
	u32	count;
	u8	pad[3];
	u8	targetId[MAX_LOGICAL_DRIVES];
	u8	targetId[MAX_LOGICAL_DRIVES_EXT];
};


@@ -941,6 +940,15 @@ struct megasas_ctrl_info {
	* HA cluster information
	*/
	struct {
#if defined(__BIG_ENDIAN_BITFIELD)
		u32     reserved:26;
		u32     premiumFeatureMismatch:1;
		u32     ctrlPropIncompatible:1;
		u32     fwVersionMismatch:1;
		u32     hwIncompatible:1;
		u32     peerIsIncompatible:1;
		u32     peerIsPresent:1;
#else
		u32     peerIsPresent:1;
		u32     peerIsIncompatible:1;
		u32     hwIncompatible:1;
@@ -948,6 +956,7 @@ struct megasas_ctrl_info {
		u32     ctrlPropIncompatible:1;
		u32     premiumFeatureMismatch:1;
		u32     reserved:26;
#endif
	} cluster;

	char clusterId[16];                     /*7D4h */
@@ -962,9 +971,17 @@ struct megasas_ctrl_info {
#if defined(__BIG_ENDIAN_BITFIELD)
		u32     reserved:25;
		u32     supportCrashDump:1;
		u32     reserved1:6;
		u32     supportMaxExtLDs:1;
		u32     supportT10RebuildAssist:1;
		u32     supportDisableImmediateIO:1;
		u32     supportThermalPollInterval:1;
		u32     supportPersonalityChange:2;
#else
		u32     reserved1:6;
		u32     supportPersonalityChange:2;
		u32     supportThermalPollInterval:1;
		u32     supportDisableImmediateIO:1;
		u32     supportT10RebuildAssist:1;
		u32     supportMaxExtLDs:1;
		u32     supportCrashDump:1;
		u32     reserved:25;
#endif
@@ -979,13 +996,12 @@ struct megasas_ctrl_info {
 * ===============================
 */
#define MEGASAS_MAX_PD_CHANNELS			2
#define MEGASAS_MAX_LD_CHANNELS			1
#define MEGASAS_MAX_LD_CHANNELS			2
#define MEGASAS_MAX_CHANNELS			(MEGASAS_MAX_PD_CHANNELS + \
						MEGASAS_MAX_LD_CHANNELS)
#define MEGASAS_MAX_DEV_PER_CHANNEL		128
#define MEGASAS_DEFAULT_INIT_ID			-1
#define MEGASAS_MAX_LUN				8
#define MEGASAS_MAX_LD				64
#define MEGASAS_DEFAULT_CMD_PER_LUN		256
#define MEGASAS_MAX_PD                          (MEGASAS_MAX_PD_CHANNELS * \
						MEGASAS_MAX_DEV_PER_CHANNEL)
@@ -998,6 +1014,8 @@ struct megasas_ctrl_info {

#define MEGASAS_FW_BUSY				1

#define VD_EXT_DEBUG 0

/* Frame Type */
#define IO_FRAME				0
#define PTHRU_FRAME				1
@@ -1170,13 +1188,17 @@ union megasas_sgl_frame {
typedef union _MFI_CAPABILITIES {
	struct {
#if   defined(__BIG_ENDIAN_BITFIELD)
		u32     reserved:30;
		u32     reserved:28;
		u32	support_max_255lds:1;
		u32	reserved1:1;
		u32     support_additional_msix:1;
		u32     support_fp_remote_lun:1;
#else
		u32     support_fp_remote_lun:1;
		u32     support_additional_msix:1;
		u32     reserved:30;
		u32	reserved1:1;
		u32	support_max_255lds:1;
		u32     reserved:28;
#endif
	} mfi_capabilities;
	u32     reg;
@@ -1665,6 +1687,14 @@ struct megasas_instance {
	u8 issuepend_done;
	u8 disableOnlineCtrlReset;
	u8 UnevenSpanSupport;

	u8 supportmax256vd;
	u16 fw_supported_vd_count;
	u16 fw_supported_pd_count;

	u16 drv_supported_vd_count;
	u16 drv_supported_pd_count;

	u8 adprecovery;
	unsigned long last_time;
	u32 mfiStatus;
@@ -1674,6 +1704,8 @@ struct megasas_instance {

	/* Ptr to hba specific information */
	void *ctrl_context;
	u32 ctrl_context_pages;
	struct megasas_ctrl_info *ctrl_info;
	unsigned int msix_vectors;
	struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES];
	struct megasas_irq_context irq_context[MEGASAS_MAX_MSIX_QUEUES];
@@ -1874,16 +1906,21 @@ u8
MR_BuildRaidContext(struct megasas_instance *instance,
		    struct IO_REQUEST_INFO *io_info,
		    struct RAID_CONTEXT *pRAID_Context,
		    struct MR_FW_RAID_MAP_ALL *map, u8 **raidLUN);
u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map);
struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map);
u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_FW_RAID_MAP_ALL *map);
u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_FW_RAID_MAP_ALL *map);
u16 MR_PdDevHandleGet(u32 pd, struct MR_FW_RAID_MAP_ALL *map);
u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map);

		    struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN);
u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map);
struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map);
u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map);

void mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
	struct LD_LOAD_BALANCE_INFO *lbInfo);
int megasas_get_ctrl_info(struct megasas_instance *instance,
	struct megasas_ctrl_info *ctrl_info);
int megasas_set_crash_dump_params(struct megasas_instance *instance,
	u8 crash_buf_state);
void megasas_free_host_crash_buffer(struct megasas_instance *instance);
void megasas_fusion_crash_dump_wq(struct work_struct *work);

#endif				/*LSI_MEGARAID_SAS_H */
+120 −85
Original line number Diff line number Diff line
@@ -1581,7 +1581,8 @@ megasas_queue_command_lck(struct scsi_cmnd *scmd, void (*done) (struct scsi_cmnd
	scmd->result = 0;

	if (MEGASAS_IS_LOGICAL(scmd) &&
	    (scmd->device->id >= MEGASAS_MAX_LD || scmd->device->lun)) {
	    (scmd->device->id >= instance->fw_supported_vd_count ||
		scmd->device->lun)) {
		scmd->result = DID_BAD_TARGET << 16;
		goto out_done;
	}
@@ -3846,6 +3847,8 @@ megasas_get_ld_list(struct megasas_instance *instance)
	memset(ci, 0, sizeof(*ci));
	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

	if (instance->supportmax256vd)
		dcmd->mbox.b[0] = 1;
	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = 0xFF;
	dcmd->sge_count = 1;
@@ -3867,8 +3870,8 @@ megasas_get_ld_list(struct megasas_instance *instance)

	/* the following function will get the instance PD LIST */

	if ((ret == 0) && (ld_count <= MAX_LOGICAL_DRIVES)) {
		memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
	if ((ret == 0) && (ld_count <= instance->fw_supported_vd_count)) {
		memset(instance->ld_ids, 0xff, MAX_LOGICAL_DRIVES_EXT);

		for (ld_index = 0; ld_index < ld_count; ld_index++) {
			if (ci->ldList[ld_index].state != 0) {
@@ -3931,6 +3934,8 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
	memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

	dcmd->mbox.b[0] = query_type;
	if (instance->supportmax256vd)
		dcmd->mbox.b[2] = 1;

	dcmd->cmd = MFI_CMD_DCMD;
	dcmd->cmd_status = 0xFF;
@@ -3952,7 +3957,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)

	tgtid_count = le32_to_cpu(ci->count);

	if ((ret == 0) && (tgtid_count <= (MAX_LOGICAL_DRIVES))) {
	if ((ret == 0) && (tgtid_count <= (instance->fw_supported_vd_count))) {
		memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS);
		for (ld_index = 0; ld_index < tgtid_count; ld_index++) {
			ids = ci->targetId[ld_index];
@@ -3978,7 +3983,7 @@ megasas_ld_list_query(struct megasas_instance *instance, u8 query_type)
 * This information is mainly used to find out the maximum IO transfer per
 * command supported by the FW.
 */
static int
int
megasas_get_ctrl_info(struct megasas_instance *instance,
		      struct megasas_ctrl_info *ctrl_info)
{
@@ -4019,6 +4024,7 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
	dcmd->opcode = cpu_to_le32(MR_DCMD_CTRL_GET_INFO);
	dcmd->sgl.sge32[0].phys_addr = cpu_to_le32(ci_h);
	dcmd->sgl.sge32[0].length = cpu_to_le32(sizeof(struct megasas_ctrl_info));
	dcmd->mbox.b[0] = 1;

	if (!megasas_issue_polled(instance, cmd)) {
		ret = 0;
@@ -4217,6 +4223,13 @@ megasas_init_adapter_mfi(struct megasas_instance *instance)
	if (megasas_issue_init_mfi(instance))
		goto fail_fw_init;

	if (megasas_get_ctrl_info(instance, instance->ctrl_info)) {
		dev_err(&instance->pdev->dev, "(%d): Could get controller info "
			"Fail from %s %d\n", instance->unique_id,
			__func__, __LINE__);
		goto fail_fw_init;
	}

	instance->fw_support_ieee = 0;
	instance->fw_support_ieee =
		(instance->instancet->read_fw_status_reg(reg_set) &
@@ -4255,7 +4268,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
	u32 tmp_sectors, msix_enable, scratch_pad_2;
	resource_size_t base_addr;
	struct megasas_register_set __iomem *reg_set;
	struct megasas_ctrl_info *ctrl_info;
	struct megasas_ctrl_info *ctrl_info = NULL;
	unsigned long bar_list;
	int i, loop, fw_msix_count = 0;
	struct IOV_111 *iovPtr;
@@ -4386,6 +4399,17 @@ static int megasas_init_fw(struct megasas_instance *instance)
			instance->msix_vectors);
	}

	instance->ctrl_info = kzalloc(sizeof(struct megasas_ctrl_info),
				GFP_KERNEL);
	if (instance->ctrl_info == NULL)
		goto fail_init_adapter;

	/*
	 * Below are default value for legacy Firmware.
	 * non-fusion based controllers
	 */
	instance->fw_supported_vd_count = MAX_LOGICAL_DRIVES;
	instance->fw_supported_pd_count = MAX_PHYSICAL_DEVICES;
	/* Get operational params, sge flags, send init cmd to controller */
	if (instance->instancet->init_adapter(instance))
		goto fail_init_adapter;
@@ -4408,8 +4432,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
				  MR_LD_QUERY_TYPE_EXPOSED_TO_HOST))
		megasas_get_ld_list(instance);

	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);

	/*
	 * Compute the max allowed sectors per IO: The controller info has two
	 * limits on max sectors. Driver should use the minimum of these two.
@@ -4420,7 +4442,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
	 * to calculate max_sectors_1. So the number ended up as zero always.
	 */
	tmp_sectors = 0;
	if (ctrl_info && !megasas_get_ctrl_info(instance, ctrl_info)) {
	ctrl_info = instance->ctrl_info;

	max_sectors_1 = (1 << ctrl_info->stripe_sz_ops.min) *
		le16_to_cpu(ctrl_info->max_strips_per_io);
@@ -4450,6 +4472,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
		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))
@@ -4469,7 +4492,7 @@ static int megasas_init_fw(struct megasas_instance *instance)
			iovPtr = (struct IOV_111 *)((unsigned char *)ctrl_info + IOV_111_OFFSET);
			instance->requestorId = iovPtr->requestorId;
		}
			printk(KERN_WARNING "megaraid_sas: I am VF "
		dev_warn(&instance->pdev->dev, "I am VF "
		       "requestorId %d\n", instance->requestorId);
	}

@@ -4493,7 +4516,6 @@ static int megasas_init_fw(struct megasas_instance *instance)
				instance->crash_dump_h);
		instance->crash_dump_buf = NULL;
	}
	}
	instance->max_sectors_per_req = instance->max_num_sge *
						PAGE_SIZE / 512;
	if (tmp_sectors && (instance->max_sectors_per_req > tmp_sectors))
@@ -4540,6 +4562,8 @@ static int megasas_init_fw(struct megasas_instance *instance)

fail_init_adapter:
fail_ready_state:
	kfree(instance->ctrl_info);
	instance->ctrl_info = NULL;
	iounmap(instance->reg_set);

      fail_ioremap:
@@ -4918,6 +4942,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
	struct Scsi_Host *host;
	struct megasas_instance *instance;
	u16 control = 0;
	struct fusion_context *fusion = NULL;

	/* Reset MSI-X in the kdump kernel */
	if (reset_devices) {
@@ -4978,10 +5003,10 @@ static int megasas_probe_one(struct pci_dev *pdev,
	case PCI_DEVICE_ID_LSI_INVADER:
	case PCI_DEVICE_ID_LSI_FURY:
	{
		struct fusion_context *fusion;

		instance->ctrl_context =
			kzalloc(sizeof(struct fusion_context), GFP_KERNEL);
		instance->ctrl_context_pages =
			get_order(sizeof(struct fusion_context));
		instance->ctrl_context = (void *)__get_free_pages(GFP_KERNEL,
				instance->ctrl_context_pages);
		if (!instance->ctrl_context) {
			printk(KERN_DEBUG "megasas: Failed to allocate "
			       "memory for Fusion context info\n");
@@ -4990,6 +5015,8 @@ static int megasas_probe_one(struct pci_dev *pdev,
		fusion = instance->ctrl_context;
		INIT_LIST_HEAD(&fusion->cmd_pool);
		spin_lock_init(&fusion->cmd_pool_lock);
		memset(fusion->load_balance_info, 0,
			sizeof(struct LD_LOAD_BALANCE_INFO) * MAX_LOGICAL_DRIVES_EXT);
	}
	break;
	default: /* For all other supported controllers */
@@ -5035,7 +5062,6 @@ static int megasas_probe_one(struct pci_dev *pdev,
	instance->issuepend_done = 1;
	instance->adprecovery = MEGASAS_HBA_OPERATIONAL;
	instance->is_imr = 0;
	megasas_poll_wait_aen = 0;

	instance->evt_detail = pci_alloc_consistent(pdev,
						    sizeof(struct
@@ -5072,6 +5098,7 @@ static int megasas_probe_one(struct pci_dev *pdev,
	instance->host = host;
	instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
	instance->init_id = MEGASAS_DEFAULT_INIT_ID;
	instance->ctrl_info = NULL;

	if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
		(instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
@@ -5632,14 +5659,18 @@ static void megasas_detach_one(struct pci_dev *pdev)
	case PCI_DEVICE_ID_LSI_INVADER:
	case PCI_DEVICE_ID_LSI_FURY:
		megasas_release_fusion(instance);
		for (i = 0; i < 2 ; i++)
		for (i = 0; i < 2 ; i++) {
			if (fusion->ld_map[i])
				dma_free_coherent(&instance->pdev->dev,
						  fusion->map_sz,
						  fusion->max_map_sz,
						  fusion->ld_map[i],
						  fusion->
						  ld_map_phys[i]);
		kfree(instance->ctrl_context);
						  fusion->ld_map_phys[i]);
			if (fusion->ld_drv_map[i])
				free_pages((ulong)fusion->ld_drv_map[i],
					fusion->drv_map_pages);
		}
		free_pages((ulong)instance->ctrl_context,
			instance->ctrl_context_pages);
		break;
	default:
		megasas_release_mfi(instance);
@@ -5652,6 +5683,8 @@ static void megasas_detach_one(struct pci_dev *pdev)
		break;
	}

	kfree(instance->ctrl_info);

	if (instance->evt_detail)
		pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
				instance->evt_detail, instance->evt_detail_h);
@@ -5762,8 +5795,10 @@ static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
	spin_lock_irqsave(&poll_aen_lock, flags);
	if (megasas_poll_wait_aen)
		mask =   (POLLIN | POLLRDNORM);

	else
		mask = 0;
	megasas_poll_wait_aen = 0;
	spin_unlock_irqrestore(&poll_aen_lock, flags);
	return mask;
}
+141 −54
Original line number Diff line number Diff line
@@ -66,16 +66,13 @@
#define SPAN_INVALID  0xff

/* Prototypes */
void mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
	struct LD_LOAD_BALANCE_INFO *lbInfo);

static void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map,
static void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map,
	PLD_SPAN_INFO ldSpanInfo);
static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
	u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info,
	struct RAID_CONTEXT *pRAID_Context, struct MR_FW_RAID_MAP_ALL *map);
	struct RAID_CONTEXT *pRAID_Context, struct MR_DRV_RAID_MAP_ALL *map);
static u64 get_row_from_strip(struct megasas_instance *instance, u32 ld,
	u64 strip, struct MR_FW_RAID_MAP_ALL *map);
	u64 strip, struct MR_DRV_RAID_MAP_ALL *map);

u32 mega_mod64(u64 dividend, u32 divisor)
{
@@ -109,94 +106,183 @@ u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
	return d;
}

struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_FW_RAID_MAP_ALL *map)
struct MR_LD_RAID *MR_LdRaidGet(u32 ld, struct MR_DRV_RAID_MAP_ALL *map)
{
	return &map->raidMap.ldSpanMap[ld].ldRaid;
}

static struct MR_SPAN_BLOCK_INFO *MR_LdSpanInfoGet(u32 ld,
						   struct MR_FW_RAID_MAP_ALL
						   struct MR_DRV_RAID_MAP_ALL
						   *map)
{
	return &map->raidMap.ldSpanMap[ld].spanBlock[0];
}

static u8 MR_LdDataArmGet(u32 ld, u32 armIdx, struct MR_FW_RAID_MAP_ALL *map)
static u8 MR_LdDataArmGet(u32 ld, u32 armIdx, struct MR_DRV_RAID_MAP_ALL *map)
{
	return map->raidMap.ldSpanMap[ld].dataArmMap[armIdx];
}

u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_FW_RAID_MAP_ALL *map)
u16 MR_ArPdGet(u32 ar, u32 arm, struct MR_DRV_RAID_MAP_ALL *map)
{
	return le16_to_cpu(map->raidMap.arMapInfo[ar].pd[arm]);
}

u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_FW_RAID_MAP_ALL *map)
u16 MR_LdSpanArrayGet(u32 ld, u32 span, struct MR_DRV_RAID_MAP_ALL *map)
{
	return le16_to_cpu(map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef);
}

u16 MR_PdDevHandleGet(u32 pd, struct MR_FW_RAID_MAP_ALL *map)
u16 MR_PdDevHandleGet(u32 pd, struct MR_DRV_RAID_MAP_ALL *map)
{
	return map->raidMap.devHndlInfo[pd].curDevHdl;
}

u16 MR_GetLDTgtId(u32 ld, struct MR_FW_RAID_MAP_ALL *map)
u16 MR_GetLDTgtId(u32 ld, struct MR_DRV_RAID_MAP_ALL *map)
{
	return le16_to_cpu(map->raidMap.ldSpanMap[ld].ldRaid.targetId);
}

u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_FW_RAID_MAP_ALL *map)
u8 MR_TargetIdToLdGet(u32 ldTgtId, struct MR_DRV_RAID_MAP_ALL *map)
{
	return map->raidMap.ldTgtIdToLd[ldTgtId];
}

static struct MR_LD_SPAN *MR_LdSpanPtrGet(u32 ld, u32 span,
					  struct MR_FW_RAID_MAP_ALL *map)
					  struct MR_DRV_RAID_MAP_ALL *map)
{
	return &map->raidMap.ldSpanMap[ld].spanBlock[span].span;
}

/*
 * This function will Populate Driver Map using firmware raid map
 */
void MR_PopulateDrvRaidMap(struct megasas_instance *instance)
{
	struct fusion_context *fusion = instance->ctrl_context;
	struct MR_FW_RAID_MAP_ALL     *fw_map_old    = NULL;
	struct MR_FW_RAID_MAP         *pFwRaidMap    = NULL;
	int i;


	struct MR_DRV_RAID_MAP_ALL *drv_map =
			fusion->ld_drv_map[(instance->map_id & 1)];
	struct MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap;

	if (instance->supportmax256vd) {
		memcpy(fusion->ld_drv_map[instance->map_id & 1],
			fusion->ld_map[instance->map_id & 1],
			fusion->current_map_sz);
		/* New Raid map will not set totalSize, so keep expected value
		 * for legacy code in ValidateMapInfo
		 */
		pDrvRaidMap->totalSize = sizeof(struct MR_FW_RAID_MAP_EXT);
	} else {
		fw_map_old = (struct MR_FW_RAID_MAP_ALL *)
			fusion->ld_map[(instance->map_id & 1)];
		pFwRaidMap = &fw_map_old->raidMap;

#if VD_EXT_DEBUG
		for (i = 0; i < pFwRaidMap->ldCount; i++) {
			dev_dbg(&instance->pdev->dev, "(%d) :Index 0x%x "
				"Target Id 0x%x Seq Num 0x%x Size 0/%llx\n",
				instance->unique_id, i,
				fw_map_old->raidMap.ldSpanMap[i].ldRaid.targetId,
				fw_map_old->raidMap.ldSpanMap[i].ldRaid.seqNum,
				fw_map_old->raidMap.ldSpanMap[i].ldRaid.size);
		}
#endif

		memset(drv_map, 0, fusion->drv_map_sz);
		pDrvRaidMap->totalSize = pFwRaidMap->totalSize;
		pDrvRaidMap->ldCount = pFwRaidMap->ldCount;
		pDrvRaidMap->fpPdIoTimeoutSec = pFwRaidMap->fpPdIoTimeoutSec;
		for (i = 0; i < MAX_RAIDMAP_LOGICAL_DRIVES + MAX_RAIDMAP_VIEWS; i++)
			pDrvRaidMap->ldTgtIdToLd[i] =
				(u8)pFwRaidMap->ldTgtIdToLd[i];
		for (i = 0; i < pDrvRaidMap->ldCount; i++) {
			pDrvRaidMap->ldSpanMap[i] = pFwRaidMap->ldSpanMap[i];
#if VD_EXT_DEBUG
			dev_dbg(&instance->pdev->dev,
				"pFwRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x "
				"pFwRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x "
				"size 0x%x\n", i, i,
				pFwRaidMap->ldSpanMap[i].ldRaid.targetId,
				pFwRaidMap->ldSpanMap[i].ldRaid.seqNum,
				(u32)pFwRaidMap->ldSpanMap[i].ldRaid.rowSize);
			dev_dbg(&instance->pdev->dev,
				"pDrvRaidMap->ldSpanMap[%d].ldRaid.targetId 0x%x "
				"pDrvRaidMap->ldSpanMap[%d].ldRaid.seqNum 0x%x "
				"size 0x%x\n", i, i,
				pDrvRaidMap->ldSpanMap[i].ldRaid.targetId,
				pDrvRaidMap->ldSpanMap[i].ldRaid.seqNum,
				(u32)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize);
			dev_dbg(&instance->pdev->dev, "Driver raid map all %p "
				"raid map %p LD RAID MAP %p/%p\n", drv_map,
				pDrvRaidMap, &pFwRaidMap->ldSpanMap[i].ldRaid,
				&pDrvRaidMap->ldSpanMap[i].ldRaid);
#endif
		}
		memcpy(pDrvRaidMap->arMapInfo, pFwRaidMap->arMapInfo,
			sizeof(struct MR_ARRAY_INFO) * MAX_RAIDMAP_ARRAYS);
		memcpy(pDrvRaidMap->devHndlInfo, pFwRaidMap->devHndlInfo,
			sizeof(struct MR_DEV_HANDLE_INFO) *
			MAX_RAIDMAP_PHYSICAL_DEVICES);
	}
}

/*
 * This function will validate Map info data provided by FW
 */
u8 MR_ValidateMapInfo(struct megasas_instance *instance)
{
	struct fusion_context *fusion = instance->ctrl_context;
	struct MR_FW_RAID_MAP_ALL *map = fusion->ld_map[(instance->map_id & 1)];
	struct LD_LOAD_BALANCE_INFO *lbInfo = fusion->load_balance_info;
	PLD_SPAN_INFO ldSpanInfo = fusion->log_to_span;
	struct MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap;
	struct fusion_context *fusion;
	struct MR_DRV_RAID_MAP_ALL *drv_map;
	struct MR_DRV_RAID_MAP *pDrvRaidMap;
	struct LD_LOAD_BALANCE_INFO *lbInfo;
	PLD_SPAN_INFO ldSpanInfo;
	struct MR_LD_RAID         *raid;
	int ldCount, num_lds;
	u16 ld;
	u32 expected_size;


	if (le32_to_cpu(pFwRaidMap->totalSize) !=
	MR_PopulateDrvRaidMap(instance);

	fusion = instance->ctrl_context;
	drv_map = fusion->ld_drv_map[(instance->map_id & 1)];
	pDrvRaidMap = &drv_map->raidMap;

	lbInfo = fusion->load_balance_info;
	ldSpanInfo = fusion->log_to_span;

	if (instance->supportmax256vd)
		expected_size = sizeof(struct MR_FW_RAID_MAP_EXT);
	else
		expected_size =
			(sizeof(struct MR_FW_RAID_MAP) - sizeof(struct MR_LD_SPAN_MAP) +
	     (sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(pFwRaidMap->ldCount)))) {
		printk(KERN_ERR "megasas: map info structure size 0x%x is not matching with ld count\n",
		       (unsigned int)((sizeof(struct MR_FW_RAID_MAP) -
				       sizeof(struct MR_LD_SPAN_MAP)) +
				      (sizeof(struct MR_LD_SPAN_MAP) *
					le32_to_cpu(pFwRaidMap->ldCount))));
		printk(KERN_ERR "megasas: span map %x, pFwRaidMap->totalSize "
		       ": %x\n", (unsigned int)sizeof(struct MR_LD_SPAN_MAP),
			le32_to_cpu(pFwRaidMap->totalSize));
			(sizeof(struct MR_LD_SPAN_MAP) * le32_to_cpu(pDrvRaidMap->ldCount)));

	if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) {
		dev_err(&instance->pdev->dev, "map info structure size 0x%x is not matching with ld count\n",
		       (unsigned int) expected_size);
		dev_err(&instance->pdev->dev, "megasas: span map %x, pDrvRaidMap->totalSize : %x\n",
			(unsigned int)sizeof(struct MR_LD_SPAN_MAP),
			le32_to_cpu(pDrvRaidMap->totalSize));
		return 0;
	}

	if (instance->UnevenSpanSupport)
		mr_update_span_set(map, ldSpanInfo);
		mr_update_span_set(drv_map, ldSpanInfo);

	mr_update_load_balance_params(map, lbInfo);
	mr_update_load_balance_params(drv_map, lbInfo);

	num_lds = le32_to_cpu(map->raidMap.ldCount);
	num_lds = le32_to_cpu(drv_map->raidMap.ldCount);

	/*Convert Raid capability values to CPU arch */
	for (ldCount = 0; ldCount < num_lds; ldCount++) {
		ld = MR_TargetIdToLdGet(ldCount, map);
		raid = MR_LdRaidGet(ld, map);
		ld = MR_TargetIdToLdGet(ldCount, drv_map);
		raid = MR_LdRaidGet(ld, drv_map);
		le32_to_cpus((u32 *)&raid->capability);
	}

@@ -204,7 +290,7 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance)
}

u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
		    struct MR_FW_RAID_MAP_ALL *map)
		    struct MR_DRV_RAID_MAP_ALL *map)
{
	struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
	struct MR_QUAD_ELEMENT    *quad;
@@ -246,7 +332,8 @@ u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
* ldSpanInfo - ldSpanInfo per HBA instance
*/
#if SPAN_DEBUG
static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo)
static int getSpanInfo(struct MR_DRV_RAID_MAP_ALL *map,
	PLD_SPAN_INFO ldSpanInfo)
{

	u8   span;
@@ -257,9 +344,9 @@ static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo)
	int ldCount;
	u16 ld;

	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) {
		ld = MR_TargetIdToLdGet(ldCount, map);
			if (ld >= MAX_LOGICAL_DRIVES)
			if (ld >= MAX_LOGICAL_DRIVES_EXT)
				continue;
		raid = MR_LdRaidGet(ld, map);
		dev_dbg(&instance->pdev->dev, "LD %x: span_depth=%x\n",
@@ -339,7 +426,7 @@ static int getSpanInfo(struct MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo)
*/

u32 mr_spanset_get_span_block(struct megasas_instance *instance,
		u32 ld, u64 row, u64 *span_blk, struct MR_FW_RAID_MAP_ALL *map)
		u32 ld, u64 row, u64 *span_blk, struct MR_DRV_RAID_MAP_ALL *map)
{
	struct fusion_context *fusion = instance->ctrl_context;
	struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
@@ -402,7 +489,7 @@ u32 mr_spanset_get_span_block(struct megasas_instance *instance,
*/

static u64  get_row_from_strip(struct megasas_instance *instance,
	u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map)
	u32 ld, u64 strip, struct MR_DRV_RAID_MAP_ALL *map)
{
	struct fusion_context *fusion = instance->ctrl_context;
	struct MR_LD_RAID	*raid = MR_LdRaidGet(ld, map);
@@ -471,7 +558,7 @@ static u64 get_row_from_strip(struct megasas_instance *instance,
*/

static u64 get_strip_from_row(struct megasas_instance *instance,
		u32 ld, u64 row, struct MR_FW_RAID_MAP_ALL *map)
		u32 ld, u64 row, struct MR_DRV_RAID_MAP_ALL *map)
{
	struct fusion_context *fusion = instance->ctrl_context;
	struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
@@ -532,7 +619,7 @@ static u64 get_strip_from_row(struct megasas_instance *instance,
*/

static u32 get_arm_from_strip(struct megasas_instance *instance,
	u32 ld, u64 strip, struct MR_FW_RAID_MAP_ALL *map)
	u32 ld, u64 strip, struct MR_DRV_RAID_MAP_ALL *map)
{
	struct fusion_context *fusion = instance->ctrl_context;
	struct MR_LD_RAID         *raid = MR_LdRaidGet(ld, map);
@@ -580,7 +667,7 @@ static u32 get_arm_from_strip(struct megasas_instance *instance,

/* This Function will return Phys arm */
u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
		struct MR_FW_RAID_MAP_ALL *map)
		struct MR_DRV_RAID_MAP_ALL *map)
{
	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
	/* Need to check correct default value */
@@ -624,7 +711,7 @@ u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
		u64 stripRow, u16 stripRef, struct IO_REQUEST_INFO *io_info,
		struct RAID_CONTEXT *pRAID_Context,
		struct MR_FW_RAID_MAP_ALL *map)
		struct MR_DRV_RAID_MAP_ALL *map)
{
	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
	u32     pd, arRef;
@@ -705,7 +792,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld,
u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
		u16 stripRef, struct IO_REQUEST_INFO *io_info,
		struct RAID_CONTEXT *pRAID_Context,
		struct MR_FW_RAID_MAP_ALL *map)
		struct MR_DRV_RAID_MAP_ALL *map)
{
	struct MR_LD_RAID  *raid = MR_LdRaidGet(ld, map);
	u32         pd, arRef;
@@ -794,7 +881,7 @@ u8
MR_BuildRaidContext(struct megasas_instance *instance,
		    struct IO_REQUEST_INFO *io_info,
		    struct RAID_CONTEXT *pRAID_Context,
		    struct MR_FW_RAID_MAP_ALL *map, u8 **raidLUN)
		    struct MR_DRV_RAID_MAP_ALL *map, u8 **raidLUN)
{
	struct MR_LD_RAID  *raid;
	u32         ld, stripSize, stripe_mask;
@@ -1043,7 +1130,7 @@ MR_BuildRaidContext(struct megasas_instance *instance,
* ldSpanInfo - ldSpanInfo per HBA instance
*
*/
void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map,
void mr_update_span_set(struct MR_DRV_RAID_MAP_ALL *map,
			PLD_SPAN_INFO ldSpanInfo)
{
	u8   span, count;
@@ -1056,9 +1143,9 @@ void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map,
	u16 ld;


	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) {
		ld = MR_TargetIdToLdGet(ldCount, map);
		if (ld >= MAX_LOGICAL_DRIVES)
		if (ld >= MAX_LOGICAL_DRIVES_EXT)
			continue;
		raid = MR_LdRaidGet(ld, map);
		for (element = 0; element < MAX_QUAD_DEPTH; element++) {
@@ -1153,16 +1240,16 @@ void mr_update_span_set(struct MR_FW_RAID_MAP_ALL *map,
}

void
mr_update_load_balance_params(struct MR_FW_RAID_MAP_ALL *map,
mr_update_load_balance_params(struct MR_DRV_RAID_MAP_ALL *map,
			      struct LD_LOAD_BALANCE_INFO *lbInfo)
{
	int ldCount;
	u16 ld;
	struct MR_LD_RAID *raid;

	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
	for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) {
		ld = MR_TargetIdToLdGet(ldCount, map);
		if (ld >= MAX_LOGICAL_DRIVES) {
		if (ld >= MAX_LOGICAL_DRIVES_EXT) {
			lbInfo[ldCount].loadBalanceFlag = 0;
			continue;
		}
+94 −24

File changed.

Preview size limit exceeded, changes collapsed.

+90 −4

File changed.

Preview size limit exceeded, changes collapsed.