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

📄 setup-pci.c

📁 ep9315平台下硬盘驱动的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	ide_hwif_t *hwif;	/*  Possibly we should fail if these checks report true */	ide_pci_check_iomem(dev, d, 2*port);	ide_pci_check_iomem(dev, d, 2*port+1); 	ctl  = pci_resource_start(dev, 2*port+1);	base = pci_resource_start(dev, 2*port);	if ((ctl && !base) || (base && !ctl)) {		printk(KERN_ERR "%s: inconsistent baseregs (BIOS) "			"for port %d, skipping\n", d->name, port);		return NULL;	}	if (!ctl)	{		/* Use default values */		ctl = port ? 0x374 : 0x3f4;		base = port ? 0x170 : 0x1f0;	}	if ((hwif = ide_match_hwif(base, d->bootable, d->name)) == NULL)		return NULL;	/* no room in ide_hwifs[] */	if (hwif->io_ports[IDE_DATA_OFFSET] != base) {fixup_address:		ide_init_hwif_ports(&hwif->hw, base, (ctl | 2), NULL);		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];	} else if (hwif->io_ports[IDE_CONTROL_OFFSET] != (ctl | 2)) {		goto fixup_address;	}	hwif->chipset = ide_pci;	hwif->pci_dev = dev;	hwif->cds = (struct ide_pci_device_s *) d;	hwif->channel = port;	if (!hwif->irq)		hwif->irq = irq;	if (mate) {		hwif->mate = mate;		mate->mate = hwif;	}	return hwif;}/** *	ide_hwif_setup_dma	-	configure DMA interface *	@dev: PCI device *	@d: IDE pci data *	@hwif: Hardware interface we are configuring * *	Set up the DMA base for the interface. Enable the master bits as *	neccessary and attempt to bring the device DMA into a ready to use *	state */ static void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif){	u16 pcicmd;	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);	if ((d->autodma == AUTODMA) ||	    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&	     (dev->class & 0x80))) {		unsigned long dma_base = ide_get_or_set_dma_base(hwif);		if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {			/* 			 * Set up BM-DMA capability			 * (PnP BIOS should have done this) 			 */			if (!((d->device == PCI_DEVICE_ID_CYRIX_5530_IDE && d->vendor == PCI_VENDOR_ID_CYRIX)			    ||(d->device == PCI_DEVICE_ID_NS_SCx200_IDE && d->vendor == PCI_VENDOR_ID_NS)))			{				/*				 * default DMA off if we had to				 * configure it here				 */				hwif->autodma = 0;			}			pci_set_master(dev);			if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {				printk(KERN_ERR "%s: %s error updating PCICMD\n",					hwif->name, d->name);				dma_base = 0;			}		}		if (dma_base) {			if (d->init_dma) {				d->init_dma(hwif, dma_base);			} else {				ide_setup_dma(hwif, dma_base, 8);			}		} else {			printk(KERN_INFO "%s: %s Bus-Master DMA disabled "				"(BIOS)\n", hwif->name, d->name);		}	}}/** *	ide_setup_pci_controller	-	set up IDE PCI *	@dev: PCI device *	@d: IDE PCI data *	@noisy: verbose flag *	@config: returned as 1 if we configured the hardware * *	Set up the PCI and controller side of the IDE interface. This brings *	up the PCI side of the device, checks that the device is enabled *	and enables it if need be */ static int ide_setup_pci_controller(struct pci_dev *dev, ide_pci_device_t *d, int noisy, int *config){	int ret = 0;	u32 class_rev;	u16 pcicmd;	if (!noautodma)		ret = 1;	if (noisy)		ide_setup_pci_noise(dev, d);	if (ide_pci_enable(dev, d))		return -EBUSY;			if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) {		printk(KERN_ERR "%s: error accessing PCI regs\n", d->name);		return -EIO;	}	if (!(pcicmd & PCI_COMMAND_IO)) {	/* is device disabled? */		if (ide_pci_configure(dev, d))			return -ENODEV;		/* default DMA off if we had to configure it here */		ret = 0;		*config = 1;		printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);	}	pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);	class_rev &= 0xff;	if (noisy)		printk(KERN_INFO "%s: chipset revision %d\n", d->name, class_rev);	return ret;}/* * ide_setup_pci_device() looks at the primary/secondary interfaces * on a PCI IDE device and, if they are enabled, prepares the IDE driver * for use with them.  This generic code works for most PCI chipsets. * * One thing that is not standardized is the location of the * primary/secondary interface "enable/disable" bits.  For chipsets that * we "know" about, this information is in the ide_pci_device_t struct; * for all other chipsets, we just assume both interfaces are enabled. */static ata_index_t do_ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d, u8 noisy){	u32 port, at_least_one_hwif_enabled = 0, autodma = 0;	unsigned int pciirq = 0;	int tried_config = 0;	int drive0_tune, drive1_tune;	ata_index_t index;	u8 tmp = 0;	ide_hwif_t *hwif, *mate = NULL;	static int secondpdc = 0;	index.all = 0xf0f0;	if((autodma = ide_setup_pci_controller(dev, d, noisy, &tried_config)) < 0)		return index;	/*	 * Can we trust the reported IRQ?	 */	pciirq = dev->irq;		if ((dev->class & ~(0xfa)) != ((PCI_CLASS_STORAGE_IDE << 8) | 5)) {		if (noisy)			printk(KERN_INFO "%s: not 100%% native mode: "				"will probe irqs later\n", d->name);		/*		 * This allows offboard ide-pci cards the enable a BIOS,		 * verify interrupt settings of split-mirror pci-config		 * space, place chipset into init-mode, and/or preserve		 * an interrupt if the card is not native ide support.		 */		pciirq = (d->init_chipset) ? d->init_chipset(dev, d->name) : 0;	} else if (tried_config) {		if (noisy)			printk(KERN_INFO "%s: will probe irqs later\n", d->name);		pciirq = 0;	} else if (!pciirq) {		if (noisy)			printk(KERN_WARNING "%s: bad irq (%d): will probe later\n",				d->name, pciirq);		pciirq = 0;	} else {		if (d->init_chipset)			d->init_chipset(dev, d->name);		if (noisy)#ifdef __sparc__			printk(KERN_INFO "%s: 100%% native mode on irq %s\n",			       d->name, __irq_itoa(pciirq));#else			printk(KERN_INFO "%s: 100%% native mode on irq %d\n",				d->name, pciirq);#endif	}		/*	 * Set up the IDE ports	 */	 	for (port = 0; port <= 1; ++port) {		ide_pci_enablebit_t *e = &(d->enablebits[port]);			/* 		 * If this is a Promise FakeRaid controller,		 * the 2nd controller will be marked as 		 * disabled while it is actually there and enabled		 * by the bios for raid purposes. 		 * Skip the normal "is it enabled" test for those.		 */		if (((d->vendor == PCI_VENDOR_ID_PROMISE) &&		     ((d->device == PCI_DEVICE_ID_PROMISE_20262) ||		      (d->device == PCI_DEVICE_ID_PROMISE_20265))) &&		    (secondpdc++==1) && (port==1))			goto controller_ok;					if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||		    (tmp & e->mask) != e->val))			continue;	/* port not enabled */controller_ok:		if (d->channels	<= port)			return index;			if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)			continue;		/* setup proper ancestral information */		// 2.5 only hwif->gendev.parent = &dev->dev;		if (hwif->channel) {			index.b.high = hwif->index;		} else {			index.b.low = hwif->index;		}				if (d->init_iops)			d->init_iops(hwif);		if (d->autodma == NODMA)			goto bypass_legacy_dma;		if (d->autodma == NOAUTODMA)			autodma = 0;		if (autodma)			hwif->autodma = 1;		ide_hwif_setup_dma(dev, d, hwif);bypass_legacy_dma:		drive0_tune = hwif->drives[0].autotune;		drive1_tune = hwif->drives[1].autotune;		if (d->init_hwif)			/* Call chipset-specific routine			 * for each enabled hwif			 */			d->init_hwif(hwif);		mate = hwif;		at_least_one_hwif_enabled = 1;	}	if (!at_least_one_hwif_enabled)		printk(KERN_INFO "%s: neither IDE port enabled (BIOS)\n", d->name);	return index;}void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d){	do_ide_setup_pci_device(dev, d, 1);}EXPORT_SYMBOL_GPL(ide_setup_pci_device);void ide_setup_pci_devices (struct pci_dev *dev, struct pci_dev *dev2, ide_pci_device_t *d){	do_ide_setup_pci_device(dev, d, 1);	do_ide_setup_pci_device(dev2, d, 0);}EXPORT_SYMBOL_GPL(ide_setup_pci_devices);/* *	Module interfaces */ static int pre_init = 1;		/* Before first ordered IDE scan */static LIST_HEAD(ide_pci_drivers);/* *	ide_register_pci_driver		-	attach IDE driver *	@driver: pci driver * *	Registers a driver with the IDE layer. The IDE layer arranges that *	boot time setup is done in the expected device order and then  *	hands the controllers off to the core PCI code to do the rest of *	the work. * *	The driver_data of the driver table must point to an ide_pci_device_t *	describing the interface. * *	Returns are the same as for pci_register_driver */int ide_pci_register_driver(struct pci_driver *driver){	if(!pre_init)		return pci_module_init(driver);	list_add_tail(&driver->node, &ide_pci_drivers);	return 0;}EXPORT_SYMBOL_GPL(ide_pci_register_driver);/** *	ide_unregister_pci_driver	-	unregister an IDE driver *	@driver: driver to remove * *	Unregister a currently installed IDE driver. Returns are the same *	as for pci_unregister_driver */ void ide_pci_unregister_driver(struct pci_driver *driver){	if(!pre_init)		pci_unregister_driver(driver);	else		list_del(&driver->node);}EXPORT_SYMBOL_GPL(ide_pci_unregister_driver);/** *	ide_scan_pcidev		-	find an IDE driver for a device *	@dev: PCI device to check * *	Look for an IDE driver to handle the device we are considering. *	This is only used during boot up to get the ordering correct. After *	boot up the pci layer takes over the job. */ static int __init ide_scan_pcidev(struct pci_dev *dev){	struct list_head *l;	struct pci_driver *d;		list_for_each(l, &ide_pci_drivers)	{		d = list_entry(l, struct pci_driver, node);		if(d->id_table)		{			const struct pci_device_id *id = pci_match_device(d->id_table, dev);			if(id != NULL)			{				if(d->probe(dev, id) >= 0)				{					dev->driver = d;					return 1;				}			}		}	}	return 0;}/** *	ide_scan_pcibus		-	perform the initial IDE driver scan *	@scan_direction: set for reverse order scanning * *	Perform the initial bus rather than driver ordered scan of the *	PCI drivers. After this all IDE pci handling becomes standard *	module ordering not traditionally ordered. */ 	void __init ide_scan_pcibus (int scan_direction){	struct pci_dev *dev;	struct pci_driver *d;	struct list_head *l, *n;	pre_init = 0;	if (!scan_direction) {		pci_for_each_dev(dev) {			ide_scan_pcidev(dev);		}	} else {		pci_for_each_dev_reverse(dev) {			ide_scan_pcidev(dev);		}	}		/*	 *	Hand the drivers over to the PCI layer now we	 *	are post init.	 */	list_for_each_safe(l, n, &ide_pci_drivers)	{		list_del(l);		d = list_entry(l, struct pci_driver, node);		pci_register_driver(d);	}}

⌨️ 快捷键说明

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