-
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.
yaml --- r: 133375 b: refs/heads/master c: 11938c9 h: refs/heads/master i: 133373: 523c1c4 133371: 5b2f930 133367: e1cf312 133359: fa93c01 133343: 22dcde8 133311: 128e0f6 133247: cdcff01 133119: d1f7ac0 v: v3
- Loading branch information
Bartlomiej Zolnierkiewicz
committed
Mar 24, 2009
1 parent
c088286
commit 0c995b7
Showing
6 changed files
with
194 additions
and
193 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: c4e66c36cce3f23d68013c4112013123ffe80bdb | ||
refs/heads/master: 11938c929022bb92b1a42f5e1289524a1e465dc0 |
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.