diff options
author | Dave Jones <davej@redhat.com> | 2006-12-12 18:13:32 -0500 |
---|---|---|
committer | Dave Jones <davej@redhat.com> | 2006-12-12 18:13:32 -0500 |
commit | f0eef25339f92f7cd4aeea23d9ae97987a5a1e82 (patch) | |
tree | 2472e94d39f43a9580a6d2d5d92de0b749023263 /drivers/ide/ide-lib.c | |
parent | 0cfea5dd98205f2fa318836da664a7d7df1afbc1 (diff) | |
parent | e1036502e5263851259d147771226161e5ccc85a (diff) |
Merge ../linus
Diffstat (limited to 'drivers/ide/ide-lib.c')
-rw-r--r-- | drivers/ide/ide-lib.c | 130 |
1 files changed, 76 insertions, 54 deletions
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 1feff23487d..8237d89eec6 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -71,75 +71,96 @@ EXPORT_SYMBOL(ide_xfer_verbose); /** * ide_dma_speed - compute DMA speed * @drive: drive - * @mode; intended mode + * @mode: modes available * * Checks the drive capabilities and returns the speed to use - * for the transfer. Returns -1 if the requested mode is unknown - * (eg PIO) + * for the DMA transfer. Returns 0 if the drive is incapable + * of DMA transfers. */ u8 ide_dma_speed(ide_drive_t *drive, u8 mode) { struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); + u8 ultra_mask, mwdma_mask, swdma_mask; u8 speed = 0; if (drive->media != ide_disk && hwif->atapi_dma == 0) return 0; - switch(mode) { - case 0x04: - if ((id->dma_ultra & 0x0040) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_6; break; } - case 0x03: - if ((id->dma_ultra & 0x0020) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_5; break; } - case 0x02: - if ((id->dma_ultra & 0x0010) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_4; break; } - if ((id->dma_ultra & 0x0008) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_3; break; } - case 0x01: - if ((id->dma_ultra & 0x0004) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_2; break; } - if ((id->dma_ultra & 0x0002) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_1; break; } - if ((id->dma_ultra & 0x0001) && - (id->dma_ultra & hwif->ultra_mask)) - { speed = XFER_UDMA_0; break; } - case 0x00: - if ((id->dma_mword & 0x0004) && - (id->dma_mword & hwif->mwdma_mask)) - { speed = XFER_MW_DMA_2; break; } - if ((id->dma_mword & 0x0002) && - (id->dma_mword & hwif->mwdma_mask)) - { speed = XFER_MW_DMA_1; break; } - if ((id->dma_mword & 0x0001) && - (id->dma_mword & hwif->mwdma_mask)) - { speed = XFER_MW_DMA_0; break; } - if ((id->dma_1word & 0x0004) && - (id->dma_1word & hwif->swdma_mask)) - { speed = XFER_SW_DMA_2; break; } - if ((id->dma_1word & 0x0002) && - (id->dma_1word & hwif->swdma_mask)) - { speed = XFER_SW_DMA_1; break; } - if ((id->dma_1word & 0x0001) && - (id->dma_1word & hwif->swdma_mask)) - { speed = XFER_SW_DMA_0; break; } - } + /* Capable of UltraDMA modes? */ + ultra_mask = id->dma_ultra & hwif->ultra_mask; + + if (!(id->field_valid & 4)) + mode = 0; /* fallback to MW/SW DMA if no UltraDMA */ + + switch (mode) { + case 4: + if (ultra_mask & 0x40) { + speed = XFER_UDMA_6; + break; + } + case 3: + if (ultra_mask & 0x20) { + speed = XFER_UDMA_5; + break; + } + case 2: + if (ultra_mask & 0x10) { + speed = XFER_UDMA_4; + break; + } + if (ultra_mask & 0x08) { + speed = XFER_UDMA_3; + break; + } + case 1: + if (ultra_mask & 0x04) { + speed = XFER_UDMA_2; + break; + } + if (ultra_mask & 0x02) { + speed = XFER_UDMA_1; + break; + } + if (ultra_mask & 0x01) { + speed = XFER_UDMA_0; + break; + } + case 0: + mwdma_mask = id->dma_mword & hwif->mwdma_mask; -// printk("%s: %s: mode 0x%02x, speed 0x%02x\n", -// __FUNCTION__, drive->name, mode, speed); + if (mwdma_mask & 0x04) { + speed = XFER_MW_DMA_2; + break; + } + if (mwdma_mask & 0x02) { + speed = XFER_MW_DMA_1; + break; + } + if (mwdma_mask & 0x01) { + speed = XFER_MW_DMA_0; + break; + } + + swdma_mask = id->dma_1word & hwif->swdma_mask; + + if (swdma_mask & 0x04) { + speed = XFER_SW_DMA_2; + break; + } + if (swdma_mask & 0x02) { + speed = XFER_SW_DMA_1; + break; + } + if (swdma_mask & 0x01) { + speed = XFER_SW_DMA_0; + break; + } + } return speed; } - EXPORT_SYMBOL(ide_dma_speed); @@ -456,13 +477,14 @@ static void ide_dump_opcode(ide_drive_t *drive) spin_unlock(&ide_lock); if (!rq) return; - if (rq->flags & (REQ_DRIVE_CMD | REQ_DRIVE_TASK)) { + if (rq->cmd_type == REQ_TYPE_ATA_CMD || + rq->cmd_type == REQ_TYPE_ATA_TASK) { char *args = rq->buffer; if (args) { opcode = args[0]; found = 1; } - } else if (rq->flags & REQ_DRIVE_TASKFILE) { + } else if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { ide_task_t *args = rq->special; if (args) { task_struct_t *tf = (task_struct_t *) args->tfRegister; |