⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 via82cxxx.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -