Merge branch 'topic/bjorn-trivial' into next
authorBjorn Helgaas <bhelgaas@google.com>
Fri, 22 Jun 2012 21:32:50 +0000 (15:32 -0600)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 22 Jun 2012 21:32:50 +0000 (15:32 -0600)
* topic/bjorn-trivial:
  PCI: remove useless pcix_set_mmrbc() dev->bus check
  PCI: acpiphp: check whether _ADR evaluation succeeded
  PCI: shpchp: remove dead code
  PCI: fix P2P bridge I/O port window sign extension
  PCI: fix upstream P2P bridge checks when enabling OBFF and LTR
  PCI: use __weak consistently
  PCI: cleanup assign_requested_resources_sorted() kernel-doc warning
  sparc/PCI: remove unused pcibios_assign_resource() definition

1  2 
drivers/pci/hotplug/acpiphp_glue.c
drivers/pci/pci.c
drivers/pci/probe.c
drivers/pci/setup-bus.c

@@@ -100,11 -100,11 +100,11 @@@ static int post_dock_fixups(struct noti
                        PCI_PRIMARY_BUS,
                        &buses);
  
 -      if (((buses >> 8) & 0xff) != bus->secondary) {
 +      if (((buses >> 8) & 0xff) != bus->busn_res.start) {
                buses = (buses & 0xff000000)
                        | ((unsigned int)(bus->primary)     <<  0)
 -                      | ((unsigned int)(bus->secondary)   <<  8)
 -                      | ((unsigned int)(bus->subordinate) << 16);
 +                      | ((unsigned int)(bus->busn_res.start)   <<  8)
 +                      | ((unsigned int)(bus->busn_res.end) << 16);
                pci_write_config_dword(bus->self, PCI_PRIMARY_BUS, buses);
        }
        return NOTIFY_OK;
@@@ -132,6 -132,15 +132,15 @@@ register_slot(acpi_handle handle, u32 l
        if (!acpi_pci_check_ejectable(pbus, handle) && !is_dock_device(handle))
                return AE_OK;
  
+       status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
+       if (ACPI_FAILURE(status)) {
+               warn("can't evaluate _ADR (%#x)\n", status);
+               return AE_OK;
+       }
+       device = (adr >> 16) & 0xffff;
+       function = adr & 0xffff;
        pdev = pbus->self;
        if (pdev && pci_is_pcie(pdev)) {
                tmp = acpi_find_root_bridge_handle(pdev);
                }
        }
  
-       acpi_evaluate_integer(handle, "_ADR", NULL, &adr);
-       device = (adr >> 16) & 0xffff;
-       function = adr & 0xffff;
        newfunc = kzalloc(sizeof(struct acpiphp_func), GFP_KERNEL);
        if (!newfunc)
                return AE_NO_MEMORY;
@@@ -692,7 -697,7 +697,7 @@@ static unsigned char acpiphp_max_busnr(
         * bus->subordinate value because it could have
         * padding in it.
         */
 -      max = bus->secondary;
 +      max = bus->busn_res.start;
  
        list_for_each(tmp, &bus->children) {
                n = pci_bus_max_busnr(pci_bus_b(tmp));
@@@ -878,24 -883,6 +883,24 @@@ static void disable_bridges(struct pci_
        }
  }
  
 +/* return first device in slot, acquiring a reference on it */
 +static struct pci_dev *dev_in_slot(struct acpiphp_slot *slot)
 +{
 +      struct pci_bus *bus = slot->bridge->pci_bus;
 +      struct pci_dev *dev;
 +      struct pci_dev *ret = NULL;
 +
 +      down_read(&pci_bus_sem);
 +      list_for_each_entry(dev, &bus->devices, bus_list)
 +              if (PCI_SLOT(dev->devfn) == slot->device) {
 +                      ret = pci_dev_get(dev);
 +                      break;
 +              }
 +      up_read(&pci_bus_sem);
 +
 +      return ret;
 +}
 +
  /**
   * disable_device - disable a slot
   * @slot: ACPI PHP slot
@@@ -911,7 -898,6 +916,7 @@@ static int disable_device(struct acpiph
        pdev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0));
        if (!pdev)
                goto err_exit;
 +      pci_dev_put(pdev);
  
        list_for_each_entry(func, &slot->funcs, sibling) {
                if (func->bridge) {
                                                (u32)1, NULL, NULL);
                        func->bridge = NULL;
                }
 +      }
  
 -              pdev = pci_get_slot(slot->bridge->pci_bus,
 -                                  PCI_DEVFN(slot->device, func->function));
 -              if (pdev) {
 -                      pci_stop_bus_device(pdev);
 -                      if (pdev->subordinate) {
 -                              disable_bridges(pdev->subordinate);
 -                              pci_disable_device(pdev);
 -                      }
 -                      __pci_remove_bus_device(pdev);
 -                      pci_dev_put(pdev);
 +      /*
 +       * enable_device() enumerates all functions in this device via
 +       * pci_scan_slot(), whether they have associated ACPI hotplug
 +       * methods (_EJ0, etc.) or not.  Therefore, we remove all functions
 +       * here.
 +       */
 +      while ((pdev = dev_in_slot(slot))) {
 +              pci_stop_bus_device(pdev);
 +              if (pdev->subordinate) {
 +                      disable_bridges(pdev->subordinate);
 +                      pci_disable_device(pdev);
                }
 +              __pci_remove_bus_device(pdev);
 +              pci_dev_put(pdev);
        }
  
        list_for_each_entry(func, &slot->funcs, sibling) {
diff --combined drivers/pci/pci.c
@@@ -110,7 -110,7 +110,7 @@@ unsigned char pci_bus_max_busnr(struct 
        struct list_head *tmp;
        unsigned char max, n;
  
 -      max = bus->subordinate;
 +      max = bus->busn_res.end;
        list_for_each(tmp, &bus->children) {
                n = pci_bus_max_busnr(pci_bus_b(tmp));
                if(n > max)
@@@ -136,6 -136,30 +136,6 @@@ void __iomem *pci_ioremap_bar(struct pc
  EXPORT_SYMBOL_GPL(pci_ioremap_bar);
  #endif
  
 -#if 0
 -/**
 - * pci_max_busnr - returns maximum PCI bus number
 - *
 - * Returns the highest PCI bus number present in the system global list of
 - * PCI buses.
 - */
 -unsigned char __devinit
 -pci_max_busnr(void)
 -{
 -      struct pci_bus *bus = NULL;
 -      unsigned char max, n;
 -
 -      max = 0;
 -      while ((bus = pci_find_next_bus(bus)) != NULL) {
 -              n = pci_bus_max_busnr(bus);
 -              if(n > max)
 -                      max = n;
 -      }
 -      return max;
 -}
 -
 -#endif  /*  0  */
 -
  #define PCI_FIND_CAP_TTL      48
  
  static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
@@@ -253,38 -277,6 +253,38 @@@ int pci_bus_find_capability(struct pci_
        return pos;
  }
  
 +/**
 + * pci_pcie_cap2 - query for devices' PCI_CAP_ID_EXP v2 capability structure
 + * @dev: PCI device to check
 + *
 + * Like pci_pcie_cap() but also checks that the PCIe capability version is
 + * >= 2.  Note that v1 capability structures could be sparse in that not
 + * all register fields were required.  v2 requires the entire structure to
 + * be present size wise, while still allowing for non-implemented registers
 + * to exist but they must be hardwired to 0.
 + *
 + * Due to the differences in the versions of capability structures, one
 + * must be careful not to try and access non-existant registers that may
 + * exist in early versions - v1 - of Express devices.
 + *
 + * Returns the offset of the PCIe capability structure as long as the
 + * capability version is >= 2; otherwise 0 is returned.
 + */
 +static int pci_pcie_cap2(struct pci_dev *dev)
 +{
 +      u16 flags;
 +      int pos;
 +
 +      pos = pci_pcie_cap(dev);
 +      if (pos) {
 +              pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &flags);
 +              if ((flags & PCI_EXP_FLAGS_VERS) < 2)
 +                      pos = 0;
 +      }
 +
 +      return pos;
 +}
 +
  /**
   * pci_find_ext_capability - Find an extended capability
   * @dev: PCI device to query
@@@ -337,6 -329,49 +337,6 @@@ int pci_find_ext_capability(struct pci_
  }
  EXPORT_SYMBOL_GPL(pci_find_ext_capability);
  
 -/**
 - * pci_bus_find_ext_capability - find an extended capability
 - * @bus:   the PCI bus to query
 - * @devfn: PCI device to query
 - * @cap:   capability code
 - *
 - * Like pci_find_ext_capability() but works for pci devices that do not have a
 - * pci_dev structure set up yet.
 - *
 - * Returns the address of the requested capability structure within the
 - * device's PCI configuration space or 0 in case the device does not
 - * support it.
 - */
 -int pci_bus_find_ext_capability(struct pci_bus *bus, unsigned int devfn,
 -                              int cap)
 -{
 -      u32 header;
 -      int ttl;
 -      int pos = PCI_CFG_SPACE_SIZE;
 -
 -      /* minimum 8 bytes per capability */
 -      ttl = (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8;
 -
 -      if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
 -              return 0;
 -      if (header == 0xffffffff || header == 0)
 -              return 0;
 -
 -      while (ttl-- > 0) {
 -              if (PCI_EXT_CAP_ID(header) == cap)
 -                      return pos;
 -
 -              pos = PCI_EXT_CAP_NEXT(header);
 -              if (pos < PCI_CFG_SPACE_SIZE)
 -                      break;
 -
 -              if (!pci_bus_read_config_dword(bus, devfn, pos, &header))
 -                      break;
 -      }
 -
 -      return 0;
 -}
 -
  static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
  {
        int rc, ttl = PCI_FIND_CAP_TTL;
@@@ -787,6 -822,12 +787,6 @@@ EXPORT_SYMBOL(pci_choose_state)
                ((flags & PCI_EXP_FLAGS_VERS) > 1 ||    \
                 (type == PCI_EXP_TYPE_ROOT_PORT ||     \
                  type == PCI_EXP_TYPE_RC_EC))
 -#define pcie_cap_has_devctl2(type, flags)             \
 -              ((flags & PCI_EXP_FLAGS_VERS) > 1)
 -#define pcie_cap_has_lnkctl2(type, flags)             \
 -              ((flags & PCI_EXP_FLAGS_VERS) > 1)
 -#define pcie_cap_has_sltctl2(type, flags)             \
 -              ((flags & PCI_EXP_FLAGS_VERS) > 1)
  
  static struct pci_cap_saved_state *pci_find_saved_cap(
        struct pci_dev *pci_dev, char cap)
@@@ -829,14 -870,13 +829,14 @@@ static int pci_save_pcie_state(struct p
                pci_read_config_word(dev, pos + PCI_EXP_SLTCTL, &cap[i++]);
        if (pcie_cap_has_rtctl(dev->pcie_type, flags))
                pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &cap[i++]);
 -      if (pcie_cap_has_devctl2(dev->pcie_type, flags))
 -              pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
 -      if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
 -              pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
 -      if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
 -              pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
  
 +      pos = pci_pcie_cap2(dev);
 +      if (!pos)
 +              return 0;
 +
 +      pci_read_config_word(dev, pos + PCI_EXP_DEVCTL2, &cap[i++]);
 +      pci_read_config_word(dev, pos + PCI_EXP_LNKCTL2, &cap[i++]);
 +      pci_read_config_word(dev, pos + PCI_EXP_SLTCTL2, &cap[i++]);
        return 0;
  }
  
@@@ -863,14 -903,12 +863,14 @@@ static void pci_restore_pcie_state(stru
                pci_write_config_word(dev, pos + PCI_EXP_SLTCTL, cap[i++]);
        if (pcie_cap_has_rtctl(dev->pcie_type, flags))
                pci_write_config_word(dev, pos + PCI_EXP_RTCTL, cap[i++]);
 -      if (pcie_cap_has_devctl2(dev->pcie_type, flags))
 -              pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
 -      if (pcie_cap_has_lnkctl2(dev->pcie_type, flags))
 -              pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
 -      if (pcie_cap_has_sltctl2(dev->pcie_type, flags))
 -              pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
 +
 +      pos = pci_pcie_cap2(dev);
 +      if (!pos)
 +              return;
 +
 +      pci_write_config_word(dev, pos + PCI_EXP_DEVCTL2, cap[i++]);
 +      pci_write_config_word(dev, pos + PCI_EXP_LNKCTL2, cap[i++]);
 +      pci_write_config_word(dev, pos + PCI_EXP_SLTCTL2, cap[i++]);
  }
  
  
@@@ -1311,7 -1349,7 +1311,7 @@@ void pcim_pin_device(struct pci_dev *pd
   * is the default implementation. Architecture implementations can
   * override this.
   */
- void __attribute__ ((weak)) pcibios_disable_device (struct pci_dev *dev) {}
+ void __weak pcibios_disable_device (struct pci_dev *dev) {}
  
  static void do_pci_disable_device(struct pci_dev *dev)
  {
@@@ -1375,8 -1413,8 +1375,8 @@@ pci_disable_device(struct pci_dev *dev
   * Sets the PCIe reset state for the device. This is the default
   * implementation. Architecture implementations can override this.
   */
- int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev,
-                                                       enum pcie_reset_state state)
+ int __weak pcibios_set_pcie_reset_state(struct pci_dev *dev,
+                                       enum pcie_reset_state state)
  {
        return -EINVAL;
  }
@@@ -1945,7 -1983,7 +1945,7 @@@ void pci_enable_ari(struct pci_dev *dev
  {
        int pos;
        u32 cap;
 -      u16 flags, ctrl;
 +      u16 ctrl;
        struct pci_dev *bridge;
  
        if (pcie_ari_disabled || !pci_is_pcie(dev) || dev->devfn)
                return;
  
        bridge = dev->bus->self;
 -      if (!bridge || !pci_is_pcie(bridge))
 +      if (!bridge)
                return;
  
 -      pos = pci_pcie_cap(bridge);
 +      /* ARI is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(bridge);
        if (!pos)
                return;
  
 -      /* ARI is a PCIe v2 feature */
 -      pci_read_config_word(bridge, pos + PCI_EXP_FLAGS, &flags);
 -      if ((flags & PCI_EXP_FLAGS_VERS) < 2)
 -              return;
 -
        pci_read_config_dword(bridge, pos + PCI_EXP_DEVCAP2, &cap);
        if (!(cap & PCI_EXP_DEVCAP2_ARI))
                return;
  }
  
  /**
 - * pci_enable_ido - enable ID-based ordering on a device
 + * pci_enable_ido - enable ID-based Ordering on a device
   * @dev: the PCI device
   * @type: which types of IDO to enable
   *
@@@ -1989,8 -2031,7 +1989,8 @@@ void pci_enable_ido(struct pci_dev *dev
        int pos;
        u16 ctrl;
  
 -      pos = pci_pcie_cap(dev);
 +      /* ID-based Ordering is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
  
@@@ -2013,8 -2054,10 +2013,8 @@@ void pci_disable_ido(struct pci_dev *de
        int pos;
        u16 ctrl;
  
 -      if (!pci_is_pcie(dev))
 -              return;
 -
 -      pos = pci_pcie_cap(dev);
 +      /* ID-based Ordering is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
  
@@@ -2053,8 -2096,10 +2053,8 @@@ int pci_enable_obff(struct pci_dev *dev
        u16 ctrl;
        int ret;
  
 -      if (!pci_is_pcie(dev))
 -              return -ENOTSUPP;
 -
 -      pos = pci_pcie_cap(dev);
 +      /* OBFF is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return -ENOTSUPP;
  
                return -ENOTSUPP; /* no OBFF support at all */
  
        /* Make sure the topology supports OBFF as well */
-       if (dev->bus) {
+       if (dev->bus->self) {
                ret = pci_enable_obff(dev->bus->self, type);
                if (ret)
                        return ret;
@@@ -2104,8 -2149,10 +2104,8 @@@ void pci_disable_obff(struct pci_dev *d
        int pos;
        u16 ctrl;
  
 -      if (!pci_is_pcie(dev))
 -              return;
 -
 -      pos = pci_pcie_cap(dev);
 +      /* OBFF is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
  
@@@ -2122,13 -2169,15 +2122,13 @@@ EXPORT_SYMBOL(pci_disable_obff)
   * RETURNS:
   * True if @dev supports latency tolerance reporting, false otherwise.
   */
 -bool pci_ltr_supported(struct pci_dev *dev)
 +static bool pci_ltr_supported(struct pci_dev *dev)
  {
        int pos;
        u32 cap;
  
 -      if (!pci_is_pcie(dev))
 -              return false;
 -
 -      pos = pci_pcie_cap(dev);
 +      /* LTR is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return false;
  
  
        return cap & PCI_EXP_DEVCAP2_LTR;
  }
 -EXPORT_SYMBOL(pci_ltr_supported);
  
  /**
   * pci_enable_ltr - enable latency tolerance reporting
@@@ -2156,8 -2206,7 +2156,8 @@@ int pci_enable_ltr(struct pci_dev *dev
        if (!pci_ltr_supported(dev))
                return -ENOTSUPP;
  
 -      pos = pci_pcie_cap(dev);
 +      /* LTR is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return -ENOTSUPP;
  
                return -EINVAL;
  
        /* Enable upstream ports first */
-       if (dev->bus) {
+       if (dev->bus->self) {
                ret = pci_enable_ltr(dev->bus->self);
                if (ret)
                        return ret;
@@@ -2192,8 -2241,7 +2192,8 @@@ void pci_disable_ltr(struct pci_dev *de
        if (!pci_ltr_supported(dev))
                return;
  
 -      pos = pci_pcie_cap(dev);
 +      /* LTR is a PCIe cap v2 feature */
 +      pos = pci_pcie_cap2(dev);
        if (!pos)
                return;
  
@@@ -2311,75 -2359,6 +2311,75 @@@ void pci_enable_acs(struct pci_dev *dev
        pci_write_config_word(dev, pos + PCI_ACS_CTRL, ctrl);
  }
  
 +/**
 + * pci_acs_enabled - test ACS against required flags for a given device
 + * @pdev: device to test
 + * @acs_flags: required PCI ACS flags
 + *
 + * Return true if the device supports the provided flags.  Automatically
 + * filters out flags that are not implemented on multifunction devices.
 + */
 +bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags)
 +{
 +      int pos, ret;
 +      u16 ctrl;
 +
 +      ret = pci_dev_specific_acs_enabled(pdev, acs_flags);
 +      if (ret >= 0)
 +              return ret > 0;
 +
 +      if (!pci_is_pcie(pdev))
 +              return false;
 +
 +      /* Filter out flags not applicable to multifunction */
 +      if (pdev->multifunction)
 +              acs_flags &= (PCI_ACS_RR | PCI_ACS_CR |
 +                            PCI_ACS_EC | PCI_ACS_DT);
 +
 +      if (pdev->pcie_type == PCI_EXP_TYPE_DOWNSTREAM ||
 +          pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT ||
 +          pdev->multifunction) {
 +              pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_ACS);
 +              if (!pos)
 +                      return false;
 +
 +              pci_read_config_word(pdev, pos + PCI_ACS_CTRL, &ctrl);
 +              if ((ctrl & acs_flags) != acs_flags)
 +                      return false;
 +      }
 +
 +      return true;
 +}
 +
 +/**
 + * pci_acs_path_enable - test ACS flags from start to end in a hierarchy
 + * @start: starting downstream device
 + * @end: ending upstream device or NULL to search to the root bus
 + * @acs_flags: required flags
 + *
 + * Walk up a device tree from start to end testing PCI ACS support.  If
 + * any step along the way does not support the required flags, return false.
 + */
 +bool pci_acs_path_enabled(struct pci_dev *start,
 +                        struct pci_dev *end, u16 acs_flags)
 +{
 +      struct pci_dev *pdev, *parent = start;
 +
 +      do {
 +              pdev = parent;
 +
 +              if (!pci_acs_enabled(pdev, acs_flags))
 +                      return false;
 +
 +              if (pci_is_root_bus(pdev->bus))
 +                      return (end == NULL);
 +
 +              parent = pdev->bus->self;
 +      } while (pdev != end);
 +
 +      return true;
 +}
 +
  /**
   * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge
   * @dev: the PCI device
@@@ -2897,9 -2876,6 +2897,9 @@@ bool pci_intx_mask_supported(struct pci
        bool mask_supported = false;
        u16 orig, new;
  
 +      if (dev->broken_intx_masking)
 +              return false;
 +
        pci_cfg_access_lock(dev);
  
        pci_read_config_word(dev, PCI_COMMAND, &orig);
@@@ -3419,8 -3395,7 +3419,7 @@@ int pcix_set_mmrbc(struct pci_dev *dev
  
        o = (cmd & PCI_X_CMD_MAX_READ) >> 2;
        if (o != v) {
-               if (v > o && dev->bus &&
-                  (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
+               if (v > o && (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC))
                        return -EIO;
  
                cmd &= ~PCI_X_CMD_MAX_READ;
@@@ -3875,7 -3850,7 +3874,7 @@@ static void __devinit pci_no_domains(vo
   * greater than 0xff). This is the default implementation. Architecture
   * implementations can override this.
   */
- int __attribute__ ((weak)) pci_ext_cfg_avail(struct pci_dev *dev)
+ int __weak pci_ext_cfg_avail(struct pci_dev *dev)
  {
        return 1;
  }
diff --combined drivers/pci/probe.c
  #define CARDBUS_LATENCY_TIMER 176     /* secondary latency timer */
  #define CARDBUS_RESERVE_BUSNR 3
  
 +struct resource busn_resource = {
 +      .name   = "PCI busn",
 +      .start  = 0,
 +      .end    = 255,
 +      .flags  = IORESOURCE_BUS,
 +};
 +
  /* Ugh.  Need to stop exporting this to modules. */
  LIST_HEAD(pci_root_buses);
  EXPORT_SYMBOL(pci_root_buses);
  
 +static LIST_HEAD(pci_domain_busn_res_list);
 +
 +struct pci_domain_busn_res {
 +      struct list_head list;
 +      struct resource res;
 +      int domain_nr;
 +};
 +
 +static struct resource *get_pci_domain_busn_res(int domain_nr)
 +{
 +      struct pci_domain_busn_res *r;
 +
 +      list_for_each_entry(r, &pci_domain_busn_res_list, list)
 +              if (r->domain_nr == domain_nr)
 +                      return &r->res;
 +
 +      r = kzalloc(sizeof(*r), GFP_KERNEL);
 +      if (!r)
 +              return NULL;
 +
 +      r->domain_nr = domain_nr;
 +      r->res.start = 0;
 +      r->res.end = 0xff;
 +      r->res.flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED;
 +
 +      list_add_tail(&r->list, &pci_domain_busn_res_list);
 +
 +      return &r->res;
 +}
 +
  static int find_anything(struct device *dev, void *data)
  {
        return 1;
@@@ -318,10 -281,11 +318,11 @@@ static void __devinit pci_read_bridge_i
  
        if ((io_base_lo & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
                u16 io_base_hi, io_limit_hi;
                pci_read_config_word(dev, PCI_IO_BASE_UPPER16, &io_base_hi);
                pci_read_config_word(dev, PCI_IO_LIMIT_UPPER16, &io_limit_hi);
-               base |= (io_base_hi << 16);
-               limit |= (io_limit_hi << 16);
+               base |= ((unsigned long) io_base_hi << 16);
+               limit |= ((unsigned long) io_limit_hi << 16);
        }
  
        if (base && base <= limit) {
@@@ -349,8 -313,8 +350,8 @@@ static void __devinit pci_read_bridge_m
        res = child->resource[1];
        pci_read_config_word(dev, PCI_MEMORY_BASE, &mem_base_lo);
        pci_read_config_word(dev, PCI_MEMORY_LIMIT, &mem_limit_lo);
-       base = (mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
-       limit = (mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
+       base = ((unsigned long) mem_base_lo & PCI_MEMORY_RANGE_MASK) << 16;
+       limit = ((unsigned long) mem_limit_lo & PCI_MEMORY_RANGE_MASK) << 16;
        if (base && base <= limit) {
                res->flags = (mem_base_lo & PCI_MEMORY_RANGE_TYPE_MASK) | IORESOURCE_MEM;
                region.start = base;
@@@ -371,11 -335,12 +372,12 @@@ static void __devinit pci_read_bridge_m
        res = child->resource[2];
        pci_read_config_word(dev, PCI_PREF_MEMORY_BASE, &mem_base_lo);
        pci_read_config_word(dev, PCI_PREF_MEMORY_LIMIT, &mem_limit_lo);
-       base = (mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
-       limit = (mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
+       base = ((unsigned long) mem_base_lo & PCI_PREF_RANGE_MASK) << 16;
+       limit = ((unsigned long) mem_limit_lo & PCI_PREF_RANGE_MASK) << 16;
  
        if ((mem_base_lo & PCI_PREF_RANGE_TYPE_MASK) == PCI_PREF_RANGE_TYPE_64) {
                u32 mem_base_hi, mem_limit_hi;
                pci_read_config_dword(dev, PCI_PREF_BASE_UPPER32, &mem_base_hi);
                pci_read_config_dword(dev, PCI_PREF_LIMIT_UPPER32, &mem_limit_hi);
  
                 */
                if (mem_base_hi <= mem_limit_hi) {
  #if BITS_PER_LONG == 64
-                       base |= ((long) mem_base_hi) << 32;
-                       limit |= ((long) mem_limit_hi) << 32;
+                       base |= ((unsigned long) mem_base_hi) << 32;
+                       limit |= ((unsigned long) mem_limit_hi) << 32;
  #else
                        if (mem_base_hi || mem_limit_hi) {
                                dev_err(&dev->dev, "can't handle 64-bit "
@@@ -418,8 -383,8 +420,8 @@@ void __devinit pci_read_bridge_bases(st
        if (pci_is_root_bus(child))     /* It's a host bus, nothing to read */
                return;
  
 -      dev_info(&dev->dev, "PCI bridge to [bus %02x-%02x]%s\n",
 -               child->secondary, child->subordinate,
 +      dev_info(&dev->dev, "PCI bridge to %pR%s\n",
 +               &child->busn_res,
                 dev->transparent ? " (subtractive decode)" : "");
  
        pci_bus_remove_resources(child);
@@@ -636,9 -601,9 +638,9 @@@ static struct pci_bus *pci_alloc_child_
         * Set up the primary, secondary and subordinate
         * bus numbers.
         */
 -      child->number = child->secondary = busnr;
 -      child->primary = parent->secondary;
 -      child->subordinate = 0xff;
 +      child->number = child->busn_res.start = busnr;
 +      child->primary = parent->busn_res.start;
 +      child->busn_res.end = 0xff;
  
        if (!bridge)
                return child;
@@@ -680,8 -645,8 +682,8 @@@ static void pci_fixup_parent_subordinat
        if (!pcibios_assign_all_busses())
                return;
  
 -      while (parent->parent && parent->subordinate < max) {
 -              parent->subordinate = max;
 +      while (parent->parent && parent->busn_res.end < max) {
 +              parent->busn_res.end = max;
                pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);
                parent = parent->parent;
        }
@@@ -755,15 -720,15 +757,15 @@@ int __devinit pci_scan_bridge(struct pc
                        if (!child)
                                goto out;
                        child->primary = primary;
 -                      child->subordinate = subordinate;
 +                      pci_bus_insert_busn_res(child, secondary, subordinate);
                        child->bridge_ctl = bctl;
                }
  
                cmax = pci_scan_child_bus(child);
                if (cmax > max)
                        max = cmax;
 -              if (child->subordinate > max)
 -                      max = child->subordinate;
 +              if (child->busn_res.end > max)
 +                      max = child->busn_res.end;
        } else {
                /*
                 * We need to assign a number to this bus which we always
                        child = pci_add_new_bus(bus, dev, ++max);
                        if (!child)
                                goto out;
 +                      pci_bus_insert_busn_res(child, max, 0xff);
                }
                buses = (buses & 0xff000000)
                      | ((unsigned int)(child->primary)     <<  0)
 -                    | ((unsigned int)(child->secondary)   <<  8)
 -                    | ((unsigned int)(child->subordinate) << 16);
 +                    | ((unsigned int)(child->busn_res.start)   <<  8)
 +                    | ((unsigned int)(child->busn_res.end) << 16);
  
                /*
                 * yenta.c forces a secondary latency timer of 176.
                                        break;
                                while (parent->parent) {
                                        if ((!pcibios_assign_all_busses()) &&
 -                                          (parent->subordinate > max) &&
 -                                          (parent->subordinate <= max+i)) {
 +                                          (parent->busn_res.end > max) &&
 +                                          (parent->busn_res.end <= max+i)) {
                                                j = 1;
                                        }
                                        parent = parent->parent;
                /*
                 * Set the subordinate bus number to its real value.
                 */
 -              child->subordinate = max;
 +              pci_bus_update_busn_res_end(child, max);
                pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, max);
        }
  
  
        /* Has only triggered on CardBus, fixup is in yenta_socket */
        while (bus->parent) {
 -              if ((child->subordinate > bus->subordinate) ||
 -                  (child->number > bus->subordinate) ||
 +              if ((child->busn_res.end > bus->busn_res.end) ||
 +                  (child->number > bus->busn_res.end) ||
                    (child->number < bus->number) ||
 -                  (child->subordinate < bus->number)) {
 -                      dev_info(&child->dev, "[bus %02x-%02x] %s "
 -                              "hidden behind%s bridge %s [bus %02x-%02x]\n",
 -                              child->number, child->subordinate,
 -                              (bus->number > child->subordinate &&
 -                               bus->subordinate < child->number) ?
 +                  (child->busn_res.end < bus->number)) {
 +                      dev_info(&child->dev, "%pR %s "
 +                              "hidden behind%s bridge %s %pR\n",
 +                              &child->busn_res,
 +                              (bus->number > child->busn_res.end &&
 +                               bus->busn_res.end < child->number) ?
                                        "wholly" : "partially",
                                bus->self->transparent ? " transparent" : "",
                                dev_name(&bus->dev),
 -                              bus->number, bus->subordinate);
 +                              &bus->busn_res);
                }
                bus = bus->parent;
        }
@@@ -1586,7 -1550,7 +1588,7 @@@ EXPORT_SYMBOL_GPL(pcie_bus_configure_se
  
  unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus)
  {
 -      unsigned int devfn, pass, max = bus->secondary;
 +      unsigned int devfn, pass, max = bus->busn_res.start;
        struct pci_dev *dev;
  
        dev_dbg(&bus->dev, "scanning bus\n");
@@@ -1680,7 -1644,7 +1682,7 @@@ struct pci_bus *pci_create_root_bus(str
        /* Create legacy_io and legacy_mem files for this bus */
        pci_create_legacy_files(b);
  
 -      b->number = b->secondary = bus;
 +      b->number = b->busn_res.start = bus;
  
        if (parent)
                dev_info(parent, "PCI host bridge to bus %s\n", dev_name(&b->dev));
                list_move_tail(&window->list, &bridge->windows);
                res = window->res;
                offset = window->offset;
 -              pci_bus_add_resource(b, res, 0);
 +              if (res->flags & IORESOURCE_BUS)
 +                      pci_bus_insert_busn_res(b, bus, res->end);
 +              else
 +                      pci_bus_add_resource(b, res, 0);
                if (offset) {
                        if (resource_type(res) == IORESOURCE_IO)
                                fmt = " (bus address [%#06llx-%#06llx])";
@@@ -1725,104 -1686,16 +1727,104 @@@ err_out
        return NULL;
  }
  
 +int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max)
 +{
 +      struct resource *res = &b->busn_res;
 +      struct resource *parent_res, *conflict;
 +
 +      res->start = bus;
 +      res->end = bus_max;
 +      res->flags = IORESOURCE_BUS;
 +
 +      if (!pci_is_root_bus(b))
 +              parent_res = &b->parent->busn_res;
 +      else {
 +              parent_res = get_pci_domain_busn_res(pci_domain_nr(b));
 +              res->flags |= IORESOURCE_PCI_FIXED;
 +      }
 +
 +      conflict = insert_resource_conflict(parent_res, res);
 +
 +      if (conflict)
 +              dev_printk(KERN_DEBUG, &b->dev,
 +                         "busn_res: can not insert %pR under %s%pR (conflicts with %s %pR)\n",
 +                          res, pci_is_root_bus(b) ? "domain " : "",
 +                          parent_res, conflict->name, conflict);
 +      else
 +              dev_printk(KERN_DEBUG, &b->dev,
 +                         "busn_res: %pR is inserted under %s%pR\n",
 +                         res, pci_is_root_bus(b) ? "domain " : "",
 +                         parent_res);
 +
 +      return conflict == NULL;
 +}
 +
 +int pci_bus_update_busn_res_end(struct pci_bus *b, int bus_max)
 +{
 +      struct resource *res = &b->busn_res;
 +      struct resource old_res = *res;
 +      resource_size_t size;
 +      int ret;
 +
 +      if (res->start > bus_max)
 +              return -EINVAL;
 +
 +      size = bus_max - res->start + 1;
 +      ret = adjust_resource(res, res->start, size);
 +      dev_printk(KERN_DEBUG, &b->dev,
 +                      "busn_res: %pR end %s updated to %02x\n",
 +                      &old_res, ret ? "can not be" : "is", bus_max);
 +
 +      if (!ret && !res->parent)
 +              pci_bus_insert_busn_res(b, res->start, res->end);
 +
 +      return ret;
 +}
 +
 +void pci_bus_release_busn_res(struct pci_bus *b)
 +{
 +      struct resource *res = &b->busn_res;
 +      int ret;
 +
 +      if (!res->flags || !res->parent)
 +              return;
 +
 +      ret = release_resource(res);
 +      dev_printk(KERN_DEBUG, &b->dev,
 +                      "busn_res: %pR %s released\n",
 +                      res, ret ? "can not be" : "is");
 +}
 +
  struct pci_bus * __devinit pci_scan_root_bus(struct device *parent, int bus,
                struct pci_ops *ops, void *sysdata, struct list_head *resources)
  {
 +      struct pci_host_bridge_window *window;
 +      bool found = false;
        struct pci_bus *b;
 +      int max;
 +
 +      list_for_each_entry(window, resources, list)
 +              if (window->res->flags & IORESOURCE_BUS) {
 +                      found = true;
 +                      break;
 +              }
  
        b = pci_create_root_bus(parent, bus, ops, sysdata, resources);
        if (!b)
                return NULL;
  
 -      b->subordinate = pci_scan_child_bus(b);
 +      if (!found) {
 +              dev_info(&b->dev,
 +               "No busn resource found for root bus, will use [bus %02x-ff]\n",
 +                      bus);
 +              pci_bus_insert_busn_res(b, bus, 255);
 +      }
 +
 +      max = pci_scan_child_bus(b);
 +
 +      if (!found)
 +              pci_bus_update_busn_res_end(b, max);
 +
        pci_bus_add_devices(b);
        return b;
  }
@@@ -1837,10 -1710,9 +1839,10 @@@ struct pci_bus * __devinit pci_scan_bus
  
        pci_add_resource(&resources, &ioport_resource);
        pci_add_resource(&resources, &iomem_resource);
 +      pci_add_resource(&resources, &busn_resource);
        b = pci_create_root_bus(parent, bus, ops, sysdata, &resources);
        if (b)
 -              b->subordinate = pci_scan_child_bus(b);
 +              pci_scan_child_bus(b);
        else
                pci_free_resource_list(&resources);
        return b;
@@@ -1855,10 -1727,9 +1857,10 @@@ struct pci_bus * __devinit pci_scan_bus
  
        pci_add_resource(&resources, &ioport_resource);
        pci_add_resource(&resources, &iomem_resource);
 +      pci_add_resource(&resources, &busn_resource);
        b = pci_create_root_bus(NULL, bus, ops, sysdata, &resources);
        if (b) {
 -              b->subordinate = pci_scan_child_bus(b);
 +              pci_scan_child_bus(b);
                pci_bus_add_devices(b);
        } else {
                pci_free_resource_list(&resources);
diff --combined drivers/pci/setup-bus.c
@@@ -265,7 -265,7 +265,7 @@@ out
   * assign_requested_resources_sorted() - satisfy resource requests
   *
   * @head : head of the list tracking requests for resources
-  * @failed_list : head of the list tracking requests that could
+  * @fail_head : head of the list tracking requests that could
   *            not be allocated
   *
   * Satisfy resource requests of each element in the list. Add
@@@ -404,8 -404,8 +404,8 @@@ void pci_setup_cardbus(struct pci_bus *
        struct resource *res;
        struct pci_bus_region region;
  
 -      dev_info(&bridge->dev, "CardBus bridge to [bus %02x-%02x]\n",
 -               bus->secondary, bus->subordinate);
 +      dev_info(&bridge->dev, "CardBus bridge to %pR\n",
 +               &bus->busn_res);
  
        res = bus->resource[0];
        pcibios_resource_to_bus(bridge, &region, res);
@@@ -553,8 -553,8 +553,8 @@@ static void __pci_setup_bridge(struct p
  {
        struct pci_dev *bridge = bus->self;
  
 -      dev_info(&bridge->dev, "PCI bridge to [bus %02x-%02x]\n",
 -               bus->secondary, bus->subordinate);
 +      dev_info(&bridge->dev, "PCI bridge to %pR\n",
 +               &bus->busn_res);
  
        if (type & IORESOURCE_IO)
                pci_setup_bridge_io(bus);
@@@ -745,8 -745,8 +745,8 @@@ static void pbus_size_io(struct pci_bu
        if (!size0 && !size1) {
                if (b_res->start || b_res->end)
                        dev_info(&bus->self->dev, "disabling bridge window "
 -                               "%pR to [bus %02x-%02x] (unused)\n", b_res,
 -                               bus->secondary, bus->subordinate);
 +                               "%pR to %pR (unused)\n", b_res,
 +                               &bus->busn_res);
                b_res->flags = 0;
                return;
        }
        if (size1 > size0 && realloc_head) {
                add_to_list(realloc_head, bus->self, b_res, size1-size0, 4096);
                dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
 -                               "%pR to [bus %02x-%02x] add_size %lx\n", b_res,
 -                               bus->secondary, bus->subordinate, size1-size0);
 +                               "%pR to %pR add_size %lx\n", b_res,
 +                               &bus->busn_res, size1-size0);
        }
  }
  
@@@ -863,8 -863,8 +863,8 @@@ static int pbus_size_mem(struct pci_bu
        if (!size0 && !size1) {
                if (b_res->start || b_res->end)
                        dev_info(&bus->self->dev, "disabling bridge window "
 -                               "%pR to [bus %02x-%02x] (unused)\n", b_res,
 -                               bus->secondary, bus->subordinate);
 +                               "%pR to %pR (unused)\n", b_res,
 +                               &bus->busn_res);
                b_res->flags = 0;
                return 1;
        }
        if (size1 > size0 && realloc_head) {
                add_to_list(realloc_head, bus->self, b_res, size1-size0, min_align);
                dev_printk(KERN_DEBUG, &bus->self->dev, "bridge window "
 -                               "%pR to [bus %02x-%02x] add_size %llx\n", b_res,
 -                               bus->secondary, bus->subordinate, (unsigned long long)size1-size0);
 +                               "%pR to %pR add_size %llx\n", b_res,
 +                               &bus->busn_res, (unsigned long long)size1-size0);
        }
        return 1;
  }