1/* 2 * The USB Monitor, inspired by Dave Harding's USBMon. 3 * 4 * mon_main.c: Main file, module initiation and exit, registrations, etc. 5 * 6 * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com) 7 */ 8 9#include <linux/kernel.h> 10#include <linux/module.h> 11#include <linux/usb.h> 12#include <linux/notifier.h> 13#include <linux/mutex.h> 14 15#include "usb_mon.h" 16#include "../core/hcd.h" 17 18static void mon_stop(struct mon_bus *mbus); 19static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); 20static void mon_bus_drop(struct kref *r); 21static void mon_bus_init(struct usb_bus *ubus); 22 23DEFINE_MUTEX(mon_lock); 24 25struct mon_bus mon_bus0; /* Pseudo bus meaning "all buses" */ 26static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ 27 28/* 29 * Link a reader into the bus. 30 * 31 * This must be called with mon_lock taken because of mbus->ref. 32 */ 33void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r) 34{ 35 unsigned long flags; 36 struct list_head *p; 37 38 spin_lock_irqsave(&mbus->lock, flags); 39 if (mbus->nreaders == 0) { 40 if (mbus == &mon_bus0) { 41 list_for_each (p, &mon_buses) { 42 struct mon_bus *m1; 43 m1 = list_entry(p, struct mon_bus, bus_link); 44 m1->u_bus->monitored = 1; 45 } 46 } else { 47 mbus->u_bus->monitored = 1; 48 } 49 } 50 mbus->nreaders++; 51 list_add_tail(&r->r_link, &mbus->r_list); 52 spin_unlock_irqrestore(&mbus->lock, flags); 53 54 kref_get(&mbus->ref); 55} 56 57/* 58 * Unlink reader from the bus. 59 * 60 * This is called with mon_lock taken, so we can decrement mbus->ref. 61 */ 62void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r) 63{ 64 unsigned long flags; 65 66 spin_lock_irqsave(&mbus->lock, flags); 67 list_del(&r->r_link); 68 --mbus->nreaders; 69 if (mbus->nreaders == 0) 70 mon_stop(mbus); 71 spin_unlock_irqrestore(&mbus->lock, flags); 72 73 kref_put(&mbus->ref, mon_bus_drop); 74} 75 76/* 77 */ 78static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb) 79{ 80 unsigned long flags; 81 struct list_head *pos; 82 struct mon_reader *r; 83 84 spin_lock_irqsave(&mbus->lock, flags); 85 mbus->cnt_events++; 86 list_for_each (pos, &mbus->r_list) { 87 r = list_entry(pos, struct mon_reader, r_link); 88 r->rnf_submit(r->r_data, urb); 89 } 90 spin_unlock_irqrestore(&mbus->lock, flags); 91 return; 92} 93 94static void mon_submit(struct usb_bus *ubus, struct urb *urb) 95{ 96 struct mon_bus *mbus; 97 98 if ((mbus = ubus->mon_bus) != NULL) 99 mon_bus_submit(mbus, urb); 100 mon_bus_submit(&mon_bus0, urb); 101} 102 103/* 104 */ 105static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error) 106{ 107 unsigned long flags; 108 struct list_head *pos; 109 struct mon_reader *r; 110 111 spin_lock_irqsave(&mbus->lock, flags); 112 mbus->cnt_events++; 113 list_for_each (pos, &mbus->r_list) { 114 r = list_entry(pos, struct mon_reader, r_link); 115 r->rnf_error(r->r_data, urb, error); 116 } 117 spin_unlock_irqrestore(&mbus->lock, flags); 118 return; 119} 120 121static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) 122{ 123 struct mon_bus *mbus; 124 125 if ((mbus = ubus->mon_bus) != NULL) 126 mon_bus_submit_error(mbus, urb, error); 127 mon_bus_submit_error(&mon_bus0, urb, error); 128} 129 130/* 131 */ 132static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) 133{ 134 unsigned long flags; 135 struct list_head *pos; 136 struct mon_reader *r; 137 138 spin_lock_irqsave(&mbus->lock, flags); 139 mbus->cnt_events++; 140 list_for_each (pos, &mbus->r_list) { 141 r = list_entry(pos, struct mon_reader, r_link); 142 r->rnf_complete(r->r_data, urb); 143 } 144 spin_unlock_irqrestore(&mbus->lock, flags); 145} 146 147static void mon_complete(struct usb_bus *ubus, struct urb *urb) 148{ 149 struct mon_bus *mbus; 150 151 mbus = ubus->mon_bus; 152 if (mbus == NULL) { 153 /* 154 * This should not happen. 155 * At this point we do not even know the bus number... 156 */ 157 printk(KERN_ERR TAG ": Null mon bus in URB, pipe 0x%x\n", 158 urb->pipe); 159 return; 160 } 161 162 mon_bus_complete(mbus, urb); 163 mon_bus_complete(&mon_bus0, urb); 164} 165 166/* int (*unlink_urb) (struct urb *urb, int status); */ 167 168/* 169 * Stop monitoring. 170 */ 171static void mon_stop(struct mon_bus *mbus) 172{ 173 struct usb_bus *ubus = mbus->u_bus; 174 struct list_head *p; 175 176 if (mbus == &mon_bus0) { 177 list_for_each (p, &mon_buses) { 178 mbus = list_entry(p, struct mon_bus, bus_link); 179 /* 180 * We do not change nreaders here, so rely on mon_lock. 181 */ 182 if (mbus->nreaders == 0 && (ubus = mbus->u_bus) != NULL) 183 ubus->monitored = 0; 184 } 185 } else { 186 /* 187 * A stop can be called for a dissolved mon_bus in case of 188 * a reader staying across an rmmod foo_hcd, so test ->u_bus. 189 */ 190 if (mon_bus0.nreaders == 0 && (ubus = mbus->u_bus) != NULL) { 191 ubus->monitored = 0; 192 mb(); 193 } 194 } 195} 196 197/* 198 * Add a USB bus (usually by a modprobe foo-hcd) 199 * 200 * This does not return an error code because the core cannot care less 201 * if monitoring is not established. 202 */ 203static void mon_bus_add(struct usb_bus *ubus) 204{ 205 mon_bus_init(ubus); 206 mutex_lock(&mon_lock); 207 if (mon_bus0.nreaders != 0) 208 ubus->monitored = 1; 209 mutex_unlock(&mon_lock); 210} 211 212/* 213 * Remove a USB bus (either from rmmod foo-hcd or from a hot-remove event). 214 */ 215static void mon_bus_remove(struct usb_bus *ubus) 216{ 217 struct mon_bus *mbus = ubus->mon_bus; 218 219 mutex_lock(&mon_lock); 220 list_del(&mbus->bus_link); 221 if (mbus->text_inited) 222 mon_text_del(mbus); 223 224 mon_dissolve(mbus, ubus); 225 kref_put(&mbus->ref, mon_bus_drop); 226 mutex_unlock(&mon_lock); 227} 228 229static int mon_notify(struct notifier_block *self, unsigned long action, 230 void *dev) 231{ 232 switch (action) { 233 case USB_BUS_ADD: 234 mon_bus_add(dev); 235 break; 236 case USB_BUS_REMOVE: 237 mon_bus_remove(dev); 238 } 239 return NOTIFY_OK; 240} 241 242static struct notifier_block mon_nb = { 243 .notifier_call = mon_notify, 244}; 245 246/* 247 * Ops 248 */ 249static struct usb_mon_operations mon_ops_0 = { 250 .urb_submit = mon_submit, 251 .urb_submit_error = mon_submit_error, 252 .urb_complete = mon_complete, 253}; 254 255/* 256 * Tear usb_bus and mon_bus apart. 257 */ 258static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus) 259{ 260 261 if (ubus->monitored) { 262 ubus->monitored = 0; 263 mb(); 264 } 265 266 ubus->mon_bus = NULL; 267 mbus->u_bus = NULL; 268 mb(); 269 270 /* We want synchronize_irq() here, but that needs an argument. */ 271} 272 273/* 274 */ 275static void mon_bus_drop(struct kref *r) 276{ 277 struct mon_bus *mbus = container_of(r, struct mon_bus, ref); 278 kfree(mbus); 279} 280 281/* 282 * Initialize a bus for us: 283 * - allocate mon_bus 284 * - refcount USB bus struct 285 * - link 286 */ 287static void mon_bus_init(struct usb_bus *ubus) 288{ 289 struct mon_bus *mbus; 290 291 if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) 292 goto err_alloc; 293 kref_init(&mbus->ref); 294 spin_lock_init(&mbus->lock); 295 INIT_LIST_HEAD(&mbus->r_list); 296 297 /* 298 * We don't need to take a reference to ubus, because we receive 299 * a notification if the bus is about to be removed. 300 */ 301 mbus->u_bus = ubus; 302 ubus->mon_bus = mbus; 303 304 mbus->text_inited = mon_text_add(mbus, ubus->busnum); 305 // mon_bin_add(...) 306 307 mutex_lock(&mon_lock); 308 list_add_tail(&mbus->bus_link, &mon_buses); 309 mutex_unlock(&mon_lock); 310 return; 311 312err_alloc: 313 return; 314} 315 316static void mon_bus0_init(void) 317{ 318 struct mon_bus *mbus = &mon_bus0; 319 320 kref_init(&mbus->ref); 321 spin_lock_init(&mbus->lock); 322 INIT_LIST_HEAD(&mbus->r_list); 323 324 mbus->text_inited = mon_text_add(mbus, 0); 325 // mbus->bin_inited = mon_bin_add(mbus, 0); 326} 327 328/* 329 * Search a USB bus by number. Notice that USB bus numbers start from one, 330 * which we may later use to identify "all" with zero. 331 * 332 * This function must be called with mon_lock held. 333 * 334 * This is obviously inefficient and may be revised in the future. 335 */ 336struct mon_bus *mon_bus_lookup(unsigned int num) 337{ 338 struct list_head *p; 339 struct mon_bus *mbus; 340 341 if (num == 0) { 342 return &mon_bus0; 343 } 344 list_for_each (p, &mon_buses) { 345 mbus = list_entry(p, struct mon_bus, bus_link); 346 if (mbus->u_bus->busnum == num) { 347 return mbus; 348 } 349 } 350 return NULL; 351} 352 353static int __init mon_init(void) 354{ 355 struct usb_bus *ubus; 356 int rc; 357 358 if ((rc = mon_text_init()) != 0) 359 goto err_text; 360 if ((rc = mon_bin_init()) != 0) 361 goto err_bin; 362 363 mon_bus0_init(); 364 365 if (usb_mon_register(&mon_ops_0) != 0) { 366 printk(KERN_NOTICE TAG ": unable to register with the core\n"); 367 rc = -ENODEV; 368 goto err_reg; 369 } 370 // MOD_INC_USE_COUNT(which_module?); 371 372 usb_register_notify(&mon_nb); 373 374 mutex_lock(&usb_bus_list_lock); 375 list_for_each_entry (ubus, &usb_bus_list, bus_list) { 376 mon_bus_init(ubus); 377 } 378 mutex_unlock(&usb_bus_list_lock); 379 return 0; 380 381err_reg: 382 mon_bin_exit(); 383err_bin: 384 mon_text_exit(); 385err_text: 386 return rc; 387} 388 389static void __exit mon_exit(void) 390{ 391 struct mon_bus *mbus; 392 struct list_head *p; 393 394 usb_unregister_notify(&mon_nb); 395 usb_mon_deregister(); 396 397 mutex_lock(&mon_lock); 398 399 while (!list_empty(&mon_buses)) { 400 p = mon_buses.next; 401 mbus = list_entry(p, struct mon_bus, bus_link); 402 list_del(p); 403 404 if (mbus->text_inited) 405 mon_text_del(mbus); 406 407 /* 408 * This never happens, because the open/close paths in 409 * file level maintain module use counters and so rmmod fails 410 * before reaching here. However, better be safe... 411 */ 412 if (mbus->nreaders) { 413 printk(KERN_ERR TAG 414 ": Outstanding opens (%d) on usb%d, leaking...\n", 415 mbus->nreaders, mbus->u_bus->busnum); 416 atomic_set(&mbus->ref.refcount, 2); /* Force leak */ 417 } 418 419 mon_dissolve(mbus, mbus->u_bus); 420 kref_put(&mbus->ref, mon_bus_drop); 421 } 422 423 mbus = &mon_bus0; 424 if (mbus->text_inited) 425 mon_text_del(mbus); 426 427 mutex_unlock(&mon_lock); 428 429 mon_text_exit(); 430 mon_bin_exit(); 431} 432 433module_init(mon_init); 434module_exit(mon_exit); 435 436MODULE_LICENSE("GPL"); 437