[PATCH 06/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-10-31 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

* NVMe device detection, addition and removal are reported by the
firmware through PCIe Topology Change list events.

* The PCIe device state change events are sent when the firmware
detects any abnormal conditions with a NVMe device or switch.

* The enumeration event are sent when the firmware starts PCIe device
enumeration and stops.

* This patch has the code change to handle the events and add/remove
NVMe devices in driver's inventory.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 471 ++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b0a75c6..0da639d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -663,6 +663,26 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Cable Event";
break;
+   case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+   desc = "PCIE Device Status Change";
+   break;
+   case MPI2_EVENT_PCIE_ENUMERATION:
+   {
+   Mpi26EventDataPCIeEnumeration_t *event_data =
+   (Mpi26EventDataPCIeEnumeration_t *)mpi_reply->EventData;
+   pr_info(MPT3SAS_FMT "PCIE Enumeration: (%s)", ioc->name,
+  (event_data->ReasonCode ==
+   MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+   "start" : "stop");
+   if (event_data->EnumerationStatus)
+   pr_info("enumeration_status(0x%08x)",
+  le32_to_cpu(event_data->EnumerationStatus));
+   pr_info("\n");
+   return;
+   }
+   case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+   desc = "PCIE Topology Change List";
+   break;
}
 
if (!desc)
@@ -6125,7 +6145,15 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
-
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
+   if (ioc->is_gen35_ioc) {
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+   _base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+   }
+   }
r = _base_make_ioc_operational(ioc);
if (r)
goto out_free_resources;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d83560c..21260bd 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3476,8 +3478,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
struct _sas_device *sas_device;
 
sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-   if (!sas_device)
-   return;
 
shost_for_each_device(sdev, ioc->shost) {
sas_device_priv_data = sdev->hostdata;
@@ -3487,7 +3487,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
continue;
if (sas_device_priv_data->block)
continue;
-   if (sas_device->pend_sas_rphy_add)
+   if (sas_device && sas_device->pend_sas_rphy_add)
continue;
if (sas_device_priv_data->ignore_delay_remove) {
sdev_printk(KERN_INFO, sdev,
@@ -3498,7 +3498,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if (sas_device)
+   sas_device_put(sas_device);
 }
 
 /**
@@ -3582,6 +3583,33 @@ _scsih_block_io_to_children_attached_directly(struct 
MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * 

[PATCH 06/13] mpt3sas: Handle NVMe PCIe device related events generated from firmware.

2017-10-31 Thread Suganath Prabu S
* The controller firmware sends separate events for NVMe devices and
PCIe switches similar to existing SAS events.

* NVMe device detection, addition and removal are reported by the
firmware through PCIe Topology Change list events.

* The PCIe device state change events are sent when the firmware
detects any abnormal conditions with a NVMe device or switch.

* The enumeration event are sent when the firmware starts PCIe device
enumeration and stops.

* This patch has the code change to handle the events and add/remove
NVMe devices in driver's inventory.

Signed-off-by: Chaitra P B 
Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  |  30 ++-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 471 ++-
 2 files changed, 495 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index b0a75c6..0da639d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -663,6 +663,26 @@ _base_display_event_data(struct MPT3SAS_ADAPTER *ioc,
case MPI2_EVENT_ACTIVE_CABLE_EXCEPTION:
desc = "Cable Event";
break;
+   case MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE:
+   desc = "PCIE Device Status Change";
+   break;
+   case MPI2_EVENT_PCIE_ENUMERATION:
+   {
+   Mpi26EventDataPCIeEnumeration_t *event_data =
+   (Mpi26EventDataPCIeEnumeration_t *)mpi_reply->EventData;
+   pr_info(MPT3SAS_FMT "PCIE Enumeration: (%s)", ioc->name,
+  (event_data->ReasonCode ==
+   MPI26_EVENT_PCIE_ENUM_RC_STARTED) ?
+   "start" : "stop");
+   if (event_data->EnumerationStatus)
+   pr_info("enumeration_status(0x%08x)",
+  le32_to_cpu(event_data->EnumerationStatus));
+   pr_info("\n");
+   return;
+   }
+   case MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST:
+   desc = "PCIE Topology Change List";
+   break;
}
 
if (!desc)
@@ -6125,7 +6145,15 @@ mpt3sas_base_attach(struct MPT3SAS_ADAPTER *ioc)
_base_unmask_events(ioc, MPI2_EVENT_LOG_ENTRY_ADDED);
_base_unmask_events(ioc, MPI2_EVENT_TEMP_THRESHOLD);
_base_unmask_events(ioc, MPI2_EVENT_ACTIVE_CABLE_EXCEPTION);
-
+   if (ioc->hba_mpi_version_belonged == MPI26_VERSION) {
+   if (ioc->is_gen35_ioc) {
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_DEVICE_STATUS_CHANGE);
+   _base_unmask_events(ioc, MPI2_EVENT_PCIE_ENUMERATION);
+   _base_unmask_events(ioc,
+   MPI2_EVENT_PCIE_TOPOLOGY_CHANGE_LIST);
+   }
+   }
r = _base_make_ioc_operational(ioc);
if (r)
goto out_free_resources;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index d83560c..21260bd 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -75,6 +75,8 @@ static int _scsih_add_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle,
 static int _scsih_pcie_add_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static void _scsih_pcie_device_remove_from_sml(struct MPT3SAS_ADAPTER *ioc,
struct _pcie_device *pcie_device);
+static void
+_scsih_pcie_check_device(struct MPT3SAS_ADAPTER *ioc, u16 handle);
 static u8 _scsih_check_for_pending_tm(struct MPT3SAS_ADAPTER *ioc, u16 smid);
 
 /* global parameters */
@@ -3476,8 +3478,6 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
struct _sas_device *sas_device;
 
sas_device = mpt3sas_get_sdev_by_handle(ioc, handle);
-   if (!sas_device)
-   return;
 
shost_for_each_device(sdev, ioc->shost) {
sas_device_priv_data = sdev->hostdata;
@@ -3487,7 +3487,7 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
continue;
if (sas_device_priv_data->block)
continue;
-   if (sas_device->pend_sas_rphy_add)
+   if (sas_device && sas_device->pend_sas_rphy_add)
continue;
if (sas_device_priv_data->ignore_delay_remove) {
sdev_printk(KERN_INFO, sdev,
@@ -3498,7 +3498,8 @@ _scsih_block_io_device(struct MPT3SAS_ADAPTER *ioc, u16 
handle)
_scsih_internal_device_block(sdev, sas_device_priv_data);
}
 
-   sas_device_put(sas_device);
+   if (sas_device)
+   sas_device_put(sas_device);
 }
 
 /**
@@ -3582,6 +3583,33 @@ _scsih_block_io_to_children_attached_directly(struct 
MPT3SAS_ADAPTER *ioc,
 }
 
 /**
+ * _scsih_block_io_to_pcie_children_attached_directly
+ * @ioc: per adapter object
+ * @event_data: topology