ide: move device settings code to ide-devsets.c
Remove stale comment from ide.c while at it. Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
parent
c4e66c36cc
commit
11938c9290
|
@ -5,7 +5,8 @@
|
||||||
EXTRA_CFLAGS += -Idrivers/ide
|
EXTRA_CFLAGS += -Idrivers/ide
|
||||||
|
|
||||||
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
|
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
|
||||||
ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o ide-sysfs.o
|
ide-taskfile.o ide-pm.o ide-park.o ide-pio-blacklist.o \
|
||||||
|
ide-sysfs.o ide-devsets.o
|
||||||
|
|
||||||
# core IDE code
|
# core IDE code
|
||||||
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
|
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/ide.h>
|
||||||
|
|
||||||
|
DEFINE_MUTEX(ide_setting_mtx);
|
||||||
|
|
||||||
|
ide_devset_get(io_32bit, io_32bit);
|
||||||
|
|
||||||
|
static int set_io_32bit(ide_drive_t *drive, int arg)
|
||||||
|
{
|
||||||
|
if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
drive->io_32bit = arg;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
|
||||||
|
|
||||||
|
static int set_ksettings(ide_drive_t *drive, int arg)
|
||||||
|
{
|
||||||
|
if (arg < 0 || arg > 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (arg)
|
||||||
|
drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
|
||||||
|
else
|
||||||
|
drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
|
||||||
|
|
||||||
|
static int set_using_dma(ide_drive_t *drive, int arg)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_BLK_DEV_IDEDMA
|
||||||
|
int err = -EPERM;
|
||||||
|
|
||||||
|
if (arg < 0 || arg > 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (ata_id_has_dma(drive->id) == 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (drive->hwif->dma_ops == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
if (arg) {
|
||||||
|
if (ide_set_dma(drive))
|
||||||
|
err = -EIO;
|
||||||
|
} else
|
||||||
|
ide_dma_off(drive);
|
||||||
|
|
||||||
|
out:
|
||||||
|
return err;
|
||||||
|
#else
|
||||||
|
if (arg < 0 || arg > 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return -EPERM;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
|
||||||
|
*/
|
||||||
|
static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
|
||||||
|
{
|
||||||
|
switch (req_pio) {
|
||||||
|
case 202:
|
||||||
|
case 201:
|
||||||
|
case 200:
|
||||||
|
case 102:
|
||||||
|
case 101:
|
||||||
|
case 100:
|
||||||
|
return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
|
||||||
|
case 9:
|
||||||
|
case 8:
|
||||||
|
return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
|
||||||
|
case 7:
|
||||||
|
case 6:
|
||||||
|
return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_pio_mode(ide_drive_t *drive, int arg)
|
||||||
|
{
|
||||||
|
ide_hwif_t *hwif = drive->hwif;
|
||||||
|
const struct ide_port_ops *port_ops = hwif->port_ops;
|
||||||
|
|
||||||
|
if (arg < 0 || arg > 255)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
|
||||||
|
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
|
||||||
|
return -ENOSYS;
|
||||||
|
|
||||||
|
if (set_pio_mode_abuse(drive->hwif, arg)) {
|
||||||
|
if (arg == 8 || arg == 9) {
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
|
||||||
|
spin_lock_irqsave(&hwif->lock, flags);
|
||||||
|
port_ops->set_pio_mode(drive, arg);
|
||||||
|
spin_unlock_irqrestore(&hwif->lock, flags);
|
||||||
|
} else
|
||||||
|
port_ops->set_pio_mode(drive, arg);
|
||||||
|
} else {
|
||||||
|
int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
|
||||||
|
|
||||||
|
ide_set_pio(drive, arg);
|
||||||
|
|
||||||
|
if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
|
||||||
|
if (keep_dma)
|
||||||
|
ide_dma_on(drive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
|
||||||
|
|
||||||
|
static int set_unmaskirq(ide_drive_t *drive, int arg)
|
||||||
|
{
|
||||||
|
if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (arg < 0 || arg > 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (arg)
|
||||||
|
drive->dev_flags |= IDE_DFLAG_UNMASK;
|
||||||
|
else
|
||||||
|
drive->dev_flags &= ~IDE_DFLAG_UNMASK;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_ext_devset_rw_sync(io_32bit, io_32bit);
|
||||||
|
ide_ext_devset_rw_sync(keepsettings, ksettings);
|
||||||
|
ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
|
||||||
|
ide_ext_devset_rw_sync(using_dma, using_dma);
|
||||||
|
__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
|
||||||
|
|
||||||
|
int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
|
||||||
|
int arg)
|
||||||
|
{
|
||||||
|
struct request_queue *q = drive->queue;
|
||||||
|
struct request *rq;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (!(setting->flags & DS_SYNC))
|
||||||
|
return setting->set(drive, arg);
|
||||||
|
|
||||||
|
rq = blk_get_request(q, READ, __GFP_WAIT);
|
||||||
|
rq->cmd_type = REQ_TYPE_SPECIAL;
|
||||||
|
rq->cmd_len = 5;
|
||||||
|
rq->cmd[0] = REQ_DEVSET_EXEC;
|
||||||
|
*(int *)&rq->cmd[1] = arg;
|
||||||
|
rq->special = setting->set;
|
||||||
|
|
||||||
|
if (blk_execute_rq(q, NULL, rq, 0))
|
||||||
|
ret = rq->errors;
|
||||||
|
blk_put_request(rq);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
|
||||||
|
{
|
||||||
|
int err, (*setfunc)(ide_drive_t *, int) = rq->special;
|
||||||
|
|
||||||
|
err = setfunc(drive, *(int *)&rq->cmd[1]);
|
||||||
|
if (err)
|
||||||
|
rq->errors = err;
|
||||||
|
else
|
||||||
|
err = 1;
|
||||||
|
ide_end_request(drive, err, 0);
|
||||||
|
return ide_stopped;
|
||||||
|
}
|
|
@ -490,43 +490,6 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
|
||||||
return ide_stopped;
|
return ide_stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
|
|
||||||
int arg)
|
|
||||||
{
|
|
||||||
struct request_queue *q = drive->queue;
|
|
||||||
struct request *rq;
|
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
if (!(setting->flags & DS_SYNC))
|
|
||||||
return setting->set(drive, arg);
|
|
||||||
|
|
||||||
rq = blk_get_request(q, READ, __GFP_WAIT);
|
|
||||||
rq->cmd_type = REQ_TYPE_SPECIAL;
|
|
||||||
rq->cmd_len = 5;
|
|
||||||
rq->cmd[0] = REQ_DEVSET_EXEC;
|
|
||||||
*(int *)&rq->cmd[1] = arg;
|
|
||||||
rq->special = setting->set;
|
|
||||||
|
|
||||||
if (blk_execute_rq(q, NULL, rq, 0))
|
|
||||||
ret = rq->errors;
|
|
||||||
blk_put_request(rq);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ide_startstop_t ide_do_devset(ide_drive_t *drive, struct request *rq)
|
|
||||||
{
|
|
||||||
int err, (*setfunc)(ide_drive_t *, int) = rq->special;
|
|
||||||
|
|
||||||
err = setfunc(drive, *(int *)&rq->cmd[1]);
|
|
||||||
if (err)
|
|
||||||
rq->errors = err;
|
|
||||||
else
|
|
||||||
err = 1;
|
|
||||||
ide_end_request(drive, err, 0);
|
|
||||||
return ide_stopped;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
|
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
|
||||||
{
|
{
|
||||||
u8 cmd = rq->cmd[0];
|
u8 cmd = rq->cmd[0];
|
||||||
|
|
|
@ -62,160 +62,6 @@
|
||||||
|
|
||||||
struct class *ide_port_class;
|
struct class *ide_port_class;
|
||||||
|
|
||||||
/*
|
|
||||||
* Locks for IDE setting functionality
|
|
||||||
*/
|
|
||||||
|
|
||||||
DEFINE_MUTEX(ide_setting_mtx);
|
|
||||||
|
|
||||||
ide_devset_get(io_32bit, io_32bit);
|
|
||||||
|
|
||||||
static int set_io_32bit(ide_drive_t *drive, int arg)
|
|
||||||
{
|
|
||||||
if (drive->dev_flags & IDE_DFLAG_NO_IO_32BIT)
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
if (arg < 0 || arg > 1 + (SUPPORT_VLB_SYNC << 1))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
drive->io_32bit = arg;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ide_devset_get_flag(ksettings, IDE_DFLAG_KEEP_SETTINGS);
|
|
||||||
|
|
||||||
static int set_ksettings(ide_drive_t *drive, int arg)
|
|
||||||
{
|
|
||||||
if (arg < 0 || arg > 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (arg)
|
|
||||||
drive->dev_flags |= IDE_DFLAG_KEEP_SETTINGS;
|
|
||||||
else
|
|
||||||
drive->dev_flags &= ~IDE_DFLAG_KEEP_SETTINGS;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ide_devset_get_flag(using_dma, IDE_DFLAG_USING_DMA);
|
|
||||||
|
|
||||||
static int set_using_dma(ide_drive_t *drive, int arg)
|
|
||||||
{
|
|
||||||
#ifdef CONFIG_BLK_DEV_IDEDMA
|
|
||||||
int err = -EPERM;
|
|
||||||
|
|
||||||
if (arg < 0 || arg > 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (ata_id_has_dma(drive->id) == 0)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
if (drive->hwif->dma_ops == NULL)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
if (arg) {
|
|
||||||
if (ide_set_dma(drive))
|
|
||||||
err = -EIO;
|
|
||||||
} else
|
|
||||||
ide_dma_off(drive);
|
|
||||||
|
|
||||||
out:
|
|
||||||
return err;
|
|
||||||
#else
|
|
||||||
if (arg < 0 || arg > 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
return -EPERM;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* handle HDIO_SET_PIO_MODE ioctl abusers here, eventually it will go away
|
|
||||||
*/
|
|
||||||
static int set_pio_mode_abuse(ide_hwif_t *hwif, u8 req_pio)
|
|
||||||
{
|
|
||||||
switch (req_pio) {
|
|
||||||
case 202:
|
|
||||||
case 201:
|
|
||||||
case 200:
|
|
||||||
case 102:
|
|
||||||
case 101:
|
|
||||||
case 100:
|
|
||||||
return (hwif->host_flags & IDE_HFLAG_ABUSE_DMA_MODES) ? 1 : 0;
|
|
||||||
case 9:
|
|
||||||
case 8:
|
|
||||||
return (hwif->host_flags & IDE_HFLAG_ABUSE_PREFETCH) ? 1 : 0;
|
|
||||||
case 7:
|
|
||||||
case 6:
|
|
||||||
return (hwif->host_flags & IDE_HFLAG_ABUSE_FAST_DEVSEL) ? 1 : 0;
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int set_pio_mode(ide_drive_t *drive, int arg)
|
|
||||||
{
|
|
||||||
ide_hwif_t *hwif = drive->hwif;
|
|
||||||
const struct ide_port_ops *port_ops = hwif->port_ops;
|
|
||||||
|
|
||||||
if (arg < 0 || arg > 255)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (port_ops == NULL || port_ops->set_pio_mode == NULL ||
|
|
||||||
(hwif->host_flags & IDE_HFLAG_NO_SET_MODE))
|
|
||||||
return -ENOSYS;
|
|
||||||
|
|
||||||
if (set_pio_mode_abuse(drive->hwif, arg)) {
|
|
||||||
if (arg == 8 || arg == 9) {
|
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
/* take lock for IDE_DFLAG_[NO_]UNMASK/[NO_]IO_32BIT */
|
|
||||||
spin_lock_irqsave(&hwif->lock, flags);
|
|
||||||
port_ops->set_pio_mode(drive, arg);
|
|
||||||
spin_unlock_irqrestore(&hwif->lock, flags);
|
|
||||||
} else
|
|
||||||
port_ops->set_pio_mode(drive, arg);
|
|
||||||
} else {
|
|
||||||
int keep_dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
|
|
||||||
|
|
||||||
ide_set_pio(drive, arg);
|
|
||||||
|
|
||||||
if (hwif->host_flags & IDE_HFLAG_SET_PIO_MODE_KEEP_DMA) {
|
|
||||||
if (keep_dma)
|
|
||||||
ide_dma_on(drive);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ide_devset_get_flag(unmaskirq, IDE_DFLAG_UNMASK);
|
|
||||||
|
|
||||||
static int set_unmaskirq(ide_drive_t *drive, int arg)
|
|
||||||
{
|
|
||||||
if (drive->dev_flags & IDE_DFLAG_NO_UNMASK)
|
|
||||||
return -EPERM;
|
|
||||||
|
|
||||||
if (arg < 0 || arg > 1)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (arg)
|
|
||||||
drive->dev_flags |= IDE_DFLAG_UNMASK;
|
|
||||||
else
|
|
||||||
drive->dev_flags &= ~IDE_DFLAG_UNMASK;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ide_ext_devset_rw_sync(io_32bit, io_32bit);
|
|
||||||
ide_ext_devset_rw_sync(keepsettings, ksettings);
|
|
||||||
ide_ext_devset_rw_sync(unmaskirq, unmaskirq);
|
|
||||||
ide_ext_devset_rw_sync(using_dma, using_dma);
|
|
||||||
__IDE_DEVSET(pio_mode, DS_SYNC, NULL, set_pio_mode);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ide_device_get - get an additional reference to a ide_drive_t
|
* ide_device_get - get an additional reference to a ide_drive_t
|
||||||
* @drive: device to get a reference to
|
* @drive: device to get a reference to
|
||||||
|
|
|
@ -1170,6 +1170,7 @@ int ide_busy_sleep(ide_hwif_t *, unsigned long, int);
|
||||||
int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
|
int ide_wait_stat(ide_startstop_t *, ide_drive_t *, u8, u8, unsigned long);
|
||||||
|
|
||||||
ide_startstop_t ide_do_park_unpark(ide_drive_t *, struct request *);
|
ide_startstop_t ide_do_park_unpark(ide_drive_t *, struct request *);
|
||||||
|
ide_startstop_t ide_do_devset(ide_drive_t *, struct request *);
|
||||||
|
|
||||||
extern ide_startstop_t ide_do_reset (ide_drive_t *);
|
extern ide_startstop_t ide_do_reset (ide_drive_t *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue