/*
 * libusual
 *
 * The libusual contains the table of devices common for ub and usb-storage.
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb_usual.h>
#include <linux/vmalloc.h>
#include <linux/kthread.h>

/*
 */
#define USU_MOD_FL_THREAD   1	/* Thread is running */
#define USU_MOD_FL_PRESENT  2	/* The module is loaded */

struct mod_status {
	unsigned long fls;
};

static struct mod_status stat[3];
static DEFINE_SPINLOCK(usu_lock);

/*
 */
#define USB_US_DEFAULT_BIAS	USB_US_TYPE_STOR
static atomic_t usu_bias = ATOMIC_INIT(USB_US_DEFAULT_BIAS);

#define BIAS_NAME_SIZE  (sizeof("usb-storage"))
static const char *bias_names[3] = { "none", "usb-storage", "ub" };

static DECLARE_MUTEX_LOCKED(usu_init_notify);
static DECLARE_COMPLETION(usu_end_notify);
static atomic_t total_threads = ATOMIC_INIT(0);

static int usu_probe_thread(void *arg);

/*
 * The table.
 */
#define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
		    vendorName, productName,useProtocol, useTransport, \
		    initFunction, flags) \
{ USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \
  .driver_info = (flags)|(USB_US_TYPE_STOR<<24) }

#define USUAL_DEV(useProto, useTrans, useType) \
{ USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \
  .driver_info = ((useType)<<24) }

struct usb_device_id storage_usb_ids [] = {
#	include "unusual_devs.h"
	{ } /* Terminating entry */
};

#undef USUAL_DEV
#undef UNUSUAL_DEV

MODULE_DEVICE_TABLE(usb, storage_usb_ids);
EXPORT_SYMBOL_GPL(storage_usb_ids);

/*
 * @type: the module type as an integer
 */
void usb_usual_set_present(int type)
{
	struct mod_status *st;
	unsigned long flags;

	if (type <= 0 || type >= 3)
		return;
	st = &stat[type];
	spin_lock_irqsave(&usu_lock, flags);
	st->fls |= USU_MOD_FL_PRESENT;
	spin_unlock_irqrestore(&usu_lock, flags);
}
EXPORT_SYMBOL_GPL(usb_usual_set_present);

void usb_usual_clear_present(int type)
{
	struct mod_status *st;
	unsigned long flags;

	if (type <= 0 || type >= 3)
		return;
	st = &stat[type];
	spin_lock_irqsave(&usu_lock, flags);
	st->fls &= ~USU_MOD_FL_PRESENT;
	spin_unlock_irqrestore(&usu_lock, flags);
}
EXPORT_SYMBOL_GPL(usb_usual_clear_present);

/*
 * Match the calling driver type against the table.
 * Returns: 0 if the device matches.
 */
int usb_usual_check_type(const struct usb_device_id *id, int caller_type)
{
	int id_type = USB_US_TYPE(id->driver_info);

	if (caller_type <= 0 || caller_type >= 3)
		return -EINVAL;

	/* Drivers grab fixed assignment devices */
	if (id_type == caller_type)
		return 0;
	/* Drivers grab devices biased to them */
	if (id_type == USB_US_TYPE_NONE && caller_type == atomic_read(&usu_bias))
		return 0;
	return -ENODEV;
}
EXPORT_SYMBOL_GPL(usb_usual_check_type);

/*
 */
static int usu_probe(struct usb_interface *intf,
			 const struct usb_device_id *id)
{
	unsigned long type;
	struct task_struct* task;
	unsigned long flags;

	type = USB_US_TYPE(id->driver_info);
	if (type == 0)
		type = atomic_read(&usu_bias);

	spin_lock_irqsave(&usu_lock, flags);
	if ((stat[type].fls & (USU_MOD_FL_THREAD|USU_MOD_FL_PRESENT)) != 0) {
		spin_unlock_irqrestore(&usu_lock, flags);
		return -ENXIO;
	}
	stat[type].fls |= USU_MOD_FL_THREAD;
	spin_unlock_irqrestore(&usu_lock, flags);

	task = kthread_run(usu_probe_thread, (void*)type, "libusual_%d", type);
	if (IS_ERR(task)) {
		int rc = PTR_ERR(task);
		printk(KERN_WARNING "libusual: "
		    "Unable to start the thread for %s: %d\n",
		    bias_names[type], rc);
		spin_lock_irqsave(&usu_lock, flags);
		stat[type].fls &= ~USU_MOD_FL_THREAD;
		spin_unlock_irqrestore(&usu_lock, flags);
		return rc;	/* Not being -ENXIO causes a message printed */
	}
	atomic_inc(&total_threads);

	return -ENXIO;
}

static void usu_disconnect(struct usb_interface *intf)
{
	;	/* We should not be here. */
}

static struct usb_driver usu_driver = {
	.name =		"libusual",
	.probe =	usu_probe,
	.disconnect =	usu_disconnect,
	.id_table =	storage_usb_ids,
};

/*
 * A whole new thread for a purpose of request_module seems quite stupid.
 * The request_module forks once inside again. However, if we attempt
 * to load a storage module from our own modprobe thread, that module
 * references our symbols, which cannot be resolved until our module is
 * initialized. I wish there was a way to wait for the end of initialization.
 * The module notifier reports MODULE_STATE_COMING only.
 * So, we wait until module->init ends as the next best thing.
 */
static int usu_probe_thread(void *arg)
{
	int type = (unsigned long) arg;
	struct mod_status *st = &stat[type];
	int rc;
	unsigned long flags;

	/* A completion does not work here because it's counted. */
	down(&usu_init_notify);
	up(&usu_init_notify);

	rc = request_module(bias_names[type]);
	spin_lock_irqsave(&usu_lock, flags);
	if (rc == 0 && (st->fls & USU_MOD_FL_PRESENT) == 0) {
		/*
		 * This should not happen, but let us keep tabs on it.
		 */
		printk(KERN_NOTICE "libusual: "
		    "modprobe for %s succeeded, but module is not present\n",
		    bias_names[type]);
	}
	st->fls &= ~USU_MOD_FL_THREAD;
	spin_unlock_irqrestore(&usu_lock, flags);

	complete_and_exit(&usu_end_notify, 0);
}

/*
 */
static int __init usb_usual_init(void)
{
	int rc;

	rc = usb_register(&usu_driver);
	up(&usu_init_notify);
	return rc;
}

static void __exit usb_usual_exit(void)
{
	/*
	 * We do not check for any drivers present, because
	 * they keep us pinned with symbol references.
	 */

	usb_deregister(&usu_driver);

	while (atomic_read(&total_threads) > 0) {
		wait_for_completion(&usu_end_notify);
		atomic_dec(&total_threads);
	}
}

/*
 * Validate and accept the bias parameter.
 */
static int usu_set_bias(const char *bias_s, struct kernel_param *kp)
{
	int i;
	int len;
	int bias_n = 0;

	len = strlen(bias_s);
	if (len == 0)
		return -EDOM;
	if (bias_s[len-1] == '\n')
		--len;

	for (i = 1; i < 3; i++) {
		if (strncmp(bias_s, bias_names[i], len) == 0) {
			bias_n = i;
			break;
		}
	}
	if (bias_n == 0)
		return -EINVAL;

	atomic_set(&usu_bias, bias_n);
	return 0;
}

static int usu_get_bias(char *buffer, struct kernel_param *kp)
{
	return strlen(strcpy(buffer, bias_names[atomic_read(&usu_bias)]));
}

module_init(usb_usual_init);
module_exit(usb_usual_exit);

module_param_call(bias, usu_set_bias, usu_get_bias, NULL, S_IRUGO|S_IWUSR);
__MODULE_PARM_TYPE(bias, "string");
MODULE_PARM_DESC(bias, "Bias to usb-storage or ub");

MODULE_LICENSE("GPL");
