📄 io_common.c
字号:
{ int cnode; struct pci_controller *controller; struct hubdev_info *hubdev_info; int nasid; void *provider_soft; struct sn_pcibus_provider *provider; struct sn_platform_data *sn_platform_data; controller = PCI_CONTROLLER(bus); /* * Per-provider fixup. Copies the bus soft structure from prom * to local area and links SN_PCIBUS_BUSSOFT(). */ if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) { printk(KERN_WARNING "sn_common_bus_fixup: Unsupported asic type, %d", prom_bussoft_ptr->bs_asic_type); return; } if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) return; /* no further fixup necessary */ provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; if (provider == NULL) panic("sn_common_bus_fixup: No provider registered for this asic type, %d", prom_bussoft_ptr->bs_asic_type); if (provider->bus_fixup) provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); else provider_soft = NULL; /* * Generic bus fixup goes here. Don't reference prom_bussoft_ptr * after this point. */ controller->platform_data = kzalloc(sizeof(struct sn_platform_data), GFP_KERNEL); if (controller->platform_data == NULL) BUG(); sn_platform_data = (struct sn_platform_data *) controller->platform_data; sn_platform_data->provider_soft = provider_soft; INIT_LIST_HEAD(&((struct sn_platform_data *) controller->platform_data)->pcidev_info); nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); cnode = nasid_to_cnodeid(nasid); hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); /* * If the node information we obtained during the fixup phase is * invalid then set controller->node to -1 (undetermined) */ if (controller->node >= num_online_nodes()) { struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u " "L_IO=%lx L_MEM=%lx BASE=%lx\n", b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); printk(KERN_WARNING "on node %d but only %d nodes online." "Association set to undetermined.\n", controller->node, num_online_nodes()); controller->node = -1; }}void sn_bus_store_sysdata(struct pci_dev *dev){ struct sysdata_el *element; element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); if (!element) { dev_dbg(&dev->dev, "%s: out of memory!\n", __FUNCTION__); return; } element->sysdata = SN_PCIDEV_INFO(dev); list_add(&element->entry, &sn_sysdata_list);}void sn_bus_free_sysdata(void){ struct sysdata_el *element; struct list_head *list, *safe; list_for_each_safe(list, safe, &sn_sysdata_list) { element = list_entry(list, struct sysdata_el, entry); list_del(&element->entry); list_del(&(((struct pcidev_info *) (element->sysdata))->pdi_list)); kfree(element->sysdata); kfree(element); } return;}/* * hubdev_init_node() - Creates the HUB data structure and link them to it's * own NODE specific data area. */void __init hubdev_init_node(nodepda_t * npda, cnodeid_t node){ struct hubdev_info *hubdev_info; int size; pg_data_t *pg; size = sizeof(struct hubdev_info); if (node >= num_online_nodes()) /* Headless/memless IO nodes */ pg = NODE_DATA(0); else pg = NODE_DATA(node); hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); npda->pdinfo = (void *)hubdev_info;}geoid_tcnodeid_get_geoid(cnodeid_t cnode){ struct hubdev_info *hubdev; hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); return hubdev->hdi_geoid;}void sn_generate_path(struct pci_bus *pci_bus, char *address){ nasid_t nasid; cnodeid_t cnode; geoid_t geoid; moduleid_t moduleid; u16 bricktype; nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); cnode = nasid_to_cnodeid(nasid); geoid = cnodeid_get_geoid(cnode); moduleid = geo_module(geoid); sprintf(address, "module_%c%c%c%c%.2d", '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)), '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)), '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)), MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid)); /* Tollhouse requires slot id to be displayed */ bricktype = MODULE_GET_BTYPE(moduleid); if ((bricktype == L1_BRICKTYPE_191010) || (bricktype == L1_BRICKTYPE_1932)) sprintf(address, "%s^%d", address, geo_slot(geoid));}void __devinitsn_pci_fixup_bus(struct pci_bus *bus){ if (SN_ACPI_BASE_SUPPORT()) sn_acpi_bus_fixup(bus); else sn_bus_fixup(bus);}/* * sn_io_early_init - Perform early IO (and some non-IO) initialization. * In particular, setup the sn_pci_provider[] array. * This needs to be done prior to any bus scanning * (acpi_scan_init()) in the ACPI case, as the SN * bus fixup code will reference the array. */static int __initsn_io_early_init(void){ int i; if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; /* we set the acpi revision to that of the DSDT table OEM rev. */ { struct acpi_table_header *header = NULL; acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); BUG_ON(header == NULL); sn_acpi_rev = header->oem_revision; } /* * prime sn_pci_provider[]. Individual provider init routines will * override their respective default entries. */ for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++) sn_pci_provider[i] = &sn_pci_default_provider; pcibr_init_provider(); tioca_init_provider(); tioce_init_provider(); /* * This is needed to avoid bounce limit checks in the blk layer */ ia64_max_iommu_merge_mask = ~PAGE_MASK; sn_irq_lh_init(); INIT_LIST_HEAD(&sn_sysdata_list); sn_init_cpei_timer();#ifdef CONFIG_PROC_FS register_sn_procfs();#endif { struct acpi_table_header *header; (void)acpi_get_table_by_index(ACPI_TABLE_INDEX_DSDT, &header); printk(KERN_INFO "ACPI DSDT OEM Rev 0x%x\n", header->oem_revision); } if (SN_ACPI_BASE_SUPPORT()) sn_io_acpi_init(); else sn_io_init(); return 0;}arch_initcall(sn_io_early_init);/* * sn_io_late_init() - Perform any final platform specific IO initialization. */int __initsn_io_late_init(void){ struct pci_bus *bus; struct pcibus_bussoft *bussoft; cnodeid_t cnode; nasid_t nasid; cnodeid_t near_cnode; if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; /* * Setup closest node in pci_controller->node for * PIC, TIOCP, TIOCE (TIOCA does it during bus fixup using * info from the PROM). */ bus = NULL; while ((bus = pci_find_next_bus(bus)) != NULL) { bussoft = SN_PCIBUS_BUSSOFT(bus); nasid = NASID_GET(bussoft->bs_base); cnode = nasid_to_cnodeid(nasid); if ((bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCP) || (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_TIOCE) || (bussoft->bs_asic_type == PCIIO_ASIC_TYPE_PIC)) { /* PCI Bridge: find nearest node with CPUs */ int e = sn_hwperf_get_nearest_node(cnode, NULL, &near_cnode); if (e < 0) { near_cnode = (cnodeid_t)-1; /* use any node */ printk(KERN_WARNING "sn_io_late_init: failed " "to find near node with CPUs for " "node %d, err=%d\n", cnode, e); } PCI_CONTROLLER(bus)->node = near_cnode; } } sn_ioif_inited = 1; /* SN I/O infrastructure now initialized */ return 0;}fs_initcall(sn_io_late_init);EXPORT_SYMBOL(sn_pci_unfixup_slot);EXPORT_SYMBOL(sn_bus_store_sysdata);EXPORT_SYMBOL(sn_bus_free_sysdata);EXPORT_SYMBOL(sn_generate_path);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -