scsi: mpt3sas: For NVME device, issue a protocol level reset
1) Manufacturing Page 11 contains parameters to control internal firmware behavior. Based on AddlFlags2 field FW/Driver behaviour can be changed, (flag tm_custom_handling is used for this) a) For PCIe device, protocol level reset should be used if flag tm_custom_handling is 0. Since Abort Task Set, LUN reset and Target reset will result in a protocol level reset. Drivers should issue only one type of this reset, if that fails then it should escalate to a controller reset (diag reset/OCR). b) If the driver has control over the TM reset timeout value, then driver should use the value exposed in PCIe Device Page 2 for pcie device (field ControllerResetTO). Signed-off-by: Chaitra P B <chaitra.basappa@broadcom.com> Signed-off-by: Suganath Prabu S <suganath-prabu.subramani@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
65928d1f41
commit
c1a6c5ac42
@ -4142,6 +4142,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
|
|||||||
Mpi2ConfigReply_t mpi_reply;
|
Mpi2ConfigReply_t mpi_reply;
|
||||||
u32 iounit_pg1_flags;
|
u32 iounit_pg1_flags;
|
||||||
|
|
||||||
|
ioc->nvme_abort_timeout = 30;
|
||||||
mpt3sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
|
mpt3sas_config_get_manufacturing_pg0(ioc, &mpi_reply, &ioc->manu_pg0);
|
||||||
if (ioc->ir_firmware)
|
if (ioc->ir_firmware)
|
||||||
mpt3sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
|
mpt3sas_config_get_manufacturing_pg10(ioc, &mpi_reply,
|
||||||
@ -4160,6 +4161,18 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
|
|||||||
mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply,
|
mpt3sas_config_set_manufacturing_pg11(ioc, &mpi_reply,
|
||||||
&ioc->manu_pg11);
|
&ioc->manu_pg11);
|
||||||
}
|
}
|
||||||
|
if (ioc->manu_pg11.AddlFlags2 & NVME_TASK_MNGT_CUSTOM_MASK)
|
||||||
|
ioc->tm_custom_handling = 1;
|
||||||
|
else {
|
||||||
|
ioc->tm_custom_handling = 0;
|
||||||
|
if (ioc->manu_pg11.NVMeAbortTO < NVME_TASK_ABORT_MIN_TIMEOUT)
|
||||||
|
ioc->nvme_abort_timeout = NVME_TASK_ABORT_MIN_TIMEOUT;
|
||||||
|
else if (ioc->manu_pg11.NVMeAbortTO >
|
||||||
|
NVME_TASK_ABORT_MAX_TIMEOUT)
|
||||||
|
ioc->nvme_abort_timeout = NVME_TASK_ABORT_MAX_TIMEOUT;
|
||||||
|
else
|
||||||
|
ioc->nvme_abort_timeout = ioc->manu_pg11.NVMeAbortTO;
|
||||||
|
}
|
||||||
|
|
||||||
mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
|
mpt3sas_config_get_bios_pg2(ioc, &mpi_reply, &ioc->bios_pg2);
|
||||||
mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
|
mpt3sas_config_get_bios_pg3(ioc, &mpi_reply, &ioc->bios_pg3);
|
||||||
|
@ -146,8 +146,12 @@
|
|||||||
#define NVME_CMD_PRP1_OFFSET 24 /* PRP1 offset in NVMe cmd */
|
#define NVME_CMD_PRP1_OFFSET 24 /* PRP1 offset in NVMe cmd */
|
||||||
#define NVME_CMD_PRP2_OFFSET 32 /* PRP2 offset in NVMe cmd */
|
#define NVME_CMD_PRP2_OFFSET 32 /* PRP2 offset in NVMe cmd */
|
||||||
#define NVME_ERROR_RESPONSE_SIZE 16 /* Max NVME Error Response */
|
#define NVME_ERROR_RESPONSE_SIZE 16 /* Max NVME Error Response */
|
||||||
|
#define NVME_TASK_ABORT_MIN_TIMEOUT 6
|
||||||
|
#define NVME_TASK_ABORT_MAX_TIMEOUT 60
|
||||||
|
#define NVME_TASK_MNGT_CUSTOM_MASK (0x0010)
|
||||||
#define NVME_PRP_PAGE_SIZE 4096 /* Page size */
|
#define NVME_PRP_PAGE_SIZE 4096 /* Page size */
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reset phases
|
* reset phases
|
||||||
*/
|
*/
|
||||||
@ -363,7 +367,15 @@ struct Mpi2ManufacturingPage11_t {
|
|||||||
u8 EEDPTagMode; /* 09h */
|
u8 EEDPTagMode; /* 09h */
|
||||||
u8 Reserved3; /* 0Ah */
|
u8 Reserved3; /* 0Ah */
|
||||||
u8 Reserved4; /* 0Bh */
|
u8 Reserved4; /* 0Bh */
|
||||||
__le32 Reserved5[23]; /* 0Ch-60h*/
|
__le32 Reserved5[8]; /* 0Ch-2Ch */
|
||||||
|
u16 AddlFlags2; /* 2Ch */
|
||||||
|
u8 AddlFlags3; /* 2Eh */
|
||||||
|
u8 Reserved6; /* 2Fh */
|
||||||
|
__le32 Reserved7[7]; /* 30h - 4Bh */
|
||||||
|
u8 NVMeAbortTO; /* 4Ch */
|
||||||
|
u8 Reserved8; /* 4Dh */
|
||||||
|
u16 Reserved9; /* 4Eh */
|
||||||
|
__le32 Reserved10[4]; /* 50h - 60h */
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -573,6 +585,7 @@ struct _pcie_device {
|
|||||||
u8 enclosure_level;
|
u8 enclosure_level;
|
||||||
u8 connector_name[4];
|
u8 connector_name[4];
|
||||||
u8 *serial_number;
|
u8 *serial_number;
|
||||||
|
u8 reset_timeout;
|
||||||
struct kref refcount;
|
struct kref refcount;
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
@ -1211,6 +1224,10 @@ struct MPT3SAS_ADAPTER {
|
|||||||
void *event_log;
|
void *event_log;
|
||||||
u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
|
u32 event_masks[MPI2_EVENT_NOTIFY_EVENTMASK_WORDS];
|
||||||
|
|
||||||
|
u8 tm_custom_handling;
|
||||||
|
u8 nvme_abort_timeout;
|
||||||
|
|
||||||
|
|
||||||
/* static config pages */
|
/* static config pages */
|
||||||
struct mpt3sas_facts facts;
|
struct mpt3sas_facts facts;
|
||||||
struct mpt3sas_port_facts *pfacts;
|
struct mpt3sas_port_facts *pfacts;
|
||||||
@ -1473,10 +1490,11 @@ u8 mpt3sas_scsih_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
|
|||||||
u32 reply);
|
u32 reply);
|
||||||
void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
|
void mpt3sas_scsih_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase);
|
||||||
|
|
||||||
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
int mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun,
|
||||||
u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout);
|
u8 type, u16 smid_task, u16 msix_task, u8 timeout, u8 tr_method);
|
||||||
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout);
|
u64 lun, u8 type, u16 smid_task, u16 msix_task,
|
||||||
|
u8 timeout, u8 tr_method);
|
||||||
|
|
||||||
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
void mpt3sas_scsih_set_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
void mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle);
|
||||||
|
@ -644,9 +644,10 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
|||||||
MPI2RequestHeader_t *mpi_request = NULL, *request;
|
MPI2RequestHeader_t *mpi_request = NULL, *request;
|
||||||
MPI2DefaultReply_t *mpi_reply;
|
MPI2DefaultReply_t *mpi_reply;
|
||||||
Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL;
|
Mpi26NVMeEncapsulatedRequest_t *nvme_encap_request = NULL;
|
||||||
|
struct _pcie_device *pcie_device = NULL;
|
||||||
u32 ioc_state;
|
u32 ioc_state;
|
||||||
u16 smid;
|
u16 smid;
|
||||||
unsigned long timeout;
|
u8 timeout;
|
||||||
u8 issue_reset;
|
u8 issue_reset;
|
||||||
u32 sz, sz_arg;
|
u32 sz, sz_arg;
|
||||||
void *psge;
|
void *psge;
|
||||||
@ -659,6 +660,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
|||||||
long ret;
|
long ret;
|
||||||
u16 wait_state_count;
|
u16 wait_state_count;
|
||||||
u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE;
|
u16 device_handle = MPT3SAS_INVALID_DEVICE_HANDLE;
|
||||||
|
u8 tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
|
||||||
|
|
||||||
issue_reset = 0;
|
issue_reset = 0;
|
||||||
|
|
||||||
@ -1074,14 +1076,26 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
|
|||||||
ioc->name,
|
ioc->name,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1));
|
le16_to_cpu(mpi_request->FunctionDependent1));
|
||||||
mpt3sas_halt_firmware(ioc);
|
mpt3sas_halt_firmware(ioc);
|
||||||
mpt3sas_scsih_issue_locked_tm(ioc,
|
pcie_device = mpt3sas_get_pdev_by_handle(ioc,
|
||||||
le16_to_cpu(mpi_request->FunctionDependent1), 0,
|
le16_to_cpu(mpi_request->FunctionDependent1));
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, 30);
|
if (pcie_device && (!ioc->tm_custom_handling))
|
||||||
|
mpt3sas_scsih_issue_locked_tm(ioc,
|
||||||
|
le16_to_cpu(mpi_request->FunctionDependent1),
|
||||||
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
||||||
|
0, pcie_device->reset_timeout,
|
||||||
|
tr_method);
|
||||||
|
else
|
||||||
|
mpt3sas_scsih_issue_locked_tm(ioc,
|
||||||
|
le16_to_cpu(mpi_request->FunctionDependent1),
|
||||||
|
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
|
||||||
|
0, 30, MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET);
|
||||||
} else
|
} else
|
||||||
mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (pcie_device)
|
||||||
|
pcie_device_put(pcie_device);
|
||||||
|
|
||||||
/* free memory associated with sg buffers */
|
/* free memory associated with sg buffers */
|
||||||
if (data_in)
|
if (data_in)
|
||||||
|
@ -1088,7 +1088,7 @@ _scsih_pcie_device_remove(struct MPT3SAS_ADAPTER *ioc,
|
|||||||
pcie_device->slot);
|
pcie_device->slot);
|
||||||
if (pcie_device->connector_name[0] != '\0')
|
if (pcie_device->connector_name[0] != '\0')
|
||||||
pr_info(MPT3SAS_FMT
|
pr_info(MPT3SAS_FMT
|
||||||
"removing enclosure level(0x%04x), connector name( %s)\n",
|
"removing enclosure level(0x%04x), connector name( %s)\n",
|
||||||
ioc->name, pcie_device->enclosure_level,
|
ioc->name, pcie_device->enclosure_level,
|
||||||
pcie_device->connector_name);
|
pcie_device->connector_name);
|
||||||
|
|
||||||
@ -2632,6 +2632,7 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|||||||
* @smid_task: smid assigned to the task
|
* @smid_task: smid assigned to the task
|
||||||
* @msix_task: MSIX table index supplied by the OS
|
* @msix_task: MSIX table index supplied by the OS
|
||||||
* @timeout: timeout in seconds
|
* @timeout: timeout in seconds
|
||||||
|
* @tr_method: Target Reset Method
|
||||||
* Context: user
|
* Context: user
|
||||||
*
|
*
|
||||||
* A generic API for sending task management requests to firmware.
|
* A generic API for sending task management requests to firmware.
|
||||||
@ -2642,8 +2643,8 @@ mpt3sas_scsih_clear_tm_flag(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|||||||
* Return SUCCESS or FAILED.
|
* Return SUCCESS or FAILED.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle, u64 lun,
|
||||||
u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout)
|
u8 type, u16 smid_task, u16 msix_task, u8 timeout, u8 tr_method)
|
||||||
{
|
{
|
||||||
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
Mpi2SCSITaskManagementRequest_t *mpi_request;
|
||||||
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
Mpi2SCSITaskManagementReply_t *mpi_reply;
|
||||||
@ -2689,8 +2690,8 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
dtmprintk(ioc, pr_info(MPT3SAS_FMT
|
dtmprintk(ioc, pr_info(MPT3SAS_FMT
|
||||||
"sending tm: handle(0x%04x), task_type(0x%02x), smid(%d)\n",
|
"sending tm: handle(0x%04x), task_type(0x%02x), smid(%d), timeout(%d), tr_method(0x%x)\n",
|
||||||
ioc->name, handle, type, smid_task));
|
ioc->name, handle, type, smid_task, timeout, tr_method));
|
||||||
ioc->tm_cmds.status = MPT3_CMD_PENDING;
|
ioc->tm_cmds.status = MPT3_CMD_PENDING;
|
||||||
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
|
||||||
ioc->tm_cmds.smid = smid;
|
ioc->tm_cmds.smid = smid;
|
||||||
@ -2699,6 +2700,7 @@ mpt3sas_scsih_issue_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
|||||||
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
||||||
mpi_request->DevHandle = cpu_to_le16(handle);
|
mpi_request->DevHandle = cpu_to_le16(handle);
|
||||||
mpi_request->TaskType = type;
|
mpi_request->TaskType = type;
|
||||||
|
mpi_request->MsgFlags = tr_method;
|
||||||
mpi_request->TaskMID = cpu_to_le16(smid_task);
|
mpi_request->TaskMID = cpu_to_le16(smid_task);
|
||||||
int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
|
int_to_scsilun(lun, (struct scsi_lun *)mpi_request->LUN);
|
||||||
mpt3sas_scsih_set_tm_flag(ioc, handle);
|
mpt3sas_scsih_set_tm_flag(ioc, handle);
|
||||||
@ -2745,13 +2747,14 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
|
||||||
u64 lun, u8 type, u16 smid_task, u16 msix_task, ulong timeout)
|
u64 lun, u8 type, u16 smid_task, u16 msix_task,
|
||||||
|
u8 timeout, u8 tr_method)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&ioc->tm_cmds.mutex);
|
mutex_lock(&ioc->tm_cmds.mutex);
|
||||||
ret = mpt3sas_scsih_issue_tm(ioc, handle, lun, type, smid_task,
|
ret = mpt3sas_scsih_issue_tm(ioc, handle, lun, type, smid_task,
|
||||||
msix_task, timeout);
|
msix_task, timeout, tr_method);
|
||||||
mutex_unlock(&ioc->tm_cmds.mutex);
|
mutex_unlock(&ioc->tm_cmds.mutex);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -2854,6 +2857,8 @@ scsih_abort(struct scsi_cmnd *scmd)
|
|||||||
u16 handle;
|
u16 handle;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
u8 timeout = 30;
|
||||||
|
struct _pcie_device *pcie_device = NULL;
|
||||||
sdev_printk(KERN_INFO, scmd->device,
|
sdev_printk(KERN_INFO, scmd->device,
|
||||||
"attempting task abort! scmd(%p)\n", scmd);
|
"attempting task abort! scmd(%p)\n", scmd);
|
||||||
_scsih_tm_display_info(ioc, scmd);
|
_scsih_tm_display_info(ioc, scmd);
|
||||||
@ -2888,15 +2893,20 @@ scsih_abort(struct scsi_cmnd *scmd)
|
|||||||
mpt3sas_halt_firmware(ioc);
|
mpt3sas_halt_firmware(ioc);
|
||||||
|
|
||||||
handle = sas_device_priv_data->sas_target->handle;
|
handle = sas_device_priv_data->sas_target->handle;
|
||||||
|
pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle);
|
||||||
|
if (pcie_device && (!ioc->tm_custom_handling))
|
||||||
|
timeout = ioc->nvme_abort_timeout;
|
||||||
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
|
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
|
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
|
||||||
st->smid, st->msix_io, 30);
|
st->smid, st->msix_io, timeout, 0);
|
||||||
/* Command must be cleared after abort */
|
/* Command must be cleared after abort */
|
||||||
if (r == SUCCESS && st->cb_idx != 0xFF)
|
if (r == SUCCESS && st->cb_idx != 0xFF)
|
||||||
r = FAILED;
|
r = FAILED;
|
||||||
out:
|
out:
|
||||||
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
sdev_printk(KERN_INFO, scmd->device, "task abort: %s scmd(%p)\n",
|
||||||
((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
|
((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
|
||||||
|
if (pcie_device)
|
||||||
|
pcie_device_put(pcie_device);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2912,7 +2922,10 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
|
|||||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
||||||
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
||||||
struct _sas_device *sas_device = NULL;
|
struct _sas_device *sas_device = NULL;
|
||||||
|
struct _pcie_device *pcie_device = NULL;
|
||||||
u16 handle;
|
u16 handle;
|
||||||
|
u8 tr_method = 0;
|
||||||
|
u8 tr_timeout = 30;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
struct scsi_target *starget = scmd->device->sdev_target;
|
struct scsi_target *starget = scmd->device->sdev_target;
|
||||||
@ -2950,8 +2963,16 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle);
|
||||||
|
|
||||||
|
if (pcie_device && (!ioc->tm_custom_handling)) {
|
||||||
|
tr_timeout = pcie_device->reset_timeout;
|
||||||
|
tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
|
||||||
|
} else
|
||||||
|
tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
|
||||||
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
|
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0, 30);
|
MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0,
|
||||||
|
tr_timeout, tr_method);
|
||||||
/* Check for busy commands after reset */
|
/* Check for busy commands after reset */
|
||||||
if (r == SUCCESS && atomic_read(&scmd->device->device_busy))
|
if (r == SUCCESS && atomic_read(&scmd->device->device_busy))
|
||||||
r = FAILED;
|
r = FAILED;
|
||||||
@ -2961,6 +2982,8 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
|
|||||||
|
|
||||||
if (sas_device)
|
if (sas_device)
|
||||||
sas_device_put(sas_device);
|
sas_device_put(sas_device);
|
||||||
|
if (pcie_device)
|
||||||
|
pcie_device_put(pcie_device);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -2977,7 +3000,10 @@ scsih_target_reset(struct scsi_cmnd *scmd)
|
|||||||
struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
|
||||||
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
struct MPT3SAS_DEVICE *sas_device_priv_data;
|
||||||
struct _sas_device *sas_device = NULL;
|
struct _sas_device *sas_device = NULL;
|
||||||
|
struct _pcie_device *pcie_device = NULL;
|
||||||
u16 handle;
|
u16 handle;
|
||||||
|
u8 tr_method = 0;
|
||||||
|
u8 tr_timeout = 30;
|
||||||
int r;
|
int r;
|
||||||
struct scsi_target *starget = scmd->device->sdev_target;
|
struct scsi_target *starget = scmd->device->sdev_target;
|
||||||
struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
|
struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
|
||||||
@ -3014,8 +3040,16 @@ scsih_target_reset(struct scsi_cmnd *scmd)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle);
|
||||||
|
|
||||||
|
if (pcie_device && (!ioc->tm_custom_handling)) {
|
||||||
|
tr_timeout = pcie_device->reset_timeout;
|
||||||
|
tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
|
||||||
|
} else
|
||||||
|
tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
|
||||||
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, 0,
|
r = mpt3sas_scsih_issue_locked_tm(ioc, handle, 0,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, 30);
|
MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0,
|
||||||
|
tr_timeout, tr_method);
|
||||||
/* Check for busy commands after reset */
|
/* Check for busy commands after reset */
|
||||||
if (r == SUCCESS && atomic_read(&starget->target_busy))
|
if (r == SUCCESS && atomic_read(&starget->target_busy))
|
||||||
r = FAILED;
|
r = FAILED;
|
||||||
@ -3025,7 +3059,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
|
|||||||
|
|
||||||
if (sas_device)
|
if (sas_device)
|
||||||
sas_device_put(sas_device);
|
sas_device_put(sas_device);
|
||||||
|
if (pcie_device)
|
||||||
|
pcie_device_put(pcie_device);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3559,6 +3594,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct _tr_list *delayed_tr;
|
struct _tr_list *delayed_tr;
|
||||||
u32 ioc_state;
|
u32 ioc_state;
|
||||||
|
u8 tr_method = 0;
|
||||||
|
|
||||||
if (ioc->pci_error_recovery) {
|
if (ioc->pci_error_recovery) {
|
||||||
dewtprintk(ioc, pr_info(MPT3SAS_FMT
|
dewtprintk(ioc, pr_info(MPT3SAS_FMT
|
||||||
@ -3601,6 +3637,11 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|||||||
sas_address = pcie_device->wwid;
|
sas_address = pcie_device->wwid;
|
||||||
}
|
}
|
||||||
spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
|
spin_unlock_irqrestore(&ioc->pcie_device_lock, flags);
|
||||||
|
if (pcie_device && (!ioc->tm_custom_handling))
|
||||||
|
tr_method =
|
||||||
|
MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
|
||||||
|
else
|
||||||
|
tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET;
|
||||||
}
|
}
|
||||||
if (sas_target_priv_data) {
|
if (sas_target_priv_data) {
|
||||||
dewtprintk(ioc, pr_info(MPT3SAS_FMT
|
dewtprintk(ioc, pr_info(MPT3SAS_FMT
|
||||||
@ -3664,6 +3705,7 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|||||||
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
mpi_request->Function = MPI2_FUNCTION_SCSI_TASK_MGMT;
|
||||||
mpi_request->DevHandle = cpu_to_le16(handle);
|
mpi_request->DevHandle = cpu_to_le16(handle);
|
||||||
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
|
mpi_request->TaskType = MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET;
|
||||||
|
mpi_request->MsgFlags = tr_method;
|
||||||
set_bit(handle, ioc->device_remove_in_progress);
|
set_bit(handle, ioc->device_remove_in_progress);
|
||||||
mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
|
mpt3sas_base_put_smid_hi_priority(ioc, smid, 0);
|
||||||
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
|
mpt3sas_trigger_master(ioc, MASTER_TRIGGER_DEVICE_REMOVAL);
|
||||||
@ -6938,6 +6980,11 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
|
|||||||
}
|
}
|
||||||
pcie_device->nvme_mdts =
|
pcie_device->nvme_mdts =
|
||||||
le32_to_cpu(pcie_device_pg2.MaximumDataTransferSize);
|
le32_to_cpu(pcie_device_pg2.MaximumDataTransferSize);
|
||||||
|
if (pcie_device_pg2.ControllerResetTO)
|
||||||
|
pcie_device->reset_timeout =
|
||||||
|
pcie_device_pg2.ControllerResetTO;
|
||||||
|
else
|
||||||
|
pcie_device->reset_timeout = 30;
|
||||||
|
|
||||||
if (ioc->wait_for_discovery_to_complete)
|
if (ioc->wait_for_discovery_to_complete)
|
||||||
_scsih_pcie_device_init_add(ioc, pcie_device);
|
_scsih_pcie_device_init_add(ioc, pcie_device);
|
||||||
@ -7190,6 +7237,9 @@ _scsih_pcie_device_status_change_event_debug(struct MPT3SAS_ADAPTER *ioc,
|
|||||||
case MPI26_EVENT_PCIDEV_STAT_RC_ASYNC_NOTIFICATION:
|
case MPI26_EVENT_PCIDEV_STAT_RC_ASYNC_NOTIFICATION:
|
||||||
reason_str = "internal async notification";
|
reason_str = "internal async notification";
|
||||||
break;
|
break;
|
||||||
|
case MPI26_EVENT_PCIDEV_STAT_RC_PCIE_HOT_RESET_FAILED:
|
||||||
|
reason_str = "pcie hot reset failed";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
reason_str = "unknown reason";
|
reason_str = "unknown reason";
|
||||||
break;
|
break;
|
||||||
@ -7444,7 +7494,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
|
|||||||
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, lun,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, st->smid,
|
MPI2_SCSITASKMGMT_TASKTYPE_QUERY_TASK, st->smid,
|
||||||
st->msix_io, 30);
|
st->msix_io, 30, 0);
|
||||||
if (r == FAILED) {
|
if (r == FAILED) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
"mpt3sas_scsih_issue_tm: FAILED when sending "
|
"mpt3sas_scsih_issue_tm: FAILED when sending "
|
||||||
@ -7485,7 +7535,7 @@ _scsih_sas_broadcast_primitive_event(struct MPT3SAS_ADAPTER *ioc,
|
|||||||
|
|
||||||
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->lun,
|
r = mpt3sas_scsih_issue_tm(ioc, handle, sdev->lun,
|
||||||
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, st->smid,
|
MPI2_SCSITASKMGMT_TASKTYPE_ABORT_TASK, st->smid,
|
||||||
st->msix_io, 30);
|
st->msix_io, 30, 0);
|
||||||
if (r == FAILED || st->cb_idx != 0xFF) {
|
if (r == FAILED || st->cb_idx != 0xFF) {
|
||||||
sdev_printk(KERN_WARNING, sdev,
|
sdev_printk(KERN_WARNING, sdev,
|
||||||
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
"mpt3sas_scsih_issue_tm: ABORT_TASK: FAILED : "
|
||||||
|
Loading…
Reference in New Issue
Block a user