Commit 4a5c814d authored by Sumit.Saxena@avagotech.com's avatar Sumit.Saxena@avagotech.com Committed by James Bottomley

megaraid_sas : Add separate functions for building sysPD IOs and non RW LDIOs

Signed-off-by: default avatarKashyap Desai <kashyap.desai@avagotech.com>
Signed-off-by: default avatarSumit Saxena <sumit.saxena@avagotech.com>
Reviewed-by: default avatarTomas Henzl <thenzl@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent 9b828182
...@@ -1864,9 +1864,13 @@ struct megasas_instance_template { ...@@ -1864,9 +1864,13 @@ struct megasas_instance_template {
#define MEGASAS_IS_LOGICAL(scp) \ #define MEGASAS_IS_LOGICAL(scp) \
(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1 (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
#define MEGASAS_DEV_INDEX(inst, scp) \ #define MEGASAS_DEV_INDEX(scp) \
((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \ (((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) + \
scp->device->id scp->device->id)
#define MEGASAS_PD_INDEX(scp) \
((scp->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + \
scp->device->id)
struct megasas_cmd { struct megasas_cmd {
......
...@@ -1196,7 +1196,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp, ...@@ -1196,7 +1196,7 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
struct megasas_pthru_frame *pthru; struct megasas_pthru_frame *pthru;
is_logical = MEGASAS_IS_LOGICAL(scp); 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; pthru = (struct megasas_pthru_frame *)cmd->frame;
if (scp->sc_data_direction == PCI_DMA_TODEVICE) if (scp->sc_data_direction == PCI_DMA_TODEVICE)
...@@ -1294,7 +1294,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp, ...@@ -1294,7 +1294,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
u16 flags = 0; u16 flags = 0;
struct megasas_io_frame *ldio; 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; ldio = (struct megasas_io_frame *)cmd->frame;
if (scp->sc_data_direction == PCI_DMA_TODEVICE) if (scp->sc_data_direction == PCI_DMA_TODEVICE)
......
...@@ -1497,7 +1497,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, ...@@ -1497,7 +1497,7 @@ megasas_build_ldio_fusion(struct megasas_instance *instance,
struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
u8 *raidLUN; u8 *raidLUN;
device_id = MEGASAS_DEV_INDEX(instance, scp); device_id = MEGASAS_DEV_INDEX(scp);
fusion = instance->ctrl_context; fusion = instance->ctrl_context;
...@@ -1650,23 +1650,19 @@ megasas_build_ldio_fusion(struct megasas_instance *instance, ...@@ -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 * @instance: Adapter soft state
* @scp: SCSI command * @scp: SCSI command
* @cmd: Command to be prepared * @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 static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance,
megasas_build_dcdb_fusion(struct megasas_instance *instance, struct scsi_cmnd *scmd, struct megasas_cmd_fusion *cmd)
struct scsi_cmnd *scmd,
struct megasas_cmd_fusion *cmd)
{ {
u32 device_id; u32 device_id;
struct MPI2_RAID_SCSI_IO_REQUEST *io_request; struct MPI2_RAID_SCSI_IO_REQUEST *io_request;
u16 pd_index = 0; u16 pd_index = 0;
u16 os_timeout_value;
u16 timeout_limit;
struct MR_DRV_RAID_MAP_ALL *local_map_ptr; struct MR_DRV_RAID_MAP_ALL *local_map_ptr;
struct fusion_context *fusion = instance->ctrl_context; struct fusion_context *fusion = instance->ctrl_context;
u8 span, physArm; u8 span, physArm;
...@@ -1674,97 +1670,48 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, ...@@ -1674,97 +1670,48 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
u32 ld, arRef, pd; u32 ld, arRef, pd;
struct MR_LD_RAID *raid; struct MR_LD_RAID *raid;
struct RAID_CONTEXT *pRAID_Context; struct RAID_CONTEXT *pRAID_Context;
u8 fp_possible = 1;
io_request = cmd->io_request; io_request = cmd->io_request;
device_id = MEGASAS_DEV_INDEX(instance, scmd); device_id = MEGASAS_DEV_INDEX(scmd);
pd_index = (scmd->device->channel * MEGASAS_MAX_DEV_PER_CHANNEL) pd_index = MEGASAS_PD_INDEX(scmd);
+scmd->device->id;
local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)]; local_map_ptr = fusion->ld_drv_map[(instance->map_id & 1)];
io_request->DataLength = cpu_to_le32(scsi_bufflen(scmd)); 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 && if (fusion->fast_path_io && (
instance->pd_list[pd_index].driveState == MR_PD_STATE_SYSTEM) { device_id < instance->fw_supported_vd_count)) {
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;
ld = MR_TargetIdToLdGet(device_id, local_map_ptr); ld = MR_TargetIdToLdGet(device_id, local_map_ptr);
if (ld >= instance->fw_supported_vd_count) if (ld >= instance->fw_supported_vd_count)
goto NonFastPath; fp_possible = 0;
raid = MR_LdRaidGet(ld, local_map_ptr); raid = MR_LdRaidGet(ld, local_map_ptr);
/* check if this LD is FP capable */
if (!(raid->capability.fpNonRWCapable)) if (!(raid->capability.fpNonRWCapable))
/* not FP capable, send as non-FP */ fp_possible = 0;
goto NonFastPath; } else
fp_possible = 0;
/* get RAID_Context pointer */ if (!fp_possible) {
pRAID_Context = &io_request->RaidContext; 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 */ /* set RAID context values */
pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ; pRAID_Context->configSeqNum = raid->seqNum;
pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd); pRAID_Context->regLockFlags = REGION_TYPE_SHARED_READ;
pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id); pRAID_Context->timeoutValue = cpu_to_le16(raid->fpIoTimeoutForLd);
pRAID_Context->regLockRowLBA = 0;
pRAID_Context->regLockLength = 0;
pRAID_Context->configSeqNum = raid->seqNum;
/* get the DevHandle for the PD (since this is /* get the DevHandle for the PD (since this is
fpNonRWCapable, this is a single disk RAID0) */ fpNonRWCapable, this is a single disk RAID0) */
...@@ -1776,7 +1723,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, ...@@ -1776,7 +1723,7 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* build request descriptor */ /* build request descriptor */
cmd->request_desc->SCSIIO.RequestFlags = cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY << (MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY <<
MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT); MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
cmd->request_desc->SCSIIO.DevHandle = devHandle; cmd->request_desc->SCSIIO.DevHandle = devHandle;
/* populate the LUN field */ /* populate the LUN field */
...@@ -1785,18 +1732,87 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance, ...@@ -1785,18 +1732,87 @@ megasas_build_dcdb_fusion(struct megasas_instance *instance,
/* build the raidScsiIO structure */ /* build the raidScsiIO structure */
io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST; io_request->Function = MPI2_FUNCTION_SCSI_IO_REQUEST;
io_request->DevHandle = devHandle; 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->Function = MEGASAS_MPI2_FUNCTION_LD_IO_REQUEST;
io_request->DevHandle = cpu_to_le16(device_id);
cmd->request_desc->SCSIIO.RequestFlags = cmd->request_desc->SCSIIO.RequestFlags =
(MPI2_REQ_DESCRIPT_FLAGS_SCSI_IO << (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, ...@@ -1813,11 +1829,10 @@ megasas_build_io_fusion(struct megasas_instance *instance,
struct scsi_cmnd *scp, struct scsi_cmnd *scp,
struct megasas_cmd_fusion *cmd) 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; 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 */ /* Zero out some fields so they don't get reused */
memset(io_request->LUN, 0x0, 8); memset(io_request->LUN, 0x0, 8);
io_request->CDB.EEDP32.PrimaryReferenceTag = 0; io_request->CDB.EEDP32.PrimaryReferenceTag = 0;
...@@ -1837,10 +1852,24 @@ megasas_build_io_fusion(struct megasas_instance *instance, ...@@ -1837,10 +1852,24 @@ megasas_build_io_fusion(struct megasas_instance *instance,
*/ */
io_request->IoFlags = cpu_to_le16(scp->cmd_len); 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); megasas_build_ldio_fusion(instance, scp, cmd);
else break;
megasas_build_dcdb_fusion(instance, scp, cmd); 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 * Construct SGL
...@@ -2016,8 +2045,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex) ...@@ -2016,8 +2045,7 @@ complete_cmd_fusion(struct megasas_instance *instance, u32 MSIxIndex)
switch (scsi_io_req->Function) { switch (scsi_io_req->Function) {
case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/ case MPI2_FUNCTION_SCSI_IO_REQUEST: /*Fast Path IO.*/
/* Update load balancing info */ /* Update load balancing info */
device_id = MEGASAS_DEV_INDEX(instance, device_id = MEGASAS_DEV_INDEX(cmd_fusion->scmd);
cmd_fusion->scmd);
lbinfo = &fusion->load_balance_info[device_id]; lbinfo = &fusion->load_balance_info[device_id];
if (cmd_fusion->scmd->SCp.Status & if (cmd_fusion->scmd->SCp.Status &
MEGASAS_LOAD_BALANCE_FLAG) { MEGASAS_LOAD_BALANCE_FLAG) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment