diff options
author | Pete Zaitcev <zaitcev@redhat.com> | 2007-04-11 16:47:26 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2007-04-27 16:28:39 -0400 |
commit | ecb658d387dc09f344b3d755e8674076072032c7 (patch) | |
tree | b24067478554d5514db22ca6b107b8258e22b7e3 /drivers/usb | |
parent | 35d07fd58f47284adecf219d3b73e4ea197cf29f (diff) |
usbmon: bus zero
Add the "bus zero" feature to the usbmon. If a user process specifies bus
with number zero, it receives events from all buses. This is useful when
we wish to see initial enumeration when a bus is created, typically after
a modprobe. Until now, an application had to loop until a new bus could
be open, then start capturing on it. This procedure was cumbersome and
could lose initial events. Also, often it's too bothersome to find exactly
to which bus a specific device is attached.
Paolo Albeni provided the original concept implementation. I added the
handling of "bus->monitored" flag and generally fixed it up.
Signed-off-by: Pete Zaitcev <zaitcev@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/mon/mon_bin.c | 14 | ||||
-rw-r--r-- | drivers/usb/mon/mon_main.c | 158 | ||||
-rw-r--r-- | drivers/usb/mon/mon_text.c | 23 | ||||
-rw-r--r-- | drivers/usb/mon/usb_mon.h | 5 |
4 files changed, 116 insertions, 84 deletions
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index b2bedd974ac3..0af11a66207c 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -356,8 +356,10 @@ static inline char mon_bin_get_setup(unsigned char *setupb, | |||
356 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | 356 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') |
357 | return '-'; | 357 | return '-'; |
358 | 358 | ||
359 | if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) | 359 | if (urb->dev->bus->uses_dma && |
360 | (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
360 | return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); | 361 | return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); |
362 | } | ||
361 | if (urb->setup_packet == NULL) | 363 | if (urb->setup_packet == NULL) |
362 | return 'Z'; | 364 | return 'Z'; |
363 | 365 | ||
@@ -369,7 +371,8 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp, | |||
369 | unsigned int offset, struct urb *urb, unsigned int length) | 371 | unsigned int offset, struct urb *urb, unsigned int length) |
370 | { | 372 | { |
371 | 373 | ||
372 | if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) { | 374 | if (urb->dev->bus->uses_dma && |
375 | (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { | ||
373 | mon_dmapeek_vec(rp, offset, urb->transfer_dma, length); | 376 | mon_dmapeek_vec(rp, offset, urb->transfer_dma, length); |
374 | return 0; | 377 | return 0; |
375 | } | 378 | } |
@@ -440,7 +443,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
440 | /* We use the fact that usb_pipein() returns 0x80 */ | 443 | /* We use the fact that usb_pipein() returns 0x80 */ |
441 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | 444 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); |
442 | ep->devnum = usb_pipedevice(urb->pipe); | 445 | ep->devnum = usb_pipedevice(urb->pipe); |
443 | ep->busnum = rp->r.m_bus->u_bus->busnum; | 446 | ep->busnum = urb->dev->bus->busnum; |
444 | ep->id = (unsigned long) urb; | 447 | ep->id = (unsigned long) urb; |
445 | ep->ts_sec = ts.tv_sec; | 448 | ep->ts_sec = ts.tv_sec; |
446 | ep->ts_usec = ts.tv_usec; | 449 | ep->ts_usec = ts.tv_usec; |
@@ -500,7 +503,7 @@ static void mon_bin_error(void *data, struct urb *urb, int error) | |||
500 | /* We use the fact that usb_pipein() returns 0x80 */ | 503 | /* We use the fact that usb_pipein() returns 0x80 */ |
501 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | 504 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); |
502 | ep->devnum = usb_pipedevice(urb->pipe); | 505 | ep->devnum = usb_pipedevice(urb->pipe); |
503 | ep->busnum = rp->r.m_bus->u_bus->busnum; | 506 | ep->busnum = urb->dev->bus->busnum; |
504 | ep->id = (unsigned long) urb; | 507 | ep->id = (unsigned long) urb; |
505 | ep->status = error; | 508 | ep->status = error; |
506 | 509 | ||
@@ -515,7 +518,6 @@ static void mon_bin_error(void *data, struct urb *urb, int error) | |||
515 | static int mon_bin_open(struct inode *inode, struct file *file) | 518 | static int mon_bin_open(struct inode *inode, struct file *file) |
516 | { | 519 | { |
517 | struct mon_bus *mbus; | 520 | struct mon_bus *mbus; |
518 | struct usb_bus *ubus; | ||
519 | struct mon_reader_bin *rp; | 521 | struct mon_reader_bin *rp; |
520 | size_t size; | 522 | size_t size; |
521 | int rc; | 523 | int rc; |
@@ -525,7 +527,7 @@ static int mon_bin_open(struct inode *inode, struct file *file) | |||
525 | mutex_unlock(&mon_lock); | 527 | mutex_unlock(&mon_lock); |
526 | return -ENODEV; | 528 | return -ENODEV; |
527 | } | 529 | } |
528 | if ((ubus = mbus->u_bus) == NULL) { | 530 | if (mbus != &mon_bus0 && mbus->u_bus == NULL) { |
529 | printk(KERN_ERR TAG ": consistency error on open\n"); | 531 | printk(KERN_ERR TAG ": consistency error on open\n"); |
530 | mutex_unlock(&mon_lock); | 532 | mutex_unlock(&mon_lock); |
531 | return -ENODEV; | 533 | return -ENODEV; |
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index c9739e7b35e5..8a1df2c9c73e 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -16,8 +16,6 @@ | |||
16 | #include "usb_mon.h" | 16 | #include "usb_mon.h" |
17 | #include "../core/hcd.h" | 17 | #include "../core/hcd.h" |
18 | 18 | ||
19 | static void mon_submit(struct usb_bus *ubus, struct urb *urb); | ||
20 | static void mon_complete(struct usb_bus *ubus, struct urb *urb); | ||
21 | static void mon_stop(struct mon_bus *mbus); | 19 | static void mon_stop(struct mon_bus *mbus); |
22 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); | 20 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); |
23 | static void mon_bus_drop(struct kref *r); | 21 | static void mon_bus_drop(struct kref *r); |
@@ -25,6 +23,7 @@ static void mon_bus_init(struct usb_bus *ubus); | |||
25 | 23 | ||
26 | DEFINE_MUTEX(mon_lock); | 24 | DEFINE_MUTEX(mon_lock); |
27 | 25 | ||
26 | struct mon_bus mon_bus0; /* Pseudo bus meaning "all buses" */ | ||
28 | static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ | 27 | static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ |
29 | 28 | ||
30 | /* | 29 | /* |
@@ -35,22 +34,19 @@ static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ | |||
35 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r) | 34 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r) |
36 | { | 35 | { |
37 | unsigned long flags; | 36 | unsigned long flags; |
38 | struct usb_bus *ubus; | 37 | struct list_head *p; |
39 | 38 | ||
40 | spin_lock_irqsave(&mbus->lock, flags); | 39 | spin_lock_irqsave(&mbus->lock, flags); |
41 | if (mbus->nreaders == 0) { | 40 | if (mbus->nreaders == 0) { |
42 | ubus = mbus->u_bus; | 41 | if (mbus == &mon_bus0) { |
43 | if (ubus->monitored) { | 42 | list_for_each (p, &mon_buses) { |
44 | /* | 43 | struct mon_bus *m1; |
45 | * Something is really broken, refuse to go on and | 44 | m1 = list_entry(p, struct mon_bus, bus_link); |
46 | * possibly corrupt ops pointers or worse. | 45 | m1->u_bus->monitored = 1; |
47 | */ | 46 | } |
48 | printk(KERN_ERR TAG ": bus %d is already monitored\n", | 47 | } else { |
49 | ubus->busnum); | 48 | mbus->u_bus->monitored = 1; |
50 | spin_unlock_irqrestore(&mbus->lock, flags); | ||
51 | return; | ||
52 | } | 49 | } |
53 | ubus->monitored = 1; | ||
54 | } | 50 | } |
55 | mbus->nreaders++; | 51 | mbus->nreaders++; |
56 | list_add_tail(&r->r_link, &mbus->r_list); | 52 | list_add_tail(&r->r_link, &mbus->r_list); |
@@ -80,77 +76,79 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r) | |||
80 | 76 | ||
81 | /* | 77 | /* |
82 | */ | 78 | */ |
83 | static void mon_submit(struct usb_bus *ubus, struct urb *urb) | 79 | static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb) |
84 | { | 80 | { |
85 | struct mon_bus *mbus; | ||
86 | unsigned long flags; | 81 | unsigned long flags; |
87 | struct list_head *pos; | 82 | struct list_head *pos; |
88 | struct mon_reader *r; | 83 | struct mon_reader *r; |
89 | 84 | ||
90 | mbus = ubus->mon_bus; | ||
91 | if (mbus == NULL) | ||
92 | goto out_unlocked; | ||
93 | |||
94 | spin_lock_irqsave(&mbus->lock, flags); | 85 | spin_lock_irqsave(&mbus->lock, flags); |
95 | if (mbus->nreaders == 0) | ||
96 | goto out_locked; | ||
97 | |||
98 | mbus->cnt_events++; | 86 | mbus->cnt_events++; |
99 | list_for_each (pos, &mbus->r_list) { | 87 | list_for_each (pos, &mbus->r_list) { |
100 | r = list_entry(pos, struct mon_reader, r_link); | 88 | r = list_entry(pos, struct mon_reader, r_link); |
101 | r->rnf_submit(r->r_data, urb); | 89 | r->rnf_submit(r->r_data, urb); |
102 | } | 90 | } |
103 | |||
104 | spin_unlock_irqrestore(&mbus->lock, flags); | 91 | spin_unlock_irqrestore(&mbus->lock, flags); |
105 | return; | 92 | return; |
93 | } | ||
106 | 94 | ||
107 | out_locked: | 95 | static void mon_submit(struct usb_bus *ubus, struct urb *urb) |
108 | spin_unlock_irqrestore(&mbus->lock, flags); | 96 | { |
109 | out_unlocked: | 97 | struct mon_bus *mbus; |
110 | return; | 98 | |
99 | if ((mbus = ubus->mon_bus) != NULL) | ||
100 | mon_bus_submit(mbus, urb); | ||
101 | mon_bus_submit(&mon_bus0, urb); | ||
111 | } | 102 | } |
112 | 103 | ||
113 | /* | 104 | /* |
114 | */ | 105 | */ |
115 | static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) | 106 | static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error) |
116 | { | 107 | { |
117 | struct mon_bus *mbus; | ||
118 | unsigned long flags; | 108 | unsigned long flags; |
119 | struct list_head *pos; | 109 | struct list_head *pos; |
120 | struct mon_reader *r; | 110 | struct mon_reader *r; |
121 | 111 | ||
122 | mbus = ubus->mon_bus; | ||
123 | if (mbus == NULL) | ||
124 | goto out_unlocked; | ||
125 | |||
126 | spin_lock_irqsave(&mbus->lock, flags); | 112 | spin_lock_irqsave(&mbus->lock, flags); |
127 | if (mbus->nreaders == 0) | ||
128 | goto out_locked; | ||
129 | |||
130 | mbus->cnt_events++; | 113 | mbus->cnt_events++; |
131 | list_for_each (pos, &mbus->r_list) { | 114 | list_for_each (pos, &mbus->r_list) { |
132 | r = list_entry(pos, struct mon_reader, r_link); | 115 | r = list_entry(pos, struct mon_reader, r_link); |
133 | r->rnf_error(r->r_data, urb, error); | 116 | r->rnf_error(r->r_data, urb, error); |
134 | } | 117 | } |
135 | |||
136 | spin_unlock_irqrestore(&mbus->lock, flags); | 118 | spin_unlock_irqrestore(&mbus->lock, flags); |
137 | return; | 119 | return; |
120 | } | ||
138 | 121 | ||
139 | out_locked: | 122 | static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) |
140 | spin_unlock_irqrestore(&mbus->lock, flags); | 123 | { |
141 | out_unlocked: | 124 | struct mon_bus *mbus; |
142 | return; | 125 | |
126 | if ((mbus = ubus->mon_bus) != NULL) | ||
127 | mon_bus_submit_error(mbus, urb, error); | ||
128 | mon_bus_submit_error(&mon_bus0, urb, error); | ||
143 | } | 129 | } |
144 | 130 | ||
145 | /* | 131 | /* |
146 | */ | 132 | */ |
147 | static void mon_complete(struct usb_bus *ubus, struct urb *urb) | 133 | static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) |
148 | { | 134 | { |
149 | struct mon_bus *mbus; | ||
150 | unsigned long flags; | 135 | unsigned long flags; |
151 | struct list_head *pos; | 136 | struct list_head *pos; |
152 | struct mon_reader *r; | 137 | struct mon_reader *r; |
153 | 138 | ||
139 | spin_lock_irqsave(&mbus->lock, flags); | ||
140 | mbus->cnt_events++; | ||
141 | list_for_each (pos, &mbus->r_list) { | ||
142 | r = list_entry(pos, struct mon_reader, r_link); | ||
143 | r->rnf_complete(r->r_data, urb); | ||
144 | } | ||
145 | spin_unlock_irqrestore(&mbus->lock, flags); | ||
146 | } | ||
147 | |||
148 | static void mon_complete(struct usb_bus *ubus, struct urb *urb) | ||
149 | { | ||
150 | struct mon_bus *mbus; | ||
151 | |||
154 | mbus = ubus->mon_bus; | 152 | mbus = ubus->mon_bus; |
155 | if (mbus == NULL) { | 153 | if (mbus == NULL) { |
156 | /* | 154 | /* |
@@ -162,13 +160,8 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) | |||
162 | return; | 160 | return; |
163 | } | 161 | } |
164 | 162 | ||
165 | spin_lock_irqsave(&mbus->lock, flags); | 163 | mon_bus_complete(mbus, urb); |
166 | mbus->cnt_events++; | 164 | mon_bus_complete(&mon_bus0, urb); |
167 | list_for_each (pos, &mbus->r_list) { | ||
168 | r = list_entry(pos, struct mon_reader, r_link); | ||
169 | r->rnf_complete(r->r_data, urb); | ||
170 | } | ||
171 | spin_unlock_irqrestore(&mbus->lock, flags); | ||
172 | } | 165 | } |
173 | 166 | ||
174 | /* int (*unlink_urb) (struct urb *urb, int status); */ | 167 | /* int (*unlink_urb) (struct urb *urb, int status); */ |
@@ -179,14 +172,26 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) | |||
179 | static void mon_stop(struct mon_bus *mbus) | 172 | static void mon_stop(struct mon_bus *mbus) |
180 | { | 173 | { |
181 | struct usb_bus *ubus = mbus->u_bus; | 174 | struct usb_bus *ubus = mbus->u_bus; |
175 | struct list_head *p; | ||
182 | 176 | ||
183 | /* | 177 | if (mbus == &mon_bus0) { |
184 | * A stop can be called for a dissolved mon_bus in case of | 178 | list_for_each (p, &mon_buses) { |
185 | * a reader staying across an rmmod foo_hcd. | 179 | mbus = list_entry(p, struct mon_bus, bus_link); |
186 | */ | 180 | /* |
187 | if (ubus != NULL) { | 181 | * We do not change nreaders here, so rely on mon_lock. |
188 | ubus->monitored = 0; | 182 | */ |
189 | mb(); | 183 | if (mbus->nreaders == 0 && (ubus = mbus->u_bus) != NULL) |
184 | ubus->monitored = 0; | ||
185 | } | ||
186 | } else { | ||
187 | /* | ||
188 | * A stop can be called for a dissolved mon_bus in case of | ||
189 | * a reader staying across an rmmod foo_hcd, so test ->u_bus. | ||
190 | */ | ||
191 | if (mon_bus0.nreaders == 0 && (ubus = mbus->u_bus) != NULL) { | ||
192 | ubus->monitored = 0; | ||
193 | mb(); | ||
194 | } | ||
190 | } | 195 | } |
191 | } | 196 | } |
192 | 197 | ||
@@ -199,6 +204,10 @@ static void mon_stop(struct mon_bus *mbus) | |||
199 | static void mon_bus_add(struct usb_bus *ubus) | 204 | static void mon_bus_add(struct usb_bus *ubus) |
200 | { | 205 | { |
201 | mon_bus_init(ubus); | 206 | mon_bus_init(ubus); |
207 | mutex_lock(&mon_lock); | ||
208 | if (mon_bus0.nreaders != 0) | ||
209 | ubus->monitored = 1; | ||
210 | mutex_unlock(&mon_lock); | ||
202 | } | 211 | } |
203 | 212 | ||
204 | /* | 213 | /* |
@@ -250,12 +259,7 @@ static struct usb_mon_operations mon_ops_0 = { | |||
250 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus) | 259 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus) |
251 | { | 260 | { |
252 | 261 | ||
253 | /* | ||
254 | * Never happens, but... | ||
255 | */ | ||
256 | if (ubus->monitored) { | 262 | if (ubus->monitored) { |
257 | printk(KERN_ERR TAG ": bus %d is dissolved while monitored\n", | ||
258 | ubus->busnum); | ||
259 | ubus->monitored = 0; | 263 | ubus->monitored = 0; |
260 | mb(); | 264 | mb(); |
261 | } | 265 | } |
@@ -263,6 +267,8 @@ static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus) | |||
263 | ubus->mon_bus = NULL; | 267 | ubus->mon_bus = NULL; |
264 | mbus->u_bus = NULL; | 268 | mbus->u_bus = NULL; |
265 | mb(); | 269 | mb(); |
270 | |||
271 | /* We want synchronize_irq() here, but that needs an argument. */ | ||
266 | } | 272 | } |
267 | 273 | ||
268 | /* | 274 | /* |
@@ -295,9 +301,8 @@ static void mon_bus_init(struct usb_bus *ubus) | |||
295 | */ | 301 | */ |
296 | mbus->u_bus = ubus; | 302 | mbus->u_bus = ubus; |
297 | ubus->mon_bus = mbus; | 303 | ubus->mon_bus = mbus; |
298 | mbus->uses_dma = ubus->uses_dma; | ||
299 | 304 | ||
300 | mbus->text_inited = mon_text_add(mbus, ubus); | 305 | mbus->text_inited = mon_text_add(mbus, ubus->busnum); |
301 | // mon_bin_add(...) | 306 | // mon_bin_add(...) |
302 | 307 | ||
303 | mutex_lock(&mon_lock); | 308 | mutex_lock(&mon_lock); |
@@ -309,6 +314,18 @@ err_alloc: | |||
309 | return; | 314 | return; |
310 | } | 315 | } |
311 | 316 | ||
317 | static void mon_bus0_init(void) | ||
318 | { | ||
319 | struct mon_bus *mbus = &mon_bus0; | ||
320 | |||
321 | kref_init(&mbus->ref); | ||
322 | spin_lock_init(&mbus->lock); | ||
323 | INIT_LIST_HEAD(&mbus->r_list); | ||
324 | |||
325 | mbus->text_inited = mon_text_add(mbus, 0); | ||
326 | // mbus->bin_inited = mon_bin_add(mbus, 0); | ||
327 | } | ||
328 | |||
312 | /* | 329 | /* |
313 | * Search a USB bus by number. Notice that USB bus numbers start from one, | 330 | * Search a USB bus by number. Notice that USB bus numbers start from one, |
314 | * which we may later use to identify "all" with zero. | 331 | * which we may later use to identify "all" with zero. |
@@ -322,6 +339,9 @@ struct mon_bus *mon_bus_lookup(unsigned int num) | |||
322 | struct list_head *p; | 339 | struct list_head *p; |
323 | struct mon_bus *mbus; | 340 | struct mon_bus *mbus; |
324 | 341 | ||
342 | if (num == 0) { | ||
343 | return &mon_bus0; | ||
344 | } | ||
325 | list_for_each (p, &mon_buses) { | 345 | list_for_each (p, &mon_buses) { |
326 | mbus = list_entry(p, struct mon_bus, bus_link); | 346 | mbus = list_entry(p, struct mon_bus, bus_link); |
327 | if (mbus->u_bus->busnum == num) { | 347 | if (mbus->u_bus->busnum == num) { |
@@ -341,6 +361,8 @@ static int __init mon_init(void) | |||
341 | if ((rc = mon_bin_init()) != 0) | 361 | if ((rc = mon_bin_init()) != 0) |
342 | goto err_bin; | 362 | goto err_bin; |
343 | 363 | ||
364 | mon_bus0_init(); | ||
365 | |||
344 | if (usb_mon_register(&mon_ops_0) != 0) { | 366 | if (usb_mon_register(&mon_ops_0) != 0) { |
345 | printk(KERN_NOTICE TAG ": unable to register with the core\n"); | 367 | printk(KERN_NOTICE TAG ": unable to register with the core\n"); |
346 | rc = -ENODEV; | 368 | rc = -ENODEV; |
@@ -374,6 +396,7 @@ static void __exit mon_exit(void) | |||
374 | usb_mon_deregister(); | 396 | usb_mon_deregister(); |
375 | 397 | ||
376 | mutex_lock(&mon_lock); | 398 | mutex_lock(&mon_lock); |
399 | |||
377 | while (!list_empty(&mon_buses)) { | 400 | while (!list_empty(&mon_buses)) { |
378 | p = mon_buses.next; | 401 | p = mon_buses.next; |
379 | mbus = list_entry(p, struct mon_bus, bus_link); | 402 | mbus = list_entry(p, struct mon_bus, bus_link); |
@@ -397,6 +420,11 @@ static void __exit mon_exit(void) | |||
397 | mon_dissolve(mbus, mbus->u_bus); | 420 | mon_dissolve(mbus, mbus->u_bus); |
398 | kref_put(&mbus->ref, mon_bus_drop); | 421 | kref_put(&mbus->ref, mon_bus_drop); |
399 | } | 422 | } |
423 | |||
424 | mbus = &mon_bus0; | ||
425 | if (mbus->text_inited) | ||
426 | mon_text_del(mbus); | ||
427 | |||
400 | mutex_unlock(&mon_lock); | 428 | mutex_unlock(&mon_lock); |
401 | 429 | ||
402 | mon_text_exit(); | 430 | mon_text_exit(); |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index bbf54396e5f2..ec0cc51e39ac 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -124,8 +124,10 @@ static inline char mon_text_get_setup(struct mon_event_text *ep, | |||
124 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | 124 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') |
125 | return '-'; | 125 | return '-'; |
126 | 126 | ||
127 | if (mbus->uses_dma && (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 127 | if (urb->dev->bus->uses_dma && |
128 | (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
128 | return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); | 129 | return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); |
130 | } | ||
129 | if (urb->setup_packet == NULL) | 131 | if (urb->setup_packet == NULL) |
130 | return 'Z'; /* '0' would be not as pretty. */ | 132 | return 'Z'; /* '0' would be not as pretty. */ |
131 | 133 | ||
@@ -160,8 +162,10 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
160 | * contain non-NULL garbage in case the upper level promised to | 162 | * contain non-NULL garbage in case the upper level promised to |
161 | * set DMA for the HCD. | 163 | * set DMA for the HCD. |
162 | */ | 164 | */ |
163 | if (mbus->uses_dma && (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | 165 | if (urb->dev->bus->uses_dma && |
166 | (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { | ||
164 | return mon_dmapeek(ep->data, urb->transfer_dma, len); | 167 | return mon_dmapeek(ep->data, urb->transfer_dma, len); |
168 | } | ||
165 | 169 | ||
166 | if (urb->transfer_buffer == NULL) | 170 | if (urb->transfer_buffer == NULL) |
167 | return 'Z'; /* '0' would be not as pretty. */ | 171 | return 'Z'; /* '0' would be not as pretty. */ |
@@ -201,7 +205,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | |||
201 | ep->type = ev_type; | 205 | ep->type = ev_type; |
202 | ep->pipe = urb->pipe; | 206 | ep->pipe = urb->pipe; |
203 | ep->id = (unsigned long) urb; | 207 | ep->id = (unsigned long) urb; |
204 | ep->busnum = rp->r.m_bus->u_bus->busnum; | 208 | ep->busnum = urb->dev->bus->busnum; |
205 | ep->tstamp = stamp; | 209 | ep->tstamp = stamp; |
206 | ep->length = (ev_type == 'S') ? | 210 | ep->length = (ev_type == 'S') ? |
207 | urb->transfer_buffer_length : urb->actual_length; | 211 | urb->transfer_buffer_length : urb->actual_length; |
@@ -305,13 +309,11 @@ static struct mon_event_text *mon_text_fetch(struct mon_reader_text *rp, | |||
305 | static int mon_text_open(struct inode *inode, struct file *file) | 309 | static int mon_text_open(struct inode *inode, struct file *file) |
306 | { | 310 | { |
307 | struct mon_bus *mbus; | 311 | struct mon_bus *mbus; |
308 | struct usb_bus *ubus; | ||
309 | struct mon_reader_text *rp; | 312 | struct mon_reader_text *rp; |
310 | int rc; | 313 | int rc; |
311 | 314 | ||
312 | mutex_lock(&mon_lock); | 315 | mutex_lock(&mon_lock); |
313 | mbus = inode->i_private; | 316 | mbus = inode->i_private; |
314 | ubus = mbus->u_bus; | ||
315 | 317 | ||
316 | rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); | 318 | rp = kzalloc(sizeof(struct mon_reader_text), GFP_KERNEL); |
317 | if (rp == NULL) { | 319 | if (rp == NULL) { |
@@ -335,8 +337,7 @@ static int mon_text_open(struct inode *inode, struct file *file) | |||
335 | rp->r.rnf_error = mon_text_error; | 337 | rp->r.rnf_error = mon_text_error; |
336 | rp->r.rnf_complete = mon_text_complete; | 338 | rp->r.rnf_complete = mon_text_complete; |
337 | 339 | ||
338 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon%dt_%lx", ubus->busnum, | 340 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp); |
339 | (long)rp); | ||
340 | rp->e_slab = kmem_cache_create(rp->slab_name, | 341 | rp->e_slab = kmem_cache_create(rp->slab_name, |
341 | sizeof(struct mon_event_text), sizeof(long), 0, | 342 | sizeof(struct mon_event_text), sizeof(long), 0, |
342 | mon_text_ctor, NULL); | 343 | mon_text_ctor, NULL); |
@@ -654,14 +655,14 @@ static const struct file_operations mon_fops_text_u = { | |||
654 | .release = mon_text_release, | 655 | .release = mon_text_release, |
655 | }; | 656 | }; |
656 | 657 | ||
657 | int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) | 658 | int mon_text_add(struct mon_bus *mbus, int busnum) |
658 | { | 659 | { |
659 | struct dentry *d; | 660 | struct dentry *d; |
660 | enum { NAMESZ = 10 }; | 661 | enum { NAMESZ = 10 }; |
661 | char name[NAMESZ]; | 662 | char name[NAMESZ]; |
662 | int rc; | 663 | int rc; |
663 | 664 | ||
664 | rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); | 665 | rc = snprintf(name, NAMESZ, "%dt", busnum); |
665 | if (rc <= 0 || rc >= NAMESZ) | 666 | if (rc <= 0 || rc >= NAMESZ) |
666 | goto err_print_t; | 667 | goto err_print_t; |
667 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t); | 668 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_t); |
@@ -669,7 +670,7 @@ int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) | |||
669 | goto err_create_t; | 670 | goto err_create_t; |
670 | mbus->dent_t = d; | 671 | mbus->dent_t = d; |
671 | 672 | ||
672 | rc = snprintf(name, NAMESZ, "%du", ubus->busnum); | 673 | rc = snprintf(name, NAMESZ, "%du", busnum); |
673 | if (rc <= 0 || rc >= NAMESZ) | 674 | if (rc <= 0 || rc >= NAMESZ) |
674 | goto err_print_u; | 675 | goto err_print_u; |
675 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u); | 676 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text_u); |
@@ -677,7 +678,7 @@ int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) | |||
677 | goto err_create_u; | 678 | goto err_create_u; |
678 | mbus->dent_u = d; | 679 | mbus->dent_u = d; |
679 | 680 | ||
680 | rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); | 681 | rc = snprintf(name, NAMESZ, "%ds", busnum); |
681 | if (rc <= 0 || rc >= NAMESZ) | 682 | if (rc <= 0 || rc >= NAMESZ) |
682 | goto err_print_s; | 683 | goto err_print_s; |
683 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); | 684 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); |
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index a1e2b8e9d777..13d63255283e 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h | |||
@@ -23,7 +23,6 @@ struct mon_bus { | |||
23 | struct dentry *dent_s; /* Debugging file */ | 23 | struct dentry *dent_s; /* Debugging file */ |
24 | struct dentry *dent_t; /* Text interface file */ | 24 | struct dentry *dent_t; /* Text interface file */ |
25 | struct dentry *dent_u; /* Second text interface file */ | 25 | struct dentry *dent_u; /* Second text interface file */ |
26 | int uses_dma; | ||
27 | 26 | ||
28 | /* Ref */ | 27 | /* Ref */ |
29 | int nreaders; /* Under mon_lock AND mbus->lock */ | 28 | int nreaders; /* Under mon_lock AND mbus->lock */ |
@@ -53,7 +52,7 @@ void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); | |||
53 | 52 | ||
54 | struct mon_bus *mon_bus_lookup(unsigned int num); | 53 | struct mon_bus *mon_bus_lookup(unsigned int num); |
55 | 54 | ||
56 | int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus); | 55 | int /*bool*/ mon_text_add(struct mon_bus *mbus, int busnum); |
57 | void mon_text_del(struct mon_bus *mbus); | 56 | void mon_text_del(struct mon_bus *mbus); |
58 | // void mon_bin_add(struct mon_bus *); | 57 | // void mon_bin_add(struct mon_bus *); |
59 | 58 | ||
@@ -82,4 +81,6 @@ extern struct mutex mon_lock; | |||
82 | 81 | ||
83 | extern const struct file_operations mon_fops_stat; | 82 | extern const struct file_operations mon_fops_stat; |
84 | 83 | ||
84 | extern struct mon_bus mon_bus0; /* Only for redundant checks */ | ||
85 | |||
85 | #endif /* __USB_MON_H */ | 86 | #endif /* __USB_MON_H */ |