All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/47] SCSI EH argument reshuffle part II
@ 2017-06-28  8:32 Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 01/47] aacraid: split off functions to generate reset FIB Hannes Reinecke
                   ` (48 more replies)
  0 siblings, 49 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

Hi all,
finally here's the patchset to revamp the SCSI EH callback arguments
which I promised to do (some years ago ...).

The overall idea is to match the scope of the eh_XXX callbacks with
the appropriate argument, eg eh_device_reset_handler() should have a
scsi device as argument etc.
Relying on the scsi command has the problem that
a) we're holding a reference on that command for the entire lifetime
of the error handling and
b) it leads to some 'interesting' driver implementations; some
higher-level EH callback implementations go through the list of
outstanding commands and try to abort this particular command only;
makes one wonder what'll happen to the other commands ...

However, this patchset has the nice side-effect that we don't need to
allocate an out-of-order scsi command in scsi_ioctl_reset(), but can
call the function directly.

As per request from hch the patchset has been split in two parts;
this is the second part which rearranges the individual EH handler
implementation to not rely on the passed in scsi command and do
the final conversion to the new calling convention.

The entire patchset can be found at

https://git.kernel.org/hare/scsi-devel/h/eh-reset.v3

As usual, comments and reviews are welcome.

Hannes Reinecke (47):
  aacraid: split off functions to generate reset FIB
  aacraid: split off host reset
  aacraid: split off device, target, and bus reset
  aacraid: use aac_tmf_callback for reset fib
  aacraid: enable sending of TMFs from aac_hba_send()
  aacraid: add fib flag to mark scsi command callback
  aacraid: complete all commands during bus reset
  sym53c8xx_2: split off bus reset from host reset
  zfcp: open-code fc_block_scsi_eh() for host reset
  ips: Do not try to abort command from host reset
  snic: reserve tag for TMF
  qla1280: separate out host reset function from qla1280_error_action()
  megaraid: pass in NULL scb for host reset
  scsi: Use Scsi_Host as argument for eh_host_reset_handler
  scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh
  mptfc: simplify mpt_fc_block_error_handler()
  mptfusion: correct definitions for mptscsih_dev_reset()
  mptfc: open-code mptfc_block_error_handler() for bus reset
  pmcraid: Select device in pmcraid_eh_bus_reset_handler()
  scsi: Use Scsi_Host and channel number as argument for
    eh_bus_reset_handler()
  libiscsi: use cls_session as argument for target and session reset
  bnx2fc: Do not rely on a scsi command when issueing lun or target
    reset
  zfcp: do not rely on scsi command for debugging message
  zfcp: use scsi device as argument for zfcp_task_mgmt_function()
  ibmvfc: open-code reset loop for target reset
  lpfc: use rport as argument for lpfc_send_taskmgmt()
  lpfc: use rport as argument for lpfc_chk_tgt_mapped()
  qla2xxx: open-code qla2xxx_generic_reset()
  qedf: use fc rport as argument for qedf_initiate_tmf()
  sym53c8xx_2: rework reset handling
  bfa: Do not use scsi command to signal TMF status
  scsi: Use scsi_target as argument for eh_target_reset_handler()
  cxlflash: use dedicated reset command in send_tmf()
  aha152x: look for stuck command when resetting device
  fnic: use dedicated device reset command
  a1000u2w: do not rely on the command for inia100_device_reset()
  aic79xx: use scsi device as argument for BUILD_SCSIID()
  aic7xxx: use scsi device as argument for BUILD_SCSIID()
  aic79xx: do not reference scsi command when resetting device
  aic7xxx: do not reference scsi command when resetting device
  xen-scsifront: add scsi device as argument to scsifront_do_request()
  xen-scsifront: call scsifront_action_handler() with a NULL command
    argument
  fas216: Rework device reset to not rely on SCSI command pointer
  csiostor: use separate TMF command
  snic: use dedicated device reset command
  scsi: Move eh_device_reset_handler() to use scsi_device as argument
  scsi: Do not allocate scsi command in scsi_ioctl_reset()

 Documentation/scsi/scsi_eh.txt                  |   6 +-
 Documentation/scsi/scsi_mid_low_api.txt         |  13 +-
 arch/ia64/hp/sim/simscsi.c                      |   2 +-
 drivers/block/cciss_scsi.c                      |  14 +-
 drivers/infiniband/ulp/srp/ib_srp.c             |  14 +-
 drivers/message/fusion/mptfc.c                  |  99 +++++---
 drivers/message/fusion/mptsas.c                 |  10 +-
 drivers/message/fusion/mptscsih.c               | 117 ++++++---
 drivers/message/fusion/mptscsih.h               |   7 +-
 drivers/message/fusion/mptspi.c                 |   8 +-
 drivers/s390/scsi/zfcp_dbf.c                    |  28 +--
 drivers/s390/scsi/zfcp_dbf.h                    |  10 +-
 drivers/s390/scsi/zfcp_ext.h                    |   6 +-
 drivers/s390/scsi/zfcp_fc.h                     |   9 +-
 drivers/s390/scsi/zfcp_fsf.c                    |  21 +-
 drivers/s390/scsi/zfcp_scsi.c                   |  73 ++++--
 drivers/scsi/3w-9xxx.c                          |  11 +-
 drivers/scsi/3w-sas.c                           |  11 +-
 drivers/scsi/3w-xxxx.c                          |  11 +-
 drivers/scsi/53c700.c                           |  39 +--
 drivers/scsi/BusLogic.c                         |  14 +-
 drivers/scsi/NCR5380.c                          |   5 +-
 drivers/scsi/NCR53c406a.c                       |   6 +-
 drivers/scsi/a100u2w.c                          |  52 ++--
 drivers/scsi/aacraid/aacraid.h                  |   1 +
 drivers/scsi/aacraid/commsup.c                  |   3 +-
 drivers/scsi/aacraid/linit.c                    | 318 +++++++++++++++++-------
 drivers/scsi/advansys.c                         |  26 +-
 drivers/scsi/aha152x.c                          |  39 ++-
 drivers/scsi/aha152x.h                          |   2 +-
 drivers/scsi/aha1542.c                          |  27 +-
 drivers/scsi/aic7xxx/aic79xx_osm.c              |  64 ++---
 drivers/scsi/aic7xxx/aic7xxx_osm.c              | 120 ++++-----
 drivers/scsi/arcmsr/arcmsr_hba.c                |   9 +-
 drivers/scsi/arm/fas216.c                       |  67 +++--
 drivers/scsi/arm/fas216.h                       |  11 +-
 drivers/scsi/atari_scsi.c                       |   4 +-
 drivers/scsi/be2iscsi/be_main.c                 |  18 +-
 drivers/scsi/bfa/bfad_im.c                      | 113 +++++----
 drivers/scsi/bfa/bfad_im.h                      |   2 +
 drivers/scsi/bnx2fc/bnx2fc.h                    |   5 +-
 drivers/scsi/bnx2fc/bnx2fc_hwi.c                |  14 +-
 drivers/scsi/bnx2fc/bnx2fc_io.c                 |  97 ++++----
 drivers/scsi/csiostor/csio_hw.h                 |   2 +
 drivers/scsi/csiostor/csio_init.c               |   2 +-
 drivers/scsi/csiostor/csio_scsi.c               |  53 ++--
 drivers/scsi/cxlflash/common.h                  |   3 +-
 drivers/scsi/cxlflash/main.c                    |  51 ++--
 drivers/scsi/dc395x.c                           |  25 +-
 drivers/scsi/dpt_i2o.c                          |  43 ++--
 drivers/scsi/dpti.h                             |   6 +-
 drivers/scsi/eata.c                             |  10 +-
 drivers/scsi/eata_pio.c                         |  29 ++-
 drivers/scsi/esas2r/esas2r.h                    |   8 +-
 drivers/scsi/esas2r/esas2r_main.c               |  55 ++--
 drivers/scsi/esp_scsi.c                         |   8 +-
 drivers/scsi/fdomain.c                          |   2 +-
 drivers/scsi/fdomain.h                          |   2 +-
 drivers/scsi/fnic/fnic.h                        |   4 +-
 drivers/scsi/fnic/fnic_main.c                   |   2 +
 drivers/scsi/fnic/fnic_scsi.c                   | 117 ++++-----
 drivers/scsi/gdth.c                             |  16 +-
 drivers/scsi/hpsa.c                             |  14 +-
 drivers/scsi/hptiop.c                           |   6 +-
 drivers/scsi/ibmvscsi/ibmvfc.c                  |  58 +++--
 drivers/scsi/ibmvscsi/ibmvscsi.c                |  23 +-
 drivers/scsi/imm.c                              |   6 +-
 drivers/scsi/initio.c                           |  11 +-
 drivers/scsi/ipr.c                              |  35 +--
 drivers/scsi/ips.c                              |  40 +--
 drivers/scsi/libfc/fc_fcp.c                     |  18 +-
 drivers/scsi/libiscsi.c                         |  38 ++-
 drivers/scsi/libsas/sas_scsi_host.c             |  21 +-
 drivers/scsi/lpfc/lpfc_scsi.c                   |  67 +++--
 drivers/scsi/mac53c94.c                         |   8 +-
 drivers/scsi/megaraid.c                         |  46 ++--
 drivers/scsi/megaraid.h                         |   2 +-
 drivers/scsi/megaraid/megaraid_mbox.c           |  14 +-
 drivers/scsi/megaraid/megaraid_sas.h            |   3 +-
 drivers/scsi/megaraid/megaraid_sas_base.c       |  38 ++-
 drivers/scsi/megaraid/megaraid_sas_fusion.c     |  47 ++--
 drivers/scsi/mesh.c                             |  10 +-
 drivers/scsi/mpt3sas/mpt3sas_scsih.c            |  77 +++---
 drivers/scsi/mvumi.c                            |   7 +-
 drivers/scsi/ncr53c8xx.c                        |   4 +-
 drivers/scsi/nsp32.c                            |  12 +-
 drivers/scsi/pcmcia/aha152x_stub.c              |   2 +-
 drivers/scsi/pcmcia/nsp_cs.c                    |  10 +-
 drivers/scsi/pcmcia/qlogic_stub.c               |   4 +-
 drivers/scsi/pcmcia/sym53c500_cs.c              |   8 +-
 drivers/scsi/pmcraid.c                          |  75 ++++--
 drivers/scsi/ppa.c                              |   6 +-
 drivers/scsi/qedf/qedf.h                        |   5 +-
 drivers/scsi/qedf/qedf_io.c                     |  48 ++--
 drivers/scsi/qedf/qedf_main.c                   |  16 +-
 drivers/scsi/qedi/qedi_iscsi.c                  |   3 +-
 drivers/scsi/qla1280.c                          |  72 +++---
 drivers/scsi/qla2xxx/qla_os.c                   | 167 +++++++------
 drivers/scsi/qla4xxx/ql4_os.c                   |  85 ++++---
 drivers/scsi/qlogicfas408.c                     |  10 +-
 drivers/scsi/qlogicfas408.h                     |   2 +-
 drivers/scsi/scsi_debug.c                       |  86 +++----
 drivers/scsi/scsi_error.c                       | 160 ++++++------
 drivers/scsi/scsi_transport_fc.c                |   7 +-
 drivers/scsi/scsi_transport_iscsi.c             |   6 +-
 drivers/scsi/smartpqi/smartpqi_init.c           |   6 +-
 drivers/scsi/snic/snic.h                        |   6 +-
 drivers/scsi/snic/snic_main.c                   |   3 +
 drivers/scsi/snic/snic_scsi.c                   | 126 ++++------
 drivers/scsi/stex.c                             |   7 +-
 drivers/scsi/storvsc_drv.c                      |   4 +-
 drivers/scsi/sym53c416.c                        |  16 +-
 drivers/scsi/sym53c8xx_2/sym_glue.c             | 190 ++++++++------
 drivers/scsi/ufs/ufshcd.c                       |  24 +-
 drivers/scsi/virtio_scsi.c                      |  14 +-
 drivers/scsi/vmw_pvscsi.c                       |  20 +-
 drivers/scsi/wd33c93.c                          |   4 +-
 drivers/scsi/wd33c93.h                          |   2 +-
 drivers/scsi/wd719x.c                           |  17 +-
 drivers/scsi/xen-scsifront.c                    |  54 ++--
 drivers/staging/rts5208/rtsx.c                  |   4 +-
 drivers/staging/unisys/visorhba/visorhba_main.c |  42 ++--
 drivers/target/loopback/tcm_loop.c              |  17 +-
 drivers/usb/image/microtek.c                    |   4 +-
 drivers/usb/storage/scsiglue.c                  |   8 +-
 drivers/usb/storage/uas.c                       |   3 +-
 include/scsi/libfc.h                            |   4 +-
 include/scsi/libiscsi.h                         |   6 +-
 include/scsi/libsas.h                           |   4 +-
 include/scsi/scsi_host.h                        |   8 +-
 include/scsi/scsi_transport_fc.h                |   2 +-
 include/scsi/scsi_transport_iscsi.h             |   2 +-
 132 files changed, 2093 insertions(+), 1845 deletions(-)

-- 
1.8.5.6

^ permalink raw reply	[flat|nested] 89+ messages in thread

* [PATCH 01/47] aacraid: split off functions to generate reset FIB
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:07   ` Johannes Thumshirn
  2017-06-29 19:59   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 02/47] aacraid: split off host reset Hannes Reinecke
                   ` (47 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Split off reset FIB generation into separate functions.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/linit.c | 83 ++++++++++++++++++++++++++------------------
 1 file changed, 50 insertions(+), 33 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 0f277df..9a8a27f 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -814,6 +814,52 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
 	return ret;
 }
 
+static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
+				   int bus, int cid, u64 tmf_lun)
+{
+	struct aac_hba_tm_req *tmf;
+	u64 address;
+
+	/* start a HBA_TMF_LUN_RESET TMF request */
+	tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
+	memset(tmf, 0, sizeof(*tmf));
+	tmf->tmf = HBA_TMF_LUN_RESET;
+	tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+	int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
+
+	address = (u64)fib->hw_error_pa;
+	tmf->error_ptr_hi = cpu_to_le32
+		((u32)(address >> 32));
+	tmf->error_ptr_lo = cpu_to_le32
+		((u32)(address & 0xffffffff));
+	tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+	fib->hbacmd_size = sizeof(*tmf);
+
+	return HBA_IU_TYPE_SCSI_TM_REQ;
+}
+
+static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
+				    int bus, int cid)
+{
+	struct aac_hba_reset_req *rst;
+	u64 address;
+
+	/* already tried, start a hard reset now */
+	rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
+	memset(rst, 0, sizeof(*rst));
+	/* reset_type is already zero... */
+	rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+
+	address = (u64)fib->hw_error_pa;
+	rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
+	rst->error_ptr_lo = cpu_to_le32
+		((u32)(address & 0xffffffff));
+	rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
+	fib->hbacmd_size = sizeof(*rst);
+
+       return HBA_IU_TYPE_SATA_REQ;
+}
+
 /*
  *	aac_eh_reset	- Reset command handling
  *	@scsi_cmd:	SCSI command block causing the reset
@@ -840,7 +886,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 		aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
 		struct fib *fib;
 		int status;
-		u64 address;
 		u8 command;
 
 		pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -852,42 +897,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 
 
 		if (aac->hba_map[bus][cid].reset_state == 0) {
-			struct aac_hba_tm_req *tmf;
-
 			/* start a HBA_TMF_LUN_RESET TMF request */
-			tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
-			memset(tmf, 0, sizeof(*tmf));
-			tmf->tmf = HBA_TMF_LUN_RESET;
-			tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
-			tmf->lun[1] = cmd->device->lun;
-
-			address = (u64)fib->hw_error_pa;
-			tmf->error_ptr_hi = cpu_to_le32
-					((u32)(address >> 32));
-			tmf->error_ptr_lo = cpu_to_le32
-					((u32)(address & 0xffffffff));
-			tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
-			fib->hbacmd_size = sizeof(*tmf);
-
-			command = HBA_IU_TYPE_SCSI_TM_REQ;
+			command = aac_eh_tmf_lun_reset_fib(aac, fib,
+							   bus, cid,
+							   cmd->device->lun);
 			aac->hba_map[bus][cid].reset_state++;
 		} else if (aac->hba_map[bus][cid].reset_state >= 1) {
-			struct aac_hba_reset_req *rst;
-
 			/* already tried, start a hard reset now */
-			rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
-			memset(rst, 0, sizeof(*rst));
-			/* reset_type is already zero... */
-			rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
-
-			address = (u64)fib->hw_error_pa;
-			rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
-			rst->error_ptr_lo = cpu_to_le32
-				((u32)(address & 0xffffffff));
-			rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
-			fib->hbacmd_size = sizeof(*rst);
-
-			command = HBA_IU_TYPE_SATA_REQ;
+			command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
 			aac->hba_map[bus][cid].reset_state = 0;
 		}
 		cmd->SCp.sent_command = 0;
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 02/47] aacraid: split off host reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 01/47] aacraid: split off functions to generate reset FIB Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:10   ` Johannes Thumshirn
  2017-06-29 20:00   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 03/47] aacraid: split off device, target, and bus reset Hannes Reinecke
                   ` (46 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Split off the host reset parts of aac_eh_reset() into a separate
host reset function.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/linit.c | 33 ++++++++++++++++++++++-----------
 1 file changed, 22 insertions(+), 11 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9a8a27f..bf21006 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -874,10 +874,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 	u32 bus, cid;
 	int ret = FAILED;
 	int status = 0;
-	__le32 supported_options2 = 0;
-	bool is_mu_reset;
-	bool is_ignore_reset;
-	bool is_doorbell_reset;
 
 
 	bus = aac_logical_to_phys(scmd_channel(cmd));
@@ -923,7 +919,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 		}
 
 		if (ret == SUCCESS)
-			goto out;
+			return ret;
 
 	} else {
 
@@ -952,8 +948,24 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 		dev_err(&aac->pdev->dev, "Adapter health - %d\n", status);
 
 	count = get_num_of_incomplete_fibs(aac);
-	if (count == 0)
-		return SUCCESS;
+	return (count == 0) ? SUCCESS : FAILED;
+}
+
+/*
+ *	aac_eh_host_reset	- Host reset command handling
+ *	@scsi_cmd:	SCSI command block causing the reset
+ *
+ */
+int aac_eh_host_reset(struct scsi_cmnd *cmd)
+{
+	struct scsi_device * dev = cmd->device;
+	struct Scsi_Host * host = dev->host;
+	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+	int ret = FAILED;
+	__le32 supported_options2 = 0;
+	bool is_mu_reset;
+	bool is_ignore_reset;
+	bool is_doorbell_reset;
 
 	/*
 	 * Check if reset is supported by the firmware
@@ -972,10 +984,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
 	 && (aac_check_reset != -1 || !is_ignore_reset)) {
 		/* Bypass wait for command quiesce */
 		aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
+		ret = SUCCESS;
 	}
-	ret = SUCCESS;
-
-out:
 	return ret;
 }
 
@@ -1399,7 +1409,8 @@ ssize_t aac_get_serial_number(struct device *device, char *buf)
 	.change_queue_depth		= aac_change_queue_depth,
 	.sdev_attrs			= aac_dev_attrs,
 	.eh_abort_handler		= aac_eh_abort,
-	.eh_host_reset_handler		= aac_eh_reset,
+	.eh_bus_reset_handler		= aac_eh_reset,
+	.eh_host_reset_handler		= aac_eh_host_reset,
 	.can_queue			= AAC_NUM_IO_FIB,
 	.this_id			= MAXIMUM_NUM_CONTAINERS,
 	.sg_tablesize			= 16,
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 03/47] aacraid: split off device, target, and bus reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 01/47] aacraid: split off functions to generate reset FIB Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 02/47] aacraid: split off host reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:14   ` Johannes Thumshirn
  2017-06-29 20:01   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
                   ` (45 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Split off device, target, and bus reset functionality into
individual functions.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/linit.c | 141 +++++++++++++++++++++++++++++++------------
 1 file changed, 102 insertions(+), 39 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index bf21006..57b2077 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -861,68 +861,129 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
 }
 
 /*
- *	aac_eh_reset	- Reset command handling
+ *	aac_eh_dev_reset	- Device reset command handling
  *	@scsi_cmd:	SCSI command block causing the reset
  *
  */
-static int aac_eh_reset(struct scsi_cmnd* cmd)
+static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
 {
 	struct scsi_device * dev = cmd->device;
 	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
 	int count;
 	u32 bus, cid;
+	struct fib *fib;
 	int ret = FAILED;
-	int status = 0;
-
+	int status;
+	u8 command;
 
 	bus = aac_logical_to_phys(scmd_channel(cmd));
 	cid = scmd_id(cmd);
-	if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&
-		aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
-		struct fib *fib;
-		int status;
-		u8 command;
+	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+	    aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+		return FAILED;
 
-		pr_err("%s: Host adapter reset request. SCSI hang ?\n",
-			AAC_DRIVERNAME);
+	pr_err("%s: Host adapter reset request. SCSI hang ?\n",
+	       AAC_DRIVERNAME);
 
-		fib = aac_fib_alloc(aac);
-		if (!fib)
-			return ret;
+	fib = aac_fib_alloc(aac);
+	if (!fib)
+		return ret;
 
 
-		if (aac->hba_map[bus][cid].reset_state == 0) {
-			/* start a HBA_TMF_LUN_RESET TMF request */
-			command = aac_eh_tmf_lun_reset_fib(aac, fib,
-							   bus, cid,
-							   cmd->device->lun);
-			aac->hba_map[bus][cid].reset_state++;
-		} else if (aac->hba_map[bus][cid].reset_state >= 1) {
-			/* already tried, start a hard reset now */
-			command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
-			aac->hba_map[bus][cid].reset_state = 0;
+	/* start a HBA_TMF_LUN_RESET TMF request */
+	command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
+					   cmd->device->lun);
+
+	cmd->SCp.sent_command = 0;
+
+	status = aac_hba_send(command, fib,
+			      (fib_callback) aac_hba_callback,
+			      (void *) cmd);
+
+	/* Wait up to 15 seconds for completion */
+	for (count = 0; count < 15; ++count) {
+		if (cmd->SCp.sent_command) {
+			ret = SUCCESS;
+			break;
 		}
-		cmd->SCp.sent_command = 0;
+		msleep(1000);
+	}
 
-		status = aac_hba_send(command, fib,
-				  (fib_callback) aac_hba_callback,
-				  (void *) cmd);
+	return ret;
+}
 
-		/* Wait up to 15 seconds for completion */
-		for (count = 0; count < 15; ++count) {
-			if (cmd->SCp.sent_command) {
-				ret = SUCCESS;
-				break;
-			}
-			msleep(1000);
+/*
+ *	aac_eh_target_reset	- Target reset command handling
+ *	@scsi_cmd:	SCSI command block causing the reset
+ *
+ */
+static int aac_eh_target_reset(struct scsi_cmnd *cmd)
+{
+	struct scsi_device * dev = cmd->device;
+	struct Scsi_Host * host = dev->host;
+	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+	int count;
+	u32 bus, cid;
+	int ret = FAILED;
+	struct fib *fib;
+	int status;
+	u8 command;
+
+	bus = aac_logical_to_phys(scmd_channel(cmd));
+	cid = scmd_id(cmd);
+	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+	    aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+		return FAILED;
+
+	pr_err("%s: Host adapter reset request. SCSI hang ?\n",
+	       AAC_DRIVERNAME);
+
+	fib = aac_fib_alloc(aac);
+	if (!fib)
+		return ret;
+
+
+	/* already tried, start a hard reset now */
+	command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
+
+	cmd->SCp.sent_command = 0;
+
+	status = aac_hba_send(command, fib,
+			      (fib_callback) aac_hba_callback,
+			      (void *) cmd);
+
+	/* Wait up to 15 seconds for completion */
+	for (count = 0; count < 15; ++count) {
+		if (cmd->SCp.sent_command) {
+			ret = SUCCESS;
+			break;
 		}
+		msleep(1000);
+	}
 
-		if (ret == SUCCESS)
-			return ret;
+	return ret;
+}
+
+/*
+ *	aac_eh_bus_reset	- Bus reset command handling
+ *	@scsi_cmd:	SCSI command block causing the reset
+ *
+ */
+static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
+{
+	struct scsi_device * dev = cmd->device;
+	struct Scsi_Host * host = dev->host;
+	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+	int count;
+	u32 bus, cid;
+	int status = 0;
 
-	} else {
 
+	bus = aac_logical_to_phys(scmd_channel(cmd));
+	cid = scmd_id(cmd);
+	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+	    aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) {
 		/* Mark the assoc. FIB to not complete, eh handler does this */
 		for (count = 0;
 			count < (host->can_queue + AAC_NUM_MGT_FIB);
@@ -1409,7 +1470,9 @@ ssize_t aac_get_serial_number(struct device *device, char *buf)
 	.change_queue_depth		= aac_change_queue_depth,
 	.sdev_attrs			= aac_dev_attrs,
 	.eh_abort_handler		= aac_eh_abort,
-	.eh_bus_reset_handler		= aac_eh_reset,
+	.eh_device_reset_handler	= aac_eh_dev_reset,
+	.eh_target_reset_handler	= aac_eh_target_reset,
+	.eh_bus_reset_handler		= aac_eh_bus_reset,
 	.eh_host_reset_handler		= aac_eh_host_reset,
 	.can_queue			= AAC_NUM_IO_FIB,
 	.this_id			= MAXIMUM_NUM_CONTAINERS,
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (2 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 03/47] aacraid: split off device, target, and bus reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28 19:42   ` Dave Carroll
  2017-06-29 20:06   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
                   ` (44 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When sending a reset fib we shouldn't rely on the scsi command,
but rather set the TMF status in the map_info->reset_state variable.
That allows us to send a TMF independent on a scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/linit.c | 96 ++++++++++++++++++++++++++++++++------------
 1 file changed, 71 insertions(+), 25 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 57b2077..9b284a0 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -814,8 +814,8 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
 	return ret;
 }
 
-static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
-				   int bus, int cid, u64 tmf_lun)
+static u8 aac_eh_tmf_lun_reset_fib(struct aac_hba_map_info *info,
+				   struct fib *fib, u64 tmf_lun)
 {
 	struct aac_hba_tm_req *tmf;
 	u64 address;
@@ -824,7 +824,7 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
 	tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
 	memset(tmf, 0, sizeof(*tmf));
 	tmf->tmf = HBA_TMF_LUN_RESET;
-	tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+	tmf->it_nexus = info->rmw_nexus;
 	int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
 
 	address = (u64)fib->hw_error_pa;
@@ -838,8 +838,8 @@ static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
 	return HBA_IU_TYPE_SCSI_TM_REQ;
 }
 
-static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
-				    int bus, int cid)
+static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
+				    struct fib *fib)
 {
 	struct aac_hba_reset_req *rst;
 	u64 address;
@@ -847,8 +847,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
 	/* already tried, start a hard reset now */
 	rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
 	memset(rst, 0, sizeof(*rst));
-	/* reset_type is already zero... */
-	rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
+	rst->it_nexus = info->rmw_nexus;
 
 	address = (u64)fib->hw_error_pa;
 	rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
@@ -860,6 +859,33 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
        return HBA_IU_TYPE_SATA_REQ;
 }
 
+void aac_tmf_callback(void *context, struct fib *fibptr)
+{
+	struct aac_hba_resp *err =
+		&((struct aac_native_hba *)fibptr->hw_fib_va)->resp.err;
+	struct aac_hba_map_info *info = context;
+	int res;
+
+	switch (err->service_response) {
+	case HBA_RESP_SVCRES_TMF_REJECTED:
+		res = -1;
+		break;
+	case HBA_RESP_SVCRES_TMF_LUN_INVALID:
+		res = 0;
+		break;
+	case HBA_RESP_SVCRES_TMF_COMPLETE:
+	case HBA_RESP_SVCRES_TMF_SUCCEEDED:
+		res = 0;
+		break;
+	default:
+		res = -2;
+		break;
+	}
+	aac_fib_complete(fibptr);
+
+	info->reset_state = res;
+}
+
 /*
  *	aac_eh_dev_reset	- Device reset command handling
  *	@scsi_cmd:	SCSI command block causing the reset
@@ -870,6 +896,7 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
 	struct scsi_device * dev = cmd->device;
 	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+	struct aac_hba_map_info *info;
 	int count;
 	u32 bus, cid;
 	struct fib *fib;
@@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
 
 	bus = aac_logical_to_phys(scmd_channel(cmd));
 	cid = scmd_id(cmd);
+	info = &aac->hba_map[bus][cid];
 	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
-	    aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+	    info->devtype != AAC_DEVTYPE_NATIVE_RAW)
+		return FAILED;
+
+	if (info->reset_state > 0)
 		return FAILED;
 
 	pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -890,21 +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
 	if (!fib)
 		return ret;
 
-
 	/* start a HBA_TMF_LUN_RESET TMF request */
-	command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
-					   cmd->device->lun);
+	command = aac_eh_tmf_lun_reset_fib(info, fib, dev->lun);
 
-	cmd->SCp.sent_command = 0;
+	info->reset_state = 1;
 
 	status = aac_hba_send(command, fib,
-			      (fib_callback) aac_hba_callback,
-			      (void *) cmd);
+			      (fib_callback) aac_tmf_callback,
+			      (void *) info);
 
 	/* Wait up to 15 seconds for completion */
 	for (count = 0; count < 15; ++count) {
-		if (cmd->SCp.sent_command) {
-			ret = SUCCESS;
+		if (info->reset_state == 0) {
+			ret = info->reset_state == 0 ? SUCCESS : FAILED;
 			break;
 		}
 		msleep(1000);
@@ -923,6 +952,7 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
 	struct scsi_device * dev = cmd->device;
 	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
+	struct aac_hba_map_info *info;
 	int count;
 	u32 bus, cid;
 	int ret = FAILED;
@@ -932,8 +962,9 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
 
 	bus = aac_logical_to_phys(scmd_channel(cmd));
 	cid = scmd_id(cmd);
+	info = &aac->hba_map[bus][cid];
 	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
-	    aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
+	    info->devtype != AAC_DEVTYPE_NATIVE_RAW)
 		return FAILED;
 
 	pr_err("%s: Host adapter reset request. SCSI hang ?\n",
@@ -945,18 +976,18 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
 
 
 	/* already tried, start a hard reset now */
-	command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
+	command = aac_eh_tmf_hard_reset_fib(info, fib);
 
-	cmd->SCp.sent_command = 0;
+	info->reset_state = 2;
 
 	status = aac_hba_send(command, fib,
-			      (fib_callback) aac_hba_callback,
-			      (void *) cmd);
+			      (fib_callback) aac_tmf_callback,
+			      (void *) info);
 
 	/* Wait up to 15 seconds for completion */
 	for (count = 0; count < 15; ++count) {
-		if (cmd->SCp.sent_command) {
-			ret = SUCCESS;
+		if (info->reset_state <= 0) {
+			ret = info->reset_state == 0 ? SUCCESS : FAILED;
 			break;
 		}
 		msleep(1000);
@@ -1044,8 +1075,23 @@ int aac_eh_host_reset(struct scsi_cmnd *cmd)
 	 && aac_check_reset
 	 && (aac_check_reset != -1 || !is_ignore_reset)) {
 		/* Bypass wait for command quiesce */
-		aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
-		ret = SUCCESS;
+		if (aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET) == 0)
+			ret = SUCCESS;
+	}
+	/*
+	 * Reset EH state
+	 */
+	if (ret == SUCCESS) {
+		int bus, cid;
+		struct aac_hba_map_info *info;
+
+		for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
+			for (cid = 0; cid < AAC_MAX_TARGETS; cid++) {
+				info = &aac->hba_map[bus][cid];
+				if (info->devtype == AAC_DEVTYPE_NATIVE_RAW)
+					info->reset_state = 0;
+			}
+		}
 	}
 	return ret;
 }
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (3 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:17   ` Johannes Thumshirn
  2017-06-29 20:07   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 06/47] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
                   ` (43 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

aac_hba_send() will return FAILED for any non-SCSI command requests,
failing any TMFs. This patch updates the check to allow TMFs.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/commsup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 1c617cc..348f0ea 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -770,7 +770,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
 		/* bit1 of request_id must be 0 */
 		hbacmd->request_id =
 			cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
-	} else
+	} else if (command != HBA_IU_TYPE_SCSI_TM_REQ)
 		return -EINVAL;
 
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 06/47] aacraid: add fib flag to mark scsi command callback
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (4 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:18   ` Johannes Thumshirn
  2017-06-29 20:07   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 07/47] aacraid: complete all commands during bus reset Hannes Reinecke
                   ` (42 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

To correctly identify which fib has a scsi command callback this
patch implements a flag FIB_CONTEXT_FLAG_SCSI_CMD.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/aacraid.h | 1 +
 drivers/scsi/aacraid/commsup.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
index d31a9bc..6981299 100644
--- a/drivers/scsi/aacraid/aacraid.h
+++ b/drivers/scsi/aacraid/aacraid.h
@@ -1723,6 +1723,7 @@ struct aac_dev
 #define FIB_CONTEXT_FLAG_FASTRESP		(0x00000008)
 #define FIB_CONTEXT_FLAG_NATIVE_HBA		(0x00000010)
 #define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF	(0x00000020)
+#define FIB_CONTEXT_FLAG_SCSI_CMD	(0x00000040)
 
 /*
  *	Define the command values
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index 348f0ea..dfe8e70 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -770,6 +770,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
 		/* bit1 of request_id must be 0 */
 		hbacmd->request_id =
 			cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
+		fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD;
 	} else if (command != HBA_IU_TYPE_SCSI_TM_REQ)
 		return -EINVAL;
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 07/47] aacraid: complete all commands during bus reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (5 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 06/47] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:19   ` Johannes Thumshirn
  2017-06-29 20:07   ` Raghava Aditya Renukunta
  2017-06-28  8:32 ` [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset Hannes Reinecke
                   ` (41 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When issuing a bus reset we should complete all commands, not
just the command triggering the reset.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aacraid/linit.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 9b284a0..c26130e 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1007,23 +1007,29 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
 	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
 	int count;
-	u32 bus, cid;
+	u32 cmd_bus;
 	int status = 0;
 
 
-	bus = aac_logical_to_phys(scmd_channel(cmd));
-	cid = scmd_id(cmd);
-	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
-	    aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) {
-		/* Mark the assoc. FIB to not complete, eh handler does this */
-		for (count = 0;
-			count < (host->can_queue + AAC_NUM_MGT_FIB);
-			++count) {
-			struct fib *fib = &aac->fibs[count];
-
-			if (fib->hw_fib_va->header.XferState &&
-				(fib->flags & FIB_CONTEXT_FLAG) &&
-				(fib->callback_data == cmd)) {
+	cmd_bus = aac_logical_to_phys(scmd_channel(cmd));
+	/* Mark the assoc. FIB to not complete, eh handler does this */
+	for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
+		struct fib *fib = &aac->fibs[count];
+
+		if (fib->hw_fib_va->header.XferState &&
+		    (fib->flags & FIB_CONTEXT_FLAG) &&
+		    (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) {
+			struct aac_hba_map_info *info;
+			u32 bus, cid;
+
+			cmd = (struct scsi_cmnd *)fib->callback_data;
+			bus = aac_logical_to_phys(scmd_channel(cmd));
+			if (bus != cmd_bus)
+				continue;
+			cid = scmd_id(cmd);
+			info = &aac->hba_map[bus][cid];
+			if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
+			    info->devtype != AAC_DEVTYPE_NATIVE_RAW) {
 				fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
 				cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
 			}
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (6 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 07/47] aacraid: complete all commands during bus reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:19   ` Johannes Thumshirn
  2017-06-28  9:25   ` Johannes Thumshirn
  2017-06-28  8:32 ` [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for " Hannes Reinecke
                   ` (40 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The current handler does both, bus reset and host reset.
So split them off into two distinct functions.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/sym53c8xx_2/sym_glue.c | 107 ++++++++++++++++++++++--------------
 1 file changed, 66 insertions(+), 41 deletions(-)

diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index d32e3ba..5055469 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -581,8 +581,6 @@ static void sym53c8xx_timer(unsigned long npref)
  */
 #define SYM_EH_ABORT		0
 #define SYM_EH_DEVICE_RESET	1
-#define SYM_EH_BUS_RESET	2
-#define SYM_EH_HOST_RESET	3
 
 /*
  *  Generic method for our eh processing.
@@ -602,35 +600,11 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
 
 	scmd_printk(KERN_WARNING, cmd, "%s operation started\n", opname);
 
-	/* We may be in an error condition because the PCI bus
-	 * went down. In this case, we need to wait until the
-	 * PCI bus is reset, the card is reset, and only then
-	 * proceed with the scsi error recovery.  There's no
-	 * point in hurrying; take a leisurely wait.
+	/*
+	 * Escalate to host reset if the PCI bus went down
 	 */
-#define WAIT_FOR_PCI_RECOVERY	35
-	if (pci_channel_offline(pdev)) {
-		int finished_reset = 0;
-		init_completion(&eh_done);
-		spin_lock_irq(shost->host_lock);
-		/* Make sure we didn't race */
-		if (pci_channel_offline(pdev)) {
-			BUG_ON(sym_data->io_reset);
-			sym_data->io_reset = &eh_done;
-		} else {
-			finished_reset = 1;
-		}
-		spin_unlock_irq(shost->host_lock);
-		if (!finished_reset)
-			finished_reset = wait_for_completion_timeout
-						(sym_data->io_reset,
-						WAIT_FOR_PCI_RECOVERY*HZ);
-		spin_lock_irq(shost->host_lock);
-		sym_data->io_reset = NULL;
-		spin_unlock_irq(shost->host_lock);
-		if (!finished_reset)
-			return SCSI_FAILED;
-	}
+	if (pci_channel_offline(pdev))
+		return SCSI_FAILED;
 
 	spin_lock_irq(shost->host_lock);
 	/* This one is queued in some place -> to wait for completion */
@@ -651,15 +625,6 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
 	case SYM_EH_DEVICE_RESET:
 		sts = sym_reset_scsi_target(np, cmd->device->id);
 		break;
-	case SYM_EH_BUS_RESET:
-		sym_reset_scsi_bus(np, 1);
-		sts = 0;
-		break;
-	case SYM_EH_HOST_RESET:
-		sym_reset_scsi_bus(np, 0);
-		sym_start_up(shost, 1);
-		sts = 0;
-		break;
 	default:
 		break;
 	}
@@ -701,12 +666,72 @@ static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
 
 static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_BUS_RESET, "BUS RESET", cmd);
+	struct Scsi_Host *shost = cmd->device->host;
+	struct sym_data *sym_data = shost_priv(shost);
+	struct pci_dev *pdev = sym_data->pdev;
+	struct sym_hcb *np = sym_data->ncb;
+
+	scmd_printk(KERN_WARNING, cmd, "BUS RESET operation started\n");
+
+	/*
+	 * Escalate to host reset if the PCI bus went down
+	 */
+	if (pci_channel_offline(pdev))
+		return SCSI_FAILED;
+
+	spin_lock_irq(shost->host_lock);
+	sym_reset_scsi_bus(np, 1);
+	spin_unlock_irq(shost->host_lock);
+
+	dev_warn(&cmd->device->sdev_gendev, "BUS RESET operation complete.\n");
+	return SCSI_SUCCESS;
 }
 
 static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_HOST_RESET, "HOST RESET", cmd);
+	struct Scsi_Host *shost = cmd->device->host;
+	struct sym_data *sym_data = shost_priv(shost);
+	struct pci_dev *pdev = sym_data->pdev;
+	struct sym_hcb *np = sym_data->ncb;
+	struct completion eh_done;
+	int finished_reset = 1;
+
+	shost_printk(KERN_WARNING, shost, "HOST RESET operation started\n");
+
+	/* We may be in an error condition because the PCI bus
+	 * went down. In this case, we need to wait until the
+	 * PCI bus is reset, the card is reset, and only then
+	 * proceed with the scsi error recovery.  There's no
+	 * point in hurrying; take a leisurely wait.
+	 */
+#define WAIT_FOR_PCI_RECOVERY	35
+	if (pci_channel_offline(pdev)) {
+		init_completion(&eh_done);
+		spin_lock_irq(shost->host_lock);
+		/* Make sure we didn't race */
+		if (pci_channel_offline(pdev)) {
+			BUG_ON(sym_data->io_reset);
+			sym_data->io_reset = &eh_done;
+			finished_reset = 0;
+		}
+		spin_unlock_irq(shost->host_lock);
+		if (!finished_reset)
+			finished_reset = wait_for_completion_timeout
+						(sym_data->io_reset,
+						WAIT_FOR_PCI_RECOVERY*HZ);
+		spin_lock_irq(shost->host_lock);
+		sym_data->io_reset = NULL;
+		spin_unlock_irq(shost->host_lock);
+	}
+
+	if (finished_reset) {
+		sym_reset_scsi_bus(np, 0);
+		sym_start_up(shost, 1);
+	}
+
+	shost_printk(KERN_WARNING, shost, "HOST RESET operation %s.\n",
+			finished_reset==1 ? "complete" : "failed");
+	return finished_reset ? SCSI_SUCCESS : SCSI_FAILED;
 }
 
 /*
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for host reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (7 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-07-24 16:18   ` Steffen Maier
  2017-07-24 16:24   ` Steffen Maier
  2017-06-28  8:32 ` [PATCH 10/47] ips: Do not try to abort command from " Hannes Reinecke
                   ` (39 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When issuing a host reset we should be waiting for all
ports to become unblocked; just waiting for one might
be resulting in host reset to return too early.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/s390/scsi/zfcp_scsi.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 0678cf7..3d18659 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -311,13 +311,32 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
 
 static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
 {
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
-	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
-	int ret;
+	struct Scsi_Host *host = scpnt->device->host;
+	struct zfcp_adapter *adapter = (struct zfcp_adapter *)host->hostdata[0];
+	int ret = 0;
+	unsigned long flags;
+	struct zfcp_port *port;
 
 	zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
 	zfcp_erp_wait(adapter);
-	ret = fc_block_scsi_eh(scpnt);
+retry_rport_blocked:
+	spin_lock_irqsave(host->host_lock, flags);
+	list_for_each_entry(port, &adapter->port_list, list) {
+		struct fc_rport *rport = port->rport;
+
+		if (rport->port_state == FC_PORTSTATE_BLOCKED) {
+			if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
+				ret = FAST_IO_FAIL;
+			else
+				ret = NEEDS_RETRY;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(host->host_lock, flags);
+	if (ret == NEEDS_RETRY) {
+		msleep(1000);
+		goto retry_rport_blocked;
+	}
 	if (ret)
 		return ret;
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 10/47] ips: Do not try to abort command from host reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (8 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for " Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:31   ` Johannes Thumshirn
  2017-06-28  8:32 ` [PATCH 11/47] snic: reserve tag for TMF Hannes Reinecke
                   ` (38 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The code for aborting an outstanding command is a copy of the
functionality from command abort. As we already have called this
function once we reach host reset there's no point in trying to
do so again.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/ips.c | 17 -----------------
 1 file changed, 17 deletions(-)

diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 3419e1b..97d9cca 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -865,23 +865,6 @@ static int __ips_eh_reset(struct scsi_cmnd *SC)
 	if (!ha->active)
 		return (FAILED);
 
-	/* See if the command is on the copp queue */
-	item = ha->copp_waitlist.head;
-	while ((item) && (item->scsi_cmd != SC))
-		item = item->next;
-
-	if (item) {
-		/* Found it */
-		ips_removeq_copp(&ha->copp_waitlist, item);
-		return (SUCCESS);
-	}
-
-	/* See if the command is on the wait queue */
-	if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
-		/* command not sent yet */
-		return (SUCCESS);
-	}
-
 	/* An explanation for the casual observer:                              */
 	/* Part of the function of a RAID controller is automatic error         */
 	/* detection and recovery.  As such, the only problem that physically   */
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 11/47] snic: reserve tag for TMF
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (9 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 10/47] ips: Do not try to abort command from " Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:37   ` Johannes Thumshirn
  2017-06-28  8:32 ` [PATCH 12/47] qla1280: separate out host reset function from qla1280_error_action() Hannes Reinecke
                   ` (37 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Rather than re-using the failed command the snic driver should
reserve one command for TMFs.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/snic/snic.h      |  3 ++-
 drivers/scsi/snic/snic_main.c |  3 +++
 drivers/scsi/snic/snic_scsi.c | 51 ++++++++++++++++++-------------------------
 3 files changed, 26 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h
index de0ab5f..46837ee9 100644
--- a/drivers/scsi/snic/snic.h
+++ b/drivers/scsi/snic/snic.h
@@ -310,6 +310,7 @@ struct snic {
 	struct list_head spl_cmd_list;
 
 	unsigned int max_tag_id;
+	unsigned int tmf_tag_id;
 	atomic_t ios_inflight;		/* io in flight counter */
 
 	struct vnic_snic_config config;
@@ -380,7 +381,7 @@ struct snic_global {
 int snic_abort_cmd(struct scsi_cmnd *);
 int snic_device_reset(struct scsi_cmnd *);
 int snic_host_reset(struct scsi_cmnd *);
-int snic_reset(struct Scsi_Host *, struct scsi_cmnd *);
+int snic_reset(struct Scsi_Host *);
 void snic_shutdown_scsi_cleanup(struct snic *);
 
 
diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
index 7cf70aa..0530ca1 100644
--- a/drivers/scsi/snic/snic_main.c
+++ b/drivers/scsi/snic/snic_main.c
@@ -538,6 +538,9 @@
 					 max_t(u32, SNIC_MIN_IO_REQ, max_ios));
 
 	snic->max_tag_id = shost->can_queue;
+	/* Reserve one reset command */
+	shost->can_queue--;
+	snic->tmf_tag_id = shost->can_queue;
 
 	shost->max_lun = snic->config.luns_per_tgt;
 	shost->max_id = SNIC_MAX_TARGET;
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 05c3a72..56b0eb4 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -1022,17 +1022,6 @@
 		      "reset_cmpl: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x, ctx = %lx\n",
 		      typ, hdr_stat, cmnd_id, hid, ctx);
 
-	/* spl case, host reset issued through ioctl */
-	if (cmnd_id == SCSI_NO_TAG) {
-		rqi = (struct snic_req_info *) ctx;
-		SNIC_HOST_INFO(snic->shost,
-			       "reset_cmpl:Tag %d ctx %lx cmpl stat %s\n",
-			       cmnd_id, ctx, snic_io_status_to_str(hdr_stat));
-		sc = rqi->sc;
-
-		goto ioctl_hba_rst;
-	}
-
 	if (cmnd_id >= snic->max_tag_id) {
 		SNIC_HOST_ERR(snic->shost,
 			      "reset_cmpl: Tag 0x%x out of Range,HdrStat %s\n",
@@ -1043,7 +1032,6 @@
 	}
 
 	sc = scsi_host_find_tag(snic->shost, cmnd_id);
-ioctl_hba_rst:
 	if (!sc) {
 		atomic64_inc(&snic->s_stats.io.sc_null);
 		SNIC_HOST_ERR(snic->shost,
@@ -1733,7 +1721,7 @@
 {
 	struct snic_req_info *rqi = NULL;
 	struct snic_tgt *tgt = NULL;
-	struct scsi_cmnd *sc = NULL;
+	struct scsi_cmnd *sc;
 	spinlock_t *io_lock = NULL;
 	u32 sv_state = 0, tmf = 0;
 	DECLARE_COMPLETION_ONSTACK(tm_done);
@@ -2246,13 +2234,6 @@
 		goto hba_rst_end;
 	}
 
-	if (snic_cmd_tag(sc) == SCSI_NO_TAG) {
-		memset(scsi_cmd_priv(sc), 0,
-			sizeof(struct snic_internal_io_state));
-		SNIC_HOST_INFO(snic->shost, "issu_hr:Host reset thru ioctl.\n");
-		rqi->sc = sc;
-	}
-
 	req = rqi_to_req(rqi);
 
 	io_lock = snic_io_lock_hash(snic, sc);
@@ -2327,11 +2308,13 @@
 } /* end of snic_issue_hba_reset */
 
 int
-snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc)
+snic_reset(struct Scsi_Host *shost)
 {
 	struct snic *snic = shost_priv(shost);
+	struct scsi_cmnd *sc = NULL;
 	enum snic_state sv_state;
 	unsigned long flags;
+	u32 start_time  = jiffies;
 	int ret = FAILED;
 
 	/* Set snic state as SNIC_FWRESET*/
@@ -2356,6 +2339,18 @@
 	while (atomic_read(&snic->ios_inflight))
 		schedule_timeout(msecs_to_jiffies(1));
 
+	sc = scsi_host_find_tag(shost, snic->tmf_tag_id);
+	if (!sc) {
+		SNIC_HOST_ERR(shost,
+			      "reset:Host Reset Failed to allocate sc.\n");
+		spin_lock_irqsave(&snic->snic_lock, flags);
+		snic_set_state(snic, sv_state);
+		spin_unlock_irqrestore(&snic->snic_lock, flags);
+		atomic64_inc(&snic->s_stats.reset.hba_reset_fail);
+		ret = FAILED;
+
+		goto reset_end;
+	}
 	ret = snic_issue_hba_reset(snic, sc);
 	if (ret) {
 		SNIC_HOST_ERR(shost,
@@ -2373,6 +2368,10 @@
 	ret = SUCCESS;
 
 reset_end:
+	SNIC_TRC(shost->host_no, sc ? snic_cmd_tag(sc) : SCSI_NO_TAG,
+		 (ulong) sc, jiffies_to_msecs(jiffies - start_time),
+		 0, 0, 0);
+
 	return ret;
 } /* end of snic_reset */
 
@@ -2387,21 +2386,13 @@
 snic_host_reset(struct scsi_cmnd *sc)
 {
 	struct Scsi_Host *shost = sc->device->host;
-	u32 start_time  = jiffies;
-	int ret = FAILED;
 
 	SNIC_SCSI_DBG(shost,
 		      "host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n",
 		      sc, sc->cmnd[0], sc->request,
 		      snic_cmd_tag(sc), CMD_FLAGS(sc));
 
-	ret = snic_reset(shost, sc);
-
-	SNIC_TRC(shost->host_no, snic_cmd_tag(sc), (ulong) sc,
-		 jiffies_to_msecs(jiffies - start_time),
-		 0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));
-
-	return ret;
+	return snic_reset(shost);
 } /* end of snic_host_reset */
 
 /*
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 12/47] qla1280: separate out host reset function from qla1280_error_action()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (10 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 11/47] snic: reserve tag for TMF Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:39   ` Johannes Thumshirn
  2017-06-28  8:32 ` [PATCH 13/47] megaraid: pass in NULL scb for host reset Hannes Reinecke
                   ` (36 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

There's not much in common between host reset and all other error
handlers, so use a separate function here.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/qla1280.c | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index 634254a..d712bfe 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -754,7 +754,6 @@ enum action {
 	ABORT_COMMAND,
 	DEVICE_RESET,
 	BUS_RESET,
-	ADAPTER_RESET,
 };
 
 
@@ -936,22 +935,9 @@ static void qla1280_mailbox_timeout(unsigned long __data)
 		}
 		break;
 
-	case ADAPTER_RESET:
 	default:
-		if (qla1280_verbose) {
-			printk(KERN_INFO
-			       "scsi(%ld): Issued ADAPTER RESET\n",
-			       ha->host_no);
-			printk(KERN_INFO "scsi(%ld): I/O processing will "
-			       "continue automatically\n", ha->host_no);
-		}
-		ha->flags.reset_active = 1;
-
-		if (qla1280_abort_isp(ha) != 0) {	/* it's dead */
-			result = FAILED;
-		}
-
-		ha->flags.reset_active = 0;
+		dprintk(1, "RESET invalid action %d\n", action);
+		return FAILED;
 	}
 
 	/*
@@ -1050,10 +1036,26 @@ static void qla1280_mailbox_timeout(unsigned long __data)
 qla1280_eh_adapter_reset(struct scsi_cmnd *cmd)
 {
 	int rc;
+	struct Scsi_Host *shost = cmd->device->host;
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)shost->hostdata;
 
-	spin_lock_irq(cmd->device->host->host_lock);
-	rc = qla1280_error_action(cmd, ADAPTER_RESET);
-	spin_unlock_irq(cmd->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	if (qla1280_verbose) {
+		printk(KERN_INFO
+		       "scsi(%ld): Issued ADAPTER RESET\n",
+		       ha->host_no);
+		printk(KERN_INFO "scsi(%ld): I/O processing will "
+		       "continue automatically\n", ha->host_no);
+	}
+	ha->flags.reset_active = 1;
+
+	if (qla1280_abort_isp(ha) != 0) {	/* it's dead */
+		rc = FAILED;
+	}
+
+	ha->flags.reset_active = 0;
+
+	spin_unlock_irq(shost->host_lock);
 
 	return rc;
 }
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (11 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 12/47] qla1280: separate out host reset function from qla1280_error_action() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  9:39   ` Johannes Thumshirn
  2017-06-28 13:41   ` Sumit Saxena
  2017-06-28  8:32 ` [PATCH 14/47] scsi: Use Scsi_Host as argument for eh_host_reset_handler Hannes Reinecke
                   ` (35 subsequent siblings)
  48 siblings, 2 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When calling a host reset we shouldn't rely on the command triggering
the reset, so allow megaraid_abort_and_reset() to be called with a
NULL scb.
And drop the pointless 'bus_reset' and 'target_reset' handlers, which
just call the same function as host_reset.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/megaraid.c | 42 ++++++++++++++++--------------------------
 1 file changed, 16 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 3c63c29..7e504d3 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -1909,7 +1909,7 @@ static DEF_SCSI_QCMD(megaraid_queue)
 
 	spin_lock_irq(&adapter->lock);
 
-	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
+	rval =  megaraid_abort_and_reset(adapter, NULL, SCB_RESET);
 
 	/*
 	 * This is required here to complete any completed requests
@@ -1948,7 +1948,7 @@ static DEF_SCSI_QCMD(megaraid_queue)
 
 		scb = list_entry(pos, scb_t, list);
 
-		if (scb->cmd == cmd) { /* Found command */
+		if (!cmd || scb->cmd == cmd) { /* Found command */
 
 			scb->state |= aor;
 
@@ -1967,31 +1967,23 @@ static DEF_SCSI_QCMD(megaraid_queue)
 
 				return FAILED;
 			}
-			else {
-
-				/*
-				 * Not yet issued! Remove from the pending
-				 * list
-				 */
-				dev_warn(&adapter->dev->dev,
-					"%s-[%x], driver owner\n",
-					(aor==SCB_ABORT) ? "ABORTING":"RESET",
-					scb->idx);
-
-				mega_free_scb(adapter, scb);
-
-				if( aor == SCB_ABORT ) {
-					cmd->result = (DID_ABORT << 16);
-				}
-				else {
-					cmd->result = (DID_RESET << 16);
-				}
+			/*
+			 * Not yet issued! Remove from the pending
+			 * list
+			 */
+			dev_warn(&adapter->dev->dev,
+				 "%s-[%x], driver owner\n",
+				 (cmd) ? "ABORTING":"RESET",
+				 scb->idx);
+			mega_free_scb(adapter, scb);
 
+			if (cmd) {
+				cmd->result = (DID_ABORT << 16);
 				list_add_tail(SCSI_LIST(cmd),
-						&adapter->completed_list);
-
-				return SUCCESS;
+					      &adapter->completed_list);
 			}
+
+			return SUCCESS;
 		}
 	}
 
@@ -4180,8 +4172,6 @@ static inline void mega_create_proc_entry(int index, struct proc_dir_entry *pare
 	.cmd_per_lun			= DEF_CMD_PER_LUN,
 	.use_clustering			= ENABLE_CLUSTERING,
 	.eh_abort_handler		= megaraid_abort,
-	.eh_device_reset_handler	= megaraid_reset,
-	.eh_bus_reset_handler		= megaraid_reset,
 	.eh_host_reset_handler		= megaraid_reset,
 	.no_write_same			= 1,
 };
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 14/47] scsi: Use Scsi_Host as argument for eh_host_reset_handler
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (12 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 13/47] megaraid: pass in NULL scb for host reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-07-24 16:55   ` Steffen Maier
  2017-06-28  8:32 ` [PATCH 15/47] scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh Hannes Reinecke
                   ` (34 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

Issuing a host reset should not rely on any commands.
So use Scsi_Host as argument for eh_host_reset_handler.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 Documentation/scsi/scsi_eh.txt                  |  2 +-
 Documentation/scsi/scsi_mid_low_api.txt         |  4 +--
 arch/ia64/hp/sim/simscsi.c                      |  2 +-
 drivers/infiniband/ulp/srp/ib_srp.c             |  6 ++--
 drivers/message/fusion/mptscsih.c               | 21 +++++++------
 drivers/message/fusion/mptscsih.h               |  2 +-
 drivers/s390/scsi/zfcp_scsi.c                   |  3 +-
 drivers/scsi/3w-9xxx.c                          | 11 +++----
 drivers/scsi/3w-sas.c                           | 11 +++----
 drivers/scsi/3w-xxxx.c                          | 11 ++++---
 drivers/scsi/53c700.c                           | 39 +++++++++++++------------
 drivers/scsi/BusLogic.c                         | 14 +++------
 drivers/scsi/NCR5380.c                          |  5 ++--
 drivers/scsi/NCR53c406a.c                       |  6 ++--
 drivers/scsi/aacraid/linit.c                    |  6 ++--
 drivers/scsi/advansys.c                         | 26 +++++++++--------
 drivers/scsi/aha152x.c                          | 11 +------
 drivers/scsi/aha152x.h                          |  2 +-
 drivers/scsi/aha1542.c                          | 17 +++++------
 drivers/scsi/arm/fas216.c                       |  4 +--
 drivers/scsi/arm/fas216.h                       |  6 ++--
 drivers/scsi/atari_scsi.c                       |  4 +--
 drivers/scsi/cxlflash/main.c                    | 13 ++-------
 drivers/scsi/dpt_i2o.c                          | 14 ++++-----
 drivers/scsi/dpti.h                             |  2 +-
 drivers/scsi/eata.c                             | 10 ++-----
 drivers/scsi/eata_pio.c                         | 29 +++++++++---------
 drivers/scsi/esas2r/esas2r.h                    |  2 +-
 drivers/scsi/esas2r/esas2r_main.c               | 16 +++++-----
 drivers/scsi/esp_scsi.c                         |  4 +--
 drivers/scsi/fdomain.c                          |  2 +-
 drivers/scsi/fdomain.h                          |  2 +-
 drivers/scsi/fnic/fnic.h                        |  2 +-
 drivers/scsi/fnic/fnic_scsi.c                   |  3 +-
 drivers/scsi/hptiop.c                           |  6 ++--
 drivers/scsi/ibmvscsi/ibmvfc.c                  |  4 +--
 drivers/scsi/ibmvscsi/ibmvscsi.c                |  4 +--
 drivers/scsi/imm.c                              |  6 ++--
 drivers/scsi/ipr.c                              |  4 +--
 drivers/scsi/ips.c                              | 23 +++++----------
 drivers/scsi/libfc/fc_fcp.c                     |  5 ++--
 drivers/scsi/lpfc/lpfc_scsi.c                   |  3 +-
 drivers/scsi/mac53c94.c                         |  8 ++---
 drivers/scsi/megaraid.c                         |  4 +--
 drivers/scsi/megaraid.h                         |  2 +-
 drivers/scsi/megaraid/megaraid_mbox.c           | 14 +++------
 drivers/scsi/megaraid/megaraid_sas_base.c       | 28 +++++++-----------
 drivers/scsi/mesh.c                             | 10 +++----
 drivers/scsi/mpt3sas/mpt3sas_scsih.c            | 13 ++++-----
 drivers/scsi/mvumi.c                            |  7 ++---
 drivers/scsi/nsp32.c                            | 12 ++++----
 drivers/scsi/pcmcia/aha152x_stub.c              |  2 +-
 drivers/scsi/pcmcia/nsp_cs.c                    |  4 +--
 drivers/scsi/pcmcia/qlogic_stub.c               |  4 +--
 drivers/scsi/pcmcia/sym53c500_cs.c              |  8 ++---
 drivers/scsi/pmcraid.c                          |  6 ++--
 drivers/scsi/ppa.c                              |  6 ++--
 drivers/scsi/qedf/qedf_main.c                   |  4 +--
 drivers/scsi/qedi/qedi_iscsi.c                  |  3 +-
 drivers/scsi/qla1280.c                          |  3 +-
 drivers/scsi/qla2xxx/qla_os.c                   | 20 +++++--------
 drivers/scsi/qla4xxx/ql4_os.c                   | 18 +++++-------
 drivers/scsi/qlogicfas408.c                     | 10 +++----
 drivers/scsi/qlogicfas408.h                     |  2 +-
 drivers/scsi/scsi_debug.c                       | 16 +++++-----
 drivers/scsi/scsi_error.c                       |  2 +-
 drivers/scsi/snic/snic.h                        |  3 +-
 drivers/scsi/snic/snic_scsi.c                   | 29 +++++-------------
 drivers/scsi/stex.c                             |  7 ++---
 drivers/scsi/storvsc_drv.c                      |  4 +--
 drivers/scsi/sym53c416.c                        | 16 ++++------
 drivers/scsi/sym53c8xx_2/sym_glue.c             |  3 +-
 drivers/scsi/ufs/ufshcd.c                       |  8 ++---
 drivers/scsi/vmw_pvscsi.c                       |  5 ++--
 drivers/scsi/wd33c93.c                          |  4 +--
 drivers/scsi/wd33c93.h                          |  2 +-
 drivers/scsi/wd719x.c                           |  4 +--
 drivers/staging/unisys/visorhba/visorhba_main.c |  4 +--
 drivers/usb/image/microtek.c                    |  4 +--
 include/scsi/libfc.h                            |  2 +-
 include/scsi/scsi_host.h                        |  2 +-
 81 files changed, 290 insertions(+), 380 deletions(-)

diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
index 11e447b..78cd6b9 100644
--- a/Documentation/scsi/scsi_eh.txt
+++ b/Documentation/scsi/scsi_eh.txt
@@ -208,7 +208,7 @@ considered to fail always.
 int (* eh_abort_handler)(struct scsi_cmnd *);
 int (* eh_device_reset_handler)(struct scsi_cmnd *);
 int (* eh_bus_reset_handler)(struct scsi_cmnd *);
-int (* eh_host_reset_handler)(struct scsi_cmnd *);
+int (* eh_host_reset_handler)(struct Scsi_Host *);
 
  Higher-severity actions are taken only when lower-severity actions
 cannot recover some of failed scmds.  Also, note that failure of the
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index 6338400..ad517d5 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -891,7 +891,7 @@ Details:
 
 /**
  *      eh_host_reset_handler - reset host (host bus adapter)
- *      @scp: SCSI host that contains this device should be reset
+ *      @shost: SCSI host that should be reset
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
@@ -908,7 +908,7 @@ Details:
  *
  *      Optionally defined in: LLD
  **/
-     int eh_host_reset_handler(struct scsi_cmnd * scp)
+     int eh_host_reset_handler(struct Scsi_Host * shost)
 
 
 /**
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index 085047f..1bff66b 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -329,7 +329,7 @@ struct disk_stat {
 static DEF_SCSI_QCMD(simscsi_queuecommand)
 
 static int
-simscsi_host_reset (struct scsi_cmnd *sc)
+simscsi_host_reset (struct Scsi_Host *shost)
 {
 	printk(KERN_ERR "simscsi_host_reset: not implemented\n");
 	return 0;
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 2354c74..588fc08 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -2679,11 +2679,11 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 	return SUCCESS;
 }
 
-static int srp_reset_host(struct scsi_cmnd *scmnd)
+static int srp_reset_host(struct Scsi_Host *shost)
 {
-	struct srp_target_port *target = host_to_target(scmnd->device->host);
+	struct srp_target_port *target = host_to_target(shost);
 
-	shost_printk(KERN_ERR, target->scsi_host, PFX "SRP reset_host called\n");
+	shost_printk(KERN_ERR, shost, PFX "SRP reset_host called\n");
 
 	return srp_reconnect_rport(target->rport) == 0 ? SUCCESS : FAILED;
 }
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 6ba07c7..0719d6d 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1902,15 +1902,15 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
- *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
+ *	mptscsih_host_reset - Perform a SCSI host adapter RESET
+ *	@sh: Pointer to Scsi_Host structure, which is reset due to
  *
  *	(linux scsi_host_template.eh_host_reset_handler routine)
  *
  *	Returns SUCCESS or FAILED.
  */
 int
-mptscsih_host_reset(struct scsi_cmnd *SCpnt)
+mptscsih_host_reset(struct Scsi_Host *sh)
 {
 	MPT_SCSI_HOST *  hd;
 	int              status = SUCCESS;
@@ -1918,9 +1918,8 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 	int		retval;
 
 	/*  If we can't locate the host to reset, then we failed. */
-	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
-		printk(KERN_ERR MYNAM ": host reset: "
-		    "Can't locate host! (sc=%p)\n", SCpnt);
+	if ((hd = shost_priv(sh)) == NULL){
+		printk(KERN_ERR MYNAM ": host reset: Can't locate host!\n");
 		return FAILED;
 	}
 
@@ -1928,20 +1927,20 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 	mptscsih_flush_running_cmds(hd);
 
 	ioc = hd->ioc;
-	printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
-	    ioc->name, SCpnt);
+	printk(MYIOC_s_INFO_FMT "attempting host reset!\n",
+	    ioc->name);
 
 	/*  If our attempts to reset the host failed, then return a failed
 	 *  status.  The host will be taken off line by the SCSI mid-layer.
 	 */
-    retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
+	retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
 	if (retval < 0)
 		status = FAILED;
 	else
 		status = SUCCESS;
 
-	printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
-	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+	printk(MYIOC_s_INFO_FMT "host reset: %s\n",
+	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ));
 
 	return status;
 }
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 2baeefd..6ab8254 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -121,7 +121,7 @@ extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
 extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
 extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
-extern int mptscsih_host_reset(struct scsi_cmnd *SCpnt);
+extern int mptscsih_host_reset(struct Scsi_Host *sh);
 extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
 extern int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
 extern int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 3d18659..d7d4a63 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -309,9 +309,8 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
 	return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
 }
 
-static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
+static int zfcp_scsi_eh_host_reset_handler(struct Scsi_Host *host)
 {
-	struct Scsi_Host *host = scpnt->device->host;
 	struct zfcp_adapter *adapter = (struct zfcp_adapter *)host->hostdata[0];
 	int ret = 0;
 	unsigned long flags;
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index 00e7968..463e053 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1715,18 +1715,19 @@ static int twa_scsi_biosparam(struct scsi_device *sdev, struct block_device *bde
 } /* End twa_scsi_biosparam() */
 
 /* This is the new scsi eh reset function */
-static int twa_scsi_eh_reset(struct scsi_cmnd *SCpnt)
+static int twa_scsi_eh_reset(struct Scsi_Host *shost)
 {
 	TW_Device_Extension *tw_dev = NULL;
 	int retval = FAILED;
 
-	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+	tw_dev = (TW_Device_Extension *)shost->hostdata;
 
 	tw_dev->num_resets++;
 
-	sdev_printk(KERN_WARNING, SCpnt->device,
-		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
-		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
+	shost_printk(KERN_WARNING, shost,
+		     "WARNING: (0x%02X:0x%04X): "
+		     "Command timed out, resetting card.\n",
+		     TW_DRIVER, 0x2c);
 
 	/* Make sure we are not issuing an ioctl or resetting from ioctl */
 	mutex_lock(&tw_dev->ioctl_lock);
diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c
index b150e13..5edaa0f2 100644
--- a/drivers/scsi/3w-sas.c
+++ b/drivers/scsi/3w-sas.c
@@ -1428,18 +1428,19 @@ static int twl_scsi_biosparam(struct scsi_device *sdev, struct block_device *bde
 } /* End twl_scsi_biosparam() */
 
 /* This is the new scsi eh reset function */
-static int twl_scsi_eh_reset(struct scsi_cmnd *SCpnt)
+static int twl_scsi_eh_reset(struct Scsi_Host *shost)
 {
 	TW_Device_Extension *tw_dev = NULL;
 	int retval = FAILED;
 
-	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+	tw_dev = (TW_Device_Extension *)shost->hostdata;
 
 	tw_dev->num_resets++;
 
-	sdev_printk(KERN_WARNING, SCpnt->device,
-		"WARNING: (0x%02X:0x%04X): Command (0x%x) timed out, resetting card.\n",
-		TW_DRIVER, 0x2c, SCpnt->cmnd[0]);
+	shost_printk(KERN_WARNING, shost,
+		     "WARNING: (0x%02X:0x%04X): "
+		     "Command timed out, resetting card.\n",
+		     TW_DRIVER, 0x2c);
 
 	/* Make sure we are not issuing an ioctl or resetting from ioctl */
 	mutex_lock(&tw_dev->ioctl_lock);
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index 33261b6..f999e06 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1357,25 +1357,24 @@ static int tw_scsi_biosparam(struct scsi_device *sdev, struct block_device *bdev
 } /* End tw_scsi_biosparam() */
 
 /* This is the new scsi eh reset function */
-static int tw_scsi_eh_reset(struct scsi_cmnd *SCpnt) 
+static int tw_scsi_eh_reset(struct Scsi_Host *shost)
 {
 	TW_Device_Extension *tw_dev=NULL;
 	int retval = FAILED;
 
-	tw_dev = (TW_Device_Extension *)SCpnt->device->host->hostdata;
+	tw_dev = (TW_Device_Extension *)shost->hostdata;
 
 	tw_dev->num_resets++;
 
-	sdev_printk(KERN_WARNING, SCpnt->device,
-		"WARNING: Command (0x%x) timed out, resetting card.\n",
-		SCpnt->cmnd[0]);
+	shost_printk(KERN_WARNING, shost,
+		"WARNING: Command timed out, resetting card.\n");
 
 	/* Make sure we are not issuing an ioctl or resetting from ioctl */
 	mutex_lock(&tw_dev->ioctl_lock);
 
 	/* Now reset the card and some of the device extension data */
 	if (tw_reset_device_extension(tw_dev)) {
-		printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no);
+		shost_printk(KERN_WARNING, shost, "Reset failed.\n");
 		goto out;
 	}
 
diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
index 2b8cc32..9635d00 100644
--- a/drivers/scsi/53c700.c
+++ b/drivers/scsi/53c700.c
@@ -168,7 +168,7 @@
 
 STATIC int NCR_700_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *);
 STATIC int NCR_700_abort(struct scsi_cmnd * SCpnt);
-STATIC int NCR_700_host_reset(struct scsi_cmnd * SCpnt);
+STATIC int NCR_700_host_reset(struct Scsi_Host *host);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
 STATIC int NCR_700_slave_alloc(struct scsi_device *SDpnt);
@@ -1937,40 +1937,41 @@ STATIC DEF_SCSI_QCMD(NCR_700_queuecommand)
 }
 
 STATIC int
-NCR_700_host_reset(struct scsi_cmnd * SCp)
+NCR_700_host_reset(struct Scsi_Host * host)
 {
 	DECLARE_COMPLETION_ONSTACK(complete);
-	struct NCR_700_Host_Parameters *hostdata = 
-		(struct NCR_700_Host_Parameters *)SCp->device->host->hostdata[0];
+	struct NCR_700_Host_Parameters *hostdata =
+		(struct NCR_700_Host_Parameters *)host->hostdata[0];
 
-	scmd_printk(KERN_INFO, SCp,
-		"New error handler wants HOST reset, cmd %p\n\t", SCp);
-	scsi_print_command(SCp);
+	shost_printk(KERN_INFO, host,
+		"New error handler wants HOST reset\n");
 
 	/* In theory, eh_complete should always be null because the
 	 * eh is single threaded, but just in case we're handling a
 	 * reset via sg or something */
-	spin_lock_irq(SCp->device->host->host_lock);
+	spin_lock_irq(host->host_lock);
 	while (hostdata->eh_complete != NULL) {
-		spin_unlock_irq(SCp->device->host->host_lock);
+		spin_unlock_irq(host->host_lock);
 		msleep_interruptible(100);
-		spin_lock_irq(SCp->device->host->host_lock);
+		spin_lock_irq(host->host_lock);
 	}
 
 	hostdata->eh_complete = &complete;
-	NCR_700_internal_bus_reset(SCp->device->host);
-	NCR_700_chip_reset(SCp->device->host);
+	NCR_700_internal_bus_reset(host);
+	NCR_700_chip_reset(host);
 
-	spin_unlock_irq(SCp->device->host->host_lock);
+	spin_unlock_irq(host->host_lock);
 	wait_for_completion(&complete);
-	spin_lock_irq(SCp->device->host->host_lock);
+	spin_lock_irq(host->host_lock);
 
 	hostdata->eh_complete = NULL;
-	/* Revalidate the transport parameters of the failing device */
-	if(hostdata->fast)
-		spi_schedule_dv_device(SCp->device);
-
-	spin_unlock_irq(SCp->device->host->host_lock);
+	/* Revalidate the transport parameters for attached devices */
+	if(hostdata->fast) {
+		struct scsi_device *sdev;
+		__shost_for_each_device(sdev, host)
+			spi_schedule_dv_device(sdev);
+	}
+	spin_unlock_irq(host->host_lock);
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 35380a5..44b0ec0 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -2998,21 +2998,15 @@ static bool blogic_write_outbox(struct blogic_adapter *adapter,
 
 /* Error Handling (EH) support */
 
-static int blogic_hostreset(struct scsi_cmnd *SCpnt)
+static int blogic_hostreset(struct Scsi_Host *shost)
 {
 	struct blogic_adapter *adapter =
-		(struct blogic_adapter *) SCpnt->device->host->hostdata;
-
-	unsigned int id = SCpnt->device->id;
-	struct blogic_tgt_stats *stats = &adapter->tgt_stats[id];
+		(struct blogic_adapter *) shost->hostdata;
 	int rc;
 
-	spin_lock_irq(SCpnt->device->host->host_lock);
-
-	blogic_inc_count(&stats->adapter_reset_req);
-
+	spin_lock_irq(shost->host_lock);
 	rc = blogic_resetadapter(adapter, false);
-	spin_unlock_irq(SCpnt->device->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 	return rc;
 }
 
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c
index 429cb00..b77ce28 100644
--- a/drivers/scsi/NCR5380.c
+++ b/drivers/scsi/NCR5380.c
@@ -2297,14 +2297,13 @@ static int NCR5380_abort(struct scsi_cmnd *cmd)
 
 /**
  * NCR5380_host_reset - reset the SCSI host
- * @cmd: SCSI command undergoing EH
+ * @instance: SCSI host undergoing EH
  *
  * Returns SUCCESS
  */
 
-static int NCR5380_host_reset(struct scsi_cmnd *cmd)
+static int NCR5380_host_reset(struct Scsi_Host *instance)
 {
-	struct Scsi_Host *instance = cmd->device->host;
 	struct NCR5380_hostdata *hostdata = shost_priv(instance);
 	int i;
 	unsigned long flags;
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index 6e110c6..002177e 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -728,11 +728,11 @@ static int NCR53c406a_queue_lck(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
 
 static DEF_SCSI_QCMD(NCR53c406a_queue)
 
-static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
+static int NCR53c406a_host_reset(struct Scsi_Host * shost)
 {
 	DEB(printk("NCR53c406a_reset called\n"));
 
-	spin_lock_irq(SCpnt->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 
 	outb(C4_IMG, CONFIG4);	/* Select reg set 0 */
 	outb(CHIP_RESET, CMD_REG);
@@ -742,7 +742,7 @@ static int NCR53c406a_host_reset(Scsi_Cmnd * SCpnt)
 
 	rtrc(2);
 
-	spin_unlock_irq(SCpnt->device->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	return SUCCESS;
 }
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index c26130e..bef2c0d 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -1051,13 +1051,11 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
 
 /*
  *	aac_eh_host_reset	- Host reset command handling
- *	@scsi_cmd:	SCSI command block causing the reset
+ *	@host:	SCSI host to be reset
  *
  */
-int aac_eh_host_reset(struct scsi_cmnd *cmd)
+int aac_eh_host_reset(struct Scsi_Host *host)
 {
-	struct scsi_device * dev = cmd->device;
-	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
 	int ret = FAILED;
 	__le32 supported_options2 = 0;
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c
index 24e57e7..7e7b203 100644
--- a/drivers/scsi/advansys.c
+++ b/drivers/scsi/advansys.c
@@ -7108,9 +7108,8 @@ static int AscISR(ASC_DVC_VAR *asc_dvc)
  * sleeping is allowed and no locking other than for host structures is
  * required. Returns SUCCESS or FAILED.
  */
-static int advansys_reset(struct scsi_cmnd *scp)
+static int advansys_reset(struct Scsi_Host *shost)
 {
-	struct Scsi_Host *shost = scp->device->host;
 	struct asc_board *boardp = shost_priv(shost);
 	unsigned long flags;
 	int status;
@@ -7120,7 +7119,7 @@ static int advansys_reset(struct scsi_cmnd *scp)
 
 	ASC_STATS(shost, reset);
 
-	scmd_printk(KERN_INFO, scp, "SCSI host reset started...\n");
+	shost_printk(KERN_INFO, shost, "SCSI host reset started...\n");
 
 	if (ASC_NARROW_BOARD(boardp)) {
 		ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var;
@@ -7131,16 +7130,18 @@ static int advansys_reset(struct scsi_cmnd *scp)
 
 		/* Refer to ASC_IERR_* definitions for meaning of 'err_code'. */
 		if (asc_dvc->err_code || !asc_dvc->overrun_dma) {
-			scmd_printk(KERN_INFO, scp, "SCSI host reset error: "
-				    "0x%x, status: 0x%x\n", asc_dvc->err_code,
+			shost_printk(KERN_INFO, shost,
+				     "SCSI host reset error: 0x%x, status: 0x%x\n",
+				     asc_dvc->err_code,
 				    status);
 			ret = FAILED;
 		} else if (status) {
-			scmd_printk(KERN_INFO, scp, "SCSI host reset warning: "
-				    "0x%x\n", status);
+			shost_printk(KERN_INFO, shost,
+				     "SCSI host reset warning: 0x%x\n",
+				     status);
 		} else {
-			scmd_printk(KERN_INFO, scp, "SCSI host reset "
-				    "successful\n");
+			shost_printk(KERN_INFO, shost,
+				     "SCSI host reset successful\n");
 		}
 
 		ASC_DBG(1, "after AscInitAsc1000Driver()\n");
@@ -7157,12 +7158,13 @@ static int advansys_reset(struct scsi_cmnd *scp)
 		ASC_DBG(1, "before AdvResetChipAndSB()\n");
 		switch (AdvResetChipAndSB(adv_dvc)) {
 		case ASC_TRUE:
-			scmd_printk(KERN_INFO, scp, "SCSI host reset "
-				    "successful\n");
+			shost_printk(KERN_INFO, shost,
+				     "SCSI host reset successful\n");
 			break;
 		case ASC_FALSE:
 		default:
-			scmd_printk(KERN_INFO, scp, "SCSI host reset error\n");
+			shost_printk(KERN_INFO, shost,
+				     "SCSI host reset error\n");
 			ret = FAILED;
 			break;
 		}
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 21e9d7c..857884a 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1205,7 +1205,7 @@ static void reset_ports(struct Scsi_Host *shpnt)
  * Reset the host (bus and controller)
  *
  */
-int aha152x_host_reset_host(struct Scsi_Host *shpnt)
+int aha152x_host_reset(struct Scsi_Host *shpnt)
 {
 	aha152x_bus_reset_host(shpnt);
 	reset_ports(shpnt);
@@ -1214,15 +1214,6 @@ int aha152x_host_reset_host(struct Scsi_Host *shpnt)
 }
 
 /*
- * Reset the host (bus and controller)
- *
- */
-static int aha152x_host_reset(Scsi_Cmnd *SCpnt)
-{
-	return aha152x_host_reset_host(SCpnt->device->host);
-}
-
-/*
  * Return the "logical geometry"
  *
  */
diff --git a/drivers/scsi/aha152x.h b/drivers/scsi/aha152x.h
index ac4bfa438b..3ccf724 100644
--- a/drivers/scsi/aha152x.h
+++ b/drivers/scsi/aha152x.h
@@ -332,6 +332,6 @@ struct aha152x_setup {
 
 struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *);
 void aha152x_release(struct Scsi_Host *);
-int aha152x_host_reset_host(struct Scsi_Host *);
+int aha152x_host_reset(struct Scsi_Host *);
 
 #endif /* _AHA152X_H */
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index a23cc9a..3d4c404 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -849,9 +849,8 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
 	return SUCCESS;
 }
 
-static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
+static int aha1542_reset(struct Scsi_Host *sh, u8 reset_cmd)
 {
-	struct Scsi_Host *sh = cmd->device->host;
 	struct aha1542_hostdata *aha1542 = shost_priv(sh);
 	unsigned long flags;
 	int i;
@@ -863,9 +862,9 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
 	 * we do this?  Try this first, and we can add that later
 	 * if it turns out to be useful.
 	 */
-	outb(reset_cmd, CONTROL(cmd->device->host->io_port));
+	outb(reset_cmd, CONTROL(sh->io_port));
 
-	if (!wait_mask(STATUS(cmd->device->host->io_port),
+	if (!wait_mask(STATUS(sh->io_port),
 	     STATMASK, IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) {
 		spin_unlock_irqrestore(sh->host_lock, flags);
 		return FAILED;
@@ -876,7 +875,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
 	 * us again after host reset.
 	 */
 	if (reset_cmd & HRST)
-		setup_mailboxes(cmd->device->host);
+		setup_mailboxes(sh);
 
 	/*
 	 * Now try to pick up the pieces.  For all pending commands,
@@ -884,7 +883,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
 	 * out.  We do not try and restart any commands or anything - 
 	 * the strategy handler takes care of that crap.
 	 */
-	shost_printk(KERN_WARNING, cmd->device->host, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);
+	shost_printk(KERN_WARNING, sh, "Sent BUS RESET to scsi host %d\n", cmd->device->host->host_no);
 
 	for (i = 0; i < AHA1542_MAILBOXES; i++) {
 		if (aha1542->int_cmds[i] != NULL) {
@@ -913,12 +912,12 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
 
 static int aha1542_bus_reset(struct scsi_cmnd *cmd)
 {
-	return aha1542_reset(cmd, SCRST);
+	return aha1542_reset(cmd->device->host, SCRST);
 }
 
-static int aha1542_host_reset(struct scsi_cmnd *cmd)
+static int aha1542_host_reset(struct Scsi_Host *sh)
 {
-	return aha1542_reset(cmd, HRST | SCRST);
+	return aha1542_reset(sh, HRST | SCRST);
 }
 
 static int aha1542_biosparam(struct scsi_device *sdev,
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index 2438879..e4a08e8 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2650,9 +2650,9 @@ static void fas216_init_chip(FAS216_Info *info)
  * Returns: FAILED if unable to reset.
  * Notes: io_request_lock is taken, and irqs are disabled
  */
-int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
+int fas216_eh_host_reset(struct Scsi_Host *shost)
 {
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
+	FAS216_Info *info = (FAS216_Info *)shost->hostdata;
 
 	spin_lock_irq(info->host->host_lock);
 
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
index c57c16e..e0e74ee 100644
--- a/drivers/scsi/arm/fas216.h
+++ b/drivers/scsi/arm/fas216.h
@@ -383,11 +383,11 @@
  */
 extern int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt);
 
-/* Function: int fas216_eh_host_reset(struct scsi_cmnd *SCpnt)
+/* Function: int fas216_eh_host_reset(struct Scsi_Host *shost)
  * Purpose : Reset the host associated with this command
- * Params  : SCpnt - command specifing host to reset
+ * Params  : shost - host to reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_host_reset(struct scsi_cmnd *SCpnt);
+extern int fas216_eh_host_reset(struct Scsi_Host *shost);
 
 #endif /* FAS216_H */
diff --git a/drivers/scsi/atari_scsi.c b/drivers/scsi/atari_scsi.c
index 89f5154..d524dde 100644
--- a/drivers/scsi/atari_scsi.c
+++ b/drivers/scsi/atari_scsi.c
@@ -671,7 +671,7 @@ static void atari_scsi_falcon_reg_write(unsigned int reg, u8 value)
 
 #include "NCR5380.c"
 
-static int atari_scsi_host_reset(struct scsi_cmnd *cmd)
+static int atari_scsi_host_reset(struct Scsi_Host *shost)
 {
 	int rv;
 	unsigned long flags;
@@ -688,7 +688,7 @@ static int atari_scsi_host_reset(struct scsi_cmnd *cmd)
 		atari_dma_orig_addr = NULL;
 	}
 
-	rv = NCR5380_host_reset(cmd);
+	rv = NCR5380_host_reset(shost);
 
 	/* The 5380 raises its IRQ line while _RST is active but the ST DMA
 	 * "lock" has been released so this interrupt may end up handled by
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
index 7a787b6..462e8fc 100644
--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -2466,7 +2466,7 @@ static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
 
 /**
  * cxlflash_eh_host_reset_handler() - reset the host adapter
- * @scp:	SCSI command from stack identifying host.
+ * @host:	SCSI host adapter.
  *
  * Following a reset, the state is evaluated again in case an EEH occurred
  * during the reset. In such a scenario, the host reset will either yield
@@ -2477,21 +2477,14 @@ static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
  *	SUCCESS as defined in scsi/scsi.h
  *	FAILED as defined in scsi/scsi.h
  */
-static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
+static int cxlflash_eh_host_reset_handler(struct Scsi_Host *host)
 {
 	int rc = SUCCESS;
 	int rcr = 0;
-	struct Scsi_Host *host = scp->device->host;
 	struct cxlflash_cfg *cfg = shost_priv(host);
 	struct device *dev = &cfg->dev->dev;
 
-	dev_dbg(dev, "%s: (scp=%p) %d/%d/%d/%llu "
-		"cdb=(%08x-%08x-%08x-%08x)\n", __func__, scp, host->host_no,
-		scp->device->channel, scp->device->id, scp->device->lun,
-		get_unaligned_be32(&((u32 *)scp->cmnd)[0]),
-		get_unaligned_be32(&((u32 *)scp->cmnd)[1]),
-		get_unaligned_be32(&((u32 *)scp->cmnd)[2]),
-		get_unaligned_be32(&((u32 *)scp->cmnd)[3]));
+	dev_dbg(dev, "%s: %d/-1/-1/-1\n", __func__, host->host_no);
 
 	switch (cfg->state) {
 	case STATE_NORMAL:
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 256dd67..d28f4a4 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -797,12 +797,12 @@ static int adpt_bus_reset(struct scsi_cmnd* cmd)
 }
 
 // This version of reset is called by the eh_error_handler
-static int __adpt_reset(struct scsi_cmnd* cmd)
+static int __adpt_reset(struct Scsi_Host* shost)
 {
 	adpt_hba* pHba;
 	int rcode;
-	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
-	printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid );
+	pHba = (adpt_hba*)shost->hostdata[0];
+	printk(KERN_WARNING"%s: Hba Reset\n",pHba->name);
 	rcode =  adpt_hba_reset(pHba);
 	if(rcode == 0){
 		printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
@@ -813,13 +813,13 @@ static int __adpt_reset(struct scsi_cmnd* cmd)
 	}
 }
 
-static int adpt_reset(struct scsi_cmnd* cmd)
+static int adpt_reset(struct Scsi_Host* shost)
 {
 	int rc;
 
-	spin_lock_irq(cmd->device->host->host_lock);
-	rc = __adpt_reset(cmd);
-	spin_unlock_irq(cmd->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	rc = __adpt_reset(shost);
+	spin_unlock_irq(shost->host_lock);
 
 	return rc;
 }
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 1fa345a..ba88ceb 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -31,7 +31,7 @@
 static int adpt_detect(struct scsi_host_template * sht);
 static int adpt_queue(struct Scsi_Host *h, struct scsi_cmnd * cmd);
 static int adpt_abort(struct scsi_cmnd * cmd);
-static int adpt_reset(struct scsi_cmnd* cmd);
+static int adpt_reset(struct Scsi_Host * host);
 static int adpt_release(struct Scsi_Host *host);
 static int adpt_slave_configure(struct scsi_device *);
 
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index 6501c33..187bfaf 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -507,7 +507,7 @@
 static int eata2x_release(struct Scsi_Host *);
 static int eata2x_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 static int eata2x_eh_abort(struct scsi_cmnd *);
-static int eata2x_eh_host_reset(struct scsi_cmnd *);
+static int eata2x_eh_host_reset(struct Scsi_Host *);
 static int eata2x_bios_param(struct scsi_device *, struct block_device *,
 			     sector_t, int *);
 static int eata2x_slave_configure(struct scsi_device *);
@@ -1896,20 +1896,16 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg)
 	panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i);
 }
 
-static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg)
+static int eata2x_eh_host_reset(struct Scsi_Host *shost)
 {
 	unsigned int i, time, k, c, limit = 0;
 	struct scsi_cmnd *SCpnt;
-	struct Scsi_Host *shost = SCarg->device->host;
 	struct hostdata *ha = (struct hostdata *)shost->hostdata;
 
-	scmd_printk(KERN_INFO, SCarg, "reset, enter.\n");
+	shost_printk(KERN_INFO, shost, "reset, enter.\n");
 
 	spin_lock_irq(shost->host_lock);
 
-	if (SCarg->host_scribble == NULL)
-		printk("%s: reset, inactive.\n", ha->board_name);
-
 	if (ha->in_reset) {
 		printk("%s: reset, exit, already in reset.\n", ha->board_name);
 		spin_unlock_irq(shost->host_lock);
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c
index 4299fa4..bf42876 100644
--- a/drivers/scsi/eata_pio.c
+++ b/drivers/scsi/eata_pio.c
@@ -435,19 +435,18 @@ static int eata_pio_abort(struct scsi_cmnd *cmd)
 	panic("eata_pio: abort: invalid slot status\n");
 }
 
-static int eata_pio_host_reset(struct scsi_cmnd *cmd)
+static int eata_pio_host_reset(struct Scsi_Host *host)
 {
 	unsigned int x, limit = 0;
 	unsigned char success = 0;
 	struct scsi_cmnd *sp;
-	struct Scsi_Host *host = cmd->device->host;
 
-	DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd,
+	DBG(DBG_ABNORM, shost_printk(KERN_WARNING, host,
 		"eata_pio_reset called\n"));
 
 	spin_lock_irq(host->host_lock);
 
-	if (HD(cmd)->state == RESET) {
+	if (SD(host)->state == RESET) {
 		printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
 		spin_unlock_irq(host->host_lock);
 		return FAILED;
@@ -455,13 +454,13 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
 
 	/* force all slots to be free */
 
-	for (x = 0; x < cmd->device->host->can_queue; x++) {
+	for (x = 0; x < host->can_queue; x++) {
 
-		if (HD(cmd)->ccb[x].status == FREE)
+		if (SD(host)->ccb[x].status == FREE)
 			continue;
 
-		sp = HD(cmd)->ccb[x].cmd;
-		HD(cmd)->ccb[x].status = RESET;
+		sp = SD(host)->ccb[x].cmd;
+		SD(host)->ccb[x].status = RESET;
 		printk(KERN_WARNING "eata_pio_reset: slot %d in reset.\n", x);
 
 		if (sp == NULL)
@@ -469,10 +468,10 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
 	}
 
 	/* hard reset the HBA  */
-	outb(EATA_CMD_RESET, cmd->device->host->base + HA_WCOMMAND);
+	outb(EATA_CMD_RESET, host->base + HA_WCOMMAND);
 
 	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n"));
-	HD(cmd)->state = RESET;
+	SD(host)->state = RESET;
 
 	spin_unlock_irq(host->host_lock);
 	msleep(3000);
@@ -480,23 +479,23 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd)
 
 	DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, " "loops %d.\n", limit));
 
-	for (x = 0; x < cmd->device->host->can_queue; x++) {
+	for (x = 0; x < host->can_queue; x++) {
 
 		/* Skip slots already set free by interrupt */
-		if (HD(cmd)->ccb[x].status != RESET)
+		if (SD(host)->ccb[x].status != RESET)
 			continue;
 
-		sp = HD(cmd)->ccb[x].cmd;
+		sp = SD(host)->ccb[x].cmd;
 		sp->result = DID_RESET << 16;
 
 		/* This mailbox is terminated */
 		printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n", x);
-		HD(cmd)->ccb[x].status = FREE;
+		SD(host)->ccb[x].status = FREE;
 
 		sp->scsi_done(sp);
 	}
 
-	HD(cmd)->state = 0;
+	SD(host)->state = 0;
 
 	spin_unlock_irq(host->host_lock);
 
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index 1da6407..d130a59 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -977,7 +977,7 @@ u8 handle_hba_ioctl(struct esas2r_adapter *a,
 /* SCSI error handler (eh) functions */
 int esas2r_eh_abort(struct scsi_cmnd *cmd);
 int esas2r_device_reset(struct scsi_cmnd *cmd);
-int esas2r_host_reset(struct scsi_cmnd *cmd);
+int esas2r_host_reset(struct Scsi_Host *shost);
 int esas2r_bus_reset(struct scsi_cmnd *cmd);
 int esas2r_target_reset(struct scsi_cmnd *cmd);
 
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index f2e9d8a..4f6dbc8 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -1122,10 +1122,10 @@ int esas2r_eh_abort(struct scsi_cmnd *cmd)
 	return SUCCESS;
 }
 
-static int esas2r_host_bus_reset(struct scsi_cmnd *cmd, bool host_reset)
+static int esas2r_host_bus_reset(struct Scsi_Host *shost, bool host_reset)
 {
 	struct esas2r_adapter *a =
-		(struct esas2r_adapter *)cmd->device->host->hostdata;
+		(struct esas2r_adapter *)shost->hostdata;
 
 	if (test_bit(AF_DEGRADED_MODE, &a->flags))
 		return FAILED;
@@ -1150,18 +1150,20 @@ static int esas2r_host_bus_reset(struct scsi_cmnd *cmd, bool host_reset)
 	return SUCCESS;
 }
 
-int esas2r_host_reset(struct scsi_cmnd *cmd)
+int esas2r_host_reset(struct Scsi_Host *shost)
 {
-	esas2r_log(ESAS2R_LOG_INFO, "host_reset (%p)", cmd);
+	esas2r_log(ESAS2R_LOG_INFO, "host_reset (%p)", shost);
 
-	return esas2r_host_bus_reset(cmd, true);
+	return esas2r_host_bus_reset(shost, true);
 }
 
 int esas2r_bus_reset(struct scsi_cmnd *cmd)
 {
-	esas2r_log(ESAS2R_LOG_INFO, "bus_reset (%p)", cmd);
+	struct Scsi_Host *shost = cmd->device->host;
+
+	esas2r_log(ESAS2R_LOG_INFO, "bus_reset (%p)", shost);
 
-	return esas2r_host_bus_reset(cmd, false);
+	return esas2r_host_bus_reset(shost, false);
 }
 
 static int esas2r_dev_targ_reset(struct scsi_cmnd *cmd, bool target_reset)
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index 71cb05b..15185a0 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -2655,9 +2655,9 @@ static int esp_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 }
 
 /* All bets are off, reset the entire device.  */
-static int esp_eh_host_reset_handler(struct scsi_cmnd *cmd)
+static int esp_eh_host_reset_handler(struct Scsi_Host *shost)
 {
-	struct esp *esp = shost_priv(cmd->device->host);
+	struct esp *esp = shost_priv(shost);
 	unsigned long flags;
 
 	spin_lock_irqsave(esp->host->host_lock, flags);
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
index ebbe5a3..d0b9583 100644
--- a/drivers/scsi/fdomain.c
+++ b/drivers/scsi/fdomain.c
@@ -1568,7 +1568,7 @@ static int fdomain_16x0_abort(struct scsi_cmnd *SCpnt)
    return SUCCESS;
 }
 
-int fdomain_16x0_host_reset(struct scsi_cmnd *SCpnt)
+int fdomain_16x0_host_reset(struct Scsi_Host *shost)
 {
    unsigned long flags;
 
diff --git a/drivers/scsi/fdomain.h b/drivers/scsi/fdomain.h
index 5cbe86b..85eab71 100644
--- a/drivers/scsi/fdomain.h
+++ b/drivers/scsi/fdomain.h
@@ -21,4 +21,4 @@
 extern struct scsi_host_template fdomain_driver_template;
 extern int fdomain_setup(char *str);
 extern struct Scsi_Host *__fdomain_16x0_detect(struct  scsi_host_template *tpnt );
-extern int fdomain_16x0_host_reset(struct scsi_cmnd *SCpnt);
+extern int fdomain_16x0_host_reset(struct Scsi_Host *shost);
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 67aab96..35a4080 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -343,7 +343,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip)
 int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fnic_abort_cmd(struct scsi_cmnd *);
 int fnic_device_reset(struct scsi_cmnd *);
-int fnic_host_reset(struct scsi_cmnd *);
+int fnic_host_reset(struct Scsi_Host *);
 int fnic_reset(struct Scsi_Host *);
 void fnic_scsi_cleanup(struct fc_lport *);
 void fnic_scsi_abort_io(struct fc_lport *);
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 242e2ee..2716222 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -2629,11 +2629,10 @@ int fnic_reset(struct Scsi_Host *shost)
  * host is offlined by SCSI.
  *
  */
-int fnic_host_reset(struct scsi_cmnd *sc)
+int fnic_host_reset(struct Scsi_Host *shost)
 {
 	int ret;
 	unsigned long wait_host_tmo;
-	struct Scsi_Host *shost = sc->device->host;
 	struct fc_lport *lp = shost_priv(shost);
 	struct fnic *fnic = lport_priv(lp);
 	unsigned long flags;
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 2fad7f0..d8b78ba 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -1104,12 +1104,12 @@ static int hptiop_reset_hba(struct hptiop_hba *hba)
 	return 0;
 }
 
-static int hptiop_reset(struct scsi_cmnd *scp)
+static int hptiop_reset(struct Scsi_Host *host)
 {
-	struct hptiop_hba * hba = (struct hptiop_hba *)scp->device->host->hostdata;
+	struct hptiop_hba * hba = (struct hptiop_hba *)host->hostdata;
 
 	printk(KERN_WARNING "hptiop_reset(%d/%d/%d)\n",
-	       scp->device->host->host_no, -1, -1);
+	       host->host_no, -1, -1);
 
 	return hptiop_reset_hba(hba)? FAILED : SUCCESS;
 }
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index bb033ce..5dccf07 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2526,10 +2526,10 @@ static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
  * @cmd:	struct scsi_cmnd having problems
  *
  **/
-static int ibmvfc_eh_host_reset_handler(struct scsi_cmnd *cmd)
+static int ibmvfc_eh_host_reset_handler(struct Scsi_Host *shost)
 {
 	int rc;
-	struct ibmvfc_host *vhost = shost_priv(cmd->device->host);
+	struct ibmvfc_host *vhost = shost_priv(shost);
 
 	dev_err(vhost->dev, "Resetting connection due to error recovery\n");
 	rc = ibmvfc_issue_fc_host_lip(vhost->host);
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 1deb0a9..262b30c 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1731,10 +1731,10 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
  * ibmvscsi_eh_host_reset_handler - Reset the connection to the server
  * @cmd:	struct scsi_cmnd having problems
 */
-static int ibmvscsi_eh_host_reset_handler(struct scsi_cmnd *cmd)
+static int ibmvscsi_eh_host_reset_handler(struct Scsi_Host *shost)
 {
 	unsigned long wait_switch = 0;
-	struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host);
+	struct ibmvscsi_host_data *hostdata = shost_priv(shost);
 
 	dev_err(hostdata->dev, "Resetting connection due to error recovery\n");
 
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c
index 87c9419..5232dfb 100644
--- a/drivers/scsi/imm.c
+++ b/drivers/scsi/imm.c
@@ -986,11 +986,11 @@ static void imm_reset_pulse(unsigned int base)
 	w_ctr(base, 0x04);
 }
 
-static int imm_reset(struct scsi_cmnd *cmd)
+static int imm_reset(struct Scsi_Host *shost)
 {
-	imm_struct *dev = imm_dev(cmd->device->host);
+	imm_struct *dev = imm_dev(shost);
 
-	if (cmd->SCp.phase)
+	if (dev->cur_cmd->SCp.phase)
 		imm_disconnect(dev);
 	dev->cur_cmd = NULL;	/* Forget the problem */
 
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index b0c68d2..2ab2a9e 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5152,14 +5152,14 @@ static int ipr_wait_for_ops(struct ipr_ioa_cfg *ioa_cfg, void *device,
 	return SUCCESS;
 }
 
-static int ipr_eh_host_reset(struct scsi_cmnd *cmd)
+static int ipr_eh_host_reset(struct Scsi_Host *shost)
 {
 	struct ipr_ioa_cfg *ioa_cfg;
 	unsigned long lock_flags = 0;
 	int rc = SUCCESS;
 
 	ENTER;
-	ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata;
+	ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata;
 	spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
 
 	if (!ioa_cfg->in_reset_reload && !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) {
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 97d9cca..8507fb0 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -227,7 +227,7 @@
 static int ips_detect(struct scsi_host_template *);
 static int ips_release(struct Scsi_Host *);
 static int ips_eh_abort(struct scsi_cmnd *);
-static int ips_eh_reset(struct scsi_cmnd *);
+static int ips_eh_reset(struct Scsi_Host *);
 static int ips_queue(struct Scsi_Host *, struct scsi_cmnd *);
 static const char *ips_info(struct Scsi_Host *);
 static irqreturn_t do_ipsintr(int, void *);
@@ -834,13 +834,12 @@ int ips_eh_abort(struct scsi_cmnd *SC)
 /* NOTE: this routine is called under the io_request_lock spinlock          */
 /*                                                                          */
 /****************************************************************************/
-static int __ips_eh_reset(struct scsi_cmnd *SC)
+static int __ips_eh_reset(struct Scsi_Host *shost)
 {
 	int ret;
 	int i;
 	ips_ha_t *ha;
 	ips_scb_t *scb;
-	ips_copp_wait_item_t *item;
 
 	METHOD_TRACE("ips_eh_reset", 1);
 
@@ -848,13 +847,7 @@ static int __ips_eh_reset(struct scsi_cmnd *SC)
 	return (FAILED);
 #else
 
-	if (!SC) {
-		DEBUG(1, "Reset called with NULL scsi command");
-
-		return (FAILED);
-	}
-
-	ha = (ips_ha_t *) SC->device->host->hostdata;
+	ha = (ips_ha_t *) shost->hostdata;
 
 	if (!ha) {
 		DEBUG(1, "Reset called with NULL ha struct");
@@ -1003,13 +996,13 @@ static int __ips_eh_reset(struct scsi_cmnd *SC)
 
 }
 
-static int ips_eh_reset(struct scsi_cmnd *SC)
+static int ips_eh_reset(struct Scsi_Host *shost)
 {
 	int rc;
 
-	spin_lock_irq(SC->device->host->host_lock);
-	rc = __ips_eh_reset(SC);
-	spin_unlock_irq(SC->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	rc = __ips_eh_reset(shost);
+	spin_unlock_irq(shost->host_lock);
 
 	return rc;
 }
@@ -1088,7 +1081,7 @@ static int ips_queue_lck(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *)
 				return (0);
 			}
 			ha->ioctl_reset = 1;	/* This reset request is from an IOCTL */
-			__ips_eh_reset(SC);
+			__ips_eh_reset(SC->device->host);
 			SC->result = DID_OK << 16;
 			SC->scsi_done(SC);
 			return (0);
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 772c35a..2ec903a 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -2212,11 +2212,10 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 
 /**
  * fc_eh_host_reset() - Reset a Scsi_Host.
- * @sc_cmd: The SCSI command that identifies the SCSI host to be reset
+ * @shost: The SCSI host to be reset
  */
-int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
+int fc_eh_host_reset(struct Scsi_Host *shost)
 {
-	struct Scsi_Host *shost = sc_cmd->device->host;
 	struct fc_lport *lport = shost_priv(shost);
 	unsigned long wait_tmo;
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 19b1202..79981b9 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5310,9 +5310,8 @@ void lpfc_poll_timeout(unsigned long ptr)
  *  0x2002 - Success
  **/
 static int
-lpfc_host_reset_handler(struct scsi_cmnd *cmnd)
+lpfc_host_reset_handler(struct Scsi_Host *shost)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_hba *phba = vport->phba;
 	int rc, ret = SUCCESS;
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index a6682c5..120a719 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -101,14 +101,14 @@ static int mac53c94_queue_lck(struct scsi_cmnd *cmd, void (*done)(struct scsi_cm
 
 static DEF_SCSI_QCMD(mac53c94_queue)
 
-static int mac53c94_host_reset(struct scsi_cmnd *cmd)
+static int mac53c94_host_reset(struct Scsi_Host *shost)
 {
-	struct fsc_state *state = (struct fsc_state *) cmd->device->host->hostdata;
+	struct fsc_state *state = (struct fsc_state *) shost->hostdata;
 	struct mac53c94_regs __iomem *regs = state->regs;
 	struct dbdma_regs __iomem *dma = state->dma;
 	unsigned long flags;
 
-	spin_lock_irqsave(cmd->device->host->host_lock, flags);
+	spin_lock_irqsave(shost->host_lock, flags);
 
 	writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control);
 	writeb(CMD_SCSI_RESET, &regs->command);	/* assert RST */
@@ -118,7 +118,7 @@ static int mac53c94_host_reset(struct scsi_cmnd *cmd)
 	mac53c94_init(state);
 	writeb(CMD_NOP, &regs->command);
 
-	spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
+	spin_unlock_irqrestore(shost->host_lock, flags);
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index 7e504d3..f7a79f8 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -1887,13 +1887,13 @@ static DEF_SCSI_QCMD(megaraid_queue)
 
 
 static int
-megaraid_reset(struct scsi_cmnd *cmd)
+megaraid_reset(struct Scsi_Host *shost)
 {
 	adapter_t	*adapter;
 	megacmd_t	mc;
 	int		rval;
 
-	adapter = (adapter_t *)cmd->device->host->hostdata;
+	adapter = (adapter_t *)shost->hostdata;
 
 #if MEGA_HAVE_CLUSTERING
 	mc.cmd = MEGA_CLUSTER_CMD;
diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
index 508d65e..6fb6adf 100644
--- a/drivers/scsi/megaraid.h
+++ b/drivers/scsi/megaraid.h
@@ -963,7 +963,7 @@ struct mega_hbas {
 static void mega_free_scb(adapter_t *, scb_t *);
 
 static int megaraid_abort(Scsi_Cmnd *);
-static int megaraid_reset(Scsi_Cmnd *);
+static int megaraid_reset(struct Scsi_Host *);
 static int megaraid_abort_and_reset(adapter_t *, Scsi_Cmnd *, int);
 static int megaraid_biosparam(struct scsi_device *, struct block_device *,
 		sector_t, int []);
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index 3f914b1..85e8a2f 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -97,7 +97,7 @@
 static void megaraid_sysfs_free_resources(adapter_t *);
 
 static int megaraid_abort_handler(struct scsi_cmnd *);
-static int megaraid_reset_handler(struct scsi_cmnd *);
+static int megaraid_reset_handler(struct Scsi_Host *);
 
 static int mbox_post_sync_cmd(adapter_t *, uint8_t []);
 static int mbox_post_sync_cmd_fast(adapter_t *, uint8_t []);
@@ -2567,7 +2567,7 @@ static DEF_SCSI_QCMD(megaraid_queue_command)
  * host.
  **/
 static int
-megaraid_reset_handler(struct scsi_cmnd *scp)
+megaraid_reset_handler(struct Scsi_Host *shost)
 {
 	adapter_t	*adapter;
 	scb_t		*scb;
@@ -2581,7 +2581,7 @@ static DEF_SCSI_QCMD(megaraid_queue_command)
 	int		i;
 	uioc_t		*kioc;
 
-	adapter		= SCP2ADAPTER(scp);
+	adapter		= (adapter_t *)SCSIHOST2ADAP(shost);
 	raid_dev	= ADAP2RAIDDEV(adapter);
 
 	// return failure if adapter is not responding
@@ -2613,15 +2613,9 @@ static DEF_SCSI_QCMD(megaraid_queue_command)
 
 			megaraid_mbox_mm_done(adapter, scb);
 		} else {
-			if (scb->scp == scp) {	// Found command
-				con_log(CL_ANN, (KERN_WARNING
-					"megaraid: %d[%d:%d], reset from pending list\n",
-					scb->sno, scb->dev_channel, scb->dev_target));
-			} else {
-				con_log(CL_ANN, (KERN_WARNING
+			con_log(CL_ANN, (KERN_WARNING
 				"megaraid: IO packet with %d[%d:%d] being reset\n",
 				scb->sno, scb->dev_channel, scb->dev_target));
-			}
 
 			scb->scp->result = (DID_RESET << 16);
 			scb->scp->scsi_done(scb->scp);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 316c3df..89e3fd6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2691,15 +2691,14 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
  * reset requests. Device, bus and host specific reset handlers can use this
  * function after they do their specific tasks.
  */
-static int megasas_generic_reset(struct scsi_cmnd *scmd)
+static int megasas_generic_reset(struct Scsi_Host *shost)
 {
 	int ret_val;
 	struct megasas_instance *instance;
 
-	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+	instance = (struct megasas_instance *)shost->hostdata;
 
-	scmd_printk(KERN_NOTICE, scmd, "megasas: RESET cmd=%x retries=%x\n",
-		 scmd->cmnd[0], scmd->retries);
+	shost_printk(KERN_NOTICE, shost, "megasas: RESET\n");
 
 	if (atomic_read(&instance->adprecovery) == MEGASAS_HW_CRITICAL_ERROR) {
 		dev_err(&instance->pdev->dev, "cannot recover from previous reset failures\n");
@@ -2768,34 +2767,29 @@ blk_eh_timer_return megasas_reset_timer(struct scsi_cmnd *scmd)
 /**
  * megasas_reset_bus_host -	Bus & host reset handler entry point
  */
-static int megasas_reset_bus_host(struct scsi_cmnd *scmd)
+static int megasas_reset_bus_host(struct Scsi_Host *shost)
 {
 	int ret;
 	struct megasas_instance *instance;
 
-	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+	instance = (struct megasas_instance *)shost->hostdata;
 
-	scmd_printk(KERN_INFO, scmd,
+	shost_printk(KERN_INFO, shost,
 		"Controller reset is requested due to IO timeout\n"
-		"SCSI command pointer: (%p)\t SCSI host state: %d\t"
+		"SCSI host state: %d\t"
 		" SCSI host busy: %d\t FW outstanding: %d\n",
-		scmd, scmd->device->host->shost_state,
-		atomic_read((atomic_t *)&scmd->device->host->host_busy),
+		shost->shost_state,
+		atomic_read(&shost->host_busy),
 		atomic_read(&instance->fw_outstanding));
 
 	/*
 	 * First wait for all commands to complete
 	 */
 	if (instance->ctrl_context) {
-		struct megasas_cmd_fusion *cmd;
-		cmd = (struct megasas_cmd_fusion *)scmd->SCp.ptr;
-		if (cmd)
-			megasas_dump_frame(cmd->io_request,
-				sizeof(struct MPI2_RAID_SCSI_IO_REQUEST));
-		ret = megasas_reset_fusion(scmd->device->host,
+		ret = megasas_reset_fusion(shost,
 				SCSIIO_TIMEOUT_OCR);
 	} else
-		ret = megasas_generic_reset(scmd);
+		ret = megasas_generic_reset(shost);
 
 	return ret;
 }
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 1753e42..6067d3c 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1700,9 +1700,9 @@ static int mesh_abort(struct scsi_cmnd *cmd)
  * The midlayer will wait for devices to come back, we don't need
  * to do that ourselves
  */
-static int mesh_host_reset(struct scsi_cmnd *cmd)
+static int mesh_host_reset(struct Scsi_Host *shost)
 {
-	struct mesh_state *ms = (struct mesh_state *) cmd->device->host->hostdata;
+	struct mesh_state *ms = (struct mesh_state *) shost->hostdata;
 	volatile struct mesh_regs __iomem *mr = ms->mesh;
 	volatile struct dbdma_regs __iomem *md = ms->dma;
 	unsigned long flags;
@@ -1716,7 +1716,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd)
 	out_8(&mr->exception, 0xff);	/* clear all exception bits */
 	out_8(&mr->error, 0xff);	/* clear all error bits */
 	out_8(&mr->sequence, SEQ_RESETMESH);
-       	mesh_flush_io(mr);
+	mesh_flush_io(mr);
 	udelay(1);
 	out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE);
 	out_8(&mr->source_id, ms->host->this_id);
@@ -1725,13 +1725,13 @@ static int mesh_host_reset(struct scsi_cmnd *cmd)
 
 	/* Reset the bus */
 	out_8(&mr->bus_status1, BS1_RST);	/* assert RST */
-       	mesh_flush_io(mr);
+	mesh_flush_io(mr);
 	udelay(30);			/* leave it on for >= 25us */
 	out_8(&mr->bus_status1, 0);	/* negate RST */
 
 	/* Complete pending commands */
 	handle_reset(ms);
-	
+
 	spin_unlock_irqrestore(ms->host->host_lock, flags);
 	return SUCCESS;
 }
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 22998cb..6ecf672 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2643,14 +2643,13 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
  * Returns SUCCESS if command aborted else FAILED
  */
 static int
-scsih_host_reset(struct scsi_cmnd *scmd)
+scsih_host_reset(struct Scsi_Host *shost)
 {
-	struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
+	struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
 	int r, retval;
 
-	pr_info(MPT3SAS_FMT "attempting host reset! scmd(%p)\n",
-	    ioc->name, scmd);
-	scsi_print_command(scmd);
+	pr_info(MPT3SAS_FMT "attempting host reset!\n",
+	    ioc->name);
 
 	if (ioc->is_driver_loading) {
 		pr_info(MPT3SAS_FMT "Blocking the host reset\n",
@@ -2662,8 +2661,8 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 	retval = mpt3sas_base_hard_reset_handler(ioc, FORCE_BIG_HAMMER);
 	r = (retval < 0) ? FAILED : SUCCESS;
 out:
-	pr_info(MPT3SAS_FMT "host reset: %s scmd(%p)\n",
-	    ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+	pr_info(MPT3SAS_FMT "host reset: %s\n",
+	    ioc->name, ((r == SUCCESS) ? "SUCCESS" : "FAILED"));
 
 	return r;
 }
diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c
index fe97401..d76b958 100644
--- a/drivers/scsi/mvumi.c
+++ b/drivers/scsi/mvumi.c
@@ -709,14 +709,13 @@ static int mvumi_reset_host_9143(struct mvumi_hba *mhba)
 	return mvumi_wait_for_outstanding(mhba);
 }
 
-static int mvumi_host_reset(struct scsi_cmnd *scmd)
+static int mvumi_host_reset(struct Scsi_Host *shost)
 {
 	struct mvumi_hba *mhba;
 
-	mhba = (struct mvumi_hba *) scmd->device->host->hostdata;
+	mhba = (struct mvumi_hba *) shost->hostdata;
 
-	scmd_printk(KERN_NOTICE, scmd, "RESET -%ld cmd=%x retries=%x\n",
-			scmd->serial_number, scmd->cmnd[0], scmd->retries);
+	shost_printk(KERN_NOTICE, shost, "RESET\n");
 
 	return mhba->instancet->reset_host(mhba);
 }
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 107e191..f511dd8 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -2885,23 +2885,21 @@ static void nsp32_do_bus_reset(nsp32_hw_data *data)
 	data->CurrentSC = NULL;
 }
 
-static int nsp32_eh_host_reset(struct scsi_cmnd *SCpnt)
+static int nsp32_eh_host_reset(struct Scsi_Host *host)
 {
-	struct Scsi_Host *host = SCpnt->device->host;
-	unsigned int      base = SCpnt->device->host->io_port;
+	unsigned int      base = host->io_port;
 	nsp32_hw_data    *data = (nsp32_hw_data *)host->hostdata;
 
-	nsp32_msg(KERN_INFO, "Host Reset");	
-	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
+	nsp32_msg(KERN_INFO, "Host Reset");
 
-	spin_lock_irq(SCpnt->device->host->host_lock);
+	spin_lock_irq(host->host_lock);
 
 	nsp32hw_init(data);
 	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
 	nsp32_do_bus_reset(data);
 	nsp32_write2(base, IRQ_CONTROL, 0);
 
-	spin_unlock_irq(SCpnt->device->host->host_lock);
+	spin_unlock_irq(host->host_lock);
 	return SUCCESS;	/* Host reset is succeeded at any time. */
 }
 
diff --git a/drivers/scsi/pcmcia/aha152x_stub.c b/drivers/scsi/pcmcia/aha152x_stub.c
index 7d1609f..f95abd9 100644
--- a/drivers/scsi/pcmcia/aha152x_stub.c
+++ b/drivers/scsi/pcmcia/aha152x_stub.c
@@ -197,7 +197,7 @@ static int aha152x_resume(struct pcmcia_device *link)
 {
 	scsi_info_t *info = link->priv;
 
-	aha152x_host_reset_host(info->host);
+	aha152x_host_reset(info->host);
 
 	return 0;
 }
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 5fb6eef..48ec923 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1485,9 +1485,9 @@ static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
 	return nsp_bus_reset(data);
 }
 
-static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
+static int nsp_eh_host_reset(struct Scsi_Host *host)
 {
-	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	nsp_hw_data *data = (nsp_hw_data *)host->hostdata;
 
 	nsp_dbg(NSP_DEBUG_BUSRESET, "in");
 
diff --git a/drivers/scsi/pcmcia/qlogic_stub.c b/drivers/scsi/pcmcia/qlogic_stub.c
index 0556054..ab68880 100644
--- a/drivers/scsi/pcmcia/qlogic_stub.c
+++ b/drivers/scsi/pcmcia/qlogic_stub.c
@@ -263,8 +263,8 @@ static int qlogic_resume(struct pcmcia_device *link)
 		outb(0x24, link->resource[0]->start + 0x9);
 		outb(0x04, link->resource[0]->start + 0xd);
 	}
-	/* Ugggglllyyyy!!! */
-	qlogicfas408_host_reset(NULL);
+
+	qlogicfas408_host_reset(info->host);
 
 	return 0;
 }
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 20011c8..d0ee84c 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -586,14 +586,14 @@ enum Phase {
 static DEF_SCSI_QCMD(SYM53C500_queue)
 
 static int 
-SYM53C500_host_reset(struct scsi_cmnd *SCpnt)
+SYM53C500_host_reset(struct Scsi_Host *shost)
 {
-	int port_base = SCpnt->device->host->io_port;
+	int port_base = shost->io_port;
 
 	DEB(printk("SYM53C500_host_reset called\n"));
-	spin_lock_irq(SCpnt->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	SYM53C500_int_host_reset(port_base);
-	spin_unlock_irq(SCpnt->device->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	return SUCCESS;
 }
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 1cc814f..4b66b92 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3089,19 +3089,19 @@ static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
 /**
  * pmcraid_eh_host_reset_handler - adapter reset handler callback
  *
- * @scmd: pointer to scsi_cmd that was sent to a resource of adapter
+ * @shost: pointer to scsi_host
  *
  * Initiates adapter reset to bring it up to operational state
  *
  * Return value
  *	SUCCESS or FAILED
  */
-static int pmcraid_eh_host_reset_handler(struct scsi_cmnd *scmd)
+static int pmcraid_eh_host_reset_handler(struct Scsi_Host *shost)
 {
 	unsigned long interval = 10000; /* 10 seconds interval */
 	int waits = jiffies_to_msecs(PMCRAID_RESET_HOST_TIMEOUT) / interval;
 	struct pmcraid_instance *pinstance =
-		(struct pmcraid_instance *)(scmd->device->host->hostdata);
+		(struct pmcraid_instance *)(shost->hostdata);
 
 
 	/* wait for an additional 150 seconds just in case firmware could come
diff --git a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
index 7be5823..0ce0f9a 100644
--- a/drivers/scsi/ppa.c
+++ b/drivers/scsi/ppa.c
@@ -857,11 +857,11 @@ static void ppa_reset_pulse(unsigned int base)
 	w_ctr(base, 0xc);
 }
 
-static int ppa_reset(struct scsi_cmnd *cmd)
+static int ppa_reset(struct Scsi_Host *shost)
 {
-	ppa_struct *dev = ppa_dev(cmd->device->host);
+	ppa_struct *dev = ppa_dev(shost);
 
-	if (cmd->SCp.phase)
+	if (dev->cur_cmd->SCp.phase)
 		ppa_disconnect(dev);
 	dev->cur_cmd = NULL;	/* Forget the problem */
 
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index d48a13a..b06ef7c 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -666,12 +666,12 @@ static void qedf_ctx_soft_reset(struct fc_lport *lport)
 }
 
 /* Reset the host by gracefully logging out and then logging back in */
-static int qedf_eh_host_reset(struct scsi_cmnd *sc_cmd)
+static int qedf_eh_host_reset(struct Scsi_Host *shost)
 {
 	struct fc_lport *lport;
 	struct qedf_ctx *qedf;
 
-	lport = shost_priv(sc_cmd->device->host);
+	lport = shost_priv(shost);
 	qedf = lport_priv(lport);
 
 	if (atomic_read(&qedf->link_state) == QEDF_LINK_DOWN ||
diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c
index 87f0af3..3fa489e 100644
--- a/drivers/scsi/qedi/qedi_iscsi.c
+++ b/drivers/scsi/qedi/qedi_iscsi.c
@@ -33,9 +33,8 @@ int qedi_recover_all_conns(struct qedi_ctx *qedi)
 	return SUCCESS;
 }
 
-static int qedi_eh_host_reset(struct scsi_cmnd *cmd)
+static int qedi_eh_host_reset(struct Scsi_Host *shost)
 {
-	struct Scsi_Host *shost = cmd->device->host;
 	struct qedi_ctx *qedi;
 
 	qedi = iscsi_host_priv(shost);
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index d712bfe..c6240ce 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -1033,10 +1033,9 @@ static void qla1280_mailbox_timeout(unsigned long __data)
  *     Reset the specified adapter (both channels)
  **************************************************************************/
 static int
-qla1280_eh_adapter_reset(struct scsi_cmnd *cmd)
+qla1280_eh_adapter_reset(struct Scsi_Host *shost)
 {
 	int rc;
-	struct Scsi_Host *shost = cmd->device->host;
 	struct scsi_qla_host *ha = (struct scsi_qla_host *)shost->hostdata;
 
 	spin_lock_irq(shost->host_lock);
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index df57655..fe2ff0a 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -275,7 +275,7 @@
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
-static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
+static int qla2xxx_eh_host_reset(struct Scsi_Host *);
 
 static void qla2x00_clear_drv_active(struct qla_hw_data *);
 static void qla2x00_free_device(scsi_qla_host_t *);
@@ -1550,8 +1550,7 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 *    The reset function will reset the Adapter.
 *
 * Input:
-*      cmd = Linux SCSI command packet of the command that cause the
-*            adapter reset.
+*      shost = Linux SCSI host to be reset
 *
 * Returns:
 *      Either SUCCESS or FAILED.
@@ -1559,13 +1558,11 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 * Note:
 **************************************************************************/
 static int
-qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
+qla2xxx_eh_host_reset(struct Scsi_Host *shost)
 {
-	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
+	scsi_qla_host_t *vha = shost_priv(shost);
 	struct qla_hw_data *ha = vha->hw;
 	int ret = FAILED;
-	unsigned int id;
-	uint64_t lun;
 	scsi_qla_host_t *base_vha = pci_get_drvdata(ha->pdev);
 
 	if (qla2x00_isp_reg_stat(ha)) {
@@ -1575,11 +1572,8 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 		return SUCCESS;
 	}
 
-	id = cmd->device->id;
-	lun = cmd->device->lun;
-
 	ql_log(ql_log_info, vha, 0x8018,
-	    "ADAPTER RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun);
+	    "ADAPTER RESET ISSUED host=%ld.\n", vha->host_no);
 
 	/*
 	 * No point in issuing another reset if one is active.  Also do not
@@ -1625,8 +1619,8 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 
 eh_host_reset_lock:
 	ql_log(ql_log_info, vha, 0x8017,
-	    "ADAPTER RESET %s nexus=%ld:%d:%llu.\n",
-	    (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
+	    "ADAPTER RESET %s host=%ld.\n",
+	    (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no);
 
 	return ret;
 }
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 64c6fa5..11bd2da 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -160,7 +160,7 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void  *data,
 static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);
-static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd);
+static int qla4xxx_eh_host_reset(struct Scsi_Host *shost);
 static int qla4xxx_slave_alloc(struct scsi_device *device);
 static umode_t qla4_attr_is_visible(int param_type, int param);
 static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
@@ -9367,17 +9367,17 @@ static int qla4xxx_is_eh_active(struct Scsi_Host *shost)
 
 /**
  * qla4xxx_eh_host_reset - kernel callback
- * @cmd: Pointer to Linux's SCSI command structure
+ * @host: Pointer to Linux's SCSI host structure
  *
  * This routine is invoked by the Linux kernel to perform fatal error
  * recovery on the specified adapter.
  **/
-static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
+static int qla4xxx_eh_host_reset(struct Scsi_Host *host)
 {
 	int return_status = FAILED;
 	struct scsi_qla_host *ha;
 
-	ha = to_qla_host(cmd->device->host);
+	ha = to_qla_host(host);
 
 	if ((is_qla8032(ha) || is_qla8042(ha)) && ql4xdontresethba)
 		qla4_83xx_set_idc_dontreset(ha);
@@ -9393,20 +9393,18 @@ static int qla4xxx_eh_host_reset(struct scsi_cmnd *cmd)
 		     ha->host_no, __func__));
 
 		/* Clear outstanding srb in queues */
-		if (qla4xxx_is_eh_active(cmd->device->host))
+		if (qla4xxx_is_eh_active(host))
 			qla4xxx_abort_active_cmds(ha, DID_ABORT << 16);
 
 		return FAILED;
 	}
 
 	ql4_printk(KERN_INFO, ha,
-		   "scsi(%ld:%d:%d:%llu): HOST RESET ISSUED.\n", ha->host_no,
-		   cmd->device->channel, cmd->device->id, cmd->device->lun);
+		   "scsi%ld: HOST RESET ISSUED.\n", ha->host_no);
 
 	if (qla4xxx_wait_for_hba_online(ha) != QLA_SUCCESS) {
-		DEBUG2(printk("scsi%ld:%d: %s: Unable to reset host.  Adapter "
-			      "DEAD.\n", ha->host_no, cmd->device->channel,
-			      __func__));
+		DEBUG2(printk("scsi%ld: %s: Unable to reset host.  Adapter "
+			      "DEAD.\n", ha->host_no, __func__));
 
 		return FAILED;
 	}
diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c
index 8b471a9..83a17ef 100644
--- a/drivers/scsi/qlogicfas408.c
+++ b/drivers/scsi/qlogicfas408.c
@@ -498,20 +498,18 @@ int qlogicfas408_abort(struct scsi_cmnd *cmd)
 
 /*
  *	Reset SCSI bus
- *	FIXME: This function is invoked with cmd = NULL directly by
- *	the PCMCIA qlogic_stub code. This wants fixing
  */
 
-int qlogicfas408_host_reset(struct scsi_cmnd *cmd)
+int qlogicfas408_host_reset(struct Scsi_Host *host)
 {
-	struct qlogicfas408_priv *priv = get_priv_by_cmd(cmd);
+	struct qlogicfas408_priv *priv = get_priv_by_host(host);
 	unsigned long flags;
 
 	priv->qabort = 2;
 
-	spin_lock_irqsave(cmd->device->host->host_lock, flags);
+	spin_lock_irqsave(host->host_lock, flags);
 	ql_zap(priv);
-	spin_unlock_irqrestore(cmd->device->host->host_lock, flags);
+	spin_unlock_irqrestore(host->host_lock, flags);
 
 	return SUCCESS;
 }
diff --git a/drivers/scsi/qlogicfas408.h b/drivers/scsi/qlogicfas408.h
index f6b1216..58459ba 100644
--- a/drivers/scsi/qlogicfas408.h
+++ b/drivers/scsi/qlogicfas408.h
@@ -108,7 +108,7 @@ int qlogicfas408_biosparam(struct scsi_device * disk,
 			   struct block_device *dev,
 			   sector_t capacity, int ip[]);
 int qlogicfas408_abort(struct scsi_cmnd * cmd);
-extern int qlogicfas408_host_reset(struct scsi_cmnd *cmd);
+extern int qlogicfas408_host_reset(struct Scsi_Host *host);
 const char *qlogicfas408_info(struct Scsi_Host *host);
 int qlogicfas408_get_chip_type(int qbase, int int_type);
 void qlogicfas408_setup(int qbase, int id, int int_type);
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index dc095a2..ebf525b 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3878,27 +3878,27 @@ static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
+static int scsi_debug_host_reset(struct Scsi_Host * shost)
 {
 	struct sdebug_host_info * sdbg_host;
 	struct sdebug_dev_info *devip;
 	int k = 0;
 
 	++num_host_resets;
-	if ((SCpnt->device) && (SDEBUG_OPT_ALL_NOISE & sdebug_opts))
-		sdev_printk(KERN_INFO, SCpnt->device, "%s\n", __func__);
-        spin_lock(&sdebug_host_list_lock);
-        list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
+	if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
+		shost_printk(KERN_INFO, shost, "%s\n", __func__);
+	spin_lock(&sdebug_host_list_lock);
+	list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
 		list_for_each_entry(devip, &sdbg_host->dev_info_list,
 				    dev_list) {
 			set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
 			++k;
 		}
-        }
-        spin_unlock(&sdebug_host_list_lock);
+	}
+	spin_unlock(&sdebug_host_list_lock);
 	stop_all_queued();
 	if (SDEBUG_OPT_RESET_NOISE & sdebug_opts)
-		sdev_printk(KERN_INFO, SCpnt->device,
+		shost_printk(KERN_INFO, shost,
 			    "%s: %d device(s) found\n", __func__, k);
 	return SUCCESS;
 }
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index ac31964..808167f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -745,7 +745,7 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
 	if (!hostt->eh_host_reset_handler)
 		return FAILED;
 
-	rtn = hostt->eh_host_reset_handler(scmd);
+	rtn = hostt->eh_host_reset_handler(host);
 
 	if (rtn == SUCCESS) {
 		if (!hostt->skip_settle_delay)
diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h
index 46837ee9..9171b90 100644
--- a/drivers/scsi/snic/snic.h
+++ b/drivers/scsi/snic/snic.h
@@ -380,8 +380,7 @@ struct snic_global {
 int snic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int snic_abort_cmd(struct scsi_cmnd *);
 int snic_device_reset(struct scsi_cmnd *);
-int snic_host_reset(struct scsi_cmnd *);
-int snic_reset(struct Scsi_Host *);
+int snic_host_reset(struct Scsi_Host *);
 void snic_shutdown_scsi_cleanup(struct snic *);
 
 
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 56b0eb4..ec11293 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -2307,8 +2307,15 @@
 	return ret;
 } /* end of snic_issue_hba_reset */
 
+/*
+ * SCSI Error handling calls driver's eh_host_reset if all prior
+ * error handling levels return FAILED.
+ *
+ * Host Reset is the highest level of error recovery. If this fails, then
+ * host is offlined by SCSI.
+ */
 int
-snic_reset(struct Scsi_Host *shost)
+snic_host_reset(struct Scsi_Host *shost)
 {
 	struct snic *snic = shost_priv(shost);
 	struct scsi_cmnd *sc = NULL;
@@ -2373,26 +2380,6 @@
 		 0, 0, 0);
 
 	return ret;
-} /* end of snic_reset */
-
-/*
- * SCSI Error handling calls driver's eh_host_reset if all prior
- * error handling levels return FAILED.
- *
- * Host Reset is the highest level of error recovery. If this fails, then
- * host is offlined by SCSI.
- */
-int
-snic_host_reset(struct scsi_cmnd *sc)
-{
-	struct Scsi_Host *shost = sc->device->host;
-
-	SNIC_SCSI_DBG(shost,
-		      "host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n",
-		      sc, sc->cmnd[0], sc->request,
-		      snic_cmd_tag(sc), CMD_FLAGS(sc));
-
-	return snic_reset(shost);
 } /* end of snic_host_reset */
 
 /*
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 9b20643..c8db82c 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -1441,14 +1441,13 @@ static int stex_do_reset(struct st_hba *hba)
 	return -1;
 }
 
-static int stex_reset(struct scsi_cmnd *cmd)
+static int stex_reset(struct Scsi_Host *shost)
 {
 	struct st_hba *hba;
 
-	hba = (struct st_hba *) &cmd->device->host->hostdata[0];
+	hba = (struct st_hba *) &shost->hostdata[0];
 
-	shost_printk(KERN_INFO, cmd->device->host,
-		     "resetting host\n");
+	shost_printk(KERN_INFO, shost, "resetting host\n");
 
 	return stex_do_reset(hba) ? FAILED : SUCCESS;
 }
diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c
index 3cc8d67..b6a58b8 100644
--- a/drivers/scsi/storvsc_drv.c
+++ b/drivers/scsi/storvsc_drv.c
@@ -1437,9 +1437,9 @@ static int storvsc_get_chs(struct scsi_device *sdev, struct block_device * bdev,
 	return 0;
 }
 
-static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd)
+static int storvsc_host_reset_handler(struct Scsi_Host *shost)
 {
-	struct hv_host_device *host_dev = shost_priv(scmnd->device->host);
+	struct hv_host_device *host_dev = shost_priv(shost);
 	struct hv_device *device = host_dev->dev;
 
 	struct storvsc_device *stor_device;
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index 5bdcbe8..78c6bac 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -723,12 +723,9 @@ const char *sym53c416_info(struct Scsi_Host *SChost)
 	int i;
 	int base = SChost->io_port;
 	int irq = SChost->irq;
-	int scsi_id = 0;
+	int scsi_id = SChost->this_id;
 	int rev = inb(base + TC_HIGH);
 
-	for(i = 0; i < host_index; i++)
-		if(hosts[i].base == base)
-			scsi_id = hosts[i].scsi_id;
 	sprintf(info, "Symbios Logic 53c416 (rev. %d) at 0x%03x, irq %d, SCSI-ID %d, %s pio", rev, base, irq, scsi_id, (fastpio)? "fast" : "slow");
 	return info;
 }
@@ -762,21 +759,18 @@ static int sym53c416_queuecommand_lck(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *
 
 DEF_SCSI_QCMD(sym53c416_queuecommand)
 
-static int sym53c416_host_reset(Scsi_Cmnd *SCpnt)
+static int sym53c416_host_reset(struct Scsi_Host *SChost)
 {
 	int base;
-	int scsi_id = -1;	
+	int scsi_id;
 	int i;
 	unsigned long flags;
 
 	spin_lock_irqsave(&sym53c416_lock, flags);
 
 	/* printk("sym53c416_reset\n"); */
-	base = SCpnt->device->host->io_port;
-	/* search scsi_id - fixme, we shouldn't need to iterate for this! */
-	for(i = 0; i < host_index && scsi_id == -1; i++)
-		if(hosts[i].base == base)
-			scsi_id = hosts[i].scsi_id;
+	base = SChost->io_port;
+	scsi_id = SChost->this_id;
 	outb(RESET_CHIP, base + COMMAND_REG);
 	outb(NOOP | PIO_MODE, base + COMMAND_REG);
 	outb(RESET_SCSI_BUS, base + COMMAND_REG);
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 5055469..9861c45 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -687,9 +687,8 @@ static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 	return SCSI_SUCCESS;
 }
 
-static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd)
+static int sym53c8xx_eh_host_reset_handler(struct Scsi_Host *shost)
 {
-	struct Scsi_Host *shost = cmd->device->host;
 	struct sym_data *sym_data = shost_priv(shost);
 	struct pci_dev *pdev = sym_data->pdev;
 	struct sym_hcb *np = sym_data->ncb;
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 88ccd63..47a8722 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -214,7 +214,7 @@ enum {
 static void ufshcd_tmc_handler(struct ufs_hba *hba);
 static void ufshcd_async_scan(void *data, async_cookie_t cookie);
 static int ufshcd_reset_and_restore(struct ufs_hba *hba);
-static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd);
+static int ufshcd_eh_host_reset_handler(struct Scsi_Host *shost);
 static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag);
 static void ufshcd_hba_exit(struct ufs_hba *hba);
 static int ufshcd_probe_hba(struct ufs_hba *hba);
@@ -5585,7 +5585,7 @@ static int ufshcd_abort(struct scsi_cmnd *cmd)
 	 * handling stage: reset and restore.
 	 */
 	if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN)
-		return ufshcd_eh_host_reset_handler(cmd);
+		return ufshcd_eh_host_reset_handler(host);
 
 	ufshcd_hold(hba, false);
 	reg = ufshcd_readl(hba, REG_UTP_TRANSFER_REQ_DOOR_BELL);
@@ -5791,13 +5791,13 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba)
  *
  * Returns SUCCESS/FAILED
  */
-static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd)
+static int ufshcd_eh_host_reset_handler(struct Scsi_Host *shost)
 {
 	int err;
 	unsigned long flags;
 	struct ufs_hba *hba;
 
-	hba = shost_priv(cmd->device->host);
+	hba = shost_priv(shost);
 
 	ufshcd_hold(hba, false);
 	/*
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index c374e3b..b99c58a 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -873,14 +873,13 @@ static void pvscsi_reset_all(struct pvscsi_adapter *adapter)
 	}
 }
 
-static int pvscsi_host_reset(struct scsi_cmnd *cmd)
+static int pvscsi_host_reset(struct Scsi_Host *host)
 {
-	struct Scsi_Host *host = cmd->device->host;
 	struct pvscsi_adapter *adapter = shost_priv(host);
 	unsigned long flags;
 	bool use_msg;
 
-	scmd_printk(KERN_INFO, cmd, "SCSI Host reset\n");
+	shost_printk(KERN_INFO, host, "SCSI Host reset\n");
 
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c
index 74be04f..815c9a9 100644
--- a/drivers/scsi/wd33c93.c
+++ b/drivers/scsi/wd33c93.c
@@ -1571,13 +1571,11 @@
 }
 
 int
-wd33c93_host_reset(struct scsi_cmnd * SCpnt)
+wd33c93_host_reset(struct Scsi_Host * instance)
 {
-	struct Scsi_Host *instance;
 	struct WD33C93_hostdata *hostdata;
 	int i;
 
-	instance = SCpnt->device->host;
 	spin_lock_irq(instance->host_lock);
 	hostdata = (struct WD33C93_hostdata *) instance->hostdata;
 
diff --git a/drivers/scsi/wd33c93.h b/drivers/scsi/wd33c93.h
index 08abe50..4d2d3cb 100644
--- a/drivers/scsi/wd33c93.h
+++ b/drivers/scsi/wd33c93.h
@@ -347,6 +347,6 @@ void wd33c93_init (struct Scsi_Host *instance, const wd33c93_regs regs,
 void wd33c93_intr (struct Scsi_Host *instance);
 int wd33c93_show_info(struct seq_file *, struct Scsi_Host *);
 int wd33c93_write_info(struct Scsi_Host *, char *, int);
-int wd33c93_host_reset (struct scsi_cmnd *);
+int wd33c93_host_reset (struct Scsi_Host *);
 
 #endif /* WD33C93_H */
diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c
index 2a9da2e..4c27913 100644
--- a/drivers/scsi/wd719x.c
+++ b/drivers/scsi/wd719x.c
@@ -510,9 +510,9 @@ static int wd719x_bus_reset(struct scsi_cmnd *cmd)
 	return wd719x_reset(cmd, WD719X_CMD_BUSRESET, 0);
 }
 
-static int wd719x_host_reset(struct scsi_cmnd *cmd)
+static int wd719x_host_reset(struct Scsi_Host *host)
 {
-	struct wd719x *wd = shost_priv(cmd->device->host);
+	struct wd719x *wd = shost_priv(host);
 	struct wd719x_scb *scb, *tmp;
 	unsigned long flags;
 	int result;
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index 811abfc..c58bf09 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -437,13 +437,13 @@ static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
 
 /*
  *	visorhba_host_reset_handler - Not supported
- *	@scsicmd: The scsicmd that needs aborted
+ *	@shost: The scsi host that needs resetting
  *
  *	Not supported, return SUCCESS
  *	Returns SUCCESS
  */
 static int
-visorhba_host_reset_handler(struct scsi_cmnd *scsicmd)
+visorhba_host_reset_handler(struct Scsi_Host *shost)
 {
 	/* issue TASK_MGMT_TARGET_RESET for each target on each bus for host */
 	return SUCCESS;
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
index a4dbb0c..178d39c 100644
--- a/drivers/usb/image/microtek.c
+++ b/drivers/usb/image/microtek.c
@@ -344,9 +344,9 @@ static int mts_scsi_abort(struct scsi_cmnd *srb)
 	return FAILED;
 }
 
-static int mts_scsi_host_reset(struct scsi_cmnd *srb)
+static int mts_scsi_host_reset(struct Scsi_Host *shost)
 {
-	struct mts_desc* desc = (struct mts_desc*)(srb->device->host->hostdata[0]);
+	struct mts_desc* desc = (struct mts_desc*)(shost->hostdata[0]);
 	int result;
 
 	MTS_DEBUG_GOT_HERE();
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index 2109844..fe4789d 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -953,7 +953,7 @@ static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc)
 int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fc_eh_abort(struct scsi_cmnd *);
 int fc_eh_device_reset(struct scsi_cmnd *);
-int fc_eh_host_reset(struct scsi_cmnd *);
+int fc_eh_host_reset(struct Scsi_Host *);
 int fc_slave_alloc(struct scsi_device *);
 
 /*
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index afb0481..b85f8a5 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -148,7 +148,7 @@ struct scsi_host_template {
 	int (* eh_device_reset_handler)(struct scsi_cmnd *);
 	int (* eh_target_reset_handler)(struct scsi_cmnd *);
 	int (* eh_bus_reset_handler)(struct scsi_cmnd *);
-	int (* eh_host_reset_handler)(struct scsi_cmnd *);
+	int (* eh_host_reset_handler)(struct Scsi_Host *);
 
 	/*
 	 * Before the mid layer attempts to scan for a new device where none
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 15/47] scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (13 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 14/47] scsi: Use Scsi_Host as argument for eh_host_reset_handler Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-07-24 16:34   ` Steffen Maier
  2017-06-28  8:32 ` [PATCH 16/47] mptfc: simplify mpt_fc_block_error_handler() Hannes Reinecke
                   ` (33 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

fc_block_scsi_eh() works on a remote port, so we should be using
that as an argument, and not the scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/s390/scsi/zfcp_scsi.c     |  6 ++++--
 drivers/scsi/bnx2fc/bnx2fc_io.c   |  4 ++--
 drivers/scsi/csiostor/csio_scsi.c |  4 ++--
 drivers/scsi/fnic/fnic_scsi.c     | 18 ++++++++++++------
 drivers/scsi/ibmvscsi/ibmvfc.c    |  9 ++++++---
 drivers/scsi/libfc/fc_fcp.c       |  5 +++--
 drivers/scsi/lpfc/lpfc_scsi.c     | 10 +++++++---
 drivers/scsi/qla2xxx/qla_os.c     | 21 +++++++++++++--------
 drivers/scsi/scsi_transport_fc.c  |  7 +++----
 include/scsi/scsi_transport_fc.h  |  2 +-
 10 files changed, 53 insertions(+), 33 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index d7d4a63..e3160fc 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -150,6 +150,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 	struct zfcp_adapter *adapter =
 		(struct zfcp_adapter *) scsi_host->hostdata[0];
 	struct zfcp_fsf_req *old_req, *abrt_req;
+	struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
 	unsigned long flags;
 	unsigned long old_reqid = (unsigned long) scpnt->host_scribble;
 	int retval = SUCCESS, ret;
@@ -176,7 +177,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 			break;
 
 		zfcp_erp_wait(adapter);
-		ret = fc_block_scsi_eh(scpnt);
+		ret = fc_block_scsi_eh(rport);
 		if (ret) {
 			zfcp_dbf_scsi_abort("abrt_bl", scpnt, NULL);
 			return ret;
@@ -262,6 +263,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 {
 	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
 	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
+	struct fc_port *rport = zfcp_sdev->port->rport;
 	struct zfcp_fsf_req *fsf_req = NULL;
 	int retval = SUCCESS, ret;
 	int retry = 3;
@@ -272,7 +274,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 			break;
 
 		zfcp_erp_wait(adapter);
-		ret = fc_block_scsi_eh(scpnt);
+		ret = fc_block_scsi_eh(rport);
 		if (ret)
 			return ret;
 
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 5b6153f..266a92e 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -691,7 +691,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 	}
 	rp = rport->dd_data;
 
-	rc = fc_block_scsi_eh(sc_cmd);
+	rc = fc_block_scsi_eh(rport);
 	if (rc)
 		return rc;
 
@@ -1119,7 +1119,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
 	struct bnx2fc_rport *tgt;
 	int rc;
 
-	rc = fc_block_scsi_eh(sc_cmd);
+	rc = fc_block_scsi_eh(rport);
 	if (rc)
 		return rc;
 
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index a1ff75f..93b6891 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -1920,7 +1920,7 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	int rv;
 	struct csio_rnode *rn = (struct csio_rnode *)(cmnd->device->hostdata);
 
-	ret = fc_block_scsi_eh(cmnd);
+	ret = fc_block_scsi_eh(rn->rport);
 	if (ret)
 		return ret;
 
@@ -2087,7 +2087,7 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	}
 
 	/* Lnode is ready, now wait on rport node readiness */
-	ret = fc_block_scsi_eh(cmnd);
+	ret = fc_block_scsi_eh(rn->rport);
 	if (ret)
 		return ret;
 
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 2716222..731ec87 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -1818,7 +1818,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
 	spinlock_t *io_lock;
 	unsigned long flags;
 	unsigned long start_time = 0;
-	int ret = SUCCESS;
+	int ret;
 	u32 task_req = 0;
 	struct scsi_lun fc_lun;
 	struct fnic_stats *fnic_stats;
@@ -1830,8 +1830,12 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
 	DECLARE_COMPLETION_ONSTACK(tm_done);
 
 	/* Wait for rport to unblock */
-	fc_block_scsi_eh(sc);
+	rport = starget_to_rport(scsi_target(sc->device));
+	ret = fc_block_scsi_eh(rport);
+	if (ret)
+		return ret;
 
+	ret = SUCCESS;
 	/* Get local-port, check ready and link up */
 	lp = shost_priv(sc->device->host);
 
@@ -1840,7 +1844,6 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
 	abts_stats = &fnic->fnic_stats.abts_stats;
 	term_stats = &fnic->fnic_stats.term_stats;
 
-	rport = starget_to_rport(scsi_target(sc->device));
 	tag = sc->request->tag;
 	FNIC_SCSI_DBG(KERN_DEBUG,
 		fnic->lport->host,
@@ -2336,7 +2339,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	struct fnic_io_req *io_req = NULL;
 	struct fc_rport *rport;
 	int status;
-	int ret = FAILED;
+	int ret;
 	spinlock_t *io_lock;
 	unsigned long flags;
 	unsigned long start_time = 0;
@@ -2349,8 +2352,12 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	bool new_sc = 0;
 
 	/* Wait for rport to unblock */
-	fc_block_scsi_eh(sc);
+	rport = starget_to_rport(scsi_target(sc->device));
+	ret = fc_block_scsi_eh(rport);
+	if (ret)
+		return ret;
 
+	ret = FAILED;
 	/* Get local-port, check ready and link up */
 	lp = shost_priv(sc->device->host);
 
@@ -2360,7 +2367,6 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 
 	atomic64_inc(&reset_stats->device_resets);
 
-	rport = starget_to_rport(scsi_target(sc->device));
 	FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
 		      "Device reset called FCID 0x%x, LUN 0x%llx sc 0x%p\n",
 		      rport->port_id, sc->device->lun, sc);
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 5dccf07..21f7e88 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2406,11 +2406,12 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd)
 {
 	struct scsi_device *sdev = cmd->device;
 	struct ibmvfc_host *vhost = shost_priv(sdev->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	int cancel_rc, block_rc;
 	int rc = FAILED;
 
 	ENTER;
-	block_rc = fc_block_scsi_eh(cmd);
+	block_rc = fc_block_scsi_eh(rport);
 	ibmvfc_wait_while_resetting(vhost);
 	if (block_rc != FAST_IO_FAIL) {
 		cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_ABORT_TASK_SET);
@@ -2439,11 +2440,12 @@ static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd)
 {
 	struct scsi_device *sdev = cmd->device;
 	struct ibmvfc_host *vhost = shost_priv(sdev->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	int cancel_rc, block_rc, reset_rc = 0;
 	int rc = FAILED;
 
 	ENTER;
-	block_rc = fc_block_scsi_eh(cmd);
+	block_rc = fc_block_scsi_eh(rport);
 	ibmvfc_wait_while_resetting(vhost);
 	if (block_rc != FAST_IO_FAIL) {
 		cancel_rc = ibmvfc_cancel_all(sdev, IBMVFC_TMF_LUN_RESET);
@@ -2497,13 +2499,14 @@ static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
 	struct scsi_device *sdev = cmd->device;
 	struct ibmvfc_host *vhost = shost_priv(sdev->host);
 	struct scsi_target *starget = scsi_target(sdev);
+	struct fc_rport *rport = starget_to_rport(starget);
 	int block_rc;
 	int reset_rc = 0;
 	int rc = FAILED;
 	unsigned long cancel_rc = 0;
 
 	ENTER;
-	block_rc = fc_block_scsi_eh(cmd);
+	block_rc = fc_block_scsi_eh(rport);
 	ibmvfc_wait_while_resetting(vhost);
 	if (block_rc != FAST_IO_FAIL) {
 		starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset);
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 2ec903a..ef6c8bc 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -2118,11 +2118,12 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
 	struct fc_fcp_pkt *fsp;
 	struct fc_lport *lport;
 	struct fc_fcp_internal *si;
+	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	int rc = FAILED;
 	unsigned long flags;
 	int rval;
 
-	rval = fc_block_scsi_eh(sc_cmd);
+	rval = fc_block_scsi_eh(rport);
 	if (rval)
 		return rval;
 
@@ -2174,7 +2175,7 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 	int rc = FAILED;
 	int rval;
 
-	rval = fc_block_scsi_eh(sc_cmd);
+	rval = fc_block_scsi_eh(rport);
 	if (rval)
 		return rval;
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 79981b9..db2716a 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -4696,6 +4696,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	struct lpfc_iocbq *iocb;
 	struct lpfc_iocbq *abtsiocb;
 	struct lpfc_scsi_buf *lpfc_cmd;
+	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	IOCB_t *cmd, *icmd;
 	int ret = SUCCESS, status = 0;
 	struct lpfc_sli_ring *pring_s4;
@@ -4703,7 +4704,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	unsigned long flags, iflags;
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(waitq);
 
-	status = fc_block_scsi_eh(cmnd);
+	status = fc_block_scsi_eh(rport);
 	if (status != 0 && status != SUCCESS)
 		return status;
 
@@ -5166,6 +5167,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	unsigned tgt_id = cmnd->device->id;
 	uint64_t lun_id = cmnd->device->lun;
 	struct lpfc_scsi_event_header scsi_event;
+	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int status;
 
 	rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
@@ -5176,7 +5178,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 		return FAILED;
 	}
 	pnode = rdata->pnode;
-	status = fc_block_scsi_eh(cmnd);
+	status = fc_block_scsi_eh(rport);
 	if (status != 0 && status != SUCCESS)
 		return status;
 
@@ -5237,6 +5239,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	unsigned tgt_id = cmnd->device->id;
 	uint64_t lun_id = cmnd->device->lun;
 	struct lpfc_scsi_event_header scsi_event;
+	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int status;
 
 	rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
@@ -5246,7 +5249,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 		return FAILED;
 	}
 	pnode = rdata->pnode;
-	status = fc_block_scsi_eh(cmnd);
+	status = fc_block_scsi_eh(rport);
 	if (status != 0 && status != SUCCESS)
 		return status;
 
@@ -5294,6 +5297,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 }
 
 /**
+_scsi_eh
  * lpfc_host_reset_handler - scsi_host_template eh_host_reset_handler entry pt
  * @cmnd: Pointer to scsi_cmnd data structure.
  *
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index fe2ff0a..35180aa 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1247,6 +1247,7 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 {
 	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
+	struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device));
 	srb_t *sp;
 	int ret;
 	unsigned int id;
@@ -1263,7 +1264,7 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 	if (!CMD_SP(cmd))
 		return SUCCESS;
 
-	ret = fc_block_scsi_eh(cmd);
+	ret = fc_block_scsi_eh(rport);
 	if (ret != 0)
 		return ret;
 	ret = SUCCESS;
@@ -1394,9 +1395,11 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 		return FAILED;
 	}
 
-	err = fc_block_scsi_eh(cmd);
-	if (err != 0)
-		return err;
+	if (fcport->rport) {
+		err = fc_block_scsi_eh(fcport->rport);
+		if (err != 0)
+			return err;
+	}
 
 	ql_log(ql_log_info, vha, 0x8009,
 	    "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no,
@@ -1507,10 +1510,12 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 		return ret;
 	}
 
-	ret = fc_block_scsi_eh(cmd);
-	if (ret != 0)
-		return ret;
-	ret = FAILED;
+	if (fcport->rport) {
+		ret = fc_block_scsi_eh(fcport->rport);
+		if (ret != 0)
+			return ret;
+		ret = FAILED;
+	}
 
 	ql_log(ql_log_info, vha, 0x8012,
 	    "BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun);
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
index 6dd0922..f83e512 100644
--- a/drivers/scsi/scsi_transport_fc.c
+++ b/drivers/scsi/scsi_transport_fc.c
@@ -3273,7 +3273,7 @@ struct fc_rport *
 
 /**
  * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
- * @cmnd: SCSI command that scsi_eh is trying to recover
+ * @rport: remote port to be checked
  *
  * This routine can be called from a FC LLD scsi_eh callback. It
  * blocks the scsi_eh thread until the fc_rport leaves the
@@ -3285,10 +3285,9 @@ struct fc_rport *
  *	    FAST_IO_FAIL if the fast_io_fail_tmo fired, this should be
  *	    passed back to scsi_eh.
  */
-int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
+int fc_block_scsi_eh(struct fc_rport *rport)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+	struct Scsi_Host *shost = rport_to_shost(rport);
 	unsigned long flags;
 
 	spin_lock_irqsave(shost->host_lock, flags);
diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
index e308cd5..5b26943 100644
--- a/include/scsi/scsi_transport_fc.h
+++ b/include/scsi/scsi_transport_fc.h
@@ -804,7 +804,7 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
 struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
 		struct fc_vport_identifiers *);
 int fc_vport_terminate(struct fc_vport *vport);
-int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
+int fc_block_scsi_eh(struct fc_rport *rport);
 enum blk_eh_timer_return fc_eh_timed_out(struct scsi_cmnd *scmd);
 
 static inline struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job)
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 16/47] mptfc: simplify mpt_fc_block_error_handler()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (14 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 15/47] scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 17/47] mptfusion: correct definitions for mptscsih_dev_reset() Hannes Reinecke
                   ` (32 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Instead of passing the a function we can as well return a status
and call the function directly afterwards.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/message/fusion/mptfc.c | 83 +++++++++++++++++++++++++++---------------
 1 file changed, 54 insertions(+), 29 deletions(-)

diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 6d461ca..da9e060 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -184,73 +184,98 @@
 };
 
 static int
-mptfc_block_error_handler(struct scsi_cmnd *SCpnt,
-			  int (*func)(struct scsi_cmnd *SCpnt),
-			  const char *caller)
+mptfc_block_error_handler(struct fc_rport *rport)
 {
 	MPT_SCSI_HOST		*hd;
-	struct scsi_device	*sdev = SCpnt->device;
-	struct Scsi_Host	*shost = sdev->host;
-	struct fc_rport		*rport = starget_to_rport(scsi_target(sdev));
+	struct Scsi_Host	*shost = rport_to_shost(rport);
 	unsigned long		flags;
 	int			ready;
-	MPT_ADAPTER 		*ioc;
+	MPT_ADAPTER		*ioc;
 	int			loops = 40;	/* seconds */
 
-	hd = shost_priv(SCpnt->device->host);
+	hd = shost_priv(shost);
 	ioc = hd->ioc;
 	spin_lock_irqsave(shost->host_lock, flags);
 	while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY
 	 || (loops > 0 && ioc->active == 0)) {
 		spin_unlock_irqrestore(shost->host_lock, flags);
 		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
-			"mptfc_block_error_handler.%d: %d:%llu, port status is "
-			"%x, active flag %d, deferring %s recovery.\n",
+			"mptfc_block_error_handler.%d: %s, port status is "
+			"%x, active flag %d, deferring recovery.\n",
 			ioc->name, ioc->sh->host_no,
-			SCpnt->device->id, SCpnt->device->lun,
-			ready, ioc->active, caller));
+			dev_name(&rport->dev), ready, ioc->active));
 		msleep(1000);
 		spin_lock_irqsave(shost->host_lock, flags);
 		loops --;
 	}
 	spin_unlock_irqrestore(shost->host_lock, flags);
 
-	if (ready == DID_NO_CONNECT || !SCpnt->device->hostdata
-	 || ioc->active == 0) {
+	if (ready == DID_NO_CONNECT || ioc->active == 0) {
 		dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
-			"%s.%d: %d:%llu, failing recovery, "
-			"port state %x, active %d, vdevice %p.\n", caller,
+			"mpt_block_error_handler.%d: %s, failing recovery, "
+			"port state %x, active %d.\n",
 			ioc->name, ioc->sh->host_no,
-			SCpnt->device->id, SCpnt->device->lun, ready,
-			ioc->active, SCpnt->device->hostdata));
+			dev_name(&rport->dev), ready, ioc->active));
 		return FAILED;
 	}
-	dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT
-		"%s.%d: %d:%llu, executing recovery.\n", caller,
-		ioc->name, ioc->sh->host_no,
-		SCpnt->device->id, SCpnt->device->lun));
-	return (*func)(SCpnt);
+	return SUCCESS;
 }
 
 static int
 mptfc_abort(struct scsi_cmnd *SCpnt)
 {
-	return
-	    mptfc_block_error_handler(SCpnt, mptscsih_abort, __func__);
+	struct Scsi_Host *shost = SCpnt->device->host;
+	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
+	MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
+	int rtn;
+
+	rtn = mptfc_block_error_handler(rport);
+	if (rtn == SUCCESS) {
+		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
+			"%s.%d: %d:%llu, executing recovery.\n", __func__,
+			hd->ioc->name, shost->host_no,
+			SCpnt->device->id, SCpnt->device->lun));
+		rtn = mptscsih_abort(SCpnt);
+	}
+	return rtn;
 }
 
 static int
 mptfc_dev_reset(struct scsi_cmnd *SCpnt)
 {
-	return
-	    mptfc_block_error_handler(SCpnt, mptscsih_dev_reset, __func__);
+	struct Scsi_Host *shost = SCpnt->device->host;
+	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
+	MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
+	int rtn;
+
+	rtn = mptfc_block_error_handler(rport);
+	if (rtn == SUCCESS) {
+		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
+			"%s.%d: %d:%llu, executing recovery.\n", __func__,
+			hd->ioc->name, shost->host_no,
+			SCpnt->device->id, SCpnt->device->lun));
+		rtn = mptscsih_dev_reset(SCpnt);
+	}
+	return rtn;
 }
 
 static int
 mptfc_bus_reset(struct scsi_cmnd *SCpnt)
 {
-	return
-	    mptfc_block_error_handler(SCpnt, mptscsih_bus_reset, __func__);
+	struct Scsi_Host *shost = SCpnt->device->host;
+	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
+	MPT_SCSI_HOST *hd = shost_priv(shost);
+	int rtn;
+
+	rtn = mptfc_block_error_handler(rport);
+	if (rtn == SUCCESS) {
+		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
+			"%s.%d: %d:%llu, executing recovery.\n", __func__,
+			hd->ioc->name, shost->host_no,
+			SCpnt->device->id, SCpnt->device->lun));
+		rtn = mptscsih_bus_reset(SCpnt);
+	}
+	return rtn;
 }
 
 static void
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 17/47] mptfusion: correct definitions for mptscsih_dev_reset()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (15 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 16/47] mptfc: simplify mpt_fc_block_error_handler() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 18/47] mptfc: open-code mptfc_block_error_handler() for bus reset Hannes Reinecke
                   ` (31 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

From: Hannes Reinecke <hare@suse.com>

mptscsih_dev_reset() is _not_ a device reset, but rather a
target reset. Nevertheless it's being used for either purpose.
This patch is adding a correct implementation for
mptscsih_dev_reset(), and renames the original function
to mptscsih_target_reset.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/message/fusion/mptscsih.c | 55 ++++++++++++++++++++++++++++++++++++++-
 drivers/message/fusion/mptscsih.h |  1 +
 2 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 0719d6d..6ca4799 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1792,7 +1792,7 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
- *	mptscsih_dev_reset - Perform a SCSI TARGET_RESET!  new_eh variant
+ *	mptscsih_dev_reset - Perform a SCSI LOGICAL_UNIT_RESET!
  *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  *
  *	(linux scsi_host_template.eh_dev_reset_handler routine)
@@ -1810,6 +1810,58 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
 	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
+		printk(KERN_ERR MYNAM ": lun reset: "
+		   "Can't locate host! (sc=%p)\n", SCpnt);
+		return FAILED;
+	}
+
+	ioc = hd->ioc;
+	printk(MYIOC_s_INFO_FMT "attempting lun reset! (sc=%p)\n",
+	       ioc->name, SCpnt);
+	scsi_print_command(SCpnt);
+
+	vdevice = SCpnt->device->hostdata;
+	if (!vdevice || !vdevice->vtarget) {
+		retval = 0;
+		goto out;
+	}
+
+	retval = mptscsih_IssueTaskMgmt(hd,
+				MPI_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET,
+				vdevice->vtarget->channel,
+				vdevice->vtarget->id, vdevice->lun, 0,
+				mptscsih_get_tm_timeout(ioc));
+
+ out:
+	printk (MYIOC_s_INFO_FMT "lun reset: %s (sc=%p)\n",
+	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+
+	if (retval == 0)
+		return SUCCESS;
+	else
+		return FAILED;
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+/**
+ *	mptscsih_target_reset - Perform a SCSI TARGET_RESET!
+ *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
+ *
+ *	(linux scsi_host_template.eh_target_reset_handler routine)
+ *
+ *	Returns SUCCESS or FAILED.
+ **/
+int
+mptscsih_target_reset(struct scsi_cmnd * SCpnt)
+{
+	MPT_SCSI_HOST	*hd;
+	int		 retval;
+	VirtDevice	 *vdevice;
+	MPT_ADAPTER	*ioc;
+
+	/* If we can't locate our host adapter structure, return FAILED status.
+	 */
+	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
 		printk(KERN_ERR MYNAM ": target reset: "
 		   "Can't locate host! (sc=%p)\n", SCpnt);
 		return FAILED;
@@ -3246,6 +3298,7 @@ struct device_attribute *mptscsih_host_attrs[] = {
 EXPORT_SYMBOL(mptscsih_slave_configure);
 EXPORT_SYMBOL(mptscsih_abort);
 EXPORT_SYMBOL(mptscsih_dev_reset);
+EXPORT_SYMBOL(mptscsih_target_reset);
 EXPORT_SYMBOL(mptscsih_bus_reset);
 EXPORT_SYMBOL(mptscsih_host_reset);
 EXPORT_SYMBOL(mptscsih_bios_param);
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 6ab8254..50af52a 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -120,6 +120,7 @@ extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
 extern int mptscsih_slave_configure(struct scsi_device *device);
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
 extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
+extern int mptscsih_target_reset(struct scsi_cmnd * SCpnt);
 extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
 extern int mptscsih_host_reset(struct Scsi_Host *sh);
 extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 18/47] mptfc: open-code mptfc_block_error_handler() for bus reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (16 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 17/47] mptfusion: correct definitions for mptscsih_dev_reset() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 19/47] pmcraid: Select device in pmcraid_eh_bus_reset_handler() Hannes Reinecke
                   ` (30 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When calling bus_reset we have potentially several ports to be
reset, so this patch open-codes the existing mptfc_block_error_handler()
to wait for all ports attached to this bus.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/message/fusion/mptfc.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index da9e060..ff886bc 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -263,12 +263,23 @@
 mptfc_bus_reset(struct scsi_cmnd *SCpnt)
 {
 	struct Scsi_Host *shost = SCpnt->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
 	MPT_SCSI_HOST *hd = shost_priv(shost);
+	int channel = SCpnt->device->channel;
+	struct mptfc_rport_info *ri;
 	int rtn;
 
-	rtn = mptfc_block_error_handler(rport);
-	if (rtn == SUCCESS) {
+	list_for_each_entry(ri, &hd->ioc->fc_rports, list) {
+		if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
+			VirtTarget *vtarget = ri->starget->hostdata;
+
+			if (!vtarget || vtarget->channel != channel)
+				continue;
+			rtn = fc_block_scsi_eh(ri->rport);
+			if (rtn != 0)
+				break;
+		}
+	}
+	if (rtn == 0) {
 		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
 			"%s.%d: %d:%llu, executing recovery.\n", __func__,
 			hd->ioc->name, shost->host_no,
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 19/47] pmcraid: Select device in pmcraid_eh_bus_reset_handler()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (17 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 18/47] mptfc: open-code mptfc_block_error_handler() for bus reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 20/47] scsi: Use Scsi_Host and channel number as argument for eh_bus_reset_handler() Hannes Reinecke
                   ` (29 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The reset code requires a device to be selected, but we shouldn't
rely on the command to provide a device for us. So select the first
device on the bus when sending down a bus reset.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/pmcraid.c | 46 ++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 4b66b92..9f0517d 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -2733,7 +2733,7 @@ static int pmcraid_error_handler(struct pmcraid_cmd *cmd)
  *	SUCCESS / FAILED
  */
 static int pmcraid_reset_device(
-	struct scsi_cmnd *scsi_cmd,
+	struct scsi_device *scsi_dev,
 	unsigned long timeout,
 	u8 modifier
 )
@@ -2746,11 +2746,11 @@ static int pmcraid_reset_device(
 	u32 ioasc;
 
 	pinstance =
-		(struct pmcraid_instance *)scsi_cmd->device->host->hostdata;
-	res = scsi_cmd->device->hostdata;
+		(struct pmcraid_instance *)scsi_dev->host->hostdata;
+	res = scsi_dev->hostdata;
 
 	if (!res) {
-		sdev_printk(KERN_ERR, scsi_cmd->device,
+		sdev_printk(KERN_ERR, scsi_dev,
 			    "reset_device: NULL resource pointer\n");
 		return FAILED;
 	}
@@ -3063,16 +3063,46 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
 {
 	scmd_printk(KERN_INFO, scmd,
 		    "resetting device due to an I/O command timeout.\n");
-	return pmcraid_reset_device(scmd,
+	return pmcraid_reset_device(scmd->device,
 				    PMCRAID_INTERNAL_TIMEOUT,
 				    RESET_DEVICE_LUN);
 }
 
 static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
 {
-	scmd_printk(KERN_INFO, scmd,
+	struct Scsi_Host *host = scmd->device->host;
+	struct pmcraid_instance *pinstance =
+		(struct pmcraid_instance *)host->hostdata;
+	struct pmcraid_resource_entry *res = NULL;
+	struct pmcraid_resource_entry *temp;
+	struct scsi_device *sdev = NULL;
+	unsigned long lock_flags;
+
+	/*
+	 * The reset device code insists on us passing down
+	 * a device, so grab the first device on the bus.
+	 */
+	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
+	list_for_each_entry(temp, &pinstance->used_res_q, queue) {
+		if (scmd->device->channel == PMCRAID_VSET_BUS_ID &&
+		    RES_IS_VSET(temp->cfg_entry)) {
+			res = temp;
+			break;
+		} else if (scmd->device->channel == PMCRAID_PHYS_BUS_ID &&
+			   RES_IS_GSCSI(temp->cfg_entry)) {
+			res = temp;
+			break;
+		}
+	}
+	if (res)
+		sdev = res->scsi_dev;
+	spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags);
+	if (!sdev)
+		return FAILED;
+
+	sdev_printk(KERN_INFO, sdev,
 		    "Doing bus reset due to an I/O command timeout.\n");
-	return pmcraid_reset_device(scmd,
+	return pmcraid_reset_device(sdev,
 				    PMCRAID_RESET_BUS_TIMEOUT,
 				    RESET_DEVICE_BUS);
 }
@@ -3081,7 +3111,7 @@ static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
 {
 	scmd_printk(KERN_INFO, scmd,
 		    "Doing target reset due to an I/O command timeout.\n");
-	return pmcraid_reset_device(scmd,
+	return pmcraid_reset_device(scmd->device,
 				    PMCRAID_INTERNAL_TIMEOUT,
 				    RESET_DEVICE_TARGET);
 }
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 20/47] scsi: Use Scsi_Host and channel number as argument for eh_bus_reset_handler()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (18 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 19/47] pmcraid: Select device in pmcraid_eh_bus_reset_handler() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 21/47] libiscsi: use cls_session as argument for target and session reset Hannes Reinecke
                   ` (28 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The bus reset should not depend on any command, but rather only
use the SCSI Host and the channel/bus number as argument.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 Documentation/scsi/scsi_eh.txt                  |  2 +-
 Documentation/scsi/scsi_mid_low_api.txt         |  5 ++--
 drivers/message/fusion/mptfc.c                  | 13 ++++-------
 drivers/message/fusion/mptscsih.c               | 21 +++++++----------
 drivers/message/fusion/mptscsih.h               |  2 +-
 drivers/scsi/a100u2w.c                          |  4 ++--
 drivers/scsi/aacraid/linit.c                    | 11 ++++-----
 drivers/scsi/aha1542.c                          |  4 ++--
 drivers/scsi/aic7xxx/aic79xx_osm.c              | 10 ++++----
 drivers/scsi/aic7xxx/aic7xxx_osm.c              |  6 ++---
 drivers/scsi/arcmsr/arcmsr_hba.c                |  9 +++----
 drivers/scsi/arm/fas216.c                       |  9 +++----
 drivers/scsi/arm/fas216.h                       |  5 ++--
 drivers/scsi/dc395x.c                           | 25 ++++++++++----------
 drivers/scsi/dpt_i2o.c                          |  9 +++----
 drivers/scsi/dpti.h                             |  2 +-
 drivers/scsi/esas2r/esas2r.h                    |  2 +-
 drivers/scsi/esas2r/esas2r_main.c               |  4 +---
 drivers/scsi/esp_scsi.c                         |  4 ++--
 drivers/scsi/gdth.c                             | 16 ++++---------
 drivers/scsi/initio.c                           | 11 +++++----
 drivers/scsi/ncr53c8xx.c                        |  4 ++--
 drivers/scsi/pcmcia/nsp_cs.c                    |  6 ++---
 drivers/scsi/pmcraid.c                          |  7 +++---
 drivers/scsi/qla1280.c                          | 10 ++++----
 drivers/scsi/qla2xxx/qla_os.c                   | 29 +++++------------------
 drivers/scsi/scsi_debug.c                       | 31 +++++++++----------------
 drivers/scsi/scsi_error.c                       |  2 +-
 drivers/scsi/sym53c8xx_2/sym_glue.c             |  7 +++---
 drivers/scsi/vmw_pvscsi.c                       |  5 ++--
 drivers/scsi/wd719x.c                           | 11 +++++----
 drivers/staging/unisys/visorhba/visorhba_main.c | 24 ++++++++++---------
 drivers/usb/storage/scsiglue.c                  |  4 ++--
 include/scsi/scsi_host.h                        |  2 +-
 34 files changed, 139 insertions(+), 177 deletions(-)

diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
index 78cd6b9..cb9f4bc22 100644
--- a/Documentation/scsi/scsi_eh.txt
+++ b/Documentation/scsi/scsi_eh.txt
@@ -207,7 +207,7 @@ considered to fail always.
 
 int (* eh_abort_handler)(struct scsi_cmnd *);
 int (* eh_device_reset_handler)(struct scsi_cmnd *);
-int (* eh_bus_reset_handler)(struct scsi_cmnd *);
+int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
 int (* eh_host_reset_handler)(struct Scsi_Host *);
 
  Higher-severity actions are taken only when lower-severity actions
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index ad517d5..e2609a63 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -855,7 +855,8 @@ Details:
 
 /**
  *      eh_bus_reset_handler - issue SCSI bus reset
- *      @scp: SCSI bus that contains this device should be reset
+ *      @shost: SCSI host that contains the bus which should be reset
+ *      @channel: Number of the SCSI bus which should be reset
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
@@ -868,7 +869,7 @@ Details:
  *
  *      Optionally defined in: LLD
  **/
-     int eh_bus_reset_handler(struct scsi_cmnd * scp)
+     int eh_bus_reset_handler(struct Scsi_Host * shost, int channel)
 
 
 /**
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index ff886bc..9e164af 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -103,7 +103,7 @@
 static void mptfc_remove(struct pci_dev *pdev);
 static int mptfc_abort(struct scsi_cmnd *SCpnt);
 static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
-static int mptfc_bus_reset(struct scsi_cmnd *SCpnt);
+static int mptfc_bus_reset(struct Scsi_Host *shost, int channel);
 
 static struct scsi_host_template mptfc_driver_template = {
 	.module				= THIS_MODULE,
@@ -260,11 +260,9 @@
 }
 
 static int
-mptfc_bus_reset(struct scsi_cmnd *SCpnt)
+mptfc_bus_reset(struct Scsi_Host *shost, int channel)
 {
-	struct Scsi_Host *shost = SCpnt->device->host;
 	MPT_SCSI_HOST *hd = shost_priv(shost);
-	int channel = SCpnt->device->channel;
 	struct mptfc_rport_info *ri;
 	int rtn;
 
@@ -281,10 +279,9 @@
 	}
 	if (rtn == 0) {
 		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
-			"%s.%d: %d:%llu, executing recovery.\n", __func__,
-			hd->ioc->name, shost->host_no,
-			SCpnt->device->id, SCpnt->device->lun));
-		rtn = mptscsih_bus_reset(SCpnt);
+			"%s.%d: 0:0, executing recovery.\n", __func__,
+			hd->ioc->name, shost->host_no));
+		rtn = mptscsih_bus_reset(shost, channel);
 	}
 	return rtn;
 }
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 6ca4799..ca79982 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1912,39 +1912,34 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
  *	Returns SUCCESS or FAILED.
  **/
 int
-mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
+mptscsih_bus_reset(struct Scsi_Host * shost, int channel)
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
-	VirtDevice	 *vdevice;
 	MPT_ADAPTER	*ioc;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
-	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
+	if ((hd = shost_priv(shost)) == NULL){
 		printk(KERN_ERR MYNAM ": bus reset: "
-		   "Can't locate host! (sc=%p)\n", SCpnt);
+		   "Can't locate host!\n");
 		return FAILED;
 	}
 
 	ioc = hd->ioc;
-	printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
-	       ioc->name, SCpnt);
-	scsi_print_command(SCpnt);
+	printk(MYIOC_s_INFO_FMT "attempting bus reset!\n",
+	       ioc->name);
 
 	if (ioc->timeouts < -1)
 		ioc->timeouts++;
 
-	vdevice = SCpnt->device->hostdata;
-	if (!vdevice || !vdevice->vtarget)
-		return SUCCESS;
 	retval = mptscsih_IssueTaskMgmt(hd,
 					MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-					vdevice->vtarget->channel, 0, 0, 0,
+					channel, 0, 0, 0,
 					mptscsih_get_tm_timeout(ioc));
 
-	printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
-	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+	printk(MYIOC_s_INFO_FMT "bus reset: %s\n",
+	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ));
 
 	if (retval == 0)
 		return SUCCESS;
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 50af52a..54f2604 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -121,7 +121,7 @@ extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
 extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
 extern int mptscsih_target_reset(struct scsi_cmnd * SCpnt);
-extern int mptscsih_bus_reset(struct scsi_cmnd * SCpnt);
+extern int mptscsih_bus_reset(struct Scsi_Host *, int);
 extern int mptscsih_host_reset(struct Scsi_Host *sh);
 extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
 extern int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 8086bd0..1c61d7a 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -956,10 +956,10 @@ static int inia100_abort(struct scsi_cmnd * cmd)
  Output         : None.
  Return         : pSRB  -       Pointer to SCSI request block.
 *****************************************************************************/
-static int inia100_bus_reset(struct scsi_cmnd * cmd)
+static int inia100_bus_reset(struct Scsi_Host * shost, int channel)
 {				/* I need Host Control Block Information */
 	struct orc_host *host;
-	host = (struct orc_host *) cmd->device->host->hostdata;
+	host = (struct orc_host *) shost->hostdata;
 	return orc_reset_scsi_bus(host);
 }
 
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index bef2c0d..1e157c6 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -998,20 +998,18 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
 
 /*
  *	aac_eh_bus_reset	- Bus reset command handling
- *	@scsi_cmd:	SCSI command block causing the reset
+ *	@host:	SCSI host causing the reset
+ *	@channel:	Number of the bus to be reset
  *
  */
-static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
+static int aac_eh_bus_reset(struct Scsi_Host *host, int channel)
 {
-	struct scsi_device * dev = cmd->device;
-	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
 	int count;
 	u32 cmd_bus;
 	int status = 0;
 
-
-	cmd_bus = aac_logical_to_phys(scmd_channel(cmd));
+	cmd_bus = aac_logical_to_phys(channel);
 	/* Mark the assoc. FIB to not complete, eh handler does this */
 	for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB); ++count) {
 		struct fib *fib = &aac->fibs[count];
@@ -1019,6 +1017,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
 		if (fib->hw_fib_va->header.XferState &&
 		    (fib->flags & FIB_CONTEXT_FLAG) &&
 		    (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) {
+			struct scsi_cmnd *cmd;
 			struct aac_hba_map_info *info;
 			u32 bus, cid;
 
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 3d4c404..ed44e1e 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -910,9 +910,9 @@ static int aha1542_reset(struct Scsi_Host *sh, u8 reset_cmd)
 	return SUCCESS;
 }
 
-static int aha1542_bus_reset(struct scsi_cmnd *cmd)
+static int aha1542_bus_reset(struct Scsi_Host *sh, int channel)
 {
-	return aha1542_reset(cmd->device->host, SCRST);
+	return aha1542_reset(sh, SCRST);
 }
 
 static int aha1542_host_reset(struct Scsi_Host *sh)
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 2588b8f..0797c2f 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -877,21 +877,21 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
  * Reset the SCSI bus.
  */
 static int
-ahd_linux_bus_reset(struct scsi_cmnd *cmd)
+ahd_linux_bus_reset(struct Scsi_Host *shost, int channel)
 {
 	struct ahd_softc *ahd;
 	int    found;
 	unsigned long flags;
 
-	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
+	ahd = *(struct ahd_softc **)shost->hostdata;
 #ifdef AHD_DEBUG
 	if ((ahd_debug & AHD_SHOW_RECOVERY) != 0)
-		printk("%s: Bus reset called for cmd %p\n",
-		       ahd_name(ahd), cmd);
+		printk("%s: Bus reset called for channel %d\n",
+		       ahd_name(ahd), channel);
 #endif
 	ahd_lock(ahd, &flags);
 
-	found = ahd_reset_channel(ahd, scmd_channel(cmd) + 'A',
+	found = ahd_reset_channel(ahd, channel + 'A',
 				  /*initiate reset*/TRUE);
 	ahd_unlock(ahd, &flags);
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index fc6a831..5f9d2ae 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -769,16 +769,16 @@ static DEF_SCSI_QCMD(ahc_linux_queue)
  * Reset the SCSI bus.
  */
 static int
-ahc_linux_bus_reset(struct scsi_cmnd *cmd)
+ahc_linux_bus_reset(struct Scsi_Host *shost, int channel)
 {
 	struct ahc_softc *ahc;
 	int    found;
 	unsigned long flags;
 
-	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+	ahc = *(struct ahc_softc **)shost->hostdata;
 
 	ahc_lock(ahc, &flags);
-	found = ahc_reset_channel(ahc, scmd_channel(cmd) + 'A',
+	found = ahc_reset_channel(ahc, channel + 'A',
 				  /*initiate reset*/TRUE);
 	ahc_unlock(ahc, &flags);
 
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index af032c4..7fe7e21 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -83,7 +83,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
 					struct scsi_cmnd *cmd);
 static int arcmsr_iop_confirm(struct AdapterControlBlock *acb);
 static int arcmsr_abort(struct scsi_cmnd *);
-static int arcmsr_bus_reset(struct scsi_cmnd *);
+static int arcmsr_bus_reset(struct Scsi_Host *, int);
 static int arcmsr_bios_param(struct scsi_device *sdev,
 		struct block_device *bdev, sector_t capacity, int *info);
 static int arcmsr_queue_command(struct Scsi_Host *h, struct scsi_cmnd *cmd);
@@ -3726,14 +3726,15 @@ static uint8_t arcmsr_iop_reset(struct AdapterControlBlock *acb)
 	return rtnval;
 }
 
-static int arcmsr_bus_reset(struct scsi_cmnd *cmd)
+static int arcmsr_bus_reset(struct Scsi_Host *shost, int channel)
 {
 	struct AdapterControlBlock *acb;
 	uint32_t intmask_org, outbound_doorbell;
 	int retry_count = 0;
 	int rtn = FAILED;
-	acb = (struct AdapterControlBlock *) cmd->device->host->hostdata;
-	printk(KERN_ERR "arcmsr: executing bus reset eh.....num_resets = %d, num_aborts = %d \n", acb->num_resets, acb->num_aborts);
+	acb = (struct AdapterControlBlock *) shost->hostdata;
+	printk(KERN_ERR "arcmsr: executing bus reset eh.....num_resets = %d, "
+	       "num_aborts = %d \n", acb->num_resets, acb->num_aborts);
 	acb->num_resets++;
 
 	switch(acb->adapter_type){
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index e4a08e8..c93ad3a 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2544,15 +2544,16 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 
 /**
  * fas216_eh_bus_reset - Reset the bus associated with the command
- * @SCpnt: command specifing bus to reset
+ * @shost: host to be reset
+ * @channel: bus number to reset
  *
- * Reset the bus associated with the command.
+ * Reset the bus.
  * Returns: FAILED if unable to reset.
  * Notes: Further commands are blocked.
  */
-int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
+int fas216_eh_bus_reset(struct Scsi_Host *shost, int channel)
 {
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
+	FAS216_Info *info = (FAS216_Info *)shost->hostdata;
 	unsigned long flags;
 	struct scsi_device *SDpnt;
 
diff --git a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
index e0e74ee..4ea1a38 100644
--- a/drivers/scsi/arm/fas216.h
+++ b/drivers/scsi/arm/fas216.h
@@ -378,10 +378,11 @@
 
 /* Function: int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt)
  * Purpose : Reset the complete bus associated with this command
- * Params  : SCpnt - command specifing bus to reset
+ * Params  : shost - host to be reset
+ *           channel - bus to be reset
  * Returns : FAILED if unable to reset
  */
-extern int fas216_eh_bus_reset(struct scsi_cmnd *SCpnt);
+extern int fas216_eh_bus_reset(struct Scsi_Host *shost, int channel);
 
 /* Function: int fas216_eh_host_reset(struct Scsi_Host *shost)
  * Purpose : Reset the host associated with this command
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 5ee7f44..0d2b7b6 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -1296,19 +1296,18 @@ static void reset_dev_param(struct AdapterCtlBlk *acb)
  * @cmd - some command for this host (for fetching hooks)
  * Returns: SUCCESS (0x2002) on success, else FAILED (0x2003).
  */
-static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+static int __dc395x_eh_bus_reset(struct Scsi_Host *shost, int channel)
 {
 	struct AdapterCtlBlk *acb =
-		(struct AdapterCtlBlk *)cmd->device->host->hostdata;
+		(struct AdapterCtlBlk *)shost->hostdata;
 	dprintkl(KERN_INFO,
-		"eh_bus_reset: (0%p) target=<%02i-%i> cmd=%p\n",
-		cmd, cmd->device->id, (u8)cmd->device->lun, cmd);
+		 "eh_bus_reset: bus=<%02i>\n", channel);
 
 	if (timer_pending(&acb->waiting_timer))
 		del_timer(&acb->waiting_timer);
 
 	/*
-	 * disable interrupt    
+	 * disable interrupt
 	 */
 	DC395x_write8(acb, TRM_S1040_DMA_INTEN, 0x00);
 	DC395x_write8(acb, TRM_S1040_SCSI_INTEN, 0x00);
@@ -1324,7 +1323,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
 	    HZ * acb->eeprom.delay_time;
 
 	/*
-	 * re-enable interrupt      
+	 * re-enable interrupt
 	 */
 	/* Clear SCSI FIFO          */
 	DC395x_write8(acb, TRM_S1040_DMA_CONTROL, CLRXFIFO);
@@ -1334,7 +1333,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
 	set_basic_config(acb);
 
 	reset_dev_param(acb);
-	doing_srb_done(acb, DID_RESET, cmd, 0);
+	doing_srb_done(acb, DID_RESET, NULL, 0);
 	acb->active_dcb = NULL;
 	acb->acb_flag = 0;	/* RESET_DETECT, RESET_DONE ,RESET_DEV */
 	waiting_process_next(acb);
@@ -1342,13 +1341,13 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
 	return SUCCESS;
 }
 
-static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd)
+static int dc395x_eh_bus_reset(struct Scsi_Host *shost, int channel)
 {
 	int rc;
 
-	spin_lock_irq(cmd->device->host->host_lock);
-	rc = __dc395x_eh_bus_reset(cmd);
-	spin_unlock_irq(cmd->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	rc = __dc395x_eh_bus_reset(shost, channel);
+	spin_unlock_irq(shost->host_lock);
 
 	return rc;
 }
@@ -3520,7 +3519,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
 
 /* abort all cmds in our queues */
 static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
-		struct scsi_cmnd *cmd, u8 force)
+			   struct scsi_cmnd *cmd, u8 force)
 {
 	struct DeviceCtlBlk *dcb;
 	dprintkl(KERN_INFO, "doing_srb_done: pids ");
@@ -3574,7 +3573,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag,
 			p->result = result;
 			pci_unmap_srb_sense(acb, srb);
 			pci_unmap_srb(acb, srb);
-			if (force) {
+			if (force && cmd) {
 				/* For new EH, we normally don't need to give commands back,
 				 * as they all complete or all time out */
 				cmd->scsi_done(cmd);
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index d28f4a4..da1c461 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -769,17 +769,18 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
 
 #define I2O_HBA_BUS_RESET 0x87
 // This version of bus reset is called by the eh_error handler
-static int adpt_bus_reset(struct scsi_cmnd* cmd)
+static int adpt_bus_reset(struct Scsi_Host *shost, int channel)
 {
 	adpt_hba* pHba;
 	u32 msg[4];
 	u32 rcode;
 
-	pHba = (adpt_hba*)cmd->device->host->hostdata[0];
+	pHba = (adpt_hba*)shost->hostdata[0];
 	memset(msg, 0, sizeof(msg));
-	printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->device->channel,pHba->channel[cmd->device->channel].tid );
+	printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",
+	       pHba->name, channel, pHba->channel[channel].tid );
 	msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
-	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
+	msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[channel].tid);
 	msg[2] = 0;
 	msg[3] = 0;
 	if (pHba->host)
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index ba88ceb..48a9139 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -39,7 +39,7 @@
 static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev,
 		sector_t, int geom[]);
 
-static int adpt_bus_reset(struct scsi_cmnd* cmd);
+static int adpt_bus_reset(struct Scsi_Host* shost, int channel);
 static int adpt_device_reset(struct scsi_cmnd* cmd);
 
 
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index d130a59..b63bab9 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -978,7 +978,7 @@ u8 handle_hba_ioctl(struct esas2r_adapter *a,
 int esas2r_eh_abort(struct scsi_cmnd *cmd);
 int esas2r_device_reset(struct scsi_cmnd *cmd);
 int esas2r_host_reset(struct Scsi_Host *shost);
-int esas2r_bus_reset(struct scsi_cmnd *cmd);
+int esas2r_bus_reset(struct Scsi_Host *shost, int channel);
 int esas2r_target_reset(struct scsi_cmnd *cmd);
 
 /* Internal functions */
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index 4f6dbc8..606bb82 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -1157,10 +1157,8 @@ int esas2r_host_reset(struct Scsi_Host *shost)
 	return esas2r_host_bus_reset(shost, true);
 }
 
-int esas2r_bus_reset(struct scsi_cmnd *cmd)
+int esas2r_bus_reset(struct Scsi_Host *shost, int channel)
 {
-	struct Scsi_Host *shost = cmd->device->host;
-
 	esas2r_log(ESAS2R_LOG_INFO, "bus_reset (%p)", shost);
 
 	return esas2r_host_bus_reset(shost, false);
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c
index 15185a0..0b5ff0d 100644
--- a/drivers/scsi/esp_scsi.c
+++ b/drivers/scsi/esp_scsi.c
@@ -2619,9 +2619,9 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd)
 	return FAILED;
 }
 
-static int esp_eh_bus_reset_handler(struct scsi_cmnd *cmd)
+static int esp_eh_bus_reset_handler(struct Scsi_Host *shost, int channel)
 {
-	struct esp *esp = shost_priv(cmd->device->host);
+	struct esp *esp = shost_priv(shost);
 	struct completion eh_reset;
 	unsigned long flags;
 
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c
index facc727..dbcd881 100644
--- a/drivers/scsi/gdth.c
+++ b/drivers/scsi/gdth.c
@@ -3911,9 +3911,9 @@ static enum blk_eh_timer_return gdth_timed_out(struct scsi_cmnd *scp)
 }
 
 
-static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
+static int gdth_eh_bus_reset(struct Scsi_Host *sh, int channel)
 {
-    gdth_ha_str *ha = shost_priv(scp->device->host);
+    gdth_ha_str *ha = shost_priv(sh);
     int i;
     unsigned long flags;
     Scsi_Cmnd *cmnd;
@@ -3921,7 +3921,7 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp)
 
     TRACE2(("gdth_eh_bus_reset()\n"));
 
-    b = scp->device->channel;
+    b = channel;
 
     /* clear command tab */
     spin_lock_irqsave(&ha->smp_lock, flags);
@@ -4467,7 +4467,6 @@ static int ioc_rescan(void __user *arg, char *cmnd)
 static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
 {
     gdth_ha_str *ha; 
-    Scsi_Cmnd *scp;
     unsigned long flags;
     char cmnd[MAX_COMMAND_SIZE];   
     void __user *argp = (void __user *)arg;
@@ -4588,15 +4587,8 @@ static int gdth_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
             (NULL == (ha = gdth_find_ha(res.ionode))))
             return -EFAULT;
 
-        scp  = kzalloc(sizeof(*scp), GFP_KERNEL);
-        if (!scp)
-            return -ENOMEM;
-        scp->device = ha->sdev;
-        scp->cmd_len = 12;
-        scp->device->channel = res.number;
-        rval = gdth_eh_bus_reset(scp);
+	rval = gdth_eh_bus_reset(ha->shost, res.number);
         res.status = (rval == SUCCESS ? S_OK : S_GENERR);
-        kfree(scp);
 
         if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset)))
             return -EFAULT;
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index 7a91cf3..b363e0a 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2644,20 +2644,21 @@ static DEF_SCSI_QCMD(i91u_queuecommand)
 
 /**
  *	i91u_bus_reset		-	reset the SCSI bus
- *	@cmnd: Command block we want to trigger the reset for
+ *	@shost: SCSI host to be reset
+ *	@channel: Bus number to be reset
  *
  *	Initiate a SCSI bus reset sequence
  */
 
-static int i91u_bus_reset(struct scsi_cmnd * cmnd)
+static int i91u_bus_reset(struct Scsi_Host * shost, int channel)
 {
 	struct initio_host *host;
 
-	host = (struct initio_host *) cmnd->device->host->hostdata;
+	host = (struct initio_host *) shost->hostdata;
 
-	spin_lock_irq(cmnd->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
 	initio_reset_scsi(host, 0);
-	spin_unlock_irq(cmnd->device->host->host_lock);
+	spin_unlock_irq(shost->host_lock);
 
 	return SUCCESS;
 }
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c
index 5b93ed8..f0fa8b4 100644
--- a/drivers/scsi/ncr53c8xx.c
+++ b/drivers/scsi/ncr53c8xx.c
@@ -8109,9 +8109,9 @@ static void ncr53c8xx_timeout(unsigned long npref)
 		ncr_flush_done_cmds(done_list);
 }
 
-static int ncr53c8xx_bus_reset(struct scsi_cmnd *cmd)
+static int ncr53c8xx_bus_reset(struct Scsi_Host *host, int channel)
 {
-	struct ncb *np = ((struct host_data *) cmd->device->host->hostdata)->ncb;
+	struct ncb *np = ((struct host_data *) host->hostdata)->ncb;
 	int sts;
 	unsigned long flags;
 	struct scsi_cmnd *done_list;
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index 48ec923..563bf21 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -1476,11 +1476,11 @@ static int nsp_bus_reset(nsp_hw_data *data)
 	return SUCCESS;
 }
 
-static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
+static int nsp_eh_bus_reset(struct Scsi_Host *host, int channel)
 {
-	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	nsp_hw_data *data = (nsp_hw_data *)host->hostdata;
 
-	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
+	nsp_dbg(NSP_DEBUG_BUSRESET, "channel=0x%d", channel);
 
 	return nsp_bus_reset(data);
 }
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 9f0517d..35a6e34 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3068,9 +3068,8 @@ static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
 				    RESET_DEVICE_LUN);
 }
 
-static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
+static int pmcraid_eh_bus_reset_handler(struct Scsi_Host *host, int channel)
 {
-	struct Scsi_Host *host = scmd->device->host;
 	struct pmcraid_instance *pinstance =
 		(struct pmcraid_instance *)host->hostdata;
 	struct pmcraid_resource_entry *res = NULL;
@@ -3084,11 +3083,11 @@ static int pmcraid_eh_bus_reset_handler(struct scsi_cmnd *scmd)
 	 */
 	spin_lock_irqsave(&pinstance->resource_lock, lock_flags);
 	list_for_each_entry(temp, &pinstance->used_res_q, queue) {
-		if (scmd->device->channel == PMCRAID_VSET_BUS_ID &&
+		if (channel == PMCRAID_VSET_BUS_ID &&
 		    RES_IS_VSET(temp->cfg_entry)) {
 			res = temp;
 			break;
-		} else if (scmd->device->channel == PMCRAID_PHYS_BUS_ID &&
+		} else if (channel == PMCRAID_PHYS_BUS_ID &&
 			   RES_IS_GSCSI(temp->cfg_entry)) {
 			res = temp;
 			break;
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index c6240ce..b5484a49 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -1017,13 +1017,15 @@ static void qla1280_mailbox_timeout(unsigned long __data)
  *     Reset the specified bus.
  **************************************************************************/
 static int
-qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
+qla1280_eh_bus_reset(struct Scsi_Host *shost, int bus)
 {
 	int rc;
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)shost->hostdata;
 
-	spin_lock_irq(cmd->device->host->host_lock);
-	rc = qla1280_error_action(cmd, BUS_RESET);
-	spin_unlock_irq(cmd->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	if (qla1280_bus_reset(ha, bus) == 0)
+		rc = qla1280_wait_for_pending_commands(ha, 1, 0);
+	spin_unlock_irq(shost->host_lock);
 
 	return rc;
 }
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 35180aa..a43f249 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -274,7 +274,7 @@
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
-static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
+static int qla2xxx_eh_bus_reset(struct Scsi_Host *, int);
 static int qla2xxx_eh_host_reset(struct Scsi_Host *);
 
 static void qla2x00_clear_drv_active(struct qla_hw_data *);
@@ -1488,13 +1488,10 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 *
 **************************************************************************/
 static int
-qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
+qla2xxx_eh_bus_reset(struct Scsi_Host *shost, int channel)
 {
-	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
-	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
+	scsi_qla_host_t *vha = shost_priv(shost);
 	int ret = FAILED;
-	unsigned int id;
-	uint64_t lun;
 	struct qla_hw_data *ha = vha->hw;
 
 	if (qla2x00_isp_reg_stat(ha)) {
@@ -1503,22 +1500,8 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 		return FAILED;
 	}
 
-	id = cmd->device->id;
-	lun = cmd->device->lun;
-
-	if (!fcport) {
-		return ret;
-	}
-
-	if (fcport->rport) {
-		ret = fc_block_scsi_eh(fcport->rport);
-		if (ret != 0)
-			return ret;
-		ret = FAILED;
-	}
-
 	ql_log(ql_log_info, vha, 0x8012,
-	    "BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun);
+	    "BUS RESET ISSUED channel=%ld:%d.\n", vha->host_no, channel);
 
 	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
 		ql_log(ql_log_fatal, vha, 0x8013,
@@ -1542,8 +1525,8 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 
 eh_bus_reset_done:
 	ql_log(ql_log_warn, vha, 0x802b,
-	    "BUS RESET %s nexus=%ld:%d:%llu.\n",
-	    (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, id, lun);
+	    "BUS RESET %s nexus=%ld:%d.\n",
+	    (ret == FAILED) ? "FAILED" : "SUCCEEDED", vha->host_no, channel);
 
 	return ret;
 }
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index ebf525b..1e89598 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3845,36 +3845,27 @@ static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
+static int scsi_debug_bus_reset(struct Scsi_Host * hp, int channel)
 {
-	struct sdebug_host_info *sdbg_host;
+	struct sdebug_host_info *sdbg_host =
+		*(struct sdebug_host_info **)shost_priv(hp);
 	struct sdebug_dev_info *devip;
-        struct scsi_device * sdp;
-        struct Scsi_Host * hp;
 	int k = 0;
 
 	++num_bus_resets;
-	if (!(SCpnt && SCpnt->device))
-		goto lie;
-	sdp = SCpnt->device;
 	if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
-		sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
-	hp = sdp->host;
-	if (hp) {
-		sdbg_host = *(struct sdebug_host_info **)shost_priv(hp);
-		if (sdbg_host) {
-			list_for_each_entry(devip,
-                                            &sdbg_host->dev_info_list,
-					    dev_list) {
-				set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
-				++k;
-			}
+		shost_printk(KERN_INFO, hp, "%s\n", __func__);
+	if (sdbg_host) {
+		list_for_each_entry(devip,
+				    &sdbg_host->dev_info_list,
+				    dev_list) {
+			set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
+			++k;
 		}
 	}
 	if (SDEBUG_OPT_RESET_NOISE & sdebug_opts)
-		sdev_printk(KERN_INFO, sdp,
+		shost_printk(KERN_INFO, hp,
 			    "%s: %d device(s) found in host\n", __func__, k);
-lie:
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 808167f..9dd51ed 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -775,7 +775,7 @@ static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
 	if (!hostt->eh_bus_reset_handler)
 		return FAILED;
 
-	rtn = hostt->eh_bus_reset_handler(scmd);
+	rtn = hostt->eh_bus_reset_handler(host, scmd_channel(scmd));
 
 	if (rtn == SUCCESS) {
 		if (!hostt->skip_settle_delay)
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 9861c45..69d23bb 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -664,14 +664,13 @@ static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
 	return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
 }
 
-static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
+static int sym53c8xx_eh_bus_reset_handler(struct Scsi_Host *shost, int channel)
 {
-	struct Scsi_Host *shost = cmd->device->host;
 	struct sym_data *sym_data = shost_priv(shost);
 	struct pci_dev *pdev = sym_data->pdev;
 	struct sym_hcb *np = sym_data->ncb;
 
-	scmd_printk(KERN_WARNING, cmd, "BUS RESET operation started\n");
+	shost_printk(KERN_WARNING, shost, "BUS RESET operation started\n");
 
 	/*
 	 * Escalate to host reset if the PCI bus went down
@@ -683,7 +682,7 @@ static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd)
 	sym_reset_scsi_bus(np, 1);
 	spin_unlock_irq(shost->host_lock);
 
-	dev_warn(&cmd->device->sdev_gendev, "BUS RESET operation complete.\n");
+	shost_printk(KERN_WARNING, shost, "BUS RESET operation complete.\n");
 	return SCSI_SUCCESS;
 }
 
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index b99c58a..521cd9e 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -926,13 +926,12 @@ static int pvscsi_host_reset(struct Scsi_Host *host)
 	return SUCCESS;
 }
 
-static int pvscsi_bus_reset(struct scsi_cmnd *cmd)
+static int pvscsi_bus_reset(struct Scsi_Host *host, int channel)
 {
-	struct Scsi_Host *host = cmd->device->host;
 	struct pvscsi_adapter *adapter = shost_priv(host);
 	unsigned long flags;
 
-	scmd_printk(KERN_INFO, cmd, "SCSI Bus reset\n");
+	shost_printk(KERN_INFO, host, "SCSI Bus reset\n");
 
 	/*
 	 * We don't want to queue new requests for this bus after
diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c
index 4c27913..a302943 100644
--- a/drivers/scsi/wd719x.c
+++ b/drivers/scsi/wd719x.c
@@ -481,11 +481,11 @@ static int wd719x_abort(struct scsi_cmnd *cmd)
 	return SUCCESS;
 }
 
-static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device)
+static int wd719x_reset(struct Scsi_Host *shost, u8 opcode, u8 device)
 {
 	int result;
 	unsigned long flags;
-	struct wd719x *wd = shost_priv(cmd->device->host);
+	struct wd719x *wd = shost_priv(shost);
 
 	dev_info(&wd->pdev->dev, "%s reset requested\n",
 		 (opcode == WD719X_CMD_BUSRESET) ? "bus" : "device");
@@ -502,12 +502,13 @@ static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device)
 
 static int wd719x_dev_reset(struct scsi_cmnd *cmd)
 {
-	return wd719x_reset(cmd, WD719X_CMD_RESET, cmd->device->id);
+	return wd719x_reset(cmd->device->host, WD719X_CMD_RESET,
+			    cmd->device->id);
 }
 
-static int wd719x_bus_reset(struct scsi_cmnd *cmd)
+static int wd719x_bus_reset(struct Scsi_Host *host, int channel)
 {
-	return wd719x_reset(cmd, WD719X_CMD_BUSRESET, 0);
+	return wd719x_reset(host, WD719X_CMD_BUSRESET, 0);
 }
 
 static int wd719x_host_reset(struct Scsi_Host *host)
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index c58bf09..ba66cd1 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -101,6 +101,10 @@ struct visorhba_devices_open {
 	struct visorhba_devdata *devdata;
 };
 
+#define for_each_vbus_match(iter, list, match) \
+	for (iter = &list->head; iter->next; iter = iter->next) \
+		if ((iter->channel == match->channel))
+
 /*
  *	visor_thread_start - starts a thread for the device
  *	@threadfn: Function the thread starts
@@ -413,25 +417,23 @@ static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
  *
  *	Returns SUCCESS
  */
-static int visorhba_bus_reset_handler(struct scsi_cmnd *scsicmd)
+static int visorhba_bus_reset_handler(struct Scsi_Host *scsihost, int channel)
 {
-	struct scsi_device *scsidev;
+	struct scsi_device *scsidev = NULL, *tmp;
 	struct visordisk_info *vdisk;
-	int rtn;
+	int rtn = SUCCESS;
 
-	scsidev = scsicmd->device;
-	shost_for_each_device(scsidev, scsidev->host) {
-		vdisk = scsidev->hostdata;
+	shost_for_each_device(tmp, scsihost) {
+		vdisk = tmp->hostdata;
 		if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
 			atomic_inc(&vdisk->error_count);
 		else
 			atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
+		if (!scsidev)
+			scsidev = tmp;
 	}
-	rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev);
-	if (rtn == SUCCESS) {
-		scsicmd->result = DID_RESET << 16;
-		scsicmd->scsi_done(scsicmd);
-	}
+	if (scsidev)
+		rtn = forward_taskmgmt_command(TASK_MGMT_BUS_RESET, scsidev);
 	return rtn;
 }
 
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 8cd2926..04f8fb7 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -465,9 +465,9 @@ static int device_reset(struct scsi_cmnd *srb)
 }
 
 /* Simulate a SCSI bus reset by resetting the device's USB port. */
-static int bus_reset(struct scsi_cmnd *srb)
+static int bus_reset(struct Scsi_Host *shost, int channel)
 {
-	struct us_data *us = host_to_us(srb->device->host);
+	struct us_data *us = host_to_us(shost);
 	int result;
 
 	usb_stor_dbg(us, "%s called\n", __func__);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index b85f8a5..0c5ce78 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -147,7 +147,7 @@ struct scsi_host_template {
 	int (* eh_abort_handler)(struct scsi_cmnd *);
 	int (* eh_device_reset_handler)(struct scsi_cmnd *);
 	int (* eh_target_reset_handler)(struct scsi_cmnd *);
-	int (* eh_bus_reset_handler)(struct scsi_cmnd *);
+	int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
 	int (* eh_host_reset_handler)(struct Scsi_Host *);
 
 	/*
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 21/47] libiscsi: use cls_session as argument for target and session reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (19 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 20/47] scsi: Use Scsi_Host and channel number as argument for eh_bus_reset_handler() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 22/47] bnx2fc: Do not rely on a scsi command when issueing lun or target reset Hannes Reinecke
                   ` (27 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

iscsi_eh_target_reset() and iscsi_eh_session_reset() only depend
on the cls_session, so use that as an argument.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/be2iscsi/be_main.c | 10 +++++++++-
 drivers/scsi/libiscsi.c         | 21 +++++++++------------
 include/scsi/libiscsi.h         |  2 +-
 3 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index f862332..b5a88ce 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -363,6 +363,14 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
 	return rc;
 }
 
+static int beiscsi_eh_session_reset(struct scsi_cmnd *sc)
+{
+	struct iscsi_cls_session *cls_session;
+
+	cls_session = starget_to_session(scsi_target(sc->device));
+	return iscsi_eh_session_reset(cls_session);
+}
+
 /*------------------- PCI Driver operations and data ----------------- */
 static const struct pci_device_id beiscsi_pci_id_table[] = {
 	{ PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -387,7 +395,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
 	.eh_timed_out = iscsi_eh_cmd_timed_out,
 	.eh_abort_handler = beiscsi_eh_abort,
 	.eh_device_reset_handler = beiscsi_eh_device_reset,
-	.eh_target_reset_handler = iscsi_eh_session_reset,
+	.eh_target_reset_handler = beiscsi_eh_session_reset,
 	.shost_attrs = beiscsi_attrs,
 	.sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
 	.can_queue = BE2_IO_DEPTH,
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 42381ad..5bc685c 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2378,13 +2378,11 @@ void iscsi_session_recovery_timedout(struct iscsi_cls_session *cls_session)
  * This function will wait for a relogin, session termination from
  * userspace, or a recovery/replacement timeout.
  */
-int iscsi_eh_session_reset(struct scsi_cmnd *sc)
+int iscsi_eh_session_reset(struct iscsi_cls_session *cls_session)
 {
-	struct iscsi_cls_session *cls_session;
 	struct iscsi_session *session;
 	struct iscsi_conn *conn;
 
-	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
 	conn = session->leadconn;
 
@@ -2431,7 +2429,7 @@ int iscsi_eh_session_reset(struct scsi_cmnd *sc)
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_session_reset);
 
-static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
+static void iscsi_prep_tgt_reset_pdu(struct iscsi_tm *hdr)
 {
 	memset(hdr, 0, sizeof(*hdr));
 	hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
@@ -2446,19 +2444,16 @@ static void iscsi_prep_tgt_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
  *
  * This will attempt to send a warm target reset.
  */
-static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
+static int iscsi_eh_target_reset(struct iscsi_cls_session *cls_session)
 {
-	struct iscsi_cls_session *cls_session;
 	struct iscsi_session *session;
 	struct iscsi_conn *conn;
 	struct iscsi_tm *hdr;
 	int rc = FAILED;
 
-	cls_session = starget_to_session(scsi_target(sc->device));
 	session = cls_session->dd_data;
 
-	ISCSI_DBG_EH(session, "tgt Reset [sc %p tgt %s]\n", sc,
-		     session->targetname);
+	ISCSI_DBG_EH(session, "tgt Reset [tgt %s]\n", session->targetname);
 
 	mutex_lock(&session->eh_mutex);
 	spin_lock_bh(&session->frwd_lock);
@@ -2476,7 +2471,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
 	conn->tmf_state = TMF_QUEUED;
 
 	hdr = &conn->tmhdr;
-	iscsi_prep_tgt_reset_pdu(sc, hdr);
+	iscsi_prep_tgt_reset_pdu(hdr);
 
 	if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age,
 				    session->tgt_reset_timeout)) {
@@ -2528,11 +2523,13 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc)
  */
 int iscsi_eh_recover_target(struct scsi_cmnd *sc)
 {
+	struct iscsi_cls_session *cls_session;
 	int rc;
 
-	rc = iscsi_eh_target_reset(sc);
+	cls_session = starget_to_session(scsi_target(sc->device));
+	rc = iscsi_eh_target_reset(cls_session);
 	if (rc == FAILED)
-		rc = iscsi_eh_session_reset(sc);
+		rc = iscsi_eh_session_reset(cls_session);
 	return rc;
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_recover_target);
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index c9bd935..d34daf8 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -382,7 +382,7 @@ struct iscsi_host {
  */
 extern int iscsi_eh_abort(struct scsi_cmnd *sc);
 extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
-extern int iscsi_eh_session_reset(struct scsi_cmnd *sc);
+extern int iscsi_eh_session_reset(struct iscsi_cls_session *cls_session);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
 extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
 extern enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 22/47] bnx2fc: Do not rely on a scsi command when issueing lun or target reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (20 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 21/47] libiscsi: use cls_session as argument for target and session reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 23/47] zfcp: do not rely on scsi command for debugging message Hannes Reinecke
                   ` (26 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When a LUN or target reset is issued we should not rely on a scsi
command to be present; this isn't very reliable and is going away
with the next patch anyway.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/bnx2fc/bnx2fc.h     |  1 +
 drivers/scsi/bnx2fc/bnx2fc_hwi.c | 14 ++++---
 drivers/scsi/bnx2fc/bnx2fc_io.c  | 89 +++++++++++++++++++---------------------
 3 files changed, 52 insertions(+), 52 deletions(-)

diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index 901a316..b9c101f 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -386,6 +386,7 @@ struct bnx2fc_rport {
 };
 
 struct bnx2fc_mp_req {
+	u64 tm_lun;
 	u8 tm_flags;
 
 	u32 req_len;
diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
index 913c750..e3d39dc 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c
@@ -1691,7 +1691,8 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
 	struct fcoe_cached_sge_ctx *cached_sge;
 	struct fcoe_ext_mul_sges_ctx *sgl;
 	int dev_type = tgt->dev_type;
-	u64 *fcp_cmnd;
+	struct fcp_cmnd *fcp_cmnd;
+	u64 *raw_fcp_cmnd;
 	u64 tmp_fcp_cmnd[4];
 	u32 context_id;
 	int cnt, i;
@@ -1760,16 +1761,19 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
 	task->txwr_rxrd.union_ctx.tx_seq.ctx.seq_cnt = 1;
 
 	/* Fill FCP_CMND IU */
-	fcp_cmnd = (u64 *)
+	fcp_cmnd = (struct fcp_cmnd *)&tmp_fcp_cmnd;
+	bnx2fc_build_fcp_cmnd(io_req, fcp_cmnd);
+	int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
+	memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
+	raw_fcp_cmnd = (u64 *)
 		    task->txwr_rxrd.union_ctx.fcp_cmd.opaque;
-	bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)&tmp_fcp_cmnd);
 
 	/* swap fcp_cmnd */
 	cnt = sizeof(struct fcp_cmnd) / sizeof(u64);
 
 	for (i = 0; i < cnt; i++) {
-		*fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]);
-		fcp_cmnd++;
+		*raw_fcp_cmnd = cpu_to_be64(tmp_fcp_cmnd[i]);
+		raw_fcp_cmnd++;
 	}
 
 	/* Rx Write Tx Read */
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 266a92e..3be742a 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -658,10 +658,9 @@ int bnx2fc_init_mp_req(struct bnx2fc_cmd *io_req)
 	return SUCCESS;
 }
 
-static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
+static int bnx2fc_initiate_tmf(struct fc_lport *lport, struct fc_rport *rport,
+			       u64 tm_lun, u8 tm_flags)
 {
-	struct fc_lport *lport;
-	struct fc_rport *rport;
 	struct fc_rport_libfc_priv *rp;
 	struct fcoe_port *port;
 	struct bnx2fc_interface *interface;
@@ -670,7 +669,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 	struct bnx2fc_mp_req *tm_req;
 	struct fcoe_task_ctx_entry *task;
 	struct fcoe_task_ctx_entry *task_page;
-	struct Scsi_Host *host = sc_cmd->device->host;
 	struct fc_frame_header *fc_hdr;
 	struct fcp_cmnd *fcp_cmnd;
 	int task_idx, index;
@@ -679,8 +677,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 	u32 sid, did;
 	unsigned long start = jiffies;
 
-	lport = shost_priv(host);
-	rport = starget_to_rport(scsi_target(sc_cmd->device));
 	port = lport_priv(lport);
 	interface = port->priv;
 
@@ -720,7 +716,7 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 		goto retry_tmf;
 	}
 	/* Initialize rest of io_req fields */
-	io_req->sc_cmd = sc_cmd;
+	io_req->sc_cmd = NULL;
 	io_req->port = port;
 	io_req->tgt = tgt;
 
@@ -738,11 +734,13 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 	/* Set TM flags */
 	io_req->io_req_flags = 0;
 	tm_req->tm_flags = tm_flags;
+	tm_req->tm_lun = tm_lun;
 
 	/* Fill FCP_CMND */
 	bnx2fc_build_fcp_cmnd(io_req, (struct fcp_cmnd *)tm_req->req_buf);
 	fcp_cmnd = (struct fcp_cmnd *)tm_req->req_buf;
-	memset(fcp_cmnd->fc_cdb, 0,  sc_cmd->cmd_len);
+	int_to_scsilun(tm_lun, &fcp_cmnd->fc_lun);
+	memset(fcp_cmnd->fc_cdb, 0,  BNX2FC_MAX_CMD_LEN);
 	fcp_cmnd->fc_dl = 0;
 
 	/* Fill FC header */
@@ -765,8 +763,6 @@ static int bnx2fc_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 	task = &(task_page[index]);
 	bnx2fc_init_mp_task(io_req, task);
 
-	sc_cmd->SCp.ptr = (char *)io_req;
-
 	/* Obtain free SQ entry */
 	spin_lock_bh(&tgt->tgt_lock);
 	bnx2fc_add_2_sq(tgt, xid);
@@ -1064,7 +1060,10 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req)
  */
 int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
 {
-	return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+	struct fc_lport *lport = shost_priv(rport_to_shost(rport));
+
+	return bnx2fc_initiate_tmf(lport, rport, 0, FCP_TMF_TGT_RESET);
 }
 
 /**
@@ -1077,7 +1076,11 @@ int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
  */
 int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 {
-	return bnx2fc_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
+	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+	struct fc_lport *lport = shost_priv(rport_to_shost(rport));
+
+	return bnx2fc_initiate_tmf(lport, rport, sc_cmd->device->lun,
+				   FCP_TMF_LUN_RESET);
 }
 
 static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req)
@@ -1394,10 +1397,9 @@ void bnx2fc_process_abts_compl(struct bnx2fc_cmd *io_req,
 
 static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
 {
-	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
 	struct bnx2fc_rport *tgt = io_req->tgt;
 	struct bnx2fc_cmd *cmd, *tmp;
-	u64 tm_lun = sc_cmd->device->lun;
+	struct bnx2fc_mp_req *tm_req = &io_req->mp_req;
 	u64 lun;
 	int rc = 0;
 
@@ -1409,8 +1411,10 @@ static void bnx2fc_lun_reset_cmpl(struct bnx2fc_cmd *io_req)
 	 */
 	list_for_each_entry_safe(cmd, tmp, &tgt->active_cmd_queue, link) {
 		BNX2FC_TGT_DBG(tgt, "LUN RST cmpl: scan for pending IOs\n");
+		if (!cmd->sc_cmd)
+			continue;
 		lun = cmd->sc_cmd->device->lun;
-		if (lun == tm_lun) {
+		if (lun == tm_req->tm_lun) {
 			/* Initiate ABTS on this cmd */
 			if (!test_and_set_bit(BNX2FC_FLAG_ISSUE_ABTS,
 					      &cmd->req_flags)) {
@@ -1513,32 +1517,32 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
 		printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n",
 			fc_hdr->fh_r_ctl);
 	}
-	if (!sc_cmd->SCp.ptr) {
-		printk(KERN_ERR PFX "tm_compl: SCp.ptr is NULL\n");
-		return;
-	}
-	switch (io_req->fcp_status) {
-	case FC_GOOD:
-		if (io_req->cdb_status == 0) {
-			/* Good IO completion */
-			sc_cmd->result = DID_OK << 16;
-		} else {
-			/* Transport status is good, SCSI status not good */
-			sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;
+	if (sc_cmd && sc_cmd->SCp.ptr) {
+		switch (io_req->fcp_status) {
+		case FC_GOOD:
+			if (io_req->cdb_status == 0) {
+				/* Good IO completion */
+				sc_cmd->result = DID_OK << 16;
+			} else {
+				/* Transport status is good, SCSI status not good */
+				sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;
+			}
+			if (io_req->fcp_resid)
+				scsi_set_resid(sc_cmd, io_req->fcp_resid);
+			break;
+
+		default:
+			BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n",
+				      io_req->fcp_status);
+			break;
 		}
-		if (io_req->fcp_resid)
-			scsi_set_resid(sc_cmd, io_req->fcp_resid);
-		break;
 
-	default:
-		BNX2FC_IO_DBG(io_req, "process_tm_compl: fcp_status = %d\n",
-			   io_req->fcp_status);
-		break;
-	}
-
-	sc_cmd = io_req->sc_cmd;
-	io_req->sc_cmd = NULL;
+		sc_cmd = io_req->sc_cmd;
+		io_req->sc_cmd = NULL;
 
+		sc_cmd->SCp.ptr = NULL;
+		sc_cmd->scsi_done(sc_cmd);
+	}
 	/* check if the io_req exists in tgt's tmf_q */
 	if (io_req->on_tmf_queue) {
 
@@ -1550,9 +1554,6 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
 		return;
 	}
 
-	sc_cmd->SCp.ptr = NULL;
-	sc_cmd->scsi_done(sc_cmd);
-
 	kref_put(&io_req->refcount, bnx2fc_cmd_release);
 	if (io_req->wait_for_comp) {
 		BNX2FC_IO_DBG(io_req, "tm_compl - wake up the waiter\n");
@@ -1670,15 +1671,9 @@ static void bnx2fc_unmap_sg_list(struct bnx2fc_cmd *io_req)
 void bnx2fc_build_fcp_cmnd(struct bnx2fc_cmd *io_req,
 				  struct fcp_cmnd *fcp_cmnd)
 {
-	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
-
 	memset(fcp_cmnd, 0, sizeof(struct fcp_cmnd));
 
-	int_to_scsilun(sc_cmd->device->lun, &fcp_cmnd->fc_lun);
-
 	fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
-	memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);
-
 	fcp_cmnd->fc_cmdref = 0;
 	fcp_cmnd->fc_pri_ta = 0;
 	fcp_cmnd->fc_tm_flags = io_req->mp_req.tm_flags;
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 23/47] zfcp: do not rely on scsi command for debugging message
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (21 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 22/47] bnx2fc: Do not rely on a scsi command when issueing lun or target reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function() Hannes Reinecke
                   ` (25 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When generating debugging messages the code should not rely on
a scsi command to be present.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/s390/scsi/zfcp_dbf.c  | 28 ++++++++++++++--------------
 drivers/s390/scsi/zfcp_dbf.h  | 10 +++++++---
 drivers/s390/scsi/zfcp_ext.h  |  4 ++--
 drivers/s390/scsi/zfcp_scsi.c |  9 ++++++---
 4 files changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
index d5bf36e..f825a30 100644
--- a/drivers/s390/scsi/zfcp_dbf.c
+++ b/drivers/s390/scsi/zfcp_dbf.c
@@ -535,11 +535,10 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
  * @sc: pointer to struct scsi_cmnd
  * @fsf: pointer to struct zfcp_fsf_req
  */
-void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
-		   struct zfcp_fsf_req *fsf)
+void zfcp_dbf_scsi(struct zfcp_adapter *adapter, char *tag, int level,
+		   int scsi_id, u64 scsi_lun,
+		   struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
 {
-	struct zfcp_adapter *adapter =
-		(struct zfcp_adapter *) sc->device->host->hostdata[0];
 	struct zfcp_dbf *dbf = adapter->dbf;
 	struct zfcp_dbf_scsi *rec = &dbf->scsi_buf;
 	struct fcp_resp_with_ext *fcp_rsp;
@@ -551,17 +550,18 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
 
 	memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
 	rec->id = ZFCP_DBF_SCSI_CMND;
-	rec->scsi_result = sc->result;
-	rec->scsi_retries = sc->retries;
-	rec->scsi_allowed = sc->allowed;
-	rec->scsi_id = sc->device->id;
+	rec->scsi_id = scsi_id;
 	/* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */
-	rec->scsi_lun = (u32)sc->device->lun;
-	rec->host_scribble = (unsigned long)sc->host_scribble;
-
-	memcpy(rec->scsi_opcode, sc->cmnd,
-	       min((int)sc->cmd_len, ZFCP_DBF_SCSI_OPCODE));
-
+	rec->scsi_lun = (u32)scsi_lun;
+	if (sc) {
+		rec->scsi_result = sc->result;
+		rec->scsi_retries = sc->retries;
+		rec->scsi_allowed = sc->allowed;
+		rec->host_scribble = (unsigned long)sc->host_scribble;
+
+		memcpy(rec->scsi_opcode, sc->cmnd,
+		       min((int)sc->cmd_len, ZFCP_DBF_SCSI_OPCODE));
+	}
 	if (fsf) {
 		rec->fsf_req_id = fsf->req_id;
 		fcp_rsp = (struct fcp_resp_with_ext *)
diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
index db186d4..09a9524 100644
--- a/drivers/s390/scsi/zfcp_dbf.h
+++ b/drivers/s390/scsi/zfcp_dbf.h
@@ -352,7 +352,8 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
 					scmd->device->host->hostdata[0];
 
 	if (debug_level_enabled(adapter->dbf->scsi, level))
-		zfcp_dbf_scsi(tag, level, scmd, req);
+		zfcp_dbf_scsi(adapter, tag, level, scmd->device->id,
+			      scmd->device->lun, scmd, req);
 }
 
 /**
@@ -401,17 +402,20 @@ void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd,
  * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
  */
 static inline
-void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
+void zfcp_dbf_scsi_devreset(struct zfcp_adapter *adapter, char *tag,
+			    int id, u64 lun, u8 flag)
 {
 	char tmp_tag[ZFCP_DBF_TAG_LEN];
 
+	if (!debug_level_enabled(adapter->dbf->scsi, 1))
+		return;
 	if (flag == FCP_TMF_TGT_RESET)
 		memcpy(tmp_tag, "tr_", 3);
 	else
 		memcpy(tmp_tag, "lr_", 3);
 
 	memcpy(&tmp_tag[3], tag, 4);
-	_zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
+	zfcp_dbf_scsi(adapter, tmp_tag, 1, id, lun, NULL, NULL);
 }
 
 /**
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 9afdbc3..57f1d4a 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -47,8 +47,8 @@ extern void zfcp_dbf_rec_run_lvl(int level, char *tag,
 extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
 extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
 extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
-extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *,
-			  struct zfcp_fsf_req *);
+extern void zfcp_dbf_scsi(struct zfcp_adapter *, char *, int, int,
+			  u64, struct scsi_cmnd *, struct zfcp_fsf_req *);
 
 /* zfcp_erp.c */
 extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index e3160fc..5fada93 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -280,7 +280,8 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 
 		if (!(atomic_read(&adapter->status) &
 		      ZFCP_STATUS_COMMON_RUNNING)) {
-			zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags);
+			zfcp_dbf_scsi_devreset(adapter, "nres", sdev->id,
+					       sdev->lun, tm_flags);
 			return SUCCESS;
 		}
 	}
@@ -290,10 +291,12 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 	wait_for_completion(&fsf_req->completion);
 
 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
-		zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
+		zfcp_dbf_scsi_devreset(adapter, "fail", sdev->id,
+				       sdev->lun, tm_flags);
 		retval = FAILED;
 	} else {
-		zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
+		zfcp_dbf_scsi_devreset(adapter, "okay", sdev->id,
+				       sdev->lun, tm_flags);
 		zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags);
 	}
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (22 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 23/47] zfcp: do not rely on scsi command for debugging message Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-07-24 17:15   ` Steffen Maier
  2017-06-28  8:32 ` [PATCH 25/47] ibmvfc: open-code reset loop for target reset Hannes Reinecke
                   ` (24 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

zfcp_task_mgmt_function() is only used for lun and device reset,
so it should be using the scsi device as an argument, not the
scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/s390/scsi/zfcp_ext.h  |  2 +-
 drivers/s390/scsi/zfcp_fc.h   |  9 +--------
 drivers/s390/scsi/zfcp_fsf.c  | 21 +++++++++++----------
 drivers/s390/scsi/zfcp_scsi.c | 12 ++++++------
 4 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
index 57f1d4a..64d4db7 100644
--- a/drivers/s390/scsi/zfcp_ext.h
+++ b/drivers/s390/scsi/zfcp_ext.h
@@ -117,7 +117,7 @@ extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
 			     struct zfcp_fsf_ct_els *, unsigned int);
 extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *);
 extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
-extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *, u8);
+extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *, u8);
 extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *);
 extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
 
diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
index df2b541..f08eaf9 100644
--- a/drivers/s390/scsi/zfcp_fc.h
+++ b/drivers/s390/scsi/zfcp_fc.h
@@ -206,19 +206,12 @@ struct zfcp_fc_wka_ports {
  * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
  * @fcp: fcp_cmnd to setup
  * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
- * @tm: task management flags to setup task management command
  */
 static inline
-void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi,
-			 u8 tm_flags)
+void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
 {
 	int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
 
-	if (unlikely(tm_flags)) {
-		fcp->fc_tm_flags = tm_flags;
-		return;
-	}
-
 	fcp->fc_pri_ta = FCP_PTA_SIMPLE;
 
 	if (scsi->sc_data_direction == DMA_FROM_DEVICE)
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index 27ff38f..c4bd3d4 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2036,10 +2036,9 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
 			    sizeof(blktrc));
 }
 
-static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
+static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req,
+					struct scsi_device *sdev)
 {
-	struct scsi_cmnd *scmnd = req->data;
-	struct scsi_device *sdev = scmnd->device;
 	struct zfcp_scsi_dev *zfcp_sdev;
 	struct fsf_qtcb_header *header = &req->qtcb->header;
 
@@ -2120,7 +2119,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)
 		return;
 	}
 
-	zfcp_fsf_fcp_handler_common(req);
+	zfcp_fsf_fcp_handler_common(req, scpnt->device);
 
 	if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) {
 		set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED);
@@ -2256,7 +2255,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
 		goto failed_scsi_cmnd;
 
 	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
-	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0);
+	zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd);
 
 	if (scsi_prot_sg_count(scsi_cmnd)) {
 		zfcp_qdio_set_data_div(qdio, &req->qdio_req,
@@ -2296,8 +2295,9 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
 {
 	struct fcp_resp_with_ext *fcp_rsp;
 	struct fcp_resp_rsp_info *rsp_info;
+	struct scsi_device *sdev = req->data;
 
-	zfcp_fsf_fcp_handler_common(req);
+	zfcp_fsf_fcp_handler_common(req, sdev);
 
 	fcp_rsp = (struct fcp_resp_with_ext *) &req->qtcb->bottom.io.fcp_rsp;
 	rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1];
@@ -2313,12 +2313,12 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
  * @tm_flags: unsigned byte for task management flags
  * Returns: on success pointer to struct fsf_req, NULL otherwise
  */
-struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
+struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
 					    u8 tm_flags)
 {
 	struct zfcp_fsf_req *req = NULL;
 	struct fcp_cmnd *fcp_cmnd;
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scmnd->device);
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
 	struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
 
 	if (unlikely(!(atomic_read(&zfcp_sdev->status) &
@@ -2338,7 +2338,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
 		goto out;
 	}
 
-	req->data = scmnd;
+	req->data = sdev;
 	req->handler = zfcp_fsf_fcp_task_mgmt_handler;
 	req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
 	req->qtcb->header.port_handle = zfcp_sdev->port->handle;
@@ -2349,7 +2349,8 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
 	zfcp_qdio_set_sbale_last(qdio, &req->qdio_req);
 
 	fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd;
-	zfcp_fc_scsi_to_fcp(fcp_cmnd, scmnd, tm_flags);
+	int_to_scsilun(sdev->lun, (struct scsi_lun *)&fcp_cmnd->fc_lun);
+	fcp_cmnd->fc_tm_flags = tm_flags;
 
 	zfcp_fsf_start_timer(req, ZFCP_SCSI_ER_TIMEOUT);
 	if (!zfcp_fsf_req_send(req))
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 5fada93..dd7bea0 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -259,17 +259,17 @@ static void zfcp_scsi_forget_cmnds(struct zfcp_scsi_dev *zsdev, u8 tm_flags)
 	write_unlock_irqrestore(&adapter->abort_lock, flags);
 }
 
-static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
+static int zfcp_task_mgmt_function(struct scsi_device *sdev, u8 tm_flags)
 {
-	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
+	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
 	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
-	struct fc_port *rport = zfcp_sdev->port->rport;
+	struct fc_rport *rport = zfcp_sdev->port->rport;
 	struct zfcp_fsf_req *fsf_req = NULL;
 	int retval = SUCCESS, ret;
 	int retry = 3;
 
 	while (retry--) {
-		fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags);
+		fsf_req = zfcp_fsf_fcp_task_mgmt(sdev, tm_flags);
 		if (fsf_req)
 			break;
 
@@ -306,12 +306,12 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
 
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 {
-	return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
+	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
 }
 
 static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
 {
-	return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
+	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_TGT_RESET);
 }
 
 static int zfcp_scsi_eh_host_reset_handler(struct Scsi_Host *host)
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 25/47] ibmvfc: open-code reset loop for target reset
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (23 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 26/47] lpfc: use rport as argument for lpfc_send_taskmgmt() Hannes Reinecke
                   ` (23 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

From: Hannes Reinecke <hare@suse.com>

For target reset we need a device to send the target reset to,
so open-code the loop in target reset to send the target reset TMF
to the correct device.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/ibmvscsi/ibmvfc.c | 39 +++++++++++++++++++++------------------
 1 file changed, 21 insertions(+), 18 deletions(-)

diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 21f7e88..2e2a613 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2476,18 +2476,6 @@ static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data)
 }
 
 /**
- * ibmvfc_dev_cancel_all_reset - Device iterated cancel all function
- * @sdev:	scsi device struct
- * @data:	return code
- *
- **/
-static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data)
-{
-	unsigned long *rc = data;
-	*rc |= ibmvfc_cancel_all(sdev, IBMVFC_TMF_TGT_RESET);
-}
-
-/**
  * ibmvfc_eh_target_reset_handler - Reset the target
  * @cmd:	scsi command struct
  *
@@ -2496,23 +2484,38 @@ static void ibmvfc_dev_cancel_all_reset(struct scsi_device *sdev, void *data)
  **/
 static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
 {
-	struct scsi_device *sdev = cmd->device;
-	struct ibmvfc_host *vhost = shost_priv(sdev->host);
-	struct scsi_target *starget = scsi_target(sdev);
+	struct scsi_target *starget = scsi_target(cmd->device);
 	struct fc_rport *rport = starget_to_rport(starget);
+	struct Scsi_Host *shost = rport_to_shost(rport);
+	struct ibmvfc_host *vhost = shost_priv(shost);
 	int block_rc;
 	int reset_rc = 0;
 	int rc = FAILED;
 	unsigned long cancel_rc = 0;
+	bool tgt_reset = false;
 
 	ENTER;
 	block_rc = fc_block_scsi_eh(rport);
 	ibmvfc_wait_while_resetting(vhost);
 	if (block_rc != FAST_IO_FAIL) {
-		starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_reset);
-		reset_rc = ibmvfc_reset_device(sdev, IBMVFC_TARGET_RESET, "target");
+		struct scsi_device *sdev;
+
+		shost_for_each_device(sdev, shost) {
+			if ((sdev->channel != starget->channel) ||
+			    (sdev->id != starget->id))
+				continue;
+
+			cancel_rc |= ibmvfc_cancel_all(sdev,
+						       IBMVFC_TMF_TGT_RESET);
+			if (!tgt_reset) {
+				reset_rc = ibmvfc_reset_device(sdev,
+					IBMVFC_TARGET_RESET, "target");
+				tgt_reset = true;
+			}
+		}
 	} else
-		starget_for_each_device(starget, &cancel_rc, ibmvfc_dev_cancel_all_noreset);
+		starget_for_each_device(starget, &cancel_rc,
+					ibmvfc_dev_cancel_all_noreset);
 
 	if (!cancel_rc && !reset_rc)
 		rc = ibmvfc_wait_for_ops(vhost, starget, ibmvfc_match_target);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 26/47] lpfc: use rport as argument for lpfc_send_taskmgmt()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (24 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 25/47] ibmvfc: open-code reset loop for target reset Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 27/47] lpfc: use rport as argument for lpfc_chk_tgt_mapped() Hannes Reinecke
                   ` (22 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Instead of passing in a scsi device we should be using the rport;
we already have the target and lun id as parameters, so there's
no need to pass the scsi device, too.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/lpfc/lpfc_scsi.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index db2716a..f100779 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -4954,7 +4954,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 /**
  * lpfc_send_taskmgmt - Generic SCSI Task Mgmt Handler
  * @vport: The virtual port for which this call is being executed.
- * @rdata: Pointer to remote port local data
+ * @rport: Pointer to remote port
  * @tgt_id: Target ID of remote device.
  * @lun_id: Lun number for the TMF
  * @task_mgmt_cmd: type of TMF to send
@@ -4967,7 +4967,7 @@ void lpfc_poll_timeout(unsigned long ptr)
  *   0x2002 - Success.
  **/
 static int
-lpfc_send_taskmgmt(struct lpfc_vport *vport, struct scsi_cmnd *cmnd,
+lpfc_send_taskmgmt(struct lpfc_vport *vport, struct fc_rport *rport,
 		   unsigned int tgt_id, uint64_t lun_id,
 		   uint8_t task_mgmt_cmd)
 {
@@ -4980,7 +4980,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	int ret;
 	int status;
 
-	rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
+	rdata = rport->dd_data;
 	if (!rdata || !rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode))
 		return FAILED;
 	pnode = rdata->pnode;
@@ -4990,7 +4990,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 		return FAILED;
 	lpfc_cmd->timeout = phba->cfg_task_mgmt_tmo;
 	lpfc_cmd->rdata = rdata;
-	lpfc_cmd->pCmd = cmnd;
+	lpfc_cmd->pCmd = NULL;
 
 	status = lpfc_scsi_prep_task_mgmt_cmd(vport, lpfc_cmd, lun_id,
 					   task_mgmt_cmd);
@@ -5198,7 +5198,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	fc_host_post_vendor_event(shost, fc_get_event_number(),
 		sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
 
-	status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id,
+	status = lpfc_send_taskmgmt(vport, rport, tgt_id, lun_id,
 						FCP_LUN_RESET);
 
 	lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
@@ -5277,7 +5277,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	fc_host_post_vendor_event(shost, fc_get_event_number(),
 		sizeof(scsi_event), (char *)&scsi_event, LPFC_NL_VENDOR_ID);
 
-	status = lpfc_send_taskmgmt(vport, cmnd, tgt_id, lun_id,
+	status = lpfc_send_taskmgmt(vport, rport, tgt_id, lun_id,
 					FCP_TARGET_RESET);
 
 	lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 27/47] lpfc: use rport as argument for lpfc_chk_tgt_mapped()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (25 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 26/47] lpfc: use rport as argument for lpfc_send_taskmgmt() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 28/47] qla2xxx: open-code qla2xxx_generic_reset() Hannes Reinecke
                   ` (21 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

We only need the rport structure for lpfc_chk_tgt_mapped().

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/lpfc/lpfc_scsi.c | 24 ++++++++++--------------
 1 file changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index f100779..107c0f6 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5055,7 +5055,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 /**
  * lpfc_chk_tgt_mapped -
  * @vport: The virtual port to check on
- * @cmnd: Pointer to scsi_cmnd data structure.
+ * @rport: Pointer to fc_rport data structure.
  *
  * This routine delays until the scsi target (aka rport) for the
  * command exists (is present and logged in) or we declare it non-existent.
@@ -5065,19 +5065,15 @@ void lpfc_poll_timeout(unsigned long ptr)
  *  0x2002 - Success
  **/
 static int
-lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct scsi_cmnd *cmnd)
+lpfc_chk_tgt_mapped(struct lpfc_vport *vport, struct fc_rport *rport)
 {
 	struct lpfc_rport_data *rdata;
-	struct lpfc_nodelist *pnode;
+	struct lpfc_nodelist *pnode = NULL;
 	unsigned long later;
 
-	rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
-	if (!rdata) {
-		lpfc_printf_vlog(vport, KERN_INFO, LOG_FCP,
-			"0797 Tgt Map rport failure: rdata x%p\n", rdata);
-		return FAILED;
-	}
-	pnode = rdata->pnode;
+	rdata = rport->dd_data;
+	if (rdata)
+		pnode = rdata->pnode;
 	/*
 	 * If target is not in a MAPPED state, delay until
 	 * target is rediscovered or devloss timeout expires.
@@ -5089,7 +5085,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 		if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
 			return SUCCESS;
 		schedule_timeout_uninterruptible(msecs_to_jiffies(500));
-		rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
+		rdata = rport->dd_data;
 		if (!rdata)
 			return FAILED;
 		pnode = rdata->pnode;
@@ -5182,7 +5178,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	if (status != 0 && status != SUCCESS)
 		return status;
 
-	status = lpfc_chk_tgt_mapped(vport, cmnd);
+	status = lpfc_chk_tgt_mapped(vport, rport);
 	if (status == FAILED) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
 			"0721 Device Reset rport failure: rdata x%p\n", rdata);
@@ -5242,7 +5238,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int status;
 
-	rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
+	rdata = rport->dd_data;
 	if (!rdata) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
 			"0799 Target Reset rport failure: rdata x%p\n", rdata);
@@ -5253,7 +5249,7 @@ void lpfc_poll_timeout(unsigned long ptr)
 	if (status != 0 && status != SUCCESS)
 		return status;
 
-	status = lpfc_chk_tgt_mapped(vport, cmnd);
+	status = lpfc_chk_tgt_mapped(vport, rport);
 	if (status == FAILED) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
 			"0722 Target Reset rport failure: rdata x%p\n", rdata);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 28/47] qla2xxx: open-code qla2xxx_generic_reset()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (26 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 27/47] lpfc: use rport as argument for lpfc_chk_tgt_mapped() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 29/47] qedf: use fc rport as argument for qedf_initiate_tmf() Hannes Reinecke
                   ` (20 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Device and target reset will be using different calling sequences,
so there's not point in trying to combine both.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/qla2xxx/qla_os.c | 106 ++++++++++++++++++++++++++++--------------
 1 file changed, 71 insertions(+), 35 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index a43f249..c068041 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -1384,13 +1384,20 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 };
 
 static int
-__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
-    struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, uint64_t, int))
+qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
 {
-	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
-	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
+	struct scsi_device *sdev = cmd->device;
+	scsi_qla_host_t *vha = shost_priv(sdev->host);
+	struct qla_hw_data *ha = vha->hw;
+	fc_port_t *fcport = (struct fc_port *) sdev->hostdata;
 	int err;
 
+	if (qla2x00_isp_reg_stat(ha)) {
+		ql_log(ql_log_info, vha, 0x803e,
+		    "PCI/Register disconnect, exiting.\n");
+		return FAILED;
+	}
+
 	if (!fcport) {
 		return FAILED;
 	}
@@ -1402,74 +1409,103 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 	}
 
 	ql_log(ql_log_info, vha, 0x8009,
-	    "%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no,
-	    cmd->device->id, cmd->device->lun, cmd);
+	    "DEVICE RESET ISSUED nexus=%ld:%d:%llu\n", vha->host_no,
+	    sdev->id, sdev->lun);
 
 	err = 0;
 	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x800a,
-		    "Wait for hba online failed for cmd=%p.\n", cmd);
+		    "Wait for hba online failed.\n");
 		goto eh_reset_failed;
 	}
 	err = 2;
-	if (do_reset(fcport, cmd->device->lun, cmd->request->cpu + 1)
+	if (ha->isp_ops->lun_reset(fcport, sdev->lun, smp_processor_id() + 1)
 		!= QLA_SUCCESS) {
-		ql_log(ql_log_warn, vha, 0x800c,
-		    "do_reset failed for cmd=%p.\n", cmd);
+		ql_log(ql_log_warn, vha, 0x800c, "lun_reset failed.\n");
 		goto eh_reset_failed;
 	}
 	err = 3;
-	if (qla2x00_eh_wait_for_pending_commands(vha, cmd->device->id,
-	    cmd->device->lun, type) != QLA_SUCCESS) {
+	if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
+		sdev->lun, WAIT_LUN) != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x800d,
-		    "wait for pending cmds failed for cmd=%p.\n", cmd);
+		       "wait for pending cmds failed.\n");
 		goto eh_reset_failed;
 	}
 
 	ql_log(ql_log_info, vha, 0x800e,
-	    "%s RESET SUCCEEDED nexus:%ld:%d:%llu cmd=%p.\n", name,
-	    vha->host_no, cmd->device->id, cmd->device->lun, cmd);
+	    "DEVICE RESET SUCCEEDED nexus:%ld:%d:%llu\n",
+	    vha->host_no, sdev->id, sdev->lun);
 
 	return SUCCESS;
 
 eh_reset_failed:
 	ql_log(ql_log_info, vha, 0x800f,
-	    "%s RESET FAILED: %s nexus=%ld:%d:%llu cmd=%p.\n", name,
-	    reset_errors[err], vha->host_no, cmd->device->id, cmd->device->lun,
-	    cmd);
+	    "DEVICE RESET FAILED: %s nexus=%ld:%d:%llu\n",
+	    reset_errors[err], vha->host_no, sdev->id, sdev->lun);
 	return FAILED;
 }
 
 static int
-qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
+qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
 {
-	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
+	struct scsi_device *sdev = cmd->device;
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+	scsi_qla_host_t *vha = shost_priv(rport_to_shost(rport));
 	struct qla_hw_data *ha = vha->hw;
+	fc_port_t *fcport = (struct fc_port *) rport->dd_data;
+	int err;
 
 	if (qla2x00_isp_reg_stat(ha)) {
-		ql_log(ql_log_info, vha, 0x803e,
+		ql_log(ql_log_info, vha, 0x803f,
 		    "PCI/Register disconnect, exiting.\n");
 		return FAILED;
 	}
 
-	return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
-	    ha->isp_ops->lun_reset);
-}
+	if (!fcport) {
+		return FAILED;
+	}
 
-static int
-qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
-{
-	scsi_qla_host_t *vha = shost_priv(cmd->device->host);
-	struct qla_hw_data *ha = vha->hw;
+	if (fcport->rport) {
+		err = fc_block_scsi_eh(fcport->rport);
+		if (err != 0)
+			return err;
+	}
 
-	if (qla2x00_isp_reg_stat(ha)) {
-		ql_log(ql_log_info, vha, 0x803f,
-		    "PCI/Register disconnect, exiting.\n");
-		return FAILED;
+	ql_log(ql_log_info, vha, 0x8009,
+	    "TARGET RESET ISSUED nexus=%ld:%d:0.\n", vha->host_no,
+	    cmd->device->id);
+
+	err = 0;
+	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
+		ql_log(ql_log_warn, vha, 0x800a,
+		    "Wait for hba online failed.\n");
+		goto eh_reset_failed;
+	}
+	err = 2;
+	if (ha->isp_ops->target_reset(fcport, 0, smp_processor_id() + 1)
+	    != QLA_SUCCESS) {
+		ql_log(ql_log_warn, vha, 0x800c, "do_reset failed.\n");
+		goto eh_reset_failed;
+	}
+	err = 3;
+	if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
+		0, WAIT_TARGET) != QLA_SUCCESS) {
+		ql_log(ql_log_warn, vha, 0x800d,
+		       "wait for pending cmds failed.\n");
+		goto eh_reset_failed;
 	}
 
-	return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
-	    ha->isp_ops->target_reset);
+	ql_log(ql_log_info, vha, 0x800e,
+	    "TARGET RESET SUCCEEDED nexus:%ld:%d:0.\n",
+	    vha->host_no, sdev->id);
+
+	return SUCCESS;
+
+eh_reset_failed:
+	ql_log(ql_log_info, vha, 0x800f,
+	    "TARGET RESET FAILED: %s nexus=%ld:%d:0\n",
+	    reset_errors[err], vha->host_no, sdev->id);
+	return FAILED;
 }
 
 /**************************************************************************
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 29/47] qedf: use fc rport as argument for qedf_initiate_tmf()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (27 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 28/47] qla2xxx: open-code qla2xxx_generic_reset() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 30/47] sym53c8xx_2: rework reset handling Hannes Reinecke
                   ` (19 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When sending a TMF we're only concerned with the rport and the LUN ID,
so use struct fc_rport as argument for qedf_initiate_tmf().

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/qedf/qedf.h      |  5 +++--
 drivers/scsi/qedf/qedf_io.c   | 48 +++++++++++++++++++------------------------
 drivers/scsi/qedf/qedf_main.c |  9 ++++++--
 3 files changed, 31 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h
index 4d03892..dcd51d6 100644
--- a/drivers/scsi/qedf/qedf.h
+++ b/drivers/scsi/qedf/qedf.h
@@ -119,6 +119,7 @@ struct qedf_ioreq {
 #define QEDF_CMD_SRR_SENT		0x3
 	u8 io_req_flags;
 	uint8_t tm_flags;
+	u64 tm_lun;
 	struct qedf_rport *fcport;
 	unsigned long flags;
 	enum qedf_ioreq_event event;
@@ -453,7 +454,7 @@ extern void qedf_process_warning_compl(struct qedf_ctx *qedf,
 	struct fcoe_cqe *cqe, struct qedf_ioreq *io_req);
 extern void qedf_process_error_detect(struct qedf_ctx *qedf,
 	struct fcoe_cqe *cqe, struct qedf_ioreq *io_req);
-extern void qedf_flush_active_ios(struct qedf_rport *fcport, int lun);
+extern void qedf_flush_active_ios(struct qedf_rport *fcport, u64 lun);
 extern void qedf_release_cmd(struct kref *ref);
 extern int qedf_initiate_abts(struct qedf_ioreq *io_req,
 	bool return_scsi_cmd_on_abts);
@@ -478,7 +479,7 @@ extern int qedf_initiate_cleanup(struct qedf_ioreq *io_req,
 	bool return_scsi_cmd_on_abts);
 extern void qedf_process_cleanup_compl(struct qedf_ctx *qedf,
 	struct fcoe_cqe *cqe, struct qedf_ioreq *io_req);
-extern int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags);
+extern int qedf_initiate_tmf(struct fc_rport *rport, u64 lun, u8 tm_flags);
 extern void qedf_process_tmf_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
 	struct qedf_ioreq *io_req);
 extern void qedf_process_cqe(struct qedf_ctx *qedf, struct fcoe_cqe *cqe);
diff --git a/drivers/scsi/qedf/qedf_io.c b/drivers/scsi/qedf/qedf_io.c
index ded3860..df7cbe9 100644
--- a/drivers/scsi/qedf/qedf_io.c
+++ b/drivers/scsi/qedf/qedf_io.c
@@ -541,7 +541,7 @@ static int qedf_build_bd_list_from_sg(struct qedf_ioreq *io_req)
 }
 
 static void qedf_build_fcp_cmnd(struct qedf_ioreq *io_req,
-				  struct fcp_cmnd *fcp_cmnd)
+				struct fcp_cmnd *fcp_cmnd)
 {
 	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
 
@@ -549,8 +549,12 @@ static void qedf_build_fcp_cmnd(struct qedf_ioreq *io_req,
 	memset(fcp_cmnd, 0, FCP_CMND_LEN);
 
 	/* 8 bytes: SCSI LUN info */
-	int_to_scsilun(sc_cmd->device->lun,
-			(struct scsi_lun *)&fcp_cmnd->fc_lun);
+	if (io_req->cmd_type == QEDF_TASK_MGMT_CMD)
+		int_to_scsilun(io_req->tm_lun,
+			       (struct scsi_lun *)&fcp_cmnd->fc_lun);
+	else
+		int_to_scsilun(sc_cmd->device->lun,
+			       (struct scsi_lun *)&fcp_cmnd->fc_lun);
 
 	/* 4 bytes: flag info */
 	fcp_cmnd->fc_pri_ta = 0;
@@ -1010,8 +1014,9 @@ static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req,
 		io_req->fcp_resid = fcp_rsp->fcp_resid;
 
 	io_req->scsi_comp_flags = rsp_flags;
-	CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status =
-	    fcp_rsp->scsi_status_code;
+	if (sc_cmd)
+		CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status =
+			fcp_rsp->scsi_status_code;
 
 	if (rsp_flags &
 	    FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID)
@@ -1042,7 +1047,7 @@ static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req,
 	}
 
 	/* The sense buffer can be NULL for TMF commands */
-	if (sc_cmd->sense_buffer) {
+	if (sc_cmd && sc_cmd->sense_buffer) {
 		memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
 		if (fcp_sns_len)
 			memcpy(sc_cmd->sense_buffer, sense_data,
@@ -1404,7 +1409,7 @@ static void qedf_flush_els_req(struct qedf_ctx *qedf,
 /* A value of -1 for lun is a wild card that means flush all
  * active SCSI I/Os for the target.
  */
-void qedf_flush_active_ios(struct qedf_rport *fcport, int lun)
+void qedf_flush_active_ios(struct qedf_rport *fcport, u64 lun)
 {
 	struct qedf_ioreq *io_req;
 	struct qedf_ctx *qedf;
@@ -1444,11 +1449,9 @@ void qedf_flush_active_ios(struct qedf_rport *fcport, int lun)
 
 		if (!io_req->sc_cmd)
 			continue;
-		if (lun > 0) {
-			if (io_req->sc_cmd->device->lun !=
-			    (u64)lun)
-				continue;
-		}
+		if ((lun != (u64)-1) && io_req->sc_cmd &&
+		    io_req->sc_cmd->device->lun != lun)
+			continue;
 
 		/*
 		 * Use kref_get_unless_zero in the unlikely case the command
@@ -1831,7 +1834,7 @@ void qedf_process_cleanup_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
 	complete(&io_req->tm_done);
 }
 
-static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
+static int qedf_execute_tmf(struct qedf_rport *fcport, u64 tm_lun,
 	uint8_t tm_flags)
 {
 	struct qedf_ioreq *io_req;
@@ -1845,11 +1848,6 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
 	struct fcoe_wqe *sqe;
 	u16 sqe_idx;
 
-	if (!sc_cmd) {
-		QEDF_ERR(&(qedf->dbg_ctx), "invalid arg\n");
-		return FAILED;
-	}
-
 	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
 		QEDF_ERR(&(qedf->dbg_ctx), "fcport not offloaded\n");
 		rc = FAILED;
@@ -1867,7 +1865,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
 	}
 
 	/* Initialize rest of io_req fields */
-	io_req->sc_cmd = sc_cmd;
+	io_req->sc_cmd = NULL;
 	io_req->fcport = fcport;
 	io_req->cmd_type = QEDF_TASK_MGMT_CMD;
 
@@ -1878,9 +1876,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
 	io_req->io_req_flags = QEDF_READ;
 	io_req->data_xfer_len = 0;
 	io_req->tm_flags = tm_flags;
-
-	/* Default is to return a SCSI command when an error occurs */
-	io_req->return_scsi_cmd_on_abts = true;
+	io_req->tm_lun = tm_lun;
 
 	/* Obtain exchange id */
 	xid = io_req->xid;
@@ -1919,7 +1915,7 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
 	}
 
 	if (tm_flags == FCP_TMF_LUN_RESET)
-		qedf_flush_active_ios(fcport, (int)sc_cmd->device->lun);
+		qedf_flush_active_ios(fcport, tm_lun);
 	else
 		qedf_flush_active_ios(fcport, -1);
 
@@ -1936,9 +1932,8 @@ static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
 	return rc;
 }
 
-int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
+int qedf_initiate_tmf(struct fc_rport *rport, u64 lun, u8 tm_flags)
 {
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
 	struct fc_rport_libfc_priv *rp = rport->dd_data;
 	struct qedf_rport *fcport = (struct qedf_rport *)&rp[1];
 	struct qedf_ctx *qedf;
@@ -1975,7 +1970,7 @@ int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
 		goto tmf_err;
 	}
 
-	rc = qedf_execute_tmf(fcport, sc_cmd, tm_flags);
+	rc = qedf_execute_tmf(fcport, lun, tm_flags);
 
 tmf_err:
 	return rc;
@@ -1989,7 +1984,6 @@ void qedf_process_tmf_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
 	fcp_rsp = &cqe->cqe_info.rsp_info;
 	qedf_parse_fcp_rsp(io_req, fcp_rsp);
 
-	io_req->sc_cmd = NULL;
 	complete(&io_req->tm_done);
 }
 
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index b06ef7c..a0853ac 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -619,14 +619,19 @@ static int qedf_eh_abort(struct scsi_cmnd *sc_cmd)
 
 static int qedf_eh_target_reset(struct scsi_cmnd *sc_cmd)
 {
+	struct scsi_target *starget = scsi_target(sc_cmd->device);
+	struct fc_rport *rport = starget_to_rport(starget);
+
 	QEDF_ERR(NULL, "TARGET RESET Issued...");
-	return qedf_initiate_tmf(sc_cmd, FCP_TMF_TGT_RESET);
+	return qedf_initiate_tmf(rport, 0, FCP_TMF_TGT_RESET);
 }
 
 static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd)
 {
+	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+
 	QEDF_ERR(NULL, "LUN RESET Issued...\n");
-	return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
+	return qedf_initiate_tmf(rport, sc_cmd->device->lun, FCP_TMF_LUN_RESET);
 }
 
 void qedf_wait_for_upload(struct qedf_ctx *qedf)
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 30/47] sym53c8xx_2: rework reset handling
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (28 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 29/47] qedf: use fc rport as argument for qedf_initiate_tmf() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 31/47] bfa: Do not use scsi command to signal TMF status Hannes Reinecke
                   ` (18 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Split off the combined abort and device reset handling into
distinct functions.
And the current device reset handler really is a target reset,
so rename it.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/sym53c8xx_2/sym_glue.c | 82 +++++++++++++++++++++++++------------
 1 file changed, 55 insertions(+), 27 deletions(-)

diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 69d23bb..6afebc4 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -586,7 +586,10 @@ static void sym53c8xx_timer(unsigned long npref)
  *  Generic method for our eh processing.
  *  The 'op' argument tells what we have to do.
  */
-static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
+/*
+ * Error handlers called from the eh thread (one thread per HBA).
+ */
+static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
 {
 	struct sym_ucmd *ucmd = SYM_UCMD_PTR(cmd);
 	struct Scsi_Host *shost = cmd->device->host;
@@ -598,7 +601,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
 	int sts = -1;
 	struct completion eh_done;
 
-	scmd_printk(KERN_WARNING, cmd, "%s operation started\n", opname);
+	scmd_printk(KERN_WARNING, cmd, "ABORT operation started\n");
 
 	/*
 	 * Escalate to host reset if the PCI bus went down
@@ -616,19 +619,7 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
 		}
 	}
 
-	/* Try to proceed the operation we have been asked for */
-	sts = -1;
-	switch(op) {
-	case SYM_EH_ABORT:
-		sts = sym_abort_scsiio(np, cmd, 1);
-		break;
-	case SYM_EH_DEVICE_RESET:
-		sts = sym_reset_scsi_target(np, cmd->device->id);
-		break;
-	default:
-		break;
-	}
-
+	sts = sym_abort_scsiio(np, cmd, 1);
 	/* On error, restore everything and cross fingers :) */
 	if (sts)
 		cmd_queued = 0;
@@ -645,23 +636,60 @@ static int sym_eh_handler(int op, char *opname, struct scsi_cmnd *cmd)
 		spin_unlock_irq(shost->host_lock);
 	}
 
-	dev_warn(&cmd->device->sdev_gendev, "%s operation %s.\n", opname,
+	dev_warn(&cmd->device->sdev_gendev, "ABORT operation %s.\n",
 			sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
 	return sts ? SCSI_FAILED : SCSI_SUCCESS;
 }
 
-
-/*
- * Error handlers called from the eh thread (one thread per HBA).
- */
-static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
+static int sym53c8xx_eh_target_reset_handler(struct scsi_cmnd *cmd)
 {
-	return sym_eh_handler(SYM_EH_ABORT, "ABORT", cmd);
-}
+	struct scsi_target *starget = scsi_target(cmd->device);
+	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
+	struct sym_data *sym_data = shost_priv(shost);
+	struct pci_dev *pdev = sym_data->pdev;
+	struct sym_hcb *np = sym_data->ncb;
+	SYM_QUEHEAD *qp;
+	int sts;
+	struct completion eh_done;
 
-static int sym53c8xx_eh_device_reset_handler(struct scsi_cmnd *cmd)
-{
-	return sym_eh_handler(SYM_EH_DEVICE_RESET, "DEVICE RESET", cmd);
+	starget_printk(KERN_WARNING, starget,
+		       "TARGET RESET operation started\n");
+
+	/*
+	 * Escalate to host reset if the PCI bus went down
+	 */
+	if (pci_channel_offline(pdev))
+		return SCSI_FAILED;
+
+	spin_lock_irq(shost->host_lock);
+	sts = sym_reset_scsi_target(np, starget->id);
+	if (!sts) {
+		FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) {
+			struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb,
+							   link_ccbq);
+			struct scsi_cmnd *cmd = cp->cmd;
+			struct sym_ucmd *ucmd;
+
+			if (!cmd || cmd->device->channel != starget->channel ||
+			    cmd->device->id != starget->id)
+				continue;
+
+			ucmd = SYM_UCMD_PTR(cmd);
+			init_completion(&eh_done);
+			ucmd->eh_done = &eh_done;
+			spin_unlock_irq(shost->host_lock);
+			if (!wait_for_completion_timeout(&eh_done, 5*HZ)) {
+				ucmd->eh_done = NULL;
+				sts = -2;
+			}
+			spin_lock_irq(shost->host_lock);
+		}
+	}
+	spin_unlock_irq(shost->host_lock);
+
+	starget_printk(KERN_WARNING, starget, "TARGET RESET operation %s.\n",
+			sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed");
+	return SCSI_SUCCESS;
 }
 
 static int sym53c8xx_eh_bus_reset_handler(struct Scsi_Host *shost, int channel)
@@ -1681,7 +1709,7 @@ static int sym_detach(struct Scsi_Host *shost, struct pci_dev *pdev)
 	.slave_configure	= sym53c8xx_slave_configure,
 	.slave_destroy		= sym53c8xx_slave_destroy,
 	.eh_abort_handler	= sym53c8xx_eh_abort_handler,
-	.eh_device_reset_handler = sym53c8xx_eh_device_reset_handler,
+	.eh_target_reset_handler = sym53c8xx_eh_target_reset_handler,
 	.eh_bus_reset_handler	= sym53c8xx_eh_bus_reset_handler,
 	.eh_host_reset_handler	= sym53c8xx_eh_host_reset_handler,
 	.this_id		= 7,
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 31/47] bfa: Do not use scsi command to signal TMF status
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (29 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 30/47] sym53c8xx_2: rework reset handling Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28  8:32 ` [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler() Hannes Reinecke
                   ` (17 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The bfa driver hijacks the scsi command to signal the TMF status,
which will no longer work if the TMF handler will be converted.
So rework TMF handling to not use a scsi command but rather add
new TMF fields to the per-device structure.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/bfa/bfad_im.c | 109 ++++++++++++++++++++++++---------------------
 drivers/scsi/bfa/bfad_im.h |   2 +
 2 files changed, 61 insertions(+), 50 deletions(-)

diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 24e657a..ae77ba1 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -158,13 +158,12 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
 		   enum bfi_tskim_status tsk_status)
 {
-	struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dtsk;
+	struct bfad_itnim_data_s *itnim_data = (struct bfad_itnim_data_s *)dtsk;
 	wait_queue_head_t *wq;
 
-	cmnd->SCp.Status |= tsk_status << 1;
-	set_bit(IO_DONE_BIT, (unsigned long *)&cmnd->SCp.Status);
-	wq = (wait_queue_head_t *) cmnd->SCp.ptr;
-	cmnd->SCp.ptr = NULL;
+	itnim_data->tmf_status |= tsk_status << 1;
+	set_bit(IO_DONE_BIT, &itnim_data->tmf_status);
+	wq = itnim_data->tmf_wq;
 
 	if (wq)
 		wake_up(wq);
@@ -249,15 +248,16 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 }
 
 static bfa_status_t
-bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
-		     struct bfad_itnim_s *itnim)
+bfad_im_target_reset_send(struct bfad_s *bfad,
+			  struct bfad_itnim_data_s *itnim_data)
 {
+	struct bfad_itnim_s *itnim = itnim_data->itnim;
 	struct bfa_tskim_s *tskim;
 	struct bfa_itnim_s *bfa_itnim;
 	bfa_status_t    rc = BFA_STATUS_OK;
 	struct scsi_lun scsilun;
 
-	tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
+	tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) itnim_data);
 	if (!tskim) {
 		BFA_LOG(KERN_ERR, bfad, bfa_log_level,
 			"target reset, fail to allocate tskim\n");
@@ -265,12 +265,6 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 		goto out;
 	}
 
-	/*
-	 * Set host_scribble to NULL to avoid aborting a task command if
-	 * happens.
-	 */
-	cmnd->host_scribble = NULL;
-	cmnd->SCp.Status = 0;
 	bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
 	/*
 	 * bfa_itnim can be NULL if the port gets disconnected and the bfa
@@ -301,10 +295,11 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 static int
 bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
+	struct scsi_device *sdev = cmnd->device;
+	struct Scsi_Host *shost = sdev->host;
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
-	struct bfad_itnim_data_s *itnim_data = cmnd->device->hostdata;
+	struct bfad_itnim_data_s *itnim_data = sdev->hostdata;
 	struct bfad_s         *bfad = im_port->bfad;
 	struct bfa_tskim_s *tskim;
 	struct bfad_itnim_s   *itnim;
@@ -316,14 +311,20 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 	struct scsi_lun scsilun;
 
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	if (itnim_data->tmf_wq) {
+		BFA_LOG(KERN_ERR, bfad, bfa_log_level,
+			"LUN reset, TMF already active");
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		rc = FAILED;
+		goto out;
+	}
 	itnim = itnim_data->itnim;
 	if (!itnim) {
 		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 		rc = FAILED;
 		goto out;
 	}
-
-	tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd);
+	tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) itnim_data);
 	if (!tskim) {
 		BFA_LOG(KERN_ERR, bfad, bfa_log_level,
 				"LUN reset, fail to allocate tskim");
@@ -332,13 +333,8 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 		goto out;
 	}
 
-	/*
-	 * Set host_scribble to NULL to avoid aborting a task command
-	 * if happens.
-	 */
-	cmnd->host_scribble = NULL;
-	cmnd->SCp.ptr = (char *)&wq;
-	cmnd->SCp.Status = 0;
+	itnim_data->tmf_wq = &wq;
+	itnim_data->tmf_status = 0;
 	bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
 	/*
 	 * bfa_itnim can be NULL if the port gets disconnected and the bfa
@@ -353,15 +349,16 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 		rc = FAILED;
 		goto out;
 	}
-	int_to_scsilun(cmnd->device->lun, &scsilun);
+	int_to_scsilun(sdev->lun, &scsilun);
 	bfa_tskim_start(tskim, bfa_itnim, scsilun,
 			    FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO);
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
-	wait_event(wq, test_bit(IO_DONE_BIT,
-			(unsigned long *)&cmnd->SCp.Status));
-
-	task_status = cmnd->SCp.Status >> 1;
+	wait_event(wq, test_bit(IO_DONE_BIT, &itnim_data->tmf_status));
+	spin_lock_irqsave(&bfad->bfad_lock, flags);
+	itnim_data->tmf_wq = NULL;
+	task_status = itnim_data->tmf_status >> 1;
+	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 	if (task_status != BFI_TSKIM_STS_OK) {
 		BFA_LOG(KERN_ERR, bfad, bfa_log_level,
 			"LUN reset failure, status: %d\n", task_status);
@@ -378,37 +375,49 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
 static int
 bfad_im_reset_target_handler(struct scsi_cmnd *cmnd)
 {
-	struct Scsi_Host *shost = cmnd->device->host;
 	struct scsi_target *starget = scsi_target(cmnd->device);
+	struct fc_rport *rport = starget_to_rport(starget);
+	struct Scsi_Host *shost = rport_to_shost(rport);
+	struct bfad_itnim_data_s *itnim_data;
+	struct bfad_itnim_s *itnim;
 	struct bfad_im_port_s *im_port =
 				(struct bfad_im_port_s *) shost->hostdata[0];
 	struct bfad_s         *bfad = im_port->bfad;
-	struct bfad_itnim_s   *itnim;
 	unsigned long   flags;
 	u32        rc, rtn = FAILED;
 	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
 	enum bfi_tskim_status task_status;
 
 	spin_lock_irqsave(&bfad->bfad_lock, flags);
-	itnim = bfad_get_itnim(im_port, starget->id);
-	if (itnim) {
-		cmnd->SCp.ptr = (char *)&wq;
-		rc = bfad_im_target_reset_send(bfad, cmnd, itnim);
-		if (rc == BFA_STATUS_OK) {
-			/* wait target reset to complete */
-			spin_unlock_irqrestore(&bfad->bfad_lock, flags);
-			wait_event(wq, test_bit(IO_DONE_BIT,
-					(unsigned long *)&cmnd->SCp.Status));
-			spin_lock_irqsave(&bfad->bfad_lock, flags);
+	if (!rport->dd_data) {
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		return rtn;
+	}
+	itnim_data = rport->dd_data;
+	if (itnim_data->tmf_wq) {
+		BFA_LOG(KERN_ERR, bfad, bfa_log_level,
+			"target reset failed, TMF already active");
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		return rtn;
+	}
+	itnim = itnim_data->itnim;
 
-			task_status = cmnd->SCp.Status >> 1;
-			if (task_status != BFI_TSKIM_STS_OK)
-				BFA_LOG(KERN_ERR, bfad, bfa_log_level,
-					"target reset failure,"
-					" status: %d\n", task_status);
-			else
-				rtn = SUCCESS;
-		}
+	itnim_data->tmf_wq = &wq;
+	itnim_data->tmf_status = 0;
+	rc = bfad_im_target_reset_send(bfad, itnim_data);
+	if (rc == BFA_STATUS_OK) {
+		/* wait target reset to complete */
+		spin_unlock_irqrestore(&bfad->bfad_lock, flags);
+		wait_event(wq, test_bit(IO_DONE_BIT, &itnim_data->tmf_status));
+		spin_lock_irqsave(&bfad->bfad_lock, flags);
+
+		task_status = itnim_data->tmf_status >> 1;
+		if (task_status != BFI_TSKIM_STS_OK)
+			BFA_LOG(KERN_ERR, bfad, bfa_log_level,
+				"target reset failure,"
+				" status: %d\n", task_status);
+		else
+			rtn = SUCCESS;
 	}
 	spin_unlock_irqrestore(&bfad->bfad_lock, flags);
 
diff --git a/drivers/scsi/bfa/bfad_im.h b/drivers/scsi/bfa/bfad_im.h
index c81ec2a..e57ea05 100644
--- a/drivers/scsi/bfa/bfad_im.h
+++ b/drivers/scsi/bfa/bfad_im.h
@@ -54,6 +54,8 @@ void bfad_im_scsi_host_free(struct bfad_s *bfad,
 
 struct bfad_itnim_data_s {
 	struct bfad_itnim_s *itnim;
+	wait_queue_head_t *tmf_wq;
+	unsigned long tmf_status;
 };
 
 struct bfad_im_port_s {
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (30 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 31/47] bfa: Do not use scsi command to signal TMF status Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-07-24 18:10   ` Steffen Maier
  2017-06-28  8:32 ` [PATCH 33/47] cxlflash: use dedicated reset command in send_tmf() Hannes Reinecke
                   ` (16 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The target reset function should only depend on the scsi target,
not the scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/message/fusion/mptsas.c             | 10 +++++-
 drivers/message/fusion/mptscsih.c           | 27 +++++++----------
 drivers/message/fusion/mptscsih.h           |  2 +-
 drivers/message/fusion/mptspi.c             |  8 ++++-
 drivers/s390/scsi/zfcp_scsi.c               | 20 ++++++++++--
 drivers/scsi/aacraid/linit.c                |  9 +++---
 drivers/scsi/be2iscsi/be_main.c             |  4 +--
 drivers/scsi/bfa/bfad_im.c                  |  3 +-
 drivers/scsi/bnx2fc/bnx2fc.h                |  2 +-
 drivers/scsi/bnx2fc/bnx2fc_io.c             |  4 +--
 drivers/scsi/esas2r/esas2r.h                |  2 +-
 drivers/scsi/esas2r/esas2r_main.c           | 38 ++++++++++++-----------
 drivers/scsi/ibmvscsi/ibmvfc.c              |  3 +-
 drivers/scsi/libiscsi.c                     |  4 +--
 drivers/scsi/libsas/sas_scsi_host.c         |  9 +++---
 drivers/scsi/lpfc/lpfc_scsi.c               | 10 +++---
 drivers/scsi/megaraid/megaraid_sas.h        |  3 +-
 drivers/scsi/megaraid/megaraid_sas_base.c   | 10 +++---
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 47 +++++++++++++++--------------
 drivers/scsi/mpt3sas/mpt3sas_scsih.c        | 35 +++++++++++----------
 drivers/scsi/pmcraid.c                      | 24 +++++++++++----
 drivers/scsi/qedf/qedf_main.c               |  3 +-
 drivers/scsi/qla2xxx/qla_os.c               | 18 +++++------
 drivers/scsi/qla4xxx/ql4_os.c               | 41 ++++++++++++++-----------
 drivers/scsi/scsi_debug.c                   | 21 ++++---------
 drivers/scsi/scsi_error.c                   |  5 +--
 drivers/scsi/scsi_transport_iscsi.c         |  6 ++--
 drivers/scsi/sym53c8xx_2/sym_glue.c         |  3 +-
 drivers/target/loopback/tcm_loop.c          |  9 +++---
 include/scsi/libiscsi.h                     |  2 +-
 include/scsi/libsas.h                       |  2 +-
 include/scsi/scsi_host.h                    |  2 +-
 include/scsi/scsi_transport_iscsi.h         |  2 +-
 33 files changed, 214 insertions(+), 174 deletions(-)

diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index f6308ad..bdb420b 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -1970,6 +1970,14 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
 }
 
 
+static int mptsas_eh_target_reset(struct scsi_target *starget)
+{
+	struct sas_rphy *rphy = dev_to_rphy(starget->dev.parent);
+	MPT_ADAPTER *ioc = rphy_to_ioc(rphy);
+
+	return mptscsih_target_reset(ioc->sh, starget);
+}
+
 static struct scsi_host_template mptsas_driver_template = {
 	.module				= THIS_MODULE,
 	.proc_name			= "mptsas",
@@ -1985,7 +1993,7 @@ static enum blk_eh_timer_return mptsas_eh_timed_out(struct scsi_cmnd *sc)
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_timed_out			= mptsas_eh_timed_out,
 	.eh_abort_handler		= mptscsih_abort,
-	.eh_device_reset_handler	= mptscsih_dev_reset,
+	.eh_target_reset_handler	= mptsas_eh_target_reset,
 	.eh_host_reset_handler		= mptscsih_host_reset,
 	.bios_param			= mptscsih_bios_param,
 	.can_queue			= MPT_SAS_CAN_QUEUE,
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index ca79982..0f25a2a 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1852,48 +1852,43 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
  *	Returns SUCCESS or FAILED.
  **/
 int
-mptscsih_target_reset(struct scsi_cmnd * SCpnt)
+mptscsih_target_reset(struct Scsi_Host *shost, struct scsi_target * starget)
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
-	VirtDevice	 *vdevice;
+	VirtTarget	 *vtarget;
 	MPT_ADAPTER	*ioc;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
-	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
-		printk(KERN_ERR MYNAM ": target reset: "
-		   "Can't locate host! (sc=%p)\n", SCpnt);
+	if ((hd = shost_priv(shost)) == NULL){
+		printk(KERN_ERR MYNAM ": target reset: Can't locate host!\n");
 		return FAILED;
 	}
 
 	ioc = hd->ioc;
-	printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
-	       ioc->name, SCpnt);
-	scsi_print_command(SCpnt);
-
-	vdevice = SCpnt->device->hostdata;
-	if (!vdevice || !vdevice->vtarget) {
+	printk(MYIOC_s_INFO_FMT "attempting target reset!\n", ioc->name);
+	vtarget = starget->hostdata;
+	if (!vtarget) {
 		retval = 0;
 		goto out;
 	}
 
 	/* Target reset to hidden raid component is not supported
 	 */
-	if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
+	if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
 		retval = FAILED;
 		goto out;
 	}
 
 	retval = mptscsih_IssueTaskMgmt(hd,
 				MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
-				vdevice->vtarget->channel,
-				vdevice->vtarget->id, 0, 0,
+				vtarget->channel, vtarget->id, 0, 0,
 				mptscsih_get_tm_timeout(ioc));
 
  out:
-	printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
-	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+	printk (MYIOC_s_INFO_FMT "target reset: %s\n",
+	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ));
 
 	if (retval == 0)
 		return SUCCESS;
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 54f2604..a5069a84 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -120,7 +120,7 @@ extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
 extern int mptscsih_slave_configure(struct scsi_device *device);
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
 extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
-extern int mptscsih_target_reset(struct scsi_cmnd * SCpnt);
+extern int mptscsih_target_reset(struct Scsi_Host *, struct scsi_target *);
 extern int mptscsih_bus_reset(struct Scsi_Host *, int);
 extern int mptscsih_host_reset(struct Scsi_Host *sh);
 extern int mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, sector_t capacity, int geom[]);
diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c
index 9a336a1..af4dc93 100644
--- a/drivers/message/fusion/mptspi.c
+++ b/drivers/message/fusion/mptspi.c
@@ -825,6 +825,12 @@ static void mptspi_slave_destroy(struct scsi_device *sdev)
 	mptscsih_slave_destroy(sdev);
 }
 
+static int mptspi_eh_target_reset(struct scsi_target *starget)
+{
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+	return mptscsih_target_reset(shost, starget);
+}
+
 static struct scsi_host_template mptspi_driver_template = {
 	.module				= THIS_MODULE,
 	.proc_name			= "mptspi",
@@ -839,7 +845,7 @@ static void mptspi_slave_destroy(struct scsi_device *sdev)
 	.slave_destroy			= mptspi_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
-	.eh_device_reset_handler	= mptscsih_dev_reset,
+	.eh_target_reset_handler	= mptspi_eh_target_reset,
 	.eh_bus_reset_handler		= mptscsih_bus_reset,
 	.eh_host_reset_handler		= mptscsih_host_reset,
 	.bios_param			= mptscsih_bios_param,
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index dd7bea0..92a3902 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -309,9 +309,25 @@ static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
 }
 
-static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
+/*
+ * Note: We need to select a LUN as the storage array doesn't
+ * necessarily supports LUN 0 and might refuse the target reset.
+ */
+static int zfcp_scsi_eh_target_reset_handler(struct scsi_target *starget)
 {
-	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_TGT_RESET);
+	struct fc_rport *rport = starget_to_rport(starget);
+	struct Scsi_Host *shost = rport_to_shost(rport);
+	struct scsi_device *sdev = NULL, *tmp_sdev;
+
+	shost_for_each_device(tmp_sdev, shost) {
+		if (tmp_sdev->id == starget->id) {
+			sdev = tmp_sdev;
+			break;
+		}
+	}
+	if (!sdev)
+		return FAILED;
+	return zfcp_task_mgmt_function(sdev, FCP_TMF_TGT_RESET);
 }
 
 static int zfcp_scsi_eh_host_reset_handler(struct Scsi_Host *host)
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 1e157c6..7214600 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -947,10 +947,9 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
  *	@scsi_cmd:	SCSI command block causing the reset
  *
  */
-static int aac_eh_target_reset(struct scsi_cmnd *cmd)
+static int aac_eh_target_reset(struct scsi_target *starget)
 {
-	struct scsi_device * dev = cmd->device;
-	struct Scsi_Host * host = dev->host;
+	struct Scsi_Host * host = dev_to_shost(&starget->dev);
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
 	struct aac_hba_map_info *info;
 	int count;
@@ -960,8 +959,8 @@ static int aac_eh_target_reset(struct scsi_cmnd *cmd)
 	int status;
 	u8 command;
 
-	bus = aac_logical_to_phys(scmd_channel(cmd));
-	cid = scmd_id(cmd);
+	bus = aac_logical_to_phys(starget->channel);
+	cid = starget->id;
 	info = &aac->hba_map[bus][cid];
 	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
 	    info->devtype != AAC_DEVTYPE_NATIVE_RAW)
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index b5a88ce..2b0d14c 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -363,11 +363,11 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
 	return rc;
 }
 
-static int beiscsi_eh_session_reset(struct scsi_cmnd *sc)
+static int beiscsi_eh_session_reset(struct scsi_target *starget)
 {
 	struct iscsi_cls_session *cls_session;
 
-	cls_session = starget_to_session(scsi_target(sc->device));
+	cls_session = starget_to_session(starget);
 	return iscsi_eh_session_reset(cls_session);
 }
 
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index ae77ba1..6613ef3 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -373,9 +373,8 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
  * Scsi_Host template entry, resets the target and abort all commands.
  */
 static int
-bfad_im_reset_target_handler(struct scsi_cmnd *cmnd)
+bfad_im_reset_target_handler(struct scsi_target *starget)
 {
-	struct scsi_target *starget = scsi_target(cmnd->device);
 	struct fc_rport *rport = starget_to_rport(starget);
 	struct Scsi_Host *shost = rport_to_shost(rport);
 	struct bfad_itnim_data_s *itnim_data;
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index b9c101f..d115281 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -540,7 +540,7 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
 void bnx2fc_add_2_sq(struct bnx2fc_rport *tgt, u16 xid);
 void bnx2fc_ring_doorbell(struct bnx2fc_rport *tgt);
 int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd);
-int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd);
+int bnx2fc_eh_target_reset(struct scsi_target *sc_tgt);
 int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd);
 void bnx2fc_rport_event_handler(struct fc_lport *lport,
 				struct fc_rport_priv *rport,
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 3be742a..7b8de5e 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1058,9 +1058,9 @@ int bnx2fc_initiate_cleanup(struct bnx2fc_cmd *io_req)
  * Set from SCSI host template to send task mgmt command to the target
  *	and wait for the response
  */
-int bnx2fc_eh_target_reset(struct scsi_cmnd *sc_cmd)
+int bnx2fc_eh_target_reset(struct scsi_target *sc_tgt)
 {
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+	struct fc_rport *rport = starget_to_rport(sc_tgt);
 	struct fc_lport *lport = shost_priv(rport_to_shost(rport));
 
 	return bnx2fc_initiate_tmf(lport, rport, 0, FCP_TMF_TGT_RESET);
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index b63bab9..3ed1aca 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -979,7 +979,7 @@ u8 handle_hba_ioctl(struct esas2r_adapter *a,
 int esas2r_device_reset(struct scsi_cmnd *cmd);
 int esas2r_host_reset(struct Scsi_Host *shost);
 int esas2r_bus_reset(struct Scsi_Host *shost, int channel);
-int esas2r_target_reset(struct scsi_cmnd *cmd);
+int esas2r_target_reset(struct scsi_target *starget);
 
 /* Internal functions */
 int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index 606bb82..f0aa2d4 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -1164,10 +1164,11 @@ int esas2r_bus_reset(struct Scsi_Host *shost, int channel)
 	return esas2r_host_bus_reset(shost, false);
 }
 
-static int esas2r_dev_targ_reset(struct scsi_cmnd *cmd, bool target_reset)
+static int esas2r_dev_targ_reset(struct Scsi_Host *shost, int id, u64 lun,
+				 bool target_reset)
 {
 	struct esas2r_adapter *a =
-		(struct esas2r_adapter *)cmd->device->host->hostdata;
+		(struct esas2r_adapter *)shost->hostdata;
 	struct esas2r_request *rq;
 	u8 task_management_status = RS_PENDING;
 	bool completed;
@@ -1181,34 +1182,30 @@ static int esas2r_dev_targ_reset(struct scsi_cmnd *cmd, bool target_reset)
 		if (target_reset) {
 			esas2r_log(ESAS2R_LOG_CRIT,
 				   "unable to allocate a request for a "
-				   "target reset (%d)!",
-				   cmd->device->id);
+				   "target reset (%d)!", id);
 		} else {
 			esas2r_log(ESAS2R_LOG_CRIT,
 				   "unable to allocate a request for a "
-				   "device reset (%d:%llu)!",
-				   cmd->device->id,
-				   cmd->device->lun);
+				   "device reset (%d:%llu)!", id, lun);
 		}
 
 
 		return FAILED;
 	}
 
-	rq->target_id = cmd->device->id;
-	rq->vrq->scsi.flags |= cpu_to_le32(cmd->device->lun);
+	rq->target_id = id;
+	rq->vrq->scsi.flags |= cpu_to_le32(lun);
 	rq->req_stat = RS_PENDING;
 
 	rq->comp_cb = complete_task_management_request;
 	rq->task_management_status_ptr = &task_management_status;
 
 	if (target_reset) {
-		esas2r_debug("issuing target reset (%p) to id %d", rq,
-			     cmd->device->id);
+		esas2r_debug("issuing target reset (%p) to id %d", rq, id);
 		completed = esas2r_send_task_mgmt(a, rq, 0x20);
 	} else {
-		esas2r_debug("issuing device reset (%p) to id %d lun %d", rq,
-			     cmd->device->id, cmd->device->lun);
+		esas2r_debug("issuing device reset (%p) to id %d lun %llu", rq,
+			     id, lun);
 		completed = esas2r_send_task_mgmt(a, rq, 0x10);
 	}
 
@@ -1242,17 +1239,22 @@ static int esas2r_dev_targ_reset(struct scsi_cmnd *cmd, bool target_reset)
 
 int esas2r_device_reset(struct scsi_cmnd *cmd)
 {
-	esas2r_log(ESAS2R_LOG_INFO, "device_reset (%p)", cmd);
+	struct scsi_device *sdev = cmd->device;
+	struct Scsi_Host *shost = sdev->host;
+
+	esas2r_log(ESAS2R_LOG_INFO, "device_reset");
 
-	return esas2r_dev_targ_reset(cmd, false);
+	return esas2r_dev_targ_reset(shost, sdev->id, sdev->lun, false);
 
 }
 
-int esas2r_target_reset(struct scsi_cmnd *cmd)
+int esas2r_target_reset(struct scsi_target *starget)
 {
-	esas2r_log(ESAS2R_LOG_INFO, "target_reset (%p)", cmd);
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+
+	esas2r_log(ESAS2R_LOG_INFO, "target_reset");
 
-	return esas2r_dev_targ_reset(cmd, true);
+	return esas2r_dev_targ_reset(shost, starget->id, 0, true);
 }
 
 void esas2r_log_request_failure(struct esas2r_adapter *a,
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index 2e2a613..f7b9601 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2482,9 +2482,8 @@ static void ibmvfc_dev_cancel_all_noreset(struct scsi_device *sdev, void *data)
  * Returns:
  *	SUCCESS / FAST_IO_FAIL / FAILED
  **/
-static int ibmvfc_eh_target_reset_handler(struct scsi_cmnd *cmd)
+static int ibmvfc_eh_target_reset_handler(struct scsi_target *starget)
 {
-	struct scsi_target *starget = scsi_target(cmd->device);
 	struct fc_rport *rport = starget_to_rport(starget);
 	struct Scsi_Host *shost = rport_to_shost(rport);
 	struct ibmvfc_host *vhost = shost_priv(shost);
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 5bc685c..d51c9ba 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2521,12 +2521,12 @@ static int iscsi_eh_target_reset(struct iscsi_cls_session *cls_session)
  * This will attempt to send a warm target reset. If that fails,
  * we will escalate to ERL0 session recovery.
  */
-int iscsi_eh_recover_target(struct scsi_cmnd *sc)
+int iscsi_eh_recover_target(struct scsi_target *starget)
 {
 	struct iscsi_cls_session *cls_session;
 	int rc;
 
-	cls_session = starget_to_session(scsi_target(sc->device));
+	cls_session = starget_to_session(starget);
 	rc = iscsi_eh_target_reset(cls_session);
 	if (rc == FAILED)
 		rc = iscsi_eh_session_reset(cls_session);
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 3c51da8..2001a6e 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -526,11 +526,12 @@ int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
 	return FAILED;
 }
 
-int sas_eh_target_reset_handler(struct scsi_cmnd *cmd)
+int sas_eh_target_reset_handler(struct scsi_target *starget)
 {
 	int res;
-	struct Scsi_Host *host = cmd->device->host;
-	struct domain_device *dev = cmd_to_domain_dev(cmd);
+	struct domain_device *dev = starget_to_domain_dev(starget);
+	struct sas_rphy *rphy = dev->rphy;
+	struct Scsi_Host *host = dev_to_shost(rphy->dev.parent);
 	struct sas_internal *i = to_sas_internal(host->transportt);
 
 	if (current != host->ehandler)
@@ -562,7 +563,7 @@ static int try_to_reset_cmd_device(struct scsi_cmnd *cmd)
 
 try_target_reset:
 	if (shost->hostt->eh_target_reset_handler)
-		return shost->hostt->eh_target_reset_handler(cmd);
+		return shost->hostt->eh_target_reset_handler(scsi_target(cmd->device));
 
 	return FAILED;
 }
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 107c0f6..573bd43 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5226,16 +5226,16 @@ void lpfc_poll_timeout(unsigned long ptr)
  *  0x2002 - Success
  **/
 static int
-lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
+lpfc_target_reset_handler(struct scsi_target *starget)
 {
-	struct Scsi_Host  *shost = cmnd->device->host;
+	struct fc_rport *rport = starget_to_rport(starget);
+	struct Scsi_Host  *shost = rport_to_shost(rport);
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_rport_data *rdata;
 	struct lpfc_nodelist *pnode;
-	unsigned tgt_id = cmnd->device->id;
-	uint64_t lun_id = cmnd->device->lun;
+	unsigned tgt_id = starget->id;
+	uint64_t lun_id = 0;
 	struct lpfc_scsi_event_header scsi_event;
-	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
 	int status;
 
 	rdata = rport->dd_data;
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 2b209bb..37f92a4 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2485,7 +2485,8 @@ void megasas_return_mfi_mpt_pthr(struct megasas_instance *instance,
 void megasas_update_sdev_properties(struct scsi_device *sdev);
 int megasas_reset_fusion(struct Scsi_Host *shost, int reason);
 int megasas_task_abort_fusion(struct scsi_cmnd *scmd);
-int megasas_reset_target_fusion(struct scsi_cmnd *scmd);
+int megasas_reset_target_fusion(struct Scsi_Host *shost,
+				struct scsi_target *starget);
 u32 mega_mod64(u64 dividend, u32 divisor);
 int megasas_alloc_fusion_context(struct megasas_instance *instance);
 void megasas_free_fusion_context(struct megasas_instance *instance);
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 89e3fd6..0784f06 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -2821,17 +2821,19 @@ static int megasas_task_abort(struct scsi_cmnd *scmd)
  *                        (supported only for fusion adapters)
  * @scmd:                 SCSI command pointer
  */
-static int megasas_reset_target(struct scsi_cmnd *scmd)
+static int megasas_reset_target(struct scsi_target *starget)
 {
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
 	int ret;
 	struct megasas_instance *instance;
 
-	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+	instance = (struct megasas_instance *)shost->hostdata;
 
 	if (instance->ctrl_context)
-		ret = megasas_reset_target_fusion(scmd);
+		ret = megasas_reset_target_fusion(shost, starget);
 	else {
-		sdev_printk(KERN_NOTICE, scmd->device, "TARGET RESET not supported\n");
+		starget_printk(KERN_NOTICE, starget,
+			       "TARGET RESET not supported\n");
 		ret = FAILED;
 	}
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index f990ab4d..db40ddf 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -4010,26 +4010,28 @@ int megasas_task_abort_fusion(struct scsi_cmnd *scmd)
 
 /*
  * megasas_reset_target_fusion : target reset function for fusion adapters
- * scmd: SCSI command pointer
+ * shost: SCSI host pointer
+ * starget: SCSI target pointer
  *
  * Returns SUCCESS if all commands associated with target aborted else FAILED
  */
 
-int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
+int megasas_reset_target_fusion(struct Scsi_Host *shost,
+				struct scsi_target *starget)
 {
 
 	struct megasas_instance *instance;
+	struct scsi_device *sdev;
 	int ret = FAILED;
 	u16 devhandle;
 	struct fusion_context *fusion;
-	struct MR_PRIV_DEVICE *mr_device_priv_data;
-	mr_device_priv_data = scmd->device->hostdata;
+	struct MR_PRIV_DEVICE *mr_device_priv_data = NULL;
 
-	instance = (struct megasas_instance *)scmd->device->host->hostdata;
+	instance = (struct megasas_instance *)shost->hostdata;
 	fusion = instance->ctrl_context;
 
-	sdev_printk(KERN_INFO, scmd->device,
-		    "target reset called for scmd(%p)\n", scmd);
+	starget_printk(KERN_INFO, starget,
+		    "target reset called\n");
 
 	if (atomic_read(&instance->adprecovery) != MEGASAS_HBA_OPERATIONAL) {
 		dev_err(&instance->pdev->dev, "Controller is not OPERATIONAL,"
@@ -4038,42 +4040,43 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)
 		return ret;
 	}
 
+	shost_for_each_device(sdev, shost) {
+		if (!sdev->hostdata)
+			continue;
+		mr_device_priv_data = sdev->hostdata;
+		if (mr_device_priv_data->is_tm_capable) {
+			devhandle = megasas_get_tm_devhandle(sdev);
+			break;
+		}
+	}
+
 	if (!mr_device_priv_data) {
-		sdev_printk(KERN_INFO, scmd->device, "device been deleted! "
-			"scmd(%p)\n", scmd);
-		scmd->result = DID_NO_CONNECT << 16;
 		ret = SUCCESS;
 		goto out;
-	}
-
-
-	if (!mr_device_priv_data->is_tm_capable) {
+	} else if (!mr_device_priv_data->is_tm_capable) {
 		ret = FAILED;
 		goto out;
 	}
 
 	mutex_lock(&instance->reset_mutex);
-	devhandle = megasas_get_tm_devhandle(scmd->device);
-
 	if (devhandle == (u16)ULONG_MAX) {
 		ret = SUCCESS;
-		sdev_printk(KERN_INFO, scmd->device,
+		starget_printk(KERN_INFO, starget,
 			"target reset issued for invalid devhandle\n");
 		mutex_unlock(&instance->reset_mutex);
 		goto out;
 	}
 
-	sdev_printk(KERN_INFO, scmd->device,
-		"attempting target reset! scmd(%p) tm_dev_handle 0x%x\n",
-		scmd, devhandle);
+	starget_printk(KERN_INFO, starget,
+		"attempting target reset! tm_dev_handle 0x%x\n", devhandle);
 	mr_device_priv_data->tm_busy = 1;
 	ret = megasas_issue_tm(instance, devhandle,
-			scmd->device->channel, scmd->device->id, 0,
+			starget->channel, starget->id, 0,
 			MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
 	mr_device_priv_data->tm_busy = 0;
 	mutex_unlock(&instance->reset_mutex);
 out:
-	scmd_printk(KERN_NOTICE, scmd, "megasas: target reset %s!!\n",
+	starget_printk(KERN_NOTICE, starget, "megasas: target reset %s!!\n",
 		(ret == SUCCESS) ? "SUCCESS" : "FAILED");
 
 	return ret;
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 6ecf672..f3c2310 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2580,26 +2580,30 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
  * Returns SUCCESS if command aborted else FAILED
  */
 static int
-scsih_target_reset(struct scsi_cmnd *scmd)
+scsih_target_reset(struct scsi_target *starget)
 {
-	struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+	struct scsi_device *sdev = NULL, *tmp_sdev;
+	struct MPT3SAS_ADAPTER *ioc = shost_priv(shost);
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	struct _sas_device *sas_device = NULL;
 	u16	handle;
 	int r;
-	struct scsi_target *starget = scmd->device->sdev_target;
 	struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
 
-	starget_printk(KERN_INFO, starget, "attempting target reset! scmd(%p)\n",
-		scmd);
-	_scsih_tm_display_info(ioc, scmd);
+	starget_printk(KERN_INFO, starget, "attempting target reset!\n");
 
-	sas_device_priv_data = scmd->device->hostdata;
+	shost_for_each_device(tmp_sdev, shost) {
+		if (scsi_target(tmp_sdev) == starget) {
+			if (!tmp_sdev->hostdata)
+				continue;
+			sdev = tmp_sdev;
+			break;
+		}
+	}
+	sas_device_priv_data = sdev->hostdata;
 	if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-		starget_printk(KERN_INFO, starget, "target been deleted! scmd(%p)\n",
-			scmd);
-		scmd->result = DID_NO_CONNECT << 16;
-		scmd->scsi_done(scmd);
+		starget_printk(KERN_INFO, starget, "target been deleted!\n");
 		r = SUCCESS;
 		goto out;
 	}
@@ -2616,18 +2620,17 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 		handle = sas_device_priv_data->sas_target->handle;
 
 	if (!handle) {
-		scmd->result = DID_RESET << 16;
 		r = FAILED;
 		goto out;
 	}
 
-	r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
-	    scmd->device->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
+	r = mpt3sas_scsih_issue_locked_tm(ioc, handle, starget->channel,
+	    starget->id, 0, MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 0,
 	    30);
 
  out:
-	starget_printk(KERN_INFO, starget, "target reset: %s scmd(%p)\n",
-	    ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+	starget_printk(KERN_INFO, starget, "target reset: %s\n",
+	    ((r == SUCCESS) ? "SUCCESS" : "FAILED"));
 
 	if (sas_device)
 		sas_device_put(sas_device);
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 35a6e34..289edfe 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -2738,6 +2738,7 @@ static int pmcraid_reset_device(
 	u8 modifier
 )
 {
+	struct Scsi_Host *shost = scsi_dev->host;
 	struct pmcraid_cmd *cmd;
 	struct pmcraid_instance *pinstance;
 	struct pmcraid_resource_entry *res;
@@ -2745,10 +2746,9 @@ static int pmcraid_reset_device(
 	unsigned long lock_flags;
 	u32 ioasc;
 
-	pinstance =
-		(struct pmcraid_instance *)scsi_dev->host->hostdata;
-	res = scsi_dev->hostdata;
+	pinstance = (struct pmcraid_instance *)shost->hostdata;
 
+	res = scsi_dev->hostdata;
 	if (!res) {
 		sdev_printk(KERN_ERR, scsi_dev,
 			    "reset_device: NULL resource pointer\n");
@@ -3106,11 +3106,23 @@ static int pmcraid_eh_bus_reset_handler(struct Scsi_Host *host, int channel)
 				    RESET_DEVICE_BUS);
 }
 
-static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
+static int pmcraid_eh_target_reset_handler(struct scsi_target *starget)
 {
-	scmd_printk(KERN_INFO, scmd,
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
+	struct scsi_device *scsi_dev = NULL, *tmp;
+
+	shost_for_each_device(tmp, shost) {
+		if ((tmp->channel == starget->channel) &&
+		    (tmp->id == starget->id)) {
+			scsi_dev = tmp;
+			break;
+		}
+	}
+	if (!scsi_dev)
+		return FAILED;
+	sdev_printk(KERN_INFO, scsi_dev,
 		    "Doing target reset due to an I/O command timeout.\n");
-	return pmcraid_reset_device(scmd->device,
+	return pmcraid_reset_device(scsi_dev,
 				    PMCRAID_INTERNAL_TIMEOUT,
 				    RESET_DEVICE_TARGET);
 }
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index a0853ac..5ccfb14 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -617,9 +617,8 @@ static int qedf_eh_abort(struct scsi_cmnd *sc_cmd)
 	return rc;
 }
 
-static int qedf_eh_target_reset(struct scsi_cmnd *sc_cmd)
+static int qedf_eh_target_reset(struct scsi_target *starget)
 {
-	struct scsi_target *starget = scsi_target(sc_cmd->device);
 	struct fc_rport *rport = starget_to_rport(starget);
 
 	QEDF_ERR(NULL, "TARGET RESET Issued...");
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index c068041..2345695 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -273,7 +273,7 @@
 static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
-static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
+static int qla2xxx_eh_target_reset(struct scsi_target *);
 static int qla2xxx_eh_bus_reset(struct Scsi_Host *, int);
 static int qla2xxx_eh_host_reset(struct Scsi_Host *);
 
@@ -1446,10 +1446,9 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 }
 
 static int
-qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
+qla2xxx_eh_target_reset(struct scsi_target *starget)
 {
-	struct scsi_device *sdev = cmd->device;
-	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
+	struct fc_rport *rport = starget_to_rport(starget);
 	scsi_qla_host_t *vha = shost_priv(rport_to_shost(rport));
 	struct qla_hw_data *ha = vha->hw;
 	fc_port_t *fcport = (struct fc_port *) rport->dd_data;
@@ -1473,7 +1472,7 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 
 	ql_log(ql_log_info, vha, 0x8009,
 	    "TARGET RESET ISSUED nexus=%ld:%d:0.\n", vha->host_no,
-	    cmd->device->id);
+	    starget->id);
 
 	err = 0;
 	if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS) {
@@ -1482,13 +1481,14 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 		goto eh_reset_failed;
 	}
 	err = 2;
-	if (ha->isp_ops->target_reset(fcport, 0, smp_processor_id() + 1)
+	if (ha->isp_ops->target_reset(fcport, starget->id,
+				      smp_processor_id() + 1)
 	    != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x800c, "do_reset failed.\n");
 		goto eh_reset_failed;
 	}
 	err = 3;
-	if (qla2x00_eh_wait_for_pending_commands(vha, sdev->id,
+	if (qla2x00_eh_wait_for_pending_commands(vha, starget->id,
 		0, WAIT_TARGET) != QLA_SUCCESS) {
 		ql_log(ql_log_warn, vha, 0x800d,
 		       "wait for pending cmds failed.\n");
@@ -1497,14 +1497,14 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 
 	ql_log(ql_log_info, vha, 0x800e,
 	    "TARGET RESET SUCCEEDED nexus:%ld:%d:0.\n",
-	    vha->host_no, sdev->id);
+	    vha->host_no, starget->id);
 
 	return SUCCESS;
 
 eh_reset_failed:
 	ql_log(ql_log_info, vha, 0x800f,
 	    "TARGET RESET FAILED: %s nexus=%ld:%d:0\n",
-	    reset_errors[err], vha->host_no, sdev->id);
+	    reset_errors[err], vha->host_no, starget->id);
 	return FAILED;
 }
 
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 11bd2da..0ce84d6 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -159,7 +159,7 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void  *data,
 static int qla4xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);
 static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
-static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd);
+static int qla4xxx_eh_target_reset(struct scsi_target *starget);
 static int qla4xxx_eh_host_reset(struct Scsi_Host *shost);
 static int qla4xxx_slave_alloc(struct scsi_device *device);
 static umode_t qla4_attr_is_visible(int param_type, int param);
@@ -9241,13 +9241,15 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
 static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
 {
 	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
+	struct iscsi_cls_session *session;
 	struct ddb_entry *ddb_entry = cmd->device->hostdata;
 	int ret = FAILED, stat;
 
 	if (!ddb_entry)
 		return ret;
 
-	ret = iscsi_block_scsi_eh(cmd);
+	session = starget_to_session(scsi_target(cmd->device));
+	ret = iscsi_block_scsi_eh(session);
 	if (ret)
 		return ret;
 	ret = FAILED;
@@ -9300,53 +9302,56 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
  *
  * This routine is called by the Linux OS to reset the target.
  **/
-static int qla4xxx_eh_target_reset(struct scsi_cmnd *cmd)
+static int qla4xxx_eh_target_reset(struct scsi_target *starget)
 {
-	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
-	struct ddb_entry *ddb_entry = cmd->device->hostdata;
+	struct iscsi_cls_session *cls_session = starget_to_session(starget);
+	struct iscsi_session *sess;
+	struct scsi_qla_host *ha;
+	struct ddb_entry *ddb_entry;
 	int stat, ret;
 
+	sess = cls_session->dd_data;
+	ddb_entry = sess->dd_data;
 	if (!ddb_entry)
 		return FAILED;
+	ha = ddb_entry->ha;
 
-	ret = iscsi_block_scsi_eh(cmd);
+	ret = iscsi_block_scsi_eh(cls_session);
 	if (ret)
 		return ret;
 
-	starget_printk(KERN_INFO, scsi_target(cmd->device),
+	starget_printk(KERN_INFO, starget,
 		       "WARM TARGET RESET ISSUED.\n");
 
 	DEBUG2(printk(KERN_INFO
-		      "scsi%ld: TARGET_DEVICE_RESET cmd=%p jiffies = 0x%lx, "
-		      "to=%x,dpc_flags=%lx, status=%x allowed=%d\n",
-		      ha->host_no, cmd, jiffies, cmd->request->timeout / HZ,
-		      ha->dpc_flags, cmd->result, cmd->allowed));
+		      "scsi%ld: TARGET_DEVICE_RESET jiffies = 0x%lx, "
+		      "dpc_flags=%lx\n",
+		      ha->host_no, jiffies, ha->dpc_flags));
 
 	stat = qla4xxx_reset_target(ha, ddb_entry);
 	if (stat != QLA_SUCCESS) {
-		starget_printk(KERN_INFO, scsi_target(cmd->device),
+		starget_printk(KERN_INFO, starget,
 			       "WARM TARGET RESET FAILED.\n");
 		return FAILED;
 	}
 
-	if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device),
-					 NULL)) {
-		starget_printk(KERN_INFO, scsi_target(cmd->device),
+	if (qla4xxx_eh_wait_for_commands(ha, starget, NULL)) {
+		starget_printk(KERN_INFO, starget,
 			       "WARM TARGET DEVICE RESET FAILED - "
 			       "waiting for commands.\n");
 		return FAILED;
 	}
 
 	/* Send marker. */
-	if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun,
+	if (qla4xxx_send_marker_iocb(ha, ddb_entry, 0,
 		MM_TGT_WARM_RESET) != QLA_SUCCESS) {
-		starget_printk(KERN_INFO, scsi_target(cmd->device),
+		starget_printk(KERN_INFO, starget,
 			       "WARM TARGET DEVICE RESET FAILED - "
 			       "marker iocb failed.\n");
 		return FAILED;
 	}
 
-	starget_printk(KERN_INFO, scsi_target(cmd->device),
+	starget_printk(KERN_INFO, starget,
 		       "WARM TARGET RESET SUCCEEDED.\n");
 	return SUCCESS;
 }
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 1e89598..37e511f 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3809,39 +3809,30 @@ static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
+static int scsi_debug_target_reset(struct scsi_target *starget)
 {
+	struct Scsi_Host *hp = dev_to_shost(&starget->dev);
 	struct sdebug_host_info *sdbg_host;
 	struct sdebug_dev_info *devip;
-	struct scsi_device *sdp;
-	struct Scsi_Host *hp;
 	int k = 0;
 
 	++num_target_resets;
-	if (!SCpnt)
-		goto lie;
-	sdp = SCpnt->device;
-	if (!sdp)
-		goto lie;
 	if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
-		sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
-	hp = sdp->host;
-	if (!hp)
-		goto lie;
+		starget_printk(KERN_INFO, starget, "%s\n", __func__);
 	sdbg_host = *(struct sdebug_host_info **)shost_priv(hp);
 	if (sdbg_host) {
 		list_for_each_entry(devip,
 				    &sdbg_host->dev_info_list,
 				    dev_list)
-			if (devip->target == sdp->id) {
+			if (devip->target == starget->id) {
 				set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
 				++k;
 			}
 	}
 	if (SDEBUG_OPT_RESET_NOISE & sdebug_opts)
-		sdev_printk(KERN_INFO, sdp,
+		starget_printk(KERN_INFO, starget,
 			    "%s: %d device(s) found in target\n", __func__, k);
-lie:
+
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 9dd51ed..368a961 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -810,14 +810,15 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd)
 	int rtn;
 	struct Scsi_Host *host = scmd->device->host;
 	struct scsi_host_template *hostt = host->hostt;
+	struct scsi_target *starget = scsi_target(scmd->device);
 
 	if (!hostt->eh_target_reset_handler)
 		return FAILED;
 
-	rtn = hostt->eh_target_reset_handler(scmd);
+	rtn = hostt->eh_target_reset_handler(starget);
 	if (rtn == SUCCESS) {
 		spin_lock_irqsave(host->host_lock, flags);
-		__starget_for_each_device(scsi_target(scmd->device), NULL,
+		__starget_for_each_device(starget, NULL,
 					  __scsi_report_device_reset);
 		spin_unlock_irqrestore(host->host_lock, flags);
 	}
diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index a424eae..88269f8 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1855,17 +1855,15 @@ static void iscsi_scan_session(struct work_struct *work)
 
 /**
  * iscsi_block_scsi_eh - block scsi eh until session state has transistioned
- * @cmd: scsi cmd passed to scsi eh handler
+ * @session: session to be blocked
  *
  * If the session is down this function will wait for the recovery
  * timer to fire or for the session to be logged back in. If the
  * recovery timer fires then FAST_IO_FAIL is returned. The caller
  * should pass this error value to the scsi eh.
  */
-int iscsi_block_scsi_eh(struct scsi_cmnd *cmd)
+int iscsi_block_scsi_eh(struct iscsi_cls_session *session)
 {
-	struct iscsi_cls_session *session =
-			starget_to_session(scsi_target(cmd->device));
 	unsigned long flags;
 	int ret = 0;
 
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 6afebc4..757add6 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -641,9 +641,8 @@ static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd)
 	return sts ? SCSI_FAILED : SCSI_SUCCESS;
 }
 
-static int sym53c8xx_eh_target_reset_handler(struct scsi_cmnd *cmd)
+static int sym53c8xx_eh_target_reset_handler(struct scsi_target *starget)
 {
-	struct scsi_target *starget = scsi_target(cmd->device);
 	struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
 	struct sym_data *sym_data = shost_priv(shost);
 	struct pci_dev *pdev = sym_data->pdev;
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 5091b31..1a10270 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -328,24 +328,25 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
 	return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
 }
 
-static int tcm_loop_target_reset(struct scsi_cmnd *sc)
+static int tcm_loop_target_reset(struct scsi_target *starget)
 {
 	struct tcm_loop_hba *tl_hba;
 	struct tcm_loop_tpg *tl_tpg;
+	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
 
 	/*
 	 * Locate the tcm_loop_hba_t pointer
 	 */
-	tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
+	tl_hba = *(struct tcm_loop_hba **)shost_priv(shost);
 	if (!tl_hba) {
 		pr_err("Unable to perform device reset without"
 				" active I_T Nexus\n");
 		return FAILED;
 	}
 	/*
-	 * Locate the tl_tpg pointer from TargetID in sc->device->id
+	 * Locate the tl_tpg pointer from TargetID in starget->id
 	 */
-	tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+	tl_tpg = &tl_hba->tl_hba_tpgs[starget->id];
 	if (tl_tpg) {
 		tl_tpg->tl_transport_status = TCM_TRANSPORT_ONLINE;
 		return SUCCESS;
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index d34daf8..a8fff96 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -381,7 +381,7 @@ struct iscsi_host {
  * scsi host template
  */
 extern int iscsi_eh_abort(struct scsi_cmnd *sc);
-extern int iscsi_eh_recover_target(struct scsi_cmnd *sc);
+extern int iscsi_eh_recover_target(struct scsi_target *starget);
 extern int iscsi_eh_session_reset(struct iscsi_cls_session *cls_session);
 extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
 extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index e7c012c..5953bcb 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -714,7 +714,7 @@ extern int sas_bios_param(struct scsi_device *,
 void sas_task_abort(struct sas_task *);
 int sas_eh_abort_handler(struct scsi_cmnd *cmd);
 int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
-int sas_eh_target_reset_handler(struct scsi_cmnd *cmd);
+int sas_eh_target_reset_handler(struct scsi_target *starget);
 
 extern void sas_target_destroy(struct scsi_target *);
 extern int sas_slave_alloc(struct scsi_device *);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 0c5ce78..33bc523 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -146,7 +146,7 @@ struct scsi_host_template {
 	 */
 	int (* eh_abort_handler)(struct scsi_cmnd *);
 	int (* eh_device_reset_handler)(struct scsi_cmnd *);
-	int (* eh_target_reset_handler)(struct scsi_cmnd *);
+	int (* eh_target_reset_handler)(struct scsi_target *);
 	int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
 	int (* eh_host_reset_handler)(struct Scsi_Host *);
 
diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h
index 6183d20..9e541d5 100644
--- a/include/scsi/scsi_transport_iscsi.h
+++ b/include/scsi/scsi_transport_iscsi.h
@@ -444,7 +444,7 @@ extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess,
 extern struct iscsi_endpoint *iscsi_create_endpoint(int dd_size);
 extern void iscsi_destroy_endpoint(struct iscsi_endpoint *ep);
 extern struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle);
-extern int iscsi_block_scsi_eh(struct scsi_cmnd *cmd);
+extern int iscsi_block_scsi_eh(struct iscsi_cls_session *session);
 extern struct iscsi_iface *iscsi_create_iface(struct Scsi_Host *shost,
 					      struct iscsi_transport *t,
 					      uint32_t iface_type,
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 33/47] cxlflash: use dedicated reset command in send_tmf()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (31 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler() Hannes Reinecke
@ 2017-06-28  8:32 ` Hannes Reinecke
  2017-06-28 16:29   ` Matthew R. Ochs
  2017-06-28  8:33 ` [PATCH 34/47] aha152x: look for stuck command when resetting device Hannes Reinecke
                   ` (15 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:32 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

From: Hannes Reinecke <hare@suse.com>

Reduce the queue depth by 1, and use this command as a dedicated
reset command send_tmf().

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/cxlflash/common.h |  3 ++-
 drivers/scsi/cxlflash/main.c   | 23 ++++++++++++++++-------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h
index 6d95e8e..b2b3bdc 100644
--- a/drivers/scsi/cxlflash/common.h
+++ b/drivers/scsi/cxlflash/common.h
@@ -54,7 +54,8 @@
 
 /* Command management definitions */
 #define CXLFLASH_MAX_CMDS               256
-#define CXLFLASH_MAX_CMDS_PER_LUN       CXLFLASH_MAX_CMDS
+#define CXLFLASH_MAX_CMDS_PER_LUN       CXLFLASH_MAX_CMDS - 1
+#define CXLFLASH_RESET_CMD              255
 
 /* RRQ for master issued cmds */
 #define NUM_RRQ_ENTRY                   CXLFLASH_MAX_CMDS
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
index 462e8fc..b33e3e7 100644
--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -23,6 +23,7 @@
 
 #include <scsi/scsi_cmnd.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_tcq.h>
 #include <uapi/scsi/cxlflash_ioctl.h>
 
 #include "main.h"
@@ -460,15 +461,16 @@ static u32 cmd_to_target_hwq(struct Scsi_Host *host, struct scsi_cmnd *scp,
 /**
  * send_tmf() - sends a Task Management Function (TMF)
  * @afu:	AFU to checkout from.
- * @scp:	SCSI command from stack describing target.
+ * @sdev:	SCSI device to reset.
  * @tmfcmd:	TMF command to send.
  *
  * Return:
  *	0 on success, SCSI_MLQUEUE_HOST_BUSY or -errno on failure
  */
-static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
+static int send_tmf(struct afu *afu, struct scsi_device *sdev, u64 tmfcmd)
 {
-	struct Scsi_Host *host = scp->device->host;
+	struct scsi_cmnd *scp;
+	struct Scsi_Host *host = sdev->host;
 	struct cxlflash_cfg *cfg = shost_priv(host);
 	struct afu_cmd *cmd = NULL;
 	struct device *dev = &cfg->dev->dev;
@@ -498,14 +500,21 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
 	cfg->tmf_active = true;
 	spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
 
+	scp = scsi_host_find_tag(host, CXLFLASH_RESET_CMD);
+	scp->device = sdev;
+	cmd = sc_to_afucz(scp);
+	hwq_index = cmd_to_target_hwq(host, scp, afu);
+	hwq = get_hwq(afu, hwq_index);
+
+	cmd->scp = scp;
 	cmd->parent = afu;
 	cmd->cmd_tmf = true;
 	cmd->hwq_index = hwq_index;
 
 	cmd->rcb.ctx_id = hwq->ctx_hndl;
 	cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
-	cmd->rcb.port_sel = CHAN2PORTMASK(scp->device->channel);
-	cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);
+	cmd->rcb.port_sel = CHAN2PORTMASK(sdev->channel);
+	cmd->rcb.lun_id = lun_to_lunid(sdev->lun);
 	cmd->rcb.req_flags = (SISL_REQ_FLAGS_PORT_LUN_ID |
 			      SISL_REQ_FLAGS_SUP_UNDERRUN |
 			      SISL_REQ_FLAGS_TMF_CMD);
@@ -2448,7 +2457,7 @@ static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
 retry:
 	switch (cfg->state) {
 	case STATE_NORMAL:
-		rcr = send_tmf(afu, scp, TMF_LUN_RESET);
+		rcr = send_tmf(afu, sdev, TMF_LUN_RESET);
 		if (unlikely(rcr))
 			rc = FAILED;
 		break;
@@ -3139,7 +3148,7 @@ static ssize_t mode_show(struct device *dev,
 	.eh_host_reset_handler = cxlflash_eh_host_reset_handler,
 	.change_queue_depth = cxlflash_change_queue_depth,
 	.cmd_per_lun = CXLFLASH_MAX_CMDS_PER_LUN,
-	.can_queue = CXLFLASH_MAX_CMDS,
+	.can_queue = CXLFLASH_MAX_CMDS - 1,
 	.cmd_size = sizeof(struct afu_cmd) + __alignof__(struct afu_cmd) - 1,
 	.this_id = -1,
 	.sg_tablesize = 1,	/* No scatter gather support */
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 34/47] aha152x: look for stuck command when resetting device
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (32 preceding siblings ...)
  2017-06-28  8:32 ` [PATCH 33/47] cxlflash: use dedicated reset command in send_tmf() Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 35/47] fnic: use dedicated device reset command Hannes Reinecke
                   ` (14 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

From: Hannes Reinecke <hare@suse.com>

The LLDD needs a command to send the reset with, so look at the
list of outstanding commands to get one.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aha152x.c | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 857884a..896c36e 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1055,23 +1055,27 @@ static int aha152x_abort(Scsi_Cmnd *SCpnt)
 static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
 {
 	struct Scsi_Host *shpnt = SCpnt->device->host;
+	struct scsi_cmnd *SCprev = NULL;
 	DECLARE_COMPLETION(done);
 	int ret, issued, disconnected;
-	unsigned char old_cmd_len = SCpnt->cmd_len;
+	unsigned char old_cmd_len;
 	unsigned long flags;
 	unsigned long timeleft;
 
-	if(CURRENT_SC==SCpnt) {
-		scmd_printk(KERN_ERR, SCpnt, "cannot reset current device\n");
-		return FAILED;
-	}
-
 	DO_LOCK(flags);
-	issued       = remove_SC(&ISSUE_SC, SCpnt) == NULL;
-	disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);
+	/* Look for the stuck command */
+	SCpnt = remove_lun_SC(&ISSUE_SC, sdev->id, sdev->lun);
+	if (SCpnt)
+		issued = 1;
+	else
+		SCpnt = remove_lun_SC(&DISCONNECTED_SC, sdev->id, sdev->lun);
+	if (!issued && SCpnt)
+		disconnected = 1;
 	DO_UNLOCK(flags);
-
-	SCpnt->cmd_len         = 0;
+	if (!SCpnt)
+		return FAILED;
+	old_cmd_len = SCpnt->cmd_len;
+	SCpnt->cmd_len = 0;
 
 	aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 35/47] fnic: use dedicated device reset command
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (33 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 34/47] aha152x: look for stuck command when resetting device Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 36/47] a1000u2w: do not rely on the command for inia100_device_reset() Hannes Reinecke
                   ` (13 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Use a dedicated command to send a device reset instead of relying
on using the command which triggered the device failure.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/fnic/fnic_main.c |  2 ++
 drivers/scsi/fnic/fnic_scsi.c | 78 +++++++++++++------------------------------
 2 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c
index aacadbf..22fd37c 100644
--- a/drivers/scsi/fnic/fnic_main.c
+++ b/drivers/scsi/fnic/fnic_main.c
@@ -706,6 +706,8 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 					fnic->config.io_throttle_count));
 	}
 	fnic->fnic_max_tag_id = host->can_queue;
+	/* Reserve the last tag for device reset */
+	host->can_queue--;
 
 	host->max_lun = fnic->config.luns_per_tgt;
 	host->max_id = FNIC_MAX_FCP_TARGET;
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index 731ec87..acf7d1d 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -2106,9 +2106,7 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
  * successfully aborted, 1 otherwise
  */
 static int fnic_clean_pending_aborts(struct fnic *fnic,
-				     struct scsi_cmnd *lr_sc,
-					 bool new_sc)
-
+				     struct scsi_cmnd *lr_sc)
 {
 	int tag, abt_tag;
 	struct fnic_io_req *io_req;
@@ -2129,7 +2127,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
 		 * ignore this lun reset cmd if issued using new SC
 		 * or cmds that do not belong to this lun
 		 */
-		if (!sc || ((sc == lr_sc) && new_sc) || sc->device != lun_dev) {
+		if (!sc || sc == lr_sc || sc->device != lun_dev) {
 			spin_unlock_irqrestore(io_lock, flags);
 			continue;
 		}
@@ -2334,6 +2332,7 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
  */
 int fnic_device_reset(struct scsi_cmnd *sc)
 {
+	struct scsi_device *sdev = sc->device;
 	struct fc_lport *lp;
 	struct fnic *fnic;
 	struct fnic_io_req *io_req = NULL;
@@ -2348,18 +2347,16 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	struct reset_stats *reset_stats;
 	int tag = 0;
 	DECLARE_COMPLETION_ONSTACK(tm_done);
-	int tag_gen_flag = 0;   /*to track tags allocated by fnic driver*/
-	bool new_sc = 0;
 
 	/* Wait for rport to unblock */
-	rport = starget_to_rport(scsi_target(sc->device));
+	rport = starget_to_rport(scsi_target(sdev));
 	ret = fc_block_scsi_eh(rport);
 	if (ret)
 		return ret;
 
 	ret = FAILED;
 	/* Get local-port, check ready and link up */
-	lp = shost_priv(sc->device->host);
+	lp = shost_priv(sdev->host);
 
 	fnic = lport_priv(lp);
 	fnic_stats = &fnic->fnic_stats;
@@ -2368,8 +2365,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	atomic64_inc(&reset_stats->device_resets);
 
 	FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
-		      "Device reset called FCID 0x%x, LUN 0x%llx sc 0x%p\n",
-		      rport->port_id, sc->device->lun, sc);
+		      "Device reset called FCID 0x%x, LUN 0x%llx\n",
+		      rport->port_id, sdev->lun);
 
 	if (lp->state != LPORT_ST_READY || !(lp->link_up))
 		goto fnic_device_reset_end;
@@ -2379,51 +2376,28 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 		atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
 		goto fnic_device_reset_end;
 	}
-
-	CMD_FLAGS(sc) = FNIC_DEVICE_RESET;
-	/* Allocate tag if not present */
-
-	tag = sc->request->tag;
-	if (unlikely(tag < 0)) {
+	/* The last tag is reserved for device reset */
+	sc = scsi_host_find_tag(sdev->host, fnic->fnic_max_tag_id - 1);
+	io_lock = fnic_io_lock_hash(fnic, sc);
+	spin_lock_irqsave(io_lock, flags);
+	if (CMD_SP(sc)) {
 		/*
-		 * XXX(hch): current the midlayer fakes up a struct
-		 * request for the explicit reset ioctls, and those
-		 * don't have a tag allocated to them.  The below
-		 * code pokes into midlayer structures to paper over
-		 * this design issue, but that won't work for blk-mq.
-		 *
-		 * Either someone who can actually test the hardware
-		 * will have to come up with a similar hack for the
-		 * blk-mq case, or we'll have to bite the bullet and
-		 * fix the way the EH ioctls work for real, but until
-		 * that happens we fail these explicit requests here.
+		 * Reset tag busy
 		 */
-
-		tag = fnic_scsi_host_start_tag(fnic, sc);
-		if (unlikely(tag == SCSI_NO_TAG))
-			goto fnic_device_reset_end;
-		tag_gen_flag = 1;
-		new_sc = 1;
+		spin_unlock_irqrestore(io_lock, flags);
+		goto fnic_device_reset_end;
 	}
-	io_lock = fnic_io_lock_hash(fnic, sc);
-	spin_lock_irqsave(io_lock, flags);
-	io_req = (struct fnic_io_req *)CMD_SP(sc);
-
-	/*
-	 * If there is a io_req attached to this command, then use it,
-	 * else allocate a new one.
-	 */
+	io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC);
 	if (!io_req) {
-		io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC);
-		if (!io_req) {
-			spin_unlock_irqrestore(io_lock, flags);
-			goto fnic_device_reset_end;
-		}
-		memset(io_req, 0, sizeof(*io_req));
-		io_req->port_id = rport->port_id;
-		CMD_SP(sc) = (char *)io_req;
+		spin_unlock_irqrestore(io_lock, flags);
+		goto fnic_device_reset_end;
 	}
+	memset(io_req, 0, sizeof(*io_req));
+	io_req->port_id = rport->port_id;
+	CMD_SP(sc) = (char *)io_req;
 	io_req->dr_done = &tm_done;
+
+	CMD_FLAGS(sc) = FNIC_DEVICE_RESET;
 	CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING;
 	CMD_LR_STATUS(sc) = FCPIO_INVALID_CODE;
 	spin_unlock_irqrestore(io_lock, flags);
@@ -2538,7 +2512,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	 * the lun reset cmd. If all cmds get cleaned, the lun reset
 	 * succeeds
 	 */
-	if (fnic_clean_pending_aborts(fnic, sc, new_sc)) {
+	if (fnic_clean_pending_aborts(fnic, sc)) {
 		spin_lock_irqsave(io_lock, flags);
 		io_req = (struct fnic_io_req *)CMD_SP(sc);
 		FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
@@ -2575,10 +2549,6 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 		  (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
 		  (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc)));
 
-	/* free tag if it is allocated */
-	if (unlikely(tag_gen_flag))
-		fnic_scsi_host_end_tag(fnic, sc);
-
 	FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
 		      "Returning from device reset %s\n",
 		      (ret == SUCCESS) ?
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 36/47] a1000u2w: do not rely on the command for inia100_device_reset()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (34 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 35/47] fnic: use dedicated device reset command Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 37/47] aic79xx: use scsi device as argument for BUILD_SCSIID() Hannes Reinecke
                   ` (12 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Use the scsi device as argument to orc_device_reset() instead
of relying on the passed in scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/a100u2w.c | 43 +++++++++++--------------------------------
 1 file changed, 11 insertions(+), 32 deletions(-)

diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 1c61d7a..8802d23 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -592,39 +592,20 @@ static int orc_reset_scsi_bus(struct orc_host * host)
  *	commands for target w/o soft reset
  */
 
-static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsigned int target)
+static int orc_device_reset(struct orc_host * host, struct scsi_device *sdev)
 {				/* I need Host Control Block Information */
 	struct orc_scb *scb;
 	struct orc_extended_scb *escb;
-	struct orc_scb *host_scb;
-	u8 i;
 	unsigned long flags;
 
 	spin_lock_irqsave(&(host->allocation_lock), flags);
 	scb = (struct orc_scb *) NULL;
 	escb = (struct orc_extended_scb *) NULL;
 
-	/* setup scatter list address with one buffer */
-	host_scb = host->scb_virt;
-
 	/* FIXME: is this safe if we then fail to issue the reset or race
 	   a completion ? */
 	init_alloc_map(host);
 
-	/* Find the scb corresponding to the command */
-	for (i = 0; i < ORC_MAXQUEUE; i++) {
-		escb = host_scb->escb;
-		if (host_scb->status && escb->srb == cmd)
-			break;
-		host_scb++;
-	}
-
-	if (i == ORC_MAXQUEUE) {
-		printk(KERN_ERR "Unable to Reset - No SCB Found\n");
-		spin_unlock_irqrestore(&(host->allocation_lock), flags);
-		return FAILED;
-	}
-
 	/* Allocate a new SCB for the reset command to the firmware */
 	if ((scb = __orc_alloc_scb(host)) == NULL) {
 		/* Can't happen.. */
@@ -635,7 +616,7 @@ static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsig
 	/* Reset device is handled by the firmware, we fill in an SCB and
 	   fire it at the controller, it does the rest */
 	scb->opcode = ORC_BUSDEVRST;
-	scb->target = target;
+	scb->target = sdev->id;
 	scb->hastat = 0;
 	scb->tastat = 0;
 	scb->status = 0x0;
@@ -645,8 +626,8 @@ static int orc_device_reset(struct orc_host * host, struct scsi_cmnd *cmd, unsig
 	scb->xferlen = cpu_to_le32(0);
 	scb->sg_len = cpu_to_le32(0);
 
+	escb = scb->escb;
 	escb->srb = NULL;
-	escb->srb = cmd;
 	orc_exec_scb(host, scb);	/* Start execute SCB            */
 	spin_unlock_irqrestore(&host->allocation_lock, flags);
 	return SUCCESS;
@@ -974,7 +955,7 @@ static int inia100_device_reset(struct scsi_cmnd * cmd)
 {				/* I need Host Control Block Information */
 	struct orc_host *host;
 	host = (struct orc_host *) cmd->device->host->hostdata;
-	return orc_device_reset(host, cmd, scmd_id(cmd));
+	return orc_device_reset(host, cmd->device);
 
 }
 
@@ -994,11 +975,7 @@ static void inia100_scb_handler(struct orc_host *host, struct orc_scb *scb)
 	struct orc_extended_scb *escb;
 
 	escb = scb->escb;
-	if ((cmd = (struct scsi_cmnd *) escb->srb) == NULL) {
-		printk(KERN_ERR "inia100_scb_handler: SRB pointer is empty\n");
-		orc_release_scb(host, scb);	/* Release SCB for current channel */
-		return;
-	}
+	cmd = (struct scsi_cmnd *)escb->srb;
 	escb->srb = NULL;
 
 	switch (scb->hastat) {
@@ -1036,13 +1013,15 @@ static void inia100_scb_handler(struct orc_host *host, struct orc_scb *scb)
 		break;
 	}
 
-	if (scb->tastat == 2) {	/* Check condition              */
+	if (cmd && scb->tastat == 2) {	/* Check condition              */
 		memcpy((unsigned char *) &cmd->sense_buffer[0],
 		   (unsigned char *) &escb->sglist[0], SENSE_SIZE);
 	}
-	cmd->result = scb->tastat | (scb->hastat << 16);
-	scsi_dma_unmap(cmd);
-	cmd->scsi_done(cmd);	/* Notify system DONE           */
+	if (cmd) {
+		cmd->result = scb->tastat | (scb->hastat << 16);
+		scsi_dma_unmap(cmd);
+		cmd->scsi_done(cmd);	/* Notify system DONE           */
+	}
 	orc_release_scb(host, scb);	/* Release SCB for current channel */
 }
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 37/47] aic79xx: use scsi device as argument for BUILD_SCSIID()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (35 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 36/47] a1000u2w: do not rely on the command for inia100_device_reset() Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 38/47] aic7xxx: " Hannes Reinecke
                   ` (11 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aic7xxx/aic79xx_osm.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 0797c2f..66f9450 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -541,8 +541,8 @@ void ahd_insb(struct ahd_softc * ahd, long port,
 }
 
 /******************************** Macros **************************************/
-#define BUILD_SCSIID(ahd, cmd)						\
-	(((scmd_id(cmd) << TID_SHIFT) & TID) | (ahd)->our_id)
+#define BUILD_SCSIID(ahd, sdev)					\
+	(((sdev_id(sdev) << TID_SHIFT) & TID) | (ahd)->our_id)
 
 /*
  * Return a string describing the driver.
@@ -837,7 +837,7 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
 	ahd_set_sense_residual(reset_scb, 0);
 	reset_scb->platform_data->xfer_len = 0;
 	reset_scb->hscb->control = 0;
-	reset_scb->hscb->scsiid = BUILD_SCSIID(ahd,cmd);
+	reset_scb->hscb->scsiid = BUILD_SCSIID(ahd, cmd->device);
 	reset_scb->hscb->lun = cmd->device->lun;
 	reset_scb->hscb->cdb_len = 0;
 	reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
@@ -1598,7 +1598,7 @@ struct scsi_host_template aic79xx_driver_template = {
 	 * Fill out basics of the HSCB.
 	 */
 	hscb->control = 0;
-	hscb->scsiid = BUILD_SCSIID(ahd, cmd);
+	hscb->scsiid = BUILD_SCSIID(ahd, cmd->device);
 	hscb->lun = cmd->device->lun;
 	scb->hscb->task_management = 0;
 	mask = SCB_GET_TARGET_MASK(ahd, scb);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 38/47] aic7xxx: use scsi device as argument for BUILD_SCSIID()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (36 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 37/47] aic79xx: use scsi device as argument for BUILD_SCSIID() Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 39/47] aic79xx: do not reference scsi command when resetting device Hannes Reinecke
                   ` (10 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aic7xxx/aic7xxx_osm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 5f9d2ae..72f3007 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -817,10 +817,10 @@ struct scsi_host_template aic7xxx_driver_template = {
 /**************************** Tasklet Handler *********************************/
 
 /******************************** Macros **************************************/
-#define BUILD_SCSIID(ahc, cmd)						    \
-	((((cmd)->device->id << TID_SHIFT) & TID)			    \
-	| (((cmd)->device->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
-	| (((cmd)->device->channel == 0) ? 0 : TWIN_CHNLB))
+#define BUILD_SCSIID(ahc, sdev)						    \
+	((((sdev)->id << TID_SHIFT) & TID)			    \
+	| (((sdev)->channel == 0) ? (ahc)->our_id : (ahc)->our_id_b) \
+	| (((sdev)->channel == 0) ? 0 : TWIN_CHNLB))
 
 /******************************** Bus DMA *************************************/
 int
@@ -1477,7 +1477,7 @@ struct scsi_host_template aic7xxx_driver_template = {
 	 * Fill out basics of the HSCB.
 	 */
 	hscb->control = 0;
-	hscb->scsiid = BUILD_SCSIID(ahc, cmd);
+	hscb->scsiid = BUILD_SCSIID(ahc, cmd->device);
 	hscb->lun = cmd->device->lun;
 	mask = SCB_GET_TARGET_MASK(ahc, scb);
 	tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb),
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 39/47] aic79xx: do not reference scsi command when resetting device
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (37 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 38/47] aic7xxx: " Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 40/47] aic7xxx: " Hannes Reinecke
                   ` (9 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When sending a device reset we should not take a reference to the
scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aic7xxx/aic79xx_osm.c | 21 +++++++++++++++------
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 66f9450..695e93e 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -536,8 +536,10 @@ void ahd_insb(struct ahd_softc * ahd, long port,
 	struct scsi_cmnd *cmd;
 
 	cmd = scb->io_ctx;
-	ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
-	scsi_dma_unmap(cmd);
+	if (cmd) {
+		ahd_sync_sglist(ahd, scb, BUS_DMASYNC_POSTWRITE);
+		scsi_dma_unmap(cmd);
+	}
 }
 
 /******************************** Macros **************************************/
@@ -830,7 +832,7 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
 
 	tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
 				    cmd->device->id, &tstate);
-	reset_scb->io_ctx = cmd;
+	reset_scb->io_ctx = NULL;
 	reset_scb->platform_data->dev = dev;
 	reset_scb->sg_count = 0;
 	ahd_set_residual(reset_scb, 0);
@@ -1787,9 +1789,16 @@ struct scsi_host_template aic79xx_driver_template = {
 	dev = scb->platform_data->dev;
 	dev->active--;
 	dev->openings++;
-	if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
-		cmd->result &= ~(CAM_DEV_QFRZN << 16);
-		dev->qfrozen--;
+	if (cmd) {
+		if ((cmd->result & (CAM_DEV_QFRZN << 16)) != 0) {
+			cmd->result &= ~(CAM_DEV_QFRZN << 16);
+			dev->qfrozen--;
+		}
+	} else if (scb->flags & SCB_DEVICE_RESET) {
+		if (ahd->platform_data->eh_done)
+			complete(ahd->platform_data->eh_done);
+		ahd_free_scb(ahd, scb);
+		return;
 	}
 	ahd_linux_unmap_scb(ahd, scb);
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 40/47] aic7xxx: do not reference scsi command when resetting device
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (38 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 39/47] aic79xx: do not reference scsi command when resetting device Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 41/47] xen-scsifront: add scsi device as argument to scsifront_do_request() Hannes Reinecke
                   ` (8 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When sending a device reset we should not take a reference to the
scsi command.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/aic7xxx/aic7xxx_osm.c | 102 ++++++++++++++++++++-----------------
 1 file changed, 54 insertions(+), 48 deletions(-)

diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 72f3007..fe8f675 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -365,7 +365,8 @@ static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc,
 					 struct scsi_cmnd *cmd);
 static void ahc_linux_freeze_simq(struct ahc_softc *ahc);
 static void ahc_linux_release_simq(struct ahc_softc *ahc);
-static int  ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag);
+static int  ahc_linux_queue_recovery_cmd(struct scsi_device *sdev,
+					 struct scsi_cmnd *cmd);
 static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc);
 static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc,
 				     struct ahc_devinfo *devinfo);
@@ -745,7 +746,7 @@ static DEF_SCSI_QCMD(ahc_linux_queue)
 {
 	int error;
 
-	error = ahc_linux_queue_recovery_cmd(cmd, SCB_ABORT);
+	error = ahc_linux_queue_recovery_cmd(cmd->device, cmd);
 	if (error != 0)
 		printk("aic7xxx_abort returns 0x%x\n", error);
 	return (error);
@@ -759,7 +760,7 @@ static DEF_SCSI_QCMD(ahc_linux_queue)
 {
 	int error;
 
-	error = ahc_linux_queue_recovery_cmd(cmd, SCB_DEVICE_RESET);
+	error = ahc_linux_queue_recovery_cmd(cmd->device, NULL);
 	if (error != 0)
 		printk("aic7xxx_dev_reset returns 0x%x\n", error);
 	return (error);
@@ -2050,11 +2051,12 @@ struct scsi_host_template aic7xxx_driver_template = {
 }
 
 static int
-ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag)
+ahc_linux_queue_recovery_cmd(struct scsi_device *sdev,
+			     struct scsi_cmnd *cmd)
 {
 	struct ahc_softc *ahc;
 	struct ahc_linux_device *dev;
-	struct scb *pending_scb;
+	struct scb *pending_scb = NULL, *scb;
 	u_int  saved_scbptr;
 	u_int  active_scb_index;
 	u_int  last_phase;
@@ -2067,18 +2069,19 @@ struct scsi_host_template aic7xxx_driver_template = {
 	int    disconnected;
 	unsigned long flags;
 
-	pending_scb = NULL;
 	paused = FALSE;
 	wait = FALSE;
-	ahc = *(struct ahc_softc **)cmd->device->host->hostdata;
+	ahc = *(struct ahc_softc **)sdev->host->hostdata;
 
-	scmd_printk(KERN_INFO, cmd, "Attempting to queue a%s message\n",
-	       flag == SCB_ABORT ? "n ABORT" : " TARGET RESET");
+	sdev_printk(KERN_INFO, sdev, "Attempting to queue a%s message\n",
+	       cmd ? "n ABORT" : " TARGET RESET");
 
-	printk("CDB:");
-	for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
-		printk(" 0x%x", cmd->cmnd[cdb_byte]);
-	printk("\n");
+	if (cmd) {
+		printk("CDB:");
+		for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
+			printk(" 0x%x", cmd->cmnd[cdb_byte]);
+		printk("\n");
+	}
 
 	ahc_lock(ahc, &flags);
 
@@ -2089,7 +2092,7 @@ struct scsi_host_template aic7xxx_driver_template = {
 	 * at all, and the system wanted us to just abort the
 	 * command, return success.
 	 */
-	dev = scsi_transport_device_data(cmd->device);
+	dev = scsi_transport_device_data(sdev);
 
 	if (dev == NULL) {
 		/*
@@ -2097,13 +2100,12 @@ struct scsi_host_template aic7xxx_driver_template = {
 		 * so we must not still own the command.
 		 */
 		printk("%s:%d:%d:%d: Is not an active device\n",
-		       ahc_name(ahc), cmd->device->channel, cmd->device->id,
-		       (u8)cmd->device->lun);
+		       ahc_name(ahc), sdev->channel, sdev->id, (u8)sdev->lun);
 		retval = SUCCESS;
 		goto no_cmd;
 	}
 
-	if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
+	if (cmd && (dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0
 	 && ahc_search_untagged_queues(ahc, cmd, cmd->device->id,
 				       cmd->device->channel + 'A',
 				       (u8)cmd->device->lun,
@@ -2118,25 +2120,28 @@ struct scsi_host_template aic7xxx_driver_template = {
 	/*
 	 * See if we can find a matching cmd in the pending list.
 	 */
-	LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
-		if (pending_scb->io_ctx == cmd)
+	LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
+		if (cmd && scb->io_ctx == cmd) {
+			pending_scb = scb;
 			break;
+		}
 	}
 
-	if (pending_scb == NULL && flag == SCB_DEVICE_RESET) {
-
+	if (!cmd) {
 		/* Any SCB for this device will do for a target reset */
-		LIST_FOREACH(pending_scb, &ahc->pending_scbs, pending_links) {
-		  	if (ahc_match_scb(ahc, pending_scb, scmd_id(cmd),
-					  scmd_channel(cmd) + 'A',
+		LIST_FOREACH(scb, &ahc->pending_scbs, pending_links) {
+			if (ahc_match_scb(ahc, scb, sdev->id,
+					  sdev->channel + 'A',
 					  CAM_LUN_WILDCARD,
-					  SCB_LIST_NULL, ROLE_INITIATOR))
+					  SCB_LIST_NULL, ROLE_INITIATOR)) {
+				pending_scb = scb;
 				break;
+			}
 		}
 	}
 
 	if (pending_scb == NULL) {
-		scmd_printk(KERN_INFO, cmd, "Command not found\n");
+		sdev_printk(KERN_INFO, sdev, "Command not found\n");
 		goto no_cmd;
 	}
 
@@ -2167,22 +2172,22 @@ struct scsi_host_template aic7xxx_driver_template = {
 	ahc_dump_card_state(ahc);
 
 	disconnected = TRUE;
-	if (flag == SCB_ABORT) {
-		if (ahc_search_qinfifo(ahc, cmd->device->id,
-				       cmd->device->channel + 'A',
-				       cmd->device->lun,
+	if (cmd) {
+		if (ahc_search_qinfifo(ahc, sdev->id,
+				       sdev->channel + 'A',
+				       sdev->lun,
 				       pending_scb->hscb->tag,
 				       ROLE_INITIATOR, CAM_REQ_ABORTED,
 				       SEARCH_COMPLETE) > 0) {
 			printk("%s:%d:%d:%d: Cmd aborted from QINFIFO\n",
-			       ahc_name(ahc), cmd->device->channel,
-			       cmd->device->id, (u8)cmd->device->lun);
+			       ahc_name(ahc), sdev->channel,
+			       sdev->id, (u8)sdev->lun);
 			retval = SUCCESS;
 			goto done;
 		}
-	} else if (ahc_search_qinfifo(ahc, cmd->device->id,
-				      cmd->device->channel + 'A',
-				      cmd->device->lun,
+	} else if (ahc_search_qinfifo(ahc, sdev->id,
+				      sdev->channel + 'A',
+				      sdev->lun,
 				      pending_scb->hscb->tag,
 				      ROLE_INITIATOR, /*status*/0,
 				      SEARCH_COUNT) > 0) {
@@ -2195,7 +2200,7 @@ struct scsi_host_template aic7xxx_driver_template = {
 		bus_scb = ahc_lookup_scb(ahc, ahc_inb(ahc, SCB_TAG));
 		if (bus_scb == pending_scb)
 			disconnected = FALSE;
-		else if (flag != SCB_ABORT
+		else if (!cmd
 		      && ahc_inb(ahc, SAVED_SCSIID) == pending_scb->hscb->scsiid
 		      && ahc_inb(ahc, SAVED_LUN) == SCB_GET_LUN(pending_scb))
 			disconnected = FALSE;
@@ -2215,18 +2220,18 @@ struct scsi_host_template aic7xxx_driver_template = {
 	saved_scsiid = ahc_inb(ahc, SAVED_SCSIID);
 	if (last_phase != P_BUSFREE
 	 && (pending_scb->hscb->tag == active_scb_index
-	  || (flag == SCB_DEVICE_RESET
-	   && SCSIID_TARGET(ahc, saved_scsiid) == scmd_id(cmd)))) {
+	  || (!cmd && SCSIID_TARGET(ahc, saved_scsiid) == sdev->id))) {
 
 		/*
 		 * We're active on the bus, so assert ATN
 		 * and hope that the target responds.
 		 */
 		pending_scb = ahc_lookup_scb(ahc, active_scb_index);
-		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
+		pending_scb->flags |= SCB_RECOVERY_SCB;
+		pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET;
 		ahc_outb(ahc, MSG_OUT, HOST_MSG);
 		ahc_outb(ahc, SCSISIGO, last_phase|ATNO);
-		scmd_printk(KERN_INFO, cmd, "Device is active, asserting ATN\n");
+		sdev_printk(KERN_INFO, sdev, "Device is active, asserting ATN\n");
 		wait = TRUE;
 	} else if (disconnected) {
 
@@ -2247,7 +2252,8 @@ struct scsi_host_template aic7xxx_driver_template = {
 		 * an unsolicited reselection occurred.
 		 */
 		pending_scb->hscb->control |= MK_MESSAGE|DISCONNECTED;
-		pending_scb->flags |= SCB_RECOVERY_SCB|flag;
+		pending_scb->flags |= SCB_RECOVERY_SCB;
+		pending_scb->flags |= cmd ? SCB_ABORT : SCB_DEVICE_RESET;
 
 		/*
 		 * Remove any cached copy of this SCB in the
@@ -2256,9 +2262,9 @@ struct scsi_host_template aic7xxx_driver_template = {
 		 * same element in the SCB, SCB_NEXT, for
 		 * both the qinfifo and the disconnected list.
 		 */
-		ahc_search_disc_list(ahc, cmd->device->id,
-				     cmd->device->channel + 'A',
-				     cmd->device->lun, pending_scb->hscb->tag,
+		ahc_search_disc_list(ahc, sdev->id,
+				     sdev->channel + 'A',
+				     sdev->lun, pending_scb->hscb->tag,
 				     /*stop_on_first*/TRUE,
 				     /*remove*/TRUE,
 				     /*save_state*/FALSE);
@@ -2281,9 +2287,9 @@ struct scsi_host_template aic7xxx_driver_template = {
 		 * so we are the next SCB for this target
 		 * to run.
 		 */
-		ahc_search_qinfifo(ahc, cmd->device->id,
-				   cmd->device->channel + 'A',
-				   cmd->device->lun, SCB_LIST_NULL,
+		ahc_search_qinfifo(ahc, sdev->id,
+				   sdev->channel + 'A',
+				   (u8)sdev->lun, SCB_LIST_NULL,
 				   ROLE_INITIATOR, CAM_REQUEUE_REQ,
 				   SEARCH_COMPLETE);
 		ahc_qinfifo_requeue_tail(ahc, pending_scb);
@@ -2292,7 +2298,7 @@ struct scsi_host_template aic7xxx_driver_template = {
 		printk("Device is disconnected, re-queuing SCB\n");
 		wait = TRUE;
 	} else {
-		scmd_printk(KERN_INFO, cmd, "Unable to deliver message\n");
+		sdev_printk(KERN_INFO, sdev, "Unable to deliver message\n");
 		retval = FAILED;
 		goto done;
 	}
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 41/47] xen-scsifront: add scsi device as argument to scsifront_do_request()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (39 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 40/47] aic7xxx: " Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 42/47] xen-scsifront: call scsifront_action_handler() with a NULL command argument Hannes Reinecke
                   ` (7 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Add scsi device as argument to scsifront_do_request() so that it
will be possible to call it with a NULL command pointer.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/xen-scsifront.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index 36f59a1..04af950 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -175,7 +175,8 @@ static void scsifront_put_rqid(struct vscsifrnt_info *info, uint32_t id)
 		scsifront_wake_up(info);
 }
 
-static int scsifront_do_request(struct vscsifrnt_info *info,
+static int scsifront_do_request(struct scsi_device *sdev,
+				struct vscsifrnt_info *info,
 				struct vscsifrnt_shadow *shadow)
 {
 	struct vscsiif_front_ring *ring = &(info->ring);
@@ -202,17 +203,20 @@ static int scsifront_do_request(struct vscsifrnt_info *info,
 	ring_req->ref_rqid    = shadow->ref_rqid;
 	ring_req->nr_segments = shadow->nr_segments;
 
-	ring_req->id      = sc->device->id;
-	ring_req->lun     = sc->device->lun;
-	ring_req->channel = sc->device->channel;
-	ring_req->cmd_len = sc->cmd_len;
-
-	BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE);
-
-	memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len);
-
-	ring_req->sc_data_direction   = (uint8_t)sc->sc_data_direction;
-	ring_req->timeout_per_command = sc->request->timeout / HZ;
+	ring_req->id      = sdev->id;
+	ring_req->lun     = sdev->lun;
+	ring_req->channel = sdev->channel;
+	if (sc) {
+		ring_req->cmd_len = sc->cmd_len;
+		BUG_ON(sc->cmd_len > VSCSIIF_MAX_COMMAND_SIZE);
+		memcpy(ring_req->cmnd, sc->cmnd, sc->cmd_len);
+		ring_req->sc_data_direction   = (uint8_t)sc->sc_data_direction;
+		ring_req->timeout_per_command = sc->request->timeout / HZ;
+	} else {
+		ring_req->cmd_len = VSCSIIF_MAX_COMMAND_SIZE;
+		memset(ring_req->cmnd, 0, VSCSIIF_MAX_COMMAND_SIZE);
+		ring_req->sc_data_direction = DMA_NONE;
+	}
 
 	for (i = 0; i < (shadow->nr_segments & ~VSCSIIF_SG_GRANT); i++)
 		ring_req->seg[i] = shadow->seg[i];
@@ -556,7 +560,7 @@ static int scsifront_queuecommand(struct Scsi_Host *shost,
 		return 0;
 	}
 
-	if (scsifront_do_request(info, shadow)) {
+	if (scsifront_do_request(sc->device, info, shadow)) {
 		scsifront_gnttab_done(info, shadow);
 		goto busy;
 	}
@@ -601,7 +605,7 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)
 		if (scsifront_enter(info))
 			goto fail;
 
-		if (!scsifront_do_request(info, shadow))
+		if (!scsifront_do_request(sc->device, info, shadow))
 			break;
 
 		scsifront_return(info);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 42/47] xen-scsifront: call scsifront_action_handler() with a NULL command argument
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (40 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 41/47] xen-scsifront: add scsi device as argument to scsifront_do_request() Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 43/47] fas216: Rework device reset to not rely on SCSI command pointer Hannes Reinecke
                   ` (6 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

For device reset we shouldn't rely on the scsi command, so allow
scsifront_action_handler() to be called with a NULL command argument.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/xen-scsifront.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index 04af950..b093619 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -582,21 +582,27 @@ static int scsifront_queuecommand(struct Scsi_Host *shost,
  * We have to wait until an answer is returned. This answer contains the
  * result to be returned to the requestor.
  */
-static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)
+static int scsifront_action_handler(struct scsi_device *sdev,
+				    struct scsi_cmnd *sc)
 {
-	struct Scsi_Host *host = sc->device->host;
+	struct Scsi_Host *host = sdev->host;
 	struct vscsifrnt_info *info = shost_priv(host);
-	struct vscsifrnt_shadow *shadow, *s = scsi_cmd_priv(sc);
+	struct vscsifrnt_shadow *shadow, *s;
 	int err = 0;
 
 	shadow = kzalloc(sizeof(*shadow), GFP_NOIO);
 	if (!shadow)
 		return FAILED;
 
-	shadow->act = act;
 	shadow->rslt_reset = RSLT_RESET_WAITING;
 	shadow->sc = sc;
-	shadow->ref_rqid = s->rqid;
+	if (sc) {
+		s = scsi_cmd_priv(sc);
+		shadow->ref_rqid = s->rqid;
+		shadow->act = VSCSIIF_ACT_SCSI_ABORT;
+	} else
+		shadow->act = VSCSIIF_ACT_SCSI_RESET;
+
 	init_waitqueue_head(&shadow->wq_reset);
 
 	spin_lock_irq(host->host_lock);
@@ -646,13 +652,13 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act)
 static int scsifront_eh_abort_handler(struct scsi_cmnd *sc)
 {
 	pr_debug("%s\n", __func__);
-	return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_ABORT);
+	return scsifront_action_handler(sc->device, sc);
 }
 
 static int scsifront_dev_reset_handler(struct scsi_cmnd *sc)
 {
 	pr_debug("%s\n", __func__);
-	return scsifront_action_handler(sc, VSCSIIF_ACT_SCSI_RESET);
+	return scsifront_action_handler(sc->device, NULL);
 }
 
 static int scsifront_sdev_configure(struct scsi_device *sdev)
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 43/47] fas216: Rework device reset to not rely on SCSI command pointer
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (41 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 42/47] xen-scsifront: call scsifront_action_handler() with a NULL command argument Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 44/47] csiostor: use separate TMF command Hannes Reinecke
                   ` (5 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

The device reset code should not rely on the SCSI command pointer;
it will be going away with the device reset handler rework.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/arm/fas216.c | 51 +++++++++++++++++++++++------------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index c93ad3a..e3ff1c3 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -1985,8 +1985,7 @@ static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
 {
 	fas216_log(info, LOG_ERROR, "fas216 device reset complete");
 
-	info->rstSCpnt = NULL;
-	info->rst_dev_status = 1;
+	info->rst_dev_status = 0;
 	wake_up(&info->eh_wait);
 }
 
@@ -2139,12 +2138,12 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
 
 	fas216_checkmagic(info);
 
-	if (!info->SCpnt)
+	if (!info->SCpnt && !info->rst_dev_status)
 		goto no_command;
 
 	SCpnt = info->SCpnt;
 	info->SCpnt = NULL;
-    	info->scsi.phase = PHASE_IDLE;
+	info->scsi.phase = PHASE_IDLE;
 
 	if (info->scsi.aborting) {
 		fas216_log(info, 0, "uncaught abort - returning DID_ABORT");
@@ -2156,7 +2155,7 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
 	 * Sanity check the completion - if we have zero bytes left
 	 * to transfer, we should not have a valid pointer.
 	 */
-	if (info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
+	if (SCpnt && info->scsi.SCp.ptr && info->scsi.SCp.this_residual == 0) {
 		scmd_printk(KERN_INFO, SCpnt,
 			    "zero bytes left to transfer, but buffer pointer still valid: ptr=%p len=%08x\n",
 			    info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
@@ -2169,12 +2168,18 @@ static void fas216_done(FAS216_Info *info, unsigned int result)
 	 * the sense information, fas216_kick will re-assert the busy
 	 * status.
 	 */
-	info->device[SCpnt->device->id].parity_check = 0;
-	clear_bit(SCpnt->device->id * 8 +
-		  (u8)(SCpnt->device->lun & 0x7), info->busyluns);
-
-	fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
-	fn(info, SCpnt, result);
+	if (SCpnt) {
+		info->device[SCpnt->device->id].parity_check = 0;
+		clear_bit(SCpnt->device->id * 8 +
+			  (u8)(SCpnt->device->lun & 0x7), info->busyluns);
+	}
+	if (info->rst_dev_status) {
+		info->rst_dev_status = 0;
+		wake_up(&info->eh_wait);
+	} else {
+		fn = (void (*)(FAS216_Info *, struct scsi_cmnd *, unsigned int))SCpnt->host_scribble;
+		fn(info, SCpnt, result);
+	}
 
 	if (info->scsi.irq) {
 		spin_lock_irqsave(&info->host_lock, flags);
@@ -2326,9 +2331,9 @@ static void fas216_eh_timer(unsigned long data)
 
 	del_timer(&info->eh_timer);
 
-	if (info->rst_bus_status == 0)
+	if (info->rst_bus_status == 1)
 		info->rst_bus_status = -1;
-	if (info->rst_dev_status == 0)
+	if (info->rst_dev_status == 1)
 		info->rst_dev_status = -1;
 
 	wake_up(&info->eh_wait);
@@ -2471,9 +2476,10 @@ int fas216_eh_abort(struct scsi_cmnd *SCpnt)
  */
 int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 {
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
+	struct scsi_device *sdev = SCpnt->device;
+	FAS216_Info *info = (FAS216_Info *)sdev->host->hostdata;
 	unsigned long flags;
-	int i, res = FAILED, target = SCpnt->device->id;
+	int i, res = FAILED, target = sdev->id;
 
 	fas216_log(info, LOG_ERROR, "device reset for target %d", target);
 
@@ -2487,7 +2493,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 		 * and we need a bus reset.
 		 */
 		if (info->SCpnt && !info->scsi.disconnectable &&
-		    info->SCpnt->device->id == SCpnt->device->id)
+		    info->SCpnt->device->id == sdev->id)
 			break;
 
 		/*
@@ -2505,14 +2511,7 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 		for (i = 0; i < 8; i++)
 			clear_bit(target * 8 + i, info->busyluns);
 
-		/*
-		 * Hijack this SCSI command structure to send
-		 * a bus device reset message to this device.
-		 */
-		SCpnt->host_scribble = (void *)fas216_devicereset_done;
-
-		info->rst_dev_status = 0;
-		info->rstSCpnt = SCpnt;
+		info->rst_dev_status = 1;
 
 		if (info->scsi.phase == PHASE_IDLE)
 			fas216_kick(info);
@@ -2523,13 +2522,13 @@ int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
 		/*
 		 * Wait up to 30 seconds for the reset to complete.
 		 */
-		wait_event(info->eh_wait, info->rst_dev_status);
+		wait_event(info->eh_wait, info->rst_dev_status <= 0);
 
 		del_timer_sync(&info->eh_timer);
 		spin_lock_irqsave(&info->host_lock, flags);
 		info->rstSCpnt = NULL;
 
-		if (info->rst_dev_status == 1)
+		if (info->rst_dev_status == 0)
 			res = SUCCESS;
 	} while (0);
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 44/47] csiostor: use separate TMF command
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (42 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 43/47] fas216: Rework device reset to not rely on SCSI command pointer Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 45/47] snic: use dedicated device reset command Hannes Reinecke
                   ` (4 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Set one command aside as a TMF command, and use this command to
send the TMF. This avoids having to rely on the passed-in scsi
command when resetting the device.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/csiostor/csio_hw.h   |  2 ++
 drivers/scsi/csiostor/csio_init.c |  2 +-
 drivers/scsi/csiostor/csio_scsi.c | 44 ++++++++++++++++++++++++++-------------
 3 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/drivers/scsi/csiostor/csio_hw.h b/drivers/scsi/csiostor/csio_hw.h
index 9acb895..18b2afb 100644
--- a/drivers/scsi/csiostor/csio_hw.h
+++ b/drivers/scsi/csiostor/csio_hw.h
@@ -68,6 +68,8 @@
 
 #define CSIO_MAX_LUN		0xFFFF
 #define CSIO_MAX_QUEUE		2048
+#define CSIO_TMF_TAG		(CSIO_MAX_QUEUE - 1)
+
 #define CSIO_MAX_CMD_PER_LUN	32
 #define CSIO_MAX_DDP_BUF_SIZE	(1024 * 1024)
 #define CSIO_MAX_SECTOR_SIZE	128
diff --git a/drivers/scsi/csiostor/csio_init.c b/drivers/scsi/csiostor/csio_init.c
index ea0c310..4fd03cf 100644
--- a/drivers/scsi/csiostor/csio_init.c
+++ b/drivers/scsi/csiostor/csio_init.c
@@ -628,7 +628,7 @@ struct csio_lnode *
 	/* Link common lnode to this lnode */
 	ln->dev_num = (shost->host_no << 16);
 
-	shost->can_queue = CSIO_MAX_QUEUE;
+	shost->can_queue = CSIO_MAX_QUEUE - 1;
 	shost->this_id = -1;
 	shost->unique_id = shost->host_no;
 	shost->max_cmd_len = 16; /* Max CDB length supported */
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index 93b6891..133f683 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -2055,17 +2055,20 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 
 	/* Wake up the TM handler thread */
 	csio_scsi_cmnd(req) = NULL;
+	cmnd->host_scribble = NULL;
 }
 
 static int
 csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
 {
-	struct csio_lnode *ln = shost_priv(cmnd->device->host);
+	struct scsi_device *sdev = cmnd->device;
+	struct csio_lnode *ln = shost_priv(sdev->host);
 	struct csio_hw *hw = csio_lnode_to_hw(ln);
 	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
-	struct csio_rnode *rn = (struct csio_rnode *)(cmnd->device->hostdata);
+	struct csio_rnode *rn = (struct csio_rnode *)(sdev->hostdata);
 	struct csio_ioreq *ioreq = NULL;
 	struct csio_scsi_qset *sqset;
+	struct scsi_cmnd *tmf_cmnd;
 	unsigned long flags;
 	int retval;
 	int count, ret;
@@ -2076,13 +2079,13 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 		goto fail;
 
 	csio_dbg(hw, "Request to reset LUN:%llu (ssni:0x%x tgtid:%d)\n",
-		      cmnd->device->lun, rn->flowid, rn->scsi_id);
+		      sdev->lun, rn->flowid, rn->scsi_id);
 
 	if (!csio_is_lnode_ready(ln)) {
 		csio_err(hw,
 			 "LUN reset cannot be issued on non-ready"
 			 " local node vnpi:0x%x (LUN:%llu)\n",
-			 ln->vnp_flowid, cmnd->device->lun);
+			 ln->vnp_flowid, sdev->lun);
 		goto fail;
 	}
 
@@ -2102,7 +2105,15 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 		csio_err(hw,
 			 "LUN reset cannot be issued on non-ready"
 			 " remote node ssni:0x%x (LUN:%llu)\n",
-			 rn->flowid, cmnd->device->lun);
+			 rn->flowid, sdev->lun);
+		goto fail;
+	}
+
+	tmf_cmnd = scsi_host_find_tag(sdev->host, CSIO_TMF_TAG);
+	if (!tmf_cmnd || tmf_cmnd->host_scribble) {
+		csio_err(hw,
+			 "LUN reset TMF already busy (LUN:%llu)\n",
+			 sdev->lun);
 		goto fail;
 	}
 
@@ -2122,11 +2133,12 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	ioreq->iq_idx		= sqset->iq_idx;
 	ioreq->eq_idx		= sqset->eq_idx;
 
-	csio_scsi_cmnd(ioreq)	= cmnd;
-	cmnd->host_scribble	= (unsigned char *)ioreq;
-	cmnd->SCp.Status	= 0;
+	csio_scsi_cmnd(ioreq)	= tmf_cmnd;
+	tmf_cmnd->host_scribble	= (unsigned char *)ioreq;
+	tmf_cmnd->SCp.Status	= 0;
+	tmf_cmnd->device	= sdev;
 
-	cmnd->SCp.Message	= FCP_TMF_LUN_RESET;
+	tmf_cmnd->SCp.Message	= FCP_TMF_LUN_RESET;
 	ioreq->tmo		= CSIO_SCSI_LUNRST_TMO_MS / 1000;
 
 	/*
@@ -2143,7 +2155,7 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	sld.level = CSIO_LEV_LUN;
 	sld.lnode = ioreq->lnode;
 	sld.rnode = ioreq->rnode;
-	sld.oslun = cmnd->device->lun;
+	sld.oslun = sdev->lun;
 
 	spin_lock_irqsave(&hw->lock, flags);
 	/* Kick off TM SM on the ioreq */
@@ -2153,6 +2165,7 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	if (retval != 0) {
 		csio_err(hw, "Failed to issue LUN reset, req:%p, status:%d\n",
 			    ioreq, retval);
+		tmf_cmnd->host_scribble = NULL;
 		goto fail_ret_ioreq;
 	}
 
@@ -2166,20 +2179,21 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	/* LUN reset timed-out */
 	if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd) {
 		csio_err(hw, "LUN reset (%d:%llu) timed out\n",
-			 cmnd->device->id, cmnd->device->lun);
+			 sdev->id, sdev->lun);
 
 		spin_lock_irq(&hw->lock);
 		csio_scsi_drvcleanup(ioreq);
 		list_del_init(&ioreq->sm.sm_list);
 		spin_unlock_irq(&hw->lock);
 
+		tmf_cmnd->host_scribble = NULL;
 		goto fail_ret_ioreq;
 	}
 
 	/* LUN reset returned, check cached status */
-	if (cmnd->SCp.Status != FW_SUCCESS) {
+	if (tmf_cmnd->SCp.Status != FW_SUCCESS) {
 		csio_err(hw, "LUN reset failed (%d:%llu), status: %d\n",
-			 cmnd->device->id, cmnd->device->lun, cmnd->SCp.Status);
+			 sdev->id, sdev->lun, tmf_cmnd->SCp.Status);
 		goto fail;
 	}
 
@@ -2199,7 +2213,7 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	if (retval != 0) {
 		csio_err(hw,
 			 "Attempt to abort I/Os during LUN reset of %llu"
-			 " returned %d\n", cmnd->device->lun, retval);
+			 " returned %d\n", sdev->lun, retval);
 		/* Return I/Os back to active_q */
 		spin_lock_irq(&hw->lock);
 		list_splice_tail_init(&local_q, &scsim->active_q);
@@ -2210,7 +2224,7 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	CSIO_INC_STATS(rn, n_lun_rst);
 
 	csio_info(hw, "LUN reset occurred (%d:%llu)\n",
-		  cmnd->device->id, cmnd->device->lun);
+		  sdev->id, sdev->lun);
 
 	return SUCCESS;
 
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 45/47] snic: use dedicated device reset command
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (43 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 44/47] csiostor: use separate TMF command Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28  8:33 ` [PATCH 46/47] scsi: Move eh_device_reset_handler() to use scsi_device as argument Hannes Reinecke
                   ` (3 subsequent siblings)
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

Use a dedicated command to send a device reset instead of relying
on using the command which triggered the device failure.

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/snic/snic_scsi.c | 52 ++++++++++++++++++++-----------------------
 1 file changed, 24 insertions(+), 28 deletions(-)

diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index ec11293..f50d274 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -2136,57 +2136,53 @@
 int
 snic_device_reset(struct scsi_cmnd *sc)
 {
-	struct Scsi_Host *shost = sc->device->host;
+	struct scsi_device *sdev = sc->device;
+	struct Scsi_Host *shost = sdev->host;
 	struct snic *snic = shost_priv(shost);
 	struct snic_req_info *rqi = NULL;
-	int tag = snic_cmd_tag(sc);
 	int start_time = jiffies;
 	int ret = FAILED;
 	int dr_supp = 0;
 
-	SNIC_SCSI_DBG(shost, "dev_reset:sc %p :0x%x :req = %p :tag = %d\n",
-		      sc, sc->cmnd[0], sc->request,
-		      snic_cmd_tag(sc));
-	dr_supp = snic_dev_reset_supported(sc->device);
+	SNIC_SCSI_DBG(shost, "dev_reset\n");
+	dr_supp = snic_dev_reset_supported(sdev);
 	if (!dr_supp) {
 		/* device reset op is not supported */
 		SNIC_HOST_INFO(shost, "LUN Reset Op not supported.\n");
-		snic_unlink_and_release_req(snic, sc, SNIC_DEV_RST_NOTSUP);
-
 		goto dev_rst_end;
 	}
 
 	if (unlikely(snic_get_state(snic) != SNIC_ONLINE)) {
-		snic_unlink_and_release_req(snic, sc, 0);
 		SNIC_HOST_ERR(shost, "Devrst: Parent Devs are not online.\n");
 
 		goto dev_rst_end;
 	}
 
-	/* There is no tag when lun reset is issue through ioctl. */
-	if (unlikely(tag <= SNIC_NO_TAG)) {
-		SNIC_HOST_INFO(snic->shost,
-			       "Devrst: LUN Reset Recvd thru IOCTL.\n");
-
-		rqi = snic_req_init(snic, 0);
-		if (!rqi)
-			goto dev_rst_end;
-
-		memset(scsi_cmd_priv(sc), 0,
-			sizeof(struct snic_internal_io_state));
-		CMD_SP(sc) = (char *)rqi;
-		CMD_FLAGS(sc) = SNIC_NO_FLAGS;
+	rqi = snic_req_init(snic, 0);
+	if (!rqi)
+		goto dev_rst_end;
 
-		/* Add special tag for dr coming from user spc */
-		rqi->tm_tag = SNIC_TAG_IOCTL_DEV_RST;
-		rqi->sc = sc;
+	/* The last tag is reserved for device reset */
+	sc = scsi_host_find_tag(snic->shost, snic->tmf_tag_id);
+	if (!sc || CMD_SP(sc)) {
+		SNIC_HOST_ERR(snic->shost,
+			      "Devrst: TMF busy\n");
+		goto dev_rst_end;
 	}
+	memset(scsi_cmd_priv(sc), 0,
+	       sizeof(struct snic_internal_io_state));
+	CMD_SP(sc) = (char *)rqi;
+	CMD_FLAGS(sc) = SNIC_NO_FLAGS;
+
+	/* Add special tag for dr coming from user spc */
+	rqi->tm_tag = SNIC_TAG_IOCTL_DEV_RST;
+	rqi->sc = sc;
 
 	ret = snic_send_dr_and_wait(snic, sc);
 	if (ret) {
 		SNIC_HOST_ERR(snic->shost,
 			      "Devrst: IO w/ Tag %x Failed w/ err = %d\n",
-			      tag, ret);
+			      snic_cmd_tag(sc), ret);
 
 		snic_unlink_and_release_req(snic, sc, 0);
 
@@ -2196,7 +2192,7 @@
 	ret = snic_dr_finish(snic, sc);
 
 dev_rst_end:
-	SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
+	SNIC_TRC(snic->shost->host_no, snic_cmd_tag(sc), (ulong) sc,
 		 jiffies_to_msecs(jiffies - start_time),
 		 0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));
 
@@ -2347,7 +2343,7 @@
 		schedule_timeout(msecs_to_jiffies(1));
 
 	sc = scsi_host_find_tag(shost, snic->tmf_tag_id);
-	if (!sc) {
+	if (!sc || CMD_SP(sc)) {
 		SNIC_HOST_ERR(shost,
 			      "reset:Host Reset Failed to allocate sc.\n");
 		spin_lock_irqsave(&snic->snic_lock, flags);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 46/47] scsi: Move eh_device_reset_handler() to use scsi_device as argument
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (44 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 45/47] snic: use dedicated device reset command Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-07-24 18:42   ` Steffen Maier
  2017-06-28  8:33 ` [PATCH 47/47] scsi: Do not allocate scsi command in scsi_ioctl_reset() Hannes Reinecke
                   ` (2 subsequent siblings)
  48 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

When resetting a device we shouldn't depend on an existing SCSI
device, so use 'struct scsi_device' as argument for
eh_device_reset_handler().

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 Documentation/scsi/scsi_eh.txt                  |  2 +-
 Documentation/scsi/scsi_mid_low_api.txt         |  4 +--
 drivers/block/cciss_scsi.c                      | 14 +++++-----
 drivers/infiniband/ulp/srp/ib_srp.c             |  8 +++---
 drivers/message/fusion/mptfc.c                  | 12 ++++-----
 drivers/message/fusion/mptscsih.c               | 19 ++++++--------
 drivers/message/fusion/mptscsih.h               |  2 +-
 drivers/s390/scsi/zfcp_scsi.c                   |  4 +--
 drivers/scsi/a100u2w.c                          |  7 +++--
 drivers/scsi/aacraid/linit.c                    |  9 +++----
 drivers/scsi/aha152x.c                          |  6 ++---
 drivers/scsi/aha1542.c                          |  8 +++---
 drivers/scsi/aic7xxx/aic79xx_osm.c              | 27 ++++++++-----------
 drivers/scsi/aic7xxx/aic7xxx_osm.c              |  4 +--
 drivers/scsi/arm/fas216.c                       |  5 ++--
 drivers/scsi/be2iscsi/be_main.c                 |  8 +++---
 drivers/scsi/bfa/bfad_im.c                      |  3 +--
 drivers/scsi/bnx2fc/bnx2fc.h                    |  2 +-
 drivers/scsi/bnx2fc/bnx2fc_io.c                 |  6 ++---
 drivers/scsi/csiostor/csio_scsi.c               |  7 +++--
 drivers/scsi/cxlflash/main.c                    | 15 ++++-------
 drivers/scsi/dpt_i2o.c                          | 20 +++++++-------
 drivers/scsi/dpti.h                             |  2 +-
 drivers/scsi/esas2r/esas2r.h                    |  2 +-
 drivers/scsi/esas2r/esas2r_main.c               |  3 +--
 drivers/scsi/fnic/fnic.h                        |  2 +-
 drivers/scsi/fnic/fnic_scsi.c                   | 26 +++++++++---------
 drivers/scsi/hpsa.c                             | 14 +++++-----
 drivers/scsi/ibmvscsi/ibmvfc.c                  |  5 ++--
 drivers/scsi/ibmvscsi/ibmvscsi.c                | 19 +++++++-------
 drivers/scsi/ipr.c                              | 31 +++++++++++-----------
 drivers/scsi/libfc/fc_fcp.c                     |  8 +++---
 drivers/scsi/libiscsi.c                         | 15 +++++------
 drivers/scsi/libsas/sas_scsi_host.c             | 12 ++++-----
 drivers/scsi/lpfc/lpfc_scsi.c                   | 12 ++++-----
 drivers/scsi/mpt3sas/mpt3sas_scsih.c            | 29 +++++++++-----------
 drivers/scsi/pmcraid.c                          |  6 ++---
 drivers/scsi/qedf/qedf_main.c                   |  6 ++---
 drivers/scsi/qla1280.c                          | 21 +++++++++++----
 drivers/scsi/qla2xxx/qla_os.c                   |  5 ++--
 drivers/scsi/qla4xxx/ql4_os.c                   | 28 +++++++++-----------
 drivers/scsi/scsi_debug.c                       | 18 ++++++-------
 drivers/scsi/scsi_error.c                       | 35 +++++++++++++++++--------
 drivers/scsi/smartpqi/smartpqi_init.c           |  6 ++---
 drivers/scsi/snic/snic.h                        |  2 +-
 drivers/scsi/snic/snic_scsi.c                   |  4 +--
 drivers/scsi/ufs/ufshcd.c                       | 16 +++++------
 drivers/scsi/virtio_scsi.c                      | 14 +++++-----
 drivers/scsi/vmw_pvscsi.c                       | 10 +++----
 drivers/scsi/wd719x.c                           |  6 ++---
 drivers/scsi/xen-scsifront.c                    |  4 +--
 drivers/staging/rts5208/rtsx.c                  |  4 +--
 drivers/staging/unisys/visorhba/visorhba_main.c | 14 +++-------
 drivers/target/loopback/tcm_loop.c              |  8 +++---
 drivers/usb/storage/scsiglue.c                  |  4 +--
 drivers/usb/storage/uas.c                       |  3 +--
 include/scsi/libfc.h                            |  2 +-
 include/scsi/libiscsi.h                         |  2 +-
 include/scsi/libsas.h                           |  2 +-
 include/scsi/scsi_host.h                        |  2 +-
 60 files changed, 287 insertions(+), 307 deletions(-)

diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
index cb9f4bc22..f8a6566 100644
--- a/Documentation/scsi/scsi_eh.txt
+++ b/Documentation/scsi/scsi_eh.txt
@@ -206,7 +206,7 @@ hostt EH callbacks.  Callbacks may be omitted and omitted ones are
 considered to fail always.
 
 int (* eh_abort_handler)(struct scsi_cmnd *);
-int (* eh_device_reset_handler)(struct scsi_cmnd *);
+int (* eh_device_reset_handler)(struct scsi_device *);
 int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
 int (* eh_host_reset_handler)(struct Scsi_Host *);
 
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
index e2609a63..28dc029 100644
--- a/Documentation/scsi/scsi_mid_low_api.txt
+++ b/Documentation/scsi/scsi_mid_low_api.txt
@@ -874,7 +874,7 @@ Details:
 
 /**
  *      eh_device_reset_handler - issue SCSI device reset
- *      @scp: identifies SCSI device to be reset
+ *      @sdev: identifies SCSI device to be reset
  *
  *      Returns SUCCESS if command aborted else FAILED
  *
@@ -887,7 +887,7 @@ Details:
  *
  *      Optionally defined in: LLD
  **/
-     int eh_device_reset_handler(struct scsi_cmnd * scp)
+     int eh_device_reset_handler(struct scsi_device * sdev)
 
 
 /**
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 01a1f7e..82a371b 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -62,7 +62,7 @@ static int cciss_scsi_show_info(struct seq_file *m,
 
 static int cciss_scsi_queue_command (struct Scsi_Host *h,
 				     struct scsi_cmnd *cmd);
-static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
+static int cciss_eh_device_reset_handler(struct scsi_device *);
 static int cciss_eh_abort_handler(struct scsi_cmnd *);
 
 static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
@@ -1591,23 +1591,21 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h,
  * as a boot device (embedded controller on HP/Compaq systems.)
 */
 
-static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
+static int cciss_eh_device_reset_handler(struct scsi_device *scsidev)
 {
 	int rc;
-	CommandList_struct *cmd_in_trouble;
 	unsigned char lunaddr[8];
 	ctlr_info_t *h;
 
 	/* find the controller to which the command to be aborted was sent */
-	h = (ctlr_info_t *) scsicmd->device->host->hostdata[0];
+	h = (ctlr_info_t *) scsidev->host->hostdata[0];
 	if (h == NULL) /* paranoia */
 		return FAILED;
 	dev_warn(&h->pdev->dev, "resetting tape drive or medium changer.\n");
-	/* find the command that's giving us trouble */
-	cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
-	if (cmd_in_trouble == NULL) /* paranoia */
+	rc = lookup_scsi3addr(h, scsidev->channel, scsidev->id,
+			      scsidev->lun, lunaddr);
+	if (rc != 0)
 		return FAILED;
-	memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8);
 	/* send a reset to the SCSI LUN which the command was sent to */
 	rc = sendcmd_withirq(h, CCISS_RESET_MSG, NULL, 0, 0, lunaddr,
 		TYPE_MSG);
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 588fc08..b0304a5 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -2651,9 +2651,9 @@ static int srp_abort(struct scsi_cmnd *scmnd)
 	return ret;
 }
 
-static int srp_reset_device(struct scsi_cmnd *scmnd)
+static int srp_reset_device(struct scsi_device *sdev)
 {
-	struct srp_target_port *target = host_to_target(scmnd->device->host);
+	struct srp_target_port *target = host_to_target(sdev->host);
 	struct srp_rdma_ch *ch;
 	int i;
 	u8 status;
@@ -2661,7 +2661,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 	shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
 
 	ch = &target->ch[0];
-	if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, scmnd->device->lun,
+	if (srp_send_tsk_mgmt(ch, SRP_TAG_NO_REQ, sdev->lun,
 			      SRP_TSK_LUN_RESET, &status))
 		return FAILED;
 	if (status)
@@ -2672,7 +2672,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 		for (i = 0; i < target->req_ring_size; ++i) {
 			struct srp_request *req = &ch->req_ring[i];
 
-			srp_finish_req(ch, req, scmnd->device, DID_RESET << 16);
+			srp_finish_req(ch, req, sdev, DID_RESET << 16);
 		}
 	}
 
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index 9e164af..c7d7568 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -102,7 +102,7 @@
 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 static void mptfc_remove(struct pci_dev *pdev);
 static int mptfc_abort(struct scsi_cmnd *SCpnt);
-static int mptfc_dev_reset(struct scsi_cmnd *SCpnt);
+static int mptfc_dev_reset(struct scsi_device *sdev);
 static int mptfc_bus_reset(struct Scsi_Host *shost, int channel);
 
 static struct scsi_host_template mptfc_driver_template = {
@@ -241,10 +241,10 @@
 }
 
 static int
-mptfc_dev_reset(struct scsi_cmnd *SCpnt)
+mptfc_dev_reset(struct scsi_device *sdev)
 {
-	struct Scsi_Host *shost = SCpnt->device->host;
-	struct fc_rport *rport = starget_to_rport(scsi_target(SCpnt->device));
+	struct Scsi_Host *shost = sdev->host;
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	MPT_SCSI_HOST __maybe_unused *hd = shost_priv(shost);
 	int rtn;
 
@@ -253,8 +253,8 @@
 		dfcprintk (hd->ioc, printk(MYIOC_s_DEBUG_FMT
 			"%s.%d: %d:%llu, executing recovery.\n", __func__,
 			hd->ioc->name, shost->host_no,
-			SCpnt->device->id, SCpnt->device->lun));
-		rtn = mptscsih_dev_reset(SCpnt);
+			sdev->id, sdev->lun));
+		rtn = mptscsih_dev_reset(sdev);
 	}
 	return rtn;
 }
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 0f25a2a..c7f5e73 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1793,14 +1793,14 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_dev_reset - Perform a SCSI LOGICAL_UNIT_RESET!
- *	@SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
+ *	@device: Pointer to scsi_device structure, which reset is due to
  *
  *	(linux scsi_host_template.eh_dev_reset_handler routine)
  *
  *	Returns SUCCESS or FAILED.
  **/
 int
-mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
+mptscsih_dev_reset(struct scsi_device * device)
 {
 	MPT_SCSI_HOST	*hd;
 	int		 retval;
@@ -1809,18 +1809,15 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
-	if ((hd = shost_priv(SCpnt->device->host)) == NULL){
-		printk(KERN_ERR MYNAM ": lun reset: "
-		   "Can't locate host! (sc=%p)\n", SCpnt);
+	if ((hd = shost_priv(device->host)) == NULL){
+		printk(KERN_ERR MYNAM ": lun reset: Can't locate host!\n");
 		return FAILED;
 	}
 
 	ioc = hd->ioc;
-	printk(MYIOC_s_INFO_FMT "attempting lun reset! (sc=%p)\n",
-	       ioc->name, SCpnt);
-	scsi_print_command(SCpnt);
+	printk(MYIOC_s_INFO_FMT "attempting lun reset!\n", ioc->name);
 
-	vdevice = SCpnt->device->hostdata;
+	vdevice = device->hostdata;
 	if (!vdevice || !vdevice->vtarget) {
 		retval = 0;
 		goto out;
@@ -1833,8 +1830,8 @@ int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
 				mptscsih_get_tm_timeout(ioc));
 
  out:
-	printk (MYIOC_s_INFO_FMT "lun reset: %s (sc=%p)\n",
-	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
+	printk (MYIOC_s_INFO_FMT "lun reset: %s\n",
+	    ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ));
 
 	if (retval == 0)
 		return SUCCESS;
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index a5069a84..a7eabef 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -119,7 +119,7 @@ extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel,
 extern void mptscsih_slave_destroy(struct scsi_device *device);
 extern int mptscsih_slave_configure(struct scsi_device *device);
 extern int mptscsih_abort(struct scsi_cmnd * SCpnt);
-extern int mptscsih_dev_reset(struct scsi_cmnd * SCpnt);
+extern int mptscsih_dev_reset(struct scsi_device *);
 extern int mptscsih_target_reset(struct Scsi_Host *, struct scsi_target *);
 extern int mptscsih_bus_reset(struct Scsi_Host *, int);
 extern int mptscsih_host_reset(struct Scsi_Host *sh);
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
index 92a3902..23b5a7d 100644
--- a/drivers/s390/scsi/zfcp_scsi.c
+++ b/drivers/s390/scsi/zfcp_scsi.c
@@ -304,9 +304,9 @@ static int zfcp_task_mgmt_function(struct scsi_device *sdev, u8 tm_flags)
 	return retval;
 }
 
-static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
+static int zfcp_scsi_eh_device_reset_handler(struct scsi_device *sdev)
 {
-	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
+	return zfcp_task_mgmt_function(sdev, FCP_TMF_LUN_RESET);
 }
 
 /*
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index 8802d23..cfc0cc2 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -951,12 +951,11 @@ static int inia100_bus_reset(struct Scsi_Host * shost, int channel)
  Output         : None.
  Return         : pSRB  -       Pointer to SCSI request block.
 *****************************************************************************/
-static int inia100_device_reset(struct scsi_cmnd * cmd)
+static int inia100_device_reset(struct scsi_device * dev)
 {				/* I need Host Control Block Information */
 	struct orc_host *host;
-	host = (struct orc_host *) cmd->device->host->hostdata;
-	return orc_device_reset(host, cmd->device);
-
+	host = (struct orc_host *) dev->host->hostdata;
+	return orc_device_reset(host, dev);
 }
 
 /**
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 7214600..8247e8b 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -888,12 +888,11 @@ void aac_tmf_callback(void *context, struct fib *fibptr)
 
 /*
  *	aac_eh_dev_reset	- Device reset command handling
- *	@scsi_cmd:	SCSI command block causing the reset
+ *	@dev:	SCSI device to be reset
  *
  */
-static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
+static int aac_eh_dev_reset(struct scsi_device *dev)
 {
-	struct scsi_device * dev = cmd->device;
 	struct Scsi_Host * host = dev->host;
 	struct aac_dev * aac = (struct aac_dev *)host->hostdata;
 	struct aac_hba_map_info *info;
@@ -904,8 +903,8 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
 	int status;
 	u8 command;
 
-	bus = aac_logical_to_phys(scmd_channel(cmd));
-	cid = scmd_id(cmd);
+	bus = aac_logical_to_phys(sdev_channel(dev));
+	cid = sdev_id(dev);
 	info = &aac->hba_map[bus][cid];
 	if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
 	    info->devtype != AAC_DEVTYPE_NATIVE_RAW)
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
index 896c36e..ed21ed0 100644
--- a/drivers/scsi/aha152x.c
+++ b/drivers/scsi/aha152x.c
@@ -1052,10 +1052,10 @@ static int aha152x_abort(Scsi_Cmnd *SCpnt)
  * Reset a device
  *
  */
-static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
+static int aha152x_device_reset(struct scsi_device * sdev)
 {
-	struct Scsi_Host *shpnt = SCpnt->device->host;
-	struct scsi_cmnd *SCprev = NULL;
+	struct Scsi_Host *shpnt = sdev->host;
+	struct scsi_cmnd *SCpnt, *SCprev = NULL;
 	DECLARE_COMPLETION(done);
 	int ret, issued, disconnected;
 	unsigned char old_cmd_len;
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index ed44e1e..14752df 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -792,14 +792,14 @@ static int aha1542_release(struct Scsi_Host *sh)
  * This is a device reset.  This is handled by sending a special command
  * to the device.
  */
-static int aha1542_dev_reset(struct scsi_cmnd *cmd)
+static int aha1542_dev_reset(struct scsi_device *sdev)
 {
-	struct Scsi_Host *sh = cmd->device->host;
+	struct Scsi_Host *sh = sdev->host;
 	struct aha1542_hostdata *aha1542 = shost_priv(sh);
 	unsigned long flags;
 	struct mailbox *mb = aha1542->mb;
-	u8 target = cmd->device->id;
-	u8 lun = cmd->device->lun;
+	u8 target = sdev->id;
+	u8 lun = sdev->lun;
 	int mbo;
 	struct ccb *ccb = aha1542->ccb;
 
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index 695e93e..56f94be 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -780,12 +780,11 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
  * Attempt to send a target reset message to the device that timed out.
  */
 static int
-ahd_linux_dev_reset(struct scsi_cmnd *cmd)
+ahd_linux_dev_reset(struct scsi_device *sdev)
 {
 	struct ahd_softc *ahd;
 	struct ahd_linux_device *dev;
 	struct scb *reset_scb;
-	u_int  cdb_byte;
 	int    retval = SUCCESS;
 	int    paused;
 	int    wait;
@@ -797,27 +796,22 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
 	reset_scb = NULL;
 	paused = FALSE;
 	wait = FALSE;
-	ahd = *(struct ahd_softc **)cmd->device->host->hostdata;
+	ahd = *(struct ahd_softc **)sdev->host->hostdata;
 
-	scmd_printk(KERN_INFO, cmd,
+	sdev_printk(KERN_INFO, sdev,
 		    "Attempting to queue a TARGET RESET message:");
 
-	printk("CDB:");
-	for (cdb_byte = 0; cdb_byte < cmd->cmd_len; cdb_byte++)
-		printk(" 0x%x", cmd->cmnd[cdb_byte]);
-	printk("\n");
-
 	/*
 	 * Determine if we currently own this command.
 	 */
-	dev = scsi_transport_device_data(cmd->device);
+	dev = scsi_transport_device_data(sdev);
 
 	if (dev == NULL) {
 		/*
 		 * No target device for this command exists,
 		 * so we must not still own the command.
 		 */
-		scmd_printk(KERN_INFO, cmd, "Is not an active device\n");
+		sdev_printk(KERN_INFO, sdev, "Is not an active device\n");
 		return SUCCESS;
 	}
 
@@ -826,12 +820,12 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
 	 */
 	reset_scb = ahd_get_scb(ahd, AHD_NEVER_COL_IDX);
 	if (!reset_scb) {
-		scmd_printk(KERN_INFO, cmd, "No SCB available\n");
+		sdev_printk(KERN_INFO, sdev, "No SCB available\n");
 		return FAILED;
 	}
 
 	tinfo = ahd_fetch_transinfo(ahd, 'A', ahd->our_id,
-				    cmd->device->id, &tstate);
+				    sdev->id, &tstate);
 	reset_scb->io_ctx = NULL;
 	reset_scb->platform_data->dev = dev;
 	reset_scb->sg_count = 0;
@@ -839,8 +833,8 @@ static DEF_SCSI_QCMD(ahd_linux_queue)
 	ahd_set_sense_residual(reset_scb, 0);
 	reset_scb->platform_data->xfer_len = 0;
 	reset_scb->hscb->control = 0;
-	reset_scb->hscb->scsiid = BUILD_SCSIID(ahd, cmd->device);
-	reset_scb->hscb->lun = cmd->device->lun;
+	reset_scb->hscb->scsiid = BUILD_SCSIID(ahd, sdev);
+	reset_scb->hscb->lun = sdev->lun;
 	reset_scb->hscb->cdb_len = 0;
 	reset_scb->hscb->task_management = SIU_TASKMGMT_LUN_RESET;
 	reset_scb->flags |= SCB_DEVICE_RESET|SCB_RECOVERY_SCB|SCB_ACTIVE;
@@ -1808,7 +1802,8 @@ struct scsi_host_template aic79xx_driver_template = {
 	 * was retrieved anytime the first byte of
 	 * the sense buffer looks "sane".
 	 */
-	cmd->sense_buffer[0] = 0;
+	if (cmd)
+		cmd->sense_buffer[0] = 0;
 	if (ahd_get_transaction_status(scb) == CAM_REQ_INPROG) {
 		uint32_t amount_xferred;
 
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index fe8f675..ee861f6 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -756,11 +756,11 @@ static DEF_SCSI_QCMD(ahc_linux_queue)
  * Attempt to send a target reset message to the device that timed out.
  */
 static int
-ahc_linux_dev_reset(struct scsi_cmnd *cmd)
+ahc_linux_dev_reset(struct scsi_device *sdev)
 {
 	int error;
 
-	error = ahc_linux_queue_recovery_cmd(cmd->device, NULL);
+	error = ahc_linux_queue_recovery_cmd(sdev, NULL);
 	if (error != 0)
 		printk("aic7xxx_dev_reset returns 0x%x\n", error);
 	return (error);
diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
index e3ff1c3..913485f 100644
--- a/drivers/scsi/arm/fas216.c
+++ b/drivers/scsi/arm/fas216.c
@@ -2467,16 +2467,15 @@ int fas216_eh_abort(struct scsi_cmnd *SCpnt)
 
 /**
  * fas216_eh_device_reset - Reset the device associated with this command
- * @SCpnt: command specifing device to reset
+ * @sdev: device to reset
  *
  * Reset the device associated with this command.
  * Returns: FAILED if unable to reset.
  * Notes: We won't be re-entered, so we'll only have one device
  * reset on the go at one time.
  */
-int fas216_eh_device_reset(struct scsi_cmnd *SCpnt)
+int fas216_eh_device_reset(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = SCpnt->device;
 	FAS216_Info *info = (FAS216_Info *)sdev->host->hostdata;
 	unsigned long flags;
 	int i, res = FAILED, target = sdev->id;
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 2b0d14c..34f7047 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -260,7 +260,7 @@ static int beiscsi_eh_abort(struct scsi_cmnd *sc)
 	return iscsi_eh_abort(sc);
 }
 
-static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
+static int beiscsi_eh_device_reset(struct scsi_device *sdev)
 {
 	struct beiscsi_invldt_cmd_tbl {
 		struct invldt_cmd_tbl tbl[BE_INVLDT_CMD_TBL_SZ];
@@ -276,7 +276,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
 	unsigned int i, nents;
 	int rc, more = 0;
 
-	cls_session = starget_to_session(scsi_target(sc->device));
+	cls_session = starget_to_session(scsi_target(sdev));
 	session = cls_session->dd_data;
 
 	spin_lock_bh(&session->frwd_lock);
@@ -304,7 +304,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
 		if (!task->sc)
 			continue;
 
-		if (sc->device->lun != task->sc->device->lun)
+		if (sdev->lun != task->sc->device->lun)
 			continue;
 		/**
 		 * Can't fit in more cmds? Normally this won't happen b'coz
@@ -359,7 +359,7 @@ static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
 	kfree(inv_tbl);
 
 	if (rc == SUCCESS)
-		rc = iscsi_eh_device_reset(sc);
+		rc = iscsi_eh_device_reset(sdev);
 	return rc;
 }
 
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c
index 6613ef3..2ddfe7e 100644
--- a/drivers/scsi/bfa/bfad_im.c
+++ b/drivers/scsi/bfa/bfad_im.c
@@ -293,9 +293,8 @@ static void bfad_im_fc_rport_add(struct bfad_im_port_s  *im_port,
  *
  */
 static int
-bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
+bfad_im_reset_lun_handler(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = cmnd->device;
 	struct Scsi_Host *shost = sdev->host;
 	struct bfad_im_port_s *im_port =
 			(struct bfad_im_port_s *) shost->hostdata[0];
diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h
index d115281..db63da1 100644
--- a/drivers/scsi/bnx2fc/bnx2fc.h
+++ b/drivers/scsi/bnx2fc/bnx2fc.h
@@ -541,7 +541,7 @@ void bnx2fc_init_task(struct bnx2fc_cmd *io_req,
 void bnx2fc_ring_doorbell(struct bnx2fc_rport *tgt);
 int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd);
 int bnx2fc_eh_target_reset(struct scsi_target *sc_tgt);
-int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd);
+int bnx2fc_eh_device_reset(struct scsi_device *sdev);
 void bnx2fc_rport_event_handler(struct fc_lport *lport,
 				struct fc_rport_priv *rport,
 				enum fc_rport_event event);
diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c
index 7b8de5e..279de8b 100644
--- a/drivers/scsi/bnx2fc/bnx2fc_io.c
+++ b/drivers/scsi/bnx2fc/bnx2fc_io.c
@@ -1074,12 +1074,12 @@ int bnx2fc_eh_target_reset(struct scsi_target *sc_tgt)
  * Set from SCSI host template to send task mgmt command to the target
  *	and wait for the response
  */
-int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
+int bnx2fc_eh_device_reset(struct scsi_device *sdev)
 {
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	struct fc_lport *lport = shost_priv(rport_to_shost(rport));
 
-	return bnx2fc_initiate_tmf(lport, rport, sc_cmd->device->lun,
+	return bnx2fc_initiate_tmf(lport, rport, sdev->lun,
 				   FCP_TMF_LUN_RESET);
 }
 
diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c
index 133f683..99347b0 100644
--- a/drivers/scsi/csiostor/csio_scsi.c
+++ b/drivers/scsi/csiostor/csio_scsi.c
@@ -2059,9 +2059,8 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 }
 
 static int
-csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
+csio_eh_lun_reset_handler(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = cmnd->device;
 	struct csio_lnode *ln = shost_priv(sdev->host);
 	struct csio_hw *hw = csio_lnode_to_hw(ln);
 	struct csio_scsim *scsim = csio_hw_to_scsim(hw);
@@ -2172,12 +2171,12 @@ static DEVICE_ATTR(dbg_level, S_IRUGO | S_IWUSR, csio_show_dbg_level,
 	csio_dbg(hw, "Waiting max %d secs for LUN reset completion\n",
 		    count * (CSIO_SCSI_TM_POLL_MS / 1000));
 	/* Wait for completion */
-	while ((((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd)
+	while ((((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == tmf_cmnd)
 								&& count--)
 		msleep(CSIO_SCSI_TM_POLL_MS);
 
 	/* LUN reset timed-out */
-	if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == cmnd) {
+	if (((struct scsi_cmnd *)csio_scsi_cmnd(ioreq)) == tmf_cmnd) {
 		csio_err(hw, "LUN reset (%d:%llu) timed out\n",
 			 sdev->id, sdev->lun);
 
diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
index b33e3e7..e146339 100644
--- a/drivers/scsi/cxlflash/main.c
+++ b/drivers/scsi/cxlflash/main.c
@@ -2431,28 +2431,23 @@ static int cxlflash_eh_abort_handler(struct scsi_cmnd *scp)
 
 /**
  * cxlflash_eh_device_reset_handler() - reset a single LUN
- * @scp:	SCSI command to send.
+ * @sdev:	SCSI device to be reset.
  *
  * Return:
  *	SUCCESS as defined in scsi/scsi.h
  *	FAILED as defined in scsi/scsi.h
  */
-static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
+static int cxlflash_eh_device_reset_handler(struct scsi_device *sdev)
 {
 	int rc = SUCCESS;
-	struct Scsi_Host *host = scp->device->host;
+	struct Scsi_Host *host = sdev->host;
 	struct cxlflash_cfg *cfg = shost_priv(host);
 	struct device *dev = &cfg->dev->dev;
 	struct afu *afu = cfg->afu;
 	int rcr = 0;
 
-	dev_dbg(dev, "%s: (scp=%p) %d/%d/%d/%llu "
-		"cdb=(%08x-%08x-%08x-%08x)\n", __func__, scp, host->host_no,
-		scp->device->channel, scp->device->id, scp->device->lun,
-		get_unaligned_be32(&((u32 *)scp->cmnd)[0]),
-		get_unaligned_be32(&((u32 *)scp->cmnd)[1]),
-		get_unaligned_be32(&((u32 *)scp->cmnd)[2]),
-		get_unaligned_be32(&((u32 *)scp->cmnd)[3]));
+	dev_dbg(dev, "%s: %d/%d/%d/%llu\n", __func__, host->host_no,
+		sdev->channel, sdev->id, sdev->lun);
 
 retry:
 	switch (cfg->state) {
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index da1c461..aa7870d 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -725,18 +725,19 @@ static int adpt_abort(struct scsi_cmnd * cmd)
 // This is the same for BLK and SCSI devices
 // NOTE this is wrong in the i2o.h definitions
 // This is not currently supported by our adapter but we issue it anyway
-static int adpt_device_reset(struct scsi_cmnd* cmd)
+static int adpt_device_reset(struct scsi_device * sdev)
 {
 	adpt_hba* pHba;
 	u32 msg[4];
 	u32 rcode;
 	int old_state;
-	struct adpt_device* d = cmd->device->hostdata;
+	struct adpt_device* d = sdev->hostdata;
 
-	pHba = (void*) cmd->device->host->hostdata[0];
-	printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
+	pHba = (void*) sdev->host->hostdata[0];
+	printk(KERN_INFO "%s: Trying to reset device\n", pHba->name);
 	if (!d) {
-		printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
+		printk(KERN_INFO "%s: Reset Device: Device Not found\n",
+		       pHba->name);
 		return FAILED;
 	}
 	memset(msg, 0, sizeof(msg));
@@ -749,19 +750,20 @@ static int adpt_device_reset(struct scsi_cmnd* cmd)
 		spin_lock_irq(pHba->host->host_lock);
 	old_state = d->state;
 	d->state |= DPTI_DEV_RESET;
-	rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
+	rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
 	d->state = old_state;
 	if (pHba->host)
 		spin_unlock_irq(pHba->host->host_lock);
 	if (rcode != 0) {
 		if(rcode == -EOPNOTSUPP ){
-			printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
+			printk(KERN_INFO "%s: Device reset not supported\n",
+			       pHba->name);
 			return FAILED;
 		}
-		printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
+		printk(KERN_INFO "%s: Device reset failed\n", pHba->name);
 		return FAILED;
 	} else {
-		printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
+		printk(KERN_INFO "%s: Device reset successful\n", pHba->name);
 		return SUCCESS;
 	}
 }
diff --git a/drivers/scsi/dpti.h b/drivers/scsi/dpti.h
index 48a9139..efa266d 100644
--- a/drivers/scsi/dpti.h
+++ b/drivers/scsi/dpti.h
@@ -40,7 +40,7 @@ static int adpt_bios_param(struct scsi_device * sdev, struct block_device *dev,
 		sector_t, int geom[]);
 
 static int adpt_bus_reset(struct Scsi_Host* shost, int channel);
-static int adpt_device_reset(struct scsi_cmnd* cmd);
+static int adpt_device_reset(struct scsi_device * sdev);
 
 
 /*
diff --git a/drivers/scsi/esas2r/esas2r.h b/drivers/scsi/esas2r/esas2r.h
index 3ed1aca..0b8e12c 100644
--- a/drivers/scsi/esas2r/esas2r.h
+++ b/drivers/scsi/esas2r/esas2r.h
@@ -976,7 +976,7 @@ u8 handle_hba_ioctl(struct esas2r_adapter *a,
 
 /* SCSI error handler (eh) functions */
 int esas2r_eh_abort(struct scsi_cmnd *cmd);
-int esas2r_device_reset(struct scsi_cmnd *cmd);
+int esas2r_device_reset(struct scsi_device *sdev);
 int esas2r_host_reset(struct Scsi_Host *shost);
 int esas2r_bus_reset(struct Scsi_Host *shost, int channel);
 int esas2r_target_reset(struct scsi_target *starget);
diff --git a/drivers/scsi/esas2r/esas2r_main.c b/drivers/scsi/esas2r/esas2r_main.c
index f0aa2d4..3b8fd41 100644
--- a/drivers/scsi/esas2r/esas2r_main.c
+++ b/drivers/scsi/esas2r/esas2r_main.c
@@ -1237,9 +1237,8 @@ static int esas2r_dev_targ_reset(struct Scsi_Host *shost, int id, u64 lun,
 	return SUCCESS;
 }
 
-int esas2r_device_reset(struct scsi_cmnd *cmd)
+int esas2r_device_reset(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = cmd->device;
 	struct Scsi_Host *shost = sdev->host;
 
 	esas2r_log(ESAS2R_LOG_INFO, "device_reset");
diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h
index 35a4080..a9df966 100644
--- a/drivers/scsi/fnic/fnic.h
+++ b/drivers/scsi/fnic/fnic.h
@@ -342,7 +342,7 @@ static inline struct fnic *fnic_from_ctlr(struct fcoe_ctlr *fip)
 
 int fnic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fnic_abort_cmd(struct scsi_cmnd *);
-int fnic_device_reset(struct scsi_cmnd *);
+int fnic_device_reset(struct scsi_device *);
 int fnic_host_reset(struct Scsi_Host *);
 int fnic_reset(struct Scsi_Host *);
 void fnic_scsi_cleanup(struct fc_lport *);
diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c
index acf7d1d..d633d6c 100644
--- a/drivers/scsi/fnic/fnic_scsi.c
+++ b/drivers/scsi/fnic/fnic_scsi.c
@@ -2330,9 +2330,8 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
  * fail to get aborted. It calls driver's eh_device_reset with a SCSI command
  * on the LUN.
  */
-int fnic_device_reset(struct scsi_cmnd *sc)
+int fnic_device_reset(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = sc->device;
 	struct fc_lport *lp;
 	struct fnic *fnic;
 	struct fnic_io_req *io_req = NULL;
@@ -2345,8 +2344,10 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	struct scsi_lun fc_lun;
 	struct fnic_stats *fnic_stats;
 	struct reset_stats *reset_stats;
-	int tag = 0;
+	int tag;
+	u64 sc_state = 0;
 	DECLARE_COMPLETION_ONSTACK(tm_done);
+	struct scsi_cmnd *sc;
 
 	/* Wait for rport to unblock */
 	rport = starget_to_rport(scsi_target(sdev));
@@ -2361,7 +2362,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	fnic = lport_priv(lp);
 	fnic_stats = &fnic->fnic_stats;
 	reset_stats = &fnic->fnic_stats.reset_stats;
-
+	tag = fnic->fnic_max_tag_id - 1;
 	atomic64_inc(&reset_stats->device_resets);
 
 	FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
@@ -2377,10 +2378,10 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 		goto fnic_device_reset_end;
 	}
 	/* The last tag is reserved for device reset */
-	sc = scsi_host_find_tag(sdev->host, fnic->fnic_max_tag_id - 1);
+	sc = scsi_host_find_tag(sdev->host, tag);
 	io_lock = fnic_io_lock_hash(fnic, sc);
 	spin_lock_irqsave(io_lock, flags);
-	if (CMD_SP(sc)) {
+	if (!sc || CMD_SP(sc)) {
 		/*
 		 * Reset tag busy
 		 */
@@ -2541,13 +2542,12 @@ int fnic_device_reset(struct scsi_cmnd *sc)
 	}
 
 fnic_device_reset_end:
-	FNIC_TRACE(fnic_device_reset, sc->device->host->host_no,
-		  sc->request->tag, sc,
-		  jiffies_to_msecs(jiffies - start_time),
-		  0, ((u64)sc->cmnd[0] << 32 |
-		  (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 |
-		  (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
-		  (((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc)));
+	if (sc)
+		sc_state = ((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc);
+	FNIC_TRACE(fnic_device_reset, sdev->host->host_no,
+		   tag, sc,
+		   jiffies_to_msecs(jiffies - start_time),
+		   0, 0, sc_state);
 
 	FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
 		      "Returning from device reset %s\n",
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
index 8914eab..bc781ba 100644
--- a/drivers/scsi/hpsa.c
+++ b/drivers/scsi/hpsa.c
@@ -257,7 +257,7 @@ static int hpsa_scan_finished(struct Scsi_Host *sh,
 	unsigned long elapsed_time);
 static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth);
 
-static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd);
+static int hpsa_eh_device_reset_handler(struct scsi_device *sdev);
 static int hpsa_slave_alloc(struct scsi_device *sdev);
 static int hpsa_slave_configure(struct scsi_device *sdev);
 static void hpsa_slave_destroy(struct scsi_device *sdev);
@@ -5748,7 +5748,7 @@ static int wait_for_device_to_become_ready(struct ctlr_info *h,
 /* Need at least one of these error handlers to keep ../scsi/hosts.c from
  * complaining.  Doing a host- or bus-reset can't do anything good here.
  */
-static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
+static int hpsa_eh_device_reset_handler(struct scsi_device *sdev)
 {
 	int rc = SUCCESS;
 	struct ctlr_info *h;
@@ -5758,7 +5758,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 	unsigned long flags;
 
 	/* find the controller to which the command to be aborted was sent */
-	h = sdev_to_hba(scsicmd->device);
+	h = sdev_to_hba(sdev);
 	if (h == NULL) /* paranoia */
 		return FAILED;
 
@@ -5771,7 +5771,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 		goto return_reset_status;
 	}
 
-	dev = scsicmd->device->hostdata;
+	dev = sdev->hostdata;
 	if (!dev) {
 		dev_err(&h->pdev->dev, "%s: device lookup failed\n", __func__);
 		rc = FAILED;
@@ -5786,8 +5786,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 	/* if controller locked up, we can guarantee command won't complete */
 	if (lockup_detected(h)) {
 		snprintf(msg, sizeof(msg),
-			 "cmd %d RESET FAILED, lockup detected",
-			 hpsa_get_cmd_index(scsicmd));
+			 "RESET FAILED, lockup detected");
 		hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 		rc = FAILED;
 		goto return_reset_status;
@@ -5796,8 +5795,7 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
 	/* this reset request might be the result of a lockup; check */
 	if (detect_controller_lockup(h)) {
 		snprintf(msg, sizeof(msg),
-			 "cmd %d RESET FAILED, new lockup detected",
-			 hpsa_get_cmd_index(scsicmd));
+			 "RESET FAILED, new lockup detected");
 		hpsa_show_dev_msg(KERN_WARNING, h, dev, msg);
 		rc = FAILED;
 		goto return_reset_status;
diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
index f7b9601..7cfade3 100644
--- a/drivers/scsi/ibmvscsi/ibmvfc.c
+++ b/drivers/scsi/ibmvscsi/ibmvfc.c
@@ -2431,14 +2431,13 @@ static int ibmvfc_eh_abort_handler(struct scsi_cmnd *cmd)
 
 /**
  * ibmvfc_eh_device_reset_handler - Reset a single LUN
- * @cmd:	scsi command struct
+ * @sdev:	scsi device struct
  *
  * Returns:
  *	SUCCESS / FAST_IO_FAIL / FAILED
  **/
-static int ibmvfc_eh_device_reset_handler(struct scsi_cmnd *cmd)
+static int ibmvfc_eh_device_reset_handler(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = cmd->device;
 	struct ibmvfc_host *vhost = shost_priv(sdev->host);
 	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	int cancel_rc, block_rc, reset_rc = 0;
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index 262b30c..9fe323a 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1620,16 +1620,16 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd)
  * template send this over to the server and wait synchronously for the 
  * response
  */
-static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
+static int ibmvscsi_eh_device_reset_handler(struct scsi_device *sdev)
 {
-	struct ibmvscsi_host_data *hostdata = shost_priv(cmd->device->host);
+	struct ibmvscsi_host_data *hostdata = shost_priv(sdev->host);
 	struct srp_tsk_mgmt *tsk_mgmt;
 	struct srp_event_struct *evt;
 	struct srp_event_struct *tmp_evt, *pos;
 	union viosrp_iu srp_rsp;
 	int rsp_rc;
 	unsigned long flags;
-	u16 lun = lun_from_dev(cmd->device);
+	u16 lun = lun_from_dev(sdev);
 	unsigned long wait_switch = 0;
 
 	spin_lock_irqsave(hostdata->host->host_lock, flags);
@@ -1638,7 +1638,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
 		evt = get_event_struct(&hostdata->pool);
 		if (evt == NULL) {
 			spin_unlock_irqrestore(hostdata->host->host_lock, flags);
-			sdev_printk(KERN_ERR, cmd->device,
+			sdev_printk(KERN_ERR, sdev,
 				"failed to allocate reset event\n");
 			return FAILED;
 		}
@@ -1672,12 +1672,12 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
 	spin_unlock_irqrestore(hostdata->host->host_lock, flags);
 
 	if (rsp_rc != 0) {
-		sdev_printk(KERN_ERR, cmd->device,
+		sdev_printk(KERN_ERR, sdev,
 			    "failed to send reset event. rc=%d\n", rsp_rc);
 		return FAILED;
 	}
 
-	sdev_printk(KERN_INFO, cmd->device, "resetting device. lun 0x%llx\n",
+	sdev_printk(KERN_INFO, sdev, "resetting device. lun 0x%llx\n",
 		    (((u64) lun) << 48));
 
 	wait_for_completion(&evt->comp);
@@ -1685,7 +1685,8 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
 	/* make sure we got a good response */
 	if (unlikely(srp_rsp.srp.rsp.opcode != SRP_RSP)) {
 		if (printk_ratelimit())
-			sdev_printk(KERN_WARNING, cmd->device, "reset bad SRP RSP type %d\n",
+			sdev_printk(KERN_WARNING, sdev,
+				    "reset bad SRP RSP type %d\n",
 				    srp_rsp.srp.rsp.opcode);
 		return FAILED;
 	}
@@ -1697,7 +1698,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
 
 	if (rsp_rc) {
 		if (printk_ratelimit())
-			sdev_printk(KERN_WARNING, cmd->device,
+			sdev_printk(KERN_WARNING, sdev,
 				    "reset code %d for task tag 0x%llx\n",
 				    rsp_rc, tsk_mgmt->task_tag);
 		return FAILED;
@@ -1708,7 +1709,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd)
 	 */
 	spin_lock_irqsave(hostdata->host->host_lock, flags);
 	list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) {
-		if ((tmp_evt->cmnd) && (tmp_evt->cmnd->device == cmd->device)) {
+		if ((tmp_evt->cmnd) && (tmp_evt->cmnd->device == sdev)) {
 			if (tmp_evt->cmnd)
 				tmp_evt->cmnd->result = (DID_RESET << 16);
 			list_del(&tmp_evt->list);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 2ab2a9e..3824c63 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -5296,7 +5296,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes,
 
 /**
  * ipr_eh_dev_reset - Reset the device
- * @scsi_cmd:	scsi command struct
+ * @scsi_dev:	scsi device struct
  *
  * This function issues a device reset to the affected device.
  * A LUN reset will be sent to the device first. If that does
@@ -5305,7 +5305,7 @@ static int ipr_sata_reset(struct ata_link *link, unsigned int *classes,
  * Return value:
  *	SUCCESS / FAILED
  **/
-static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
+static int __ipr_eh_dev_reset(struct scsi_device *scsi_dev)
 {
 	struct ipr_cmnd *ipr_cmd;
 	struct ipr_ioa_cfg *ioa_cfg;
@@ -5315,8 +5315,8 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
 	struct ipr_hrr_queue *hrrq;
 
 	ENTER;
-	ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
-	res = scsi_cmd->device->hostdata;
+	ioa_cfg = (struct ipr_ioa_cfg *) scsi_dev->host->hostdata;
+	res = scsi_dev->hostdata;
 
 	/*
 	 * If we are currently going through reset/reload, return failed. This will force the
@@ -5333,7 +5333,8 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
 		for (i = hrrq->min_cmd_id; i <= hrrq->max_cmd_id; i++) {
 			ipr_cmd = ioa_cfg->ipr_cmnd_list[i];
 
-			if (ipr_cmd->ioarcb.res_handle == res->res_handle) {
+			if (ipr_cmd->scsi_cmd &&
+			    ipr_cmd->scsi_cmd->device == scsi_dev) {
 				if (!ipr_cmd->qc)
 					continue;
 				if (ipr_cmnd_is_free(ipr_cmd))
@@ -5349,13 +5350,13 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
 		spin_unlock(&hrrq->_lock);
 	}
 	res->resetting_device = 1;
-	scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n");
+	sdev_printk(KERN_ERR, scsi_dev, "Resetting device\n");
 
 	if (ipr_is_gata(res) && res->sata_port) {
 		ap = res->sata_port->ap;
-		spin_unlock_irq(scsi_cmd->device->host->host_lock);
+		spin_unlock_irq(scsi_dev->host->host_lock);
 		ata_std_error_handler(ap);
-		spin_lock_irq(scsi_cmd->device->host->host_lock);
+		spin_lock_irq(scsi_dev->host->host_lock);
 	} else
 		rc = ipr_device_reset(ioa_cfg, res);
 	res->resetting_device = 0;
@@ -5365,27 +5366,27 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd)
 	return rc ? FAILED : SUCCESS;
 }
 
-static int ipr_eh_dev_reset(struct scsi_cmnd *cmd)
+static int ipr_eh_dev_reset(struct scsi_device *sdev)
 {
 	int rc;
 	struct ipr_ioa_cfg *ioa_cfg;
 	struct ipr_resource_entry *res;
 
-	ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata;
-	res = cmd->device->hostdata;
+	ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata;
+	res = sdev->hostdata;
 
 	if (!res)
 		return FAILED;
 
-	spin_lock_irq(cmd->device->host->host_lock);
-	rc = __ipr_eh_dev_reset(cmd);
-	spin_unlock_irq(cmd->device->host->host_lock);
+	spin_lock_irq(sdev->host->host_lock);
+	rc = __ipr_eh_dev_reset(sdev);
+	spin_unlock_irq(sdev->host->host_lock);
 
 	if (rc == SUCCESS) {
 		if (ipr_is_gata(res) && res->sata_port)
 			rc = ipr_wait_for_ops(ioa_cfg, res, ipr_match_res);
 		else
-			rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun);
+			rc = ipr_wait_for_ops(ioa_cfg, sdev, ipr_match_lun);
 	}
 
 	return rc;
diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index ef6c8bc..c510c3e 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -2167,11 +2167,11 @@ int fc_eh_abort(struct scsi_cmnd *sc_cmd)
  *
  * Set from SCSI host template.
  */
-int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
+int fc_eh_device_reset(struct scsi_device *sdev)
 {
 	struct fc_lport *lport;
 	struct fc_fcp_pkt *fsp;
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	int rc = FAILED;
 	int rval;
 
@@ -2179,7 +2179,7 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 	if (rval)
 		return rval;
 
-	lport = shost_priv(sc_cmd->device->host);
+	lport = shost_priv(sdev->host);
 
 	if (lport->state != LPORT_ST_READY)
 		return rc;
@@ -2202,7 +2202,7 @@ int fc_eh_device_reset(struct scsi_cmnd *sc_cmd)
 	/*
 	 * flush outstanding commands
 	 */
-	rc = fc_lun_reset(lport, fsp, scmd_id(sc_cmd), sc_cmd->device->lun);
+	rc = fc_lun_reset(lport, fsp, sdev->id, sdev->lun);
 	fsp->state = FC_SRB_FREE;
 	fc_fcp_pkt_release(fsp);
 
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index d51c9ba..97e4b24 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -2273,17 +2273,17 @@ int iscsi_eh_abort(struct scsi_cmnd *sc)
 }
 EXPORT_SYMBOL_GPL(iscsi_eh_abort);
 
-static void iscsi_prep_lun_reset_pdu(struct scsi_cmnd *sc, struct iscsi_tm *hdr)
+static void iscsi_prep_lun_reset_pdu(struct scsi_device *sdev, struct iscsi_tm *hdr)
 {
 	memset(hdr, 0, sizeof(*hdr));
 	hdr->opcode = ISCSI_OP_SCSI_TMFUNC | ISCSI_OP_IMMEDIATE;
 	hdr->flags = ISCSI_TM_FUNC_LOGICAL_UNIT_RESET & ISCSI_FLAG_TM_FUNC_MASK;
 	hdr->flags |= ISCSI_FLAG_CMD_FINAL;
-	int_to_scsilun(sc->device->lun, &hdr->lun);
+	int_to_scsilun(sdev->lun, &hdr->lun);
 	hdr->rtt = RESERVED_ITT;
 }
 
-int iscsi_eh_device_reset(struct scsi_cmnd *sc)
+int iscsi_eh_device_reset(struct scsi_device *sdev)
 {
 	struct iscsi_cls_session *cls_session;
 	struct iscsi_session *session;
@@ -2291,11 +2291,10 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
 	struct iscsi_tm *hdr;
 	int rc = FAILED;
 
-	cls_session = starget_to_session(scsi_target(sc->device));
+	cls_session = starget_to_session(scsi_target(sdev));
 	session = cls_session->dd_data;
 
-	ISCSI_DBG_EH(session, "LU Reset [sc %p lun %llu]\n", sc,
-		     sc->device->lun);
+	ISCSI_DBG_EH(session, "LU Reset [lun %llu]\n", sdev->lun);
 
 	mutex_lock(&session->eh_mutex);
 	spin_lock_bh(&session->frwd_lock);
@@ -2313,7 +2312,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
 	conn->tmf_state = TMF_QUEUED;
 
 	hdr = &conn->tmhdr;
-	iscsi_prep_lun_reset_pdu(sc, hdr);
+	iscsi_prep_lun_reset_pdu(sdev, hdr);
 
 	if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age,
 				    session->lu_reset_timeout)) {
@@ -2340,7 +2339,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc)
 
 	spin_lock_bh(&session->frwd_lock);
 	memset(hdr, 0, sizeof(*hdr));
-	fail_scsi_tasks(conn, sc->device->lun, DID_ERROR);
+	fail_scsi_tasks(conn, sdev->lun, DID_ERROR);
 	conn->tmf_state = TMF_INITIAL;
 	spin_unlock_bh(&session->frwd_lock);
 
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 2001a6e..b966ec1 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -503,18 +503,18 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd)
 EXPORT_SYMBOL_GPL(sas_eh_abort_handler);
 
 /* Attempt to send a LUN reset message to a device */
-int sas_eh_device_reset_handler(struct scsi_cmnd *cmd)
+int sas_eh_device_reset_handler(struct scsi_device *sdev)
 {
 	int res;
 	struct scsi_lun lun;
-	struct Scsi_Host *host = cmd->device->host;
-	struct domain_device *dev = cmd_to_domain_dev(cmd);
+	struct Scsi_Host *host = sdev->host;
+	struct domain_device *dev = sdev_to_domain_dev(sdev);
 	struct sas_internal *i = to_sas_internal(host->transportt);
 
 	if (current != host->ehandler)
-		return sas_queue_reset(dev, SAS_DEV_LU_RESET, cmd->device->lun, 0);
+		return sas_queue_reset(dev, SAS_DEV_LU_RESET, sdev->lun, 0);
 
-	int_to_scsilun(cmd->device->lun, &lun);
+	int_to_scsilun(sdev->lun, &lun);
 
 	if (!i->dft->lldd_lu_reset)
 		return FAILED;
@@ -557,7 +557,7 @@ static int try_to_reset_cmd_device(struct scsi_cmnd *cmd)
 	if (!shost->hostt->eh_device_reset_handler)
 		goto try_target_reset;
 
-	res = shost->hostt->eh_device_reset_handler(cmd);
+	res = shost->hostt->eh_device_reset_handler(cmd->device);
 	if (res == SUCCESS)
 		return res;
 
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 573bd43..0fe6d83 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -5154,19 +5154,19 @@ void lpfc_poll_timeout(unsigned long ptr)
  *  0x2002 - Success
  **/
 static int
-lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
+lpfc_device_reset_handler(struct scsi_device *sdev)
 {
-	struct Scsi_Host  *shost = cmnd->device->host;
+	struct Scsi_Host  *shost = sdev->host;
 	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
 	struct lpfc_rport_data *rdata;
 	struct lpfc_nodelist *pnode;
-	unsigned tgt_id = cmnd->device->id;
-	uint64_t lun_id = cmnd->device->lun;
+	unsigned tgt_id = sdev->id;
+	uint64_t lun_id = sdev->lun;
 	struct lpfc_scsi_event_header scsi_event;
-	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 	int status;
 
-	rdata = lpfc_rport_data_from_scsi_device(cmnd->device);
+	rdata = lpfc_rport_data_from_scsi_device(sdev);
 	if (!rdata || !rdata->pnode) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_FCP,
 				 "0798 Device Reset rport failure: rdata x%p\n",
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index f3c2310..33b7c66 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -2517,27 +2517,23 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
  * Returns SUCCESS if command aborted else FAILED
  */
 static int
-scsih_dev_reset(struct scsi_cmnd *scmd)
+scsih_dev_reset(struct scsi_device *sdev)
 {
-	struct MPT3SAS_ADAPTER *ioc = shost_priv(scmd->device->host);
+	struct MPT3SAS_ADAPTER *ioc = shost_priv(sdev->host);
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	struct _sas_device *sas_device = NULL;
 	u16	handle;
 	int r;
-
-	struct scsi_target *starget = scmd->device->sdev_target;
+	struct scsi_target *starget = scsi_target(sdev);
 	struct MPT3SAS_TARGET *target_priv_data = starget->hostdata;
 
-	sdev_printk(KERN_INFO, scmd->device,
-		"attempting device reset! scmd(%p)\n", scmd);
-	_scsih_tm_display_info(ioc, scmd);
+	sdev_printk(KERN_INFO, sdev,
+		"attempting device reset!\n");
 
-	sas_device_priv_data = scmd->device->hostdata;
+	sas_device_priv_data = sdev->hostdata;
 	if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
-		sdev_printk(KERN_INFO, scmd->device,
-			"device been deleted! scmd(%p)\n", scmd);
-		scmd->result = DID_NO_CONNECT << 16;
-		scmd->scsi_done(scmd);
+		sdev_printk(KERN_INFO, sdev,
+			"device been deleted!\n");
 		r = SUCCESS;
 		goto out;
 	}
@@ -2554,18 +2550,17 @@ int mpt3sas_scsih_issue_locked_tm(struct MPT3SAS_ADAPTER *ioc, u16 handle,
 		handle = sas_device_priv_data->sas_target->handle;
 
 	if (!handle) {
-		scmd->result = DID_RESET << 16;
 		r = FAILED;
 		goto out;
 	}
 
-	r = mpt3sas_scsih_issue_locked_tm(ioc, handle, scmd->device->channel,
-	    scmd->device->id, scmd->device->lun,
+	r = mpt3sas_scsih_issue_locked_tm(ioc, handle, sdev->channel,
+	    sdev->id, sdev->lun,
 	    MPI2_SCSITASKMGMT_TASKTYPE_LOGICAL_UNIT_RESET, 0, 30);
 
  out:
-	sdev_printk(KERN_INFO, scmd->device, "device reset: %s scmd(%p)\n",
-	    ((r == SUCCESS) ? "SUCCESS" : "FAILED"), scmd);
+	sdev_printk(KERN_INFO, sdev, "device reset: %s\n",
+	    ((r == SUCCESS) ? "SUCCESS" : "FAILED"));
 
 	if (sas_device)
 		sas_device_put(sas_device);
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c
index 289edfe..f8fe609 100644
--- a/drivers/scsi/pmcraid.c
+++ b/drivers/scsi/pmcraid.c
@@ -3059,11 +3059,11 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd)
  * Return value
  *	SUCCESS or FAILED
  */
-static int pmcraid_eh_device_reset_handler(struct scsi_cmnd *scmd)
+static int pmcraid_eh_device_reset_handler(struct scsi_device *sdev)
 {
-	scmd_printk(KERN_INFO, scmd,
+	sdev_printk(KERN_INFO, sdev,
 		    "resetting device due to an I/O command timeout.\n");
-	return pmcraid_reset_device(scmd->device,
+	return pmcraid_reset_device(sdev,
 				    PMCRAID_INTERNAL_TIMEOUT,
 				    RESET_DEVICE_LUN);
 }
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index 5ccfb14..8feab7e 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -625,12 +625,12 @@ static int qedf_eh_target_reset(struct scsi_target *starget)
 	return qedf_initiate_tmf(rport, 0, FCP_TMF_TGT_RESET);
 }
 
-static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd)
+static int qedf_eh_device_reset(struct scsi_device *sdev)
 {
-	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
+	struct fc_rport *rport = starget_to_rport(scsi_target(sdev));
 
 	QEDF_ERR(NULL, "LUN RESET Issued...\n");
-	return qedf_initiate_tmf(rport, sc_cmd->device->lun, FCP_TMF_LUN_RESET);
+	return qedf_initiate_tmf(rport, sdev->lun, FCP_TMF_LUN_RESET);
 }
 
 void qedf_wait_for_upload(struct qedf_ctx *qedf)
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index b5484a49..338fe5b 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -1001,13 +1001,24 @@ static void qla1280_mailbox_timeout(unsigned long __data)
  *     Reset the specified SCSI device
  **************************************************************************/
 static int
-qla1280_eh_device_reset(struct scsi_cmnd *cmd)
+qla1280_eh_device_reset(struct scsi_device *sdev)
 {
-	int rc;
+	struct Scsi_Host *shost = sdev->host;
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)shost->hostdata;
+	int rc = FAILED;
 
-	spin_lock_irq(cmd->device->host->host_lock);
-	rc = qla1280_error_action(cmd, DEVICE_RESET);
-	spin_unlock_irq(cmd->device->host->host_lock);
+	spin_lock_irq(shost->host_lock);
+	if (qla1280_verbose)
+		printk(KERN_INFO
+		       "scsi(%ld:%d:%d:%llu): Queueing device reset "
+		       "command.\n", ha->host_no, sdev->channel,
+		       sdev->id, sdev->lun);
+	if (qla1280_device_reset(ha, sdev->channel, sdev->id) == 0) {
+		/* issued device reset, set wait conditions */
+		rc = qla1280_wait_for_pending_commands(ha,
+			sdev->channel, sdev->id);
+	}
+	spin_unlock_irq(shost->host_lock);
 
 	return rc;
 }
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 2345695..14bf189 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -272,7 +272,7 @@
 static void qla2xxx_slave_destroy(struct scsi_device *);
 static int qla2xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
-static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
+static int qla2xxx_eh_device_reset(struct scsi_device *);
 static int qla2xxx_eh_target_reset(struct scsi_target *);
 static int qla2xxx_eh_bus_reset(struct Scsi_Host *, int);
 static int qla2xxx_eh_host_reset(struct Scsi_Host *);
@@ -1384,9 +1384,8 @@ uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha)
 };
 
 static int
-qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
+qla2xxx_eh_device_reset(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = cmd->device;
 	scsi_qla_host_t *vha = shost_priv(sdev->host);
 	struct qla_hw_data *ha = vha->hw;
 	fc_port_t *fcport = (struct fc_port *) sdev->hostdata;
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 0ce84d6..5271c78 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -158,7 +158,7 @@ static int qla4xxx_set_chap_entry(struct Scsi_Host *shost, void  *data,
  */
 static int qla4xxx_queuecommand(struct Scsi_Host *h, struct scsi_cmnd *cmd);
 static int qla4xxx_eh_abort(struct scsi_cmnd *cmd);
-static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd);
+static int qla4xxx_eh_device_reset(struct scsi_device *sdev);
 static int qla4xxx_eh_target_reset(struct scsi_target *starget);
 static int qla4xxx_eh_host_reset(struct Scsi_Host *shost);
 static int qla4xxx_slave_alloc(struct scsi_device *device);
@@ -9238,17 +9238,17 @@ static int qla4xxx_eh_abort(struct scsi_cmnd *cmd)
  * This routine is called by the Linux OS to reset all luns on the
  * specified target.
  **/
-static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
+static int qla4xxx_eh_device_reset(struct scsi_device *sdev)
 {
-	struct scsi_qla_host *ha = to_qla_host(cmd->device->host);
+	struct scsi_qla_host *ha = to_qla_host(sdev->host);
 	struct iscsi_cls_session *session;
-	struct ddb_entry *ddb_entry = cmd->device->hostdata;
+	struct ddb_entry *ddb_entry = sdev->hostdata;
 	int ret = FAILED, stat;
 
 	if (!ddb_entry)
 		return ret;
 
-	session = starget_to_session(scsi_target(cmd->device));
+	session = starget_to_session(scsi_target(sdev));
 	ret = iscsi_block_scsi_eh(session);
 	if (ret)
 		return ret;
@@ -9256,23 +9256,20 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
 
 	ql4_printk(KERN_INFO, ha,
 		   "scsi%ld:%d:%d:%llu: DEVICE RESET ISSUED.\n", ha->host_no,
-		   cmd->device->channel, cmd->device->id, cmd->device->lun);
+		   sdev->channel, sdev->id, sdev->lun);
 
 	DEBUG2(printk(KERN_INFO
-		      "scsi%ld: DEVICE_RESET cmd=%p jiffies = 0x%lx, to=%x,"
-		      "dpc_flags=%lx, status=%x allowed=%d\n", ha->host_no,
-		      cmd, jiffies, cmd->request->timeout / HZ,
-		      ha->dpc_flags, cmd->result, cmd->allowed));
+		      "scsi%ld: DEVICE_RESET dpc_flags=%lx\n",
+		      ha->host_no, ha->dpc_flags));
 
 	/* FIXME: wait for hba to go online */
-	stat = qla4xxx_reset_lun(ha, ddb_entry, cmd->device->lun);
+	stat = qla4xxx_reset_lun(ha, ddb_entry, sdev->lun);
 	if (stat != QLA_SUCCESS) {
 		ql4_printk(KERN_INFO, ha, "DEVICE RESET FAILED. %d\n", stat);
 		goto eh_dev_reset_done;
 	}
 
-	if (qla4xxx_eh_wait_for_commands(ha, scsi_target(cmd->device),
-					 cmd->device)) {
+	if (qla4xxx_eh_wait_for_commands(ha, scsi_target(sdev), sdev)) {
 		ql4_printk(KERN_INFO, ha,
 			   "DEVICE RESET FAILED - waiting for "
 			   "commands.\n");
@@ -9280,14 +9277,13 @@ static int qla4xxx_eh_device_reset(struct scsi_cmnd *cmd)
 	}
 
 	/* Send marker. */
-	if (qla4xxx_send_marker_iocb(ha, ddb_entry, cmd->device->lun,
+	if (qla4xxx_send_marker_iocb(ha, ddb_entry, sdev->lun,
 		MM_LUN_RESET) != QLA_SUCCESS)
 		goto eh_dev_reset_done;
 
 	ql4_printk(KERN_INFO, ha,
 		   "scsi(%ld:%d:%d:%llu): DEVICE RESET SUCCEEDED.\n",
-		   ha->host_no, cmd->device->channel, cmd->device->id,
-		   cmd->device->lun);
+		   ha->host_no, sdev->channel, sdev->id, sdev->lun);
 
 	ret = SUCCESS;
 
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 37e511f..9029500 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -3793,19 +3793,17 @@ static int scsi_debug_abort(struct scsi_cmnd *SCpnt)
 	return SUCCESS;
 }
 
-static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
+static int scsi_debug_device_reset(struct scsi_device * sdp)
 {
+	struct sdebug_dev_info *devip =
+		(struct sdebug_dev_info *)sdp->hostdata;
+
 	++num_dev_resets;
-	if (SCpnt && SCpnt->device) {
-		struct scsi_device *sdp = SCpnt->device;
-		struct sdebug_dev_info *devip =
-				(struct sdebug_dev_info *)sdp->hostdata;
 
-		if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
-			sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
-		if (devip)
-			set_bit(SDEBUG_UA_POR, devip->uas_bm);
-	}
+	if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
+		sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
+	if (devip)
+		set_bit(SDEBUG_UA_POR, devip->uas_bm);
 	return SUCCESS;
 }
 
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 368a961..4a7fe97f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -844,7 +844,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
 	if (!hostt->eh_device_reset_handler)
 		return FAILED;
 
-	rtn = hostt->eh_device_reset_handler(scmd);
+	rtn = hostt->eh_device_reset_handler(scmd->device);
 	if (rtn == SUCCESS)
 		__scsi_report_device_reset(scmd->device, NULL);
 	return rtn;
@@ -1106,6 +1106,7 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
  * scsi_eh_finish_cmd - Handle a cmd that eh is finished with.
  * @scmd:	Original SCSI cmd that eh has finished.
  * @done_q:	Queue for processed commands.
+ * @result:	Final command status to be set
  *
  * Notes:
  *    We don't want to use the normal command completion while we are are
@@ -1114,10 +1115,18 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
  *    keep a list of pending commands for final completion, and once we
  *    are ready to leave error handling we handle completion for real.
  */
-void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
+void __scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q,
+			int host_byte)
 {
+	if (host_byte)
+		set_host_byte(scmd, host_byte);
 	list_move_tail(&scmd->eh_entry, done_q);
 }
+
+void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
+{
+	__scsi_eh_finish_cmd(scmd, done_q, 0);
+}
 EXPORT_SYMBOL(scsi_eh_finish_cmd);
 
 /**
@@ -1284,7 +1293,8 @@ static int scsi_eh_test_devices(struct list_head *cmd_list,
 				if (finish_cmds &&
 				    (try_stu ||
 				     scsi_eh_action(scmd, SUCCESS) == SUCCESS))
-					scsi_eh_finish_cmd(scmd, done_q);
+					__scsi_eh_finish_cmd(scmd, done_q,
+							     DID_RESET);
 				else
 					list_move_tail(&scmd->eh_entry, work_q);
 			}
@@ -1429,8 +1439,9 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
 							 work_q, eh_entry) {
 					if (scmd->device == sdev &&
 					    scsi_eh_action(scmd, rtn) != FAILED)
-						scsi_eh_finish_cmd(scmd,
-								   done_q);
+						__scsi_eh_finish_cmd(scmd,
+								     done_q,
+								     DID_RESET);
 				}
 			}
 		} else {
@@ -1498,7 +1509,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
 			if (rtn == SUCCESS)
 				list_move_tail(&scmd->eh_entry, &check_list);
 			else if (rtn == FAST_IO_FAIL)
-				scsi_eh_finish_cmd(scmd, done_q);
+				__scsi_eh_finish_cmd(scmd, done_q,
+						     DID_TRANSPORT_DISRUPTED);
 			else
 				/* push back on work queue for further processing */
 				list_move(&scmd->eh_entry, work_q);
@@ -1563,8 +1575,9 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
 			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 				if (channel == scmd_channel(scmd)) {
 					if (rtn == FAST_IO_FAIL)
-						scsi_eh_finish_cmd(scmd,
-								   done_q);
+						__scsi_eh_finish_cmd(scmd,
+								     done_q,
+								     DID_TRANSPORT_DISRUPTED);
 					else
 						list_move_tail(&scmd->eh_entry,
 							       &check_list);
@@ -1607,9 +1620,9 @@ static int scsi_eh_host_reset(struct Scsi_Host *shost,
 		if (rtn == SUCCESS) {
 			list_splice_init(work_q, &check_list);
 		} else if (rtn == FAST_IO_FAIL) {
-			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
-					scsi_eh_finish_cmd(scmd, done_q);
-			}
+			list_for_each_entry_safe(scmd, next, work_q, eh_entry)
+				__scsi_eh_finish_cmd(scmd, done_q,
+						     DID_TRANSPORT_DISRUPTED);
 		} else {
 			SCSI_LOG_ERROR_RECOVERY(3,
 				shost_printk(KERN_INFO, shost,
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index cb8f886..e830d0e 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -5259,16 +5259,16 @@ static int pqi_device_reset(struct pqi_ctrl_info *ctrl_info,
 	return rc == 0 ? SUCCESS : FAILED;
 }
 
-static int pqi_eh_device_reset_handler(struct scsi_cmnd *scmd)
+static int pqi_eh_device_reset_handler(struct scsi_device *sdev)
 {
 	int rc;
 	struct Scsi_Host *shost;
 	struct pqi_ctrl_info *ctrl_info;
 	struct pqi_scsi_dev *device;
 
-	shost = scmd->device->host;
+	shost = sdev->host;
 	ctrl_info = shost_to_hba(shost);
-	device = scmd->device->hostdata;
+	device = sdev->hostdata;
 
 	dev_err(&ctrl_info->pci_dev->dev,
 		"resetting scsi %d:%d:%d:%d\n",
diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h
index 9171b90..b27e130 100644
--- a/drivers/scsi/snic/snic.h
+++ b/drivers/scsi/snic/snic.h
@@ -379,7 +379,7 @@ struct snic_global {
 
 int snic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int snic_abort_cmd(struct scsi_cmnd *);
-int snic_device_reset(struct scsi_cmnd *);
+int snic_device_reset(struct scsi_device *);
 int snic_host_reset(struct Scsi_Host *);
 void snic_shutdown_scsi_cleanup(struct snic *);
 
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index f50d274..90990cf 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -2134,15 +2134,15 @@
  * command on the LUN.
  */
 int
-snic_device_reset(struct scsi_cmnd *sc)
+snic_device_reset(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = sc->device;
 	struct Scsi_Host *shost = sdev->host;
 	struct snic *snic = shost_priv(shost);
 	struct snic_req_info *rqi = NULL;
 	int start_time = jiffies;
 	int ret = FAILED;
 	int dr_supp = 0;
+	struct scsi_cmnd tmf_sc, *sc = &tmf_sc;
 
 	SNIC_SCSI_DBG(shost, "dev_reset\n");
 	dr_supp = snic_dev_reset_supported(sdev);
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 47a8722..3b95b0c 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5481,27 +5481,25 @@ static int ufshcd_issue_tm_cmd(struct ufs_hba *hba, int lun_id, int task_id,
 /**
  * ufshcd_eh_device_reset_handler - device reset handler registered to
  *                                    scsi layer.
- * @cmd: SCSI command pointer
+ * @sdev: SCSI device pointer
  *
  * Returns SUCCESS/FAILED
  */
-static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
+static int ufshcd_eh_device_reset_handler(struct scsi_device *sdev)
 {
 	struct Scsi_Host *host;
 	struct ufs_hba *hba;
-	unsigned int tag;
+	unsigned int lun;
 	u32 pos;
 	int err;
 	u8 resp = 0xF;
-	struct ufshcd_lrb *lrbp;
 	unsigned long flags;
 
-	host = cmd->device->host;
+	host = sdev->host;
 	hba = shost_priv(host);
-	tag = cmd->request->tag;
+	lun = ufshcd_scsi_to_upiu_lun(sdev->lun);
 
-	lrbp = &hba->lrb[tag];
-	err = ufshcd_issue_tm_cmd(hba, lrbp->lun, 0, UFS_LOGICAL_RESET, &resp);
+	err = ufshcd_issue_tm_cmd(hba, lun, 0, UFS_LOGICAL_RESET, &resp);
 	if (err || resp != UPIU_TASK_MANAGEMENT_FUNC_COMPL) {
 		if (!err)
 			err = resp;
@@ -5510,7 +5508,7 @@ static int ufshcd_eh_device_reset_handler(struct scsi_cmnd *cmd)
 
 	/* clear the commands that were pending for corresponding LUN */
 	for_each_set_bit(pos, &hba->outstanding_reqs, hba->nutrs) {
-		if (hba->lrb[pos].lun == lrbp->lun) {
+		if (hba->lrb[pos].lun == lun) {
 			err = ufshcd_clear_cmd(hba, pos);
 			if (err)
 				break;
diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
index 8b93197..bc97e41 100644
--- a/drivers/scsi/virtio_scsi.c
+++ b/drivers/scsi/virtio_scsi.c
@@ -681,26 +681,26 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
 	return ret;
 }
 
-static int virtscsi_device_reset(struct scsi_cmnd *sc)
+static int virtscsi_device_reset(struct scsi_device *sdev)
 {
-	struct virtio_scsi *vscsi = shost_priv(sc->device->host);
+	struct virtio_scsi *vscsi = shost_priv(sdev->host);
 	struct virtio_scsi_cmd *cmd;
 
-	sdev_printk(KERN_INFO, sc->device, "device reset\n");
+	sdev_printk(KERN_INFO, sdev, "device reset\n");
 	cmd = mempool_alloc(virtscsi_cmd_pool, GFP_NOIO);
 	if (!cmd)
 		return FAILED;
 
 	memset(cmd, 0, sizeof(*cmd));
-	cmd->sc = sc;
+	cmd->sc = NULL;
 	cmd->req.tmf = (struct virtio_scsi_ctrl_tmf_req){
 		.type = VIRTIO_SCSI_T_TMF,
 		.subtype = cpu_to_virtio32(vscsi->vdev,
 					     VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET),
 		.lun[0] = 1,
-		.lun[1] = sc->device->id,
-		.lun[2] = (sc->device->lun >> 8) | 0x40,
-		.lun[3] = sc->device->lun & 0xff,
+		.lun[1] = sdev->id,
+		.lun[2] = (sdev->lun >> 8) | 0x40,
+		.lun[3] = sdev->lun & 0xff,
 	};
 	return virtscsi_tmf(vscsi, cmd);
 }
diff --git a/drivers/scsi/vmw_pvscsi.c b/drivers/scsi/vmw_pvscsi.c
index 521cd9e..e6c49ea 100644
--- a/drivers/scsi/vmw_pvscsi.c
+++ b/drivers/scsi/vmw_pvscsi.c
@@ -950,14 +950,14 @@ static int pvscsi_bus_reset(struct Scsi_Host *host, int channel)
 	return SUCCESS;
 }
 
-static int pvscsi_device_reset(struct scsi_cmnd *cmd)
+static int pvscsi_device_reset(struct scsi_device *sdev)
 {
-	struct Scsi_Host *host = cmd->device->host;
+	struct Scsi_Host *host = sdev->host;
 	struct pvscsi_adapter *adapter = shost_priv(host);
 	unsigned long flags;
 
-	scmd_printk(KERN_INFO, cmd, "SCSI device reset on scsi%u:%u\n",
-		    host->host_no, cmd->device->id);
+	sdev_printk(KERN_INFO, sdev, "SCSI device reset on scsi%u:%u\n",
+		    host->host_no, sdev->id);
 
 	/*
 	 * We don't want to queue new requests for this device after flushing
@@ -967,7 +967,7 @@ static int pvscsi_device_reset(struct scsi_cmnd *cmd)
 	spin_lock_irqsave(&adapter->hw_lock, flags);
 
 	pvscsi_process_request_ring(adapter);
-	ll_device_reset(adapter, cmd->device->id);
+	ll_device_reset(adapter, sdev->id);
 	pvscsi_process_completion_ring(adapter);
 
 	spin_unlock_irqrestore(&adapter->hw_lock, flags);
diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c
index a302943..0fb444f 100644
--- a/drivers/scsi/wd719x.c
+++ b/drivers/scsi/wd719x.c
@@ -500,10 +500,10 @@ static int wd719x_reset(struct Scsi_Host *shost, u8 opcode, u8 device)
 	return SUCCESS;
 }
 
-static int wd719x_dev_reset(struct scsi_cmnd *cmd)
+static int wd719x_dev_reset(struct scsi_device *sdev)
 {
-	return wd719x_reset(cmd->device->host, WD719X_CMD_RESET,
-			    cmd->device->id);
+	return wd719x_reset(sdev->host, WD719X_CMD_RESET,
+			    sdev->id);
 }
 
 static int wd719x_bus_reset(struct Scsi_Host *host, int channel)
diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c
index b093619..91b0fd06 100644
--- a/drivers/scsi/xen-scsifront.c
+++ b/drivers/scsi/xen-scsifront.c
@@ -655,10 +655,10 @@ static int scsifront_eh_abort_handler(struct scsi_cmnd *sc)
 	return scsifront_action_handler(sc->device, sc);
 }
 
-static int scsifront_dev_reset_handler(struct scsi_cmnd *sc)
+static int scsifront_dev_reset_handler(struct scsi_device *sdev)
 {
 	pr_debug("%s\n", __func__);
-	return scsifront_action_handler(sc->device, NULL);
+	return scsifront_action_handler(sdev, NULL);
 }
 
 static int scsifront_sdev_configure(struct scsi_device *sdev)
diff --git a/drivers/staging/rts5208/rtsx.c b/drivers/staging/rts5208/rtsx.c
index e719b1e..6df7754 100644
--- a/drivers/staging/rts5208/rtsx.c
+++ b/drivers/staging/rts5208/rtsx.c
@@ -196,9 +196,9 @@ static int command_abort(struct scsi_cmnd *srb)
  * This invokes the transport reset mechanism to reset the state of the
  * device
  */
-static int device_reset(struct scsi_cmnd *srb)
+static int device_reset(struct scsi_device *sdev)
 {
-	struct rtsx_dev *dev = host_to_rtsx(srb->device->host);
+	struct rtsx_dev *dev = host_to_rtsx(sdev->host);
 
 	dev_info(&dev->pci->dev, "%s called\n", __func__);
 
diff --git a/drivers/staging/unisys/visorhba/visorhba_main.c b/drivers/staging/unisys/visorhba/visorhba_main.c
index ba66cd1..ce98a30 100644
--- a/drivers/staging/unisys/visorhba/visorhba_main.c
+++ b/drivers/staging/unisys/visorhba/visorhba_main.c
@@ -385,29 +385,21 @@ static int visorhba_abort_handler(struct scsi_cmnd *scsicmd)
 
 /*
  *	visorhba_device_reset_handler - Send TASK_MGMT_LUN_RESET
- *	@scsicmd: The scsicmd that needs aborted
+ *	@scsidev: The scsidev to be reset
  *
  *	Returns SUCCESS if inserted, failure otherwise
  */
-static int visorhba_device_reset_handler(struct scsi_cmnd *scsicmd)
+static int visorhba_device_reset_handler(struct scsi_device *scsidev)
 {
 	/* issue TASK_MGMT_LUN_RESET */
-	struct scsi_device *scsidev;
 	struct visordisk_info *vdisk;
-	int rtn;
 
-	scsidev = scsicmd->device;
 	vdisk = scsidev->hostdata;
 	if (atomic_read(&vdisk->error_count) < VISORHBA_ERROR_COUNT)
 		atomic_inc(&vdisk->error_count);
 	else
 		atomic_set(&vdisk->ios_threshold, IOS_ERROR_THRESHOLD);
-	rtn = forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev);
-	if (rtn == SUCCESS) {
-		scsicmd->result = DID_RESET << 16;
-		scsicmd->scsi_done(scsicmd);
-	}
-	return rtn;
+	return forward_taskmgmt_command(TASK_MGMT_LUN_RESET, scsidev);
 }
 
 /*
diff --git a/drivers/target/loopback/tcm_loop.c b/drivers/target/loopback/tcm_loop.c
index 1a10270..f2a6a3e 100644
--- a/drivers/target/loopback/tcm_loop.c
+++ b/drivers/target/loopback/tcm_loop.c
@@ -311,7 +311,7 @@ static int tcm_loop_abort_task(struct scsi_cmnd *sc)
  * Called from SCSI EH process context to issue a LUN_RESET TMR
  * to struct scsi_device
  */
-static int tcm_loop_device_reset(struct scsi_cmnd *sc)
+static int tcm_loop_device_reset(struct scsi_device *sdev)
 {
 	struct tcm_loop_hba *tl_hba;
 	struct tcm_loop_tpg *tl_tpg;
@@ -320,10 +320,10 @@ static int tcm_loop_device_reset(struct scsi_cmnd *sc)
 	/*
 	 * Locate the tcm_loop_hba_t pointer
 	 */
-	tl_hba = *(struct tcm_loop_hba **)shost_priv(sc->device->host);
-	tl_tpg = &tl_hba->tl_hba_tpgs[sc->device->id];
+	tl_hba = *(struct tcm_loop_hba **)shost_priv(sdev->host);
+	tl_tpg = &tl_hba->tl_hba_tpgs[sdev->id];
 
-	ret = tcm_loop_issue_tmr(tl_tpg, sc->device->lun,
+	ret = tcm_loop_issue_tmr(tl_tpg, sdev->lun,
 				 0, TMR_LUN_RESET);
 	return (ret == TMR_FUNCTION_COMPLETE) ? SUCCESS : FAILED;
 }
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 04f8fb7..2898112 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -449,9 +449,9 @@ static int command_abort(struct scsi_cmnd *srb)
  * This invokes the transport reset mechanism to reset the state of the
  * device
  */
-static int device_reset(struct scsi_cmnd *srb)
+static int device_reset(struct scsi_device *sdev)
 {
-	struct us_data *us = host_to_us(srb->device->host);
+	struct us_data *us = host_to_us(sdev->host);
 	int result;
 
 	usb_stor_dbg(us, "%s called\n", __func__);
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index cfb1e3b..82a2256 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -737,9 +737,8 @@ static int uas_eh_abort_handler(struct scsi_cmnd *cmnd)
 	return FAILED;
 }
 
-static int uas_eh_device_reset_handler(struct scsi_cmnd *cmnd)
+static int uas_eh_device_reset_handler(struct scsi_device *sdev)
 {
-	struct scsi_device *sdev = cmnd->device;
 	struct uas_dev_info *devinfo = sdev->hostdata;
 	struct usb_device *udev = devinfo->udev;
 	unsigned long flags;
diff --git a/include/scsi/libfc.h b/include/scsi/libfc.h
index fe4789d..bb68735 100644
--- a/include/scsi/libfc.h
+++ b/include/scsi/libfc.h
@@ -952,7 +952,7 @@ static inline struct fc_lport *fc_disc_lport(struct fc_disc *disc)
  *****************************/
 int fc_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
 int fc_eh_abort(struct scsi_cmnd *);
-int fc_eh_device_reset(struct scsi_cmnd *);
+int fc_eh_device_reset(struct scsi_device *);
 int fc_eh_host_reset(struct Scsi_Host *);
 int fc_slave_alloc(struct scsi_device *);
 
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index a8fff96..34d6d90 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -383,7 +383,7 @@ struct iscsi_host {
 extern int iscsi_eh_abort(struct scsi_cmnd *sc);
 extern int iscsi_eh_recover_target(struct scsi_target *starget);
 extern int iscsi_eh_session_reset(struct iscsi_cls_session *cls_session);
-extern int iscsi_eh_device_reset(struct scsi_cmnd *sc);
+extern int iscsi_eh_device_reset(struct scsi_device *sdev);
 extern int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc);
 extern enum blk_eh_timer_return iscsi_eh_cmd_timed_out(struct scsi_cmnd *sc);
 
diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
index 5953bcb..3d0242f 100644
--- a/include/scsi/libsas.h
+++ b/include/scsi/libsas.h
@@ -713,7 +713,7 @@ extern int sas_bios_param(struct scsi_device *,
 
 void sas_task_abort(struct sas_task *);
 int sas_eh_abort_handler(struct scsi_cmnd *cmd);
-int sas_eh_device_reset_handler(struct scsi_cmnd *cmd);
+int sas_eh_device_reset_handler(struct scsi_device *sdev);
 int sas_eh_target_reset_handler(struct scsi_target *starget);
 
 extern void sas_target_destroy(struct scsi_target *);
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 33bc523..7095076 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -145,7 +145,7 @@ struct scsi_host_template {
 	 * Status: REQUIRED	(at least one of them)
 	 */
 	int (* eh_abort_handler)(struct scsi_cmnd *);
-	int (* eh_device_reset_handler)(struct scsi_cmnd *);
+	int (* eh_device_reset_handler)(struct scsi_device *);
 	int (* eh_target_reset_handler)(struct scsi_target *);
 	int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
 	int (* eh_host_reset_handler)(struct Scsi_Host *);
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* [PATCH 47/47] scsi: Do not allocate scsi command in scsi_ioctl_reset()
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (45 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 46/47] scsi: Move eh_device_reset_handler() to use scsi_device as argument Hannes Reinecke
@ 2017-06-28  8:33 ` Hannes Reinecke
  2017-06-28 14:06 ` [PATCH 00/47] SCSI EH argument reshuffle part II Christoph Hellwig
  2018-01-08 11:26 ` Christoph Hellwig
  48 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28  8:33 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Hannes Reinecke

As we now have moved the error handler functions to not rely on
a scsi command we can drop the out-of-band scsi command allocation
from scsi_ioctl_reset().

Signed-off-by: Hannes Reinecke <hare@suse.com>
---
 drivers/scsi/scsi_error.c | 124 +++++++++++++++++++---------------------------
 1 file changed, 50 insertions(+), 74 deletions(-)

diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 4a7fe97f..ab178e8 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -728,16 +728,22 @@ static void scsi_eh_done(struct scsi_cmnd *scmd)
 		complete(eh_action);
 }
 
+static void __scsi_report_device_reset(struct scsi_device *sdev)
+{
+	sdev->was_reset = 1;
+	sdev->expecting_cc_ua = 1;
+}
+
 /**
  * scsi_try_host_reset - ask host adapter to reset itself
- * @scmd:	SCSI cmd to send host reset.
+ * @host:	SCSI host to be reset.
  */
-static int scsi_try_host_reset(struct scsi_cmnd *scmd)
+static int scsi_try_host_reset(struct Scsi_Host *host)
 {
 	unsigned long flags;
 	int rtn;
-	struct Scsi_Host *host = scmd->device->host;
 	struct scsi_host_template *hostt = host->hostt;
+	struct scsi_device *sdev;
 
 	SCSI_LOG_ERROR_RECOVERY(3,
 		shost_printk(KERN_INFO, host, "Snd Host RST\n"));
@@ -751,7 +757,8 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
 		if (!hostt->skip_settle_delay)
 			ssleep(HOST_RESET_SETTLE_TIME);
 		spin_lock_irqsave(host->host_lock, flags);
-		scsi_report_bus_reset(host, scmd_channel(scmd));
+		__shost_for_each_device(sdev, host)
+			__scsi_report_device_reset(sdev);
 		spin_unlock_irqrestore(host->host_lock, flags);
 	}
 
@@ -760,43 +767,38 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
 
 /**
  * scsi_try_bus_reset - ask host to perform a bus reset
- * @scmd:	SCSI cmd to send bus reset.
+ * @host:	SCSI host to send bus reset.
+ * @channel:	bus number to be reset.
  */
-static int scsi_try_bus_reset(struct scsi_cmnd *scmd)
+static int scsi_try_bus_reset(struct Scsi_Host *host, int channel)
 {
 	unsigned long flags;
 	int rtn;
-	struct Scsi_Host *host = scmd->device->host;
 	struct scsi_host_template *hostt = host->hostt;
 
-	SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
+	SCSI_LOG_ERROR_RECOVERY(3, shost_printk(KERN_INFO, host,
 		"%s: Snd Bus RST\n", __func__));
 
 	if (!hostt->eh_bus_reset_handler)
 		return FAILED;
 
-	rtn = hostt->eh_bus_reset_handler(host, scmd_channel(scmd));
+	rtn = hostt->eh_bus_reset_handler(host, channel);
 
 	if (rtn == SUCCESS) {
 		if (!hostt->skip_settle_delay)
 			ssleep(BUS_RESET_SETTLE_TIME);
 		spin_lock_irqsave(host->host_lock, flags);
-		scsi_report_bus_reset(host, scmd_channel(scmd));
+		scsi_report_bus_reset(host, channel);
 		spin_unlock_irqrestore(host->host_lock, flags);
 	}
 
 	return rtn;
 }
 
-static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
-{
-	sdev->was_reset = 1;
-	sdev->expecting_cc_ua = 1;
-}
-
 /**
  * scsi_try_target_reset - Ask host to perform a target reset
- * @scmd:	SCSI cmd used to send a target reset
+ * @shost:	SCSI Host
+ * @starget:	SCSI target to be reset
  *
  * Notes:
  *    There is no timeout for this operation.  if this operation is
@@ -804,13 +806,13 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
  *    timer on it, and set the host back to a consistent state prior to
  *    returning.
  */
-static int scsi_try_target_reset(struct scsi_cmnd *scmd)
+static int scsi_try_target_reset(struct Scsi_Host *host,
+				 struct scsi_target *starget)
 {
 	unsigned long flags;
 	int rtn;
-	struct Scsi_Host *host = scmd->device->host;
+	struct scsi_device *sdev;
 	struct scsi_host_template *hostt = host->hostt;
-	struct scsi_target *starget = scsi_target(scmd->device);
 
 	if (!hostt->eh_target_reset_handler)
 		return FAILED;
@@ -818,8 +820,11 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd)
 	rtn = hostt->eh_target_reset_handler(starget);
 	if (rtn == SUCCESS) {
 		spin_lock_irqsave(host->host_lock, flags);
-		__starget_for_each_device(starget, NULL,
-					  __scsi_report_device_reset);
+		__shost_for_each_device(sdev, host) {
+			if ((sdev->channel == starget->channel) &&
+			    (sdev->id == starget->id))
+				__scsi_report_device_reset(sdev);
+		}
 		spin_unlock_irqrestore(host->host_lock, flags);
 	}
 
@@ -836,17 +841,17 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd)
  *    timer on it, and set the host back to a consistent state prior to
  *    returning.
  */
-static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
+static int scsi_try_bus_device_reset(struct scsi_device *sdev)
 {
 	int rtn;
-	struct scsi_host_template *hostt = scmd->device->host->hostt;
+	struct scsi_host_template *hostt = sdev->host->hostt;
 
 	if (!hostt->eh_device_reset_handler)
 		return FAILED;
 
-	rtn = hostt->eh_device_reset_handler(scmd->device);
+	rtn = hostt->eh_device_reset_handler(sdev);
 	if (rtn == SUCCESS)
-		__scsi_report_device_reset(scmd->device, NULL);
+		__scsi_report_device_reset(sdev);
 	return rtn;
 }
 
@@ -878,11 +883,15 @@ static int scsi_try_to_abort_cmd(struct scsi_host_template *hostt,
 
 static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
 {
-	if (scsi_try_to_abort_cmd(scmd->device->host->hostt, scmd) != SUCCESS)
-		if (scsi_try_bus_device_reset(scmd) != SUCCESS)
-			if (scsi_try_target_reset(scmd) != SUCCESS)
-				if (scsi_try_bus_reset(scmd) != SUCCESS)
-					scsi_try_host_reset(scmd);
+	struct Scsi_Host *host = scmd->device->host;
+	struct scsi_target *starget = scsi_target(scmd->device);
+	int channel = scmd->device->channel;
+
+	if (scsi_try_to_abort_cmd(host->hostt, scmd) != SUCCESS)
+		if (scsi_try_bus_device_reset(scmd->device) != SUCCESS)
+			if (scsi_try_target_reset(host, starget) != SUCCESS)
+				if (scsi_try_bus_reset(host, channel) != SUCCESS)
+					scsi_try_host_reset(host);
 }
 
 /**
@@ -1430,7 +1439,7 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
 		SCSI_LOG_ERROR_RECOVERY(3,
 			sdev_printk(KERN_INFO, sdev,
 				     "%s: Sending BDR\n", current->comm));
-		rtn = scsi_try_bus_device_reset(bdr_scmd);
+		rtn = scsi_try_bus_device_reset(sdev);
 		if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
 			if (!scsi_device_online(sdev) ||
 			    rtn == FAST_IO_FAIL ||
@@ -1495,7 +1504,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
 			shost_printk(KERN_INFO, shost,
 				     "%s: Sending target reset to target %d\n",
 				     current->comm, id));
-		rtn = scsi_try_target_reset(scmd);
+		rtn = scsi_try_target_reset(shost, scsi_target(scmd->device));
 		if (rtn != SUCCESS && rtn != FAST_IO_FAIL)
 			SCSI_LOG_ERROR_RECOVERY(3,
 				shost_printk(KERN_INFO, shost,
@@ -1570,7 +1579,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
 			shost_printk(KERN_INFO, shost,
 				     "%s: Sending BRST chan: %d\n",
 				     current->comm, channel));
-		rtn = scsi_try_bus_reset(chan_scmd);
+		rtn = scsi_try_bus_reset(shost, channel);
 		if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
 			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
 				if (channel == scmd_channel(scmd)) {
@@ -1608,15 +1617,12 @@ static int scsi_eh_host_reset(struct Scsi_Host *shost,
 	int rtn;
 
 	if (!list_empty(work_q)) {
-		scmd = list_entry(work_q->next,
-				  struct scsi_cmnd, eh_entry);
-
 		SCSI_LOG_ERROR_RECOVERY(3,
 			shost_printk(KERN_INFO, shost,
 				     "%s: Sending HRST\n",
 				     current->comm));
 
-		rtn = scsi_try_host_reset(scmd);
+		rtn = scsi_try_host_reset(shost);
 		if (rtn == SUCCESS) {
 			list_splice_init(work_q, &check_list);
 		} else if (rtn == FAST_IO_FAIL) {
@@ -2221,7 +2227,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, int channel)
 
 	__shost_for_each_device(sdev, shost) {
 		if (channel == sdev_channel(sdev))
-			__scsi_report_device_reset(sdev, NULL);
+			__scsi_report_device_reset(sdev);
 	}
 }
 EXPORT_SYMBOL(scsi_report_bus_reset);
@@ -2255,16 +2261,11 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
 	__shost_for_each_device(sdev, shost) {
 		if (channel == sdev_channel(sdev) &&
 		    target == sdev_id(sdev))
-			__scsi_report_device_reset(sdev, NULL);
+			__scsi_report_device_reset(sdev);
 	}
 }
 EXPORT_SYMBOL(scsi_report_device_reset);
 
-static void
-scsi_reset_provider_done_command(struct scsi_cmnd *scmd)
-{
-}
-
 /**
  * scsi_ioctl_reset: explicitly reset a host/bus/target/device
  * @dev:	scsi_device to operate on
@@ -2273,9 +2274,7 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
 int
 scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
 {
-	struct scsi_cmnd *scmd;
 	struct Scsi_Host *shost = dev->host;
-	struct request *rq;
 	unsigned long flags;
 	int error = 0, rtn, val;
 
@@ -2290,24 +2289,6 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
 		return -EIO;
 
 	error = -EIO;
-	rq = kzalloc(sizeof(struct request) + sizeof(struct scsi_cmnd) +
-			shost->hostt->cmd_size, GFP_KERNEL);
-	if (!rq)
-		goto out_put_autopm_host;
-	blk_rq_init(NULL, rq);
-
-	scmd = (struct scsi_cmnd *)(rq + 1);
-	scsi_init_command(dev, scmd);
-	scmd->request = rq;
-	scmd->cmnd = scsi_req(rq)->cmd;
-
-	scmd->scsi_done		= scsi_reset_provider_done_command;
-	memset(&scmd->sdb, 0, sizeof(scmd->sdb));
-
-	scmd->cmd_len			= 0;
-
-	scmd->sc_data_direction		= DMA_BIDIRECTIONAL;
-
 	spin_lock_irqsave(shost->host_lock, flags);
 	shost->tmf_in_progress = 1;
 	spin_unlock_irqrestore(shost->host_lock, flags);
@@ -2317,22 +2298,22 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
 		rtn = SUCCESS;
 		break;
 	case SG_SCSI_RESET_DEVICE:
-		rtn = scsi_try_bus_device_reset(scmd);
+		rtn = scsi_try_bus_device_reset(dev);
 		if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
 			break;
 		/* FALLTHROUGH */
 	case SG_SCSI_RESET_TARGET:
-		rtn = scsi_try_target_reset(scmd);
+		rtn = scsi_try_target_reset(shost, scsi_target(dev));
 		if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
 			break;
 		/* FALLTHROUGH */
 	case SG_SCSI_RESET_BUS:
-		rtn = scsi_try_bus_reset(scmd);
+		rtn = scsi_try_bus_reset(shost, dev->channel);
 		if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
 			break;
 		/* FALLTHROUGH */
 	case SG_SCSI_RESET_HOST:
-		rtn = scsi_try_host_reset(scmd);
+		rtn = scsi_try_host_reset(shost);
 		if (rtn == SUCCESS)
 			break;
 	default:
@@ -2357,11 +2338,6 @@ void scsi_report_device_reset(struct Scsi_Host *shost, int channel, int target)
 
 	wake_up(&shost->host_wait);
 	scsi_run_host_queues(shost);
-
-	scsi_put_command(scmd);
-	kfree(rq);
-
-out_put_autopm_host:
 	scsi_autopm_put_host(shost);
 	return error;
 }
-- 
1.8.5.6

^ permalink raw reply related	[flat|nested] 89+ messages in thread

* Re: [PATCH 01/47] aacraid: split off functions to generate reset FIB
  2017-06-28  8:32 ` [PATCH 01/47] aacraid: split off functions to generate reset FIB Hannes Reinecke
@ 2017-06-28  9:07   ` Johannes Thumshirn
  2017-06-29 19:59   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:07 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 02/47] aacraid: split off host reset
  2017-06-28  8:32 ` [PATCH 02/47] aacraid: split off host reset Hannes Reinecke
@ 2017-06-28  9:10   ` Johannes Thumshirn
  2017-06-29 20:00   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:10 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke

On Wed, Jun 28, 2017 at 10:32:28AM +0200, Hannes Reinecke wrote:
> +	struct scsi_device * dev = cmd->device;
> +	struct Scsi_Host * host = dev->host;
> +	struct aac_dev * aac = (struct aac_dev *)host->hostdata;

Minor nit, if you happen to re-send, please remove the space between the
asterisk and the variable names.

Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>

-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 03/47] aacraid: split off device, target, and bus reset
  2017-06-28  8:32 ` [PATCH 03/47] aacraid: split off device, target, and bus reset Hannes Reinecke
@ 2017-06-28  9:14   ` Johannes Thumshirn
  2017-06-29 20:01   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:14 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send()
  2017-06-28  8:32 ` [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
@ 2017-06-28  9:17   ` Johannes Thumshirn
  2017-06-29 20:07   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:17 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 06/47] aacraid: add fib flag to mark scsi command callback
  2017-06-28  8:32 ` [PATCH 06/47] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
@ 2017-06-28  9:18   ` Johannes Thumshirn
  2017-06-29 20:07   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:18 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 07/47] aacraid: complete all commands during bus reset
  2017-06-28  8:32 ` [PATCH 07/47] aacraid: complete all commands during bus reset Hannes Reinecke
@ 2017-06-28  9:19   ` Johannes Thumshirn
  2017-06-29 20:07   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:19 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset
  2017-06-28  8:32 ` [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset Hannes Reinecke
@ 2017-06-28  9:19   ` Johannes Thumshirn
  2017-06-28  9:25   ` Johannes Thumshirn
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:19 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset
  2017-06-28  8:32 ` [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset Hannes Reinecke
  2017-06-28  9:19   ` Johannes Thumshirn
@ 2017-06-28  9:25   ` Johannes Thumshirn
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:25 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 10/47] ips: Do not try to abort command from host reset
  2017-06-28  8:32 ` [PATCH 10/47] ips: Do not try to abort command from " Hannes Reinecke
@ 2017-06-28  9:31   ` Johannes Thumshirn
  0 siblings, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:31 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 11/47] snic: reserve tag for TMF
  2017-06-28  8:32 ` [PATCH 11/47] snic: reserve tag for TMF Hannes Reinecke
@ 2017-06-28  9:37   ` Johannes Thumshirn
  0 siblings, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:37 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 12/47] qla1280: separate out host reset function from qla1280_error_action()
  2017-06-28  8:32 ` [PATCH 12/47] qla1280: separate out host reset function from qla1280_error_action() Hannes Reinecke
@ 2017-06-28  9:39   ` Johannes Thumshirn
  0 siblings, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:39 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-28  8:32 ` [PATCH 13/47] megaraid: pass in NULL scb for host reset Hannes Reinecke
@ 2017-06-28  9:39   ` Johannes Thumshirn
  2017-06-28 13:41   ` Sumit Saxena
  1 sibling, 0 replies; 89+ messages in thread
From: Johannes Thumshirn @ 2017-06-28  9:39 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke


Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
-- 
Johannes Thumshirn                                          Storage
jthumshirn@suse.de                                +49 911 74053 689
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Felix Imendörffer, Jane Smithard, Graham Norton
HRB 21284 (AG Nürnberg)
Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-28  8:32 ` [PATCH 13/47] megaraid: pass in NULL scb for host reset Hannes Reinecke
  2017-06-28  9:39   ` Johannes Thumshirn
@ 2017-06-28 13:41   ` Sumit Saxena
  2017-06-28 15:30     ` Hannes Reinecke
  1 sibling, 1 reply; 89+ messages in thread
From: Sumit Saxena @ 2017-06-28 13:41 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

>-----Original Message-----
>From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
>owner@vger.kernel.org] On Behalf Of Hannes Reinecke
>Sent: Wednesday, June 28, 2017 2:03 PM
>To: Christoph Hellwig
>Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
Hannes
>Reinecke; Hannes Reinecke
>Subject: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>
>When calling a host reset we shouldn't rely on the command triggering the
>reset, so allow megaraid_abort_and_reset() to be called with a NULL scb.
>And drop the pointless 'bus_reset' and 'target_reset' handlers, which
just call
>the same function as host_reset.

If this patch address any functional issue, then we should consider this.
If it's code optimization, can we ignore this as this is being very old
driver
and no more maintained by Broadcom/LSI ?

>
>Signed-off-by: Hannes Reinecke <hare@suse.com>
>---
> drivers/scsi/megaraid.c | 42 ++++++++++++++++--------------------------
> 1 file changed, 16 insertions(+), 26 deletions(-)
>
>diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index
>3c63c29..7e504d3 100644
>--- a/drivers/scsi/megaraid.c
>+++ b/drivers/scsi/megaraid.c
>@@ -1909,7 +1909,7 @@ static DEF_SCSI_QCMD(megaraid_queue)
>
> 	spin_lock_irq(&adapter->lock);
>
>-	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
>+	rval =  megaraid_abort_and_reset(adapter, NULL, SCB_RESET);

If cmd=NULL is passed, it will crash inside function
megaraid_abort_and_reset() while dereferencing "cmd" pointer.
Below is the code of function  megaraid_abort_and_reset() where it will
crash-

static int
megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
{
	struct list_head	*pos, *next;
	scb_t			*scb;

	dev_warn(&adapter->dev->dev, "%s cmd=%x <c=%d t=%d l=%d>\n",
	     (aor == SCB_ABORT)? "ABORTING":"RESET",
	     cmd->cmnd[0],
cmd->device->channel,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>it should crash
here
	     cmd->device->id, (u32)cmd->device->lun);

Please correct if I am missing something here.
>
> 	/*
> 	 * This is required here to complete any completed requests @@ -
>1948,7 +1948,7 @@ static DEF_SCSI_QCMD(megaraid_queue)
>
> 		scb = list_entry(pos, scb_t, list);
>
>-		if (scb->cmd == cmd) { /* Found command */
>+		if (!cmd || scb->cmd == cmd) { /* Found command */
>
> 			scb->state |= aor;
>
>@@ -1967,31 +1967,23 @@ static DEF_SCSI_QCMD(megaraid_queue)
>
> 				return FAILED;
> 			}
>-			else {
>-
>-				/*
>-				 * Not yet issued! Remove from the pending
>-				 * list
>-				 */
>-				dev_warn(&adapter->dev->dev,
>-					"%s-[%x], driver owner\n",
>-					(aor==SCB_ABORT) ?
>"ABORTING":"RESET",
>-					scb->idx);
>-
>-				mega_free_scb(adapter, scb);
>-
>-				if( aor == SCB_ABORT ) {
>-					cmd->result = (DID_ABORT << 16);
>-				}
>-				else {
>-					cmd->result = (DID_RESET << 16);
>-				}
>+			/*
>+			 * Not yet issued! Remove from the pending
>+			 * list
>+			 */
>+			dev_warn(&adapter->dev->dev,
>+				 "%s-[%x], driver owner\n",
>+				 (cmd) ? "ABORTING":"RESET",
>+				 scb->idx);
>+			mega_free_scb(adapter, scb);
>
>+			if (cmd) {
>+				cmd->result = (DID_ABORT << 16);
> 				list_add_tail(SCSI_LIST(cmd),
>-						&adapter->completed_list);
>-
>-				return SUCCESS;
>+					      &adapter->completed_list);
> 			}
>+
>+			return SUCCESS;
> 		}
> 	}
>
>@@ -4180,8 +4172,6 @@ static inline void mega_create_proc_entry(int
index,
>struct proc_dir_entry *pare
> 	.cmd_per_lun			= DEF_CMD_PER_LUN,
> 	.use_clustering			= ENABLE_CLUSTERING,
> 	.eh_abort_handler		= megaraid_abort,
>-	.eh_device_reset_handler	= megaraid_reset,
>-	.eh_bus_reset_handler		= megaraid_reset,
> 	.eh_host_reset_handler		= megaraid_reset,
> 	.no_write_same			= 1,
> };
>--
>1.8.5.6

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 00/47] SCSI EH argument reshuffle part II
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (46 preceding siblings ...)
  2017-06-28  8:33 ` [PATCH 47/47] scsi: Do not allocate scsi command in scsi_ioctl_reset() Hannes Reinecke
@ 2017-06-28 14:06 ` Christoph Hellwig
  2018-01-08 11:26 ` Christoph Hellwig
  48 siblings, 0 replies; 89+ messages in thread
From: Christoph Hellwig @ 2017-06-28 14:06 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley, linux-scsi

On Wed, Jun 28, 2017 at 10:32:26AM +0200, Hannes Reinecke wrote:
> Hi all,
> finally here's the patchset to revamp the SCSI EH callback arguments
> which I promised to do (some years ago ...).

Still looks like a way to big series to review.  Once we got the
first part 1 it might make sense to start resending just the various
prep patches..

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-28 13:41   ` Sumit Saxena
@ 2017-06-28 15:30     ` Hannes Reinecke
  2017-06-28 17:40       ` Kashyap Desai
  0 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-28 15:30 UTC (permalink / raw)
  To: Sumit Saxena, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

On 06/28/2017 03:41 PM, Sumit Saxena wrote:
>> -----Original Message-----
>> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
>> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
>> Sent: Wednesday, June 28, 2017 2:03 PM
>> To: Christoph Hellwig
>> Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
> Hannes
>> Reinecke; Hannes Reinecke
>> Subject: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>>
>> When calling a host reset we shouldn't rely on the command triggering the
>> reset, so allow megaraid_abort_and_reset() to be called with a NULL scb.
>> And drop the pointless 'bus_reset' and 'target_reset' handlers, which
> just call
>> the same function as host_reset.
> 
> If this patch address any functional issue, then we should consider this.
> If it's code optimization, can we ignore this as this is being very old
> driver
> and no more maintained by Broadcom/LSI ?
>
Sadly, ignoring is not an option.
I'm planning to update the calling convention for SCSI EH, to resolve
the long-standing problem with sg_reset ioctls.
sg_reset ioctl will allocate an out-of-band SCSI command, which does no
longer work with the new command allocation scheme in multiqueue.
So it's not possible to just 'ignore' it, as then SCSI EH will cease to
function with that driver.

Sorry.

>>
>> Signed-off-by: Hannes Reinecke <hare@suse.com>
>> ---
>> drivers/scsi/megaraid.c | 42 ++++++++++++++++--------------------------
>> 1 file changed, 16 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index
>> 3c63c29..7e504d3 100644
>> --- a/drivers/scsi/megaraid.c
>> +++ b/drivers/scsi/megaraid.c
>> @@ -1909,7 +1909,7 @@ static DEF_SCSI_QCMD(megaraid_queue)
>>
>> 	spin_lock_irq(&adapter->lock);
>>
>> -	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
>> +	rval =  megaraid_abort_and_reset(adapter, NULL, SCB_RESET);
> 
> If cmd=NULL is passed, it will crash inside function
> megaraid_abort_and_reset() while dereferencing "cmd" pointer.
> Below is the code of function  megaraid_abort_and_reset() where it will
> crash-
> 
> static int
> megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
> {
> 	struct list_head	*pos, *next;
> 	scb_t			*scb;
> 
> 	dev_warn(&adapter->dev->dev, "%s cmd=%x <c=%d t=%d l=%d>\n",
> 	     (aor == SCB_ABORT)? "ABORTING":"RESET",
> 	     cmd->cmnd[0],
> cmd->device->channel,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>it should crash
> here
> 	     cmd->device->id, (u32)cmd->device->lun);
> 
> Please correct if I am missing something here.Ah, correct. Will be fixing it up.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 33/47] cxlflash: use dedicated reset command in send_tmf()
  2017-06-28  8:32 ` [PATCH 33/47] cxlflash: use dedicated reset command in send_tmf() Hannes Reinecke
@ 2017-06-28 16:29   ` Matthew R. Ochs
  0 siblings, 0 replies; 89+ messages in thread
From: Matthew R. Ochs @ 2017-06-28 16:29 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley,
	linux-scsi, Hannes Reinecke

Hi Hannes,

We actually just reworked these paths in a series that
was pulled in on Monday. While testing, I came across a
bug in that series and was planning on sending out a fix
for it. I'll include some patches that will ease the burden
of incorporating your EH updates for cxlflash.

Many thanks for leading this effort, it really helps to clean
up the SCSI EH paths! =)


-matt

> On Jun 28, 2017, at 3:32 AM, Hannes Reinecke <hare@suse.de> wrote:
> 
> From: Hannes Reinecke <hare@suse.com>
> 
> Reduce the queue depth by 1, and use this command as a dedicated
> reset command send_tmf().
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
> drivers/scsi/cxlflash/common.h |  3 ++-
> drivers/scsi/cxlflash/main.c   | 23 ++++++++++++++++-------
> 2 files changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h
> index 6d95e8e..b2b3bdc 100644
> --- a/drivers/scsi/cxlflash/common.h
> +++ b/drivers/scsi/cxlflash/common.h
> @@ -54,7 +54,8 @@
> 
> /* Command management definitions */
> #define CXLFLASH_MAX_CMDS               256
> -#define CXLFLASH_MAX_CMDS_PER_LUN       CXLFLASH_MAX_CMDS
> +#define CXLFLASH_MAX_CMDS_PER_LUN       CXLFLASH_MAX_CMDS - 1
> +#define CXLFLASH_RESET_CMD              255
> 
> /* RRQ for master issued cmds */
> #define NUM_RRQ_ENTRY                   CXLFLASH_MAX_CMDS
> diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
> index 462e8fc..b33e3e7 100644
> --- a/drivers/scsi/cxlflash/main.c
> +++ b/drivers/scsi/cxlflash/main.c
> @@ -23,6 +23,7 @@
> 
> #include <scsi/scsi_cmnd.h>
> #include <scsi/scsi_host.h>
> +#include <scsi/scsi_tcq.h>
> #include <uapi/scsi/cxlflash_ioctl.h>
> 
> #include "main.h"
> @@ -460,15 +461,16 @@ static u32 cmd_to_target_hwq(struct Scsi_Host *host, struct scsi_cmnd *scp,
> /**
>  * send_tmf() - sends a Task Management Function (TMF)
>  * @afu:	AFU to checkout from.
> - * @scp:	SCSI command from stack describing target.
> + * @sdev:	SCSI device to reset.
>  * @tmfcmd:	TMF command to send.
>  *
>  * Return:
>  *	0 on success, SCSI_MLQUEUE_HOST_BUSY or -errno on failure
>  */
> -static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
> +static int send_tmf(struct afu *afu, struct scsi_device *sdev, u64 tmfcmd)
> {
> -	struct Scsi_Host *host = scp->device->host;
> +	struct scsi_cmnd *scp;
> +	struct Scsi_Host *host = sdev->host;
> 	struct cxlflash_cfg *cfg = shost_priv(host);
> 	struct afu_cmd *cmd = NULL;
> 	struct device *dev = &cfg->dev->dev;
> @@ -498,14 +500,21 @@ static int send_tmf(struct afu *afu, struct scsi_cmnd *scp, u64 tmfcmd)
> 	cfg->tmf_active = true;
> 	spin_unlock_irqrestore(&cfg->tmf_slock, lock_flags);
> 
> +	scp = scsi_host_find_tag(host, CXLFLASH_RESET_CMD);
> +	scp->device = sdev;
> +	cmd = sc_to_afucz(scp);
> +	hwq_index = cmd_to_target_hwq(host, scp, afu);
> +	hwq = get_hwq(afu, hwq_index);
> +
> +	cmd->scp = scp;
> 	cmd->parent = afu;
> 	cmd->cmd_tmf = true;
> 	cmd->hwq_index = hwq_index;
> 
> 	cmd->rcb.ctx_id = hwq->ctx_hndl;
> 	cmd->rcb.msi = SISL_MSI_RRQ_UPDATED;
> -	cmd->rcb.port_sel = CHAN2PORTMASK(scp->device->channel);
> -	cmd->rcb.lun_id = lun_to_lunid(scp->device->lun);
> +	cmd->rcb.port_sel = CHAN2PORTMASK(sdev->channel);
> +	cmd->rcb.lun_id = lun_to_lunid(sdev->lun);
> 	cmd->rcb.req_flags = (SISL_REQ_FLAGS_PORT_LUN_ID |
> 			      SISL_REQ_FLAGS_SUP_UNDERRUN |
> 			      SISL_REQ_FLAGS_TMF_CMD);
> @@ -2448,7 +2457,7 @@ static int cxlflash_eh_device_reset_handler(struct scsi_cmnd *scp)
> retry:
> 	switch (cfg->state) {
> 	case STATE_NORMAL:
> -		rcr = send_tmf(afu, scp, TMF_LUN_RESET);
> +		rcr = send_tmf(afu, sdev, TMF_LUN_RESET);
> 		if (unlikely(rcr))
> 			rc = FAILED;
> 		break;
> @@ -3139,7 +3148,7 @@ static ssize_t mode_show(struct device *dev,
> 	.eh_host_reset_handler = cxlflash_eh_host_reset_handler,
> 	.change_queue_depth = cxlflash_change_queue_depth,
> 	.cmd_per_lun = CXLFLASH_MAX_CMDS_PER_LUN,
> -	.can_queue = CXLFLASH_MAX_CMDS,
> +	.can_queue = CXLFLASH_MAX_CMDS - 1,
> 	.cmd_size = sizeof(struct afu_cmd) + __alignof__(struct afu_cmd) - 1,
> 	.this_id = -1,
> 	.sg_tablesize = 1,	/* No scatter gather support */
> -- 
> 1.8.5.6
> 

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-28 15:30     ` Hannes Reinecke
@ 2017-06-28 17:40       ` Kashyap Desai
       [not found]         ` <CAHtARFFTFMaUsVZ_KuYGr3hFcTuD5sf=h2+1RM6aj8yfpwsCWQ@mail.gmail.com>
  2017-06-29  5:53         ` Hannes Reinecke
  0 siblings, 2 replies; 89+ messages in thread
From: Kashyap Desai @ 2017-06-28 17:40 UTC (permalink / raw)
  To: Hannes Reinecke, Sumit Saxena, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 9:00 PM
> To: Sumit Saxena; Christoph Hellwig
> Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
> Hannes
> Reinecke
> Subject: Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>
> On 06/28/2017 03:41 PM, Sumit Saxena wrote:
> >> -----Original Message-----
> >> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> >> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> >> Sent: Wednesday, June 28, 2017 2:03 PM
> >> To: Christoph Hellwig
> >> Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
> > Hannes
> >> Reinecke; Hannes Reinecke
> >> Subject: [PATCH 13/47] megaraid: pass in NULL scb for host reset
> >>
> >> When calling a host reset we shouldn't rely on the command triggering
> >> the reset, so allow megaraid_abort_and_reset() to be called with a NULL
> scb.
> >> And drop the pointless 'bus_reset' and 'target_reset' handlers, which
> > just call
> >> the same function as host_reset.
> >
> > If this patch address any functional issue, then we should consider
> > this.
> > If it's code optimization, can we ignore this as this is being very
> > old driver and no more maintained by Broadcom/LSI ?
> >
> Sadly, ignoring is not an option.
> I'm planning to update the calling convention for SCSI EH, to resolve the
> long-
> standing problem with sg_reset ioctls.
> sg_reset ioctl will allocate an out-of-band SCSI command, which does no
> longer
> work with the new command allocation scheme in multiqueue.
> So it's not possible to just 'ignore' it, as then SCSI EH will cease to
> function with
> that driver.

Hannes - We are in process of sending megaraid and 3ware driver removal as
LSI/Broadcom  stopped supporting those products.
I agree we should review this closely, but lack of test coverage and end of
life cycle of product is requesting us to know the rational.
For now, let's consider NACK for this patch. We will be removing old
megaraid (mbox) driver and 3Ware drivers soon.

>
> Sorry.
>
> >>
> >> Signed-off-by: Hannes Reinecke <hare@suse.com>
> >> ---
> >> drivers/scsi/megaraid.c | 42
> >> ++++++++++++++++--------------------------
> >> 1 file changed, 16 insertions(+), 26 deletions(-)
> >>
> >> diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index
> >> 3c63c29..7e504d3 100644
> >> --- a/drivers/scsi/megaraid.c
> >> +++ b/drivers/scsi/megaraid.c
> >> @@ -1909,7 +1909,7 @@ static DEF_SCSI_QCMD(megaraid_queue)
> >>
> >> 	spin_lock_irq(&adapter->lock);
> >>
> >> -	rval =  megaraid_abort_and_reset(adapter, cmd, SCB_RESET);
> >> +	rval =  megaraid_abort_and_reset(adapter, NULL, SCB_RESET);
> >
> > If cmd=NULL is passed, it will crash inside function
> > megaraid_abort_and_reset() while dereferencing "cmd" pointer.
> > Below is the code of function  megaraid_abort_and_reset() where it
> > will
> > crash-
> >
> > static int
> > megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor)
> > {
> > 	struct list_head	*pos, *next;
> > 	scb_t			*scb;
> >
> > 	dev_warn(&adapter->dev->dev, "%s cmd=%x <c=%d t=%d l=%d>\n",
> > 	     (aor == SCB_ABORT)? "ABORTING":"RESET",
> > 	     cmd->cmnd[0],
> > cmd->device->channel,>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>it should
> > cmd->device->crash
> > here
> > 	     cmd->device->id, (u32)cmd->device->lun);
> >
> > Please correct if I am missing something here.Ah, correct. Will be
> > fixing it up.
>
> Cheers,
>
> Hannes
> --
> Dr. Hannes Reinecke		   Teamlead Storage & Networking
> hare@suse.de			               +49 911 74053 688
> SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
> GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284
> (AG
> Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
       [not found]         ` <CAHtARFFTFMaUsVZ_KuYGr3hFcTuD5sf=h2+1RM6aj8yfpwsCWQ@mail.gmail.com>
@ 2017-06-28 18:40           ` Christoph Hellwig
  0 siblings, 0 replies; 89+ messages in thread
From: Christoph Hellwig @ 2017-06-28 18:40 UTC (permalink / raw)
  To: adam radford
  Cc: Kashyap Desai, Hannes Reinecke, Sumit Saxena, Christoph Hellwig,
	Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

On Wed, Jun 28, 2017 at 11:38:22AM -0700, adam radford wrote:
> LSI/Broadcom isn't the maintainer of the 3ware drivers.  See 'MAINTAINERS'.
>   Your attempts
> to remove them may get a NACK from the Maintainer since I believe there are
> still users of these controllers.

Same for the legacy megaraid driver, but we can just mark that as
orphan for now.

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib
  2017-06-28  8:32 ` [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
@ 2017-06-28 19:42   ` Dave Carroll
  2017-06-29 20:06   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Dave Carroll @ 2017-06-28 19:42 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	dl-esc-Aacraid Linux Driver

> 
> 
> When sending a reset fib we shouldn't rely on the scsi command, but rather set
> the TMF status in the map_info->reset_state variable.
> That allows us to send a TMF independent on a scsi command.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
<snip>
>  /*
>   *     aac_eh_dev_reset        - Device reset command handling
>   *     @scsi_cmd:      SCSI command block causing the reset
> +921,19 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
<snip>
> 
>         /* Wait up to 15 seconds for completion */
>         for (count = 0; count < 15; ++count) {
> -               if (cmd->SCp.sent_command) {
> -                       ret = SUCCESS;
> +               if (info->reset_state == 0) {

Should this be <= 0, as in target reset? Otherwise it will always be success ...

-Dave

> +                       ret = info->reset_state == 0 ? SUCCESS : FAILED;
>                         break;

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-28 17:40       ` Kashyap Desai
       [not found]         ` <CAHtARFFTFMaUsVZ_KuYGr3hFcTuD5sf=h2+1RM6aj8yfpwsCWQ@mail.gmail.com>
@ 2017-06-29  5:53         ` Hannes Reinecke
  2017-06-29  7:51           ` Sumit Saxena
  1 sibling, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-29  5:53 UTC (permalink / raw)
  To: Kashyap Desai, Sumit Saxena, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

On 06/28/2017 07:40 PM, Kashyap Desai wrote:
>> -----Original Message-----
>> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
>> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
>> Sent: Wednesday, June 28, 2017 9:00 PM
>> To: Sumit Saxena; Christoph Hellwig
>> Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
>> Hannes
>> Reinecke
>> Subject: Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>>
>> On 06/28/2017 03:41 PM, Sumit Saxena wrote:
>>>> -----Original Message-----
>>>> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
>>>> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
>>>> Sent: Wednesday, June 28, 2017 2:03 PM
>>>> To: Christoph Hellwig
>>>> Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
>>> Hannes
>>>> Reinecke; Hannes Reinecke
>>>> Subject: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>>>>
>>>> When calling a host reset we shouldn't rely on the command triggering
>>>> the reset, so allow megaraid_abort_and_reset() to be called with a NULL
>> scb.
>>>> And drop the pointless 'bus_reset' and 'target_reset' handlers, which
>>> just call
>>>> the same function as host_reset.
>>>
>>> If this patch address any functional issue, then we should consider
>>> this.
>>> If it's code optimization, can we ignore this as this is being very
>>> old driver and no more maintained by Broadcom/LSI ?
>>>
>> Sadly, ignoring is not an option.
>> I'm planning to update the calling convention for SCSI EH, to resolve the
>> long-
>> standing problem with sg_reset ioctls.
>> sg_reset ioctl will allocate an out-of-band SCSI command, which does no
>> longer
>> work with the new command allocation scheme in multiqueue.
>> So it's not possible to just 'ignore' it, as then SCSI EH will cease to
>> function with
>> that driver.
> 
> Hannes - We are in process of sending megaraid and 3ware driver removal as
> LSI/Broadcom  stopped supporting those products.
> I agree we should review this closely, but lack of test coverage and end of
> life cycle of product is requesting us to know the rational.
> For now, let's consider NACK for this patch. We will be removing old
> megaraid (mbox) driver and 3Ware drivers soon.
> 
Hmm.
Can't we do the removal now?
There is not a lot of testing involved with _that_, surely?

I'd be happy to do a patch if you like ...

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 13/47] megaraid: pass in NULL scb for host reset
  2017-06-29  5:53         ` Hannes Reinecke
@ 2017-06-29  7:51           ` Sumit Saxena
  0 siblings, 0 replies; 89+ messages in thread
From: Sumit Saxena @ 2017-06-29  7:51 UTC (permalink / raw)
  To: Hannes Reinecke, Kashyap Desai, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	adam radford

>-----Original Message-----
>From: Hannes Reinecke [mailto:hare@suse.de]
>Sent: Thursday, June 29, 2017 11:23 AM
>To: Kashyap Desai; Sumit Saxena; Christoph Hellwig
>Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org; Hannes
>Reinecke
>Subject: Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>
>On 06/28/2017 07:40 PM, Kashyap Desai wrote:
>>> -----Original Message-----
>>> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
>>> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
>>> Sent: Wednesday, June 28, 2017 9:00 PM
>>> To: Sumit Saxena; Christoph Hellwig
>>> Cc: Martin K. Petersen; James Bottomley; linux-scsi@vger.kernel.org;
>>> Hannes Reinecke
>>> Subject: Re: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>>>
>>> On 06/28/2017 03:41 PM, Sumit Saxena wrote:
>>>>> -----Original Message-----
>>>>> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
>>>>> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
>>>>> Sent: Wednesday, June 28, 2017 2:03 PM
>>>>> To: Christoph Hellwig
>>>>> Cc: Martin K. Petersen; James Bottomley;
>>>>> linux-scsi@vger.kernel.org;
>>>> Hannes
>>>>> Reinecke; Hannes Reinecke
>>>>> Subject: [PATCH 13/47] megaraid: pass in NULL scb for host reset
>>>>>
>>>>> When calling a host reset we shouldn't rely on the command
>>>>> triggering the reset, so allow megaraid_abort_and_reset() to be
>>>>> called with a NULL
>>> scb.
>>>>> And drop the pointless 'bus_reset' and 'target_reset' handlers,
>>>>> which
>>>> just call
>>>>> the same function as host_reset.
>>>>
>>>> If this patch address any functional issue, then we should consider
>>>> this.
>>>> If it's code optimization, can we ignore this as this is being very
>>>> old driver and no more maintained by Broadcom/LSI ?
>>>>
>>> Sadly, ignoring is not an option.
>>> I'm planning to update the calling convention for SCSI EH, to resolve
>>> the
>>> long-
>>> standing problem with sg_reset ioctls.
>>> sg_reset ioctl will allocate an out-of-band SCSI command, which does
>>> no longer work with the new command allocation scheme in multiqueue.
>>> So it's not possible to just 'ignore' it, as then SCSI EH will cease
>>> to function with that driver.
>>
>> Hannes - We are in process of sending megaraid and 3ware driver
>> removal as LSI/Broadcom  stopped supporting those products.
>> I agree we should review this closely, but lack of test coverage and
>> end of life cycle of product is requesting us to know the rational.
>> For now, let's consider NACK for this patch. We will be removing old
>> megaraid (mbox) driver and 3Ware drivers soon.
>>
>Hmm.
>Can't we do the removal now?
>There is not a lot of testing involved with _that_, surely?
>
>I'd be happy to do a patch if you like ...
We are fine with you submitting the patch to remove megaraid and megaraid_mm
drivers. 3ware drivers are maintained by Adam Radford so we can not remove
them.
>
>Cheers,
>
>Hannes
>--
>Dr. Hannes Reinecke		   Teamlead Storage & Networking
>hare@suse.de			               +49 911 74053 688
>SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
>GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton HRB 21284
>(AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 01/47] aacraid: split off functions to generate reset FIB
  2017-06-28  8:32 ` [PATCH 01/47] aacraid: split off functions to generate reset FIB Hannes Reinecke
  2017-06-28  9:07   ` Johannes Thumshirn
@ 2017-06-29 19:59   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 19:59 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 1:32 AM
> To: Christoph Hellwig <hch@lst.de>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 01/47] aacraid: split off functions to generate reset FIB
> 
> EXTERNAL EMAIL
> 
> 
> Split off reset FIB generation into separate functions.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/aacraid/linit.c | 83 ++++++++++++++++++++++++++--------------
> ----
>  1 file changed, 50 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index 0f277df..9a8a27f 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -814,6 +814,52 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
>         return ret;
>  }
> 
> +static u8 aac_eh_tmf_lun_reset_fib(struct aac_dev *aac, struct fib *fib,
> +                                  int bus, int cid, u64 tmf_lun)
> +{
> +       struct aac_hba_tm_req *tmf;
> +       u64 address;
> +
> +       /* start a HBA_TMF_LUN_RESET TMF request */
> +       tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
> +       memset(tmf, 0, sizeof(*tmf));
> +       tmf->tmf = HBA_TMF_LUN_RESET;
> +       tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> +       int_to_scsilun(tmf_lun, (struct scsi_lun *)tmf->lun);
> +
> +       address = (u64)fib->hw_error_pa;
> +       tmf->error_ptr_hi = cpu_to_le32
> +               ((u32)(address >> 32));
> +       tmf->error_ptr_lo = cpu_to_le32
> +               ((u32)(address & 0xffffffff));
> +       tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
> +       fib->hbacmd_size = sizeof(*tmf);
> +
> +       return HBA_IU_TYPE_SCSI_TM_REQ;
> +}
> +
> +static u8 aac_eh_tmf_hard_reset_fib(struct aac_dev *aac, struct fib *fib,
> +                                   int bus, int cid)
> +{
> +       struct aac_hba_reset_req *rst;
> +       u64 address;
> +
> +       /* already tried, start a hard reset now */
> +       rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
> +       memset(rst, 0, sizeof(*rst));
> +       /* reset_type is already zero... */
> +       rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> +
> +       address = (u64)fib->hw_error_pa;
> +       rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
> +       rst->error_ptr_lo = cpu_to_le32
> +               ((u32)(address & 0xffffffff));
> +       rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
> +       fib->hbacmd_size = sizeof(*rst);
> +
> +       return HBA_IU_TYPE_SATA_REQ;
> +}
> +
>  /*
>   *     aac_eh_reset    - Reset command handling
>   *     @scsi_cmd:      SCSI command block causing the reset
> @@ -840,7 +886,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
>                 aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
>                 struct fib *fib;
>                 int status;
> -               u64 address;
>                 u8 command;
> 
>                 pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> @@ -852,42 +897,14 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
> 
> 
>                 if (aac->hba_map[bus][cid].reset_state == 0) {
> -                       struct aac_hba_tm_req *tmf;
> -
>                         /* start a HBA_TMF_LUN_RESET TMF request */
> -                       tmf = (struct aac_hba_tm_req *)fib->hw_fib_va;
> -                       memset(tmf, 0, sizeof(*tmf));
> -                       tmf->tmf = HBA_TMF_LUN_RESET;
> -                       tmf->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> -                       tmf->lun[1] = cmd->device->lun;
> -
> -                       address = (u64)fib->hw_error_pa;
> -                       tmf->error_ptr_hi = cpu_to_le32
> -                                       ((u32)(address >> 32));
> -                       tmf->error_ptr_lo = cpu_to_le32
> -                                       ((u32)(address & 0xffffffff));
> -                       tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
> -                       fib->hbacmd_size = sizeof(*tmf);
> -
> -                       command = HBA_IU_TYPE_SCSI_TM_REQ;
> +                       command = aac_eh_tmf_lun_reset_fib(aac, fib,
> +                                                          bus, cid,
> +                                                          cmd->device->lun);
>                         aac->hba_map[bus][cid].reset_state++;
>                 } else if (aac->hba_map[bus][cid].reset_state >= 1) {
> -                       struct aac_hba_reset_req *rst;
> -
>                         /* already tried, start a hard reset now */
> -                       rst = (struct aac_hba_reset_req *)fib->hw_fib_va;
> -                       memset(rst, 0, sizeof(*rst));
> -                       /* reset_type is already zero... */
> -                       rst->it_nexus = aac->hba_map[bus][cid].rmw_nexus;
> -
> -                       address = (u64)fib->hw_error_pa;
> -                       rst->error_ptr_hi = cpu_to_le32((u32)(address >> 32));
> -                       rst->error_ptr_lo = cpu_to_le32
> -                               ((u32)(address & 0xffffffff));
> -                       rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
> -                       fib->hbacmd_size = sizeof(*rst);
> -
> -                       command = HBA_IU_TYPE_SATA_REQ;
> +                       command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
>                         aac->hba_map[bus][cid].reset_state = 0;
>                 }
>                 cmd->SCp.sent_command = 0;

Reviewed-by: Raghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 02/47] aacraid: split off host reset
  2017-06-28  8:32 ` [PATCH 02/47] aacraid: split off host reset Hannes Reinecke
  2017-06-28  9:10   ` Johannes Thumshirn
@ 2017-06-29 20:00   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 20:00 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 1:32 AM
> To: Christoph Hellwig <hch@lst.de>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 02/47] aacraid: split off host reset
> 
> EXTERNAL EMAIL
> 
> 
> Split off the host reset parts of aac_eh_reset() into a separate
> host reset function.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/aacraid/linit.c | 33 ++++++++++++++++++++++-----------
>  1 file changed, 22 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index 9a8a27f..bf21006 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -874,10 +874,6 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
>         u32 bus, cid;
>         int ret = FAILED;
>         int status = 0;
> -       __le32 supported_options2 = 0;
> -       bool is_mu_reset;
> -       bool is_ignore_reset;
> -       bool is_doorbell_reset;
> 
> 
>         bus = aac_logical_to_phys(scmd_channel(cmd));
> @@ -923,7 +919,7 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
>                 }
> 
>                 if (ret == SUCCESS)
> -                       goto out;
> +                       return ret;
> 
>         } else {
> 
> @@ -952,8 +948,24 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
>                 dev_err(&aac->pdev->dev, "Adapter health - %d\n", status);
> 
>         count = get_num_of_incomplete_fibs(aac);
> -       if (count == 0)
> -               return SUCCESS;
> +       return (count == 0) ? SUCCESS : FAILED;
> +}
> +
> +/*
> + *     aac_eh_host_reset       - Host reset command handling
> + *     @scsi_cmd:      SCSI command block causing the reset
> + *
> + */
> +int aac_eh_host_reset(struct scsi_cmnd *cmd)
> +{
> +       struct scsi_device * dev = cmd->device;
> +       struct Scsi_Host * host = dev->host;
> +       struct aac_dev * aac = (struct aac_dev *)host->hostdata;
> +       int ret = FAILED;
> +       __le32 supported_options2 = 0;
> +       bool is_mu_reset;
> +       bool is_ignore_reset;
> +       bool is_doorbell_reset;
> 
>         /*
>          * Check if reset is supported by the firmware
> @@ -972,10 +984,8 @@ static int aac_eh_reset(struct scsi_cmnd* cmd)
>          && (aac_check_reset != -1 || !is_ignore_reset)) {
>                 /* Bypass wait for command quiesce */
>                 aac_reset_adapter(aac, 2, IOP_HWSOFT_RESET);
> +               ret = SUCCESS;
>         }
> -       ret = SUCCESS;
> -
> -out:
>         return ret;
>  }
> 
> @@ -1399,7 +1409,8 @@ ssize_t aac_get_serial_number(struct device
> *device, char *buf)
>         .change_queue_depth             = aac_change_queue_depth,
>         .sdev_attrs                     = aac_dev_attrs,
>         .eh_abort_handler               = aac_eh_abort,
> -       .eh_host_reset_handler          = aac_eh_reset,
> +       .eh_bus_reset_handler           = aac_eh_reset,
> +       .eh_host_reset_handler          = aac_eh_host_reset,
>         .can_queue                      = AAC_NUM_IO_FIB,
>         .this_id                        = MAXIMUM_NUM_CONTAINERS,
>         .sg_tablesize                   = 16,

Reviewed-by: Raghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 03/47] aacraid: split off device, target, and bus reset
  2017-06-28  8:32 ` [PATCH 03/47] aacraid: split off device, target, and bus reset Hannes Reinecke
  2017-06-28  9:14   ` Johannes Thumshirn
@ 2017-06-29 20:01   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 20:01 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 1:32 AM
> To: Christoph Hellwig <hch@lst.de>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 03/47] aacraid: split off device, target, and bus reset
> 
> EXTERNAL EMAIL
> 
> 
> Split off device, target, and bus reset functionality into
> individual functions.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/aacraid/linit.c | 141 +++++++++++++++++++++++++++++++-----
> -------
>  1 file changed, 102 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index bf21006..57b2077 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -861,68 +861,129 @@ static u8 aac_eh_tmf_hard_reset_fib(struct
> aac_dev *aac, struct fib *fib,
>  }
> 
>  /*
> - *     aac_eh_reset    - Reset command handling
> + *     aac_eh_dev_reset        - Device reset command handling
>   *     @scsi_cmd:      SCSI command block causing the reset
>   *
>   */
> -static int aac_eh_reset(struct scsi_cmnd* cmd)
> +static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
>  {
>         struct scsi_device * dev = cmd->device;
>         struct Scsi_Host * host = dev->host;
>         struct aac_dev * aac = (struct aac_dev *)host->hostdata;
>         int count;
>         u32 bus, cid;
> +       struct fib *fib;
>         int ret = FAILED;
> -       int status = 0;
> -
> +       int status;
> +       u8 command;
> 
>         bus = aac_logical_to_phys(scmd_channel(cmd));
>         cid = scmd_id(cmd);
> -       if (bus < AAC_MAX_BUSES && cid < AAC_MAX_TARGETS &&
> -               aac->hba_map[bus][cid].devtype == AAC_DEVTYPE_NATIVE_RAW) {
> -               struct fib *fib;
> -               int status;
> -               u8 command;
> +       if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> +           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
> +               return FAILED;
> 
> -               pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> -                       AAC_DRIVERNAME);
> +       pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> +              AAC_DRIVERNAME);
> 
> -               fib = aac_fib_alloc(aac);
> -               if (!fib)
> -                       return ret;
> +       fib = aac_fib_alloc(aac);
> +       if (!fib)
> +               return ret;
> 
> 
> -               if (aac->hba_map[bus][cid].reset_state == 0) {
> -                       /* start a HBA_TMF_LUN_RESET TMF request */
> -                       command = aac_eh_tmf_lun_reset_fib(aac, fib,
> -                                                          bus, cid,
> -                                                          cmd->device->lun);
> -                       aac->hba_map[bus][cid].reset_state++;
> -               } else if (aac->hba_map[bus][cid].reset_state >= 1) {
> -                       /* already tried, start a hard reset now */
> -                       command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
> -                       aac->hba_map[bus][cid].reset_state = 0;
> +       /* start a HBA_TMF_LUN_RESET TMF request */
> +       command = aac_eh_tmf_lun_reset_fib(aac, fib, bus, cid,
> +                                          cmd->device->lun);
> +
> +       cmd->SCp.sent_command = 0;
> +
> +       status = aac_hba_send(command, fib,
> +                             (fib_callback) aac_hba_callback,
> +                             (void *) cmd);
> +
> +       /* Wait up to 15 seconds for completion */
> +       for (count = 0; count < 15; ++count) {
> +               if (cmd->SCp.sent_command) {
> +                       ret = SUCCESS;
> +                       break;
>                 }
> -               cmd->SCp.sent_command = 0;
> +               msleep(1000);
> +       }
> 
> -               status = aac_hba_send(command, fib,
> -                                 (fib_callback) aac_hba_callback,
> -                                 (void *) cmd);
> +       return ret;
> +}
> 
> -               /* Wait up to 15 seconds for completion */
> -               for (count = 0; count < 15; ++count) {
> -                       if (cmd->SCp.sent_command) {
> -                               ret = SUCCESS;
> -                               break;
> -                       }
> -                       msleep(1000);
> +/*
> + *     aac_eh_target_reset     - Target reset command handling
> + *     @scsi_cmd:      SCSI command block causing the reset
> + *
> + */
> +static int aac_eh_target_reset(struct scsi_cmnd *cmd)
> +{
> +       struct scsi_device * dev = cmd->device;
> +       struct Scsi_Host * host = dev->host;
> +       struct aac_dev * aac = (struct aac_dev *)host->hostdata;
> +       int count;
> +       u32 bus, cid;
> +       int ret = FAILED;
> +       struct fib *fib;
> +       int status;
> +       u8 command;
> +
> +       bus = aac_logical_to_phys(scmd_channel(cmd));
> +       cid = scmd_id(cmd);
> +       if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> +           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
> +               return FAILED;
> +
> +       pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> +              AAC_DRIVERNAME);
> +
> +       fib = aac_fib_alloc(aac);
> +       if (!fib)
> +               return ret;
> +
> +
> +       /* already tried, start a hard reset now */
> +       command = aac_eh_tmf_hard_reset_fib(aac, fib, bus, cid);
> +
> +       cmd->SCp.sent_command = 0;
> +
> +       status = aac_hba_send(command, fib,
> +                             (fib_callback) aac_hba_callback,
> +                             (void *) cmd);
> +
> +       /* Wait up to 15 seconds for completion */
> +       for (count = 0; count < 15; ++count) {
> +               if (cmd->SCp.sent_command) {
> +                       ret = SUCCESS;
> +                       break;
>                 }
> +               msleep(1000);
> +       }
> 
> -               if (ret == SUCCESS)
> -                       return ret;
> +       return ret;
> +}
> +
> +/*
> + *     aac_eh_bus_reset        - Bus reset command handling
> + *     @scsi_cmd:      SCSI command block causing the reset
> + *
> + */
> +static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
> +{
> +       struct scsi_device * dev = cmd->device;
> +       struct Scsi_Host * host = dev->host;
> +       struct aac_dev * aac = (struct aac_dev *)host->hostdata;
> +       int count;
> +       u32 bus, cid;
> +       int status = 0;
> 
> -       } else {
> 
> +       bus = aac_logical_to_phys(scmd_channel(cmd));
> +       cid = scmd_id(cmd);
> +       if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> +           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) {
>                 /* Mark the assoc. FIB to not complete, eh handler does this */
>                 for (count = 0;
>                         count < (host->can_queue + AAC_NUM_MGT_FIB);
> @@ -1409,7 +1470,9 @@ ssize_t aac_get_serial_number(struct device
> *device, char *buf)
>         .change_queue_depth             = aac_change_queue_depth,
>         .sdev_attrs                     = aac_dev_attrs,
>         .eh_abort_handler               = aac_eh_abort,
> -       .eh_bus_reset_handler           = aac_eh_reset,
> +       .eh_device_reset_handler        = aac_eh_dev_reset,
> +       .eh_target_reset_handler        = aac_eh_target_reset,
> +       .eh_bus_reset_handler           = aac_eh_bus_reset,
>         .eh_host_reset_handler          = aac_eh_host_reset,
>         .can_queue                      = AAC_NUM_IO_FIB,
>         .this_id                        = MAXIMUM_NUM_CONTAINERS,
> --
> 1.8.5.6

Reviewed-by: Raghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib
  2017-06-28  8:32 ` [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
  2017-06-28 19:42   ` Dave Carroll
@ 2017-06-29 20:06   ` Raghava Aditya Renukunta
  2017-06-30  7:19     ` Hannes Reinecke
  1 sibling, 1 reply; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 20:06 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

[.....]
> @@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
[......]
>         bus = aac_logical_to_phys(scmd_channel(cmd));
>         cid = scmd_id(cmd);
> +       info = &aac->hba_map[bus][cid];
>         if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> -           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
> +           info->devtype != AAC_DEVTYPE_NATIVE_RAW)
> +               return FAILED;
> +
> +       if (info->reset_state > 0)
>                 return FAILED;
[......]
 
> @@ -932,8 +962,9 @@ static int aac_eh_target_reset(struct scsi_cmnd
> *cmd)
> 
>         bus = aac_logical_to_phys(scmd_channel(cmd));
>         cid = scmd_id(cmd);
> +       info = &aac->hba_map[bus][cid];
>         if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> -           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
> +           info->devtype != AAC_DEVTYPE_NATIVE_RAW)
>                 return FAILED;

Can we have a 
	If (info->reset_state > 0
		Return FAILED;
here as well?

>         pr_err("%s: Host adapter reset request. SCSI hang ?\n",
> @@ -945,18 +976,18 @@ static int aac_eh_target_reset(struct scsi_cmnd
> *cmd)
> 
[.....]

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send()
  2017-06-28  8:32 ` [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
  2017-06-28  9:17   ` Johannes Thumshirn
@ 2017-06-29 20:07   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 20:07 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 1:33 AM
> To: Christoph Hellwig <hch@lst.de>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 05/47] aacraid: enable sending of TMFs from
> aac_hba_send()
> 
> EXTERNAL EMAIL
> 
> 
> aac_hba_send() will return FAILED for any non-SCSI command requests,
> failing any TMFs. This patch updates the check to allow TMFs.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/aacraid/commsup.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
> index 1c617cc..348f0ea 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -770,7 +770,7 @@ int aac_hba_send(u8 command, struct fib *fibptr,
> fib_callback callback,
>                 /* bit1 of request_id must be 0 */
>                 hbacmd->request_id =
>                         cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
> -       } else
> +       } else if (command != HBA_IU_TYPE_SCSI_TM_REQ)
>                 return -EINVAL;
> 
> 
> --
> 1.8.5.6

Reviewed-by: Raghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 06/47] aacraid: add fib flag to mark scsi command callback
  2017-06-28  8:32 ` [PATCH 06/47] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
  2017-06-28  9:18   ` Johannes Thumshirn
@ 2017-06-29 20:07   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 20:07 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 1:33 AM
> To: Christoph Hellwig <hch@lst.de>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 06/47] aacraid: add fib flag to mark scsi command callback
> 
> EXTERNAL EMAIL
> 
> 
> To correctly identify which fib has a scsi command callback this
> patch implements a flag FIB_CONTEXT_FLAG_SCSI_CMD.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/aacraid/aacraid.h | 1 +
>  drivers/scsi/aacraid/commsup.c | 1 +
>  2 files changed, 2 insertions(+)
> 
> diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
> index d31a9bc..6981299 100644
> --- a/drivers/scsi/aacraid/aacraid.h
> +++ b/drivers/scsi/aacraid/aacraid.h
> @@ -1723,6 +1723,7 @@ struct aac_dev
>  #define FIB_CONTEXT_FLAG_FASTRESP              (0x00000008)
>  #define FIB_CONTEXT_FLAG_NATIVE_HBA            (0x00000010)
>  #define FIB_CONTEXT_FLAG_NATIVE_HBA_TMF        (0x00000020)
> +#define FIB_CONTEXT_FLAG_SCSI_CMD      (0x00000040)
> 
>  /*
>   *     Define the command values
> diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
> index 348f0ea..dfe8e70 100644
> --- a/drivers/scsi/aacraid/commsup.c
> +++ b/drivers/scsi/aacraid/commsup.c
> @@ -770,6 +770,7 @@ int aac_hba_send(u8 command, struct fib *fibptr,
> fib_callback callback,
>                 /* bit1 of request_id must be 0 */
>                 hbacmd->request_id =
>                         cpu_to_le32((((u32)(fibptr - dev->fibs)) << 2) + 1);
> +               fibptr->flags |= FIB_CONTEXT_FLAG_SCSI_CMD;
>         } else if (command != HBA_IU_TYPE_SCSI_TM_REQ)
>                 return -EINVAL;
> 
> --
> 1.8.5.6

Reviewed-by: Raghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>

^ permalink raw reply	[flat|nested] 89+ messages in thread

* RE: [PATCH 07/47] aacraid: complete all commands during bus reset
  2017-06-28  8:32 ` [PATCH 07/47] aacraid: complete all commands during bus reset Hannes Reinecke
  2017-06-28  9:19   ` Johannes Thumshirn
@ 2017-06-29 20:07   ` Raghava Aditya Renukunta
  1 sibling, 0 replies; 89+ messages in thread
From: Raghava Aditya Renukunta @ 2017-06-29 20:07 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



> -----Original Message-----
> From: linux-scsi-owner@vger.kernel.org [mailto:linux-scsi-
> owner@vger.kernel.org] On Behalf Of Hannes Reinecke
> Sent: Wednesday, June 28, 2017 1:33 AM
> To: Christoph Hellwig <hch@lst.de>
> Cc: Martin K. Petersen <martin.petersen@oracle.com>; James Bottomley
> <james.bottomley@hansenpartnership.com>; linux-scsi@vger.kernel.org;
> Hannes Reinecke <hare@suse.de>; Hannes Reinecke <hare@suse.com>
> Subject: [PATCH 07/47] aacraid: complete all commands during bus reset
> 
> EXTERNAL EMAIL
> 
> 
> When issuing a bus reset we should complete all commands, not
> just the command triggering the reset.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>  drivers/scsi/aacraid/linit.c | 34 ++++++++++++++++++++--------------
>  1 file changed, 20 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
> index 9b284a0..c26130e 100644
> --- a/drivers/scsi/aacraid/linit.c
> +++ b/drivers/scsi/aacraid/linit.c
> @@ -1007,23 +1007,29 @@ static int aac_eh_bus_reset(struct scsi_cmnd*
> cmd)
>         struct Scsi_Host * host = dev->host;
>         struct aac_dev * aac = (struct aac_dev *)host->hostdata;
>         int count;
> -       u32 bus, cid;
> +       u32 cmd_bus;
>         int status = 0;
> 
> 
> -       bus = aac_logical_to_phys(scmd_channel(cmd));
> -       cid = scmd_id(cmd);
> -       if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> -           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW) {
> -               /* Mark the assoc. FIB to not complete, eh handler does this */
> -               for (count = 0;
> -                       count < (host->can_queue + AAC_NUM_MGT_FIB);
> -                       ++count) {
> -                       struct fib *fib = &aac->fibs[count];
> -
> -                       if (fib->hw_fib_va->header.XferState &&
> -                               (fib->flags & FIB_CONTEXT_FLAG) &&
> -                               (fib->callback_data == cmd)) {
> +       cmd_bus = aac_logical_to_phys(scmd_channel(cmd));
> +       /* Mark the assoc. FIB to not complete, eh handler does this */
> +       for (count = 0; count < (host->can_queue + AAC_NUM_MGT_FIB);
> ++count) {
> +               struct fib *fib = &aac->fibs[count];
> +
> +               if (fib->hw_fib_va->header.XferState &&
> +                   (fib->flags & FIB_CONTEXT_FLAG) &&
> +                   (fib->flags & FIB_CONTEXT_FLAG_SCSI_CMD)) {
> +                       struct aac_hba_map_info *info;
> +                       u32 bus, cid;
> +
> +                       cmd = (struct scsi_cmnd *)fib->callback_data;
> +                       bus = aac_logical_to_phys(scmd_channel(cmd));
> +                       if (bus != cmd_bus)
> +                               continue;
> +                       cid = scmd_id(cmd);
> +                       info = &aac->hba_map[bus][cid];
> +                       if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
> +                           info->devtype != AAC_DEVTYPE_NATIVE_RAW) {
>                                 fib->flags |= FIB_CONTEXT_FLAG_TIMED_OUT;
>                                 cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
>                         }
> --
> 1.8.5.6

Reviewed-by: Raghava Aditya Renukunta  <RaghavaAditya.Renukunta@microsemi.com>

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib
  2017-06-29 20:06   ` Raghava Aditya Renukunta
@ 2017-06-30  7:19     ` Hannes Reinecke
  0 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-06-30  7:19 UTC (permalink / raw)
  To: Raghava Aditya Renukunta, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

On 06/29/2017 10:06 PM, Raghava Aditya Renukunta wrote:
> [.....]
>> @@ -879,8 +906,12 @@ static int aac_eh_dev_reset(struct scsi_cmnd *cmd)
> [......]
>>         bus = aac_logical_to_phys(scmd_channel(cmd));
>>         cid = scmd_id(cmd);
>> +       info = &aac->hba_map[bus][cid];
>>         if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
>> -           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
>> +           info->devtype != AAC_DEVTYPE_NATIVE_RAW)
>> +               return FAILED;
>> +
>> +       if (info->reset_state > 0)
>>                 return FAILED;
> [......]
>  
>> @@ -932,8 +962,9 @@ static int aac_eh_target_reset(struct scsi_cmnd
>> *cmd)
>>
>>         bus = aac_logical_to_phys(scmd_channel(cmd));
>>         cid = scmd_id(cmd);
>> +       info = &aac->hba_map[bus][cid];
>>         if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
>> -           aac->hba_map[bus][cid].devtype != AAC_DEVTYPE_NATIVE_RAW)
>> +           info->devtype != AAC_DEVTYPE_NATIVE_RAW)
>>                 return FAILED;
> 
> Can we have a 
> 	If (info->reset_state > 0
> 		Return FAILED;
> here as well?
> 
Sure.

Thanks for the review.

Cheers

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for host reset
  2017-06-28  8:32 ` [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for " Hannes Reinecke
@ 2017-07-24 16:18   ` Steffen Maier
  2017-07-24 18:01     ` Hannes Reinecke
  2017-07-24 16:24   ` Steffen Maier
  1 sibling, 1 reply; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 16:18 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Benjamin Block

Hi Hannes,

unfortunately I only realized now by accident that there's stuff to 
review. Would be nice to send it also explicitly to driver maintainers 
in addition to the list.

Since you've asked for this multiple times, I happened to just now code 
a patch series of 6 patches in order to decouple zfcp from scsi_cmnd for 
device, target, and host reset.

While I provide some review comments below, I think it might be clearer 
and easier to review if you would rebase your series on top of my 
decoupling.

Let me know how urgent you'd like to see my code. I planned to send it 
as RFC soon anyway. However, it hasn't seen any function testing yet. If 
you don't care, let me know and I can send it.

On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
> When issuing a host reset we should be waiting for all
> ports to become unblocked; just waiting for one might
> be resulting in host reset to return too early.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>   drivers/s390/scsi/zfcp_scsi.c | 27 +++++++++++++++++++++++----
>   1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index 0678cf7..3d18659 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -311,13 +311,32 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
> 
>   static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
>   {
> -	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
> -	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
> -	int ret;
> +	struct Scsi_Host *host = scpnt->device->host;
> +	struct zfcp_adapter *adapter = (struct zfcp_adapter *)host->hostdata[0];
> +	int ret = 0;
> +	unsigned long flags;
> +	struct zfcp_port *port;
> 
>   	zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
>   	zfcp_erp_wait(adapter);
> -	ret = fc_block_scsi_eh(scpnt);
> +retry_rport_blocked:
> +	spin_lock_irqsave(host->host_lock, flags);

missing read_lock(&adapter->port_list_lock);

Hm, well, I have to think about lock ordering, because my patch has the 
port_list as outer loop and inside it calls fc_block_scsi_eh (also 
modified with fc_rport as argument).
If there's any other location taking both locks we better get them in 
the same order.

> +	list_for_each_entry(port, &adapter->port_list, list) {
> +		struct fc_rport *rport = port->rport;

port->rport can be NULL, so need to check

> +
> +		if (rport->port_state == FC_PORTSTATE_BLOCKED) {
> +			if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)
> +				ret = FAST_IO_FAIL;

Hm, doesn't this get lost if a next iteration hits ret=NEEDS_RETRY?

I was pondering in my own patch version what to return of just a subset 
of ports ran into fast_io_fail. And for now I thought just fast_io_fail 
would be good to let I/O bubble up for path failover, even if this would 
include of rport which meanwhile unblocked properly and would not need 
bubbling up pending requests because they could service them with a 
simple retry.

> +			else
> +				ret = NEEDS_RETRY;
> +			break;
> +		}

Why do you open code fc_block_scsi_eh() instead of calling it with 
port->rport (if it's !=NULL)?

Typically all rports would be blocked after adapter recovery, until they 
become unblocked (via zfcp's async rport_work). So we can wait for each 
in turn which should still only wait in summary for the last one to 
unblock. E.g. if the first rport takes longest we wait for it, and the 
rest of the loop will be fast since the others happen to be unblocked 
(or fast_io_fail) already?

> +	}

missing read_unlock(&adapter->port_list_lock);

> +	spin_unlock_irqrestore(host->host_lock, flags);
> +	if (ret == NEEDS_RETRY) {
> +		msleep(1000);
> +		goto retry_rport_blocked;
> +	}
>   	if (ret)
>   		return ret;
> 

-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for host reset
  2017-06-28  8:32 ` [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for " Hannes Reinecke
  2017-07-24 16:18   ` Steffen Maier
@ 2017-07-24 16:24   ` Steffen Maier
  1 sibling, 0 replies; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 16:24 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
> When issuing a host reset we should be waiting for all
> ports to become unblocked; just waiting for one might
> be resulting in host reset to return too early.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>   drivers/s390/scsi/zfcp_scsi.c | 27 +++++++++++++++++++++++----
>   1 file changed, 23 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index 0678cf7..3d18659 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -311,13 +311,32 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
> 
>   static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
>   {
> -	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
> -	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
> -	int ret;
> +	struct Scsi_Host *host = scpnt->device->host;
> +	struct zfcp_adapter *adapter = (struct zfcp_adapter *)host->hostdata[0];

Oh, only realized when reading the later "[PATCH 14/47] scsi: Use 
Scsi_Host as argument for eh_host_reset_handler" that this part already 
anticipates parts of that later patch. Seems not fully topically 
separated patches to me, if this one is only about the fc_block_scsi_eh 
aspect in zfcp_scsi_eh_host_reset_handler().


-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 15/47] scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh
  2017-06-28  8:32 ` [PATCH 15/47] scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh Hannes Reinecke
@ 2017-07-24 16:34   ` Steffen Maier
  0 siblings, 0 replies; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 16:34 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi


On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
> fc_block_scsi_eh() works on a remote port, so we should be using
> that as an argument, and not the scsi command.

> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index d7d4a63..e3160fc 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -150,6 +150,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
>   	struct zfcp_adapter *adapter =
>   		(struct zfcp_adapter *) scsi_host->hostdata[0];
>   	struct zfcp_fsf_req *old_req, *abrt_req;
> +	struct fc_rport *rport = starget_to_rport(scsi_target(scpnt->device));
>   	unsigned long flags;
>   	unsigned long old_reqid = (unsigned long) scpnt->host_scribble;
>   	int retval = SUCCESS, ret;
> @@ -176,7 +177,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
>   			break;
> 
>   		zfcp_erp_wait(adapter);
> -		ret = fc_block_scsi_eh(scpnt);
> +		ret = fc_block_scsi_eh(rport);

I think for abort handlers some original fc_block_scsi_eh with scsi_cmnd 
as argument would be perfectly valid as this really has the scope of a 
particular single command.

Do you really want to touch all abort handlers just because of this?

In my zfcp decoupling I had created a new fc_block_rport for 
TMFs/host_reset and kept using the old fc_block_scsi_eh (which does the 
argument lifting and simply delegates to the new fc_block_rport) for the 
abort handler.
Admittedly, of course, I also did so because I did not touch all other 
users/callers of the old function with the scsi_cmnd argument.

>   		if (ret) {
>   			zfcp_dbf_scsi_abort("abrt_bl", scpnt, NULL);
>   			return ret;
> @@ -262,6 +263,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
>   {
>   	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
>   	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
> +	struct fc_port *rport = zfcp_sdev->port->rport;

port->rport could be NULL

[async zfcp_scsi_rport_block()]

>   	struct zfcp_fsf_req *fsf_req = NULL;
>   	int retval = SUCCESS, ret;
>   	int retry = 3;
> @@ -272,7 +274,7 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
>   			break;
> 
>   		zfcp_erp_wait(adapter);
> -		ret = fc_block_scsi_eh(scpnt);
> +		ret = fc_block_scsi_eh(rport);
>   		if (ret)
>   			return ret;
> 

> diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c
> index 6dd0922..f83e512 100644
> --- a/drivers/scsi/scsi_transport_fc.c
> +++ b/drivers/scsi/scsi_transport_fc.c
> @@ -3273,7 +3273,7 @@ struct fc_rport *
> 
>   /**
>    * fc_block_scsi_eh - Block SCSI eh thread for blocked fc_rport
> - * @cmnd: SCSI command that scsi_eh is trying to recover
> + * @rport: remote port to be checked
>    *
>    * This routine can be called from a FC LLD scsi_eh callback. It
>    * blocks the scsi_eh thread until the fc_rport leaves the
> @@ -3285,10 +3285,9 @@ struct fc_rport *
>    *	    FAST_IO_FAIL if the fast_io_fail_tmo fired, this should be
>    *	    passed back to scsi_eh.
>    */
> -int fc_block_scsi_eh(struct scsi_cmnd *cmnd)
> +int fc_block_scsi_eh(struct fc_rport *rport)
>   {
> -	struct Scsi_Host *shost = cmnd->device->host;
> -	struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device));
> +	struct Scsi_Host *shost = rport_to_shost(rport);
>   	unsigned long flags;
> 
>   	spin_lock_irqsave(shost->host_lock, flags);
> diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h
> index e308cd5..5b26943 100644
> --- a/include/scsi/scsi_transport_fc.h
> +++ b/include/scsi/scsi_transport_fc.h
> @@ -804,7 +804,7 @@ void fc_host_post_vendor_event(struct Scsi_Host *shost, u32 event_number,
>   struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
>   		struct fc_vport_identifiers *);
>   int fc_vport_terminate(struct fc_vport *vport);
> -int fc_block_scsi_eh(struct scsi_cmnd *cmnd);
> +int fc_block_scsi_eh(struct fc_rport *rport);
>   enum blk_eh_timer_return fc_eh_timed_out(struct scsi_cmnd *scmd);
> 
>   static inline struct Scsi_Host *fc_bsg_to_shost(struct bsg_job *job)
> 

Aside from above thoughts, the coding of the argument change seems good.


-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 14/47] scsi: Use Scsi_Host as argument for eh_host_reset_handler
  2017-06-28  8:32 ` [PATCH 14/47] scsi: Use Scsi_Host as argument for eh_host_reset_handler Hannes Reinecke
@ 2017-07-24 16:55   ` Steffen Maier
  0 siblings, 0 replies; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 16:55 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi


On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
> Issuing a host reset should not rely on any commands.
> So use Scsi_Host as argument for eh_host_reset_handler.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.de>
> ---
>   Documentation/scsi/scsi_eh.txt                  |  2 +-
>   Documentation/scsi/scsi_mid_low_api.txt         |  4 +--

>   drivers/s390/scsi/zfcp_scsi.c                   |  3 +-

>   drivers/scsi/scsi_debug.c                       | 16 +++++-----
>   drivers/scsi/scsi_error.c                       |  2 +-

>   include/scsi/scsi_host.h                        |  2 +-
>   81 files changed, 290 insertions(+), 380 deletions(-)
> 
> diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
> index 11e447b..78cd6b9 100644
> --- a/Documentation/scsi/scsi_eh.txt
> +++ b/Documentation/scsi/scsi_eh.txt
> @@ -208,7 +208,7 @@ considered to fail always.
>   int (* eh_abort_handler)(struct scsi_cmnd *);
>   int (* eh_device_reset_handler)(struct scsi_cmnd *);
>   int (* eh_bus_reset_handler)(struct scsi_cmnd *);
> -int (* eh_host_reset_handler)(struct scsi_cmnd *);
> +int (* eh_host_reset_handler)(struct Scsi_Host *);
> 
>    Higher-severity actions are taken only when lower-severity actions
>   cannot recover some of failed scmds.  Also, note that failure of the
> diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
> index 6338400..ad517d5 100644
> --- a/Documentation/scsi/scsi_mid_low_api.txt
> +++ b/Documentation/scsi/scsi_mid_low_api.txt
> @@ -891,7 +891,7 @@ Details:
> 
>   /**
>    *      eh_host_reset_handler - reset host (host bus adapter)
> - *      @scp: SCSI host that contains this device should be reset
> + *      @shost: SCSI host that should be reset
>    *
>    *      Returns SUCCESS if command aborted else FAILED
>    *
> @@ -908,7 +908,7 @@ Details:
>    *
>    *      Optionally defined in: LLD
>    **/
> -     int eh_host_reset_handler(struct scsi_cmnd * scp)
> +     int eh_host_reset_handler(struct Scsi_Host * shost)
> 
> 
>   /**



> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index 3d18659..d7d4a63 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -309,9 +309,8 @@ static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
>   	return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
>   }
> 
> -static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
> +static int zfcp_scsi_eh_host_reset_handler(struct Scsi_Host *host)
>   {
> -	struct Scsi_Host *host = scpnt->device->host;
>   	struct zfcp_adapter *adapter = (struct zfcp_adapter *)host->hostdata[0];
>   	int ret = 0;
>   	unsigned long flags;



> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index dc095a2..ebf525b 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -3878,27 +3878,27 @@ static int scsi_debug_bus_reset(struct scsi_cmnd * SCpnt)
>   	return SUCCESS;
>   }
> 
> -static int scsi_debug_host_reset(struct scsi_cmnd * SCpnt)
> +static int scsi_debug_host_reset(struct Scsi_Host * shost)
>   {
>   	struct sdebug_host_info * sdbg_host;
>   	struct sdebug_dev_info *devip;
>   	int k = 0;
> 
>   	++num_host_resets;
> -	if ((SCpnt->device) && (SDEBUG_OPT_ALL_NOISE & sdebug_opts))
> -		sdev_printk(KERN_INFO, SCpnt->device, "%s\n", __func__);
> -        spin_lock(&sdebug_host_list_lock);
> -        list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
> +	if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
> +		shost_printk(KERN_INFO, shost, "%s\n", __func__);
> +	spin_lock(&sdebug_host_list_lock);
> +	list_for_each_entry(sdbg_host, &sdebug_host_list, host_list) {
>   		list_for_each_entry(devip, &sdbg_host->dev_info_list,
>   				    dev_list) {
>   			set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
>   			++k;
>   		}
> -        }
> -        spin_unlock(&sdebug_host_list_lock);
> +	}
> +	spin_unlock(&sdebug_host_list_lock);
>   	stop_all_queued();
>   	if (SDEBUG_OPT_RESET_NOISE & sdebug_opts)
> -		sdev_printk(KERN_INFO, SCpnt->device,
> +		shost_printk(KERN_INFO, shost,
>   			    "%s: %d device(s) found\n", __func__, k);
>   	return SUCCESS;
>   }

Mechanically, the change looks good.

However, is it correct that it's been looping over all its shosts and 
doing something even for those that do not match SCpnt or now shost?
I thought it should only reset on the scope but it seems to call 
stop_all_queued(void) which might reset all shosts?
But then again the loop seems about unit attentions so the loop may be 
correct.
Anyway, this is not related to your change.

The other quoted parts incl. zfcp look good to me.

> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index ac31964..808167f 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -745,7 +745,7 @@ static int scsi_try_host_reset(struct scsi_cmnd *scmd)
>   	if (!hostt->eh_host_reset_handler)
>   		return FAILED;
> 
> -	rtn = hostt->eh_host_reset_handler(scmd);
> +	rtn = hostt->eh_host_reset_handler(host);
> 
>   	if (rtn == SUCCESS) {
>   		if (!hostt->skip_settle_delay)



> diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
> index afb0481..b85f8a5 100644
> --- a/include/scsi/scsi_host.h
> +++ b/include/scsi/scsi_host.h
> @@ -148,7 +148,7 @@ struct scsi_host_template {
>   	int (* eh_device_reset_handler)(struct scsi_cmnd *);
>   	int (* eh_target_reset_handler)(struct scsi_cmnd *);
>   	int (* eh_bus_reset_handler)(struct scsi_cmnd *);
> -	int (* eh_host_reset_handler)(struct scsi_cmnd *);
> +	int (* eh_host_reset_handler)(struct Scsi_Host *);
> 
>   	/*
>   	 * Before the mid layer attempts to scan for a new device where none
> 

-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function()
  2017-06-28  8:32 ` [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function() Hannes Reinecke
@ 2017-07-24 17:15   ` Steffen Maier
  2017-07-25 14:14     ` Hannes Reinecke
  0 siblings, 1 reply; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 17:15 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke



On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
> zfcp_task_mgmt_function() is only used for lun and device reset,
> so it should be using the scsi device as an argument, not the
> scsi command.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>   drivers/s390/scsi/zfcp_ext.h  |  2 +-
>   drivers/s390/scsi/zfcp_fc.h   |  9 +--------
>   drivers/s390/scsi/zfcp_fsf.c  | 21 +++++++++++----------
>   drivers/s390/scsi/zfcp_scsi.c | 12 ++++++------
>   4 files changed, 19 insertions(+), 25 deletions(-)
> 
> diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
> index 57f1d4a..64d4db7 100644
> --- a/drivers/s390/scsi/zfcp_ext.h
> +++ b/drivers/s390/scsi/zfcp_ext.h
> @@ -117,7 +117,7 @@ extern int zfcp_fsf_send_els(struct zfcp_adapter *, u32,
>   			     struct zfcp_fsf_ct_els *, unsigned int);
>   extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *);
>   extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
> -extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *, u8);
> +extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *, u8);
>   extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *);
>   extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
> 
> diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
> index df2b541..f08eaf9 100644
> --- a/drivers/s390/scsi/zfcp_fc.h
> +++ b/drivers/s390/scsi/zfcp_fc.h
> @@ -206,19 +206,12 @@ struct zfcp_fc_wka_ports {
>    * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
>    * @fcp: fcp_cmnd to setup
>    * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
> - * @tm: task management flags to setup task management command
>    */
>   static inline
> -void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi,
> -			 u8 tm_flags)
> +void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
>   {
>   	int_to_scsilun(scsi->device->lun, (struct scsi_lun *) &fcp->fc_lun);
> 
> -	if (unlikely(tm_flags)) {
> -		fcp->fc_tm_flags = tm_flags;
> -		return;
> -	}
> -
>   	fcp->fc_pri_ta = FCP_PTA_SIMPLE;
> 
>   	if (scsi->sc_data_direction == DMA_FROM_DEVICE)

When I wrote my zfcp decoupling patch series I did a lot of git history 
research in order to double check if my changes are OK.

Here, I figured that I'd like to separately revert commit 2443c8b23aea 
("[SCSI] zfcp: Merge FCP task management setup with regular FCP command 
setup"), because this introduced a dependency on the unsuitable SCSI 
command for scsi_eh / TMF. Even though it was one of the first commits I 
posted upstream as newbie zfcp maintainer... little did I know.

> diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
> index 27ff38f..c4bd3d4 100644
> --- a/drivers/s390/scsi/zfcp_fsf.c
> +++ b/drivers/s390/scsi/zfcp_fsf.c
> @@ -2036,10 +2036,9 @@ static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)

> -static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
> +static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req,
> +					struct scsi_device *sdev)


> @@ -2120,7 +2119,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req)

> -	zfcp_fsf_fcp_handler_common(req);
> +	zfcp_fsf_fcp_handler_common(req, scpnt->device);

> @@ -2296,8 +2295,9 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
>   {

> +	struct scsi_device *sdev = req->data;
> 
> -	zfcp_fsf_fcp_handler_common(req);
> +	zfcp_fsf_fcp_handler_common(req, sdev);

Moving the resolving of req->data into the callers of 
zfcp_fsf_fcp_handler_common() I did the same way in my own patch series.

> @@ -2313,12 +2313,12 @@ static void zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)

> -struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
> +struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
>   					    u8 tm_flags)

> @@ -2338,7 +2338,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,

> -	req->data = scmnd;
> +	req->data = sdev;

> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index 5fada93..dd7bea0 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -259,17 +259,17 @@ static void zfcp_scsi_forget_cmnds(struct zfcp_scsi_dev *zsdev, u8 tm_flags)

> -static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
> +static int zfcp_task_mgmt_function(struct scsi_device *sdev, u8 tm_flags)
>   {
> -	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
> +	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
>   	struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
> -	struct fc_port *rport = zfcp_sdev->port->rport;

This smells very odd: fc_port instead of fc_*r*port.
Looks like this was introduced buggy in "[PATCH 15/47] 
scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh" and 
should be avoided for bisectability.

> +	struct fc_rport *rport = zfcp_sdev->port->rport;

> -		fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags);
> +		fsf_req = zfcp_fsf_fcp_task_mgmt(sdev, tm_flags);

>   static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
>   {
> -	return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
> +	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
>   }
> 
>   static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
>   {
> -	return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
> +	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_TGT_RESET);
>   }

Won't the target_reset_handler eventually have scsi_target as argument 
and thus we will not have any particular scsi_device to pass anymore 
later in the patch set?

In my patch series, I replaced scsi_cmnd with a mandatory zfcp_port and 
an optional(!) scsi_device for the TMF call chains in zfcp.
I thought scsi_device must be optional because it only exists for LUN 
reset but not for target reset.
Does this make sense?

-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for host reset
  2017-07-24 16:18   ` Steffen Maier
@ 2017-07-24 18:01     ` Hannes Reinecke
  0 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-07-24 18:01 UTC (permalink / raw)
  To: Steffen Maier, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke,
	Benjamin Block

On 07/24/2017 06:18 PM, Steffen Maier wrote:
> Hi Hannes,
> 
> unfortunately I only realized now by accident that there's stuff to
> review. Would be nice to send it also explicitly to driver maintainers
> in addition to the list.
> 
Well, the entire patchset got send as an RFC anyway, and as such I
didn't include all the individual driver maintainers.
But will be doing so for the actual patchset.

> Since you've asked for this multiple times, I happened to just now code
> a patch series of 6 patches in order to decouple zfcp from scsi_cmnd for
> device, target, and host reset.
> 
Oh, cool. That's precisely what I need.

> While I provide some review comments below, I think it might be clearer
> and easier to review if you would rebase your series on top of my
> decoupling.
> 
Sure. Get me the patches and I'll be doing it :-)

> Let me know how urgent you'd like to see my code. I planned to send it
> as RFC soon anyway. However, it hasn't seen any function testing yet. If
> you don't care, let me know and I can send it.
> 
At this stage I don't really care; the idea is to get the preliminary
patches in (preferably before the next merge window), so that the actual
patch to modify SCSI EH syntax doesn't have to modify the drivers
themselves, only the calling sequence.

> On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
>> When issuing a host reset we should be waiting for all
>> ports to become unblocked; just waiting for one might
>> be resulting in host reset to return too early.
>>
>> Signed-off-by: Hannes Reinecke <hare@suse.com>
>> ---
>>   drivers/s390/scsi/zfcp_scsi.c | 27 +++++++++++++++++++++++----
>>   1 file changed, 23 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/s390/scsi/zfcp_scsi.c
>> b/drivers/s390/scsi/zfcp_scsi.c
>> index 0678cf7..3d18659 100644
>> --- a/drivers/s390/scsi/zfcp_scsi.c
>> +++ b/drivers/s390/scsi/zfcp_scsi.c
>> @@ -311,13 +311,32 @@ static int
>> zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
>>
>>   static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
>>   {
>> -    struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
>> -    struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
>> -    int ret;
>> +    struct Scsi_Host *host = scpnt->device->host;
>> +    struct zfcp_adapter *adapter = (struct zfcp_adapter
>> *)host->hostdata[0];
>> +    int ret = 0;
>> +    unsigned long flags;
>> +    struct zfcp_port *port;
>>
>>       zfcp_erp_adapter_reopen(adapter, 0, "schrh_1");
>>       zfcp_erp_wait(adapter);
>> -    ret = fc_block_scsi_eh(scpnt);
>> +retry_rport_blocked:
>> +    spin_lock_irqsave(host->host_lock, flags);
> 
> missing read_lock(&adapter->port_list_lock);
> 
> Hm, well, I have to think about lock ordering, because my patch has the
> port_list as outer loop and inside it calls fc_block_scsi_eh (also
> modified with fc_rport as argument).
> If there's any other location taking both locks we better get them in
> the same order.
> 
In general I'm not terribly happy with this; after all, there is no
guarantee that the rport list after host reset is identical to the list
prior to it; in extremis we could even end up with no rports whatsoever.
In which case we wouldn't have anything to synchronize upon, leaving
host reset in a somewhat dubious state.
I'd be far happier if we could have a synchronisation point independent
on the rport states; then this problem wouldn't occur.
(And rports would be handled separately via the dev_loss_tmo mechanism
anyway, so it wouldn't matter if the rports are still recovering after
host reset returned.)

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler()
  2017-06-28  8:32 ` [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler() Hannes Reinecke
@ 2017-07-24 18:10   ` Steffen Maier
  2017-07-25 14:19     ` Hannes Reinecke
  0 siblings, 1 reply; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 18:10 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke


On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
> The target reset function should only depend on the scsi target,
> not the scsi command.
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---

>   drivers/s390/scsi/zfcp_scsi.c               | 20 ++++++++++--

>   drivers/scsi/scsi_debug.c                   | 21 ++++---------
>   drivers/scsi/scsi_error.c                   |  5 +--

>   include/scsi/scsi_host.h                    |  2 +-

>   33 files changed, 214 insertions(+), 174 deletions(-)

> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index dd7bea0..92a3902 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -309,9 +309,25 @@ static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
>   	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
>   }
> 
> -static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
> +/*
> + * Note: We need to select a LUN as the storage array doesn't
> + * necessarily supports LUN 0 and might refuse the target reset.
> + */

Do you have any real experience with targets regarding this?

Did you even try this and it failed?
If so, how did it fail?

It seems other drivers hardcode LUN 0 for target reset [see below].

At least you made a similar loop to search for a suitable "victim" 
scsi_device with some other driver changes below, so zfcp is not the 
only one.

In fact, this is one of my open questions in my own patch set:
Is the TMF flag in the FCP_CMND IU sufficient or does the transmission 
path require a valid FCP_LUN also in the same IU even for a target reset.

> +static int zfcp_scsi_eh_target_reset_handler(struct scsi_target *starget)
>   {
> -	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_TGT_RESET);
> +	struct fc_rport *rport = starget_to_rport(starget);
> +	struct Scsi_Host *shost = rport_to_shost(rport);
> +	struct scsi_device *sdev = NULL, *tmp_sdev;
> +

In "[PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for host reset" you 
introduced a shost lock, but here you did not?

Does the midlayer already hold an shost lock when calling any of these 
eh callbacks?

Not sure if that's the corresponding part of 
Documentation/scsi/scsi_eh.txt (but even if, I don't understand who's 
supposed to have the shost lock):
> [2-1-2] Flow of scmds through EH
>  2. EH starts
>     ACTION: move all scmds to EH's local eh_work_q.  shost->eh_cmd_q
> 	    is cleared.
>     LOCKING: shost->host_lock (not strictly necessary, just for
>              consistency)
> [2-2-3] Things to consider
>  - For consistency, when accessing/modifying shost data structure,
>    grab shost->host_lock.


> +	shost_for_each_device(tmp_sdev, shost) {
> +		if (tmp_sdev->id == starget->id) {
> +			sdev = tmp_sdev;
> +			break;
> +		}
> +	}
> +	if (!sdev)
> +		return FAILED;
> +	return zfcp_task_mgmt_function(sdev, FCP_TMF_TGT_RESET);
>   }

Ah, this "solves" the problem of needing a scsi_device even though we 
only get scsi_target as scope argument.

> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
> index 107c0f6..573bd43 100644
> --- a/drivers/scsi/lpfc/lpfc_scsi.c
> +++ b/drivers/scsi/lpfc/lpfc_scsi.c
> @@ -5226,16 +5226,16 @@ void lpfc_poll_timeout(unsigned long ptr)
>    *  0x2002 - Success
>    **/
>   static int
> -lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
> +lpfc_target_reset_handler(struct scsi_target *starget)
>   {
> -	struct Scsi_Host  *shost = cmnd->device->host;
> +	struct fc_rport *rport = starget_to_rport(starget);
> +	struct Scsi_Host  *shost = rport_to_shost(rport);
>   	struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
>   	struct lpfc_rport_data *rdata;
>   	struct lpfc_nodelist *pnode;
> -	unsigned tgt_id = cmnd->device->id;
> -	uint64_t lun_id = cmnd->device->lun;
> +	unsigned tgt_id = starget->id;
> +	uint64_t lun_id = 0;



> diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> index f990ab4d..db40ddf 100644
> --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
> +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c

> @@ -4038,42 +4040,43 @@ int megasas_reset_target_fusion(struct scsi_cmnd *scmd)

> +	shost_for_each_device(sdev, shost) {
> +		if (!sdev->hostdata)
> +			continue;
> +		mr_device_priv_data = sdev->hostdata;
> +		if (mr_device_priv_data->is_tm_capable) {
> +			devhandle = megasas_get_tm_devhandle(sdev);
> +			break;
> +		}
> +	}
> +

> -	devhandle = megasas_get_tm_devhandle(scmd->device);

>   	ret = megasas_issue_tm(instance, devhandle,
> -			scmd->device->channel, scmd->device->id, 0,
> +			starget->channel, starget->id, 0,
>   			MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);

The called function seems to internally have hardcoded LUN 0:

static int
megasas_issue_tm(struct megasas_instance *instance, u16 device_handle,
	uint channel, uint id, u16 smid_task, u8 type)
{
...
	mpi_request->LUN[1] = 0;

> -static int pmcraid_eh_target_reset_handler(struct scsi_cmnd *scmd)
> +static int pmcraid_eh_target_reset_handler(struct scsi_target *starget)
>   {
> -	scmd_printk(KERN_INFO, scmd,
> +	struct Scsi_Host *shost = dev_to_shost(&starget->dev);
> +	struct scsi_device *scsi_dev = NULL, *tmp;
> +
> +	shost_for_each_device(tmp, shost) {
> +		if ((tmp->channel == starget->channel) &&
> +		    (tmp->id == starget->id)) {
> +			scsi_dev = tmp;
> +			break;
> +		}
> +	}
> +	if (!scsi_dev)
> +		return FAILED;
> +	sdev_printk(KERN_INFO, scsi_dev,
>   		    "Doing target reset due to an I/O command timeout.\n");
> -	return pmcraid_reset_device(scmd->device,
> +	return pmcraid_reset_device(scsi_dev,
>   				    PMCRAID_INTERNAL_TIMEOUT,
>   				    RESET_DEVICE_TARGET);
>   }



> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 1e89598..37e511f 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -3809,39 +3809,30 @@ static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
>   	return SUCCESS;
>   }
> 
> -static int scsi_debug_target_reset(struct scsi_cmnd *SCpnt)
> +static int scsi_debug_target_reset(struct scsi_target *starget)
>   {
> +	struct Scsi_Host *hp = dev_to_shost(&starget->dev);

> -	if (!hp)
> -		goto lie;

Does dev_to_shost(&starget->dev) in this particular case always return 
!=NULL?
I would hope that starget always has an shost as some ancestor in driver 
core.

Other than that question, the scsi_debug change looks good.

(Although I don't understand how this function actually triggers the 
forgetting of pending requests on the scope in addition to setting the 
unit attention bit, but then again I'm not familiar with scsi_debug 
internals.)

> +		starget_printk(KERN_INFO, starget, "%s\n", __func__);
>   	sdbg_host = *(struct sdebug_host_info **)shost_priv(hp);
>   	if (sdbg_host) {
>   		list_for_each_entry(devip,
>   				    &sdbg_host->dev_info_list,
>   				    dev_list)
> -			if (devip->target == sdp->id) {
> +			if (devip->target == starget->id) {
>   				set_bit(SDEBUG_UA_BUS_RESET, devip->uas_bm);
>   				++k;
>   			}
>   	}
>   	if (SDEBUG_OPT_RESET_NOISE & sdebug_opts)
> -		sdev_printk(KERN_INFO, sdp,
> +		starget_printk(KERN_INFO, starget,
>   			    "%s: %d device(s) found in target\n", __func__, k);
> -lie:
> +
>   	return SUCCESS;
>   }
> 
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index 9dd51ed..368a961 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -810,14 +810,15 @@ static int scsi_try_target_reset(struct scsi_cmnd *scmd)
>   	int rtn;
>   	struct Scsi_Host *host = scmd->device->host;
>   	struct scsi_host_template *hostt = host->hostt;
> +	struct scsi_target *starget = scsi_target(scmd->device);
> 
>   	if (!hostt->eh_target_reset_handler)
>   		return FAILED;
> 
> -	rtn = hostt->eh_target_reset_handler(scmd);
> +	rtn = hostt->eh_target_reset_handler(starget);
>   	if (rtn == SUCCESS) {
>   		spin_lock_irqsave(host->host_lock, flags);
> -		__starget_for_each_device(scsi_target(scmd->device), NULL,
> +		__starget_for_each_device(starget, NULL,
>   					  __scsi_report_device_reset);
>   		spin_unlock_irqrestore(host->host_lock, flags);
>   	}

looks good

> diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
> index 0c5ce78..33bc523 100644
> --- a/include/scsi/scsi_host.h
> +++ b/include/scsi/scsi_host.h
> @@ -146,7 +146,7 @@ struct scsi_host_template {
>   	 */
>   	int (* eh_abort_handler)(struct scsi_cmnd *);
>   	int (* eh_device_reset_handler)(struct scsi_cmnd *);
> -	int (* eh_target_reset_handler)(struct scsi_cmnd *);
> +	int (* eh_target_reset_handler)(struct scsi_target *);
>   	int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
>   	int (* eh_host_reset_handler)(struct Scsi_Host *);
> 

looks good



-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 46/47] scsi: Move eh_device_reset_handler() to use scsi_device as argument
  2017-06-28  8:33 ` [PATCH 46/47] scsi: Move eh_device_reset_handler() to use scsi_device as argument Hannes Reinecke
@ 2017-07-24 18:42   ` Steffen Maier
  0 siblings, 0 replies; 89+ messages in thread
From: Steffen Maier @ 2017-07-24 18:42 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

sparse review comments below...

On 06/28/2017 10:33 AM, Hannes Reinecke wrote:
> When resetting a device we shouldn't depend on an existing SCSI
> device, so use 'struct scsi_device' as argument for
> eh_device_reset_handler().
> 
> Signed-off-by: Hannes Reinecke <hare@suse.com>
> ---
>   Documentation/scsi/scsi_eh.txt                  |  2 +-
>   Documentation/scsi/scsi_mid_low_api.txt         |  4 +--

>   drivers/s390/scsi/zfcp_scsi.c                   |  4 +--

>   drivers/scsi/scsi_debug.c                       | 18 ++++++-------
>   drivers/scsi/scsi_error.c                       | 35 +++++++++++++++++--------

>   include/scsi/scsi_host.h                        |  2 +-
>   60 files changed, 287 insertions(+), 307 deletions(-)
> 
> diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
> index cb9f4bc22..f8a6566 100644
> --- a/Documentation/scsi/scsi_eh.txt
> +++ b/Documentation/scsi/scsi_eh.txt
> @@ -206,7 +206,7 @@ hostt EH callbacks.  Callbacks may be omitted and omitted ones are
>   considered to fail always.
> 
>   int (* eh_abort_handler)(struct scsi_cmnd *);
> -int (* eh_device_reset_handler)(struct scsi_cmnd *);
> +int (* eh_device_reset_handler)(struct scsi_device *);
>   int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
>   int (* eh_host_reset_handler)(struct Scsi_Host *);
> 
> diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt
> index e2609a63..28dc029 100644
> --- a/Documentation/scsi/scsi_mid_low_api.txt
> +++ b/Documentation/scsi/scsi_mid_low_api.txt
> @@ -874,7 +874,7 @@ Details:
> 
>   /**
>    *      eh_device_reset_handler - issue SCSI device reset
> - *      @scp: identifies SCSI device to be reset
> + *      @sdev: identifies SCSI device to be reset
>    *
>    *      Returns SUCCESS if command aborted else FAILED
>    *
> @@ -887,7 +887,7 @@ Details:
>    *
>    *      Optionally defined in: LLD
>    **/
> -     int eh_device_reset_handler(struct scsi_cmnd * scp)
> +     int eh_device_reset_handler(struct scsi_device * sdev)
> 
> 
>   /**


> diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
> index 92a3902..23b5a7d 100644
> --- a/drivers/s390/scsi/zfcp_scsi.c
> +++ b/drivers/s390/scsi/zfcp_scsi.c
> @@ -304,9 +304,9 @@ static int zfcp_task_mgmt_function(struct scsi_device *sdev, u8 tm_flags)
>   	return retval;
>   }
> 
> -static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
> +static int zfcp_scsi_eh_device_reset_handler(struct scsi_device *sdev)
>   {
> -	return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
> +	return zfcp_task_mgmt_function(sdev, FCP_TMF_LUN_RESET);
>   }
> 
>   /*


> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 37e511f..9029500 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -3793,19 +3793,17 @@ static int scsi_debug_abort(struct scsi_cmnd *SCpnt)
>   	return SUCCESS;
>   }
> 
> -static int scsi_debug_device_reset(struct scsi_cmnd * SCpnt)
> +static int scsi_debug_device_reset(struct scsi_device * sdp)
>   {
> +	struct sdebug_dev_info *devip =
> +		(struct sdebug_dev_info *)sdp->hostdata;
> +
>   	++num_dev_resets;
> -	if (SCpnt && SCpnt->device) {
> -		struct scsi_device *sdp = SCpnt->device;
> -		struct sdebug_dev_info *devip =
> -				(struct sdebug_dev_info *)sdp->hostdata;
> 
> -		if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
> -			sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
> -		if (devip)
> -			set_bit(SDEBUG_UA_POR, devip->uas_bm);
> -	}
> +	if (SDEBUG_OPT_ALL_NOISE & sdebug_opts)
> +		sdev_printk(KERN_INFO, sdp, "%s\n", __func__);
> +	if (devip)
> +		set_bit(SDEBUG_UA_POR, devip->uas_bm);
>   	return SUCCESS;
>   }
> 
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index 368a961..4a7fe97f 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -844,7 +844,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
>   	if (!hostt->eh_device_reset_handler)
>   		return FAILED;
> 
> -	rtn = hostt->eh_device_reset_handler(scmd);
> +	rtn = hostt->eh_device_reset_handler(scmd->device);
>   	if (rtn == SUCCESS)
>   		__scsi_report_device_reset(scmd->device, NULL);
>   	return rtn;

up to here it looks good,
however ...

> @@ -1106,6 +1106,7 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
>    * scsi_eh_finish_cmd - Handle a cmd that eh is finished with.

__scsi_eh_finish_cmd  ?

>    * @scmd:	Original SCSI cmd that eh has finished.
>    * @done_q:	Queue for processed commands.
> + * @result:	Final command status to be set
>    *
>    * Notes:
>    *    We don't want to use the normal command completion while we are are

Did this hunk slip in accidentally?
I don't see a new additional argument result being introduced with 
either the new __scsi_eh_finish_cmd() nor the old scsi_eh_finish_cmd().
However, the former __scsi_eh_finish_cmd() seems to have an additional 
argument @host_byte:. Maybe that should go where @result: is above, 
because the old kernel doc now belongs to the new __scsi_eh_finish_cmd().

But then you'd also need to change the function name in the kernel doc?!

> @@ -1114,10 +1115,18 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
>    *    keep a list of pending commands for final completion, and once we
>    *    are ready to leave error handling we handle completion for real.
>    */
> -void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
> +void __scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q,
> +			int host_byte)

Should new internal helper function be declared static?

>   {
> +	if (host_byte)
> +		set_host_byte(scmd, host_byte);
>   	list_move_tail(&scmd->eh_entry, done_q);
>   }
> +
> +void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
> +{
> +	__scsi_eh_finish_cmd(scmd, done_q, 0);
> +}
>   EXPORT_SYMBOL(scsi_eh_finish_cmd);
> 
>   /**
> @@ -1284,7 +1293,8 @@ static int scsi_eh_test_devices(struct list_head *cmd_list,
>   				if (finish_cmds &&
>   				    (try_stu ||
>   				     scsi_eh_action(scmd, SUCCESS) == SUCCESS))
> -					scsi_eh_finish_cmd(scmd, done_q);
> +					__scsi_eh_finish_cmd(scmd, done_q,
> +							     DID_RESET);
>   				else
>   					list_move_tail(&scmd->eh_entry, work_q);
>   			}
> @@ -1429,8 +1439,9 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
>   							 work_q, eh_entry) {
>   					if (scmd->device == sdev &&
>   					    scsi_eh_action(scmd, rtn) != FAILED)
> -						scsi_eh_finish_cmd(scmd,
> -								   done_q);
> +						__scsi_eh_finish_cmd(scmd,
> +								     done_q,
> +								     DID_RESET);
>   				}
>   			}
>   		} else {
> @@ -1498,7 +1509,8 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
>   			if (rtn == SUCCESS)
>   				list_move_tail(&scmd->eh_entry, &check_list);
>   			else if (rtn == FAST_IO_FAIL)
> -				scsi_eh_finish_cmd(scmd, done_q);
> +				__scsi_eh_finish_cmd(scmd, done_q,
> +						     DID_TRANSPORT_DISRUPTED);
>   			else
>   				/* push back on work queue for further processing */
>   				list_move(&scmd->eh_entry, work_q);
> @@ -1563,8 +1575,9 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
>   			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
>   				if (channel == scmd_channel(scmd)) {
>   					if (rtn == FAST_IO_FAIL)
> -						scsi_eh_finish_cmd(scmd,
> -								   done_q);
> +						__scsi_eh_finish_cmd(scmd,
> +								     done_q,
> +								     DID_TRANSPORT_DISRUPTED);
>   					else
>   						list_move_tail(&scmd->eh_entry,
>   							       &check_list);
> @@ -1607,9 +1620,9 @@ static int scsi_eh_host_reset(struct Scsi_Host *shost,
>   		if (rtn == SUCCESS) {
>   			list_splice_init(work_q, &check_list);
>   		} else if (rtn == FAST_IO_FAIL) {
> -			list_for_each_entry_safe(scmd, next, work_q, eh_entry) {
> -					scsi_eh_finish_cmd(scmd, done_q);
> -			}
> +			list_for_each_entry_safe(scmd, next, work_q, eh_entry)
> +				__scsi_eh_finish_cmd(scmd, done_q,
> +						     DID_TRANSPORT_DISRUPTED);

I can somewhat imagine why you set DID_TRANSPORT_DISRUPTED for the cases 
above where the eh callback told us FAST_IO_FAIL.
However, here you (now) seem to do it unconditionally. As a result this 
seems to render all attempts to return either a proper FAST_IO_FAIL or 
SUCCESS from a host_reset_handler() futile?

>   		} else {
>   			SCSI_LOG_ERROR_RECOVERY(3,
>   				shost_printk(KERN_INFO, shost,

How is this related to just changing the callback argument?

Haven't we previously set the host_byte to anything?

Is the above part rather an independent change or even fix which should 
live in a separate topical commit explaining why and what it does?

(I don't understand especially the DID_RESET cases.)


> diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
> index 8b93197..bc97e41 100644
> --- a/drivers/scsi/virtio_scsi.c
> +++ b/drivers/scsi/virtio_scsi.c
> @@ -681,26 +681,26 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd)
>   	return ret;
>   }
> 
> -static int virtscsi_device_reset(struct scsi_cmnd *sc)
> +static int virtscsi_device_reset(struct scsi_device *sdev)
>   {
> -	struct virtio_scsi *vscsi = shost_priv(sc->device->host);
> +	struct virtio_scsi *vscsi = shost_priv(sdev->host);
>   	struct virtio_scsi_cmd *cmd;
> 
> -	sdev_printk(KERN_INFO, sc->device, "device reset\n");
> +	sdev_printk(KERN_INFO, sdev, "device reset\n");
>   	cmd = mempool_alloc(virtscsi_cmd_pool, GFP_NOIO);
>   	if (!cmd)
>   		return FAILED;
> 
>   	memset(cmd, 0, sizeof(*cmd));
> -	cmd->sc = sc;
> +	cmd->sc = NULL;

I hope we are protected to never land in virtscsi_complete_cmd() with 
cmd->sc==NULL, not even e.g. if the virtio queue gets hot unplugged the 
hard way in parallel (forcing some completion to drain).
I'm thinking of commit 773c7220e22d193e5667c352fcbf8d47eefc817f
("scsi: virtio_scsi: Reject commands when virtqueue is broken").

>   	cmd->req.tmf = (struct virtio_scsi_ctrl_tmf_req){
>   		.type = VIRTIO_SCSI_T_TMF,
>   		.subtype = cpu_to_virtio32(vscsi->vdev,
>   					     VIRTIO_SCSI_T_TMF_LOGICAL_UNIT_RESET),
>   		.lun[0] = 1,
> -		.lun[1] = sc->device->id,
> -		.lun[2] = (sc->device->lun >> 8) | 0x40,
> -		.lun[3] = sc->device->lun & 0xff,
> +		.lun[1] = sdev->id,
> +		.lun[2] = (sdev->lun >> 8) | 0x40,
> +		.lun[3] = sdev->lun & 0xff,
>   	};
>   	return virtscsi_tmf(vscsi, cmd);
>   }


> diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
> index 33bc523..7095076 100644
> --- a/include/scsi/scsi_host.h
> +++ b/include/scsi/scsi_host.h
> @@ -145,7 +145,7 @@ struct scsi_host_template {
>   	 * Status: REQUIRED	(at least one of them)
>   	 */
>   	int (* eh_abort_handler)(struct scsi_cmnd *);
> -	int (* eh_device_reset_handler)(struct scsi_cmnd *);
> +	int (* eh_device_reset_handler)(struct scsi_device *);
>   	int (* eh_target_reset_handler)(struct scsi_target *);
>   	int (* eh_bus_reset_handler)(struct Scsi_Host *, int);
>   	int (* eh_host_reset_handler)(struct Scsi_Host *);
> 

anything else, that I quoted but did not comment, looks good


-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function()
  2017-07-24 17:15   ` Steffen Maier
@ 2017-07-25 14:14     ` Hannes Reinecke
  0 siblings, 0 replies; 89+ messages in thread
From: Hannes Reinecke @ 2017-07-25 14:14 UTC (permalink / raw)
  To: Steffen Maier, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

On 07/24/2017 07:15 PM, Steffen Maier wrote:
> 
> 
> On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
>> zfcp_task_mgmt_function() is only used for lun and device reset,
>> so it should be using the scsi device as an argument, not the
>> scsi command.
>>
>> Signed-off-by: Hannes Reinecke <hare@suse.com>
>> ---
>>   drivers/s390/scsi/zfcp_ext.h  |  2 +-
>>   drivers/s390/scsi/zfcp_fc.h   |  9 +--------
>>   drivers/s390/scsi/zfcp_fsf.c  | 21 +++++++++++----------
>>   drivers/s390/scsi/zfcp_scsi.c | 12 ++++++------
>>   4 files changed, 19 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
>> index 57f1d4a..64d4db7 100644
>> --- a/drivers/s390/scsi/zfcp_ext.h
>> +++ b/drivers/s390/scsi/zfcp_ext.h
>> @@ -117,7 +117,7 @@ extern int zfcp_fsf_send_els(struct zfcp_adapter
>> *, u32,
>>                    struct zfcp_fsf_ct_els *, unsigned int);
>>   extern int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *);
>>   extern void zfcp_fsf_req_free(struct zfcp_fsf_req *);
>> -extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd
>> *, u8);
>> +extern struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device
>> *, u8);
>>   extern struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd
>> *);
>>   extern void zfcp_fsf_reqid_check(struct zfcp_qdio *, int);
>>
>> diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h
>> index df2b541..f08eaf9 100644
>> --- a/drivers/s390/scsi/zfcp_fc.h
>> +++ b/drivers/s390/scsi/zfcp_fc.h
>> @@ -206,19 +206,12 @@ struct zfcp_fc_wka_ports {
>>    * zfcp_fc_scsi_to_fcp - setup FCP command with data from scsi_cmnd
>>    * @fcp: fcp_cmnd to setup
>>    * @scsi: scsi_cmnd where to get LUN, task attributes/flags and CDB
>> - * @tm: task management flags to setup task management command
>>    */
>>   static inline
>> -void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi,
>> -             u8 tm_flags)
>> +void zfcp_fc_scsi_to_fcp(struct fcp_cmnd *fcp, struct scsi_cmnd *scsi)
>>   {
>>       int_to_scsilun(scsi->device->lun, (struct scsi_lun *)
>> &fcp->fc_lun);
>>
>> -    if (unlikely(tm_flags)) {
>> -        fcp->fc_tm_flags = tm_flags;
>> -        return;
>> -    }
>> -
>>       fcp->fc_pri_ta = FCP_PTA_SIMPLE;
>>
>>       if (scsi->sc_data_direction == DMA_FROM_DEVICE)
> 
> When I wrote my zfcp decoupling patch series I did a lot of git history
> research in order to double check if my changes are OK.
> 
> Here, I figured that I'd like to separately revert commit 2443c8b23aea
> ("[SCSI] zfcp: Merge FCP task management setup with regular FCP command
> setup"), because this introduced a dependency on the unsuitable SCSI
> command for scsi_eh / TMF. Even though it was one of the first commits I
> posted upstream as newbie zfcp maintainer... little did I know.
> 
Okay, do.

>> diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
>> index 27ff38f..c4bd3d4 100644
>> --- a/drivers/s390/scsi/zfcp_fsf.c
>> +++ b/drivers/s390/scsi/zfcp_fsf.c
>> @@ -2036,10 +2036,9 @@ static void zfcp_fsf_req_trace(struct
>> zfcp_fsf_req *req, struct scsi_cmnd *scsi)
> 
>> -static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req)
>> +static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req,
>> +                    struct scsi_device *sdev)
> 
> 
>> @@ -2120,7 +2119,7 @@ static void zfcp_fsf_fcp_cmnd_handler(struct
>> zfcp_fsf_req *req)
> 
>> -    zfcp_fsf_fcp_handler_common(req);
>> +    zfcp_fsf_fcp_handler_common(req, scpnt->device);
> 
>> @@ -2296,8 +2295,9 @@ static void
>> zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
>>   {
> 
>> +    struct scsi_device *sdev = req->data;
>>
>> -    zfcp_fsf_fcp_handler_common(req);
>> +    zfcp_fsf_fcp_handler_common(req, sdev);
> 
> Moving the resolving of req->data into the callers of
> zfcp_fsf_fcp_handler_common() I did the same way in my own patch series.
> 
:-)

>> @@ -2313,12 +2313,12 @@ static void
>> zfcp_fsf_fcp_task_mgmt_handler(struct zfcp_fsf_req *req)
> 
>> -struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
>> +struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
>>                           u8 tm_flags)
> 
>> @@ -2338,7 +2338,7 @@ struct zfcp_fsf_req
>> *zfcp_fsf_fcp_task_mgmt(struct scsi_cmnd *scmnd,
> 
>> -    req->data = scmnd;
>> +    req->data = sdev;
> 
>> diff --git a/drivers/s390/scsi/zfcp_scsi.c
>> b/drivers/s390/scsi/zfcp_scsi.c
>> index 5fada93..dd7bea0 100644
>> --- a/drivers/s390/scsi/zfcp_scsi.c
>> +++ b/drivers/s390/scsi/zfcp_scsi.c
>> @@ -259,17 +259,17 @@ static void zfcp_scsi_forget_cmnds(struct
>> zfcp_scsi_dev *zsdev, u8 tm_flags)
> 
>> -static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
>> +static int zfcp_task_mgmt_function(struct scsi_device *sdev, u8
>> tm_flags)
>>   {
>> -    struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
>> +    struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
>>       struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
>> -    struct fc_port *rport = zfcp_sdev->port->rport;
> 
> This smells very odd: fc_port instead of fc_*r*port.
> Looks like this was introduced buggy in "[PATCH 15/47]
> scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh" and
> should be avoided for bisectability.
> 
Yes, indeed. Will be checking.

>> +    struct fc_rport *rport = zfcp_sdev->port->rport;
> 
>> -        fsf_req = zfcp_fsf_fcp_task_mgmt(scpnt, tm_flags);
>> +        fsf_req = zfcp_fsf_fcp_task_mgmt(sdev, tm_flags);
> 
>>   static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
>>   {
>> -    return zfcp_task_mgmt_function(scpnt, FCP_TMF_LUN_RESET);
>> +    return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
>>   }
>>
>>   static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
>>   {
>> -    return zfcp_task_mgmt_function(scpnt, FCP_TMF_TGT_RESET);
>> +    return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_TGT_RESET);
>>   }
> 
> Won't the target_reset_handler eventually have scsi_target as argument
> and thus we will not have any particular scsi_device to pass anymore
> later in the patch set?
> 
> In my patch series, I replaced scsi_cmnd with a mandatory zfcp_port and
> an optional(!) scsi_device for the TMF call chains in zfcp.
> I thought scsi_device must be optional because it only exists for LUN
> reset but not for target reset.
> Does this make sense?
> 
Perfectly.
There are some drivers where I did a similar trick.
So I'd be happy to have a look at your patches, and rebase my series on
top of that.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler()
  2017-07-24 18:10   ` Steffen Maier
@ 2017-07-25 14:19     ` Hannes Reinecke
  2017-08-02 16:52       ` Steffen Maier
  0 siblings, 1 reply; 89+ messages in thread
From: Hannes Reinecke @ 2017-07-25 14:19 UTC (permalink / raw)
  To: Steffen Maier, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

On 07/24/2017 08:10 PM, Steffen Maier wrote:
> 
> On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
>> The target reset function should only depend on the scsi target,
>> not the scsi command.
>>
>> Signed-off-by: Hannes Reinecke <hare@suse.com>
>> ---
> 
>>   drivers/s390/scsi/zfcp_scsi.c               | 20 ++++++++++--
> 
>>   drivers/scsi/scsi_debug.c                   | 21 ++++---------
>>   drivers/scsi/scsi_error.c                   |  5 +--
> 
>>   include/scsi/scsi_host.h                    |  2 +-
> 
>>   33 files changed, 214 insertions(+), 174 deletions(-)
> 
>> diff --git a/drivers/s390/scsi/zfcp_scsi.c
>> b/drivers/s390/scsi/zfcp_scsi.c
>> index dd7bea0..92a3902 100644
>> --- a/drivers/s390/scsi/zfcp_scsi.c
>> +++ b/drivers/s390/scsi/zfcp_scsi.c
>> @@ -309,9 +309,25 @@ static int
>> zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
>>       return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
>>   }
>>
>> -static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
>> +/*
>> + * Note: We need to select a LUN as the storage array doesn't
>> + * necessarily supports LUN 0 and might refuse the target reset.
>> + */
> 
> Do you have any real experience with targets regarding this?
> 
> Did you even try this and it failed?
> If so, how did it fail?
> 
Hehe.

Actually, it was _you_ (well, not you personally, but the zfcp
maintainer at that time) who insisted on _not_ having to rely on LUN 0,
as that LUN might not be available on non-NPIV setups.
In the same vein he argued that we should be using the WLUN here.

> It seems other drivers hardcode LUN 0 for target reset [see below].
> 
> At least you made a similar loop to search for a suitable "victim"
> scsi_device with some other driver changes below, so zfcp is not the
> only one.
> 
> In fact, this is one of my open questions in my own patch set:
> Is the TMF flag in the FCP_CMND IU sufficient or does the transmission
> path require a valid FCP_LUN also in the same IU even for a target reset.
> 
Technically, you need an IT nexus for the target reset.
As the SCSI target is somewhat under-represented in the linux SCSI stack
typically it's easier to use a scsi device for this, and derive the IT
nexus from there.
And target reset is a tad tricky anyway; it got deprecated with later
SCSI releases (SPC-3?), so chances is that it doesn't do anything.

(You could do yourself a favour and enquire with your friendly array
vendors if _they_ support target reset; I have a strong feeling that
they don't. In which case you might as well drop it completely, and
target reset doing an IT nexus reset.)

>> +static int zfcp_scsi_eh_target_reset_handler(struct scsi_target
>> *starget)
>>   {
>> -    return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_TGT_RESET);
>> +    struct fc_rport *rport = starget_to_rport(starget);
>> +    struct Scsi_Host *shost = rport_to_shost(rport);
>> +    struct scsi_device *sdev = NULL, *tmp_sdev;
>> +
> 
> In "[PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for host reset" you
> introduced a shost lock, but here you did not?
> 
> Does the midlayer already hold an shost lock when calling any of these
> eh callbacks?
> 
Yes.

> Not sure if that's the corresponding part of
> Documentation/scsi/scsi_eh.txt (but even if, I don't understand who's
> supposed to have the shost lock):
>> [2-1-2] Flow of scmds through EH
>>  2. EH starts
>>     ACTION: move all scmds to EH's local eh_work_q.  shost->eh_cmd_q
>>         is cleared.
>>     LOCKING: shost->host_lock (not strictly necessary, just for
>>              consistency)
>> [2-2-3] Things to consider
>>  - For consistency, when accessing/modifying shost data structure,
>>    grab shost->host_lock.
> 
> 
>> +    shost_for_each_device(tmp_sdev, shost) {
>> +        if (tmp_sdev->id == starget->id) {
>> +            sdev = tmp_sdev;
>> +            break;
>> +        }
>> +    }
>> +    if (!sdev)
>> +        return FAILED;
>> +    return zfcp_task_mgmt_function(sdev, FCP_TMF_TGT_RESET);
>>   }
> 
> Ah, this "solves" the problem of needing a scsi_device even though we
> only get scsi_target as scope argument.
> 
>> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c
>> b/drivers/scsi/lpfc/lpfc_scsi.c
>> index 107c0f6..573bd43 100644
>> --- a/drivers/scsi/lpfc/lpfc_scsi.c
>> +++ b/drivers/scsi/lpfc/lpfc_scsi.c
>> @@ -5226,16 +5226,16 @@ void lpfc_poll_timeout(unsigned long ptr)
>>    *  0x2002 - Success
>>    **/
>>   static int
>> -lpfc_target_reset_handler(struct scsi_cmnd *cmnd)
>> +lpfc_target_reset_handler(struct scsi_target *starget)
>>   {
>> -    struct Scsi_Host  *shost = cmnd->device->host;
>> +    struct fc_rport *rport = starget_to_rport(starget);
>> +    struct Scsi_Host  *shost = rport_to_shost(rport);
>>       struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata;
>>       struct lpfc_rport_data *rdata;
>>       struct lpfc_nodelist *pnode;
>> -    unsigned tgt_id = cmnd->device->id;
>> -    uint64_t lun_id = cmnd->device->lun;
>> +    unsigned tgt_id = starget->id;
>> +    uint64_t lun_id = 0;
> 
> 
> 
>> diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c
>> b/drivers/scsi/megaraid/megaraid_sas_fusion.c
>> index f990ab4d..db40ddf 100644
>> --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
>> +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
> 
>> @@ -4038,42 +4040,43 @@ int megasas_reset_target_fusion(struct
>> scsi_cmnd *scmd)
> 
>> +    shost_for_each_device(sdev, shost) {
>> +        if (!sdev->hostdata)
>> +            continue;
>> +        mr_device_priv_data = sdev->hostdata;
>> +        if (mr_device_priv_data->is_tm_capable) {
>> +            devhandle = megasas_get_tm_devhandle(sdev);
>> +            break;
>> +        }
>> +    }
>> +
> 
>> -    devhandle = megasas_get_tm_devhandle(scmd->device);
> 
>>       ret = megasas_issue_tm(instance, devhandle,
>> -            scmd->device->channel, scmd->device->id, 0,
>> +            starget->channel, starget->id, 0,
>>               MPI2_SCSITASKMGMT_TASKTYPE_TARGET_RESET);
> 
> The called function seems to internally have hardcoded LUN 0:
> 
> static int
> megasas_issue_tm(struct megasas_instance *instance, u16 device_handle,
>     uint channel, uint id, u16 smid_task, u8 type)
> {
> ...
>     mpi_request->LUN[1] = 0;
> 
Indeed. But that's megaraid_sas specific; other drivers have different
requirements here.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG Nürnberg)

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler()
  2017-07-25 14:19     ` Hannes Reinecke
@ 2017-08-02 16:52       ` Steffen Maier
  0 siblings, 0 replies; 89+ messages in thread
From: Steffen Maier @ 2017-08-02 16:52 UTC (permalink / raw)
  To: Hannes Reinecke, Christoph Hellwig
  Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke

just an intermediate update on storage processing of target reset...

On 07/25/2017 04:19 PM, Hannes Reinecke wrote:
> On 07/24/2017 08:10 PM, Steffen Maier wrote:
>> On 06/28/2017 10:32 AM, Hannes Reinecke wrote:
>>> The target reset function should only depend on the scsi target,
>>> not the scsi command.
>>>
>>> Signed-off-by: Hannes Reinecke <hare@suse.com>
>>> ---
>>
>>>    drivers/s390/scsi/zfcp_scsi.c               | 20 ++++++++++--

>>>    33 files changed, 214 insertions(+), 174 deletions(-)
>>
>>> diff --git a/drivers/s390/scsi/zfcp_scsi.c
>>> b/drivers/s390/scsi/zfcp_scsi.c
>>> index dd7bea0..92a3902 100644
>>> --- a/drivers/s390/scsi/zfcp_scsi.c
>>> +++ b/drivers/s390/scsi/zfcp_scsi.c
>>> @@ -309,9 +309,25 @@ static int
>>> zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
>>>        return zfcp_task_mgmt_function(scpnt->device, FCP_TMF_LUN_RESET);
>>>    }
>>>
>>> -static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
>>> +/*
>>> + * Note: We need to select a LUN as the storage array doesn't
>>> + * necessarily supports LUN 0 and might refuse the target reset.
>>> + */
>>
>> Do you have any real experience with targets regarding this?
>>
>> Did you even try this and it failed?
>> If so, how did it fail?
>>
> Hehe.
> 
> Actually, it was _you_ (well, not you personally, but the zfcp
> maintainer at that time) who insisted on _not_ having to rely on LUN 0,
> as that LUN might not be available on non-NPIV setups.
> In the same vein he argued that we should be using the WLUN here.

Thanks a lot for letting me know!

>> It seems other drivers hardcode LUN 0 for target reset [see below].
>>
>> At least you made a similar loop to search for a suitable "victim"
>> scsi_device with some other driver changes below, so zfcp is not the
>> only one.
>>
>> In fact, this is one of my open questions in my own patch set:
>> Is the TMF flag in the FCP_CMND IU sufficient or does the transmission
>> path require a valid FCP_LUN also in the same IU even for a target reset.
>>
> Technically, you need an IT nexus for the target reset.
> As the SCSI target is somewhat under-represented in the linux SCSI stack
> typically it's easier to use a scsi device for this, and derive the IT
> nexus from there.
> And target reset is a tad tricky anyway; it got deprecated with later
> SCSI releases (SPC-3?), so chances is that it doesn't do anything.
> 
> (You could do yourself a favour and enquire with your friendly array
> vendors if _they_ support target reset; I have a strong feeling that
> they don't. In which case you might as well drop it completely, and
> target reset doing an IT nexus reset.)

# lsscsi
[0:0:0:1073758277]disk    IBM      2107900          .280  /dev/sdc
[0:0:0:1073823813]disk    IBM      2107900          .280  /dev/sda
[0:0:0:1073889349]disk    IBM      2107900          .280  /dev/sdb

With test code I made the following request run into a timeout:

# dd count=1 of=/dev/null if=/dev/sda iflag=direct

> [  633.459218] sd 0:0:0:1073823813: [sda] tag#0 Done: TIMEOUT_ERROR Result: hostbyte=DID_OK driverbyte=DRIVER_OK
> [  633.459267] sd 0:0:0:1073823813: [sda] tag#0 CDB: Read(10) 28 00 00 00 00 00 00 00 01 00
> [  633.459277] sd 0:0:0:1073823813: [sda] tag#0 abort scheduled
> [  633.479364] sd 0:0:0:1073823813: [sda] tag#0 aborting command
> [  633.479382] sd 0:0:0:1073823813: [sda] tag#0 cmd abort failed

More test code makes the abort fail (before even attempting it).

> [  633.479456] scsi host0: scsi_eh_0: waking up 0/1/1
> [  633.479483] scsi host0: scsi_eh_prt_fail_stats: cmds failed: 0, cancel: 1
> [  633.479492] scsi host0: Total of 1 commands on 1 devices require eh work
> [  633.479502] sd 0:0:0:1073823813: scsi_eh_0: Sending BDR
> [  633.479512] sd 0:0:0:1073823813: scsi_eh_0: BDR failed

More test code makes the LUN reset fail (before even attempting it).

> [  633.479519] scsi host0: scsi_eh_0: Sending target reset to target 0
> [  633.483654] sd 0:0:0:1073823813: [sda] tag#0 scsi_eh_done result: 2
> [  633.483729] sd 0:0:0:1073823813: [sda] tag#0 Done: SUCCESS Result: hostbyte=DID_OK driverbyte=DRIVER_OK
> [  633.483736] sd 0:0:0:1073823813: [sda] tag#0 CDB: Test Unit Ready 00 00 00 00 00 00
> [  633.483741] sd 0:0:0:1073823813: [sda] tag#0 Sense Key : Unit Attention [current] 
> [  633.483747] sd 0:0:0:1073823813: [sda] tag#0 Add. Sense: Power on, reset, or bus device reset occurred
> [  633.483753] sd 0:0:0:1073823813: [sda] tag#0 scsi_send_eh_cmnd timeleft: 1000
> [  633.483758] sd 0:0:0:1073823813: [sda] tag#0 scsi_send_eh_cmnd: scsi_eh_completed_normally 2001
> [  633.483764] sd 0:0:0:1073823813: [sda] tag#0 scsi_eh_tur return: 2001
> [  633.484074] sd 0:0:0:1073823813: [sda] tag#0 scsi_eh_done result: 0
> [  633.484093] sd 0:0:0:1073823813: [sda] tag#0 scsi_send_eh_cmnd timeleft: 1000
> [  633.484118] sd 0:0:0:1073823813: [sda] tag#0 scsi_send_eh_cmnd: scsi_eh_completed_normally 2002
> [  633.484124] sd 0:0:0:1073823813: [sda] tag#0 scsi_eh_tur return: 2002
> [  633.484130] sd 0:0:0:1073823813: [sda] tag#0 scsi_eh_0: flush retry cmd
> [  633.484260] scsi host0: waking up host to restart
> [  633.484299] scsi host0: scsi_eh_0: sleeping

The target reset succeeds and scsi_eh finishes.

For the first I/O request to each of the other LUNs behind the same 
target port, I do get UA sense data:

> [  654.479419] sd 0:0:0:1073758277: [sdc] tag#0 Done: NEEDS_RETRY Result: hostbyte=DID_OK driverbyte=DRIVER_OK
> [  654.479429] sd 0:0:0:1073758277: [sdc] tag#0 CDB: Read(10) 28 00 00 00 00 00 00 00 01 00
> [  654.479434] sd 0:0:0:1073758277: [sdc] tag#0 Sense Key : Unit Attention [current] 
> [  654.479439] sd 0:0:0:1073758277: [sdc] tag#0 Add. Sense: Power on, reset, or bus device reset occurred
> [  660.112234] sd 0:0:0:1073889349: [sdb] tag#0 Done: NEEDS_RETRY Result: hostbyte=DID_OK driverbyte=DRIVER_OK
> [  660.112245] sd 0:0:0:1073889349: [sdb] tag#0 CDB: Read(10) 28 00 00 00 00 00 00 00 01 00
> [  660.112250] sd 0:0:0:1073889349: [sdb] tag#0 Sense Key : Unit Attention [current] 
> [  660.112256] sd 0:0:0:1073889349: [sdb] tag#0 Add. Sense: Power on, reset, or bus device reset occurred

 From this pending UA on the relevant scope, I conclude that DS8000 does 
handle target reset.
Therefore, I'd like to keep our eh handler code for the time being.

-- 
Mit freundlichen Grüßen / Kind regards
Steffen Maier

Linux on z Systems Development

IBM Deutschland Research & Development GmbH
Vorsitzende des Aufsichtsrats: Martina Koederitz
Geschaeftsfuehrung: Dirk Wittkopp
Sitz der Gesellschaft: Boeblingen
Registergericht: Amtsgericht Stuttgart, HRB 243294

^ permalink raw reply	[flat|nested] 89+ messages in thread

* Re: [PATCH 00/47] SCSI EH argument reshuffle part II
  2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
                   ` (47 preceding siblings ...)
  2017-06-28 14:06 ` [PATCH 00/47] SCSI EH argument reshuffle part II Christoph Hellwig
@ 2018-01-08 11:26 ` Christoph Hellwig
  48 siblings, 0 replies; 89+ messages in thread
From: Christoph Hellwig @ 2018-01-08 11:26 UTC (permalink / raw)
  To: Hannes Reinecke
  Cc: Christoph Hellwig, Martin K. Petersen, James Bottomley, linux-scsi

On Wed, Jun 28, 2017 at 10:32:26AM +0200, Hannes Reinecke wrote:
> Hi all,
> finally here's the patchset to revamp the SCSI EH callback arguments
> which I promised to do (some years ago ...).

What happened to this series?

^ permalink raw reply	[flat|nested] 89+ messages in thread

end of thread, other threads:[~2018-01-08 11:26 UTC | newest]

Thread overview: 89+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-28  8:32 [PATCH 00/47] SCSI EH argument reshuffle part II Hannes Reinecke
2017-06-28  8:32 ` [PATCH 01/47] aacraid: split off functions to generate reset FIB Hannes Reinecke
2017-06-28  9:07   ` Johannes Thumshirn
2017-06-29 19:59   ` Raghava Aditya Renukunta
2017-06-28  8:32 ` [PATCH 02/47] aacraid: split off host reset Hannes Reinecke
2017-06-28  9:10   ` Johannes Thumshirn
2017-06-29 20:00   ` Raghava Aditya Renukunta
2017-06-28  8:32 ` [PATCH 03/47] aacraid: split off device, target, and bus reset Hannes Reinecke
2017-06-28  9:14   ` Johannes Thumshirn
2017-06-29 20:01   ` Raghava Aditya Renukunta
2017-06-28  8:32 ` [PATCH 04/47] aacraid: use aac_tmf_callback for reset fib Hannes Reinecke
2017-06-28 19:42   ` Dave Carroll
2017-06-29 20:06   ` Raghava Aditya Renukunta
2017-06-30  7:19     ` Hannes Reinecke
2017-06-28  8:32 ` [PATCH 05/47] aacraid: enable sending of TMFs from aac_hba_send() Hannes Reinecke
2017-06-28  9:17   ` Johannes Thumshirn
2017-06-29 20:07   ` Raghava Aditya Renukunta
2017-06-28  8:32 ` [PATCH 06/47] aacraid: add fib flag to mark scsi command callback Hannes Reinecke
2017-06-28  9:18   ` Johannes Thumshirn
2017-06-29 20:07   ` Raghava Aditya Renukunta
2017-06-28  8:32 ` [PATCH 07/47] aacraid: complete all commands during bus reset Hannes Reinecke
2017-06-28  9:19   ` Johannes Thumshirn
2017-06-29 20:07   ` Raghava Aditya Renukunta
2017-06-28  8:32 ` [PATCH 08/47] sym53c8xx_2: split off bus reset from host reset Hannes Reinecke
2017-06-28  9:19   ` Johannes Thumshirn
2017-06-28  9:25   ` Johannes Thumshirn
2017-06-28  8:32 ` [PATCH 09/47] zfcp: open-code fc_block_scsi_eh() for " Hannes Reinecke
2017-07-24 16:18   ` Steffen Maier
2017-07-24 18:01     ` Hannes Reinecke
2017-07-24 16:24   ` Steffen Maier
2017-06-28  8:32 ` [PATCH 10/47] ips: Do not try to abort command from " Hannes Reinecke
2017-06-28  9:31   ` Johannes Thumshirn
2017-06-28  8:32 ` [PATCH 11/47] snic: reserve tag for TMF Hannes Reinecke
2017-06-28  9:37   ` Johannes Thumshirn
2017-06-28  8:32 ` [PATCH 12/47] qla1280: separate out host reset function from qla1280_error_action() Hannes Reinecke
2017-06-28  9:39   ` Johannes Thumshirn
2017-06-28  8:32 ` [PATCH 13/47] megaraid: pass in NULL scb for host reset Hannes Reinecke
2017-06-28  9:39   ` Johannes Thumshirn
2017-06-28 13:41   ` Sumit Saxena
2017-06-28 15:30     ` Hannes Reinecke
2017-06-28 17:40       ` Kashyap Desai
     [not found]         ` <CAHtARFFTFMaUsVZ_KuYGr3hFcTuD5sf=h2+1RM6aj8yfpwsCWQ@mail.gmail.com>
2017-06-28 18:40           ` Christoph Hellwig
2017-06-29  5:53         ` Hannes Reinecke
2017-06-29  7:51           ` Sumit Saxena
2017-06-28  8:32 ` [PATCH 14/47] scsi: Use Scsi_Host as argument for eh_host_reset_handler Hannes Reinecke
2017-07-24 16:55   ` Steffen Maier
2017-06-28  8:32 ` [PATCH 15/47] scsi_transport_fc: Use fc_rport as argument for fc_block_scsi_eh Hannes Reinecke
2017-07-24 16:34   ` Steffen Maier
2017-06-28  8:32 ` [PATCH 16/47] mptfc: simplify mpt_fc_block_error_handler() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 17/47] mptfusion: correct definitions for mptscsih_dev_reset() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 18/47] mptfc: open-code mptfc_block_error_handler() for bus reset Hannes Reinecke
2017-06-28  8:32 ` [PATCH 19/47] pmcraid: Select device in pmcraid_eh_bus_reset_handler() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 20/47] scsi: Use Scsi_Host and channel number as argument for eh_bus_reset_handler() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 21/47] libiscsi: use cls_session as argument for target and session reset Hannes Reinecke
2017-06-28  8:32 ` [PATCH 22/47] bnx2fc: Do not rely on a scsi command when issueing lun or target reset Hannes Reinecke
2017-06-28  8:32 ` [PATCH 23/47] zfcp: do not rely on scsi command for debugging message Hannes Reinecke
2017-06-28  8:32 ` [PATCH 24/47] zfcp: use scsi device as argument for zfcp_task_mgmt_function() Hannes Reinecke
2017-07-24 17:15   ` Steffen Maier
2017-07-25 14:14     ` Hannes Reinecke
2017-06-28  8:32 ` [PATCH 25/47] ibmvfc: open-code reset loop for target reset Hannes Reinecke
2017-06-28  8:32 ` [PATCH 26/47] lpfc: use rport as argument for lpfc_send_taskmgmt() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 27/47] lpfc: use rport as argument for lpfc_chk_tgt_mapped() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 28/47] qla2xxx: open-code qla2xxx_generic_reset() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 29/47] qedf: use fc rport as argument for qedf_initiate_tmf() Hannes Reinecke
2017-06-28  8:32 ` [PATCH 30/47] sym53c8xx_2: rework reset handling Hannes Reinecke
2017-06-28  8:32 ` [PATCH 31/47] bfa: Do not use scsi command to signal TMF status Hannes Reinecke
2017-06-28  8:32 ` [PATCH 32/47] scsi: Use scsi_target as argument for eh_target_reset_handler() Hannes Reinecke
2017-07-24 18:10   ` Steffen Maier
2017-07-25 14:19     ` Hannes Reinecke
2017-08-02 16:52       ` Steffen Maier
2017-06-28  8:32 ` [PATCH 33/47] cxlflash: use dedicated reset command in send_tmf() Hannes Reinecke
2017-06-28 16:29   ` Matthew R. Ochs
2017-06-28  8:33 ` [PATCH 34/47] aha152x: look for stuck command when resetting device Hannes Reinecke
2017-06-28  8:33 ` [PATCH 35/47] fnic: use dedicated device reset command Hannes Reinecke
2017-06-28  8:33 ` [PATCH 36/47] a1000u2w: do not rely on the command for inia100_device_reset() Hannes Reinecke
2017-06-28  8:33 ` [PATCH 37/47] aic79xx: use scsi device as argument for BUILD_SCSIID() Hannes Reinecke
2017-06-28  8:33 ` [PATCH 38/47] aic7xxx: " Hannes Reinecke
2017-06-28  8:33 ` [PATCH 39/47] aic79xx: do not reference scsi command when resetting device Hannes Reinecke
2017-06-28  8:33 ` [PATCH 40/47] aic7xxx: " Hannes Reinecke
2017-06-28  8:33 ` [PATCH 41/47] xen-scsifront: add scsi device as argument to scsifront_do_request() Hannes Reinecke
2017-06-28  8:33 ` [PATCH 42/47] xen-scsifront: call scsifront_action_handler() with a NULL command argument Hannes Reinecke
2017-06-28  8:33 ` [PATCH 43/47] fas216: Rework device reset to not rely on SCSI command pointer Hannes Reinecke
2017-06-28  8:33 ` [PATCH 44/47] csiostor: use separate TMF command Hannes Reinecke
2017-06-28  8:33 ` [PATCH 45/47] snic: use dedicated device reset command Hannes Reinecke
2017-06-28  8:33 ` [PATCH 46/47] scsi: Move eh_device_reset_handler() to use scsi_device as argument Hannes Reinecke
2017-07-24 18:42   ` Steffen Maier
2017-06-28  8:33 ` [PATCH 47/47] scsi: Do not allocate scsi command in scsi_ioctl_reset() Hannes Reinecke
2017-06-28 14:06 ` [PATCH 00/47] SCSI EH argument reshuffle part II Christoph Hellwig
2018-01-08 11:26 ` Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.