33 #include <linux/kernel.h>
34 #include <linux/types.h>
35 #include <linux/pci.h>
36 #include <linux/list.h>
38 #include <linux/module.h>
42 #include <linux/uio.h>
47 #include <linux/poll.h>
49 #include <scsi/scsi.h>
56 #include <asm/div64.h>
58 #define ABS_DIFF(a, b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
59 #define MR_LD_STATE_OPTIMAL 3
76 remainder =
do_div(d, divisor);
95 remainder =
do_div(d, divisor);
102 return &map->
raidMap.ldSpanMap[
ld].ldRaid;
109 return &map->
raidMap.ldSpanMap[
ld].spanBlock[0];
114 return map->
raidMap.ldSpanMap[
ld].dataArmMap[armIdx];
124 return map->
raidMap.ldSpanMap[
ld].spanBlock[
span].span.arrayRef;
129 return map->
raidMap.devHndlInfo[pd].curDevHdl;
134 return map->
raidMap.ldSpanMap[
ld].ldRaid.targetId;
139 return map->
raidMap.ldTgtIdToLd[ldTgtId];
145 return &map->
raidMap.ldSpanMap[
ld].spanBlock[span].span;
159 printk(
KERN_ERR "megasas: map info structure size 0x%x is not matching with ld count\n",
183 for (span = 0; span < raid->
spanDepth; span++, pSpanBlock++) {
188 if (quad->
diff == 0) {
192 if (quad->
logStart <= row && row <= quad->logEnd &&
194 if (span_blk !=
NULL) {
231 u16 stripRef,
u64 *pdBlock,
u16 *pDevHandle,
244 if (raid->
level == 6) {
261 physArm = MR_LdDataArmGet(ld,
mega_mod64(stripRow,
276 arRef = MR_LdSpanArrayGet(ld, span, map);
277 pd = MR_ArPdGet(arRef, physArm, map);
281 *pDevHandle = MR_PdDevHandleGet(pd, map);
284 if ((raid->
level >= 5) &&
289 else if (raid->
level == 1) {
291 pd = MR_ArPdGet(arRef, physArm + 1, map);
294 *pDevHandle = MR_PdDevHandleGet(pd, map);
298 *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
320 u32 ld, stripSize, stripe_mask;
321 u64 endLba, endStrip, endRow, start_row, start_strip;
324 u8 num_strips, numRows;
325 u16 ref_in_start_stripe, ref_in_end_stripe;
327 u32 numBlocks, ldTgtId;
340 stripe_mask = stripSize-1;
345 ref_in_start_stripe = (
u16)(ldStartBlock & stripe_mask);
346 endLba = ldStartBlock + numBlocks - 1;
347 ref_in_end_stripe = (
u16)(endLba & stripe_mask);
349 num_strips = (
u8)(endStrip - start_strip + 1);
354 numRows = (
u8)(endRow - start_row + 1);
369 ((num_strips == 1) ||
374 ((num_strips == 1) ||
382 if (num_strips == 1) {
383 regStart += ref_in_start_stripe;
388 if (start_strip == (start_row + 1) * raid->
rowDataSize - 1) {
390 regStart += ref_in_start_stripe;
391 regSize = stripSize - ref_in_start_stripe;
402 regSize += ref_in_end_stripe+1;
404 regSize += stripSize;
433 for (stripIdx = 0; stripIdx < num_strips; stripIdx++) {
435 start_strip + stripIdx,
456 if (ld >= MAX_LOGICAL_DRIVES) {
472 arRef = MR_LdSpanArrayGet(ld, 0, map);
475 pd = MR_ArPdGet(arRef, 0, map);
478 MR_PdDevHandleGet(pd, map);
480 pd = MR_ArPdGet(arRef, 1, map);
484 MR_PdDevHandleGet(pd, map);
504 bestArm = (diff0 <= diff1 ? 0 : 1);
506 if ((bestArm == arm && pend0 > pend1 + 16) ||
507 (bestArm != arm && pend1 > pend0 + 16))