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

📄 sis5513.c

📁 三星2410,廣州友善之臂開發板附帶的linux下的硬盤IDE驅動.
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (host_dev) {		switch(host_dev->device) {			case PCI_DEVICE_ID_SI_530:			case PCI_DEVICE_ID_SI_540:			case PCI_DEVICE_ID_SI_620:			case PCI_DEVICE_ID_SI_630:			case PCI_DEVICE_ID_SI_635:			case PCI_DEVICE_ID_SI_640:			case PCI_DEVICE_ID_SI_645:			case PCI_DEVICE_ID_SI_650:			case PCI_DEVICE_ID_SI_730:			case PCI_DEVICE_ID_SI_735:			case PCI_DEVICE_ID_SI_740:			case PCI_DEVICE_ID_SI_745:			case PCI_DEVICE_ID_SI_750:				unmask   = 0xF0;				four_two = 0x01;				break;			default:				unmask   = 0xE0;				four_two = 0x00;				break;		}	} else {		unmask   = 0xE0;		four_two = 0x00;	}	switch(drive->dn) {		case 0:		drive_pci = 0x40;break;		case 1:		drive_pci = 0x42;break;		case 2:		drive_pci = 0x44;break;		case 3:		drive_pci = 0x46;break;		default:	return ide_dma_off;	}	pci_read_config_byte(dev, drive_pci, &test1);	pci_read_config_byte(dev, drive_pci|0x01, &test2);	if ((speed <= XFER_MW_DMA_2) && (test2 & 0x80)) {		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~0x80);		pci_read_config_byte(dev, drive_pci|0x01, &test2);	} else {		pci_write_config_byte(dev, drive_pci|0x01, test2 & ~unmask);	}	switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA		case XFER_UDMA_5: mask = 0x80; break;		case XFER_UDMA_4: mask = 0x90; break;		case XFER_UDMA_3: mask = 0xA0; break;		case XFER_UDMA_2: mask = (four_two) ? 0xB0 : 0xA0; break;		case XFER_UDMA_1: mask = (four_two) ? 0xD0 : 0xC0; break;		case XFER_UDMA_0: mask = unmask; break;		case XFER_MW_DMA_2:		case XFER_MW_DMA_1:		case XFER_MW_DMA_0:		case XFER_SW_DMA_2:		case XFER_SW_DMA_1:		case XFER_SW_DMA_0: break;#endif /* CONFIG_BLK_DEV_IDEDMA */		case XFER_PIO_4: return((int) config_chipset_for_pio(drive, 4));		case XFER_PIO_3: return((int) config_chipset_for_pio(drive, 3));		case XFER_PIO_2: return((int) config_chipset_for_pio(drive, 2));		case XFER_PIO_1: return((int) config_chipset_for_pio(drive, 1));		case XFER_PIO_0:		default:	 return((int) config_chipset_for_pio(drive, 0));	}	if (speed > XFER_MW_DMA_2)		pci_write_config_byte(dev, drive_pci|0x01, test2|mask);	drive->current_speed = speed;	return ((int) ide_config_drive_speed(drive, speed));}static void sis5513_tune_drive (ide_drive_t *drive, byte pio){	(void) config_chipset_for_pio(drive, pio);}#ifdef CONFIG_BLK_DEV_IDEDMA/* * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) */static int config_chipset_for_dma (ide_drive_t *drive, byte ultra){	struct hd_driveid *id	= drive->id;	ide_hwif_t *hwif	= HWIF(drive);	byte			four_two = 0, speed = 0;	int			err;	byte unit		= (drive->select.b.unit & 0x01);	byte udma_66		= eighty_ninty_three(drive);	byte ultra_100		= 0;	if (host_dev) {		switch(host_dev->device) {			case PCI_DEVICE_ID_SI_635:			case PCI_DEVICE_ID_SI_640:			case PCI_DEVICE_ID_SI_645:			case PCI_DEVICE_ID_SI_650:			case PCI_DEVICE_ID_SI_730:			case PCI_DEVICE_ID_SI_735:			case PCI_DEVICE_ID_SI_740:			case PCI_DEVICE_ID_SI_745:			case PCI_DEVICE_ID_SI_750:				ultra_100 = 1;			case PCI_DEVICE_ID_SI_530:			case PCI_DEVICE_ID_SI_540:			case PCI_DEVICE_ID_SI_620:			case PCI_DEVICE_ID_SI_630:				four_two = 0x01;				break;			default:				four_two = 0x00; break;		}	}	if ((id->dma_ultra & 0x0020) && (ultra) && (udma_66) && (four_two) && (ultra_100))		speed = XFER_UDMA_5;	else if ((id->dma_ultra & 0x0010) && (ultra) && (udma_66) && (four_two))		speed = XFER_UDMA_4;	else if ((id->dma_ultra & 0x0008) && (ultra) && (udma_66) && (four_two))		speed = XFER_UDMA_3;	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_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		return ((int) ide_dma_off_quietly);	outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2);	err = sis5513_tune_chipset(drive, speed);#if SIS5513_DEBUG_DRIVE_INFO	printk("%s: %s drive%d\n", drive->name, ide_xfer_verbose(speed), drive->dn);#endif /* SIS5513_DEBUG_DRIVE_INFO */	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_dma_action_t dma_func	= ide_dma_off_quietly;	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 & 0x003F) {				/* 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)) &&			   (id->eide_dma_time > 150)) {			/* 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);}/* * sis5513_dmaproc() initiates/aborts (U)DMA read/write operations on a drive. */int sis5513_dmaproc (ide_dma_action_t func, ide_drive_t *drive){	switch (func) {		case ide_dma_check:			config_drive_art_rwp(drive);			config_art_rwp_pio(drive, 5);			return config_drive_xfer_rate(drive);		default:			break;	}	return ide_dmaproc(func, drive);	/* use standard DMA stuff */}#endif /* CONFIG_BLK_DEV_IDEDMA */unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name){	struct pci_dev *host;	int i = 0;	byte latency = 0;	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &latency);	for (i = 0; i < ARRAY_SIZE (SiSHostChipInfo) && !host_dev; i++) {		host = pci_find_device (PCI_VENDOR_ID_SI,					SiSHostChipInfo[i].host_id,					NULL);		if (!host)			continue;		host_dev = host;		printk(SiSHostChipInfo[i].name);		printk("\n");		if (SiSHostChipInfo[i].flags & SIS5513_FLAG_LATENCY) {			if (latency != 0x10)				pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x10);		}	}	if (host_dev) {		byte reg52h = 0;		pci_read_config_byte(dev, 0x52, &reg52h);		if (!(reg52h & 0x04)) {			/* set IDE controller to operate in Compabitility mode only */			pci_write_config_byte(dev, 0x52, reg52h|0x04);		}#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)		if (!sis_proc) {			sis_proc = 1;			bmide_dev = dev;			sis_display_info = &sis_get_info;		}#endif /* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */	}	return 0;}unsigned int __init ata66_sis5513 (ide_hwif_t *hwif){	byte reg48h = 0, ata66 = 0;	byte mask = hwif->channel ? 0x20 : 0x10;	pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);	if (host_dev) {		switch(host_dev->device) {			case PCI_DEVICE_ID_SI_530:			case PCI_DEVICE_ID_SI_540:			case PCI_DEVICE_ID_SI_620:			case PCI_DEVICE_ID_SI_630:			case PCI_DEVICE_ID_SI_635:			case PCI_DEVICE_ID_SI_640:			case PCI_DEVICE_ID_SI_645:			case PCI_DEVICE_ID_SI_650:			case PCI_DEVICE_ID_SI_730:			case PCI_DEVICE_ID_SI_735:			case PCI_DEVICE_ID_SI_740:			case PCI_DEVICE_ID_SI_745:			case PCI_DEVICE_ID_SI_750:				ata66 = (reg48h & mask) ? 0 : 1;			default:				break;		}	}        return (ata66);}void __init ide_init_sis5513 (ide_hwif_t *hwif){	hwif->irq = hwif->channel ? 15 : 14;	hwif->tuneproc = &sis5513_tune_drive;	hwif->speedproc = &sis5513_tune_chipset;	if (!(hwif->dma_base))		return;	if (host_dev) {		switch(host_dev->device) {#ifdef CONFIG_BLK_DEV_IDEDMA			case PCI_DEVICE_ID_SI_530:			case PCI_DEVICE_ID_SI_540:			case PCI_DEVICE_ID_SI_620:			case PCI_DEVICE_ID_SI_630:			case PCI_DEVICE_ID_SI_635:			case PCI_DEVICE_ID_SI_640:			case PCI_DEVICE_ID_SI_645:			case PCI_DEVICE_ID_SI_650:			case PCI_DEVICE_ID_SI_730:			case PCI_DEVICE_ID_SI_735:			case PCI_DEVICE_ID_SI_740:			case PCI_DEVICE_ID_SI_745:			case PCI_DEVICE_ID_SI_750:			case PCI_DEVICE_ID_SI_5600:			case PCI_DEVICE_ID_SI_5597:			case PCI_DEVICE_ID_SI_5591:				if (!noautodma)					hwif->autodma = 1;				hwif->dmaproc = &sis5513_dmaproc;				break;#endif /* CONFIG_BLK_DEV_IDEDMA */			default:				hwif->autodma = 0;				break;		}	}	return;}

⌨️ 快捷键说明

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