예제 #1
0
int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
	ide_hwif_t *hwif = HWIF(drive);
	int ix, dstat;
	volatile struct dbdma_regs *dma;

	/* Can we stuff a pointer to our intf structure in config_data
	 * or select_data in hwif ?
	 */
	ix = pmac_ide_find(drive);
	if (ix < 0)
		return 0;		
	dma = pmac_ide[ix].dma_regs;

	switch (func) {
	case ide_dma_on:
	case ide_dma_off:
	case ide_dma_off_quietly:
		pmac_ide_dma_onoff(drive, (func == ide_dma_on));
		break;
	case ide_dma_check:
		if (hwif->autodma)
			pmac_ide_dma_onoff(drive, 1);
		break;
	case ide_dma_read:
	case ide_dma_write:
		if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write))
			return 1;
		drive->waiting_for_dma = 1;
		if (drive->media != ide_disk)
			return 0;
		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
		OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
			 IDE_COMMAND_REG);
	case ide_dma_begin:
		out_le32(&dma->control, (RUN << 16) | RUN);
		break;
	case ide_dma_end:
		drive->waiting_for_dma = 0;
		dstat = in_le32(&dma->status);
		out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
		/* verify good dma status */
		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
	case ide_dma_test_irq:
		return (in_le32(&dma->status) & (RUN|ACTIVE)) == RUN;
	default:
		printk(KERN_ERR "pmac_ide_dmaproc: bad func %d\n", func);
	}
	return 0;
}
예제 #2
0
파일: pmac.c 프로젝트: AK101111/linux
/*
 * Prepare a DMA transfer. We build the DMA table, adjust the timings for
 * a read on KeyLargo ATA/66 and mark us as waiting for DMA completion
 */
static int pmac_ide_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
{
	ide_hwif_t *hwif = drive->hwif;
	pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);
	u8 unit = drive->dn & 1, ata4 = (pmif->kind == controller_kl_ata4);
	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);

	if (pmac_ide_build_dmatable(drive, cmd) == 0)
		return 1;

	/* Apple adds 60ns to wrDataSetup on reads */
	if (ata4 && (pmif->timings[unit] & TR_66_UDMA_EN)) {
		writel(pmif->timings[unit] + (write ? 0 : 0x00800000UL),
			PMAC_IDE_REG(IDE_TIMING_CONFIG));
		(void)readl(PMAC_IDE_REG(IDE_TIMING_CONFIG));
	}

	return 0;
}
예제 #3
0
int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
{
	int ix, dstat, i;
	volatile struct dbdma_regs *dma;

	/* Can we stuff a pointer to our intf structure in config_data
	 * or select_data in hwif ?
	 */
	ix = pmac_ide_find(drive);
	if (ix < 0)
		return 0;		
	dma = pmac_ide[ix].dma_regs;

	switch (func) {
	case ide_dma_off:
		printk(KERN_INFO "%s: DMA disabled\n", drive->name);
	case ide_dma_off_quietly:
		drive->using_dma = 0;
		break;
	case ide_dma_on:
	case ide_dma_check:
		pmac_ide_check_dma(drive);
		break;
	case ide_dma_read:
	case ide_dma_write:
		if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write))
			return 1;
		drive->waiting_for_dma = 1;
		if (drive->media != ide_disk)
			return 0;
		ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
		OUT_BYTE(func==ide_dma_write? WIN_WRITEDMA: WIN_READDMA,
			 IDE_COMMAND_REG);
	case ide_dma_begin:
		out_le32(&dma->control, (RUN << 16) | RUN);
		break;
	case ide_dma_end:
		drive->waiting_for_dma = 0;
		dstat = in_le32(&dma->status);
		out_le32(&dma->control, ((RUN|WAKE|DEAD) << 16));
		/* verify good dma status */
		return (dstat & (RUN|DEAD|ACTIVE)) != RUN;
	case ide_dma_test_irq:
		if ((in_le32(&dma->status) & (RUN|ACTIVE)) == RUN)
			return 1;
		/* That's a bit ugly and dangerous, but works in our case
		 * to workaround a problem with the channel status staying
		 * active if the drive returns an error
		 */
		if (IDE_CONTROL_REG) {
			byte stat;
			stat = GET_ALTSTAT();
			if (stat & ERR_STAT)
				return 1;
		}
		/* In some edge cases, some datas may still be in the dbdma
		 * engine fifo, we wait a bit for dbdma to complete
		 */
		while ((in_le32(&dma->status) & (RUN|ACTIVE)) != RUN) {
			if (++i > 100)
				return 0;
			udelay(1);
		}
		return 1;

		/* Let's implement tose just in case someone wants them */
	case ide_dma_bad_drive:
	case ide_dma_good_drive:
		return check_drive_lists(drive, (func == ide_dma_good_drive));
	case ide_dma_verbose:
		return report_drive_dmaing(drive);
	case ide_dma_retune:
	case ide_dma_lostirq:
	case ide_dma_timeout:
		printk(KERN_WARNING "ide_pmac_dmaproc: chipset supported %s func only: %d\n", ide_dmafunc_verbose(func),  func);
		return 1;
	default:
		printk(KERN_WARNING "ide_pmac_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func);
		return 1;
	}
	return 0;
}