forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/scsi/megaraid/megaraid_sas_fp.c
....@@ -1,35 +1,21 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Linux MegaRAID driver for SAS based RAID controllers
34 *
45 * Copyright (c) 2009-2013 LSI Corporation
5
- * Copyright (c) 2013-2014 Avago Technologies
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version 2
10
- * of the License, or (at your option) any later version.
11
- *
12
- * This program is distributed in the hope that it will be useful,
13
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- * GNU General Public License for more details.
16
- *
17
- * You should have received a copy of the GNU General Public License
18
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
6
+ * Copyright (c) 2013-2016 Avago Technologies
7
+ * Copyright (c) 2016-2018 Broadcom Inc.
198 *
209 * FILE: megaraid_sas_fp.c
2110 *
22
- * Authors: Avago Technologies
11
+ * Authors: Broadcom Inc.
2312 * Sumant Patro
2413 * Varad Talamacki
2514 * Manoj Jose
26
- * Kashyap Desai <kashyap.desai@avagotech.com>
27
- * Sumit Saxena <sumit.saxena@avagotech.com>
15
+ * Kashyap Desai <kashyap.desai@broadcom.com>
16
+ * Sumit Saxena <sumit.saxena@broadcom.com>
2817 *
29
- * Send feedback to: megaraidlinux.pdl@avagotech.com
30
- *
31
- * Mail to: Avago Technologies, 350 West Trimble Road, Building 90,
32
- * San Jose, California 95131
18
+ * Send feedback to: megaraidlinux.pdl@broadcom.com
3319 */
3420
3521 #include <linux/kernel.h>
....@@ -47,6 +33,7 @@
4733 #include <linux/compat.h>
4834 #include <linux/blkdev.h>
4935 #include <linux/poll.h>
36
+#include <linux/irq_poll.h>
5037
5138 #include <scsi/scsi.h>
5239 #include <scsi/scsi_cmnd.h>
....@@ -59,7 +46,7 @@
5946
6047 #define LB_PENDING_CMDS_DEFAULT 4
6148 static unsigned int lb_pending_cmds = LB_PENDING_CMDS_DEFAULT;
62
-module_param(lb_pending_cmds, int, S_IRUGO);
49
+module_param(lb_pending_cmds, int, 0444);
6350 MODULE_PARM_DESC(lb_pending_cmds, "Change raid-1 load balancing outstanding "
6451 "threshold. Valid Values are 1-128. Default: 4");
6552
....@@ -93,21 +80,20 @@
9380 }
9481
9582 /**
96
- * @param dividend : Dividend
97
- * @param divisor : Divisor
83
+ * mega_div64_32 - Do a 64-bit division
84
+ * @dividend: Dividend
85
+ * @divisor: Divisor
9886 *
9987 * @return quotient
10088 **/
101
-u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
89
+static u64 mega_div64_32(uint64_t dividend, uint32_t divisor)
10290 {
103
- u32 remainder;
104
- u64 d;
91
+ u64 d = dividend;
10592
10693 if (!divisor)
10794 printk(KERN_ERR "megasas : DIVISOR is zero in mod fn\n");
10895
109
- d = dividend;
110
- remainder = do_div(d, divisor);
96
+ do_div(d, divisor);
11197
11298 return d;
11399 }
....@@ -363,24 +349,28 @@
363349
364350 num_lds = le16_to_cpu(drv_map->raidMap.ldCount);
365351
352
+ memcpy(instance->ld_ids_prev,
353
+ instance->ld_ids_from_raidmap,
354
+ sizeof(instance->ld_ids_from_raidmap));
355
+ memset(instance->ld_ids_from_raidmap, 0xff, MEGASAS_MAX_LD_IDS);
366356 /*Convert Raid capability values to CPU arch */
367357 for (i = 0; (num_lds > 0) && (i < MAX_LOGICAL_DRIVES_EXT); i++) {
368358 ld = MR_TargetIdToLdGet(i, drv_map);
369359
370360 /* For non existing VDs, iterate to next VD*/
371
- if (ld >= (MAX_LOGICAL_DRIVES_EXT - 1))
361
+ if (ld >= MEGASAS_MAX_SUPPORTED_LD_IDS)
372362 continue;
373363
374364 raid = MR_LdRaidGet(ld, drv_map);
375365 le32_to_cpus((u32 *)&raid->capability);
376
-
366
+ instance->ld_ids_from_raidmap[i] = i;
377367 num_lds--;
378368 }
379369
380370 return 1;
381371 }
382372
383
-u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
373
+static u32 MR_GetSpanBlock(u32 ld, u64 row, u64 *span_blk,
384374 struct MR_DRV_RAID_MAP_ALL *map)
385375 {
386376 struct MR_SPAN_BLOCK_INFO *pSpanBlock = MR_LdSpanInfoGet(ld, map);
....@@ -399,9 +389,8 @@
399389 le64_to_cpu(quad->logEnd) && (mega_mod64(row - le64_to_cpu(quad->logStart),
400390 le32_to_cpu(quad->diff))) == 0) {
401391 if (span_blk != NULL) {
402
- u64 blk, debugBlk;
392
+ u64 blk;
403393 blk = mega_div64_32((row-le64_to_cpu(quad->logStart)), le32_to_cpu(quad->diff));
404
- debugBlk = blk;
405394
406395 blk = (blk + le64_to_cpu(quad->offsetInSpan)) << raid->stripeShift;
407396 *span_blk = blk;
....@@ -431,7 +420,7 @@
431420 * div_error - Devide error code.
432421 */
433422
434
-u32 mr_spanset_get_span_block(struct megasas_instance *instance,
423
+static u32 mr_spanset_get_span_block(struct megasas_instance *instance,
435424 u32 ld, u64 row, u64 *span_blk, struct MR_DRV_RAID_MAP_ALL *map)
436425 {
437426 struct fusion_context *fusion = instance->ctrl_context;
....@@ -656,7 +645,7 @@
656645 }
657646
658647 /* This Function will return Phys arm */
659
-u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
648
+static u8 get_arm(struct megasas_instance *instance, u32 ld, u8 span, u64 stripe,
660649 struct MR_DRV_RAID_MAP_ALL *map)
661650 {
662651 struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
....@@ -712,9 +701,7 @@
712701 __le16 *pDevHandle = &io_info->devHandle;
713702 u8 *pPdInterface = &io_info->pd_interface;
714703 u32 logArm, rowMod, armQ, arm;
715
- struct fusion_context *fusion;
716704
717
- fusion = instance->ctrl_context;
718705 *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
719706
720707 /*Get row and span from io_info for Uneven Span IO.*/
....@@ -745,7 +732,7 @@
745732 *pDevHandle = MR_PdDevHandleGet(pd, map);
746733 *pPdInterface = MR_PdInterfaceTypeGet(pd, map);
747734 /* get second pd also for raid 1/10 fast path writes*/
748
- if ((instance->adapter_type == VENTURA_SERIES) &&
735
+ if ((instance->adapter_type >= VENTURA_SERIES) &&
749736 (raid->level == 1) &&
750737 !io_info->isRead) {
751738 r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map);
....@@ -770,7 +757,7 @@
770757 }
771758
772759 *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk);
773
- if (instance->adapter_type == VENTURA_SERIES) {
760
+ if (instance->adapter_type >= VENTURA_SERIES) {
774761 ((struct RAID_CONTEXT_G35 *)pRAID_Context)->span_arm =
775762 (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
776763 io_info->span_arm =
....@@ -801,7 +788,7 @@
801788 * span - Span number
802789 * block - Absolute Block number in the physical disk
803790 */
804
-u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
791
+static u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow,
805792 u16 stripRef, struct IO_REQUEST_INFO *io_info,
806793 struct RAID_CONTEXT *pRAID_Context,
807794 struct MR_DRV_RAID_MAP_ALL *map)
....@@ -814,9 +801,7 @@
814801 u64 *pdBlock = &io_info->pdBlock;
815802 __le16 *pDevHandle = &io_info->devHandle;
816803 u8 *pPdInterface = &io_info->pd_interface;
817
- struct fusion_context *fusion;
818804
819
- fusion = instance->ctrl_context;
820805 *pDevHandle = cpu_to_le16(MR_DEVHANDLE_INVALID);
821806
822807 row = mega_div64_32(stripRow, raid->rowDataSize);
....@@ -861,7 +846,7 @@
861846 *pDevHandle = MR_PdDevHandleGet(pd, map);
862847 *pPdInterface = MR_PdInterfaceTypeGet(pd, map);
863848 /* get second pd also for raid 1/10 fast path writes*/
864
- if ((instance->adapter_type == VENTURA_SERIES) &&
849
+ if ((instance->adapter_type >= VENTURA_SERIES) &&
865850 (raid->level == 1) &&
866851 !io_info->isRead) {
867852 r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map);
....@@ -888,7 +873,7 @@
888873 }
889874
890875 *pdBlock += stripRef + le64_to_cpu(MR_LdSpanPtrGet(ld, span, map)->startBlk);
891
- if (instance->adapter_type == VENTURA_SERIES) {
876
+ if (instance->adapter_type >= VENTURA_SERIES) {
892877 ((struct RAID_CONTEXT_G35 *)pRAID_Context)->span_arm =
893878 (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
894879 io_info->span_arm =
....@@ -900,6 +885,77 @@
900885 }
901886 io_info->pd_after_lb = pd;
902887 return retval;
888
+}
889
+
890
+/*
891
+ * mr_get_phy_params_r56_rmw - Calculate parameters for R56 CTIO write operation
892
+ * @instance: Adapter soft state
893
+ * @ld: LD index
894
+ * @stripNo: Strip Number
895
+ * @io_info: IO info structure pointer
896
+ * pRAID_Context: RAID context pointer
897
+ * map: RAID map pointer
898
+ *
899
+ * This routine calculates the logical arm, data Arm, row number and parity arm
900
+ * for R56 CTIO write operation.
901
+ */
902
+static void mr_get_phy_params_r56_rmw(struct megasas_instance *instance,
903
+ u32 ld, u64 stripNo,
904
+ struct IO_REQUEST_INFO *io_info,
905
+ struct RAID_CONTEXT_G35 *pRAID_Context,
906
+ struct MR_DRV_RAID_MAP_ALL *map)
907
+{
908
+ struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map);
909
+ u8 span, dataArms, arms, dataArm, logArm;
910
+ s8 rightmostParityArm, PParityArm;
911
+ u64 rowNum;
912
+ u64 *pdBlock = &io_info->pdBlock;
913
+
914
+ dataArms = raid->rowDataSize;
915
+ arms = raid->rowSize;
916
+
917
+ rowNum = mega_div64_32(stripNo, dataArms);
918
+ /* parity disk arm, first arm is 0 */
919
+ rightmostParityArm = (arms - 1) - mega_mod64(rowNum, arms);
920
+
921
+ /* logical arm within row */
922
+ logArm = mega_mod64(stripNo, dataArms);
923
+ /* physical arm for data */
924
+ dataArm = mega_mod64((rightmostParityArm + 1 + logArm), arms);
925
+
926
+ if (raid->spanDepth == 1) {
927
+ span = 0;
928
+ } else {
929
+ span = (u8)MR_GetSpanBlock(ld, rowNum, pdBlock, map);
930
+ if (span == SPAN_INVALID)
931
+ return;
932
+ }
933
+
934
+ if (raid->level == 6) {
935
+ /* P Parity arm, note this can go negative adjust if negative */
936
+ PParityArm = (arms - 2) - mega_mod64(rowNum, arms);
937
+
938
+ if (PParityArm < 0)
939
+ PParityArm += arms;
940
+
941
+ /* rightmostParityArm is P-Parity for RAID 5 and Q-Parity for RAID */
942
+ pRAID_Context->flow_specific.r56_arm_map = rightmostParityArm;
943
+ pRAID_Context->flow_specific.r56_arm_map |=
944
+ (u16)(PParityArm << RAID_CTX_R56_P_ARM_SHIFT);
945
+ } else {
946
+ pRAID_Context->flow_specific.r56_arm_map |=
947
+ (u16)(rightmostParityArm << RAID_CTX_R56_P_ARM_SHIFT);
948
+ }
949
+
950
+ pRAID_Context->reg_lock_row_lba = cpu_to_le64(rowNum);
951
+ pRAID_Context->flow_specific.r56_arm_map |=
952
+ (u16)(logArm << RAID_CTX_R56_LOG_ARM_SHIFT);
953
+ cpu_to_le16s(&pRAID_Context->flow_specific.r56_arm_map);
954
+ pRAID_Context->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | dataArm;
955
+ pRAID_Context->raid_flags = (MR_RAID_FLAGS_IO_SUB_TYPE_R56_DIV_OFFLOAD <<
956
+ MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT);
957
+
958
+ return;
903959 }
904960
905961 /*
....@@ -968,6 +1024,7 @@
9681024 stripSize = 1 << raid->stripeShift;
9691025 stripe_mask = stripSize-1;
9701026
1027
+ io_info->data_arms = raid->rowDataSize;
9711028
9721029 /*
9731030 * calculate starting row and stripe, and number of strips and rows
....@@ -1109,6 +1166,13 @@
11091166 /* save pointer to raid->LUN array */
11101167 *raidLUN = raid->LUN;
11111168
1169
+ /* Aero R5/6 Division Offload for WRITE */
1170
+ if (fusion->r56_div_offload && (raid->level >= 5) && !isRead) {
1171
+ mr_get_phy_params_r56_rmw(instance, ld, start_strip, io_info,
1172
+ (struct RAID_CONTEXT_G35 *)pRAID_Context,
1173
+ map);
1174
+ return true;
1175
+ }
11121176
11131177 /*Get Phy Params only if FP capable, or else leave it to MR firmware
11141178 to do the calculation.*/
....@@ -1281,7 +1345,7 @@
12811345 }
12821346 }
12831347
1284
-u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
1348
+static u8 megasas_get_best_arm_pd(struct megasas_instance *instance,
12851349 struct LD_LOAD_BALANCE_INFO *lbInfo,
12861350 struct IO_REQUEST_INFO *io_info,
12871351 struct MR_DRV_RAID_MAP_ALL *drv_map)