setup-pci.c

来自「linux 内核源代码」· C语言 代码 · 共 804 行 · 第 1/2 页

C
804
字号
		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 port info *	@hwif: IDE interface * *	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 */static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif){#ifdef CONFIG_BLK_DEV_IDEDMA_PCI	u16 pcicmd;	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);	if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||	    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&	     (dev->class & 0x80))) {		unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);		if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {			/* 			 * Set up BM-DMA capability			 * (PnP BIOS should have done this) 			 */			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 port info *	@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, const struct ide_port_info *d, int noisy, int *config){	int ret;	u16 pcicmd;	if (noisy)		ide_setup_pci_noise(dev, d);	ret = ide_pci_enable(dev, d);	if (ret < 0)		goto out;	ret = pci_read_config_word(dev, PCI_COMMAND, &pcicmd);	if (ret < 0) {		printk(KERN_ERR "%s: error accessing PCI regs\n", d->name);		goto out;	}	if (!(pcicmd & PCI_COMMAND_IO)) {	/* is device disabled? */		ret = ide_pci_configure(dev, d);		if (ret < 0)			goto out;		*config = 1;		printk(KERN_INFO "%s: device enabled (Linux)\n", d->name);	}out:	return ret;}/** *	ide_pci_setup_ports	-	configure ports/devices on PCI IDE *	@dev: PCI device *	@d: IDE port info *	@pciirq: IRQ line *	@idx: ATA index table 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, const struct ide_port_info *d, int pciirq, u8 *idx){	int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;	ide_hwif_t *hwif, *mate = NULL;	u8 tmp;	/*	 * Set up the IDE ports	 */	for (port = 0; port < channels; ++port) {		const ide_pci_enablebit_t *e = &(d->enablebits[port]);		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||		    (tmp & e->mask) != e->val)) {			printk(KERN_INFO "%s: IDE port disabled\n", d->name);			continue;	/* port not enabled */		}		if ((hwif = ide_hwif_configure(dev, d, mate, port, pciirq)) == NULL)			continue;		/* setup proper ancestral information */		hwif->gendev.parent = &dev->dev;		*(idx + port) = hwif->index;				if (d->init_iops)			d->init_iops(hwif);		if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)			ide_hwif_setup_dma(dev, d, hwif);		if ((!hwif->irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||		    (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))			hwif->irq = port ? 15 : 14;		hwif->fixup = d->fixup;		hwif->host_flags = d->host_flags;		hwif->pio_mask = d->pio_mask;		if ((d->host_flags & IDE_HFLAG_SERIALIZE) && hwif->mate)			hwif->mate->serialized = hwif->serialized = 1;		if (d->host_flags & IDE_HFLAG_IO_32BIT) {			hwif->drives[0].io_32bit = 1;			hwif->drives[1].io_32bit = 1;		}		if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {			hwif->drives[0].unmask = 1;			hwif->drives[1].unmask = 1;		}		if (hwif->dma_base) {			hwif->swdma_mask = d->swdma_mask;			hwif->mwdma_mask = d->mwdma_mask;			hwif->ultra_mask = d->udma_mask;		}		hwif->drives[0].autotune = 1;		hwif->drives[1].autotune = 1;		if (d->host_flags & IDE_HFLAG_RQSIZE_256)			hwif->rqsize = 256;		if (d->init_hwif)			/* Call chipset-specific routine			 * for each enabled hwif			 */			d->init_hwif(hwif);		mate = hwif;	}}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 struct ide_port_info; * for all other chipsets, we just assume both interfaces are enabled. */static int do_ide_setup_pci_device(struct pci_dev *dev,				   const struct ide_port_info *d,				   u8 *idx, u8 noisy){	int tried_config = 0;	int pciirq, ret;	ret = ide_setup_pci_controller(dev, d, noisy, &tried_config);	if (ret < 0)		goto out;	/*	 * 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.		 */		ret = d->init_chipset ? d->init_chipset(dev, d->name) : 0;		if (ret < 0)			goto out;		pciirq = ret;	} 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) {			ret = d->init_chipset(dev, d->name);			if (ret < 0)				goto out;		}		if (noisy)			printk(KERN_INFO "%s: 100%% native mode on irq %d\n",				d->name, pciirq);	}	/* FIXME: silent failure can happen */	ide_pci_setup_ports(dev, d, pciirq, idx);out:	return ret;}int ide_setup_pci_device(struct pci_dev *dev, const struct ide_port_info *d){	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };	int ret;	ret = do_ide_setup_pci_device(dev, d, &idx[0], 1);	if (ret >= 0)		ide_device_add(idx);	return ret;}EXPORT_SYMBOL_GPL(ide_setup_pci_device);int ide_setup_pci_devices(struct pci_dev *dev1, struct pci_dev *dev2,			  const struct ide_port_info *d){	struct pci_dev *pdev[] = { dev1, dev2 };	int ret, i;	u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };	for (i = 0; i < 2; i++) {		ret = do_ide_setup_pci_device(pdev[i], d, &idx[i*2], !i);		/*		 * FIXME: Mom, mom, they stole me the helper function to undo		 * do_ide_setup_pci_device() on the first device!		 */		if (ret < 0)			goto out;	}	ide_device_add(idx);out:	return ret;}EXPORT_SYMBOL_GPL(ide_setup_pci_devices);#ifdef CONFIG_IDEPCI_PCIBUS_ORDER/* *	Module interfaces */static int pre_init = 1;		/* Before first ordered IDE scan */static LIST_HEAD(ide_pci_drivers);/* *	__ide_pci_register_driver	-	attach IDE driver *	@driver: pci driver *	@module: owner module of the 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. * *	Returns are the same as for pci_register_driver */int __ide_pci_register_driver(struct pci_driver *driver, struct module *module,			      const char *mod_name){	if (!pre_init)		return __pci_register_driver(driver, module, mod_name);	driver->driver.owner = module;	list_add_tail(&driver->node, &ide_pci_drivers);	return 0;}EXPORT_SYMBOL_GPL(__ide_pci_register_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_id(d->id_table, dev);			if (id != NULL && d->probe(dev, id) >= 0) {				dev->driver = d;				pci_dev_get(dev);				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_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)))			ide_scan_pcidev(dev);	else		while ((dev = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID,						     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);		if (__pci_register_driver(d, d->driver.owner,					  d->driver.mod_name))			printk(KERN_ERR "%s: failed to register %s driver\n",					__FUNCTION__, d->driver.mod_name);	}}#endif

⌨️ 快捷键说明

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