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

📄 cmd64x.c

📁 Linux环境下java编程的经典书籍
💻 C
📖 第 1 页 / 共 2 页
字号:
		case XFER_PIO_4:	cmd64x_tuneproc(drive, 4); break;		case XFER_PIO_3:	cmd64x_tuneproc(drive, 3); break;		case XFER_PIO_2:	cmd64x_tuneproc(drive, 2); break;		case XFER_PIO_1:	cmd64x_tuneproc(drive, 1); break;		case XFER_PIO_0:	cmd64x_tuneproc(drive, 0); break;		default:			return 1;	}#ifdef CONFIG_BLK_DEV_IDEDMA	(void) pci_write_config_byte(dev, pciU, regU);#endif /* CONFIG_BLK_DEV_IDEDMA */	err = ide_config_drive_speed(drive, speed);	drive->current_speed = speed;#ifdef CONFIG_BLK_DEV_IDEDMA	regD |= (unit ? 0x40 : 0x20);	(void) pci_write_config_byte(dev, pciD, regD);#endif /* CONFIG_BLK_DEV_IDEDMA */	return err;}#ifdef CONFIG_BLK_DEV_IDEDMAstatic int config_chipset_for_dma (ide_drive_t *drive, unsigned int rev, byte ultra_66){	struct hd_driveid *id	= drive->id;	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	byte speed		= 0x00;	byte set_pio		= 0x00;	byte udma_33		= ((rev >= 0x05) || (ultra_66)) ? 1 : 0;	byte udma_66		= eighty_ninty_three(drive);	byte udma_100		= 0;	int rval;	switch(dev->device) {		case PCI_DEVICE_ID_CMD_649: udma_100 = 1; break;		case PCI_DEVICE_ID_CMD_648:		case PCI_DEVICE_ID_CMD_646:		case PCI_DEVICE_ID_CMD_643:		default:			break;	}	if (drive->media != ide_disk) {		cmdprintk("CMD64X: drive->media != ide_disk at double check, inital check failed!!\n");		return ((int) ide_dma_off);	}	/* UltraDMA only supported on PCI646U and PCI646U2,	 * which correspond to revisions 0x03, 0x05 and 0x07 respectively.	 * Actually, although the CMD tech support people won't	 * tell me the details, the 0x03 revision cannot support	 * UDMA correctly without hardware modifications, and even	 * then it only works with Quantum disks due to some	 * hold time assumptions in the 646U part which are fixed	 * in the 646U2.	 * So we only do UltraDMA on revision 0x05 and 0x07 chipsets.	 */	if ((id->dma_ultra & 0x0020) && (udma_100) && (udma_66) && (udma_33)) {		speed = XFER_UDMA_5;	} else if ((id->dma_ultra & 0x0010) && (udma_66) && (udma_33)) {		speed = XFER_UDMA_4;	} else if ((id->dma_ultra & 0x0008) && (udma_66) && (udma_33)) {		speed = XFER_UDMA_3;	} else if ((id->dma_ultra & 0x0004) && (udma_33)) {		speed = XFER_UDMA_2;	} else if ((id->dma_ultra & 0x0002) && (udma_33)) {		speed = XFER_UDMA_1;	} else if ((id->dma_ultra & 0x0001) && (udma_33)) {		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_mword & 0x0001) {		speed = XFER_MW_DMA_0;	} else if (id->dma_1word & 0x0004) {		speed = XFER_SW_DMA_2;	} else if (id->dma_1word & 0x0002) {		speed = XFER_SW_DMA_1;	} else if (id->dma_1word & 0x0001) {		speed = XFER_SW_DMA_0;	} else {		set_pio = 1;	}	if (!drive->init_speed)		drive->init_speed = speed;	config_chipset_for_pio(drive, set_pio);	if (set_pio)		return ((int) ide_dma_off_quietly);	if (cmd64x_tune_chipset(drive, speed))		return ((int) ide_dma_off);	rval = (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);	return rval;}static int cmd64x_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;	unsigned int class_rev	= 0;	byte can_ultra_33	= 0;	byte can_ultra_66	= 0;	byte can_ultra_100	= 0;	ide_dma_action_t dma_func = ide_dma_on;	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;		switch(dev->device) {		case PCI_DEVICE_ID_CMD_649:			can_ultra_100 = 1;		case PCI_DEVICE_ID_CMD_648:			can_ultra_66  = 1;		case PCI_DEVICE_ID_CMD_643:			can_ultra_33  = 1;			break;		case PCI_DEVICE_ID_CMD_646:			can_ultra_33  = (class_rev >= 0x05) ? 1 : 0;			can_ultra_66  = 0;			can_ultra_100 = 0;			break;		default:			return hwif->dmaproc(ide_dma_off, drive);	}	if ((id != NULL) && ((id->capability & 1) != 0) &&	    hwif->autodma && (drive->media == ide_disk)) {		/* 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) && (can_ultra_33)) {			if (id->dma_ultra & 0x002F) {				/* Force if Capable UltraDMA */				dma_func = config_chipset_for_dma(drive, class_rev, can_ultra_66);				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 & 0x0007)) {				/* Force if Capable regular DMA modes */				dma_func = config_chipset_for_dma(drive, class_rev, 0);				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, class_rev, 0);			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, 1);	}	return HWIF(drive)->dmaproc(dma_func, drive);}static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive){	byte dma_stat		= 0;	byte dma_alt_stat	= 0;	byte mask		= (HWIF(drive)->channel) ? MRDMODE_INTR_CH1 : MRDMODE_INTR_CH0;	unsigned long dma_base	= HWIF(drive)->dma_base;	struct pci_dev *dev	= HWIF(drive)->pci_dev;	byte jack_slap		= ((dev->device == PCI_DEVICE_ID_CMD_648) || (dev->device == PCI_DEVICE_ID_CMD_649)) ? 1 : 0;	switch (func) {		case ide_dma_check:			return cmd64x_config_drive_for_dma(drive);		case ide_dma_end: /* returns 1 on error, 0 otherwise */			drive->waiting_for_dma = 0;			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */			dma_stat = inb(dma_base+2);		/* get DMA status */			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */			if (jack_slap) {				byte dma_intr	= 0;				byte dma_mask	= (HWIF(drive)->channel) ? ARTTIM23_INTR_CH1 : CFR_INTR_CH0;				byte dma_reg	= (HWIF(drive)->channel) ? ARTTIM2 : CFR;				(void) pci_read_config_byte(dev, dma_reg, &dma_intr);				/*				 * DAMN BMIDE is not connected to PCI space!				 * Have to manually jack-slap that bitch!				 * To allow the PCI side to read incoming interrupts.				 */				(void) pci_write_config_byte(dev, dma_reg, dma_intr|dma_mask);	/* clear the INTR bit */			}			ide_destroy_dmatable(drive);		/* purge DMA mappings */			return (dma_stat & 7) != 4;		/* verify good DMA status */		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */			dma_stat = inb(dma_base+2);			(void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);#ifdef DEBUG			printk("%s: dma_stat: 0x%02x dma_alt_stat: 0x%02x mask: 0x%02x\n", drive->name, dma_stat, dma_alt_stat, mask);#endif			if (!(dma_alt_stat & mask)) {				return 0;			}			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */		default:			break;	}	/* Other cases are done by generic IDE-DMA code. */	return ide_dmaproc(func, drive);}/* * ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old * event order for DMA transfers. */static int cmd646_1_dmaproc (ide_dma_action_t func, ide_drive_t *drive){	ide_hwif_t *hwif = HWIF(drive);	unsigned long dma_base = hwif->dma_base;	byte dma_stat;	switch (func) {		case ide_dma_check:			return cmd64x_config_drive_for_dma(drive);		case ide_dma_end:			drive->waiting_for_dma = 0;			dma_stat = inb(dma_base+2);		/* get DMA status */			outb(inb(dma_base)&~1, dma_base);	/* stop DMA */			outb(dma_stat|6, dma_base+2);		/* clear the INTR & ERROR bits */			ide_destroy_dmatable(drive);		/* and free any DMA resources */			return (dma_stat & 7) != 4;		/* verify good DMA status */		default:			break;	}	/* Other cases are done by generic IDE-DMA code. */	return ide_dmaproc(func, drive);}#endif /* CONFIG_BLK_DEV_IDEDMA */unsigned int __init pci_init_cmd64x (struct pci_dev *dev, const char *name){	unsigned char mrdmode;	unsigned int class_rev;	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;#ifdef __i386__	if (dev->resource[PCI_ROM_RESOURCE].start) {		pci_write_config_byte(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE);		printk("%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start);	}#endif	switch(dev->device) {		case PCI_DEVICE_ID_CMD_643:			break;		case PCI_DEVICE_ID_CMD_646:			printk("%s: chipset revision 0x%02X, ", name, class_rev);			switch(class_rev) {				case 0x07:				case 0x05:					printk("UltraDMA Capable");					break;				case 0x03:					printk("MultiWord DMA Force Limited");					break;				case 0x01:				default:					printk("MultiWord DMA Limited, IRQ workaround enabled");					break;				}			printk("\n");                        break;		case PCI_DEVICE_ID_CMD_648:		case PCI_DEVICE_ID_CMD_649:			break;		default:			break;	}	/* Set a good latency timer and cache line size value. */	(void) pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);#ifdef __sparc_v9__	(void) pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x10);#endif	/* Setup interrupts. */	(void) pci_read_config_byte(dev, MRDMODE, &mrdmode);	mrdmode &= ~(0x30);	(void) pci_write_config_byte(dev, MRDMODE, mrdmode);	/* Use MEMORY READ LINE for reads.	 * NOTE: Although not mentioned in the PCI0646U specs,	 *       these bits are write only and won't be read	 *       back as set or not.  The PCI0646U2 specs clarify	 *       this point.	 */	(void) pci_write_config_byte(dev, MRDMODE, mrdmode | 0x02);	/* Set reasonable active/recovery/address-setup values. */	(void) pci_write_config_byte(dev, ARTTIM0,  0x40);	(void) pci_write_config_byte(dev, DRWTIM0,  0x3f);	(void) pci_write_config_byte(dev, ARTTIM1,  0x40);	(void) pci_write_config_byte(dev, DRWTIM1,  0x3f);#ifdef __i386__	(void) pci_write_config_byte(dev, ARTTIM23, 0x1c);#else	(void) pci_write_config_byte(dev, ARTTIM23, 0x5c);#endif	(void) pci_write_config_byte(dev, DRWTIM23, 0x3f);	(void) pci_write_config_byte(dev, DRWTIM3,  0x3f);#ifdef CONFIG_PPC	(void) pci_write_config_byte(dev, UDIDETCR0, 0xf0);#endif /* CONFIG_PPC */#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)	if (!cmd64x_proc) {		cmd64x_proc = 1;		bmide_dev = dev;		cmd64x_display_info = &cmd64x_get_info;	}#endif /* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */	return 0;}unsigned int __init ata66_cmd64x (ide_hwif_t *hwif){	byte ata66 = 0;	byte mask = (hwif->channel) ? 0x02 : 0x01;	pci_read_config_byte(hwif->pci_dev, BMIDECSR, &ata66);	return (ata66 & mask) ? 1 : 0;}void __init ide_init_cmd64x (ide_hwif_t *hwif){	struct pci_dev *dev	= hwif->pci_dev;	unsigned int class_rev;	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;	hwif->tuneproc	= &cmd64x_tuneproc;	hwif->speedproc	= &cmd64x_tune_chipset;	hwif->drives[0].autotune = 1;	hwif->drives[1].autotune = 1;	if (!hwif->dma_base)		return;#ifdef CONFIG_BLK_DEV_IDEDMA	switch(dev->device) {		case PCI_DEVICE_ID_CMD_649:		case PCI_DEVICE_ID_CMD_648:		case PCI_DEVICE_ID_CMD_643:			hwif->dmaproc = &cmd64x_dmaproc;			break;		case PCI_DEVICE_ID_CMD_646:			hwif->chipset = ide_cmd646;			if (class_rev == 0x01) {				hwif->dmaproc = &cmd646_1_dmaproc;			} else {				hwif->dmaproc = &cmd64x_dmaproc;			}			break;		default:			break;	}#endif /* CONFIG_BLK_DEV_IDEDMA */}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -