aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJeff Garzik <jgarzik@pobox.com>2004-08-14 07:38:01 -0400
committerJeff Garzik <jgarzik@pobox.com>2004-08-14 07:38:01 -0400
commit815b472b87a7074bb171213aedd4c6c439e6b18d (patch)
tree816945734b4eade37a4985ee8836672deb9aa9d8 /drivers
parent7af09f972ad4360d99a0f9dfbbaaaa4050eb055c (diff)
downloadhistory-815b472b87a7074bb171213aedd4c6c439e6b18d.tar.gz
[libata] add ioctl infrastructure
Mainly adding the infrastructure for various ATA ioctls. Currently only supports two ATA-specific ioctls: HDIO_GET_32BIT and HDIO_SET_32BIT (hdparm -c)
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/ata_piix.c1
-rw-r--r--drivers/scsi/libata-core.c4
-rw-r--r--drivers/scsi/libata-scsi.c60
-rw-r--r--drivers/scsi/libata.h1
-rw-r--r--drivers/scsi/sata_nv.c1
-rw-r--r--drivers/scsi/sata_promise.c1
-rw-r--r--drivers/scsi/sata_sil.c1
-rw-r--r--drivers/scsi/sata_sis.c1
-rw-r--r--drivers/scsi/sata_svw.c1
-rw-r--r--drivers/scsi/sata_sx4.c1
-rw-r--r--drivers/scsi/sata_via.c1
-rw-r--r--drivers/scsi/sata_vsc.c1
12 files changed, 63 insertions, 11 deletions
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c
index bf48ed41ecdf24..05d108139a5ff3 100644
--- a/drivers/scsi/ata_piix.c
+++ b/drivers/scsi/ata_piix.c
@@ -104,6 +104,7 @@ static struct pci_driver piix_pci_driver = {
static Scsi_Host_Template piix_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 7187432cf970a6..f187640cd94a82 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -59,7 +59,6 @@ static int ata_choose_xfer_mode(struct ata_port *ap,
u8 *xfer_mode_out,
unsigned int *xfer_shift_out);
static int ata_qc_complete_noop(struct ata_queued_cmd *qc, u8 drv_stat);
-static void swap_buf_le16(u16 *buf, unsigned int buf_words);
static unsigned int ata_unique_id = 1;
static struct workqueue_struct *ata_wq;
@@ -2066,7 +2065,7 @@ static void ata_pio_complete (struct ata_port *ap)
ata_qc_complete(qc, drv_stat);
}
-static void swap_buf_le16(u16 *buf, unsigned int buf_words)
+void swap_buf_le16(u16 *buf, unsigned int buf_words)
{
#ifdef __BIG_ENDIAN
unsigned int i;
@@ -3561,6 +3560,7 @@ EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
+EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_error);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c
index 75af616c7e0497..9b022304d8fb9a 100644
--- a/drivers/scsi/libata-scsi.c
+++ b/drivers/scsi/libata-scsi.c
@@ -29,6 +29,7 @@
#include "scsi.h"
#include <scsi/scsi_host.h>
#include <linux/libata.h>
+#include <asm/uaccess.h>
#include "libata.h"
@@ -36,6 +37,8 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc, u8 *scsicmd);
static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *));
+static struct ata_device *
+ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev);
/**
@@ -67,6 +70,43 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
return 0;
}
+int ata_scsi_ioctl(struct scsi_device *scsidev, int cmd, void __user *arg)
+{
+ struct ata_port *ap;
+ struct ata_device *dev;
+ int val = -EINVAL, rc = -EINVAL;
+
+ ap = (struct ata_port *) &scsidev->host->hostdata[0];
+ if (!ap)
+ goto out;
+
+ dev = ata_scsi_find_dev(ap, scsidev);
+ if (!dev) {
+ rc = -ENODEV;
+ goto out;
+ }
+
+ switch (cmd) {
+ case ATA_IOC_GET_IO32:
+ val = 0;
+ if (copy_to_user(arg, &val, 1))
+ return -EFAULT;
+ return 0;
+
+ case ATA_IOC_SET_IO32:
+ val = (long) arg;
+ if (val != 0)
+ return -EINVAL;
+ return 0;
+
+ default:
+ rc = -EOPNOTSUPP;
+ break;
+ }
+
+out:
+ return rc;
+}
/**
* ata_scsi_qc_new - acquire new ata_queued_cmd reference
@@ -1172,19 +1212,19 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
* Associated ATA device, or %NULL if not found.
*/
-static inline struct ata_device *
-ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
+static struct ata_device *
+ata_scsi_find_dev(struct ata_port *ap, struct scsi_device *scsidev)
{
struct ata_device *dev;
/* skip commands not addressed to targets we simulate */
- if (likely(cmd->device->id < ATA_MAX_DEVICES))
- dev = &ap->device[cmd->device->id];
+ if (likely(scsidev->id < ATA_MAX_DEVICES))
+ dev = &ap->device[scsidev->id];
else
return NULL;
- if (unlikely((cmd->device->channel != 0) ||
- (cmd->device->lun != 0)))
+ if (unlikely((scsidev->channel != 0) ||
+ (scsidev->lun != 0)))
return NULL;
if (unlikely(!ata_dev_present(dev)))
@@ -1247,11 +1287,12 @@ static inline void ata_scsi_dump_cdb(struct ata_port *ap,
struct scsi_cmnd *cmd)
{
#ifdef ATA_DEBUG
+ struct scsi_device *scsidev = cmd->device;
u8 *scsicmd = cmd->cmnd;
DPRINTK("CDB (%u:%d,%d,%d) %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
ap->id,
- cmd->device->channel, cmd->device->id, cmd->device->lun,
+ scsidev->channel, scsidev->id, scsidev->lun,
scsicmd[0], scsicmd[1], scsicmd[2], scsicmd[3],
scsicmd[4], scsicmd[5], scsicmd[6], scsicmd[7],
scsicmd[8]);
@@ -1281,12 +1322,13 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
{
struct ata_port *ap;
struct ata_device *dev;
+ struct scsi_device *scsidev = cmd->device;
- ap = (struct ata_port *) &cmd->device->host->hostdata[0];
+ ap = (struct ata_port *) &scsidev->host->hostdata[0];
ata_scsi_dump_cdb(ap, cmd);
- dev = ata_scsi_find_dev(ap, cmd);
+ dev = ata_scsi_find_dev(ap, scsidev);
if (unlikely(!dev)) {
cmd->result = (DID_BAD_TARGET << 16);
done(cmd);
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h
index 460c72c1b80d8a..c09f953d749af7 100644
--- a/drivers/scsi/libata.h
+++ b/drivers/scsi/libata.h
@@ -42,6 +42,7 @@ extern int ata_qc_issue(struct ata_queued_cmd *qc);
extern void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep);
extern void ata_tf_to_host_nolock(struct ata_port *ap, struct ata_taskfile *tf);
+extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
/* libata-scsi.c */
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c
index a772f5f80f113d..1092a4b97d315f 100644
--- a/drivers/scsi/sata_nv.c
+++ b/drivers/scsi/sata_nv.c
@@ -178,6 +178,7 @@ static struct pci_driver nv_pci_driver = {
static Scsi_Host_Template nv_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c
index 50459877bd24e8..6cf0a718734550 100644
--- a/drivers/scsi/sata_promise.c
+++ b/drivers/scsi/sata_promise.c
@@ -88,6 +88,7 @@ static int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
static Scsi_Host_Template pdc_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c
index 5f8ae9c808c633..cc9917d11f3ecb 100644
--- a/drivers/scsi/sata_sil.c
+++ b/drivers/scsi/sata_sil.c
@@ -106,6 +106,7 @@ static struct pci_driver sil_pci_driver = {
static Scsi_Host_Template sil_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c
index 3c1a9549400104..68f83040df9a7a 100644
--- a/drivers/scsi/sata_sis.c
+++ b/drivers/scsi/sata_sis.c
@@ -76,6 +76,7 @@ static struct pci_driver sis_pci_driver = {
static Scsi_Host_Template sis_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c
index 03b59868835f3a..defd6930448eef 100644
--- a/drivers/scsi/sata_svw.c
+++ b/drivers/scsi/sata_svw.c
@@ -205,6 +205,7 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
static Scsi_Host_Template k2_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c
index 89cd82bfd975d3..634a08c6820a7d 100644
--- a/drivers/scsi/sata_sx4.c
+++ b/drivers/scsi/sata_sx4.c
@@ -174,6 +174,7 @@ static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
static Scsi_Host_Template pdc_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c
index 5aa40208483e20..6c0001f55b7566 100644
--- a/drivers/scsi/sata_via.c
+++ b/drivers/scsi/sata_via.c
@@ -81,6 +81,7 @@ static struct pci_driver svia_pci_driver = {
static Scsi_Host_Template svia_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c
index 2ff10ecf9156e6..3dbb5b7f4cd078 100644
--- a/drivers/scsi/sata_vsc.c
+++ b/drivers/scsi/sata_vsc.c
@@ -190,6 +190,7 @@ irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, struct pt_regs *reg
static Scsi_Host_Template vsc_sata_sht = {
.module = THIS_MODULE,
.name = DRV_NAME,
+ .ioctl = ata_scsi_ioctl,
.queuecommand = ata_scsi_queuecmd,
.eh_strategy_handler = ata_scsi_error,
.can_queue = ATA_DEF_QUEUE,