scsi: mpi3mr: Add support for PCIe Managed Switch SES device
authorSreekanth Reddy <sreekanth.reddy@broadcom.com>
Mon, 20 Dec 2021 14:11:40 +0000 (19:41 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 23 Dec 2021 05:04:22 +0000 (00:04 -0500)
The SAS4 Controller firmware exposes the SES devices in Managed PCIe Switch
as a PCIe Device Type SCSI Device
(MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE).

Driver is enhanced to handle this device type by:

 - Exposing the device to the upper layers and

 - Not updating any hardware sectors & virtual boundary settings as these
   settings are needed only for NVMe devices.

Link: https://lore.kernel.org/r/20211220141159.16117-7-sreekanth.reddy@broadcom.com
Signed-off-by: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/mpi3mr/mpi3mr.h
drivers/scsi/mpi3mr/mpi3mr_os.c

index cdbd1cb..fe3cfd5 100644 (file)
@@ -147,6 +147,7 @@ extern int prot_mask;
                        MPI3_SCSITASKMGMT_RSPCODE_IO_QUEUED_ON_IOC
 
 #define MPI3MR_DEFAULT_MDTS    (128 * 1024)
+#define MPI3MR_DEFAULT_PGSZEXP         (12)
 /* Command retry count definitions */
 #define MPI3MR_DEV_RMHS_RETRY_COUNT 3
 
@@ -389,6 +390,7 @@ struct tgt_dev_sas_sata {
  * @pgsz: Device page size
  * @abort_to: Timeout for abort TM
  * @reset_to: Timeout for Target/LUN reset TM
+ * @dev_info: Device information bits
  */
 struct tgt_dev_pcie {
        u32 mdts;
@@ -396,6 +398,7 @@ struct tgt_dev_pcie {
        u8 pgsz;
        u8 abort_to;
        u8 reset_to;
+       u16 dev_info;
 };
 
 /**
index e887d31..14621dc 100644 (file)
@@ -742,11 +742,18 @@ mpi3mr_update_sdev(struct scsi_device *sdev, void *data)
        switch (tgtdev->dev_type) {
        case MPI3_DEVICE_DEVFORM_PCIE:
                /*The block layer hw sector size = 512*/
-               blk_queue_max_hw_sectors(sdev->request_queue,
-                   tgtdev->dev_spec.pcie_inf.mdts / 512);
-               blk_queue_virt_boundary(sdev->request_queue,
-                   ((1 << tgtdev->dev_spec.pcie_inf.pgsz) - 1));
-
+               if ((tgtdev->dev_spec.pcie_inf.dev_info &
+                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) ==
+                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) {
+                       blk_queue_max_hw_sectors(sdev->request_queue,
+                           tgtdev->dev_spec.pcie_inf.mdts / 512);
+                       if (tgtdev->dev_spec.pcie_inf.pgsz == 0)
+                               blk_queue_virt_boundary(sdev->request_queue,
+                                   ((1 << MPI3MR_DEFAULT_PGSZEXP) - 1));
+                       else
+                               blk_queue_virt_boundary(sdev->request_queue,
+                                   ((1 << tgtdev->dev_spec.pcie_inf.pgsz) - 1));
+               }
                break;
        default:
                break;
@@ -848,6 +855,7 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
                    &dev_pg0->device_specific.pcie_format;
                u16 dev_info = le16_to_cpu(pcieinf->device_info);
 
+               tgtdev->dev_spec.pcie_inf.dev_info = dev_info;
                tgtdev->dev_spec.pcie_inf.capb =
                    le32_to_cpu(pcieinf->capabilities);
                tgtdev->dev_spec.pcie_inf.mdts = MPI3MR_DEFAULT_MDTS;
@@ -864,8 +872,10 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc,
                }
                if (tgtdev->dev_spec.pcie_inf.mdts > (1024 * 1024))
                        tgtdev->dev_spec.pcie_inf.mdts = (1024 * 1024);
-               if ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
-                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE)
+               if (((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
+                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) &&
+                   ((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) !=
+                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_SCSI_DEVICE))
                        tgtdev->is_hidden = 1;
                if (!mrioc->shost)
                        break;
@@ -3190,10 +3200,18 @@ static int mpi3mr_slave_configure(struct scsi_device *sdev)
        switch (tgt_dev->dev_type) {
        case MPI3_DEVICE_DEVFORM_PCIE:
                /*The block layer hw sector size = 512*/
-               blk_queue_max_hw_sectors(sdev->request_queue,
-                   tgt_dev->dev_spec.pcie_inf.mdts / 512);
-               blk_queue_virt_boundary(sdev->request_queue,
-                   ((1 << tgt_dev->dev_spec.pcie_inf.pgsz) - 1));
+               if ((tgt_dev->dev_spec.pcie_inf.dev_info &
+                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) ==
+                   MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_NVME_DEVICE) {
+                       blk_queue_max_hw_sectors(sdev->request_queue,
+                           tgt_dev->dev_spec.pcie_inf.mdts / 512);
+                       if (tgt_dev->dev_spec.pcie_inf.pgsz == 0)
+                               blk_queue_virt_boundary(sdev->request_queue,
+                                   ((1 << MPI3MR_DEFAULT_PGSZEXP) - 1));
+                       else
+                               blk_queue_virt_boundary(sdev->request_queue,
+                                   ((1 << tgt_dev->dev_spec.pcie_inf.pgsz) - 1));
+               }
                break;
        default:
                break;