aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/trace/trace_mmiotrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_mmiotrace.c')
-rw-r--r--kernel/trace/trace_mmiotrace.c60
1 files changed, 53 insertions, 7 deletions
diff --git a/kernel/trace/trace_mmiotrace.c b/kernel/trace/trace_mmiotrace.c
index 79be4a18ec1e..6d2edbdde939 100644
--- a/kernel/trace/trace_mmiotrace.c
+++ b/kernel/trace/trace_mmiotrace.c
@@ -12,6 +12,10 @@
12 12
13#include "trace.h" 13#include "trace.h"
14 14
15struct header_iter {
16 struct pci_dev *dev;
17};
18
15static struct trace_array *mmio_trace_array; 19static struct trace_array *mmio_trace_array;
16 20
17static void mmio_reset_data(struct trace_array *tr) 21static void mmio_reset_data(struct trace_array *tr)
@@ -89,17 +93,57 @@ static int mmio_print_pcidev(struct trace_seq *s, const struct pci_dev *dev)
89 return ret; 93 return ret;
90} 94}
91 95
92/* XXX: This is not called for trace_pipe file! */ 96static void destroy_header_iter(struct header_iter *hiter)
93static void mmio_print_header(struct trace_iterator *iter) 97{
98 if (!hiter)
99 return;
100 pci_dev_put(hiter->dev);
101 kfree(hiter);
102}
103
104static void mmio_pipe_open(struct trace_iterator *iter)
94{ 105{
106 struct header_iter *hiter;
95 struct trace_seq *s = &iter->seq; 107 struct trace_seq *s = &iter->seq;
96 struct pci_dev *dev = NULL;
97 108
98 trace_seq_printf(s, "VERSION 20070824\n"); 109 trace_seq_printf(s, "VERSION 20070824\n");
99 110
100 for_each_pci_dev(dev) 111 hiter = kzalloc(sizeof(*hiter), GFP_KERNEL);
101 mmio_print_pcidev(s, dev); 112 if (!hiter)
102 /* XXX: return value? What if header is very long? */ 113 return;
114
115 hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, NULL);
116 iter->private = hiter;
117}
118
119/* XXX: This is not called when the pipe is closed! */
120static void mmio_close(struct trace_iterator *iter)
121{
122 struct header_iter *hiter = iter->private;
123 destroy_header_iter(hiter);
124 iter->private = NULL;
125}
126
127static ssize_t mmio_read(struct trace_iterator *iter, struct file *filp,
128 char __user *ubuf, size_t cnt, loff_t *ppos)
129{
130 ssize_t ret;
131 struct header_iter *hiter = iter->private;
132 struct trace_seq *s = &iter->seq;
133
134 if (!hiter)
135 return 0;
136
137 mmio_print_pcidev(s, hiter->dev);
138 hiter->dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, hiter->dev);
139
140 if (!hiter->dev) {
141 destroy_header_iter(hiter);
142 iter->private = NULL;
143 }
144
145 ret = trace_seq_to_user(s, ubuf, cnt);
146 return (ret == -EBUSY) ? 0 : ret;
103} 147}
104 148
105static int mmio_print_rw(struct trace_iterator *iter) 149static int mmio_print_rw(struct trace_iterator *iter)
@@ -190,7 +234,9 @@ static struct tracer mmio_tracer __read_mostly =
190 .name = "mmiotrace", 234 .name = "mmiotrace",
191 .init = mmio_trace_init, 235 .init = mmio_trace_init,
192 .reset = mmio_trace_reset, 236 .reset = mmio_trace_reset,
193 .open = mmio_print_header, 237 .pipe_open = mmio_pipe_open,
238 .close = mmio_close,
239 .read = mmio_read,
194 .ctrl_update = mmio_trace_ctrl_update, 240 .ctrl_update = mmio_trace_ctrl_update,
195 .print_line = mmio_print_line, 241 .print_line = mmio_print_line,
196}; 242};