Print this page
5719 Add support for LSI Fury adapters


   4  * ld_pd_map.c
   5  *
   6  * Solaris MegaRAID device driver for SAS2.0 controllers
   7  * Copyright (c) 2008-2012, LSI Logic Corporation.
   8  * All rights reserved.
   9  *
  10  * Version:
  11  * Author:
  12  *              Swaminathan K S
  13  *              Arun Chandrashekhar
  14  *              Manju R
  15  *              Rasheed
  16  *              Shakeel Bukhari
  17  *
  18  *
  19  * This module contains functions for device drivers
  20  * to get pd-ld mapping information.
  21  *
  22  * **********************************************************************
  23  */



  24 
  25 #include <sys/scsi/scsi.h>
  26 #include "mr_sas.h"
  27 #include "ld_pd_map.h"
  28 
  29 /*
  30  * This function will check if FAST IO is possible on this logical drive
  31  * by checking the EVENT information available in the driver
  32  */
  33 #define MR_LD_STATE_OPTIMAL 3
  34 #define ABS_DIFF(a, b)   (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
  35 
  36 static void mr_update_load_balance_params(MR_FW_RAID_MAP_ALL *,
  37     PLD_LOAD_BALANCE_INFO);
  38 
  39 #define FALSE 0
  40 #define TRUE 1
  41 
  42 typedef U64     REGION_KEY;
  43 typedef U32     REGION_LEN;


 192  *
 193  * Outputs :
 194  *
 195  *    span          - Span number
 196  *    block         - Absolute Block number in the physical disk
 197  */
 198 U8
 199 MR_GetPhyParams(struct mrsas_instance *instance, U32 ld, U64 stripRow,
 200     U16 stripRef, U64 *pdBlock, U16 *pDevHandle,
 201     MPI2_SCSI_IO_VENDOR_UNIQUE *pRAID_Context, MR_FW_RAID_MAP_ALL *map)
 202 {
 203         MR_LD_RAID      *raid = MR_LdRaidGet(ld, map);
 204         U32             pd, arRef;
 205         U8              physArm, span;
 206         U64             row;
 207         int             error_code = 0;
 208         U8              retval = TRUE;
 209         U32             rowMod;
 210         U32             armQ;
 211         U32             arm;

 212 
 213         ASSERT(raid->rowDataSize != 0);
 214 
 215         row = (stripRow / raid->rowDataSize);
 216 
 217         if (raid->level == 6) {
 218                 U32 logArm =  (stripRow % (raid->rowDataSize));
 219 
 220                 if (raid->rowSize == 0) {
 221                         return (FALSE);
 222                 }
 223                 rowMod = (row % (raid->rowSize));
 224                 armQ = raid->rowSize-1-rowMod;
 225                 arm = armQ + 1 + logArm;
 226                 if (arm >= raid->rowSize)
 227                         arm -= raid->rowSize;
 228                 physArm = (U8)arm;
 229         } else {
 230                 if (raid->modFactor == 0)
 231                         return (FALSE);


 234         }
 235         if (raid->spanDepth == 1) {
 236                 span = 0;
 237                 *pdBlock = row << raid->stripeShift;
 238         } else
 239                 span = (U8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code);
 240 
 241         if (error_code == 1)
 242                 return (FALSE);
 243 
 244         /* Get the array on which this span is present. */
 245         arRef           = MR_LdSpanArrayGet(ld, span, map);
 246         /* Get the Pd. */
 247         pd              = MR_ArPdGet(arRef, physArm, map);
 248         /* Get dev handle from Pd. */
 249         if (pd != MR_PD_INVALID) {
 250                 *pDevHandle     = MR_PdDevHandleGet(pd, map);
 251         } else {
 252                 *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
 253                 if ((raid->level >= 5) &&
 254                     ((instance->device_id != PCI_DEVICE_ID_LSI_INVADER) ||
 255                     (instance->device_id == PCI_DEVICE_ID_LSI_INVADER &&

 256                     raid->regTypeReqOnRead != REGION_TYPE_UNUSED))) {
 257                         pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
 258                 } else if (raid->level == 1) {
 259                         /* Get Alternate Pd. */
 260                         pd = MR_ArPdGet(arRef, physArm + 1, map);
 261                         /* Get dev handle from Pd. */
 262                         if (pd != MR_PD_INVALID)
 263                                 *pDevHandle = MR_PdDevHandleGet(pd, map);
 264                 }
 265         }
 266 
 267         *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
 268 
 269         pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
 270             physArm;
 271 
 272         return (retval);
 273 }
 274 
 275 


 381                 }
 382         } else {
 383                 if (start_strip == (start_row + 1) * raid->rowDataSize - 1) {
 384                         regStart += ref_in_start_stripe;
 385                 regSize = stripSize - ref_in_start_stripe;
 386                 }
 387 
 388                 if (numRows > 2) {
 389                         regSize += (numRows - 2) << raid->stripeShift;
 390                 }
 391 
 392                 if (endStrip == endRow * raid->rowDataSize) {
 393                         regSize += ref_in_end_stripe + 1;
 394                 } else {
 395                         regSize += stripSize;
 396                 }
 397         }
 398 
 399         pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec;
 400 
 401         if (instance->device_id == PCI_DEVICE_ID_LSI_INVADER) {

 402                 pRAID_Context->regLockFlags = (isRead) ?
 403                     raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
 404         } else {
 405                 pRAID_Context->regLockFlags = (isRead) ?
 406                     REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
 407         }
 408 
 409         pRAID_Context->ldTargetId = raid->targetId;
 410         pRAID_Context->regLockRowLBA = regStart;
 411         pRAID_Context->regLockLength = regSize;
 412         pRAID_Context->configSeqNum = raid->seqNum;
 413 
 414         /*
 415          * Get Phy Params only if FP capable,
 416          * or else leave it to MR firmware to do the calculation.
 417          */
 418         if (io_info->fpOkForIo) {
 419                 /* if fast path possible then get the physical parameters */
 420                 retval = MR_GetPhyParams(instance, ld, start_strip,
 421                     ref_in_start_stripe, &io_info->pdBlock,




   4  * ld_pd_map.c
   5  *
   6  * Solaris MegaRAID device driver for SAS2.0 controllers
   7  * Copyright (c) 2008-2012, LSI Logic Corporation.
   8  * All rights reserved.
   9  *
  10  * Version:
  11  * Author:
  12  *              Swaminathan K S
  13  *              Arun Chandrashekhar
  14  *              Manju R
  15  *              Rasheed
  16  *              Shakeel Bukhari
  17  *
  18  *
  19  * This module contains functions for device drivers
  20  * to get pd-ld mapping information.
  21  *
  22  * **********************************************************************
  23  */
  24 /*
  25  * Copyright 2015 Garrett D'Amore <garrett@damore.org>
  26  */
  27 
  28 #include <sys/scsi/scsi.h>
  29 #include "mr_sas.h"
  30 #include "ld_pd_map.h"
  31 
  32 /*
  33  * This function will check if FAST IO is possible on this logical drive
  34  * by checking the EVENT information available in the driver
  35  */
  36 #define MR_LD_STATE_OPTIMAL 3
  37 #define ABS_DIFF(a, b)   (((a) > (b)) ? ((a) - (b)) : ((b) - (a)))
  38 
  39 static void mr_update_load_balance_params(MR_FW_RAID_MAP_ALL *,
  40     PLD_LOAD_BALANCE_INFO);
  41 
  42 #define FALSE 0
  43 #define TRUE 1
  44 
  45 typedef U64     REGION_KEY;
  46 typedef U32     REGION_LEN;


 195  *
 196  * Outputs :
 197  *
 198  *    span          - Span number
 199  *    block         - Absolute Block number in the physical disk
 200  */
 201 U8
 202 MR_GetPhyParams(struct mrsas_instance *instance, U32 ld, U64 stripRow,
 203     U16 stripRef, U64 *pdBlock, U16 *pDevHandle,
 204     MPI2_SCSI_IO_VENDOR_UNIQUE *pRAID_Context, MR_FW_RAID_MAP_ALL *map)
 205 {
 206         MR_LD_RAID      *raid = MR_LdRaidGet(ld, map);
 207         U32             pd, arRef;
 208         U8              physArm, span;
 209         U64             row;
 210         int             error_code = 0;
 211         U8              retval = TRUE;
 212         U32             rowMod;
 213         U32             armQ;
 214         U32             arm;
 215         U16             devid = instance->device_id;
 216 
 217         ASSERT(raid->rowDataSize != 0);
 218 
 219         row = (stripRow / raid->rowDataSize);
 220 
 221         if (raid->level == 6) {
 222                 U32 logArm =  (stripRow % (raid->rowDataSize));
 223 
 224                 if (raid->rowSize == 0) {
 225                         return (FALSE);
 226                 }
 227                 rowMod = (row % (raid->rowSize));
 228                 armQ = raid->rowSize-1-rowMod;
 229                 arm = armQ + 1 + logArm;
 230                 if (arm >= raid->rowSize)
 231                         arm -= raid->rowSize;
 232                 physArm = (U8)arm;
 233         } else {
 234                 if (raid->modFactor == 0)
 235                         return (FALSE);


 238         }
 239         if (raid->spanDepth == 1) {
 240                 span = 0;
 241                 *pdBlock = row << raid->stripeShift;
 242         } else
 243                 span = (U8)MR_GetSpanBlock(ld, row, pdBlock, map, &error_code);
 244 
 245         if (error_code == 1)
 246                 return (FALSE);
 247 
 248         /* Get the array on which this span is present. */
 249         arRef           = MR_LdSpanArrayGet(ld, span, map);
 250         /* Get the Pd. */
 251         pd              = MR_ArPdGet(arRef, physArm, map);
 252         /* Get dev handle from Pd. */
 253         if (pd != MR_PD_INVALID) {
 254                 *pDevHandle     = MR_PdDevHandleGet(pd, map);
 255         } else {
 256                 *pDevHandle = MR_PD_INVALID; /* set dev handle as invalid. */
 257                 if ((raid->level >= 5) &&
 258                     ((devid != PCI_DEVICE_ID_LSI_INVADER) ||
 259                     ((devid == PCI_DEVICE_ID_LSI_INVADER ||
 260                     (devid == PCI_DEVICE_ID_LSI_FURY)) &&
 261                     raid->regTypeReqOnRead != REGION_TYPE_UNUSED))) {
 262                         pRAID_Context->regLockFlags = REGION_TYPE_EXCLUSIVE;
 263                 } else if (raid->level == 1) {
 264                         /* Get Alternate Pd. */
 265                         pd = MR_ArPdGet(arRef, physArm + 1, map);
 266                         /* Get dev handle from Pd. */
 267                         if (pd != MR_PD_INVALID)
 268                                 *pDevHandle = MR_PdDevHandleGet(pd, map);
 269                 }
 270         }
 271 
 272         *pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
 273 
 274         pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) |
 275             physArm;
 276 
 277         return (retval);
 278 }
 279 
 280 


 386                 }
 387         } else {
 388                 if (start_strip == (start_row + 1) * raid->rowDataSize - 1) {
 389                         regStart += ref_in_start_stripe;
 390                 regSize = stripSize - ref_in_start_stripe;
 391                 }
 392 
 393                 if (numRows > 2) {
 394                         regSize += (numRows - 2) << raid->stripeShift;
 395                 }
 396 
 397                 if (endStrip == endRow * raid->rowDataSize) {
 398                         regSize += ref_in_end_stripe + 1;
 399                 } else {
 400                         regSize += stripSize;
 401                 }
 402         }
 403 
 404         pRAID_Context->timeoutValue = map->raidMap.fpPdIoTimeoutSec;
 405 
 406         if ((instance->device_id == PCI_DEVICE_ID_LSI_INVADER) ||
 407             (instance->device_id == PCI_DEVICE_ID_LSI_FURY)) {
 408                 pRAID_Context->regLockFlags = (isRead) ?
 409                     raid->regTypeReqOnRead : raid->regTypeReqOnWrite;
 410         } else {
 411                 pRAID_Context->regLockFlags = (isRead) ?
 412                     REGION_TYPE_SHARED_READ : raid->regTypeReqOnWrite;
 413         }
 414 
 415         pRAID_Context->ldTargetId = raid->targetId;
 416         pRAID_Context->regLockRowLBA = regStart;
 417         pRAID_Context->regLockLength = regSize;
 418         pRAID_Context->configSeqNum = raid->seqNum;
 419 
 420         /*
 421          * Get Phy Params only if FP capable,
 422          * or else leave it to MR firmware to do the calculation.
 423          */
 424         if (io_info->fpOkForIo) {
 425                 /* if fast path possible then get the physical parameters */
 426                 retval = MR_GetPhyParams(instance, ld, start_strip,
 427                     ref_in_start_stripe, &io_info->pdBlock,