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

📄 pdc202xx.c

📁 Linux环境下java编程的经典书籍
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef CONFIG_BLK_DEV_IDEDMA        if (speed >= XFER_SW_DMA_0) {		pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);		pci_write_config_byte(dev, (drive_pci)|0x02, CP|TC);	} else {#else	{#endif /* CONFIG_BLK_DEV_IDEDMA */		pci_write_config_byte(dev, (drive_pci), AP|TA);		pci_write_config_byte(dev, (drive_pci)|0x01, BP|TB);	}#if PDC202XX_DECODE_REGISTER_INFO	pci_read_config_byte(dev, (drive_pci), &AP);	pci_read_config_byte(dev, (drive_pci)|0x01, &BP);	pci_read_config_byte(dev, (drive_pci)|0x02, &CP);	pci_read_config_byte(dev, (drive_pci)|0x03, &DP);	decode_registers(REG_A, AP);	decode_registers(REG_B, BP);	decode_registers(REG_C, CP);	decode_registers(REG_D, DP);#endif /* PDC202XX_DECODE_REGISTER_INFO */skip_register_hell:	if (!drive->init_speed)		drive->init_speed = speed;	err = ide_config_drive_speed(drive, speed);	drive->current_speed = speed;#if PDC202XX_DEBUG_DRIVE_INFO	printk("%s: %s drive%d 0x%08x ",		drive->name, ide_xfer_verbose(speed),		drive->dn, drive_conf);		pci_read_config_dword(dev, drive_pci, &drive_conf);	printk("0x%08x\n", drive_conf);#endif /* PDC202XX_DEBUG_DRIVE_INFO */	return err;}/*   0    1    2    3    4    5    6   7   8 * 960, 480, 390, 300, 240, 180, 120, 90, 60 *           180, 150, 120,  90,  60 * DMA_Speed * 180, 120,  90,  90,  90,  60,  30 *  11,   5,   4,   3,   2,   1,   0 */static int config_chipset_for_pio (ide_drive_t *drive, byte pio){	byte speed = 0x00;	pio = (pio == 5) ? 4 : pio;	speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);        	return ((int) pdc202xx_tune_chipset(drive, speed));}static void pdc202xx_tune_drive (ide_drive_t *drive, byte pio){	(void) config_chipset_for_pio(drive, pio);}#ifdef CONFIG_BLK_DEV_IDEDMAstatic int config_chipset_for_dma (ide_drive_t *drive, byte ultra){	struct hd_driveid *id	= drive->id;	ide_hwif_t *hwif	= HWIF(drive);	struct pci_dev *dev	= hwif->pci_dev;	unsigned long high_16   = pci_resource_start(dev, 4);	unsigned long dma_base  = hwif->dma_base;	byte unit		= (drive->select.b.unit & 0x01);	unsigned int		drive_conf;	byte			drive_pci;	byte			test1, test2, speed = -1;	byte			AP;	unsigned short		EP;	byte CLKSPD		= IN_BYTE(high_16 + 0x11);	byte udma_33		= ultra ? (inb(high_16 + 0x001f) & 1) : 0;	byte udma_66		= ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;	byte udma_100		= (((dev->device == PCI_DEVICE_ID_PROMISE_20265) || (dev->device == PCI_DEVICE_ID_PROMISE_20267) || (dev->device == PCI_DEVICE_ID_PROMISE_20268)) && udma_66) ? 1 : 0;	/*	 * Set the control register to use the 66Mhz system	 * clock for UDMA 3/4 mode operation. If one drive on	 * a channel is U66 capable but the other isn't we	 * fall back to U33 mode. The BIOS INT 13 hooks turn	 * the clock on then off for each read/write issued. I don't	 * do that here because it would require modifying the	 * kernel, seperating the fop routines from the kernel or	 * somehow hooking the fops calls. It may also be possible to	 * leave the 66Mhz clock on and readjust the timing	 * parameters.	 */	byte mask		= hwif->channel ? 0x08 : 0x02;	unsigned short c_mask	= hwif->channel ? (1<<11) : (1<<10);	byte ultra_66		= ((id->dma_ultra & 0x0010) ||				   (id->dma_ultra & 0x0008)) ? 1 : 0;	byte ultra_100		= ((id->dma_ultra & 0x0020) ||				   (id->dma_ultra & 0x0010) ||				   (id->dma_ultra & 0x0008)) ? 1 : 0;	if (dev->device == PCI_DEVICE_ID_PROMISE_20268)		goto jump_pci_mucking;	pci_read_config_word(dev, 0x50, &EP);	if (((ultra_66) || (ultra_100)) && (EP & c_mask)) {#ifdef DEBUG		printk("ULTRA66: %s channel of Ultra 66 requires an 80-pin cable for Ultra66 operation.\n", hwif->channel ? "Secondary" : "Primary");		printk("         Switching to Ultra33 mode.\n");#endif /* DEBUG */		/* Primary   : zero out second bit */		/* Secondary : zero out fourth bit */		OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));	} else {		if ((ultra_66) || (ultra_100)) {			/*			 * check to make sure drive on same channel			 * is u66 capable			 */			if (hwif->drives[!(drive->dn%2)].id) {				if ((hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0020) ||				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0010) ||				    (hwif->drives[!(drive->dn%2)].id->dma_ultra & 0x0008)) {					OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));				} else {					OUT_BYTE(CLKSPD & ~mask, (high_16 + 0x11));				}			} else { /* udma4 drive by itself */				OUT_BYTE(CLKSPD | mask, (high_16 + 0x11));			}		}	}	switch(drive->dn) {		case 0:	drive_pci = 0x60;			pci_read_config_dword(dev, drive_pci, &drive_conf);			if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))				goto chipset_is_set;			pci_read_config_byte(dev, (drive_pci), &test1);			if (!(test1 & SYNC_ERRDY_EN))				pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN);			break;		case 1:	drive_pci = 0x64;			pci_read_config_dword(dev, drive_pci, &drive_conf);			if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))				goto chipset_is_set;			pci_read_config_byte(dev, 0x60, &test1);			pci_read_config_byte(dev, (drive_pci), &test2);			if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN))				pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN);			break;		case 2:	drive_pci = 0x68;			pci_read_config_dword(dev, drive_pci, &drive_conf);			if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))				goto chipset_is_set;			pci_read_config_byte(dev, (drive_pci), &test1);			if (!(test1 & SYNC_ERRDY_EN))				pci_write_config_byte(dev, (drive_pci), test1|SYNC_ERRDY_EN);			break;		case 3:	drive_pci = 0x6c;			pci_read_config_dword(dev, drive_pci, &drive_conf);			if ((drive_conf != 0x004ff304) && (drive_conf != 0x004ff3c4))				goto chipset_is_set;			pci_read_config_byte(dev, 0x68, &test1);			pci_read_config_byte(dev, (drive_pci), &test2);			if ((test1 & SYNC_ERRDY_EN) && !(test2 & SYNC_ERRDY_EN))				pci_write_config_byte(dev, (drive_pci), test2|SYNC_ERRDY_EN);			break;		default:			return ide_dma_off;	}chipset_is_set:	if (drive->media != ide_disk)	return ide_dma_off_quietly;	pci_read_config_byte(dev, (drive_pci), &AP);	if (id->capability & 4)	/* IORDY_EN */		pci_write_config_byte(dev, (drive_pci), AP|IORDY_EN);	pci_read_config_byte(dev, (drive_pci), &AP);	if (drive->media == ide_disk)	/* PREFETCH_EN */		pci_write_config_byte(dev, (drive_pci), AP|PREFETCH_EN);jump_pci_mucking:	if ((id->dma_ultra & 0x0020) && (udma_100))	speed = XFER_UDMA_5;	else if ((id->dma_ultra & 0x0010) && (udma_66))	speed = XFER_UDMA_4;	else if ((id->dma_ultra & 0x0008) && (udma_66))	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 {		/* restore original pci-config space */		if (dev->device != PCI_DEVICE_ID_PROMISE_20268)			pci_write_config_dword(dev, drive_pci, drive_conf);		return ide_dma_off_quietly;	}	outb(inb(dma_base+2) & ~(1<<(5+unit)), dma_base+2);	(void) pdc202xx_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 int config_drive_xfer_rate (ide_drive_t *drive){	struct hd_driveid *id = drive->id;	ide_hwif_t *hwif = HWIF(drive);	ide_dma_action_t dma_func = ide_dma_off_quietly;	if (id && (id->capability & 1) && hwif->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, 1);				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, 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, 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:		(void) config_chipset_for_pio(drive, 5);	}	return HWIF(drive)->dmaproc(dma_func, drive);}int pdc202xx_quirkproc (ide_drive_t *drive){	return ((int) check_in_drive_lists(drive, pdc_quirk_drives));}/* * pdc202xx_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. */int pdc202xx_dmaproc (ide_dma_action_t func, ide_drive_t *drive){	byte dma_stat = 0, sc1d = 0;	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);	unsigned long dma_base	= HWIF(drive)->dma_base;	switch (func) {		case ide_dma_check:			return config_drive_xfer_rate(drive);		case ide_dma_test_irq:	/* returns 1 if dma irq issued, 0 otherwise */			dma_stat = inb(dma_base+2);			sc1d = inb(high_16 + 0x001d);			if (HWIF(drive)->channel) {				if ((sc1d & 0x50) == 0x50) goto somebody_else;				else if ((sc1d & 0x40) == 0x40)					return (dma_stat & 4) == 4;			} else {				if ((sc1d & 0x05) == 0x05) goto somebody_else;				else if ((sc1d & 0x04) == 0x04)					return (dma_stat & 4) == 4;			}somebody_else:			return (dma_stat & 4) == 4;	/* return 1 if INTR asserted */		case ide_dma_lostirq:		case ide_dma_timeout:			if (HWIF(drive)->resetproc != NULL)				HWIF(drive)->resetproc(drive);		default:			break;	}	return ide_dmaproc(func, drive);	/* use standard DMA stuff */}#endif /* CONFIG_BLK_DEV_IDEDMA */void pdc202xx_reset (ide_drive_t *drive){	unsigned long high_16	= pci_resource_start(HWIF(drive)->pci_dev, 4);	byte udma_speed_flag	= inb(high_16 + 0x001f);	OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);	mdelay(100);	OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);	mdelay(2000);		/* 2 seconds ?! */}unsigned int __init pci_init_pdc202xx (struct pci_dev *dev, const char *name){	unsigned long high_16 = pci_resource_start(dev, 4);	byte udma_speed_flag	= inb(high_16 + 0x001f);	byte primary_mode	= inb(high_16 + 0x001a);	byte secondary_mode	= inb(high_16 + 0x001b);	if ((dev->device == PCI_DEVICE_ID_PROMISE_20262) ||	    (dev->device == PCI_DEVICE_ID_PROMISE_20265) ||	    (dev->device == PCI_DEVICE_ID_PROMISE_20267)) {		/*		 * software reset -  this is required because the bios		 * will set UDMA timing on if the hdd supports it. The		 * user may want to turn udma off. A bug in the pdc20262		 * is that it cannot handle a downgrade in timing from UDMA		 * to DMA. Disk accesses after issuing a set feature command		 * will result in errors. A software reset leaves the timing		 * registers intact, but resets the drives.		 */		OUT_BYTE(udma_speed_flag | 0x10, high_16 + 0x001f);		mdelay(100);		OUT_BYTE(udma_speed_flag & ~0x10, high_16 + 0x001f);		mdelay(2000);	/* 2 seconds ?! */	}	if (dev->resource[PCI_ROM_RESOURCE].start) {		pci_write_config_dword(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);	}	if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) {		byte irq = 0, irq2 = 0;		pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);		pci_read_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, &irq2);	/* 0xbc */		if ((irq != irq2) &&		    (dev->device != PCI_DEVICE_ID_PROMISE_20265) &&		    (dev->device != PCI_DEVICE_ID_PROMISE_20267) &&		    (dev->device != PCI_DEVICE_ID_PROMISE_20268)) {			pci_write_config_byte(dev, (PCI_INTERRUPT_LINE)|0x80, irq);	/* 0xbc */			printk("%s: pci-config space interrupt mirror fixed.\n", name);		}	}	printk("%s: (U)DMA Burst Bit %sABLED " \		"Primary %s Mode " \		"Secondary %s Mode.\n",		name,		(udma_speed_flag & 1) ? "EN" : "DIS",		(primary_mode & 1) ? "MASTER" : "PCI",		(secondary_mode & 1) ? "MASTER" : "PCI" );#ifdef CONFIG_PDC202XX_BURST	if (!(udma_speed_flag & 1)) {		printk("%s: FORCING BURST BIT 0x%02x -> 0x%02x ", name, udma_speed_flag, (udma_speed_flag|1));		outb(udma_speed_flag|1, high_16 + 0x001f);		printk("%sCTIVE\n", (inb(high_16 + 0x001f) & 1) ? "A" : "INA");	}#endif /* CONFIG_PDC202XX_BURST */#ifdef CONFIG_PDC202XX_MASTER	if (!(primary_mode & 1)) {		printk("%s: FORCING PRIMARY MODE BIT 0x%02x -> 0x%02x ",			name, primary_mode, (primary_mode|1));		outb(primary_mode|1, high_16 + 0x001a);		printk("%s\n", (inb(high_16 + 0x001a) & 1) ? "MASTER" : "PCI");	}	if (!(secondary_mode & 1)) {		printk("%s: FORCING SECONDARY MODE BIT 0x%02x -> 0x%02x ",			name, secondary_mode, (secondary_mode|1));		outb(secondary_mode|1, high_16 + 0x001b);		printk("%s\n", (inb(high_16 + 0x001b) & 1) ? "MASTER" : "PCI");	}#endif /* CONFIG_PDC202XX_MASTER */#if defined(DISPLAY_PDC202XX_TIMINGS) && defined(CONFIG_PROC_FS)	if (!pdc202xx_proc) {		pdc202xx_proc = 1;		bmide_dev = dev;		pdc202xx_display_info = &pdc202xx_get_info;	}#endif /* DISPLAY_PDC202XX_TIMINGS && CONFIG_PROC_FS */	return dev->irq;}unsigned int __init ata66_pdc202xx (ide_hwif_t *hwif){	unsigned short mask = (hwif->channel) ? (1<<11) : (1<<10);	unsigned short CIS;	pci_read_config_word(hwif->pci_dev, 0x50, &CIS);	return ((CIS & mask) ? 0 : 1);}void __init ide_init_pdc202xx (ide_hwif_t *hwif){	hwif->tuneproc	= &pdc202xx_tune_drive;	hwif->speedproc	= &pdc202xx_tune_chipset;	hwif->quirkproc	= &pdc202xx_quirkproc;	if ((hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20262) ||	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20265) ||	    (hwif->pci_dev->device == PCI_DEVICE_ID_PROMISE_20267)) {		hwif->resetproc	= &pdc202xx_reset;	}#undef CONFIG_PDC202XX_32_UNMASK#ifdef CONFIG_PDC202XX_32_UNMASK	hwif->drives[0].io_32bit = 1;	hwif->drives[1].io_32bit = 1;	hwif->drives[0].unmask = 1;	hwif->drives[1].unmask = 1;#endif /* CONFIG_PDC202XX_32_UNMASK */#ifdef CONFIG_BLK_DEV_IDEDMA	if (hwif->dma_base) {		hwif->dmaproc = &pdc202xx_dmaproc;		if (!noautodma)			hwif->autodma = 1;	} else {		hwif->drives[0].autotune = 1;		hwif->drives[1].autotune = 1;		hwif->autodma = 0;	}#else /* !CONFIG_BLK_DEV_IDEDMA */	hwif->drives[0].autotune = 1;	hwif->drives[1].autotune = 1;	hwif->autodma = 0;#endif /* CONFIG_BLK_DEV_IDEDMA */}

⌨️ 快捷键说明

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