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

📄 pmac.c

📁 LINUX 2.6.17.4的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	unsigned int value, value2 = 0;		switch(pmif->kind) {		case controller_sh_ata6:			value = 0x0a820c97;			value2 = 0x00033031;			break;		case controller_un_ata6:		case controller_k2_ata6:			value = 0x08618a92;			value2 = 0x00002921;			break;		case controller_kl_ata4:			value = 0x0008438c;			break;		case controller_kl_ata3:			value = 0x00084526;			break;		case controller_heathrow:		case controller_ohare:		default:			value = 0x00074526;			break;	}	pmif->timings[0] = pmif->timings[1] = value;	pmif->timings[2] = pmif->timings[3] = value2;}unsigned longpmac_ide_get_base(int index){	return pmac_ide[index].regbase;}intpmac_ide_check_base(unsigned long base){	int ix;	 	for (ix = 0; ix < MAX_HWIFS; ++ix)		if (base == pmac_ide[ix].regbase)			return ix;	return -1;}intpmac_ide_get_irq(unsigned long 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[] = { 3, 22, 33, 34, 56, 57 };dev_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;}/* Suspend call back, should be called after the child devices * have actually been suspended */static intpmac_ide_do_suspend(ide_hwif_t *hwif){	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;		/* We clear the timings */	pmif->timings[0] = 0;	pmif->timings[1] = 0;	#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK	/* Note: This code will be called for every hwif, thus we'll	 * try several time to stop the LED blinker timer,  but that	 * should be harmless	 */	if (pmu_ide_blink_enabled) {		unsigned long flags;		/* Make sure we don't hit the PMU blink */		spin_lock_irqsave(&pmu_blink_lock, flags);		if (pmu_blink_ledstate)			del_timer(&pmu_blink_timer);		pmu_blink_ledstate = 0;		spin_unlock_irqrestore(&pmu_blink_lock, flags);	}#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */	disable_irq(pmif->irq);	/* The media bay will handle itself just fine */	if (pmif->mediabay)		return 0;		/* Kauai has bus control FCRs directly here */	if (pmif->kauai_fcr) {		u32 fcr = readl(pmif->kauai_fcr);		fcr &= ~(KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE);		writel(fcr, pmif->kauai_fcr);	}	/* Disable the bus on older machines and the cell on kauai */	ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id,			    0);	return 0;}/* Resume call back, should be called before the child devices * are resumed */static intpmac_ide_do_resume(ide_hwif_t *hwif){	pmac_ide_hwif_t *pmif = (pmac_ide_hwif_t *)hwif->hwif_data;		/* Hard reset & re-enable controller (do we really need to reset ? -BenH) */	if (!pmif->mediabay) {		ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 1);		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, pmif->node, pmif->aapl_bus_id, 1);		msleep(10);		ppc_md.feature_call(PMAC_FTR_IDE_RESET, pmif->node, pmif->aapl_bus_id, 0);		/* Kauai has it different */		if (pmif->kauai_fcr) {			u32 fcr = readl(pmif->kauai_fcr);			fcr |= KAUAI_FCR_UATA_RESET_N | KAUAI_FCR_UATA_ENABLE;			writel(fcr, pmif->kauai_fcr);		}		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));	}	/* Sanitize drive timings */	sanitize_timings(pmif);	enable_irq(pmif->irq);	return 0;}/* * Setup, register & probe an IDE channel driven by this driver, this is * called by one of the 2 probe functions (macio or PCI). Note that a channel * that ends up beeing free of any device is not kept around by this driver * (it is kept in 2.4). This introduce an interface numbering change on some * rare machines unfortunately, but it's better this way. */static intpmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif){	struct device_node *np = pmif->node;	int *bidp;	pmif->cable_80 = 0;	pmif->broken_dma = pmif->broken_dma_warn = 0;	if (device_is_compatible(np, "shasta-ata"))		pmif->kind = controller_sh_ata6;	else if (device_is_compatible(np, "kauai-ata"))		pmif->kind = controller_un_ata6;	else if (device_is_compatible(np, "K2-UATA"))		pmif->kind = controller_k2_ata6;	else if (device_is_compatible(np, "keylargo-ata")) {		if (strcmp(np->name, "ata-4") == 0)			pmif->kind = controller_kl_ata4;		else			pmif->kind = controller_kl_ata3;	} else if (device_is_compatible(np, "heathrow-ata"))		pmif->kind = controller_heathrow;	else {		pmif->kind = controller_ohare;		pmif->broken_dma = 1;	}	bidp = (int *)get_property(np, "AAPL,bus-id", NULL);	pmif->aapl_bus_id =  bidp ? *bidp : 0;	/* Get cable type from device-tree */	if (pmif->kind == controller_kl_ata4 || pmif->kind == controller_un_ata6	    || pmif->kind == controller_k2_ata6	    || pmif->kind == controller_sh_ata6) {		char* cable = get_property(np, "cable-type", NULL);		if (cable && !strncmp(cable, "80-", 3))			pmif->cable_80 = 1;	}	/* G5's seem to have incorrect cable type in device-tree. Let's assume	 * they have a 80 conductor cable, this seem to be always the case unless	 * the user mucked around	 */	if (device_is_compatible(np, "K2-UATA") ||	    device_is_compatible(np, "shasta-ata"))		pmif->cable_80 = 1;	/* On Kauai-type controllers, we make sure the FCR is correct */	if (pmif->kauai_fcr)		writel(KAUAI_FCR_UATA_MAGIC |		       KAUAI_FCR_UATA_RESET_N |		       KAUAI_FCR_UATA_ENABLE, pmif->kauai_fcr);	pmif->mediabay = 0;		/* Make sure we have sane timings */	sanitize_timings(pmif);#ifndef CONFIG_PPC64	/* XXX FIXME: Media bay stuff need re-organizing */	if (np->parent && np->parent->name	    && strcasecmp(np->parent->name, "media-bay") == 0) {#ifdef CONFIG_PMAC_MEDIABAY		media_bay_set_ide_infos(np->parent, pmif->regbase, pmif->irq, hwif->index);#endif /* CONFIG_PMAC_MEDIABAY */		pmif->mediabay = 1;		if (!bidp)			pmif->aapl_bus_id = 1;	} else if (pmif->kind == controller_ohare) {		/* The code below is having trouble on some ohare machines		 * (timing related ?). Until I can put my hand on one of these		 * units, I keep the old way		 */		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, 0, 1);	} else#endif	{ 		/* This is necessary to enable IDE when net-booting */		ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 1);		ppc_md.feature_call(PMAC_FTR_IDE_ENABLE, np, pmif->aapl_bus_id, 1);		msleep(10);		ppc_md.feature_call(PMAC_FTR_IDE_RESET, np, pmif->aapl_bus_id, 0);		msleep(jiffies_to_msecs(IDE_WAKEUP_DELAY));	}	/* Setup MMIO ops */	default_hwif_mmiops(hwif);       	hwif->OUTBSYNC = pmac_outbsync;	/* Tell common code _not_ to mess with resources */	hwif->mmio = 2;	hwif->hwif_data = pmif;	pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);	memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));	hwif->chipset = ide_pmac;	hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET] || pmif->mediabay;	hwif->hold = pmif->mediabay;	hwif->udma_four = pmif->cable_80;	hwif->drives[0].unmask = 1;	hwif->drives[1].unmask = 1;	hwif->tuneproc = pmac_ide_tuneproc;	if (pmif->kind == controller_un_ata6	    || pmif->kind == controller_k2_ata6	    || pmif->kind == controller_sh_ata6)		hwif->selectproc = pmac_ide_kauai_selectproc;	else		hwif->selectproc = pmac_ide_selectproc;	hwif->speedproc = pmac_ide_tune_chipset;#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK	pmu_ide_blink_enabled = pmu_hd_blink_init();	if (pmu_ide_blink_enabled)		hwif->led_act = pmu_hd_kick_blink;#endif	printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n",	       hwif->index, model_name[pmif->kind], pmif->aapl_bus_id,	       pmif->mediabay ? " (mediabay)" : "", hwif->irq);			#ifdef CONFIG_PMAC_MEDIABAY	if (pmif->mediabay && check_media_bay_by_base(pmif->regbase, MB_CD) == 0)		hwif->noprobe = 0;#endif /* CONFIG_PMAC_MEDIABAY */	hwif->sg_max_nents = MAX_DCMDS;#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC	/* has a DBDMA controller channel */	if (pmif->dma_regs)		pmac_ide_setup_dma(pmif, hwif);#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */	/* We probe the hwif now */	probe_hwif_init(hwif);	return 0;}/* * Attach to a macio probed interface */static int __devinitpmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match){	void __iomem *base;	unsigned long regbase;	int irq;	ide_hwif_t *hwif;	pmac_ide_hwif_t *pmif;	int i, rc;	i = 0;	while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0	    || pmac_ide[i].node != NULL))		++i;	if (i >= MAX_HWIFS) {		printk(KERN_ERR "ide-pmac: MacIO interface attach with no slot\n");		printk(KERN_ERR "          %s\n", mdev->ofdev.node->full_name);		return -ENODEV;	}	pmif = &pmac_ide[i];	hwif = &ide_hwifs[i];	if (macio_resource_count(mdev) == 0) {		printk(KERN_WARNING "ide%d: no address for %s\n",		       i, mdev->ofdev.node->full_name);		return -ENXIO;	}	/* Request memory resource for IO ports */	if (macio_request_resource(mdev, 0, "ide-pmac (ports)")) {		printk(KERN_ERR "ide%d: can't request mmio resource !\n", i);		return -EBUSY;	}				/* XXX This is bogus. Should be fixed in the registry by checking	 * the kind of host interrupt controller, a bit like gatwick	 * fixes in irq.c. That works well enough for the single case	 * where that happens though...	 */	if (macio_irq_count(mdev) == 0) {		printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",			i, mdev->ofdev.node->full_name);		irq = 13;	} else		irq = macio_irq(mdev, 0);	base = ioremap(macio_resource_start(mdev, 0), 0x400);	regbase = (unsigned long) base;	hwif->pci_dev = mdev->bus->pdev;	hwif->gendev.parent = &mdev->ofdev.dev;	pmif->mdev = mdev;	pmif->node = mdev->ofdev.node;	pmif->regbase = regbase;	pmif->irq = irq;	pmif->kauai_fcr = NULL;#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC	if (macio_resource_count(mdev) >= 2) {		if (macio_request_resource(mdev, 1, "ide-pmac (dma)"))			printk(KERN_WARNING "ide%d: can't request DMA resource !\n", i);		else			pmif->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x1000);	} else		pmif->dma_regs = NULL;#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */	dev_set_drvdata(&mdev->ofdev.dev, hwif);	rc = pmac_ide_setup_device(pmif, hwif);	if (rc != 0) {		/* The inteface is released to the common IDE layer */		dev_set_drvdata(&mdev->ofdev.dev, NULL);		iounmap(base);		if (pmif->dma_regs)			iounmap(pmif->dma_regs);		memset(pmif, 0, sizeof(*pmif));		macio_release_resource(mdev, 0);		if (pmif->dma_regs)			macio_release_resource(mdev, 1);	}	return rc;}static intpmac_ide_macio_suspend(struct macio_dev *mdev, pm_message_t state){	ide_hwif_t	*hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);	int		rc = 0;	if (state.event != mdev->ofdev.dev.power.power_state.event && state.event >= PM_EVENT_SUSPEND) {		rc = pmac_ide_do_suspend(hwif);		if (rc == 0)			mdev->ofdev.dev.power.power_state = state;	}	return rc;}static intpmac_ide_macio_resume(struct macio_dev *mdev){	ide_hwif_t	*hwif = (ide_hwif_t *)dev_get_drvdata(&mdev->ofdev.dev);	int		rc = 0;		if (mdev->ofdev.dev.power.power_state.event != PM_EVENT_ON) {		rc = pmac_ide_do_resume(hwif);		if (rc == 0)			mdev->ofdev.dev.power.power_state = PMSG_ON;	}	return rc;}/* * Attach to a PCI probed interface */static int __devinitpmac_ide_pci_attach(struct pci_dev *pdev, const struct pci_device_id *id){	ide_hwif_t *hwif;	struct device_node *np;	pmac_ide_hwif_t *pmif;	void __iomem *base;	unsigned long rbase, rlen;	int i, rc;	np = pci_device_to_OF_node(pdev);	if (np == NULL) {		printk(KERN_ERR "ide-pmac: cannot find MacIO node for Kauai ATA interface\n");		return -ENODEV;	}	i = 0;	while (i < MAX_HWIFS && (ide_hwifs[i].io_ports[IDE_DATA_OFFSET] != 0	    || pmac_ide[i].node != NULL))		++i;	if (i >= MAX_HWIFS) {		printk(KERN_ERR "ide-pmac: PCI interface attach with no slot\n");		printk(KERN_ERR "          %s\n", np->full_name);		return -ENODEV;	}	pmif = &pmac_ide[i];	hwif = &ide_hwifs[i];	if (pci_enable_device(pdev)) {		printk(KERN_WARNING "ide%i: Can't enable PCI device for %s\n",			i, np->full_name);		return -ENXIO;	}	pci_set_master(pdev);				if (pci_request_regions(pdev, "Kauai ATA")) {		printk(KERN_ERR "ide%d: Cannot obtain PCI resources for %s\n",			i, np->full_name);		return -ENXIO;	}	hwif->pci_dev = pdev;	hwif->gendev.parent = &pdev->dev;	pmif->mdev = NULL;	pmif->node = np;	rbase = pci_resource_start(pdev, 0);	rlen = pci_resource_len(pdev, 0);	base = ioremap(rbase, rlen);	pmif->regbase = (unsigned long) base + 0x2000;#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC	pmif->dma_regs = base + 0x1000;#endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */	pmif->kauai_fcr = base;	pmif->irq = pdev->irq;	pci_set_drvdata(pdev, hwif);	rc = pmac_ide_setup_device(pmif, hwif);	if (rc != 0) {		/* The inteface is released to the common IDE layer */		pci_set_drvdata(pdev, NULL);		iounmap(base);		memset(pmif, 0, sizeof(*pmif));		pci_release_regions(pdev);	}	return rc;}static intpmac_ide_pci_suspend(struct pci_dev *pdev, pm_message_t state){	ide_hwif_t	*hwif = (ide_hwif_t *)pci_get_drvdata(pdev);	int		rc = 0;		if (state.event != pdev->dev.power.power_state.event && state.event >= 2) {		rc = pmac_ide_do_suspend(hwif);		if (rc == 0)			pdev->dev.power.power_state = state;	}	return rc;}static intpmac_ide_pci_resume(struct pci_dev *pdev){	ide_hwif_t	*hwif = (ide_hwif_t *)pci_get_drvdata(pdev);	int		rc = 0;		if (pdev->dev.power.power_state.event != PM_EVENT_ON) {		rc = pmac_ide_do_resume(hwif);		if (rc == 0)			pdev->dev.power.power_state = PMSG_ON;	}	return rc;}static struct of_device_id pmac_ide_macio_match[] = {	{	.name 		= "IDE",	},	{	.name 		= "ATA",	},	{	.type		= "ide",	},	{	.type		= "ata",	},	{},};static struct macio_driver pmac_ide_macio_driver = {	.name 		= "ide-pmac",	.match_table	= pmac_ide_macio_match,	.probe		= pmac_ide_macio_attach,	.suspend	= pmac_ide_macio_suspend,

⌨️ 快捷键说明

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