-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
- Loading branch information
Bartlomiej Zolnierkiewicz
committed
Mar 24, 2009
1 parent
c4e66c3
commit 11938c9
Showing
5 changed files
with
193 additions
and
192 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.