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

📄 ide-pmac.c

📁 at91rm9200处理器ide接口驱动程序源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
			case XFER_UDMA_4:   drive->id->dma_ultra |= 0x1010; break;			case XFER_UDMA_3:   drive->id->dma_ultra |= 0x0808; break;			case XFER_UDMA_2:   drive->id->dma_ultra |= 0x0404; break;			case XFER_UDMA_1:   drive->id->dma_ultra |= 0x0202; break;			case XFER_UDMA_0:   drive->id->dma_ultra |= 0x0101; break;			case XFER_MW_DMA_2: drive->id->dma_mword |= 0x0404; break;			case XFER_MW_DMA_1: drive->id->dma_mword |= 0x0202; break;			case XFER_MW_DMA_0: drive->id->dma_mword |= 0x0101; break;			case XFER_SW_DMA_2: drive->id->dma_1word |= 0x0404; break;			case XFER_SW_DMA_1: drive->id->dma_1word |= 0x0202; break;			case XFER_SW_DMA_0: drive->id->dma_1word |= 0x0101; break;			default: break;		}	}	enable_irq(hwif->irq);	return result;}/* Calculate PIO timings */static void __pmacpmac_ide_tuneproc(ide_drive_t *drive, byte pio){	ide_pio_data_t d;	int i;	u32 *timings;	unsigned accessTicks, recTicks;	unsigned accessTime, recTime;		i = pmac_ide_find(drive);	if (i < 0)		return;			pio = ide_get_best_pio_mode(drive, pio, 4, &d);	accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);	if (drive->select.b.unit & 0x01)		timings = &pmac_ide[i].timings[1];	else		timings = &pmac_ide[i].timings[0];	recTime = d.cycle_time - ide_pio_timings[pio].active_time			- ide_pio_timings[pio].setup_time;	recTime = max(recTime, 150U);	accessTime = ide_pio_timings[pio].active_time;	accessTime = max(accessTime, 150U);	if (pmac_ide[i].kind == controller_kl_ata4 ||		pmac_ide[i].kind == controller_kl_ata4_80) {		/* 66Mhz cell */		accessTicks = SYSCLK_TICKS_66(accessTime);		accessTicks = min(accessTicks, 0x1fU);		recTicks = SYSCLK_TICKS_66(recTime);		recTicks = min(recTicks, 0x1fU);		*timings = ((*timings) & ~TR_66_PIO_MASK) |				(accessTicks << TR_66_PIO_ACCESS_SHIFT) |				(recTicks << TR_66_PIO_RECOVERY_SHIFT);	} else {		/* 33Mhz cell */		int ebit = 0;		accessTicks = SYSCLK_TICKS(accessTime);		accessTicks = min(accessTicks, 0x1fU);		accessTicks = max(accessTicks, 4U);		recTicks = SYSCLK_TICKS(recTime);		recTicks = min(recTicks, 0x1fU);		recTicks = max(recTicks, 5U) - 4;		if (recTicks > 9) {			recTicks--; /* guess, but it's only for PIO0, so... */			ebit = 1;		}		*timings = ((*timings) & ~TR_33_PIO_MASK) |				(accessTicks << TR_33_PIO_ACCESS_SHIFT) |				(recTicks << TR_33_PIO_RECOVERY_SHIFT);		if (ebit)			*timings |= TR_33_PIO_E;	}#ifdef IDE_PMAC_DEBUG	printk(KERN_ERR "ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n",		pio,  *timings);#endif				if (drive->select.all == IN_BYTE(IDE_SELECT_REG))		pmac_ide_selectproc(drive);}#ifdef CONFIG_BLK_DEV_IDEDMA_PMACstatic int __pmacset_timings_udma(u32 *timings, byte speed){	unsigned rdyToPauseTicks, wrDataSetupTicks, addrTicks;	rdyToPauseTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].rdy2pause);	wrDataSetupTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].wrDataSetup);	addrTicks = SYSCLK_TICKS_66(udma_timings[speed & 0xf].addrSetup);	*timings = ((*timings) & ~(TR_66_UDMA_MASK | TR_66_MDMA_MASK)) |			(wrDataSetupTicks << TR_66_UDMA_WRDATASETUP_SHIFT) | 			(rdyToPauseTicks << TR_66_UDMA_RDY2PAUS_SHIFT) |			(addrTicks <<TR_66_UDMA_ADDRSETUP_SHIFT) |			TR_66_UDMA_EN;#ifdef IDE_PMAC_DEBUG	printk(KERN_ERR "ide_pmac: Set UDMA timing for mode %d, reg: 0x%08x\n",		speed & 0xf,  *timings);#endif		return 0;}static int __pmacset_timings_mdma(int intf_type, u32 *timings, byte speed, int drive_cycle_time){	int cycleTime, accessTime, recTime;	unsigned accessTicks, recTicks;	struct mdma_timings_t* tm;	int i;	/* Get default cycle time for mode */	switch(speed & 0xf) {		case 0: cycleTime = 480; break;		case 1: cycleTime = 150; break;		case 2: cycleTime = 120; break;		default:			return -1;	}	/* Adjust for drive */	if (drive_cycle_time && drive_cycle_time > cycleTime)		cycleTime = drive_cycle_time;	/* OHare limits according to some old Apple sources */		if ((intf_type == controller_ohare) && (cycleTime < 150))		cycleTime = 150;	/* Get the proper timing array for this controller */	switch(intf_type) {		case controller_kl_ata4:		case controller_kl_ata4_80:			tm = mdma_timings_66;			break;		case controller_kl_ata3:			tm = mdma_timings_33k;			break;		default:			tm = mdma_timings_33;			break;	}	/* Lookup matching access & recovery times */	i = -1;	for (;;) {		if (tm[i+1].cycleTime < cycleTime)			break;		i++;	}	if (i < 0)		return -1;	cycleTime = tm[i].cycleTime;	accessTime = tm[i].accessTime;	recTime = tm[i].recoveryTime;#ifdef IDE_PMAC_DEBUG	printk(KERN_ERR "ide_pmac: MDMA, cycleTime: %d, accessTime: %d, recTime: %d\n",		cycleTime, accessTime, recTime);#endif		if (intf_type == controller_kl_ata4 || intf_type == controller_kl_ata4_80) {		/* 66Mhz cell */		accessTicks = SYSCLK_TICKS_66(accessTime);		accessTicks = min(accessTicks, 0x1fU);		accessTicks = max(accessTicks, 0x1U);		recTicks = SYSCLK_TICKS_66(recTime);		recTicks = min(recTicks, 0x1fU);		recTicks = max(recTicks, 0x3U);		/* Clear out mdma bits and disable udma */		*timings = ((*timings) & ~(TR_66_MDMA_MASK | TR_66_UDMA_MASK)) |			(accessTicks << TR_66_MDMA_ACCESS_SHIFT) |			(recTicks << TR_66_MDMA_RECOVERY_SHIFT);	} else if (intf_type == controller_kl_ata3) {		/* 33Mhz cell on KeyLargo */		accessTicks = SYSCLK_TICKS(accessTime);		accessTicks = max(accessTicks, 1U);		accessTicks = min(accessTicks, 0x1fU);		accessTime = accessTicks * IDE_SYSCLK_NS;		recTicks = SYSCLK_TICKS(recTime);		recTicks = max(recTicks, 1U);		recTicks = min(recTicks, 0x1fU);		*timings = ((*timings) & ~TR_33_MDMA_MASK) |				(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |				(recTicks << TR_33_MDMA_RECOVERY_SHIFT);	} else {		/* 33Mhz cell on others */		int halfTick = 0;		int origAccessTime = accessTime;		int origRecTime = recTime;				accessTicks = SYSCLK_TICKS(accessTime);		accessTicks = max(accessTicks, 1U);		accessTicks = min(accessTicks, 0x1fU);		accessTime = accessTicks * IDE_SYSCLK_NS;		recTicks = SYSCLK_TICKS(recTime);		recTicks = max(recTicks, 2U) - 1;		recTicks = min(recTicks, 0x1fU);		recTime = (recTicks + 1) * IDE_SYSCLK_NS;		if ((accessTicks > 1) &&		    ((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) &&		    ((recTime - IDE_SYSCLK_NS/2) >= origRecTime)) {            		halfTick = 1;			accessTicks--;		}		*timings = ((*timings) & ~TR_33_MDMA_MASK) |				(accessTicks << TR_33_MDMA_ACCESS_SHIFT) |				(recTicks << TR_33_MDMA_RECOVERY_SHIFT);		if (halfTick)			*timings |= TR_33_MDMA_HALFTICK;	}#ifdef IDE_PMAC_DEBUG	printk(KERN_ERR "ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n",		speed & 0xf,  *timings);#endif		return 0;}#endif /* #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC *//* You may notice we don't use this function on normal operation, * our, normal mdma function is supposed to be more precise */static int __pmacpmac_ide_tune_chipset (ide_drive_t *drive, byte speed){	int intf		= pmac_ide_find(drive);	int unit		= (drive->select.b.unit & 0x01);	int ret			= 0;	u32 *timings;	if (intf < 0)		return 1;			timings = &pmac_ide[intf].timings[unit];		switch(speed) {#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC		case XFER_UDMA_4:		case XFER_UDMA_3:			if (pmac_ide[intf].kind != controller_kl_ata4_80)				return 1;				case XFER_UDMA_2:		case XFER_UDMA_1:		case XFER_UDMA_0:			if (pmac_ide[intf].kind != controller_kl_ata4 &&				pmac_ide[intf].kind != controller_kl_ata4_80)				return 1;					ret = set_timings_udma(timings, speed);			break;		case XFER_MW_DMA_2:		case XFER_MW_DMA_1:		case XFER_MW_DMA_0:			ret = set_timings_mdma(pmac_ide[intf].kind, timings, speed, 0);			break;		case XFER_SW_DMA_2:		case XFER_SW_DMA_1:		case XFER_SW_DMA_0:			return 1;#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */		case XFER_PIO_4:		case XFER_PIO_3:		case XFER_PIO_2:		case XFER_PIO_1:		case XFER_PIO_0:			pmac_ide_tuneproc(drive, speed & 0x07);			break;		default:			ret = 1;	}	if (ret)		return ret;	ret = pmac_ide_do_setfeature(drive, speed);	if (ret)		return ret;			pmac_ide_selectproc(drive);		drive->current_speed = speed;	return 0;}static void __pmacsanitize_timings(int i){	unsigned value;		switch(pmac_ide[i].kind) {		case controller_kl_ata4:		case controller_kl_ata4_80:			value = 0x0008438c;			break;		case controller_kl_ata3:			value = 0x00084526;			break;		case controller_heathrow:		case controller_ohare:		default:			value = 0x00074526;			break;	}	pmac_ide[i].timings[0] = pmac_ide[i].timings[1] = value;}ide_ioreg_t __pmacpmac_ide_get_base(int index){	return pmac_ide[index].regbase;}int __pmacpmac_ide_check_base(ide_ioreg_t base){	int ix;	 	for (ix = 0; ix < MAX_HWIFS; ++ix)		if (base == pmac_ide[ix].regbase)			return ix;	return -1;}int __pmacpmac_ide_get_irq(ide_ioreg_t base){	int ix;	for (ix = 0; ix < MAX_HWIFS; ++ix)		if (base == pmac_ide[ix].regbase)			return pmac_ide[ix].irq;	return 0;}static int ide_majors[]  __pmacdata = { 3, 22, 33, 34, 56, 57 };kdev_t __initpmac_find_ide_boot(char *bootdevice, int n){	int i;		/*	 * Look through the list of IDE interfaces for this one.	 */	for (i = 0; i < pmac_ide_count; ++i) {		char *name;		if (!pmac_ide[i].node || !pmac_ide[i].node->full_name)			continue;		name = pmac_ide[i].node->full_name;		if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {			/* XXX should cope with the 2nd drive as well... */			return MKDEV(ide_majors[i], 0);		}	}	return 0;}void __initpmac_ide_probe(void){	struct device_node *np;	int i;	struct device_node *atas;	struct device_node *p, **pp, *removables, **rp;	unsigned long base;	int irq, big_delay;	ide_hwif_t *hwif;	if (_machine != _MACH_Pmac)		return;	pp = &atas;	rp = &removables;	p = find_devices("ATA");	if (p == NULL)		p = find_devices("IDE");	if (p == NULL)		p = find_type_devices("ide");	if (p == NULL)		p = find_type_devices("ata");	/* Move removable devices such as the media-bay CDROM	   on the PB3400 to the end of the list. */	for (; p != NULL; p = p->next) {		if (p->parent && p->parent->type		    && strcasecmp(p->parent->type, "media-bay") == 0) {			*rp = p;			rp = &p->next;		} else {			*pp = p;			pp = &p->next;		}	}	*rp = NULL;	*pp = removables;	big_delay = 0;	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {		struct device_node *tp;		struct pmac_ide_hwif* pmhw;		int *bidp;		int in_bay = 0;		u8 pbus, pid;		struct pci_dev *pdev = NULL;		/*		 * If this node is not under a mac-io or dbdma node,		 * leave it to the generic PCI driver.		 */		for (tp = np->parent; tp != 0; tp = tp->parent)			if (tp->type && (strcmp(tp->type, "mac-io") == 0					 || strcmp(tp->type, "dbdma") == 0))				break;		if (tp == 0)			continue;		if (np->n_addrs == 0) {			printk(KERN_WARNING "ide: no address for device %s\n",			       np->full_name);			continue;		}		/* We need to find the pci_dev of the mac-io holding the		 * IDE interface		 */		if (pci_device_from_OF_node(tp, &pbus, &pid) == 0)			pdev = pci_find_slot(pbus, pid);		if (pdev == NULL)			printk(KERN_WARNING "ide: no PCI host for device %s, DMA disabled\n",			       np->full_name);		/*		 * If this slot is taken (e.g. by ide-pci.c) try the next one.		 */		while (i < MAX_HWIFS		       && ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0)			++i;		if (i >= MAX_HWIFS)			break;		pmhw = &pmac_ide[i];		/*		 * Some older OFs have bogus sizes, causing request_OF_resource		 * to fail. We fix them up here		 */

⌨️ 快捷键说明

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