diff mbox series

[RFC,v3,16/41] aacraid: use scsi_host_busy_iter() to traverse commands

Message ID 20200430131904.5847-17-hare@suse.de (mailing list archive)
State Changes Requested
Headers show
Series scsi: enable reserved commands for LLDDs | expand

Commit Message

Hannes Reinecke April 30, 2020, 1:18 p.m. UTC
Now that the block layer manages all commands we can use
scsi_host_busy_iter() to traverse outstanding commands.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/aacraid/linit.c | 137 ++++++++++++++++++++-----------------------
 1 file changed, 62 insertions(+), 75 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index 91a4780d9815..e3f8eac6cebe 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -680,7 +680,7 @@  static int aac_eh_abort(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, found;
+	int count;
 	u32 bus, cid;
 	int ret = FAILED;
 
@@ -699,17 +699,13 @@  static int aac_eh_abort(struct scsi_cmnd* cmd)
 		 AAC_DRIVERNAME,
 		 host->host_no, sdev_channel(dev), sdev_id(dev), (int)dev->lun);
 
-		found = 0;
-		for (count = 0; count < host->can_queue; ++count) {
-			fib = &aac->fibs[count];
-			if (*(u8 *)fib->hw_fib_va != 0 &&
-				(fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) &&
-				(fib->callback_data == cmd)) {
-				found = 1;
-				break;
-			}
-		}
-		if (!found)
+		if (cmd->request->tag >= host->can_queue)
+			return ret;
+
+		fib = &aac->fibs[cmd->request->tag];
+		if (*(u8 *)fib->hw_fib_va == 0 ||
+		    !(fib->flags & FIB_CONTEXT_FLAG_NATIVE_HBA) ||
+		    (fib->callback_data != cmd))
 			return ret;
 
 		/* start a HBA_TMF_ABORT_TASK TMF request */
@@ -767,12 +763,13 @@  static int aac_eh_abort(struct scsi_cmnd* cmd)
 			/* fall through */
 		case INQUIRY:
 		case READ_CAPACITY:
+		case TEST_UNIT_READY:
 			/*
 			 * Mark associated FIB to not complete,
 			 * eh handler does this
 			 */
-			for (count = 0; count < host->can_queue; ++count) {
-				struct fib *fib = &aac->fibs[count];
+			if (cmd->request->tag < host->can_queue) {
+				struct fib *fib = &aac->fibs[cmd->request->tag];
 
 				if (fib->hw_fib_va->header.XferState &&
 				(fib->flags & FIB_CONTEXT_FLAG) &&
@@ -785,32 +782,6 @@  static int aac_eh_abort(struct scsi_cmnd* cmd)
 				}
 			}
 			break;
-		case TEST_UNIT_READY:
-			/*
-			 * Mark associated FIB to not complete,
-			 * eh handler does this
-			 */
-			for (count = 0; count < host->can_queue; ++count) {
-				struct scsi_cmnd *command;
-				struct fib *fib = &aac->fibs[count];
-
-				command = fib->callback_data;
-
-				if ((fib->hw_fib_va->header.XferState &
-					cpu_to_le32
-					(Async | NoResponseExpected)) &&
-					(fib->flags & FIB_CONTEXT_FLAG) &&
-					((command)) &&
-					(command->device == cmd->device)) {
-					fib->flags |=
-						FIB_CONTEXT_FLAG_TIMED_OUT;
-					command->SCp.phase =
-						AAC_OWNER_ERROR_HANDLER;
-					if (command == cmd)
-						ret = SUCCESS;
-				}
-			}
-			break;
 		}
 	}
 	return ret;
@@ -1016,6 +987,36 @@  static int aac_eh_target_reset(struct scsi_cmnd *cmd)
 	return ret;
 }
 
+struct aac_abort_fibs_iter_data {
+	struct aac_dev *aac;
+	u32 bus;
+};
+
+static bool aac_abort_fibs_iter(struct scsi_cmnd *scmd, void *data, bool rsvd)
+{
+	struct aac_abort_fibs_iter_data *iter_data = data;
+	struct aac_dev *aac = iter_data->aac;
+	struct fib *fib = &aac->fibs[scmd->request->tag];
+
+	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;
+
+		bus = aac_logical_to_phys(scmd_channel(scmd));
+		if (bus != iter_data->bus)
+			return true;
+		cid = scmd_id(scmd);
+		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_EH_RESET;
+			scmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
+		}
+	}
+	return true;
+}
 /*
  *	aac_eh_bus_reset	- Bus reset command handling
  *	@scsi_cmd:	SCSI command block causing the reset
@@ -1027,34 +1028,13 @@  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 cmd_bus;
 	int status = 0;
+	struct aac_abort_fibs_iter_data data = {
+		.aac = aac,
+		.bus = aac_logical_to_phys(scmd_channel(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; ++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_EH_RESET;
-				cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER;
-			}
-		}
-	}
+	scsi_host_busy_iter(host, aac_abort_fibs_iter, &data);
 
 	pr_err("%s: Host bus reset request. SCSI hang ?\n", AAC_DRIVERNAME);
 
@@ -1558,23 +1538,28 @@  static struct scsi_host_template aac_driver_template = {
 	.no_write_same			= 1,
 };
 
-static void __aac_shutdown(struct aac_dev * aac)
+static bool __aac_shutdown_iter(struct scsi_cmnd *scmd, void *data, bool rsvd)
 {
-	int i;
+	struct aac_dev *aac = data;
+	struct fib *fib = &aac->fibs[scmd->request->tag];
+
+	if (!(fib->hw_fib_va->header.XferState &
+	      cpu_to_le32(NoResponseExpected | Async)) &&
+	    (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
+		complete(&fib->event_wait);
+	return true;
+}
 
+static void __aac_shutdown(struct aac_dev * aac)
+{
 	mutex_lock(&aac->ioctl_mutex);
 	aac->adapter_shutdown = 1;
 	mutex_unlock(&aac->ioctl_mutex);
 
 	if (aac->aif_thread) {
-		int i;
 		/* Clear out events first */
-		for (i = 0; i < aac->scsi_host_ptr->can_queue; i++) {
-			struct fib *fib = &aac->fibs[i];
-			if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
-			    (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
-				complete(&fib->event_wait);
-		}
+		scsi_host_busy_iter(aac->scsi_host_ptr,
+				    __aac_shutdown_iter, aac);
 		kthread_stop(aac->thread);
 		aac->thread = NULL;
 	}
@@ -1585,6 +1570,8 @@  static void __aac_shutdown(struct aac_dev * aac)
 
 	if (aac_is_src(aac)) {
 		if (aac->max_msix > 1) {
+			int i;
+
 			for (i = 0; i < aac->max_msix; i++) {
 				free_irq(pci_irq_vector(aac->pdev, i),
 					 &(aac->aac_msix[i]));