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 + -
显示快捷键?