/* * * This routine calculates the arm, span and block for the specified stripe and * reference in stripe using spanset * * Inputs : * sc - HBA instance * ld - Logical drive number * stripRow: Stripe number * stripRef: Reference in stripe * * Outputs : span - Span number block - Absolute Block * number in the physical disk */ static u_int8_t mr_spanset_get_phy_params(struct mrsas_softc *sc, u_int32_t ld, u_int64_t stripRow, u_int16_t stripRef, struct IO_REQUEST_INFO *io_info, RAID_CONTEXT * pRAID_Context, MR_DRV_RAID_MAP_ALL * map) { MR_LD_RAID *raid = MR_LdRaidGet(ld, map); u_int32_t pd, arRef; u_int8_t physArm, span; u_int64_t row; u_int8_t retval = TRUE; u_int64_t *pdBlock = &io_info->pdBlock; u_int16_t *pDevHandle = &io_info->devHandle; u_int32_t logArm, rowMod, armQ, arm; u_int8_t do_invader = 0; if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY)) do_invader = 1; /* Get row and span from io_info for Uneven Span IO. */ row = io_info->start_row; span = io_info->start_span; if (raid->level == 6) { logArm = get_arm_from_strip(sc, ld, stripRow, map); rowMod = mega_mod64(row, SPAN_ROW_SIZE(map, ld, span)); armQ = SPAN_ROW_SIZE(map, ld, span) - 1 - rowMod; arm = armQ + 1 + logArm; if (arm >= SPAN_ROW_SIZE(map, ld, span)) arm -= SPAN_ROW_SIZE(map, ld, span); physArm = (u_int8_t)arm; } else /* Calculate the arm */ physArm = get_arm(sc, ld, span, stripRow, map); arRef = MR_LdSpanArrayGet(ld, span, map); pd = MR_ArPdGet(arRef, physArm, map); if (pd != MR_PD_INVALID) *pDevHandle = MR_PdDevHandleGet(pd, map); else { *pDevHandle = MR_PD_INVALID; if ((raid->level >= 5) && ((!do_invader) || (do_invader && raid->regTypeReqOnRead != REGION_TYPE_UNUSED))) pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; else if (raid->level == 1) { pd = MR_ArPdGet(arRef, physArm + 1, map); if (pd != MR_PD_INVALID) *pDevHandle = MR_PdDevHandleGet(pd, map); } } *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk; pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; io_info->span_arm = pRAID_Context->spanArm; return retval; }
void mr_update_load_balance_params(MR_FW_RAID_MAP_ALL *map, PLD_LOAD_BALANCE_INFO lbInfo) { int ldCount; U16 ld; MR_LD_RAID *raid; for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { ld = MR_TargetIdToLdGet(ldCount, map); if (ld >= MAX_LOGICAL_DRIVES) { con_log(CL_ANN1, (CE_NOTE, "mrsas: ld=%d Invalid ld \n", ld)); continue; } raid = MR_LdRaidGet(ld, map); /* Two drive Optimal RAID 1 */ if ((raid->level == 1) && (raid->rowSize == 2) && (raid->spanDepth == 1) && raid->ldState == MR_LD_STATE_OPTIMAL) { U32 pd, arRef; lbInfo[ldCount].loadBalanceFlag = 1; /* Get the array on which this span is present. */ arRef = MR_LdSpanArrayGet(ld, 0, map); pd = MR_ArPdGet(arRef, 0, map); /* Get the Pd. */ /* Get dev handle from Pd. */ lbInfo[ldCount].raid1DevHandle[0] = MR_PdDevHandleGet(pd, map); pd = MR_ArPdGet(arRef, 1, map); /* Get the Pd. */ /* Get dev handle from Pd. */ lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map); con_log(CL_ANN1, (CE_NOTE, "mrsas: ld=%d load balancing enabled \n", ldCount)); } else { lbInfo[ldCount].loadBalanceFlag = 0; } } }
void mr_update_load_balance_params(struct MR_FW_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++) { ld = MR_TargetIdToLdGet(ldCount, map); if (ld >= MAX_LOGICAL_DRIVES) { lbInfo[ldCount].loadBalanceFlag = 0; continue; } raid = MR_LdRaidGet(ld, map); /* Two drive Optimal RAID 1 */ if ((raid->level == 1) && (raid->rowSize == 2) && (raid->spanDepth == 1) && raid->ldState == MR_LD_STATE_OPTIMAL) { u32 pd, arRef; lbInfo[ldCount].loadBalanceFlag = 1; /* Get the array on which this span is present */ arRef = MR_LdSpanArrayGet(ld, 0, map); /* Get the Pd */ pd = MR_ArPdGet(arRef, 0, map); /* Get dev handle from Pd */ lbInfo[ldCount].raid1DevHandle[0] = MR_PdDevHandleGet(pd, map); /* Get the Pd */ pd = MR_ArPdGet(arRef, 1, map); /* Get the dev handle from Pd */ lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map); } else lbInfo[ldCount].loadBalanceFlag = 0; } }
/* ****************************************************************************** * * This routine calculates the arm, span and block for the specified stripe and * reference in stripe. * * Inputs : * * ld - Logical drive number * stripRow - Stripe number * stripRef - Reference in stripe * * Outputs : * * span - Span number * block - Absolute Block number in the physical disk */ 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_LD_RAID *raid = MR_LdRaidGet(ld, map); u32 pd, arRef; u8 physArm, span; u64 row; u8 retval = TRUE; u8 do_invader = 0; u64 *pdBlock = &io_info->pdBlock; u16 *pDevHandle = &io_info->devHandle; if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER || instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) do_invader = 1; row = mega_div64_32(stripRow, raid->rowDataSize); if (raid->level == 6) { /* logical arm within row */ u32 logArm = mega_mod64(stripRow, raid->rowDataSize); u32 rowMod, armQ, arm; if (raid->rowSize == 0) return FALSE; /* get logical row mod */ rowMod = mega_mod64(row, raid->rowSize); armQ = raid->rowSize-1-rowMod; /* index of Q drive */ arm = armQ+1+logArm; /* data always logically follows Q */ if (arm >= raid->rowSize) /* handle wrap condition */ arm -= raid->rowSize; physArm = (u8)arm; } else { if (raid->modFactor == 0) return FALSE; physArm = MR_LdDataArmGet(ld, mega_mod64(stripRow, raid->modFactor), map); } if (raid->spanDepth == 1) { span = 0; *pdBlock = row << raid->stripeShift; } else { span = (u8)MR_GetSpanBlock(ld, row, pdBlock, map); if (span == SPAN_INVALID) return FALSE; } /* Get the array on which this span is present */ arRef = MR_LdSpanArrayGet(ld, span, map); pd = MR_ArPdGet(arRef, physArm, map); /* Get the pd */ if (pd != MR_PD_INVALID) /* Get dev handle from Pd. */ *pDevHandle = MR_PdDevHandleGet(pd, map); else { *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */ if ((raid->level >= 5) && (!do_invader || (do_invader && (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; else if (raid->level == 1) { /* Get alternate Pd. */ pd = MR_ArPdGet(arRef, physArm + 1, map); if (pd != MR_PD_INVALID) /* Get dev handle from Pd */ *pDevHandle = MR_PdDevHandleGet(pd, map); } } *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk); pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; return retval; }
/* ****************************************************************************** * * This routine calculates the arm, span and block for the specified stripe and * reference in stripe using spanset * * Inputs : * * ld - Logical drive number * stripRow - Stripe number * stripRef - Reference in stripe * * Outputs : * * span - Span number * block - Absolute Block number in the physical disk */ 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_LD_RAID *raid = MR_LdRaidGet(ld, map); u32 pd, arRef; u8 physArm, span; u64 row; u8 retval = TRUE; u8 do_invader = 0; u64 *pdBlock = &io_info->pdBlock; u16 *pDevHandle = &io_info->devHandle; u32 logArm, rowMod, armQ, arm; if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER || instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) do_invader = 1; /*Get row and span from io_info for Uneven Span IO.*/ row = io_info->start_row; span = io_info->start_span; if (raid->level == 6) { logArm = get_arm_from_strip(instance, ld, stripRow, map); if (logArm == -1U) return FALSE; rowMod = mega_mod64(row, SPAN_ROW_SIZE(map, ld, span)); armQ = SPAN_ROW_SIZE(map, ld, span) - 1 - rowMod; arm = armQ + 1 + logArm; if (arm >= SPAN_ROW_SIZE(map, ld, span)) arm -= SPAN_ROW_SIZE(map, ld, span); physArm = (u8)arm; } else /* Calculate the arm */ physArm = get_arm(instance, ld, span, stripRow, map); if (physArm == 0xFF) return FALSE; arRef = MR_LdSpanArrayGet(ld, span, map); pd = MR_ArPdGet(arRef, physArm, map); if (pd != MR_PD_INVALID) *pDevHandle = MR_PdDevHandleGet(pd, map); else { *pDevHandle = MR_PD_INVALID; if ((raid->level >= 5) && (!do_invader || (do_invader && (raid->regTypeReqOnRead != REGION_TYPE_UNUSED)))) pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; else if (raid->level == 1) { pd = MR_ArPdGet(arRef, physArm + 1, map); if (pd != MR_PD_INVALID) *pDevHandle = MR_PdDevHandleGet(pd, map); } } *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk); pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; return retval; }
/* * ************************************************************* * * This routine calculates the arm, span and block for * the specified stripe and reference in stripe. * * Inputs : * * ld - Logical drive number * stripRow - Stripe number * stripRef - Reference in stripe * * Outputs : * * span - Span number * block - Absolute Block number in the physical disk */ U8 MR_GetPhyParams(struct mrsas_instance *instance, U32 ld, U64 stripRow, U16 stripRef, U64 *pdBlock, U16 *pDevHandle, MPI2_SCSI_IO_VENDOR_UNIQUE *pRAID_Context, MR_FW_RAID_MAP_ALL *map) { MR_LD_RAID *raid = MR_LdRaidGet(ld, map); U32 pd, arRef; U8 physArm, span; U64 row; int error_code = 0; U8 retval = TRUE; U32 rowMod; U32 armQ; U32 arm; U16 devid = instance->device_id; ASSERT(raid->rowDataSize != 0); row = (stripRow / raid->rowDataSize); if (raid->level == 6) { U32 logArm = (stripRow % (raid->rowDataSize)); if (raid->rowSize == 0) { return (FALSE); } rowMod = (row % (raid->rowSize)); armQ = raid->rowSize-1-rowMod; arm = armQ + 1 + logArm; if (arm >= raid->rowSize) arm -= raid->rowSize; physArm = (U8)arm; } else { if (raid->modFactor == 0) return (FALSE); physArm = MR_LdDataArmGet(ld, (stripRow % (raid->modFactor)), map); } if (raid->spanDepth == 1) { span = 0; *pdBlock = row << raid->stripeShift; } else span = (U8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code); if (error_code == 1) return (FALSE); /* Get the array on which this span is present. */ arRef = MR_LdSpanArrayGet(ld, span, map); /* Get the Pd. */ pd = MR_ArPdGet(arRef, physArm, map); /* Get dev handle from Pd. */ if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); } else { *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */ if ((raid->level >= 5) && ((devid != PCI_DEVICE_ID_LSI_INVADER) || ((devid == PCI_DEVICE_ID_LSI_INVADER || (devid == PCI_DEVICE_ID_LSI_FURY)) && raid->regTypeReqOnRead != REGION_TYPE_UNUSED))) { pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE; } else if (raid->level == 1) { /* Get Alternate Pd. */ pd = MR_ArPdGet(arRef, physArm + 1, map); /* Get dev handle from Pd. */ if (pd != MR_PD_INVALID) *pDevHandle = MR_PdDevHandleGet(pd, map); } } *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk; pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; return (retval); }