if (addr0 & 0x02000000) {
flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY;
+ flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64;
flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M;
- if (addr0 & 0x01000000)
- flags |= IORESOURCE_MEM_64
- | PCI_BASE_ADDRESS_MEM_TYPE_64;
if (addr0 & 0x40000000)
flags |= IORESOURCE_PREFETCH
| PCI_BASE_ADDRESS_MEM_PREFETCH;
pbm->io_space.start);
pci_add_resource_offset(&resources, &pbm->mem_space,
pbm->mem_space.start);
- if (pbm->mem64_space.flags)
- pci_add_resource_offset(&resources, &pbm->mem64_space,
- pbm->mem_space.start);
pbm->busn.start = pbm->pci_first_busno;
pbm->busn.end = pbm->pci_last_busno;
pbm->busn.flags = IORESOURCE_BUS;
}
num_pbm_ranges = i / sizeof(*pbm_ranges);
- memset(&pbm->mem64_space, 0, sizeof(struct resource));
for (i = 0; i < num_pbm_ranges; i++) {
const struct linux_prom_pci_ranges *pr = &pbm_ranges[i];
break;
case 3:
- /* 64-bit MEM handling */
- pbm->mem64_space.start = a;
- pbm->mem64_space.end = a + size - 1UL;
- pbm->mem64_space.flags = IORESOURCE_MEM;
- break;
+ /* XXX 64-bit MEM handling XXX */
default:
break;
prom_halt();
}
- printk("%s: PCI IO[%llx] MEM[%llx]",
+ printk("%s: PCI IO[%llx] MEM[%llx]\n",
pbm->name,
pbm->io_space.start,
pbm->mem_space.start);
- if (pbm->mem64_space.flags)
- printk(" MEM64[%llx]",
- pbm->mem64_space.start);
- printk("\n");
pbm->io_space.name = pbm->mem_space.name = pbm->name;
request_resource(&ioport_resource, &pbm->io_space);
request_resource(&iomem_resource, &pbm->mem_space);
- if (pbm->mem64_space.flags)
- request_resource(&iomem_resource, &pbm->mem64_space);
pci_register_legacy_regions(&pbm->io_space,
&pbm->mem_space);
/* PBM I/O and Memory space resources. */
struct resource io_space;
struct resource mem_space;
- struct resource mem64_space;
struct resource busn;
/* Base of PCI Config space, can be per-PBM or shared. */
type_mask |= IORESOURCE_TYPE_BITS;
- pci_set_pref_under_pref(res);
-
pci_bus_for_each_resource(bus, r, i) {
if (!r)
continue;
/* Ok, try it out.. */
ret = allocate_resource(r, res, size, min, max,
align, alignf, alignf_data);
- if (ret == 0) {
- pci_clear_pref_under_pref(res);
+ if (ret == 0)
return 0;
- }
}
-
- pci_clear_pref_under_pref(res);
-
return -ENOMEM;
}
struct list_head *fail_head);
bool pci_bus_clip_resource(struct pci_dev *dev, int idx);
-static inline void pci_set_pref_under_pref(struct resource *res)
-{
- if (res->flags & IORESOURCE_UNDER_PREF)
- res->flags |= IORESOURCE_PREFETCH;
-}
-static inline void pci_clear_pref_under_pref(struct resource *res)
-{
- if (res->flags & IORESOURCE_UNDER_PREF)
- res->flags &= ~IORESOURCE_PREFETCH;
-}
-
/**
* pci_ari_enabled - query ARI forwarding status
* @bus: the PCI bus
pci_enable_acs(dev);
}
-static bool pci_up_path_over_pcie(struct pci_bus *bus)
-{
- if (!bus)
- return true;
-
- if (bus->self && !pci_is_pcie(bus->self))
- return false;
-
- return pci_up_path_over_pcie(bus->parent);
-}
-
-/*
- * According to
- * https://www.pcisig.com/specifications/pciexpress/base2/PCIe_Base_r2.1_Errata_08Jun10.pdf
- * page 13, system firmware could put some 64bit non-pref under 64bit pref,
- * on some cases.
- * Let's set pref bit for 64bit mmio when entire path from the host to
- * the adapter is over PCI Express.
- */
-static void set_pcie_64bit_under_pref(struct pci_dev *dev)
-{
- int i;
-
- if (!pci_is_pcie(dev))
- return;
-
- if (!pci_up_path_over_pcie(dev->bus))
- return;
-
- for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
- struct resource *res = &dev->resource[i];
- enum pci_bar_type type;
- int reg;
-
- if (!(res->flags & IORESOURCE_MEM_64))
- continue;
-
- if (res->flags & IORESOURCE_PREFETCH)
- continue;
-
- reg = pci_resource_bar(dev, i, &type);
- dev_printk(KERN_DEBUG, &dev->dev, "reg 0x%x %pR + under_pref\n",
- reg, res);
- res->flags |= IORESOURCE_UNDER_PREF;
- }
-}
-
void pci_device_add(struct pci_dev *dev, struct pci_bus *bus)
{
int ret;
/* Initialize various capabilities */
pci_init_capabilities(dev);
- /* After pcie_cap is assigned and sriov bar is probed */
- set_pcie_64bit_under_pref(dev);
-
/*
* Add the device to our list of discovered devices
* and the bus list for fixup functions, etc.
struct resource *r = &dev->resource[i];
resource_size_t r_size;
- pci_set_pref_under_pref(r);
if (r->parent || ((r->flags & mask) != type &&
(r->flags & mask) != type2 &&
- (r->flags & mask) != type3)) {
- pci_clear_pref_under_pref(r);
+ (r->flags & mask) != type3))
continue;
- }
r_size = resource_size(r);
#ifdef CONFIG_PCI_IOV
/* put SRIOV requested res to the optional list */
r->end = r->start - 1;
add_to_list(realloc_head, dev, r, r_size, 0/* don't care */);
children_add_size += r_size;
- pci_clear_pref_under_pref(r);
continue;
}
#endif
children_add_align = get_res_add_align(realloc_head, r);
add_align = max(add_align, children_add_align);
}
- pci_clear_pref_under_pref(r);
}
}
return -EINVAL;
}
- pci_set_pref_under_pref(res);
-
root = pci_find_parent_resource(dev, res);
if (!root) {
dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
resource, res);
res->flags |= IORESOURCE_UNSET;
- pci_clear_pref_under_pref(res);
return -EINVAL;
}
dev_info(&dev->dev, "can't claim BAR %d %pR: address conflict with %s %pR\n",
resource, res, conflict->name, conflict);
res->flags |= IORESOURCE_UNSET;
- pci_clear_pref_under_pref(res);
return -EBUSY;
}
- pci_clear_pref_under_pref(res);
-
return 0;
}
EXPORT_SYMBOL(pci_claim_resource);
static int _pci_assign_resource(struct pci_dev *dev, int resno,
resource_size_t size, resource_size_t min_align)
{
- struct resource *res = dev->resource + resno;
struct pci_bus *bus;
int ret;
- pci_set_pref_under_pref(res);
bus = dev->bus;
while ((ret = __pci_assign_resource(bus, dev, resno, size, min_align))) {
if (!bus->parent || !bus->self->transparent)
bus = bus->parent;
}
- pci_clear_pref_under_pref(res);
-
return ret;
}
#define IORESOURCE_WINDOW 0x00200000 /* forwarded by bridge */
#define IORESOURCE_MUXED 0x00400000 /* Resource is software muxed */
-#define IORESOURCE_UNDER_PREF 0x00800000 /* non-pref could under pref */
-
#define IORESOURCE_EXCLUSIVE 0x08000000 /* Userland may not map this resource */
#define IORESOURCE_DISABLED 0x10000000
#define IORESOURCE_UNSET 0x20000000 /* No address assigned yet */