megaraid_sas : Add separate functions for building sysPD IOs and non RW LDIOs
authorSumit.Saxena@avagotech.com <Sumit.Saxena@avagotech.com>
Thu, 23 Apr 2015 11:00:39 +0000 (16:30 +0530)
committerJames Bottomley <JBottomley@Odin.com>
Mon, 25 May 2015 15:46:27 +0000 (08:46 -0700)
Signed-off-by: Kashyap Desai <kashyap.desai@avagotech.com>
Signed-off-by: Sumit Saxena <sumit.saxena@avagotech.com>
Reviewed-by: Tomas Henzl <thenzl@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
drivers/scsi/megaraid/megaraid_sas.h
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/megaraid/megaraid_sas_fusion.c

index 14e5c7cea929246b8c0caaffef675e83101bc4b7..bdcf2b69778dcddc90e07ca78ffa621042bd4740 100644 (file)
@@ -1864,9 +1864,13 @@ struct megasas_instance_template {
 #define MEGASAS_IS_LOGICAL(scp)                                                \
        (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
 
-#define MEGASAS_DEV_INDEX(inst, scp)                                   \
-       ((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) +    \
-       scp->device->id
+#define MEGASAS_DEV_INDEX(scp)                                         \
+       (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) +   \
+       scp->device->id)
+
+#define MEGASAS_PD_INDEX(scp)                                          \
+       ((scp->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +         \
+       scp->device->id)
 
 struct megasas_cmd {
 
index 5be9ce45bde8e1ae1dab2cdbc0441505c5f24cdc..1bd32721131d6427c372b0b8d233d3715b358196 100644 (file)
@@ -1196,7 +1196,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
        struct megasas_pthru_frame *pthru;
 
        is_logical = MEGASAS_IS_LOGICAL(scp);
-       device_id = MEGASAS_DEV_INDEX(instance, scp);
+       device_id = MEGASAS_DEV_INDEX(scp);
        pthru = (struct megasas_pthru_frame *)cmd->frame;
 
        if (scp->sc_data_direction == PCI_DMA_TODEVICE)
@@ -1294,7 +1294,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
        u16 flags = 0;
        struct megasas_io_frame *ldio;
 
-       device_id = MEGASAS_DEV_INDEX(instance, scp);
+       device_id = MEGASAS_DEV_INDEX(scp);
        ldio = (struct megasas_io_frame *)cmd->frame;
 
        if (scp->sc_data_direction == PCI_DMA_TODEVICE)
index 58b96f9e3bce1dd4e5888174af9d909c19165292..d38f85e6f26e2d5e86eeeba943de58e101c0dd9c 100644 (file)
@@ -1497,7 +1497,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
        struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
        u8 *raidLUN;
 
-       device_id = MEGASAS_DEV_INDEX(instance, scp);
+       device_id = MEGASAS_DEV_INDEX(scp);
 
        fusion = instance->ctrl_context;
 
@@ -1650,23 +1650,19 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
 }
 
 /**
- * megasas_build_dcdb_fusion - Prepares IOs to devices
+ * megasas_build_ld_nonrw_fusion - prepares non rw ios for virtual disk
  * @instance:          Adapter soft state
  * @scp:               SCSI command
  * @cmd:               Command to be prepared
  *
- * Prepares the io_request frame for non-io cmds
+ * Prepares the io_request frame for non-rw io cmds for vd.
  */
-static void
-megasas_build_dcdb_fusion(struct megasas_instance *instance,
-                         struct scsi_cmnd *scmd,
-                         struct megasas_cmd_fusion *cmd)
+static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
+                         struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd)
 {
        u32 device_id;
        struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
        u16 pd_index = 0;
-       u16 os_timeout_value;
-       u16 timeout_limit;
        struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
        struct fusion_context *fusion = instance->ctrl_context;
        u8                          span, physArm;
@@ -1674,97 +1670,48 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
        u32                         ld, arRef, pd;
        struct MR_LD_RAID                  *raid;
        struct RAID_CONTEXT                *pRAID_Context;
+       u8 fp_possible = 1;
 
        io_request = cmd->io_request;
-       device_id = MEGASAS_DEV_INDEX(instance, scmd);
-       pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL)
-               +scmd->device->id;
+       device_id = MEGASAS_DEV_INDEX(scmd);
+       pd_index = MEGASAS_PD_INDEX(scmd);
        local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
-
        io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
+       /* get RAID_Context pointer */
+       pRAID_Context = &io_request->RaidContext;
+       /* Check with FW team */
+       pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+       pRAID_Context->regLockRowLBA    = 0;
+       pRAID_Context->regLockLength    = 0;
 
-       if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS &&
-           instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) {
-               if (fusion->fast_path_io)
-                       io_request->DevHandle =
-                       local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
-               io_request->RaidContext.RAIDFlags =
-                       MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
-                       << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
-               cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
-               cmd->request_desc->SCSIIO.MSIxIndex =
-                       instance->msix_vectors ?
-                               raw_smp_processor_id() %
-                                       instance->msix_vectors :
-                               0;
-               os_timeout_value = scmd->request->timeout / HZ;
-
-               if (instance->secure_jbod_support &&
-                       (megasas_cmd_type(scmd) == NON_READ_WRITE_SYSPDIO)) {
-                       /* system pd firmware path */
-                       io_request->Function  =
-                               MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
-                       cmd->request_desc->SCSIIO.RequestFlags =
-                               (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
-                               MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-                       io_request->RaidContext.timeoutValue =
-                               cpu_to_le16(os_timeout_value);
-               } else {
-                       /* system pd Fast Path */
-                       io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
-                       io_request->RaidContext.regLockFlags = 0;
-                       io_request->RaidContext.regLockRowLBA = 0;
-                       io_request->RaidContext.regLockLength = 0;
-                       timeout_limit = (scmd->device->type == TYPE_DISK) ?
-                                       255 : 0xFFFF;
-                       io_request->RaidContext.timeoutValue =
-                               cpu_to_le16((os_timeout_value > timeout_limit) ?
-                               timeout_limit : os_timeout_value);
-               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
-                       (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY))
-                       io_request->IoFlags |=
-                       cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
-
-                       cmd->request_desc->SCSIIO.RequestFlags =
-                               (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
-                               MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
-               }
-       } else {
-               if (scmd->device->channel < MEGASAS_MAX_PD_CHANNELS)
-                       goto NonFastPath;
-
-               /*
-                * For older firmware, Driver should not access ldTgtIdToLd
-                * beyond index 127 and for Extended VD firmware, ldTgtIdToLd
-                * should not go beyond 255.
-                */
-
-               if ((!fusion->fast_path_io) ||
-                       (device_id >= instance->fw_supported_vd_count))
-                       goto NonFastPath;
+       if (fusion->fast_path_io && (
+               device_id < instance->fw_supported_vd_count)) {
 
                ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
-
                if (ld >= instance->fw_supported_vd_count)
-                       goto NonFastPath;
+                       fp_possible = 0;
 
                raid = MR_LdRaidGet(ld, local_map_ptr);
-
-               /* check if this LD is FP capable */
                if (!(raid->capability.fpNonRWCapable))
-                       /* not FP capable, send as non-FP */
-                       goto NonFastPath;
+                       fp_possible = 0;
+       } else
+               fp_possible = 0;
 
-               /* get RAID_Context pointer */
-               pRAID_Context = &io_request->RaidContext;
+       if (!fp_possible) {
+               io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
+               io_request->DevHandle = cpu_to_le16(device_id);
+               io_request->LUN[1] = scmd->device->lun;
+               pRAID_Context->timeoutValue =
+                       cpu_to_le16 (scmd->request->timeout / HZ);
+               cmd->request_desc->SCSIIO.RequestFlags =
+                       (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
+                       MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+       } else {
 
                /* set RAID context values */
-               pRAID_Context->regLockFlags     = REGION_TYPE_SHARED_READ;
-               pRAID_Context->timeoutValue     = cpu_to_le16(raid->fpIoTimeoutForLd);
-               pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
-               pRAID_Context->regLockRowLBA    = 0;
-               pRAID_Context->regLockLength    = 0;
-               pRAID_Context->configSeqNum     = raid->seqNum;
+               pRAID_Context->configSeqNum = raid->seqNum;
+               pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
+               pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
 
                /* get the DevHandle for the PD (since this is
                   fpNonRWCapable, this is a single disk RAID0) */
@@ -1776,7 +1723,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
                /* build request descriptor */
                cmd->request_desc->SCSIIO.RequestFlags =
                        (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
-                        MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+                       MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
                cmd->request_desc->SCSIIO.DevHandle = devHandle;
 
                /* populate the LUN field */
@@ -1785,18 +1732,87 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
                /* build the raidScsiIO structure */
                io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
                io_request->DevHandle = devHandle;
+       }
+}
 
-               return;
+/**
+ * megasas_build_syspd_fusion - prepares rw/non-rw ios for syspd
+ * @instance:          Adapter soft state
+ * @scp:               SCSI command
+ * @cmd:               Command to be prepared
+ * @fp_possible:       parameter to detect fast path or firmware path io.
+ *
+ * Prepares the io_request frame for rw/non-rw io cmds for syspds
+ */
+static void
+megasas_build_syspd_fusion(struct megasas_instance *instance,
+       struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd, u8 fp_possible)
+{
+       u32 device_id;
+       struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
+       u16 pd_index = 0;
+       u16 os_timeout_value;
+       u16 timeout_limit;
+       struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
+       struct RAID_CONTEXT     *pRAID_Context;
+       struct fusion_context *fusion = instance->ctrl_context;
+
+       device_id = MEGASAS_DEV_INDEX(scmd);
+       pd_index = MEGASAS_PD_INDEX(scmd);
+       os_timeout_value = scmd->request->timeout / HZ;
 
-NonFastPath:
+       io_request = cmd->io_request;
+       /* get RAID_Context pointer */
+       pRAID_Context = &io_request->RaidContext;
+       io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd));
+       io_request->LUN[1] = scmd->device->lun;
+       pRAID_Context->RAIDFlags = MR_RAID_FLAGS_IO_SUB_TYPE_SYSTEM_PD
+               << MR_RAID_CTX_RAID_FLAGS_IO_SUB_TYPE_SHIFT;
+
+       pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+       pRAID_Context->configSeqNum = 0;
+       local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
+       io_request->DevHandle =
+               local_map_ptr->raidMap.devHndlInfo[device_id].curDevHdl;
+
+       cmd->request_desc->SCSIIO.DevHandle = io_request->DevHandle;
+       cmd->request_desc->SCSIIO.MSIxIndex =
+               instance->msix_vectors ?
+               (raw_smp_processor_id() % instance->msix_vectors) : 0;
+
+
+       if (!fp_possible) {
+               /* system pd firmware path */
                io_request->Function  = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
-               io_request->DevHandle = cpu_to_le16(device_id);
                cmd->request_desc->SCSIIO.RequestFlags =
                        (MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO <<
-                        MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+                               MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+               pRAID_Context->timeoutValue = cpu_to_le16(os_timeout_value);
+       } else {
+               /* system pd Fast Path */
+               io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
+               pRAID_Context->regLockFlags = 0;
+               pRAID_Context->regLockRowLBA = 0;
+               pRAID_Context->regLockLength = 0;
+               timeout_limit = (scmd->device->type == TYPE_DISK) ?
+                               255 : 0xFFFF;
+               pRAID_Context->timeoutValue =
+                       cpu_to_le16((os_timeout_value > timeout_limit) ?
+                       timeout_limit : os_timeout_value);
+               if ((instance->pdev->device == PCI_DEVICE_ID_LSI_INVADER) ||
+                       (instance->pdev->device == PCI_DEVICE_ID_LSI_FURY)) {
+                       cmd->request_desc->SCSIIO.RequestFlags |=
+                               (MEGASAS_REQ_DESCRIPT_FLAGS_NO_LOCK <<
+                               MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+                       pRAID_Context->Type = MPI2_TYPE_CUDA;
+                       pRAID_Context->nseg = 0x1;
+                       io_request->IoFlags |=
+                               cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
+               }
+               cmd->request_desc->SCSIIO.RequestFlags =
+                       (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
+                               MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
        }
-       io_request->RaidContext.VirtualDiskTgtId = cpu_to_le16(device_id);
-       int_to_scsilun(scmd->device->lun, (struct scsi_lun *)io_request->LUN);
 }
 
 /**
@@ -1813,11 +1829,10 @@ megasas_build_io_fusion(struct megasas_instance *instance,
                        struct scsi_cmnd *scp,
                        struct megasas_cmd_fusion *cmd)
 {
-       u32 device_id, sge_count;
+       u32 sge_count;
+       u8  cmd_type;
        struct MPI2_RAID_SCSI_IO_REQUEST *io_request = cmd->io_request;
 
-       device_id = MEGASAS_DEV_INDEX(instance, scp);
-
        /* Zero out some fields so they don't get reused */
        memset(io_request->LUN, 0x0, 8);
        io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
@@ -1837,10 +1852,24 @@ megasas_build_io_fusion(struct megasas_instance *instance,
         */
        io_request->IoFlags = cpu_to_le16(scp->cmd_len);
 
-       if (megasas_cmd_type(scp) == READ_WRITE_LDIO)
+       switch (cmd_type = megasas_cmd_type(scp)) {
+       case READ_WRITE_LDIO:
                megasas_build_ldio_fusion(instance, scp, cmd);
-       else
-               megasas_build_dcdb_fusion(instance, scp, cmd);
+               break;
+       case NON_READ_WRITE_LDIO:
+               megasas_build_ld_nonrw_fusion(instance, scp, cmd);
+               break;
+       case READ_WRITE_SYSPDIO:
+       case NON_READ_WRITE_SYSPDIO:
+               if (instance->secure_jbod_support &&
+                       (cmd_type == NON_READ_WRITE_SYSPDIO))
+                       megasas_build_syspd_fusion(instance, scp, cmd, 0);
+               else
+                       megasas_build_syspd_fusion(instance, scp, cmd, 1);
+               break;
+       default:
+               break;
+       }
 
        /*
         * Construct SGL
@@ -2016,8 +2045,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
                switch (scsi_io_req->Function) {
                case MPI2_FUNCTION_SCSI_IO_REQUEST:  /*Fast Path IO.*/
                        /* Update load balancing info */
-                       device_id = MEGASAS_DEV_INDEX(instance,
-                                                     cmd_fusion->scmd);
+                       device_id = MEGASAS_DEV_INDEX(cmd_fusion->scmd);
                        lbinfo = &fusion->load_balance_info[device_id];
                        if (cmd_fusion->scmd->SCp.Status &
                            MEGASAS_LOAD_BALANCE_FLAG) {