linux/drivers/usb/mon/mon_main.c
<<
>>
Prefs
   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, 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