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

📄 siimage.c

📁 ep9315平台下硬盘驱动的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
static int siimage_reset_poll (ide_drive_t *drive){	if (SATA_STATUS_REG) {		ide_hwif_t *hwif	= HWIF(drive);		if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) {			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",				hwif->name, hwif->INL(SATA_STATUS_REG));			HWGROUP(drive)->poll_timeout = 0;			return ide_started;		}		return 0;	} else {		return 0;	}}/** *	siimage_pre_reset	-	reset hook *	@drive: IDE device being reset * *	For the SATA devices we need to handle recalibration/geometry *	differently */ static void siimage_pre_reset (ide_drive_t *drive){	if (drive->media != ide_disk)		return;	if (HWIF(drive)->pci_dev->device == PCI_DEVICE_ID_SII_3112) {		drive->special.b.set_geometry = 0;		drive->special.b.recalibrate = 0;	}}/** *	siimage_reset	-	reset a device on an siimage controller *	@drive: drive to reset * *	Perform a controller level reset fo the device. For *	SATA we must also check the PHY. */ static void siimage_reset (ide_drive_t *drive){	ide_hwif_t *hwif	= HWIF(drive);	u8 reset		= 0;	if (hwif->mmio) {		reset = hwif->INB(SELADDR(0));		hwif->OUTB((reset|0x03), SELADDR(0));		udelay(25);		hwif->OUTB(reset, SELADDR(0));		(void) hwif->INB(SELADDR(0));	} else {		pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset);		pci_write_config_byte(hwif->pci_dev, SELREG(0), reset|0x03);		udelay(25);		pci_write_config_byte(hwif->pci_dev, SELREG(0), reset);		pci_read_config_byte(hwif->pci_dev, SELREG(0), &reset);	}	if (SATA_STATUS_REG) {		u32 sata_stat = hwif->INL(SATA_STATUS_REG);		printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n",			hwif->name, sata_stat, __FUNCTION__);		if (!(sata_stat)) {			printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",				hwif->name, sata_stat);			drive->failures++;		}	}}/** *	proc_reports_siimage		-	add siimage controller to proc *	@dev: PCI device *	@clocking: SCSC value *	@name: controller name * *	Report the clocking mode of the controller and add it to *	the /proc interface layer */ static void proc_reports_siimage (struct pci_dev *dev, u8 clocking, const char *name){	if (dev->device == PCI_DEVICE_ID_SII_3112)		goto sata_skip;	printk(KERN_INFO "%s: BASE CLOCK ", name);	clocking &= ~0x03;	switch(clocking) {		case 0x03: printk("DISABLED !\n"); break;		case 0x02: printk("== 2X PCI \n"); break;		case 0x01: printk("== 133 \n"); break;		case 0x00: printk("== 100 \n"); break;	}sata_skip:#if defined(DISPLAY_SIIMAGE_TIMINGS) && defined(CONFIG_PROC_FS)	siimage_devs[n_siimage_devs++] = dev;	if (!siimage_proc) {		siimage_proc = 1;		ide_pci_register_host_proc(&siimage_procs[0]);	}#endif /* DISPLAY_SIIMAGE_TIMINGS && CONFIG_PROC_FS */}static unsigned int setup_mmio_siimage (struct pci_dev *dev, const char *name){	unsigned long bar5	= pci_resource_start(dev, 5);	unsigned long len5	= pci_resource_len(dev, 5);	u8 tmpbyte	= 0;	unsigned long addr;	void *ioaddr;	/*	 *	Drop back to PIO if we can't map the mmio. Some	 *	systems seem to get terminally confused in the PCI	 *	spaces.	 */	 	if(check_mem_region(bar5, len5)!=0)	{		printk(KERN_WARNING "siimage: IDE controller MMIO ports not available.\n");		return 0;	}			ioaddr = ioremap_nocache(bar5, len5);	if (ioaddr == NULL)		return 0;	pci_set_master(dev);	pci_set_drvdata(dev, ioaddr);	addr = (unsigned long) ioaddr;	if (dev->device == PCI_DEVICE_ID_SII_3112) {		writel(0, DEVADDR(0x148));		writel(0, DEVADDR(0x1C8));	}	writeb(0, DEVADDR(0xB4));	writeb(0, DEVADDR(0xF4));	tmpbyte = readb(DEVADDR(0x4A));	switch(tmpbyte & 0x30) {		case 0x00:			/* In 100 MHz clocking, try and switch to 133 */			writeb(tmpbyte|0x10, DEVADDR(0x4A));			break;		case 0x10:			/* On 133Mhz clocking */			break;		case 0x20:			/* On PCIx2 clocking */			break;		case 0x30:			/* Clocking is disabled */			/* 133 clock attempt to force it on */			writeb(tmpbyte & ~0x20, DEVADDR(0x4A));			break;	}		writeb(0x72, DEVADDR(0xA1));	writew(0x328A, DEVADDR(0xA2));	writel(0x62DD62DD, DEVADDR(0xA4));	writel(0x43924392, DEVADDR(0xA8));	writel(0x40094009, DEVADDR(0xAC));	writeb(0x72, DEVADDR(0xE1));	writew(0x328A, DEVADDR(0xE2));	writel(0x62DD62DD, DEVADDR(0xE4));	writel(0x43924392, DEVADDR(0xE8));	writel(0x40094009, DEVADDR(0xEC));	if (dev->device == PCI_DEVICE_ID_SII_3112) {		writel(0xFFFF0000, DEVADDR(0x108));		writel(0xFFFF0000, DEVADDR(0x188));		writel(0x00680000, DEVADDR(0x148));		writel(0x00680000, DEVADDR(0x1C8));	}	tmpbyte = readb(DEVADDR(0x4A));	proc_reports_siimage(dev, (tmpbyte>>=4), name);	return 1;}static unsigned int __init init_chipset_siimage (struct pci_dev *dev, const char *name){	u32 class_rev	= 0;	u8 tmpbyte	= 0;	u8 BA5_EN	= 0;        pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);        class_rev &= 0xff;	pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (class_rev) ? 1 : 255);		pci_read_config_byte(dev, 0x8A, &BA5_EN);	if ((BA5_EN & 0x01) || (pci_resource_start(dev, 5))) {		if (setup_mmio_siimage(dev, name)) {			return 0;		}	}	pci_write_config_byte(dev, 0x80, 0x00);	pci_write_config_byte(dev, 0x84, 0x00);	pci_read_config_byte(dev, 0x8A, &tmpbyte);	switch(tmpbyte & 0x30) {		case 0x00:			/* 133 clock attempt to force it on */			pci_write_config_byte(dev, 0x8A, tmpbyte|0x10);		case 0x30:			/* if clocking is disabled */			/* 133 clock attempt to force it on */			pci_write_config_byte(dev, 0x8A, tmpbyte & ~0x20);		case 0x10:			/* 133 already */			break;		case 0x20:			/* BIOS set PCI x2 clocking */			break;	}	pci_read_config_byte(dev, 0x8A, &tmpbyte);	pci_write_config_byte(dev, 0xA1, 0x72);	pci_write_config_word(dev, 0xA2, 0x328A);	pci_write_config_dword(dev, 0xA4, 0x62DD62DD);	pci_write_config_dword(dev, 0xA8, 0x43924392);	pci_write_config_dword(dev, 0xAC, 0x40094009);	pci_write_config_byte(dev, 0xB1, 0x72);	pci_write_config_word(dev, 0xB2, 0x328A);	pci_write_config_dword(dev, 0xB4, 0x62DD62DD);	pci_write_config_dword(dev, 0xB8, 0x43924392);	pci_write_config_dword(dev, 0xBC, 0x40094009);	pci_read_config_byte(dev, 0x8A, &tmpbyte);	proc_reports_siimage(dev, (tmpbyte>>=4), name);	return 0;}static void __init init_mmio_iops_siimage (ide_hwif_t *hwif){	struct pci_dev *dev	= hwif->pci_dev;	unsigned long addr	= (unsigned long) pci_get_drvdata(hwif->pci_dev);	u8 ch			= hwif->channel;//	u16 i			= 0;	hw_regs_t hw;	default_hwif_mmiops(hwif);	memset(&hw, 0, sizeof(hw_regs_t));#if 1#ifdef SIIMAGE_BUFFERED_TASKFILE	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xD0 : 0x90);	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xD1 : 0x91);	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xD2 : 0x92);	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xD3 : 0x93);	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xD4 : 0x94);	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xD5 : 0x95);	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xD6 : 0x96);	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xD7 : 0x97);	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xDA : 0x9A);#else /* ! SIIMAGE_BUFFERED_TASKFILE */	hw.io_ports[IDE_DATA_OFFSET]	= DEVADDR((ch) ? 0xC0 : 0x80);	hw.io_ports[IDE_ERROR_OFFSET]	= DEVADDR((ch) ? 0xC1 : 0x81);	hw.io_ports[IDE_NSECTOR_OFFSET]	= DEVADDR((ch) ? 0xC2 : 0x82);	hw.io_ports[IDE_SECTOR_OFFSET]	= DEVADDR((ch) ? 0xC3 : 0x83);	hw.io_ports[IDE_LCYL_OFFSET]	= DEVADDR((ch) ? 0xC4 : 0x84);	hw.io_ports[IDE_HCYL_OFFSET]	= DEVADDR((ch) ? 0xC5 : 0x85);	hw.io_ports[IDE_SELECT_OFFSET]	= DEVADDR((ch) ? 0xC6 : 0x86);	hw.io_ports[IDE_STATUS_OFFSET]	= DEVADDR((ch) ? 0xC7 : 0x87);	hw.io_ports[IDE_CONTROL_OFFSET]	= DEVADDR((ch) ? 0xCA : 0x8A);#endif /* SIIMAGE_BUFFERED_TASKFILE */#else#ifdef SIIMAGE_BUFFERED_TASKFILE	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)		hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i);	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A);#else /* ! SIIMAGE_BUFFERED_TASKFILE */	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)		hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i);	hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A);#endif /* SIIMAGE_BUFFERED_TASKFILE */#endif#if 0	printk(KERN_DEBUG "%s: ", hwif->name);	for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)		printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i));	printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i));#endif	hw.io_ports[IDE_IRQ_OFFSET]	= 0;        if (dev->device == PCI_DEVICE_ID_SII_3112) {		hw.sata_scr[SATA_STATUS_OFFSET]	= DEVADDR((ch) ? 0x184 : 0x104);		hw.sata_scr[SATA_ERROR_OFFSET]	= DEVADDR((ch) ? 0x188 : 0x108);		hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100);		hw.sata_misc[SATA_MISC_OFFSET]	= DEVADDR((ch) ? 0x1C0 : 0x140);		hw.sata_misc[SATA_PHY_OFFSET]	= DEVADDR((ch) ? 0x1C4 : 0x144);		hw.sata_misc[SATA_IEN_OFFSET]	= DEVADDR((ch) ? 0x1C8 : 0x148);	}	hw.priv				= (void *) addr;//	hw.priv				= pci_get_drvdata(hwif->pci_dev);	hw.irq				= hwif->pci_dev->irq;	memcpy(&hwif->hw, &hw, sizeof(hw));	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports));	if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) {		memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr));		memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc));	}#ifdef SIIMAGE_BUFFERED_TASKFILE        hwif->addressing = 1;#endif /* SIIMAGE_BUFFERED_TASKFILE */	hwif->irq			= hw.irq;	hwif->hwif_data			= pci_get_drvdata(hwif->pci_dev);#ifdef SIIMAGE_LARGE_DMA	hwif->dma_base			= DEVADDR((ch) ? 0x18 : 0x10);	hwif->dma_base2			= DEVADDR((ch) ? 0x08 : 0x00);	hwif->dma_prdtable		= (hwif->dma_base2 + 4);#else /* ! SIIMAGE_LARGE_DMA */	hwif->dma_base			= DEVADDR((ch) ? 0x08 : 0x00);	hwif->dma_base2			= DEVADDR((ch) ? 0x18 : 0x10);#endif /* SIIMAGE_LARGE_DMA */	hwif->mmio			= 2;}static void __init init_iops_siimage (ide_hwif_t *hwif){	struct pci_dev *dev	= hwif->pci_dev;	u32 class_rev		= 0;	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;	hwif->rqsize = 128;	if ((dev->device == PCI_DEVICE_ID_SII_3112) && (!(class_rev)))		hwif->rqsize = 16;	if (pci_get_drvdata(dev) == NULL)		return;	init_mmio_iops_siimage(hwif);}static unsigned int __init ata66_siimage (ide_hwif_t *hwif){	if (pci_get_drvdata(hwif->pci_dev) == NULL) {		u8 ata66 = 0;		pci_read_config_byte(hwif->pci_dev, SELREG(0), &ata66);		return (ata66 & 0x01) ? 1 : 0;	}	return (hwif->INB(SELADDR(0)) & 0x01) ? 1 : 0;}static void __init init_hwif_siimage (ide_hwif_t *hwif){	hwif->autodma = 0;		hwif->resetproc = &siimage_reset;	hwif->speedproc = &siimage_tune_chipset;	hwif->tuneproc	= &siimage_tuneproc;	hwif->reset_poll = &siimage_reset_poll;	hwif->pre_reset = &siimage_pre_reset;	if(hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112)		hwif->busproc   = &siimage_busproc;	if (!hwif->dma_base) {		hwif->drives[0].autotune = 1;		hwif->drives[1].autotune = 1;		return;	}	hwif->ultra_mask = 0x7f;	hwif->mwdma_mask = 0x07;	hwif->swdma_mask = 0x07;	if (hwif->pci_dev->device != PCI_DEVICE_ID_SII_3112)		hwif->atapi_dma = 1;	hwif->ide_dma_check = &siimage_config_drive_for_dma;	if (!(hwif->udma_four))		hwif->udma_four = ata66_siimage(hwif);	if (hwif->mmio) {		hwif->ide_dma_count = &siimage_mmio_ide_dma_count;		hwif->ide_dma_test_irq = &siimage_mmio_ide_dma_test_irq;		hwif->ide_dma_verbose = &siimage_mmio_ide_dma_verbose;	} else {		hwif->ide_dma_test_irq = & siimage_io_ide_dma_test_irq;	}	if (!noautodma)		hwif->autodma = 1;	hwif->drives[0].autodma = hwif->autodma;	hwif->drives[1].autodma = hwif->autodma;}static void __init init_dma_siimage (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 siimage_init_one(struct pci_dev *dev, const struct pci_device_id *id){	ide_pci_device_t *d = &siimage_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 siimage_pci_tbl[] __devinitdata = {	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680,  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	{ PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1},	{ 0, },};static struct pci_driver driver = {	.name		= "SiI IDE",	.id_table	= siimage_pci_tbl,	.probe		= siimage_init_one,};static int siimage_ide_init(void){	return ide_pci_register_driver(&driver);}static void siimage_ide_exit(void){	ide_pci_unregister_driver(&driver);}module_init(siimage_ide_init);module_exit(siimage_ide_exit);MODULE_AUTHOR("Andre Hedrick, Alan Cox");MODULE_DESCRIPTION("PCI driver module for SiI IDE");MODULE_LICENSE("GPL");EXPORT_NO_SYMBOLS;

⌨️ 快捷键说明

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