diff options
author | smh <smh@FreeBSD.org> | 2014-12-21 02:35:22 +0000 |
---|---|---|
committer | smh <smh@FreeBSD.org> | 2014-12-21 02:35:22 +0000 |
commit | 4749aacddd68c5e6f458ef3ab31505bbdc7f5630 (patch) | |
tree | 27d095c1e4733fc868ac6a3f1b64ad8a5c4e5c8b /sys/dev/mrsas/mrsas_fp.c | |
parent | 90167d8975073c532726b475b01d8a7b81094d64 (diff) | |
download | FreeBSD-src-4749aacddd68c5e6f458ef3ab31505bbdc7f5630.zip FreeBSD-src-4749aacddd68c5e6f458ef3ab31505bbdc7f5630.tar.gz |
MFC r272735:
Support upto 256VD.
MFC r272737:
Support 32-bit linux binaries on FreeBSD 64bit.
MFC r272738:
Fix the minor svn add issue.
MFC r272739:
Extended MSI-x vectors support for Invader and Fury(12Gb/s HBA).
MFC r272740:
Add d_poll support.
MFC r272741:
Fix leak of mfi cmd in the passthru and correctly limit oustanding.
MFC r272742:
Import vendor Phase 6.5 driver
MFC r272744:
Style (9) fixes.
MFC r273040:
Fix for build issue on i386.xen and amd64.xen.
Sponsored by: Multiplay
Diffstat (limited to 'sys/dev/mrsas/mrsas_fp.c')
-rw-r--r-- | sys/dev/mrsas/mrsas_fp.c | 2523 |
1 files changed, 1295 insertions, 1228 deletions
diff --git a/sys/dev/mrsas/mrsas_fp.c b/sys/dev/mrsas/mrsas_fp.c index 91005a5..cd0d57f 100644 --- a/sys/dev/mrsas/mrsas_fp.c +++ b/sys/dev/mrsas/mrsas_fp.c @@ -1,43 +1,38 @@ /* - * Copyright (c) 2014, LSI Corp. - * All rights reserved. - * Author: Marian Choy + * Copyright (c) 2014, LSI Corp. All rights reserved. Author: Marian Choy * Support: freebsdraid@lsi.com * * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * modification, are permitted provided that the following conditions are + * met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * 3. Neither the name of the <ORGANIZATION> nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. 2. Redistributions + * in binary form must reproduce the above copyright notice, this list of + * conditions and the following disclaimer in the documentation and/or other + * materials provided with the distribution. 3. Neither the name of the + * <ORGANIZATION> nor the names of its contributors may be used to endorse or + * promote products derived from this software without specific prior written + * permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * The views and conclusions contained in the software and documentation - * are those of the authors and should not be interpreted as representing + * The views and conclusions contained in the software and documentation are + * those of the authors and should not be interpreted as representing * official policies,either expressed or implied, of the FreeBSD Project. * - * Send feedback to: <megaraidfbsd@lsi.com> - * Mail to: LSI Corporation, 1621 Barber Lane, Milpitas, CA 95035 - * ATTN: MegaRaid FreeBSD + * Send feedback to: <megaraidfbsd@lsi.com> Mail to: LSI Corporation, 1621 + * Barber Lane, Milpitas, CA 95035 ATTN: MegaRaid FreeBSD * */ @@ -59,88 +54,106 @@ __FBSDID("$FreeBSD$"); * Function prototypes */ u_int8_t MR_ValidateMapInfo(struct mrsas_softc *sc); -u_int8_t mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm, - u_int64_t block, u_int32_t count); -u_int8_t MR_BuildRaidContext(struct mrsas_softc *sc, - struct IO_REQUEST_INFO *io_info, - RAID_CONTEXT *pRAID_Context, MR_FW_RAID_MAP_ALL *map); -u_int8_t MR_GetPhyParams(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_FW_RAID_MAP_ALL *map); -u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_FW_RAID_MAP_ALL *map); -u_int32_t MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_FW_RAID_MAP_ALL *map); -u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_FW_RAID_MAP_ALL *map); -u_int16_t mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo, - struct IO_REQUEST_INFO *io_info); +u_int8_t +mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm, + u_int64_t block, u_int32_t count); +u_int8_t +MR_BuildRaidContext(struct mrsas_softc *sc, + struct IO_REQUEST_INFO *io_info, + RAID_CONTEXT * pRAID_Context, MR_DRV_RAID_MAP_ALL * map); +u_int8_t +MR_GetPhyParams(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); +u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map); +u_int32_t MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map); +u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map); +u_int16_t +mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo, + struct IO_REQUEST_INFO *io_info); u_int32_t mega_mod64(u_int64_t dividend, u_int32_t divisor); -u_int32_t MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk, - MR_FW_RAID_MAP_ALL *map, int *div_error); +u_int32_t +MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk, + MR_DRV_RAID_MAP_ALL * map, int *div_error); u_int64_t mega_div64_32(u_int64_t dividend, u_int32_t divisor); -void mrsas_update_load_balance_params(MR_FW_RAID_MAP_ALL *map, - PLD_LOAD_BALANCE_INFO lbInfo); -void mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST *io_request, - u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb, - MR_FW_RAID_MAP_ALL *local_map_ptr, u_int32_t ref_tag, - u_int32_t ld_block_size); -static u_int16_t MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span, - MR_FW_RAID_MAP_ALL *map); -static u_int16_t MR_PdDevHandleGet(u_int32_t pd, MR_FW_RAID_MAP_ALL *map); -static u_int16_t MR_ArPdGet(u_int32_t ar, u_int32_t arm, - MR_FW_RAID_MAP_ALL *map); -static MR_LD_SPAN *MR_LdSpanPtrGet(u_int32_t ld, u_int32_t span, - MR_FW_RAID_MAP_ALL *map); -static u_int8_t MR_LdDataArmGet(u_int32_t ld, u_int32_t armIdx, - MR_FW_RAID_MAP_ALL *map); -static MR_SPAN_BLOCK_INFO *MR_LdSpanInfoGet(u_int32_t ld, - MR_FW_RAID_MAP_ALL *map); -MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_FW_RAID_MAP_ALL *map); +void +mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map, + PLD_LOAD_BALANCE_INFO lbInfo); +void +mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, + u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb, + MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag, + u_int32_t ld_block_size); +static u_int16_t +MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span, + MR_DRV_RAID_MAP_ALL * map); +static u_int16_t MR_PdDevHandleGet(u_int32_t pd, MR_DRV_RAID_MAP_ALL * map); +static u_int16_t +MR_ArPdGet(u_int32_t ar, u_int32_t arm, + MR_DRV_RAID_MAP_ALL * map); +static MR_LD_SPAN * +MR_LdSpanPtrGet(u_int32_t ld, u_int32_t span, + MR_DRV_RAID_MAP_ALL * map); +static u_int8_t +MR_LdDataArmGet(u_int32_t ld, u_int32_t armIdx, + MR_DRV_RAID_MAP_ALL * map); +static MR_SPAN_BLOCK_INFO * +MR_LdSpanInfoGet(u_int32_t ld, + MR_DRV_RAID_MAP_ALL * map); +MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map); +void MR_PopulateDrvRaidMap(struct mrsas_softc *sc); + /* - * Spanset related function prototypes - * Added for PRL11 configuration (Uneven span support) + * Spanset related function prototypes Added for PRL11 configuration (Uneven + * span support) */ -void mr_update_span_set(MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo); -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_FW_RAID_MAP_ALL *map); -static u_int64_t get_row_from_strip(struct mrsas_softc *sc, u_int32_t ld, - u_int64_t strip, MR_FW_RAID_MAP_ALL *map); -static u_int32_t mr_spanset_get_span_block(struct mrsas_softc *sc, - u_int32_t ld, u_int64_t row, u_int64_t *span_blk, - MR_FW_RAID_MAP_ALL *map, int *div_error); -static u_int8_t get_arm(struct mrsas_softc *sc, u_int32_t ld, u_int8_t span, - u_int64_t stripe, MR_FW_RAID_MAP_ALL *map); +void mr_update_span_set(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo); +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); +static u_int64_t +get_row_from_strip(struct mrsas_softc *sc, u_int32_t ld, + u_int64_t strip, MR_DRV_RAID_MAP_ALL * map); +static u_int32_t +mr_spanset_get_span_block(struct mrsas_softc *sc, + u_int32_t ld, u_int64_t row, u_int64_t *span_blk, + MR_DRV_RAID_MAP_ALL * map, int *div_error); +static u_int8_t +get_arm(struct mrsas_softc *sc, u_int32_t ld, u_int8_t span, + u_int64_t stripe, MR_DRV_RAID_MAP_ALL * map); /* - * Spanset related defines - * Added for PRL11 configuration(Uneven span support) + * Spanset related defines Added for PRL11 configuration(Uneven span support) */ -#define SPAN_ROW_SIZE(map, ld, index_) MR_LdSpanPtrGet(ld, index_, map)->spanRowSize -#define SPAN_ROW_DATA_SIZE(map_, ld, index_) MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize -#define SPAN_INVALID 0xff -#define SPAN_DEBUG 0 +#define SPAN_ROW_SIZE(map, ld, index_) MR_LdSpanPtrGet(ld, index_, map)->spanRowSize +#define SPAN_ROW_DATA_SIZE(map_, ld, index_) \ + MR_LdSpanPtrGet(ld, index_, map)->spanRowDataSize +#define SPAN_INVALID 0xff +#define SPAN_DEBUG 0 /* * Related Defines */ -typedef u_int64_t REGION_KEY; -typedef u_int32_t REGION_LEN; +typedef u_int64_t REGION_KEY; +typedef u_int32_t REGION_LEN; -#define MR_LD_STATE_OPTIMAL 3 -#define FALSE 0 -#define TRUE 1 +#define MR_LD_STATE_OPTIMAL 3 +#define FALSE 0 +#define TRUE 1 /* * Related Macros */ -#define ABS_DIFF(a,b) ( ((a) > (b)) ? ((a) - (b)) : ((b) - (a)) ) +#define ABS_DIFF(a,b) ( ((a) > (b)) ? ((a) - (b)) : ((b) - (a)) ) -#define swap32(x) \ +#define swap32(x) \ ((unsigned int)( \ (((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \ (((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \ @@ -149,20 +162,20 @@ typedef u_int32_t REGION_LEN; /* - * In-line functions for mod and divide of 64-bit dividend and 32-bit divisor. - * Assumes a check for a divisor of zero is not possible. - * - * @param dividend : Dividend - * @param divisor : Divisor - * @return remainder + * In-line functions for mod and divide of 64-bit dividend and 32-bit + * divisor. Assumes a check for a divisor of zero is not possible. + * + * @param dividend: Dividend + * @param divisor: Divisor + * @return remainder */ -#define mega_mod64(dividend, divisor) ({ \ +#define mega_mod64(dividend, divisor) ({ \ int remainder; \ remainder = ((u_int64_t) (dividend)) % (u_int32_t) (divisor); \ remainder;}) -#define mega_div64_32(dividend, divisor) ({ \ +#define mega_div64_32(dividend, divisor) ({ \ int quotient; \ quotient = ((u_int64_t) (dividend)) / (u_int32_t) (divisor); \ quotient;}) @@ -170,1282 +183,1336 @@ quotient;}) /* * Various RAID map access functions. These functions access the various - * parts of the RAID map and returns the appropriate parameters. + * parts of the RAID map and returns the appropriate parameters. */ -MR_LD_RAID *MR_LdRaidGet(u_int32_t ld, MR_FW_RAID_MAP_ALL *map) +MR_LD_RAID * +MR_LdRaidGet(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map) { - return (&map->raidMap.ldSpanMap[ld].ldRaid); + return (&map->raidMap.ldSpanMap[ld].ldRaid); } -u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_FW_RAID_MAP_ALL *map) +u_int16_t +MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map) { - return (map->raidMap.ldSpanMap[ld].ldRaid.targetId); + return (map->raidMap.ldSpanMap[ld].ldRaid.targetId); } -static u_int16_t MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span, MR_FW_RAID_MAP_ALL *map) +static u_int16_t +MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span, MR_DRV_RAID_MAP_ALL * map) { - return map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef; + return map->raidMap.ldSpanMap[ld].spanBlock[span].span.arrayRef; } -static u_int8_t MR_LdDataArmGet(u_int32_t ld, u_int32_t armIdx, MR_FW_RAID_MAP_ALL *map) +static u_int8_t +MR_LdDataArmGet(u_int32_t ld, u_int32_t armIdx, MR_DRV_RAID_MAP_ALL * map) { - return map->raidMap.ldSpanMap[ld].dataArmMap[armIdx]; + return map->raidMap.ldSpanMap[ld].dataArmMap[armIdx]; } -static u_int16_t MR_PdDevHandleGet(u_int32_t pd, MR_FW_RAID_MAP_ALL *map) +static u_int16_t +MR_PdDevHandleGet(u_int32_t pd, MR_DRV_RAID_MAP_ALL * map) { - return map->raidMap.devHndlInfo[pd].curDevHdl; + return map->raidMap.devHndlInfo[pd].curDevHdl; } -static u_int16_t MR_ArPdGet(u_int32_t ar, u_int32_t arm, MR_FW_RAID_MAP_ALL *map) +static u_int16_t +MR_ArPdGet(u_int32_t ar, u_int32_t arm, MR_DRV_RAID_MAP_ALL * map) { - return map->raidMap.arMapInfo[ar].pd[arm]; + return map->raidMap.arMapInfo[ar].pd[arm]; } -static MR_LD_SPAN *MR_LdSpanPtrGet(u_int32_t ld, u_int32_t span, MR_FW_RAID_MAP_ALL *map) +static MR_LD_SPAN * +MR_LdSpanPtrGet(u_int32_t ld, u_int32_t span, MR_DRV_RAID_MAP_ALL * map) { - return &map->raidMap.ldSpanMap[ld].spanBlock[span].span; + return &map->raidMap.ldSpanMap[ld].spanBlock[span].span; } -static MR_SPAN_BLOCK_INFO *MR_LdSpanInfoGet(u_int32_t ld, MR_FW_RAID_MAP_ALL *map) +static MR_SPAN_BLOCK_INFO * +MR_LdSpanInfoGet(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map) { - return &map->raidMap.ldSpanMap[ld].spanBlock[0]; + return &map->raidMap.ldSpanMap[ld].spanBlock[0]; } -u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_FW_RAID_MAP_ALL *map) +u_int16_t +MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map) { - return map->raidMap.ldTgtIdToLd[ldTgtId]; + return map->raidMap.ldTgtIdToLd[ldTgtId]; } -u_int32_t MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_FW_RAID_MAP_ALL *map) +u_int32_t +MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map) { - MR_LD_RAID *raid; - u_int32_t ld, ldBlockSize = MRSAS_SCSIBLOCKSIZE; + MR_LD_RAID *raid; + u_int32_t ld, ldBlockSize = MRSAS_SCSIBLOCKSIZE; + + ld = MR_TargetIdToLdGet(ldTgtId, map); + + /* + * Check if logical drive was removed. + */ + if (ld >= MAX_LOGICAL_DRIVES) + return ldBlockSize; - ld = MR_TargetIdToLdGet(ldTgtId, map); + raid = MR_LdRaidGet(ld, map); + ldBlockSize = raid->logicalBlockLength; + if (!ldBlockSize) + ldBlockSize = MRSAS_SCSIBLOCKSIZE; - /* - * Check if logical drive was removed. - */ - if (ld >= MAX_LOGICAL_DRIVES) - return ldBlockSize; + return ldBlockSize; +} - raid = MR_LdRaidGet(ld, map); - ldBlockSize = raid->logicalBlockLength; - if (!ldBlockSize) - ldBlockSize = MRSAS_SCSIBLOCKSIZE; +/* + * This function will Populate Driver Map using firmware raid map + */ +void +MR_PopulateDrvRaidMap(struct mrsas_softc *sc) +{ + MR_FW_RAID_MAP_ALL *fw_map_old = NULL; + MR_FW_RAID_MAP *pFwRaidMap = NULL; + unsigned int i; + + MR_DRV_RAID_MAP_ALL *drv_map = sc->ld_drv_map[(sc->map_id & 1)]; + MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap; + + if (sc->max256vdSupport) { + memcpy(sc->ld_drv_map[sc->map_id & 1], + sc->raidmap_mem[sc->map_id & 1], + sc->current_map_sz); + /* + * New Raid map will not set totalSize, so keep expected + * value for legacy code in ValidateMapInfo + */ + pDrvRaidMap->totalSize = sizeof(MR_FW_RAID_MAP_EXT); + } else { + fw_map_old = (MR_FW_RAID_MAP_ALL *) sc->raidmap_mem[(sc->map_id & 1)]; + pFwRaidMap = &fw_map_old->raidMap; + +#if VD_EXT_DEBUG + for (i = 0; i < pFwRaidMap->ldCount; i++) { + device_printf(sc->mrsas_dev, + "Index 0x%x Target Id 0x%x Seq Num 0x%x Size 0/%lx\n", 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, sc->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] = + (u_int8_t)pFwRaidMap->ldTgtIdToLd[i]; + } + + for (i = 0; i < pDrvRaidMap->ldCount; i++) { + pDrvRaidMap->ldSpanMap[i] = + pFwRaidMap->ldSpanMap[i]; + +#if VD_EXT_DEBUG + device_printf(sc->mrsas_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, + (u_int32_t)pFwRaidMap->ldSpanMap[i].ldRaid.rowSize); + device_printf(sc->mrsas_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, + (u_int32_t)pDrvRaidMap->ldSpanMap[i].ldRaid.rowSize); + device_printf(sc->mrsas_dev, "drv 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 + } - return ldBlockSize; + memcpy(pDrvRaidMap->arMapInfo, pFwRaidMap->arMapInfo, + sizeof(MR_ARRAY_INFO) * MAX_RAIDMAP_ARRAYS); + memcpy(pDrvRaidMap->devHndlInfo, pFwRaidMap->devHndlInfo, + sizeof(MR_DEV_HANDLE_INFO) * + MAX_RAIDMAP_PHYSICAL_DEVICES); + } } -/** - * MR_ValidateMapInfo: Validate RAID map - * input: Adapter instance soft state +/* + * MR_ValidateMapInfo: Validate RAID map + * input: Adapter instance soft state * - * This function checks and validates the loaded RAID map. It returns 0 if + * This function checks and validates the loaded RAID map. It returns 0 if * successful, and 1 otherwise. */ -u_int8_t MR_ValidateMapInfo(struct mrsas_softc *sc) +u_int8_t +MR_ValidateMapInfo(struct mrsas_softc *sc) { if (!sc) { return 1; } - uint32_t total_map_sz; - MR_FW_RAID_MAP_ALL *map = sc->raidmap_mem[(sc->map_id & 1)]; - MR_FW_RAID_MAP *pFwRaidMap = &map->raidMap; - PLD_SPAN_INFO ldSpanInfo = (PLD_SPAN_INFO) &sc->log_to_span; - - total_map_sz = (sizeof(MR_FW_RAID_MAP) - sizeof(MR_LD_SPAN_MAP) + - (sizeof(MR_LD_SPAN_MAP) * pFwRaidMap->ldCount)); - - if (pFwRaidMap->totalSize != total_map_sz) { - device_printf(sc->mrsas_dev, "map size %x not matching ld count\n", total_map_sz); - device_printf(sc->mrsas_dev, "span map= %x\n", (unsigned int)sizeof(MR_LD_SPAN_MAP)); - device_printf(sc->mrsas_dev, "pFwRaidMap->totalSize=%x\n", pFwRaidMap->totalSize); - return 1; - } - - if (sc->UnevenSpanSupport) { - mr_update_span_set(map, ldSpanInfo); - } + MR_PopulateDrvRaidMap(sc); + + MR_DRV_RAID_MAP_ALL *drv_map = sc->ld_drv_map[(sc->map_id & 1)]; + MR_DRV_RAID_MAP *pDrvRaidMap = &drv_map->raidMap; + + u_int32_t expected_map_size; + + drv_map = sc->ld_drv_map[(sc->map_id & 1)]; + pDrvRaidMap = &drv_map->raidMap; + PLD_SPAN_INFO ldSpanInfo = (PLD_SPAN_INFO) & sc->log_to_span; + + if (sc->max256vdSupport) + expected_map_size = sizeof(MR_FW_RAID_MAP_EXT); + else + expected_map_size = + (sizeof(MR_FW_RAID_MAP) - sizeof(MR_LD_SPAN_MAP)) + + (sizeof(MR_LD_SPAN_MAP) * pDrvRaidMap->ldCount); - mrsas_update_load_balance_params(map, sc->load_balance_info); + if (pDrvRaidMap->totalSize != expected_map_size) { + device_printf(sc->mrsas_dev, "map size %x not matching ld count\n", expected_map_size); + device_printf(sc->mrsas_dev, "span map= %x\n", (unsigned int)sizeof(MR_LD_SPAN_MAP)); + device_printf(sc->mrsas_dev, "pDrvRaidMap->totalSize=%x\n", pDrvRaidMap->totalSize); + return 1; + } + if (sc->UnevenSpanSupport) { + printf("Updating span set\n\n"); + mr_update_span_set(drv_map, ldSpanInfo); + } + mrsas_update_load_balance_params(drv_map, sc->load_balance_info); - return 0; + return 0; } /* - * ****************************************************************************** - * - * Function to print info about span set created in driver from FW raid map - * - * Inputs : - * map - LD map - * ldSpanInfo - ldSpanInfo per HBA instance - * - * - * */ + * + * Function to print info about span set created in driver from FW raid map + * + * Inputs: map + * ldSpanInfo: ld map span info per HBA instance + * + * + */ #if SPAN_DEBUG -static int getSpanInfo(MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo) +static int +getSpanInfo(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo) { - u_int8_t span; - u_int32_t element; - MR_LD_RAID *raid; - LD_SPAN_SET *span_set; - MR_QUAD_ELEMENT *quad; - int ldCount; - u_int16_t ld; - - for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) - { - ld = MR_TargetIdToLdGet(ldCount, map); - if (ld >= MAX_LOGICAL_DRIVES) { - continue; - } - raid = MR_LdRaidGet(ld, map); - printf("LD %x: span_depth=%x\n", ld, raid->spanDepth); - for (span=0; span<raid->spanDepth; span++) - printf("Span=%x, number of quads=%x\n", span, - map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements); - for (element=0; element < MAX_QUAD_DEPTH; element++) { - span_set = &(ldSpanInfo[ld].span_set[element]); - if (span_set->span_row_data_width == 0) break; - - printf(" Span Set %x: width=%x, diff=%x\n", element, - (unsigned int)span_set->span_row_data_width, - (unsigned int)span_set->diff); - printf(" logical LBA start=0x%08lx, end=0x%08lx\n", - (long unsigned int)span_set->log_start_lba, - (long unsigned int)span_set->log_end_lba); - printf(" span row start=0x%08lx, end=0x%08lx\n", - (long unsigned int)span_set->span_row_start, - (long unsigned int)span_set->span_row_end); - printf(" data row start=0x%08lx, end=0x%08lx\n", - (long unsigned int)span_set->data_row_start, - (long unsigned int)span_set->data_row_end); - printf(" data strip start=0x%08lx, end=0x%08lx\n", - (long unsigned int)span_set->data_strip_start, - (long unsigned int)span_set->data_strip_end); - - for (span=0; span<raid->spanDepth; span++) { - if (map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements >=element+1){ - quad = &map->raidMap.ldSpanMap[ld]. - spanBlock[span].block_span_info. - quad[element]; - printf(" Span=%x, Quad=%x, diff=%x\n", span, - element, quad->diff); - printf(" offset_in_span=0x%08lx\n", - (long unsigned int)quad->offsetInSpan); - printf(" logical start=0x%08lx, end=0x%08lx\n", - (long unsigned int)quad->logStart, - (long unsigned int)quad->logEnd); - } - } - } - } - return 0; + u_int8_t span; + u_int32_t element; + MR_LD_RAID *raid; + LD_SPAN_SET *span_set; + MR_QUAD_ELEMENT *quad; + int ldCount; + u_int16_t ld; + + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { + ld = MR_TargetIdToLdGet(ldCount, map); + if (ld >= MAX_LOGICAL_DRIVES) { + continue; + } + raid = MR_LdRaidGet(ld, map); + printf("LD %x: span_depth=%x\n", ld, raid->spanDepth); + for (span = 0; span < raid->spanDepth; span++) + printf("Span=%x, number of quads=%x\n", span, + map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements); + for (element = 0; element < MAX_QUAD_DEPTH; element++) { + span_set = &(ldSpanInfo[ld].span_set[element]); + if (span_set->span_row_data_width == 0) + break; + + printf("Span Set %x: width=%x, diff=%x\n", element, + (unsigned int)span_set->span_row_data_width, + (unsigned int)span_set->diff); + printf("logical LBA start=0x%08lx, end=0x%08lx\n", + (long unsigned int)span_set->log_start_lba, + (long unsigned int)span_set->log_end_lba); + printf("span row start=0x%08lx, end=0x%08lx\n", + (long unsigned int)span_set->span_row_start, + (long unsigned int)span_set->span_row_end); + printf("data row start=0x%08lx, end=0x%08lx\n", + (long unsigned int)span_set->data_row_start, + (long unsigned int)span_set->data_row_end); + printf("data strip start=0x%08lx, end=0x%08lx\n", + (long unsigned int)span_set->data_strip_start, + (long unsigned int)span_set->data_strip_end); + + for (span = 0; span < raid->spanDepth; span++) { + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= element + 1) { + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span].block_span_info. + quad[element]; + printf("Span=%x, Quad=%x, diff=%x\n", span, + element, quad->diff); + printf("offset_in_span=0x%08lx\n", + (long unsigned int)quad->offsetInSpan); + printf("logical start=0x%08lx, end=0x%08lx\n", + (long unsigned int)quad->logStart, + (long unsigned int)quad->logEnd); + } + } + } + } + return 0; } + #endif /* -****************************************************************************** -* -* This routine calculates the Span block for given row using spanset. -* -* Inputs : -* instance - HBA instance -* ld - Logical drive number -* row - Row number -* map - LD map -* -* Outputs : -* -* span - Span number -* block - Absolute Block number in the physical disk -* div_error - Devide error code. -*/ - -u_int32_t mr_spanset_get_span_block(struct mrsas_softc *sc, u_int32_t ld, u_int64_t row, - u_int64_t *span_blk, MR_FW_RAID_MAP_ALL *map, int *div_error) + * + * This routine calculates the Span block for given row using spanset. + * + * Inputs : HBA instance + * ld: Logical drive number + * row: Row number + * map: LD map + * + * Outputs : span - Span number block + * - Absolute Block number in the physical disk + * div_error - Devide error code. + */ + +u_int32_t +mr_spanset_get_span_block(struct mrsas_softc *sc, u_int32_t ld, u_int64_t row, + u_int64_t *span_blk, MR_DRV_RAID_MAP_ALL * map, int *div_error) { - MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - LD_SPAN_SET *span_set; - MR_QUAD_ELEMENT *quad; - u_int32_t span, info; - PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; - - for (info=0; info < MAX_QUAD_DEPTH; info++) { - span_set = &(ldSpanInfo[ld].span_set[info]); - - if (span_set->span_row_data_width == 0) break; - if (row > span_set->data_row_end) continue; - - for (span=0; span<raid->spanDepth; span++) - if (map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements >= info+1) { - quad = &map->raidMap.ldSpanMap[ld]. - spanBlock[span]. - block_span_info.quad[info]; - if (quad->diff == 0) { - *div_error = 1; - return span; - } - if ( quad->logStart <= row && - row <= quad->logEnd && - (mega_mod64(row - quad->logStart, - quad->diff)) == 0 ) { - if (span_blk != NULL) { - u_int64_t blk; - blk = mega_div64_32 - ((row - quad->logStart), - quad->diff); - blk = (blk + quad->offsetInSpan) - << raid->stripeShift; - *span_blk = blk; - } - return span; - } - } - } - return SPAN_INVALID; + MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + MR_QUAD_ELEMENT *quad; + u_int32_t span, info; + PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (row > span_set->data_row_end) + continue; + + for (span = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info + 1) { + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span]. + block_span_info.quad[info]; + if (quad->diff == 0) { + *div_error = 1; + return span; + } + if (quad->logStart <= row && + row <= quad->logEnd && + (mega_mod64(row - quad->logStart, + quad->diff)) == 0) { + if (span_blk != NULL) { + u_int64_t blk; + + blk = mega_div64_32 + ((row - quad->logStart), + quad->diff); + blk = (blk + quad->offsetInSpan) + << raid->stripeShift; + *span_blk = blk; + } + return span; + } + } + } + return SPAN_INVALID; } /* -****************************************************************************** -* -* This routine calculates the row for given strip using spanset. -* -* Inputs : -* instance - HBA instance -* ld - Logical drive number -* Strip - Strip -* map - LD map -* -* Outputs : -* -* row - row associated with strip -*/ - -static u_int64_t get_row_from_strip(struct mrsas_softc *sc, - u_int32_t ld, u_int64_t strip, MR_FW_RAID_MAP_ALL *map) + * + * This routine calculates the row for given strip using spanset. + * + * Inputs : HBA instance + * ld: Logical drive number + * Strip: Strip + * map: LD map + * + * Outputs : row - row associated with strip + */ + +static u_int64_t +get_row_from_strip(struct mrsas_softc *sc, + u_int32_t ld, u_int64_t strip, MR_DRV_RAID_MAP_ALL * map) { - MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - LD_SPAN_SET *span_set; - PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; - u_int32_t info, strip_offset, span, span_offset; - u_int64_t span_set_Strip, span_set_Row; - - for (info=0; info < MAX_QUAD_DEPTH; info++) { - span_set = &(ldSpanInfo[ld].span_set[info]); - - if (span_set->span_row_data_width == 0) break; - if (strip > span_set->data_strip_end) continue; - - span_set_Strip = strip - span_set->data_strip_start; - strip_offset = mega_mod64(span_set_Strip, - span_set->span_row_data_width); - span_set_Row = mega_div64_32(span_set_Strip, - span_set->span_row_data_width) * span_set->diff; - for (span=0,span_offset=0; span<raid->spanDepth; span++) - if (map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements >=info+1) { - if (strip_offset >= - span_set->strip_offset[span]) - span_offset++; - else - break; - } - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : Strip 0x%llx, span_set_Strip 0x%llx, span_set_Row 0x%llx " - "data width 0x%llx span offset 0x%llx\n", (unsigned long long)strip, - (unsigned long long)span_set_Strip, - (unsigned long long)span_set_Row, - (unsigned long long)span_set->span_row_data_width, (unsigned long long)span_offset); - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : For strip 0x%llx row is 0x%llx\n", (unsigned long long)strip, - (unsigned long long) span_set->data_row_start + - (unsigned long long) span_set_Row + (span_offset - 1)); - return (span_set->data_row_start + span_set_Row + (span_offset - 1)); - } - return -1LLU; + MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; + u_int32_t info, strip_offset, span, span_offset; + u_int64_t span_set_Strip, span_set_Row; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (strip > span_set->data_strip_end) + continue; + + span_set_Strip = strip - span_set->data_strip_start; + strip_offset = mega_mod64(span_set_Strip, + span_set->span_row_data_width); + span_set_Row = mega_div64_32(span_set_Strip, + span_set->span_row_data_width) * span_set->diff; + for (span = 0, span_offset = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info + 1) { + if (strip_offset >= + span_set->strip_offset[span]) + span_offset++; + else + break; + } + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : Strip 0x%llx, span_set_Strip 0x%llx, span_set_Row 0x%llx " + "data width 0x%llx span offset 0x%llx\n", (unsigned long long)strip, + (unsigned long long)span_set_Strip, + (unsigned long long)span_set_Row, + (unsigned long long)span_set->span_row_data_width, (unsigned long long)span_offset); + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : For strip 0x%llx row is 0x%llx\n", (unsigned long long)strip, + (unsigned long long)span_set->data_row_start + + (unsigned long long)span_set_Row + (span_offset - 1)); + return (span_set->data_row_start + span_set_Row + (span_offset - 1)); + } + return -1LLU; } /* -****************************************************************************** -* -* This routine calculates the Start Strip for given row using spanset. -* -* Inputs : -* instance - HBA instance -* ld - Logical drive number -* row - Row number -* map - LD map -* -* Outputs : -* -* Strip - Start strip associated with row -*/ - -static u_int64_t get_strip_from_row(struct mrsas_softc *sc, - u_int32_t ld, u_int64_t row, MR_FW_RAID_MAP_ALL *map) + * + * This routine calculates the Start Strip for given row using spanset. + * + * Inputs: HBA instance + * ld: Logical drive number + * row: Row number + * map: LD map + * + * Outputs : Strip - Start strip associated with row + */ + +static u_int64_t +get_strip_from_row(struct mrsas_softc *sc, + u_int32_t ld, u_int64_t row, MR_DRV_RAID_MAP_ALL * map) { - MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - LD_SPAN_SET *span_set; - MR_QUAD_ELEMENT *quad; - PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; - u_int32_t span, info; - u_int64_t strip; - - for (info=0; info<MAX_QUAD_DEPTH; info++) { - span_set = &(ldSpanInfo[ld].span_set[info]); - - if (span_set->span_row_data_width == 0) break; - if (row > span_set->data_row_end) continue; - - for (span=0; span<raid->spanDepth; span++) - if (map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements >=info+1) { - quad = &map->raidMap.ldSpanMap[ld]. - spanBlock[span].block_span_info.quad[info]; - if ( quad->logStart <= row && - row <= quad->logEnd && - mega_mod64((row - quad->logStart), - quad->diff) == 0 ) { - strip = mega_div64_32 - (((row - span_set->data_row_start) - - quad->logStart), - quad->diff); - strip *= span_set->span_row_data_width; - strip += span_set->data_strip_start; - strip += span_set->strip_offset[span]; - return strip; - } - } - } - mrsas_dprint(sc, MRSAS_PRL11,"LSI Debug - get_strip_from_row: returns invalid " - "strip for ld=%x, row=%lx\n", ld, (long unsigned int)row); - return -1; + MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + MR_QUAD_ELEMENT *quad; + PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; + u_int32_t span, info; + u_int64_t strip; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (row > span_set->data_row_end) + continue; + + for (span = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info + 1) { + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span].block_span_info.quad[info]; + if (quad->logStart <= row && + row <= quad->logEnd && + mega_mod64((row - quad->logStart), + quad->diff) == 0) { + strip = mega_div64_32 + (((row - span_set->data_row_start) + - quad->logStart), + quad->diff); + strip *= span_set->span_row_data_width; + strip += span_set->data_strip_start; + strip += span_set->strip_offset[span]; + return strip; + } + } + } + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug - get_strip_from_row: returns invalid " + "strip for ld=%x, row=%lx\n", ld, (long unsigned int)row); + return -1; } /* -****************************************************************************** -* -* This routine calculates the Physical Arm for given strip using spanset. -* -* Inputs : -* instance - HBA instance -* ld - Logical drive number -* strip - Strip -* map - LD map -* -* Outputs : -* -* Phys Arm - Phys Arm associated with strip -*/ - -static u_int32_t get_arm_from_strip(struct mrsas_softc *sc, - u_int32_t ld, u_int64_t strip, MR_FW_RAID_MAP_ALL *map) + * ***************************************************************************** + * + * + * This routine calculates the Physical Arm for given strip using spanset. + * + * Inputs : HBA instance + * Logical drive number + * Strip + * LD map + * + * Outputs : Phys Arm - Phys Arm associated with strip + */ + +static u_int32_t +get_arm_from_strip(struct mrsas_softc *sc, + u_int32_t ld, u_int64_t strip, MR_DRV_RAID_MAP_ALL * map) { - MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - LD_SPAN_SET *span_set; - PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; - u_int32_t info, strip_offset, span, span_offset; - - for (info=0; info<MAX_QUAD_DEPTH; info++) { - span_set = &(ldSpanInfo[ld].span_set[info]); - - if (span_set->span_row_data_width == 0) break; - if (strip > span_set->data_strip_end) continue; - - strip_offset = (u_int32_t)mega_mod64 - ((strip - span_set->data_strip_start), - span_set->span_row_data_width); - - for (span=0,span_offset=0; span<raid->spanDepth; span++) - if (map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements >=info+1) { - if (strip_offset >= - span_set->strip_offset[span]) - span_offset = - span_set->strip_offset[span]; - else - break; - } - mrsas_dprint(sc, MRSAS_PRL11, "LSI PRL11: get_arm_from_strip: " - " for ld=0x%x strip=0x%lx arm is 0x%x\n", ld, - (long unsigned int)strip, (strip_offset - span_offset)); - return (strip_offset - span_offset); - } - - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: - get_arm_from_strip: returns invalid arm" - " for ld=%x strip=%lx\n", ld, (long unsigned int)strip); - - return -1; + MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + LD_SPAN_SET *span_set; + PLD_SPAN_INFO ldSpanInfo = sc->log_to_span; + u_int32_t info, strip_offset, span, span_offset; + + for (info = 0; info < MAX_QUAD_DEPTH; info++) { + span_set = &(ldSpanInfo[ld].span_set[info]); + + if (span_set->span_row_data_width == 0) + break; + if (strip > span_set->data_strip_end) + continue; + + strip_offset = (u_int32_t)mega_mod64 + ((strip - span_set->data_strip_start), + span_set->span_row_data_width); + + for (span = 0, span_offset = 0; span < raid->spanDepth; span++) + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements >= info + 1) { + if (strip_offset >= span_set->strip_offset[span]) + span_offset = span_set->strip_offset[span]; + else + break; + } + mrsas_dprint(sc, MRSAS_PRL11, "LSI PRL11: get_arm_from_strip: " + "for ld=0x%x strip=0x%lx arm is 0x%x\n", ld, + (long unsigned int)strip, (strip_offset - span_offset)); + return (strip_offset - span_offset); + } + + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: - get_arm_from_strip: returns invalid arm" + " for ld=%x strip=%lx\n", ld, (long unsigned int)strip); + + return -1; } /* This Function will return Phys arm */ -u_int8_t get_arm(struct mrsas_softc *sc, u_int32_t ld, u_int8_t span, u_int64_t stripe, - MR_FW_RAID_MAP_ALL *map) +u_int8_t +get_arm(struct mrsas_softc *sc, u_int32_t ld, u_int8_t span, u_int64_t stripe, + MR_DRV_RAID_MAP_ALL * map) { - MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - /* Need to check correct default value */ - u_int32_t arm = 0; - - switch (raid->level) { - case 0: - case 5: - case 6: - arm = mega_mod64(stripe, SPAN_ROW_SIZE(map, ld, span)); - break; - case 1: - // start with logical arm - arm = get_arm_from_strip(sc, ld, stripe, map); - arm *= 2; - break; - - } - - return arm; + MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + + /* Need to check correct default value */ + u_int32_t arm = 0; + + switch (raid->level) { + case 0: + case 5: + case 6: + arm = mega_mod64(stripe, SPAN_ROW_SIZE(map, ld, span)); + break; + case 1: + /* start with logical arm */ + arm = get_arm_from_strip(sc, ld, stripe, map); + arm *= 2; + break; + } + + return arm; } /* -****************************************************************************** -* -* 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 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_FW_RAID_MAP_ALL *map) + * + * This routine calculates the arm, span and block for the specified stripe and + * reference in stripe using spanset + * + * Inputs : 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; - return retval; + 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; + return retval; } -/** -* MR_BuildRaidContext: Set up Fast path RAID context -* -* This function will initiate command processing. The start/end row -* and strip information is calculated then the lock is acquired. -* This function will return 0 if region lock was acquired OR return -* num strips. -*/ -u_int8_t +/* + * MR_BuildRaidContext: Set up Fast path RAID context + * + * This function will initiate command processing. The start/end row and strip + * information is calculated then the lock is acquired. This function will + * return 0 if region lock was acquired OR return num strips. + */ +u_int8_t MR_BuildRaidContext(struct mrsas_softc *sc, struct IO_REQUEST_INFO *io_info, - RAID_CONTEXT *pRAID_Context, MR_FW_RAID_MAP_ALL *map) + RAID_CONTEXT * pRAID_Context, MR_DRV_RAID_MAP_ALL * map) { - MR_LD_RAID *raid; - u_int32_t ld, stripSize, stripe_mask; - u_int64_t endLba, endStrip, endRow, start_row, start_strip; - REGION_KEY regStart; - REGION_LEN regSize; - u_int8_t num_strips, numRows; - u_int16_t ref_in_start_stripe, ref_in_end_stripe; - u_int64_t ldStartBlock; - u_int32_t numBlocks, ldTgtId; - u_int8_t isRead, stripIdx; - u_int8_t retval = 0; + MR_LD_RAID *raid; + u_int32_t ld, stripSize, stripe_mask; + u_int64_t endLba, endStrip, endRow, start_row, start_strip; + REGION_KEY regStart; + REGION_LEN regSize; + u_int8_t num_strips, numRows; + u_int16_t ref_in_start_stripe, ref_in_end_stripe; + u_int64_t ldStartBlock; + u_int32_t numBlocks, ldTgtId; + u_int8_t isRead, stripIdx; + u_int8_t retval = 0; u_int8_t startlba_span = SPAN_INVALID; - u_int64_t *pdBlock = &io_info->pdBlock; - int error_code = 0; - - ldStartBlock = io_info->ldStartBlock; - numBlocks = io_info->numBlocks; - ldTgtId = io_info->ldTgtId; - isRead = io_info->isRead; - + u_int64_t *pdBlock = &io_info->pdBlock; + int error_code = 0; + + ldStartBlock = io_info->ldStartBlock; + numBlocks = io_info->numBlocks; + ldTgtId = io_info->ldTgtId; + isRead = io_info->isRead; + io_info->IoforUnevenSpan = 0; - io_info->start_span = SPAN_INVALID; - - ld = MR_TargetIdToLdGet(ldTgtId, map); - raid = MR_LdRaidGet(ld, map); - - /* - * if rowDataSize @RAID map and spanRowDataSize @SPAN INFO are zero - * return FALSE - */ - if (raid->rowDataSize == 0) { - if (MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize == 0) - return FALSE; - else if (sc->UnevenSpanSupport) { - io_info->IoforUnevenSpan = 1; - } - else { - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: raid->rowDataSize is 0, but has SPAN[0] rowDataSize = 0x%0x," - " but there is _NO_ UnevenSpanSupport\n", - MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize); - return FALSE; - } + io_info->start_span = SPAN_INVALID; + + ld = MR_TargetIdToLdGet(ldTgtId, map); + raid = MR_LdRaidGet(ld, map); + + if (raid->rowDataSize == 0) { + if (MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize == 0) + return FALSE; + else if (sc->UnevenSpanSupport) { + io_info->IoforUnevenSpan = 1; + } else { + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: raid->rowDataSize is 0, but has SPAN[0] rowDataSize = 0x%0x," + " but there is _NO_ UnevenSpanSupport\n", + MR_LdSpanPtrGet(ld, 0, map)->spanRowDataSize); + return FALSE; + } + } + stripSize = 1 << raid->stripeShift; + stripe_mask = stripSize - 1; + /* + * calculate starting row and stripe, and number of strips and rows + */ + start_strip = ldStartBlock >> raid->stripeShift; + ref_in_start_stripe = (u_int16_t)(ldStartBlock & stripe_mask); + endLba = ldStartBlock + numBlocks - 1; + ref_in_end_stripe = (u_int16_t)(endLba & stripe_mask); + endStrip = endLba >> raid->stripeShift; + num_strips = (u_int8_t)(endStrip - start_strip + 1); /* End strip */ + if (io_info->IoforUnevenSpan) { + start_row = get_row_from_strip(sc, ld, start_strip, map); + endRow = get_row_from_strip(sc, ld, endStrip, map); + if (raid->spanDepth == 1) { + startlba_span = 0; + *pdBlock = start_row << raid->stripeShift; + } else { + startlba_span = (u_int8_t)mr_spanset_get_span_block(sc, ld, start_row, + pdBlock, map, &error_code); + if (error_code == 1) { + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d. Send IO w/o region lock.\n", + __func__, __LINE__); + return FALSE; + } + } + if (startlba_span == SPAN_INVALID) { + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d for row 0x%llx," + "start strip %llx endSrip %llx\n", __func__, + __LINE__, (unsigned long long)start_row, + (unsigned long long)start_strip, + (unsigned long long)endStrip); + return FALSE; + } + io_info->start_span = startlba_span; + io_info->start_row = start_row; + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: Check Span number from %s %d for row 0x%llx, " + " start strip 0x%llx endSrip 0x%llx span 0x%x\n", + __func__, __LINE__, (unsigned long long)start_row, + (unsigned long long)start_strip, + (unsigned long long)endStrip, startlba_span); + mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : 1. start_row 0x%llx endRow 0x%llx Start span 0x%x\n", + (unsigned long long)start_row, (unsigned long long)endRow, startlba_span); + } else { + start_row = mega_div64_32(start_strip, raid->rowDataSize); + endRow = mega_div64_32(endStrip, raid->rowDataSize); } - stripSize = 1 << raid->stripeShift; - stripe_mask = stripSize-1; - /* - * calculate starting row and stripe, and number of strips and rows - */ - start_strip = ldStartBlock >> raid->stripeShift; - ref_in_start_stripe = (u_int16_t)(ldStartBlock & stripe_mask); - endLba = ldStartBlock + numBlocks - 1; - ref_in_end_stripe = (u_int16_t)(endLba & stripe_mask); - endStrip = endLba >> raid->stripeShift; - num_strips = (u_int8_t)(endStrip - start_strip + 1); // End strip - if (io_info->IoforUnevenSpan) { - start_row = get_row_from_strip(sc, ld, start_strip, map); - endRow = get_row_from_strip(sc, ld, endStrip, map); - if (raid->spanDepth == 1) { - startlba_span = 0; - *pdBlock = start_row << raid->stripeShift; - } else { - startlba_span = (u_int8_t)mr_spanset_get_span_block(sc, ld, start_row, - pdBlock, map, &error_code); - if (error_code == 1) { - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d. Send IO w/o region lock.\n", - __func__, __LINE__); - return FALSE; - } - } - if (startlba_span == SPAN_INVALID) { - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: return from %s %d for row 0x%llx," - "start strip %llx endSrip %llx\n", __func__, - __LINE__, (unsigned long long)start_row, - (unsigned long long)start_strip, - (unsigned long long)endStrip); - return FALSE; - } - io_info->start_span = startlba_span; - io_info->start_row = start_row; - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug: Check Span number from %s %d for row 0x%llx, " - " start strip 0x%llx endSrip 0x%llx span 0x%x\n", - __func__, __LINE__, (unsigned long long)start_row, - (unsigned long long)start_strip, - (unsigned long long)endStrip, startlba_span); - mrsas_dprint(sc, MRSAS_PRL11, "LSI Debug : 1. start_row 0x%llx endRow 0x%llx Start span 0x%x\n", - (unsigned long long)start_row, (unsigned long long)endRow, startlba_span); - } else { - start_row = mega_div64_32(start_strip, raid->rowDataSize); // Start Row - endRow = mega_div64_32(endStrip, raid->rowDataSize); - } - - numRows = (u_int8_t)(endRow - start_row + 1); // get the row count - - /* - * Calculate region info. (Assume region at start of first row, and - * assume this IO needs the full row - will adjust if not true.) - */ - regStart = start_row << raid->stripeShift; - regSize = stripSize; - - /* Check if we can send this I/O via FastPath */ - if (raid->capability.fpCapable) { - if (isRead) - io_info->fpOkForIo = (raid->capability.fpReadCapable && - ((num_strips == 1) || - raid->capability. - fpReadAcrossStripe)); - else - io_info->fpOkForIo = (raid->capability.fpWriteCapable && - ((num_strips == 1) || - raid->capability. - fpWriteAcrossStripe)); - } - else - io_info->fpOkForIo = FALSE; - - if (numRows == 1) { - if (num_strips == 1) { - /* single-strip IOs can always lock only the data needed, - multi-strip IOs always need to full stripe locked */ - regStart += ref_in_start_stripe; - regSize = numBlocks; - } - } - else if (io_info->IoforUnevenSpan == 0){ - // For Even span region lock optimization. - // If the start strip is the last in the start row - if (start_strip == (start_row + 1) * raid->rowDataSize - 1) { - regStart += ref_in_start_stripe; - // initialize count to sectors from startRef to end of strip - regSize = stripSize - ref_in_start_stripe; - } - // add complete rows in the middle of the transfer + + numRows = (u_int8_t)(endRow - start_row + 1); /* get the row count */ + + /* + * Calculate region info. (Assume region at start of first row, and + * assume this IO needs the full row - will adjust if not true.) + */ + regStart = start_row << raid->stripeShift; + regSize = stripSize; + + /* Check if we can send this I/O via FastPath */ + if (raid->capability.fpCapable) { + if (isRead) + io_info->fpOkForIo = (raid->capability.fpReadCapable && + ((num_strips == 1) || + raid->capability.fpReadAcrossStripe)); + else + io_info->fpOkForIo = (raid->capability.fpWriteCapable && + ((num_strips == 1) || + raid->capability.fpWriteAcrossStripe)); + } else + io_info->fpOkForIo = FALSE; + + if (numRows == 1) { + if (num_strips == 1) { + regStart += ref_in_start_stripe; + regSize = numBlocks; + } + } else if (io_info->IoforUnevenSpan == 0) { + /* + * For Even span region lock optimization. If the start strip + * is the last in the start row + */ + if (start_strip == (start_row + 1) * raid->rowDataSize - 1) { + regStart += ref_in_start_stripe; + /* + * initialize count to sectors from startRef to end + * of strip + */ + regSize = stripSize - ref_in_start_stripe; + } + /* add complete rows in the middle of the transfer */ if (numRows > 2) - regSize += (numRows-2) << raid->stripeShift; - - // if IO ends within first strip of last row - if (endStrip == endRow*raid->rowDataSize) - regSize += ref_in_end_stripe+1; - else - regSize += stripSize; - } else { - //For Uneven span region lock optimization. - // If the start strip is the last in the start row - if (start_strip == (get_strip_from_row(sc, ld, start_row, map) + - SPAN_ROW_DATA_SIZE(map, ld, startlba_span) - 1)) { - regStart += ref_in_start_stripe; - // initialize count to sectors from startRef to end of strip + regSize += (numRows - 2) << raid->stripeShift; + + /* if IO ends within first strip of last row */ + if (endStrip == endRow * raid->rowDataSize) + regSize += ref_in_end_stripe + 1; + else + regSize += stripSize; + } else { + if (start_strip == (get_strip_from_row(sc, ld, start_row, map) + + SPAN_ROW_DATA_SIZE(map, ld, startlba_span) - 1)) { + regStart += ref_in_start_stripe; + /* + * initialize count to sectors from startRef to end + * of strip + */ regSize = stripSize - ref_in_start_stripe; - } - // add complete rows in the middle of the transfer - if (numRows > 2) - regSize += (numRows-2) << raid->stripeShift; - - // if IO ends within first strip of last row - if (endStrip == get_strip_from_row(sc, ld, endRow, map)) - regSize += ref_in_end_stripe+1; - else - regSize += stripSize; - } - pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec; - if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY)) - pRAID_Context->regLockFlags = (isRead)? raid->regTypeReqOnRead : raid->regTypeReqOnWrite; - else - pRAID_Context->regLockFlags = (isRead)? REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite; - pRAID_Context->VirtualDiskTgtId = raid->targetId; - pRAID_Context->regLockRowLBA = regStart; - pRAID_Context->regLockLength = regSize; - pRAID_Context->configSeqNum = raid->seqNum; - - /* - * Get Phy Params only if FP capable, or else leave it to MR firmware - * to do the calculation. - */ - if (io_info->fpOkForIo) { - retval = io_info->IoforUnevenSpan ? - mr_spanset_get_phy_params(sc, ld, - start_strip, ref_in_start_stripe, io_info, - pRAID_Context, map) : - MR_GetPhyParams(sc, ld, start_strip, - ref_in_start_stripe, io_info, pRAID_Context, map); - /* If IO on an invalid Pd, then FP is not possible */ - if (io_info->devHandle == MR_PD_INVALID) - io_info->fpOkForIo = FALSE; - return retval; - } - else if (isRead) { - for (stripIdx=0; stripIdx<num_strips; stripIdx++) { - retval = io_info->IoforUnevenSpan ? - mr_spanset_get_phy_params(sc, ld, - start_strip + stripIdx, - ref_in_start_stripe, io_info, - pRAID_Context, map) : - MR_GetPhyParams(sc, ld, - start_strip + stripIdx, ref_in_start_stripe, - io_info, pRAID_Context, map); - if (!retval) - return TRUE; - } - } + } + /* add complete rows in the middle of the transfer */ + if (numRows > 2) + regSize += (numRows - 2) << raid->stripeShift; + + /* if IO ends within first strip of last row */ + if (endStrip == get_strip_from_row(sc, ld, endRow, map)) + regSize += ref_in_end_stripe + 1; + else + regSize += stripSize; + } + pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec; + if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY)) + pRAID_Context->regLockFlags = (isRead) ? raid->regTypeReqOnRead : raid->regTypeReqOnWrite; + else + pRAID_Context->regLockFlags = (isRead) ? REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite; + pRAID_Context->VirtualDiskTgtId = raid->targetId; + pRAID_Context->regLockRowLBA = regStart; + pRAID_Context->regLockLength = regSize; + pRAID_Context->configSeqNum = raid->seqNum; + + /* + * Get Phy Params only if FP capable, or else leave it to MR firmware + * to do the calculation. + */ + if (io_info->fpOkForIo) { + retval = io_info->IoforUnevenSpan ? + mr_spanset_get_phy_params(sc, ld, start_strip, + ref_in_start_stripe, io_info, pRAID_Context, map) : + MR_GetPhyParams(sc, ld, start_strip, + ref_in_start_stripe, io_info, pRAID_Context, map); + /* If IO on an invalid Pd, then FP is not possible */ + if (io_info->devHandle == MR_PD_INVALID) + io_info->fpOkForIo = FALSE; + return retval; + } else if (isRead) { + for (stripIdx = 0; stripIdx < num_strips; stripIdx++) { + retval = io_info->IoforUnevenSpan ? + mr_spanset_get_phy_params(sc, ld, start_strip + stripIdx, + ref_in_start_stripe, io_info, pRAID_Context, map) : + MR_GetPhyParams(sc, ld, start_strip + stripIdx, + ref_in_start_stripe, io_info, pRAID_Context, map); + if (!retval) + return TRUE; + } + } #if SPAN_DEBUG - // Just for testing what arm we get for strip. - get_arm_from_strip(sc, ld, start_strip, map); + /* Just for testing what arm we get for strip. */ + get_arm_from_strip(sc, ld, start_strip, map); #endif - return TRUE; + return TRUE; } /* -****************************************************************************** -* -* This routine pepare spanset info from Valid Raid map and store it into -* local copy of ldSpanInfo per instance data structure. -* -* Inputs : -* map - LD map -* ldSpanInfo - ldSpanInfo per HBA instance -* -*/ -void mr_update_span_set(MR_FW_RAID_MAP_ALL *map, PLD_SPAN_INFO ldSpanInfo) + * + * This routine pepare spanset info from Valid Raid map and store it into local + * copy of ldSpanInfo per instance data structure. + * + * Inputs : LD map + * ldSpanInfo per HBA instance + * + */ +void +mr_update_span_set(MR_DRV_RAID_MAP_ALL * map, PLD_SPAN_INFO ldSpanInfo) { - u_int8_t span,count; - u_int32_t element,span_row_width; - u_int64_t span_row; - MR_LD_RAID *raid; - LD_SPAN_SET *span_set, *span_set_prev; - MR_QUAD_ELEMENT *quad; - int ldCount; - u_int16_t ld; - - if (!ldSpanInfo) - return; - - for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) - { - ld = MR_TargetIdToLdGet(ldCount, map); - if (ld >= MAX_LOGICAL_DRIVES) - continue; - raid = MR_LdRaidGet(ld, map); - for (element=0; element < MAX_QUAD_DEPTH; element++) { - for (span=0; span < raid->spanDepth; span++) { - if (map->raidMap.ldSpanMap[ld].spanBlock[span]. - block_span_info.noElements < element+1) - continue; - // TO-DO - span_set = &(ldSpanInfo[ld].span_set[element]); - quad = &map->raidMap.ldSpanMap[ld]. - spanBlock[span].block_span_info. - quad[element]; - - span_set->diff = quad->diff; - - for (count=0,span_row_width=0; - count<raid->spanDepth; count++) { - if (map->raidMap.ldSpanMap[ld]. - spanBlock[count]. - block_span_info. - noElements >=element+1) { - span_set->strip_offset[count] = - span_row_width; - span_row_width += - MR_LdSpanPtrGet - (ld, count, map)->spanRowDataSize; + u_int8_t span, count; + u_int32_t element, span_row_width; + u_int64_t span_row; + MR_LD_RAID *raid; + LD_SPAN_SET *span_set, *span_set_prev; + MR_QUAD_ELEMENT *quad; + int ldCount; + u_int16_t ld; + + for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) { + ld = MR_TargetIdToLdGet(ldCount, map); + if (ld >= MAX_LOGICAL_DRIVES) + continue; + raid = MR_LdRaidGet(ld, map); + for (element = 0; element < MAX_QUAD_DEPTH; element++) { + for (span = 0; span < raid->spanDepth; span++) { + if (map->raidMap.ldSpanMap[ld].spanBlock[span]. + block_span_info.noElements < element + 1) + continue; + /* TO-DO */ + span_set = &(ldSpanInfo[ld].span_set[element]); + quad = &map->raidMap.ldSpanMap[ld]. + spanBlock[span].block_span_info.quad[element]; + + span_set->diff = quad->diff; + + for (count = 0, span_row_width = 0; + count < raid->spanDepth; count++) { + if (map->raidMap.ldSpanMap[ld].spanBlock[count]. + block_span_info.noElements >= element + 1) { + span_set->strip_offset[count] = span_row_width; + span_row_width += + MR_LdSpanPtrGet(ld, count, map)->spanRowDataSize; #if SPAN_DEBUG - printf("LSI Debug span %x rowDataSize %x\n", - count, MR_LdSpanPtrGet - (ld, count, map)->spanRowDataSize); + printf("LSI Debug span %x rowDataSize %x\n", count, + MR_LdSpanPtrGet(ld, count, map)->spanRowDataSize); #endif - } - } - - span_set->span_row_data_width = span_row_width; - span_row = mega_div64_32(((quad->logEnd - - quad->logStart) + quad->diff), quad->diff); - - if (element == 0) { - span_set->log_start_lba = 0; - span_set->log_end_lba = - ((span_row << raid->stripeShift) * span_row_width) - 1; - - span_set->span_row_start = 0; - span_set->span_row_end = span_row - 1; - - span_set->data_strip_start = 0; - span_set->data_strip_end = - (span_row * span_row_width) - 1; - - span_set->data_row_start = 0; - span_set->data_row_end = - (span_row * quad->diff) - 1; - } else { - span_set_prev = &(ldSpanInfo[ld]. - span_set[element - 1]); - span_set->log_start_lba = - span_set_prev->log_end_lba + 1; - span_set->log_end_lba = - span_set->log_start_lba + - ((span_row << raid->stripeShift) * span_row_width) - 1; - - span_set->span_row_start = - span_set_prev->span_row_end + 1; - span_set->span_row_end = - span_set->span_row_start + span_row - 1; - - span_set->data_strip_start = - span_set_prev->data_strip_end + 1; - span_set->data_strip_end = - span_set->data_strip_start + - (span_row * span_row_width) - 1; - - span_set->data_row_start = - span_set_prev->data_row_end + 1; - span_set->data_row_end = - span_set->data_row_start + - (span_row * quad->diff) - 1; - } - break; - } - if (span == raid->spanDepth) break; // no quads remain - } - } + } + } + + span_set->span_row_data_width = span_row_width; + span_row = mega_div64_32(((quad->logEnd - + quad->logStart) + quad->diff), quad->diff); + + if (element == 0) { + span_set->log_start_lba = 0; + span_set->log_end_lba = + ((span_row << raid->stripeShift) * span_row_width) - 1; + + span_set->span_row_start = 0; + span_set->span_row_end = span_row - 1; + + span_set->data_strip_start = 0; + span_set->data_strip_end = (span_row * span_row_width) - 1; + + span_set->data_row_start = 0; + span_set->data_row_end = (span_row * quad->diff) - 1; + } else { + span_set_prev = &(ldSpanInfo[ld].span_set[element - 1]); + span_set->log_start_lba = span_set_prev->log_end_lba + 1; + span_set->log_end_lba = span_set->log_start_lba + + ((span_row << raid->stripeShift) * span_row_width) - 1; + + span_set->span_row_start = span_set_prev->span_row_end + 1; + span_set->span_row_end = + span_set->span_row_start + span_row - 1; + + span_set->data_strip_start = + span_set_prev->data_strip_end + 1; + span_set->data_strip_end = span_set->data_strip_start + + (span_row * span_row_width) - 1; + + span_set->data_row_start = span_set_prev->data_row_end + 1; + span_set->data_row_end = span_set->data_row_start + + (span_row * quad->diff) - 1; + } + break; + } + if (span == raid->spanDepth) + break; /* no quads remain */ + } + } #if SPAN_DEBUG - getSpanInfo(map, ldSpanInfo); //to get span set info + getSpanInfo(map, ldSpanInfo); /* to get span set info */ #endif } -/** - * mrsas_update_load_balance_params: Update load balance parmas - * Inputs: map pointer - * Load balance info - * io_info pointer +/* + * mrsas_update_load_balance_params: Update load balance parmas + * Inputs: map pointer + * Load balance info * - * This function updates the load balance parameters for the LD config - * of a two drive optimal RAID-1. + * This function updates the load balance parameters for the LD config of a two + * drive optimal RAID-1. */ -void mrsas_update_load_balance_params(MR_FW_RAID_MAP_ALL *map, - PLD_LOAD_BALANCE_INFO lbInfo) +void +mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map, + PLD_LOAD_BALANCE_INFO lbInfo) { - int ldCount; - u_int16_t ld; - u_int32_t pd, arRef; - 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) { - 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); - pd = MR_ArPdGet(arRef, 1, map); - lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map); - } - else - lbInfo[ldCount].loadBalanceFlag = 0; - } + int ldCount; + u_int16_t ld; + u_int32_t pd, arRef; + 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) { + 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); + pd = MR_ArPdGet(arRef, 1, map); + lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map); + } else + lbInfo[ldCount].loadBalanceFlag = 0; + } } -/** - * mrsas_set_pd_lba: Sets PD LBA - * input: io_request pointer - * CDB length - * io_info pointer - * Pointer to CCB - * Local RAID map pointer - * Start block of IO - * Block Size +/* + * mrsas_set_pd_lba: Sets PD LBA + * input: io_request pointer + * CDB length + * io_info pointer + * Pointer to CCB + * Local RAID map pointer + * Start block of IO Block Size * * Used to set the PD logical block address in CDB for FP IOs. */ -void mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST *io_request, u_int8_t cdb_len, +void +mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request, u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb, - MR_FW_RAID_MAP_ALL *local_map_ptr, u_int32_t ref_tag, + MR_DRV_RAID_MAP_ALL * local_map_ptr, u_int32_t ref_tag, u_int32_t ld_block_size) { - MR_LD_RAID *raid; - u_int32_t ld; - u_int64_t start_blk = io_info->pdBlock; - u_int8_t *cdb = io_request->CDB.CDB32; - u_int32_t num_blocks = io_info->numBlocks; - u_int8_t opcode = 0, flagvals = 0, groupnum = 0, control = 0; - struct ccb_hdr *ccb_h = &(ccb->ccb_h); - - /* Check if T10 PI (DIF) is enabled for this LD */ - ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr); - raid = MR_LdRaidGet(ld, local_map_ptr); - if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) { - memset(cdb, 0, sizeof(io_request->CDB.CDB32)); - cdb[0] = MRSAS_SCSI_VARIABLE_LENGTH_CMD; - cdb[7] = MRSAS_SCSI_ADDL_CDB_LEN; - - if (ccb_h->flags == CAM_DIR_OUT) - cdb[9] = MRSAS_SCSI_SERVICE_ACTION_READ32; - else - cdb[9] = MRSAS_SCSI_SERVICE_ACTION_WRITE32; - cdb[10] = MRSAS_RD_WR_PROTECT_CHECK_ALL; - - /* LBA */ - cdb[12] = (u_int8_t)((start_blk >> 56) & 0xff); - cdb[13] = (u_int8_t)((start_blk >> 48) & 0xff); - cdb[14] = (u_int8_t)((start_blk >> 40) & 0xff); - cdb[15] = (u_int8_t)((start_blk >> 32) & 0xff); - cdb[16] = (u_int8_t)((start_blk >> 24) & 0xff); - cdb[17] = (u_int8_t)((start_blk >> 16) & 0xff); - cdb[18] = (u_int8_t)((start_blk >> 8) & 0xff); - cdb[19] = (u_int8_t)(start_blk & 0xff); - - /* Logical block reference tag */ - io_request->CDB.EEDP32.PrimaryReferenceTag = swap32(ref_tag); - io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff; - io_request->IoFlags = 32; /* Specify 32-byte cdb */ - - /* Transfer length */ - cdb[28] = (u_int8_t)((num_blocks >> 24) & 0xff); - cdb[29] = (u_int8_t)((num_blocks >> 16) & 0xff); - cdb[30] = (u_int8_t)((num_blocks >> 8) & 0xff); - cdb[31] = (u_int8_t)(num_blocks & 0xff); - - /* set SCSI IO EEDP Flags */ - if (ccb_h->flags == CAM_DIR_OUT) { - io_request->EEDPFlags = - MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | - MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | - MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP | - MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG | - MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; - } - else { - io_request->EEDPFlags = - MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | - MPI2_SCSIIO_EEDPFLAGS_INSERT_OP; - } - io_request->Control |= (0x4 << 26); - io_request->EEDPBlockSize = ld_block_size; - } - else { - /* Some drives don't support 16/12 byte CDB's, convert to 10 */ - if (((cdb_len == 12) || (cdb_len == 16)) && - (start_blk <= 0xffffffff)) { - if (cdb_len == 16) { - opcode = cdb[0] == READ_16 ? READ_10 : WRITE_10; - flagvals = cdb[1]; - groupnum = cdb[14]; - control = cdb[15]; - } - else { - opcode = cdb[0] == READ_12 ? READ_10 : WRITE_10; - flagvals = cdb[1]; - groupnum = cdb[10]; - control = cdb[11]; - } - - memset(cdb, 0, sizeof(io_request->CDB.CDB32)); - - cdb[0] = opcode; - cdb[1] = flagvals; - cdb[6] = groupnum; - cdb[9] = control; - - /* Transfer length */ - cdb[8] = (u_int8_t)(num_blocks & 0xff); - cdb[7] = (u_int8_t)((num_blocks >> 8) & 0xff); - - io_request->IoFlags = 10; /* Specify 10-byte cdb */ - cdb_len = 10; - } else if ((cdb_len < 16) && (start_blk > 0xffffffff)) { - /* Convert to 16 byte CDB for large LBA's */ - switch (cdb_len) { - case 6: - opcode = cdb[0] == READ_6 ? READ_16 : WRITE_16; - control = cdb[5]; - break; - case 10: - opcode = cdb[0] == READ_10 ? READ_16 : WRITE_16; - flagvals = cdb[1]; - groupnum = cdb[6]; - control = cdb[9]; - break; - case 12: - opcode = cdb[0] == READ_12 ? READ_16 : WRITE_16; - flagvals = cdb[1]; - groupnum = cdb[10]; - control = cdb[11]; - break; - } - - memset(cdb, 0, sizeof(io_request->CDB.CDB32)); - - cdb[0] = opcode; - cdb[1] = flagvals; - cdb[14] = groupnum; - cdb[15] = control; - - /* Transfer length */ - cdb[13] = (u_int8_t)(num_blocks & 0xff); - cdb[12] = (u_int8_t)((num_blocks >> 8) & 0xff); - cdb[11] = (u_int8_t)((num_blocks >> 16) & 0xff); - cdb[10] = (u_int8_t)((num_blocks >> 24) & 0xff); - - io_request->IoFlags = 16; /* Specify 16-byte cdb */ - cdb_len = 16; - } else if ((cdb_len == 6) && (start_blk > 0x1fffff)) { - /* convert to 10 byte CDB */ - opcode = cdb[0] == READ_6 ? READ_10 : WRITE_10; - control = cdb[5]; - - memset(cdb, 0, sizeof(io_request->CDB.CDB32)); - cdb[0] = opcode; - cdb[9] = control; - - /* Set transfer length */ - cdb[8] = (u_int8_t)(num_blocks & 0xff); - cdb[7] = (u_int8_t)((num_blocks >> 8) & 0xff); - - /* Specify 10-byte cdb */ - cdb_len = 10; + MR_LD_RAID *raid; + u_int32_t ld; + u_int64_t start_blk = io_info->pdBlock; + u_int8_t *cdb = io_request->CDB.CDB32; + u_int32_t num_blocks = io_info->numBlocks; + u_int8_t opcode = 0, flagvals = 0, groupnum = 0, control = 0; + struct ccb_hdr *ccb_h = &(ccb->ccb_h); + + /* Check if T10 PI (DIF) is enabled for this LD */ + ld = MR_TargetIdToLdGet(io_info->ldTgtId, local_map_ptr); + raid = MR_LdRaidGet(ld, local_map_ptr); + if (raid->capability.ldPiMode == MR_PROT_INFO_TYPE_CONTROLLER) { + memset(cdb, 0, sizeof(io_request->CDB.CDB32)); + cdb[0] = MRSAS_SCSI_VARIABLE_LENGTH_CMD; + cdb[7] = MRSAS_SCSI_ADDL_CDB_LEN; + + if (ccb_h->flags == CAM_DIR_OUT) + cdb[9] = MRSAS_SCSI_SERVICE_ACTION_READ32; + else + cdb[9] = MRSAS_SCSI_SERVICE_ACTION_WRITE32; + cdb[10] = MRSAS_RD_WR_PROTECT_CHECK_ALL; + + /* LBA */ + cdb[12] = (u_int8_t)((start_blk >> 56) & 0xff); + cdb[13] = (u_int8_t)((start_blk >> 48) & 0xff); + cdb[14] = (u_int8_t)((start_blk >> 40) & 0xff); + cdb[15] = (u_int8_t)((start_blk >> 32) & 0xff); + cdb[16] = (u_int8_t)((start_blk >> 24) & 0xff); + cdb[17] = (u_int8_t)((start_blk >> 16) & 0xff); + cdb[18] = (u_int8_t)((start_blk >> 8) & 0xff); + cdb[19] = (u_int8_t)(start_blk & 0xff); + + /* Logical block reference tag */ + io_request->CDB.EEDP32.PrimaryReferenceTag = swap32(ref_tag); + io_request->CDB.EEDP32.PrimaryApplicationTagMask = 0xffff; + io_request->IoFlags = 32; /* Specify 32-byte cdb */ + + /* Transfer length */ + cdb[28] = (u_int8_t)((num_blocks >> 24) & 0xff); + cdb[29] = (u_int8_t)((num_blocks >> 16) & 0xff); + cdb[30] = (u_int8_t)((num_blocks >> 8) & 0xff); + cdb[31] = (u_int8_t)(num_blocks & 0xff); + + /* set SCSI IO EEDP Flags */ + if (ccb_h->flags == CAM_DIR_OUT) { + io_request->EEDPFlags = + MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | + MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | + MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP | + MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG | + MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD; + } else { + io_request->EEDPFlags = + MPI2_SCSIIO_EEDPFLAGS_INC_PRI_REFTAG | + MPI2_SCSIIO_EEDPFLAGS_INSERT_OP; + } + io_request->Control |= (0x4 << 26); + io_request->EEDPBlockSize = ld_block_size; + } else { + /* Some drives don't support 16/12 byte CDB's, convert to 10 */ + if (((cdb_len == 12) || (cdb_len == 16)) && + (start_blk <= 0xffffffff)) { + if (cdb_len == 16) { + opcode = cdb[0] == READ_16 ? READ_10 : WRITE_10; + flagvals = cdb[1]; + groupnum = cdb[14]; + control = cdb[15]; + } else { + opcode = cdb[0] == READ_12 ? READ_10 : WRITE_10; + flagvals = cdb[1]; + groupnum = cdb[10]; + control = cdb[11]; + } + + memset(cdb, 0, sizeof(io_request->CDB.CDB32)); + + cdb[0] = opcode; + cdb[1] = flagvals; + cdb[6] = groupnum; + cdb[9] = control; + + /* Transfer length */ + cdb[8] = (u_int8_t)(num_blocks & 0xff); + cdb[7] = (u_int8_t)((num_blocks >> 8) & 0xff); + + io_request->IoFlags = 10; /* Specify 10-byte cdb */ + cdb_len = 10; + } else if ((cdb_len < 16) && (start_blk > 0xffffffff)) { + /* Convert to 16 byte CDB for large LBA's */ + switch (cdb_len) { + case 6: + opcode = cdb[0] == READ_6 ? READ_16 : WRITE_16; + control = cdb[5]; + break; + case 10: + opcode = cdb[0] == READ_10 ? READ_16 : WRITE_16; + flagvals = cdb[1]; + groupnum = cdb[6]; + control = cdb[9]; + break; + case 12: + opcode = cdb[0] == READ_12 ? READ_16 : WRITE_16; + flagvals = cdb[1]; + groupnum = cdb[10]; + control = cdb[11]; + break; + } + + memset(cdb, 0, sizeof(io_request->CDB.CDB32)); + + cdb[0] = opcode; + cdb[1] = flagvals; + cdb[14] = groupnum; + cdb[15] = control; + + /* Transfer length */ + cdb[13] = (u_int8_t)(num_blocks & 0xff); + cdb[12] = (u_int8_t)((num_blocks >> 8) & 0xff); + cdb[11] = (u_int8_t)((num_blocks >> 16) & 0xff); + cdb[10] = (u_int8_t)((num_blocks >> 24) & 0xff); + + io_request->IoFlags = 16; /* Specify 16-byte cdb */ + cdb_len = 16; + } else if ((cdb_len == 6) && (start_blk > 0x1fffff)) { + /* convert to 10 byte CDB */ + opcode = cdb[0] == READ_6 ? READ_10 : WRITE_10; + control = cdb[5]; + + memset(cdb, 0, sizeof(io_request->CDB.CDB32)); + cdb[0] = opcode; + cdb[9] = control; + + /* Set transfer length */ + cdb[8] = (u_int8_t)(num_blocks & 0xff); + cdb[7] = (u_int8_t)((num_blocks >> 8) & 0xff); + + /* Specify 10-byte cdb */ + cdb_len = 10; + } + /* Fall through normal case, just load LBA here */ + u_int8_t val = cdb[1] & 0xE0; + switch (cdb_len) { + case 6: + cdb[3] = (u_int8_t)(start_blk & 0xff); + cdb[2] = (u_int8_t)((start_blk >> 8) & 0xff); + cdb[1] = val | ((u_int8_t)(start_blk >> 16) & 0x1f); + break; + case 10: + cdb[5] = (u_int8_t)(start_blk & 0xff); + cdb[4] = (u_int8_t)((start_blk >> 8) & 0xff); + cdb[3] = (u_int8_t)((start_blk >> 16) & 0xff); + cdb[2] = (u_int8_t)((start_blk >> 24) & 0xff); + break; + case 12: + cdb[5] = (u_int8_t)(start_blk & 0xff); + cdb[4] = (u_int8_t)((start_blk >> 8) & 0xff); + cdb[3] = (u_int8_t)((start_blk >> 16) & 0xff); + cdb[2] = (u_int8_t)((start_blk >> 24) & 0xff); + break; + case 16: + cdb[9] = (u_int8_t)(start_blk & 0xff); + cdb[8] = (u_int8_t)((start_blk >> 8) & 0xff); + cdb[7] = (u_int8_t)((start_blk >> 16) & 0xff); + cdb[6] = (u_int8_t)((start_blk >> 24) & 0xff); + cdb[5] = (u_int8_t)((start_blk >> 32) & 0xff); + cdb[4] = (u_int8_t)((start_blk >> 40) & 0xff); + cdb[3] = (u_int8_t)((start_blk >> 48) & 0xff); + cdb[2] = (u_int8_t)((start_blk >> 56) & 0xff); + break; + } } - - /* Fall through normal case, just load LBA here */ - switch (cdb_len) - { - case 6: - { - u_int8_t val = cdb[1] & 0xE0; - cdb[3] = (u_int8_t)(start_blk & 0xff); - cdb[2] = (u_int8_t)((start_blk >> 8) & 0xff); - cdb[1] = val | ((u_int8_t)(start_blk >> 16) & 0x1f); - break; - } - case 10: - cdb[5] = (u_int8_t)(start_blk & 0xff); - cdb[4] = (u_int8_t)((start_blk >> 8) & 0xff); - cdb[3] = (u_int8_t)((start_blk >> 16) & 0xff); - cdb[2] = (u_int8_t)((start_blk >> 24) & 0xff); - break; - case 12: - cdb[5] = (u_int8_t)(start_blk & 0xff); - cdb[4] = (u_int8_t)((start_blk >> 8) & 0xff); - cdb[3] = (u_int8_t)((start_blk >> 16) & 0xff); - cdb[2] = (u_int8_t)((start_blk >> 24) & 0xff); - break; - case 16: - cdb[9] = (u_int8_t)(start_blk & 0xff); - cdb[8] = (u_int8_t)((start_blk >> 8) & 0xff); - cdb[7] = (u_int8_t)((start_blk >> 16) & 0xff); - cdb[6] = (u_int8_t)((start_blk >> 24) & 0xff); - cdb[5] = (u_int8_t)((start_blk >> 32) & 0xff); - cdb[4] = (u_int8_t)((start_blk >> 40) & 0xff); - cdb[3] = (u_int8_t)((start_blk >> 48) & 0xff); - cdb[2] = (u_int8_t)((start_blk >> 56) & 0xff); - break; - } - } } -/** - * mrsas_get_best_arm Determine the best spindle arm - * Inputs: Load balance info +/* + * mrsas_get_best_arm: Determine the best spindle arm + * Inputs: Load balance info * * This function determines and returns the best arm by looking at the * parameters of the last PD access. */ -u_int8_t mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm, - u_int64_t block, u_int32_t count) +u_int8_t +mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm, + u_int64_t block, u_int32_t count) { - u_int16_t pend0, pend1; - u_int64_t diff0, diff1; - u_int8_t bestArm; + u_int16_t pend0, pend1; + u_int64_t diff0, diff1; + u_int8_t bestArm; - /* get the pending cmds for the data and mirror arms */ - pend0 = atomic_read(&lbInfo->scsi_pending_cmds[0]); - pend1 = atomic_read(&lbInfo->scsi_pending_cmds[1]); + /* get the pending cmds for the data and mirror arms */ + pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[0]); + pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[1]); - /* Determine the disk whose head is nearer to the req. block */ - diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]); - diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]); - bestArm = (diff0 <= diff1 ? 0 : 1); + /* Determine the disk whose head is nearer to the req. block */ + diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]); + diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]); + bestArm = (diff0 <= diff1 ? 0 : 1); - if ((bestArm == arm && pend0 > pend1 + 16) || (bestArm != arm && pend1 > pend0 + 16)) - bestArm ^= 1; + if ((bestArm == arm && pend0 > pend1 + 16) || (bestArm != arm && pend1 > pend0 + 16)) + bestArm ^= 1; - /* Update the last accessed block on the correct pd */ - lbInfo->last_accessed_block[bestArm] = block + count - 1; + /* Update the last accessed block on the correct pd */ + lbInfo->last_accessed_block[bestArm] = block + count - 1; - return bestArm; + return bestArm; } -/** - * mrsas_get_updated_dev_handle Get the update dev handle - * Inputs: Load balance info - * io_info pointer +/* + * mrsas_get_updated_dev_handle: Get the update dev handle + * Inputs: Load balance info io_info pointer * * This function determines and returns the updated dev handle. */ -u_int16_t mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo, - struct IO_REQUEST_INFO *io_info) +u_int16_t +mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo, + struct IO_REQUEST_INFO *io_info) { - u_int8_t arm, old_arm; - u_int16_t devHandle; + u_int8_t arm, old_arm; + u_int16_t devHandle; - old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1; + old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1; - /* get best new arm */ - arm = mrsas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock, io_info->numBlocks); - devHandle = lbInfo->raid1DevHandle[arm]; - atomic_inc(&lbInfo->scsi_pending_cmds[arm]); + /* get best new arm */ + arm = mrsas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock, io_info->numBlocks); + devHandle = lbInfo->raid1DevHandle[arm]; + mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm]); - return devHandle; + return devHandle; } -/** - * MR_GetPhyParams Calculates arm, span, and block - * Inputs: Adapter instance soft state - * Logical drive number (LD) - * Stripe number (stripRow) - * Reference in stripe (stripRef) - * Outputs: Span number - * Absolute Block number in the physical disk +/* + * MR_GetPhyParams: Calculates arm, span, and block + * Inputs: Adapter soft state + * Logical drive number (LD) + * Stripe number(stripRow) + * Reference in stripe (stripRef) * - * This routine calculates the arm, span and block for the specified stripe - * and reference in stripe. + * Outputs: Absolute Block number in the physical disk + * + * This routine calculates the arm, span and block for the specified stripe and + * reference in stripe. */ -u_int8_t MR_GetPhyParams(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_FW_RAID_MAP_ALL *map) +u_int8_t +MR_GetPhyParams(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; - int error_code = 0; + 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; + int error_code = 0; u_int64_t *pdBlock = &io_info->pdBlock; - u_int16_t *pDevHandle = &io_info->devHandle; - u_int32_t rowMod, armQ, arm, logArm; + u_int16_t *pDevHandle = &io_info->devHandle; + u_int32_t rowMod, armQ, arm, logArm; u_int8_t do_invader = 0; if ((sc->device_id == MRSAS_INVADER) || (sc->device_id == MRSAS_FURY)) do_invader = 1; - row = mega_div64_32(stripRow, raid->rowDataSize); - - if (raid->level == 6) { - logArm = mega_mod64(stripRow, raid->rowDataSize); // logical arm within row - if (raid->rowSize == 0) - return FALSE; - rowMod = mega_mod64(row, raid->rowSize); // get logical row mod - 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 = (u_int8_t)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 = (u_int8_t)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); - - pd = MR_ArPdGet(arRef, physArm, map); // Get the Pd. - - if (pd != MR_PD_INVALID) - *pDevHandle = MR_PdDevHandleGet(pd, map); // Get dev handle from Pd. - 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) { - pd = MR_ArPdGet(arRef, physArm + 1, map); // Get Alternate Pd. - if (pd != MR_PD_INVALID) - *pDevHandle = MR_PdDevHandleGet(pd, map);//Get dev handle from Pd. - } - } - - *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk; - pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; - return retval; + row = mega_div64_32(stripRow, raid->rowDataSize); + + if (raid->level == 6) { + /* logical arm within row */ + logArm = mega_mod64(stripRow, raid->rowDataSize); + if (raid->rowSize == 0) + return FALSE; + rowMod = mega_mod64(row, raid->rowSize); /* get logical row mod */ + 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 = (u_int8_t)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 = (u_int8_t)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); + + 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 + MR_LdSpanPtrGet(ld, span, map)->startBlk; + pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm; + return retval; } -/** - * MR_GetSpanBlock Calculates span block - * Inputs: LD - * row - * PD span block - * RAID map pointer - * Outputs: Span number - * Error code +/* + * MR_GetSpanBlock: Calculates span block + * Inputs: LD + * row PD + * span block + * RAID map pointer * - * This routine calculates the span from the span block info. + * Outputs: Span number Error code + * + * This routine calculates the span from the span block info. */ -u_int32_t MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk, - MR_FW_RAID_MAP_ALL *map, int *div_error) +u_int32_t +MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk, + MR_DRV_RAID_MAP_ALL * map, int *div_error) { - MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map); - MR_QUAD_ELEMENT *quad; - MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - u_int32_t span, j; - u_int64_t blk, debugBlk; - - for (span=0; span < raid->spanDepth; span++, pSpanBlock++) { - for (j=0; j < pSpanBlock->block_span_info.noElements; j++) { - quad = &pSpanBlock->block_span_info.quad[j]; - if (quad->diff == 0) { - *div_error = 1; - return span; - } - if (quad->logStart <= row && row <= quad->logEnd && - (mega_mod64(row-quad->logStart, quad->diff)) == 0) { - if (span_blk != NULL) { - blk = mega_div64_32((row-quad->logStart), quad->diff); - debugBlk = blk; - blk = (blk + quad->offsetInSpan) << raid->stripeShift; - *span_blk = blk; - } - return span; - } - } - } - return span; + MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map); + MR_QUAD_ELEMENT *quad; + MR_LD_RAID *raid = MR_LdRaidGet(ld, map); + u_int32_t span, j; + u_int64_t blk, debugBlk; + + for (span = 0; span < raid->spanDepth; span++, pSpanBlock++) { + for (j = 0; j < pSpanBlock->block_span_info.noElements; j++) { + quad = &pSpanBlock->block_span_info.quad[j]; + if (quad->diff == 0) { + *div_error = 1; + return span; + } + if (quad->logStart <= row && row <= quad->logEnd && + (mega_mod64(row - quad->logStart, quad->diff)) == 0) { + if (span_blk != NULL) { + blk = mega_div64_32((row - quad->logStart), quad->diff); + debugBlk = blk; + blk = (blk + quad->offsetInSpan) << raid->stripeShift; + *span_blk = blk; + } + return span; + } + } + } + return span; } - |