diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2004-08-14 07:38:01 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2004-08-14 07:38:01 -0400 |
commit | 815b472b87a7074bb171213aedd4c6c439e6b18d (patch) | |
tree | 816945734b4eade37a4985ee8836672deb9aa9d8 /drivers | |
parent | 7af09f972ad4360d99a0f9dfbbaaaa4050eb055c (diff) | |
download | history-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.c | 1 | ||||
-rw-r--r-- | drivers/scsi/libata-core.c | 4 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 60 | ||||
-rw-r--r-- | drivers/scsi/libata.h | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_nv.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_promise.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_sil.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_sis.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_svw.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_sx4.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_via.c | 1 | ||||
-rw-r--r-- | drivers/scsi/sata_vsc.c | 1 |
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, |