diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/trace/trace_mmiotrace.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c index 3a12b1ad0c63..361472b5788c 100644 --- a/kernel/trace/trace_mmiotrace.c +++ b/kernel/trace/trace_mmiotrace.c | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | 8 | ||
| 9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
| 10 | #include <linux/mmiotrace.h> | 10 | #include <linux/mmiotrace.h> |
| 11 | #include <linux/pci.h> | ||
| 11 | 12 | ||
| 12 | #include "trace.h" | 13 | #include "trace.h" |
| 13 | 14 | ||
| @@ -53,12 +54,52 @@ static void mmio_trace_ctrl_update(struct trace_array *tr) | |||
| 53 | } | 54 | } |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 57 | static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev) | ||
| 58 | { | ||
| 59 | int ret = 0; | ||
| 60 | int i; | ||
| 61 | resource_size_t start, end; | ||
| 62 | const struct pci_driver *drv = pci_dev_driver(dev); | ||
| 63 | |||
| 64 | /* XXX: incomplete checks for trace_seq_printf() return value */ | ||
| 65 | ret += trace_seq_printf(s, "PCIDEV %02x%02x %04x%04x %x", | ||
| 66 | dev->bus->number, dev->devfn, | ||
| 67 | dev->vendor, dev->device, dev->irq); | ||
| 68 | /* | ||
| 69 | * XXX: is pci_resource_to_user() appropriate, since we are | ||
| 70 | * supposed to interpret the __ioremap() phys_addr argument based on | ||
| 71 | * these printed values? | ||
| 72 | */ | ||
| 73 | for (i = 0; i < 7; i++) { | ||
| 74 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | ||
| 75 | ret += trace_seq_printf(s, " %llx", | ||
| 76 | (unsigned long long)(start | | ||
| 77 | (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); | ||
| 78 | } | ||
| 79 | for (i = 0; i < 7; i++) { | ||
| 80 | pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); | ||
| 81 | ret += trace_seq_printf(s, " %llx", | ||
| 82 | dev->resource[i].start < dev->resource[i].end ? | ||
| 83 | (unsigned long long)(end - start) + 1 : 0); | ||
| 84 | } | ||
| 85 | if (drv) | ||
| 86 | ret += trace_seq_printf(s, " %s\n", drv->name); | ||
| 87 | else | ||
| 88 | ret += trace_seq_printf(s, " \n"); | ||
| 89 | return ret; | ||
| 90 | } | ||
| 91 | |||
| 56 | /* XXX: This is not called for trace_pipe file! */ | 92 | /* XXX: This is not called for trace_pipe file! */ |
| 57 | void mmio_print_header(struct trace_iterator *iter) | 93 | static void mmio_print_header(struct trace_iterator *iter) |
| 58 | { | 94 | { |
| 59 | struct trace_seq *s = &iter->seq; | 95 | struct trace_seq *s = &iter->seq; |
| 60 | trace_seq_printf(s, "VERSION broken 20070824\n"); | 96 | struct pci_dev *dev = NULL; |
| 61 | /* TODO: print /proc/bus/pci/devices contents as PCIDEV lines */ | 97 | |
| 98 | trace_seq_printf(s, "VERSION 20070824\n"); | ||
| 99 | |||
| 100 | for_each_pci_dev(dev) | ||
| 101 | mmio_print_pcidev(s, dev); | ||
| 102 | /* XXX: return value? What if header is very long? */ | ||
| 62 | } | 103 | } |
| 63 | 104 | ||
| 64 | static int mmio_print_rw(struct trace_iterator *iter) | 105 | static int mmio_print_rw(struct trace_iterator *iter) |
