/*
 * The USB Monitor, inspired by Dave Harding's USBMon.
 *
 * mon_main.c: Main file, module initiation and exit, registrations, etc.
 *
 * Copyright (C) 2005 Pete Zaitcev (zaitcev@redhat.com)
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/slab.h>
#include <linux/notifier.h>
#include <linux/mutex.h>

#include "usb_mon.h"


static void mon_stop(struct mon_bus *mbus);
static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus);
static void mon_bus_drop(struct kref *r);
static void mon_bus_init(struct usb_bus *ubus);

DEFINE_MUTEX(mon_lock);

struct mon_bus mon_bus0;		/* Pseudo bus meaning "all buses" */
static LIST_HEAD(mon_buses);		/* All buses we know: struct mon_bus */

/*
 * Link a reader into the bus.
 *
 * This must be called with mon_lock taken because of mbus->ref.
 */
void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r)
{
	unsigned long flags;
	struct list_head *p;

	spin_lock_irqsave(&mbus->lock, flags);
	if (mbus->nreaders == 0) {
		if (mbus == &mon_bus0) {
			list_for_each (p, &mon_buses) {
				struct mon_bus *m1;
				m1 = list_entry(p, struct mon_bus, bus_link);
				m1->u_bus->monitored = 1;
			}
		} else {
			mbus->u_bus->monitored = 1;
		}
	}
	mbus->nreaders++;
	list_add_tail(&r->r_link, &mbus->r_list);
	spin_unlock_irqrestore(&mbus->lock, flags);

	kref_get(&mbus->ref);
}

/*
 * Unlink reader from the bus.
 *
 * This is called with mon_lock taken, so we can decrement mbus->ref.
 */
void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r)
{
	unsigned long flags;

	spin_lock_irqsave(&mbus->lock, flags);
	list_del(&r->r_link);
	--mbus->nreaders;
	if (mbus->nreaders == 0)
		mon_stop(mbus);
	spin_unlock_irqrestore(&mbus->lock, flags);

	kref_put(&mbus->ref, mon_bus_drop);
}

/*
 */
static void mon_bus_submit(struct mon_bus *mbus, struct urb *urb)
{
	unsigned long flags;
	struct list_head *pos;
	struct mon_reader *r;

	spin_lock_irqsave(&mbus->lock, flags);
	mbus->cnt_events++;
	list_for_each (pos, &mbus->r_list) {
		r = list_entry(pos, struct mon_reader, r_link);
		r->rnf_submit(r->r_data, urb);
	}
	spin_unlock_irqrestore(&mbus->lock, flags);
}

static void mon_submit(struct usb_bus *ubus, struct urb *urb)
{
	struct mon_bus *mbus;

	if ((mbus = ubus->mon_bus) != NULL)
		mon_bus_submit(mbus, urb);
	mon_bus_submit(&mon_bus0, urb);
}

/*
 */
static void mon_bus_submit_error(struct mon_bus *mbus, struct urb *urb, int error)
{
	unsigned long flags;
	struct list_head *pos;
	struct mon_reader *r;

	spin_lock_irqsave(&mbus->lock, flags);
	mbus->cnt_events++;
	list_for_each (pos, &mbus->r_list) {
		r = list_entry(pos, struct mon_reader, r_link);
		r->rnf_error(r->r_data, urb, error);
	}
	spin_unlock_irqrestore(&mbus->lock, flags);
}

static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error)
{
	struct mon_bus *mbus;

	if ((mbus = ubus->mon_bus) != NULL)
		mon_bus_submit_error(mbus, urb, error);
	mon_bus_submit_error(&mon_bus0, urb, error);
}

/*
 */
static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, int status)
{
	unsigned long flags;
	struct list_head *pos;
	struct mon_reader *r;

	spin_lock_irqsave(&mbus->lock, flags);
	mbus->cnt_events++;
	list_for_each (pos, &mbus->r_list) {
		r = list_entry(pos, struct mon_reader, r_link);
		r->rnf_complete(r->r_data, urb, status);
	}
	spin_unlock_irqrestore(&mbus->lock, flags);
}

static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status)
{
	struct mon_bus *mbus;

	if ((mbus = ubus->mon_bus) != NULL)
		mon_bus_complete(mbus, urb, status);
	mon_bus_complete(&mon_bus0, urb, status);
}

/* int (*unlink_urb) (struct urb *urb, int status); */

/*
 * Stop monitoring.
 */
static void mon_stop(struct mon_bus *mbus)
{
	struct usb_bus *ubus;
	struct list_head *p;

	if (mbus == &mon_bus0) {
		list_for_each (p, &mon_buses) {
			mbus = list_entry(p, struct mon_bus, bus_link);
			/*
			 * We do not change nreaders here, so rely on mon_lock.
			 */
			if (mbus->nreaders == 0 && (ubus = mbus->u_bus) != NULL)
				ubus->monitored = 0;
		}
	} else {
		/*
		 * A stop can be called for a dissolved mon_bus in case of
		 * a reader staying across an rmmod foo_hcd, so test ->u_bus.
		 */
		if (mon_bus0.nreaders == 0 && (ubus = mbus->u_bus) != NULL) {
			ubus->monitored = 0;
			mb();
		}
	}
}

/*
 * Add a USB bus (usually by a modprobe foo-hcd)
 *
 * This does not return an error code because the core cannot care less
 * if monitoring is not established.
 */
static void mon_bus_add(struct usb_bus *ubus)
{
	mon_bus_init(ubus);
	mutex_lock(&mon_lock);
	if (mon_bus0.nreaders != 0)
		ubus->monitored = 1;
	mutex_unlock(&mon_lock);
}

/*
 * Remove a USB bus (either from rmmod foo-hcd or from a hot-remove event).
 */
static void mon_bus_remove(struct usb_bus *ubus)
{
	struct mon_bus *mbus = ubus->mon_bus;

	mutex_lock(&mon_lock);
	list_del(&mbus->bus_link);
	if (mbus->text_inited)
		mon_text_del(mbus);
	if (mbus->bin_inited)
		mon_bin_del(mbus);

	mon_dissolve(mbus, ubus);
	kref_put(&mbus->ref, mon_bus_drop);
	mutex_unlock(&mon_lock);
}

static int mon_notify(struct notifier_block *self, unsigned long action,
		      void *dev)
{
	switch (action) {
	case USB_BUS_ADD:
		mon_bus_add(dev);
		break;
	case USB_BUS_REMOVE:
		mon_bus_remove(dev);
	}
	return NOTIFY_OK;
}

static struct notifier_block mon_nb = {
	.notifier_call = 	mon_notify,
};

/*
 * Ops
 */
static struct usb_mon_operations mon_ops_0 = {
	.urb_submit =	mon_submit,
	.urb_submit_error = mon_submit_error,
	.urb_complete =	mon_complete,
};

/*
 * Tear usb_bus and mon_bus apart.
 */
static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus)
{

	if (ubus->monitored) {
		ubus->monitored = 0;
		mb();
	}

	ubus->mon_bus = NULL;
	mbus->u_bus = NULL;
	mb();

	/* We want synchronize_irq() here, but that needs an argument. */
}

/*
 */
static void mon_bus_drop(struct kref *r)
{
	struct mon_bus *mbus = container_of(r, struct mon_bus, ref);
	kfree(mbus);
}

/*
 * Initialize a bus for us:
 *  - allocate mon_bus
 *  - refcount USB bus struct
 *  - link
 */
static void mon_bus_init(struct usb_bus *ubus)
{
	struct mon_bus *mbus;

	if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL)
		goto err_alloc;
	kref_init(&mbus->ref);
	spin_lock_init(&mbus->lock);
	INIT_LIST_HEAD(&mbus->r_list);

	/*
	 * We don't need to take a reference to ubus, because we receive
	 * a notification if the bus is about to be removed.
	 */
	mbus->u_bus = ubus;
	ubus->mon_bus = mbus;

	mbus->text_inited = mon_text_add(mbus, ubus);
	mbus->bin_inited = mon_bin_add(mbus, ubus);

	mutex_lock(&mon_lock);
	list_add_tail(&mbus->bus_link, &mon_buses);
	mutex_unlock(&mon_lock);
	return;

err_alloc:
	return;
}

static void mon_bus0_init(void)
{
	struct mon_bus *mbus = &mon_bus0;

	kref_init(&mbus->ref);
	spin_lock_init(&mbus->lock);
	INIT_LIST_HEAD(&mbus->r_list);

	mbus->text_inited = mon_text_add(mbus, NULL);
	mbus->bin_inited = mon_bin_add(mbus, NULL);
}

/*
 * Search a USB bus by number. Notice that USB bus numbers start from one,
 * which we may later use to identify "all" with zero.
 *
 * This function must be called with mon_lock held.
 *
 * This is obviously inefficient and may be revised in the future.
 */
struct mon_bus *mon_bus_lookup(unsigned int num)
{
	struct list_head *p;
	struct mon_bus *mbus;

	if (num == 0) {
		return &mon_bus0;
	}
	list_for_each (p, &mon_buses) {
		mbus = list_entry(p, struct mon_bus, bus_link);
		if (mbus->u_bus->busnum == num) {
			return mbus;
		}
	}
	return NULL;
}

static int __init mon_init(void)
{
	struct usb_bus *ubus;
	int rc;

	if ((rc = mon_text_init()) != 0)
		goto err_text;
	if ((rc = mon_bin_init()) != 0)
		goto err_bin;

	mon_bus0_init();

	if (usb_mon_register(&mon_ops_0) != 0) {
		printk(KERN_NOTICE TAG ": unable to register with the core\n");
		rc = -ENODEV;
		goto err_reg;
	}
	// MOD_INC_USE_COUNT(which_module?);

	mutex_lock(&usb_bus_list_lock);
	list_for_each_entry (ubus, &usb_bus_list, bus_list) {
		mon_bus_init(ubus);
	}
	usb_register_notify(&mon_nb);
	mutex_unlock(&usb_bus_list_lock);
	return 0;

err_reg:
	mon_bin_exit();
err_bin:
	mon_text_exit();
err_text:
	return rc;
}

static void __exit mon_exit(void)
{
	struct mon_bus *mbus;
	struct list_head *p;

	usb_unregister_notify(&mon_nb);
	usb_mon_deregister();

	mutex_lock(&mon_lock);

	while (!list_empty(&mon_buses)) {
		p = mon_buses.next;
		mbus = list_entry(p, struct mon_bus, bus_link);
		list_del(p);

		if (mbus->text_inited)
			mon_text_del(mbus);
		if (mbus->bin_inited)
			mon_bin_del(mbus);

		/*
		 * This never happens, because the open/close paths in
		 * file level maintain module use counters and so rmmod fails
		 * before reaching here. However, better be safe...
		 */
		if (mbus->nreaders) {
			printk(KERN_ERR TAG
			    ": Outstanding opens (%d) on usb%d, leaking...\n",
			    mbus->nreaders, mbus->u_bus->busnum);
			atomic_set(&mbus->ref.refcount, 2);	/* Force leak */
		}

		mon_dissolve(mbus, mbus->u_bus);
		kref_put(&mbus->ref, mon_bus_drop);
	}

	mbus = &mon_bus0;
	if (mbus->text_inited)
		mon_text_del(mbus);
	if (mbus->bin_inited)
		mon_bin_del(mbus);

	mutex_unlock(&mon_lock);

	mon_text_exit();
	mon_bin_exit();
}

module_init(mon_init);
module_exit(mon_exit);

MODULE_LICENSE("GPL");
