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