/* ****************************************************************************** * * 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. * * 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); }