📄 icside.c
字号:
printk("%s: Disabling DMA for %s\n", drive->name, id->model); return(blacklist);}int icside_dma_check(ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); int autodma = hwif->autodma; int xfer_mode = XFER_PIO_2; if (!id || !(id->capability & 1) || !autodma) return hwif->ide_dma_off_quietly(drive); /* * Consult the list of known "bad" drives */ if (check_drive_bad_lists(drive)) return hwif->ide_dma_off(drive); /* * Enable DMA on any drive that has multiword DMA */ if (id->field_valid & 2) { if (id->dma_mword & 4) { xfer_mode = XFER_MW_DMA_2; } else if (id->dma_mword & 2) { xfer_mode = XFER_MW_DMA_1; } else if (id->dma_mword & 1) { xfer_mode = XFER_MW_DMA_0; } goto out; } /* * Consult the list of known "good" drives */ if (check_drive_good_lists(drive)) { if (id->eide_dma_time > 150) goto out; xfer_mode = XFER_MW_DMA_1; }out: if (icside_config_if(drive, xfer_mode)) return hwif->ide_dma_on(drive); return hwif->ide_dma_off(drive);}int icside_dma_verbose(ide_drive_t *drive){ printk(", DMA"); return 1;}int icside_dma_test_irq(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); return inb((unsigned long)hwif->hw.priv) & 1;}int icside_dma_host_off(ide_drive_t *drive){ return 0;}int icside_dma_off_quietly(ide_drive_t *drive){ drive->using_dma = 0; return icside_dma_host_off(drive);}int icside_dma_off(ide_drive_t *drive){ printk("%s: DMA disabled\n", drive->name); return icside_dma_off_quietly(drive);}int icside_dma_host_on(ide_drive_t *drive){ return 0;}int icside_dma_on(ide_drive_t *drive){ drive->using_dma = 1; return icside_dma_host_on(drive);}int icside_dma_begin(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); enable_dma(hwif->hw.dma); return 0;}int icside_dma_end(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); drive->waiting_for_dma = 0; disable_dma(hwif->hw.dma); icside_destroy_dmatable(drive); return get_dma_residue(hwif->hw.dma) != 0;}int icside_dma_count (ide_drive_t *drive){ return icside_dma_begin(drive);}int icside_dma_read(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive);// ide_task_t *args = HWGROUP(drive)->rq->special; int count = 0; u8 lba48 = (drive->addressing == 1) ? 1 : 0; task_ioreg_t command = WIN_NOP; count = icside_build_dmatable(drive, PCI_DMA_FROMDEVICE); if (!count) return 1; disable_dma(hwif->hw.dma); /* Route the DMA signals to * to the correct interface. */ HWIF(drive)->OUTB(hwif->select_data, hwif->config_data); /* Select the correct timing * for this drive */ set_dma_speed(hwif->hw.dma, drive->drive_data); set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count); set_dma_mode(hwif->hw.dma, DMA_MODE_READ); drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; if (HWGROUP(drive)->handler != NULL) /* paranoia check */ BUG(); ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); /* * FIX ME to use only ACB ide_task_t args Struct */#if 0 { ide_task_t *args = HWGROUP(drive)->rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; }#else command = (lba48) ? WIN_READDMA_EXT : WIN_READDMA; if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) { ide_task_t *args = HWGROUP(drive)->rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; }#endif /* issue cmd to drive */ HWIF(drive)->OUTB(command, IDE_COMMAND_REG); return icside_dma_count(drive);}int icside_dma_write(ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive);// ide_task_t *args = HWGROUP(drive)->rq->special; int count = 0; u8 lba48 = (drive->addressing == 1) ? 1 : 0; task_ioreg_t command = WIN_NOP; count = icside_build_dmatable(drive, PCI_DMA_TODEVICE); if (!count) return 1; disable_dma(hwif->hw.dma); /* Route the DMA signals to * to the correct interface. */ HWIF(drive)->OUTB(hwif->select_data, hwif->config_data); /* Select the correct timing * for this drive */ set_dma_speed(hwif->hw.dma, drive->drive_data); set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count); set_dma_mode(hwif->hw.dma, DMA_MODE_WRITE); drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; if (HWGROUP(drive)->handler != NULL) BUG(); ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); /* * FIX ME to use only ACB ide_task_t args Struct */#if 0 { ide_task_t *args = HWGROUP(drive)->rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; }#else command = (lba48) ? WIN_WRITEDMA_EXT : WIN_WRITEDMA; if (HWGROUP(drive)->rq->flags & REQ_DRIVE_TASKFILE) { ide_task_t *args = HWGROUP(drive)->rq->special; command = args->tfRegister[IDE_COMMAND_OFFSET]; }#endif /* issue cmd to drive */ HWIF(drive)->OUTB(command, IDE_COMMAND_REG); return icside_dma_count(drive);}static inticside_setup_dma(ide_hwif_t *hwif, int autodma){ printk(" %s: SG-DMA", hwif->name); hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES, GFP_KERNEL); if (!hwif->sg_table) goto failed; hwif->dmatable_cpu = NULL; hwif->dmatable_dma = 0; hwif->speedproc = icside_set_speed; hwif->autodma = autodma; hwif->ide_dma_check = icside_dma_check; hwif->ide_dma_host_off = icside_dma_host_off; hwif->ide_dma_off_quietly = icside_dma_off_quietly; hwif->ide_dma_off = icside_dma_off; hwif->ide_dma_host_on = icside_dma_host_on; hwif->ide_dma_on = icside_dma_on; hwif->ide_dma_read = icside_dma_read; hwif->ide_dma_write = icside_dma_write; hwif->ide_dma_count = icside_dma_count; hwif->ide_dma_begin = icside_dma_begin; hwif->ide_dma_end = icside_dma_end; hwif->ide_dma_verbose = icside_dma_verbose; hwif->ide_dma_bad_drive = check_drive_bad_lists; hwif->ide_dma_good_drive = check_drive_good_lists; hwif->ide_dma_test_irq = icside_dma_test_irq; printk(" capable%s\n", autodma ? ", auto-enable" : ""); return 1;failed: printk(" -- ERROR, unable to allocate DMA table\n"); return 0;}#endifstatic ide_hwif_t *icside_find_hwif(unsigned long dataport){ ide_hwif_t *hwif; int index; for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; if (hwif->io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport) goto found; } for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; if (!hwif->io_ports[IDE_DATA_OFFSET]) goto found; } return NULL;found: return hwif;}static ide_hwif_t *icside_setup(unsigned long base, struct cardinfo *info, int irq){ unsigned long port = base + info->dataoffset; ide_hwif_t *hwif; hwif = icside_find_hwif(base); if (hwif) { int i; memset(&hwif->hw, 0, sizeof(hw_regs_t)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hwif->hw.io_ports[i] = (ide_ioreg_t)port; hwif->io_ports[i] = (ide_ioreg_t)port; port += 1 << info->stepping; } hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset; hwif->io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset; hwif->hw.irq = irq; hwif->irq = irq; hwif->hw.dma = NO_DMA; hwif->noprobe = 0; hwif->chipset = ide_acorn; } return hwif;}static int __init icside_register_v5(struct expansion_card *ec, int autodma){ unsigned long slot_port; ide_hwif_t *hwif; slot_port = ecard_address(ec, ECARD_MEMC, 0); ec->irqaddr = (unsigned char *)ioaddr(slot_port + ICS_ARCIN_V5_INTRSTAT); ec->irqmask = 1; ec->irq_data = (void *)slot_port; ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5; /* * Be on the safe side - disable interrupts */ inb(slot_port + ICS_ARCIN_V5_INTROFFSET); hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq); return hwif ? 0 : -1;}static int __init icside_register_v6(struct expansion_card *ec, int autodma){ unsigned long slot_port, port; ide_hwif_t *hwif, *mate; int sel = 0; slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST); port = ecard_address(ec, ECARD_EASI, ECARD_FAST); if (port == 0) port = slot_port; else sel = 1 << 5; outb(sel, slot_port); ec->irq_data = (void *)port; ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6; /* * Be on the safe side - disable interrupts */ inb(port + ICS_ARCIN_V6_INTROFFSET_1); inb(port + ICS_ARCIN_V6_INTROFFSET_2); hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq); mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq);#ifdef CONFIG_BLK_DEV_IDEDMA_ICS if (ec->dma != NO_DMA) { if (request_dma(ec->dma, hwif->name)) goto no_dma; if (hwif) { hwif->config_data = slot_port; hwif->select_data = sel; hwif->hw.dma = ec->dma; hwif->hw.priv = (void *) (port + ICS_ARCIN_V6_INTRSTAT_1); hwif->channel = 0; icside_setup_dma(hwif, autodma); hwif->drives[0].autodma = autodma; hwif->drives[1].autodma = autodma; } if (mate) { mate->config_data = slot_port; mate->select_data = sel | 1; mate->hw.dma = ec->dma; mate->hw.priv = (void *) (port + ICS_ARCIN_V6_INTRSTAT_2); mate->channel = 1; icside_setup_dma(mate, autodma); mate->drives[0].autodma = autodma; mate->drives[1].autodma = autodma; } }no_dma:#endif return hwif || mate ? 0 : -1;}int __init icside_init(void){ int autodma = 0;#ifdef CONFIG_IDEDMA_ICS_AUTO autodma = 1;#endif ecard_startfind (); do { struct expansion_card *ec; int result; ec = ecard_find(0, icside_cids); if (ec == NULL) break; ecard_claim(ec); switch (icside_identifyif(ec)) { case ics_if_arcin_v5: result = icside_register_v5(ec, autodma); break; case ics_if_arcin_v6: result = icside_register_v6(ec, autodma); break; default: result = -1; break; } if (result) ecard_release(ec); } while (1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -