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

📄 sis5513.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 3 页
字号:
		case XFER_UDMA_6:		case XFER_UDMA_5:		case XFER_UDMA_4:		case XFER_UDMA_3:		case XFER_UDMA_2:		case XFER_UDMA_1:		case XFER_UDMA_0:			if (chipset_family >= ATA_133) {				regdw |= 0x04;				regdw &= 0xfffff00f;				/* check if ATA133 enable */				if (regdw & 0x08) {					regdw |= (unsigned long)cycle_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 4;					regdw |= (unsigned long)cvs_time_value[ATA_133-ATA_00][speed-XFER_UDMA_0] << 8;				} else {				/* if ATA133 disable, we should not set speed above UDMA5 */					if (speed > XFER_UDMA_5)						speed = XFER_UDMA_5;					regdw |= (unsigned long)cycle_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 4;					regdw |= (unsigned long)cvs_time_value[ATA_100-ATA_00][speed-XFER_UDMA_0] << 8;				}				pci_write_config_dword(dev, (unsigned long)drive_pci, regdw);			} else {				/* Force the UDMA bit on if we want to use UDMA */				reg |= 0x80;				/* clean reg cycle time bits */				reg &= ~((0xFF >> (8 - cycle_time_range[chipset_family]))					 << cycle_time_offset[chipset_family]);				/* set reg cycle time bits */				reg |= cycle_time_value[chipset_family-ATA_00][speed-XFER_UDMA_0]					<< cycle_time_offset[chipset_family];				pci_write_config_byte(dev, drive_pci+1, reg);			}			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;		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));		}#ifdef DEBUG	sis5513_load_verify_registers(dev, "sis5513_tune_chipset end");#endif	return ((int) ide_config_drive_speed(drive, speed));}static void sis5513_tune_drive (ide_drive_t *drive, u8 pio){	(void) config_chipset_for_pio(drive, pio);}/* * ((id->hw_config & 0x4000|0x2000) && (HWIF(drive)->udma_four)) */static int config_chipset_for_dma (ide_drive_t *drive){	u8 speed	= ide_dma_speed(drive, sis5513_ratemask(drive));#ifdef DEBUG	printk("SIS5513: config_chipset_for_dma, drive %d, ultra %x\n",	       drive->dn, drive->id->dma_ultra);#endif	if (!(speed))		return 0;	sis5513_tune_chipset(drive, speed);	return ide_dma_enable(drive);}static int sis5513_config_drive_xfer_rate (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	struct hd_driveid *id	= drive->id;	drive->init_speed = 0;	if (id && (id->capability & 1) && drive->autodma) {		/* Consult the list of known "bad" drives */		if (hwif->ide_dma_bad_drive(drive))			goto fast_ata_pio;		if (id->field_valid & 4) {			if (id->dma_ultra & hwif->ultra_mask) {				/* Force if Capable UltraDMA */				int dma = config_chipset_for_dma(drive);				if ((id->field_valid & 2) && !dma)					goto try_dma_modes;			}		} else if (id->field_valid & 2) {try_dma_modes:			if ((id->dma_mword & hwif->mwdma_mask) ||			    (id->dma_1word & hwif->swdma_mask)) {				/* Force if Capable regular DMA modes */				if (!config_chipset_for_dma(drive))					goto no_dma_set;			}		} else if (hwif->ide_dma_good_drive(drive) &&			   (id->eide_dma_time < 150)) {			/* Consult the list of known "good" drives */			if (!config_chipset_for_dma(drive))				goto no_dma_set;		} else {			goto fast_ata_pio;		}	} else if ((id->capability & 8) || (id->field_valid & 2)) {fast_ata_pio:no_dma_set:		sis5513_tune_drive(drive, 5);		return hwif->ide_dma_off_quietly(drive);	}	return hwif->ide_dma_on(drive);}/* initiates/aborts (U)DMA read/write operations on a drive. */static int sis5513_config_xfer_rate (ide_drive_t *drive){	config_drive_art_rwp(drive);	config_art_rwp_pio(drive, 5);	return sis5513_config_drive_xfer_rate(drive);}/* Chip detection and general config */static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name){	struct pci_dev *host;	int i = 0;	/* Find the chip */	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;		chipset_family = SiSHostChipInfo[i].chipset_family;			/* check 100/133 chipset family */		if (chipset_family == ATA_133) {			u32 reg54h;			u16 reg02h;			pci_read_config_dword(dev, 0x54, &reg54h);			pci_write_config_dword(dev, 0x54, (reg54h & 0x7fffffff));			pci_read_config_word(dev, 0x02, &reg02h);			pci_write_config_dword(dev, 0x54, reg54h);			/* devid 5518 here means SiS962 or later			   which supports ATA133 */			if (reg02h != 0x5518) {				u8 reg49h;				unsigned long sbrev;				/* SiS961 family */		/*		 * FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING 		 */				outl(0x80001008, 0x0cf8);				sbrev = inl(0x0cfc);				pci_read_config_byte(dev, 0x49, &reg49h);				if (((sbrev & 0xff) == 0x10) && (reg49h & 0x80))					chipset_family = ATA_133a;				else					chipset_family = ATA_100;			}		}		printk(SiSHostChipInfo[i].name);		printk("    %s controller", chipset_capability[chipset_family]);		printk("\n");#ifdef DEBUG		sis5513_print_registers(dev, "pci_init_sis5513 start");#endif		if (SiSHostChipInfo[i].flags & SIS5513_LATENCY) {			u8 latency = (chipset_family == ATA_100)? 0x80 : 0x10; /* Lacking specs */			pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency);		}	}	/* Make general config ops here	   1/ tell IDE channels to operate in Compabitility mode only	   2/ tell old chips to allow per drive IDE timings */	if (host_dev) {		u8 reg;		u16 regw;		switch(chipset_family) {			case ATA_133:				/* SiS962 operation mode */				pci_read_config_word(dev, 0x50, &regw);				if (regw & 0x08)					pci_write_config_word(dev, 0x50, regw&0xfff7);				pci_read_config_word(dev, 0x52, &regw);				if (regw & 0x08)					pci_write_config_word(dev, 0x52, regw&0xfff7);				break;			case ATA_133a:			case ATA_100:				/* Set compatibility bit */				pci_read_config_byte(dev, 0x49, &reg);				if (!(reg & 0x01)) {					pci_write_config_byte(dev, 0x49, reg|0x01);				}				break;			case ATA_100a:			case ATA_66:				/* On ATA_66 chips the bit was elsewhere */				pci_read_config_byte(dev, 0x52, &reg);				if (!(reg & 0x04)) {					pci_write_config_byte(dev, 0x52, reg|0x04);				}				break;			case ATA_33:				/* On ATA_33 we didn't have a single bit to set */				pci_read_config_byte(dev, 0x09, &reg);				if ((reg & 0x0f) != 0x00) {					pci_write_config_byte(dev, 0x09, reg&0xf0);				}			case ATA_16:				/* force per drive recovery and active timings				   needed on ATA_33 and below chips */				pci_read_config_byte(dev, 0x52, &reg);				if (!(reg & 0x08)) {					pci_write_config_byte(dev, 0x52, reg|0x08);				}				break;			case ATA_00:			default: break;		}#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)		if (!sis_proc) {			sis_proc = 1;			bmide_dev = dev;			ide_pci_register_host_proc(&sis_procs[0]);		}#endif	}#ifdef DEBUG	sis5513_load_verify_registers(dev, "pci_init_sis5513 end");#endif	return 0;}static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif){	u8 ata66 = 0;	if (chipset_family >= ATA_133) {		u16 regw = 0;		u16 reg_addr = hwif->channel ? 0x52: 0x50;		pci_read_config_word(hwif->pci_dev, reg_addr, &regw);		ata66 = (regw & 0x8000) ? 0 : 1;	} else if (chipset_family >= ATA_66) {		u8 reg48h = 0;		u8 mask = hwif->channel ? 0x20 : 0x10;		pci_read_config_byte(hwif->pci_dev, 0x48, &reg48h);		ata66 = (reg48h & mask) ? 0 : 1;	}        return ata66;}static void __init init_hwif_sis5513 (ide_hwif_t *hwif){	hwif->autodma = 0;	if (!hwif->irq)		hwif->irq = hwif->channel ? 15 : 14;	hwif->tuneproc = &sis5513_tune_drive;	hwif->speedproc = &sis5513_tune_chipset;	if (!(hwif->dma_base)) {		hwif->drives[0].autotune = 1;		hwif->drives[1].autotune = 1;		return;	}	hwif->atapi_dma = 1;	hwif->ultra_mask = 0x7f;	hwif->mwdma_mask = 0x07;	hwif->swdma_mask = 0x07;	if (!host_dev)		return;	if (!(hwif->udma_four))		hwif->udma_four = ata66_sis5513(hwif);	if (chipset_family > ATA_16) {		hwif->ide_dma_check = &sis5513_config_xfer_rate;		if (!noautodma)			hwif->autodma = 1;	}	hwif->drives[0].autodma = hwif->autodma;	hwif->drives[1].autodma = hwif->autodma;	return;}static void __init init_dma_sis5513 (ide_hwif_t *hwif, unsigned long dmabase){	ide_setup_dma(hwif, dmabase, 8);}extern void ide_setup_pci_device(struct pci_dev *, ide_pci_device_t *);static int __devinit sis5513_init_one(struct pci_dev *dev, const struct pci_device_id *id){	ide_pci_device_t *d = &sis5513_chipsets[id->driver_data];	if (dev->device != d->device)		BUG();	ide_setup_pci_device(dev, d);	MOD_INC_USE_COUNT;	return 0;}static struct pci_device_id sis5513_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5513, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	{ 0, },};static struct pci_driver driver = {	.name		= "SIS IDE",	.id_table	= sis5513_pci_tbl,	.probe		= sis5513_init_one,};static int sis5513_ide_init(void){	return ide_pci_register_driver(&driver);}static void sis5513_ide_exit(void){	ide_pci_unregister_driver(&driver);}module_init(sis5513_ide_init);module_exit(sis5513_ide_exit);MODULE_AUTHOR("Lionel Bouton, L C Chang, Andre Hedrick");MODULE_DESCRIPTION("PCI driver module for SIS IDE");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;/* * TODO: *	- Get ridden of SisHostChipInfo[] completness dependancy. *	- Study drivers/ide/ide-timing.h. *	- Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them *	  or remove ATA_00 define *	- More checks in the config registers (force values instead of *	  relying on the BIOS setting them correctly). *	- Further optimisations ? *	  . for example ATA66+ regs 0x48 & 0x4A */

⌨️ 快捷键说明

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