/*
 * WUSB Wire Adapter: Radio Control Interface (WUSB[8])
 * Notification and Event Handling
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version
 * 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * The RC interface of the Host Wire Adapter (USB dongle) or WHCI PCI
 * card delivers a stream of notifications and events to the
 * notification end event endpoint or area. This code takes care of
 * getting a buffer with that data, breaking it up in separate
 * notifications and events and then deliver those.
 *
 * Events are answers to commands and they carry a context ID that
 * associates them to the command. Notifications are that,
 * notifications, they come out of the blue and have a context ID of
 * zero. Think of the context ID kind of like a handler. The
 * uwb_rc_neh_* code deals with managing context IDs.
 *
 * This is why you require a handle to operate on a UWB host. When you
 * open a handle a context ID is assigned to you.
 *
 * So, as it is done is:
 *
 * 1. Add an event handler [uwb_rc_neh_add()] (assigns a ctx id)
 * 2. Issue command [rc->cmd(rc, ...)]
 * 3. Arm the timeout timer [uwb_rc_neh_arm()]
 * 4, Release the reference to the neh [uwb_rc_neh_put()]
 * 5. Wait for the callback
 * 6. Command result (RCEB) is passed to the callback
 *
 * If (2) fails, you should remove the handle [uwb_rc_neh_rm()]
 * instead of arming the timer.
 *
 * Handles are for using in *serialized* code, single thread.
 *
 * When the notification/event comes, the IRQ handler/endpoint
 * callback passes the data read to uwb_rc_neh_grok() which will break
 * it up in a discrete series of events, look up who is listening for
 * them and execute the pertinent callbacks.
 *
 * If the reader detects an error while reading the data stream, call
 * uwb_rc_neh_error().
 *
 * CONSTRAINTS/ASSUMPTIONS:
 *
 * - Most notifications/events are small (less thank .5k), copying
 *   around is ok.
 *
 * - Notifications/events are ALWAYS smaller than PAGE_SIZE
 *
 * - Notifications/events always come in a single piece (ie: a buffer
 *   will always contain entire notifications/events).
 *
 * - we cannot know in advance how long each event is (because they
 *   lack a length field in their header--smart move by the standards
 *   body, btw). So we need a facility to get the event size given the
 *   header. This is what the EST code does (notif/Event Size
 *   Tables), check nest.c--as well, you can associate the size to
 *   the handle [w/ neh->extra_size()].
 *
 * - Most notifications/events are fixed size; only a few are variable
 *   size (NEST takes care of that).
 *
 * - Listeners of events expect them, so they usually provide a
 *   buffer, as they know the size. Listeners to notifications don't,
 *   so we allocate their buffers dynamically.
 */
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/export.h>

#include "uwb-internal.h"

/*
 * UWB Radio Controller Notification/Event Handle
 *
 * Represents an entity waiting for an event coming from the UWB Radio
 * Controller with a given context id (context) and type (evt_type and
 * evt). On reception of the notification/event, the callback (cb) is
 * called with the event.
 *
 * If the timer expires before the event is received, the callback is
 * called with -ETIMEDOUT as the event size.
 */
struct uwb_rc_neh {
	struct kref kref;

	struct uwb_rc *rc;
	u8 evt_type;
	__le16 evt;
	u8 context;
	uwb_rc_cmd_cb_f cb;
	void *arg;

	struct timer_list timer;
	struct list_head list_node;
};

static void uwb_rc_neh_timer(unsigned long arg);

static void uwb_rc_neh_release(struct kref *kref)
{
	struct uwb_rc_neh *neh = container_of(kref, struct uwb_rc_neh, kref);

	kfree(neh);
}

static void uwb_rc_neh_get(struct uwb_rc_neh *neh)
{
	kref_get(&neh->kref);
}

/**
 * uwb_rc_neh_put - release reference to a neh
 * @neh: the neh
 */
void uwb_rc_neh_put(struct uwb_rc_neh *neh)
{
	kref_put(&neh->kref, uwb_rc_neh_release);
}


/**
 * Assigns @neh a context id from @rc's pool
 *
 * @rc:	    UWB Radio Controller descriptor; @rc->neh_lock taken
 * @neh:    Notification/Event Handle
 * @returns 0 if context id was assigned ok; < 0 errno on error (if
 *	    all the context IDs are taken).
 *
 * (assumes @wa is locked).
 *
 * NOTE: WUSB spec reserves context ids 0x00 for notifications and
 *	 0xff is invalid, so they must not be used. Initialization
 *	 fills up those two in the bitmap so they are not allocated.
 *
 * We spread the allocation around to reduce the possibility of two
 * consecutive opened @neh's getting the same context ID assigned (to
 * avoid surprises with late events that timed out long time ago). So
 * first we search from where @rc->ctx_roll is, if not found, we
 * search from zero.
 */
static
int __uwb_rc_ctx_get(struct uwb_rc *rc, struct uwb_rc_neh *neh)
{
	int result;
	result = find_next_zero_bit(rc->ctx_bm, UWB_RC_CTX_MAX,
				    rc->ctx_roll++);
	if (result < UWB_RC_CTX_MAX)
		goto found;
	result = find_first_zero_bit(rc->ctx_bm, UWB_RC_CTX_MAX);
	if (result < UWB_RC_CTX_MAX)
		goto found;
	return -ENFILE;
found:
	set_bit(result, rc->ctx_bm);
	neh->context = result;
	return 0;
}


/** Releases @neh's context ID back to @rc (@rc->neh_lock is locked). */
static
void __uwb_rc_ctx_put(struct uwb_rc *rc, struct uwb_rc_neh *neh)
{
	struct device *dev = &rc->uwb_dev.dev;
	if (neh->context == 0)
		return;
	if (test_bit(neh->context, rc->ctx_bm) == 0) {
		dev_err(dev, "context %u not set in bitmap\n",
			neh->context);
		WARN_ON(1);
	}
	clear_bit(neh->context, rc->ctx_bm);
	neh->context = 0;
}

/**
 * uwb_rc_neh_add - add a neh for a radio controller command
 * @rc:             the radio controller
 * @cmd:            the radio controller command
 * @expected_type:  the type of the expected response event
 * @expected_event: the expected event ID
 * @cb:             callback for when the event is received
 * @arg:            argument for the callback
 *
 * Creates a neh and adds it to the list of those waiting for an
 * event.  A context ID will be assigned to the command.
 */
struct uwb_rc_neh *uwb_rc_neh_add(struct uwb_rc *rc, struct uwb_rccb *cmd,
				  u8 expected_type, u16 expected_event,
				  uwb_rc_cmd_cb_f cb, void *arg)
{
	int result;
	unsigned long flags;
	struct device *dev = &rc->uwb_dev.dev;
	struct uwb_rc_neh *neh;

	neh = kzalloc(sizeof(*neh), GFP_KERNEL);
	if (neh == NULL) {
		result = -ENOMEM;
		goto error_kzalloc;
	}

	kref_init(&neh->kref);
	INIT_LIST_HEAD(&neh->list_node);
	init_timer(&neh->timer);
	neh->timer.function = uwb_rc_neh_timer;
	neh->timer.data     = (unsigned long)neh;

	neh->rc = rc;
	neh->evt_type = expected_type;
	neh->evt = cpu_to_le16(expected_event);
	neh->cb = cb;
	neh->arg = arg;

	spin_lock_irqsave(&rc->neh_lock, flags);
	result = __uwb_rc_ctx_get(rc, neh);
	if (result >= 0) {
		cmd->bCommandContext = neh->context;
		list_add_tail(&neh->list_node, &rc->neh_list);
		uwb_rc_neh_get(neh);
	}
	spin_unlock_irqrestore(&rc->neh_lock, flags);
	if (result < 0)
		goto error_ctx_get;

	return neh;

error_ctx_get:
	kfree(neh);
error_kzalloc:
	dev_err(dev, "cannot open handle to radio controller: %d\n", result);
	return ERR_PTR(result);
}

static void __uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
{
	__uwb_rc_ctx_put(rc, neh);
	list_del(&neh->list_node);
}

/**
 * uwb_rc_neh_rm - remove a neh.
 * @rc:  the radio controller
 * @neh: the neh to remove
 *
 * Remove an active neh immediately instead of waiting for the event
 * (or a time out).
 */
void uwb_rc_neh_rm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
{
	unsigned long flags;

	spin_lock_irqsave(&rc->neh_lock, flags);
	__uwb_rc_neh_rm(rc, neh);
	spin_unlock_irqrestore(&rc->neh_lock, flags);

	del_timer_sync(&neh->timer);
	uwb_rc_neh_put(neh);
}

/**
 * uwb_rc_neh_arm - arm an event handler timeout timer
 *
 * @rc:     UWB Radio Controller
 * @neh:    Notification/event handler for @rc
 *
 * The timer is only armed if the neh is active.
 */
void uwb_rc_neh_arm(struct uwb_rc *rc, struct uwb_rc_neh *neh)
{
	unsigned long flags;

	spin_lock_irqsave(&rc->neh_lock, flags);
	if (neh->context)
		mod_timer(&neh->timer,
			  jiffies + msecs_to_jiffies(UWB_RC_CMD_TIMEOUT_MS));
	spin_unlock_irqrestore(&rc->neh_lock, flags);
}

static void uwb_rc_neh_cb(struct uwb_rc_neh *neh, struct uwb_rceb *rceb, size_t size)
{
	(*neh->cb)(neh->rc, neh->arg, rceb, size);
	uwb_rc_neh_put(neh);
}

static bool uwb_rc_neh_match(struct uwb_rc_neh *neh, const struct uwb_rceb *rceb)
{
	return neh->evt_type == rceb->bEventType
		&& neh->evt == rceb->wEvent
		&& neh->context == rceb->bEventContext;
}

/**
 * Find the handle waiting for a RC Radio Control Event
 *
 * @rc:         UWB Radio Controller
 * @rceb:       Pointer to the RCEB buffer
 * @event_size: Pointer to the size of the RCEB buffer. Might be
 *              adjusted to take into account the @neh->extra_size
 *              settings.
 *
 * If the listener has no buffer (NULL buffer), one is allocated for
 * the right size (the amount of data received). @neh->ptr will point
 * to the event payload, which always starts with a 'struct
 * uwb_rceb'. kfree() it when done.
 */
static
struct uwb_rc_neh *uwb_rc_neh_lookup(struct uwb_rc *rc,
				     const struct uwb_rceb *rceb)
{
	struct uwb_rc_neh *neh = NULL, *h;
	unsigned long flags;

	spin_lock_irqsave(&rc->neh_lock, flags);

	list_for_each_entry(h, &rc->neh_list, list_node) {
		if (uwb_rc_neh_match(h, rceb)) {
			neh = h;
			break;
		}
	}

	if (neh)
		__uwb_rc_neh_rm(rc, neh);

	spin_unlock_irqrestore(&rc->neh_lock, flags);

	return neh;
}


/*
 * Process notifications coming from the radio control interface
 *
 * @rc:    UWB Radio Control Interface descriptor
 * @neh:   Notification/Event Handler @neh->ptr points to
 *         @uwb_evt->buffer.
 *
 * This function is called by the event/notif handling subsystem when
 * notifications arrive (hwarc_probe() arms a notification/event handle
 * that calls back this function for every received notification; this
 * function then will rearm itself).
 *
 * Notification data buffers are dynamically allocated by the NEH
 * handling code in neh.c [uwb_rc_neh_lookup()]. What is actually
 * allocated is space to contain the notification data.
 *
 * Buffers are prefixed with a Radio Control Event Block (RCEB) as
 * defined by the WUSB Wired-Adapter Radio Control interface. We
 * just use it for the notification code.
 *
 * On each case statement we just transcode endianess of the different
 * fields. We declare a pointer to a RCI definition of an event, and
 * then to a UWB definition of the same event (which are the same,
 * remember). Event if we use different pointers
 */
static
void uwb_rc_notif(struct uwb_rc *rc, struct uwb_rceb *rceb, ssize_t size)
{
	struct device *dev = &rc->uwb_dev.dev;
	struct uwb_event *uwb_evt;

	if (size == -ESHUTDOWN)
		return;
	if (size < 0) {
		dev_err(dev, "ignoring event with error code %zu\n",
			size);
		return;
	}

	uwb_evt = kzalloc(sizeof(*uwb_evt), GFP_ATOMIC);
	if (unlikely(uwb_evt == NULL)) {
		dev_err(dev, "no memory to queue event 0x%02x/%04x/%02x\n",
			rceb->bEventType, le16_to_cpu(rceb->wEvent),
			rceb->bEventContext);
		return;
	}
	uwb_evt->rc = __uwb_rc_get(rc);	/* will be put by uwbd's uwbd_event_handle() */
	uwb_evt->ts_jiffies = jiffies;
	uwb_evt->type = UWB_EVT_TYPE_NOTIF;
	uwb_evt->notif.size = size;
	uwb_evt->notif.rceb = rceb;

	uwbd_event_queue(uwb_evt);
}

static void uwb_rc_neh_grok_event(struct uwb_rc *rc, struct uwb_rceb *rceb, size_t size)
{
	struct device *dev = &rc->uwb_dev.dev;
	struct uwb_rc_neh *neh;
	struct uwb_rceb *notif;

	if (rceb->bEventContext == 0) {
		notif = kmalloc(size, GFP_ATOMIC);
		if (notif) {
			memcpy(notif, rceb, size);
			uwb_rc_notif(rc, notif, size);
		} else
			dev_err(dev, "event 0x%02x/%04x/%02x (%zu bytes): no memory\n",
				rceb->bEventType, le16_to_cpu(rceb->wEvent),
				rceb->bEventContext, size);
	} else {
		neh = uwb_rc_neh_lookup(rc, rceb);
		if (neh) {
			del_timer_sync(&neh->timer);
			uwb_rc_neh_cb(neh, rceb, size);
		} else
			dev_warn(dev, "event 0x%02x/%04x/%02x (%zu bytes): nobody cared\n",
				 rceb->bEventType, le16_to_cpu(rceb->wEvent),
				 rceb->bEventContext, size);
	}
}

/**
 * Given a buffer with one or more UWB RC events/notifications, break
 * them up and dispatch them.
 *
 * @rc:	      UWB Radio Controller
 * @buf:      Buffer with the stream of notifications/events
 * @buf_size: Amount of data in the buffer
 *
 * Note each notification/event starts always with a 'struct
 * uwb_rceb', so the minimum size if 4 bytes.
 *
 * The device may pass us events formatted differently than expected.
 * These are first filtered, potentially creating a new event in a new
 * memory location. If a new event is created by the filter it is also
 * freed here.
 *
 * For each notif/event, tries to guess the size looking at the EST
 * tables, then looks for a neh that is waiting for that event and if
 * found, copies the payload to the neh's buffer and calls it back. If
 * not, the data is ignored.
 *
 * Note that if we can't find a size description in the EST tables, we
 * still might find a size in the 'neh' handle in uwb_rc_neh_lookup().
 *
 * Assumptions:
 *
 *   @rc->neh_lock is NOT taken
 *
 * We keep track of various sizes here:
 * size:      contains the size of the buffer that is processed for the
 *            incoming event. this buffer may contain events that are not
 *            formatted as WHCI.
 * real_size: the actual space taken by this event in the buffer.
 *            We need to keep track of the real size of an event to be able to
 *            advance the buffer correctly.
 * event_size: the size of the event as expected by the core layer
 *            [OR] the size of the event after filtering. if the filtering
 *            created a new event in a new memory location then this is
 *            effectively the size of a new event buffer
 */
void uwb_rc_neh_grok(struct uwb_rc *rc, void *buf, size_t buf_size)
{
	struct device *dev = &rc->uwb_dev.dev;
	void *itr;
	struct uwb_rceb *rceb;
	size_t size, real_size, event_size;
	int needtofree;

	itr = buf;
	size = buf_size;
	while (size > 0) {
		if (size < sizeof(*rceb)) {
			dev_err(dev, "not enough data in event buffer to "
				"process incoming events (%zu left, minimum is "
				"%zu)\n", size, sizeof(*rceb));
			break;
		}

		rceb = itr;
		if (rc->filter_event) {
			needtofree = rc->filter_event(rc, &rceb, size,
						      &real_size, &event_size);
			if (needtofree < 0 && needtofree != -ENOANO) {
				dev_err(dev, "BUG: Unable to filter event "
					"(0x%02x/%04x/%02x) from "
					"device. \n", rceb->bEventType,
					le16_to_cpu(rceb->wEvent),
					rceb->bEventContext);
				break;
			}
		} else
			needtofree = -ENOANO;
		/* do real processing if there was no filtering or the
		 * filtering didn't act */
		if (needtofree == -ENOANO) {
			ssize_t ret = uwb_est_find_size(rc, rceb, size);
			if (ret < 0)
				break;
			if (ret > size) {
				dev_err(dev, "BUG: hw sent incomplete event "
					"0x%02x/%04x/%02x (%zd bytes), only got "
					"%zu bytes. We don't handle that.\n",
					rceb->bEventType, le16_to_cpu(rceb->wEvent),
					rceb->bEventContext, ret, size);
				break;
			}
			real_size = event_size = ret;
		}
		uwb_rc_neh_grok_event(rc, rceb, event_size);

		if (needtofree == 1)
			kfree(rceb);

		itr += real_size;
		size -= real_size;
	}
}
EXPORT_SYMBOL_GPL(uwb_rc_neh_grok);


/**
 * The entity that reads from the device notification/event channel has
 * detected an error.
 *
 * @rc:    UWB Radio Controller
 * @error: Errno error code
 *
 */
void uwb_rc_neh_error(struct uwb_rc *rc, int error)
{
	struct uwb_rc_neh *neh;
	unsigned long flags;

	for (;;) {
		spin_lock_irqsave(&rc->neh_lock, flags);
		if (list_empty(&rc->neh_list)) {
			spin_unlock_irqrestore(&rc->neh_lock, flags);
			break;
		}
		neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
		__uwb_rc_neh_rm(rc, neh);
		spin_unlock_irqrestore(&rc->neh_lock, flags);

		del_timer_sync(&neh->timer);
		uwb_rc_neh_cb(neh, NULL, error);
	}
}
EXPORT_SYMBOL_GPL(uwb_rc_neh_error);


static void uwb_rc_neh_timer(unsigned long arg)
{
	struct uwb_rc_neh *neh = (struct uwb_rc_neh *)arg;
	struct uwb_rc *rc = neh->rc;
	unsigned long flags;

	spin_lock_irqsave(&rc->neh_lock, flags);
	if (neh->context)
		__uwb_rc_neh_rm(rc, neh);
	else
		neh = NULL;
	spin_unlock_irqrestore(&rc->neh_lock, flags);

	if (neh)
		uwb_rc_neh_cb(neh, NULL, -ETIMEDOUT);
}

/** Initializes the @rc's neh subsystem
 */
void uwb_rc_neh_create(struct uwb_rc *rc)
{
	spin_lock_init(&rc->neh_lock);
	INIT_LIST_HEAD(&rc->neh_list);
	set_bit(0, rc->ctx_bm);		/* 0 is reserved (see [WUSB] table 8-65) */
	set_bit(0xff, rc->ctx_bm);	/* and 0xff is invalid */
	rc->ctx_roll = 1;
}


/** Release's the @rc's neh subsystem */
void uwb_rc_neh_destroy(struct uwb_rc *rc)
{
	unsigned long flags;
	struct uwb_rc_neh *neh;

	for (;;) {
		spin_lock_irqsave(&rc->neh_lock, flags);
		if (list_empty(&rc->neh_list)) {
			spin_unlock_irqrestore(&rc->neh_lock, flags);
			break;
		}
		neh = list_first_entry(&rc->neh_list, struct uwb_rc_neh, list_node);
		__uwb_rc_neh_rm(rc, neh);
		spin_unlock_irqrestore(&rc->neh_lock, flags);

		del_timer_sync(&neh->timer);
		uwb_rc_neh_put(neh);
	}
}
