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