setup-pci.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 886 行 · 第 1/2 页

C
886
字号
		memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];	}	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 *	necessary and attempt to bring the device DMA into a ready to use *	state */ #ifndef CONFIG_BLK_DEV_IDEDMA_PCIstatic void ide_hwif_setup_dma(struct pci_dev *dev, ide_pci_device_t *d, ide_hwif_t *hwif){}#elsestatic 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->flags & IDEPCI_FLAG_FORCE_MASTER) == 0) {				/*				 * 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);		}	}}#endif /* CONFIG_BLK_DEV_IDEDMA_PCI*//** *	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_pci_setup_ports	-	configure ports/devices on PCI IDE *	@dev: PCI device *	@d: IDE pci device info *	@autodma: Should we enable DMA *	@pciirq: IRQ line *	@index: ata index to update * *	Scan the interfaces attached to this device and do any *	necessary per port setup. Attach the devices and ask the *	generic DMA layer to do its work for us. * *	Normally called automaticall from do_ide_pci_setup_device, *	but is also used directly as a helper function by some controllers *	where the chipset setup is not the default PCI IDE one. */ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int autodma, int pciirq, ata_index_t *index){	int port;	int at_least_one_hwif_enabled = 0;	ide_hwif_t *hwif, *mate = NULL;	static int secondpdc = 0;	u8 tmp;	index->all = 0xf0f0;	/*	 * 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->flags & IDEPCI_FLAG_FORCE_PDC) &&		    (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)			break;			if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)			continue;		/* setup proper ancestral information */		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;					if(d->init_setup_dma)			d->init_setup_dma(dev, d, hwif);		else			ide_hwif_setup_dma(dev, d, hwif);bypass_legacy_dma:		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);}EXPORT_SYMBOL_GPL(ide_pci_setup_ports);/* * 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){	int autodma = 0;	int pciirq = 0;	int tried_config = 0;	ata_index_t index = { .b = { .low = 0xff, .high = 0xff } };	if((autodma = ide_setup_pci_controller(dev, d, noisy, &tried_config)) < 0)		return index;	/*	 * Can we trust the reported IRQ?	 */	pciirq = dev->irq;	/* Is it an "IDE storage" device in non-PCI mode? */	if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && (dev->class & 5) != 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)		{			if(d->init_chipset(dev, d->name) < 0)				return index;		}		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	}		if(pciirq < 0)		/* Error not an IRQ */		return index;	ide_pci_setup_ports(dev, d, autodma, pciirq, &index);	return index;}void ide_setup_pci_device (struct pci_dev *dev, ide_pci_device_t *d){	ata_index_t index_list = do_ide_setup_pci_device(dev, d, 1);	if ((index_list.b.low & 0xf0) != 0xf0)		probe_hwif_init(&ide_hwifs[index_list.b.low]);	if ((index_list.b.high & 0xf0) != 0xf0)		probe_hwif_init(&ide_hwifs[index_list.b.high]);	create_proc_ide_interfaces();}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){	ata_index_t index_list  = do_ide_setup_pci_device(dev, d, 1);	ata_index_t index_list2 = do_ide_setup_pci_device(dev2, d, 0);	if ((index_list.b.low & 0xf0) != 0xf0)		probe_hwif_init(&ide_hwifs[index_list.b.low]);	if ((index_list.b.high & 0xf0) != 0xf0)		probe_hwif_init(&ide_hwifs[index_list.b.high]);	if ((index_list2.b.low & 0xf0) != 0xf0)		probe_hwif_init(&ide_hwifs[index_list2.b.low]);	if ((index_list2.b.high & 0xf0) != 0xf0)		probe_hwif_init(&ide_hwifs[index_list2.b.high]);	create_proc_ide_interfaces();}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 = NULL;	struct pci_driver *d;	struct list_head *l, *n;	pre_init = 0;	if (!scan_direction) {		while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {			ide_scan_pcidev(dev);		}	} else {		while ((dev = pci_find_device_reverse(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {			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 + =
减小字号Ctrl + -
显示快捷键?