summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPali Rohár <pali@kernel.org>2023-04-11 22:02:20 +0200
committerPali Rohár <pali@kernel.org>2023-04-18 00:39:41 +0200
commitf0aa3a466bc73d24d71dae7811cb673297fda752 (patch)
tree80e39256ca0d94118b9adad2336c7387acfc7db1
parent10add64069d23c3fdbff60d537cd8d7e4a5dfa53 (diff)
downloadpciutils-f0aa3a466bc73d24d71dae7811cb673297fda752.tar.gz
lspci: Fix bridge filter support in tree view
Correctly show whole subtree of PCI-to-PCI bridge in tree view when filter (-s or -d option) was specified for PCI-to-PCI bridge device itself.
-rw-r--r--ls-tree.c71
1 files changed, 43 insertions, 28 deletions
diff --git a/ls-tree.c b/ls-tree.c
index af1e659..72ac390 100644
--- a/ls-tree.c
+++ b/ls-tree.c
@@ -279,6 +279,18 @@ show_tree_dev(struct pci_filter *filter, struct device *d, char *line, char *p)
print_it(line, p);
}
+static struct pci_filter *
+get_filter_for_child(struct pci_filter *filter, struct device *d)
+{
+ if (!filter)
+ return NULL;
+
+ if (pci_filter_match(filter, d->dev))
+ return NULL;
+
+ return filter;
+}
+
static int
check_bus_filter(struct pci_filter *filter, struct bus *b);
@@ -331,32 +343,34 @@ show_tree_bus(struct pci_filter *filter, struct bus *b, char *line, char *p)
if (check_dev_filter(filter, b->first_dev))
{
p = tree_printf(line, p, "--");
- show_tree_dev(filter, b->first_dev, line, p);
+ show_tree_dev(get_filter_for_child(filter, b->first_dev), b->first_dev, line, p);
}
else
print_it(line, p);
}
else
{
- int empty = 1;
+ int i, count = 0;
struct device *d = b->first_dev;
- while (d->bus_next)
- {
- if (check_dev_filter(filter, d))
- {
- char *p2 = tree_printf(line, p, "+-");
- show_tree_dev(filter, d, line, p2);
- empty = 0;
- }
- d = d->bus_next;
- }
- if (check_dev_filter(filter, d))
+
+ do
+ {
+ if (check_dev_filter(filter, d))
+ count++;
+ d = d->bus_next;
+ }
+ while (d);
+
+ for (i = 0, d = b->first_dev; d; d = d->bus_next)
{
- p = tree_printf(line, p, "\\-");
- show_tree_dev(filter, d, line, p);
- empty = 0;
+ if (!check_dev_filter(filter, d))
+ continue;
+ char *p2 = tree_printf(line, p, count == 1 ? "--" : count == i+1 ? "\\-" : "+-");
+ show_tree_dev(get_filter_for_child(filter, d), d, line, p2);
+ i++;
}
- if (empty)
+
+ if (count == 0)
print_it(line, p);
}
}
@@ -378,27 +392,28 @@ show_tree_bridge(struct pci_filter *filter, struct bridge *b, char *line, char *
}
else
{
- int empty = 1;
+ int i, count = 0;
struct bus *u = b->first_bus;
char *k;
- while (u->sibling)
+ do
{
if (check_bus_filter(filter, u))
- {
- k = tree_printf(line, p, "+-[%04x:%02x]-", u->domain, u->number);
- show_tree_bus(filter, u, line, k);
- empty = 0;
- }
+ count++;
u = u->sibling;
}
- if (check_bus_filter(filter, u))
+ while (u);
+
+ for (i = 0, u = b->first_bus; u; u = u->sibling)
{
- k = tree_printf(line, p, "\\-[%04x:%02x]-", u->domain, u->number);
+ if (!check_bus_filter(filter, u))
+ continue;
+ k = tree_printf(line, p, count == 1 ? "[%04x:%02x]-" : count == i+1 ? "\\-[%04x:%02x]-" : "+-[%04x:%02x]-", u->domain, u->number);
show_tree_bus(filter, u, line, k);
- empty = 0;
+ i++;
}
- if (empty)
+
+ if (count == 0)
print_it(line, p);
}
}