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_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 void scc_dma_host_set(ide_drive_t *drive, int on) { ide_hwif_t *hwif = drive->hwif; u8 unit = drive->dn & 1; u8 dma_stat = scc_dma_sff_read_status(hwif); if (on) dma_stat |= (1 << (5 + unit)); else dma_stat &= ~(1 << (5 + unit)); scc_ide_outb(dma_stat, hwif->dma_base + 4); }
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); } }
static void scc_tf_load(ide_drive_t *drive, struct ide_taskfile *tf, u8 valid) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; if (valid & IDE_VALID_FEATURE) scc_ide_outb(tf->feature, io_ports->feature_addr); if (valid & IDE_VALID_NSECT) scc_ide_outb(tf->nsect, io_ports->nsect_addr); if (valid & IDE_VALID_LBAL) scc_ide_outb(tf->lbal, io_ports->lbal_addr); if (valid & IDE_VALID_LBAM) scc_ide_outb(tf->lbam, io_ports->lbam_addr); if (valid & IDE_VALID_LBAH) scc_ide_outb(tf->lbah, io_ports->lbah_addr); if (valid & IDE_VALID_DEVICE) scc_ide_outb(tf->device, io_ports->device_addr); }
static void scc_tf_load(ide_drive_t *drive, ide_task_t *task) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; struct ide_taskfile *tf = &task->tf; u8 HIHI = (task->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; if (task->tf_flags & IDE_TFLAG_FLAGGED) HIHI = 0xFF; if (task->tf_flags & IDE_TFLAG_OUT_DATA) out_be32((void *)io_ports->data_addr, (tf->hob_data << 8) | tf->data); if (task->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) scc_ide_outb(tf->hob_feature, io_ports->feature_addr); if (task->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr); if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr); if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr); if (task->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_FEATURE) scc_ide_outb(tf->feature, io_ports->feature_addr); if (task->tf_flags & IDE_TFLAG_OUT_NSECT) scc_ide_outb(tf->nsect, io_ports->nsect_addr); if (task->tf_flags & IDE_TFLAG_OUT_LBAL) scc_ide_outb(tf->lbal, io_ports->lbal_addr); if (task->tf_flags & IDE_TFLAG_OUT_LBAM) scc_ide_outb(tf->lbam, io_ports->lbam_addr); if (task->tf_flags & IDE_TFLAG_OUT_LBAH) scc_ide_outb(tf->lbah, io_ports->lbah_addr); if (task->tf_flags & IDE_TFLAG_OUT_DEVICE) scc_ide_outb((tf->device & HIHI) | drive->select.all, io_ports->device_addr); }
static void scc_tf_load(ide_drive_t *drive, struct ide_cmd *cmd) { struct ide_io_ports *io_ports = &drive->hwif->io_ports; struct ide_taskfile *tf = &cmd->tf; u8 HIHI = (cmd->tf_flags & IDE_TFLAG_LBA48) ? 0xE0 : 0xEF; if (cmd->ftf_flags & IDE_FTFLAG_FLAGGED) HIHI = 0xFF; if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_FEATURE) scc_ide_outb(tf->hob_feature, io_ports->feature_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_NSECT) scc_ide_outb(tf->hob_nsect, io_ports->nsect_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAL) scc_ide_outb(tf->hob_lbal, io_ports->lbal_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAM) scc_ide_outb(tf->hob_lbam, io_ports->lbam_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_HOB_LBAH) scc_ide_outb(tf->hob_lbah, io_ports->lbah_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_FEATURE) scc_ide_outb(tf->feature, io_ports->feature_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_NSECT) scc_ide_outb(tf->nsect, io_ports->nsect_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_LBAL) scc_ide_outb(tf->lbal, io_ports->lbal_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_LBAM) scc_ide_outb(tf->lbam, io_ports->lbam_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_LBAH) scc_ide_outb(tf->lbah, io_ports->lbah_addr); if (cmd->tf_flags & IDE_TFLAG_OUT_DEVICE) scc_ide_outb((tf->device & HIHI) | drive->select, io_ports->device_addr); }