static void scc_dma_start(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 dma_cmd = scc_ide_inb(hwif->dma_base); /* start DMA */ scc_ide_outb(dma_cmd | 1, hwif->dma_base); }
static int __scc_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 dma_stat, dma_cmd; drive->waiting_for_dma = 0; /* get DMA command mode */ dma_cmd = scc_ide_inb(hwif->dma_base); /* stop DMA */ scc_ide_outb(dma_cmd & ~1, hwif->dma_base); /* get DMA status */ dma_stat = scc_ide_inb(hwif->dma_base + 4); /* clear the INTR & ERROR bits */ scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); /* purge DMA mappings */ ide_destroy_dmatable(drive); /* verify good DMA status */ hwif->dma = 0; wmb(); return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; }
static void scc_dma_host_set(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; u8 unit = (drive->select.b.unit & 0x01); u8 dma_stat = scc_ide_inb(hwif->dma_base + 4); if (on) dma_stat |= (1 << (5 + unit)); else dma_stat &= ~(1 << (5 + unit)); scc_ide_outb(dma_stat, hwif->dma_base + 4); }
static int __scc_dma_end(ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; u8 dma_stat, dma_cmd; /* get DMA command mode */ dma_cmd = scc_ide_inb(hwif->dma_base); /* stop DMA */ scc_ide_outb(dma_cmd & ~1, hwif->dma_base); /* get DMA status */ dma_stat = scc_dma_sff_read_status(hwif); /* clear the INTR & ERROR bits */ scc_ide_outb(dma_stat | 6, hwif->dma_base + 4); /* verify good DMA status */ return (dma_stat & 7) != 4 ? (0x10 | dma_stat) : 0; }
static void scc_tf_read(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; if (valid & IDE_VALID_ERROR) tf->error = scc_ide_inb(io_ports->feature_addr); if (valid & IDE_VALID_NSECT) tf->nsect = scc_ide_inb(io_ports->nsect_addr); if (valid & IDE_VALID_LBAL) tf->lbal = scc_ide_inb(io_ports->lbal_addr); if (valid & IDE_VALID_LBAM) tf->lbam = scc_ide_inb(io_ports->lbam_addr); if (valid & IDE_VALID_LBAH) tf->lbah = scc_ide_inb(io_ports->lbah_addr); if (valid & IDE_VALID_DEVICE) tf->device = scc_ide_inb(io_ports->device_addr); }
static void scc_tf_read(ide_drive_t *drive, struct ide_cmd *cmd) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; struct ide_taskfile *tf = &cmd->tf; /* be sure we're looking at the low order bits */ scc_ide_outb(ATA_DEVCTL_OBS, io_ports->ctl_addr); if (cmd->tf_flags & IDE_TFLAG_IN_ERROR) tf->error = scc_ide_inb(io_ports->feature_addr); if (cmd->tf_flags & IDE_TFLAG_IN_NSECT) tf->nsect = scc_ide_inb(io_ports->nsect_addr); if (cmd->tf_flags & IDE_TFLAG_IN_LBAL) tf->lbal = scc_ide_inb(io_ports->lbal_addr); if (cmd->tf_flags & IDE_TFLAG_IN_LBAM) tf->lbam = scc_ide_inb(io_ports->lbam_addr); if (cmd->tf_flags & IDE_TFLAG_IN_LBAH) tf->lbah = scc_ide_inb(io_ports->lbah_addr); if (cmd->tf_flags & IDE_TFLAG_IN_DEVICE) tf->device = scc_ide_inb(io_ports->device_addr); if (cmd->tf_flags & IDE_TFLAG_LBA48) { scc_ide_outb(ATA_HOB | ATA_DEVCTL_OBS, io_ports->ctl_addr); if (cmd->tf_flags & IDE_TFLAG_IN_HOB_ERROR) tf->hob_error = scc_ide_inb(io_ports->feature_addr); if (cmd->tf_flags & IDE_TFLAG_IN_HOB_NSECT) tf->hob_nsect = scc_ide_inb(io_ports->nsect_addr); if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAL) tf->hob_lbal = scc_ide_inb(io_ports->lbal_addr); if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAM) tf->hob_lbam = scc_ide_inb(io_ports->lbam_addr); if (cmd->tf_flags & IDE_TFLAG_IN_HOB_LBAH) tf->hob_lbah = scc_ide_inb(io_ports->lbah_addr); } }