Commit 0c0d8069 authored by Martin K. Petersen's avatar Martin K. Petersen
Browse files

Merge patch series "scsi: Add struct for args to execution functions"

Mike Christie <michael.christie@oracle.com> says:

The following patches were made over Martin's scsi-staging/next
branch.  They add a struct that contains optinal arguments to the
scsi_execute* functions. This will be needed for the patches that
allow the SCSI passthrough users to control retries because I'm adding
a new optional argument. I separated the 2 sets to make it easier to
review and post.

Link: https://lore.kernel.org/r/20221229190154.7467-1-michael.christie@oracle.com


Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parents 7084eadf 946a1051
Loading
Loading
Loading
Loading
+14 −9
Original line number Diff line number Diff line
@@ -383,8 +383,12 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
	u8 scsi_cmd[MAX_COMMAND_SIZE];
	u8 args[4], *argbuf = NULL;
	int argsize = 0;
	enum dma_data_direction data_dir;
	struct scsi_sense_hdr sshdr;
	const struct scsi_exec_args exec_args = {
		.sshdr = &sshdr,
		.sense = sensebuf,
		.sense_len = sizeof(sensebuf),
	};
	int cmd_result;

	if (arg == NULL)
@@ -407,11 +411,9 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
		scsi_cmd[1]  = (4 << 1); /* PIO Data-in */
		scsi_cmd[2]  = 0x0e;     /* no off.line or cc, read from dev,
					    block count in sector count field */
		data_dir = DMA_FROM_DEVICE;
	} else {
		scsi_cmd[1]  = (3 << 1); /* Non-data */
		scsi_cmd[2]  = 0x20;     /* cc but no off.line or data xfer */
		data_dir = DMA_NONE;
	}

	scsi_cmd[0] = ATA_16;
@@ -429,9 +431,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)

	/* Good values for timeout and retries?  Values below
	   from scsi_ioctl_send_command() for default case... */
	cmd_result = scsi_execute(scsidev, scsi_cmd, data_dir, argbuf, argsize,
				  sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);

	cmd_result = scsi_execute_cmd(scsidev, scsi_cmd, REQ_OP_DRV_IN, argbuf,
				      argsize, 10 * HZ, 5, &exec_args);
	if (cmd_result < 0) {
		rc = cmd_result;
		goto error;
@@ -491,6 +492,11 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
	u8 args[7];
	struct scsi_sense_hdr sshdr;
	int cmd_result;
	const struct scsi_exec_args exec_args = {
		.sshdr = &sshdr,
		.sense = sensebuf,
		.sense_len = sizeof(sensebuf),
	};

	if (arg == NULL)
		return -EINVAL;
@@ -513,9 +519,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)

	/* Good values for timeout and retries?  Values below
	   from scsi_ioctl_send_command() for default case... */
	cmd_result = scsi_execute(scsidev, scsi_cmd, DMA_NONE, NULL, 0,
				sensebuf, &sshdr, (10*HZ), 5, 0, 0, NULL);

	cmd_result = scsi_execute_cmd(scsidev, scsi_cmd, REQ_OP_DRV_IN, NULL,
				      0, 10 * HZ, 5, &exec_args);
	if (cmd_result < 0) {
		rc = cmd_result;
		goto error;
+5 −6
Original line number Diff line number Diff line
@@ -164,7 +164,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
				 u8 lba_low, u8 lba_mid, u8 lba_high)
{
	u8 scsi_cmd[MAX_COMMAND_SIZE];
	int data_dir;
	enum req_op op;

	memset(scsi_cmd, 0, sizeof(scsi_cmd));
	scsi_cmd[0] = ATA_16;
@@ -175,7 +175,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
		 * field.
		 */
		scsi_cmd[2] = 0x06;
		data_dir = DMA_TO_DEVICE;
		op = REQ_OP_DRV_OUT;
	} else {
		scsi_cmd[1] = (4 << 1);	/* PIO Data-in */
		/*
@@ -183,7 +183,7 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
		 * field.
		 */
		scsi_cmd[2] = 0x0e;
		data_dir = DMA_FROM_DEVICE;
		op = REQ_OP_DRV_IN;
	}
	scsi_cmd[4] = feature;
	scsi_cmd[6] = 1;	/* 1 sector */
@@ -192,9 +192,8 @@ static int drivetemp_scsi_command(struct drivetemp_data *st,
	scsi_cmd[12] = lba_high;
	scsi_cmd[14] = ata_command;

	return scsi_execute_req(st->sdev, scsi_cmd, data_dir,
				st->smartdata, ATA_SECT_SIZE, NULL, HZ, 5,
				NULL);
	return scsi_execute_cmd(st->sdev, scsi_cmd, op, st->smartdata,
				ATA_SECT_SIZE, HZ, 5, NULL);
}

static int drivetemp_ata_command(struct drivetemp_data *st, u8 feature,
+15 −15
Original line number Diff line number Diff line
@@ -184,20 +184,21 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr)

static int
ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len,
	   void *buffer, unsigned buflength,
	   enum dma_data_direction direction)
	   void *buffer, unsigned int buflength, enum req_op op)
{
	int errno, retries = 0, timeout, result;
	struct scsi_sense_hdr sshdr;
	const struct scsi_exec_args exec_args = {
		.sshdr = &sshdr,
	};

	timeout = (cmd[0] == INITIALIZE_ELEMENT_STATUS)
		? timeout_init : timeout_move;

 retry:
	errno = 0;
	result = scsi_execute_req(ch->device, cmd, direction, buffer,
				  buflength, &sshdr, timeout * HZ,
				  MAX_RETRIES, NULL);
	result = scsi_execute_cmd(ch->device, cmd, op, buffer, buflength,
				  timeout * HZ, MAX_RETRIES, &exec_args);
	if (result < 0)
		return result;
	if (scsi_sense_valid(&sshdr)) {
@@ -254,7 +255,7 @@ ch_read_element_status(scsi_changer *ch, u_int elem, char *data)
	cmd[5] = 1;
	cmd[9] = 255;
	if (0 == (result = ch_do_scsi(ch, cmd, 12,
				      buffer, 256, DMA_FROM_DEVICE))) {
				      buffer, 256, REQ_OP_DRV_IN))) {
		if (((buffer[16] << 8) | buffer[17]) != elem) {
			DPRINTK("asked for element 0x%02x, got 0x%02x\n",
				elem,(buffer[16] << 8) | buffer[17]);
@@ -284,7 +285,7 @@ ch_init_elem(scsi_changer *ch)
	memset(cmd,0,sizeof(cmd));
	cmd[0] = INITIALIZE_ELEMENT_STATUS;
	cmd[1] = (ch->device->lun & 0x7) << 5;
	err = ch_do_scsi(ch, cmd, 6, NULL, 0, DMA_NONE);
	err = ch_do_scsi(ch, cmd, 6, NULL, 0, REQ_OP_DRV_IN);
	VPRINTK(KERN_INFO, "... finished\n");
	return err;
}
@@ -306,10 +307,10 @@ ch_readconfig(scsi_changer *ch)
	cmd[1] = (ch->device->lun & 0x7) << 5;
	cmd[2] = 0x1d;
	cmd[4] = 255;
	result = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
	result = ch_do_scsi(ch, cmd, 10, buffer, 255, REQ_OP_DRV_IN);
	if (0 != result) {
		cmd[1] |= (1<<3);
		result  = ch_do_scsi(ch, cmd, 10, buffer, 255, DMA_FROM_DEVICE);
		result  = ch_do_scsi(ch, cmd, 10, buffer, 255, REQ_OP_DRV_IN);
	}
	if (0 == result) {
		ch->firsts[CHET_MT] =
@@ -434,7 +435,7 @@ ch_position(scsi_changer *ch, u_int trans, u_int elem, int rotate)
	cmd[4]  = (elem  >> 8) & 0xff;
	cmd[5]  =  elem        & 0xff;
	cmd[8]  = rotate ? 1 : 0;
	return ch_do_scsi(ch, cmd, 10, NULL, 0, DMA_NONE);
	return ch_do_scsi(ch, cmd, 10, NULL, 0, REQ_OP_DRV_IN);
}

static int
@@ -455,7 +456,7 @@ ch_move(scsi_changer *ch, u_int trans, u_int src, u_int dest, int rotate)
	cmd[6]  = (dest  >> 8) & 0xff;
	cmd[7]  =  dest        & 0xff;
	cmd[10] = rotate ? 1 : 0;
	return ch_do_scsi(ch, cmd, 12, NULL,0, DMA_NONE);
	return ch_do_scsi(ch, cmd, 12, NULL, 0, REQ_OP_DRV_IN);
}

static int
@@ -481,7 +482,7 @@ ch_exchange(scsi_changer *ch, u_int trans, u_int src,
	cmd[9]  =  dest2       & 0xff;
	cmd[10] = (rotate1 ? 1 : 0) | (rotate2 ? 2 : 0);

	return ch_do_scsi(ch, cmd, 12, NULL, 0, DMA_NONE);
	return ch_do_scsi(ch, cmd, 12, NULL, 0, REQ_OP_DRV_IN);
}

static void
@@ -531,7 +532,7 @@ ch_set_voltag(scsi_changer *ch, u_int elem,
	memcpy(buffer,tag,32);
	ch_check_voltag(buffer);

	result = ch_do_scsi(ch, cmd, 12, buffer, 256, DMA_TO_DEVICE);
	result = ch_do_scsi(ch, cmd, 12, buffer, 256, REQ_OP_DRV_OUT);
	kfree(buffer);
	return result;
}
@@ -799,8 +800,7 @@ static long ch_ioctl(struct file *file,
		ch_cmd[5] = 1;
		ch_cmd[9] = 255;

		result = ch_do_scsi(ch, ch_cmd, 12,
				    buffer, 256, DMA_FROM_DEVICE);
		result = ch_do_scsi(ch, ch_cmd, 12, buffer, 256, REQ_OP_DRV_IN);
		if (!result) {
			cge.cge_status = buffer[18];
			cge.cge_flags = 0;
+18 −16
Original line number Diff line number Diff line
@@ -308,19 +308,19 @@ static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
 * @lli:	LUN destined for capacity request.
 *
 * The READ_CAP16 can take quite a while to complete. Should an EEH occur while
 * in scsi_execute(), the EEH handler will attempt to recover. As part of the
 * recovery, the handler drains all currently running ioctls, waiting until they
 * have completed before proceeding with a reset. As this routine is used on the
 * ioctl path, this can create a condition where the EEH handler becomes stuck,
 * infinitely waiting for this ioctl thread. To avoid this behavior, temporarily
 * unmark this thread as an ioctl thread by releasing the ioctl read semaphore.
 * This will allow the EEH handler to proceed with a recovery while this thread
 * is still running. Once the scsi_execute() returns, reacquire the ioctl read
 * semaphore and check the adapter state in case it changed while inside of
 * scsi_execute(). The state check will wait if the adapter is still being
 * recovered or return a failure if the recovery failed. In the event that the
 * adapter reset failed, simply return the failure as the ioctl would be unable
 * to continue.
 * in scsi_execute_cmd(), the EEH handler will attempt to recover. As part of
 * the recovery, the handler drains all currently running ioctls, waiting until
 * they have completed before proceeding with a reset. As this routine is used
 * on the ioctl path, this can create a condition where the EEH handler becomes
 * stuck, infinitely waiting for this ioctl thread. To avoid this behavior,
 * temporarily unmark this thread as an ioctl thread by releasing the ioctl
 * read semaphore. This will allow the EEH handler to proceed with a recovery
 * while this thread is still running. Once the scsi_execute_cmd() returns,
 * reacquire the ioctl read semaphore and check the adapter state in case it
 * changed while inside of scsi_execute_cmd(). The state check will wait if the
 * adapter is still being recovered or return a failure if the recovery failed.
 * In the event that the adapter reset failed, simply return the failure as the
 * ioctl would be unable to continue.
 *
 * Note that the above puts a requirement on this routine to only be called on
 * an ioctl thread.
@@ -333,6 +333,9 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
	struct device *dev = &cfg->dev->dev;
	struct glun_info *gli = lli->parent;
	struct scsi_sense_hdr sshdr;
	const struct scsi_exec_args exec_args = {
		.sshdr = &sshdr,
	};
	u8 *cmd_buf = NULL;
	u8 *scsi_cmd = NULL;
	int rc = 0;
@@ -357,9 +360,8 @@ static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)

	/* Drop the ioctl read semahpore across lengthy call */
	up_read(&cfg->ioctl_rwsem);
	result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
			      CMD_BUFSIZE, NULL, &sshdr, to, CMD_RETRIES,
			      0, 0, NULL);
	result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_IN, cmd_buf,
				  CMD_BUFSIZE, to, CMD_RETRIES, &exec_args);
	down_read(&cfg->ioctl_rwsem);
	rc = check_state(cfg);
	if (rc) {
+16 −16
Original line number Diff line number Diff line
@@ -397,19 +397,19 @@ static int init_vlun(struct llun_info *lli)
 * @nblks:	Number of logical blocks to write same.
 *
 * The SCSI WRITE_SAME16 can take quite a while to complete. Should an EEH occur
 * while in scsi_execute(), the EEH handler will attempt to recover. As part of
 * the recovery, the handler drains all currently running ioctls, waiting until
 * they have completed before proceeding with a reset. As this routine is used
 * on the ioctl path, this can create a condition where the EEH handler becomes
 * stuck, infinitely waiting for this ioctl thread. To avoid this behavior,
 * temporarily unmark this thread as an ioctl thread by releasing the ioctl read
 * semaphore. This will allow the EEH handler to proceed with a recovery while
 * this thread is still running. Once the scsi_execute() returns, reacquire the
 * ioctl read semaphore and check the adapter state in case it changed while
 * inside of scsi_execute(). The state check will wait if the adapter is still
 * being recovered or return a failure if the recovery failed. In the event that
 * the adapter reset failed, simply return the failure as the ioctl would be
 * unable to continue.
 * while in scsi_execute_cmd(), the EEH handler will attempt to recover. As
 * part of the recovery, the handler drains all currently running ioctls,
 * waiting until they have completed before proceeding with a reset. As this
 * routine is used on the ioctl path, this can create a condition where the
 * EEH handler becomes stuck, infinitely waiting for this ioctl thread. To
 * avoid this behavior, temporarily unmark this thread as an ioctl thread by
 * releasing the ioctl read semaphore. This will allow the EEH handler to
 * proceed with a recovery while this thread is still running. Once the
 * scsi_execute_cmd() returns, reacquire the ioctl read semaphore and check the
 * adapter state in case it changed while inside of scsi_execute_cmd(). The
 * state check will wait if the adapter is still being recovered or return a
 * failure if the recovery failed. In the event that the adapter reset failed,
 * simply return the failure as the ioctl would be unable to continue.
 *
 * Note that the above puts a requirement on this routine to only be called on
 * an ioctl thread.
@@ -450,9 +450,9 @@ static int write_same16(struct scsi_device *sdev,

		/* Drop the ioctl read semahpore across lengthy call */
		up_read(&cfg->ioctl_rwsem);
		result = scsi_execute(sdev, scsi_cmd, DMA_TO_DEVICE, cmd_buf,
				      CMD_BUFSIZE, NULL, NULL, to,
				      CMD_RETRIES, 0, 0, NULL);
		result = scsi_execute_cmd(sdev, scsi_cmd, REQ_OP_DRV_OUT,
					  cmd_buf, CMD_BUFSIZE, to,
					  CMD_RETRIES, NULL);
		down_read(&cfg->ioctl_rwsem);
		rc = check_state(cfg);
		if (rc) {
Loading