Commit 5bb309db authored by Suganath Prabu's avatar Suganath Prabu Committed by Martin K. Petersen

scsi: mpt3sas: Enumerate SES of a managed PCIe switch

SES device of managed PCIe switch will be enumerated same as NVMe drives.

The device info type for this SES device is

        MPI26_PCIE_DEVINFO_SCSI (0x4),

whereas the device info type for NVMe drives is

        MPI26_PCIE_DEVINFO_NVME (0x3).

Based on this device info type driver determines whether the device is NVMe
drive or a SES device of a managed PCIe switch.

This SES device doesn't have the PCIe device page 2 information like NVMe
drives, so driver won't read PCIe device page 2 information for SES device.

This SES device uses only IEEE SGL's, So driver build's IEEE SGL's whenever
it receives any SCSI commands for this SES device.
Signed-off-by: default avatarSuganath Prabu <suganath-prabu.subramani@broadcom.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 635ee6c7
...@@ -2260,6 +2260,11 @@ base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc, ...@@ -2260,6 +2260,11 @@ base_is_prp_possible(struct MPT3SAS_ADAPTER *ioc,
bool build_prp = true; bool build_prp = true;
data_length = scsi_bufflen(scmd); data_length = scsi_bufflen(scmd);
if (pcie_device &&
(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info))) {
build_prp = false;
return build_prp;
}
/* If Datalenth is <= 16K and number of SGE’s entries are <= 2 /* If Datalenth is <= 16K and number of SGE’s entries are <= 2
* we built IEEE SGL * we built IEEE SGL
......
...@@ -1735,4 +1735,20 @@ mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, ...@@ -1735,4 +1735,20 @@ mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
/* NCQ Prio Handling Check */ /* NCQ Prio Handling Check */
bool scsih_ncq_prio_supp(struct scsi_device *sdev); bool scsih_ncq_prio_supp(struct scsi_device *sdev);
/**
* _scsih_is_pcie_scsi_device - determines if device is an pcie scsi device
* @device_info: bitfield providing information about the device.
* Context: none
*
* Returns 1 if scsi device.
*/
static inline int
mpt3sas_scsih_is_pcie_scsi_device(u32 device_info)
{
if ((device_info &
MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE) == MPI26_PCIE_DEVINFO_SCSI)
return 1;
else
return 0;
}
#endif /* MPT3SAS_BASE_H_INCLUDED */ #endif /* MPT3SAS_BASE_H_INCLUDED */
...@@ -662,7 +662,6 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ...@@ -662,7 +662,6 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
size_t data_in_sz = 0; size_t data_in_sz = 0;
long ret; long ret;
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;
...@@ -1057,12 +1056,14 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, ...@@ -1057,12 +1056,14 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg,
mpt3sas_halt_firmware(ioc); mpt3sas_halt_firmware(ioc);
pcie_device = mpt3sas_get_pdev_by_handle(ioc, pcie_device = mpt3sas_get_pdev_by_handle(ioc,
le16_to_cpu(mpi_request->FunctionDependent1)); le16_to_cpu(mpi_request->FunctionDependent1));
if (pcie_device && (!ioc->tm_custom_handling)) if (pcie_device && (!ioc->tm_custom_handling) &&
(!(mpt3sas_scsih_is_pcie_scsi_device(
pcie_device->device_info))))
mpt3sas_scsih_issue_locked_tm(ioc, mpt3sas_scsih_issue_locked_tm(ioc,
le16_to_cpu(mpi_request->FunctionDependent1), le16_to_cpu(mpi_request->FunctionDependent1),
0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
0, pcie_device->reset_timeout, 0, pcie_device->reset_timeout,
tr_method); MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE);
else else
mpt3sas_scsih_issue_locked_tm(ioc, mpt3sas_scsih_issue_locked_tm(ioc,
le16_to_cpu(mpi_request->FunctionDependent1), le16_to_cpu(mpi_request->FunctionDependent1),
......
...@@ -1433,17 +1433,20 @@ _scsih_is_end_device(u32 device_info) ...@@ -1433,17 +1433,20 @@ _scsih_is_end_device(u32 device_info)
} }
/** /**
* _scsih_is_nvme_device - determines if device is an nvme device * _scsih_is_nvme_pciescsi_device - determines if
* device is an pcie nvme/scsi device
* @device_info: bitfield providing information about the device. * @device_info: bitfield providing information about the device.
* Context: none * Context: none
* *
* Return: 1 if nvme device. * Returns 1 if device is pcie device type nvme/scsi.
*/ */
static int static int
_scsih_is_nvme_device(u32 device_info) _scsih_is_nvme_pciescsi_device(u32 device_info)
{ {
if ((device_info & MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE) if (((device_info & MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE)
== MPI26_PCIE_DEVINFO_NVME) == MPI26_PCIE_DEVINFO_NVME) ||
((device_info & MPI26_PCIE_DEVINFO_MASK_DEVICE_TYPE)
== MPI26_PCIE_DEVINFO_SCSI))
return 1; return 1;
else else
return 0; return 0;
...@@ -2872,7 +2875,8 @@ scsih_abort(struct scsi_cmnd *scmd) ...@@ -2872,7 +2875,8 @@ scsih_abort(struct scsi_cmnd *scmd)
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); pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle);
if (pcie_device && (!ioc->tm_custom_handling)) if (pcie_device && (!ioc->tm_custom_handling) &&
(!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info))))
timeout = ioc->nvme_abort_timeout; 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,
...@@ -2943,11 +2947,13 @@ scsih_dev_reset(struct scsi_cmnd *scmd) ...@@ -2943,11 +2947,13 @@ scsih_dev_reset(struct scsi_cmnd *scmd)
pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle); pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle);
if (pcie_device && (!ioc->tm_custom_handling)) { if (pcie_device && (!ioc->tm_custom_handling) &&
(!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info)))) {
tr_timeout = pcie_device->reset_timeout; tr_timeout = pcie_device->reset_timeout;
tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE; tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
} else } else
tr_method = MPI2_SCSITASKMGMT_MSGFLAGS_LINK_RESET; 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, MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 0,
tr_timeout, tr_method); tr_timeout, tr_method);
...@@ -3020,7 +3026,8 @@ scsih_target_reset(struct scsi_cmnd *scmd) ...@@ -3020,7 +3026,8 @@ scsih_target_reset(struct scsi_cmnd *scmd)
pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle); pcie_device = mpt3sas_get_pdev_by_handle(ioc, handle);
if (pcie_device && (!ioc->tm_custom_handling)) { if (pcie_device && (!ioc->tm_custom_handling) &&
(!(mpt3sas_scsih_is_pcie_scsi_device(pcie_device->device_info)))) {
tr_timeout = pcie_device->reset_timeout; tr_timeout = pcie_device->reset_timeout;
tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE; tr_method = MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
} else } else
...@@ -3598,7 +3605,9 @@ _scsih_tm_tr_send(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -3598,7 +3605,9 @@ _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)) if (pcie_device && (!ioc->tm_custom_handling) &&
(!(mpt3sas_scsih_is_pcie_scsi_device(
pcie_device->device_info))))
tr_method = tr_method =
MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE; MPI26_SCSITASKMGMT_MSGFLAGS_PROTOCOL_LVL_RST_PCIE;
else else
...@@ -6694,7 +6703,7 @@ _scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -6694,7 +6703,7 @@ _scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
/* check if this is end device */ /* check if this is end device */
device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo); device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
if (!(_scsih_is_nvme_device(device_info))) if (!(_scsih_is_nvme_pciescsi_device(device_info)))
return; return;
wwid = le64_to_cpu(pcie_device_pg0.WWID); wwid = le64_to_cpu(pcie_device_pg0.WWID);
...@@ -6803,7 +6812,8 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -6803,7 +6812,8 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
pcie_device_pg0.AccessStatus)) pcie_device_pg0.AccessStatus))
return 0; return 0;
if (!(_scsih_is_nvme_device(le32_to_cpu(pcie_device_pg0.DeviceInfo)))) if (!(_scsih_is_nvme_pciescsi_device(le32_to_cpu
(pcie_device_pg0.DeviceInfo))))
return 0; return 0;
pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid); pcie_device = mpt3sas_get_pdev_by_wwid(ioc, wwid);
...@@ -6813,6 +6823,31 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -6813,6 +6823,31 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
return 0; return 0;
} }
/* PCIe Device Page 2 contains read-only information about a
* specific NVMe device; therefore, this page is only
* valid for NVMe devices and skip for pcie devices of type scsi.
*/
if (!(mpt3sas_scsih_is_pcie_scsi_device(
le32_to_cpu(pcie_device_pg0.DeviceInfo)))) {
if (mpt3sas_config_get_pcie_device_pg2(ioc, &mpi_reply,
&pcie_device_pg2, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE,
handle)) {
ioc_err(ioc,
"failure at %s:%d/%s()!\n", __FILE__,
__LINE__, __func__);
return 0;
}
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
MPI2_IOCSTATUS_MASK;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
ioc_err(ioc,
"failure at %s:%d/%s()!\n", __FILE__,
__LINE__, __func__);
return 0;
}
}
pcie_device = kzalloc(sizeof(struct _pcie_device), GFP_KERNEL); pcie_device = kzalloc(sizeof(struct _pcie_device), GFP_KERNEL);
if (!pcie_device) { if (!pcie_device) {
ioc_err(ioc, "failure at %s:%d/%s()!\n", ioc_err(ioc, "failure at %s:%d/%s()!\n",
...@@ -6855,27 +6890,16 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle) ...@@ -6855,27 +6890,16 @@ _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle)
le64_to_cpu(enclosure_dev->pg0.EnclosureLogicalID); le64_to_cpu(enclosure_dev->pg0.EnclosureLogicalID);
} }
/* TODO -- Add device name once FW supports it */ /* TODO -- Add device name once FW supports it */
if (mpt3sas_config_get_pcie_device_pg2(ioc, &mpi_reply, if (!(mpt3sas_scsih_is_pcie_scsi_device(
&pcie_device_pg2, MPI2_SAS_DEVICE_PGAD_FORM_HANDLE, handle)) { le32_to_cpu(pcie_device_pg0.DeviceInfo)))) {
ioc_err(ioc, "failure at %s:%d/%s()!\n", pcie_device->nvme_mdts =
__FILE__, __LINE__, __func__); le32_to_cpu(pcie_device_pg2.MaximumDataTransferSize);
kfree(pcie_device); if (pcie_device_pg2.ControllerResetTO)
return 0; pcie_device->reset_timeout =
} pcie_device_pg2.ControllerResetTO;
else
ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; pcie_device->reset_timeout = 30;
if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { } else
ioc_err(ioc, "failure at %s:%d/%s()!\n",
__FILE__, __LINE__, __func__);
kfree(pcie_device);
return 0;
}
pcie_device->nvme_mdts =
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; pcie_device->reset_timeout = 30;
if (ioc->wait_for_discovery_to_complete) if (ioc->wait_for_discovery_to_complete)
...@@ -8594,7 +8618,7 @@ _scsih_search_responding_pcie_devices(struct MPT3SAS_ADAPTER *ioc) ...@@ -8594,7 +8618,7 @@ _scsih_search_responding_pcie_devices(struct MPT3SAS_ADAPTER *ioc)
} }
handle = le16_to_cpu(pcie_device_pg0.DevHandle); handle = le16_to_cpu(pcie_device_pg0.DevHandle);
device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo); device_info = le32_to_cpu(pcie_device_pg0.DeviceInfo);
if (!(_scsih_is_nvme_device(device_info))) if (!(_scsih_is_nvme_pciescsi_device(device_info)))
continue; continue;
_scsih_mark_responding_pcie_device(ioc, &pcie_device_pg0); _scsih_mark_responding_pcie_device(ioc, &pcie_device_pg0);
} }
...@@ -9175,7 +9199,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc) ...@@ -9175,7 +9199,7 @@ _scsih_scan_for_devices_after_reset(struct MPT3SAS_ADAPTER *ioc)
break; break;
} }
handle = le16_to_cpu(pcie_device_pg0.DevHandle); handle = le16_to_cpu(pcie_device_pg0.DevHandle);
if (!(_scsih_is_nvme_device( if (!(_scsih_is_nvme_pciescsi_device(
le32_to_cpu(pcie_device_pg0.DeviceInfo)))) le32_to_cpu(pcie_device_pg0.DeviceInfo))))
continue; continue;
pcie_device = mpt3sas_get_pdev_by_wwid(ioc, pcie_device = mpt3sas_get_pdev_by_wwid(ioc,
......
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