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

📄 pdc202xx.c

📁 at91rm9200处理器ide接口驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
			pci_read_config_byte(dev, (drive_pci), &AP);			pci_read_config_byte(dev, (drive_pci)|0x01, &BP);		}	}	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);	for ( i = 0; i < 2; i++)		if (hwif->drives[i].present)	  		id[i+j] = hwif->drives[i].id;	/* get identify structs */	switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA		/* case XFER_UDMA_6: */		case XFER_UDMA_5:		case XFER_UDMA_4:	TB = 0x20; TC = 0x01; break;	/* speed 8 == UDMA mode 4 */		case XFER_UDMA_3:	TB = 0x40; TC = 0x02; break;	/* speed 7 == UDMA mode 3 */		case XFER_UDMA_2:	TB = 0x20; TC = 0x01; break;	/* speed 6 == UDMA mode 2 */		case XFER_UDMA_1:	TB = 0x40; TC = 0x02; break;	/* speed 5 == UDMA mode 1 */		case XFER_UDMA_0:	TB = 0x60; TC = 0x03; break;	/* speed 4 == UDMA mode 0 */		case XFER_MW_DMA_2:	TB = 0x60; TC = 0x03; break;	/* speed 4 == MDMA mode 2 */		case XFER_MW_DMA_1:	TB = 0x60; TC = 0x04; break;	/* speed 3 == MDMA mode 1 */		case XFER_MW_DMA_0:	TB = 0x60; TC = 0x05; break;	/* speed 2 == MDMA mode 0 */		case XFER_SW_DMA_2:	TB = 0x60; TC = 0x05; break;	/* speed 0 == SDMA mode 2 */		case XFER_SW_DMA_1:	TB = 0x80; TC = 0x06; break;	/* speed 1 == SDMA mode 1 */		case XFER_SW_DMA_0:	TB = 0xC0; TC = 0x0B; break;	/* speed 0 == SDMA mode 0 */#endif /* CONFIG_BLK_DEV_IDEDMA */		case XFER_PIO_4:	TA = 0x01; TB = 0x04; break;		case XFER_PIO_3:	TA = 0x02; TB = 0x06; break;		case XFER_PIO_2:	TA = 0x03; TB = 0x08; break;		case XFER_PIO_1:	TA = 0x05; TB = 0x0C; break;		case XFER_PIO_0:		default:		TA = 0x09; TB = 0x13; break;	}#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 */	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;}static int pdc202xx_new_tune_chipset (ide_drive_t *drive, byte speed){	ide_hwif_t *hwif	= HWIF(drive);#ifdef CONFIG_BLK_DEV_IDEDMA	unsigned long indexreg	= (hwif->dma_base + 1);	unsigned long datareg	= (hwif->dma_base + 3);#else	struct pci_dev *dev	= hwif->pci_dev;	unsigned long high_16	= pci_resource_start(dev, 4);	unsigned long indexreg	= high_16 + (hwif->channel ? 0x09 : 0x01);	unsigned long datareg	= (indexreg + 2);#endif /* CONFIG_BLK_DEV_IDEDMA */	byte thold		= 0x10;	byte adj		= (drive->dn%2) ? 0x08 : 0x00;	int set_speed		= 0, i=0, j=hwif->channel ? 2:0;	int                     err;	/* Setting tHOLD bit to 0 if using UDMA mode 2 */	if (speed == XFER_UDMA_2) {		OUT_BYTE((thold + adj), indexreg);		OUT_BYTE((IN_BYTE(datareg) & 0x7f), datareg);	}		/* We need to set ATA133 timing if ATA133 drives exist */	if (speed>=XFER_UDMA_6)		set_speed=1;	if (!drive->init_speed)		drive->init_speed = speed;#if PDC202XX_DEBUG_DRIVE_INFO	printk("%s: Before set_feature = %s, word88 = %#x\n",		drive->name, ide_xfer_verbose(speed), drive->id->dma_ultra );#endif /* PDC202XX_DEBUG_DRIVE_INFO */	err = ide_config_drive_speed(drive, speed);	drive->current_speed = speed;		for ( i = 0 ; i < 2 ; i++)		if (hwif->drives[i].present) {	  		id[i+j] = hwif->drives[i].id;	/* get identify structs */	 		speed_rate[i+j] = speed;	/* get current speed */	 	}	if (set_speed) {		for (i=0; i<4; i++) {			if (id[i]==NULL)				continue;			switch(speed_rate[i]) {#ifdef CONFIG_BLK_DEV_IDEDMA				case XFER_UDMA_6:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x1a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x01, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xcb, datareg);					break;				case XFER_UDMA_5:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x1a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x02, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xcb, datareg);					break;				case XFER_UDMA_4:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x1a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x03, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xcd, datareg);					break;				case XFER_UDMA_3:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x1a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x05, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xcd, datareg);					break;				case XFER_UDMA_2:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x2a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x07, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xcd, datareg);					break;				case XFER_UDMA_1:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x3a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x0a, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xd0, datareg);					break;				case XFER_UDMA_0:					OUT_BYTE((0x10 + adj), indexreg);					OUT_BYTE(0x4a, datareg);					OUT_BYTE((0x11 + adj), indexreg);					OUT_BYTE(0x0f, datareg);					OUT_BYTE((0x12 + adj), indexreg);					OUT_BYTE(0xd5, datareg);					break;				case XFER_MW_DMA_2:					OUT_BYTE((0x0e + adj), indexreg);					OUT_BYTE(0x69, datareg);					OUT_BYTE((0x0f + adj), indexreg);					OUT_BYTE(0x25, datareg);					break;				case XFER_MW_DMA_1:					OUT_BYTE((0x0e + adj), indexreg);					OUT_BYTE(0x6b, datareg);					OUT_BYTE((0x0f+ adj), indexreg);					OUT_BYTE(0x27, datareg);					break;				case XFER_MW_DMA_0:					OUT_BYTE((0x0e + adj), indexreg);					OUT_BYTE(0xdf, datareg);					OUT_BYTE((0x0f + adj), indexreg);					OUT_BYTE(0x5f, datareg);					break;#endif /* CONFIG_BLK_DEV_IDEDMA */				case XFER_PIO_4:					OUT_BYTE((0x0c + adj), indexreg);					OUT_BYTE(0x23, datareg);					OUT_BYTE((0x0d + adj), indexreg);					OUT_BYTE(0x09, datareg);					OUT_BYTE((0x13 + adj), indexreg);					OUT_BYTE(0x25, datareg);					break;				case XFER_PIO_3:					OUT_BYTE((0x0c + adj), indexreg);					OUT_BYTE(0x27, datareg);					OUT_BYTE((0x0d + adj), indexreg);					OUT_BYTE(0x0d, datareg);					OUT_BYTE((0x13 + adj), indexreg);					OUT_BYTE(0x35, datareg);					break;				case XFER_PIO_2:					OUT_BYTE((0x0c + adj), indexreg);					OUT_BYTE(0x23, datareg);					OUT_BYTE((0x0d + adj), indexreg);					OUT_BYTE(0x26, datareg);					OUT_BYTE((0x13 + adj), indexreg);					OUT_BYTE(0x64, datareg);					break;				case XFER_PIO_1:					OUT_BYTE((0x0c + adj), indexreg);					OUT_BYTE(0x46, datareg);					OUT_BYTE((0x0d + adj), indexreg);					OUT_BYTE(0x29, datareg);					OUT_BYTE((0x13 + adj), indexreg);					OUT_BYTE(0xa4, datareg);					break;				case XFER_PIO_0:					OUT_BYTE((0x0c + adj), indexreg);					OUT_BYTE(0xfb, datareg);					OUT_BYTE((0x0d + adj), indexreg);					OUT_BYTE(0x2b, datareg);					OUT_BYTE((0x13 + adj), indexreg);					OUT_BYTE(0xac, datareg);					break;				default:			}		}	}	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;	unsigned long indexreg	= dma_base + 1;	unsigned long datareg	= dma_base + 3;	byte iordy		= 0x13;	byte adj		= (drive->dn%2) ? 0x08 : 0x00;	byte cable		= 0;	byte new_chip		= 0;	byte unit		= (drive->select.b.unit & 0x01);	unsigned int		drive_conf;	byte			drive_pci = 0;	byte			test1, test2, speed = -1;	byte			AP;	unsigned short		EP;	byte CLKSPD		= 0;	byte clockreg		= high_16 + 0x11;	byte udma_33		= ultra;	byte udma_66		= ((eighty_ninty_three(drive)) && udma_33) ? 1 : 0;	byte udma_100		= 0;	byte udma_133		= 0;	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) ||				   (ultra_66)) ? 1 : 0;	byte ultra_133		= ((id->dma_ultra & 0x0040) ||				   (ultra_100)) ? 1 : 0;	switch(dev->device) {		case PCI_DEVICE_ID_PROMISE_20276:		case PCI_DEVICE_ID_PROMISE_20275:		case PCI_DEVICE_ID_PROMISE_20269:			udma_133 = (udma_66) ? 1 : 0;			udma_100 = (udma_66) ? 1 : 0;			OUT_BYTE(0x0b, (hwif->dma_base + 1));			cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04));			new_chip = 1;			break;		case PCI_DEVICE_ID_PROMISE_20268:		case PCI_DEVICE_ID_PROMISE_20270:			udma_100 = (udma_66) ? 1 : 0;			OUT_BYTE(0x0b, (hwif->dma_base + 1));			cable = ((IN_BYTE((hwif->dma_base + 3)) & 0x04));			new_chip = 1;			break;		case PCI_DEVICE_ID_PROMISE_20267:		case PCI_DEVICE_ID_PROMISE_20265:			udma_100 = (udma_66) ? 1 : 0;			pci_read_config_word(dev, 0x50, &EP);			cable = (EP & c_mask);			new_chip = 0;			CLKSPD = IN_BYTE(clockreg);			break;		case PCI_DEVICE_ID_PROMISE_20262:			pci_read_config_word(dev, 0x50, &EP);			cable = (EP & c_mask);			new_chip = 0;			CLKSPD = IN_BYTE(clockreg);			break;		default:			udma_100 = 0; udma_133 = 0; cable = 0; new_chip = 1;			break;	}	/*	 * 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.	 */	if (((ultra_66) || (ultra_100) || (ultra_133)) && (cable)) {#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 */		//if (!new_chip)		OUT_BYTE(CLKSPD & ~mask, clockreg);		printk("Warning: %s channel requires an 80-pin cable for operation.\n", hwif->channel ? "Secondary":"Primary");		printk("%s reduced to Ultra33 mode.\n", drive->name);		udma_66 = 0; udma_100 = 0; udma_133 = 0;	} else {		if ((ultra_66) || (ultra_100) || (ultra_133)) {			/*			 * 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 & 0x0040) ||				    (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, clockreg);				} else {					OUT_BYTE(CLKSPD & ~mask, clockreg);				}			} else { /* udma4 drive by itself */				OUT_BYTE(CLKSPD | mask, clockreg);			}		}	}	if (new_chip)	goto chipset_is_set;	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;

⌨️ 快捷键说明

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