/*
 * WUSB Wire Adapter: Control/Data Streaming Interface (WUSB[8])
 * Device Connect handling
 *
 * Copyright (C) 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.
 *
 *
 * FIXME: docs
 * FIXME: this file needs to be broken up, it's grown too big
 *
 *
 * WUSB1.0[7.1, 7.5.1, ]
 *
 * WUSB device connection is kind of messy. Some background:
 *
 *     When a device wants to connect it scans the UWB radio channels
 *     looking for a WUSB Channel; a WUSB channel is defined by MMCs
 *     (Micro Managed Commands or something like that) [see
 *     Design-overview for more on this] .
 *
 * So, device scans the radio, finds MMCs and thus a host and checks
 * when the next DNTS is. It sends a Device Notification Connect
 * (DN_Connect); the host picks it up (through nep.c and notif.c, ends
 * up in wusb_devconnect_ack(), which creates a wusb_dev structure in
 * wusbhc->port[port_number].wusb_dev), assigns an unauth address
 * to the device (this means from 0x80 to 0xfe) and sends, in the MMC
 * a Connect Ack Information Element (ConnAck IE).
 *
 * So now the device now has a WUSB address. From now on, we use
 * that to talk to it in the RPipes.
 *
 * ASSUMPTIONS:
 *
 *  - We use the the as device address the port number where it is
 *    connected (port 0 doesn't exist). For unauth, it is 128 + that.
 *
 * ROADMAP:
 *
 *   This file contains the logic for doing that--entry points:
 *
 *   wusb_devconnect_ack()      Ack a device until _acked() called.
 *                              Called by notif.c:wusb_handle_dn_connect()
 *                              when a DN_Connect is received.
 *
 *     wusb_devconnect_acked()  Ack done, release resources.
 *
 *   wusb_handle_dn_alive()     Called by notif.c:wusb_handle_dn()
 *                              for processing a DN_Alive pong from a device.
 *
 *   wusb_handle_dn_disconnect()Called by notif.c:wusb_handle_dn() to
 *                              process a disconenct request from a
 *                              device.
 *
 *   __wusb_dev_disable()       Called by rh.c:wusbhc_rh_clear_port_feat() when
 *                              disabling a port.
 *
 *   wusb_devconnect_create()   Called when creating the host by
 *                              lc.c:wusbhc_create().
 *
 *   wusb_devconnect_destroy()  Cleanup called removing the host. Called
 *                              by lc.c:wusbhc_destroy().
 *
 *   Each Wireless USB host maintains a list of DN_Connect requests
 *   (actually we maintain a list of pending Connect Acks, the
 *   wusbhc->ca_list).
 *
 * LIFE CYCLE OF port->wusb_dev
 *
 *   Before the @wusbhc structure put()s the reference it owns for
 *   port->wusb_dev [and clean the wusb_dev pointer], it needs to
 *   lock @wusbhc->mutex.
 */

#include <linux/jiffies.h>
#include <linux/ctype.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <linux/export.h>
#include "wusbhc.h"

static void wusbhc_devconnect_acked_work(struct work_struct *work);

static void wusb_dev_free(struct wusb_dev *wusb_dev)
{
	kfree(wusb_dev);
}

static struct wusb_dev *wusb_dev_alloc(struct wusbhc *wusbhc)
{
	struct wusb_dev *wusb_dev;

	wusb_dev = kzalloc(sizeof(*wusb_dev), GFP_KERNEL);
	if (wusb_dev == NULL)
		goto err;

	wusb_dev->wusbhc = wusbhc;

	INIT_WORK(&wusb_dev->devconnect_acked_work, wusbhc_devconnect_acked_work);

	return wusb_dev;
err:
	wusb_dev_free(wusb_dev);
	return NULL;
}


/*
 * Using the Connect-Ack list, fill out the @wusbhc Connect-Ack WUSB IE
 * properly so that it can be added to the MMC.
 *
 * We just get the @wusbhc->ca_list and fill out the first four ones or
 * less (per-spec WUSB1.0[7.5, before T7-38). If the ConnectAck WUSB
 * IE is not allocated, we alloc it.
 *
 * @wusbhc->mutex must be taken
 */
static void wusbhc_fill_cack_ie(struct wusbhc *wusbhc)
{
	unsigned cnt;
	struct wusb_dev *dev_itr;
	struct wuie_connect_ack *cack_ie;

	cack_ie = &wusbhc->cack_ie;
	cnt = 0;
	list_for_each_entry(dev_itr, &wusbhc->cack_list, cack_node) {
		cack_ie->blk[cnt].CDID = dev_itr->cdid;
		cack_ie->blk[cnt].bDeviceAddress = dev_itr->addr;
		if (++cnt >= WUIE_ELT_MAX)
			break;
	}
	cack_ie->hdr.bLength = sizeof(cack_ie->hdr)
		+ cnt * sizeof(cack_ie->blk[0]);
}

/*
 * Register a new device that wants to connect
 *
 * A new device wants to connect, so we add it to the Connect-Ack
 * list. We give it an address in the unauthorized range (bit 8 set);
 * user space will have to drive authorization further on.
 *
 * @dev_addr: address to use for the device (which is also the port
 *            number).
 *
 * @wusbhc->mutex must be taken
 */
static struct wusb_dev *wusbhc_cack_add(struct wusbhc *wusbhc,
					struct wusb_dn_connect *dnc,
					const char *pr_cdid, u8 port_idx)
{
	struct device *dev = wusbhc->dev;
	struct wusb_dev *wusb_dev;
	int new_connection = wusb_dn_connect_new_connection(dnc);
	u8 dev_addr;
	int result;

	/* Is it registered already? */
	list_for_each_entry(wusb_dev, &wusbhc->cack_list, cack_node)
		if (!memcmp(&wusb_dev->cdid, &dnc->CDID,
			    sizeof(wusb_dev->cdid)))
			return wusb_dev;
	/* We don't have it, create an entry, register it */
	wusb_dev = wusb_dev_alloc(wusbhc);
	if (wusb_dev == NULL)
		return NULL;
	wusb_dev_init(wusb_dev);
	wusb_dev->cdid = dnc->CDID;
	wusb_dev->port_idx = port_idx;

	/*
	 * Devices are always available within the cluster reservation
	 * and since the hardware will take the intersection of the
	 * per-device availability and the cluster reservation, the
	 * per-device availability can simply be set to always
	 * available.
	 */
	bitmap_fill(wusb_dev->availability.bm, UWB_NUM_MAS);

	/* FIXME: handle reconnects instead of assuming connects are
	   always new. */
	if (1 && new_connection == 0)
		new_connection = 1;
	if (new_connection) {
		dev_addr = (port_idx + 2) | WUSB_DEV_ADDR_UNAUTH;

		dev_info(dev, "Connecting new WUSB device to address %u, "
			"port %u\n", dev_addr, port_idx);

		result = wusb_set_dev_addr(wusbhc, wusb_dev, dev_addr);
		if (result < 0)
			return NULL;
	}
	wusb_dev->entry_ts = jiffies;
	list_add_tail(&wusb_dev->cack_node, &wusbhc->cack_list);
	wusbhc->cack_count++;
	wusbhc_fill_cack_ie(wusbhc);

	return wusb_dev;
}

/*
 * Remove a Connect-Ack context entry from the HCs view
 *
 * @wusbhc->mutex must be taken
 */
static void wusbhc_cack_rm(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
{
	list_del_init(&wusb_dev->cack_node);
	wusbhc->cack_count--;
	wusbhc_fill_cack_ie(wusbhc);
}

/*
 * @wusbhc->mutex must be taken */
static
void wusbhc_devconnect_acked(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev)
{
	wusbhc_cack_rm(wusbhc, wusb_dev);
	if (wusbhc->cack_count)
		wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
	else
		wusbhc_mmcie_rm(wusbhc, &wusbhc->cack_ie.hdr);
}

static void wusbhc_devconnect_acked_work(struct work_struct *work)
{
	struct wusb_dev *wusb_dev = container_of(work, struct wusb_dev,
						 devconnect_acked_work);
	struct wusbhc *wusbhc = wusb_dev->wusbhc;

	mutex_lock(&wusbhc->mutex);
	wusbhc_devconnect_acked(wusbhc, wusb_dev);
	mutex_unlock(&wusbhc->mutex);

	wusb_dev_put(wusb_dev);
}

/*
 * Ack a device for connection
 *
 * FIXME: docs
 *
 * @pr_cdid:	Printable CDID...hex Use @dnc->cdid for the real deal.
 *
 * So we get the connect ack IE (may have been allocated already),
 * find an empty connect block, an empty virtual port, create an
 * address with it (see below), make it an unauth addr [bit 7 set] and
 * set the MMC.
 *
 * Addresses: because WUSB hosts have no downstream hubs, we can do a
 *            1:1 mapping between 'port number' and device
 *            address. This simplifies many things, as during this
 *            initial connect phase the USB stack has no knoledge of
 *            the device and hasn't assigned an address yet--we know
 *            USB's choose_address() will use the same euristics we
 *            use here, so we can assume which address will be assigned.
 *
 *            USB stack always assigns address 1 to the root hub, so
 *            to the port number we add 2 (thus virtual port #0 is
 *            addr #2).
 *
 * @wusbhc shall be referenced
 */
static
void wusbhc_devconnect_ack(struct wusbhc *wusbhc, struct wusb_dn_connect *dnc,
			   const char *pr_cdid)
{
	int result;
	struct device *dev = wusbhc->dev;
	struct wusb_dev *wusb_dev;
	struct wusb_port *port;
	unsigned idx, devnum;

	mutex_lock(&wusbhc->mutex);

	/* Check we are not handling it already */
	for (idx = 0; idx < wusbhc->ports_max; idx++) {
		port = wusb_port_by_idx(wusbhc, idx);
		if (port->wusb_dev
		    && memcmp(&dnc->CDID, &port->wusb_dev->cdid, sizeof(dnc->CDID)) == 0)
			goto error_unlock;
	}
	/* Look up those fake ports we have for a free one */
	for (idx = 0; idx < wusbhc->ports_max; idx++) {
		port = wusb_port_by_idx(wusbhc, idx);
		if ((port->status & USB_PORT_STAT_POWER)
		    && !(port->status & USB_PORT_STAT_CONNECTION))
			break;
	}
	if (idx >= wusbhc->ports_max) {
		dev_err(dev, "Host controller can't connect more devices "
			"(%u already connected); device %s rejected\n",
			wusbhc->ports_max, pr_cdid);
		/* NOTE: we could send a WUIE_Disconnect here, but we haven't
		 *       event acked, so the device will eventually timeout the
		 *       connection, right? */
		goto error_unlock;
	}

	devnum = idx + 2;

	/* Make sure we are using no crypto on that "virtual port" */
	wusbhc->set_ptk(wusbhc, idx, 0, NULL, 0);

	/* Grab a filled in Connect-Ack context, fill out the
	 * Connect-Ack Wireless USB IE, set the MMC */
	wusb_dev = wusbhc_cack_add(wusbhc, dnc, pr_cdid, idx);
	if (wusb_dev == NULL)
		goto error_unlock;
	result = wusbhc_mmcie_set(wusbhc, 0, 0, &wusbhc->cack_ie.hdr);
	if (result < 0)
		goto error_unlock;
	/* Give the device at least 2ms (WUSB1.0[7.5.1p3]), let's do
	 * three for a good measure */
	msleep(3);
	port->wusb_dev = wusb_dev;
	port->status |= USB_PORT_STAT_CONNECTION;
	port->change |= USB_PORT_STAT_C_CONNECTION;
	/* Now the port status changed to connected; khubd will
	 * pick the change up and try to reset the port to bring it to
	 * the enabled state--so this process returns up to the stack
	 * and it calls back into wusbhc_rh_port_reset().
	 */
error_unlock:
	mutex_unlock(&wusbhc->mutex);
	return;

}

/*
 * Disconnect a Wireless USB device from its fake port
 *
 * Marks the port as disconnected so that khubd can pick up the change
 * and drops our knowledge about the device.
 *
 * Assumes there is a device connected
 *
 * @port_index: zero based port number
 *
 * NOTE: @wusbhc->mutex is locked
 *
 * WARNING: From here it is not very safe to access anything hanging off
 *	    wusb_dev
 */
static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc,
				    struct wusb_port *port)
{
	struct wusb_dev *wusb_dev = port->wusb_dev;

	port->status &= ~(USB_PORT_STAT_CONNECTION | USB_PORT_STAT_ENABLE
			  | USB_PORT_STAT_SUSPEND | USB_PORT_STAT_RESET
			  | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED);
	port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE;
	if (wusb_dev) {
		dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx);
		if (!list_empty(&wusb_dev->cack_node))
			list_del_init(&wusb_dev->cack_node);
		/* For the one in cack_add() */
		wusb_dev_put(wusb_dev);
	}
	port->wusb_dev = NULL;

	/* After a device disconnects, change the GTK (see [WUSB]
	 * section 6.2.11.2). */
	if (wusbhc->active)
		wusbhc_gtk_rekey(wusbhc);

	/* The Wireless USB part has forgotten about the device already; now
	 * khubd's timer will pick up the disconnection and remove the USB
	 * device from the system
	 */
}

/*
 * Refresh the list of keep alives to emit in the MMC
 *
 * We only publish the first four devices that have a coming timeout
 * condition. Then when we are done processing those, we go for the
 * next ones. We ignore the ones that have timed out already (they'll
 * be purged).
 *
 * This might cause the first devices to timeout the last devices in
 * the port array...FIXME: come up with a better algorithm?
 *
 * Note we can't do much about MMC's ops errors; we hope next refresh
 * will kind of handle it.
 *
 * NOTE: @wusbhc->mutex is locked
 */
static void __wusbhc_keep_alive(struct wusbhc *wusbhc)
{
	struct device *dev = wusbhc->dev;
	unsigned cnt;
	struct wusb_dev *wusb_dev;
	struct wusb_port *wusb_port;
	struct wuie_keep_alive *ie = &wusbhc->keep_alive_ie;
	unsigned keep_alives, old_keep_alives;

	old_keep_alives = ie->hdr.bLength - sizeof(ie->hdr);
	keep_alives = 0;
	for (cnt = 0;
	     keep_alives < WUIE_ELT_MAX && cnt < wusbhc->ports_max;
	     cnt++) {
		unsigned tt = msecs_to_jiffies(wusbhc->trust_timeout);

		wusb_port = wusb_port_by_idx(wusbhc, cnt);
		wusb_dev = wusb_port->wusb_dev;

		if (wusb_dev == NULL)
			continue;
		if (wusb_dev->usb_dev == NULL)
			continue;

		if (time_after(jiffies, wusb_dev->entry_ts + tt)) {
			dev_err(dev, "KEEPALIVE: device %u timed out\n",
				wusb_dev->addr);
			__wusbhc_dev_disconnect(wusbhc, wusb_port);
		} else if (time_after(jiffies, wusb_dev->entry_ts + tt/3)) {
			/* Approaching timeout cut off, need to refresh */
			ie->bDeviceAddress[keep_alives++] = wusb_dev->addr;
		}
	}
	if (keep_alives & 0x1)	/* pad to even number ([WUSB] section 7.5.9) */
		ie->bDeviceAddress[keep_alives++] = 0x7f;
	ie->hdr.bLength = sizeof(ie->hdr) +
		keep_alives*sizeof(ie->bDeviceAddress[0]);
	if (keep_alives > 0)
		wusbhc_mmcie_set(wusbhc, 10, 5, &ie->hdr);
	else if (old_keep_alives != 0)
		wusbhc_mmcie_rm(wusbhc, &ie->hdr);
}

/*
 * Do a run through all devices checking for timeouts
 */
static void wusbhc_keep_alive_run(struct work_struct *ws)
{
	struct delayed_work *dw = to_delayed_work(ws);
	struct wusbhc *wusbhc =	container_of(dw, struct wusbhc, keep_alive_timer);

	mutex_lock(&wusbhc->mutex);
	__wusbhc_keep_alive(wusbhc);
	mutex_unlock(&wusbhc->mutex);

	queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
			   msecs_to_jiffies(wusbhc->trust_timeout / 2));
}

/*
 * Find the wusb_dev from its device address.
 *
 * The device can be found directly from the address (see
 * wusb_cack_add() for where the device address is set to port_idx
 * +2), except when the address is zero.
 */
static struct wusb_dev *wusbhc_find_dev_by_addr(struct wusbhc *wusbhc, u8 addr)
{
	int p;

	if (addr == 0xff) /* unconnected */
		return NULL;

	if (addr > 0) {
		int port = (addr & ~0x80) - 2;
		if (port < 0 || port >= wusbhc->ports_max)
			return NULL;
		return wusb_port_by_idx(wusbhc, port)->wusb_dev;
	}

	/* Look for the device with address 0. */
	for (p = 0; p < wusbhc->ports_max; p++) {
		struct wusb_dev *wusb_dev = wusb_port_by_idx(wusbhc, p)->wusb_dev;
		if (wusb_dev && wusb_dev->addr == addr)
			return wusb_dev;
	}
	return NULL;
}

/*
 * Handle a DN_Alive notification (WUSB1.0[7.6.1])
 *
 * This just updates the device activity timestamp and then refreshes
 * the keep alive IE.
 *
 * @wusbhc shall be referenced and unlocked
 */
static void wusbhc_handle_dn_alive(struct wusbhc *wusbhc, u8 srcaddr)
{
	struct wusb_dev *wusb_dev;

	mutex_lock(&wusbhc->mutex);
	wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
	if (wusb_dev == NULL) {
		dev_dbg(wusbhc->dev, "ignoring DN_Alive from unconnected device %02x\n",
			srcaddr);
	} else {
		wusb_dev->entry_ts = jiffies;
		__wusbhc_keep_alive(wusbhc);
	}
	mutex_unlock(&wusbhc->mutex);
}

/*
 * Handle a DN_Connect notification (WUSB1.0[7.6.1])
 *
 * @wusbhc
 * @pkt_hdr
 * @size:    Size of the buffer where the notification resides; if the
 *           notification data suggests there should be more data than
 *           available, an error will be signaled and the whole buffer
 *           consumed.
 *
 * @wusbhc->mutex shall be held
 */
static void wusbhc_handle_dn_connect(struct wusbhc *wusbhc,
				     struct wusb_dn_hdr *dn_hdr,
				     size_t size)
{
	struct device *dev = wusbhc->dev;
	struct wusb_dn_connect *dnc;
	char pr_cdid[WUSB_CKHDID_STRSIZE];
	static const char *beacon_behaviour[] = {
		"reserved",
		"self-beacon",
		"directed-beacon",
		"no-beacon"
	};

	if (size < sizeof(*dnc)) {
		dev_err(dev, "DN CONNECT: short notification (%zu < %zu)\n",
			size, sizeof(*dnc));
		return;
	}

	dnc = container_of(dn_hdr, struct wusb_dn_connect, hdr);
	ckhdid_printf(pr_cdid, sizeof(pr_cdid), &dnc->CDID);
	dev_info(dev, "DN CONNECT: device %s @ %x (%s) wants to %s\n",
		 pr_cdid,
		 wusb_dn_connect_prev_dev_addr(dnc),
		 beacon_behaviour[wusb_dn_connect_beacon_behavior(dnc)],
		 wusb_dn_connect_new_connection(dnc) ? "connect" : "reconnect");
	/* ACK the connect */
	wusbhc_devconnect_ack(wusbhc, dnc, pr_cdid);
}

/*
 * Handle a DN_Disconnect notification (WUSB1.0[7.6.1])
 *
 * Device is going down -- do the disconnect.
 *
 * @wusbhc shall be referenced and unlocked
 */
static void wusbhc_handle_dn_disconnect(struct wusbhc *wusbhc, u8 srcaddr)
{
	struct device *dev = wusbhc->dev;
	struct wusb_dev *wusb_dev;

	mutex_lock(&wusbhc->mutex);
	wusb_dev = wusbhc_find_dev_by_addr(wusbhc, srcaddr);
	if (wusb_dev == NULL) {
		dev_dbg(dev, "ignoring DN DISCONNECT from unconnected device %02x\n",
			srcaddr);
	} else {
		dev_info(dev, "DN DISCONNECT: device 0x%02x going down\n",
			wusb_dev->addr);
		__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc,
			wusb_dev->port_idx));
	}
	mutex_unlock(&wusbhc->mutex);
}

/*
 * Handle a Device Notification coming a host
 *
 * The Device Notification comes from a host (HWA, DWA or WHCI)
 * wrapped in a set of headers. Somebody else has peeled off those
 * headers for us and we just get one Device Notifications.
 *
 * Invalid DNs (e.g., too short) are discarded.
 *
 * @wusbhc shall be referenced
 *
 * FIXMES:
 *  - implement priorities as in WUSB1.0[Table 7-55]?
 */
void wusbhc_handle_dn(struct wusbhc *wusbhc, u8 srcaddr,
		      struct wusb_dn_hdr *dn_hdr, size_t size)
{
	struct device *dev = wusbhc->dev;

	if (size < sizeof(struct wusb_dn_hdr)) {
		dev_err(dev, "DN data shorter than DN header (%d < %d)\n",
			(int)size, (int)sizeof(struct wusb_dn_hdr));
		return;
	}
	switch (dn_hdr->bType) {
	case WUSB_DN_CONNECT:
		wusbhc_handle_dn_connect(wusbhc, dn_hdr, size);
		break;
	case WUSB_DN_ALIVE:
		wusbhc_handle_dn_alive(wusbhc, srcaddr);
		break;
	case WUSB_DN_DISCONNECT:
		wusbhc_handle_dn_disconnect(wusbhc, srcaddr);
		break;
	case WUSB_DN_MASAVAILCHANGED:
	case WUSB_DN_RWAKE:
	case WUSB_DN_SLEEP:
		/* FIXME: handle these DNs. */
		break;
	case WUSB_DN_EPRDY:
		/* The hardware handles these. */
		break;
	default:
		dev_warn(dev, "unknown DN %u (%d octets) from %u\n",
			 dn_hdr->bType, (int)size, srcaddr);
	}
}
EXPORT_SYMBOL_GPL(wusbhc_handle_dn);

/*
 * Disconnect a WUSB device from a the cluster
 *
 * @wusbhc
 * @port     Fake port where the device is (wusbhc index, not USB port number).
 *
 * In Wireless USB, a disconnect is basically telling the device he is
 * being disconnected and forgetting about him.
 *
 * We send the device a Device Disconnect IE (WUSB1.0[7.5.11]) for 100
 * ms and then keep going.
 *
 * We don't do much in case of error; we always pretend we disabled
 * the port and disconnected the device. If physically the request
 * didn't get there (many things can fail in the way there), the stack
 * will reject the device's communication attempts.
 *
 * @wusbhc should be refcounted and locked
 */
void __wusbhc_dev_disable(struct wusbhc *wusbhc, u8 port_idx)
{
	int result;
	struct device *dev = wusbhc->dev;
	struct wusb_dev *wusb_dev;
	struct wuie_disconnect *ie;

	wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
	if (wusb_dev == NULL) {
		/* reset no device? ignore */
		dev_dbg(dev, "DISCONNECT: no device at port %u, ignoring\n",
			port_idx);
		return;
	}
	__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));

	ie = kzalloc(sizeof(*ie), GFP_KERNEL);
	if (ie == NULL)
		return;
	ie->hdr.bLength = sizeof(*ie);
	ie->hdr.bIEIdentifier = WUIE_ID_DEVICE_DISCONNECT;
	ie->bDeviceAddress = wusb_dev->addr;
	result = wusbhc_mmcie_set(wusbhc, 0, 0, &ie->hdr);
	if (result < 0)
		dev_err(dev, "DISCONNECT: can't set MMC: %d\n", result);
	else {
		/* At least 6 MMCs, assuming at least 1 MMC per zone. */
		msleep(7*4);
		wusbhc_mmcie_rm(wusbhc, &ie->hdr);
	}
	kfree(ie);
}

/*
 * Walk over the BOS descriptor, verify and grok it
 *
 * @usb_dev: referenced
 * @wusb_dev: referenced and unlocked
 *
 * The BOS descriptor is defined at WUSB1.0[7.4.1], and it defines a
 * "flexible" way to wrap all kinds of descriptors inside an standard
 * descriptor (wonder why they didn't use normal descriptors,
 * btw). Not like they lack code.
 *
 * At the end we go to look for the WUSB Device Capabilities
 * (WUSB1.0[7.4.1.1]) that is wrapped in a device capability descriptor
 * that is part of the BOS descriptor set. That tells us what does the
 * device support (dual role, beacon type, UWB PHY rates).
 */
static int wusb_dev_bos_grok(struct usb_device *usb_dev,
			     struct wusb_dev *wusb_dev,
			     struct usb_bos_descriptor *bos, size_t desc_size)
{
	ssize_t result;
	struct device *dev = &usb_dev->dev;
	void *itr, *top;

	/* Walk over BOS capabilities, verify them */
	itr = (void *)bos + sizeof(*bos);
	top = itr + desc_size - sizeof(*bos);
	while (itr < top) {
		struct usb_dev_cap_header *cap_hdr = itr;
		size_t cap_size;
		u8 cap_type;
		if (top - itr < sizeof(*cap_hdr)) {
			dev_err(dev, "Device BUG? premature end of BOS header "
				"data [offset 0x%02x]: only %zu bytes left\n",
				(int)(itr - (void *)bos), top - itr);
			result = -ENOSPC;
			goto error_bad_cap;
		}
		cap_size = cap_hdr->bLength;
		cap_type = cap_hdr->bDevCapabilityType;
		if (cap_size == 0)
			break;
		if (cap_size > top - itr) {
			dev_err(dev, "Device BUG? premature end of BOS data "
				"[offset 0x%02x cap %02x %zu bytes]: "
				"only %zu bytes left\n",
				(int)(itr - (void *)bos),
				cap_type, cap_size, top - itr);
			result = -EBADF;
			goto error_bad_cap;
		}
		switch (cap_type) {
		case USB_CAP_TYPE_WIRELESS_USB:
			if (cap_size != sizeof(*wusb_dev->wusb_cap_descr))
				dev_err(dev, "Device BUG? WUSB Capability "
					"descriptor is %zu bytes vs %zu "
					"needed\n", cap_size,
					sizeof(*wusb_dev->wusb_cap_descr));
			else
				wusb_dev->wusb_cap_descr = itr;
			break;
		default:
			dev_err(dev, "BUG? Unknown BOS capability 0x%02x "
				"(%zu bytes) at offset 0x%02x\n", cap_type,
				cap_size, (int)(itr - (void *)bos));
		}
		itr += cap_size;
	}
	result = 0;
error_bad_cap:
	return result;
}

/*
 * Add information from the BOS descriptors to the device
 *
 * @usb_dev: referenced
 * @wusb_dev: referenced and unlocked
 *
 * So what we do is we alloc a space for the BOS descriptor of 64
 * bytes; read the first four bytes which include the wTotalLength
 * field (WUSB1.0[T7-26]) and if it fits in those 64 bytes, read the
 * whole thing. If not we realloc to that size.
 *
 * Then we call the groking function, that will fill up
 * wusb_dev->wusb_cap_descr, which is what we'll need later on.
 */
static int wusb_dev_bos_add(struct usb_device *usb_dev,
			    struct wusb_dev *wusb_dev)
{
	ssize_t result;
	struct device *dev = &usb_dev->dev;
	struct usb_bos_descriptor *bos;
	size_t alloc_size = 32, desc_size = 4;

	bos = kmalloc(alloc_size, GFP_KERNEL);
	if (bos == NULL)
		return -ENOMEM;
	result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
	if (result < 4) {
		dev_err(dev, "Can't get BOS descriptor or too short: %zd\n",
			result);
		goto error_get_descriptor;
	}
	desc_size = le16_to_cpu(bos->wTotalLength);
	if (desc_size >= alloc_size) {
		kfree(bos);
		alloc_size = desc_size;
		bos = kmalloc(alloc_size, GFP_KERNEL);
		if (bos == NULL)
			return -ENOMEM;
	}
	result = usb_get_descriptor(usb_dev, USB_DT_BOS, 0, bos, desc_size);
	if (result < 0 || result != desc_size) {
		dev_err(dev, "Can't get  BOS descriptor or too short (need "
			"%zu bytes): %zd\n", desc_size, result);
		goto error_get_descriptor;
	}
	if (result < sizeof(*bos)
	    || le16_to_cpu(bos->wTotalLength) != desc_size) {
		dev_err(dev, "Can't get  BOS descriptor or too short (need "
			"%zu bytes): %zd\n", desc_size, result);
		goto error_get_descriptor;
	}

	result = wusb_dev_bos_grok(usb_dev, wusb_dev, bos, result);
	if (result < 0)
		goto error_bad_bos;
	wusb_dev->bos = bos;
	return 0;

error_bad_bos:
error_get_descriptor:
	kfree(bos);
	wusb_dev->wusb_cap_descr = NULL;
	return result;
}

static void wusb_dev_bos_rm(struct wusb_dev *wusb_dev)
{
	kfree(wusb_dev->bos);
	wusb_dev->wusb_cap_descr = NULL;
};

/*
 * USB stack's device addition Notifier Callback
 *
 * Called from drivers/usb/core/hub.c when a new device is added; we
 * use this hook to perform certain WUSB specific setup work on the
 * new device. As well, it is the first time we can connect the
 * wusb_dev and the usb_dev. So we note it down in wusb_dev and take a
 * reference that we'll drop.
 *
 * First we need to determine if the device is a WUSB device (else we
 * ignore it). For that we use the speed setting (USB_SPEED_WIRELESS)
 * [FIXME: maybe we'd need something more definitive]. If so, we track
 * it's usb_busd and from there, the WUSB HC.
 *
 * Because all WUSB HCs are contained in a 'struct wusbhc', voila, we
 * get the wusbhc for the device.
 *
 * We have a reference on @usb_dev (as we are called at the end of its
 * enumeration).
 *
 * NOTE: @usb_dev locked
 */
static void wusb_dev_add_ncb(struct usb_device *usb_dev)
{
	int result = 0;
	struct wusb_dev *wusb_dev;
	struct wusbhc *wusbhc;
	struct device *dev = &usb_dev->dev;
	u8 port_idx;

	if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
		return;		/* skip non wusb and wusb RHs */

	usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED);

	wusbhc = wusbhc_get_by_usb_dev(usb_dev);
	if (wusbhc == NULL)
		goto error_nodev;
	mutex_lock(&wusbhc->mutex);
	wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, usb_dev);
	port_idx = wusb_port_no_to_idx(usb_dev->portnum);
	mutex_unlock(&wusbhc->mutex);
	if (wusb_dev == NULL)
		goto error_nodev;
	wusb_dev->usb_dev = usb_get_dev(usb_dev);
	usb_dev->wusb_dev = wusb_dev_get(wusb_dev);
	result = wusb_dev_sec_add(wusbhc, usb_dev, wusb_dev);
	if (result < 0) {
		dev_err(dev, "Cannot enable security: %d\n", result);
		goto error_sec_add;
	}
	/* Now query the device for it's BOS and attach it to wusb_dev */
	result = wusb_dev_bos_add(usb_dev, wusb_dev);
	if (result < 0) {
		dev_err(dev, "Cannot get BOS descriptors: %d\n", result);
		goto error_bos_add;
	}
	result = wusb_dev_sysfs_add(wusbhc, usb_dev, wusb_dev);
	if (result < 0)
		goto error_add_sysfs;
out:
	wusb_dev_put(wusb_dev);
	wusbhc_put(wusbhc);
error_nodev:
	return;

	wusb_dev_sysfs_rm(wusb_dev);
error_add_sysfs:
	wusb_dev_bos_rm(wusb_dev);
error_bos_add:
	wusb_dev_sec_rm(wusb_dev);
error_sec_add:
	mutex_lock(&wusbhc->mutex);
	__wusbhc_dev_disconnect(wusbhc, wusb_port_by_idx(wusbhc, port_idx));
	mutex_unlock(&wusbhc->mutex);
	goto out;
}

/*
 * Undo all the steps done at connection by the notifier callback
 *
 * NOTE: @usb_dev locked
 */
static void wusb_dev_rm_ncb(struct usb_device *usb_dev)
{
	struct wusb_dev *wusb_dev = usb_dev->wusb_dev;

	if (usb_dev->wusb == 0 || usb_dev->devnum == 1)
		return;		/* skip non wusb and wusb RHs */

	wusb_dev_sysfs_rm(wusb_dev);
	wusb_dev_bos_rm(wusb_dev);
	wusb_dev_sec_rm(wusb_dev);
	wusb_dev->usb_dev = NULL;
	usb_dev->wusb_dev = NULL;
	wusb_dev_put(wusb_dev);
	usb_put_dev(usb_dev);
}

/*
 * Handle notifications from the USB stack (notifier call back)
 *
 * This is called when the USB stack does a
 * usb_{bus,device}_{add,remove}() so we can do WUSB specific
 * handling. It is called with [for the case of
 * USB_DEVICE_{ADD,REMOVE} with the usb_dev locked.
 */
int wusb_usb_ncb(struct notifier_block *nb, unsigned long val,
		 void *priv)
{
	int result = NOTIFY_OK;

	switch (val) {
	case USB_DEVICE_ADD:
		wusb_dev_add_ncb(priv);
		break;
	case USB_DEVICE_REMOVE:
		wusb_dev_rm_ncb(priv);
		break;
	case USB_BUS_ADD:
		/* ignore (for now) */
	case USB_BUS_REMOVE:
		break;
	default:
		WARN_ON(1);
		result = NOTIFY_BAD;
	}
	return result;
}

/*
 * Return a referenced wusb_dev given a @wusbhc and @usb_dev
 */
struct wusb_dev *__wusb_dev_get_by_usb_dev(struct wusbhc *wusbhc,
					   struct usb_device *usb_dev)
{
	struct wusb_dev *wusb_dev;
	u8 port_idx;

	port_idx = wusb_port_no_to_idx(usb_dev->portnum);
	BUG_ON(port_idx > wusbhc->ports_max);
	wusb_dev = wusb_port_by_idx(wusbhc, port_idx)->wusb_dev;
	if (wusb_dev != NULL)		/* ops, device is gone */
		wusb_dev_get(wusb_dev);
	return wusb_dev;
}
EXPORT_SYMBOL_GPL(__wusb_dev_get_by_usb_dev);

void wusb_dev_destroy(struct kref *_wusb_dev)
{
	struct wusb_dev *wusb_dev = container_of(_wusb_dev, struct wusb_dev, refcnt);

	list_del_init(&wusb_dev->cack_node);
	wusb_dev_free(wusb_dev);
}
EXPORT_SYMBOL_GPL(wusb_dev_destroy);

/*
 * Create all the device connect handling infrastructure
 *
 * This is basically the device info array, Connect Acknowledgement
 * (cack) lists, keep-alive timers (and delayed work thread).
 */
int wusbhc_devconnect_create(struct wusbhc *wusbhc)
{
	wusbhc->keep_alive_ie.hdr.bIEIdentifier = WUIE_ID_KEEP_ALIVE;
	wusbhc->keep_alive_ie.hdr.bLength = sizeof(wusbhc->keep_alive_ie.hdr);
	INIT_DELAYED_WORK(&wusbhc->keep_alive_timer, wusbhc_keep_alive_run);

	wusbhc->cack_ie.hdr.bIEIdentifier = WUIE_ID_CONNECTACK;
	wusbhc->cack_ie.hdr.bLength = sizeof(wusbhc->cack_ie.hdr);
	INIT_LIST_HEAD(&wusbhc->cack_list);

	return 0;
}

/*
 * Release all resources taken by the devconnect stuff
 */
void wusbhc_devconnect_destroy(struct wusbhc *wusbhc)
{
	/* no op */
}

/*
 * wusbhc_devconnect_start - start accepting device connections
 * @wusbhc: the WUSB HC
 *
 * Sets the Host Info IE to accept all new connections.
 *
 * FIXME: This also enables the keep alives but this is not necessary
 * until there are connected and authenticated devices.
 */
int wusbhc_devconnect_start(struct wusbhc *wusbhc)
{
	struct device *dev = wusbhc->dev;
	struct wuie_host_info *hi;
	int result;

	hi = kzalloc(sizeof(*hi), GFP_KERNEL);
	if (hi == NULL)
		return -ENOMEM;

	hi->hdr.bLength       = sizeof(*hi);
	hi->hdr.bIEIdentifier = WUIE_ID_HOST_INFO;
	hi->attributes        = cpu_to_le16((wusbhc->rsv->stream << 3) | WUIE_HI_CAP_ALL);
	hi->CHID              = wusbhc->chid;
	result = wusbhc_mmcie_set(wusbhc, 0, 0, &hi->hdr);
	if (result < 0) {
		dev_err(dev, "Cannot add Host Info MMCIE: %d\n", result);
		goto error_mmcie_set;
	}
	wusbhc->wuie_host_info = hi;

	queue_delayed_work(wusbd, &wusbhc->keep_alive_timer,
			   msecs_to_jiffies(wusbhc->trust_timeout / 2));

	return 0;

error_mmcie_set:
	kfree(hi);
	return result;
}

/*
 * wusbhc_devconnect_stop - stop managing connected devices
 * @wusbhc: the WUSB HC
 *
 * Disconnects any devices still connected, stops the keep alives and
 * removes the Host Info IE.
 */
void wusbhc_devconnect_stop(struct wusbhc *wusbhc)
{
	int i;

	mutex_lock(&wusbhc->mutex);
	for (i = 0; i < wusbhc->ports_max; i++) {
		if (wusbhc->port[i].wusb_dev)
			__wusbhc_dev_disconnect(wusbhc, &wusbhc->port[i]);
	}
	mutex_unlock(&wusbhc->mutex);

	cancel_delayed_work_sync(&wusbhc->keep_alive_timer);
	wusbhc_mmcie_rm(wusbhc, &wusbhc->wuie_host_info->hdr);
	kfree(wusbhc->wuie_host_info);
	wusbhc->wuie_host_info = NULL;
}

/*
 * wusb_set_dev_addr - set the WUSB device address used by the host
 * @wusbhc: the WUSB HC the device is connect to
 * @wusb_dev: the WUSB device
 * @addr: new device address
 */
int wusb_set_dev_addr(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev, u8 addr)
{
	int result;

	wusb_dev->addr = addr;
	result = wusbhc->dev_info_set(wusbhc, wusb_dev);
	if (result < 0)
		dev_err(wusbhc->dev, "device %d: failed to set device "
			"address\n", wusb_dev->port_idx);
	else
		dev_info(wusbhc->dev, "device %d: %s addr %u\n",
			 wusb_dev->port_idx,
			 (addr & WUSB_DEV_ADDR_UNAUTH) ? "unauth" : "auth",
			 wusb_dev->addr);

	return result;
}
