summaryrefslogtreecommitdiff
path: root/drivers/scsi/scsi_transport_spi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_transport_spi.c')
-rw-r--r--drivers/scsi/scsi_transport_spi.c110
1 files changed, 55 insertions, 55 deletions
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c
index 40b85b752b79..fe47850a8258 100644
--- a/drivers/scsi/scsi_transport_spi.c
+++ b/drivers/scsi/scsi_transport_spi.c
@@ -1,22 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Parallel SCSI (SPI) transport specific attributes exported to sysfs.
*
* Copyright (c) 2003 Silicon Graphics, Inc. All rights reserved.
* Copyright (c) 2004, 2005 James Bottomley <James.Bottomley@SteelEye.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/ctype.h>
#include <linux/init.h>
@@ -118,29 +105,33 @@ static int sprint_frac(char *dest, int value, int denom)
}
static int spi_execute(struct scsi_device *sdev, const void *cmd,
- enum dma_data_direction dir,
- void *buffer, unsigned bufflen,
+ enum req_op op, void *buffer, unsigned int bufflen,
struct scsi_sense_hdr *sshdr)
{
- int i, result;
- unsigned char sense[SCSI_SENSE_BUFFERSIZE];
- struct scsi_sense_hdr sshdr_tmp;
-
- if (!sshdr)
- sshdr = &sshdr_tmp;
-
- for(i = 0; i < DV_RETRIES; i++) {
- result = scsi_execute(sdev, cmd, dir, buffer, bufflen, sense,
- sshdr, DV_TIMEOUT, /* retries */ 1,
- REQ_FAILFAST_DEV |
- REQ_FAILFAST_TRANSPORT |
- REQ_FAILFAST_DRIVER,
- 0, NULL);
- if (driver_byte(result) != DRIVER_SENSE ||
- sshdr->sense_key != UNIT_ATTENTION)
- break;
- }
- return result;
+ blk_opf_t opf = op | REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
+ REQ_FAILFAST_DRIVER;
+ struct scsi_failure failure_defs[] = {
+ {
+ .sense = UNIT_ATTENTION,
+ .asc = SCMD_FAILURE_ASC_ANY,
+ .ascq = SCMD_FAILURE_ASCQ_ANY,
+ .allowed = DV_RETRIES,
+ .result = SAM_STAT_CHECK_CONDITION,
+ },
+ {}
+ };
+ struct scsi_failures failures = {
+ .failure_definitions = failure_defs,
+ };
+ const struct scsi_exec_args exec_args = {
+ /* bypass the SDEV_QUIESCE state with BLK_MQ_REQ_PM */
+ .req_flags = BLK_MQ_REQ_PM,
+ .sshdr = sshdr,
+ .failures = &failures,
+ };
+
+ return scsi_execute_cmd(sdev, cmd, opf, buffer, bufflen, DV_TIMEOUT, 1,
+ &exec_args);
}
static struct {
@@ -352,7 +343,7 @@ store_spi_transport_##field(struct device *dev, \
struct spi_transport_attrs *tp \
= (struct spi_transport_attrs *)&starget->starget_data; \
\
- if (i->f->set_##field) \
+ if (!i->f->set_##field) \
return -EINVAL; \
val = simple_strtoul(buf, NULL, 0); \
if (val > tp->max_##field) \
@@ -684,12 +675,12 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
}
for (r = 0; r < retries; r++) {
- result = spi_execute(sdev, spi_write_buffer, DMA_TO_DEVICE,
+ result = spi_execute(sdev, spi_write_buffer, REQ_OP_DRV_OUT,
buffer, len, &sshdr);
- if(result || !scsi_device_online(sdev)) {
+ if (result || !scsi_device_online(sdev)) {
scsi_device_set_state(sdev, SDEV_QUIESCE);
- if (scsi_sense_valid(&sshdr)
+ if (result > 0 && scsi_sense_valid(&sshdr)
&& sshdr.sense_key == ILLEGAL_REQUEST
/* INVALID FIELD IN CDB */
&& sshdr.asc == 0x24 && sshdr.ascq == 0x00)
@@ -706,7 +697,7 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer,
}
memset(ptr, 0, len);
- spi_execute(sdev, spi_read_buffer, DMA_FROM_DEVICE,
+ spi_execute(sdev, spi_read_buffer, REQ_OP_DRV_IN,
ptr, len, NULL);
scsi_device_set_state(sdev, SDEV_QUIESCE);
@@ -731,7 +722,7 @@ spi_dv_device_compare_inquiry(struct scsi_device *sdev, u8 *buffer,
for (r = 0; r < retries; r++) {
memset(ptr, 0, len);
- result = spi_execute(sdev, spi_inquiry, DMA_FROM_DEVICE,
+ result = spi_execute(sdev, spi_inquiry, REQ_OP_DRV_IN,
ptr, len, NULL);
if(result || !scsi_device_online(sdev)) {
@@ -837,7 +828,7 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer)
* (reservation conflict, device not ready, etc) just
* skip the write tests */
for (l = 0; ; l++) {
- result = spi_execute(sdev, spi_test_unit_ready, DMA_NONE,
+ result = spi_execute(sdev, spi_test_unit_ready, REQ_OP_DRV_IN,
NULL, 0, NULL);
if(result) {
@@ -850,7 +841,7 @@ spi_dv_device_get_echo_buffer(struct scsi_device *sdev, u8 *buffer)
}
result = spi_execute(sdev, spi_read_buffer_descriptor,
- DMA_FROM_DEVICE, buffer, 4, NULL);
+ REQ_OP_DRV_IN, buffer, 4, NULL);
if (result)
/* Device has no echo buffer */
@@ -994,7 +985,8 @@ spi_dv_device_internal(struct scsi_device *sdev, u8 *buffer)
}
-/** spi_dv_device - Do Domain Validation on the device
+/**
+ * spi_dv_device - Do Domain Validation on the device
* @sdev: scsi device to validate
*
* Performs the domain validation on the given device in the
@@ -1007,8 +999,9 @@ void
spi_dv_device(struct scsi_device *sdev)
{
struct scsi_target *starget = sdev->sdev_target;
- u8 *buffer;
const int len = SPI_MAX_ECHO_BUFFER_SIZE*2;
+ unsigned int sleep_flags;
+ u8 *buffer;
/*
* Because this function and the power management code both call
@@ -1016,25 +1009,28 @@ spi_dv_device(struct scsi_device *sdev)
* while suspend or resume is in progress. Hence the
* lock/unlock_system_sleep() calls.
*/
- lock_system_sleep();
+ sleep_flags = lock_system_sleep();
+
+ if (scsi_autopm_get_device(sdev))
+ goto unlock_system_sleep;
if (unlikely(spi_dv_in_progress(starget)))
- goto unlock;
+ goto put_autopm;
if (unlikely(scsi_device_get(sdev)))
- goto unlock;
+ goto put_autopm;
spi_dv_in_progress(starget) = 1;
buffer = kzalloc(len, GFP_KERNEL);
if (unlikely(!buffer))
- goto out_put;
+ goto put_sdev;
/* We need to verify that the actual device will quiesce; the
* later target quiesce is just a nice to have */
if (unlikely(scsi_device_quiesce(sdev)))
- goto out_free;
+ goto free_buffer;
scsi_target_quiesce(starget);
@@ -1054,13 +1050,17 @@ spi_dv_device(struct scsi_device *sdev)
spi_initial_dv(starget) = 1;
- out_free:
+free_buffer:
kfree(buffer);
- out_put:
+
+put_sdev:
spi_dv_in_progress(starget) = 0;
scsi_device_put(sdev);
-unlock:
- unlock_system_sleep();
+put_autopm:
+ scsi_autopm_put_device(sdev);
+
+unlock_system_sleep:
+ unlock_system_sleep(sleep_flags);
}
EXPORT_SYMBOL(spi_dv_device);
@@ -1232,7 +1232,7 @@ int spi_populate_tag_msg(unsigned char *msg, struct scsi_cmnd *cmd)
{
if (cmd->flags & SCMD_TAGGED) {
*msg++ = SIMPLE_QUEUE_TAG;
- *msg++ = cmd->request->tag;
+ *msg++ = scsi_cmd_to_rq(cmd)->tag;
return 2;
}