forked from luck/tmp_suning_uos_patched
megaraid_sas : Add separate functions for building sysPD IOs and non RW LDIOs
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>
This commit is contained in:
parent
9b82818286
commit
4a5c814d93
|
@ -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 {
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
NonFastPath:
|
||||
device_id = MEGASAS_DEV_INDEX(scmd);
|
||||
pd_index = MEGASAS_PD_INDEX(scmd);
|
||||
os_timeout_value = scmd->request->timeout / HZ;
|
||||
|
||||
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) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user