Skip to content

Commit fead6a0

Browse files
committed
Merge branch 'pci/resource'
- Ensure relaxed tail alignment does not increase min_align when computing bridge window size, to fix a regression (Ilpo Järvinen) - Fix bridge window size computation to fix a regression for devices with undefined PCI class, e.g., Samsung [144d:a5a5] (Ilpo Järvinen) - Fix error handling during resource resize to fix a regression in amdgpu (Ilpo Järvinen) - Align m68k pcibios_enable_device() with other arches (Ilpo Järvinen) - Remove several sparc pcibios_enable_device() implementations that don't do anything beyond what pci_enable_resources() does (Ilpo Järvinen) - Remove mips pcibios_enable_resources() and use pci_enable_resources() instead (Ilpo Järvinen) - Refactor and simplify find_bus_resource_of_type() (Ilpo Järvinen) - Claim bridge windows before setting them up (Ilpo Järvinen) - Disable non-claimed bridge windows so the kernel's view matches the hardware configuration (Ilpo Järvinen) - Use pci_release_resource() instead of release_resource() to reduce code duplication and increase consistency (Ilpo Järvinen) - Enable bridges even if bridge window assignment fails (Ilpo Järvinen) - Preserve bridge window resource type flags when assignment fails because we may need it later (Ilpo Järvinen) - Add bridge window selection functions to make the selection consistent across the several places that do this (Ilpo Järvinen) - Warn if bridge window cannot be released when resizing BAR (Ilpo Järvinen) - Set up bridge resources before enumerating children so we can check whether child resources are inside bridge windows (Ilpo Järvinen) * pci/resource: PCI: Set up bridge resources earlier PCI: Don't print stale information about resource PCI: Alter misleading recursion to pci_bus_release_bridge_resources() PCI: Pass bridge window to pci_bus_release_bridge_resources() PCI: Add pci_setup_one_bridge_window() PCI: Refactor remove_dev_resources() to use pbus_select_window() PCI: Refactor distributing available memory to use loops PCI: Use pbus_select_window_for_type() during mem window sizing PCI: Use pbus_select_window() in space available checker PCI: Rename resource variable from r to res PCI: Use pbus_select_window_for_type() during IO window sizing PCI: Use pbus_select_window() during BAR resize PCI: Warn if bridge window cannot be released when resizing BAR PCI: Fix finding bridge window in pci_reassign_bridge_resources() PCI: Add bridge window selection functions PCI: Add defines for bridge window indexing PCI: Preserve bridge window resource type flags PCI: Enable bridge even if bridge window fails to assign PCI: Use pci_release_resource() instead of release_resource() PCI: Disable non-claimed bridge window PCI: Always claim bridge window before its setup PCI: Refactor find_bus_resource_of_type() logic checks PCI: Move find_bus_resource_of_type() earlier MIPS: PCI: Use pci_enable_resources() sparc/PCI: Remove pcibios_enable_device() as they do nothing extra m68k/PCI: Use pci_enable_resources() in pcibios_enable_device() PCI: Fix failure detection during resource resize PCI: Fix pdev_resources_assignable() disparity PCI: Ensure relaxed tail alignment does not increase min_align
2 parents b365c0a + a43ac32 commit fead6a0

12 files changed

Lines changed: 548 additions & 594 deletions

File tree

arch/m68k/kernel/pcibios.c

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -44,41 +44,24 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
4444
*/
4545
int pcibios_enable_device(struct pci_dev *dev, int mask)
4646
{
47-
struct resource *r;
4847
u16 cmd, newcmd;
49-
int idx;
48+
int ret;
5049

51-
pci_read_config_word(dev, PCI_COMMAND, &cmd);
52-
newcmd = cmd;
53-
54-
for (idx = 0; idx < 6; idx++) {
55-
/* Only set up the requested stuff */
56-
if (!(mask & (1 << idx)))
57-
continue;
58-
59-
r = dev->resource + idx;
60-
if (!r->start && r->end) {
61-
pr_err("PCI: Device %s not available because of resource collisions\n",
62-
pci_name(dev));
63-
return -EINVAL;
64-
}
65-
if (r->flags & IORESOURCE_IO)
66-
newcmd |= PCI_COMMAND_IO;
67-
if (r->flags & IORESOURCE_MEM)
68-
newcmd |= PCI_COMMAND_MEMORY;
69-
}
50+
ret = pci_enable_resources(dev, mask);
51+
if (ret < 0)
52+
return ret;
7053

7154
/*
7255
* Bridges (eg, cardbus bridges) need to be fully enabled
7356
*/
74-
if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE)
57+
if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
58+
pci_read_config_word(dev, PCI_COMMAND, &cmd);
7559
newcmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
76-
77-
78-
if (newcmd != cmd) {
79-
pr_info("PCI: enabling device %s (0x%04x -> 0x%04x)\n",
80-
pci_name(dev), cmd, newcmd);
81-
pci_write_config_word(dev, PCI_COMMAND, newcmd);
60+
if (newcmd != cmd) {
61+
pr_info("PCI: enabling bridge %s (0x%04x -> 0x%04x)\n",
62+
pci_name(dev), cmd, newcmd);
63+
pci_write_config_word(dev, PCI_COMMAND, newcmd);
64+
}
8265
}
8366
return 0;
8467
}

arch/mips/pci/pci-legacy.c

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -249,45 +249,11 @@ static int __init pcibios_init(void)
249249

250250
subsys_initcall(pcibios_init);
251251

252-
static int pcibios_enable_resources(struct pci_dev *dev, int mask)
253-
{
254-
u16 cmd, old_cmd;
255-
int idx;
256-
struct resource *r;
257-
258-
pci_read_config_word(dev, PCI_COMMAND, &cmd);
259-
old_cmd = cmd;
260-
pci_dev_for_each_resource(dev, r, idx) {
261-
/* Only set up the requested stuff */
262-
if (!(mask & (1<<idx)))
263-
continue;
264-
265-
if (!(r->flags & (IORESOURCE_IO | IORESOURCE_MEM)))
266-
continue;
267-
if ((idx == PCI_ROM_RESOURCE) &&
268-
(!(r->flags & IORESOURCE_ROM_ENABLE)))
269-
continue;
270-
if (!r->start && r->end) {
271-
pci_err(dev,
272-
"can't enable device: resource collisions\n");
273-
return -EINVAL;
274-
}
275-
if (r->flags & IORESOURCE_IO)
276-
cmd |= PCI_COMMAND_IO;
277-
if (r->flags & IORESOURCE_MEM)
278-
cmd |= PCI_COMMAND_MEMORY;
279-
}
280-
if (cmd != old_cmd) {
281-
pci_info(dev, "enabling device (%04x -> %04x)\n", old_cmd, cmd);
282-
pci_write_config_word(dev, PCI_COMMAND, cmd);
283-
}
284-
return 0;
285-
}
286-
287252
int pcibios_enable_device(struct pci_dev *dev, int mask)
288253
{
289-
int err = pcibios_enable_resources(dev, mask);
254+
int err;
290255

256+
err = pci_enable_resources(dev, mask);
291257
if (err < 0)
292258
return err;
293259

arch/sparc/kernel/leon_pci.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,30 +60,3 @@ void leon_pci_init(struct platform_device *ofdev, struct leon_pci_info *info)
6060
pci_assign_unassigned_resources();
6161
pci_bus_add_devices(root_bus);
6262
}
63-
64-
int pcibios_enable_device(struct pci_dev *dev, int mask)
65-
{
66-
struct resource *res;
67-
u16 cmd, oldcmd;
68-
int i;
69-
70-
pci_read_config_word(dev, PCI_COMMAND, &cmd);
71-
oldcmd = cmd;
72-
73-
pci_dev_for_each_resource(dev, res, i) {
74-
/* Only set up the requested stuff */
75-
if (!(mask & (1<<i)))
76-
continue;
77-
78-
if (res->flags & IORESOURCE_IO)
79-
cmd |= PCI_COMMAND_IO;
80-
if (res->flags & IORESOURCE_MEM)
81-
cmd |= PCI_COMMAND_MEMORY;
82-
}
83-
84-
if (cmd != oldcmd) {
85-
pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd);
86-
pci_write_config_word(dev, PCI_COMMAND, cmd);
87-
}
88-
return 0;
89-
}

arch/sparc/kernel/pci.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -722,33 +722,6 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,
722722
return bus;
723723
}
724724

725-
int pcibios_enable_device(struct pci_dev *dev, int mask)
726-
{
727-
struct resource *res;
728-
u16 cmd, oldcmd;
729-
int i;
730-
731-
pci_read_config_word(dev, PCI_COMMAND, &cmd);
732-
oldcmd = cmd;
733-
734-
pci_dev_for_each_resource(dev, res, i) {
735-
/* Only set up the requested stuff */
736-
if (!(mask & (1<<i)))
737-
continue;
738-
739-
if (res->flags & IORESOURCE_IO)
740-
cmd |= PCI_COMMAND_IO;
741-
if (res->flags & IORESOURCE_MEM)
742-
cmd |= PCI_COMMAND_MEMORY;
743-
}
744-
745-
if (cmd != oldcmd) {
746-
pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd);
747-
pci_write_config_word(dev, PCI_COMMAND, cmd);
748-
}
749-
return 0;
750-
}
751-
752725
/* Platform support for /proc/bus/pci/X/Y mmap()s. */
753726
int pci_iobar_pfn(struct pci_dev *pdev, int bar, struct vm_area_struct *vma)
754727
{

arch/sparc/kernel/pcic.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -641,33 +641,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
641641
}
642642
}
643643

644-
int pcibios_enable_device(struct pci_dev *dev, int mask)
645-
{
646-
struct resource *res;
647-
u16 cmd, oldcmd;
648-
int i;
649-
650-
pci_read_config_word(dev, PCI_COMMAND, &cmd);
651-
oldcmd = cmd;
652-
653-
pci_dev_for_each_resource(dev, res, i) {
654-
/* Only set up the requested stuff */
655-
if (!(mask & (1<<i)))
656-
continue;
657-
658-
if (res->flags & IORESOURCE_IO)
659-
cmd |= PCI_COMMAND_IO;
660-
if (res->flags & IORESOURCE_MEM)
661-
cmd |= PCI_COMMAND_MEMORY;
662-
}
663-
664-
if (cmd != oldcmd) {
665-
pci_info(dev, "enabling device (%04x -> %04x)\n", oldcmd, cmd);
666-
pci_write_config_word(dev, PCI_COMMAND, cmd);
667-
}
668-
return 0;
669-
}
670-
671644
/* Makes compiler happy */
672645
static volatile int pcic_timer_dummy;
673646

drivers/pci/bus.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ static int pci_bus_alloc_from_region(struct pci_bus *bus, struct resource *res,
204204
if (!r)
205205
continue;
206206

207+
if (r->flags & (IORESOURCE_UNSET|IORESOURCE_DISABLED))
208+
continue;
209+
207210
/* type_mask must match */
208211
if ((res->flags ^ r->flags) & type_mask)
209212
continue;

drivers/pci/pci-sysfs.c

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,13 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
177177

178178
for (i = 0; i < max; i++) {
179179
struct resource *res = &pci_dev->resource[i];
180+
struct resource zerores = {};
181+
182+
/* For backwards compatibility */
183+
if (i >= PCI_BRIDGE_RESOURCES && i <= PCI_BRIDGE_RESOURCE_END &&
184+
res->flags & (IORESOURCE_UNSET | IORESOURCE_DISABLED))
185+
res = &zerores;
186+
180187
pci_resource_to_user(pci_dev, i, res, &start, &end);
181188
len += sysfs_emit_at(buf, len, "0x%016llx 0x%016llx 0x%016llx\n",
182189
(unsigned long long)start,
@@ -1573,13 +1580,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
15731580
const char *buf, size_t count)
15741581
{
15751582
struct pci_dev *pdev = to_pci_dev(dev);
1576-
unsigned long size, flags;
1583+
struct pci_bus *bus = pdev->bus;
1584+
struct resource *b_win, *res;
1585+
unsigned long size;
15771586
int ret, i;
15781587
u16 cmd;
15791588

15801589
if (kstrtoul(buf, 0, &size) < 0)
15811590
return -EINVAL;
15821591

1592+
b_win = pbus_select_window(bus, pci_resource_n(pdev, n));
1593+
if (!b_win)
1594+
return -EINVAL;
1595+
15831596
device_lock(dev);
15841597
if (dev->driver || pci_num_vf(pdev)) {
15851598
ret = -EBUSY;
@@ -1599,19 +1612,19 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
15991612
pci_write_config_word(pdev, PCI_COMMAND,
16001613
cmd & ~PCI_COMMAND_MEMORY);
16011614

1602-
flags = pci_resource_flags(pdev, n);
1603-
16041615
pci_remove_resource_files(pdev);
16051616

1606-
for (i = 0; i < PCI_BRIDGE_RESOURCES; i++) {
1607-
if (pci_resource_len(pdev, i) &&
1608-
pci_resource_flags(pdev, i) == flags)
1617+
pci_dev_for_each_resource(pdev, res, i) {
1618+
if (i >= PCI_BRIDGE_RESOURCES)
1619+
break;
1620+
1621+
if (b_win == pbus_select_window(bus, res))
16091622
pci_release_resource(pdev, i);
16101623
}
16111624

16121625
ret = pci_resize_resource(pdev, n, size);
16131626

1614-
pci_assign_unassigned_bus_resources(pdev->bus);
1627+
pci_assign_unassigned_bus_resources(bus);
16151628

16161629
if (pci_create_resource_files(pdev))
16171630
pci_warn(pdev, "Failed to recreate resource files after BAR resizing\n");

drivers/pci/pci.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ struct pcie_tlp_log;
8282
#define PCIE_MSG_CODE_DEASSERT_INTC 0x26
8383
#define PCIE_MSG_CODE_DEASSERT_INTD 0x27
8484

85+
#define PCI_BUS_BRIDGE_IO_WINDOW 0
86+
#define PCI_BUS_BRIDGE_MEM_WINDOW 1
87+
#define PCI_BUS_BRIDGE_PREF_MEM_WINDOW 2
88+
8589
extern const unsigned char pcie_link_speed[];
8690
extern bool pci_early_dump;
8791

@@ -331,7 +335,7 @@ struct device *pci_get_host_bridge_device(struct pci_dev *dev);
331335
void pci_put_host_bridge_device(struct device *dev);
332336

333337
unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);
334-
int pci_reassign_bridge_resources(struct pci_dev *bridge, unsigned long type);
338+
int pbus_reassign_bridge_resources(struct pci_bus *bus, struct resource *res);
335339
int __must_check pci_reassign_resource(struct pci_dev *dev, int i, resource_size_t add_size, resource_size_t align);
336340

337341
int pci_configure_extended_tags(struct pci_dev *dev, void *ign);
@@ -382,6 +386,8 @@ static inline int pci_resource_num(const struct pci_dev *dev,
382386
return resno;
383387
}
384388

389+
struct resource *pbus_select_window(struct pci_bus *bus,
390+
const struct resource *res);
385391
void pci_reassigndev_resource_alignment(struct pci_dev *dev);
386392
void pci_disable_bridge_window(struct pci_dev *dev);
387393
struct pci_bus *pci_bus_get(struct pci_bus *bus);

0 commit comments

Comments
 (0)