📄 ide-dma.c
字号:
hwif->OUTB(hwif->dma_status, dma_stat & 0xE4); }#endif /* return 1 if INTR asserted */ if ((dma_stat & 4) == 4) return 1; if (!drive->waiting_for_dma) printk(KERN_WARNING "%s: (%s) called while not waiting\n", drive->name, __FUNCTION__);#if 0 drive->waiting_for_dma++;#endif return 0;}EXPORT_SYMBOL(__ide_dma_test_irq);int __ide_dma_bad_drive (ide_drive_t *drive){ struct hd_driveid *id = drive->id;#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS int blacklist = in_drive_list(id, drive_blacklist); if (blacklist) { printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model); return(blacklist); }#else /* !CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ const char **list; /* Consult the list of known "bad" drives */ list = bad_dma_drives; while (*list) { if (!strcmp(*list++,id->model)) { printk("%s: Disabling (U)DMA for %s\n", drive->name, id->model); return 1; } }#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ return 0;}EXPORT_SYMBOL(__ide_dma_bad_drive);int __ide_dma_good_drive (ide_drive_t *drive){ struct hd_driveid *id = drive->id;#ifdef CONFIG_IDEDMA_NEW_DRIVE_LISTINGS return in_drive_list(id, drive_whitelist);#else /* !CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ const char **list; /* Consult the list of known "good" drives */ list = good_dma_drives; while (*list) { if (!strcmp(*list++,id->model)) return 1; }#endif /* CONFIG_IDEDMA_NEW_DRIVE_LISTINGS */ return 0;}EXPORT_SYMBOL(__ide_dma_good_drive);/* * Used for HOST FIFO counters for VDMA * PIO over DMA, effective ATA-Bridge operator. */int __ide_dma_count (ide_drive_t *drive){ return HWIF(drive)->ide_dma_begin(drive);}EXPORT_SYMBOL(__ide_dma_count);int __ide_dma_verbose (ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); if (id->field_valid & 4) { if ((id->dma_ultra >> 8) && (id->dma_mword >> 8)) { printk(", BUG DMA OFF"); return hwif->ide_dma_off_quietly(drive); } if (id->dma_ultra & ((id->dma_ultra >> 8) & hwif->ultra_mask)) { if (((id->dma_ultra >> 11) & 0x1F) && eighty_ninty_three(drive)) { if ((id->dma_ultra >> 15) & 1) { printk(", UDMA(mode 7)"); } else if ((id->dma_ultra >> 14) & 1) { printk(", UDMA(133)"); } else if ((id->dma_ultra >> 13) & 1) { printk(", UDMA(100)"); } else if ((id->dma_ultra >> 12) & 1) { printk(", UDMA(66)"); } else if ((id->dma_ultra >> 11) & 1) { printk(", UDMA(44)"); } else goto mode_two; } else { mode_two: if ((id->dma_ultra >> 10) & 1) { printk(", UDMA(33)"); } else if ((id->dma_ultra >> 9) & 1) { printk(", UDMA(25)"); } else if ((id->dma_ultra >> 8) & 1) { printk(", UDMA(16)"); } } } else { printk(", (U)DMA"); /* Can be BIOS-enabled! */ } } else if (id->field_valid & 2) { if ((id->dma_mword >> 8) && (id->dma_1word >> 8)) { printk(", BUG DMA OFF"); return hwif->ide_dma_off_quietly(drive); } printk(", DMA"); } else if (id->field_valid & 1) { printk(", BUG"); } return 1;}EXPORT_SYMBOL(__ide_dma_verbose);/** * __ide_dma_retune - default retune handler * @drive: drive to retune * * Default behaviour when we decide to return the IDE DMA setup. * The default behaviour is "we don't" */ int __ide_dma_retune (ide_drive_t *drive){ printk(KERN_WARNING "%s: chipset supported call only\n", __FUNCTION__); return 1;}EXPORT_SYMBOL(__ide_dma_retune);int __ide_dma_lostirq (ide_drive_t *drive){ printk("%s: DMA interrupt recovery\n", drive->name); return 1;}EXPORT_SYMBOL(__ide_dma_lostirq);int __ide_dma_timeout (ide_drive_t *drive){ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name); if (HWIF(drive)->ide_dma_test_irq(drive)) return 0; return HWIF(drive)->ide_dma_end(drive);}EXPORT_SYMBOL(__ide_dma_timeout);/* * Needed for allowing full modular support of ide-driver */int ide_release_dma_engine (ide_hwif_t *hwif){ if (hwif->dmatable_cpu) { pci_free_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES, hwif->dmatable_cpu, hwif->dmatable_dma); hwif->dmatable_cpu = NULL; } if (hwif->sg_table) { kfree(hwif->sg_table); hwif->sg_table = NULL; } return 1;}int ide_release_mmio_dma (ide_hwif_t *hwif){ if ((hwif->dma_extra) && (hwif->channel == 0)) release_mem_region((hwif->dma_base + 16), hwif->dma_extra); release_mem_region(hwif->dma_base, 8); if (hwif->dma_base2) release_mem_region(hwif->dma_base, 8); return 1;}int ide_release_iomio_dma (ide_hwif_t *hwif){ if ((hwif->dma_extra) && (hwif->channel == 0)) release_region((hwif->dma_base + 16), hwif->dma_extra); release_region(hwif->dma_base, 8); if (hwif->dma_base2) release_region(hwif->dma_base, 8); return 1;}/* * Needed for allowing full modular support of ide-driver */int ide_release_dma (ide_hwif_t *hwif){ if (hwif->chipset == ide_etrax100) return 1; ide_release_dma_engine(hwif); if (hwif->mmio==2) return 1; if (hwif->mmio) return ide_release_mmio_dma(hwif); return ide_release_iomio_dma(hwif);}int ide_allocate_dma_engine (ide_hwif_t *hwif){ hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev, PRD_ENTRIES * PRD_BYTES, &hwif->dmatable_dma); hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES, GFP_KERNEL); if ((hwif->dmatable_cpu) && (hwif->sg_table)) return 0; printk(KERN_ERR "%s: -- Error, unable to allocate%s%s table(s).\n", (hwif->dmatable_cpu == NULL) ? " CPU" : "", (hwif->sg_table == NULL) ? " SG DMA" : " DMA", hwif->cds->name); ide_release_dma_engine(hwif); return 1;}int ide_mapped_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports){ printk(KERN_INFO " %s: MMIO-DMA ", hwif->name); hwif->dma_base = base; if ((hwif->cds->extra) && (hwif->channel == 0)) hwif->dma_extra = hwif->cds->extra; /* There is an issue to watch here. The master might not be registered because the BIOS disabled it. Eventually this should be fixed by always registering the mate */ if(hwif->mate == NULL) hwif->dma_master = base; else hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; return 0;}int ide_mmio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports){ printk(KERN_INFO " %s: MMIO-DMA at 0x%08lx-0x%08lx", hwif->name, base, base + ports - 1); if (check_mem_region(base, ports)) { printk(" -- Error, MMIO ports already in use.\n"); return 1; } request_mem_region(base, ports, hwif->name); hwif->dma_base = base; if ((hwif->cds->extra) && (hwif->channel == 0)) { request_region(base+16, hwif->cds->extra, hwif->cds->name); hwif->dma_extra = hwif->cds->extra; } /* There is an issue to watch here. The master might not be registered because the BIOS disabled it. Eventually this should be fixed by always registering the mate */ if(hwif->mate == NULL) hwif->dma_master = base; else hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; if (hwif->dma_base2) { if (!check_mem_region(hwif->dma_base2, ports)) request_mem_region(hwif->dma_base2, ports, hwif->name); } return 0;}int ide_iomio_dma (ide_hwif_t *hwif, unsigned long base, unsigned int ports){ printk(KERN_INFO " %s: BM-DMA at 0x%04lx-0x%04lx", hwif->name, base, base + ports - 1); if (!request_region(base, ports, hwif->name)) { printk(" -- Error, ports in use.\n"); return 1; } hwif->dma_base = base; if ((hwif->cds->extra) && (hwif->channel == 0)) { request_region(base+16, hwif->cds->extra, hwif->cds->name); hwif->dma_extra = hwif->cds->extra; } /* There is an issue to watch here. The master might not be registered because the BIOS disabled it. Eventually this should be fixed by always registering the mate */ if(hwif->mate == NULL) hwif->dma_master = base; else hwif->dma_master = (hwif->channel) ? hwif->mate->dma_base : base; if (hwif->dma_base2) { if (!request_region(hwif->dma_base2, ports, hwif->name)) { printk(" -- Error, secondary ports in use.\n"); release_region(base, ports); return 1; } } return 0;}/* * */int ide_dma_iobase (ide_hwif_t *hwif, unsigned long base, unsigned int ports){ if (hwif->mmio == 2) return ide_mapped_mmio_dma(hwif, base, ports); if (hwif->mmio) return ide_mmio_dma(hwif, base, ports); return ide_iomio_dma(hwif, base, ports);}/* * This can be called for a dynamically installed interface. Don't __init it */void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_ports){ if (ide_dma_iobase(hwif, dma_base, num_ports)) return; if (ide_allocate_dma_engine(hwif)) { ide_release_dma(hwif); return; } if (!(hwif->dma_command)) hwif->dma_command = hwif->dma_base; if (!(hwif->dma_vendor1)) hwif->dma_vendor1 = (hwif->dma_base + 1); if (!(hwif->dma_status)) hwif->dma_status = (hwif->dma_base + 2); if (!(hwif->dma_vendor3)) hwif->dma_vendor3 = (hwif->dma_base + 3); if (!(hwif->dma_prdtable)) hwif->dma_prdtable = (hwif->dma_base + 4); if (!hwif->ide_dma_off) hwif->ide_dma_off = &__ide_dma_off; if (!hwif->ide_dma_off_quietly) hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; if (!hwif->ide_dma_host_off) hwif->ide_dma_host_off = &__ide_dma_host_off; if (!hwif->ide_dma_on) hwif->ide_dma_on = &__ide_dma_on; if (!hwif->ide_dma_host_on) hwif->ide_dma_host_on = &__ide_dma_host_on; if (!hwif->ide_dma_check) hwif->ide_dma_check = &__ide_dma_check; if (!hwif->ide_dma_read) hwif->ide_dma_read = &__ide_dma_read; if (!hwif->ide_dma_write) hwif->ide_dma_write = &__ide_dma_write; if (!hwif->ide_dma_count) hwif->ide_dma_count = &__ide_dma_count; if (!hwif->ide_dma_begin) hwif->ide_dma_begin = &__ide_dma_begin; if (!hwif->ide_dma_end) hwif->ide_dma_end = &__ide_dma_end; if (!hwif->ide_dma_test_irq) hwif->ide_dma_test_irq = &__ide_dma_test_irq; if (!hwif->ide_dma_bad_drive) hwif->ide_dma_bad_drive = &__ide_dma_bad_drive; if (!hwif->ide_dma_good_drive) hwif->ide_dma_good_drive = &__ide_dma_good_drive; if (!hwif->ide_dma_verbose) hwif->ide_dma_verbose = &__ide_dma_verbose; if (!hwif->ide_dma_timeout) hwif->ide_dma_timeout = &__ide_dma_timeout; if (!hwif->ide_dma_retune) hwif->ide_dma_retune = &__ide_dma_retune; if (!hwif->ide_dma_lostirq) hwif->ide_dma_lostirq = &__ide_dma_lostirq; if (hwif->chipset != ide_trm290) { u8 dma_stat = hwif->INB(hwif->dma_status); printk(", BIOS settings: %s:%s, %s:%s", hwif->drives[0].name, (dma_stat & 0x20) ? "DMA" : "pio", hwif->drives[1].name, (dma_stat & 0x40) ? "DMA" : "pio"); } printk("\n"); if (!(hwif->dma_master)) BUG();}EXPORT_SYMBOL_GPL(ide_setup_dma);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -