summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libata-scsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libata-scsi.c')
-rw-r--r--drivers/scsi/libata-scsi.c57
1 files changed, 24 insertions, 33 deletions
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index eb604b0..0df4b68 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -37,9 +37,10 @@
#include <linux/blkdev.h>
#include <linux/spinlock.h>
#include <scsi/scsi.h>
-#include "scsi.h"
#include <scsi/scsi_host.h>
+#include <scsi/scsi_eh.h>
#include <scsi/scsi_device.h>
+#include <scsi/scsi_request.h>
#include <linux/libata.h>
#include <linux/hdreg.h>
#include <asm/uaccess.h>
@@ -131,7 +132,7 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
/**
* ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl
- * @dev: Device to whom we are issuing command
+ * @scsidev: Device to which we are issuing command
* @arg: User provided data for issuing command
*
* LOCKING:
@@ -147,7 +148,8 @@ 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;
- struct scsi_request *sreq;
+ struct scsi_sense_hdr sshdr;
+ enum dma_data_direction data_dir;
if (NULL == (void *)arg)
return -EINVAL;
@@ -155,10 +157,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
if (copy_from_user(args, arg, sizeof(args)))
return -EFAULT;
- sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
- if (!sreq)
- return -EINTR;
-
memset(scsi_cmd, 0, sizeof(scsi_cmd));
if (args[3]) {
@@ -172,11 +170,11 @@ 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 */
- sreq->sr_data_direction = DMA_FROM_DEVICE;
+ data_dir = DMA_FROM_DEVICE;
} else {
scsi_cmd[1] = (3 << 1); /* Non-data */
/* scsi_cmd[2] is already 0 -- no off.line, cc, or data xfer */
- sreq->sr_data_direction = DMA_NONE;
+ data_dir = DMA_NONE;
}
scsi_cmd[0] = ATA_16;
@@ -194,9 +192,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... */
- scsi_wait_req(sreq, scsi_cmd, argbuf, argsize, (10*HZ), 5);
-
- if (sreq->sr_result) {
+ if (scsi_execute_req(scsidev, scsi_cmd, data_dir, argbuf, argsize,
+ &sshdr, (10*HZ), 5)) {
rc = -EIO;
goto error;
}
@@ -207,8 +204,6 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg)
&& copy_to_user((void *)(arg + sizeof(args)), argbuf, argsize))
rc = -EFAULT;
error:
- scsi_release_request(sreq);
-
if (argbuf)
kfree(argbuf);
@@ -217,7 +212,7 @@ error:
/**
* ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl
- * @dev: Device to whom we are issuing command
+ * @scsidev: Device to which we are issuing command
* @arg: User provided data for issuing command
*
* LOCKING:
@@ -231,7 +226,7 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
int rc = 0;
u8 scsi_cmd[MAX_COMMAND_SIZE];
u8 args[7];
- struct scsi_request *sreq;
+ struct scsi_sense_hdr sshdr;
if (NULL == (void *)arg)
return -EINVAL;
@@ -250,26 +245,13 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg)
scsi_cmd[12] = args[5];
scsi_cmd[14] = args[0];
- sreq = scsi_allocate_request(scsidev, GFP_KERNEL);
- if (!sreq) {
- rc = -EINTR;
- goto error;
- }
-
- sreq->sr_data_direction = DMA_NONE;
/* Good values for timeout and retries? Values below
- from scsi_ioctl_send_command() for default case... */
- scsi_wait_req(sreq, scsi_cmd, NULL, 0, (10*HZ), 5);
-
- if (sreq->sr_result) {
+ from scsi_ioctl_send_command() for default case... */
+ if (scsi_execute_req(scsidev, scsi_cmd, DMA_NONE, NULL, 0, &sshdr,
+ (10*HZ), 5))
rc = -EIO;
- goto error;
- }
/* Need code to retrieve data from check condition? */
-
-error:
- scsi_release_request(sreq);
return rc;
}
@@ -416,6 +398,7 @@ void ata_dump_status(unsigned id, struct ata_taskfile *tf)
/**
* ata_to_sense_error - convert ATA error to SCSI error
+ * @id: ATA device number
* @drv_stat: value contained in ATA status register
* @drv_err: value contained in ATA error register
* @sk: the sense key we'll fill out
@@ -1128,6 +1111,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
* length 0 means transfer 0 block of data.
* However, for ATA R/W commands, sector count 0 means
* 256 or 65536 sectors, not 0 sectors as in SCSI.
+ *
+ * WARNING: one or two older ATA drives treat 0 as 0...
*/
goto nothing_to_do;
@@ -2231,7 +2216,7 @@ ata_scsi_map_proto(u8 byte1)
/**
* ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile
* @qc: command structure to be initialized
- * @cmd: SCSI command to convert
+ * @scsicmd: SCSI command to convert
*
* Handles either 12 or 16-byte versions of the CDB.
*
@@ -2291,6 +2276,12 @@ ata_scsi_pass_thru(struct ata_queued_cmd *qc, const u8 *scsicmd)
tf->device = scsicmd[8];
tf->command = scsicmd[9];
}
+ /*
+ * If slave is possible, enforce correct master/slave bit
+ */
+ if (qc->ap->flags & ATA_FLAG_SLAVE_POSS)
+ tf->device = qc->dev->devno ?
+ tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1;
/*
* Filter SET_FEATURES - XFER MODE command -- otherwise,
OpenPOWER on IntegriCloud