📄 via82cxxx.c
字号:
if (active + recover < cycle) { active += (cycle - (active + recover)) / 2; recover = cycle - active; }/* * PIO address setup */ pci_read_config_byte(dev, VIA_ADDRESS_SETUP, &t); t = (t & ~(3 << ((3 - drive->dn) << 1))) | (FIT(setup - 1, 0, 3) << ((3 - drive->dn) << 1)); via_write_config_byte(dev, VIA_ADDRESS_SETUP, t);/* * PIO active & recover */ via_write_config_byte(dev, VIA_DRIVE_TIMING + (3 - drive->dn), (FIT(active - 1, 0, 0xf) << 4) | FIT(recover - 1, 0, 0xf));/* * UDMA cycle */ switch(via_isa_bridges[via_config].speed) { case XFER_UDMA_2: t = via_timing[i].udma ? (0xe0 | (FIT(ENOUGH(via_timing[i].udma, T), 2, 5) - 2)) : 0x03; break; case XFER_UDMA_4: t = via_timing[i].udma ? (0xe8 | (FIT(ENOUGH(via_timing[i].udma, T/2), 2, 9) - 2)) : 0x0f; break; } if (via_isa_bridges[via_config].speed != XFER_MW_DMA_2) via_write_config_byte(dev, VIA_UDMA_TIMING + (3 - drive->dn), t);/* * Drive init */ if (!drive->init_speed) drive->init_speed = speed; if ((err = ide_config_drive_speed(drive, speed))) return err; drive->current_speed = speed; return 0;}static void config_chipset_for_pio(ide_drive_t *drive){ short eide_pio_timing[] = {600, 383, 240, 180, 120, 100}; signed char pio, ide_pio; if (drive->id->eide_pio_iordy > 0) { /* Has timing table */ for (pio = 5; pio >= 0; pio--) if (drive->id->eide_pio_iordy <= eide_pio_timing[pio]) break; } else { /* No timing table -> use mode capabilities */ pio = (drive->id->eide_pio_modes & 4) ? 5 : (drive->id->eide_pio_modes & 2) ? 4 : (drive->id->eide_pio_modes & 1) ? 3 : (drive->id->tPIO == 2) ? 2 : (drive->id->tPIO == 1) ? 1 : 0; } ide_pio = ide_get_best_pio_mode(drive, 255, 5, NULL); pio = (pio >= ide_pio) ? pio : ide_pio; /* Phew. What about the blacklist? */ if (!pio) pio = (!drive->id->tPIO) ? XFER_PIO_0 : XFER_PIO_SLOW; else pio += XFER_PIO_0; /* Fixup because of broken ide-probe.c */ drive->dn = HWIF(drive)->channel * 2 + (drive->select.b.unit & 1); via_set_speed(drive, pio);}static void via82cxxx_tune_drive(ide_drive_t *drive, byte pio){ if (pio == 255) { config_chipset_for_pio(drive); return; } if (pio > 5) pio = 5; via_set_speed(drive, XFER_PIO_0 + pio);}#ifdef CONFIG_BLK_DEV_IDEDMAstatic int config_chipset_for_dma(ide_drive_t *drive){ struct hd_driveid *id = drive->id; unsigned char ultra66 = eighty_ninty_three(drive); unsigned char speed = ((id->dma_ultra & 0x0010) && ultra66) ? XFER_UDMA_4 : ((id->dma_ultra & 0x0008) && ultra66) ? XFER_UDMA_3 : (id->dma_ultra & 0x0004) ? XFER_UDMA_2 : (id->dma_ultra & 0x0002) ? XFER_UDMA_1 : (id->dma_ultra & 0x0001) ? XFER_UDMA_0 : (id->dma_mword & 0x0004) ? XFER_MW_DMA_2 : (id->dma_mword & 0x0002) ? XFER_MW_DMA_1 : (id->dma_mword & 0x0001) ? XFER_MW_DMA_0 : (id->dma_1word & 0x0004) ? XFER_SW_DMA_2 : (id->dma_1word & 0x0002) ? XFER_SW_DMA_1 : (id->dma_1word & 0x0001) ? XFER_SW_DMA_0 : 0; if (!speed) return (int) ide_dma_off_quietly; via_set_speed(drive, speed); return (int) ide_dma_on;}/* * Almost a library function. */static int config_drive_xfer_rate(ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_dma_action_t dma_func = ide_dma_on; if (id && (id->capability & 1) && HWIF(drive)->autodma) { /* Consult the list of known "bad" drives */ if (ide_dmaproc(ide_dma_bad_drive, drive)) { dma_func = ide_dma_off; goto fast_ata_pio; } dma_func = ide_dma_off_quietly; if (id->field_valid & 4) { if (id->dma_ultra & 0x002F) { /* Force if Capable UltraDMA */ dma_func = config_chipset_for_dma(drive); if ((id->field_valid & 2) && (dma_func != ide_dma_on)) goto try_dma_modes; } } else if (id->field_valid & 2) {try_dma_modes: if (id->dma_mword & 0x0007) { /* Force if Capable regular DMA modes */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) goto no_dma_set; } } else if (ide_dmaproc(ide_dma_good_drive, drive)) { if (id->eide_dma_time > 150) { goto no_dma_set; } /* Consult the list of known "good" drives */ dma_func = config_chipset_for_dma(drive); if (dma_func != ide_dma_on) goto no_dma_set; } else { goto fast_ata_pio; } } else if ((id->capability & 8) || (id->field_valid & 2)) {fast_ata_pio: dma_func = ide_dma_off_quietly;no_dma_set: config_chipset_for_pio(drive); } return HWIF(drive)->dmaproc(dma_func, drive);}int via82cxxx_dmaproc(ide_dma_action_t func, ide_drive_t *drive){ if (func == ide_dma_check) return config_drive_xfer_rate(drive); return ide_dmaproc(func, drive);}#endif /* CONFIG_BLK_DEV_IDEDMA */unsigned int __init pci_init_via82cxxx(struct pci_dev *dev, const char *name){ struct pci_dev *isa = NULL; unsigned char f, t, m; unsigned int u, i;/* * Find ISA bridge to see how good the IDE is. */ for (via_config = 0; via_isa_bridges[via_config].id; via_config++) if ((isa = pci_find_device(PCI_VENDOR_ID_VIA, via_isa_bridges[via_config].id, NULL))) break;/* * Read revision. */ if (via_isa_bridges[via_config].id == PCI_DEVICE_ID_VIA_82C586_0) { pci_read_config_byte(isa, PCI_REVISION_ID, &t); if (t < 0x30) via_config++; /* vt82c586a */ if (t < 0x20) via_config++; /* vt82c586 */ } if (via_isa_bridges[via_config].id == PCI_DEVICE_ID_VIA_82C596) { pci_read_config_byte(isa, PCI_REVISION_ID, &t); if (t < 0x10) via_config++; /* vt82c596a */ }/* * Check UDMA66 mode set by BIOS. */ pci_read_config_dword(dev, VIA_UDMA_TIMING, &u); for (i = 0; i < 4; i++) { pci_read_config_byte(dev, VIA_UDMA_TIMING + (3 - i), &t); if ((u & (0x80000 >> ((i >> 1) << 4))) && ((t & 7) < 2)) via_ata66 |= (1 << (i >> 1)); } #ifdef DEBUG printk(KERN_DEBUG "VP_IDE: BIOS enabled ATA66: primary: %s, secondary: %s\n", via_ata66 & 1 ? "yes" : "no", via_ata66 & 2 ? "yes" : "no");#endif/* * Set UDMA66 double clock bits. */ if (via_isa_bridges[via_config].speed == XFER_UDMA_4) pci_write_config_dword(dev, VIA_UDMA_TIMING, u | 0x80008);/* * Set up FIFO, flush, prefetch and post-writes. */ pci_read_config_dword(dev, VIA_IDE_ENABLE, &u); pci_read_config_byte(dev, VIA_FIFO_CONFIG, &f); pci_read_config_byte(dev, VIA_IDE_CONFIG, &t); pci_read_config_byte(dev, VIA_MISC_3, &m); f &= 0x90; t &= 0x0f; m &= 0x0f; switch (u & 3) { case 2: via_enabled = 1; f |= 0x06; t |= 0xc0; m |= 0xa0; break; /* primary only, 3/4 */ case 1: via_enabled = 2; f |= 0x69; t |= 0x30; m |= 0x50; break; /* secondary only, 3/4 */ case 3: via_enabled = 3; default: f |= 0x2a; t |= 0xf0; m |= 0xf0; break; /* fifo evenly distributed */ } via_write_config_byte(dev, VIA_FIFO_CONFIG, f); via_write_config_byte(dev, VIA_IDE_CONFIG, t); via_write_config_byte(dev, VIA_MISC_3, m);/* * Print the boot message. */ printk(KERN_INFO "VP_IDE: VIA %s IDE %s controller on pci%d:%d.%d\n", via_isa_bridges[via_config].name, via_isa_bridges[via_config].speed >= XFER_UDMA_4 ? "UDMA66" : via_isa_bridges[via_config].speed >= XFER_UDMA_2 ? "UDMA33" : "MWDMA16", dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));/* * Register /proc/ide/via entry */#if defined(CONFIG_PROC_FS) if (!via_proc) { via_proc = 1; bmide_dev = dev; isa_dev = isa; via_display_info = &via_get_info; }#endif return 0;}/* * Since we don't have a way to detect the 80-wire ribbon cable * we rely on the BIOS detection. We also check the IDENTIFY byte * 93 to check the drive's point of view. I think we could return * '1' here */unsigned int __init ata66_via82cxxx(ide_hwif_t *hwif){ return ((via_enabled & via_ata66) >> hwif->channel) & 1;}void __init ide_init_via82cxxx(ide_hwif_t *hwif){ hwif->tuneproc = &via82cxxx_tune_drive; hwif->speedproc = &via_set_speed; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; hwif->autodma = 0;#ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->dma_base) { hwif->dmaproc = &via82cxxx_dmaproc; hwif->autodma = 1; }#endif /* CONFIG_BLK_DEV_IDEDMA */}/* * We allow the BM-DMA driver only work on enabled interfaces. */void __init ide_dmacapable_via82cxxx(ide_hwif_t *hwif, unsigned long dmabase){ if ((via_enabled >> hwif->channel) & 1) ide_setup_dma(hwif, dmabase, 8);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -