Message ID | 1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com (mailing list archive) |
---|---|
State | New, archived |
Delegated to: | Bjorn Helgaas |
Headers | show |
Hi Pratyush and Jingoo, what is your opinion about this patch? It will be very appreciated if you could take a look at it. Thanks, Zhou On 2015/8/17 19:55, Zhou Wang wrote: > This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci, > move related operations to dw_pcie_host_init. > > In past, we use: > pci_common_init_dev > -> pcibios_init_hw > -> hw->scan (dw_pcie_scan_bus) > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0 > in each PCIe host driver which is based on pcie-designware. > > This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64 > according to the suggestion for Gabriele[1] > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU > with untranslated address" based on 1/6 in this series. we delete *_mod_base in > pcie-designware. This was discussed in [2] > > I have compiled the driver with multi_v7_defconfig. However, I don't have > ARM32 PCIe related board to do test. It will be appreciated if someone could > help to test it. > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > Tested-By: James Morse <james.morse@arm.com> > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html > --- > drivers/pci/host/pci-dra7xx.c | 15 +-- > drivers/pci/host/pci-exynos.c | 2 +- > drivers/pci/host/pci-imx6.c | 2 +- > drivers/pci/host/pci-keystone-dw.c | 2 +- > drivers/pci/host/pci-keystone.c | 2 +- > drivers/pci/host/pci-layerscape.c | 2 +- > drivers/pci/host/pcie-designware.c | 229 ++++++++++++------------------------- > drivers/pci/host/pcie-designware.h | 14 +-- > drivers/pci/host/pcie-spear13xx.c | 2 +- > 9 files changed, 95 insertions(+), 175 deletions(-) > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c > index 18ae7ff..1268c69 100644 > --- a/drivers/pci/host/pci-dra7xx.c > +++ b/drivers/pci/host/pci-dra7xx.c > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp) > { > dw_pcie_setup_rc(pp); > > - if (pp->io_mod_base) > - pp->io_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->io_base) > + pp->io_base &= CPU_TO_BUS_ADDR; > > - if (pp->mem_mod_base) > - pp->mem_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->mem_base) > + pp->mem_base &= CPU_TO_BUS_ADDR; > > - if (pp->cfg0_mod_base) { > - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; > - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->cfg0_base) { > + pp->cfg0_base &= CPU_TO_BUS_ADDR; > + pp->cfg1_base &= CPU_TO_BUS_ADDR; > } > > dra7xx_pcie_establish_link(pp); > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, > > pp = &dra7xx->pp; > pp->dev = dev; > + pp->root_bus_nr = 0; > pp->ops = &dra7xx_pcie_host_ops; > > pp->irq = platform_get_irq(pdev, 1); > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c > index f9f468d..9771bb0 100644 > --- a/drivers/pci/host/pci-exynos.c > +++ b/drivers/pci/host/pci-exynos.c > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, > } > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &exynos_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c > index 233a196..bec256c 100644 > --- a/drivers/pci/host/pci-imx6.c > +++ b/drivers/pci/host/pci-imx6.c > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, > } > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &imx6_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c > index f34892e..b1e4135 100644 > --- a/drivers/pci/host/pci-keystone-dw.c > +++ b/drivers/pci/host/pci-keystone-dw.c > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt) > void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) > { > struct pcie_port *pp = &ks_pcie->pp; > - u32 start = pp->mem.start, end = pp->mem.end; > + u32 start = pp->mem->start, end = pp->mem->end; > int i, tr_size; > > /* Disable BARs for inbound access */ > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c > index 734da58..8113832 100644 > --- a/drivers/pci/host/pci-keystone.c > +++ b/drivers/pci/host/pci-keystone.c > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie, > return ret; > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &keystone_pcie_host_ops; > ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); > if (ret) { > diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c > index b2328ea1..79ff08c 100644 > --- a/drivers/pci/host/pci-layerscape.c > +++ b/drivers/pci/host/pci-layerscape.c > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) > pp = &pcie->pp; > pp->dev = pcie->dev; > pp->dbi_base = pcie->dbi; > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &ls_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c > index c5d407c..e71a88e 100644 > --- a/drivers/pci/host/pcie-designware.c > +++ b/drivers/pci/host/pcie-designware.c > @@ -11,6 +11,7 @@ > * published by the Free Software Foundation. > */ > > +#include <linux/hardirq.h> > #include <linux/irq.h> > #include <linux/irqdomain.h> > #include <linux/kernel.h> > @@ -69,16 +70,7 @@ > #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) > #define PCIE_ATU_UPPER_TARGET 0x91C > > -static struct hw_pci dw_pci; > - > -static unsigned long global_io_offset; > - > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) > -{ > - BUG_ON(!sys->private_data); > - > - return sys->private_data; > -} > +static struct pci_ops dw_pcie_ops; > > int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val) > { > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) > static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) > { > int irq, pos0, i; > - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); > + struct pcie_port *pp = desc->dev->bus->sysdata; > > pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, > order_base_2(no_irqs)); > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, > { > int irq, pos; > struct msi_msg msg; > - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); > + struct pcie_port *pp = pdev->bus->sysdata; > > if (desc->msi_attrib.is_msix) > return -EINVAL; > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) > { > struct irq_data *data = irq_get_irq_data(irq); > struct msi_desc *msi = irq_data_get_msi(data); > - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); > + struct pcie_port *pp = msi->dev->bus->sysdata; > > clear_irq_range(pp, irq, 1, data->hwirq); > } > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp) > { > struct device_node *np = pp->dev->of_node; > struct platform_device *pdev = to_platform_device(pp->dev); > - struct of_pci_range range; > - struct of_pci_range_parser parser; > + struct pci_bus *bus; > struct resource *cfg_res; > - u32 val, ns; > - const __be32 *addrp; > - int i, index, ret; > - > - ns = of_n_size_cells(np); > + LIST_HEAD(res); > + u32 val; > + int i, ret; > + struct resource_entry *win; > > cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); > if (cfg_res) { > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp) > pp->cfg1_size = resource_size(cfg_res)/2; > pp->cfg0_base = cfg_res->start; > pp->cfg1_base = cfg_res->start + pp->cfg0_size; > - > - /* Find the untranslated configuration space address */ > - index = of_property_match_string(np, "reg-names", "config"); > - addrp = of_get_address(np, index, NULL, NULL); > - pp->cfg0_mod_base = of_read_number(addrp, ns); > - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; > } else { > dev_err(pp->dev, "missing *config* reg space\n"); > } > > - if (of_pci_range_parser_init(&parser, np)) { > - dev_err(pp->dev, "missing ranges property\n"); > - return -EINVAL; > - } > + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base); > + if (ret) > + return ret; > > /* Get the I/O and memory ranges from DT */ > - for_each_of_pci_range(&parser, &range) { > - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; > - > - if (restype == IORESOURCE_IO) { > - of_pci_range_to_resource(&range, np, &pp->io); > - pp->io.name = "I/O"; > - pp->io.start = max_t(resource_size_t, > - PCIBIOS_MIN_IO, > - range.pci_addr + global_io_offset); > - pp->io.end = min_t(resource_size_t, > - IO_SPACE_LIMIT, > - range.pci_addr + range.size > - + global_io_offset - 1); > - pp->io_size = resource_size(&pp->io); > - pp->io_bus_addr = range.pci_addr; > - pp->io_base = range.cpu_addr; > - > - /* Find the untranslated IO space address */ > - pp->io_mod_base = range.cpu_addr; > - } > - if (restype == IORESOURCE_MEM) { > - of_pci_range_to_resource(&range, np, &pp->mem); > - pp->mem.name = "MEM"; > - pp->mem_size = resource_size(&pp->mem); > - pp->mem_bus_addr = range.pci_addr; > - > - /* Find the untranslated MEM space address */ > - pp->mem_mod_base = range.cpu_addr; > - } > - if (restype == 0) { > - of_pci_range_to_resource(&range, np, &pp->cfg); > - pp->cfg0_size = resource_size(&pp->cfg)/2; > - pp->cfg1_size = resource_size(&pp->cfg)/2; > - pp->cfg0_base = pp->cfg.start; > - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; > - > - /* Find the untranslated configuration space address */ > - pp->cfg0_mod_base = range.cpu_addr; > - pp->cfg1_mod_base = pp->cfg0_mod_base + > - pp->cfg0_size; > + resource_list_for_each_entry(win, &res) { > + switch (resource_type(win->res)) { > + case IORESOURCE_IO: > + pp->io = win->res; > + pp->io->name = "I/O"; > + pp->io_size = resource_size(pp->io); > + pp->io_bus_addr = pp->io->start - win->offset; > + ret = pci_remap_iospace(pp->io, pp->io_base); > + if (ret) { > + dev_warn(pp->dev, "error %d: failed to map resource %pR\n", > + ret, pp->io); > + continue; > + } > + break; > + case IORESOURCE_MEM: > + pp->mem = win->res; > + pp->mem->name = "MEM"; > + pp->mem_size = resource_size(pp->mem); > + pp->mem_bus_addr = pp->mem->start - win->offset; > + break; > + case 0: > + pp->cfg = win->res; > + pp->cfg0_size = resource_size(pp->cfg)/2; > + pp->cfg1_size = resource_size(pp->cfg)/2; > + pp->cfg0_base = pp->cfg->start; > + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; > + break; > + case IORESOURCE_BUS: > + pp->busn = win->res; > + break; > + default: > + continue; > } > } > > - ret = of_pci_parse_bus_range(np, &pp->busn); > - if (ret < 0) { > - pp->busn.name = np->name; > - pp->busn.start = 0; > - pp->busn.end = 0xff; > - pp->busn.flags = IORESOURCE_BUS; > - dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", > - ret, &pp->busn); > - } > - > if (!pp->dbi_base) { > - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, > - resource_size(&pp->cfg)); > + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, > + resource_size(pp->cfg)); > if (!pp->dbi_base) { > dev_err(pp->dev, "error with ioremap\n"); > return -ENOMEM; > } > } > > - pp->mem_base = pp->mem.start; > + pp->mem_base = pp->mem->start; > > if (!pp->va_cfg0_base) { > pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp) > > if (!pp->ops->rd_other_conf) > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, > - PCIE_ATU_TYPE_MEM, pp->mem_mod_base, > + PCIE_ATU_TYPE_MEM, pp->mem_base, > pp->mem_bus_addr, pp->mem_size); > > dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp) > val |= PORT_LOGIC_SPEED_CHANGE; > dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); > > -#ifdef CONFIG_PCI_MSI > + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, > + pp, &res); > + if (!bus) > + return -ENOMEM; > + > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); > +#else > dw_pcie_msi_chip.dev = pp->dev; > - dw_pci.msi_ctrl = &dw_pcie_msi_chip; > + bus->msi = &dw_pcie_msi_chip; > #endif > > - dw_pci.nr_controllers = 1; > - dw_pci.private_data = (void **)&pp; > + pci_scan_child_bus(bus); > + if (pp->ops->scan_bus) > + pp->ops->scan_bus(pp); > + > +#ifdef CONFIG_ARM > + /* support old dtbs that incorrectly describe IRQs */ > + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); > +#endif > > - pci_common_init_dev(pp->dev, &dw_pci); > + pci_assign_unassigned_bus_resources(bus); > + pci_bus_add_devices(bus); > > return 0; > } > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, > > if (bus->parent->number == pp->root_bus_nr) { > type = PCIE_ATU_TYPE_CFG0; > - cpu_addr = pp->cfg0_mod_base; > + cpu_addr = pp->cfg0_base; > cfg_size = pp->cfg0_size; > va_cfg_base = pp->va_cfg0_base; > } else { > type = PCIE_ATU_TYPE_CFG1; > - cpu_addr = pp->cfg1_mod_base; > + cpu_addr = pp->cfg1_base; > cfg_size = pp->cfg1_size; > va_cfg_base = pp->va_cfg1_base; > } > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, > busdev, cfg_size); > ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val); > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > + PCIE_ATU_TYPE_IO, pp->io_base, > pp->io_bus_addr, pp->io_size); > > return ret; > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, > > if (bus->parent->number == pp->root_bus_nr) { > type = PCIE_ATU_TYPE_CFG0; > - cpu_addr = pp->cfg0_mod_base; > + cpu_addr = pp->cfg0_base; > cfg_size = pp->cfg0_size; > va_cfg_base = pp->va_cfg0_base; > } else { > type = PCIE_ATU_TYPE_CFG1; > - cpu_addr = pp->cfg1_mod_base; > + cpu_addr = pp->cfg1_base; > cfg_size = pp->cfg1_size; > va_cfg_base = pp->va_cfg1_base; > } > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, > busdev, cfg_size); > ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val); > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > + PCIE_ATU_TYPE_IO, pp->io_base, > pp->io_bus_addr, pp->io_size); > > return ret; > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp, > static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > int size, u32 *val) > { > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > + struct pcie_port *pp = bus->sysdata; > int ret; > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, > int where, int size, u32 val) > { > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > + struct pcie_port *pp = bus->sysdata; > int ret; > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = { > .write = dw_pcie_wr_conf, > }; > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) > -{ > - struct pcie_port *pp; > - > - pp = sys_to_pcie(sys); > - > - if (global_io_offset < SZ_1M && pp->io_size > 0) { > - sys->io_offset = global_io_offset - pp->io_bus_addr; > - pci_ioremap_io(global_io_offset, pp->io_base); > - global_io_offset += SZ_64K; > - pci_add_resource_offset(&sys->resources, &pp->io, > - sys->io_offset); > - } > - > - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; > - pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); > - pci_add_resource(&sys->resources, &pp->busn); > - > - return 1; > -} > - > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) > -{ > - struct pci_bus *bus; > - struct pcie_port *pp = sys_to_pcie(sys); > - > - pp->root_bus_nr = sys->busnr; > - bus = pci_scan_root_bus(pp->dev, sys->busnr, > - &dw_pcie_ops, sys, &sys->resources); > - if (!bus) > - return NULL; > - > - if (bus && pp->ops->scan_bus) > - pp->ops->scan_bus(pp); > - > - return bus; > -} > - > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) > -{ > - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); > - int irq; > - > - irq = of_irq_parse_and_map_pci(dev, slot, pin); > - if (!irq) > - irq = pp->irq; > - > - return irq; > -} > - > -static struct hw_pci dw_pci = { > - .setup = dw_pcie_setup, > - .scan = dw_pcie_scan_bus, > - .map_irq = dw_pcie_map_irq, > -}; > - > void dw_pcie_setup_rc(struct pcie_port *pp) > { > u32 val; > diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h > index d0bbd27..264c969 100644 > --- a/drivers/pci/host/pcie-designware.h > +++ b/drivers/pci/host/pcie-designware.h > @@ -27,25 +27,21 @@ struct pcie_port { > u8 root_bus_nr; > void __iomem *dbi_base; > u64 cfg0_base; > - u64 cfg0_mod_base; > void __iomem *va_cfg0_base; > u32 cfg0_size; > u64 cfg1_base; > - u64 cfg1_mod_base; > void __iomem *va_cfg1_base; > u32 cfg1_size; > - u64 io_base; > - u64 io_mod_base; > + resource_size_t io_base; > phys_addr_t io_bus_addr; > u32 io_size; > u64 mem_base; > - u64 mem_mod_base; > phys_addr_t mem_bus_addr; > u32 mem_size; > - struct resource cfg; > - struct resource io; > - struct resource mem; > - struct resource busn; > + struct resource *cfg; > + struct resource *io; > + struct resource *mem; > + struct resource *busn; > int irq; > u32 lanes; > struct pcie_host_ops *ops; > diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c > index c49fbdc..03eb204 100644 > --- a/drivers/pci/host/pcie-spear13xx.c > +++ b/drivers/pci/host/pcie-spear13xx.c > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp, > return ret; > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &spear13xx_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang: > This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci, > move related operations to dw_pcie_host_init. > > In past, we use: > pci_common_init_dev > -> pcibios_init_hw > -> hw->scan (dw_pcie_scan_bus) > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0 > in each PCIe host driver which is based on pcie-designware. > This is incorrect at least if there are 2 instances of DW PCIe host in the same SoC without using PCI domains. In that the case the bus range determines the range of valid bus numbers per instance and the first number is the root bus. Please look at the "bus-range" DT property in the DW PCIe bindings. Also we should finally remove this root-bus setup from the glue drivers altogether. It's something that entirely belongs into the DW core code. Regards, Lucas > This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64 > according to the suggestion for Gabriele[1] > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU > with untranslated address" based on 1/6 in this series. we delete *_mod_base in > pcie-designware. This was discussed in [2] > > I have compiled the driver with multi_v7_defconfig. However, I don't have > ARM32 PCIe related board to do test. It will be appreciated if someone could > help to test it. > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > Tested-By: James Morse <james.morse@arm.com> > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html > --- > drivers/pci/host/pci-dra7xx.c | 15 +-- > drivers/pci/host/pci-exynos.c | 2 +- > drivers/pci/host/pci-imx6.c | 2 +- > drivers/pci/host/pci-keystone-dw.c | 2 +- > drivers/pci/host/pci-keystone.c | 2 +- > drivers/pci/host/pci-layerscape.c | 2 +- > drivers/pci/host/pcie-designware.c | 229 ++++++++++++------------------------- > drivers/pci/host/pcie-designware.h | 14 +-- > drivers/pci/host/pcie-spear13xx.c | 2 +- > 9 files changed, 95 insertions(+), 175 deletions(-) > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c > index 18ae7ff..1268c69 100644 > --- a/drivers/pci/host/pci-dra7xx.c > +++ b/drivers/pci/host/pci-dra7xx.c > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp) > { > dw_pcie_setup_rc(pp); > > - if (pp->io_mod_base) > - pp->io_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->io_base) > + pp->io_base &= CPU_TO_BUS_ADDR; > > - if (pp->mem_mod_base) > - pp->mem_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->mem_base) > + pp->mem_base &= CPU_TO_BUS_ADDR; > > - if (pp->cfg0_mod_base) { > - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; > - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->cfg0_base) { > + pp->cfg0_base &= CPU_TO_BUS_ADDR; > + pp->cfg1_base &= CPU_TO_BUS_ADDR; > } > > dra7xx_pcie_establish_link(pp); > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, > > pp = &dra7xx->pp; > pp->dev = dev; > + pp->root_bus_nr = 0; > pp->ops = &dra7xx_pcie_host_ops; > > pp->irq = platform_get_irq(pdev, 1); > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c > index f9f468d..9771bb0 100644 > --- a/drivers/pci/host/pci-exynos.c > +++ b/drivers/pci/host/pci-exynos.c > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, > } > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &exynos_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c > index 233a196..bec256c 100644 > --- a/drivers/pci/host/pci-imx6.c > +++ b/drivers/pci/host/pci-imx6.c > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, > } > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &imx6_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c > index f34892e..b1e4135 100644 > --- a/drivers/pci/host/pci-keystone-dw.c > +++ b/drivers/pci/host/pci-keystone-dw.c > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt) > void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) > { > struct pcie_port *pp = &ks_pcie->pp; > - u32 start = pp->mem.start, end = pp->mem.end; > + u32 start = pp->mem->start, end = pp->mem->end; > int i, tr_size; > > /* Disable BARs for inbound access */ > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c > index 734da58..8113832 100644 > --- a/drivers/pci/host/pci-keystone.c > +++ b/drivers/pci/host/pci-keystone.c > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie, > return ret; > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &keystone_pcie_host_ops; > ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); > if (ret) { > diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c > index b2328ea1..79ff08c 100644 > --- a/drivers/pci/host/pci-layerscape.c > +++ b/drivers/pci/host/pci-layerscape.c > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) > pp = &pcie->pp; > pp->dev = pcie->dev; > pp->dbi_base = pcie->dbi; > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &ls_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c > index c5d407c..e71a88e 100644 > --- a/drivers/pci/host/pcie-designware.c > +++ b/drivers/pci/host/pcie-designware.c > @@ -11,6 +11,7 @@ > * published by the Free Software Foundation. > */ > > +#include <linux/hardirq.h> > #include <linux/irq.h> > #include <linux/irqdomain.h> > #include <linux/kernel.h> > @@ -69,16 +70,7 @@ > #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) > #define PCIE_ATU_UPPER_TARGET 0x91C > > -static struct hw_pci dw_pci; > - > -static unsigned long global_io_offset; > - > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) > -{ > - BUG_ON(!sys->private_data); > - > - return sys->private_data; > -} > +static struct pci_ops dw_pcie_ops; > > int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val) > { > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) > static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) > { > int irq, pos0, i; > - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); > + struct pcie_port *pp = desc->dev->bus->sysdata; > > pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, > order_base_2(no_irqs)); > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, > { > int irq, pos; > struct msi_msg msg; > - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); > + struct pcie_port *pp = pdev->bus->sysdata; > > if (desc->msi_attrib.is_msix) > return -EINVAL; > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) > { > struct irq_data *data = irq_get_irq_data(irq); > struct msi_desc *msi = irq_data_get_msi(data); > - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); > + struct pcie_port *pp = msi->dev->bus->sysdata; > > clear_irq_range(pp, irq, 1, data->hwirq); > } > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp) > { > struct device_node *np = pp->dev->of_node; > struct platform_device *pdev = to_platform_device(pp->dev); > - struct of_pci_range range; > - struct of_pci_range_parser parser; > + struct pci_bus *bus; > struct resource *cfg_res; > - u32 val, ns; > - const __be32 *addrp; > - int i, index, ret; > - > - ns = of_n_size_cells(np); > + LIST_HEAD(res); > + u32 val; > + int i, ret; > + struct resource_entry *win; > > cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); > if (cfg_res) { > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp) > pp->cfg1_size = resource_size(cfg_res)/2; > pp->cfg0_base = cfg_res->start; > pp->cfg1_base = cfg_res->start + pp->cfg0_size; > - > - /* Find the untranslated configuration space address */ > - index = of_property_match_string(np, "reg-names", "config"); > - addrp = of_get_address(np, index, NULL, NULL); > - pp->cfg0_mod_base = of_read_number(addrp, ns); > - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; > } else { > dev_err(pp->dev, "missing *config* reg space\n"); > } > > - if (of_pci_range_parser_init(&parser, np)) { > - dev_err(pp->dev, "missing ranges property\n"); > - return -EINVAL; > - } > + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base); > + if (ret) > + return ret; > > /* Get the I/O and memory ranges from DT */ > - for_each_of_pci_range(&parser, &range) { > - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; > - > - if (restype == IORESOURCE_IO) { > - of_pci_range_to_resource(&range, np, &pp->io); > - pp->io.name = "I/O"; > - pp->io.start = max_t(resource_size_t, > - PCIBIOS_MIN_IO, > - range.pci_addr + global_io_offset); > - pp->io.end = min_t(resource_size_t, > - IO_SPACE_LIMIT, > - range.pci_addr + range.size > - + global_io_offset - 1); > - pp->io_size = resource_size(&pp->io); > - pp->io_bus_addr = range.pci_addr; > - pp->io_base = range.cpu_addr; > - > - /* Find the untranslated IO space address */ > - pp->io_mod_base = range.cpu_addr; > - } > - if (restype == IORESOURCE_MEM) { > - of_pci_range_to_resource(&range, np, &pp->mem); > - pp->mem.name = "MEM"; > - pp->mem_size = resource_size(&pp->mem); > - pp->mem_bus_addr = range.pci_addr; > - > - /* Find the untranslated MEM space address */ > - pp->mem_mod_base = range.cpu_addr; > - } > - if (restype == 0) { > - of_pci_range_to_resource(&range, np, &pp->cfg); > - pp->cfg0_size = resource_size(&pp->cfg)/2; > - pp->cfg1_size = resource_size(&pp->cfg)/2; > - pp->cfg0_base = pp->cfg.start; > - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; > - > - /* Find the untranslated configuration space address */ > - pp->cfg0_mod_base = range.cpu_addr; > - pp->cfg1_mod_base = pp->cfg0_mod_base + > - pp->cfg0_size; > + resource_list_for_each_entry(win, &res) { > + switch (resource_type(win->res)) { > + case IORESOURCE_IO: > + pp->io = win->res; > + pp->io->name = "I/O"; > + pp->io_size = resource_size(pp->io); > + pp->io_bus_addr = pp->io->start - win->offset; > + ret = pci_remap_iospace(pp->io, pp->io_base); > + if (ret) { > + dev_warn(pp->dev, "error %d: failed to map resource %pR\n", > + ret, pp->io); > + continue; > + } > + break; > + case IORESOURCE_MEM: > + pp->mem = win->res; > + pp->mem->name = "MEM"; > + pp->mem_size = resource_size(pp->mem); > + pp->mem_bus_addr = pp->mem->start - win->offset; > + break; > + case 0: > + pp->cfg = win->res; > + pp->cfg0_size = resource_size(pp->cfg)/2; > + pp->cfg1_size = resource_size(pp->cfg)/2; > + pp->cfg0_base = pp->cfg->start; > + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; > + break; > + case IORESOURCE_BUS: > + pp->busn = win->res; > + break; > + default: > + continue; > } > } > > - ret = of_pci_parse_bus_range(np, &pp->busn); > - if (ret < 0) { > - pp->busn.name = np->name; > - pp->busn.start = 0; > - pp->busn.end = 0xff; > - pp->busn.flags = IORESOURCE_BUS; > - dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", > - ret, &pp->busn); > - } > - > if (!pp->dbi_base) { > - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, > - resource_size(&pp->cfg)); > + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, > + resource_size(pp->cfg)); > if (!pp->dbi_base) { > dev_err(pp->dev, "error with ioremap\n"); > return -ENOMEM; > } > } > > - pp->mem_base = pp->mem.start; > + pp->mem_base = pp->mem->start; > > if (!pp->va_cfg0_base) { > pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp) > > if (!pp->ops->rd_other_conf) > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, > - PCIE_ATU_TYPE_MEM, pp->mem_mod_base, > + PCIE_ATU_TYPE_MEM, pp->mem_base, > pp->mem_bus_addr, pp->mem_size); > > dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp) > val |= PORT_LOGIC_SPEED_CHANGE; > dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); > > -#ifdef CONFIG_PCI_MSI > + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, > + pp, &res); > + if (!bus) > + return -ENOMEM; > + > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); > +#else > dw_pcie_msi_chip.dev = pp->dev; > - dw_pci.msi_ctrl = &dw_pcie_msi_chip; > + bus->msi = &dw_pcie_msi_chip; > #endif > > - dw_pci.nr_controllers = 1; > - dw_pci.private_data = (void **)&pp; > + pci_scan_child_bus(bus); > + if (pp->ops->scan_bus) > + pp->ops->scan_bus(pp); > + > +#ifdef CONFIG_ARM > + /* support old dtbs that incorrectly describe IRQs */ > + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); > +#endif > > - pci_common_init_dev(pp->dev, &dw_pci); > + pci_assign_unassigned_bus_resources(bus); > + pci_bus_add_devices(bus); > > return 0; > } > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, > > if (bus->parent->number == pp->root_bus_nr) { > type = PCIE_ATU_TYPE_CFG0; > - cpu_addr = pp->cfg0_mod_base; > + cpu_addr = pp->cfg0_base; > cfg_size = pp->cfg0_size; > va_cfg_base = pp->va_cfg0_base; > } else { > type = PCIE_ATU_TYPE_CFG1; > - cpu_addr = pp->cfg1_mod_base; > + cpu_addr = pp->cfg1_base; > cfg_size = pp->cfg1_size; > va_cfg_base = pp->va_cfg1_base; > } > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, > busdev, cfg_size); > ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val); > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > + PCIE_ATU_TYPE_IO, pp->io_base, > pp->io_bus_addr, pp->io_size); > > return ret; > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, > > if (bus->parent->number == pp->root_bus_nr) { > type = PCIE_ATU_TYPE_CFG0; > - cpu_addr = pp->cfg0_mod_base; > + cpu_addr = pp->cfg0_base; > cfg_size = pp->cfg0_size; > va_cfg_base = pp->va_cfg0_base; > } else { > type = PCIE_ATU_TYPE_CFG1; > - cpu_addr = pp->cfg1_mod_base; > + cpu_addr = pp->cfg1_base; > cfg_size = pp->cfg1_size; > va_cfg_base = pp->va_cfg1_base; > } > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, > busdev, cfg_size); > ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val); > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > + PCIE_ATU_TYPE_IO, pp->io_base, > pp->io_bus_addr, pp->io_size); > > return ret; > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp, > static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > int size, u32 *val) > { > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > + struct pcie_port *pp = bus->sysdata; > int ret; > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, > int where, int size, u32 val) > { > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > + struct pcie_port *pp = bus->sysdata; > int ret; > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = { > .write = dw_pcie_wr_conf, > }; > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) > -{ > - struct pcie_port *pp; > - > - pp = sys_to_pcie(sys); > - > - if (global_io_offset < SZ_1M && pp->io_size > 0) { > - sys->io_offset = global_io_offset - pp->io_bus_addr; > - pci_ioremap_io(global_io_offset, pp->io_base); > - global_io_offset += SZ_64K; > - pci_add_resource_offset(&sys->resources, &pp->io, > - sys->io_offset); > - } > - > - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; > - pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); > - pci_add_resource(&sys->resources, &pp->busn); > - > - return 1; > -} > - > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) > -{ > - struct pci_bus *bus; > - struct pcie_port *pp = sys_to_pcie(sys); > - > - pp->root_bus_nr = sys->busnr; > - bus = pci_scan_root_bus(pp->dev, sys->busnr, > - &dw_pcie_ops, sys, &sys->resources); > - if (!bus) > - return NULL; > - > - if (bus && pp->ops->scan_bus) > - pp->ops->scan_bus(pp); > - > - return bus; > -} > - > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) > -{ > - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); > - int irq; > - > - irq = of_irq_parse_and_map_pci(dev, slot, pin); > - if (!irq) > - irq = pp->irq; > - > - return irq; > -} > - > -static struct hw_pci dw_pci = { > - .setup = dw_pcie_setup, > - .scan = dw_pcie_scan_bus, > - .map_irq = dw_pcie_map_irq, > -}; > - > void dw_pcie_setup_rc(struct pcie_port *pp) > { > u32 val; > diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h > index d0bbd27..264c969 100644 > --- a/drivers/pci/host/pcie-designware.h > +++ b/drivers/pci/host/pcie-designware.h > @@ -27,25 +27,21 @@ struct pcie_port { > u8 root_bus_nr; > void __iomem *dbi_base; > u64 cfg0_base; > - u64 cfg0_mod_base; > void __iomem *va_cfg0_base; > u32 cfg0_size; > u64 cfg1_base; > - u64 cfg1_mod_base; > void __iomem *va_cfg1_base; > u32 cfg1_size; > - u64 io_base; > - u64 io_mod_base; > + resource_size_t io_base; > phys_addr_t io_bus_addr; > u32 io_size; > u64 mem_base; > - u64 mem_mod_base; > phys_addr_t mem_bus_addr; > u32 mem_size; > - struct resource cfg; > - struct resource io; > - struct resource mem; > - struct resource busn; > + struct resource *cfg; > + struct resource *io; > + struct resource *mem; > + struct resource *busn; > int irq; > u32 lanes; > struct pcie_host_ops *ops; > diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c > index c49fbdc..03eb204 100644 > --- a/drivers/pci/host/pcie-spear13xx.c > +++ b/drivers/pci/host/pcie-spear13xx.c > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp, > return ret; > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = 0; > pp->ops = &spear13xx_pcie_host_ops; > > ret = dw_pcie_host_init(pp);
SGkgTHVjYXMNCg0KSSBoYXZlIHJld3JpdHRlbiB0aGUgcGF0Y2ggdG8gdGFrZSBpbnRvIGFjY291 bnQgbXVsdGlwbGUgY29udHJvbGxlcnMuDQoNCkFzIHlvdSBjYW4gc2VlIG5vdyB0aGVyZSBpcyBh IHN0YXRpYyB2YXIgaW4gZHdfcGNpZV9ob3N0X2luaXQoKSB0aGF0IHRyYWNrcw0KdGhlIGJ1cyBu dW1iZXJzIHVzZWQuDQpEcml2ZXJzIHRoYXQgZG8gbm90IHNwZWNpZnkgdGhlIGJ1cyByYW5nZSBp biB0aGUgRFRCIHNldCBwcC0+cm9vdF9idXNfbnIgPSBEV19ST09UX05SX1VOREVGSU5FRC4NCkRl c2lnbndhcmUgd2lsbCBjaGVjayBpZiB0aGUgZmxhZyBpcyBzZXQgYW5kIHdpbGwgdXNlIHRoZSBh dXRvbWF0aWMgYnVzIHJhbmdlDQphc3NpZ25tZW50Lg0KSW5zdGVhZCBpZiB0aGUgZHJpdmVyIGFz c2lnbnMgcHAtPnJvb3RfYnVzX25yIGFjY29yZGluZyB0byB0aGUgZHRiLCBkZXNpZ253d2FyZQ0K d2lsbCB1c2UgdGhlIHZhbHVlIHBhc3NlZCBpbiBieSB0aGUgZHJpdmVyLg0KQmVsb3cgdGhlIHJl bGV2YW50IHNlY3Rpb246DQoNCg0KKwlzdGF0aWMgaW50IHJvb3RfYnVzX25yID0gMDsNCi4uLg0K KwltdXRleF9sb2NrKCZyb290X2J1c19ucl9tdXgpOw0KKw0KKwlpZiAocHAtPnJvb3RfYnVzX25y ICE9IERXX1JPT1RfTlJfVU5ERUZJTkVEKQ0KKwkJcm9vdF9idXNfbnIgPSBwcC0+cm9vdF9idXNf bnI7DQorDQorCWJ1cyA9IHBjaV9jcmVhdGVfcm9vdF9idXMocHAtPmRldiwgcm9vdF9idXNfbnIs ICZkd19wY2llX29wcywNCisJCQkgICAgICBwcCwgJnJlcyk7DQorCWlmICghYnVzKSB7DQorCQlt dXRleF91bmxvY2soJnJvb3RfYnVzX25yX211eCk7DQorCQlyZXR1cm4gLUVOT01FTTsNCisJfQ0K Kw0KKwlyb290X2J1c19uciArPSBidXMtPmJ1c25fcmVzLmVuZCArIDE7DQorCW11dGV4X3VubG9j aygmcm9vdF9idXNfbnJfbXV4KTsNCg0KUGxlYXNlIGxldCBtZSBrbm93IHdoYXQgeW91IHRoaW5r Li4uDQoNCk1hbnkgVGhhbmtzDQoNCkdhYg0KLS0tLS0tLS0tLQ0KDQpGcm9tOiBnYWJyaWVsZSBw YW9sb25pIDxnYWJyaWVsZS5wYW9sb25pQGh1YXdlaS5jb20+DQoNClRoaXMgcGF0Y2ggdHJpZXMg dG8gdW5pZnkgQVJNMzIgYW5kIEFSTTY0IFBDSWUgaW4gZGVzaWdud2FyZSBkcml2ZXIuIERlbGV0 ZQ0KZnVuY3Rpb24gZHdfcGNpZV9zZXR1cCwgZHdfcGNpZV9zY2FuX2J1cywgZHdfcGNpZV9tYXBf aXJxIGFuZCBzdHJ1Y3QgaHdfcGNpLA0KbW92ZSByZWxhdGVkIG9wZXJhdGlvbnMgdG8gZHdfcGNp ZV9ob3N0X2luaXQuDQpBbHNvIHNldCBwcC0+cm9vdF9idXNfbnIgPSBEV19ST09UX05SX1VOREVG SU5FRCBpbiBhbGwgdGhlIGRyaXZlcnMgdGhhdA0KYXJlIGJhc2VkIG9uIGRlc2lnbndhcmUgdG8g ZmxhZyB0aGF0IHRoZSBkcml2ZXJzIGRvIG5vdCByZWFkIHRoZSBidXMNCnJhbmdlcyBmcm9tIERU Lg0KVGhpcyBwYXRjaCBhbHNvIGFkZHMgaGFuZGxpbmcgb2YgbXVsdGlwbGUgUENJIGRvbWFpbnMg aW4gZGVzaWdud2FyZS4NCmlmIHRoZSBQQ0kgaG9zdCBicmlkZ2UgZHJpdmVyIGRvZXMgbm90IHNw ZWNpZnkgYSByb290IGJ1cyBudW1iZXIsIGluIGNhc2UNCm9mIG11bHRpcGxlIGRvbWFpbnMsIGRl c2lnbndhcmUgd2lsbCBhdXRvbWF0aWxsYXkgc2V0IHRoZSBuZXh0IGRvbWFpbiByb290DQpidXMg bnVtYmVyIHRvIHRoZSBsYXN0IGJ1cyBudW1iZXIgdXNlZCBpbiB0aGUgbGFzdCBkb21haW4gKyAx Lg0KDQpUaGlzIHBhdGNoIGFsc28gdHJ5IHRvIHVzZSBvZl9wY2lfZ2V0X2hvc3RfYnJpZGdlX3Jl c291cmNlcyBmb3IgQVJNMzIgYW5kDQpBUk02NCBhY2NvcmRpbmcgdG8gdGhlIHN1Z2dlc3Rpb24g Zm9yIEdhYnJpZWxlWzFdDQoNClRoaXMgcGF0Y2ggaXMgYmFzZWQgb24gR2FicmllbGUncyBwYXRj aCBhYm91dCBvZl9wY2lfcmFuZ2UgZml4WzJdDQoNCkZpbmFsbHkgdGhpcyBwYXRjaCByZXZlcnRz IGNvbW1pdCBmNGM1NWM1YTNmN2YgIlBDSTogZGVzaWdud2FyZToNClByb2dyYW0gQVRVIHdpdGgg dW50cmFuc2xhdGVkIGFkZHJlc3MiLiBUaGlzIHdhcyBkaXNjdXNzZWQgaW4gWzNdDQoNCkkgaGF2 ZSBjb21waWxlZCB0aGUgZHJpdmVyIHdpdGggbXVsdGlfdjdfZGVmY29uZmlnLiBIb3dldmVyLCBJ IGRvbid0IGhhdmUNCkFSTTMyIFBDSWUgcmVsYXRlZCBib2FyZCB0byBkbyB0ZXN0LiBJdCB3aWxs IGJlIGFwcHJlY2lhdGVkIGlmIHNvbWVvbmUgY291bGQNCmhlbHAgdG8gdGVzdCBpdC4NCg0KU2ln bmVkLW9mZi1ieTogWmhvdSBXYW5nIDx3YW5nemhvdTFAaGlzaWxpY29uLmNvbT4NClNpZ25lZC1v ZmYtYnk6IEFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQpTaWduZWQtb2ZmLWJ5OiBHYWJy aWVsZSBQYW9sb25pIDxnYWJyaWVsZS5wYW9sb25pQGh1YXdlaS5jb20+DQoNClsxXSBodHRwOi8v d3d3LnNwaW5pY3MubmV0L2xpc3RzL2xpbnV4LXBjaS9tc2c0MjE5NC5odG1sDQpbMl0gaHR0cHM6 Ly9wYXRjaHdvcmsub3psYWJzLm9yZy9wYXRjaC80OTUwMTgvDQpbM10gaHR0cDovL3d3dy5zcGlu aWNzLm5ldC9saXN0cy9hcm0ta2VybmVsL21zZzQzNjc3OS5odG1sDQotLS0NCiBkcml2ZXJzL3Bj aS9ob3N0L3BjaS1kcmE3eHguYyAgICAgIHwgIDE1ICstLQ0KIGRyaXZlcnMvcGNpL2hvc3QvcGNp LWV4eW5vcy5jICAgICAgfCAgIDIgKy0NCiBkcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMgICAg ICAgIHwgICAyICstDQogZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3RvbmUtZHcuYyB8ICAgMiAr LQ0KIGRyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLmMgICAgfCAgIDIgKy0NCiBkcml2ZXJz L3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMgIHwgICAyICstDQogZHJpdmVycy9wY2kvaG9zdC9w Y2llLWRlc2lnbndhcmUuYyB8IDI0NyArKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tDQogZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaCB8ICAxNSArLS0NCiBkcml2 ZXJzL3BjaS9ob3N0L3BjaWUtc3BlYXIxM3h4LmMgIHwgICAyICstDQogOSBmaWxlcyBjaGFuZ2Vk LCAxMTAgaW5zZXJ0aW9ucygrKSwgMTc5IGRlbGV0aW9ucygtKQ0KDQpkaWZmIC0tZ2l0IGEvZHJp dmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4LmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHgu Yw0KaW5kZXggNTY3OGI1Ny4uOGQ1OThmYiAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvcGNpL2hvc3Qv cGNpLWRyYTd4eC5jDQorKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYw0KQEAgLTE0 MSwxNSArMTQxLDE1IEBAIHN0YXRpYyB2b2lkIGRyYTd4eF9wY2llX2hvc3RfaW5pdChzdHJ1Y3Qg cGNpZV9wb3J0ICpwcCkNCiB7DQogCWR3X3BjaWVfc2V0dXBfcmMocHApOw0KIA0KLQlpZiAocHAt PmlvX21vZF9iYXNlKQ0KLQkJcHAtPmlvX21vZF9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCisJ aWYgKHBwLT5pb19iYXNlKQ0KKwkJcHAtPmlvX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERSOw0KIA0K LQlpZiAocHAtPm1lbV9tb2RfYmFzZSkNCi0JCXBwLT5tZW1fbW9kX2Jhc2UgJj0gQ1BVX1RPX0JV U19BRERSOw0KKwlpZiAocHAtPm1lbV9iYXNlKQ0KKwkJcHAtPm1lbV9iYXNlICY9IENQVV9UT19C VVNfQUREUjsNCiANCi0JaWYgKHBwLT5jZmcwX21vZF9iYXNlKSB7DQotCQlwcC0+Y2ZnMF9tb2Rf YmFzZSAmPSBDUFVfVE9fQlVTX0FERFI7DQotCQlwcC0+Y2ZnMV9tb2RfYmFzZSAmPSBDUFVfVE9f QlVTX0FERFI7DQorCWlmIChwcC0+Y2ZnMF9iYXNlKSB7DQorCQlwcC0+Y2ZnMF9iYXNlICY9IENQ VV9UT19CVVNfQUREUjsNCisJCXBwLT5jZmcxX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERSOw0KIAl9 DQogDQogCWRyYTd4eF9wY2llX2VzdGFibGlzaF9saW5rKHBwKTsNCkBAIC0yODgsNiArMjg4LDcg QEAgc3RhdGljIGludCBfX2luaXQgZHJhN3h4X2FkZF9wY2llX3BvcnQoc3RydWN0IGRyYTd4eF9w Y2llICpkcmE3eHgsDQogDQogCXBwID0gJmRyYTd4eC0+cHA7DQogCXBwLT5kZXYgPSBkZXY7DQor CXBwLT5yb290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJTkVEOw0KIAlwcC0+b3BzID0gJmRy YTd4eF9wY2llX2hvc3Rfb3BzOw0KIA0KIAlwcC0+aXJxID0gcGxhdGZvcm1fZ2V0X2lycShwZGV2 LCAxKTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1leHlub3MuYyBiL2RyaXZl cnMvcGNpL2hvc3QvcGNpLWV4eW5vcy5jDQppbmRleCBmOWY0NjhkLi5lZDAzYThmIDEwMDY0NA0K LS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2ktZXh5bm9zLmMNCisrKyBiL2RyaXZlcnMvcGNpL2hv c3QvcGNpLWV4eW5vcy5jDQpAQCAtNTMwLDcgKzUzMCw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGV4 eW5vc19hZGRfcGNpZV9wb3J0KHN0cnVjdCBwY2llX3BvcnQgKnBwLA0KIAkJfQ0KIAl9DQogDQot CXBwLT5yb290X2J1c19uciA9IC0xOw0KKwlwcC0+cm9vdF9idXNfbnIgPSBEV19ST09UX05SX1VO REVGSU5FRDsNCiAJcHAtPm9wcyA9ICZleHlub3NfcGNpZV9ob3N0X29wczsNCiANCiAJcmV0ID0g ZHdfcGNpZV9ob3N0X2luaXQocHApOw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNpL2hvc3QvcGNp LWlteDYuYyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWlteDYuYw0KaW5kZXggMjMzYTE5Ni4uMGVm YWM4NSAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWlteDYuYw0KKysrIGIvZHJp dmVycy9wY2kvaG9zdC9wY2ktaW14Ni5jDQpAQCAtNTUxLDcgKzU1MSw3IEBAIHN0YXRpYyBpbnQg X19pbml0IGlteDZfYWRkX3BjaWVfcG9ydChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwNCiAJCX0NCiAJ fQ0KIA0KLQlwcC0+cm9vdF9idXNfbnIgPSAtMTsNCisJcHAtPnJvb3RfYnVzX25yID0gRFdfUk9P VF9OUl9VTkRFRklORUQ7DQogCXBwLT5vcHMgPSAmaW14Nl9wY2llX2hvc3Rfb3BzOw0KIA0KIAly ZXQgPSBkd19wY2llX2hvc3RfaW5pdChwcCk7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9z dC9wY2kta2V5c3RvbmUtZHcuYyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMN CmluZGV4IGYzNDg5MmUuLmIxZTQxMzUgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3Bj aS1rZXlzdG9uZS1kdy5jDQorKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5j DQpAQCAtMzI3LDcgKzMyNyw3IEBAIHN0YXRpYyB2b2lkIGtzX2R3X3BjaWVfY2xlYXJfZGJpX21v ZGUodm9pZCBfX2lvbWVtICpyZWdfdmlydCkNCiB2b2lkIGtzX2R3X3BjaWVfc2V0dXBfcmNfYXBw X3JlZ3Moc3RydWN0IGtleXN0b25lX3BjaWUgKmtzX3BjaWUpDQogew0KIAlzdHJ1Y3QgcGNpZV9w b3J0ICpwcCA9ICZrc19wY2llLT5wcDsNCi0JdTMyIHN0YXJ0ID0gcHAtPm1lbS5zdGFydCwgZW5k ID0gcHAtPm1lbS5lbmQ7DQorCXUzMiBzdGFydCA9IHBwLT5tZW0tPnN0YXJ0LCBlbmQgPSBwcC0+ bWVtLT5lbmQ7DQogCWludCBpLCB0cl9zaXplOw0KIA0KIAkvKiBEaXNhYmxlIEJBUnMgZm9yIGlu Ym91bmQgYWNjZXNzICovDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3Rv bmUuYyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLmMNCmluZGV4IDczNGRhNTguLmI1 MjI5NTYgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS5jDQorKysg Yi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS5jDQpAQCAtMzA5LDcgKzMwOSw3IEBAIHN0 YXRpYyBpbnQgX19pbml0IGtzX2FkZF9wY2llX3BvcnQoc3RydWN0IGtleXN0b25lX3BjaWUgKmtz X3BjaWUsDQogCQkJcmV0dXJuIHJldDsNCiAJfQ0KIA0KLQlwcC0+cm9vdF9idXNfbnIgPSAtMTsN CisJcHAtPnJvb3RfYnVzX25yID0gRFdfUk9PVF9OUl9VTkRFRklORUQ7DQogCXBwLT5vcHMgPSAm a2V5c3RvbmVfcGNpZV9ob3N0X29wczsNCiAJcmV0ID0ga3NfZHdfcGNpZV9ob3N0X2luaXQoa3Nf cGNpZSwga3NfcGNpZS0+bXNpX2ludGNfbnApOw0KIAlpZiAocmV0KSB7DQpkaWZmIC0tZ2l0IGEv ZHJpdmVycy9wY2kvaG9zdC9wY2ktbGF5ZXJzY2FwZS5jIGIvZHJpdmVycy9wY2kvaG9zdC9wY2kt bGF5ZXJzY2FwZS5jDQppbmRleCBiMjMyOGVhMS4uZGQ5MmZmYSAxMDA2NDQNCi0tLSBhL2RyaXZl cnMvcGNpL2hvc3QvcGNpLWxheWVyc2NhcGUuYw0KKysrIGIvZHJpdmVycy9wY2kvaG9zdC9wY2kt bGF5ZXJzY2FwZS5jDQpAQCAtMTA2LDcgKzEwNiw3IEBAIHN0YXRpYyBpbnQgbHNfYWRkX3BjaWVf cG9ydChzdHJ1Y3QgbHNfcGNpZSAqcGNpZSkNCiAJcHAgPSAmcGNpZS0+cHA7DQogCXBwLT5kZXYg PSBwY2llLT5kZXY7DQogCXBwLT5kYmlfYmFzZSA9IHBjaWUtPmRiaTsNCi0JcHAtPnJvb3RfYnVz X25yID0gLTE7DQorCXBwLT5yb290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJTkVEOw0KIAlw cC0+b3BzID0gJmxzX3BjaWVfaG9zdF9vcHM7DQogDQogCXJldCA9IGR3X3BjaWVfaG9zdF9pbml0 KHBwKTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5jIGIv ZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuYw0KaW5kZXggNTMwN2IzNS4uYmQyNjA2 YiAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMNCisrKyBi L2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMNCkBAIC0xMSw2ICsxMSw3IEBADQog ICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uDQogICovDQogDQor I2luY2x1ZGUgPGxpbnV4L2hhcmRpcnEuaD4NCiAjaW5jbHVkZSA8bGludXgvaXJxLmg+DQogI2lu Y2x1ZGUgPGxpbnV4L2lycWRvbWFpbi5oPg0KICNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4NCkBA IC02OSwxNiArNzAsOSBAQA0KICNkZWZpbmUgUENJRV9BVFVfRlVOQyh4KQkJKCgoeCkgJiAweDcp IDw8IDE2KQ0KICNkZWZpbmUgUENJRV9BVFVfVVBQRVJfVEFSR0VUCQkweDkxQw0KIA0KLXN0YXRp YyBzdHJ1Y3QgaHdfcGNpIGR3X3BjaTsNCitzdGF0aWMgc3RydWN0IHBjaV9vcHMgZHdfcGNpZV9v cHM7DQogDQotc3RhdGljIHVuc2lnbmVkIGxvbmcgZ2xvYmFsX2lvX29mZnNldDsNCi0NCi1zdGF0 aWMgaW5saW5lIHN0cnVjdCBwY2llX3BvcnQgKnN5c190b19wY2llKHN0cnVjdCBwY2lfc3lzX2Rh dGEgKnN5cykNCi17DQotCUJVR19PTighc3lzLT5wcml2YXRlX2RhdGEpOw0KLQ0KLQlyZXR1cm4g c3lzLT5wcml2YXRlX2RhdGE7DQotfQ0KK0RFRklORV9NVVRFWChyb290X2J1c19ucl9tdXgpOw0K IA0KIGludCBkd19wY2llX2NmZ19yZWFkKHZvaWQgX19pb21lbSAqYWRkciwgaW50IHdoZXJlLCBp bnQgc2l6ZSwgdTMyICp2YWwpDQogew0KQEAgLTI1NSw3ICsyNDksNyBAQCBzdGF0aWMgdm9pZCBk d19wY2llX21zaV9zZXRfaXJxKHN0cnVjdCBwY2llX3BvcnQgKnBwLCBpbnQgaXJxKQ0KIHN0YXRp YyBpbnQgYXNzaWduX2lycShpbnQgbm9faXJxcywgc3RydWN0IG1zaV9kZXNjICpkZXNjLCBpbnQg KnBvcykNCiB7DQogCWludCBpcnEsIHBvczAsIGk7DQotCXN0cnVjdCBwY2llX3BvcnQgKnBwID0g c3lzX3RvX3BjaWUoZGVzYy0+ZGV2LT5idXMtPnN5c2RhdGEpOw0KKwlzdHJ1Y3QgcGNpZV9wb3J0 ICpwcCA9IGRlc2MtPmRldi0+YnVzLT5zeXNkYXRhOw0KIA0KIAlwb3MwID0gYml0bWFwX2ZpbmRf ZnJlZV9yZWdpb24ocHAtPm1zaV9pcnFfaW5fdXNlLCBNQVhfTVNJX0lSUVMsDQogCQkJCSAgICAg ICBvcmRlcl9iYXNlXzIobm9faXJxcykpOw0KQEAgLTI5OCw3ICsyOTIsNyBAQCBzdGF0aWMgaW50 IGR3X21zaV9zZXR1cF9pcnEoc3RydWN0IG1zaV9jb250cm9sbGVyICpjaGlwLCBzdHJ1Y3QgcGNp X2RldiAqcGRldiwNCiB7DQogCWludCBpcnEsIHBvczsNCiAJc3RydWN0IG1zaV9tc2cgbXNnOw0K LQlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKHBkZXYtPmJ1cy0+c3lzZGF0YSk7 DQorCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gcGRldi0+YnVzLT5zeXNkYXRhOw0KIA0KIAlpZiAo ZGVzYy0+bXNpX2F0dHJpYi5pc19tc2l4KQ0KIAkJcmV0dXJuIC1FSU5WQUw7DQpAQCAtMzI3LDcg KzMyMSw3IEBAIHN0YXRpYyB2b2lkIGR3X21zaV90ZWFyZG93bl9pcnEoc3RydWN0IG1zaV9jb250 cm9sbGVyICpjaGlwLCB1bnNpZ25lZCBpbnQgaXJxKQ0KIHsNCiAJc3RydWN0IGlycV9kYXRhICpk YXRhID0gaXJxX2dldF9pcnFfZGF0YShpcnEpOw0KIAlzdHJ1Y3QgbXNpX2Rlc2MgKm1zaSA9IGly cV9kYXRhX2dldF9tc2koZGF0YSk7DQotCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3Bj aWUobXNpLT5kZXYtPmJ1cy0+c3lzZGF0YSk7DQorCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gbXNp LT5kZXYtPmJ1cy0+c3lzZGF0YTsNCiANCiAJY2xlYXJfaXJxX3JhbmdlKHBwLCBpcnEsIDEsIGRh dGEtPmh3aXJxKTsNCiB9DQpAQCAtMzU5LDIyICszNTMsMTcgQEAgc3RhdGljIGNvbnN0IHN0cnVj dCBpcnFfZG9tYWluX29wcyBtc2lfZG9tYWluX29wcyA9IHsNCiAJLm1hcCA9IGR3X3BjaWVfbXNp X21hcCwNCiB9Ow0KIA0KLWludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9wb3J0ICpw cCkNCitpbnQgX19pbml0IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0K IHsNCiAJc3RydWN0IGRldmljZV9ub2RlICpucCA9IHBwLT5kZXYtPm9mX25vZGU7DQogCXN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYgPSB0b19wbGF0Zm9ybV9kZXZpY2UocHAtPmRldik7DQot CXN0cnVjdCBvZl9wY2lfcmFuZ2UgcmFuZ2U7DQotCXN0cnVjdCBvZl9wY2lfcmFuZ2VfcGFyc2Vy IHBhcnNlcjsNCisJc3RydWN0IHBjaV9idXMgKmJ1czsNCiAJc3RydWN0IHJlc291cmNlICpjZmdf cmVzOw0KLQl1MzIgdmFsLCBuYSwgbnM7DQotCWNvbnN0IF9fYmUzMiAqYWRkcnA7DQotCWludCBp LCBpbmRleCwgcmV0Ow0KLQ0KLQkvKiBGaW5kIHRoZSBhZGRyZXNzIGNlbGwgc2l6ZSBhbmQgdGhl IG51bWJlciBvZiBjZWxscyBpbiBvcmRlciB0byBnZXQNCi0JICogdGhlIHVudHJhbnNsYXRlZCBh ZGRyZXNzLg0KLQkgKi8NCi0Jb2ZfcHJvcGVydHlfcmVhZF91MzIobnAsICIjYWRkcmVzcy1jZWxs cyIsICZuYSk7DQotCW5zID0gb2Zfbl9zaXplX2NlbGxzKG5wKTsNCisJTElTVF9IRUFEKHJlcyk7 DQorCXUzMiB2YWw7DQorCWludCBpLCByZXQ7DQorCXN0cnVjdCByZXNvdXJjZV9lbnRyeSAqd2lu Ow0KKwlzdGF0aWMgaW50IHJvb3RfYnVzX25yID0gMDsNCiANCiAJY2ZnX3JlcyA9IHBsYXRmb3Jt X2dldF9yZXNvdXJjZV9ieW5hbWUocGRldiwgSU9SRVNPVVJDRV9NRU0sICJjb25maWciKTsNCiAJ aWYgKGNmZ19yZXMpIHsNCkBAIC0zODIsODUgKzM3MSw2MCBAQCBpbnQgZHdfcGNpZV9ob3N0X2lu aXQoc3RydWN0IHBjaWVfcG9ydCAqcHApDQogCQlwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6 ZShjZmdfcmVzKS8yOw0KIAkJcHAtPmNmZzBfYmFzZSA9IGNmZ19yZXMtPnN0YXJ0Ow0KIAkJcHAt PmNmZzFfYmFzZSA9IGNmZ19yZXMtPnN0YXJ0ICsgcHAtPmNmZzBfc2l6ZTsNCi0NCi0JCS8qIEZp bmQgdGhlIHVudHJhbnNsYXRlZCBjb25maWd1cmF0aW9uIHNwYWNlIGFkZHJlc3MgKi8NCi0JCWlu ZGV4ID0gb2ZfcHJvcGVydHlfbWF0Y2hfc3RyaW5nKG5wLCAicmVnLW5hbWVzIiwgImNvbmZpZyIp Ow0KLQkJYWRkcnAgPSBvZl9nZXRfYWRkcmVzcyhucCwgaW5kZXgsIE5VTEwsIE5VTEwpOw0KLQkJ cHAtPmNmZzBfbW9kX2Jhc2UgPSBvZl9yZWFkX251bWJlcihhZGRycCwgbnMpOw0KLQkJcHAtPmNm ZzFfbW9kX2Jhc2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArIHBwLT5jZmcwX3NpemU7DQogCX0gZWxz ZSB7DQogCQlkZXZfZXJyKHBwLT5kZXYsICJtaXNzaW5nICpjb25maWcqIHJlZyBzcGFjZVxuIik7 DQogCX0NCiANCi0JaWYgKG9mX3BjaV9yYW5nZV9wYXJzZXJfaW5pdCgmcGFyc2VyLCBucCkpIHsN Ci0JCWRldl9lcnIocHAtPmRldiwgIm1pc3NpbmcgcmFuZ2VzIHByb3BlcnR5XG4iKTsNCi0JCXJl dHVybiAtRUlOVkFMOw0KLQl9DQorCXJldCA9IG9mX3BjaV9nZXRfaG9zdF9icmlkZ2VfcmVzb3Vy Y2VzKG5wLCAwLCAweGZmLCAmcmVzLCAmcHAtPmlvX2Jhc2UpOw0KKwlpZiAocmV0KQ0KKwkJcmV0 dXJuIHJldDsNCiANCiAJLyogR2V0IHRoZSBJL08gYW5kIG1lbW9yeSByYW5nZXMgZnJvbSBEVCAq Lw0KLQlmb3JfZWFjaF9vZl9wY2lfcmFuZ2UoJnBhcnNlciwgJnJhbmdlKSB7DQotCQl1bnNpZ25l ZCBsb25nIHJlc3R5cGUgPSByYW5nZS5mbGFncyAmIElPUkVTT1VSQ0VfVFlQRV9CSVRTOw0KLQ0K LQkJaWYgKHJlc3R5cGUgPT0gSU9SRVNPVVJDRV9JTykgew0KLQkJCW9mX3BjaV9yYW5nZV90b19y ZXNvdXJjZSgmcmFuZ2UsIG5wLCAmcHAtPmlvKTsNCi0JCQlwcC0+aW8ubmFtZSA9ICJJL08iOw0K LQkJCXBwLT5pby5zdGFydCA9IG1heF90KHJlc291cmNlX3NpemVfdCwNCi0JCQkJCSAgICAgUENJ QklPU19NSU5fSU8sDQotCQkJCQkgICAgIHJhbmdlLnBjaV9hZGRyICsgZ2xvYmFsX2lvX29mZnNl dCk7DQotCQkJcHAtPmlvLmVuZCA9IG1pbl90KHJlc291cmNlX3NpemVfdCwNCi0JCQkJCSAgIElP X1NQQUNFX0xJTUlULA0KLQkJCQkJICAgcmFuZ2UucGNpX2FkZHIgKyByYW5nZS5zaXplDQotCQkJ CQkgICArIGdsb2JhbF9pb19vZmZzZXQgLSAxKTsNCi0JCQlwcC0+aW9fc2l6ZSA9IHJlc291cmNl X3NpemUoJnBwLT5pbyk7DQotCQkJcHAtPmlvX2J1c19hZGRyID0gcmFuZ2UucGNpX2FkZHI7DQot CQkJcHAtPmlvX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsNCi0NCi0JCQkvKiBGaW5kIHRoZSB1bnRy YW5zbGF0ZWQgSU8gc3BhY2UgYWRkcmVzcyAqLw0KLQkJCXBwLT5pb19tb2RfYmFzZSA9IHJhbmdl LmNwdV9hZGRyOw0KLQkJfQ0KLQkJaWYgKHJlc3R5cGUgPT0gSU9SRVNPVVJDRV9NRU0pIHsNCi0J CQlvZl9wY2lfcmFuZ2VfdG9fcmVzb3VyY2UoJnJhbmdlLCBucCwgJnBwLT5tZW0pOw0KLQkJCXBw LT5tZW0ubmFtZSA9ICJNRU0iOw0KLQkJCXBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUoJnBw LT5tZW0pOw0KLQkJCXBwLT5tZW1fYnVzX2FkZHIgPSByYW5nZS5wY2lfYWRkcjsNCi0NCi0JCQkv KiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgTUVNIHNwYWNlIGFkZHJlc3MgKi8NCi0JCQlwcC0+bWVt X21vZF9iYXNlID0gcmFuZ2UuY3B1X2FkZHI7DQotCQl9DQotCQlpZiAocmVzdHlwZSA9PSAwKSB7 DQotCQkJb2ZfcGNpX3JhbmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAsICZwcC0+Y2ZnKTsNCi0J CQlwcC0+Y2ZnMF9zaXplID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPmNmZykvMjsNCi0JCQlwcC0+Y2Zn MV9zaXplID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPmNmZykvMjsNCi0JCQlwcC0+Y2ZnMF9iYXNlID0g cHAtPmNmZy5zdGFydDsNCi0JCQlwcC0+Y2ZnMV9iYXNlID0gcHAtPmNmZy5zdGFydCArIHBwLT5j ZmcwX3NpemU7DQotDQotCQkJLyogRmluZCB0aGUgdW50cmFuc2xhdGVkIGNvbmZpZ3VyYXRpb24g c3BhY2UgYWRkcmVzcyAqLw0KLQkJCXBwLT5jZmcwX21vZF9iYXNlID0gcmFuZ2UuY3B1X2FkZHI7 DQotCQkJcHAtPmNmZzFfbW9kX2Jhc2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArDQotCQkJCQkgICAg cHAtPmNmZzBfc2l6ZTsNCisJcmVzb3VyY2VfbGlzdF9mb3JfZWFjaF9lbnRyeSh3aW4sICZyZXMp IHsNCisJCXN3aXRjaCAocmVzb3VyY2VfdHlwZSh3aW4tPnJlcykpIHsNCisJCWNhc2UgSU9SRVNP VVJDRV9JTzoNCisJCQlwcC0+aW8gPSB3aW4tPnJlczsNCisJCQlwcC0+aW8tPm5hbWUgPSAiSS9P IjsNCisJCQlwcC0+aW9fc2l6ZSA9IHJlc291cmNlX3NpemUocHAtPmlvKTsNCisJCQlwcC0+aW9f YnVzX2FkZHIgPSBwcC0+aW8tPnN0YXJ0IC0gd2luLT5vZmZzZXQ7DQorCQkJcmV0ID0gcGNpX3Jl bWFwX2lvc3BhY2UocHAtPmlvLCBwcC0+aW9fYmFzZSk7DQorCQkJaWYgKHJldCkgew0KKwkJCQlk ZXZfd2FybihwcC0+ZGV2LCAiZXJyb3IgJWQ6IGZhaWxlZCB0byBtYXAgcmVzb3VyY2UgJXBSXG4i LA0KKwkJCQkJIHJldCwgcHAtPmlvKTsNCisJCQkJY29udGludWU7DQorCQkJfQ0KKwkJCWJyZWFr Ow0KKwkJY2FzZSBJT1JFU09VUkNFX01FTToNCisJCQlwcC0+bWVtID0gd2luLT5yZXM7DQorCQkJ cHAtPm1lbS0+bmFtZSA9ICJNRU0iOw0KKwkJCXBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUo cHAtPm1lbSk7DQorCQkJcHAtPm1lbV9idXNfYWRkciA9IHBwLT5tZW0tPnN0YXJ0IC0gd2luLT5v ZmZzZXQ7DQorCQkJYnJlYWs7DQorCQljYXNlIDA6DQorCQkJcHAtPmNmZyA9IHdpbi0+cmVzOw0K KwkJCXBwLT5jZmcwX3NpemUgPSByZXNvdXJjZV9zaXplKHBwLT5jZmcpLzI7DQorCQkJcHAtPmNm ZzFfc2l6ZSA9IHJlc291cmNlX3NpemUocHAtPmNmZykvMjsNCisJCQlwcC0+Y2ZnMF9iYXNlID0g cHAtPmNmZy0+c3RhcnQ7DQorCQkJcHAtPmNmZzFfYmFzZSA9IHBwLT5jZmctPnN0YXJ0ICsgcHAt PmNmZzBfc2l6ZTsNCisJCQlicmVhazsNCisJCWNhc2UgSU9SRVNPVVJDRV9CVVM6DQorCQkJcHAt PmJ1c24gPSB3aW4tPnJlczsNCisJCQlicmVhazsNCisJCWRlZmF1bHQ6DQorCQkJY29udGludWU7 DQogCQl9DQogCX0NCiANCi0JcmV0ID0gb2ZfcGNpX3BhcnNlX2J1c19yYW5nZShucCwgJnBwLT5i dXNuKTsNCi0JaWYgKHJldCA8IDApIHsNCi0JCXBwLT5idXNuLm5hbWUgPSBucC0+bmFtZTsNCi0J CXBwLT5idXNuLnN0YXJ0ID0gMDsNCi0JCXBwLT5idXNuLmVuZCA9IDB4ZmY7DQotCQlwcC0+YnVz bi5mbGFncyA9IElPUkVTT1VSQ0VfQlVTOw0KLQkJZGV2X2RiZyhwcC0+ZGV2LCAiZmFpbGVkIHRv IHBhcnNlIGJ1cy1yYW5nZSBwcm9wZXJ0eTogJWQsIHVzaW5nIGRlZmF1bHQgJXBSXG4iLA0KLQkJ CXJldCwgJnBwLT5idXNuKTsNCi0JfQ0KLQ0KIAlpZiAoIXBwLT5kYmlfYmFzZSkgew0KLQkJcHAt PmRiaV9iYXNlID0gZGV2bV9pb3JlbWFwKHBwLT5kZXYsIHBwLT5jZmcuc3RhcnQsDQotCQkJCQly ZXNvdXJjZV9zaXplKCZwcC0+Y2ZnKSk7DQorCQlwcC0+ZGJpX2Jhc2UgPSBkZXZtX2lvcmVtYXAo cHAtPmRldiwgcHAtPmNmZy0+c3RhcnQsDQorCQkJCQlyZXNvdXJjZV9zaXplKHBwLT5jZmcpKTsN CiAJCWlmICghcHAtPmRiaV9iYXNlKSB7DQogCQkJZGV2X2VycihwcC0+ZGV2LCAiZXJyb3Igd2l0 aCBpb3JlbWFwXG4iKTsNCiAJCQlyZXR1cm4gLUVOT01FTTsNCiAJCX0NCiAJfQ0KIA0KLQlwcC0+ bWVtX2Jhc2UgPSBwcC0+bWVtLnN0YXJ0Ow0KKwlwcC0+bWVtX2Jhc2UgPSBwcC0+bWVtLT5zdGFy dDsNCiANCiAJaWYgKCFwcC0+dmFfY2ZnMF9iYXNlKSB7DQogCQlwcC0+dmFfY2ZnMF9iYXNlID0g ZGV2bV9pb3JlbWFwKHBwLT5kZXYsIHBwLT5jZmcwX2Jhc2UsDQpAQCAtNTA5LDcgKzQ3Myw3IEBA IGludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCkNCiANCiAJaWYgKCFw cC0+b3BzLT5yZF9vdGhlcl9jb25mKQ0KIAkJZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwg UENJRV9BVFVfUkVHSU9OX0lOREVYMSwNCi0JCQkJCSAgUENJRV9BVFVfVFlQRV9NRU0sIHBwLT5t ZW1fbW9kX2Jhc2UsDQorCQkJCQkgIFBDSUVfQVRVX1RZUEVfTUVNLCBwcC0+bWVtX2Jhc2UsDQog CQkJCQkgIHBwLT5tZW1fYnVzX2FkZHIsIHBwLT5tZW1fc2l6ZSk7DQogDQogCWR3X3BjaWVfd3Jf b3duX2NvbmYocHAsIFBDSV9CQVNFX0FERFJFU1NfMCwgNCwgMCk7DQpAQCAtNTIxLDE1ICs0ODUs NDAgQEAgaW50IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KIAl2YWwg fD0gUE9SVF9MT0dJQ19TUEVFRF9DSEFOR0U7DQogCWR3X3BjaWVfd3Jfb3duX2NvbmYocHAsIFBD SUVfTElOS19XSURUSF9TUEVFRF9DT05UUk9MLCA0LCB2YWwpOw0KIA0KLSNpZmRlZiBDT05GSUdf UENJX01TSQ0KIAlkd19wY2llX21zaV9jaGlwLmRldiA9IHBwLT5kZXY7DQotCWR3X3BjaS5tc2lf Y3RybCA9ICZkd19wY2llX21zaV9jaGlwOw0KKw0KKwltdXRleF9sb2NrKCZyb290X2J1c19ucl9t dXgpOw0KKw0KKwlpZiAocHAtPnJvb3RfYnVzX25yICE9IERXX1JPT1RfTlJfVU5ERUZJTkVEKQ0K KwkJcm9vdF9idXNfbnIgPSBwcC0+cm9vdF9idXNfbnI7DQorDQorCWJ1cyA9IHBjaV9jcmVhdGVf cm9vdF9idXMocHAtPmRldiwgcm9vdF9idXNfbnIsICZkd19wY2llX29wcywNCisJCQkgICAgICBw cCwgJnJlcyk7DQorCWlmICghYnVzKSB7DQorCQltdXRleF91bmxvY2soJnJvb3RfYnVzX25yX211 eCk7DQorCQlyZXR1cm4gLUVOT01FTTsNCisJfQ0KKw0KKwlyb290X2J1c19uciArPSBidXMtPmJ1 c25fcmVzLmVuZCArIDE7DQorCW11dGV4X3VubG9jaygmcm9vdF9idXNfbnJfbXV4KTsNCisNCisj aWZkZWYgQ09ORklHX0dFTkVSSUNfTVNJX0lSUV9ET01BSU4NCisJYnVzLT5tc2kgPSBjb250YWlu ZXJfb2YoJnBwLT5pcnFfZG9tYWluLCBzdHJ1Y3QgbXNpX2NvbnRyb2xsZXIsIGRvbWFpbik7DQor I2Vsc2UNCisJYnVzLT5tc2kgPSAmZHdfcGNpZV9tc2lfY2hpcDsNCiAjZW5kaWYNCiANCi0JZHdf cGNpLm5yX2NvbnRyb2xsZXJzID0gMTsNCi0JZHdfcGNpLnByaXZhdGVfZGF0YSA9ICh2b2lkICoq KSZwcDsNCisJcGNpX3NjYW5fY2hpbGRfYnVzKGJ1cyk7DQorCWlmIChwcC0+b3BzLT5zY2FuX2J1 cykNCisJCXBwLT5vcHMtPnNjYW5fYnVzKHBwKTsNCisNCisjaWZkZWYgQ09ORklHX0FSTQ0KKwkv KiBzdXBwb3J0IG9sZCBkdGJzIHRoYXQgaW5jb3JyZWN0bHkgZGVzY3JpYmUgSVJRcyAqLw0KKwlw Y2lfZml4dXBfaXJxcyhwY2lfY29tbW9uX3N3aXp6bGUsIG9mX2lycV9wYXJzZV9hbmRfbWFwX3Bj aSk7DQorI2VuZGlmDQogDQotCXBjaV9jb21tb25faW5pdF9kZXYocHAtPmRldiwgJmR3X3BjaSk7 DQorCXBjaV9hc3NpZ25fdW5hc3NpZ25lZF9idXNfcmVzb3VyY2VzKGJ1cyk7DQorCXBjaV9idXNf YWRkX2RldmljZXMoYnVzKTsNCiANCiAJcmV0dXJuIDA7DQogfQ0KQEAgLTU0OCwxMiArNTM3LDEy IEBAIHN0YXRpYyBpbnQgZHdfcGNpZV9yZF9vdGhlcl9jb25mKHN0cnVjdCBwY2llX3BvcnQgKnBw LCBzdHJ1Y3QgcGNpX2J1cyAqYnVzLA0KIA0KIAlpZiAoYnVzLT5wYXJlbnQtPm51bWJlciA9PSBw cC0+cm9vdF9idXNfbnIpIHsNCiAJCXR5cGUgPSBQQ0lFX0FUVV9UWVBFX0NGRzA7DQotCQljcHVf YWRkciA9IHBwLT5jZmcwX21vZF9iYXNlOw0KKwkJY3B1X2FkZHIgPSBwcC0+Y2ZnMF9iYXNlOw0K IAkJY2ZnX3NpemUgPSBwcC0+Y2ZnMF9zaXplOw0KIAkJdmFfY2ZnX2Jhc2UgPSBwcC0+dmFfY2Zn MF9iYXNlOw0KIAl9IGVsc2Ugew0KIAkJdHlwZSA9IFBDSUVfQVRVX1RZUEVfQ0ZHMTsNCi0JCWNw dV9hZGRyID0gcHAtPmNmZzFfbW9kX2Jhc2U7DQorCQljcHVfYWRkciA9IHBwLT5jZmcxX2Jhc2U7 DQogCQljZmdfc2l6ZSA9IHBwLT5jZmcxX3NpemU7DQogCQl2YV9jZmdfYmFzZSA9IHBwLT52YV9j ZmcxX2Jhc2U7DQogCX0NCkBAIC01NjMsNyArNTUyLDcgQEAgc3RhdGljIGludCBkd19wY2llX3Jk X290aGVyX2NvbmYoc3RydWN0IHBjaWVfcG9ydCAqcHAsIHN0cnVjdCBwY2lfYnVzICpidXMsDQog CQkJCSAgYnVzZGV2LCBjZmdfc2l6ZSk7DQogCXJldCA9IGR3X3BjaWVfY2ZnX3JlYWQodmFfY2Zn X2Jhc2UgKyBhZGRyZXNzLCB3aGVyZSwgc2l6ZSwgdmFsKTsNCiAJZHdfcGNpZV9wcm9nX291dGJv dW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVYMCwNCi0JCQkJICBQQ0lFX0FUVV9UWVBF X0lPLCBwcC0+aW9fbW9kX2Jhc2UsDQorCQkJCSAgUENJRV9BVFVfVFlQRV9JTywgcHAtPmlvX2Jh c2UsDQogCQkJCSAgcHAtPmlvX2J1c19hZGRyLCBwcC0+aW9fc2l6ZSk7DQogDQogCXJldHVybiBy ZXQ7DQpAQCAtNTgzLDEyICs1NzIsMTIgQEAgc3RhdGljIGludCBkd19wY2llX3dyX290aGVyX2Nv bmYoc3RydWN0IHBjaWVfcG9ydCAqcHAsIHN0cnVjdCBwY2lfYnVzICpidXMsDQogDQogCWlmIChi dXMtPnBhcmVudC0+bnVtYmVyID09IHBwLT5yb290X2J1c19ucikgew0KIAkJdHlwZSA9IFBDSUVf QVRVX1RZUEVfQ0ZHMDsNCi0JCWNwdV9hZGRyID0gcHAtPmNmZzBfbW9kX2Jhc2U7DQorCQljcHVf YWRkciA9IHBwLT5jZmcwX2Jhc2U7DQogCQljZmdfc2l6ZSA9IHBwLT5jZmcwX3NpemU7DQogCQl2 YV9jZmdfYmFzZSA9IHBwLT52YV9jZmcwX2Jhc2U7DQogCX0gZWxzZSB7DQogCQl0eXBlID0gUENJ RV9BVFVfVFlQRV9DRkcxOw0KLQkJY3B1X2FkZHIgPSBwcC0+Y2ZnMV9tb2RfYmFzZTsNCisJCWNw dV9hZGRyID0gcHAtPmNmZzFfYmFzZTsNCiAJCWNmZ19zaXplID0gcHAtPmNmZzFfc2l6ZTsNCiAJ CXZhX2NmZ19iYXNlID0gcHAtPnZhX2NmZzFfYmFzZTsNCiAJfQ0KQEAgLTU5OCw3ICs1ODcsNyBA QCBzdGF0aWMgaW50IGR3X3BjaWVfd3Jfb3RoZXJfY29uZihzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwg c3RydWN0IHBjaV9idXMgKmJ1cywNCiAJCQkJICBidXNkZXYsIGNmZ19zaXplKTsNCiAJcmV0ID0g ZHdfcGNpZV9jZmdfd3JpdGUodmFfY2ZnX2Jhc2UgKyBhZGRyZXNzLCB3aGVyZSwgc2l6ZSwgdmFs KTsNCiAJZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVY MCwNCi0JCQkJICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fbW9kX2Jhc2UsDQorCQkJCSAgUENJ RV9BVFVfVFlQRV9JTywgcHAtPmlvX2Jhc2UsDQogCQkJCSAgcHAtPmlvX2J1c19hZGRyLCBwcC0+ aW9fc2l6ZSk7DQogDQogCXJldHVybiByZXQ7DQpAQCAtNjMwLDcgKzYxOSw3IEBAIHN0YXRpYyBp bnQgZHdfcGNpZV92YWxpZF9jb25maWcoc3RydWN0IHBjaWVfcG9ydCAqcHAsDQogc3RhdGljIGlu dCBkd19wY2llX3JkX2NvbmYoc3RydWN0IHBjaV9idXMgKmJ1cywgdTMyIGRldmZuLCBpbnQgd2hl cmUsDQogCQkJaW50IHNpemUsIHUzMiAqdmFsKQ0KIHsNCi0Jc3RydWN0IHBjaWVfcG9ydCAqcHAg PSBzeXNfdG9fcGNpZShidXMtPnN5c2RhdGEpOw0KKwlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IGJ1 cy0+c3lzZGF0YTsNCiAJaW50IHJldDsNCiANCiAJaWYgKGR3X3BjaWVfdmFsaWRfY29uZmlnKHBw LCBidXMsIFBDSV9TTE9UKGRldmZuKSkgPT0gMCkgew0KQEAgLTY1NCw3ICs2NDMsNyBAQCBzdGF0 aWMgaW50IGR3X3BjaWVfcmRfY29uZihzdHJ1Y3QgcGNpX2J1cyAqYnVzLCB1MzIgZGV2Zm4sIGlu dCB3aGVyZSwNCiBzdGF0aWMgaW50IGR3X3BjaWVfd3JfY29uZihzdHJ1Y3QgcGNpX2J1cyAqYnVz LCB1MzIgZGV2Zm4sDQogCQkJaW50IHdoZXJlLCBpbnQgc2l6ZSwgdTMyIHZhbCkNCiB7DQotCXN0 cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUoYnVzLT5zeXNkYXRhKTsNCisJc3RydWN0 IHBjaWVfcG9ydCAqcHAgPSBidXMtPnN5c2RhdGE7DQogCWludCByZXQ7DQogDQogCWlmIChkd19w Y2llX3ZhbGlkX2NvbmZpZyhwcCwgYnVzLCBQQ0lfU0xPVChkZXZmbikpID09IDApDQpAQCAtNjc4 LDYyICs2NjcsNiBAQCBzdGF0aWMgc3RydWN0IHBjaV9vcHMgZHdfcGNpZV9vcHMgPSB7DQogCS53 cml0ZSA9IGR3X3BjaWVfd3JfY29uZiwNCiB9Ow0KIA0KLXN0YXRpYyBpbnQgZHdfcGNpZV9zZXR1 cChpbnQgbnIsIHN0cnVjdCBwY2lfc3lzX2RhdGEgKnN5cykNCi17DQotCXN0cnVjdCBwY2llX3Bv cnQgKnBwOw0KLQ0KLQlwcCA9IHN5c190b19wY2llKHN5cyk7DQotDQotCWlmIChnbG9iYWxfaW9f b2Zmc2V0IDwgU1pfMU0gJiYgcHAtPmlvX3NpemUgPiAwKSB7DQotCQlzeXMtPmlvX29mZnNldCA9 IGdsb2JhbF9pb19vZmZzZXQgLSBwcC0+aW9fYnVzX2FkZHI7DQotCQlwY2lfaW9yZW1hcF9pbyhn bG9iYWxfaW9fb2Zmc2V0LCBwcC0+aW9fYmFzZSk7DQotCQlnbG9iYWxfaW9fb2Zmc2V0ICs9IFNa XzY0SzsNCi0JCXBjaV9hZGRfcmVzb3VyY2Vfb2Zmc2V0KCZzeXMtPnJlc291cmNlcywgJnBwLT5p bywNCi0JCQkJCXN5cy0+aW9fb2Zmc2V0KTsNCi0JfQ0KLQ0KLQlzeXMtPm1lbV9vZmZzZXQgPSBw cC0+bWVtLnN0YXJ0IC0gcHAtPm1lbV9idXNfYWRkcjsNCi0JcGNpX2FkZF9yZXNvdXJjZV9vZmZz ZXQoJnN5cy0+cmVzb3VyY2VzLCAmcHAtPm1lbSwgc3lzLT5tZW1fb2Zmc2V0KTsNCi0JcGNpX2Fk ZF9yZXNvdXJjZSgmc3lzLT5yZXNvdXJjZXMsICZwcC0+YnVzbik7DQotDQotCXJldHVybiAxOw0K LX0NCi0NCi1zdGF0aWMgc3RydWN0IHBjaV9idXMgKmR3X3BjaWVfc2Nhbl9idXMoaW50IG5yLCBz dHJ1Y3QgcGNpX3N5c19kYXRhICpzeXMpDQotew0KLQlzdHJ1Y3QgcGNpX2J1cyAqYnVzOw0KLQlz dHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKHN5cyk7DQotDQotCXBwLT5yb290X2J1 c19uciA9IHN5cy0+YnVzbnI7DQotCWJ1cyA9IHBjaV9zY2FuX3Jvb3RfYnVzKHBwLT5kZXYsIHN5 cy0+YnVzbnIsDQotCQkJCSAgJmR3X3BjaWVfb3BzLCBzeXMsICZzeXMtPnJlc291cmNlcyk7DQot CWlmICghYnVzKQ0KLQkJcmV0dXJuIE5VTEw7DQotDQotCWlmIChidXMgJiYgcHAtPm9wcy0+c2Nh bl9idXMpDQotCQlwcC0+b3BzLT5zY2FuX2J1cyhwcCk7DQotDQotCXJldHVybiBidXM7DQotfQ0K LQ0KLXN0YXRpYyBpbnQgZHdfcGNpZV9tYXBfaXJxKGNvbnN0IHN0cnVjdCBwY2lfZGV2ICpkZXYs IHU4IHNsb3QsIHU4IHBpbikNCi17DQotCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3Bj aWUoZGV2LT5idXMtPnN5c2RhdGEpOw0KLQlpbnQgaXJxOw0KLQ0KLQlpcnEgPSBvZl9pcnFfcGFy c2VfYW5kX21hcF9wY2koZGV2LCBzbG90LCBwaW4pOw0KLQlpZiAoIWlycSkNCi0JCWlycSA9IHBw LT5pcnE7DQotDQotCXJldHVybiBpcnE7DQotfQ0KLQ0KLXN0YXRpYyBzdHJ1Y3QgaHdfcGNpIGR3 X3BjaSA9IHsNCi0JLnNldHVwCQk9IGR3X3BjaWVfc2V0dXAsDQotCS5zY2FuCQk9IGR3X3BjaWVf c2Nhbl9idXMsDQotCS5tYXBfaXJxCT0gZHdfcGNpZV9tYXBfaXJxLA0KLX07DQotDQogdm9pZCBk d19wY2llX3NldHVwX3JjKHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KIHsNCiAJdTMyIHZhbDsNCmRp ZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5oIGIvZHJpdmVycy9w Y2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaA0KaW5kZXggZDBiYmQyNy4uMGMyYTdlYiAxMDA2NDQN Ci0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmgNCisrKyBiL2RyaXZlcnMv cGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmgNCkBAIC0yMSwzMSArMjEsMjggQEANCiAgKi8NCiAj ZGVmaW5lIE1BWF9NU0lfSVJRUwkJCTMyDQogI2RlZmluZSBNQVhfTVNJX0NUUkxTCQkJKE1BWF9N U0lfSVJRUyAvIDMyKQ0KKyNkZWZpbmUgRFdfUk9PVF9OUl9VTkRFRklORUQJLTENCiANCiBzdHJ1 Y3QgcGNpZV9wb3J0IHsNCiAJc3RydWN0IGRldmljZQkJKmRldjsNCiAJdTgJCQlyb290X2J1c19u cjsNCiAJdm9pZCBfX2lvbWVtCQkqZGJpX2Jhc2U7DQogCXU2NAkJCWNmZzBfYmFzZTsNCi0JdTY0 CQkJY2ZnMF9tb2RfYmFzZTsNCiAJdm9pZCBfX2lvbWVtCQkqdmFfY2ZnMF9iYXNlOw0KIAl1MzIJ CQljZmcwX3NpemU7DQogCXU2NAkJCWNmZzFfYmFzZTsNCi0JdTY0CQkJY2ZnMV9tb2RfYmFzZTsN CiAJdm9pZCBfX2lvbWVtCQkqdmFfY2ZnMV9iYXNlOw0KIAl1MzIJCQljZmcxX3NpemU7DQotCXU2 NAkJCWlvX2Jhc2U7DQotCXU2NAkJCWlvX21vZF9iYXNlOw0KKwlyZXNvdXJjZV9zaXplX3QJCWlv X2Jhc2U7DQogCXBoeXNfYWRkcl90CQlpb19idXNfYWRkcjsNCiAJdTMyCQkJaW9fc2l6ZTsNCiAJ dTY0CQkJbWVtX2Jhc2U7DQotCXU2NAkJCW1lbV9tb2RfYmFzZTsNCiAJcGh5c19hZGRyX3QJCW1l bV9idXNfYWRkcjsNCiAJdTMyCQkJbWVtX3NpemU7DQotCXN0cnVjdCByZXNvdXJjZQkJY2ZnOw0K LQlzdHJ1Y3QgcmVzb3VyY2UJCWlvOw0KLQlzdHJ1Y3QgcmVzb3VyY2UJCW1lbTsNCi0Jc3RydWN0 IHJlc291cmNlCQlidXNuOw0KKwlzdHJ1Y3QgcmVzb3VyY2UJCSpjZmc7DQorCXN0cnVjdCByZXNv dXJjZQkJKmlvOw0KKwlzdHJ1Y3QgcmVzb3VyY2UJCSptZW07DQorCXN0cnVjdCByZXNvdXJjZQkJ KmJ1c247DQogCWludAkJCWlycTsNCiAJdTMyCQkJbGFuZXM7DQogCXN0cnVjdCBwY2llX2hvc3Rf b3BzCSpvcHM7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5j IGIvZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jDQppbmRleCBjNDlmYmRjLi5iMmM1 OWI5IDEwMDY0NA0KLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jDQorKysg Yi9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtc3BlYXIxM3h4LmMNCkBAIC0yODYsNyArMjg2LDcgQEAg c3RhdGljIGludCBzcGVhcjEzeHhfYWRkX3BjaWVfcG9ydChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwN CiAJCXJldHVybiByZXQ7DQogCX0NCiANCi0JcHAtPnJvb3RfYnVzX25yID0gLTE7DQorCXBwLT5y b290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJTkVEOw0KIAlwcC0+b3BzID0gJnNwZWFyMTN4 eF9wY2llX2hvc3Rfb3BzOw0KIA0KIAlyZXQgPSBkd19wY2llX2hvc3RfaW5pdChwcCk7DQotLSAN CjEuOS4xDQoNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBMdWNhcyBT dGFjaCBbbWFpbHRvOmwuc3RhY2hAcGVuZ3V0cm9uaXguZGVdDQo+IFNlbnQ6IFdlZG5lc2RheSwg QXVndXN0IDE5LCAyMDE1IDE6NTQgUE0NCj4gVG86IFdhbmd6aG91IChCKQ0KPiBDYzogQmpvcm4g SGVsZ2FhczsgamluZ29vaGFuMUBnbWFpbC5jb207IFByYXR5dXNoIEFuYW5kOyBBcm5kIEJlcmdt YW5uOw0KPiBsaW51eEBhcm0ubGludXgub3JnLnVrOyB0aG9tYXMucGV0YXp6b25pQGZyZWUtZWxl Y3Ryb25zLmNvbTsgR2FicmllbGUNCj4gUGFvbG9uaTsgbG9yZW56by5waWVyYWxpc2lAYXJtLmNv bTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gTGl2aXUuRHVkYXVAYXJtLmNvbTsgamFzb25AbGFr ZWRhZW1vbi5uZXQ7IHJvYmhAa2VybmVsLm9yZzsgbGludXgtDQo+IHBjaUB2Z2VyLmtlcm5lbC5v cmc7IGxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsNCj4gZGV2aWNldHJlZUB2 Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpoYW5nanVrdW87DQo+IHFp dXpoZW5mYTsgbGl1ZG9uZ2RvbmcgKEMpOyBxaXVqaWFuZzsgeHV3ZWkgKE8pOyBMaWd1b3podSAo S2VubmV0aCkNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVzaWdud2FyZTog QWRkIEFSTTY0IHN1cHBvcnQNCj4gDQo+IEFtIE1vbnRhZywgZGVuIDE3LjA4LjIwMTUsIDE5OjU1 ICswODAwIHNjaHJpZWIgWmhvdSBXYW5nOg0KPiA+IFRoaXMgcGF0Y2ggdHJpZXMgdG8gdW5pZnkg QVJNMzIgYW5kIEFSTTY0IFBDSWUgaW4gZGVzaWdud2FyZSBkcml2ZXIuDQo+IERlbGV0ZQ0KPiA+ IGZ1bmN0aW9uIGR3X3BjaWVfc2V0dXAsIGR3X3BjaWVfc2Nhbl9idXMsIGR3X3BjaWVfbWFwX2ly cSBhbmQgc3RydWN0DQo+IGh3X3BjaSwNCj4gPiBtb3ZlIHJlbGF0ZWQgb3BlcmF0aW9ucyB0byBk d19wY2llX2hvc3RfaW5pdC4NCj4gPg0KPiA+IEluIHBhc3QsIHdlIHVzZToNCj4gPiBwY2lfY29t bW9uX2luaXRfZGV2DQo+ID4gCS0+IHBjaWJpb3NfaW5pdF9odw0KPiA+IAkJLT4gaHctPnNjYW4g KGR3X3BjaWVfc2Nhbl9idXMpDQo+ID4gdG8gcGFzcyAwIHRvIHJvb3RfYnVzX25yIGluIHN0cnVj dCBwY2llX3BvcnQuIFRoaXMgcGF0Y2ggc2V0IHBwLQ0KPiA+cm9vdF9idXNfbnIgPSAwDQo+ID4g aW4gZWFjaCBQQ0llIGhvc3QgZHJpdmVyIHdoaWNoIGlzIGJhc2VkIG9uIHBjaWUtZGVzaWdud2Fy ZS4NCj4gPg0KPiBUaGlzIGlzIGluY29ycmVjdCBhdCBsZWFzdCBpZiB0aGVyZSBhcmUgMiBpbnN0 YW5jZXMgb2YgRFcgUENJZSBob3N0IGluDQo+IHRoZSBzYW1lIFNvQyB3aXRob3V0IHVzaW5nIFBD SSBkb21haW5zLiBJbiB0aGF0IHRoZSBjYXNlIHRoZSBidXMgcmFuZ2UNCj4gZGV0ZXJtaW5lcyB0 aGUgcmFuZ2Ugb2YgdmFsaWQgYnVzIG51bWJlcnMgcGVyIGluc3RhbmNlIGFuZCB0aGUgZmlyc3QN Cj4gbnVtYmVyIGlzIHRoZSByb290IGJ1cy4gUGxlYXNlIGxvb2sgYXQgdGhlICJidXMtcmFuZ2Ui IERUIHByb3BlcnR5IGluDQo+IHRoZSBEVyBQQ0llIGJpbmRpbmdzLg0KPiANCj4gQWxzbyB3ZSBz aG91bGQgZmluYWxseSByZW1vdmUgdGhpcyByb290LWJ1cyBzZXR1cCBmcm9tIHRoZSBnbHVlIGRy aXZlcnMNCj4gYWx0b2dldGhlci4gSXQncyBzb21ldGhpbmcgdGhhdCBlbnRpcmVseSBiZWxvbmdz IGludG8gdGhlIERXIGNvcmUgY29kZS4NCj4gDQo+IFJlZ2FyZHMsDQo+IEx1Y2FzDQo+IA0KPiA+ IFRoaXMgcGF0Y2ggYWxzbyB0cnkgdG8gdXNlIG9mX3BjaV9nZXRfaG9zdF9icmlkZ2VfcmVzb3Vy Y2VzIGZvciBBUk0zMg0KPiBhbmQgQVJNNjQNCj4gPiBhY2NvcmRpbmcgdG8gdGhlIHN1Z2dlc3Rp b24gZm9yIEdhYnJpZWxlWzFdDQo+ID4NCj4gPiBGaW5hbGx5IHRoaXMgcGF0Y2ggcmV2ZXJ0cyBj b21taXQgZjRjNTVjNWEzZjdmICJQQ0k6IGRlc2lnbndhcmU6DQo+IFByb2dyYW0gQVRVDQo+ID4g d2l0aCB1bnRyYW5zbGF0ZWQgYWRkcmVzcyIgYmFzZWQgb24gMS82IGluIHRoaXMgc2VyaWVzLiB3 ZSBkZWxldGUNCj4gKl9tb2RfYmFzZSBpbg0KPiA+IHBjaWUtZGVzaWdud2FyZS4gVGhpcyB3YXMg ZGlzY3Vzc2VkIGluIFsyXQ0KPiA+DQo+ID4gSSBoYXZlIGNvbXBpbGVkIHRoZSBkcml2ZXIgd2l0 aCBtdWx0aV92N19kZWZjb25maWcuIEhvd2V2ZXIsIEkgZG9uJ3QNCj4gaGF2ZQ0KPiA+IEFSTTMy IFBDSWUgcmVsYXRlZCBib2FyZCB0byBkbyB0ZXN0LiBJdCB3aWxsIGJlIGFwcHJlY2lhdGVkIGlm DQo+IHNvbWVvbmUgY291bGQNCj4gPiBoZWxwIHRvIHRlc3QgaXQuDQo+ID4NCj4gPiBTaWduZWQt b2ZmLWJ5OiBaaG91IFdhbmcgPHdhbmd6aG91MUBoaXNpbGljb24uY29tPg0KPiA+IFNpZ25lZC1v ZmYtYnk6IEdhYnJpZWxlIFBhb2xvbmkgPGdhYnJpZWxlLnBhb2xvbmlAaHVhd2VpLmNvbT4NCj4g PiBTaWduZWQtb2ZmLWJ5OiBBcm5kIEJlcmdtYW5uIDxhcm5kQGFybmRiLmRlPg0KPiA+IFRlc3Rl ZC1CeTogSmFtZXMgTW9yc2UgPGphbWVzLm1vcnNlQGFybS5jb20+DQo+ID4NCj4gPiBbMV0gaHR0 cDovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51eC1wY2kvbXNnNDIxOTQuaHRtbA0KPiA+IFsy XSBodHRwOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL2FybS1rZXJuZWwvbXNnNDM2Nzc5Lmh0bWwN Cj4gPiAtLS0NCj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4LmMgICAgICB8ICAxNSAr LS0NCj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2ktZXh5bm9zLmMgICAgICB8ICAgMiArLQ0KPiA+ ICBkcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMgICAgICAgIHwgICAyICstDQo+ID4gIGRyaXZl cnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMgfCAgIDIgKy0NCj4gPiAgZHJpdmVycy9wY2kv aG9zdC9wY2kta2V5c3RvbmUuYyAgICB8ICAgMiArLQ0KPiA+ICBkcml2ZXJzL3BjaS9ob3N0L3Bj aS1sYXllcnNjYXBlLmMgIHwgICAyICstDQo+ID4gIGRyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNp Z253YXJlLmMgfCAyMjkgKysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0tDQo+IC0tLS0tLS0tLS0N Cj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaCB8ICAxNCArLS0NCj4gPiAg ZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jICB8ICAgMiArLQ0KPiA+ICA5IGZpbGVz IGNoYW5nZWQsIDk1IGluc2VydGlvbnMoKyksIDE3NSBkZWxldGlvbnMoLSkNCj4gPg0KPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYyBiL2RyaXZlcnMvcGNpL2hv c3QvcGNpLQ0KPiBkcmE3eHguYw0KPiA+IGluZGV4IDE4YWU3ZmYuLjEyNjhjNjkgMTAwNjQ0DQo+ ID4gLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4LmMNCj4gPiArKysgYi9kcml2ZXJz L3BjaS9ob3N0L3BjaS1kcmE3eHguYw0KPiA+IEBAIC0xNDEsMTUgKzE0MSwxNSBAQCBzdGF0aWMg dm9pZCBkcmE3eHhfcGNpZV9ob3N0X2luaXQoc3RydWN0DQo+IHBjaWVfcG9ydCAqcHApDQo+ID4g IHsNCj4gPiAgCWR3X3BjaWVfc2V0dXBfcmMocHApOw0KPiA+DQo+ID4gLQlpZiAocHAtPmlvX21v ZF9iYXNlKQ0KPiA+IC0JCXBwLT5pb19tb2RfYmFzZSAmPSBDUFVfVE9fQlVTX0FERFI7DQo+ID4g KwlpZiAocHAtPmlvX2Jhc2UpDQo+ID4gKwkJcHAtPmlvX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERS Ow0KPiA+DQo+ID4gLQlpZiAocHAtPm1lbV9tb2RfYmFzZSkNCj4gPiAtCQlwcC0+bWVtX21vZF9i YXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPiArCWlmIChwcC0+bWVtX2Jhc2UpDQo+ID4gKwkJ cHAtPm1lbV9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPg0KPiA+IC0JaWYgKHBwLT5jZmcw X21vZF9iYXNlKSB7DQo+ID4gLQkJcHAtPmNmZzBfbW9kX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERS Ow0KPiA+IC0JCXBwLT5jZmcxX21vZF9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPiArCWlm IChwcC0+Y2ZnMF9iYXNlKSB7DQo+ID4gKwkJcHAtPmNmZzBfYmFzZSAmPSBDUFVfVE9fQlVTX0FE RFI7DQo+ID4gKwkJcHAtPmNmZzFfYmFzZSAmPSBDUFVfVE9fQlVTX0FERFI7DQo+ID4gIAl9DQo+ ID4NCj4gPiAgCWRyYTd4eF9wY2llX2VzdGFibGlzaF9saW5rKHBwKTsNCj4gPiBAQCAtMjg4LDYg KzI4OCw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGRyYTd4eF9hZGRfcGNpZV9wb3J0KHN0cnVjdA0K PiBkcmE3eHhfcGNpZSAqZHJhN3h4LA0KPiA+DQo+ID4gIAlwcCA9ICZkcmE3eHgtPnBwOw0KPiA+ ICAJcHAtPmRldiA9IGRldjsNCj4gPiArCXBwLT5yb290X2J1c19uciA9IDA7DQo+ID4gIAlwcC0+ b3BzID0gJmRyYTd4eF9wY2llX2hvc3Rfb3BzOw0KPiA+DQo+ID4gIAlwcC0+aXJxID0gcGxhdGZv cm1fZ2V0X2lycShwZGV2LCAxKTsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9w Y2ktZXh5bm9zLmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS0NCj4gZXh5bm9zLmMNCj4gPiBpbmRl eCBmOWY0NjhkLi45NzcxYmIwIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNp LWV4eW5vcy5jDQo+ID4gKysrIGIvZHJpdmVycy9wY2kvaG9zdC9wY2ktZXh5bm9zLmMNCj4gPiBA QCAtNTMwLDcgKzUzMCw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGV4eW5vc19hZGRfcGNpZV9wb3J0 KHN0cnVjdA0KPiBwY2llX3BvcnQgKnBwLA0KPiA+ICAJCX0NCj4gPiAgCX0NCj4gPg0KPiA+IC0J cHAtPnJvb3RfYnVzX25yID0gLTE7DQo+ID4gKwlwcC0+cm9vdF9idXNfbnIgPSAwOw0KPiA+ICAJ cHAtPm9wcyA9ICZleHlub3NfcGNpZV9ob3N0X29wczsNCj4gPg0KPiA+ICAJcmV0ID0gZHdfcGNp ZV9ob3N0X2luaXQocHApOw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1p bXg2LmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS0NCj4gaW14Ni5jDQo+ID4gaW5kZXggMjMzYTE5 Ni4uYmVjMjU2YyAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMN Cj4gPiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMNCj4gPiBAQCAtNTUxLDcgKzU1 MSw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGlteDZfYWRkX3BjaWVfcG9ydChzdHJ1Y3QNCj4gcGNp ZV9wb3J0ICpwcCwNCj4gPiAgCQl9DQo+ID4gIAl9DQo+ID4NCj4gPiAtCXBwLT5yb290X2J1c19u ciA9IC0xOw0KPiA+ICsJcHAtPnJvb3RfYnVzX25yID0gMDsNCj4gPiAgCXBwLT5vcHMgPSAmaW14 Nl9wY2llX2hvc3Rfb3BzOw0KPiA+DQo+ID4gIAlyZXQgPSBkd19wY2llX2hvc3RfaW5pdChwcCk7 DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMNCj4g Yi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5jDQo+ID4gaW5kZXggZjM0ODkyZS4u YjFlNDEzNSAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1k dy5jDQo+ID4gKysrIGIvZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3RvbmUtZHcuYw0KPiA+IEBA IC0zMjcsNyArMzI3LDcgQEAgc3RhdGljIHZvaWQga3NfZHdfcGNpZV9jbGVhcl9kYmlfbW9kZSh2 b2lkDQo+IF9faW9tZW0gKnJlZ192aXJ0KQ0KPiA+ICB2b2lkIGtzX2R3X3BjaWVfc2V0dXBfcmNf YXBwX3JlZ3Moc3RydWN0IGtleXN0b25lX3BjaWUgKmtzX3BjaWUpDQo+ID4gIHsNCj4gPiAgCXN0 cnVjdCBwY2llX3BvcnQgKnBwID0gJmtzX3BjaWUtPnBwOw0KPiA+IC0JdTMyIHN0YXJ0ID0gcHAt Pm1lbS5zdGFydCwgZW5kID0gcHAtPm1lbS5lbmQ7DQo+ID4gKwl1MzIgc3RhcnQgPSBwcC0+bWVt LT5zdGFydCwgZW5kID0gcHAtPm1lbS0+ZW5kOw0KPiA+ICAJaW50IGksIHRyX3NpemU7DQo+ID4N Cj4gPiAgCS8qIERpc2FibGUgQkFScyBmb3IgaW5ib3VuZCBhY2Nlc3MgKi8NCj4gPiBkaWZmIC0t Z2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3RvbmUuYyBiL2RyaXZlcnMvcGNpL2hvc3Qv cGNpLQ0KPiBrZXlzdG9uZS5jDQo+ID4gaW5kZXggNzM0ZGE1OC4uODExMzgzMiAxMDA2NDQNCj4g PiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS5jDQo+ID4gKysrIGIvZHJpdmVy cy9wY2kvaG9zdC9wY2kta2V5c3RvbmUuYw0KPiA+IEBAIC0zMDksNyArMzA5LDcgQEAgc3RhdGlj IGludCBfX2luaXQga3NfYWRkX3BjaWVfcG9ydChzdHJ1Y3QNCj4ga2V5c3RvbmVfcGNpZSAqa3Nf cGNpZSwNCj4gPiAgCQkJcmV0dXJuIHJldDsNCj4gPiAgCX0NCj4gPg0KPiA+IC0JcHAtPnJvb3Rf YnVzX25yID0gLTE7DQo+ID4gKwlwcC0+cm9vdF9idXNfbnIgPSAwOw0KPiA+ICAJcHAtPm9wcyA9 ICZrZXlzdG9uZV9wY2llX2hvc3Rfb3BzOw0KPiA+ICAJcmV0ID0ga3NfZHdfcGNpZV9ob3N0X2lu aXQoa3NfcGNpZSwga3NfcGNpZS0+bXNpX2ludGNfbnApOw0KPiA+ICAJaWYgKHJldCkgew0KPiA+ IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4gYi9kcml2 ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4gPiBpbmRleCBiMjMyOGVhMS4uNzlmZjA4 YyAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4g PiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4gPiBAQCAtMTA2LDcg KzEwNiw3IEBAIHN0YXRpYyBpbnQgbHNfYWRkX3BjaWVfcG9ydChzdHJ1Y3QgbHNfcGNpZSAqcGNp ZSkNCj4gPiAgCXBwID0gJnBjaWUtPnBwOw0KPiA+ICAJcHAtPmRldiA9IHBjaWUtPmRldjsNCj4g PiAgCXBwLT5kYmlfYmFzZSA9IHBjaWUtPmRiaTsNCj4gPiAtCXBwLT5yb290X2J1c19uciA9IC0x Ow0KPiA+ICsJcHAtPnJvb3RfYnVzX25yID0gMDsNCj4gPiAgCXBwLT5vcHMgPSAmbHNfcGNpZV9o b3N0X29wczsNCj4gPg0KPiA+ICAJcmV0ID0gZHdfcGNpZV9ob3N0X2luaXQocHApOw0KPiA+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5jDQo+IGIvZHJpdmVy cy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuYw0KPiA+IGluZGV4IGM1ZDQwN2MuLmU3MWE4OGUg MTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuYw0KPiA+ ICsrKyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMNCj4gPiBAQCAtMTEsNiAr MTEsNyBAQA0KPiA+ICAgKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlv bi4NCj4gPiAgICovDQo+ID4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2hhcmRpcnEuaD4NCj4gPiAg I2luY2x1ZGUgPGxpbnV4L2lycS5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvaXJxZG9tYWluLmg+ DQo+ID4gICNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4NCj4gPiBAQCAtNjksMTYgKzcwLDcgQEAN Cj4gPiAgI2RlZmluZSBQQ0lFX0FUVV9GVU5DKHgpCQkoKCh4KSAmIDB4NykgPDwgMTYpDQo+ID4g ICNkZWZpbmUgUENJRV9BVFVfVVBQRVJfVEFSR0VUCQkweDkxQw0KPiA+DQo+ID4gLXN0YXRpYyBz dHJ1Y3QgaHdfcGNpIGR3X3BjaTsNCj4gPiAtDQo+ID4gLXN0YXRpYyB1bnNpZ25lZCBsb25nIGds b2JhbF9pb19vZmZzZXQ7DQo+ID4gLQ0KPiA+IC1zdGF0aWMgaW5saW5lIHN0cnVjdCBwY2llX3Bv cnQgKnN5c190b19wY2llKHN0cnVjdCBwY2lfc3lzX2RhdGEgKnN5cykNCj4gPiAtew0KPiA+IC0J QlVHX09OKCFzeXMtPnByaXZhdGVfZGF0YSk7DQo+ID4gLQ0KPiA+IC0JcmV0dXJuIHN5cy0+cHJp dmF0ZV9kYXRhOw0KPiA+IC19DQo+ID4gK3N0YXRpYyBzdHJ1Y3QgcGNpX29wcyBkd19wY2llX29w czsNCj4gPg0KPiA+ICBpbnQgZHdfcGNpZV9jZmdfcmVhZCh2b2lkIF9faW9tZW0gKmFkZHIsIGlu dCB3aGVyZSwgaW50IHNpemUsIHUzMg0KPiAqdmFsKQ0KPiA+ICB7DQo+ID4gQEAgLTI1NSw3ICsy NDcsNyBAQCBzdGF0aWMgdm9pZCBkd19wY2llX21zaV9zZXRfaXJxKHN0cnVjdCBwY2llX3BvcnQN Cj4gKnBwLCBpbnQgaXJxKQ0KPiA+ICBzdGF0aWMgaW50IGFzc2lnbl9pcnEoaW50IG5vX2lycXMs IHN0cnVjdCBtc2lfZGVzYyAqZGVzYywgaW50ICpwb3MpDQo+ID4gIHsNCj4gPiAgCWludCBpcnEs IHBvczAsIGk7DQo+ID4gLQlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKGRlc2Mt PmRldi0+YnVzLT5zeXNkYXRhKTsNCj4gPiArCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gZGVzYy0+ ZGV2LT5idXMtPnN5c2RhdGE7DQo+ID4NCj4gPiAgCXBvczAgPSBiaXRtYXBfZmluZF9mcmVlX3Jl Z2lvbihwcC0+bXNpX2lycV9pbl91c2UsIE1BWF9NU0lfSVJRUywNCj4gPiAgCQkJCSAgICAgICBv cmRlcl9iYXNlXzIobm9faXJxcykpOw0KPiA+IEBAIC0yOTgsNyArMjkwLDcgQEAgc3RhdGljIGlu dCBkd19tc2lfc2V0dXBfaXJxKHN0cnVjdCBtc2lfY29udHJvbGxlcg0KPiAqY2hpcCwgc3RydWN0 IHBjaV9kZXYgKnBkZXYsDQo+ID4gIHsNCj4gPiAgCWludCBpcnEsIHBvczsNCj4gPiAgCXN0cnVj dCBtc2lfbXNnIG1zZzsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUo cGRldi0+YnVzLT5zeXNkYXRhKTsNCj4gPiArCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gcGRldi0+ YnVzLT5zeXNkYXRhOw0KPiA+DQo+ID4gIAlpZiAoZGVzYy0+bXNpX2F0dHJpYi5pc19tc2l4KQ0K PiA+ICAJCXJldHVybiAtRUlOVkFMOw0KPiA+IEBAIC0zMjcsNyArMzE5LDcgQEAgc3RhdGljIHZv aWQgZHdfbXNpX3RlYXJkb3duX2lycShzdHJ1Y3QNCj4gbXNpX2NvbnRyb2xsZXIgKmNoaXAsIHVu c2lnbmVkIGludCBpcnEpDQo+ID4gIHsNCj4gPiAgCXN0cnVjdCBpcnFfZGF0YSAqZGF0YSA9IGly cV9nZXRfaXJxX2RhdGEoaXJxKTsNCj4gPiAgCXN0cnVjdCBtc2lfZGVzYyAqbXNpID0gaXJxX2Rh dGFfZ2V0X21zaShkYXRhKTsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3Bj aWUobXNpLT5kZXYtPmJ1cy0+c3lzZGF0YSk7DQo+ID4gKwlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9 IG1zaS0+ZGV2LT5idXMtPnN5c2RhdGE7DQo+ID4NCj4gPiAgCWNsZWFyX2lycV9yYW5nZShwcCwg aXJxLCAxLCBkYXRhLT5od2lycSk7DQo+ID4gIH0NCj4gPiBAQCAtMzYzLDE0ICszNTUsMTIgQEAg aW50IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KPiA+ICB7DQo+ID4g IAlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wID0gcHAtPmRldi0+b2Zfbm9kZTsNCj4gPiAgCXN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYgPSB0b19wbGF0Zm9ybV9kZXZpY2UocHAtPmRldik7DQo+ ID4gLQlzdHJ1Y3Qgb2ZfcGNpX3JhbmdlIHJhbmdlOw0KPiA+IC0Jc3RydWN0IG9mX3BjaV9yYW5n ZV9wYXJzZXIgcGFyc2VyOw0KPiA+ICsJc3RydWN0IHBjaV9idXMgKmJ1czsNCj4gPiAgCXN0cnVj dCByZXNvdXJjZSAqY2ZnX3JlczsNCj4gPiAtCXUzMiB2YWwsIG5zOw0KPiA+IC0JY29uc3QgX19i ZTMyICphZGRycDsNCj4gPiAtCWludCBpLCBpbmRleCwgcmV0Ow0KPiA+IC0NCj4gPiAtCW5zID0g b2Zfbl9zaXplX2NlbGxzKG5wKTsNCj4gPiArCUxJU1RfSEVBRChyZXMpOw0KPiA+ICsJdTMyIHZh bDsNCj4gPiArCWludCBpLCByZXQ7DQo+ID4gKwlzdHJ1Y3QgcmVzb3VyY2VfZW50cnkgKndpbjsN Cj4gPg0KPiA+ICAJY2ZnX3JlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZV9ieW5hbWUocGRldiwg SU9SRVNPVVJDRV9NRU0sDQo+ICJjb25maWciKTsNCj4gPiAgCWlmIChjZmdfcmVzKSB7DQo+ID4g QEAgLTM3OCw4NSArMzY4LDYwIEBAIGludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9w b3J0ICpwcCkNCj4gPiAgCQlwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6ZShjZmdfcmVzKS8y Ow0KPiA+ICAJCXBwLT5jZmcwX2Jhc2UgPSBjZmdfcmVzLT5zdGFydDsNCj4gPiAgCQlwcC0+Y2Zn MV9iYXNlID0gY2ZnX3Jlcy0+c3RhcnQgKyBwcC0+Y2ZnMF9zaXplOw0KPiA+IC0NCj4gPiAtCQkv KiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgY29uZmlndXJhdGlvbiBzcGFjZSBhZGRyZXNzICovDQo+ ID4gLQkJaW5kZXggPSBvZl9wcm9wZXJ0eV9tYXRjaF9zdHJpbmcobnAsICJyZWctbmFtZXMiLCAi Y29uZmlnIik7DQo+ID4gLQkJYWRkcnAgPSBvZl9nZXRfYWRkcmVzcyhucCwgaW5kZXgsIE5VTEws IE5VTEwpOw0KPiA+IC0JCXBwLT5jZmcwX21vZF9iYXNlID0gb2ZfcmVhZF9udW1iZXIoYWRkcnAs IG5zKTsNCj4gPiAtCQlwcC0+Y2ZnMV9tb2RfYmFzZSA9IHBwLT5jZmcwX21vZF9iYXNlICsgcHAt PmNmZzBfc2l6ZTsNCj4gPiAgCX0gZWxzZSB7DQo+ID4gIAkJZGV2X2VycihwcC0+ZGV2LCAibWlz c2luZyAqY29uZmlnKiByZWcgc3BhY2VcbiIpOw0KPiA+ICAJfQ0KPiA+DQo+ID4gLQlpZiAob2Zf cGNpX3JhbmdlX3BhcnNlcl9pbml0KCZwYXJzZXIsIG5wKSkgew0KPiA+IC0JCWRldl9lcnIocHAt PmRldiwgIm1pc3NpbmcgcmFuZ2VzIHByb3BlcnR5XG4iKTsNCj4gPiAtCQlyZXR1cm4gLUVJTlZB TDsNCj4gPiAtCX0NCj4gPiArCXJldCA9IG9mX3BjaV9nZXRfaG9zdF9icmlkZ2VfcmVzb3VyY2Vz KG5wLCAwLCAweGZmLCAmcmVzLCAmcHAtDQo+ID5pb19iYXNlKTsNCj4gPiArCWlmIChyZXQpDQo+ ID4gKwkJcmV0dXJuIHJldDsNCj4gPg0KPiA+ICAJLyogR2V0IHRoZSBJL08gYW5kIG1lbW9yeSBy YW5nZXMgZnJvbSBEVCAqLw0KPiA+IC0JZm9yX2VhY2hfb2ZfcGNpX3JhbmdlKCZwYXJzZXIsICZy YW5nZSkgew0KPiA+IC0JCXVuc2lnbmVkIGxvbmcgcmVzdHlwZSA9IHJhbmdlLmZsYWdzICYgSU9S RVNPVVJDRV9UWVBFX0JJVFM7DQo+ID4gLQ0KPiA+IC0JCWlmIChyZXN0eXBlID09IElPUkVTT1VS Q0VfSU8pIHsNCj4gPiAtCQkJb2ZfcGNpX3JhbmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAsICZw cC0+aW8pOw0KPiA+IC0JCQlwcC0+aW8ubmFtZSA9ICJJL08iOw0KPiA+IC0JCQlwcC0+aW8uc3Rh cnQgPSBtYXhfdChyZXNvdXJjZV9zaXplX3QsDQo+ID4gLQkJCQkJICAgICBQQ0lCSU9TX01JTl9J TywNCj4gPiAtCQkJCQkgICAgIHJhbmdlLnBjaV9hZGRyICsgZ2xvYmFsX2lvX29mZnNldCk7DQo+ ID4gLQkJCXBwLT5pby5lbmQgPSBtaW5fdChyZXNvdXJjZV9zaXplX3QsDQo+ID4gLQkJCQkJICAg SU9fU1BBQ0VfTElNSVQsDQo+ID4gLQkJCQkJICAgcmFuZ2UucGNpX2FkZHIgKyByYW5nZS5zaXpl DQo+ID4gLQkJCQkJICAgKyBnbG9iYWxfaW9fb2Zmc2V0IC0gMSk7DQo+ID4gLQkJCXBwLT5pb19z aXplID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPmlvKTsNCj4gPiAtCQkJcHAtPmlvX2J1c19hZGRyID0g cmFuZ2UucGNpX2FkZHI7DQo+ID4gLQkJCXBwLT5pb19iYXNlID0gcmFuZ2UuY3B1X2FkZHI7DQo+ ID4gLQ0KPiA+IC0JCQkvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgSU8gc3BhY2UgYWRkcmVzcyAq Lw0KPiA+IC0JCQlwcC0+aW9fbW9kX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsNCj4gPiAtCQl9DQo+ ID4gLQkJaWYgKHJlc3R5cGUgPT0gSU9SRVNPVVJDRV9NRU0pIHsNCj4gPiAtCQkJb2ZfcGNpX3Jh bmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAsICZwcC0+bWVtKTsNCj4gPiAtCQkJcHAtPm1lbS5u YW1lID0gIk1FTSI7DQo+ID4gLQkJCXBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUoJnBwLT5t ZW0pOw0KPiA+IC0JCQlwcC0+bWVtX2J1c19hZGRyID0gcmFuZ2UucGNpX2FkZHI7DQo+ID4gLQ0K PiA+IC0JCQkvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgTUVNIHNwYWNlIGFkZHJlc3MgKi8NCj4g PiAtCQkJcHAtPm1lbV9tb2RfYmFzZSA9IHJhbmdlLmNwdV9hZGRyOw0KPiA+IC0JCX0NCj4gPiAt CQlpZiAocmVzdHlwZSA9PSAwKSB7DQo+ID4gLQkJCW9mX3BjaV9yYW5nZV90b19yZXNvdXJjZSgm cmFuZ2UsIG5wLCAmcHAtPmNmZyk7DQo+ID4gLQkJCXBwLT5jZmcwX3NpemUgPSByZXNvdXJjZV9z aXplKCZwcC0+Y2ZnKS8yOw0KPiA+IC0JCQlwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6ZSgm cHAtPmNmZykvMjsNCj4gPiAtCQkJcHAtPmNmZzBfYmFzZSA9IHBwLT5jZmcuc3RhcnQ7DQo+ID4g LQkJCXBwLT5jZmcxX2Jhc2UgPSBwcC0+Y2ZnLnN0YXJ0ICsgcHAtPmNmZzBfc2l6ZTsNCj4gPiAt DQo+ID4gLQkJCS8qIEZpbmQgdGhlIHVudHJhbnNsYXRlZCBjb25maWd1cmF0aW9uIHNwYWNlIGFk ZHJlc3MNCj4gKi8NCj4gPiAtCQkJcHAtPmNmZzBfbW9kX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsN Cj4gPiAtCQkJcHAtPmNmZzFfbW9kX2Jhc2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArDQo+ID4gLQkJ CQkJICAgIHBwLT5jZmcwX3NpemU7DQo+ID4gKwlyZXNvdXJjZV9saXN0X2Zvcl9lYWNoX2VudHJ5 KHdpbiwgJnJlcykgew0KPiA+ICsJCXN3aXRjaCAocmVzb3VyY2VfdHlwZSh3aW4tPnJlcykpIHsN Cj4gPiArCQljYXNlIElPUkVTT1VSQ0VfSU86DQo+ID4gKwkJCXBwLT5pbyA9IHdpbi0+cmVzOw0K PiA+ICsJCQlwcC0+aW8tPm5hbWUgPSAiSS9PIjsNCj4gPiArCQkJcHAtPmlvX3NpemUgPSByZXNv dXJjZV9zaXplKHBwLT5pbyk7DQo+ID4gKwkJCXBwLT5pb19idXNfYWRkciA9IHBwLT5pby0+c3Rh cnQgLSB3aW4tPm9mZnNldDsNCj4gPiArCQkJcmV0ID0gcGNpX3JlbWFwX2lvc3BhY2UocHAtPmlv LCBwcC0+aW9fYmFzZSk7DQo+ID4gKwkJCWlmIChyZXQpIHsNCj4gPiArCQkJCWRldl93YXJuKHBw LT5kZXYsICJlcnJvciAlZDogZmFpbGVkIHRvIG1hcA0KPiByZXNvdXJjZSAlcFJcbiIsDQo+ID4g KwkJCQkJIHJldCwgcHAtPmlvKTsNCj4gPiArCQkJCWNvbnRpbnVlOw0KPiA+ICsJCQl9DQo+ID4g KwkJCWJyZWFrOw0KPiA+ICsJCWNhc2UgSU9SRVNPVVJDRV9NRU06DQo+ID4gKwkJCXBwLT5tZW0g PSB3aW4tPnJlczsNCj4gPiArCQkJcHAtPm1lbS0+bmFtZSA9ICJNRU0iOw0KPiA+ICsJCQlwcC0+ bWVtX3NpemUgPSByZXNvdXJjZV9zaXplKHBwLT5tZW0pOw0KPiA+ICsJCQlwcC0+bWVtX2J1c19h ZGRyID0gcHAtPm1lbS0+c3RhcnQgLSB3aW4tPm9mZnNldDsNCj4gPiArCQkJYnJlYWs7DQo+ID4g KwkJY2FzZSAwOg0KPiA+ICsJCQlwcC0+Y2ZnID0gd2luLT5yZXM7DQo+ID4gKwkJCXBwLT5jZmcw X3NpemUgPSByZXNvdXJjZV9zaXplKHBwLT5jZmcpLzI7DQo+ID4gKwkJCXBwLT5jZmcxX3NpemUg PSByZXNvdXJjZV9zaXplKHBwLT5jZmcpLzI7DQo+ID4gKwkJCXBwLT5jZmcwX2Jhc2UgPSBwcC0+ Y2ZnLT5zdGFydDsNCj4gPiArCQkJcHAtPmNmZzFfYmFzZSA9IHBwLT5jZmctPnN0YXJ0ICsgcHAt PmNmZzBfc2l6ZTsNCj4gPiArCQkJYnJlYWs7DQo+ID4gKwkJY2FzZSBJT1JFU09VUkNFX0JVUzoN Cj4gPiArCQkJcHAtPmJ1c24gPSB3aW4tPnJlczsNCj4gPiArCQkJYnJlYWs7DQo+ID4gKwkJZGVm YXVsdDoNCj4gPiArCQkJY29udGludWU7DQo+ID4gIAkJfQ0KPiA+ICAJfQ0KPiA+DQo+ID4gLQly ZXQgPSBvZl9wY2lfcGFyc2VfYnVzX3JhbmdlKG5wLCAmcHAtPmJ1c24pOw0KPiA+IC0JaWYgKHJl dCA8IDApIHsNCj4gPiAtCQlwcC0+YnVzbi5uYW1lID0gbnAtPm5hbWU7DQo+ID4gLQkJcHAtPmJ1 c24uc3RhcnQgPSAwOw0KPiA+IC0JCXBwLT5idXNuLmVuZCA9IDB4ZmY7DQo+ID4gLQkJcHAtPmJ1 c24uZmxhZ3MgPSBJT1JFU09VUkNFX0JVUzsNCj4gPiAtCQlkZXZfZGJnKHBwLT5kZXYsICJmYWls ZWQgdG8gcGFyc2UgYnVzLXJhbmdlIHByb3BlcnR5OiAlZCwNCj4gdXNpbmcgZGVmYXVsdCAlcFJc biIsDQo+ID4gLQkJCXJldCwgJnBwLT5idXNuKTsNCj4gPiAtCX0NCj4gPiAtDQo+ID4gIAlpZiAo IXBwLT5kYmlfYmFzZSkgew0KPiA+IC0JCXBwLT5kYmlfYmFzZSA9IGRldm1faW9yZW1hcChwcC0+ ZGV2LCBwcC0+Y2ZnLnN0YXJ0LA0KPiA+IC0JCQkJCXJlc291cmNlX3NpemUoJnBwLT5jZmcpKTsN Cj4gPiArCQlwcC0+ZGJpX2Jhc2UgPSBkZXZtX2lvcmVtYXAocHAtPmRldiwgcHAtPmNmZy0+c3Rh cnQsDQo+ID4gKwkJCQkJcmVzb3VyY2Vfc2l6ZShwcC0+Y2ZnKSk7DQo+ID4gIAkJaWYgKCFwcC0+ ZGJpX2Jhc2UpIHsNCj4gPiAgCQkJZGV2X2VycihwcC0+ZGV2LCAiZXJyb3Igd2l0aCBpb3JlbWFw XG4iKTsNCj4gPiAgCQkJcmV0dXJuIC1FTk9NRU07DQo+ID4gIAkJfQ0KPiA+ICAJfQ0KPiA+DQo+ ID4gLQlwcC0+bWVtX2Jhc2UgPSBwcC0+bWVtLnN0YXJ0Ow0KPiA+ICsJcHAtPm1lbV9iYXNlID0g cHAtPm1lbS0+c3RhcnQ7DQo+ID4NCj4gPiAgCWlmICghcHAtPnZhX2NmZzBfYmFzZSkgew0KPiA+ ICAJCXBwLT52YV9jZmcwX2Jhc2UgPSBkZXZtX2lvcmVtYXAocHAtPmRldiwgcHAtPmNmZzBfYmFz ZSwNCj4gPiBAQCAtNTA1LDcgKzQ3MCw3IEBAIGludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3Qg cGNpZV9wb3J0ICpwcCkNCj4gPg0KPiA+ICAJaWYgKCFwcC0+b3BzLT5yZF9vdGhlcl9jb25mKQ0K PiA+ICAJCWR3X3BjaWVfcHJvZ19vdXRib3VuZF9hdHUocHAsIFBDSUVfQVRVX1JFR0lPTl9JTkRF WDEsDQo+ID4gLQkJCQkJICBQQ0lFX0FUVV9UWVBFX01FTSwgcHAtPm1lbV9tb2RfYmFzZSwNCj4g PiArCQkJCQkgIFBDSUVfQVRVX1RZUEVfTUVNLCBwcC0+bWVtX2Jhc2UsDQo+ID4gIAkJCQkJICBw cC0+bWVtX2J1c19hZGRyLCBwcC0+bWVtX3NpemUpOw0KPiA+DQo+ID4gIAlkd19wY2llX3dyX293 bl9jb25mKHBwLCBQQ0lfQkFTRV9BRERSRVNTXzAsIDQsIDApOw0KPiA+IEBAIC01MTcsMTUgKzQ4 MiwyOSBAQCBpbnQgZHdfcGNpZV9ob3N0X2luaXQoc3RydWN0IHBjaWVfcG9ydCAqcHApDQo+ID4g IAl2YWwgfD0gUE9SVF9MT0dJQ19TUEVFRF9DSEFOR0U7DQo+ID4gIAlkd19wY2llX3dyX293bl9j b25mKHBwLCBQQ0lFX0xJTktfV0lEVEhfU1BFRURfQ09OVFJPTCwgNCwgdmFsKTsNCj4gPg0KPiA+ IC0jaWZkZWYgQ09ORklHX1BDSV9NU0kNCj4gPiArCWJ1cyA9IHBjaV9jcmVhdGVfcm9vdF9idXMo cHAtPmRldiwgcHAtPnJvb3RfYnVzX25yLCAmZHdfcGNpZV9vcHMsDQo+ID4gKwkJCQkgIHBwLCAm cmVzKTsNCj4gPiArCWlmICghYnVzKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4g PiArI2lmZGVmIENPTkZJR19HRU5FUklDX01TSV9JUlFfRE9NQUlODQo+ID4gKwlidXMtPm1zaSA9 IGNvbnRhaW5lcl9vZigmcHAtPmlycV9kb21haW4sIHN0cnVjdCBtc2lfY29udHJvbGxlciwNCj4g ZG9tYWluKTsNCj4gPiArI2Vsc2UNCj4gPiAgCWR3X3BjaWVfbXNpX2NoaXAuZGV2ID0gcHAtPmRl djsNCj4gPiAtCWR3X3BjaS5tc2lfY3RybCA9ICZkd19wY2llX21zaV9jaGlwOw0KPiA+ICsJYnVz LT5tc2kgPSAmZHdfcGNpZV9tc2lfY2hpcDsNCj4gPiAgI2VuZGlmDQo+ID4NCj4gPiAtCWR3X3Bj aS5ucl9jb250cm9sbGVycyA9IDE7DQo+ID4gLQlkd19wY2kucHJpdmF0ZV9kYXRhID0gKHZvaWQg KiopJnBwOw0KPiA+ICsJcGNpX3NjYW5fY2hpbGRfYnVzKGJ1cyk7DQo+ID4gKwlpZiAocHAtPm9w cy0+c2Nhbl9idXMpDQo+ID4gKwkJcHAtPm9wcy0+c2Nhbl9idXMocHApOw0KPiA+ICsNCj4gPiAr I2lmZGVmIENPTkZJR19BUk0NCj4gPiArCS8qIHN1cHBvcnQgb2xkIGR0YnMgdGhhdCBpbmNvcnJl Y3RseSBkZXNjcmliZSBJUlFzICovDQo+ID4gKwlwY2lfZml4dXBfaXJxcyhwY2lfY29tbW9uX3N3 aXp6bGUsIG9mX2lycV9wYXJzZV9hbmRfbWFwX3BjaSk7DQo+ID4gKyNlbmRpZg0KPiA+DQo+ID4g LQlwY2lfY29tbW9uX2luaXRfZGV2KHBwLT5kZXYsICZkd19wY2kpOw0KPiA+ICsJcGNpX2Fzc2ln bl91bmFzc2lnbmVkX2J1c19yZXNvdXJjZXMoYnVzKTsNCj4gPiArCXBjaV9idXNfYWRkX2Rldmlj ZXMoYnVzKTsNCj4gPg0KPiA+ICAJcmV0dXJuIDA7DQo+ID4gIH0NCj4gPiBAQCAtNTQ0LDEyICs1 MjMsMTIgQEAgc3RhdGljIGludCBkd19wY2llX3JkX290aGVyX2NvbmYoc3RydWN0DQo+IHBjaWVf cG9ydCAqcHAsIHN0cnVjdCBwY2lfYnVzICpidXMsDQo+ID4NCj4gPiAgCWlmIChidXMtPnBhcmVu dC0+bnVtYmVyID09IHBwLT5yb290X2J1c19ucikgew0KPiA+ICAJCXR5cGUgPSBQQ0lFX0FUVV9U WVBFX0NGRzA7DQo+ID4gLQkJY3B1X2FkZHIgPSBwcC0+Y2ZnMF9tb2RfYmFzZTsNCj4gPiArCQlj cHVfYWRkciA9IHBwLT5jZmcwX2Jhc2U7DQo+ID4gIAkJY2ZnX3NpemUgPSBwcC0+Y2ZnMF9zaXpl Ow0KPiA+ICAJCXZhX2NmZ19iYXNlID0gcHAtPnZhX2NmZzBfYmFzZTsNCj4gPiAgCX0gZWxzZSB7 DQo+ID4gIAkJdHlwZSA9IFBDSUVfQVRVX1RZUEVfQ0ZHMTsNCj4gPiAtCQljcHVfYWRkciA9IHBw LT5jZmcxX21vZF9iYXNlOw0KPiA+ICsJCWNwdV9hZGRyID0gcHAtPmNmZzFfYmFzZTsNCj4gPiAg CQljZmdfc2l6ZSA9IHBwLT5jZmcxX3NpemU7DQo+ID4gIAkJdmFfY2ZnX2Jhc2UgPSBwcC0+dmFf Y2ZnMV9iYXNlOw0KPiA+ICAJfQ0KPiA+IEBAIC01NTksNyArNTM4LDcgQEAgc3RhdGljIGludCBk d19wY2llX3JkX290aGVyX2NvbmYoc3RydWN0IHBjaWVfcG9ydA0KPiAqcHAsIHN0cnVjdCBwY2lf YnVzICpidXMsDQo+ID4gIAkJCQkgIGJ1c2RldiwgY2ZnX3NpemUpOw0KPiA+ICAJcmV0ID0gZHdf cGNpZV9jZmdfcmVhZCh2YV9jZmdfYmFzZSArIGFkZHJlc3MsIHdoZXJlLCBzaXplLCB2YWwpOw0K PiA+ICAJZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVY MCwNCj4gPiAtCQkJCSAgUENJRV9BVFVfVFlQRV9JTywgcHAtPmlvX21vZF9iYXNlLA0KPiA+ICsJ CQkJICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fYmFzZSwNCj4gPiAgCQkJCSAgcHAtPmlvX2J1 c19hZGRyLCBwcC0+aW9fc2l6ZSk7DQo+ID4NCj4gPiAgCXJldHVybiByZXQ7DQo+ID4gQEAgLTU3 OSwxMiArNTU4LDEyIEBAIHN0YXRpYyBpbnQgZHdfcGNpZV93cl9vdGhlcl9jb25mKHN0cnVjdA0K PiBwY2llX3BvcnQgKnBwLCBzdHJ1Y3QgcGNpX2J1cyAqYnVzLA0KPiA+DQo+ID4gIAlpZiAoYnVz LT5wYXJlbnQtPm51bWJlciA9PSBwcC0+cm9vdF9idXNfbnIpIHsNCj4gPiAgCQl0eXBlID0gUENJ RV9BVFVfVFlQRV9DRkcwOw0KPiA+IC0JCWNwdV9hZGRyID0gcHAtPmNmZzBfbW9kX2Jhc2U7DQo+ ID4gKwkJY3B1X2FkZHIgPSBwcC0+Y2ZnMF9iYXNlOw0KPiA+ICAJCWNmZ19zaXplID0gcHAtPmNm ZzBfc2l6ZTsNCj4gPiAgCQl2YV9jZmdfYmFzZSA9IHBwLT52YV9jZmcwX2Jhc2U7DQo+ID4gIAl9 IGVsc2Ugew0KPiA+ICAJCXR5cGUgPSBQQ0lFX0FUVV9UWVBFX0NGRzE7DQo+ID4gLQkJY3B1X2Fk ZHIgPSBwcC0+Y2ZnMV9tb2RfYmFzZTsNCj4gPiArCQljcHVfYWRkciA9IHBwLT5jZmcxX2Jhc2U7 DQo+ID4gIAkJY2ZnX3NpemUgPSBwcC0+Y2ZnMV9zaXplOw0KPiA+ICAJCXZhX2NmZ19iYXNlID0g cHAtPnZhX2NmZzFfYmFzZTsNCj4gPiAgCX0NCj4gPiBAQCAtNTk0LDcgKzU3Myw3IEBAIHN0YXRp YyBpbnQgZHdfcGNpZV93cl9vdGhlcl9jb25mKHN0cnVjdCBwY2llX3BvcnQNCj4gKnBwLCBzdHJ1 Y3QgcGNpX2J1cyAqYnVzLA0KPiA+ICAJCQkJICBidXNkZXYsIGNmZ19zaXplKTsNCj4gPiAgCXJl dCA9IGR3X3BjaWVfY2ZnX3dyaXRlKHZhX2NmZ19iYXNlICsgYWRkcmVzcywgd2hlcmUsIHNpemUs IHZhbCk7DQo+ID4gIAlkd19wY2llX3Byb2dfb3V0Ym91bmRfYXR1KHBwLCBQQ0lFX0FUVV9SRUdJ T05fSU5ERVgwLA0KPiA+IC0JCQkJICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fbW9kX2Jhc2Us DQo+ID4gKwkJCQkgIFBDSUVfQVRVX1RZUEVfSU8sIHBwLT5pb19iYXNlLA0KPiA+ICAJCQkJICBw cC0+aW9fYnVzX2FkZHIsIHBwLT5pb19zaXplKTsNCj4gPg0KPiA+ICAJcmV0dXJuIHJldDsNCj4g PiBAQCAtNjI2LDcgKzYwNSw3IEBAIHN0YXRpYyBpbnQgZHdfcGNpZV92YWxpZF9jb25maWcoc3Ry dWN0IHBjaWVfcG9ydA0KPiAqcHAsDQo+ID4gIHN0YXRpYyBpbnQgZHdfcGNpZV9yZF9jb25mKHN0 cnVjdCBwY2lfYnVzICpidXMsIHUzMiBkZXZmbiwgaW50IHdoZXJlLA0KPiA+ICAJCQlpbnQgc2l6 ZSwgdTMyICp2YWwpDQo+ID4gIHsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3Rv X3BjaWUoYnVzLT5zeXNkYXRhKTsNCj4gPiArCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gYnVzLT5z eXNkYXRhOw0KPiA+ICAJaW50IHJldDsNCj4gPg0KPiA+ICAJaWYgKGR3X3BjaWVfdmFsaWRfY29u ZmlnKHBwLCBidXMsIFBDSV9TTE9UKGRldmZuKSkgPT0gMCkgew0KPiA+IEBAIC02NTAsNyArNjI5 LDcgQEAgc3RhdGljIGludCBkd19wY2llX3JkX2NvbmYoc3RydWN0IHBjaV9idXMgKmJ1cywNCj4g dTMyIGRldmZuLCBpbnQgd2hlcmUsDQo+ID4gIHN0YXRpYyBpbnQgZHdfcGNpZV93cl9jb25mKHN0 cnVjdCBwY2lfYnVzICpidXMsIHUzMiBkZXZmbiwNCj4gPiAgCQkJaW50IHdoZXJlLCBpbnQgc2l6 ZSwgdTMyIHZhbCkNCj4gPiAgew0KPiA+IC0Jc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBzeXNfdG9f cGNpZShidXMtPnN5c2RhdGEpOw0KPiA+ICsJc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBidXMtPnN5 c2RhdGE7DQo+ID4gIAlpbnQgcmV0Ow0KPiA+DQo+ID4gIAlpZiAoZHdfcGNpZV92YWxpZF9jb25m aWcocHAsIGJ1cywgUENJX1NMT1QoZGV2Zm4pKSA9PSAwKQ0KPiA+IEBAIC02NzQsNjIgKzY1Myw2 IEBAIHN0YXRpYyBzdHJ1Y3QgcGNpX29wcyBkd19wY2llX29wcyA9IHsNCj4gPiAgCS53cml0ZSA9 IGR3X3BjaWVfd3JfY29uZiwNCj4gPiAgfTsNCj4gPg0KPiA+IC1zdGF0aWMgaW50IGR3X3BjaWVf c2V0dXAoaW50IG5yLCBzdHJ1Y3QgcGNpX3N5c19kYXRhICpzeXMpDQo+ID4gLXsNCj4gPiAtCXN0 cnVjdCBwY2llX3BvcnQgKnBwOw0KPiA+IC0NCj4gPiAtCXBwID0gc3lzX3RvX3BjaWUoc3lzKTsN Cj4gPiAtDQo+ID4gLQlpZiAoZ2xvYmFsX2lvX29mZnNldCA8IFNaXzFNICYmIHBwLT5pb19zaXpl ID4gMCkgew0KPiA+IC0JCXN5cy0+aW9fb2Zmc2V0ID0gZ2xvYmFsX2lvX29mZnNldCAtIHBwLT5p b19idXNfYWRkcjsNCj4gPiAtCQlwY2lfaW9yZW1hcF9pbyhnbG9iYWxfaW9fb2Zmc2V0LCBwcC0+ aW9fYmFzZSk7DQo+ID4gLQkJZ2xvYmFsX2lvX29mZnNldCArPSBTWl82NEs7DQo+ID4gLQkJcGNp X2FkZF9yZXNvdXJjZV9vZmZzZXQoJnN5cy0+cmVzb3VyY2VzLCAmcHAtPmlvLA0KPiA+IC0JCQkJ CXN5cy0+aW9fb2Zmc2V0KTsNCj4gPiAtCX0NCj4gPiAtDQo+ID4gLQlzeXMtPm1lbV9vZmZzZXQg PSBwcC0+bWVtLnN0YXJ0IC0gcHAtPm1lbV9idXNfYWRkcjsNCj4gPiAtCXBjaV9hZGRfcmVzb3Vy Y2Vfb2Zmc2V0KCZzeXMtPnJlc291cmNlcywgJnBwLT5tZW0sIHN5cy0NCj4gPm1lbV9vZmZzZXQp Ow0KPiA+IC0JcGNpX2FkZF9yZXNvdXJjZSgmc3lzLT5yZXNvdXJjZXMsICZwcC0+YnVzbik7DQo+ ID4gLQ0KPiA+IC0JcmV0dXJuIDE7DQo+ID4gLX0NCj4gPiAtDQo+ID4gLXN0YXRpYyBzdHJ1Y3Qg cGNpX2J1cyAqZHdfcGNpZV9zY2FuX2J1cyhpbnQgbnIsIHN0cnVjdCBwY2lfc3lzX2RhdGENCj4g KnN5cykNCj4gPiAtew0KPiA+IC0Jc3RydWN0IHBjaV9idXMgKmJ1czsNCj4gPiAtCXN0cnVjdCBw Y2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUoc3lzKTsNCj4gPiAtDQo+ID4gLQlwcC0+cm9vdF9i dXNfbnIgPSBzeXMtPmJ1c25yOw0KPiA+IC0JYnVzID0gcGNpX3NjYW5fcm9vdF9idXMocHAtPmRl diwgc3lzLT5idXNuciwNCj4gPiAtCQkJCSAgJmR3X3BjaWVfb3BzLCBzeXMsICZzeXMtPnJlc291 cmNlcyk7DQo+ID4gLQlpZiAoIWJ1cykNCj4gPiAtCQlyZXR1cm4gTlVMTDsNCj4gPiAtDQo+ID4g LQlpZiAoYnVzICYmIHBwLT5vcHMtPnNjYW5fYnVzKQ0KPiA+IC0JCXBwLT5vcHMtPnNjYW5fYnVz KHBwKTsNCj4gPiAtDQo+ID4gLQlyZXR1cm4gYnVzOw0KPiA+IC19DQo+ID4gLQ0KPiA+IC1zdGF0 aWMgaW50IGR3X3BjaWVfbWFwX2lycShjb25zdCBzdHJ1Y3QgcGNpX2RldiAqZGV2LCB1OCBzbG90 LCB1OA0KPiBwaW4pDQo+ID4gLXsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3Rv X3BjaWUoZGV2LT5idXMtPnN5c2RhdGEpOw0KPiA+IC0JaW50IGlycTsNCj4gPiAtDQo+ID4gLQlp cnEgPSBvZl9pcnFfcGFyc2VfYW5kX21hcF9wY2koZGV2LCBzbG90LCBwaW4pOw0KPiA+IC0JaWYg KCFpcnEpDQo+ID4gLQkJaXJxID0gcHAtPmlycTsNCj4gPiAtDQo+ID4gLQlyZXR1cm4gaXJxOw0K PiA+IC19DQo+ID4gLQ0KPiA+IC1zdGF0aWMgc3RydWN0IGh3X3BjaSBkd19wY2kgPSB7DQo+ID4g LQkuc2V0dXAJCT0gZHdfcGNpZV9zZXR1cCwNCj4gPiAtCS5zY2FuCQk9IGR3X3BjaWVfc2Nhbl9i dXMsDQo+ID4gLQkubWFwX2lycQk9IGR3X3BjaWVfbWFwX2lycSwNCj4gPiAtfTsNCj4gPiAtDQo+ ID4gIHZvaWQgZHdfcGNpZV9zZXR1cF9yYyhzdHJ1Y3QgcGNpZV9wb3J0ICpwcCkNCj4gPiAgew0K PiA+ICAJdTMyIHZhbDsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLWRl c2lnbndhcmUuaA0KPiBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmgNCj4gPiBp bmRleCBkMGJiZDI3Li4yNjRjOTY5IDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvcGNpL2hvc3Qv cGNpZS1kZXNpZ253YXJlLmgNCj4gPiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdu d2FyZS5oDQo+ID4gQEAgLTI3LDI1ICsyNywyMSBAQCBzdHJ1Y3QgcGNpZV9wb3J0IHsNCj4gPiAg CXU4CQkJcm9vdF9idXNfbnI7DQo+ID4gIAl2b2lkIF9faW9tZW0JCSpkYmlfYmFzZTsNCj4gPiAg CXU2NAkJCWNmZzBfYmFzZTsNCj4gPiAtCXU2NAkJCWNmZzBfbW9kX2Jhc2U7DQo+ID4gIAl2b2lk IF9faW9tZW0JCSp2YV9jZmcwX2Jhc2U7DQo+ID4gIAl1MzIJCQljZmcwX3NpemU7DQo+ID4gIAl1 NjQJCQljZmcxX2Jhc2U7DQo+ID4gLQl1NjQJCQljZmcxX21vZF9iYXNlOw0KPiA+ICAJdm9pZCBf X2lvbWVtCQkqdmFfY2ZnMV9iYXNlOw0KPiA+ICAJdTMyCQkJY2ZnMV9zaXplOw0KPiA+IC0JdTY0 CQkJaW9fYmFzZTsNCj4gPiAtCXU2NAkJCWlvX21vZF9iYXNlOw0KPiA+ICsJcmVzb3VyY2Vfc2l6 ZV90CQlpb19iYXNlOw0KPiA+ICAJcGh5c19hZGRyX3QJCWlvX2J1c19hZGRyOw0KPiA+ICAJdTMy CQkJaW9fc2l6ZTsNCj4gPiAgCXU2NAkJCW1lbV9iYXNlOw0KPiA+IC0JdTY0CQkJbWVtX21vZF9i YXNlOw0KPiA+ICAJcGh5c19hZGRyX3QJCW1lbV9idXNfYWRkcjsNCj4gPiAgCXUzMgkJCW1lbV9z aXplOw0KPiA+IC0Jc3RydWN0IHJlc291cmNlCQljZmc7DQo+ID4gLQlzdHJ1Y3QgcmVzb3VyY2UJ CWlvOw0KPiA+IC0Jc3RydWN0IHJlc291cmNlCQltZW07DQo+ID4gLQlzdHJ1Y3QgcmVzb3VyY2UJ CWJ1c247DQo+ID4gKwlzdHJ1Y3QgcmVzb3VyY2UJCSpjZmc7DQo+ID4gKwlzdHJ1Y3QgcmVzb3Vy Y2UJCSppbzsNCj4gPiArCXN0cnVjdCByZXNvdXJjZQkJKm1lbTsNCj4gPiArCXN0cnVjdCByZXNv dXJjZQkJKmJ1c247DQo+ID4gIAlpbnQJCQlpcnE7DQo+ID4gIAl1MzIJCQlsYW5lczsNCj4gPiAg CXN0cnVjdCBwY2llX2hvc3Rfb3BzCSpvcHM7DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNp L2hvc3QvcGNpZS1zcGVhcjEzeHguYw0KPiBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1zcGVhcjEz eHguYw0KPiA+IGluZGV4IGM0OWZiZGMuLjAzZWIyMDQgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVy cy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jDQo+ID4gKysrIGIvZHJpdmVycy9wY2kvaG9zdC9w Y2llLXNwZWFyMTN4eC5jDQo+ID4gQEAgLTI4Niw3ICsyODYsNyBAQCBzdGF0aWMgaW50IHNwZWFy MTN4eF9hZGRfcGNpZV9wb3J0KHN0cnVjdA0KPiBwY2llX3BvcnQgKnBwLA0KPiA+ICAJCXJldHVy biByZXQ7DQo+ID4gIAl9DQo+ID4NCj4gPiAtCXBwLT5yb290X2J1c19uciA9IC0xOw0KPiA+ICsJ cHAtPnJvb3RfYnVzX25yID0gMDsNCj4gPiAgCXBwLT5vcHMgPSAmc3BlYXIxM3h4X3BjaWVfaG9z dF9vcHM7DQo+ID4NCj4gPiAgCXJldCA9IGR3X3BjaWVfaG9zdF9pbml0KHBwKTsNCj4gDQo+IC0t DQo+IFBlbmd1dHJvbml4IGUuSy4gICAgICAgICAgICAgfCBMdWNhcyBTdGFjaCAgICAgICAgICAg ICAgICAgfA0KPiBJbmR1c3RyaWFsIExpbnV4IFNvbHV0aW9ucyAgIHwgaHR0cDovL3d3dy5wZW5n dXRyb25peC5kZS8gIHwNCg0K -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi Gab, Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni: > Hi Lucas > > I have rewritten the patch to take into account multiple controllers. > > As you can see now there is a static var in dw_pcie_host_init() that tracks > the bus numbers used. This is wrong. The DT specifies the valid bus number range. You can not just assign the next free bus number to the root bus. It is perfectly valid to have a bus range of 0x00-0x10 assigned to one instance and 0x50-0xff to the next instance. Additional with PCIe hotplug you may not use the full range of the bus numbers on one instance at the first scan, but only later populate more buses when more bridges are added to the tree. > Drivers that do not specify the bus range in the DTB set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED. > Designware will check if the flag is set and will use the automatic bus range > assignment. No, please lets get rid of this assignment altogether. The glue drivers have no business in assigning the bus range. Please remove the pp->root_bus_nr assignment from all the glue drivers. "bus range" is a generic DW PCIe property, so just parse the root bus number from the DT, it is handled the same way for all the DW based PCIe drivers. The bindings specifies that if the bus range property is missing the range is 0x00-0xff, so you can default to 0 as the root bus number in that case. Also I would think this conversion warrants a patch on its own and should not be mixed in the ARM64 support patch. Regards, Lucas > Instead if the driver assigns pp->root_bus_nr according to the dtb, designwware > will use the value passed in by the driver. > Below the relevant section: > > > + static int root_bus_nr = 0; > ... > + mutex_lock(&root_bus_nr_mux); > + > + if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED) > + root_bus_nr = pp->root_bus_nr; > + > + bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops, > + pp, &res); > + if (!bus) { > + mutex_unlock(&root_bus_nr_mux); > + return -ENOMEM; > + } > + > + root_bus_nr += bus->busn_res.end + 1; > + mutex_unlock(&root_bus_nr_mux); > > Please let me know what you think... > > Many Thanks > > Gab > ---------- > > From: gabriele paoloni <gabriele.paoloni@huawei.com> > > This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci, > move related operations to dw_pcie_host_init. > Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers that > are based on designware to flag that the drivers do not read the bus > ranges from DT. > This patch also adds handling of multiple PCI domains in designware. > if the PCI host bridge driver does not specify a root bus number, in case > of multiple domains, designware will automatillay set the next domain root > bus number to the last bus number used in the last domain + 1. > > This patch also try to use of_pci_get_host_bridge_resources for ARM32 and > ARM64 according to the suggestion for Gabriele[1] > > This patch is based on Gabriele's patch about of_pci_range fix[2] > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: > Program ATU with untranslated address". This was discussed in [3] > > I have compiled the driver with multi_v7_defconfig. However, I don't have > ARM32 PCIe related board to do test. It will be appreciated if someone could > help to test it. > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html > [2] https://patchwork.ozlabs.org/patch/495018/ > [3] http://www.spinics.net/lists/arm-kernel/msg436779.html > --- > drivers/pci/host/pci-dra7xx.c | 15 +-- > drivers/pci/host/pci-exynos.c | 2 +- > drivers/pci/host/pci-imx6.c | 2 +- > drivers/pci/host/pci-keystone-dw.c | 2 +- > drivers/pci/host/pci-keystone.c | 2 +- > drivers/pci/host/pci-layerscape.c | 2 +- > drivers/pci/host/pcie-designware.c | 247 ++++++++++++++----------------------- > drivers/pci/host/pcie-designware.h | 15 +-- > drivers/pci/host/pcie-spear13xx.c | 2 +- > 9 files changed, 110 insertions(+), 179 deletions(-) > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c > index 5678b57..8d598fb 100644 > --- a/drivers/pci/host/pci-dra7xx.c > +++ b/drivers/pci/host/pci-dra7xx.c > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp) > { > dw_pcie_setup_rc(pp); > > - if (pp->io_mod_base) > - pp->io_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->io_base) > + pp->io_base &= CPU_TO_BUS_ADDR; > > - if (pp->mem_mod_base) > - pp->mem_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->mem_base) > + pp->mem_base &= CPU_TO_BUS_ADDR; > > - if (pp->cfg0_mod_base) { > - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; > - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; > + if (pp->cfg0_base) { > + pp->cfg0_base &= CPU_TO_BUS_ADDR; > + pp->cfg1_base &= CPU_TO_BUS_ADDR; > } > > dra7xx_pcie_establish_link(pp); > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, > > pp = &dra7xx->pp; > pp->dev = dev; > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > pp->ops = &dra7xx_pcie_host_ops; > > pp->irq = platform_get_irq(pdev, 1); > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c > index f9f468d..ed03a8f 100644 > --- a/drivers/pci/host/pci-exynos.c > +++ b/drivers/pci/host/pci-exynos.c > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, > } > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > pp->ops = &exynos_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c > index 233a196..0efac85 100644 > --- a/drivers/pci/host/pci-imx6.c > +++ b/drivers/pci/host/pci-imx6.c > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, > } > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > pp->ops = &imx6_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c > index f34892e..b1e4135 100644 > --- a/drivers/pci/host/pci-keystone-dw.c > +++ b/drivers/pci/host/pci-keystone-dw.c > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt) > void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) > { > struct pcie_port *pp = &ks_pcie->pp; > - u32 start = pp->mem.start, end = pp->mem.end; > + u32 start = pp->mem->start, end = pp->mem->end; > int i, tr_size; > > /* Disable BARs for inbound access */ > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c > index 734da58..b522956 100644 > --- a/drivers/pci/host/pci-keystone.c > +++ b/drivers/pci/host/pci-keystone.c > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie, > return ret; > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > pp->ops = &keystone_pcie_host_ops; > ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); > if (ret) { > diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c > index b2328ea1..dd92ffa 100644 > --- a/drivers/pci/host/pci-layerscape.c > +++ b/drivers/pci/host/pci-layerscape.c > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) > pp = &pcie->pp; > pp->dev = pcie->dev; > pp->dbi_base = pcie->dbi; > - pp->root_bus_nr = -1; > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > pp->ops = &ls_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c > index 5307b35..bd2606b 100644 > --- a/drivers/pci/host/pcie-designware.c > +++ b/drivers/pci/host/pcie-designware.c > @@ -11,6 +11,7 @@ > * published by the Free Software Foundation. > */ > > +#include <linux/hardirq.h> > #include <linux/irq.h> > #include <linux/irqdomain.h> > #include <linux/kernel.h> > @@ -69,16 +70,9 @@ > #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) > #define PCIE_ATU_UPPER_TARGET 0x91C > > -static struct hw_pci dw_pci; > +static struct pci_ops dw_pcie_ops; > > -static unsigned long global_io_offset; > - > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) > -{ > - BUG_ON(!sys->private_data); > - > - return sys->private_data; > -} > +DEFINE_MUTEX(root_bus_nr_mux); > > int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val) > { > @@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) > static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) > { > int irq, pos0, i; > - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); > + struct pcie_port *pp = desc->dev->bus->sysdata; > > pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, > order_base_2(no_irqs)); > @@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, > { > int irq, pos; > struct msi_msg msg; > - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); > + struct pcie_port *pp = pdev->bus->sysdata; > > if (desc->msi_attrib.is_msix) > return -EINVAL; > @@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) > { > struct irq_data *data = irq_get_irq_data(irq); > struct msi_desc *msi = irq_data_get_msi(data); > - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); > + struct pcie_port *pp = msi->dev->bus->sysdata; > > clear_irq_range(pp, irq, 1, data->hwirq); > } > @@ -359,22 +353,17 @@ static const struct irq_domain_ops msi_domain_ops = { > .map = dw_pcie_msi_map, > }; > > -int dw_pcie_host_init(struct pcie_port *pp) > +int __init dw_pcie_host_init(struct pcie_port *pp) > { > struct device_node *np = pp->dev->of_node; > struct platform_device *pdev = to_platform_device(pp->dev); > - struct of_pci_range range; > - struct of_pci_range_parser parser; > + struct pci_bus *bus; > struct resource *cfg_res; > - u32 val, na, ns; > - const __be32 *addrp; > - int i, index, ret; > - > - /* Find the address cell size and the number of cells in order to get > - * the untranslated address. > - */ > - of_property_read_u32(np, "#address-cells", &na); > - ns = of_n_size_cells(np); > + LIST_HEAD(res); > + u32 val; > + int i, ret; > + struct resource_entry *win; > + static int root_bus_nr = 0; > > cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); > if (cfg_res) { > @@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp) > pp->cfg1_size = resource_size(cfg_res)/2; > pp->cfg0_base = cfg_res->start; > pp->cfg1_base = cfg_res->start + pp->cfg0_size; > - > - /* Find the untranslated configuration space address */ > - index = of_property_match_string(np, "reg-names", "config"); > - addrp = of_get_address(np, index, NULL, NULL); > - pp->cfg0_mod_base = of_read_number(addrp, ns); > - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; > } else { > dev_err(pp->dev, "missing *config* reg space\n"); > } > > - if (of_pci_range_parser_init(&parser, np)) { > - dev_err(pp->dev, "missing ranges property\n"); > - return -EINVAL; > - } > + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base); > + if (ret) > + return ret; > > /* Get the I/O and memory ranges from DT */ > - for_each_of_pci_range(&parser, &range) { > - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; > - > - if (restype == IORESOURCE_IO) { > - of_pci_range_to_resource(&range, np, &pp->io); > - pp->io.name = "I/O"; > - pp->io.start = max_t(resource_size_t, > - PCIBIOS_MIN_IO, > - range.pci_addr + global_io_offset); > - pp->io.end = min_t(resource_size_t, > - IO_SPACE_LIMIT, > - range.pci_addr + range.size > - + global_io_offset - 1); > - pp->io_size = resource_size(&pp->io); > - pp->io_bus_addr = range.pci_addr; > - pp->io_base = range.cpu_addr; > - > - /* Find the untranslated IO space address */ > - pp->io_mod_base = range.cpu_addr; > - } > - if (restype == IORESOURCE_MEM) { > - of_pci_range_to_resource(&range, np, &pp->mem); > - pp->mem.name = "MEM"; > - pp->mem_size = resource_size(&pp->mem); > - pp->mem_bus_addr = range.pci_addr; > - > - /* Find the untranslated MEM space address */ > - pp->mem_mod_base = range.cpu_addr; > - } > - if (restype == 0) { > - of_pci_range_to_resource(&range, np, &pp->cfg); > - pp->cfg0_size = resource_size(&pp->cfg)/2; > - pp->cfg1_size = resource_size(&pp->cfg)/2; > - pp->cfg0_base = pp->cfg.start; > - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; > - > - /* Find the untranslated configuration space address */ > - pp->cfg0_mod_base = range.cpu_addr; > - pp->cfg1_mod_base = pp->cfg0_mod_base + > - pp->cfg0_size; > + resource_list_for_each_entry(win, &res) { > + switch (resource_type(win->res)) { > + case IORESOURCE_IO: > + pp->io = win->res; > + pp->io->name = "I/O"; > + pp->io_size = resource_size(pp->io); > + pp->io_bus_addr = pp->io->start - win->offset; > + ret = pci_remap_iospace(pp->io, pp->io_base); > + if (ret) { > + dev_warn(pp->dev, "error %d: failed to map resource %pR\n", > + ret, pp->io); > + continue; > + } > + break; > + case IORESOURCE_MEM: > + pp->mem = win->res; > + pp->mem->name = "MEM"; > + pp->mem_size = resource_size(pp->mem); > + pp->mem_bus_addr = pp->mem->start - win->offset; > + break; > + case 0: > + pp->cfg = win->res; > + pp->cfg0_size = resource_size(pp->cfg)/2; > + pp->cfg1_size = resource_size(pp->cfg)/2; > + pp->cfg0_base = pp->cfg->start; > + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; > + break; > + case IORESOURCE_BUS: > + pp->busn = win->res; > + break; > + default: > + continue; > } > } > > - ret = of_pci_parse_bus_range(np, &pp->busn); > - if (ret < 0) { > - pp->busn.name = np->name; > - pp->busn.start = 0; > - pp->busn.end = 0xff; > - pp->busn.flags = IORESOURCE_BUS; > - dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", > - ret, &pp->busn); > - } > - > if (!pp->dbi_base) { > - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, > - resource_size(&pp->cfg)); > + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, > + resource_size(pp->cfg)); > if (!pp->dbi_base) { > dev_err(pp->dev, "error with ioremap\n"); > return -ENOMEM; > } > } > > - pp->mem_base = pp->mem.start; > + pp->mem_base = pp->mem->start; > > if (!pp->va_cfg0_base) { > pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, > @@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp) > > if (!pp->ops->rd_other_conf) > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, > - PCIE_ATU_TYPE_MEM, pp->mem_mod_base, > + PCIE_ATU_TYPE_MEM, pp->mem_base, > pp->mem_bus_addr, pp->mem_size); > > dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); > @@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp) > val |= PORT_LOGIC_SPEED_CHANGE; > dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); > > -#ifdef CONFIG_PCI_MSI > dw_pcie_msi_chip.dev = pp->dev; > - dw_pci.msi_ctrl = &dw_pcie_msi_chip; > + > + mutex_lock(&root_bus_nr_mux); > + > + if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED) > + root_bus_nr = pp->root_bus_nr; > + > + bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops, > + pp, &res); > + if (!bus) { > + mutex_unlock(&root_bus_nr_mux); > + return -ENOMEM; > + } > + > + root_bus_nr += bus->busn_res.end + 1; > + mutex_unlock(&root_bus_nr_mux); > + > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); > +#else > + bus->msi = &dw_pcie_msi_chip; > #endif > > - dw_pci.nr_controllers = 1; > - dw_pci.private_data = (void **)&pp; > + pci_scan_child_bus(bus); > + if (pp->ops->scan_bus) > + pp->ops->scan_bus(pp); > + > +#ifdef CONFIG_ARM > + /* support old dtbs that incorrectly describe IRQs */ > + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); > +#endif > > - pci_common_init_dev(pp->dev, &dw_pci); > + pci_assign_unassigned_bus_resources(bus); > + pci_bus_add_devices(bus); > > return 0; > } > @@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, > > if (bus->parent->number == pp->root_bus_nr) { > type = PCIE_ATU_TYPE_CFG0; > - cpu_addr = pp->cfg0_mod_base; > + cpu_addr = pp->cfg0_base; > cfg_size = pp->cfg0_size; > va_cfg_base = pp->va_cfg0_base; > } else { > type = PCIE_ATU_TYPE_CFG1; > - cpu_addr = pp->cfg1_mod_base; > + cpu_addr = pp->cfg1_base; > cfg_size = pp->cfg1_size; > va_cfg_base = pp->va_cfg1_base; > } > @@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, > busdev, cfg_size); > ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val); > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > + PCIE_ATU_TYPE_IO, pp->io_base, > pp->io_bus_addr, pp->io_size); > > return ret; > @@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, > > if (bus->parent->number == pp->root_bus_nr) { > type = PCIE_ATU_TYPE_CFG0; > - cpu_addr = pp->cfg0_mod_base; > + cpu_addr = pp->cfg0_base; > cfg_size = pp->cfg0_size; > va_cfg_base = pp->va_cfg0_base; > } else { > type = PCIE_ATU_TYPE_CFG1; > - cpu_addr = pp->cfg1_mod_base; > + cpu_addr = pp->cfg1_base; > cfg_size = pp->cfg1_size; > va_cfg_base = pp->va_cfg1_base; > } > @@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, > busdev, cfg_size); > ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val); > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > + PCIE_ATU_TYPE_IO, pp->io_base, > pp->io_bus_addr, pp->io_size); > > return ret; > @@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp, > static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > int size, u32 *val) > { > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > + struct pcie_port *pp = bus->sysdata; > int ret; > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { > @@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, > int where, int size, u32 val) > { > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > + struct pcie_port *pp = bus->sysdata; > int ret; > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) > @@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = { > .write = dw_pcie_wr_conf, > }; > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) > -{ > - struct pcie_port *pp; > - > - pp = sys_to_pcie(sys); > - > - if (global_io_offset < SZ_1M && pp->io_size > 0) { > - sys->io_offset = global_io_offset - pp->io_bus_addr; > - pci_ioremap_io(global_io_offset, pp->io_base); > - global_io_offset += SZ_64K; > - pci_add_resource_offset(&sys->resources, &pp->io, > - sys->io_offset); > - } > - > - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; > - pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); > - pci_add_resource(&sys->resources, &pp->busn); > - > - return 1; > -} > - > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) > -{ > - struct pci_bus *bus; > - struct pcie_port *pp = sys_to_pcie(sys); > - > - pp->root_bus_nr = sys->busnr; > - bus = pci_scan_root_bus(pp->dev, sys->busnr, > - &dw_pcie_ops, sys, &sys->resources); > - if (!bus) > - return NULL; > - > - if (bus && pp->ops->scan_bus) > - pp->ops->scan_bus(pp); > - > - return bus; > -} > - > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) > -{ > - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); > - int irq; > - > - irq = of_irq_parse_and_map_pci(dev, slot, pin); > - if (!irq) > - irq = pp->irq; > - > - return irq; > -} > - > -static struct hw_pci dw_pci = { > - .setup = dw_pcie_setup, > - .scan = dw_pcie_scan_bus, > - .map_irq = dw_pcie_map_irq, > -}; > - > void dw_pcie_setup_rc(struct pcie_port *pp) > { > u32 val; > diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h > index d0bbd27..0c2a7eb 100644 > --- a/drivers/pci/host/pcie-designware.h > +++ b/drivers/pci/host/pcie-designware.h > @@ -21,31 +21,28 @@ > */ > #define MAX_MSI_IRQS 32 > #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) > +#define DW_ROOT_NR_UNDEFINED -1 > > struct pcie_port { > struct device *dev; > u8 root_bus_nr; > void __iomem *dbi_base; > u64 cfg0_base; > - u64 cfg0_mod_base; > void __iomem *va_cfg0_base; > u32 cfg0_size; > u64 cfg1_base; > - u64 cfg1_mod_base; > void __iomem *va_cfg1_base; > u32 cfg1_size; > - u64 io_base; > - u64 io_mod_base; > + resource_size_t io_base; > phys_addr_t io_bus_addr; > u32 io_size; > u64 mem_base; > - u64 mem_mod_base; > phys_addr_t mem_bus_addr; > u32 mem_size; > - struct resource cfg; > - struct resource io; > - struct resource mem; > - struct resource busn; > + struct resource *cfg; > + struct resource *io; > + struct resource *mem; > + struct resource *busn; > int irq; > u32 lanes; > struct pcie_host_ops *ops; > diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c > index c49fbdc..b2c59b9 100644 > --- a/drivers/pci/host/pcie-spear13xx.c > +++ b/drivers/pci/host/pcie-spear13xx.c > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp, > return ret; > } > > - pp->root_bus_nr = -1; > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > pp->ops = &spear13xx_pcie_host_ops; > > ret = dw_pcie_host_init(pp); > -- > 1.9.1 > > > > -----Original Message----- > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > Sent: Wednesday, August 19, 2015 1:54 PM > > To: Wangzhou (B) > > Cc: Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; Arnd Bergmann; > > linux@arm.linux.org.uk; thomas.petazzoni@free-electrons.com; Gabriele > > Paoloni; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang: > > > This patch tries to unify ARM32 and ARM64 PCIe in designware driver. > > Delete > > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct > > hw_pci, > > > move related operations to dw_pcie_host_init. > > > > > > In past, we use: > > > pci_common_init_dev > > > -> pcibios_init_hw > > > -> hw->scan (dw_pcie_scan_bus) > > > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp- > > >root_bus_nr = 0 > > > in each PCIe host driver which is based on pcie-designware. > > > > > This is incorrect at least if there are 2 instances of DW PCIe host in > > the same SoC without using PCI domains. In that the case the bus range > > determines the range of valid bus numbers per instance and the first > > number is the root bus. Please look at the "bus-range" DT property in > > the DW PCIe bindings. > > > > Also we should finally remove this root-bus setup from the glue drivers > > altogether. It's something that entirely belongs into the DW core code. > > > > Regards, > > Lucas > > > > > This patch also try to use of_pci_get_host_bridge_resources for ARM32 > > and ARM64 > > > according to the suggestion for Gabriele[1] > > > > > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: > > Program ATU > > > with untranslated address" based on 1/6 in this series. we delete > > *_mod_base in > > > pcie-designware. This was discussed in [2] > > > > > > I have compiled the driver with multi_v7_defconfig. However, I don't > > have > > > ARM32 PCIe related board to do test. It will be appreciated if > > someone could > > > help to test it. > > > > > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> > > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> > > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > > > Tested-By: James Morse <james.morse@arm.com> > > > > > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html > > > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html > > > --- > > > drivers/pci/host/pci-dra7xx.c | 15 +-- > > > drivers/pci/host/pci-exynos.c | 2 +- > > > drivers/pci/host/pci-imx6.c | 2 +- > > > drivers/pci/host/pci-keystone-dw.c | 2 +- > > > drivers/pci/host/pci-keystone.c | 2 +- > > > drivers/pci/host/pci-layerscape.c | 2 +- > > > drivers/pci/host/pcie-designware.c | 229 ++++++++++++--------------- > > ---------- > > > drivers/pci/host/pcie-designware.h | 14 +-- > > > drivers/pci/host/pcie-spear13xx.c | 2 +- > > > 9 files changed, 95 insertions(+), 175 deletions(-) > > > > > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci- > > dra7xx.c > > > index 18ae7ff..1268c69 100644 > > > --- a/drivers/pci/host/pci-dra7xx.c > > > +++ b/drivers/pci/host/pci-dra7xx.c > > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct > > pcie_port *pp) > > > { > > > dw_pcie_setup_rc(pp); > > > > > > - if (pp->io_mod_base) > > > - pp->io_mod_base &= CPU_TO_BUS_ADDR; > > > + if (pp->io_base) > > > + pp->io_base &= CPU_TO_BUS_ADDR; > > > > > > - if (pp->mem_mod_base) > > > - pp->mem_mod_base &= CPU_TO_BUS_ADDR; > > > + if (pp->mem_base) > > > + pp->mem_base &= CPU_TO_BUS_ADDR; > > > > > > - if (pp->cfg0_mod_base) { > > > - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; > > > - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; > > > + if (pp->cfg0_base) { > > > + pp->cfg0_base &= CPU_TO_BUS_ADDR; > > > + pp->cfg1_base &= CPU_TO_BUS_ADDR; > > > } > > > > > > dra7xx_pcie_establish_link(pp); > > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct > > dra7xx_pcie *dra7xx, > > > > > > pp = &dra7xx->pp; > > > pp->dev = dev; > > > + pp->root_bus_nr = 0; > > > pp->ops = &dra7xx_pcie_host_ops; > > > > > > pp->irq = platform_get_irq(pdev, 1); > > > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci- > > exynos.c > > > index f9f468d..9771bb0 100644 > > > --- a/drivers/pci/host/pci-exynos.c > > > +++ b/drivers/pci/host/pci-exynos.c > > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct > > pcie_port *pp, > > > } > > > } > > > > > > - pp->root_bus_nr = -1; > > > + pp->root_bus_nr = 0; > > > pp->ops = &exynos_pcie_host_ops; > > > > > > ret = dw_pcie_host_init(pp); > > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci- > > imx6.c > > > index 233a196..bec256c 100644 > > > --- a/drivers/pci/host/pci-imx6.c > > > +++ b/drivers/pci/host/pci-imx6.c > > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct > > pcie_port *pp, > > > } > > > } > > > > > > - pp->root_bus_nr = -1; > > > + pp->root_bus_nr = 0; > > > pp->ops = &imx6_pcie_host_ops; > > > > > > ret = dw_pcie_host_init(pp); > > > diff --git a/drivers/pci/host/pci-keystone-dw.c > > b/drivers/pci/host/pci-keystone-dw.c > > > index f34892e..b1e4135 100644 > > > --- a/drivers/pci/host/pci-keystone-dw.c > > > +++ b/drivers/pci/host/pci-keystone-dw.c > > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void > > __iomem *reg_virt) > > > void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) > > > { > > > struct pcie_port *pp = &ks_pcie->pp; > > > - u32 start = pp->mem.start, end = pp->mem.end; > > > + u32 start = pp->mem->start, end = pp->mem->end; > > > int i, tr_size; > > > > > > /* Disable BARs for inbound access */ > > > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci- > > keystone.c > > > index 734da58..8113832 100644 > > > --- a/drivers/pci/host/pci-keystone.c > > > +++ b/drivers/pci/host/pci-keystone.c > > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct > > keystone_pcie *ks_pcie, > > > return ret; > > > } > > > > > > - pp->root_bus_nr = -1; > > > + pp->root_bus_nr = 0; > > > pp->ops = &keystone_pcie_host_ops; > > > ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); > > > if (ret) { > > > diff --git a/drivers/pci/host/pci-layerscape.c > > b/drivers/pci/host/pci-layerscape.c > > > index b2328ea1..79ff08c 100644 > > > --- a/drivers/pci/host/pci-layerscape.c > > > +++ b/drivers/pci/host/pci-layerscape.c > > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) > > > pp = &pcie->pp; > > > pp->dev = pcie->dev; > > > pp->dbi_base = pcie->dbi; > > > - pp->root_bus_nr = -1; > > > + pp->root_bus_nr = 0; > > > pp->ops = &ls_pcie_host_ops; > > > > > > ret = dw_pcie_host_init(pp); > > > diff --git a/drivers/pci/host/pcie-designware.c > > b/drivers/pci/host/pcie-designware.c > > > index c5d407c..e71a88e 100644 > > > --- a/drivers/pci/host/pcie-designware.c > > > +++ b/drivers/pci/host/pcie-designware.c > > > @@ -11,6 +11,7 @@ > > > * published by the Free Software Foundation. > > > */ > > > > > > +#include <linux/hardirq.h> > > > #include <linux/irq.h> > > > #include <linux/irqdomain.h> > > > #include <linux/kernel.h> > > > @@ -69,16 +70,7 @@ > > > #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) > > > #define PCIE_ATU_UPPER_TARGET 0x91C > > > > > > -static struct hw_pci dw_pci; > > > - > > > -static unsigned long global_io_offset; > > > - > > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) > > > -{ > > > - BUG_ON(!sys->private_data); > > > - > > > - return sys->private_data; > > > -} > > > +static struct pci_ops dw_pcie_ops; > > > > > > int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 > > *val) > > > { > > > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port > > *pp, int irq) > > > static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) > > > { > > > int irq, pos0, i; > > > - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); > > > + struct pcie_port *pp = desc->dev->bus->sysdata; > > > > > > pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, > > > order_base_2(no_irqs)); > > > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller > > *chip, struct pci_dev *pdev, > > > { > > > int irq, pos; > > > struct msi_msg msg; > > > - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); > > > + struct pcie_port *pp = pdev->bus->sysdata; > > > > > > if (desc->msi_attrib.is_msix) > > > return -EINVAL; > > > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct > > msi_controller *chip, unsigned int irq) > > > { > > > struct irq_data *data = irq_get_irq_data(irq); > > > struct msi_desc *msi = irq_data_get_msi(data); > > > - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); > > > + struct pcie_port *pp = msi->dev->bus->sysdata; > > > > > > clear_irq_range(pp, irq, 1, data->hwirq); > > > } > > > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > { > > > struct device_node *np = pp->dev->of_node; > > > struct platform_device *pdev = to_platform_device(pp->dev); > > > - struct of_pci_range range; > > > - struct of_pci_range_parser parser; > > > + struct pci_bus *bus; > > > struct resource *cfg_res; > > > - u32 val, ns; > > > - const __be32 *addrp; > > > - int i, index, ret; > > > - > > > - ns = of_n_size_cells(np); > > > + LIST_HEAD(res); > > > + u32 val; > > > + int i, ret; > > > + struct resource_entry *win; > > > > > > cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > > "config"); > > > if (cfg_res) { > > > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > pp->cfg1_size = resource_size(cfg_res)/2; > > > pp->cfg0_base = cfg_res->start; > > > pp->cfg1_base = cfg_res->start + pp->cfg0_size; > > > - > > > - /* Find the untranslated configuration space address */ > > > - index = of_property_match_string(np, "reg-names", "config"); > > > - addrp = of_get_address(np, index, NULL, NULL); > > > - pp->cfg0_mod_base = of_read_number(addrp, ns); > > > - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; > > > } else { > > > dev_err(pp->dev, "missing *config* reg space\n"); > > > } > > > > > > - if (of_pci_range_parser_init(&parser, np)) { > > > - dev_err(pp->dev, "missing ranges property\n"); > > > - return -EINVAL; > > > - } > > > + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp- > > >io_base); > > > + if (ret) > > > + return ret; > > > > > > /* Get the I/O and memory ranges from DT */ > > > - for_each_of_pci_range(&parser, &range) { > > > - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; > > > - > > > - if (restype == IORESOURCE_IO) { > > > - of_pci_range_to_resource(&range, np, &pp->io); > > > - pp->io.name = "I/O"; > > > - pp->io.start = max_t(resource_size_t, > > > - PCIBIOS_MIN_IO, > > > - range.pci_addr + global_io_offset); > > > - pp->io.end = min_t(resource_size_t, > > > - IO_SPACE_LIMIT, > > > - range.pci_addr + range.size > > > - + global_io_offset - 1); > > > - pp->io_size = resource_size(&pp->io); > > > - pp->io_bus_addr = range.pci_addr; > > > - pp->io_base = range.cpu_addr; > > > - > > > - /* Find the untranslated IO space address */ > > > - pp->io_mod_base = range.cpu_addr; > > > - } > > > - if (restype == IORESOURCE_MEM) { > > > - of_pci_range_to_resource(&range, np, &pp->mem); > > > - pp->mem.name = "MEM"; > > > - pp->mem_size = resource_size(&pp->mem); > > > - pp->mem_bus_addr = range.pci_addr; > > > - > > > - /* Find the untranslated MEM space address */ > > > - pp->mem_mod_base = range.cpu_addr; > > > - } > > > - if (restype == 0) { > > > - of_pci_range_to_resource(&range, np, &pp->cfg); > > > - pp->cfg0_size = resource_size(&pp->cfg)/2; > > > - pp->cfg1_size = resource_size(&pp->cfg)/2; > > > - pp->cfg0_base = pp->cfg.start; > > > - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; > > > - > > > - /* Find the untranslated configuration space address > > */ > > > - pp->cfg0_mod_base = range.cpu_addr; > > > - pp->cfg1_mod_base = pp->cfg0_mod_base + > > > - pp->cfg0_size; > > > + resource_list_for_each_entry(win, &res) { > > > + switch (resource_type(win->res)) { > > > + case IORESOURCE_IO: > > > + pp->io = win->res; > > > + pp->io->name = "I/O"; > > > + pp->io_size = resource_size(pp->io); > > > + pp->io_bus_addr = pp->io->start - win->offset; > > > + ret = pci_remap_iospace(pp->io, pp->io_base); > > > + if (ret) { > > > + dev_warn(pp->dev, "error %d: failed to map > > resource %pR\n", > > > + ret, pp->io); > > > + continue; > > > + } > > > + break; > > > + case IORESOURCE_MEM: > > > + pp->mem = win->res; > > > + pp->mem->name = "MEM"; > > > + pp->mem_size = resource_size(pp->mem); > > > + pp->mem_bus_addr = pp->mem->start - win->offset; > > > + break; > > > + case 0: > > > + pp->cfg = win->res; > > > + pp->cfg0_size = resource_size(pp->cfg)/2; > > > + pp->cfg1_size = resource_size(pp->cfg)/2; > > > + pp->cfg0_base = pp->cfg->start; > > > + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; > > > + break; > > > + case IORESOURCE_BUS: > > > + pp->busn = win->res; > > > + break; > > > + default: > > > + continue; > > > } > > > } > > > > > > - ret = of_pci_parse_bus_range(np, &pp->busn); > > > - if (ret < 0) { > > > - pp->busn.name = np->name; > > > - pp->busn.start = 0; > > > - pp->busn.end = 0xff; > > > - pp->busn.flags = IORESOURCE_BUS; > > > - dev_dbg(pp->dev, "failed to parse bus-range property: %d, > > using default %pR\n", > > > - ret, &pp->busn); > > > - } > > > - > > > if (!pp->dbi_base) { > > > - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, > > > - resource_size(&pp->cfg)); > > > + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, > > > + resource_size(pp->cfg)); > > > if (!pp->dbi_base) { > > > dev_err(pp->dev, "error with ioremap\n"); > > > return -ENOMEM; > > > } > > > } > > > > > > - pp->mem_base = pp->mem.start; > > > + pp->mem_base = pp->mem->start; > > > > > > if (!pp->va_cfg0_base) { > > > pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, > > > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > > > > if (!pp->ops->rd_other_conf) > > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, > > > - PCIE_ATU_TYPE_MEM, pp->mem_mod_base, > > > + PCIE_ATU_TYPE_MEM, pp->mem_base, > > > pp->mem_bus_addr, pp->mem_size); > > > > > > dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); > > > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > val |= PORT_LOGIC_SPEED_CHANGE; > > > dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); > > > > > > -#ifdef CONFIG_PCI_MSI > > > + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, > > > + pp, &res); > > > + if (!bus) > > > + return -ENOMEM; > > > + > > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > > > + bus->msi = container_of(&pp->irq_domain, struct msi_controller, > > domain); > > > +#else > > > dw_pcie_msi_chip.dev = pp->dev; > > > - dw_pci.msi_ctrl = &dw_pcie_msi_chip; > > > + bus->msi = &dw_pcie_msi_chip; > > > #endif > > > > > > - dw_pci.nr_controllers = 1; > > > - dw_pci.private_data = (void **)&pp; > > > + pci_scan_child_bus(bus); > > > + if (pp->ops->scan_bus) > > > + pp->ops->scan_bus(pp); > > > + > > > +#ifdef CONFIG_ARM > > > + /* support old dtbs that incorrectly describe IRQs */ > > > + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); > > > +#endif > > > > > > - pci_common_init_dev(pp->dev, &dw_pci); > > > + pci_assign_unassigned_bus_resources(bus); > > > + pci_bus_add_devices(bus); > > > > > > return 0; > > > } > > > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct > > pcie_port *pp, struct pci_bus *bus, > > > > > > if (bus->parent->number == pp->root_bus_nr) { > > > type = PCIE_ATU_TYPE_CFG0; > > > - cpu_addr = pp->cfg0_mod_base; > > > + cpu_addr = pp->cfg0_base; > > > cfg_size = pp->cfg0_size; > > > va_cfg_base = pp->va_cfg0_base; > > > } else { > > > type = PCIE_ATU_TYPE_CFG1; > > > - cpu_addr = pp->cfg1_mod_base; > > > + cpu_addr = pp->cfg1_base; > > > cfg_size = pp->cfg1_size; > > > va_cfg_base = pp->va_cfg1_base; > > > } > > > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port > > *pp, struct pci_bus *bus, > > > busdev, cfg_size); > > > ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val); > > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > > > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > > > + PCIE_ATU_TYPE_IO, pp->io_base, > > > pp->io_bus_addr, pp->io_size); > > > > > > return ret; > > > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct > > pcie_port *pp, struct pci_bus *bus, > > > > > > if (bus->parent->number == pp->root_bus_nr) { > > > type = PCIE_ATU_TYPE_CFG0; > > > - cpu_addr = pp->cfg0_mod_base; > > > + cpu_addr = pp->cfg0_base; > > > cfg_size = pp->cfg0_size; > > > va_cfg_base = pp->va_cfg0_base; > > > } else { > > > type = PCIE_ATU_TYPE_CFG1; > > > - cpu_addr = pp->cfg1_mod_base; > > > + cpu_addr = pp->cfg1_base; > > > cfg_size = pp->cfg1_size; > > > va_cfg_base = pp->va_cfg1_base; > > > } > > > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port > > *pp, struct pci_bus *bus, > > > busdev, cfg_size); > > > ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val); > > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > > > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > > > + PCIE_ATU_TYPE_IO, pp->io_base, > > > pp->io_bus_addr, pp->io_size); > > > > > > return ret; > > > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port > > *pp, > > > static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > > > int size, u32 *val) > > > { > > > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > > > + struct pcie_port *pp = bus->sysdata; > > > int ret; > > > > > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { > > > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, > > u32 devfn, int where, > > > static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, > > > int where, int size, u32 val) > > > { > > > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > > > + struct pcie_port *pp = bus->sysdata; > > > int ret; > > > > > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) > > > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = { > > > .write = dw_pcie_wr_conf, > > > }; > > > > > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) > > > -{ > > > - struct pcie_port *pp; > > > - > > > - pp = sys_to_pcie(sys); > > > - > > > - if (global_io_offset < SZ_1M && pp->io_size > 0) { > > > - sys->io_offset = global_io_offset - pp->io_bus_addr; > > > - pci_ioremap_io(global_io_offset, pp->io_base); > > > - global_io_offset += SZ_64K; > > > - pci_add_resource_offset(&sys->resources, &pp->io, > > > - sys->io_offset); > > > - } > > > - > > > - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; > > > - pci_add_resource_offset(&sys->resources, &pp->mem, sys- > > >mem_offset); > > > - pci_add_resource(&sys->resources, &pp->busn); > > > - > > > - return 1; > > > -} > > > - > > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data > > *sys) > > > -{ > > > - struct pci_bus *bus; > > > - struct pcie_port *pp = sys_to_pcie(sys); > > > - > > > - pp->root_bus_nr = sys->busnr; > > > - bus = pci_scan_root_bus(pp->dev, sys->busnr, > > > - &dw_pcie_ops, sys, &sys->resources); > > > - if (!bus) > > > - return NULL; > > > - > > > - if (bus && pp->ops->scan_bus) > > > - pp->ops->scan_bus(pp); > > > - > > > - return bus; > > > -} > > > - > > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 > > pin) > > > -{ > > > - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); > > > - int irq; > > > - > > > - irq = of_irq_parse_and_map_pci(dev, slot, pin); > > > - if (!irq) > > > - irq = pp->irq; > > > - > > > - return irq; > > > -} > > > - > > > -static struct hw_pci dw_pci = { > > > - .setup = dw_pcie_setup, > > > - .scan = dw_pcie_scan_bus, > > > - .map_irq = dw_pcie_map_irq, > > > -}; > > > - > > > void dw_pcie_setup_rc(struct pcie_port *pp) > > > { > > > u32 val; > > > diff --git a/drivers/pci/host/pcie-designware.h > > b/drivers/pci/host/pcie-designware.h > > > index d0bbd27..264c969 100644 > > > --- a/drivers/pci/host/pcie-designware.h > > > +++ b/drivers/pci/host/pcie-designware.h > > > @@ -27,25 +27,21 @@ struct pcie_port { > > > u8 root_bus_nr; > > > void __iomem *dbi_base; > > > u64 cfg0_base; > > > - u64 cfg0_mod_base; > > > void __iomem *va_cfg0_base; > > > u32 cfg0_size; > > > u64 cfg1_base; > > > - u64 cfg1_mod_base; > > > void __iomem *va_cfg1_base; > > > u32 cfg1_size; > > > - u64 io_base; > > > - u64 io_mod_base; > > > + resource_size_t io_base; > > > phys_addr_t io_bus_addr; > > > u32 io_size; > > > u64 mem_base; > > > - u64 mem_mod_base; > > > phys_addr_t mem_bus_addr; > > > u32 mem_size; > > > - struct resource cfg; > > > - struct resource io; > > > - struct resource mem; > > > - struct resource busn; > > > + struct resource *cfg; > > > + struct resource *io; > > > + struct resource *mem; > > > + struct resource *busn; > > > int irq; > > > u32 lanes; > > > struct pcie_host_ops *ops; > > > diff --git a/drivers/pci/host/pcie-spear13xx.c > > b/drivers/pci/host/pcie-spear13xx.c > > > index c49fbdc..03eb204 100644 > > > --- a/drivers/pci/host/pcie-spear13xx.c > > > +++ b/drivers/pci/host/pcie-spear13xx.c > > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct > > pcie_port *pp, > > > return ret; > > > } > > > > > > - pp->root_bus_nr = -1; > > > + pp->root_bus_nr = 0; > > > pp->ops = &spear13xx_pcie_host_ops; > > > > > > ret = dw_pcie_host_init(pp); > > > > -- > > Pengutronix e.K. | Lucas Stach | > > Industrial Linux Solutions | http://www.pengutronix.de/ | >
Hi Lucas First of all many thanks for the quick reply, really appreciated > -----Original Message----- > From: Lucas Stach [mailto:l.stach@pengutronix.de] > Sent: Wednesday, August 19, 2015 4:37 PM > To: Gabriele Paoloni > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > Hi Gab, > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni: > > Hi Lucas > > > > I have rewritten the patch to take into account multiple controllers. > > > > As you can see now there is a static var in dw_pcie_host_init() that > tracks > > the bus numbers used. > > This is wrong. The DT specifies the valid bus number range. You can not > just assign the next free bus number to the root bus. I think this is what is being done in http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495 and currently designware assigns the root bus number in http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L730 In general I agree with you but if you look at all the current drivers based on designware none of them define the "bus-range" dtb property. Therefore doing as you say would break the current driver when we have multiple controllers...am I right? If that is the case in order to fix this in the way you say I would need to assign "bus-range" for all the PCIe drivers with multiple controllers: in this case I would split the default range evenly (that is, if we have two controllers I would define "bus-range" 0-127 and 128-255) If you think this solution is ok I can go for it. My only doubt was about touching other vendors DTBs.... > > It is perfectly valid to have a bus range of 0x00-0x10 assigned to one > instance and 0x50-0xff to the next instance. Additional with PCIe > hotplug you may not use the full range of the bus numbers on one > instance at the first scan, but only later populate more buses when > more > bridges are added to the tree. > > > Drivers that do not specify the bus range in the DTB set pp- > >root_bus_nr = DW_ROOT_NR_UNDEFINED. > > Designware will check if the flag is set and will use the automatic > bus range > > assignment. > > No, please lets get rid of this assignment altogether. The glue drivers > have no business in assigning the bus range. Please remove the > pp->root_bus_nr assignment from all the glue drivers. > > "bus range" is a generic DW PCIe property, so just parse the root bus > number from the DT, it is handled the same way for all the DW based > PCIe > drivers. The bindings specifies that if the bus range property is > missing the range is 0x00-0xff, so you can default to 0 as the root bus > number in that case. > > Also I would think this conversion warrants a patch on its own and > should not be mixed in the ARM64 support patch. > > Regards, > Lucas > > > Instead if the driver assigns pp->root_bus_nr according to the dtb, > designwware > > will use the value passed in by the driver. > > Below the relevant section: > > > > > > + static int root_bus_nr = 0; > > ... > > + mutex_lock(&root_bus_nr_mux); > > + > > + if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED) > > + root_bus_nr = pp->root_bus_nr; > > + > > + bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops, > > + pp, &res); > > + if (!bus) { > > + mutex_unlock(&root_bus_nr_mux); > > + return -ENOMEM; > > + } > > + > > + root_bus_nr += bus->busn_res.end + 1; > > + mutex_unlock(&root_bus_nr_mux); > > > > Please let me know what you think... > > > > Many Thanks > > > > Gab > > ---------- > > > > From: gabriele paoloni <gabriele.paoloni@huawei.com> > > > > This patch tries to unify ARM32 and ARM64 PCIe in designware driver. > Delete > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct > hw_pci, > > move related operations to dw_pcie_host_init. > > Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers > that > > are based on designware to flag that the drivers do not read the bus > > ranges from DT. > > This patch also adds handling of multiple PCI domains in designware. > > if the PCI host bridge driver does not specify a root bus number, in > case > > of multiple domains, designware will automatillay set the next domain > root > > bus number to the last bus number used in the last domain + 1. > > > > This patch also try to use of_pci_get_host_bridge_resources for ARM32 > and > > ARM64 according to the suggestion for Gabriele[1] > > > > This patch is based on Gabriele's patch about of_pci_range fix[2] > > > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: > > Program ATU with untranslated address". This was discussed in [3] > > > > I have compiled the driver with multi_v7_defconfig. However, I don't > have > > ARM32 PCIe related board to do test. It will be appreciated if > someone could > > help to test it. > > > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> > > > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html > > [2] https://patchwork.ozlabs.org/patch/495018/ > > [3] http://www.spinics.net/lists/arm-kernel/msg436779.html > > --- > > drivers/pci/host/pci-dra7xx.c | 15 +-- > > drivers/pci/host/pci-exynos.c | 2 +- > > drivers/pci/host/pci-imx6.c | 2 +- > > drivers/pci/host/pci-keystone-dw.c | 2 +- > > drivers/pci/host/pci-keystone.c | 2 +- > > drivers/pci/host/pci-layerscape.c | 2 +- > > drivers/pci/host/pcie-designware.c | 247 ++++++++++++++------------- > ---------- > > drivers/pci/host/pcie-designware.h | 15 +-- > > drivers/pci/host/pcie-spear13xx.c | 2 +- > > 9 files changed, 110 insertions(+), 179 deletions(-) > > > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci- > dra7xx.c > > index 5678b57..8d598fb 100644 > > --- a/drivers/pci/host/pci-dra7xx.c > > +++ b/drivers/pci/host/pci-dra7xx.c > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct > pcie_port *pp) > > { > > dw_pcie_setup_rc(pp); > > > > - if (pp->io_mod_base) > > - pp->io_mod_base &= CPU_TO_BUS_ADDR; > > + if (pp->io_base) > > + pp->io_base &= CPU_TO_BUS_ADDR; > > > > - if (pp->mem_mod_base) > > - pp->mem_mod_base &= CPU_TO_BUS_ADDR; > > + if (pp->mem_base) > > + pp->mem_base &= CPU_TO_BUS_ADDR; > > > > - if (pp->cfg0_mod_base) { > > - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; > > - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; > > + if (pp->cfg0_base) { > > + pp->cfg0_base &= CPU_TO_BUS_ADDR; > > + pp->cfg1_base &= CPU_TO_BUS_ADDR; > > } > > > > dra7xx_pcie_establish_link(pp); > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct > dra7xx_pcie *dra7xx, > > > > pp = &dra7xx->pp; > > pp->dev = dev; > > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > > pp->ops = &dra7xx_pcie_host_ops; > > > > pp->irq = platform_get_irq(pdev, 1); > > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci- > exynos.c > > index f9f468d..ed03a8f 100644 > > --- a/drivers/pci/host/pci-exynos.c > > +++ b/drivers/pci/host/pci-exynos.c > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct > pcie_port *pp, > > } > > } > > > > - pp->root_bus_nr = -1; > > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > > pp->ops = &exynos_pcie_host_ops; > > > > ret = dw_pcie_host_init(pp); > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci- > imx6.c > > index 233a196..0efac85 100644 > > --- a/drivers/pci/host/pci-imx6.c > > +++ b/drivers/pci/host/pci-imx6.c > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct > pcie_port *pp, > > } > > } > > > > - pp->root_bus_nr = -1; > > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > > pp->ops = &imx6_pcie_host_ops; > > > > ret = dw_pcie_host_init(pp); > > diff --git a/drivers/pci/host/pci-keystone-dw.c > b/drivers/pci/host/pci-keystone-dw.c > > index f34892e..b1e4135 100644 > > --- a/drivers/pci/host/pci-keystone-dw.c > > +++ b/drivers/pci/host/pci-keystone-dw.c > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void > __iomem *reg_virt) > > void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) > > { > > struct pcie_port *pp = &ks_pcie->pp; > > - u32 start = pp->mem.start, end = pp->mem.end; > > + u32 start = pp->mem->start, end = pp->mem->end; > > int i, tr_size; > > > > /* Disable BARs for inbound access */ > > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci- > keystone.c > > index 734da58..b522956 100644 > > --- a/drivers/pci/host/pci-keystone.c > > +++ b/drivers/pci/host/pci-keystone.c > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct > keystone_pcie *ks_pcie, > > return ret; > > } > > > > - pp->root_bus_nr = -1; > > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > > pp->ops = &keystone_pcie_host_ops; > > ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); > > if (ret) { > > diff --git a/drivers/pci/host/pci-layerscape.c > b/drivers/pci/host/pci-layerscape.c > > index b2328ea1..dd92ffa 100644 > > --- a/drivers/pci/host/pci-layerscape.c > > +++ b/drivers/pci/host/pci-layerscape.c > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) > > pp = &pcie->pp; > > pp->dev = pcie->dev; > > pp->dbi_base = pcie->dbi; > > - pp->root_bus_nr = -1; > > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > > pp->ops = &ls_pcie_host_ops; > > > > ret = dw_pcie_host_init(pp); > > diff --git a/drivers/pci/host/pcie-designware.c > b/drivers/pci/host/pcie-designware.c > > index 5307b35..bd2606b 100644 > > --- a/drivers/pci/host/pcie-designware.c > > +++ b/drivers/pci/host/pcie-designware.c > > @@ -11,6 +11,7 @@ > > * published by the Free Software Foundation. > > */ > > > > +#include <linux/hardirq.h> > > #include <linux/irq.h> > > #include <linux/irqdomain.h> > > #include <linux/kernel.h> > > @@ -69,16 +70,9 @@ > > #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) > > #define PCIE_ATU_UPPER_TARGET 0x91C > > > > -static struct hw_pci dw_pci; > > +static struct pci_ops dw_pcie_ops; > > > > -static unsigned long global_io_offset; > > - > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) > > -{ > > - BUG_ON(!sys->private_data); > > - > > - return sys->private_data; > > -} > > +DEFINE_MUTEX(root_bus_nr_mux); > > > > int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 > *val) > > { > > @@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port > *pp, int irq) > > static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) > > { > > int irq, pos0, i; > > - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); > > + struct pcie_port *pp = desc->dev->bus->sysdata; > > > > pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, > > order_base_2(no_irqs)); > > @@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller > *chip, struct pci_dev *pdev, > > { > > int irq, pos; > > struct msi_msg msg; > > - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); > > + struct pcie_port *pp = pdev->bus->sysdata; > > > > if (desc->msi_attrib.is_msix) > > return -EINVAL; > > @@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct > msi_controller *chip, unsigned int irq) > > { > > struct irq_data *data = irq_get_irq_data(irq); > > struct msi_desc *msi = irq_data_get_msi(data); > > - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); > > + struct pcie_port *pp = msi->dev->bus->sysdata; > > > > clear_irq_range(pp, irq, 1, data->hwirq); > > } > > @@ -359,22 +353,17 @@ static const struct irq_domain_ops > msi_domain_ops = { > > .map = dw_pcie_msi_map, > > }; > > > > -int dw_pcie_host_init(struct pcie_port *pp) > > +int __init dw_pcie_host_init(struct pcie_port *pp) > > { > > struct device_node *np = pp->dev->of_node; > > struct platform_device *pdev = to_platform_device(pp->dev); > > - struct of_pci_range range; > > - struct of_pci_range_parser parser; > > + struct pci_bus *bus; > > struct resource *cfg_res; > > - u32 val, na, ns; > > - const __be32 *addrp; > > - int i, index, ret; > > - > > - /* Find the address cell size and the number of cells in order to > get > > - * the untranslated address. > > - */ > > - of_property_read_u32(np, "#address-cells", &na); > > - ns = of_n_size_cells(np); > > + LIST_HEAD(res); > > + u32 val; > > + int i, ret; > > + struct resource_entry *win; > > + static int root_bus_nr = 0; > > > > cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > "config"); > > if (cfg_res) { > > @@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp) > > pp->cfg1_size = resource_size(cfg_res)/2; > > pp->cfg0_base = cfg_res->start; > > pp->cfg1_base = cfg_res->start + pp->cfg0_size; > > - > > - /* Find the untranslated configuration space address */ > > - index = of_property_match_string(np, "reg-names", "config"); > > - addrp = of_get_address(np, index, NULL, NULL); > > - pp->cfg0_mod_base = of_read_number(addrp, ns); > > - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; > > } else { > > dev_err(pp->dev, "missing *config* reg space\n"); > > } > > > > - if (of_pci_range_parser_init(&parser, np)) { > > - dev_err(pp->dev, "missing ranges property\n"); > > - return -EINVAL; > > - } > > + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp- > >io_base); > > + if (ret) > > + return ret; > > > > /* Get the I/O and memory ranges from DT */ > > - for_each_of_pci_range(&parser, &range) { > > - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; > > - > > - if (restype == IORESOURCE_IO) { > > - of_pci_range_to_resource(&range, np, &pp->io); > > - pp->io.name = "I/O"; > > - pp->io.start = max_t(resource_size_t, > > - PCIBIOS_MIN_IO, > > - range.pci_addr + global_io_offset); > > - pp->io.end = min_t(resource_size_t, > > - IO_SPACE_LIMIT, > > - range.pci_addr + range.size > > - + global_io_offset - 1); > > - pp->io_size = resource_size(&pp->io); > > - pp->io_bus_addr = range.pci_addr; > > - pp->io_base = range.cpu_addr; > > - > > - /* Find the untranslated IO space address */ > > - pp->io_mod_base = range.cpu_addr; > > - } > > - if (restype == IORESOURCE_MEM) { > > - of_pci_range_to_resource(&range, np, &pp->mem); > > - pp->mem.name = "MEM"; > > - pp->mem_size = resource_size(&pp->mem); > > - pp->mem_bus_addr = range.pci_addr; > > - > > - /* Find the untranslated MEM space address */ > > - pp->mem_mod_base = range.cpu_addr; > > - } > > - if (restype == 0) { > > - of_pci_range_to_resource(&range, np, &pp->cfg); > > - pp->cfg0_size = resource_size(&pp->cfg)/2; > > - pp->cfg1_size = resource_size(&pp->cfg)/2; > > - pp->cfg0_base = pp->cfg.start; > > - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; > > - > > - /* Find the untranslated configuration space address > */ > > - pp->cfg0_mod_base = range.cpu_addr; > > - pp->cfg1_mod_base = pp->cfg0_mod_base + > > - pp->cfg0_size; > > + resource_list_for_each_entry(win, &res) { > > + switch (resource_type(win->res)) { > > + case IORESOURCE_IO: > > + pp->io = win->res; > > + pp->io->name = "I/O"; > > + pp->io_size = resource_size(pp->io); > > + pp->io_bus_addr = pp->io->start - win->offset; > > + ret = pci_remap_iospace(pp->io, pp->io_base); > > + if (ret) { > > + dev_warn(pp->dev, "error %d: failed to map > resource %pR\n", > > + ret, pp->io); > > + continue; > > + } > > + break; > > + case IORESOURCE_MEM: > > + pp->mem = win->res; > > + pp->mem->name = "MEM"; > > + pp->mem_size = resource_size(pp->mem); > > + pp->mem_bus_addr = pp->mem->start - win->offset; > > + break; > > + case 0: > > + pp->cfg = win->res; > > + pp->cfg0_size = resource_size(pp->cfg)/2; > > + pp->cfg1_size = resource_size(pp->cfg)/2; > > + pp->cfg0_base = pp->cfg->start; > > + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; > > + break; > > + case IORESOURCE_BUS: > > + pp->busn = win->res; > > + break; > > + default: > > + continue; > > } > > } > > > > - ret = of_pci_parse_bus_range(np, &pp->busn); > > - if (ret < 0) { > > - pp->busn.name = np->name; > > - pp->busn.start = 0; > > - pp->busn.end = 0xff; > > - pp->busn.flags = IORESOURCE_BUS; > > - dev_dbg(pp->dev, "failed to parse bus-range property: %d, > using default %pR\n", > > - ret, &pp->busn); > > - } > > - > > if (!pp->dbi_base) { > > - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, > > - resource_size(&pp->cfg)); > > + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, > > + resource_size(pp->cfg)); > > if (!pp->dbi_base) { > > dev_err(pp->dev, "error with ioremap\n"); > > return -ENOMEM; > > } > > } > > > > - pp->mem_base = pp->mem.start; > > + pp->mem_base = pp->mem->start; > > > > if (!pp->va_cfg0_base) { > > pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, > > @@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > > if (!pp->ops->rd_other_conf) > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, > > - PCIE_ATU_TYPE_MEM, pp->mem_mod_base, > > + PCIE_ATU_TYPE_MEM, pp->mem_base, > > pp->mem_bus_addr, pp->mem_size); > > > > dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); > > @@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp) > > val |= PORT_LOGIC_SPEED_CHANGE; > > dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); > > > > -#ifdef CONFIG_PCI_MSI > > dw_pcie_msi_chip.dev = pp->dev; > > - dw_pci.msi_ctrl = &dw_pcie_msi_chip; > > + > > + mutex_lock(&root_bus_nr_mux); > > + > > + if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED) > > + root_bus_nr = pp->root_bus_nr; > > + > > + bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops, > > + pp, &res); > > + if (!bus) { > > + mutex_unlock(&root_bus_nr_mux); > > + return -ENOMEM; > > + } > > + > > + root_bus_nr += bus->busn_res.end + 1; > > + mutex_unlock(&root_bus_nr_mux); > > + > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > > + bus->msi = container_of(&pp->irq_domain, struct msi_controller, > domain); > > +#else > > + bus->msi = &dw_pcie_msi_chip; > > #endif > > > > - dw_pci.nr_controllers = 1; > > - dw_pci.private_data = (void **)&pp; > > + pci_scan_child_bus(bus); > > + if (pp->ops->scan_bus) > > + pp->ops->scan_bus(pp); > > + > > +#ifdef CONFIG_ARM > > + /* support old dtbs that incorrectly describe IRQs */ > > + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); > > +#endif > > > > - pci_common_init_dev(pp->dev, &dw_pci); > > + pci_assign_unassigned_bus_resources(bus); > > + pci_bus_add_devices(bus); > > > > return 0; > > } > > @@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct > pcie_port *pp, struct pci_bus *bus, > > > > if (bus->parent->number == pp->root_bus_nr) { > > type = PCIE_ATU_TYPE_CFG0; > > - cpu_addr = pp->cfg0_mod_base; > > + cpu_addr = pp->cfg0_base; > > cfg_size = pp->cfg0_size; > > va_cfg_base = pp->va_cfg0_base; > > } else { > > type = PCIE_ATU_TYPE_CFG1; > > - cpu_addr = pp->cfg1_mod_base; > > + cpu_addr = pp->cfg1_base; > > cfg_size = pp->cfg1_size; > > va_cfg_base = pp->va_cfg1_base; > > } > > @@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port > *pp, struct pci_bus *bus, > > busdev, cfg_size); > > ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val); > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > > + PCIE_ATU_TYPE_IO, pp->io_base, > > pp->io_bus_addr, pp->io_size); > > > > return ret; > > @@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct > pcie_port *pp, struct pci_bus *bus, > > > > if (bus->parent->number == pp->root_bus_nr) { > > type = PCIE_ATU_TYPE_CFG0; > > - cpu_addr = pp->cfg0_mod_base; > > + cpu_addr = pp->cfg0_base; > > cfg_size = pp->cfg0_size; > > va_cfg_base = pp->va_cfg0_base; > > } else { > > type = PCIE_ATU_TYPE_CFG1; > > - cpu_addr = pp->cfg1_mod_base; > > + cpu_addr = pp->cfg1_base; > > cfg_size = pp->cfg1_size; > > va_cfg_base = pp->va_cfg1_base; > > } > > @@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port > *pp, struct pci_bus *bus, > > busdev, cfg_size); > > ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val); > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > > + PCIE_ATU_TYPE_IO, pp->io_base, > > pp->io_bus_addr, pp->io_size); > > > > return ret; > > @@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port > *pp, > > static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, > > int size, u32 *val) > > { > > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > > + struct pcie_port *pp = bus->sysdata; > > int ret; > > > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { > > @@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, > u32 devfn, int where, > > static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, > > int where, int size, u32 val) > > { > > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > > + struct pcie_port *pp = bus->sysdata; > > int ret; > > > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) > > @@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = { > > .write = dw_pcie_wr_conf, > > }; > > > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) > > -{ > > - struct pcie_port *pp; > > - > > - pp = sys_to_pcie(sys); > > - > > - if (global_io_offset < SZ_1M && pp->io_size > 0) { > > - sys->io_offset = global_io_offset - pp->io_bus_addr; > > - pci_ioremap_io(global_io_offset, pp->io_base); > > - global_io_offset += SZ_64K; > > - pci_add_resource_offset(&sys->resources, &pp->io, > > - sys->io_offset); > > - } > > - > > - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; > > - pci_add_resource_offset(&sys->resources, &pp->mem, sys- > >mem_offset); > > - pci_add_resource(&sys->resources, &pp->busn); > > - > > - return 1; > > -} > > - > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data > *sys) > > -{ > > - struct pci_bus *bus; > > - struct pcie_port *pp = sys_to_pcie(sys); > > - > > - pp->root_bus_nr = sys->busnr; > > - bus = pci_scan_root_bus(pp->dev, sys->busnr, > > - &dw_pcie_ops, sys, &sys->resources); > > - if (!bus) > > - return NULL; > > - > > - if (bus && pp->ops->scan_bus) > > - pp->ops->scan_bus(pp); > > - > > - return bus; > > -} > > - > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 > pin) > > -{ > > - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); > > - int irq; > > - > > - irq = of_irq_parse_and_map_pci(dev, slot, pin); > > - if (!irq) > > - irq = pp->irq; > > - > > - return irq; > > -} > > - > > -static struct hw_pci dw_pci = { > > - .setup = dw_pcie_setup, > > - .scan = dw_pcie_scan_bus, > > - .map_irq = dw_pcie_map_irq, > > -}; > > - > > void dw_pcie_setup_rc(struct pcie_port *pp) > > { > > u32 val; > > diff --git a/drivers/pci/host/pcie-designware.h > b/drivers/pci/host/pcie-designware.h > > index d0bbd27..0c2a7eb 100644 > > --- a/drivers/pci/host/pcie-designware.h > > +++ b/drivers/pci/host/pcie-designware.h > > @@ -21,31 +21,28 @@ > > */ > > #define MAX_MSI_IRQS 32 > > #define MAX_MSI_CTRLS (MAX_MSI_IRQS / 32) > > +#define DW_ROOT_NR_UNDEFINED -1 > > > > struct pcie_port { > > struct device *dev; > > u8 root_bus_nr; > > void __iomem *dbi_base; > > u64 cfg0_base; > > - u64 cfg0_mod_base; > > void __iomem *va_cfg0_base; > > u32 cfg0_size; > > u64 cfg1_base; > > - u64 cfg1_mod_base; > > void __iomem *va_cfg1_base; > > u32 cfg1_size; > > - u64 io_base; > > - u64 io_mod_base; > > + resource_size_t io_base; > > phys_addr_t io_bus_addr; > > u32 io_size; > > u64 mem_base; > > - u64 mem_mod_base; > > phys_addr_t mem_bus_addr; > > u32 mem_size; > > - struct resource cfg; > > - struct resource io; > > - struct resource mem; > > - struct resource busn; > > + struct resource *cfg; > > + struct resource *io; > > + struct resource *mem; > > + struct resource *busn; > > int irq; > > u32 lanes; > > struct pcie_host_ops *ops; > > diff --git a/drivers/pci/host/pcie-spear13xx.c > b/drivers/pci/host/pcie-spear13xx.c > > index c49fbdc..b2c59b9 100644 > > --- a/drivers/pci/host/pcie-spear13xx.c > > +++ b/drivers/pci/host/pcie-spear13xx.c > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct > pcie_port *pp, > > return ret; > > } > > > > - pp->root_bus_nr = -1; > > + pp->root_bus_nr = DW_ROOT_NR_UNDEFINED; > > pp->ops = &spear13xx_pcie_host_ops; > > > > ret = dw_pcie_host_init(pp); > > -- > > 1.9.1 > > > > > > > -----Original Message----- > > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > > Sent: Wednesday, August 19, 2015 1:54 PM > > > To: Wangzhou (B) > > > Cc: Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; Arnd > Bergmann; > > > linux@arm.linux.org.uk; thomas.petazzoni@free-electrons.com; > Gabriele > > > Paoloni; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > > > Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang: > > > > This patch tries to unify ARM32 and ARM64 PCIe in designware > driver. > > > Delete > > > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and > struct > > > hw_pci, > > > > move related operations to dw_pcie_host_init. > > > > > > > > In past, we use: > > > > pci_common_init_dev > > > > -> pcibios_init_hw > > > > -> hw->scan (dw_pcie_scan_bus) > > > > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp- > > > >root_bus_nr = 0 > > > > in each PCIe host driver which is based on pcie-designware. > > > > > > > This is incorrect at least if there are 2 instances of DW PCIe host > in > > > the same SoC without using PCI domains. In that the case the bus > range > > > determines the range of valid bus numbers per instance and the > first > > > number is the root bus. Please look at the "bus-range" DT property > in > > > the DW PCIe bindings. > > > > > > Also we should finally remove this root-bus setup from the glue > drivers > > > altogether. It's something that entirely belongs into the DW core > code. > > > > > > Regards, > > > Lucas > > > > > > > This patch also try to use of_pci_get_host_bridge_resources for > ARM32 > > > and ARM64 > > > > according to the suggestion for Gabriele[1] > > > > > > > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: > > > Program ATU > > > > with untranslated address" based on 1/6 in this series. we delete > > > *_mod_base in > > > > pcie-designware. This was discussed in [2] > > > > > > > > I have compiled the driver with multi_v7_defconfig. However, I > don't > > > have > > > > ARM32 PCIe related board to do test. It will be appreciated if > > > someone could > > > > help to test it. > > > > > > > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com> > > > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com> > > > > Signed-off-by: Arnd Bergmann <arnd@arndb.de> > > > > Tested-By: James Morse <james.morse@arm.com> > > > > > > > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html > > > > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html > > > > --- > > > > drivers/pci/host/pci-dra7xx.c | 15 +-- > > > > drivers/pci/host/pci-exynos.c | 2 +- > > > > drivers/pci/host/pci-imx6.c | 2 +- > > > > drivers/pci/host/pci-keystone-dw.c | 2 +- > > > > drivers/pci/host/pci-keystone.c | 2 +- > > > > drivers/pci/host/pci-layerscape.c | 2 +- > > > > drivers/pci/host/pcie-designware.c | 229 ++++++++++++----------- > ---- > > > ---------- > > > > drivers/pci/host/pcie-designware.h | 14 +-- > > > > drivers/pci/host/pcie-spear13xx.c | 2 +- > > > > 9 files changed, 95 insertions(+), 175 deletions(-) > > > > > > > > diff --git a/drivers/pci/host/pci-dra7xx.c > b/drivers/pci/host/pci- > > > dra7xx.c > > > > index 18ae7ff..1268c69 100644 > > > > --- a/drivers/pci/host/pci-dra7xx.c > > > > +++ b/drivers/pci/host/pci-dra7xx.c > > > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct > > > pcie_port *pp) > > > > { > > > > dw_pcie_setup_rc(pp); > > > > > > > > - if (pp->io_mod_base) > > > > - pp->io_mod_base &= CPU_TO_BUS_ADDR; > > > > + if (pp->io_base) > > > > + pp->io_base &= CPU_TO_BUS_ADDR; > > > > > > > > - if (pp->mem_mod_base) > > > > - pp->mem_mod_base &= CPU_TO_BUS_ADDR; > > > > + if (pp->mem_base) > > > > + pp->mem_base &= CPU_TO_BUS_ADDR; > > > > > > > > - if (pp->cfg0_mod_base) { > > > > - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; > > > > - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; > > > > + if (pp->cfg0_base) { > > > > + pp->cfg0_base &= CPU_TO_BUS_ADDR; > > > > + pp->cfg1_base &= CPU_TO_BUS_ADDR; > > > > } > > > > > > > > dra7xx_pcie_establish_link(pp); > > > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct > > > dra7xx_pcie *dra7xx, > > > > > > > > pp = &dra7xx->pp; > > > > pp->dev = dev; > > > > + pp->root_bus_nr = 0; > > > > pp->ops = &dra7xx_pcie_host_ops; > > > > > > > > pp->irq = platform_get_irq(pdev, 1); > > > > diff --git a/drivers/pci/host/pci-exynos.c > b/drivers/pci/host/pci- > > > exynos.c > > > > index f9f468d..9771bb0 100644 > > > > --- a/drivers/pci/host/pci-exynos.c > > > > +++ b/drivers/pci/host/pci-exynos.c > > > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct > > > pcie_port *pp, > > > > } > > > > } > > > > > > > > - pp->root_bus_nr = -1; > > > > + pp->root_bus_nr = 0; > > > > pp->ops = &exynos_pcie_host_ops; > > > > > > > > ret = dw_pcie_host_init(pp); > > > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci- > > > imx6.c > > > > index 233a196..bec256c 100644 > > > > --- a/drivers/pci/host/pci-imx6.c > > > > +++ b/drivers/pci/host/pci-imx6.c > > > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct > > > pcie_port *pp, > > > > } > > > > } > > > > > > > > - pp->root_bus_nr = -1; > > > > + pp->root_bus_nr = 0; > > > > pp->ops = &imx6_pcie_host_ops; > > > > > > > > ret = dw_pcie_host_init(pp); > > > > diff --git a/drivers/pci/host/pci-keystone-dw.c > > > b/drivers/pci/host/pci-keystone-dw.c > > > > index f34892e..b1e4135 100644 > > > > --- a/drivers/pci/host/pci-keystone-dw.c > > > > +++ b/drivers/pci/host/pci-keystone-dw.c > > > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void > > > __iomem *reg_virt) > > > > void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) > > > > { > > > > struct pcie_port *pp = &ks_pcie->pp; > > > > - u32 start = pp->mem.start, end = pp->mem.end; > > > > + u32 start = pp->mem->start, end = pp->mem->end; > > > > int i, tr_size; > > > > > > > > /* Disable BARs for inbound access */ > > > > diff --git a/drivers/pci/host/pci-keystone.c > b/drivers/pci/host/pci- > > > keystone.c > > > > index 734da58..8113832 100644 > > > > --- a/drivers/pci/host/pci-keystone.c > > > > +++ b/drivers/pci/host/pci-keystone.c > > > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct > > > keystone_pcie *ks_pcie, > > > > return ret; > > > > } > > > > > > > > - pp->root_bus_nr = -1; > > > > + pp->root_bus_nr = 0; > > > > pp->ops = &keystone_pcie_host_ops; > > > > ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); > > > > if (ret) { > > > > diff --git a/drivers/pci/host/pci-layerscape.c > > > b/drivers/pci/host/pci-layerscape.c > > > > index b2328ea1..79ff08c 100644 > > > > --- a/drivers/pci/host/pci-layerscape.c > > > > +++ b/drivers/pci/host/pci-layerscape.c > > > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie > *pcie) > > > > pp = &pcie->pp; > > > > pp->dev = pcie->dev; > > > > pp->dbi_base = pcie->dbi; > > > > - pp->root_bus_nr = -1; > > > > + pp->root_bus_nr = 0; > > > > pp->ops = &ls_pcie_host_ops; > > > > > > > > ret = dw_pcie_host_init(pp); > > > > diff --git a/drivers/pci/host/pcie-designware.c > > > b/drivers/pci/host/pcie-designware.c > > > > index c5d407c..e71a88e 100644 > > > > --- a/drivers/pci/host/pcie-designware.c > > > > +++ b/drivers/pci/host/pcie-designware.c > > > > @@ -11,6 +11,7 @@ > > > > * published by the Free Software Foundation. > > > > */ > > > > > > > > +#include <linux/hardirq.h> > > > > #include <linux/irq.h> > > > > #include <linux/irqdomain.h> > > > > #include <linux/kernel.h> > > > > @@ -69,16 +70,7 @@ > > > > #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) > > > > #define PCIE_ATU_UPPER_TARGET 0x91C > > > > > > > > -static struct hw_pci dw_pci; > > > > - > > > > -static unsigned long global_io_offset; > > > > - > > > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data > *sys) > > > > -{ > > > > - BUG_ON(!sys->private_data); > > > > - > > > > - return sys->private_data; > > > > -} > > > > +static struct pci_ops dw_pcie_ops; > > > > > > > > int dw_pcie_cfg_read(void __iomem *addr, int where, int size, > u32 > > > *val) > > > > { > > > > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct > pcie_port > > > *pp, int irq) > > > > static int assign_irq(int no_irqs, struct msi_desc *desc, int > *pos) > > > > { > > > > int irq, pos0, i; > > > > - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); > > > > + struct pcie_port *pp = desc->dev->bus->sysdata; > > > > > > > > pos0 = bitmap_find_free_region(pp->msi_irq_in_use, > MAX_MSI_IRQS, > > > > order_base_2(no_irqs)); > > > > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct > msi_controller > > > *chip, struct pci_dev *pdev, > > > > { > > > > int irq, pos; > > > > struct msi_msg msg; > > > > - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); > > > > + struct pcie_port *pp = pdev->bus->sysdata; > > > > > > > > if (desc->msi_attrib.is_msix) > > > > return -EINVAL; > > > > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct > > > msi_controller *chip, unsigned int irq) > > > > { > > > > struct irq_data *data = irq_get_irq_data(irq); > > > > struct msi_desc *msi = irq_data_get_msi(data); > > > > - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); > > > > + struct pcie_port *pp = msi->dev->bus->sysdata; > > > > > > > > clear_irq_range(pp, irq, 1, data->hwirq); > > > > } > > > > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > > { > > > > struct device_node *np = pp->dev->of_node; > > > > struct platform_device *pdev = to_platform_device(pp->dev); > > > > - struct of_pci_range range; > > > > - struct of_pci_range_parser parser; > > > > + struct pci_bus *bus; > > > > struct resource *cfg_res; > > > > - u32 val, ns; > > > > - const __be32 *addrp; > > > > - int i, index, ret; > > > > - > > > > - ns = of_n_size_cells(np); > > > > + LIST_HEAD(res); > > > > + u32 val; > > > > + int i, ret; > > > > + struct resource_entry *win; > > > > > > > > cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, > > > "config"); > > > > if (cfg_res) { > > > > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > > pp->cfg1_size = resource_size(cfg_res)/2; > > > > pp->cfg0_base = cfg_res->start; > > > > pp->cfg1_base = cfg_res->start + pp->cfg0_size; > > > > - > > > > - /* Find the untranslated configuration space address > */ > > > > - index = of_property_match_string(np, "reg-names", > "config"); > > > > - addrp = of_get_address(np, index, NULL, NULL); > > > > - pp->cfg0_mod_base = of_read_number(addrp, ns); > > > > - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; > > > > } else { > > > > dev_err(pp->dev, "missing *config* reg space\n"); > > > > } > > > > > > > > - if (of_pci_range_parser_init(&parser, np)) { > > > > - dev_err(pp->dev, "missing ranges property\n"); > > > > - return -EINVAL; > > > > - } > > > > + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, > &pp- > > > >io_base); > > > > + if (ret) > > > > + return ret; > > > > > > > > /* Get the I/O and memory ranges from DT */ > > > > - for_each_of_pci_range(&parser, &range) { > > > > - unsigned long restype = range.flags & > IORESOURCE_TYPE_BITS; > > > > - > > > > - if (restype == IORESOURCE_IO) { > > > > - of_pci_range_to_resource(&range, np, &pp->io); > > > > - pp->io.name = "I/O"; > > > > - pp->io.start = max_t(resource_size_t, > > > > - PCIBIOS_MIN_IO, > > > > - range.pci_addr + > global_io_offset); > > > > - pp->io.end = min_t(resource_size_t, > > > > - IO_SPACE_LIMIT, > > > > - range.pci_addr + range.size > > > > - + global_io_offset - 1); > > > > - pp->io_size = resource_size(&pp->io); > > > > - pp->io_bus_addr = range.pci_addr; > > > > - pp->io_base = range.cpu_addr; > > > > - > > > > - /* Find the untranslated IO space address */ > > > > - pp->io_mod_base = range.cpu_addr; > > > > - } > > > > - if (restype == IORESOURCE_MEM) { > > > > - of_pci_range_to_resource(&range, np, &pp->mem); > > > > - pp->mem.name = "MEM"; > > > > - pp->mem_size = resource_size(&pp->mem); > > > > - pp->mem_bus_addr = range.pci_addr; > > > > - > > > > - /* Find the untranslated MEM space address */ > > > > - pp->mem_mod_base = range.cpu_addr; > > > > - } > > > > - if (restype == 0) { > > > > - of_pci_range_to_resource(&range, np, &pp->cfg); > > > > - pp->cfg0_size = resource_size(&pp->cfg)/2; > > > > - pp->cfg1_size = resource_size(&pp->cfg)/2; > > > > - pp->cfg0_base = pp->cfg.start; > > > > - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; > > > > - > > > > - /* Find the untranslated configuration space > address > > > */ > > > > - pp->cfg0_mod_base = range.cpu_addr; > > > > - pp->cfg1_mod_base = pp->cfg0_mod_base + > > > > - pp->cfg0_size; > > > > + resource_list_for_each_entry(win, &res) { > > > > + switch (resource_type(win->res)) { > > > > + case IORESOURCE_IO: > > > > + pp->io = win->res; > > > > + pp->io->name = "I/O"; > > > > + pp->io_size = resource_size(pp->io); > > > > + pp->io_bus_addr = pp->io->start - win->offset; > > > > + ret = pci_remap_iospace(pp->io, pp->io_base); > > > > + if (ret) { > > > > + dev_warn(pp->dev, "error %d: failed to > map > > > resource %pR\n", > > > > + ret, pp->io); > > > > + continue; > > > > + } > > > > + break; > > > > + case IORESOURCE_MEM: > > > > + pp->mem = win->res; > > > > + pp->mem->name = "MEM"; > > > > + pp->mem_size = resource_size(pp->mem); > > > > + pp->mem_bus_addr = pp->mem->start - win->offset; > > > > + break; > > > > + case 0: > > > > + pp->cfg = win->res; > > > > + pp->cfg0_size = resource_size(pp->cfg)/2; > > > > + pp->cfg1_size = resource_size(pp->cfg)/2; > > > > + pp->cfg0_base = pp->cfg->start; > > > > + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; > > > > + break; > > > > + case IORESOURCE_BUS: > > > > + pp->busn = win->res; > > > > + break; > > > > + default: > > > > + continue; > > > > } > > > > } > > > > > > > > - ret = of_pci_parse_bus_range(np, &pp->busn); > > > > - if (ret < 0) { > > > > - pp->busn.name = np->name; > > > > - pp->busn.start = 0; > > > > - pp->busn.end = 0xff; > > > > - pp->busn.flags = IORESOURCE_BUS; > > > > - dev_dbg(pp->dev, "failed to parse bus-range > property: %d, > > > using default %pR\n", > > > > - ret, &pp->busn); > > > > - } > > > > - > > > > if (!pp->dbi_base) { > > > > - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, > > > > - resource_size(&pp->cfg)); > > > > + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, > > > > + resource_size(pp->cfg)); > > > > if (!pp->dbi_base) { > > > > dev_err(pp->dev, "error with ioremap\n"); > > > > return -ENOMEM; > > > > } > > > > } > > > > > > > > - pp->mem_base = pp->mem.start; > > > > + pp->mem_base = pp->mem->start; > > > > > > > > if (!pp->va_cfg0_base) { > > > > pp->va_cfg0_base = devm_ioremap(pp->dev, pp- > >cfg0_base, > > > > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > > > > > > if (!pp->ops->rd_other_conf) > > > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, > > > > - PCIE_ATU_TYPE_MEM, pp- > >mem_mod_base, > > > > + PCIE_ATU_TYPE_MEM, pp->mem_base, > > > > pp->mem_bus_addr, pp->mem_size); > > > > > > > > dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); > > > > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp) > > > > val |= PORT_LOGIC_SPEED_CHANGE; > > > > dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, > val); > > > > > > > > -#ifdef CONFIG_PCI_MSI > > > > + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, > &dw_pcie_ops, > > > > + pp, &res); > > > > + if (!bus) > > > > + return -ENOMEM; > > > > + > > > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN > > > > + bus->msi = container_of(&pp->irq_domain, struct > msi_controller, > > > domain); > > > > +#else > > > > dw_pcie_msi_chip.dev = pp->dev; > > > > - dw_pci.msi_ctrl = &dw_pcie_msi_chip; > > > > + bus->msi = &dw_pcie_msi_chip; > > > > #endif > > > > > > > > - dw_pci.nr_controllers = 1; > > > > - dw_pci.private_data = (void **)&pp; > > > > + pci_scan_child_bus(bus); > > > > + if (pp->ops->scan_bus) > > > > + pp->ops->scan_bus(pp); > > > > + > > > > +#ifdef CONFIG_ARM > > > > + /* support old dtbs that incorrectly describe IRQs */ > > > > + pci_fixup_irqs(pci_common_swizzle, > of_irq_parse_and_map_pci); > > > > +#endif > > > > > > > > - pci_common_init_dev(pp->dev, &dw_pci); > > > > + pci_assign_unassigned_bus_resources(bus); > > > > + pci_bus_add_devices(bus); > > > > > > > > return 0; > > > > } > > > > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct > > > pcie_port *pp, struct pci_bus *bus, > > > > > > > > if (bus->parent->number == pp->root_bus_nr) { > > > > type = PCIE_ATU_TYPE_CFG0; > > > > - cpu_addr = pp->cfg0_mod_base; > > > > + cpu_addr = pp->cfg0_base; > > > > cfg_size = pp->cfg0_size; > > > > va_cfg_base = pp->va_cfg0_base; > > > > } else { > > > > type = PCIE_ATU_TYPE_CFG1; > > > > - cpu_addr = pp->cfg1_mod_base; > > > > + cpu_addr = pp->cfg1_base; > > > > cfg_size = pp->cfg1_size; > > > > va_cfg_base = pp->va_cfg1_base; > > > > } > > > > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct > pcie_port > > > *pp, struct pci_bus *bus, > > > > busdev, cfg_size); > > > > ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, > val); > > > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > > > > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > > > > + PCIE_ATU_TYPE_IO, pp->io_base, > > > > pp->io_bus_addr, pp->io_size); > > > > > > > > return ret; > > > > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct > > > pcie_port *pp, struct pci_bus *bus, > > > > > > > > if (bus->parent->number == pp->root_bus_nr) { > > > > type = PCIE_ATU_TYPE_CFG0; > > > > - cpu_addr = pp->cfg0_mod_base; > > > > + cpu_addr = pp->cfg0_base; > > > > cfg_size = pp->cfg0_size; > > > > va_cfg_base = pp->va_cfg0_base; > > > > } else { > > > > type = PCIE_ATU_TYPE_CFG1; > > > > - cpu_addr = pp->cfg1_mod_base; > > > > + cpu_addr = pp->cfg1_base; > > > > cfg_size = pp->cfg1_size; > > > > va_cfg_base = pp->va_cfg1_base; > > > > } > > > > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct > pcie_port > > > *pp, struct pci_bus *bus, > > > > busdev, cfg_size); > > > > ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, > val); > > > > dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, > > > > - PCIE_ATU_TYPE_IO, pp->io_mod_base, > > > > + PCIE_ATU_TYPE_IO, pp->io_base, > > > > pp->io_bus_addr, pp->io_size); > > > > > > > > return ret; > > > > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct > pcie_port > > > *pp, > > > > static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int > where, > > > > int size, u32 *val) > > > > { > > > > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > > > > + struct pcie_port *pp = bus->sysdata; > > > > int ret; > > > > > > > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { > > > > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus > *bus, > > > u32 devfn, int where, > > > > static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, > > > > int where, int size, u32 val) > > > > { > > > > - struct pcie_port *pp = sys_to_pcie(bus->sysdata); > > > > + struct pcie_port *pp = bus->sysdata; > > > > int ret; > > > > > > > > if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) > > > > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = { > > > > .write = dw_pcie_wr_conf, > > > > }; > > > > > > > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) > > > > -{ > > > > - struct pcie_port *pp; > > > > - > > > > - pp = sys_to_pcie(sys); > > > > - > > > > - if (global_io_offset < SZ_1M && pp->io_size > 0) { > > > > - sys->io_offset = global_io_offset - pp->io_bus_addr; > > > > - pci_ioremap_io(global_io_offset, pp->io_base); > > > > - global_io_offset += SZ_64K; > > > > - pci_add_resource_offset(&sys->resources, &pp->io, > > > > - sys->io_offset); > > > > - } > > > > - > > > > - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; > > > > - pci_add_resource_offset(&sys->resources, &pp->mem, sys- > > > >mem_offset); > > > > - pci_add_resource(&sys->resources, &pp->busn); > > > > - > > > > - return 1; > > > > -} > > > > - > > > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct > pci_sys_data > > > *sys) > > > > -{ > > > > - struct pci_bus *bus; > > > > - struct pcie_port *pp = sys_to_pcie(sys); > > > > - > > > > - pp->root_bus_nr = sys->busnr; > > > > - bus = pci_scan_root_bus(pp->dev, sys->busnr, > > > > - &dw_pcie_ops, sys, &sys->resources); > > > > - if (!bus) > > > > - return NULL; > > > > - > > > > - if (bus && pp->ops->scan_bus) > > > > - pp->ops->scan_bus(pp); > > > > - > > > > - return bus; > > > > -} > > > > - > > > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, > u8 > > > pin) > > > > -{ > > > > - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); > > > > - int irq; > > > > - > > > > - irq = of_irq_parse_and_map_pci(dev, slot, pin); > > > > - if (!irq) > > > > - irq = pp->irq; > > > > - > > > > - return irq; > > > > -} > > > > - > > > > -static struct hw_pci dw_pci = { > > > > - .setup = dw_pcie_setup, > > > > - .scan = dw_pcie_scan_bus, > > > > - .map_irq = dw_pcie_map_irq, > > > > -}; > > > > - > > > > void dw_pcie_setup_rc(struct pcie_port *pp) > > > > { > > > > u32 val; > > > > diff --git a/drivers/pci/host/pcie-designware.h > > > b/drivers/pci/host/pcie-designware.h > > > > index d0bbd27..264c969 100644 > > > > --- a/drivers/pci/host/pcie-designware.h > > > > +++ b/drivers/pci/host/pcie-designware.h > > > > @@ -27,25 +27,21 @@ struct pcie_port { > > > > u8 root_bus_nr; > > > > void __iomem *dbi_base; > > > > u64 cfg0_base; > > > > - u64 cfg0_mod_base; > > > > void __iomem *va_cfg0_base; > > > > u32 cfg0_size; > > > > u64 cfg1_base; > > > > - u64 cfg1_mod_base; > > > > void __iomem *va_cfg1_base; > > > > u32 cfg1_size; > > > > - u64 io_base; > > > > - u64 io_mod_base; > > > > + resource_size_t io_base; > > > > phys_addr_t io_bus_addr; > > > > u32 io_size; > > > > u64 mem_base; > > > > - u64 mem_mod_base; > > > > phys_addr_t mem_bus_addr; > > > > u32 mem_size; > > > > - struct resource cfg; > > > > - struct resource io; > > > > - struct resource mem; > > > > - struct resource busn; > > > > + struct resource *cfg; > > > > + struct resource *io; > > > > + struct resource *mem; > > > > + struct resource *busn; > > > > int irq; > > > > u32 lanes; > > > > struct pcie_host_ops *ops; > > > > diff --git a/drivers/pci/host/pcie-spear13xx.c > > > b/drivers/pci/host/pcie-spear13xx.c > > > > index c49fbdc..03eb204 100644 > > > > --- a/drivers/pci/host/pcie-spear13xx.c > > > > +++ b/drivers/pci/host/pcie-spear13xx.c > > > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct > > > pcie_port *pp, > > > > return ret; > > > > } > > > > > > > > - pp->root_bus_nr = -1; > > > > + pp->root_bus_nr = 0; > > > > pp->ops = &spear13xx_pcie_host_ops; > > > > > > > > ret = dw_pcie_host_init(pp); > > > > > > -- > > > Pengutronix e.K. | Lucas Stach | > > > Industrial Linux Solutions | http://www.pengutronix.de/ | > > > > -- > Pengutronix e.K. | Lucas Stach | > Industrial Linux Solutions | http://www.pengutronix.de/ |
Hi Gab, Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni: > Hi Lucas > > First of all many thanks for the quick reply, really appreciated > > > -----Original Message----- > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > Sent: Wednesday, August 19, 2015 4:37 PM > > To: Gabriele Paoloni > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > Hi Gab, > > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni: > > > Hi Lucas > > > > > > I have rewritten the patch to take into account multiple controllers. > > > > > > As you can see now there is a static var in dw_pcie_host_init() that > > tracks > > > the bus numbers used. > > > > This is wrong. The DT specifies the valid bus number range. You can not > > just assign the next free bus number to the root bus. > > I think this is what is being done in > http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495 > and currently designware assigns the root bus number in > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L730 > You found the right spot. It works a bit different than I remember, but is less broken than your current code. :) It actually assigns the next instance a root bus number behind the current instances bus range. Please note the difference to your code which assigns the next free bus number, which may still lay within the current instances bus range. > > In general I agree with you but if you look at all the current drivers > based on designware none of them define the "bus-range" dtb property. > Therefore doing as you say would break the current driver when we have > multiple controllers...am I right? > The current _code_ works fine for multiple controllers. It's just that you must define the bus range property in the DTB if you want to enable multiple instances of one controller and support a kernel without PCI domains support. As all current implementations have only a single instance of the controller per SoC, or depend on PCI domain support, it's totally fine for them to not define the bus ranges property, as it's an optional property and it is well defined how things behave if it is absent. We absolutely need to keep that specified behavior. > If that is the case in order to fix this in the way you say I would need > to assign "bus-range" for all the PCIe drivers with multiple controllers: > in this case I would split the default range evenly (that is, if we have > two controllers I would define "bus-range" 0-127 and 128-255) > > If you think this solution is ok I can go for it. My only doubt was about > touching other vendors DTBs.... > You don't need to touch any of the current DTBs, as they are fine with the default bus range behavior. You need to keep the specified behavior of the bus range property with the new code. Regards, Lucas > > > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned to one > > instance and 0x50-0xff to the next instance. Additional with PCIe > > hotplug you may not use the full range of the bus numbers on one > > instance at the first scan, but only later populate more buses when > > more > > bridges are added to the tree. > > > > > Drivers that do not specify the bus range in the DTB set pp- > > >root_bus_nr = DW_ROOT_NR_UNDEFINED. > > > Designware will check if the flag is set and will use the automatic > > bus range > > > assignment. > > > > No, please lets get rid of this assignment altogether. The glue drivers > > have no business in assigning the bus range. Please remove the > > pp->root_bus_nr assignment from all the glue drivers. > > > > "bus range" is a generic DW PCIe property, so just parse the root bus > > number from the DT, it is handled the same way for all the DW based > > PCIe > > drivers. The bindings specifies that if the bus range property is > > missing the range is 0x00-0xff, so you can default to 0 as the root bus > > number in that case. > > > > Also I would think this conversion warrants a patch on its own and > > should not be mixed in the ARM64 support patch. > > > > Regards, > > Lucas > >
SGkgTHVjYXMNCg0KQWdhaW4gbWFueSB0aGFua3MgZm9yIGV4cGxhaW5pbmcgYW5kIGZvciB5b3Vy IHRpbWUuDQoNCkkgZ290IHlvdXIgcG9pbnQgbm93IGFuZCBJIGhhdmUgZHVnIGEgYml0IGJldHRl ciBpbiB0aGUgUENJX0RPTUFJTlMgY29kZS4NCg0KSG93ZXZlciBJIGhhdmUgYSBxdWVzdGlvbi4u LnNlZSBpbmxpbmUgYmVsb3cNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9t OiBMdWNhcyBTdGFjaCBbbWFpbHRvOmwuc3RhY2hAcGVuZ3V0cm9uaXguZGVdDQo+IFNlbnQ6IFRo dXJzZGF5LCBBdWd1c3QgMjAsIDIwMTUgOToyNyBBTQ0KPiBUbzogR2FicmllbGUgUGFvbG9uaQ0K PiBDYzogV2FuZ3pob3UgKEIpOyBCam9ybiBIZWxnYWFzOyBqaW5nb29oYW4xQGdtYWlsLmNvbTsg UHJhdHl1c2ggQW5hbmQ7DQo+IEFybmQgQmVyZ21hbm47IGxpbnV4QGFybS5saW51eC5vcmcudWs7 IHRob21hcy5wZXRhenpvbmlAZnJlZS0NCj4gZWxlY3Ryb25zLmNvbTsgbG9yZW56by5waWVyYWxp c2lAYXJtLmNvbTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gTGl2aXUuRHVkYXVAYXJtLmNvbTsg amFzb25AbGFrZWRhZW1vbi5uZXQ7IHJvYmhAa2VybmVsLm9yZzsgbGludXgtDQo+IHBjaUB2Z2Vy Lmtlcm5lbC5vcmc7IGxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsNCj4gZGV2 aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpoYW5nanVr dW87DQo+IHFpdXpoZW5mYTsgbGl1ZG9uZ2RvbmcgKEMpOyBxaXVqaWFuZzsgeHV3ZWkgKE8pOyBM aWd1b3podSAoS2VubmV0aCkNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVz aWdud2FyZTogQWRkIEFSTTY0IHN1cHBvcnQNCj4gDQo+IEhpIEdhYiwNCj4gDQo+IEFtIE1pdHR3 b2NoLCBkZW4gMTkuMDguMjAxNSwgMTY6MzQgKzAwMDAgc2NocmllYiBHYWJyaWVsZSBQYW9sb25p Og0KPiA+IEhpIEx1Y2FzDQo+ID4NCj4gPiBGaXJzdCBvZiBhbGwgbWFueSB0aGFua3MgZm9yIHRo ZSBxdWljayByZXBseSwgcmVhbGx5IGFwcHJlY2lhdGVkDQo+ID4NCj4gPiA+IC0tLS0tT3JpZ2lu YWwgTWVzc2FnZS0tLS0tDQo+ID4gPiBGcm9tOiBMdWNhcyBTdGFjaCBbbWFpbHRvOmwuc3RhY2hA cGVuZ3V0cm9uaXguZGVdDQo+ID4gPiBTZW50OiBXZWRuZXNkYXksIEF1Z3VzdCAxOSwgMjAxNSA0 OjM3IFBNDQo+ID4gPiBUbzogR2FicmllbGUgUGFvbG9uaQ0KPiA+ID4gQ2M6IFdhbmd6aG91IChC KTsgQmpvcm4gSGVsZ2FhczsgamluZ29vaGFuMUBnbWFpbC5jb207IFByYXR5dXNoDQo+IEFuYW5k Ow0KPiA+ID4gQXJuZCBCZXJnbWFubjsgbGludXhAYXJtLmxpbnV4Lm9yZy51azsgdGhvbWFzLnBl dGF6em9uaUBmcmVlLQ0KPiA+ID4gZWxlY3Ryb25zLmNvbTsgbG9yZW56by5waWVyYWxpc2lAYXJt LmNvbTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gPiA+IExpdml1LkR1ZGF1QGFybS5jb207IGph c29uQGxha2VkYWVtb24ubmV0OyByb2JoQGtlcm5lbC5vcmc7IGxpbnV4LQ0KPiA+ID4gcGNpQHZn ZXIua2VybmVsLm9yZzsgbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnOw0KPiA+ ID4gZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpo YW5nanVrdW87DQo+ID4gPiBxaXV6aGVuZmE7IGxpdWRvbmdkb25nIChDKTsgcWl1amlhbmc7IHh1 d2VpIChPKTsgTGlndW96aHUgKEtlbm5ldGgpDQo+ID4gPiBTdWJqZWN0OiBSZTogW1BBVENIIHY3 IDMvNl0gUENJOiBkZXNpZ253YXJlOiBBZGQgQVJNNjQgc3VwcG9ydA0KPiA+ID4NCj4gPiA+IEhp IEdhYiwNCj4gPiA+DQo+ID4gPiBBbSBNaXR0d29jaCwgZGVuIDE5LjA4LjIwMTUsIDE1OjE2ICsw MDAwIHNjaHJpZWIgR2FicmllbGUgUGFvbG9uaToNCj4gPiA+ID4gSGkgTHVjYXMNCj4gPiA+ID4N Cj4gPiA+ID4gSSBoYXZlIHJld3JpdHRlbiB0aGUgcGF0Y2ggdG8gdGFrZSBpbnRvIGFjY291bnQg bXVsdGlwbGUNCj4gY29udHJvbGxlcnMuDQo+ID4gPiA+DQo+ID4gPiA+IEFzIHlvdSBjYW4gc2Vl IG5vdyB0aGVyZSBpcyBhIHN0YXRpYyB2YXIgaW4gZHdfcGNpZV9ob3N0X2luaXQoKQ0KPiB0aGF0 DQo+ID4gPiB0cmFja3MNCj4gPiA+ID4gdGhlIGJ1cyBudW1iZXJzIHVzZWQuDQo+ID4gPg0KPiA+ ID4gVGhpcyBpcyB3cm9uZy4gVGhlIERUIHNwZWNpZmllcyB0aGUgdmFsaWQgYnVzIG51bWJlciBy YW5nZS4gWW91IGNhbg0KPiBub3QNCj4gPiA+IGp1c3QgYXNzaWduIHRoZSBuZXh0IGZyZWUgYnVz IG51bWJlciB0byB0aGUgcm9vdCBidXMuDQo+ID4NCj4gPiBJIHRoaW5rIHRoaXMgaXMgd2hhdCBp cyBiZWluZyBkb25lIGluDQo+ID4gaHR0cDovL2x4ci5mcmVlLWVsZWN0cm9ucy5jb20vc291cmNl L2FyY2gvYXJtL2tlcm5lbC9iaW9zMzIuYyNMNDk1DQo+ID4gYW5kIGN1cnJlbnRseSBkZXNpZ253 YXJlIGFzc2lnbnMgdGhlIHJvb3QgYnVzIG51bWJlciBpbg0KPiA+IGh0dHA6Ly9seHIuZnJlZS1l bGVjdHJvbnMuY29tL3NvdXJjZS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtDQo+IGRlc2lnbndhcmUu YyNMNzMwDQo+ID4NCj4gWW91IGZvdW5kIHRoZSByaWdodCBzcG90LiBJdCB3b3JrcyBhIGJpdCBk aWZmZXJlbnQgdGhhbiBJIHJlbWVtYmVyLCBidXQNCj4gaXMgbGVzcyBicm9rZW4gdGhhbiB5b3Vy IGN1cnJlbnQgY29kZS4gOikNCj4gDQo+IEl0IGFjdHVhbGx5IGFzc2lnbnMgdGhlIG5leHQgaW5z dGFuY2UgYSByb290IGJ1cyBudW1iZXIgYmVoaW5kIHRoZQ0KPiBjdXJyZW50IGluc3RhbmNlcyBi dXMgcmFuZ2UuIFBsZWFzZSBub3RlIHRoZSBkaWZmZXJlbmNlIHRvIHlvdXIgY29kZQ0KPiB3aGlj aCBhc3NpZ25zIHRoZSBuZXh0IGZyZWUgYnVzIG51bWJlciwgd2hpY2ggbWF5IHN0aWxsIGxheSB3 aXRoaW4gdGhlDQo+IGN1cnJlbnQgaW5zdGFuY2VzIGJ1cyByYW5nZS4NCg0KTW1tbSBoZXJlIEkg aGF2ZSBkb25lIGEgbWlzdGFrZTogaW4gdGhlIGN1cnJlbnQgZGVzaWdud2FyZSB0aGUgbnVtYmVy IG9mIGh3DQpjb250cm9sbGVycyBpcyBhbHdheXMgMQ0KaHR0cDovL2x4ci5mcmVlLWVsZWN0cm9u cy5jb20vc291cmNlL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMjTDUxMA0KU28g dGhlIGxvb3AgaW4gYmlvczMyLmMgZG9lcyBub3Qgd29yayBvbiBtdWx0aXBsZSBQQ0llIHBvcnRz Li4uDQpIb3dldmVyIHlvdXIgY29tbWVudCBhYm91dCBQQ0lfRE9NQUlOUyBlbmxpZ2h0ZW5lZCBt eSBtaW5kIGFuZCBub3cgSSBzZWUNCnRoYXQgd2hlbiBDT05GSUdfUENJX0RPTUFJTlMgaXMgZGVm aW5lZCB3ZSBoYXZlIHRoZSBkb21haW5zIG51bWJlcnMNCih0cmFja2VkIGJ5IF9fZG9tYWluX25y KS4NClNvIChjb3JyZWN0IG1lIGlmIEkgYW0gd3JvbmcpIGlmIHdlIGhhdmUgMiBQQ0llIHBvcnRz IHRoYXQgZG8gbm90IHNwZWNpZnkNCnRoZSAiYnVzLXJhbmdlIiBwcm9wZXJ0eSwgYm90aCByb290 IHBvcnRzIHdpbGwgZW51bWVyYXRlIHN0YXJ0aW5nIGZyb20gDQpyb290X2J1c19uciA9IDAgYW5k IGV2ZXJ5dGhpbmcgd2lsbCBzdGlsbCB3b3JrIG9rLg0KDQpTbyBpZiBteSBhc3N1bXB0aW9uIGlz IGNvcnJlY3QsIEkgZG8gbm90IHNlZSB3aHkgdGhlIG9yZ2luYWwgcGF0Y2ggZnJvbSBXYW5nIA0K WmhvdSBpcyB3cm9uZy4gDQpUaGUgb25seSBwb2ludCBjYW4gYmUgdGhhdCBhc3NpZ25pbmcgcHAt PnJvb3RfYnVzX25yID0gMCBpcyBub3QgcmVxdWlyZWQgDQphcyBwcCBtZW1vcnkgaXMga3phbGxv YydlZCAoYW4gdGhlcmVmb3JlIGluaXQgdG8gemVybykuDQoNCg0KPiANCj4gPg0KPiA+IEluIGdl bmVyYWwgSSBhZ3JlZSB3aXRoIHlvdSBidXQgaWYgeW91IGxvb2sgYXQgYWxsIHRoZSBjdXJyZW50 DQo+IGRyaXZlcnMNCj4gPiBiYXNlZCBvbiBkZXNpZ253YXJlIG5vbmUgb2YgdGhlbSBkZWZpbmUg dGhlICJidXMtcmFuZ2UiIGR0YiBwcm9wZXJ0eS4NCj4gPiBUaGVyZWZvcmUgZG9pbmcgYXMgeW91 IHNheSB3b3VsZCBicmVhayB0aGUgY3VycmVudCBkcml2ZXIgd2hlbiB3ZQ0KPiBoYXZlDQo+ID4g bXVsdGlwbGUgY29udHJvbGxlcnMuLi5hbSBJIHJpZ2h0Pw0KPiA+DQo+IFRoZSBjdXJyZW50IF9j b2RlXyB3b3JrcyBmaW5lIGZvciBtdWx0aXBsZSBjb250cm9sbGVycy4gSXQncyBqdXN0IHRoYXQN Cj4geW91IG11c3QgZGVmaW5lIHRoZSBidXMgcmFuZ2UgcHJvcGVydHkgaW4gdGhlIERUQiBpZiB5 b3Ugd2FudCB0byBlbmFibGUNCj4gbXVsdGlwbGUgaW5zdGFuY2VzIG9mIG9uZSBjb250cm9sbGVy IGFuZCBzdXBwb3J0IGEga2VybmVsIHdpdGhvdXQgUENJDQo+IGRvbWFpbnMgc3VwcG9ydC4gQXMg YWxsIGN1cnJlbnQgaW1wbGVtZW50YXRpb25zIGhhdmUgb25seSBhIHNpbmdsZQ0KPiBpbnN0YW5j ZSBvZiB0aGUgY29udHJvbGxlciBwZXIgU29DLCBvciBkZXBlbmQgb24gUENJIGRvbWFpbiBzdXBw b3J0LA0KPiBpdCdzIHRvdGFsbHkgZmluZSBmb3IgdGhlbSB0byBub3QgZGVmaW5lIHRoZSBidXMg cmFuZ2VzIHByb3BlcnR5LCBhcw0KPiBpdCdzIGFuIG9wdGlvbmFsIHByb3BlcnR5IGFuZCBpdCBp cyB3ZWxsIGRlZmluZWQgaG93IHRoaW5ncyBiZWhhdmUgaWYNCj4gaXQNCj4gaXMgYWJzZW50LiBX ZSBhYnNvbHV0ZWx5IG5lZWQgdG8ga2VlcCB0aGF0IHNwZWNpZmllZCBiZWhhdmlvci4NCj4gDQo+ ID4gSWYgdGhhdCBpcyB0aGUgY2FzZSBpbiBvcmRlciB0byBmaXggdGhpcyBpbiB0aGUgd2F5IHlv dSBzYXkgSSB3b3VsZA0KPiBuZWVkDQo+ID4gdG8gYXNzaWduICJidXMtcmFuZ2UiIGZvciBhbGwg dGhlIFBDSWUgZHJpdmVycyB3aXRoIG11bHRpcGxlDQo+IGNvbnRyb2xsZXJzOg0KPiA+IGluIHRo aXMgY2FzZSBJIHdvdWxkIHNwbGl0IHRoZSBkZWZhdWx0IHJhbmdlIGV2ZW5seSAodGhhdCBpcywg aWYgd2UNCj4gaGF2ZQ0KPiA+IHR3byBjb250cm9sbGVycyBJIHdvdWxkIGRlZmluZSAiYnVzLXJh bmdlIiAgMC0xMjcgYW5kIDEyOC0yNTUpDQo+ID4NCj4gPiBJZiB5b3UgdGhpbmsgdGhpcyBzb2x1 dGlvbiBpcyBvayBJIGNhbiBnbyBmb3IgaXQuIE15IG9ubHkgZG91YnQgd2FzDQo+IGFib3V0DQo+ ID4gdG91Y2hpbmcgb3RoZXIgdmVuZG9ycyBEVEJzLi4uLg0KPiA+DQo+IFlvdSBkb24ndCBuZWVk IHRvIHRvdWNoIGFueSBvZiB0aGUgY3VycmVudCBEVEJzLCBhcyB0aGV5IGFyZSBmaW5lIHdpdGgN Cj4gdGhlIGRlZmF1bHQgYnVzIHJhbmdlIGJlaGF2aW9yLiBZb3UgbmVlZCB0byBrZWVwIHRoZSBz cGVjaWZpZWQgYmVoYXZpb3INCj4gb2YgdGhlIGJ1cyByYW5nZSBwcm9wZXJ0eSB3aXRoIHRoZSBu ZXcgY29kZS4NCj4gDQo+IFJlZ2FyZHMsDQo+IEx1Y2FzDQo+ID4NCj4gPiA+DQo+ID4gPiBJdCBp cyBwZXJmZWN0bHkgdmFsaWQgdG8gaGF2ZSBhIGJ1cyByYW5nZSBvZiAweDAwLTB4MTAgYXNzaWdu ZWQgdG8NCj4gb25lDQo+ID4gPiBpbnN0YW5jZSBhbmQgMHg1MC0weGZmIHRvIHRoZSBuZXh0IGlu c3RhbmNlLiBBZGRpdGlvbmFsIHdpdGggUENJZQ0KPiA+ID4gaG90cGx1ZyB5b3UgbWF5IG5vdCB1 c2UgdGhlIGZ1bGwgcmFuZ2Ugb2YgdGhlIGJ1cyBudW1iZXJzIG9uIG9uZQ0KPiA+ID4gaW5zdGFu Y2UgYXQgdGhlIGZpcnN0IHNjYW4sIGJ1dCBvbmx5IGxhdGVyIHBvcHVsYXRlIG1vcmUgYnVzZXMg d2hlbg0KPiA+ID4gbW9yZQ0KPiA+ID4gYnJpZGdlcyBhcmUgYWRkZWQgdG8gdGhlIHRyZWUuDQo+ ID4gPg0KPiA+ID4gPiBEcml2ZXJzIHRoYXQgZG8gbm90IHNwZWNpZnkgdGhlIGJ1cyByYW5nZSBp biB0aGUgRFRCIHNldCBwcC0NCj4gPiA+ID5yb290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJ TkVELg0KPiA+ID4gPiBEZXNpZ253YXJlIHdpbGwgY2hlY2sgaWYgdGhlIGZsYWcgaXMgc2V0IGFu ZCB3aWxsIHVzZSB0aGUNCj4gYXV0b21hdGljDQo+ID4gPiBidXMgcmFuZ2UNCj4gPiA+ID4gYXNz aWdubWVudC4NCj4gPiA+DQo+ID4gPiBObywgcGxlYXNlIGxldHMgZ2V0IHJpZCBvZiB0aGlzIGFz c2lnbm1lbnQgYWx0b2dldGhlci4gVGhlIGdsdWUNCj4gZHJpdmVycw0KPiA+ID4gaGF2ZSBubyBi dXNpbmVzcyBpbiBhc3NpZ25pbmcgdGhlIGJ1cyByYW5nZS4gUGxlYXNlIHJlbW92ZSB0aGUNCj4g PiA+IHBwLT5yb290X2J1c19uciBhc3NpZ25tZW50IGZyb20gYWxsIHRoZSBnbHVlIGRyaXZlcnMu DQo+ID4gPg0KPiA+ID4gImJ1cyByYW5nZSIgaXMgYSBnZW5lcmljIERXIFBDSWUgcHJvcGVydHks IHNvIGp1c3QgcGFyc2UgdGhlIHJvb3QNCj4gYnVzDQo+ID4gPiBudW1iZXIgZnJvbSB0aGUgRFQs IGl0IGlzIGhhbmRsZWQgdGhlIHNhbWUgd2F5IGZvciBhbGwgdGhlIERXIGJhc2VkDQo+ID4gPiBQ Q0llDQo+ID4gPiBkcml2ZXJzLiBUaGUgYmluZGluZ3Mgc3BlY2lmaWVzIHRoYXQgaWYgdGhlIGJ1 cyByYW5nZSBwcm9wZXJ0eSBpcw0KPiA+ID4gbWlzc2luZyB0aGUgcmFuZ2UgaXMgMHgwMC0weGZm LCBzbyB5b3UgY2FuIGRlZmF1bHQgdG8gMCBhcyB0aGUgcm9vdA0KPiBidXMNCj4gPiA+IG51bWJl ciBpbiB0aGF0IGNhc2UuDQo+ID4gPg0KPiA+ID4gQWxzbyBJIHdvdWxkIHRoaW5rIHRoaXMgY29u dmVyc2lvbiB3YXJyYW50cyBhIHBhdGNoIG9uIGl0cyBvd24gYW5kDQo+ID4gPiBzaG91bGQgbm90 IGJlIG1peGVkIGluIHRoZSBBUk02NCBzdXBwb3J0IHBhdGNoLg0KPiA+ID4NCj4gPiA+IFJlZ2Fy ZHMsDQo+ID4gPiBMdWNhcw0KPiA+ID4NCj4gDQo+IC0tDQo+IFBlbmd1dHJvbml4IGUuSy4gICAg ICAgICAgICAgfCBMdWNhcyBTdGFjaCAgICAgICAgICAgICAgICAgfA0KPiBJbmR1c3RyaWFsIExp bnV4IFNvbHV0aW9ucyAgIHwgaHR0cDovL3d3dy5wZW5ndXRyb25peC5kZS8gIHwNCg0K -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote: > Hi Lucas > > Again many thanks for explaining and for your time. > > I got your point now and I have dug a bit better in the PCI_DOMAINS code. > > However I have a question...see inline below > > > -----Original Message----- > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > Sent: Thursday, August 20, 2015 9:27 AM > > To: Gabriele Paoloni > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > Hi Gab, > > > > Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni: > > > Hi Lucas > > > > > > First of all many thanks for the quick reply, really appreciated > > > > > > > -----Original Message----- > > > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > > > Sent: Wednesday, August 19, 2015 4:37 PM > > > > To: Gabriele Paoloni > > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush > > Anand; > > > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- > > > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > > > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > > > > > Hi Gab, > > > > > > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni: > > > > > Hi Lucas > > > > > > > > > > I have rewritten the patch to take into account multiple > > controllers. > > > > > > > > > > As you can see now there is a static var in dw_pcie_host_init() > > that > > > > tracks > > > > > the bus numbers used. > > > > > > > > This is wrong. The DT specifies the valid bus number range. You can > > not > > > > just assign the next free bus number to the root bus. > > > > > > I think this is what is being done in > > > http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495 > > > and currently designware assigns the root bus number in > > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie- > > designware.c#L730 > > > > > You found the right spot. It works a bit different than I remember, but > > is less broken than your current code. :) > > > > It actually assigns the next instance a root bus number behind the > > current instances bus range. Please note the difference to your code > > which assigns the next free bus number, which may still lay within the > > current instances bus range. Hi Gabriele, > > Mmmm here I have done a mistake: in the current designware the number of hw > controllers is always 1 > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L510 > So the loop in bios32.c does not work on multiple PCIe ports... Bios32.c is broken for multiple PCIe hosts for multiple reasons, this is just one of them. Hence the effort to get rid of it for maintained drivers. > However your comment about PCI_DOMAINS enlightened my mind and now I see > that when CONFIG_PCI_DOMAINS is defined we have the domains numbers > (tracked by __domain_nr). CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to your driver. You could request a new domain for each controller with a special property to disable that behaviour in the dts, or you could enable CONFIG_PCI_DOMAINS_GENERIC which will give you a new domain automatically. > So (correct me if I am wrong) if we have 2 PCIe ports that do not specify > the "bus-range" property, both root ports will enumerate starting from > root_bus_nr = 0 and everything will still work ok. Correct. Best regards, Liviu > > So if my assumption is correct, I do not see why the orginal patch from Wang > Zhou is wrong. > The only point can be that assigning pp->root_bus_nr = 0 is not required > as pp memory is kzalloc'ed (an therefore init to zero). > > > > > > > > > > In general I agree with you but if you look at all the current > > drivers > > > based on designware none of them define the "bus-range" dtb property. > > > Therefore doing as you say would break the current driver when we > > have > > > multiple controllers...am I right? > > > > > The current _code_ works fine for multiple controllers. It's just that > > you must define the bus range property in the DTB if you want to enable > > multiple instances of one controller and support a kernel without PCI > > domains support. As all current implementations have only a single > > instance of the controller per SoC, or depend on PCI domain support, > > it's totally fine for them to not define the bus ranges property, as > > it's an optional property and it is well defined how things behave if > > it > > is absent. We absolutely need to keep that specified behavior. > > > > > If that is the case in order to fix this in the way you say I would > > need > > > to assign "bus-range" for all the PCIe drivers with multiple > > controllers: > > > in this case I would split the default range evenly (that is, if we > > have > > > two controllers I would define "bus-range" 0-127 and 128-255) > > > > > > If you think this solution is ok I can go for it. My only doubt was > > about > > > touching other vendors DTBs.... > > > > > You don't need to touch any of the current DTBs, as they are fine with > > the default bus range behavior. You need to keep the specified behavior > > of the bus range property with the new code. > > > > Regards, > > Lucas > > > > > > > > > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned to > > one > > > > instance and 0x50-0xff to the next instance. Additional with PCIe > > > > hotplug you may not use the full range of the bus numbers on one > > > > instance at the first scan, but only later populate more buses when > > > > more > > > > bridges are added to the tree. > > > > > > > > > Drivers that do not specify the bus range in the DTB set pp- > > > > >root_bus_nr = DW_ROOT_NR_UNDEFINED. > > > > > Designware will check if the flag is set and will use the > > automatic > > > > bus range > > > > > assignment. > > > > > > > > No, please lets get rid of this assignment altogether. The glue > > drivers > > > > have no business in assigning the bus range. Please remove the > > > > pp->root_bus_nr assignment from all the glue drivers. > > > > > > > > "bus range" is a generic DW PCIe property, so just parse the root > > bus > > > > number from the DT, it is handled the same way for all the DW based > > > > PCIe > > > > drivers. The bindings specifies that if the bus range property is > > > > missing the range is 0x00-0xff, so you can default to 0 as the root > > bus > > > > number in that case. > > > > > > > > Also I would think this conversion warrants a patch on its own and > > > > should not be mixed in the ARM64 support patch. > > > > > > > > Regards, > > > > Lucas > > > > > > > > -- > > Pengutronix e.K. | Lucas Stach | > > Industrial Linux Solutions | http://www.pengutronix.de/ | >
Hi Liviu Many Thanks for reviewing > -----Original Message----- > From: linux-pci-owner@vger.kernel.org [mailto:linux-pci- > owner@vger.kernel.org] On Behalf Of Liviu Dudau > Sent: Friday, August 21, 2015 2:43 PM > To: Gabriele Paoloni > Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; > Pratyush Anand; Arnd Bergmann; linux@arm.linux.org.uk; > thomas.petazzoni@free-electrons.com; Lorenzo Pieralisi; James Morse; > jason@lakedaemon.net; robh@kernel.org; linux-pci@vger.kernel.org; > linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org; > Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C); > qiujiang; xuwei (O); Liguozhu (Kenneth) > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote: > > Hi Lucas > > > > Again many thanks for explaining and for your time. > > > > I got your point now and I have dug a bit better in the PCI_DOMAINS > code. > > > > However I have a question...see inline below > > > > > -----Original Message----- > > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > > Sent: Thursday, August 20, 2015 9:27 AM > > > To: Gabriele Paoloni > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush > Anand; > > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- > > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- > > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > > > Hi Gab, > > > > > > Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni: > > > > Hi Lucas > > > > > > > > First of all many thanks for the quick reply, really appreciated > > > > > > > > > -----Original Message----- > > > > > From: Lucas Stach [mailto:l.stach@pengutronix.de] > > > > > Sent: Wednesday, August 19, 2015 4:37 PM > > > > > To: Gabriele Paoloni > > > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush > > > Anand; > > > > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- > > > > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; > > > > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; > linux- > > > > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; > > > > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; > > > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu > (Kenneth) > > > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support > > > > > > > > > > Hi Gab, > > > > > > > > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele > Paoloni: > > > > > > Hi Lucas > > > > > > > > > > > > I have rewritten the patch to take into account multiple > > > controllers. > > > > > > > > > > > > As you can see now there is a static var in > dw_pcie_host_init() > > > that > > > > > tracks > > > > > > the bus numbers used. > > > > > > > > > > This is wrong. The DT specifies the valid bus number range. You > can > > > not > > > > > just assign the next free bus number to the root bus. > > > > > > > > I think this is what is being done in > > > > http://lxr.free- > electrons.com/source/arch/arm/kernel/bios32.c#L495 > > > > and currently designware assigns the root bus number in > > > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie- > > > designware.c#L730 > > > > > > > You found the right spot. It works a bit different than I remember, > but > > > is less broken than your current code. :) > > > > > > It actually assigns the next instance a root bus number behind the > > > current instances bus range. Please note the difference to your > code > > > which assigns the next free bus number, which may still lay within > the > > > current instances bus range. > > Hi Gabriele, > > > > > Mmmm here I have done a mistake: in the current designware the number > of hw > > controllers is always 1 > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie- > designware.c#L510 > > So the loop in bios32.c does not work on multiple PCIe ports... > > Bios32.c is broken for multiple PCIe hosts for multiple reasons, this > is just > one of them. Hence the effort to get rid of it for maintained drivers. As you can see we're pushing hard for this :) > > > However your comment about PCI_DOMAINS enlightened my mind and now I > see > > that when CONFIG_PCI_DOMAINS is defined we have the domains numbers > > (tracked by __domain_nr). > > CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to > your driver. > You could request a new domain for each controller with a special > property to > disable that behaviour in the dts, or you could enable > CONFIG_PCI_DOMAINS_GENERIC > which will give you a new domain automatically. So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC defaults to the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig, arch/arm64/Kconfig). So I think this is how current designware based drivers get multiple PCIe controller to work (they just enable CONFIG_PCI_DOMAINS)... > > > So (correct me if I am wrong) if we have 2 PCIe ports that do not > specify > > the "bus-range" property, both root ports will enumerate starting > from > > root_bus_nr = 0 and everything will still work ok. > > Correct. > > Best regards, > Liviu > > > > > So if my assumption is correct, I do not see why the orginal patch > from Wang > > Zhou is wrong. > > The only point can be that assigning pp->root_bus_nr = 0 is not > required > > as pp memory is kzalloc'ed (an therefore init to zero). > > > > > > > > > > > > > > > In general I agree with you but if you look at all the current > > > drivers > > > > based on designware none of them define the "bus-range" dtb > property. > > > > Therefore doing as you say would break the current driver when we > > > have > > > > multiple controllers...am I right? > > > > > > > The current _code_ works fine for multiple controllers. It's just > that > > > you must define the bus range property in the DTB if you want to > enable > > > multiple instances of one controller and support a kernel without > PCI > > > domains support. As all current implementations have only a single > > > instance of the controller per SoC, or depend on PCI domain support, > > > it's totally fine for them to not define the bus ranges property, > as > > > it's an optional property and it is well defined how things behave > if > > > it > > > is absent. We absolutely need to keep that specified behavior. > > > > > > > If that is the case in order to fix this in the way you say I > would > > > need > > > > to assign "bus-range" for all the PCIe drivers with multiple > > > controllers: > > > > in this case I would split the default range evenly (that is, if > we > > > have > > > > two controllers I would define "bus-range" 0-127 and 128-255) > > > > > > > > If you think this solution is ok I can go for it. My only doubt > was > > > about > > > > touching other vendors DTBs.... > > > > > > > You don't need to touch any of the current DTBs, as they are fine > with > > > the default bus range behavior. You need to keep the specified > behavior > > > of the bus range property with the new code. > > > > > > Regards, > > > Lucas > > > > > > > > > > > > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned > to > > > one > > > > > instance and 0x50-0xff to the next instance. Additional with > PCIe > > > > > hotplug you may not use the full range of the bus numbers on > one > > > > > instance at the first scan, but only later populate more buses > when > > > > > more > > > > > bridges are added to the tree. > > > > > > > > > > > Drivers that do not specify the bus range in the DTB set pp- > > > > > >root_bus_nr = DW_ROOT_NR_UNDEFINED. > > > > > > Designware will check if the flag is set and will use the > > > automatic > > > > > bus range > > > > > > assignment. > > > > > > > > > > No, please lets get rid of this assignment altogether. The glue > > > drivers > > > > > have no business in assigning the bus range. Please remove the > > > > > pp->root_bus_nr assignment from all the glue drivers. > > > > > > > > > > "bus range" is a generic DW PCIe property, so just parse the > root > > > bus > > > > > number from the DT, it is handled the same way for all the DW > based > > > > > PCIe > > > > > drivers. The bindings specifies that if the bus range property > is > > > > > missing the range is 0x00-0xff, so you can default to 0 as the > root > > > bus > > > > > number in that case. > > > > > > > > > > Also I would think this conversion warrants a patch on its own > and > > > > > should not be mixed in the ARM64 support patch. > > > > > > > > > > Regards, > > > > > Lucas > > > > > > > > > > > -- > > > Pengutronix e.K. | Lucas Stach | > > > Industrial Linux Solutions | http://www.pengutronix.de/ | > > > > -- > ==================== > | I would like to | > | fix the world, | > | but they're not | > | giving me the | > \ source code! / > --------------- > ¯\_(?)_/¯ > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pci" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html
On 2015/8/21 22:19, Gabriele Paoloni wrote: > Hi Liviu > > Many Thanks for reviewing > >> -----Original Message----- >> From: linux-pci-owner@vger.kernel.org [mailto:linux-pci- >> owner@vger.kernel.org] On Behalf Of Liviu Dudau >> Sent: Friday, August 21, 2015 2:43 PM >> To: Gabriele Paoloni >> Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; >> Pratyush Anand; Arnd Bergmann; linux@arm.linux.org.uk; >> thomas.petazzoni@free-electrons.com; Lorenzo Pieralisi; James Morse; >> jason@lakedaemon.net; robh@kernel.org; linux-pci@vger.kernel.org; >> linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org; >> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C); >> qiujiang; xuwei (O); Liguozhu (Kenneth) >> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support >> >> On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote: >>> Hi Lucas >>> >>> Again many thanks for explaining and for your time. >>> >>> I got your point now and I have dug a bit better in the PCI_DOMAINS >> code. >>> >>> However I have a question...see inline below >>> >>>> -----Original Message----- >>>> From: Lucas Stach [mailto:l.stach@pengutronix.de] >>>> Sent: Thursday, August 20, 2015 9:27 AM >>>> To: Gabriele Paoloni >>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush >> Anand; >>>> Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- >>>> electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; >>>> Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux- >>>> pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; >>>> devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; >>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth) >>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support >>>> >>>> Hi Gab, >>>> >>>> Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni: >>>>> Hi Lucas >>>>> >>>>> First of all many thanks for the quick reply, really appreciated >>>>> >>>>>> -----Original Message----- >>>>>> From: Lucas Stach [mailto:l.stach@pengutronix.de] >>>>>> Sent: Wednesday, August 19, 2015 4:37 PM >>>>>> To: Gabriele Paoloni >>>>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush >>>> Anand; >>>>>> Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free- >>>>>> electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com; >>>>>> Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; >> linux- >>>>>> pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org; >>>>>> devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo; >>>>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu >> (Kenneth) >>>>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support >>>>>> >>>>>> Hi Gab, >>>>>> >>>>>> Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele >> Paoloni: >>>>>>> Hi Lucas >>>>>>> >>>>>>> I have rewritten the patch to take into account multiple >>>> controllers. >>>>>>> >>>>>>> As you can see now there is a static var in >> dw_pcie_host_init() >>>> that >>>>>> tracks >>>>>>> the bus numbers used. >>>>>> >>>>>> This is wrong. The DT specifies the valid bus number range. You >> can >>>> not >>>>>> just assign the next free bus number to the root bus. >>>>> >>>>> I think this is what is being done in >>>>> http://lxr.free- >> electrons.com/source/arch/arm/kernel/bios32.c#L495 >>>>> and currently designware assigns the root bus number in >>>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie- >>>> designware.c#L730 >>>>> >>>> You found the right spot. It works a bit different than I remember, >> but >>>> is less broken than your current code. :) >>>> >>>> It actually assigns the next instance a root bus number behind the >>>> current instances bus range. Please note the difference to your >> code >>>> which assigns the next free bus number, which may still lay within >> the >>>> current instances bus range. >> >> Hi Gabriele, >> >>> >>> Mmmm here I have done a mistake: in the current designware the number >> of hw >>> controllers is always 1 >>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie- >> designware.c#L510 >>> So the loop in bios32.c does not work on multiple PCIe ports... >> >> Bios32.c is broken for multiple PCIe hosts for multiple reasons, this >> is just >> one of them. Hence the effort to get rid of it for maintained drivers. > > As you can see we're pushing hard for this :) > How about we pass pp->busn->start to pci_create_root_bus as root bus number? We get pp->busn->start from resource list(res) whose elements come from of_pci_get_host_bridge_resources. If there is a bus-range item in dts, root bus number will get from it. Oppositely, root bus number will be default value(0x0). Thanks, Zhou >> >>> However your comment about PCI_DOMAINS enlightened my mind and now I >> see >>> that when CONFIG_PCI_DOMAINS is defined we have the domains numbers >>> (tracked by __domain_nr). >> >> CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to >> your driver. >> You could request a new domain for each controller with a special >> property to >> disable that behaviour in the dts, or you could enable >> CONFIG_PCI_DOMAINS_GENERIC >> which will give you a new domain automatically. > > So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC defaults to > the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig, arch/arm64/Kconfig). > So I think this is how current designware based drivers get multiple PCIe > controller to work (they just enable CONFIG_PCI_DOMAINS)... > > > >> >>> So (correct me if I am wrong) if we have 2 PCIe ports that do not >> specify >>> the "bus-range" property, both root ports will enumerate starting >> from >>> root_bus_nr = 0 and everything will still work ok. >> >> Correct. >> >> Best regards, >> Liviu >> >>> >>> So if my assumption is correct, I do not see why the orginal patch >> from Wang >>> Zhou is wrong. >>> The only point can be that assigning pp->root_bus_nr = 0 is not >> required >>> as pp memory is kzalloc'ed (an therefore init to zero). >>> >>> >>>> >>>>> >>>>> In general I agree with you but if you look at all the current >>>> drivers >>>>> based on designware none of them define the "bus-range" dtb >> property. >>>>> Therefore doing as you say would break the current driver when we >>>> have >>>>> multiple controllers...am I right? >>>>> >>>> The current _code_ works fine for multiple controllers. It's just >> that >>>> you must define the bus range property in the DTB if you want to >> enable >>>> multiple instances of one controller and support a kernel without >> PCI >>>> domains support. As all current implementations have only a single >>>> instance of the controller per SoC, or depend on PCI domain support, >>>> it's totally fine for them to not define the bus ranges property, >> as >>>> it's an optional property and it is well defined how things behave >> if >>>> it >>>> is absent. We absolutely need to keep that specified behavior. >>>> >>>>> If that is the case in order to fix this in the way you say I >> would >>>> need >>>>> to assign "bus-range" for all the PCIe drivers with multiple >>>> controllers: >>>>> in this case I would split the default range evenly (that is, if >> we >>>> have >>>>> two controllers I would define "bus-range" 0-127 and 128-255) >>>>> >>>>> If you think this solution is ok I can go for it. My only doubt >> was >>>> about >>>>> touching other vendors DTBs.... >>>>> >>>> You don't need to touch any of the current DTBs, as they are fine >> with >>>> the default bus range behavior. You need to keep the specified >> behavior >>>> of the bus range property with the new code. >>>> >>>> Regards, >>>> Lucas >>>>> >>>>>> >>>>>> It is perfectly valid to have a bus range of 0x00-0x10 assigned >> to >>>> one >>>>>> instance and 0x50-0xff to the next instance. Additional with >> PCIe >>>>>> hotplug you may not use the full range of the bus numbers on >> one >>>>>> instance at the first scan, but only later populate more buses >> when >>>>>> more >>>>>> bridges are added to the tree. >>>>>> >>>>>>> Drivers that do not specify the bus range in the DTB set pp- >>>>>>> root_bus_nr = DW_ROOT_NR_UNDEFINED. >>>>>>> Designware will check if the flag is set and will use the >>>> automatic >>>>>> bus range >>>>>>> assignment. >>>>>> >>>>>> No, please lets get rid of this assignment altogether. The glue >>>> drivers >>>>>> have no business in assigning the bus range. Please remove the >>>>>> pp->root_bus_nr assignment from all the glue drivers. >>>>>> >>>>>> "bus range" is a generic DW PCIe property, so just parse the >> root >>>> bus >>>>>> number from the DT, it is handled the same way for all the DW >> based >>>>>> PCIe >>>>>> drivers. The bindings specifies that if the bus range property >> is >>>>>> missing the range is 0x00-0xff, so you can default to 0 as the >> root >>>> bus >>>>>> number in that case. >>>>>> >>>>>> Also I would think this conversion warrants a patch on its own >> and >>>>>> should not be mixed in the ARM64 support patch. >>>>>> >>>>>> Regards, >>>>>> Lucas >>>>>> >>>> >>>> -- >>>> Pengutronix e.K. | Lucas Stach | >>>> Industrial Linux Solutions | http://www.pengutronix.de/ | >>> >> >> -- >> ==================== >> | I would like to | >> | fix the world, | >> | but they're not | >> | giving me the | >> \ source code! / >> --------------- >> ¯\_(?)_/¯ >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pci" in >> the body of a message to majordomo@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV2FuZ3pob3UgKEIpDQo+ IFNlbnQ6IE1vbmRheSwgQXVndXN0IDI0LCAyMDE1IDc6MjYgQU0NCj4gVG86IEdhYnJpZWxlIFBh b2xvbmkNCj4gQ2M6IExpdml1IER1ZGF1OyBMdWNhcyBTdGFjaDsgQmpvcm4gSGVsZ2Fhczsgamlu Z29vaGFuMUBnbWFpbC5jb207DQo+IFByYXR5dXNoIEFuYW5kOyBBcm5kIEJlcmdtYW5uOyBsaW51 eEBhcm0ubGludXgub3JnLnVrOw0KPiB0aG9tYXMucGV0YXp6b25pQGZyZWUtZWxlY3Ryb25zLmNv bTsgTG9yZW56byBQaWVyYWxpc2k7IEphbWVzIE1vcnNlOw0KPiBqYXNvbkBsYWtlZGFlbW9uLm5l dDsgcm9iaEBrZXJuZWwub3JnOyBsaW51eC1wY2lAdmdlci5rZXJuZWwub3JnOw0KPiBsaW51eC1h cm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmc7IGRldmljZXRyZWVAdmdlci5rZXJuZWwub3Jn Ow0KPiBZdWFuemhpY2hhbmc7IFpodWRhY2FpOyB6aGFuZ2p1a3VvOyBxaXV6aGVuZmE7IGxpdWRv bmdkb25nIChDKTsNCj4gcWl1amlhbmc7IHh1d2VpIChPKTsgTGlndW96aHUgKEtlbm5ldGgpDQo+ IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjcgMy82XSBQQ0k6IGRlc2lnbndhcmU6IEFkZCBBUk02NCBz dXBwb3J0DQo+IA0KPiBPbiAyMDE1LzgvMjEgMjI6MTksIEdhYnJpZWxlIFBhb2xvbmkgd3JvdGU6 DQo+ID4gSGkgTGl2aXUNCj4gPg0KPiA+IE1hbnkgVGhhbmtzIGZvciByZXZpZXdpbmcNCj4gPg0K PiA+PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+PiBGcm9tOiBsaW51eC1wY2ktb3du ZXJAdmdlci5rZXJuZWwub3JnIFttYWlsdG86bGludXgtcGNpLQ0KPiA+PiBvd25lckB2Z2VyLmtl cm5lbC5vcmddIE9uIEJlaGFsZiBPZiBMaXZpdSBEdWRhdQ0KPiA+PiBTZW50OiBGcmlkYXksIEF1 Z3VzdCAyMSwgMjAxNSAyOjQzIFBNDQo+ID4+IFRvOiBHYWJyaWVsZSBQYW9sb25pDQo+ID4+IENj OiBMdWNhcyBTdGFjaDsgV2FuZ3pob3UgKEIpOyBCam9ybiBIZWxnYWFzOyBqaW5nb29oYW4xQGdt YWlsLmNvbTsNCj4gPj4gUHJhdHl1c2ggQW5hbmQ7IEFybmQgQmVyZ21hbm47IGxpbnV4QGFybS5s aW51eC5vcmcudWs7DQo+ID4+IHRob21hcy5wZXRhenpvbmlAZnJlZS1lbGVjdHJvbnMuY29tOyBM b3JlbnpvIFBpZXJhbGlzaTsgSmFtZXMgTW9yc2U7DQo+ID4+IGphc29uQGxha2VkYWVtb24ubmV0 OyByb2JoQGtlcm5lbC5vcmc7IGxpbnV4LXBjaUB2Z2VyLmtlcm5lbC5vcmc7DQo+ID4+IGxpbnV4 LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsgZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5v cmc7DQo+ID4+IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpoYW5nanVrdW87IHFpdXpoZW5mYTsg bGl1ZG9uZ2RvbmcgKEMpOw0KPiA+PiBxaXVqaWFuZzsgeHV3ZWkgKE8pOyBMaWd1b3podSAoS2Vu bmV0aCkNCj4gPj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVzaWdud2FyZTog QWRkIEFSTTY0IHN1cHBvcnQNCj4gPj4NCj4gPj4gT24gVGh1LCBBdWcgMjAsIDIwMTUgYXQgMTI6 MTA6MjRQTSArMDEwMCwgR2FicmllbGUgUGFvbG9uaSB3cm90ZToNCj4gPj4+IEhpIEx1Y2FzDQo+ ID4+Pg0KPiA+Pj4gQWdhaW4gbWFueSB0aGFua3MgZm9yIGV4cGxhaW5pbmcgYW5kIGZvciB5b3Vy IHRpbWUuDQo+ID4+Pg0KPiA+Pj4gSSBnb3QgeW91ciBwb2ludCBub3cgYW5kIEkgaGF2ZSBkdWcg YSBiaXQgYmV0dGVyIGluIHRoZSBQQ0lfRE9NQUlOUw0KPiA+PiBjb2RlLg0KPiA+Pj4NCj4gPj4+ IEhvd2V2ZXIgSSBoYXZlIGEgcXVlc3Rpb24uLi5zZWUgaW5saW5lIGJlbG93DQo+ID4+Pg0KPiA+ Pj4+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4+Pj4gRnJvbTogTHVjYXMgU3RhY2gg W21haWx0bzpsLnN0YWNoQHBlbmd1dHJvbml4LmRlXQ0KPiA+Pj4+IFNlbnQ6IFRodXJzZGF5LCBB dWd1c3QgMjAsIDIwMTUgOToyNyBBTQ0KPiA+Pj4+IFRvOiBHYWJyaWVsZSBQYW9sb25pDQo+ID4+ Pj4gQ2M6IFdhbmd6aG91IChCKTsgQmpvcm4gSGVsZ2FhczsgamluZ29vaGFuMUBnbWFpbC5jb207 IFByYXR5dXNoDQo+ID4+IEFuYW5kOw0KPiA+Pj4+IEFybmQgQmVyZ21hbm47IGxpbnV4QGFybS5s aW51eC5vcmcudWs7IHRob21hcy5wZXRhenpvbmlAZnJlZS0NCj4gPj4+PiBlbGVjdHJvbnMuY29t OyBsb3JlbnpvLnBpZXJhbGlzaUBhcm0uY29tOyBqYW1lcy5tb3JzZUBhcm0uY29tOw0KPiA+Pj4+ IExpdml1LkR1ZGF1QGFybS5jb207IGphc29uQGxha2VkYWVtb24ubmV0OyByb2JoQGtlcm5lbC5v cmc7IGxpbnV4LQ0KPiA+Pj4+IHBjaUB2Z2VyLmtlcm5lbC5vcmc7IGxpbnV4LWFybS1rZXJuZWxA bGlzdHMuaW5mcmFkZWFkLm9yZzsNCj4gPj4+PiBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZzsg WXVhbnpoaWNoYW5nOyBaaHVkYWNhaTsgemhhbmdqdWt1bzsNCj4gPj4+PiBxaXV6aGVuZmE7IGxp dWRvbmdkb25nIChDKTsgcWl1amlhbmc7IHh1d2VpIChPKTsgTGlndW96aHUgKEtlbm5ldGgpDQo+ ID4+Pj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVzaWdud2FyZTogQWRkIEFS TTY0IHN1cHBvcnQNCj4gPj4+Pg0KPiA+Pj4+IEhpIEdhYiwNCj4gPj4+Pg0KPiA+Pj4+IEFtIE1p dHR3b2NoLCBkZW4gMTkuMDguMjAxNSwgMTY6MzQgKzAwMDAgc2NocmllYiBHYWJyaWVsZSBQYW9s b25pOg0KPiA+Pj4+PiBIaSBMdWNhcw0KPiA+Pj4+Pg0KPiA+Pj4+PiBGaXJzdCBvZiBhbGwgbWFu eSB0aGFua3MgZm9yIHRoZSBxdWljayByZXBseSwgcmVhbGx5IGFwcHJlY2lhdGVkDQo+ID4+Pj4+ DQo+ID4+Pj4+PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+Pj4+Pj4gRnJvbTogTHVj YXMgU3RhY2ggW21haWx0bzpsLnN0YWNoQHBlbmd1dHJvbml4LmRlXQ0KPiA+Pj4+Pj4gU2VudDog V2VkbmVzZGF5LCBBdWd1c3QgMTksIDIwMTUgNDozNyBQTQ0KPiA+Pj4+Pj4gVG86IEdhYnJpZWxl IFBhb2xvbmkNCj4gPj4+Pj4+IENjOiBXYW5nemhvdSAoQik7IEJqb3JuIEhlbGdhYXM7IGppbmdv b2hhbjFAZ21haWwuY29tOyBQcmF0eXVzaA0KPiA+Pj4+IEFuYW5kOw0KPiA+Pj4+Pj4gQXJuZCBC ZXJnbWFubjsgbGludXhAYXJtLmxpbnV4Lm9yZy51azsgdGhvbWFzLnBldGF6em9uaUBmcmVlLQ0K PiA+Pj4+Pj4gZWxlY3Ryb25zLmNvbTsgbG9yZW56by5waWVyYWxpc2lAYXJtLmNvbTsgamFtZXMu bW9yc2VAYXJtLmNvbTsNCj4gPj4+Pj4+IExpdml1LkR1ZGF1QGFybS5jb207IGphc29uQGxha2Vk YWVtb24ubmV0OyByb2JoQGtlcm5lbC5vcmc7DQo+ID4+IGxpbnV4LQ0KPiA+Pj4+Pj4gcGNpQHZn ZXIua2VybmVsLm9yZzsgbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnOw0KPiA+ Pj4+Pj4gZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7 IHpoYW5nanVrdW87DQo+ID4+Pj4+PiBxaXV6aGVuZmE7IGxpdWRvbmdkb25nIChDKTsgcWl1amlh bmc7IHh1d2VpIChPKTsgTGlndW96aHUNCj4gPj4gKEtlbm5ldGgpDQo+ID4+Pj4+PiBTdWJqZWN0 OiBSZTogW1BBVENIIHY3IDMvNl0gUENJOiBkZXNpZ253YXJlOiBBZGQgQVJNNjQgc3VwcG9ydA0K PiA+Pj4+Pj4NCj4gPj4+Pj4+IEhpIEdhYiwNCj4gPj4+Pj4+DQo+ID4+Pj4+PiBBbSBNaXR0d29j aCwgZGVuIDE5LjA4LjIwMTUsIDE1OjE2ICswMDAwIHNjaHJpZWIgR2FicmllbGUNCj4gPj4gUGFv bG9uaToNCj4gPj4+Pj4+PiBIaSBMdWNhcw0KPiA+Pj4+Pj4+DQo+ID4+Pj4+Pj4gSSBoYXZlIHJl d3JpdHRlbiB0aGUgcGF0Y2ggdG8gdGFrZSBpbnRvIGFjY291bnQgbXVsdGlwbGUNCj4gPj4+PiBj b250cm9sbGVycy4NCj4gPj4+Pj4+Pg0KPiA+Pj4+Pj4+IEFzIHlvdSBjYW4gc2VlIG5vdyB0aGVy ZSBpcyBhIHN0YXRpYyB2YXIgaW4NCj4gPj4gZHdfcGNpZV9ob3N0X2luaXQoKQ0KPiA+Pj4+IHRo YXQNCj4gPj4+Pj4+IHRyYWNrcw0KPiA+Pj4+Pj4+IHRoZSBidXMgbnVtYmVycyB1c2VkLg0KPiA+ Pj4+Pj4NCj4gPj4+Pj4+IFRoaXMgaXMgd3JvbmcuIFRoZSBEVCBzcGVjaWZpZXMgdGhlIHZhbGlk IGJ1cyBudW1iZXIgcmFuZ2UuIFlvdQ0KPiA+PiBjYW4NCj4gPj4+PiBub3QNCj4gPj4+Pj4+IGp1 c3QgYXNzaWduIHRoZSBuZXh0IGZyZWUgYnVzIG51bWJlciB0byB0aGUgcm9vdCBidXMuDQo+ID4+ Pj4+DQo+ID4+Pj4+IEkgdGhpbmsgdGhpcyBpcyB3aGF0IGlzIGJlaW5nIGRvbmUgaW4NCj4gPj4+ Pj4gaHR0cDovL2x4ci5mcmVlLQ0KPiA+PiBlbGVjdHJvbnMuY29tL3NvdXJjZS9hcmNoL2FybS9r ZXJuZWwvYmlvczMyLmMjTDQ5NQ0KPiA+Pj4+PiBhbmQgY3VycmVudGx5IGRlc2lnbndhcmUgYXNz aWducyB0aGUgcm9vdCBidXMgbnVtYmVyIGluDQo+ID4+Pj4+IGh0dHA6Ly9seHIuZnJlZS1lbGVj dHJvbnMuY29tL3NvdXJjZS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtDQo+ID4+Pj4gZGVzaWdud2Fy ZS5jI0w3MzANCj4gPj4+Pj4NCj4gPj4+PiBZb3UgZm91bmQgdGhlIHJpZ2h0IHNwb3QuIEl0IHdv cmtzIGEgYml0IGRpZmZlcmVudCB0aGFuIEkgcmVtZW1iZXIsDQo+ID4+IGJ1dA0KPiA+Pj4+IGlz IGxlc3MgYnJva2VuIHRoYW4geW91ciBjdXJyZW50IGNvZGUuIDopDQo+ID4+Pj4NCj4gPj4+PiBJ dCBhY3R1YWxseSBhc3NpZ25zIHRoZSBuZXh0IGluc3RhbmNlIGEgcm9vdCBidXMgbnVtYmVyIGJl aGluZCB0aGUNCj4gPj4+PiBjdXJyZW50IGluc3RhbmNlcyBidXMgcmFuZ2UuIFBsZWFzZSBub3Rl IHRoZSBkaWZmZXJlbmNlIHRvIHlvdXINCj4gPj4gY29kZQ0KPiA+Pj4+IHdoaWNoIGFzc2lnbnMg dGhlIG5leHQgZnJlZSBidXMgbnVtYmVyLCB3aGljaCBtYXkgc3RpbGwgbGF5IHdpdGhpbg0KPiA+ PiB0aGUNCj4gPj4+PiBjdXJyZW50IGluc3RhbmNlcyBidXMgcmFuZ2UuDQo+ID4+DQo+ID4+IEhp IEdhYnJpZWxlLA0KPiA+Pg0KPiA+Pj4NCj4gPj4+IE1tbW0gaGVyZSBJIGhhdmUgZG9uZSBhIG1p c3Rha2U6IGluIHRoZSBjdXJyZW50IGRlc2lnbndhcmUgdGhlDQo+IG51bWJlcg0KPiA+PiBvZiBo dw0KPiA+Pj4gY29udHJvbGxlcnMgaXMgYWx3YXlzIDENCj4gPj4+IGh0dHA6Ly9seHIuZnJlZS1l bGVjdHJvbnMuY29tL3NvdXJjZS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtDQo+ID4+IGRlc2lnbndh cmUuYyNMNTEwDQo+ID4+PiBTbyB0aGUgbG9vcCBpbiBiaW9zMzIuYyBkb2VzIG5vdCB3b3JrIG9u IG11bHRpcGxlIFBDSWUgcG9ydHMuLi4NCj4gPj4NCj4gPj4gQmlvczMyLmMgaXMgYnJva2VuIGZv ciBtdWx0aXBsZSBQQ0llIGhvc3RzIGZvciBtdWx0aXBsZSByZWFzb25zLA0KPiB0aGlzDQo+ID4+ IGlzIGp1c3QNCj4gPj4gb25lIG9mIHRoZW0uIEhlbmNlIHRoZSBlZmZvcnQgdG8gZ2V0IHJpZCBv ZiBpdCBmb3IgbWFpbnRhaW5lZA0KPiBkcml2ZXJzLg0KPiA+DQo+ID4gQXMgeW91IGNhbiBzZWUg d2UncmUgcHVzaGluZyBoYXJkIGZvciB0aGlzIDopDQo+ID4NCj4gDQo+IEhvdyBhYm91dCB3ZSBw YXNzIHBwLT5idXNuLT5zdGFydCB0byBwY2lfY3JlYXRlX3Jvb3RfYnVzIGFzIHJvb3QgYnVzDQo+ IG51bWJlcj8NCj4gV2UgZ2V0IHBwLT5idXNuLT5zdGFydCBmcm9tIHJlc291cmNlIGxpc3QocmVz KSB3aG9zZSBlbGVtZW50cyBjb21lIGZyb20NCj4gb2ZfcGNpX2dldF9ob3N0X2JyaWRnZV9yZXNv dXJjZXMuDQo+IA0KPiBJZiB0aGVyZSBpcyBhIGJ1cy1yYW5nZSBpdGVtIGluIGR0cywgcm9vdCBi dXMgbnVtYmVyIHdpbGwgZ2V0IGZyb20gaXQuDQo+IE9wcG9zaXRlbHksIHJvb3QgYnVzIG51bWJl ciB3aWxsIGJlIGRlZmF1bHQgdmFsdWUoMHgwKS4NCj4gDQo+IFRoYW5rcywNCj4gWmhvdQ0KDQpT b3VuZHMgZ29vZCB0byBtZS4gU28gd2UgY2FuIHJlbW92ZSByb290X2J1c19ucg0KDQo+IA0KPiA+ Pg0KPiA+Pj4gSG93ZXZlciB5b3VyIGNvbW1lbnQgYWJvdXQgUENJX0RPTUFJTlMgZW5saWdodGVu ZWQgbXkgbWluZCBhbmQgbm93DQo+IEkNCj4gPj4gc2VlDQo+ID4+PiB0aGF0IHdoZW4gQ09ORklH X1BDSV9ET01BSU5TIGlzIGRlZmluZWQgd2UgaGF2ZSB0aGUgZG9tYWlucyBudW1iZXJzDQo+ID4+ PiAodHJhY2tlZCBieSBfX2RvbWFpbl9ucikuDQo+ID4+DQo+ID4+IENPTkZJR19QQ0lfRE9NQUlO UyBpbiBpdHNlbGYgZG9lc24ndCBkbyBtdWNoIHdpdGhvdXQgYWRkaW5nIGNvZGUgdG8NCj4gPj4g eW91ciBkcml2ZXIuDQo+ID4+IFlvdSBjb3VsZCByZXF1ZXN0IGEgbmV3IGRvbWFpbiBmb3IgZWFj aCBjb250cm9sbGVyIHdpdGggYSBzcGVjaWFsDQo+ID4+IHByb3BlcnR5IHRvDQo+ID4+IGRpc2Fi bGUgdGhhdCBiZWhhdmlvdXIgaW4gdGhlIGR0cywgb3IgeW91IGNvdWxkIGVuYWJsZQ0KPiA+PiBD T05GSUdfUENJX0RPTUFJTlNfR0VORVJJQw0KPiA+PiB3aGljaCB3aWxsIGdpdmUgeW91IGEgbmV3 IGRvbWFpbiBhdXRvbWF0aWNhbGx5Lg0KPiA+DQo+ID4gU28gZmFyIEkgc2VlIHRoYXQgZm9yIEFS TSBhbmQgQVJNNjQgQ09ORklHX1BDSV9ET01BSU5TX0dFTkVSSUMNCj4gZGVmYXVsdHMgdG8NCj4g PiB0aGUgc2FtZSB2YWx1ZSBhcyBDT05GSUdfUENJX0RPTUFJTlMgKHNlZSBhcmNoL2FybS9LY29u ZmlnLA0KPiBhcmNoL2FybTY0L0tjb25maWcpLg0KPiA+IFNvIEkgdGhpbmsgdGhpcyBpcyBob3cg Y3VycmVudCBkZXNpZ253YXJlIGJhc2VkIGRyaXZlcnMgZ2V0IG11bHRpcGxlDQo+IFBDSWUNCj4g PiBjb250cm9sbGVyIHRvIHdvcmsgKHRoZXkganVzdCBlbmFibGUgQ09ORklHX1BDSV9ET01BSU5T KS4uLg0KPiA+DQo+ID4NCj4gPg0KPiA+Pg0KPiA+Pj4gU28gKGNvcnJlY3QgbWUgaWYgSSBhbSB3 cm9uZykgaWYgd2UgaGF2ZSAyIFBDSWUgcG9ydHMgdGhhdCBkbyBub3QNCj4gPj4gc3BlY2lmeQ0K PiA+Pj4gdGhlICJidXMtcmFuZ2UiIHByb3BlcnR5LCBib3RoIHJvb3QgcG9ydHMgd2lsbCBlbnVt ZXJhdGUgc3RhcnRpbmcNCj4gPj4gZnJvbQ0KPiA+Pj4gcm9vdF9idXNfbnIgPSAwIGFuZCBldmVy eXRoaW5nIHdpbGwgc3RpbGwgd29yayBvay4NCj4gPj4NCj4gPj4gQ29ycmVjdC4NCj4gPj4NCj4g Pj4gQmVzdCByZWdhcmRzLA0KPiA+PiBMaXZpdQ0KPiA+Pg0KPiA+Pj4NCj4gPj4+IFNvIGlmIG15 IGFzc3VtcHRpb24gaXMgY29ycmVjdCwgSSBkbyBub3Qgc2VlIHdoeSB0aGUgb3JnaW5hbCBwYXRj aA0KPiA+PiBmcm9tIFdhbmcNCj4gPj4+IFpob3UgaXMgd3JvbmcuDQo+ID4+PiBUaGUgb25seSBw b2ludCBjYW4gYmUgdGhhdCBhc3NpZ25pbmcgcHAtPnJvb3RfYnVzX25yID0gMCBpcyBub3QNCj4g Pj4gcmVxdWlyZWQNCj4gPj4+IGFzIHBwIG1lbW9yeSBpcyBremFsbG9jJ2VkIChhbiB0aGVyZWZv cmUgaW5pdCB0byB6ZXJvKS4NCj4gPj4+DQo+ID4+Pg0KPiA+Pj4+DQo+ID4+Pj4+DQo+ID4+Pj4+ IEluIGdlbmVyYWwgSSBhZ3JlZSB3aXRoIHlvdSBidXQgaWYgeW91IGxvb2sgYXQgYWxsIHRoZSBj dXJyZW50DQo+ID4+Pj4gZHJpdmVycw0KPiA+Pj4+PiBiYXNlZCBvbiBkZXNpZ253YXJlIG5vbmUg b2YgdGhlbSBkZWZpbmUgdGhlICJidXMtcmFuZ2UiIGR0Yg0KPiA+PiBwcm9wZXJ0eS4NCj4gPj4+ Pj4gVGhlcmVmb3JlIGRvaW5nIGFzIHlvdSBzYXkgd291bGQgYnJlYWsgdGhlIGN1cnJlbnQgZHJp dmVyIHdoZW4gd2UNCj4gPj4+PiBoYXZlDQo+ID4+Pj4+IG11bHRpcGxlIGNvbnRyb2xsZXJzLi4u YW0gSSByaWdodD8NCj4gPj4+Pj4NCj4gPj4+PiBUaGUgY3VycmVudCBfY29kZV8gd29ya3MgZmlu ZSBmb3IgbXVsdGlwbGUgY29udHJvbGxlcnMuIEl0J3MganVzdA0KPiA+PiB0aGF0DQo+ID4+Pj4g eW91IG11c3QgZGVmaW5lIHRoZSBidXMgcmFuZ2UgcHJvcGVydHkgaW4gdGhlIERUQiBpZiB5b3Ug d2FudCB0bw0KPiA+PiBlbmFibGUNCj4gPj4+PiBtdWx0aXBsZSBpbnN0YW5jZXMgb2Ygb25lIGNv bnRyb2xsZXIgYW5kIHN1cHBvcnQgYSBrZXJuZWwgd2l0aG91dA0KPiA+PiBQQ0kNCj4gPj4+PiBk b21haW5zIHN1cHBvcnQuIEFzIGFsbCBjdXJyZW50IGltcGxlbWVudGF0aW9ucyBoYXZlIG9ubHkg YSBzaW5nbGUNCj4gPj4+PiBpbnN0YW5jZSBvZiB0aGUgY29udHJvbGxlciBwZXIgU29DLCBvciBk ZXBlbmQgb24gUENJIGRvbWFpbg0KPiBzdXBwb3J0LA0KPiA+Pj4+IGl0J3MgdG90YWxseSBmaW5l IGZvciB0aGVtIHRvIG5vdCBkZWZpbmUgdGhlIGJ1cyByYW5nZXMgcHJvcGVydHksDQo+ID4+IGFz DQo+ID4+Pj4gaXQncyBhbiBvcHRpb25hbCBwcm9wZXJ0eSBhbmQgaXQgaXMgd2VsbCBkZWZpbmVk IGhvdyB0aGluZ3MgYmVoYXZlDQo+ID4+IGlmDQo+ID4+Pj4gaXQNCj4gPj4+PiBpcyBhYnNlbnQu IFdlIGFic29sdXRlbHkgbmVlZCB0byBrZWVwIHRoYXQgc3BlY2lmaWVkIGJlaGF2aW9yLg0KPiA+ Pj4+DQo+ID4+Pj4+IElmIHRoYXQgaXMgdGhlIGNhc2UgaW4gb3JkZXIgdG8gZml4IHRoaXMgaW4g dGhlIHdheSB5b3Ugc2F5IEkNCj4gPj4gd291bGQNCj4gPj4+PiBuZWVkDQo+ID4+Pj4+IHRvIGFz c2lnbiAiYnVzLXJhbmdlIiBmb3IgYWxsIHRoZSBQQ0llIGRyaXZlcnMgd2l0aCBtdWx0aXBsZQ0K PiA+Pj4+IGNvbnRyb2xsZXJzOg0KPiA+Pj4+PiBpbiB0aGlzIGNhc2UgSSB3b3VsZCBzcGxpdCB0 aGUgZGVmYXVsdCByYW5nZSBldmVubHkgKHRoYXQgaXMsIGlmDQo+ID4+IHdlDQo+ID4+Pj4gaGF2 ZQ0KPiA+Pj4+PiB0d28gY29udHJvbGxlcnMgSSB3b3VsZCBkZWZpbmUgImJ1cy1yYW5nZSIgIDAt MTI3IGFuZCAxMjgtMjU1KQ0KPiA+Pj4+Pg0KPiA+Pj4+PiBJZiB5b3UgdGhpbmsgdGhpcyBzb2x1 dGlvbiBpcyBvayBJIGNhbiBnbyBmb3IgaXQuIE15IG9ubHkgZG91YnQNCj4gPj4gd2FzDQo+ID4+ Pj4gYWJvdXQNCj4gPj4+Pj4gdG91Y2hpbmcgb3RoZXIgdmVuZG9ycyBEVEJzLi4uLg0KPiA+Pj4+ Pg0KPiA+Pj4+IFlvdSBkb24ndCBuZWVkIHRvIHRvdWNoIGFueSBvZiB0aGUgY3VycmVudCBEVEJz LCBhcyB0aGV5IGFyZSBmaW5lDQo+ID4+IHdpdGgNCj4gPj4+PiB0aGUgZGVmYXVsdCBidXMgcmFu Z2UgYmVoYXZpb3IuIFlvdSBuZWVkIHRvIGtlZXAgdGhlIHNwZWNpZmllZA0KPiA+PiBiZWhhdmlv cg0KPiA+Pj4+IG9mIHRoZSBidXMgcmFuZ2UgcHJvcGVydHkgd2l0aCB0aGUgbmV3IGNvZGUuDQo+ ID4+Pj4NCj4gPj4+PiBSZWdhcmRzLA0KPiA+Pj4+IEx1Y2FzDQo+ID4+Pj4+DQo+ID4+Pj4+Pg0K PiA+Pj4+Pj4gSXQgaXMgcGVyZmVjdGx5IHZhbGlkIHRvIGhhdmUgYSBidXMgcmFuZ2Ugb2YgMHgw MC0weDEwIGFzc2lnbmVkDQo+ID4+IHRvDQo+ID4+Pj4gb25lDQo+ID4+Pj4+PiBpbnN0YW5jZSBh bmQgMHg1MC0weGZmIHRvIHRoZSBuZXh0IGluc3RhbmNlLiBBZGRpdGlvbmFsIHdpdGgNCj4gPj4g UENJZQ0KPiA+Pj4+Pj4gaG90cGx1ZyB5b3UgbWF5IG5vdCB1c2UgdGhlIGZ1bGwgcmFuZ2Ugb2Yg dGhlIGJ1cyBudW1iZXJzIG9uDQo+ID4+IG9uZQ0KPiA+Pj4+Pj4gaW5zdGFuY2UgYXQgdGhlIGZp cnN0IHNjYW4sIGJ1dCBvbmx5IGxhdGVyIHBvcHVsYXRlIG1vcmUgYnVzZXMNCj4gPj4gd2hlbg0K PiA+Pj4+Pj4gbW9yZQ0KPiA+Pj4+Pj4gYnJpZGdlcyBhcmUgYWRkZWQgdG8gdGhlIHRyZWUuDQo+ ID4+Pj4+Pg0KPiA+Pj4+Pj4+IERyaXZlcnMgdGhhdCBkbyBub3Qgc3BlY2lmeSB0aGUgYnVzIHJh bmdlIGluIHRoZSBEVEIgc2V0IHBwLQ0KPiA+Pj4+Pj4+IHJvb3RfYnVzX25yID0gRFdfUk9PVF9O Ul9VTkRFRklORUQuDQo+ID4+Pj4+Pj4gRGVzaWdud2FyZSB3aWxsIGNoZWNrIGlmIHRoZSBmbGFn IGlzIHNldCBhbmQgd2lsbCB1c2UgdGhlDQo+ID4+Pj4gYXV0b21hdGljDQo+ID4+Pj4+PiBidXMg cmFuZ2UNCj4gPj4+Pj4+PiBhc3NpZ25tZW50Lg0KPiA+Pj4+Pj4NCj4gPj4+Pj4+IE5vLCBwbGVh c2UgbGV0cyBnZXQgcmlkIG9mIHRoaXMgYXNzaWdubWVudCBhbHRvZ2V0aGVyLiBUaGUgZ2x1ZQ0K PiA+Pj4+IGRyaXZlcnMNCj4gPj4+Pj4+IGhhdmUgbm8gYnVzaW5lc3MgaW4gYXNzaWduaW5nIHRo ZSBidXMgcmFuZ2UuIFBsZWFzZSByZW1vdmUgdGhlDQo+ID4+Pj4+PiBwcC0+cm9vdF9idXNfbnIg YXNzaWdubWVudCBmcm9tIGFsbCB0aGUgZ2x1ZSBkcml2ZXJzLg0KPiA+Pj4+Pj4NCj4gPj4+Pj4+ ICJidXMgcmFuZ2UiIGlzIGEgZ2VuZXJpYyBEVyBQQ0llIHByb3BlcnR5LCBzbyBqdXN0IHBhcnNl IHRoZQ0KPiA+PiByb290DQo+ID4+Pj4gYnVzDQo+ID4+Pj4+PiBudW1iZXIgZnJvbSB0aGUgRFQs IGl0IGlzIGhhbmRsZWQgdGhlIHNhbWUgd2F5IGZvciBhbGwgdGhlIERXDQo+ID4+IGJhc2VkDQo+ ID4+Pj4+PiBQQ0llDQo+ID4+Pj4+PiBkcml2ZXJzLiBUaGUgYmluZGluZ3Mgc3BlY2lmaWVzIHRo YXQgaWYgdGhlIGJ1cyByYW5nZSBwcm9wZXJ0eQ0KPiA+PiBpcw0KPiA+Pj4+Pj4gbWlzc2luZyB0 aGUgcmFuZ2UgaXMgMHgwMC0weGZmLCBzbyB5b3UgY2FuIGRlZmF1bHQgdG8gMCBhcyB0aGUNCj4g Pj4gcm9vdA0KPiA+Pj4+IGJ1cw0KPiA+Pj4+Pj4gbnVtYmVyIGluIHRoYXQgY2FzZS4NCj4gPj4+ Pj4+DQo+ID4+Pj4+PiBBbHNvIEkgd291bGQgdGhpbmsgdGhpcyBjb252ZXJzaW9uIHdhcnJhbnRz IGEgcGF0Y2ggb24gaXRzIG93bg0KPiA+PiBhbmQNCj4gPj4+Pj4+IHNob3VsZCBub3QgYmUgbWl4 ZWQgaW4gdGhlIEFSTTY0IHN1cHBvcnQgcGF0Y2guDQo+ID4+Pj4+Pg0KPiA+Pj4+Pj4gUmVnYXJk cywNCj4gPj4+Pj4+IEx1Y2FzDQo+ID4+Pj4+Pg0KPiA+Pj4+DQo+ID4+Pj4gLS0NCj4gPj4+PiBQ ZW5ndXRyb25peCBlLksuICAgICAgICAgICAgIHwgTHVjYXMgU3RhY2ggICAgICAgICAgICAgICAg IHwNCj4gPj4+PiBJbmR1c3RyaWFsIExpbnV4IFNvbHV0aW9ucyAgIHwgaHR0cDovL3d3dy5wZW5n dXRyb25peC5kZS8gIHwNCj4gPj4+DQo+ID4+DQo+ID4+IC0tDQo+ID4+ID09PT09PT09PT09PT09 PT09PT09DQo+ID4+IHwgSSB3b3VsZCBsaWtlIHRvIHwNCj4gPj4gfCBmaXggdGhlIHdvcmxkLCAg fA0KPiA+PiB8IGJ1dCB0aGV5J3JlIG5vdCB8DQo+ID4+IHwgZ2l2aW5nIG1lIHRoZSAgIHwNCj4g Pj4gIFwgc291cmNlIGNvZGUhICAvDQo+ID4+ICAgLS0tLS0tLS0tLS0tLS0tDQo+ID4+ICAgICDC r1xfKOODhClfL8KvDQo+ID4+DQo+ID4+IC0tDQo+ID4+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhp cyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC1wY2kiDQo+IGluDQo+ID4+ IHRoZSBib2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnDQo+ID4+ IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21v LWluZm8uaHRtbA0KPiANCg0K -- To unsubscribe from this list: send the line "unsubscribe linux-pci" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c index 18ae7ff..1268c69 100644 --- a/drivers/pci/host/pci-dra7xx.c +++ b/drivers/pci/host/pci-dra7xx.c @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp) { dw_pcie_setup_rc(pp); - if (pp->io_mod_base) - pp->io_mod_base &= CPU_TO_BUS_ADDR; + if (pp->io_base) + pp->io_base &= CPU_TO_BUS_ADDR; - if (pp->mem_mod_base) - pp->mem_mod_base &= CPU_TO_BUS_ADDR; + if (pp->mem_base) + pp->mem_base &= CPU_TO_BUS_ADDR; - if (pp->cfg0_mod_base) { - pp->cfg0_mod_base &= CPU_TO_BUS_ADDR; - pp->cfg1_mod_base &= CPU_TO_BUS_ADDR; + if (pp->cfg0_base) { + pp->cfg0_base &= CPU_TO_BUS_ADDR; + pp->cfg1_base &= CPU_TO_BUS_ADDR; } dra7xx_pcie_establish_link(pp); @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, pp = &dra7xx->pp; pp->dev = dev; + pp->root_bus_nr = 0; pp->ops = &dra7xx_pcie_host_ops; pp->irq = platform_get_irq(pdev, 1); diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c index f9f468d..9771bb0 100644 --- a/drivers/pci/host/pci-exynos.c +++ b/drivers/pci/host/pci-exynos.c @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr = -1; + pp->root_bus_nr = 0; pp->ops = &exynos_pcie_host_ops; ret = dw_pcie_host_init(pp); diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c index 233a196..bec256c 100644 --- a/drivers/pci/host/pci-imx6.c +++ b/drivers/pci/host/pci-imx6.c @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, } } - pp->root_bus_nr = -1; + pp->root_bus_nr = 0; pp->ops = &imx6_pcie_host_ops; ret = dw_pcie_host_init(pp); diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c index f34892e..b1e4135 100644 --- a/drivers/pci/host/pci-keystone-dw.c +++ b/drivers/pci/host/pci-keystone-dw.c @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt) void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie) { struct pcie_port *pp = &ks_pcie->pp; - u32 start = pp->mem.start, end = pp->mem.end; + u32 start = pp->mem->start, end = pp->mem->end; int i, tr_size; /* Disable BARs for inbound access */ diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c index 734da58..8113832 100644 --- a/drivers/pci/host/pci-keystone.c +++ b/drivers/pci/host/pci-keystone.c @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie, return ret; } - pp->root_bus_nr = -1; + pp->root_bus_nr = 0; pp->ops = &keystone_pcie_host_ops; ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np); if (ret) { diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index b2328ea1..79ff08c 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie) pp = &pcie->pp; pp->dev = pcie->dev; pp->dbi_base = pcie->dbi; - pp->root_bus_nr = -1; + pp->root_bus_nr = 0; pp->ops = &ls_pcie_host_ops; ret = dw_pcie_host_init(pp); diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index c5d407c..e71a88e 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c @@ -11,6 +11,7 @@ * published by the Free Software Foundation. */ +#include <linux/hardirq.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/kernel.h> @@ -69,16 +70,7 @@ #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16) #define PCIE_ATU_UPPER_TARGET 0x91C -static struct hw_pci dw_pci; - -static unsigned long global_io_offset; - -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys) -{ - BUG_ON(!sys->private_data); - - return sys->private_data; -} +static struct pci_ops dw_pcie_ops; int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val) { @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq) static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos) { int irq, pos0, i; - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata); + struct pcie_port *pp = desc->dev->bus->sysdata; pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS, order_base_2(no_irqs)); @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev, { int irq, pos; struct msi_msg msg; - struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata); + struct pcie_port *pp = pdev->bus->sysdata; if (desc->msi_attrib.is_msix) return -EINVAL; @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq) { struct irq_data *data = irq_get_irq_data(irq); struct msi_desc *msi = irq_data_get_msi(data); - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata); + struct pcie_port *pp = msi->dev->bus->sysdata; clear_irq_range(pp, irq, 1, data->hwirq); } @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp) { struct device_node *np = pp->dev->of_node; struct platform_device *pdev = to_platform_device(pp->dev); - struct of_pci_range range; - struct of_pci_range_parser parser; + struct pci_bus *bus; struct resource *cfg_res; - u32 val, ns; - const __be32 *addrp; - int i, index, ret; - - ns = of_n_size_cells(np); + LIST_HEAD(res); + u32 val; + int i, ret; + struct resource_entry *win; cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (cfg_res) { @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp) pp->cfg1_size = resource_size(cfg_res)/2; pp->cfg0_base = cfg_res->start; pp->cfg1_base = cfg_res->start + pp->cfg0_size; - - /* Find the untranslated configuration space address */ - index = of_property_match_string(np, "reg-names", "config"); - addrp = of_get_address(np, index, NULL, NULL); - pp->cfg0_mod_base = of_read_number(addrp, ns); - pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size; } else { dev_err(pp->dev, "missing *config* reg space\n"); } - if (of_pci_range_parser_init(&parser, np)) { - dev_err(pp->dev, "missing ranges property\n"); - return -EINVAL; - } + ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base); + if (ret) + return ret; /* Get the I/O and memory ranges from DT */ - for_each_of_pci_range(&parser, &range) { - unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; - - if (restype == IORESOURCE_IO) { - of_pci_range_to_resource(&range, np, &pp->io); - pp->io.name = "I/O"; - pp->io.start = max_t(resource_size_t, - PCIBIOS_MIN_IO, - range.pci_addr + global_io_offset); - pp->io.end = min_t(resource_size_t, - IO_SPACE_LIMIT, - range.pci_addr + range.size - + global_io_offset - 1); - pp->io_size = resource_size(&pp->io); - pp->io_bus_addr = range.pci_addr; - pp->io_base = range.cpu_addr; - - /* Find the untranslated IO space address */ - pp->io_mod_base = range.cpu_addr; - } - if (restype == IORESOURCE_MEM) { - of_pci_range_to_resource(&range, np, &pp->mem); - pp->mem.name = "MEM"; - pp->mem_size = resource_size(&pp->mem); - pp->mem_bus_addr = range.pci_addr; - - /* Find the untranslated MEM space address */ - pp->mem_mod_base = range.cpu_addr; - } - if (restype == 0) { - of_pci_range_to_resource(&range, np, &pp->cfg); - pp->cfg0_size = resource_size(&pp->cfg)/2; - pp->cfg1_size = resource_size(&pp->cfg)/2; - pp->cfg0_base = pp->cfg.start; - pp->cfg1_base = pp->cfg.start + pp->cfg0_size; - - /* Find the untranslated configuration space address */ - pp->cfg0_mod_base = range.cpu_addr; - pp->cfg1_mod_base = pp->cfg0_mod_base + - pp->cfg0_size; + resource_list_for_each_entry(win, &res) { + switch (resource_type(win->res)) { + case IORESOURCE_IO: + pp->io = win->res; + pp->io->name = "I/O"; + pp->io_size = resource_size(pp->io); + pp->io_bus_addr = pp->io->start - win->offset; + ret = pci_remap_iospace(pp->io, pp->io_base); + if (ret) { + dev_warn(pp->dev, "error %d: failed to map resource %pR\n", + ret, pp->io); + continue; + } + break; + case IORESOURCE_MEM: + pp->mem = win->res; + pp->mem->name = "MEM"; + pp->mem_size = resource_size(pp->mem); + pp->mem_bus_addr = pp->mem->start - win->offset; + break; + case 0: + pp->cfg = win->res; + pp->cfg0_size = resource_size(pp->cfg)/2; + pp->cfg1_size = resource_size(pp->cfg)/2; + pp->cfg0_base = pp->cfg->start; + pp->cfg1_base = pp->cfg->start + pp->cfg0_size; + break; + case IORESOURCE_BUS: + pp->busn = win->res; + break; + default: + continue; } } - ret = of_pci_parse_bus_range(np, &pp->busn); - if (ret < 0) { - pp->busn.name = np->name; - pp->busn.start = 0; - pp->busn.end = 0xff; - pp->busn.flags = IORESOURCE_BUS; - dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n", - ret, &pp->busn); - } - if (!pp->dbi_base) { - pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start, - resource_size(&pp->cfg)); + pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start, + resource_size(pp->cfg)); if (!pp->dbi_base) { dev_err(pp->dev, "error with ioremap\n"); return -ENOMEM; } } - pp->mem_base = pp->mem.start; + pp->mem_base = pp->mem->start; if (!pp->va_cfg0_base) { pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base, @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp) if (!pp->ops->rd_other_conf) dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1, - PCIE_ATU_TYPE_MEM, pp->mem_mod_base, + PCIE_ATU_TYPE_MEM, pp->mem_base, pp->mem_bus_addr, pp->mem_size); dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0); @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp) val |= PORT_LOGIC_SPEED_CHANGE; dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val); -#ifdef CONFIG_PCI_MSI + bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops, + pp, &res); + if (!bus) + return -ENOMEM; + +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN + bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain); +#else dw_pcie_msi_chip.dev = pp->dev; - dw_pci.msi_ctrl = &dw_pcie_msi_chip; + bus->msi = &dw_pcie_msi_chip; #endif - dw_pci.nr_controllers = 1; - dw_pci.private_data = (void **)&pp; + pci_scan_child_bus(bus); + if (pp->ops->scan_bus) + pp->ops->scan_bus(pp); + +#ifdef CONFIG_ARM + /* support old dtbs that incorrectly describe IRQs */ + pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci); +#endif - pci_common_init_dev(pp->dev, &dw_pci); + pci_assign_unassigned_bus_resources(bus); + pci_bus_add_devices(bus); return 0; } @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, if (bus->parent->number == pp->root_bus_nr) { type = PCIE_ATU_TYPE_CFG0; - cpu_addr = pp->cfg0_mod_base; + cpu_addr = pp->cfg0_base; cfg_size = pp->cfg0_size; va_cfg_base = pp->va_cfg0_base; } else { type = PCIE_ATU_TYPE_CFG1; - cpu_addr = pp->cfg1_mod_base; + cpu_addr = pp->cfg1_base; cfg_size = pp->cfg1_size; va_cfg_base = pp->va_cfg1_base; } @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, busdev, cfg_size); ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val); dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_IO, pp->io_mod_base, + PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); return ret; @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, if (bus->parent->number == pp->root_bus_nr) { type = PCIE_ATU_TYPE_CFG0; - cpu_addr = pp->cfg0_mod_base; + cpu_addr = pp->cfg0_base; cfg_size = pp->cfg0_size; va_cfg_base = pp->va_cfg0_base; } else { type = PCIE_ATU_TYPE_CFG1; - cpu_addr = pp->cfg1_mod_base; + cpu_addr = pp->cfg1_base; cfg_size = pp->cfg1_size; va_cfg_base = pp->va_cfg1_base; } @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus, busdev, cfg_size); ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val); dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0, - PCIE_ATU_TYPE_IO, pp->io_mod_base, + PCIE_ATU_TYPE_IO, pp->io_base, pp->io_bus_addr, pp->io_size); return ret; @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp, static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 *val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) { @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, int where, int size, u32 val) { - struct pcie_port *pp = sys_to_pcie(bus->sysdata); + struct pcie_port *pp = bus->sysdata; int ret; if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = { .write = dw_pcie_wr_conf, }; -static int dw_pcie_setup(int nr, struct pci_sys_data *sys) -{ - struct pcie_port *pp; - - pp = sys_to_pcie(sys); - - if (global_io_offset < SZ_1M && pp->io_size > 0) { - sys->io_offset = global_io_offset - pp->io_bus_addr; - pci_ioremap_io(global_io_offset, pp->io_base); - global_io_offset += SZ_64K; - pci_add_resource_offset(&sys->resources, &pp->io, - sys->io_offset); - } - - sys->mem_offset = pp->mem.start - pp->mem_bus_addr; - pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset); - pci_add_resource(&sys->resources, &pp->busn); - - return 1; -} - -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) -{ - struct pci_bus *bus; - struct pcie_port *pp = sys_to_pcie(sys); - - pp->root_bus_nr = sys->busnr; - bus = pci_scan_root_bus(pp->dev, sys->busnr, - &dw_pcie_ops, sys, &sys->resources); - if (!bus) - return NULL; - - if (bus && pp->ops->scan_bus) - pp->ops->scan_bus(pp); - - return bus; -} - -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) -{ - struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); - int irq; - - irq = of_irq_parse_and_map_pci(dev, slot, pin); - if (!irq) - irq = pp->irq; - - return irq; -} - -static struct hw_pci dw_pci = { - .setup = dw_pcie_setup, - .scan = dw_pcie_scan_bus, - .map_irq = dw_pcie_map_irq, -}; - void dw_pcie_setup_rc(struct pcie_port *pp) { u32 val; diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h index d0bbd27..264c969 100644 --- a/drivers/pci/host/pcie-designware.h +++ b/drivers/pci/host/pcie-designware.h @@ -27,25 +27,21 @@ struct pcie_port { u8 root_bus_nr; void __iomem *dbi_base; u64 cfg0_base; - u64 cfg0_mod_base; void __iomem *va_cfg0_base; u32 cfg0_size; u64 cfg1_base; - u64 cfg1_mod_base; void __iomem *va_cfg1_base; u32 cfg1_size; - u64 io_base; - u64 io_mod_base; + resource_size_t io_base; phys_addr_t io_bus_addr; u32 io_size; u64 mem_base; - u64 mem_mod_base; phys_addr_t mem_bus_addr; u32 mem_size; - struct resource cfg; - struct resource io; - struct resource mem; - struct resource busn; + struct resource *cfg; + struct resource *io; + struct resource *mem; + struct resource *busn; int irq; u32 lanes; struct pcie_host_ops *ops; diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c index c49fbdc..03eb204 100644 --- a/drivers/pci/host/pcie-spear13xx.c +++ b/drivers/pci/host/pcie-spear13xx.c @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp, return ret; } - pp->root_bus_nr = -1; + pp->root_bus_nr = 0; pp->ops = &spear13xx_pcie_host_ops; ret = dw_pcie_host_init(pp);