📄 au1xxx-ide.c
字号:
/* Is the drive in our DMA black list? */ if ( auide_hwif.black_list ) { drive->using_dma = 0; /* Borrowed the warning message from ide-dma.c */ printk(KERN_WARNING "%s: Disabling DMA for %s (blacklisted)\n", drive->name, drive->id->model); } else drive->using_dma = 1; speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA); if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) return HWIF(drive)->ide_dma_on(drive); return HWIF(drive)->ide_dma_off_quietly(drive);}static int auide_dma_test_irq(ide_drive_t *drive){ if (drive->waiting_for_dma == 0) printk(KERN_WARNING "%s: ide_dma_test_irq \ called while not waiting\n", drive->name); /* If dbdma didn't execute the STOP command yet, the * active bit is still set */ drive->waiting_for_dma++; if (drive->waiting_for_dma >= DMA_WAIT_TIMEOUT) { printk(KERN_WARNING "%s: timeout waiting for ddma to \ complete\n", drive->name); return 1; } udelay(10); return 0;}static int auide_dma_host_on(ide_drive_t *drive){ return 0;}static int auide_dma_on(ide_drive_t *drive){ drive->using_dma = 1; return auide_dma_host_on(drive);}static int auide_dma_host_off(ide_drive_t *drive){ return 0;}static int auide_dma_off_quietly(ide_drive_t *drive){ drive->using_dma = 0; return auide_dma_host_off(drive);}static int auide_dma_lostirq(ide_drive_t *drive){ printk(KERN_ERR "%s: IRQ lost\n", drive->name); return 0;}static void auide_ddma_tx_callback(int irq, void *param, struct pt_regs *regs){ _auide_hwif *ahwif = (_auide_hwif*)param; ahwif->drive->waiting_for_dma = 0;}static void auide_ddma_rx_callback(int irq, void *param, struct pt_regs *regs){ _auide_hwif *ahwif = (_auide_hwif*)param; ahwif->drive->waiting_for_dma = 0;}#endif /* end CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */static void auide_init_dbdma_dev(dbdev_tab_t *dev, u32 dev_id, u32 tsize, u32 devwidth, u32 flags){ dev->dev_id = dev_id; dev->dev_physaddr = (u32)AU1XXX_ATA_PHYS_ADDR; dev->dev_intlevel = 0; dev->dev_intpolarity = 0; dev->dev_tsize = tsize; dev->dev_devwidth = devwidth; dev->dev_flags = flags;} #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA)static int auide_dma_timeout(ide_drive_t *drive){// printk("%s\n", __FUNCTION__); printk(KERN_ERR "%s: DMA timeout occurred: ", drive->name); if (HWIF(drive)->ide_dma_test_irq(drive)) return 0; return HWIF(drive)->ide_dma_end(drive);} static int auide_ddma_init(_auide_hwif *auide) { dbdev_tab_t source_dev_tab, target_dev_tab; u32 dev_id, tsize, devwidth, flags; ide_hwif_t *hwif = auide->hwif; dev_id = AU1XXX_ATA_DDMA_REQ; if (auide->white_list || auide->black_list) { tsize = 8; devwidth = 32; } else { tsize = 1; devwidth = 16; printk(KERN_ERR "au1xxx-ide: %s is not on ide driver whitelist.\n",auide_hwif.drive->id->model); printk(KERN_ERR " please read 'Documentation/mips/AU1xxx_IDE.README'"); }#ifdef IDE_AU1XXX_BURSTMODE flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;#else flags = DEV_FLAGS_SYNC;#endif /* setup dev_tab for tx channel */ auide_init_dbdma_dev( &source_dev_tab, dev_id, tsize, devwidth, DEV_FLAGS_OUT | flags); auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide_init_dbdma_dev( &source_dev_tab, dev_id, tsize, devwidth, DEV_FLAGS_IN | flags); auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); /* We also need to add a target device for the DMA */ auide_init_dbdma_dev( &target_dev_tab, (u32)DSCR_CMD0_ALWAYS, tsize, devwidth, DEV_FLAGS_ANYUSE); auide->target_dev_id = au1xxx_ddma_add_device(&target_dev_tab); /* Get a channel for TX */ auide->tx_chan = au1xxx_dbdma_chan_alloc(auide->target_dev_id, auide->tx_dev_id, auide_ddma_tx_callback, (void*)auide); /* Get a channel for RX */ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, auide->target_dev_id, auide_ddma_rx_callback, (void*)auide); auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, NUM_DESCRIPTORS); auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, NUM_DESCRIPTORS); hwif->dmatable_cpu = dma_alloc_coherent(auide->dev, PRD_ENTRIES * PRD_BYTES, /* 1 Page */ &hwif->dmatable_dma, GFP_KERNEL); au1xxx_dbdma_start( auide->tx_chan ); au1xxx_dbdma_start( auide->rx_chan ); return 0;} #else static int auide_ddma_init( _auide_hwif *auide ){ dbdev_tab_t source_dev_tab; int flags;#ifdef IDE_AU1XXX_BURSTMODE flags = DEV_FLAGS_SYNC | DEV_FLAGS_BURSTABLE;#else flags = DEV_FLAGS_SYNC;#endif /* setup dev_tab for tx channel */ auide_init_dbdma_dev( &source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32, DEV_FLAGS_OUT | flags); auide->tx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); auide_init_dbdma_dev( &source_dev_tab, (u32)DSCR_CMD0_ALWAYS, 8, 32, DEV_FLAGS_IN | flags); auide->rx_dev_id = au1xxx_ddma_add_device( &source_dev_tab ); /* Get a channel for TX */ auide->tx_chan = au1xxx_dbdma_chan_alloc(DSCR_CMD0_ALWAYS, auide->tx_dev_id, NULL, (void*)auide); /* Get a channel for RX */ auide->rx_chan = au1xxx_dbdma_chan_alloc(auide->rx_dev_id, DSCR_CMD0_ALWAYS, NULL, (void*)auide); auide->tx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->tx_chan, NUM_DESCRIPTORS); auide->rx_desc_head = (void*)au1xxx_dbdma_ring_alloc(auide->rx_chan, NUM_DESCRIPTORS); au1xxx_dbdma_start( auide->tx_chan ); au1xxx_dbdma_start( auide->rx_chan ); return 0;}#endifstatic void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif){ int i; unsigned long *ata_regs = hw->io_ports; /* FIXME? */ for (i = 0; i < IDE_CONTROL_OFFSET; i++) { *ata_regs++ = ahwif->regbase + (i << AU1XXX_ATA_REG_OFFSET); } /* set the Alternative Status register */ *ata_regs = ahwif->regbase + (14 << AU1XXX_ATA_REG_OFFSET);}static int au_ide_probe(struct device *dev){ struct platform_device *pdev = to_platform_device(dev); _auide_hwif *ahwif = &auide_hwif; ide_hwif_t *hwif; struct resource *res; int ret = 0;#if defined(CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA) char *mode = "MWDMA2";#elif defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA) char *mode = "PIO+DDMA(offload)";#endif memset(&auide_hwif, 0, sizeof(_auide_hwif)); auide_hwif.dev = 0; ahwif->dev = dev; ahwif->irq = platform_get_irq(pdev, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { pr_debug("%s %d: no base address\n", DRV_NAME, pdev->id); ret = -ENODEV; goto out; } if (!request_mem_region (res->start, res->end-res->start, pdev->name)) { pr_debug("%s: request_mem_region failed\n", DRV_NAME); ret = -EBUSY; goto out; } ahwif->regbase = (u32)ioremap(res->start, res->end-res->start); if (ahwif->regbase == 0) { ret = -ENOMEM; goto out; } /* FIXME: This might possibly break PCMCIA IDE devices */ hwif = &ide_hwifs[pdev->id]; hw_regs_t *hw = &hwif->hw; hwif->irq = hw->irq = ahwif->irq; hwif->chipset = ide_au1xxx; auide_setup_ports(hw, ahwif); memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); hwif->ultra_mask = 0x0; /* Disable Ultra DMA */#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA hwif->mwdma_mask = 0x07; /* Multimode-2 DMA */ hwif->swdma_mask = 0x00;#else hwif->mwdma_mask = 0x0; hwif->swdma_mask = 0x0;#endif hwif->noprobe = 0; hwif->drives[0].unmask = 1; hwif->drives[1].unmask = 1; /* hold should be on in all cases */ hwif->hold = 1; hwif->mmio = 2; /* If the user has selected DDMA assisted copies, then set up a few local I/O function entry points */#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA hwif->INSW = auide_insw; hwif->OUTSW = auide_outsw;#endif hwif->tuneproc = &auide_tune_drive; hwif->speedproc = &auide_tune_chipset;#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA hwif->ide_dma_off_quietly = &auide_dma_off_quietly; hwif->ide_dma_timeout = &auide_dma_timeout; hwif->ide_dma_check = &auide_dma_check; hwif->dma_exec_cmd = &auide_dma_exec_cmd; hwif->dma_start = &auide_dma_start; hwif->ide_dma_end = &auide_dma_end; hwif->dma_setup = &auide_dma_setup; hwif->ide_dma_test_irq = &auide_dma_test_irq; hwif->ide_dma_host_off = &auide_dma_host_off; hwif->ide_dma_host_on = &auide_dma_host_on; hwif->ide_dma_lostirq = &auide_dma_lostirq; hwif->ide_dma_on = &auide_dma_on; hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; hwif->atapi_dma = 1;#else /* !CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA */ hwif->autodma = 0; hwif->channel = 0; hwif->hold = 1; hwif->select_data = 0; /* no chipset-specific code */ hwif->config_data = 0; /* no chipset-specific code */ hwif->drives[0].autodma = 0; hwif->drives[0].autotune = 1; /* 1=autotune, 2=noautotune, 0=default */#endif hwif->drives[0].no_io_32bit = 1; auide_hwif.hwif = hwif; hwif->hwif_data = &auide_hwif;#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA auide_ddma_init(&auide_hwif); dbdma_init_done = 1;#endif probe_hwif_init(hwif); dev_set_drvdata(dev, hwif); printk(KERN_INFO "Au1xxx IDE(builtin) configured for %s\n", mode ); out: return ret;}static int au_ide_remove(struct device *dev){ struct platform_device *pdev = to_platform_device(dev); struct resource *res; ide_hwif_t *hwif = dev_get_drvdata(dev); _auide_hwif *ahwif = &auide_hwif; ide_unregister(hwif - ide_hwifs); iounmap((void *)ahwif->regbase); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, res->end - res->start); return 0;}static struct device_driver au1200_ide_driver = { .name = "au1200-ide", .bus = &platform_bus_type, .probe = au_ide_probe, .remove = au_ide_remove,};static int __init au_ide_init(void){ return driver_register(&au1200_ide_driver);}static void __exit au_ide_exit(void){ driver_unregister(&au1200_ide_driver);}MODULE_LICENSE("GPL");MODULE_DESCRIPTION("AU1200 IDE driver");module_init(au_ide_init);module_exit(au_ide_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -