/*
 * 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/err.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 posiblity 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);
	}
}
