[Patch v1 5/7] mpt3sas: Fix Sync cache command failure during driver unload.

2018-08-30 Thread Suganath Prabu S
This is to fix Sync cache and start stop command
 failures with DID_NO_CONNECT during driver unload.

1) Release drives first from SML, then remove internally
in driver.
2) And allow sync cache and Start stop commands to firmware,
even when remove_host flag is set

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 41 ++--
 drivers/scsi/mpt3sas/mpt3sas_transport.c |  7 --
 2 files changed, 44 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 2c7f44c..f796808 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -3806,6 +3806,43 @@ _scsih_tm_tr_complete(struct MPT3SAS_ADAPTER *ioc, u16 
smid, u8 msix_index,
return _scsih_check_for_pending_tm(ioc, smid);
 }
 
+/** _scsih_allow_scmd_to_device - check whether scmd needs to
+ *  issue to IOC or not.
+ * @ioc: per adapter object
+ * @scmd: pointer to scsi command object
+ *
+ * Returns true if scmd can be issued to IOC otherwise returns false.
+ */
+inline bool _scsih_allow_scmd_to_device(struct MPT3SAS_ADAPTER *ioc,
+   struct scsi_cmnd *scmd)
+{
+
+   if (ioc->pci_error_recovery)
+   return false;
+
+   if (ioc->hba_mpi_version_belonged == MPI2_VERSION) {
+   if (ioc->remove_host)
+   return false;
+
+   return true;
+   }
+
+
+   if (ioc->remove_host) {
+   if (mpt3sas_base_pci_device_is_unplugged(ioc))
+   return false;
+
+   switch (scmd->cmnd[0]) {
+   case SYNCHRONIZE_CACHE:
+   case START_STOP:
+   return true;
+   default:
+   return false;
+   }
+   }
+
+   return true;
+}
 
 /**
  * _scsih_sas_control_complete - completion routine
@@ -4640,7 +4677,7 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd 
*scmd)
return 0;
}
 
-   if (ioc->pci_error_recovery || ioc->remove_host) {
+   if (!(_scsih_allow_scmd_to_device(ioc, scmd))) {
scmd->result = DID_NO_CONNECT << 16;
scmd->scsi_done(scmd);
return 0;
@@ -9876,6 +9913,7 @@ static void scsih_remove(struct pci_dev *pdev)
 
/* release all the volumes */
_scsih_ir_shutdown(ioc);
+   sas_remove_host(shost);
list_for_each_entry_safe(raid_device, next, >raid_device_list,
list) {
if (raid_device->starget) {
@@ -9918,7 +9956,6 @@ static void scsih_remove(struct pci_dev *pdev)
ioc->sas_hba.num_phys = 0;
}
 
-   sas_remove_host(shost);
mpt3sas_base_detach(ioc);
spin_lock(_lock);
list_del(>list);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_transport.c 
b/drivers/scsi/mpt3sas/mpt3sas_transport.c
index b10d73e..742da74 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_transport.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_transport.c
@@ -817,10 +817,13 @@ mpt3sas_transport_port_remove(struct MPT3SAS_ADAPTER 
*ioc, u64 sas_address,
mpt3sas_port->remote_identify.sas_address,
mpt3sas_phy->phy_id);
mpt3sas_phy->phy_belongs_to_port = 0;
-   sas_port_delete_phy(mpt3sas_port->port, mpt3sas_phy->phy);
+   if (!ioc->remove_host)
+   sas_port_delete_phy(mpt3sas_port->port,
+   mpt3sas_phy->phy);
list_del(_phy->port_siblings);
}
-   sas_port_delete(mpt3sas_port->port);
+   if (!ioc->remove_host)
+   sas_port_delete(mpt3sas_port->port);
kfree(mpt3sas_port);
 }
 
-- 
1.8.3.1



[Patch v1 1/7] mpt3sas: Introduce mpt3sas_base_pci_device_is_unplugged

2018-08-30 Thread Suganath Prabu S
* Driver does a PCIe read to check whether HBA is hot unplugged or
not. If the returned vendor ID is 0x/0x0, then this
indicates that the device might have been hot removed and the device
will be removed from driver.

* In the PCI device remove() callback function, flush out all
the outstanding IOs with 'DID_NO_CONNECT' before removing the drives
attached to the HBA.

* In the TM abort() callback function return the scmd with
"DID_NO_CONNECT" status and free the smid, if driver detects that
HBA is hot unplugged.

* In the hard reset flush out all the outstanding IOs even if diag reset
fails and also if driver detects that HBA is hot unplugged.

v1 change set:
unlock mutex before goto "out_unlocked", 
if active reset is in progress.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 62 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  3 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 42 +---
 3 files changed, 100 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 836b2e1..8b33670 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -61,7 +61,7 @@
 #include 
 #include /* To get host page size per arch */
 #include 
-
+#include <../drivers/pci/pci.h>
 
 #include "mpt3sas_base.h"
 
@@ -543,6 +543,44 @@ static int mpt3sas_remove_dead_ioc_func(void *arg)
 }
 
 /**
+ * mpt3sas_base_pci_device_is_unplugged - Check whether HBA device is
+ *  hot unplugged or not
+ * @ioc: per adapter object
+ *
+ * Return 1 if the HBA device is hot unplugged else return 0.
+ */
+u8
+mpt3sas_base_pci_device_is_unplugged(struct MPT3SAS_ADAPTER *ioc)
+{
+   struct pci_dev *pdev = ioc->pdev;
+   int devfn = pdev->devfn;
+   u32 l;
+
+   if (pci_bus_read_dev_vendor_id(pdev->bus, devfn, , 0))
+   return 0;
+
+   return 1;
+}
+
+/**
+ * mpt3sas_base_pci_device_is_available - check whether pci device is
+ * available for any transactions with FW
+ *
+ * @ioc: per adapter object
+ *
+ * Return 1 if pci device state is up and running else return 0.
+ */
+u8
+mpt3sas_base_pci_device_is_available(struct MPT3SAS_ADAPTER *ioc)
+{
+   if (ioc->pci_error_recovery ||
+   mpt3sas_base_pci_device_is_unplugged(ioc))
+   return 0;
+
+   return 1;
+}
+
+/**
  * _base_fault_reset_work - workq handling ioc fault conditions
  * @work: input argument, used to derive ioc
  *
@@ -6853,6 +6891,14 @@ mpt3sas_wait_for_commands_to_complete(struct 
MPT3SAS_ADAPTER *ioc)
 
ioc->pending_io_count = 0;
 
+   if (!mpt3sas_base_pci_device_is_available(ioc)) {
+   pr_err(MPT3SAS_FMT
+   "%s: pci error recovery reset or"
+   " pci device unplug occurred\n",
+   ioc->name, __func__);
+   return;
+   }
+
ioc_state = mpt3sas_base_get_iocstate(ioc, 0);
if ((ioc_state & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_OPERATIONAL)
return;
@@ -6899,6 +6945,20 @@ mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER 
*ioc,
/* wait for an active reset in progress to complete */
mutex_lock(>reset_in_progress_mutex);
 
+   if (!mpt3sas_base_pci_device_is_available(ioc)) {
+   pr_err(MPT3SAS_FMT
+   "%s: pci error recovery reset or"
+   " pci device unplug occurred\n",
+   ioc->name, __func__);
+   if (mpt3sas_base_pci_device_is_unplugged(ioc))
+   ioc->schedule_dead_ioc_flush_running_cmds(ioc);
+   r = 0;
+   mutex_unlock(>reset_in_progress_mutex);
+   goto out_unlocked;
+   }
+
+   mpt3sas_halt_firmware(ioc);
+
spin_lock_irqsave(>ioc_reset_in_progress_lock, flags);
ioc->shost_recovery = 1;
spin_unlock_irqrestore(>ioc_reset_in_progress_lock, flags);
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 96dc15e..8ee3ba7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -1474,7 +1474,8 @@ void mpt3sas_base_update_missing_delay(struct 
MPT3SAS_ADAPTER *ioc,
u16 device_missing_delay, u8 io_missing_delay);
 
 int mpt3sas_port_enable(struct MPT3SAS_ADAPTER *ioc);
-
+u8 mpt3sas_base_pci_device_is_unplugged(struct MPT3SAS_ADAPTER *ioc);
+u8 mpt3sas_base_pci_device_is_available(struct MPT3SAS_ADAPTER *ioc);
 void
 mpt3sas_wait_for_commands_to_complete(struct MPT3SAS_ADAPTER *ioc);
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 8dd3d67..9da 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2846,9 +2846,19 @@ scsih_abort(struct scsi_cmnd *scmd)
"attempting 

[Patch v1 2/7] mpt3sas: Add HBA hot plug watchdog thread.

2018-08-30 Thread Suganath Prabu S
During driver load create a hba hot unplug watchdog thread
"_base_hba_hot_unplug_work".

This will poll whether HBA device is unplugged or not by reading IOC's
vendor field in IOC's PCI configuration space for every one second.

If hot unplug is detected, it terminates all the outstanding IOs
and hence kernels's PCIe hotplug module (i.e. pciehp) will clear the
instances of the hot unplugged PCI device.

Below functions starts and stops the watchdog.
mpt3sas_base_start_hba_unplug_watchdog
mpt3sas_base_stop_hba_unplug_watchdog
Watchdog thread starts immediately once IOC becomes operational.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 92 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  6 +++
 drivers/scsi/mpt3sas/mpt3sas_scsih.c |  7 +++
 3 files changed, 104 insertions(+), 1 deletion(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 8b33670..6c8a30f 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -69,6 +69,7 @@ static MPT_CALLBACK   mpt_callbacks[MPT_MAX_CALLBACKS];
 
 
 #define FAULT_POLLING_INTERVAL 1000 /* in milliseconds */
+#define HBA_HOTUNPLUG_POLLING_INTERVAL 1000 /* in milliseconds */
 
  /* maximum controller queue depth */
 #define MAX_HBA_QUEUE_DEPTH3
@@ -672,6 +673,46 @@ _base_fault_reset_work(struct work_struct *work)
spin_unlock_irqrestore(>ioc_reset_in_progress_lock, flags);
 }
 
+static void
+_base_hba_hot_unplug_work(struct work_struct *work)
+{
+   struct MPT3SAS_ADAPTER *ioc =
+   container_of(work, struct MPT3SAS_ADAPTER,
+   hba_hot_unplug_work.work);
+   unsigned longflags;
+
+   spin_lock_irqsave(>hba_hot_unplug_lock, flags);
+   if (ioc->shost_recovery || ioc->pci_error_recovery)
+   goto rearm_timer;
+
+   if (mpt3sas_base_pci_device_is_unplugged(ioc)) {
+   if (ioc->remove_host) {
+   pr_err(MPT3SAS_FMT
+   "The IOC seems hot unplugged and the driver is "
+   "waiting for pciehp module to remove the PCIe "
+   "device instance associated with IOC!!!\n",
+   ioc->name);
+   goto rearm_timer;
+   }
+
+   /* Set remove_host flag here, since kernel will invoke driver's
+* .remove() callback function one after the other for all hot
+* un-plugged devices, so it may take some time to call
+* .remove() function for subsequent hot un-plugged
+* PCI devices.
+*/
+   ioc->remove_host = 1;
+   }
+
+rearm_timer:
+   if (ioc->hba_hot_unplug_work_q)
+   queue_delayed_work(ioc->hba_hot_unplug_work_q,
+   >hba_hot_unplug_work,
+   msecs_to_jiffies(HBA_HOTUNPLUG_POLLING_INTERVAL));
+   spin_unlock_irqrestore(>hba_hot_unplug_lock, flags);
+}
+
+
 /**
  * mpt3sas_base_start_watchdog - start the fault_reset_work_q
  * @ioc: per adapter object
@@ -730,6 +771,54 @@ mpt3sas_base_stop_watchdog(struct MPT3SAS_ADAPTER *ioc)
}
 }
 
+void
+mpt3sas_base_start_hba_unplug_watchdog(struct MPT3SAS_ADAPTER *ioc)
+{
+   unsigned longflags;
+
+   if (ioc->hba_hot_unplug_work_q)
+   return;
+
+   /* Initialize hba hot unplug polling */
+   INIT_DELAYED_WORK(>hba_hot_unplug_work,
+   _base_hba_hot_unplug_work);
+   snprintf(ioc->hba_hot_unplug_work_q_name,
+   sizeof(ioc->hba_hot_unplug_work_q_name), "poll_%s%d_hba_unplug",
+   ioc->driver_name, ioc->id);
+   ioc->hba_hot_unplug_work_q =
+   create_singlethread_workqueue(ioc->hba_hot_unplug_work_q_name);
+   if (!ioc->hba_hot_unplug_work_q) {
+   pr_err(MPT3SAS_FMT "%s: failed (line=%d)\n",
+   ioc->name, __func__, __LINE__);
+   return;
+   }
+
+   spin_lock_irqsave(>hba_hot_unplug_lock, flags);
+   if (ioc->hba_hot_unplug_work_q)
+   queue_delayed_work(ioc->hba_hot_unplug_work_q,
+   >hba_hot_unplug_work,
+   msecs_to_jiffies(HBA_HOTUNPLUG_POLLING_INTERVAL));
+   spin_unlock_irqrestore(>hba_hot_unplug_lock, flags);
+}
+
+void
+mpt3sas_base_stop_hba_unplug_watchdog(struct MPT3SAS_ADAPTER *ioc)
+{
+   unsigned long flags;
+   struct workqueue_struct *wq;
+
+   spin_lock_irqsave(>hba_hot_unplug_lock, flags);
+   wq = ioc->hba_hot_unplug_work_q;
+   ioc->hba_hot_unplug_work_q = NULL;
+   spin_unlock_irqrestore(>hba_hot_unplug_lock, flags);
+
+   if (wq) {
+   if (!cancel_delayed_work_sync(>hba_hot_unplug_work))
+   flush_workqueue(wq);
+   destroy_workqueue(wq);
+   }
+}
+
 /**
  * mpt3sas_base_fault_info - verbose translation of firmware FAULT code
  * 

[Patch v1 6/7] mpt3sas: Fix driver modifying NVRAM/persistent data.

2018-08-30 Thread Suganath Prabu S
* If EEDPTagMode field in manufacturing page11 is set,
unset it. This is needed to fix a hardware bug
in SAS3/SAS2 cards, So, skipping EEDPTagMode changes
in Manufacturing page11 for SAS35 controllers.

* Fix driver modifying NVRAM/persistent data in
Manufacturing page11 along with current copy. Driver should
change only current copy of Manufacturing page11

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c   | 2 +-
 drivers/scsi/mpt3sas/mpt3sas_config.c | 4 
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index a46ded8..92637c5 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -4235,7 +4235,7 @@ _base_static_config_pages(struct MPT3SAS_ADAPTER *ioc)
 * flag unset in NVDATA.
 */
mpt3sas_config_get_manufacturing_pg11(ioc, _reply, >manu_pg11);
-   if (ioc->manu_pg11.EEDPTagMode == 0) {
+   if ((!ioc->is_gen35_ioc) && (ioc->manu_pg11.EEDPTagMode == 0)) {
pr_err("%s: overriding NVDATA EEDPTagMode setting\n",
ioc->name);
ioc->manu_pg11.EEDPTagMode &= ~0x3;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_config.c 
b/drivers/scsi/mpt3sas/mpt3sas_config.c
index 5713a2d..f2a326a 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_config.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_config.c
@@ -676,10 +676,6 @@ mpt3sas_config_set_manufacturing_pg11(struct 
MPT3SAS_ADAPTER *ioc,
r = _config_request(ioc, _request, mpi_reply,
MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
sizeof(*config_page));
-   mpi_request.Action = MPI2_CONFIG_ACTION_PAGE_WRITE_NVRAM;
-   r = _config_request(ioc, _request, mpi_reply,
-   MPT3_CONFIG_PAGE_DEFAULT_TIMEOUT, config_page,
-   sizeof(*config_page));
  out:
return r;
 }
-- 
1.8.3.1



[Patch v1 0/7] mpt3sas: Hot-Plug Surprise removal support on IOC.

2018-08-30 Thread Suganath Prabu S
Posting below set of patches to support PCIe Hot Plug surprise removal,
and few defect fixes.

This is NOT the normal PCIe Hot Plug support, whereby the user informs the
OS that a hot removal is desired, the OS does an orderly shutdown of the driver
on the device, special hot plug circuitry removes power from the PCIe slot,
then the user can remove the device and replace it
(where orderly bring-up of the device is done).

With a true surprise removal (just removing HBA from a slot)
there is a possibility to get all kinds of PCIe transaction errors,
Below patches addresses those issues and remove HBA without bringing
the system down.

For surprise removal detection, driver does a PCI
read of IOC's vendor field in IOC's PCI configuration space.
If the read value is 0x this indicates that the device
might have hot removed and the device will be removed from driver.

V1 changes:
In Patch 0001 - unlock mutex, if active reset is in progress.

Suganath Prabu S (7):
  mpt3sas: Introduce mpt3sas_base_pci_device_is_unplugged
  mpt3sas: Add HBA hot plug watchdog thread.
  mpt3sas: Seperate out  mpt3sas_wait_for_ioc_to_operational
  mpt3sas: Introdude  _scsih_get_shost_and_ioc.
  mpt3sas: Fix Sync cache command failure during driver  unload.
  mpt3sas: Fix driver modifying NVRAM/persistent data.
  mpt3sas: Bump driver version to 27.100.00.00.

 drivers/scsi/mpt3sas/mpt3sas_base.c  | 248 ++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  17 ++-
 drivers/scsi/mpt3sas/mpt3sas_config.c|  32 +---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   |  26 +---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 188 ---
 drivers/scsi/mpt3sas/mpt3sas_transport.c |  82 +++---
 6 files changed, 414 insertions(+), 179 deletions(-)

-- 
1.8.3.1



[Patch v1 3/7] mpt3sas: Seperate out mpt3sas_wait_for_ioc_to_operational

2018-08-30 Thread Suganath Prabu S
Introduce mpt3sas_wait_for_ioc_to_operational.

This section of code "wait for IOC to be operational"
is used in many places across the driver,
and hence moved this section of code in to the function
"mpt3sas_wait_for_ioc_to_operational".

Also added HBA hot unplug checks, and this returns with
error code EFAULT, if it detects HBA is hot unplugged
or IOC is not in operational state.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.c  | 92 +++-
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  4 ++
 drivers/scsi/mpt3sas/mpt3sas_config.c| 28 +++---
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 26 ++---
 drivers/scsi/mpt3sas/mpt3sas_transport.c | 75 +-
 5 files changed, 81 insertions(+), 144 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c 
b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 6c8a30f..a46ded8 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -5289,6 +5289,53 @@ _base_send_ioc_reset(struct MPT3SAS_ADAPTER *ioc, u8 
reset_type, int timeout)
 }
 
 /**
+ * mpt3sas_wait_for_ioc_to_operational - IOC's operational
+ * state and HBA hot unplug status are checked here.
+ * @ioc: per adapter object
+ * @wait_count: timeout in seconds
+ *
+ * Return:  Returns EFAULT, if HBA is hot unplugged or IOC is
+ * not in operational state, within the wait_count.
+ * And returns 0, If not hot unplugged Or ioc is in
+ * operational state.
+ */
+
+int
+mpt3sas_wait_for_ioc_to_operational(struct MPT3SAS_ADAPTER *ioc,
+   int wait_count)
+{
+   int wait_state_count = 0;
+   u32 ioc_state;
+
+   if (mpt3sas_base_pci_device_is_unplugged(ioc))
+   return -EFAULT;
+
+   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
+   while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
+
+   if (mpt3sas_base_pci_device_is_unplugged(ioc))
+   return -EFAULT;
+
+   if (wait_state_count++ == wait_count) {
+   pr_err(MPT3SAS_FMT
+   "%s: failed due to ioc not operational\n",
+   ioc->name, __func__);
+   return -EFAULT;
+   }
+   ssleep(1);
+   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
+   pr_info(MPT3SAS_FMT "%s: waiting for "
+   "operational state(count=%d)\n", ioc->name,
+   __func__, wait_state_count);
+   }
+   if (wait_state_count)
+   pr_info(MPT3SAS_FMT "%s: ioc is operational\n",
+   ioc->name, __func__);
+
+   return 0;
+}
+
+/**
  * _base_handshake_req_reply_wait - send request thru doorbell interface
  * @ioc: per adapter object
  * @request_bytes: request length
@@ -5429,11 +5476,9 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER 
*ioc,
Mpi2SasIoUnitControlRequest_t *mpi_request)
 {
u16 smid;
-   u32 ioc_state;
u8 issue_reset = 0;
int rc;
void *request;
-   u16 wait_state_count;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5447,22 +5492,10 @@ mpt3sas_base_sas_iounit_control(struct MPT3SAS_ADAPTER 
*ioc,
goto out;
}
 
-   wait_state_count = 0;
-   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
-   while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-   if (wait_state_count++ == 10) {
-   pr_err(MPT3SAS_FMT
-   "%s: failed due to ioc not operational\n",
-   ioc->name, __func__);
-   rc = -EFAULT;
-   goto out;
-   }
-   ssleep(1);
-   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
-   pr_info(MPT3SAS_FMT
-   "%s: waiting for operational state(count=%d)\n",
-   ioc->name, __func__, wait_state_count);
-   }
+   rc = mpt3sas_wait_for_ioc_to_operational(ioc,
+   IOC_OPERATIONAL_WAIT_COUNT);
+   if (rc)
+   goto out;
 
smid = mpt3sas_base_get_smid(ioc, ioc->base_cb_idx);
if (!smid) {
@@ -5529,11 +5562,9 @@ mpt3sas_base_scsi_enclosure_processor(struct 
MPT3SAS_ADAPTER *ioc,
Mpi2SepReply_t *mpi_reply, Mpi2SepRequest_t *mpi_request)
 {
u16 smid;
-   u32 ioc_state;
u8 issue_reset = 0;
int rc;
void *request;
-   u16 wait_state_count;
 
dinitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
__func__));
@@ -5547,23 +5578,10 @@ mpt3sas_base_scsi_enclosure_processor(struct 
MPT3SAS_ADAPTER *ioc,
goto out;
}
 
-   wait_state_count = 0;
-   ioc_state = mpt3sas_base_get_iocstate(ioc, 1);
-   while (ioc_state != MPI2_IOC_STATE_OPERATIONAL) {
-   if (wait_state_count++ == 10) {
- 

[Patch v1 7/7] mpt3sas: Bump driver version to 27.100.00.00.

2018-08-30 Thread Suganath Prabu S
Modify driver version to 27.100.00.00
(which is equivalent to PH8 OOB driver)

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_base.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h 
b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 8b2cc66..7f29b0e 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -74,8 +74,8 @@
 #define MPT3SAS_DRIVER_NAME"mpt3sas"
 #define MPT3SAS_AUTHOR "Avago Technologies "
 #define MPT3SAS_DESCRIPTION"LSI MPT Fusion SAS 3.0 Device Driver"
-#define MPT3SAS_DRIVER_VERSION "26.100.00.00"
-#define MPT3SAS_MAJOR_VERSION  26
+#define MPT3SAS_DRIVER_VERSION "27.100.00.00"
+#define MPT3SAS_MAJOR_VERSION  27
 #define MPT3SAS_MINOR_VERSION  100
 #define MPT3SAS_BUILD_VERSION  0
 #define MPT3SAS_RELEASE_VERSION00
-- 
1.8.3.1



[Patch v1 4/7] mpt3sas: Introdude _scsih_get_shost_and_ioc.

2018-08-30 Thread Suganath Prabu S
The code for getting shost and IOC is redundant so
moved that to function "scsih_get_shost_and_ioc".
Also checks for NULL are added to IOC and shost.

Signed-off-by: Suganath Prabu S 
---
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 98 ++--
 1 file changed, 82 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c 
b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 7e0c4ec..2c7f44c 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -9809,6 +9809,35 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
 }
 
 /**
+ * _scsih_get_shost_and_ioc - get shost and ioc
+ * and verify whether they are NULL or not
+ * @pdev: PCI device struct
+ * @shost: address of scsi host pointer
+ * @ioc: address of HBA adapter pointer
+ *
+ * Return zero if *shost and *ioc are not NULL otherwise return error number.
+ */
+static int
+_scsih_get_shost_and_ioc(struct pci_dev *pdev,
+   struct Scsi_Host **shost, struct MPT3SAS_ADAPTER **ioc)
+{
+   *shost = pci_get_drvdata(pdev);
+   if (*shost == NULL) {
+   dev_err(>dev, "pdev's driver data is null\n");
+   return -ENXIO;
+   }
+
+   *ioc = shost_priv(*shost);
+   if (*ioc == NULL) {
+   dev_err(>dev, "shost's private data is null\n");
+   return -ENXIO;
+   }
+
+   return 0;
+}
+
+
+/**
  * scsih_remove - detach and remove add host
  * @pdev: PCI device struct
  *
@@ -9816,8 +9845,8 @@ _scsih_ir_shutdown(struct MPT3SAS_ADAPTER *ioc)
  */
 static void scsih_remove(struct pci_dev *pdev)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
struct _sas_port *mpt3sas_port, *next_port;
struct _raid_device *raid_device, *next;
struct MPT3SAS_TARGET *sas_target_priv_data;
@@ -9825,6 +9854,10 @@ static void scsih_remove(struct pci_dev *pdev)
struct workqueue_struct *wq;
unsigned long flags;
 
+   if (_scsih_get_shost_and_ioc(pdev, , )) {
+   dev_err(>dev, "unable to remove device\n");
+   return;
+   }
ioc->remove_host = 1;
 
mpt3sas_wait_for_commands_to_complete(ioc);
@@ -9900,11 +9933,16 @@ static void scsih_remove(struct pci_dev *pdev)
 static void
 scsih_shutdown(struct pci_dev *pdev)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
struct workqueue_struct *wq;
unsigned long flags;
 
+   if (_scsih_get_shost_and_ioc(pdev, , )) {
+   dev_err(>dev, "unable to shutdown device\n");
+   return;
+   }
+
ioc->remove_host = 1;
 
mpt3sas_wait_for_commands_to_complete(ioc);
@@ -10721,10 +10759,16 @@ out_add_shost_fail:
 static int
 scsih_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
pci_power_t device_state;
+   int rc;
 
+   rc = _scsih_get_shost_and_ioc(pdev, , );
+   if (rc) {
+   dev_err(>dev, "unable to suspend device\n");
+   return rc;
+   }
mpt3sas_base_stop_watchdog(ioc);
mpt3sas_base_stop_hba_unplug_watchdog(ioc);
flush_scheduled_work();
@@ -10749,11 +10793,17 @@ scsih_suspend(struct pci_dev *pdev, pm_message_t 
state)
 static int
 scsih_resume(struct pci_dev *pdev)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
pci_power_t device_state = pdev->current_state;
int r;
 
+   r = _scsih_get_shost_and_ioc(pdev, , );
+   if (r) {
+   dev_err(>dev, "unable to resume device\n");
+   return r;
+   }
+
pr_info(MPT3SAS_FMT
"pdev=0x%p, slot=%s, previous operating state [D%d]\n",
ioc->name, pdev, pci_name(pdev), device_state);
@@ -10786,9 +10836,13 @@ scsih_resume(struct pci_dev *pdev)
 static pci_ers_result_t
 scsih_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state)
 {
-   struct Scsi_Host *shost = pci_get_drvdata(pdev);
-   struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
+   struct Scsi_Host *shost = NULL;
+   struct MPT3SAS_ADAPTER *ioc = NULL;
 
+   if (_scsih_get_shost_and_ioc(pdev, , )) {
+   dev_err(>dev, "device unavailable\n");
+   return PCI_ERS_RESULT_DISCONNECT;
+   }
pr_info(MPT3SAS_FMT "PCI error: detected callback, state(%d)!!\n",
ioc->name, state);
 
@@ 

Re: [PATCH v3] target/iblock: split T10 PI SGL across command bios

2018-08-30 Thread Mike Christie
On 08/30/2018 12:25 PM, Greg Edwards wrote:
> When T10 PI is enabled on a backing device for the iblock backstore, the
> PI SGL for the entire command is attached to the first bio only.  This
> works fine if the command is covered by a single bio, but can result in
> ref tag errors in the client for the other bios in a multi-bio command,
> e.g.
> 
> [   47.631236] sda: ref tag error at location 2048 (rcvd 0)
> [   47.637658] sda: ref tag error at location 4096 (rcvd 0)
> [   47.644228] sda: ref tag error at location 6144 (rcvd 0)
> 
> The command will be split into multiple bios if the number of data SG
> elements exceeds BIO_MAX_PAGES (see iblock_get_bio()).
> 
> The bios may later be split again in the block layer on the host after
> iblock_submit_bios(), depending on the queue limits of the backing
> device.  The block and SCSI layers will pass through the whole PI SGL
> down to the LLDD however that first bio is split up, but the LLDD may
> only use the portion that corresponds to the data length (depends on the
> LLDD, tested with scsi_debug).
> 
> Split the PI SGL across the bios in the command, so each bio's
> bio_integrity_payload contains the protection information for the data
> in the bio.  Use an sg_mapping_iter to keep track of where we are in PI
> SGL, so we know where to start with the next bio.
> 
> Signed-off-by: Greg Edwards 
> ---
> Changes from v2:
>   * add back min(cmd->t_prot_nents, BIO_MAX_PAGES) for bio_integrity_alloc()
> from v1
> 
> Changes from v1:
>   * expand commit message
>   * use an sg_mapping_iter to track where we are in the PI SGL
> 
> 
>  drivers/target/target_core_iblock.c | 54 -
>  1 file changed, 37 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/target/target_core_iblock.c 
> b/drivers/target/target_core_iblock.c
> index ce1321a5cb7b..db78b1c808e8 100644
> --- a/drivers/target/target_core_iblock.c
> +++ b/drivers/target/target_core_iblock.c
> @@ -635,14 +635,15 @@ static ssize_t iblock_show_configfs_dev_params(struct 
> se_device *dev, char *b)
>  }
>  
>  static int
> -iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio)
> +iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio,
> +  struct sg_mapping_iter *miter)
>  {
>   struct se_device *dev = cmd->se_dev;
>   struct blk_integrity *bi;
>   struct bio_integrity_payload *bip;
>   struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
> - struct scatterlist *sg;
> - int i, rc;
> + int rc;
> + size_t resid, len;
>  
>   bi = bdev_get_integrity(ib_dev->ibd_bd);
>   if (!bi) {
> @@ -650,31 +651,39 @@ iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio)
>   return -ENODEV;
>   }
>  
> - bip = bio_integrity_alloc(bio, GFP_NOIO, cmd->t_prot_nents);
> + bip = bio_integrity_alloc(bio, GFP_NOIO,
> + min_t(unsigned int, cmd->t_prot_nents, BIO_MAX_PAGES));
>   if (IS_ERR(bip)) {
>   pr_err("Unable to allocate bio_integrity_payload\n");
>   return PTR_ERR(bip);
>   }
>  
> - bip->bip_iter.bi_size = (cmd->data_length / dev->dev_attrib.block_size) 
> *
> -  dev->prot_length;
> - bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
> + bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio));
> + bip_set_seed(bip, bio->bi_iter.bi_sector);
>  
>   pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size,
>(unsigned long long)bip->bip_iter.bi_sector);
>  
> - for_each_sg(cmd->t_prot_sg, sg, cmd->t_prot_nents, i) {
> + resid = bip->bip_iter.bi_size;
> + while (resid > 0 && sg_miter_next(miter)) {
>  
> - rc = bio_integrity_add_page(bio, sg_page(sg), sg->length,
> - sg->offset);
> - if (rc != sg->length) {
> + len = min_t(size_t, miter->length, resid);
> + rc = bio_integrity_add_page(bio, miter->page, len,
> + offset_in_page(miter->addr));
> + if (rc != len) {
>   pr_err("bio_integrity_add_page() failed; %d\n", rc);
> + sg_miter_stop(miter);
>   return -ENOMEM;
>   }
>  
> - pr_debug("Added bio integrity page: %p length: %d offset; %d\n",
> -  sg_page(sg), sg->length, sg->offset);
> + pr_debug("Added bio integrity page: %p length: %lu offset: 
> %lu\n",
> +   miter->page, len, offset_in_page(miter->addr));
> +
> + resid -= len;
> + if (len < miter->length)
> + miter->consumed -= miter->length - len;
>   }
> + sg_miter_stop(miter);
>  
>   return 0;
>  }
> @@ -686,12 +695,13 @@ iblock_execute_rw(struct se_cmd *cmd, struct 
> scatterlist *sgl, u32 sgl_nents,
>   struct se_device *dev = cmd->se_dev;
>   sector_t block_lba = target_to_linux_sector(dev, 

Re: [PATCH 1/7] mpt3sas: Introduce mpt3sas_base_pci_device_is_unplugged (fwd)

2018-08-30 Thread Julia Lawall
Hello,

The complaint is actually about line 6956.  Has the mutex been released
there?

julia

-- Forwarded message --
Date: Fri, 31 Aug 2018 00:37:52 +0800
From: kbuild test robot 
To: kbu...@01.org
Cc: Julia Lawall 
Subject: Re: [PATCH 1/7] mpt3sas: Introduce mpt3sas_base_pci_device_is_unplugged

CC: kbuild-...@01.org
In-Reply-To: 
<1535599593-4739-2-git-send-email-suganath-prabu.subram...@broadcom.com>
References: 
<1535599593-4739-2-git-send-email-suganath-prabu.subram...@broadcom.com>
TO: Suganath Prabu S 
CC: linux-scsi@vger.kernel.org
CC: sathya.prak...@broadcom.com, sreekanth.re...@broadcom.com, Suganath Prabu S 


Hi Suganath,

I love your patch! Perhaps something to improve:

[auto build test WARNING on scsi/for-next]
[also build test WARNING on v4.19-rc1 next-20180830]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Suganath-Prabu-S/mpt3sas-Hot-Plug-Surprise-removal-support-on-IOC/20180830-203851
base:   https://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git for-next
:: branch date: 4 hours ago
:: commit date: 4 hours ago

>> drivers/scsi/mpt3sas/mpt3sas_base.c:7023:1-7: preceding lock on line 6946

# 
https://github.com/0day-ci/linux/commit/a51dfd76fefe9f96918233100ef83b5df2b1acbd
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout a51dfd76fefe9f96918233100ef83b5df2b1acbd
vim +7023 drivers/scsi/mpt3sas/mpt3sas_base.c

f92363d12 Sreekanth Reddy  2012-11-30  6915
f92363d12 Sreekanth Reddy  2012-11-30  6916  /**
f92363d12 Sreekanth Reddy  2012-11-30  6917   * mpt3sas_base_hard_reset_handler 
- reset controller
f92363d12 Sreekanth Reddy  2012-11-30  6918   * @ioc: Pointer to MPT_ADAPTER 
structure
f92363d12 Sreekanth Reddy  2012-11-30  6919   * @type: FORCE_BIG_HAMMER or 
SOFT_RESET
f92363d12 Sreekanth Reddy  2012-11-30  6920   *
4beb4867f Bart Van Assche  2018-06-15  6921   * Return: 0 for success, non-zero 
for failure.
f92363d12 Sreekanth Reddy  2012-11-30  6922   */
f92363d12 Sreekanth Reddy  2012-11-30  6923  int
98c56ad32 Calvin Owens 2016-07-28  6924  
mpt3sas_base_hard_reset_handler(struct MPT3SAS_ADAPTER *ioc,
f92363d12 Sreekanth Reddy  2012-11-30  6925 enum reset_type type)
f92363d12 Sreekanth Reddy  2012-11-30  6926  {
f92363d12 Sreekanth Reddy  2012-11-30  6927 int r;
f92363d12 Sreekanth Reddy  2012-11-30  6928 unsigned long flags;
f92363d12 Sreekanth Reddy  2012-11-30  6929 u32 ioc_state;
f92363d12 Sreekanth Reddy  2012-11-30  6930 u8 is_fault = 0, is_trigger = 0;
f92363d12 Sreekanth Reddy  2012-11-30  6931
f92363d12 Sreekanth Reddy  2012-11-30  6932 dtmprintk(ioc, 
pr_info(MPT3SAS_FMT "%s: enter\n", ioc->name,
f92363d12 Sreekanth Reddy  2012-11-30  6933 __func__));
f92363d12 Sreekanth Reddy  2012-11-30  6934
f92363d12 Sreekanth Reddy  2012-11-30  6935 if (ioc->pci_error_recovery) {
f92363d12 Sreekanth Reddy  2012-11-30  6936 pr_err(MPT3SAS_FMT "%s: 
pci error recovery reset\n",
f92363d12 Sreekanth Reddy  2012-11-30  6937 ioc->name, 
__func__);
f92363d12 Sreekanth Reddy  2012-11-30  6938 r = 0;
f92363d12 Sreekanth Reddy  2012-11-30  6939 goto out_unlocked;
f92363d12 Sreekanth Reddy  2012-11-30  6940 }
f92363d12 Sreekanth Reddy  2012-11-30  6941
f92363d12 Sreekanth Reddy  2012-11-30  6942 if (mpt3sas_fwfault_debug)
f92363d12 Sreekanth Reddy  2012-11-30  6943 
mpt3sas_halt_firmware(ioc);
f92363d12 Sreekanth Reddy  2012-11-30  6944
f92363d12 Sreekanth Reddy  2012-11-30  6945 /* wait for an active reset in 
progress to complete */
982ea6f9f Bart Van Assche  2018-06-15 @6946 
mutex_lock(>reset_in_progress_mutex);
f92363d12 Sreekanth Reddy  2012-11-30  6947
a51dfd76f Suganath Prabu S 2018-08-29  6948 if 
(!mpt3sas_base_pci_device_is_available(ioc)) {
a51dfd76f Suganath Prabu S 2018-08-29  6949 pr_err(MPT3SAS_FMT
a51dfd76f Suganath Prabu S 2018-08-29  6950 "%s: pci error 
recovery reset or"
a51dfd76f Suganath Prabu S 2018-08-29  6951 " pci device unplug 
occurred\n",
a51dfd76f Suganath Prabu S 2018-08-29  6952 ioc->name, 
__func__);
a51dfd76f Suganath Prabu S 2018-08-29  6953 if 
(mpt3sas_base_pci_device_is_unplugged(ioc))
a51dfd76f Suganath Prabu S 2018-08-29  6954 
ioc->schedule_dead_ioc_flush_running_cmds(ioc);
a51dfd76f Suganath Prabu S 2018-08-29  6955 r = 0;
a51dfd76f Suganath Prabu S 2018-08-29  6956 goto out_unlocked;
a51dfd76f Suganath Prabu S 2018-08-29  6957 }
a51dfd76f Suganath Prabu S 2018-08-29  6958
a51dfd76f Suganath Prabu S 2018-08-29  6959 mpt3sas_halt_firmware(ioc);
a51dfd76f Suganath Prabu S 2018-08-29  6960
f92363d12 Sreekanth Reddy  2012-11-30  6961 
spin_lock_irq

[PATCH v3] target/iblock: split T10 PI SGL across command bios

2018-08-30 Thread Greg Edwards
When T10 PI is enabled on a backing device for the iblock backstore, the
PI SGL for the entire command is attached to the first bio only.  This
works fine if the command is covered by a single bio, but can result in
ref tag errors in the client for the other bios in a multi-bio command,
e.g.

[   47.631236] sda: ref tag error at location 2048 (rcvd 0)
[   47.637658] sda: ref tag error at location 4096 (rcvd 0)
[   47.644228] sda: ref tag error at location 6144 (rcvd 0)

The command will be split into multiple bios if the number of data SG
elements exceeds BIO_MAX_PAGES (see iblock_get_bio()).

The bios may later be split again in the block layer on the host after
iblock_submit_bios(), depending on the queue limits of the backing
device.  The block and SCSI layers will pass through the whole PI SGL
down to the LLDD however that first bio is split up, but the LLDD may
only use the portion that corresponds to the data length (depends on the
LLDD, tested with scsi_debug).

Split the PI SGL across the bios in the command, so each bio's
bio_integrity_payload contains the protection information for the data
in the bio.  Use an sg_mapping_iter to keep track of where we are in PI
SGL, so we know where to start with the next bio.

Signed-off-by: Greg Edwards 
---
Changes from v2:
  * add back min(cmd->t_prot_nents, BIO_MAX_PAGES) for bio_integrity_alloc()
from v1

Changes from v1:
  * expand commit message
  * use an sg_mapping_iter to track where we are in the PI SGL


 drivers/target/target_core_iblock.c | 54 -
 1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/drivers/target/target_core_iblock.c 
b/drivers/target/target_core_iblock.c
index ce1321a5cb7b..db78b1c808e8 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -635,14 +635,15 @@ static ssize_t iblock_show_configfs_dev_params(struct 
se_device *dev, char *b)
 }
 
 static int
-iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio)
+iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio,
+struct sg_mapping_iter *miter)
 {
struct se_device *dev = cmd->se_dev;
struct blk_integrity *bi;
struct bio_integrity_payload *bip;
struct iblock_dev *ib_dev = IBLOCK_DEV(dev);
-   struct scatterlist *sg;
-   int i, rc;
+   int rc;
+   size_t resid, len;
 
bi = bdev_get_integrity(ib_dev->ibd_bd);
if (!bi) {
@@ -650,31 +651,39 @@ iblock_alloc_bip(struct se_cmd *cmd, struct bio *bio)
return -ENODEV;
}
 
-   bip = bio_integrity_alloc(bio, GFP_NOIO, cmd->t_prot_nents);
+   bip = bio_integrity_alloc(bio, GFP_NOIO,
+   min_t(unsigned int, cmd->t_prot_nents, BIO_MAX_PAGES));
if (IS_ERR(bip)) {
pr_err("Unable to allocate bio_integrity_payload\n");
return PTR_ERR(bip);
}
 
-   bip->bip_iter.bi_size = (cmd->data_length / dev->dev_attrib.block_size) 
*
-dev->prot_length;
-   bip->bip_iter.bi_sector = bio->bi_iter.bi_sector;
+   bip->bip_iter.bi_size = bio_integrity_bytes(bi, bio_sectors(bio));
+   bip_set_seed(bip, bio->bi_iter.bi_sector);
 
pr_debug("IBLOCK BIP Size: %u Sector: %llu\n", bip->bip_iter.bi_size,
 (unsigned long long)bip->bip_iter.bi_sector);
 
-   for_each_sg(cmd->t_prot_sg, sg, cmd->t_prot_nents, i) {
+   resid = bip->bip_iter.bi_size;
+   while (resid > 0 && sg_miter_next(miter)) {
 
-   rc = bio_integrity_add_page(bio, sg_page(sg), sg->length,
-   sg->offset);
-   if (rc != sg->length) {
+   len = min_t(size_t, miter->length, resid);
+   rc = bio_integrity_add_page(bio, miter->page, len,
+   offset_in_page(miter->addr));
+   if (rc != len) {
pr_err("bio_integrity_add_page() failed; %d\n", rc);
+   sg_miter_stop(miter);
return -ENOMEM;
}
 
-   pr_debug("Added bio integrity page: %p length: %d offset; %d\n",
-sg_page(sg), sg->length, sg->offset);
+   pr_debug("Added bio integrity page: %p length: %lu offset: 
%lu\n",
+ miter->page, len, offset_in_page(miter->addr));
+
+   resid -= len;
+   if (len < miter->length)
+   miter->consumed -= miter->length - len;
}
+   sg_miter_stop(miter);
 
return 0;
 }
@@ -686,12 +695,13 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist 
*sgl, u32 sgl_nents,
struct se_device *dev = cmd->se_dev;
sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
struct iblock_req *ibr;
-   struct bio *bio, *bio_start;
+   struct bio *bio;
struct bio_list list;
struct scatterlist *sg;
u32 

[PATCH 09/14] qla2xxx: Force fw cleanup on ADISC error

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

Turn ON logout_on_delete flag to make sure firmware
resource for fcport is cleaned up on ADISC error.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index fa6f2400a508..f840199d31cc 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -396,6 +396,9 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
ql_dbg(ql_dbg_disc, vha, 0x2066,
"%s %8phC: adisc fail: post delete\n",
__func__, ea->fcport->port_name);
+   /* deleted = 0 & logout_on_delete = force fw cleanup */
+   fcport->deleted = 0;
+   fcport->logout_on_delete = 1;
qlt_schedule_sess_for_deletion(ea->fcport);
return;
}
-- 
2.12.0



[PATCH 13/14] qla2xxx: Terminate Plogi/PRLI if WWN is 0

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

When driver receive PLOGI/PRLI from FW, the WWPN value
will be provided.  If it is not, then driver will terminate it.
The WWPN allows driver to locate the session or create a
new session.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_target.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
index 34fadd320f55..396c8a6d502c 100644
--- a/drivers/scsi/qla2xxx/qla_target.c
+++ b/drivers/scsi/qla2xxx/qla_target.c
@@ -4723,6 +4723,12 @@ static int qlt_handle_login(struct scsi_qla_host *vha,
sess = qlt_find_sess_invalidate_other(vha, wwn,
port_id, loop_id, _sess);
spin_unlock_irqrestore(>hw->tgt.sess_lock, flags);
+   } else {
+   ql_dbg(ql_dbg_disc, vha, 0x,
+   "%s %d Term INOT due to WWN=0 lid=%d, NportID %06X ",
+   __func__, __LINE__, loop_id, port_id.b24);
+   qlt_send_term_imm_notif(vha, iocb, 1);
+   goto out;
}
 
if (IS_SW_RESV_ADDR(port_id)) {
-- 
2.12.0



[PATCH 11/14] qla2xxx: Fix iIDMA error

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

when switch responds with error for Get Port Speed Command (GPSC),
driver should not proceed with telling FW about the speed
of the remote port.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 85cbe59b4f58..902106f97020 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3272,7 +3272,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
ql_dbg(ql_dbg_disc, vha, 0x2019,
"GPSC command unsupported, disabling query.\n");
ha->flags.gpsc_supported = 0;
-   res = QLA_SUCCESS;
+   goto done;
}
} else {
switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) {
@@ -3305,7 +3305,6 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
be16_to_cpu(ct_rsp->rsp.gpsc.speeds),
be16_to_cpu(ct_rsp->rsp.gpsc.speed));
}
-done:
memset(, 0, sizeof(ea));
ea.event = FCME_GPSC_DONE;
ea.rc = res;
@@ -3313,6 +3312,7 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
ea.sp = sp;
qla2x00_fcport_event_handler(vha, );
 
+done:
sp->free(sp);
 }
 
-- 
2.12.0



[PATCH 03/14] qla2xxx: Use correct qpair for ABTS/CMD

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

On Abort of initiator scsi command, the abort needs to
follow the same qpair as the the scsi command to prevent
out of order processing.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 15 +--
 drivers/scsi/qla2xxx/qla_iocb.c | 12 +++-
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 4686fb5f26aa..53c4eb3b9c27 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1747,18 +1747,18 @@ int
 qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
 {
scsi_qla_host_t *vha = cmd_sp->vha;
-   fc_port_t *fcport = cmd_sp->fcport;
struct srb_iocb *abt_iocb;
srb_t *sp;
int rval = QLA_FUNCTION_FAILED;
 
-   sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+   sp = qla2xxx_get_qpair_sp(cmd_sp->qpair, cmd_sp->fcport, GFP_KERNEL);
if (!sp)
goto done;
 
abt_iocb = >u.iocb_cmd;
sp->type = SRB_ABT_CMD;
sp->name = "abort";
+   sp->qpair = cmd_sp->qpair;
if (wait)
sp->flags = SRB_WAKEUP_ON_COMP;
 
@@ -1767,12 +1767,7 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha));
 
abt_iocb->u.abt.cmd_hndl = cmd_sp->handle;
-
-   if (vha->flags.qpairs_available && cmd_sp->qpair)
-   abt_iocb->u.abt.req_que_no =
-   cpu_to_le16(cmd_sp->qpair->req->id);
-   else
-   abt_iocb->u.abt.req_que_no = cpu_to_le16(vha->req->id);
+   abt_iocb->u.abt.req_que_no = cmd_sp->qpair->req->id;
 
sp->done = qla24xx_abort_sp_done;
 
@@ -1781,8 +1776,8 @@ qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
goto done_free_sp;
 
ql_dbg(ql_dbg_async, vha, 0x507c,
-   "Abort command issued - hdl=%x, target_id=%x\n",
-   cmd_sp->handle, fcport->tgt_id);
+   "Abort command issued - hdl=%x, type=%x\n",
+   cmd_sp->handle, cmd_sp->type);
 
if (wait) {
wait_for_completion(_iocb->u.abt.comp);
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 119927220299..c699bbb8485b 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -3297,19 +3297,21 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx 
*abt_iocb)
 {
struct srb_iocb *aio = >u.iocb_cmd;
scsi_qla_host_t *vha = sp->vha;
-   struct req_que *req = vha->req;
+   struct req_que *req = sp->qpair->req;
 
memset(abt_iocb, 0, sizeof(struct abort_entry_24xx));
abt_iocb->entry_type = ABORT_IOCB_TYPE;
abt_iocb->entry_count = 1;
abt_iocb->handle = cpu_to_le32(MAKE_HANDLE(req->id, sp->handle));
-   abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+   if (sp->fcport) {
+   abt_iocb->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+   abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
+   abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
+   abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
+   }
abt_iocb->handle_to_abort =
cpu_to_le32(MAKE_HANDLE(aio->u.abt.req_que_no,
aio->u.abt.cmd_hndl));
-   abt_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
-   abt_iocb->port_id[1] = sp->fcport->d_id.b.area;
-   abt_iocb->port_id[2] = sp->fcport->d_id.b.domain;
abt_iocb->vp_index = vha->vp_idx;
abt_iocb->req_que_no = cpu_to_le16(aio->u.abt.req_que_no);
/* Send the command to the firmware */
-- 
2.12.0



[PATCH 06/14] qla2xxx: Move rport registration out of internal work_list

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

Currently, the rport registration is being called from a single
work element that is used to process QLA internal "work_list".
This work_list is meant for quick and simple task (ie no sleep).
The Rport registration process sometime can be delayed by upper
layer.  This causes back pressure with the internal queue where
other jobs are unable to move forward.

This patch will schedule the registration process with a new work
element (fc_port.reg_work).  While the RPort is being registered,
the current state of the fcport will not move forward until the
registration is done.  If the state of the fabric has changed, a new
field/next_disc_state will record the next action on whether to
'DELETE' or 'Reverify the session/ADISC'.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_def.h|  6 ++-
 drivers/scsi/qla2xxx/qla_gbl.h|  5 ++-
 drivers/scsi/qla2xxx/qla_init.c   | 66 ++-
 drivers/scsi/qla2xxx/qla_os.c | 26 +++-
 drivers/scsi/qla2xxx/qla_target.c | 83 +++
 5 files changed, 147 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index c41d0dbbbd79..16dd59bcd60a 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2375,11 +2375,13 @@ typedef struct fc_port {
unsigned long expires;
struct list_head del_list_entry;
struct work_struct free_work;
-
+   struct work_struct reg_work;
+   uint64_t jiffies_at_registration;
struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX];
 
uint16_t tgt_id;
uint16_t old_tgt_id;
+   uint16_t sec_since_registration;
 
uint8_t fcp_prio;
 
@@ -2412,6 +2414,7 @@ typedef struct fc_port {
struct qla_tgt_sess *tgt_session;
struct ct_sns_desc ct_desc;
enum discovery_state disc_state;
+   enum discovery_state next_disc_state;
enum login_state fw_login_state;
unsigned long dm_login_expire;
unsigned long plogi_nack_done_deadline;
@@ -3222,7 +3225,6 @@ enum qla_work_type {
QLA_EVT_GPDB,
QLA_EVT_PRLI,
QLA_EVT_GPSC,
-   QLA_EVT_UPD_FCPORT,
QLA_EVT_GNL,
QLA_EVT_NACK,
QLA_EVT_RELOGIN,
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
index 178974896b5c..b8e4abe804d5 100644
--- a/drivers/scsi/qla2xxx/qla_gbl.h
+++ b/drivers/scsi/qla2xxx/qla_gbl.h
@@ -54,7 +54,7 @@ extern void qla2x00_abort_isp_cleanup(scsi_qla_host_t *);
 extern void qla2x00_quiesce_io(scsi_qla_host_t *);
 
 extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
-
+void qla_register_fcport_fn(struct work_struct *);
 extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
 extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
 
@@ -109,6 +109,7 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *, 
port_id_t *, u8 *, u8*,
 int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *);
 int qla24xx_detect_sfp(scsi_qla_host_t *vha);
 int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
+
 void qla2x00_async_prlo_done(struct scsi_qla_host *, fc_port_t *,
 uint16_t *);
 extern int qla2x00_post_async_prlo_work(struct scsi_qla_host *, fc_port_t *,
@@ -208,7 +209,7 @@ extern void qla2x00_disable_board_on_pci_error(struct 
work_struct *);
 extern void qla2x00_sp_compl(void *, int);
 extern void qla2xxx_qpair_sp_free_dma(void *);
 extern void qla2xxx_qpair_sp_compl(void *, int);
-extern int qla24xx_post_upd_fcport_work(struct scsi_qla_host *, fc_port_t *);
+extern void qla24xx_sched_upd_fcport(fc_port_t *);
 void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
 int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index cb00fd740d29..6f26e6164c04 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1182,11 +1182,7 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
vha->fcport_count++;
ea->fcport->login_succ = 1;
 
-   ql_dbg(ql_dbg_disc, vha, 0x20d6,
-   "%s %d %8phC post upd_fcport fcp_cnt %d\n",
-   __func__, __LINE__,  ea->fcport->port_name,
-   vha->fcport_count);
-   qla24xx_post_upd_fcport_work(vha, ea->fcport);
+   qla24xx_sched_upd_fcport(ea->fcport);
} else if (ea->fcport->login_succ) {
/*
 * We have an existing session. A late RSCN delivery
@@ -1304,6 +1300,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
 {
u16 data[2];
u64 wwn;
+   u16 sec;
 
ql_dbg(ql_dbg_disc, vha, 0x20d8,
"%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d retry 

[PATCH 02/14] qla2xxx: Fix incorrect port speed being set for FC adapters

2018-08-30 Thread Himanshu Madhani
Fixes: 6246b8a1d26c7c ("[SCSI] qla2xxx: Enhancements to support ISP83xx.")
Fixes: 1bb395485160d2 ("qla2xxx: Correct iiDMA-update calling conventions.")
Cc: 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_mbx.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 2c6c2cd5a0d0..c73039916c03 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -3762,10 +3762,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *vha, uint16_t 
loop_id,
mcp->mb[0] = MBC_PORT_PARAMS;
mcp->mb[1] = loop_id;
mcp->mb[2] = BIT_0;
-   if (IS_CNA_CAPABLE(vha->hw))
-   mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
-   else
-   mcp->mb[3] = port_speed & (BIT_2|BIT_1|BIT_0);
+   mcp->mb[3] = port_speed & (BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0);
mcp->mb[9] = vha->vp_idx;
mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
mcp->in_mb = MBX_3|MBX_1|MBX_0;
-- 
2.12.0



[PATCH 07/14] qla2xxx: Decrement login retry count for only plogi

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

Decrement login retry count only for plogi, instead of
number of attempt made for login.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c | 18 +-
 1 file changed, 5 insertions(+), 13 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index 6f26e6164c04..fa6f2400a508 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -1276,7 +1276,8 @@ static void qla_chk_n2n_b4_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
login = 1;
}
 
-   if (login) {
+   if (login && fcport->login_retry) {
+   fcport->login_retry--;
if (fcport->loop_id == FC_NO_LOOP_ID) {
fcport->fw_login_state = DSC_LS_PORT_UNAVAIL;
rc = qla2x00_find_new_loop_id(vha, fcport);
@@ -1302,13 +1303,12 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
u64 wwn;
u16 sec;
 
-   ql_dbg(ql_dbg_disc, vha, 0x20d8,
-   "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d retry 
%d lid %d scan %d\n",
+   ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20d8,
+   "%s %8phC DS %d LS %d P %d fl %x confl %p rscn %d|%d login %d lid 
%d scan %d\n",
__func__, fcport->port_name, fcport->disc_state,
fcport->fw_login_state, fcport->login_pause, fcport->flags,
fcport->conflict, fcport->last_rscn_gen, fcport->rscn_gen,
-   fcport->login_gen, fcport->login_retry,
-   fcport->loop_id, fcport->scan_state);
+   fcport->login_gen, fcport->loop_id, fcport->scan_state);
 
if (fcport->scan_state != QLA_FCPORT_FOUND)
return 0;
@@ -1407,10 +1407,6 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
break;
 
case DSC_LOGIN_FAILED:
-   fcport->login_retry--;
-   ql_dbg(ql_dbg_disc, vha, 0x20d0,
-   "%s %d %8phC post gidpn\n",
-   __func__, __LINE__, fcport->port_name);
if (N2N_TOPO(vha->hw))
qla_chk_n2n_b4_login(vha, fcport);
else
@@ -1419,10 +1415,6 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
 
case DSC_LOGIN_COMPLETE:
/* recheck login state */
-   ql_dbg(ql_dbg_disc, vha, 0x20d1,
-   "%s %d %8phC post adisc\n",
-   __func__, __LINE__, fcport->port_name);
-   fcport->login_retry--;
data[0] = data[1] = 0;
qla2x00_post_async_adisc_work(vha, fcport, data);
break;
-- 
2.12.0



[PATCH 05/14] qla2xxx: Remove redundant check for fcport deletion

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

Remove redundant check for fcport is deleted or being delete.
The same check is already in the deletion routine.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gs.c | 62 +++
 1 file changed, 9 insertions(+), 53 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index c0c738bbdace..6e95ba0d3c8b 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3442,26 +3442,10 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
if (ea->rc) {
/* cable is disconnected */
list_for_each_entry_safe(fcport, t, >vp_fcports, list) {
-   if (fcport->d_id.b24 == ea->id.b24) {
-   ql_dbg(ql_dbg_disc, vha, 0x,
-   "%s %d %8phC DS %d\n",
-   __func__, __LINE__,
-   fcport->port_name,
-   fcport->disc_state);
+   if (fcport->d_id.b24 == ea->id.b24)
fcport->scan_state = QLA_FCPORT_SCAN;
-   switch (fcport->disc_state) {
-   case DSC_DELETED:
-   case DSC_DELETE_PEND:
-   break;
-   default:
-   ql_dbg(ql_dbg_disc, vha, 0x,
-   "%s %d %8phC post del sess\n",
-   __func__, __LINE__,
-   fcport->port_name);
-   qlt_schedule_sess_for_deletion(fcport);
-   break;
-   }
-   }
+
+   qlt_schedule_sess_for_deletion(fcport);
}
} else {
/* cable is connected */
@@ -3470,32 +3454,16 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
list_for_each_entry_safe(conflict, t, >vp_fcports,
list) {
if ((conflict->d_id.b24 == ea->id.b24) &&
-   (fcport != conflict)) {
-   /* 2 fcports with conflict Nport ID or
+   (fcport != conflict))
+   /*
+* 2 fcports with conflict Nport ID or
 * an existing fcport is having nport ID
 * conflict with new fcport.
 */
 
-   ql_dbg(ql_dbg_disc, vha, 0x,
-   "%s %d %8phC DS %d\n",
-   __func__, __LINE__,
-   conflict->port_name,
-   conflict->disc_state);
conflict->scan_state = QLA_FCPORT_SCAN;
-   switch (conflict->disc_state) {
-   case DSC_DELETED:
-   case DSC_DELETE_PEND:
-   break;
-   default:
-   ql_dbg(ql_dbg_disc, vha, 0x,
-   "%s %d %8phC post del 
sess\n",
-   __func__, __LINE__,
-   conflict->port_name);
-   qlt_schedule_sess_for_deletion
-   (conflict);
-   break;
-   }
-   }
+
+   qlt_schedule_sess_for_deletion(conflict);
}
 
fcport->rscn_gen++;
@@ -3548,19 +3516,7 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
conflict->disc_state);
 
conflict->scan_state = QLA_FCPORT_SCAN;
-   switch (conflict->disc_state) {
-   case DSC_DELETED:
-   case DSC_DELETE_PEND:
-   break;
-   default:
-   ql_dbg(ql_dbg_disc, vha, 0x,
-

[PATCH 10/14] qla2xxx: Remove all rports if fabric scan retry fails

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

When all fabric scan retries fail, remove all RPorts, DMA resources
for the command otherwise we have stale Rports.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_gs.c | 128 +-
 1 file changed, 64 insertions(+), 64 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
index 1cb27eb46731..85cbe59b4f58 100644
--- a/drivers/scsi/qla2xxx/qla_gs.c
+++ b/drivers/scsi/qla2xxx/qla_gs.c
@@ -3995,6 +3995,41 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, 
srb_t *sp)
}
 }
 
+static int qla2x00_post_gnnft_gpnft_done_work(struct scsi_qla_host *vha,
+srb_t *sp, int cmd)
+{
+   struct qla_work_evt *e;
+
+   if (cmd != QLA_EVT_GPNFT_DONE && cmd != QLA_EVT_GNNFT_DONE)
+   return QLA_PARAMETER_ERROR;
+
+   e = qla2x00_alloc_work(vha, cmd);
+   if (!e)
+   return QLA_FUNCTION_FAILED;
+
+   e->u.iosb.sp = sp;
+
+   return qla2x00_post_work(vha, e);
+}
+
+static int qla2x00_post_nvme_gpnft_done_work(struct scsi_qla_host *vha,
+srb_t *sp, int cmd)
+{
+   struct qla_work_evt *e;
+
+   if (cmd != QLA_EVT_GPNFT)
+   return QLA_PARAMETER_ERROR;
+
+   e = qla2x00_alloc_work(vha, cmd);
+   if (!e)
+   return QLA_FUNCTION_FAILED;
+
+   e->u.gpnft.fc4_type = FC4_TYPE_NVME;
+   e->u.gpnft.sp = sp;
+
+   return qla2x00_post_work(vha, e);
+}
+
 static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
struct srb *sp)
 {
@@ -4095,22 +4130,36 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, 
int res)
 {
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
-   struct qla_work_evt *e;
struct ct_sns_req *ct_req =
(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
u16 cmd = be16_to_cpu(ct_req->command);
u8 fc4_type = sp->gen2;
unsigned long flags;
+   int rc;
 
/* gen2 field is holding the fc4type */
ql_dbg(ql_dbg_disc, vha, 0x,
"Async done-%s res %x FC4Type %x\n",
sp->name, res, sp->gen2);
 
+   sp->rc = res;
if (res) {
unsigned long flags;
+   const char *name = sp->name;
+
+   /*
+* We are in an Interrupt context, queue up this
+* sp for GNNFT_DONE work. This will allow all
+* the resource to get freed up.
+*/
+   rc = qla2x00_post_gnnft_gpnft_done_work(vha, sp,
+   QLA_EVT_GNNFT_DONE);
+   if (rc) {
+   /* Cleanup here to prevent memory leak */
+   qla24xx_sp_unmap(vha, sp);
+   sp->free(sp);
+   }
 
-   sp->free(sp);
spin_lock_irqsave(>work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
vha->scan.scan_retry++;
@@ -4121,9 +4170,9 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, 
int res)
set_bit(LOOP_RESYNC_NEEDED, >dpc_flags);
qla2xxx_wake_dpc(vha);
} else {
-   ql_dbg(ql_dbg_disc, sp->vha, 0x,
-   "Async done-%s rescan failed on all retries\n",
-   sp->name);
+   ql_dbg(ql_dbg_disc, vha, 0x,
+   "Async done-%s rescan failed on all retries.\n",
+   name);
}
return;
}
@@ -4138,80 +4187,31 @@ static void qla2x00_async_gpnft_gnnft_sp_done(void *s, 
int res)
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(>work_lock, flags);
 
-   e = qla2x00_alloc_work(vha, QLA_EVT_GPNFT);
-   if (!e) {
-   /*
-* please ignore kernel warning. Otherwise,
-* we have mem leak.
-*/
-   if (sp->u.iocb_cmd.u.ctarg.req) {
-   dma_free_coherent(>hw->pdev->dev,
-   sp->u.iocb_cmd.u.ctarg.req_allocated_size,
-   sp->u.iocb_cmd.u.ctarg.req,
-   sp->u.iocb_cmd.u.ctarg.req_dma);
-   sp->u.iocb_cmd.u.ctarg.req = NULL;
-   }
-   if (sp->u.iocb_cmd.u.ctarg.rsp) {
-   dma_free_coherent(>hw->pdev->dev,
-   sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
-   sp->u.iocb_cmd.u.ctarg.rsp,
-   sp->u.iocb_cmd.u.ctarg.rsp_dma);
-   sp->u.iocb_cmd.u.ctarg.rsp = NULL;
-   }
-
-   

[PATCH 14/14] qla2xxx: Update driver to version 10.00.00.09-k

2018-08-30 Thread Himanshu Madhani
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_version.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/qla2xxx/qla_version.h 
b/drivers/scsi/qla2xxx/qla_version.h
index 3850b28518e5..0dbba38c408f 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
 /*
  * Driver version
  */
-#define QLA2XXX_VERSION  "10.00.00.08-k"
+#define QLA2XXX_VERSION  "10.00.00.09-k"
 
 #define QLA_DRIVER_MAJOR_VER   10
 #define QLA_DRIVER_MINOR_VER   0
-- 
2.12.0



[PATCH 12/14] qla2xxx: Defer chip reset until target mode is enabled

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

For target mode, any chip reset is triggered before target mode
is enabled will be hold off until user is ready to enable.  This
prevents the chip from starting or running before it is intended.

Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_os.c | 28 +---
 1 file changed, 21 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 1ae31a119a37..9628fe4a967f 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -6047,12 +6047,27 @@ qla2x00_do_dpc(void *data)
if (test_and_clear_bit
(ISP_ABORT_NEEDED, _vha->dpc_flags) &&
!test_bit(UNLOADING, _vha->dpc_flags)) {
+   bool do_reset = true;
+
+   switch (ql2x_ini_mode) {
+   case QLA2XXX_INI_MODE_ENABLED:
+   break;
+   case QLA2XXX_INI_MODE_DISABLED:
+   if (!qla_tgt_mode_enabled(base_vha))
+   do_reset = false;
+   break;
+   case QLA2XXX_INI_MODE_DUAL:
+   if (!qla_dual_mode_enabled(base_vha))
+   do_reset = false;
+   break;
+   default:
+   break;
+   }
 
-   ql_dbg(ql_dbg_dpc, base_vha, 0x4007,
-   "ISP abort scheduled.\n");
-   if (!(test_and_set_bit(ABORT_ISP_ACTIVE,
+   if (do_reset && !(test_and_set_bit(ABORT_ISP_ACTIVE,
_vha->dpc_flags))) {
-
+   ql_dbg(ql_dbg_dpc, base_vha, 0x4007,
+   "ISP abort scheduled.\n");
if (ha->isp_ops->abort_isp(base_vha)) {
/* failed. retry later */
set_bit(ISP_ABORT_NEEDED,
@@ -6060,10 +6075,9 @@ qla2x00_do_dpc(void *data)
}
clear_bit(ABORT_ISP_ACTIVE,
_vha->dpc_flags);
+   ql_dbg(ql_dbg_dpc, base_vha, 0x4008,
+   "ISP abort end.\n");
}
-
-   ql_dbg(ql_dbg_dpc, base_vha, 0x4008,
-   "ISP abort end.\n");
}
 
if (test_and_clear_bit(FCPORT_UPDATE_NEEDED,
-- 
2.12.0



[PATCH 01/14] qla2xxx: Fix process response queue for ISP26XX and above

2018-08-30 Thread Himanshu Madhani
From: Quinn Tran 

This patch improves performance for 16G and above adaper by
removing additional call to process_response_queue().

Cc: 
Signed-off-by: Quinn Tran 
Signed-off-by: Himanshu Madhani 
---
 drivers/scsi/qla2xxx/qla_init.c |  2 --
 drivers/scsi/qla2xxx/qla_iocb.c | 17 -
 2 files changed, 19 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
index b934977c5c26..4686fb5f26aa 100644
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -7142,7 +7142,6 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
}
icb->firmware_options_2 &= cpu_to_le32(
~(BIT_3 | BIT_2 | BIT_1 | BIT_0));
-   vha->flags.process_response_queue = 0;
if (ha->zio_mode != QLA_ZIO_DISABLED) {
ha->zio_mode = QLA_ZIO_MODE_6;
 
@@ -7153,7 +7152,6 @@ qla24xx_nvram_config(scsi_qla_host_t *vha)
icb->firmware_options_2 |= cpu_to_le32(
(uint32_t)ha->zio_mode);
icb->interrupt_delay_timer = cpu_to_le16(ha->zio_timer);
-   vha->flags.process_response_queue = 1;
}
 
if (rval) {
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
index 42ac8e097419..119927220299 100644
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -1526,12 +1526,6 @@ qla24xx_start_scsi(srb_t *sp)
 
/* Set chip new ring index. */
WRT_REG_DWORD(req->req_q_in, req->ring_index);
-   RD_REG_DWORD_RELAXED(>iobase->isp24.hccr);
-
-   /* Manage unprocessed RIO/ZIO commands in response queue. */
-   if (vha->flags.process_response_queue &&
-   rsp->ring_ptr->signature != RESPONSE_PROCESSED)
-   qla24xx_process_response_queue(vha, rsp);
 
spin_unlock_irqrestore(>hardware_lock, flags);
return QLA_SUCCESS;
@@ -1725,12 +1719,6 @@ qla24xx_dif_start_scsi(srb_t *sp)
 
/* Set chip new ring index. */
WRT_REG_DWORD(req->req_q_in, req->ring_index);
-   RD_REG_DWORD_RELAXED(>iobase->isp24.hccr);
-
-   /* Manage unprocessed RIO/ZIO commands in response queue. */
-   if (vha->flags.process_response_queue &&
-   rsp->ring_ptr->signature != RESPONSE_PROCESSED)
-   qla24xx_process_response_queue(vha, rsp);
 
spin_unlock_irqrestore(>hardware_lock, flags);
 
@@ -1880,11 +1868,6 @@ qla2xxx_start_scsi_mq(srb_t *sp)
/* Set chip new ring index. */
WRT_REG_DWORD(req->req_q_in, req->ring_index);
 
-   /* Manage unprocessed RIO/ZIO commands in response queue. */
-   if (vha->flags.process_response_queue &&
-   rsp->ring_ptr->signature != RESPONSE_PROCESSED)
-   qla24xx_process_response_queue(vha, rsp);
-
spin_unlock_irqrestore(>qp_lock, flags);
return QLA_SUCCESS;
 
-- 
2.12.0



[PATCH 00/14] qla2xxx: Driver updates for scsi-misc

2018-08-30 Thread Himanshu Madhani
Hi Martin, 

This series updates driver for ABTS handling and rport management. 

Please queue this patches to 4.20/scsi-misc at your earliest convenience.

Thanks,
Himanshu

Himanshu Madhani (2):
  qla2xxx: Fix incorrect port speed being set for FC adapters
  qla2xxx: Update driver to version 10.00.00.09-k

Quinn Tran (12):
  qla2xxx: Fix process response queue for ISP26XX and above
  qla2xxx: Use correct qpair for ABTS/CMD
  qla2xxx: Update rscn_rcvd field to more meaningful scan_needed
  qla2xxx: Remove redundant check for fcport deletion
  qla2xxx: Move rport registration out of internal work_list
  qla2xxx: Decrement login retry count for only plogi
  qla2xxx: Turn off IOCB timeout timer on IOCB completion
  qla2xxx: Force fw cleanup on ADISC error
  qla2xxx: Remove all rports if fabric scan retry fails
  qla2xxx: Fix iIDMA error
  qla2xxx: Defer chip reset until target mode is enabled
  qla2xxx: Terminate Plogi/PRLI if WWN is 0

 drivers/scsi/qla2xxx/qla_def.h |   8 +-
 drivers/scsi/qla2xxx/qla_gbl.h |   5 +-
 drivers/scsi/qla2xxx/qla_gs.c  | 212 +++--
 drivers/scsi/qla2xxx/qla_init.c| 106 +--
 drivers/scsi/qla2xxx/qla_iocb.c|  29 ++---
 drivers/scsi/qla2xxx/qla_mbx.c |   5 +-
 drivers/scsi/qla2xxx/qla_os.c  |  54 +++---
 drivers/scsi/qla2xxx/qla_target.c  |  89 +---
 drivers/scsi/qla2xxx/qla_version.h |   2 +-
 9 files changed, 283 insertions(+), 227 deletions(-)

-- 
2.12.0



[Bug 199435] HPSA + P420i resetting logical Direct-Access never complete

2018-08-30 Thread bugzilla-daemon
https://bugzilla.kernel.org/show_bug.cgi?id=199435

goldyfruit (gaetan.tre...@incloudus.com) changed:

   What|Removed |Added

 CC||gaetan.tre...@incloudus.com

--- Comment #24 from goldyfruit (gaetan.tre...@incloudus.com) ---
Same behavior here with controllers P440ar and P420i on DL480 G8 and DL480p G8.

Firmware:
  - P440ar: 6.60
  - P420i: 8.32

[128958.979859] hpsa :03:00.0: scsi 0:1:0:9: resetting logical 
Direct-Access HP   LOGICAL VOLUME   RAID-0 SSDSmartPathCap- En- Exp=1
[129170.663840] INFO: task scsi_eh_0:446 blocked for more than 120 seconds.
[129170.671251]   Not tainted 4.15.0-33-generic #36~16.04.1-Ubuntu
[129170.678176] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
this message.
[129170.686930] scsi_eh_0   D0   446  2 0x8000
[129170.686934] Call Trace:
[129170.686945]  __schedule+0x3d6/0x8b0
[129170.686947]  schedule+0x36/0x80
[129170.686950]  schedule_timeout+0x1db/0x370
[129170.686954]  ? __dev_printk+0x3c/0x80
[129170.686956]  ? dev_printk+0x56/0x80
[129170.686959]  io_schedule_timeout+0x1e/0x50
[129170.686961]  wait_for_completion_io+0xb4/0x140
[129170.686965]  ? wake_up_q+0x70/0x70
[129170.686972]  hpsa_scsi_do_simple_cmd.isra.56+0xc7/0xf0 [hpsa]
[129170.686975]  hpsa_eh_device_reset_handler+0x3bb/0x790 [hpsa]
[129170.686978]  ? sched_clock_cpu+0x11/0xb0
[129170.686983]  ? scsi_device_put+0x2b/0x30
[129170.686987]  scsi_eh_ready_devs+0x368/0xc10
[129170.686993]  ? __pm_runtime_resume+0x5b/0x80
[129170.686995]  scsi_error_handler+0x4c3/0x5c0
[129170.687000]  kthread+0x105/0x140
[129170.687003]  ? scsi_eh_get_sense+0x240/0x240
[129170.687005]  ? kthread_destroy_worker+0x50/0x50
[129170.687012]  ? do_syscall_64+0x73/0x130
[129170.687015]  ? SyS_exit_group+0x14/0x20
[129170.687017]  ret_from_fork+0x35/0x40
[129170.687021] INFO: task jbd2/sda1-8:636 blocked for more than 120 seconds.
[129170.694649]   Not tainted 4.15.0-33-generic #36~16.04.1-Ubuntu
[129170.701598] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
this message.
[129170.710343] jbd2/sda1-8 D0   636  2 0x8000
[129170.710346] Call Trace:
[129170.710349]  __schedule+0x3d6/0x8b0
[129170.710351]  ? bit_wait+0x60/0x60
[129170.710352]  schedule+0x36/0x80
[129170.710354]  io_schedule+0x16/0x40
[129170.710359]  bit_wait_io+0x11/0x60
[129170.710362]  __wait_on_bit+0x63/0x90
[129170.710367]  out_of_line_wait_on_bit+0x8e/0xb0
[129170.710373]  ? bit_waitqueue+0x40/0x40
[129170.710377]  __wait_on_buffer+0x32/0x40
[129170.710381]  jbd2_journal_commit_transaction+0xdf6/0x1760
[129170.710387]  kjournald2+0xc8/0x250
[129170.710392]  ? kjournald2+0xc8/0x250
[129170.710395]  ? wait_woken+0x80/0x80
[129170.710398]  kthread+0x105/0x140
[129170.710399]  ? commit_timeout+0x20/0x20
[129170.710402]  ? kthread_destroy_worker+0x50/0x50
[129170.710404]  ? do_syscall_64+0x73/0x130
[129170.710407]  ? SyS_exit_group+0x14/0x20
[129170.710412]  ret_from_fork+0x35/0x40
[129170.710423] INFO: task rs:main Q:Reg:2907 blocked for more than 120
seconds.
[129170.718358]   Not tainted 4.15.0-33-generic #36~16.04.1-Ubuntu
[129170.725305] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables
this message.
[129170.734076] rs:main Q:Reg   D0  2907  1 0x
[129170.734079] Call Trace:
[129170.734082]  __schedule+0x3d6/0x8b0
[129170.734086]  ? bit_waitqueue+0x40/0x40
[129170.734087]  ? bit_wait+0x60/0x60
[129170.734089]  schedule+0x36/0x80
[129170.734091]  io_schedule+0x16/0x40
[129170.734092]  bit_wait_io+0x11/0x60
[129170.734094]  __wait_on_bit+0x63/0x90
[129170.734096]  out_of_line_wait_on_bit+0x8e/0xb0
[129170.734098]  ? bit_waitqueue+0x40/0x40
[129170.734100]  do_get_write_access+0x202/0x410
[129170.734102]  jbd2_journal_get_write_access+0x51/0x70
[129170.734107]  __ext4_journal_get_write_access+0x3b/0x80
[129170.734111]  ext4_reserve_inode_write+0x95/0xc0
[129170.734115]  ? ext4_dirty_inode+0x48/0x70
[129170.734117]  ext4_mark_inode_dirty+0x53/0x1d0
[129170.734119]  ? __ext4_journal_start_sb+0x6d/0x120
[129170.734121]  ext4_dirty_inode+0x48/0x70
[129170.734125]  __mark_inode_dirty+0x184/0x3b0
[129170.734129]  generic_update_time+0x7b/0xd0
[129170.734132]  ? current_time+0x32/0x70
[129170.734134]  file_update_time+0xbe/0x110
[129170.734140]  __generic_file_write_iter+0x9d/0x1f0
[129170.734142]  ext4_file_write_iter+0xc4/0x3f0
[129170.734147]  ? futex_wake+0x90/0x170
[129170.734151]  new_sync_write+0xe5/0x140
[129170.734155]  __vfs_write+0x29/0x40
[129170.734156]  vfs_write+0xb8/0x1b0
[129170.734158]  SyS_write+0x55/0xc0
[129170.734160]  do_syscall_64+0x73/0x130
[129170.734163]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
[129170.734165] RIP: 0033:0x7feefa9394bd
[129170.734166] RSP: 002b:7feef7ce8600 EFLAGS: 0293 ORIG_RAX:
0001
[129170.734168] RAX: ffda RBX: 7feeec00d120 RCX:

Re: [PATCH v2] target/iblock: split T10 PI SGL across command bios

2018-08-30 Thread Greg Edwards
On Wed, Aug 29, 2018 at 06:23:52PM -0500, Mike Christie wrote:
>
> Can you still hit the issue where t_prot_nents > BIO_MAX_PAGES so
> bio_integrity_alloc fails or is t_prot_nents always going to be smaller.
> Was wondering why you dropped that from the last patch.

There was a vhost bug that was artificially inflating the size of the
PI SGL by including both the protection and data in the PI SGL [1].  In
testing with that patch applied, I haven't seen the PI SGL get anywhere
close to BIO_MAX_PAGES.  That said, you're right, we should probably
retain that safety check.  I'll add it back for a v3.  Thanks for the
feedback.

Greg

  [1] 
https://lists.linuxfoundation.org/pipermail/virtualization/2018-August/039106.html


Re: [PATCH] libfc: remove unnecessary condition check

2018-08-30 Thread Martin K. Petersen


Chengguang,

> kmem_cache_destroy() can handle NULL pointer correctly, so there is
> no need to check NULL pointer before calling kmem_cache_destroy()

Applied to 4.20/scsi-queue, thank you.

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: lpfc: remove an unnecessary NULL check

2018-08-30 Thread Martin K. Petersen


Dan,

> Smatch complains about this code:
>
> drivers/scsi/lpfc/lpfc_scsi.c:1053 lpfc_get_scsi_buf_s4()
> warn: variable dereferenced before check 'lpfc_cmd' (see line 1039)
>
> Fortunately the NULL check isn't required so I have removed it.

Applied to 4.20/scsi-queue, thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] scsi: 53c700: Fix spelling of 'NEGOTIATION'

2018-08-30 Thread Martin K. Petersen


Faisal,

> 'NEGOTIATION' was misspelled as 'NEGOTATION'. Fixed it. It is a coding
> style change which should have no impact on runtime execution of code.

Applied to 4.20/scsi-queue, thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH] qedi: Add the CRC size within iSCSI NVM image

2018-08-30 Thread Martin K. Petersen


Nilesh,

> The QED driver commit, 1ac4329 qed: Add configuration information to
> register dump and debug data, removes the CRC length validation
> causing nvm_get_image failure while loading qedi driver,
>
> [qed_mcp_get_nvm_image:2700(host_10-0)]Image [0] is too big - 6008
> bytes where only 6004 are available [qedi_get_boot_info:2253]:10:
> Could not get NVM image. ret = -12
>
> Hence add and adjust the CRC size to iSCSI NVM image to read boot info
> at qedi load time.

Applied to 4.19/scsi-fixes, thank you!

-- 
Martin K. Petersen  Oracle Linux Engineering


Re: [PATCH 0/2] iscsi target: login fixes

2018-08-30 Thread Martin K. Petersen


Mike,

> The following patches are login fixes from the list. The set has been
> rebased against Linus's current tree so they apply over the idr/ida
> patches that have been merged.

Applied to 4.19/scsi-fixes, thanks!

-- 
Martin K. Petersen  Oracle Linux Engineering


[PATCH V12 1/2] scsi: ufs: set the device reference clock setting

2018-08-30 Thread Sayali Lokhande
From: Subhash Jadavani 

UFS host supplies the reference clock to UFS device and UFS device
specification allows host to provide one of the 4 frequencies (19.2 MHz,
26 MHz, 38.4 MHz, 52 MHz) for reference clock. Host should set the
device reference clock frequency setting in the device based on what
frequency it is supplying to UFS device.

Signed-off-by: Subhash Jadavani 
Signed-off-by: Can Guo 
Signed-off-by: Sayali Lokhande 
---
 drivers/scsi/ufs/ufs.h   | 14 +++
 drivers/scsi/ufs/ufshcd-pltfrm.c |  2 +
 drivers/scsi/ufs/ufshcd.c| 90 
 drivers/scsi/ufs/ufshcd.h|  2 +
 4 files changed, 108 insertions(+)

diff --git a/drivers/scsi/ufs/ufs.h b/drivers/scsi/ufs/ufs.h
index 14e5bf7..a2e76b1 100644
--- a/drivers/scsi/ufs/ufs.h
+++ b/drivers/scsi/ufs/ufs.h
@@ -378,6 +378,20 @@ enum query_opcode {
UPIU_QUERY_OPCODE_TOGGLE_FLAG   = 0x8,
 };
 
+/* bRefClkFreq attribute values */
+enum ufs_ref_clk_freq {
+   REF_CLK_FREQ_19_2_MHZ   = 0,
+   REF_CLK_FREQ_26_MHZ = 1,
+   REF_CLK_FREQ_38_4_MHZ   = 2,
+   REF_CLK_FREQ_52_MHZ = 3,
+   REF_CLK_FREQ_INVAL  = -1,
+};
+
+struct ufs_ref_clk {
+   u32 freq_hz;
+   enum ufs_ref_clk_freq val;
+};
+
 /* Query response result code */
 enum {
QUERY_RESULT_SUCCESS= 0x00,
diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
index e82bde0..0953563 100644
--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
@@ -343,6 +343,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
pm_runtime_set_active(>dev);
pm_runtime_enable(>dev);
 
+   ufshcd_parse_dev_ref_clk_freq(hba);
+
ufshcd_init_lanes_per_dir(hba);
 
err = ufshcd_init(hba, mmio_base, irq);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c5b1bf1..e01cdc0 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -6296,6 +6296,89 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
hba->desc_size.hlth_desc = QUERY_DESC_HEALTH_DEF_SIZE;
 }
 
+static struct ufs_ref_clk ufs_ref_clk_freqs[] = {
+   {1920, REF_CLK_FREQ_19_2_MHZ},
+   {2600, REF_CLK_FREQ_26_MHZ},
+   {3840, REF_CLK_FREQ_38_4_MHZ},
+   {5200, REF_CLK_FREQ_52_MHZ},
+   {0, REF_CLK_FREQ_INVAL},
+};
+
+static inline enum ufs_ref_clk_freq
+ufs_get_bref_clk_from_hz(u32 freq)
+{
+   int i = 0;
+
+   while (ufs_ref_clk_freqs[i].freq_hz != freq) {
+   if (!ufs_ref_clk_freqs[i].freq_hz)
+   return REF_CLK_FREQ_INVAL;
+   i++;
+   }
+
+   return ufs_ref_clk_freqs[i].val;
+}
+
+void ufshcd_parse_dev_ref_clk_freq(struct ufs_hba *hba)
+{
+   struct device *dev = hba->dev;
+   struct device_node *np = dev->of_node;
+   struct clk *refclk = NULL;
+   u32 freq = 0;
+
+   if (!np)
+   return;
+
+   refclk = of_clk_get_by_name(np, "ref_clk");
+   if (!refclk)
+   return;
+
+   freq = clk_get_rate(refclk);
+
+   hba->dev_ref_clk_freq =
+   ufs_get_bref_clk_from_hz(freq);
+
+   if (hba->dev_ref_clk_freq == REF_CLK_FREQ_INVAL)
+   dev_err(hba->dev,
+   "%s: invalid ref_clk setting = %d\n",
+   __func__, freq);
+}
+
+static int ufshcd_set_dev_ref_clk(struct ufs_hba *hba)
+{
+   int err, ref_clk = -1;
+   u32 freq = hba->dev_ref_clk_freq;
+
+   err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
+   QUERY_ATTR_IDN_REF_CLK_FREQ, 0, 0, _clk);
+
+   if (err) {
+   dev_err(hba->dev, "%s: failed reading bRefClkFreq. err = %d\n",
+__func__, err);
+   goto out;
+   }
+
+   if (ref_clk == hba->dev_ref_clk_freq)
+   goto out; /* nothing to update */
+
+   err = ufshcd_query_attr_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
+   QUERY_ATTR_IDN_REF_CLK_FREQ, 0, 0, );
+
+   if (err) {
+   dev_err(hba->dev, "%s: bRefClkFreq setting to %u Hz failed\n",
+   __func__, ufs_ref_clk_freqs[freq].freq_hz);
+   goto out;
+   }
+   /*
+* It is good to print this out here to debug any later failures
+* related to gear switch.
+*/
+   dev_dbg(hba->dev, "%s: bRefClkFreq setting to %u Hz succeeded\n",
+   __func__, ufs_ref_clk_freqs[freq].freq_hz);
+
+out:
+   return err;
+}
+
 /**
  * ufshcd_probe_hba - probe hba to detect device and initialize
  * @hba: per-adapter instance
@@ -6361,6 +6444,12 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
"%s: Failed getting max supported power mode\n",
__func__);
} else {
+   /*
+* Set the right value to bRefClkFreq before attempting to
+* switch to HS gears.
+ 

[PATCH V12 0/2] Add UFS provisioning support in driver

2018-08-30 Thread Sayali Lokhande


This patch adds Configfs support to provision UFS device at
runtime. This feature can be primarily useful in factory or
assembly line as some devices may be required to be configured
multiple times during initial system development phase.
Configuration Descriptors can be written multiple times until
bConfigDescrLock attribute is zero.

Configuration descriptor buffer consists of Device and Unit
descriptor configurable parameters which are parsed from vendor
specific provisioning file and then passed via configfs node at
runtime to provision ufs device.

Changes since V11:
1)scsi: ufs: set the device reference clock setting
No update.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Minor fixes related to missing kfree(), return statement
and indentation.

Changes since V10:
1)scsi: ufs: set the device reference clock setting
No update.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Added support for all config descriptors (namely with
index 0,1,2,3). Updated config descriptor length to reflect
actual length of each descriptor instead of hard coded macro.
Updated documentation as per new added fields (for each config
descriptor). Added support for multiple ufs hba's.

Changes since V9:
1)scsi: ufs: set the device reference clock setting
Minor fixes related to naming format, if check conditions.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Minor fixes related to naming format, function return type.

Changes since V8:
1)scsi: ufs: set the device reference clock setting
Updated one common enum for both ref_clk_freq in Hz and bref_attr
and used same in parsing api. Moved call to parse api to
ufshcd_alloc_host() instead of calling from pltfrm_init(), so that
it can be called via other paths(which dont use pltfrm_init) and
hba->dev_ref_clk can get intialized to either valid/invalid value.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Updated error returns and removed few unnecessary sanity check as
per comments.

Changes since V7:
1)scsi: ufs: set the device reference clock setting
Updated return statements and condition checks as per comments.
Added struct ufs_ref_clk_freqs which holds both bref_clk_attr val
and respective ref clk frequency in Hz and used same while parsing
ref_clk.

2)scsi: ufs: Add configfs support for UFS provisioning
Updated return statements and conditional check as per comments.

Changes since V6:
1)scsi: ufs: set the device reference clock setting
Re-introduced this patch to provisioning patch set(as per comments
from Evan). Used of_clk_get_by_name() and clk_get_rate() to set
ref_clk frequency instead of passing freq via DT.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Updated error handling in case if kstrtoint fails while parsing
input configuration buffer.

Changes since V5:
1)scsi: ufs: set the device reference clock setting
Removed this patch from provisioning patch set(as its not required
to be set as dependent changes).
This will be uploaded as a separate patch later.
 
2)scsi: ufs: Add configfs support for UFS provisioning
Removed few extra debug prints. Updated permission of ufs_provision
attribute from 0666 to 0644. Pass UFS device name as part of
ufshcd_configfs_init() to support multiple UFS controller for
embedded and removable UFS card.

Changes since V4:
1)scsi: ufs: set the device reference clock setting
Used "assigned-clock-rates" DT property to pass required ref clk
frequency.

2)scsi: ufs: Add configfs support for ufs provisioning
Combined previous patch(2) and patch(3) into single patch which
adds configfs provisioning support in driver.
Removed extra sw provisioning related fields (like lun_to_grow,
commit) and its related code.
Updated Documentation to match configuration descriptor buffer
parameters to be passed as per specs. Removed global ufs_hba ptr
added in ufs-configfs file and instead passed *hba in ufs configfs
init()/store()/show() api's. This is to support embedded as well as
removable ufs card provisioning via configfs.

Changes since V3:
1)scsi: ufs: set the device reference clock setting
  Updated logic to retain default ref_clk frequency setting
  programmed in device in case if invalid value is passed via
  devicetree setting.
  Replaced of_property_read_u32() with device_property_read_u32().
  Removed invalid checks.

2)scsi: ufs: Add ufs provisioning support
  Added 

[PATCH V12 2/2] scsi: ufs: Add configfs support for UFS provisioning

2018-08-30 Thread Sayali Lokhande
This patch adds configfs support to provision UFS device at
runtime. This feature can be primarily useful in factory or
assembly line as some devices may be required to be configured
multiple times during initial system development phase.
Configuration Descriptors can be written multiple times until
bConfigDescrLock attribute is zero.

Configuration descriptor buffer consists of Device and Unit
descriptor configurable parameters which are parsed from vendor
specific provisioning file and then passed via configfs node at
runtime to provision ufs device.
CONFIG_CONFIGFS_FS and CONFIG_UFS_PROVISION needs to be enabled
for using this feature.

Usage:
1) To read current configuration descriptor with index X
   (where index X can be 0/1/2/3) :
   cat /config/.ufshc/ufs_config_desc_X

2) To write configuration descriptor with index X :
   echo  > /config/.ufshc/ufs_config_desc_X

Signed-off-by: Sayali Lokhande 
---
 Documentation/ABI/testing/configfs-driver-ufs |  12 ++
 drivers/scsi/ufs/Kconfig  |  10 ++
 drivers/scsi/ufs/Makefile |   1 +
 drivers/scsi/ufs/ufs-configfs.c   | 232 ++
 drivers/scsi/ufs/ufshcd.c |   3 +-
 drivers/scsi/ufs/ufshcd.h |  17 ++
 6 files changed, 274 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ABI/testing/configfs-driver-ufs
 create mode 100644 drivers/scsi/ufs/ufs-configfs.c

diff --git a/Documentation/ABI/testing/configfs-driver-ufs 
b/Documentation/ABI/testing/configfs-driver-ufs
new file mode 100644
index 000..4302d57
--- /dev/null
+++ b/Documentation/ABI/testing/configfs-driver-ufs
@@ -0,0 +1,12 @@
+What:  /config/*/ufs_config_desc_X
+Date:  Jun 2018
+KernelVersion: 4.19
+Description:
+   This file shows bytes of the current ufs configuration 
descriptor
+   with index X (where X = 0/1/2/3) set in device. This can be 
used to
+   provision ufs device if bConfigDescrLock is 0.
+   For more details, refer 14.1.6.3 Configuration Descriptor and
+   table 14-12 - Unit Descriptor configurable parameters from 
specs for
+   description and format of each configuration descriptor 
parameter.
+   Parameters of Configuration descriptor buffer for respective 
index
+   needs to be passed as bytes in space separated format.
diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
index e27b4d4..a9a0a58 100644
--- a/drivers/scsi/ufs/Kconfig
+++ b/drivers/scsi/ufs/Kconfig
@@ -100,3 +100,13 @@ config SCSI_UFS_QCOM
 
  Select this if you have UFS controller on QCOM chipset.
  If unsure, say N.
+
+config UFS_PROVISION
+   tristate "Runtime UFS Provisioning support"
+   depends on SCSI_UFSHCD && CONFIGFS_FS
+   help
+ This enables runtime UFS provisioning support. This can be used
+ primarily during assembly line as some devices may be required to
+ be configured multiple times during initial development phase.
+
+ If unsure, say N.
diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
index 918f579..00110ea 100644
--- a/drivers/scsi/ufs/Makefile
+++ b/drivers/scsi/ufs/Makefile
@@ -5,5 +5,6 @@ obj-$(CONFIG_SCSI_UFS_DWC_TC_PLATFORM) += tc-dwc-g210-pltfrm.o 
ufshcd-dwc.o tc-d
 obj-$(CONFIG_SCSI_UFS_QCOM) += ufs-qcom.o
 obj-$(CONFIG_SCSI_UFSHCD) += ufshcd-core.o
 ufshcd-core-objs := ufshcd.o ufs-sysfs.o
+obj-$(CONFIG_UFS_PROVISION) += ufs-configfs.o
 obj-$(CONFIG_SCSI_UFSHCD_PCI) += ufshcd-pci.o
 obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
diff --git a/drivers/scsi/ufs/ufs-configfs.c b/drivers/scsi/ufs/ufs-configfs.c
new file mode 100644
index 000..a2c09c7
--- /dev/null
+++ b/drivers/scsi/ufs/ufs-configfs.c
@@ -0,0 +1,232 @@
+// SPDX-License-Identifier: GPL-2.0+
+// Copyright (c) 2018, Linux Foundation.
+
+#include 
+#include 
+#include 
+
+#include "ufs.h"
+#include "ufshcd.h"
+
+static inline struct ufs_hba *config_item_to_hba(struct config_item *item)
+{
+   struct config_group *group = to_config_group(item);
+   struct configfs_subsystem *subsys = to_configfs_subsystem(group);
+   struct ufs_hba *hba = container_of(subsys, struct ufs_hba, subsys);
+
+   return hba;
+}
+
+static ssize_t ufs_config_desc_show(struct config_item *item, char *buf,
+   u8 index)
+{
+   struct ufs_hba *hba = config_item_to_hba(item);
+   u8 *desc_buf = NULL;
+   int desc_buf_len = hba->desc_size.conf_desc;
+   int i, ret, curr_len = 0;
+
+   desc_buf = kzalloc(desc_buf_len, GFP_KERNEL);
+   if (!desc_buf)
+   return -ENOMEM;
+
+   ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC,
+   QUERY_DESC_IDN_CONFIGURATION, index, 0,
+   desc_buf, _buf_len);
+   if (ret)
+   goto out;
+
+   for (i = 0; i < desc_buf_len; i++)
+   curr_len += 

[PATCH] qedi: Add the CRC size within iSCSI NVM image

2018-08-30 Thread Nilesh Javali
The QED driver commit,
1ac4329 qed: Add configuration information to register dump and debug data,
removes the CRC length validation causing nvm_get_image failure while
loading qedi driver,

[qed_mcp_get_nvm_image:2700(host_10-0)]Image [0] is too big - 6008 bytes
where only 6004 are available
[qedi_get_boot_info:2253]:10: Could not get NVM image. ret = -12

Hence add and adjust the CRC size to iSCSI NVM image to read boot info at
qedi load time.

Signed-off-by: Nilesh Javali 
---
 drivers/scsi/qedi/qedi.h  |  7 ++-
 drivers/scsi/qedi/qedi_main.c | 28 +++-
 2 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h
index fc3babc..a6f96b3 100644
--- a/drivers/scsi/qedi/qedi.h
+++ b/drivers/scsi/qedi/qedi.h
@@ -77,6 +77,11 @@ enum qedi_nvm_tgts {
QEDI_NVM_TGT_SEC,
 };
 
+struct qedi_nvm_iscsi_image {
+   struct nvm_iscsi_cfg iscsi_cfg;
+   u32 crc;
+};
+
 struct qedi_uio_ctrl {
/* meta data */
u32 uio_hsi_version;
@@ -294,7 +299,7 @@ struct qedi_ctx {
void *bdq_pbl_list;
dma_addr_t bdq_pbl_list_dma;
u8 bdq_pbl_list_num_entries;
-   struct nvm_iscsi_cfg *iscsi_cfg;
+   struct qedi_nvm_iscsi_image *iscsi_image;
dma_addr_t nvm_buf_dma;
void __iomem *bdq_primary_prod;
void __iomem *bdq_secondary_prod;
diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c
index aa96bcc..cc8e64d 100644
--- a/drivers/scsi/qedi/qedi_main.c
+++ b/drivers/scsi/qedi/qedi_main.c
@@ -1346,23 +1346,26 @@ static int qedi_setup_int(struct qedi_ctx *qedi)
 
 static void qedi_free_nvm_iscsi_cfg(struct qedi_ctx *qedi)
 {
-   if (qedi->iscsi_cfg)
+   if (qedi->iscsi_image)
dma_free_coherent(>pdev->dev,
- sizeof(struct nvm_iscsi_cfg),
- qedi->iscsi_cfg, qedi->nvm_buf_dma);
+ sizeof(struct qedi_nvm_iscsi_image),
+ qedi->iscsi_image, qedi->nvm_buf_dma);
 }
 
 static int qedi_alloc_nvm_iscsi_cfg(struct qedi_ctx *qedi)
 {
-   qedi->iscsi_cfg = dma_zalloc_coherent(>pdev->dev,
-sizeof(struct nvm_iscsi_cfg),
->nvm_buf_dma, GFP_KERNEL);
-   if (!qedi->iscsi_cfg) {
+   struct qedi_nvm_iscsi_image nvm_image;
+
+   qedi->iscsi_image = dma_zalloc_coherent(>pdev->dev,
+   sizeof(nvm_image),
+   >nvm_buf_dma,
+   GFP_KERNEL);
+   if (!qedi->iscsi_image) {
QEDI_ERR(>dbg_ctx, "Could not allocate NVM BUF.\n");
return -ENOMEM;
}
QEDI_INFO(>dbg_ctx, QEDI_LOG_INFO,
- "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_cfg,
+ "NVM BUF addr=0x%p dma=0x%llx.\n", qedi->iscsi_image,
  qedi->nvm_buf_dma);
 
return 0;
@@ -1905,7 +1908,7 @@ void qedi_reset_host_mtu(struct qedi_ctx *qedi, u16 mtu)
struct nvm_iscsi_block *block;
 
pf = qedi->dev_info.common.abs_pf_id;
-   block = >iscsi_cfg->block[0];
+   block = >iscsi_image->iscsi_cfg.block[0];
for (i = 0; i < NUM_OF_ISCSI_PF_SUPPORTED; i++, block++) {
flags = ((block->id) & NVM_ISCSI_CFG_BLK_CTRL_FLAG_MASK) >>
NVM_ISCSI_CFG_BLK_CTRL_FLAG_OFFSET;
@@ -2194,15 +2197,14 @@ static void qedi_boot_release(void *data)
 static int qedi_get_boot_info(struct qedi_ctx *qedi)
 {
int ret = 1;
-   u16 len;
-
-   len = sizeof(struct nvm_iscsi_cfg);
+   struct qedi_nvm_iscsi_image nvm_image;
 
QEDI_INFO(>dbg_ctx, QEDI_LOG_INFO,
  "Get NVM iSCSI CFG image\n");
ret = qedi_ops->common->nvm_get_image(qedi->cdev,
  QED_NVM_IMAGE_ISCSI_CFG,
- (char *)qedi->iscsi_cfg, len);
+ (char *)qedi->iscsi_image,
+ sizeof(nvm_image));
if (ret)
QEDI_ERR(>dbg_ctx,
 "Could not get NVM image. ret = %d\n", ret);
-- 
1.8.3.1