📄 piix.c
字号:
} save_flags(flags); cli(); pci_write_config_word(HWIF(drive)->pci_dev, master_port, master_data); if (is_slave) pci_write_config_byte(HWIF(drive)->pci_dev, slave_port, slave_data); restore_flags(flags);}#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_PIIX_TUNING)static int piix_tune_chipset (ide_drive_t *drive, byte speed){ ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; byte maslave = hwif->channel ? 0x42 : 0x40; int a_speed = 3 << (drive->dn * 4); int u_flag = 1 << drive->dn; int v_flag = 0x01 << drive->dn; int w_flag = 0x10 << drive->dn; int u_speed = 0; int err = 0; int sitre; short reg4042, reg44, reg48, reg4a, reg54; byte reg55; pci_read_config_word(dev, maslave, ®4042); sitre = (reg4042 & 0x4000) ? 1 : 0; pci_read_config_word(dev, 0x44, ®44); pci_read_config_word(dev, 0x48, ®48); pci_read_config_word(dev, 0x4a, ®4a); pci_read_config_word(dev, 0x54, ®54); pci_read_config_byte(dev, 0x55, ®55); switch(speed) { case XFER_UDMA_4: case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; case XFER_UDMA_5: case XFER_UDMA_3: case XFER_UDMA_1: u_speed = 1 << (drive->dn * 4); break; case XFER_UDMA_0: u_speed = 0 << (drive->dn * 4); break; case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; default: return -1; } if (speed >= XFER_UDMA_0) { if (!(reg48 & u_flag)) pci_write_config_word(dev, 0x48, reg48|u_flag); if (speed == XFER_UDMA_5) { pci_write_config_byte(dev, 0x55, (byte) reg55|w_flag); } else { pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag); } if (!(reg4a & u_speed)) { pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); pci_write_config_word(dev, 0x4a, reg4a|u_speed); } if (speed > XFER_UDMA_2) { if (!(reg54 & v_flag)) { pci_write_config_word(dev, 0x54, reg54|v_flag); } } else { pci_write_config_word(dev, 0x54, reg54 & ~v_flag); } } if (speed < XFER_UDMA_0) { if (reg48 & u_flag) pci_write_config_word(dev, 0x48, reg48 & ~u_flag); if (reg4a & a_speed) pci_write_config_word(dev, 0x4a, reg4a & ~a_speed); if (reg54 & v_flag) pci_write_config_word(dev, 0x54, reg54 & ~v_flag); if (reg55 & w_flag) pci_write_config_byte(dev, 0x55, (byte) reg55 & ~w_flag); } piix_tune_drive(drive, piix_dma_2_pio(speed));#if PIIX_DEBUG_DRIVE_INFO printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);#endif /* PIIX_DEBUG_DRIVE_INFO */ if (!drive->init_speed) drive->init_speed = speed; err = ide_config_drive_speed(drive, speed); drive->current_speed = speed; return err;}static int piix_config_drive_for_dma (ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; byte speed; byte udma_66 = eighty_ninty_three(drive); int ultra100 = ((dev->device == PCI_DEVICE_ID_INTEL_82801BA_8) || (dev->device == PCI_DEVICE_ID_INTEL_82801BA_9) || (dev->device == PCI_DEVICE_ID_INTEL_82801CA_10)) ? 1 : 0; int ultra66 = ((ultra100) || (dev->device == PCI_DEVICE_ID_INTEL_82801AA_1) || (dev->device == PCI_DEVICE_ID_INTEL_82372FB_1)) ? 1 : 0; int ultra = ((ultra66) || (dev->device == PCI_DEVICE_ID_INTEL_82371AB) || (dev->device == PCI_DEVICE_ID_INTEL_82443MX_1) || (dev->device == PCI_DEVICE_ID_INTEL_82451NX) || (dev->device == PCI_DEVICE_ID_INTEL_82801AB_1)) ? 1 : 0; if ((id->dma_ultra & 0x0020) && (udma_66) && (ultra100)) { speed = XFER_UDMA_5; } else if ((id->dma_ultra & 0x0010) && (ultra)) { speed = ((udma_66) && (ultra66)) ? XFER_UDMA_4 : XFER_UDMA_2; } else if ((id->dma_ultra & 0x0008) && (ultra)) { speed = ((udma_66) && (ultra66)) ? XFER_UDMA_3 : XFER_UDMA_1; } else if ((id->dma_ultra & 0x0004) && (ultra)) { speed = XFER_UDMA_2; } else if ((id->dma_ultra & 0x0002) && (ultra)) { speed = XFER_UDMA_1; } else if ((id->dma_ultra & 0x0001) && (ultra)) { speed = XFER_UDMA_0; } else if (id->dma_mword & 0x0004) { speed = XFER_MW_DMA_2; } else if (id->dma_mword & 0x0002) { speed = XFER_MW_DMA_1; } else if (id->dma_1word & 0x0004) { speed = XFER_SW_DMA_2; } else { speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, 5, NULL); } (void) piix_tune_chipset(drive, speed); return ((int) ((id->dma_ultra >> 11) & 7) ? ide_dma_on : ((id->dma_ultra >> 8) & 7) ? ide_dma_on : ((id->dma_mword >> 8) & 7) ? ide_dma_on : ((id->dma_1word >> 8) & 7) ? ide_dma_on : ide_dma_off_quietly);}static void config_chipset_for_pio (ide_drive_t *drive){ piix_tune_drive(drive, ide_get_best_pio_mode(drive, 255, 5, NULL));}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 = piix_config_drive_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) || (id->dma_1word & 0x007)) { /* Force if Capable regular DMA modes */ dma_func = piix_config_drive_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 = piix_config_drive_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);}static int piix_dmaproc(ide_dma_action_t func, ide_drive_t *drive){ switch (func) { case ide_dma_check: return config_drive_xfer_rate(drive); default : break; } /* Other cases are done by generic IDE-DMA code. */ return ide_dmaproc(func, drive);}#endif /* defined(CONFIG_BLK_DEV_IDEDMA) && (CONFIG_PIIX_TUNING) */unsigned int __init pci_init_piix (struct pci_dev *dev, const char *name){#if defined(DISPLAY_PIIX_TIMINGS) && defined(CONFIG_PROC_FS) if (!piix_proc) { piix_proc = 1; bmide_dev = dev; piix_display_info = &piix_get_info; }#endif /* DISPLAY_PIIX_TIMINGS && CONFIG_PROC_FS */ return 0;}/* * Sheesh, someone at Intel needs to go read the ATA-4/5 T13 standards. * It does not specify device detection, but channel!!! * You determine later if bit 13 of word93 is set... */unsigned int __init ata66_piix (ide_hwif_t *hwif){ byte reg54h = 0, reg55h = 0, ata66 = 0; byte mask = hwif->channel ? 0xc0 : 0x30; pci_read_config_byte(hwif->pci_dev, 0x54, ®54h); pci_read_config_byte(hwif->pci_dev, 0x55, ®55h); ata66 = (reg54h & mask) ? 1 : 0; return ata66;}void __init ide_init_piix (ide_hwif_t *hwif){#ifndef CONFIG_IA64 if (!hwif->irq) hwif->irq = hwif->channel ? 15 : 14;#endif /* CONFIG_IA64 */ if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_82371MX) { /* This is a painful system best to let it self tune for now */ return; } hwif->tuneproc = &piix_tune_drive; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; if (!hwif->dma_base) return;#ifndef CONFIG_BLK_DEV_IDEDMA hwif->autodma = 0;#else /* CONFIG_BLK_DEV_IDEDMA */#ifdef CONFIG_PIIX_TUNING if (!noautodma) hwif->autodma = 1; hwif->dmaproc = &piix_dmaproc; hwif->speedproc = &piix_tune_chipset;#endif /* CONFIG_PIIX_TUNING */#endif /* !CONFIG_BLK_DEV_IDEDMA */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -