/*
 * Wireless USB Host Controller
 * Root Hub operations
 *
 *
 * 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.
 *
 *
 * We fake a root hub that has fake ports (as many as simultaneous
 * devices the Wireless USB Host Controller can deal with). For each
 * port we keep an state in @wusbhc->port[index] identical to the one
 * specified in the USB2.0[ch11] spec and some extra device
 * information that complements the one in 'struct usb_device' (as
 * this lacs a hcpriv pointer).
 *
 * Note this is common to WHCI and HWA host controllers.
 *
 * Through here we enable most of the state changes that the USB stack
 * will use to connect or disconnect devices. We need to do some
 * forced adaptation of Wireless USB device states vs. wired:
 *
 *        USB:                 WUSB:
 *
 * Port   Powered-off          port slot n/a
 *        Powered-on           port slot available
 *        Disconnected         port slot available
 *        Connected            port slot assigned device
 *        		       device sent DN_Connect
 *                             device was authenticated
 *        Enabled              device is authenticated, transitioned
 *                             from unauth -> auth -> default address
 *                             -> enabled
 *        Reset                disconnect
 *        Disable              disconnect
 *
 * This maps the standard USB port states with the WUSB device states
 * so we can fake ports without having to modify the USB stack.
 *
 * FIXME: this process will change in the future
 *
 *
 * ENTRY POINTS
 *
 * Our entry points into here are, as in hcd.c, the USB stack root hub
 * ops defined in the usb_hcd struct:
 *
 * wusbhc_rh_status_data()	Provide hub and port status data bitmap
 *
 * wusbhc_rh_control()          Execution of all the major requests
 *                              you can do to a hub (Set|Clear
 *                              features, get descriptors, status, etc).
 *
 * wusbhc_rh_[suspend|resume]() That
 *
 * wusbhc_rh_start_port_reset() ??? unimplemented
 */
#include "wusbhc.h"

#define D_LOCAL 0
#include <linux/uwb/debug.h>

/*
 * Reset a fake port
 *
 * This can be called to reset a port from any other state or to reset
 * it when connecting. In Wireless USB they are different; when doing
 * a new connect that involves going over the authentication. When
 * just reseting, its a different story.
 *
 * The Linux USB stack resets a port twice before it considers it
 * enabled, so we have to detect and ignore that.
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 *
 * Supposedly we are the only thread accesing @wusbhc->port; in any
 * case, maybe we should move the mutex locking from
 * wusbhc_devconnect_auth() to here.
 *
 * @port_idx refers to the wusbhc's port index, not the USB port number
 */
static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx)
{
	int result = 0;
	struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx);

	d_fnstart(3, wusbhc->dev, "(wusbhc %p port_idx %u)\n",
		  wusbhc, port_idx);
	if (port->reset_count == 0) {
		wusbhc_devconnect_auth(wusbhc, port_idx);
		port->reset_count++;
	} else if (port->reset_count == 1)
		/* see header */
		d_printf(2, wusbhc->dev, "Ignoring second reset on port_idx "
			"%u\n", port_idx);
	else
		result = wusbhc_dev_reset(wusbhc, port_idx);
	d_fnend(3, wusbhc->dev, "(wusbhc %p port_idx %u) = %d\n",
		wusbhc, port_idx, result);
	return result;
}

/*
 * Return the hub change status bitmap
 *
 * The bits in the change status bitmap are cleared when a
 * ClearPortFeature request is issued (USB2.0[11.12.3,11.12.4].
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 *
 * WARNING!! This gets called from atomic context; we cannot get the
 *           mutex--the only race condition we can find is some bit
 *           changing just after we copy it, which shouldn't be too
 *           big of a problem [and we can't make it an spinlock
 *           because other parts need to take it and sleep] .
 *
 *           @usb_hcd is refcounted, so it won't dissapear under us
 *           and before killing a host, the polling of the root hub
 *           would be stopped anyway.
 */
int wusbhc_rh_status_data(struct usb_hcd *usb_hcd, char *_buf)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	size_t cnt, size;
	unsigned long *buf = (unsigned long *) _buf;

	d_fnstart(1, wusbhc->dev, "(wusbhc %p)\n", wusbhc);
	/* WE DON'T LOCK, see comment */
	size = wusbhc->ports_max + 1 /* hub bit */;
	size = (size + 8 - 1) / 8;	/* round to bytes */
	for (cnt = 0; cnt < wusbhc->ports_max; cnt++)
		if (wusb_port_by_idx(wusbhc, cnt)->change)
			set_bit(cnt + 1, buf);
		else
			clear_bit(cnt + 1, buf);
	d_fnend(1, wusbhc->dev, "(wusbhc %p) %u, buffer:\n", wusbhc, (int)size);
	d_dump(1, wusbhc->dev, _buf, size);
	return size;
}
EXPORT_SYMBOL_GPL(wusbhc_rh_status_data);

/*
 * Return the hub's desciptor
 *
 * NOTE: almost cut and paste from ehci-hub.c
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked
 */
static int wusbhc_rh_get_hub_descr(struct wusbhc *wusbhc, u16 wValue,
				   u16 wIndex,
				   struct usb_hub_descriptor *descr,
				   u16 wLength)
{
	u16 temp = 1 + (wusbhc->ports_max / 8);
	u8 length = 7 + 2 * temp;

	if (wLength < length)
		return -ENOSPC;
	descr->bDescLength = 7 + 2 * temp;
	descr->bDescriptorType = 0x29;	/* HUB type */
	descr->bNbrPorts = wusbhc->ports_max;
	descr->wHubCharacteristics = cpu_to_le16(
		0x00			/* All ports power at once */
		| 0x00			/* not part of compound device */
		| 0x10			/* No overcurrent protection */
		| 0x00			/* 8 FS think time FIXME ?? */
		| 0x00);		/* No port indicators */
	descr->bPwrOn2PwrGood = 0;
	descr->bHubContrCurrent = 0;
	/* two bitmaps:  ports removable, and usb 1.0 legacy PortPwrCtrlMask */
	memset(&descr->bitmap[0], 0, temp);
	memset(&descr->bitmap[temp], 0xff, temp);
	return 0;
}

/*
 * Clear a hub feature
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 *
 * Nothing to do, so no locking needed ;)
 */
static int wusbhc_rh_clear_hub_feat(struct wusbhc *wusbhc, u16 feature)
{
	int result;
	struct device *dev = wusbhc->dev;

	d_fnstart(4, dev, "(%p, feature 0x%04u)\n", wusbhc, feature);
	switch (feature) {
	case C_HUB_LOCAL_POWER:
		/* FIXME: maybe plug bit 0 to the power input status,
		 * if any?
		 * see wusbhc_rh_get_hub_status() */
	case C_HUB_OVER_CURRENT:
		result = 0;
		break;
	default:
		result = -EPIPE;
	}
	d_fnend(4, dev, "(%p, feature 0x%04u), %d\n", wusbhc, feature, result);
	return result;
}

/*
 * Return hub status (it is always zero...)
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 *
 * Nothing to do, so no locking needed ;)
 */
static int wusbhc_rh_get_hub_status(struct wusbhc *wusbhc, u32 *buf,
				    u16 wLength)
{
	/* FIXME: maybe plug bit 0 to the power input status (if any)? */
	*buf = 0;
	return 0;
}

/*
 * Set a port feature
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 */
static int wusbhc_rh_set_port_feat(struct wusbhc *wusbhc, u16 feature,
				   u8 selector, u8 port_idx)
{
	int result = -EINVAL;
	struct device *dev = wusbhc->dev;

	d_fnstart(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d)\n",
		  feature, selector, port_idx);

	if (port_idx > wusbhc->ports_max)
		goto error;

	switch (feature) {
		/* According to USB2.0[11.24.2.13]p2, these features
		 * are not required to be implemented. */
	case USB_PORT_FEAT_C_OVER_CURRENT:
	case USB_PORT_FEAT_C_ENABLE:
	case USB_PORT_FEAT_C_SUSPEND:
	case USB_PORT_FEAT_C_CONNECTION:
	case USB_PORT_FEAT_C_RESET:
		result = 0;
		break;

	case USB_PORT_FEAT_POWER:
		/* No such thing, but we fake it works */
		mutex_lock(&wusbhc->mutex);
		wusb_port_by_idx(wusbhc, port_idx)->status |= USB_PORT_STAT_POWER;
		mutex_unlock(&wusbhc->mutex);
		result = 0;
		break;
	case USB_PORT_FEAT_RESET:
		result = wusbhc_rh_port_reset(wusbhc, port_idx);
		break;
	case USB_PORT_FEAT_ENABLE:
	case USB_PORT_FEAT_SUSPEND:
		dev_err(dev, "(port_idx %d) set feat %d/%d UNIMPLEMENTED\n",
			port_idx, feature, selector);
		result = -ENOSYS;
		break;
	default:
		dev_err(dev, "(port_idx %d) set feat %d/%d UNKNOWN\n",
			port_idx, feature, selector);
		result = -EPIPE;
		break;
	}
error:
	d_fnend(4, dev, "(feat 0x%04u, selector 0x%u, port_idx %d) = %d\n",
		feature, selector, port_idx, result);
	return result;
}

/*
 * Clear a port feature...
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 */
static int wusbhc_rh_clear_port_feat(struct wusbhc *wusbhc, u16 feature,
				     u8 selector, u8 port_idx)
{
	int result = -EINVAL;
	struct device *dev = wusbhc->dev;

	d_fnstart(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d)\n",
		  wusbhc, feature, selector, port_idx);

	if (port_idx > wusbhc->ports_max)
		goto error;

	mutex_lock(&wusbhc->mutex);
	result = 0;
	switch (feature) {
	case USB_PORT_FEAT_POWER:	/* fake port always on */
		/* According to USB2.0[11.24.2.7.1.4], no need to implement? */
	case USB_PORT_FEAT_C_OVER_CURRENT:
		break;
	case USB_PORT_FEAT_C_RESET:
		wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_RESET;
		break;
	case USB_PORT_FEAT_C_CONNECTION:
		wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_CONNECTION;
		break;
	case USB_PORT_FEAT_ENABLE:
		__wusbhc_dev_disable(wusbhc, port_idx);
		break;
	case USB_PORT_FEAT_C_ENABLE:
		wusb_port_by_idx(wusbhc, port_idx)->change &= ~USB_PORT_STAT_C_ENABLE;
		break;
	case USB_PORT_FEAT_SUSPEND:
	case USB_PORT_FEAT_C_SUSPEND:
	case 0xffff:		/* ??? FIXME */
		dev_err(dev, "(port_idx %d) Clear feat %d/%d UNIMPLEMENTED\n",
			port_idx, feature, selector);
		/* dump_stack(); */
		result = -ENOSYS;
		break;
	default:
		dev_err(dev, "(port_idx %d) Clear feat %d/%d UNKNOWN\n",
			port_idx, feature, selector);
		result = -EPIPE;
		break;
	}
	mutex_unlock(&wusbhc->mutex);
error:
	d_fnend(4, dev, "(wusbhc %p feat 0x%04x selector %d port_idx %d) = "
		"%d\n", wusbhc, feature, selector, port_idx, result);
	return result;
}

/*
 * Return the port's status
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 */
static int wusbhc_rh_get_port_status(struct wusbhc *wusbhc, u16 port_idx,
				     u32 *_buf, u16 wLength)
{
	int result = -EINVAL;
	u16 *buf = (u16 *) _buf;

	d_fnstart(1, wusbhc->dev, "(wusbhc %p port_idx %u wLength %u)\n",
		  wusbhc, port_idx, wLength);
	if (port_idx > wusbhc->ports_max)
		goto error;
	mutex_lock(&wusbhc->mutex);
	buf[0] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->status);
	buf[1] = cpu_to_le16(wusb_port_by_idx(wusbhc, port_idx)->change);
	result = 0;
	mutex_unlock(&wusbhc->mutex);
error:
	d_fnend(1, wusbhc->dev, "(wusbhc %p) = %d, buffer:\n", wusbhc, result);
	d_dump(1, wusbhc->dev, _buf, wLength);
	return result;
}

/*
 * Entry point for Root Hub operations
 *
 * @wusbhc is assumed referenced and @wusbhc->mutex unlocked.
 */
int wusbhc_rh_control(struct usb_hcd *usb_hcd, u16 reqntype, u16 wValue,
		      u16 wIndex, char *buf, u16 wLength)
{
	int result = -ENOSYS;
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);

	switch (reqntype) {
	case GetHubDescriptor:
		result = wusbhc_rh_get_hub_descr(
			wusbhc, wValue, wIndex,
			(struct usb_hub_descriptor *) buf, wLength);
		break;
	case ClearHubFeature:
		result = wusbhc_rh_clear_hub_feat(wusbhc, wValue);
		break;
	case GetHubStatus:
		result = wusbhc_rh_get_hub_status(wusbhc, (u32 *)buf, wLength);
		break;

	case SetPortFeature:
		result = wusbhc_rh_set_port_feat(wusbhc, wValue, wIndex >> 8,
						 (wIndex & 0xff) - 1);
		break;
	case ClearPortFeature:
		result = wusbhc_rh_clear_port_feat(wusbhc, wValue, wIndex >> 8,
						   (wIndex & 0xff) - 1);
		break;
	case GetPortStatus:
		result = wusbhc_rh_get_port_status(wusbhc, wIndex - 1,
						   (u32 *)buf, wLength);
		break;

	case SetHubFeature:
	default:
		dev_err(wusbhc->dev, "%s (%p [%p], %x, %x, %x, %p, %x) "
			"UNIMPLEMENTED\n", __func__, usb_hcd, wusbhc, reqntype,
			wValue, wIndex, buf, wLength);
		/* dump_stack(); */
		result = -ENOSYS;
	}
	return result;
}
EXPORT_SYMBOL_GPL(wusbhc_rh_control);

int wusbhc_rh_suspend(struct usb_hcd *usb_hcd)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
		usb_hcd, wusbhc);
	/* dump_stack(); */
	return -ENOSYS;
}
EXPORT_SYMBOL_GPL(wusbhc_rh_suspend);

int wusbhc_rh_resume(struct usb_hcd *usb_hcd)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	dev_err(wusbhc->dev, "%s (%p [%p]) UNIMPLEMENTED\n", __func__,
		usb_hcd, wusbhc);
	/* dump_stack(); */
	return -ENOSYS;
}
EXPORT_SYMBOL_GPL(wusbhc_rh_resume);

int wusbhc_rh_start_port_reset(struct usb_hcd *usb_hcd, unsigned port_idx)
{
	struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd);
	dev_err(wusbhc->dev, "%s (%p [%p], port_idx %u) UNIMPLEMENTED\n",
		__func__, usb_hcd, wusbhc, port_idx);
	WARN_ON(1);
	return -ENOSYS;
}
EXPORT_SYMBOL_GPL(wusbhc_rh_start_port_reset);

static void wusb_port_init(struct wusb_port *port)
{
	port->status |= USB_PORT_STAT_HIGH_SPEED;
}

/*
 * Alloc fake port specific fields and status.
 */
int wusbhc_rh_create(struct wusbhc *wusbhc)
{
	int result = -ENOMEM;
	size_t port_size, itr;
	port_size = wusbhc->ports_max * sizeof(wusbhc->port[0]);
	wusbhc->port = kzalloc(port_size, GFP_KERNEL);
	if (wusbhc->port == NULL)
		goto error_port_alloc;
	for (itr = 0; itr < wusbhc->ports_max; itr++)
		wusb_port_init(&wusbhc->port[itr]);
	result = 0;
error_port_alloc:
	return result;
}

void wusbhc_rh_destroy(struct wusbhc *wusbhc)
{
	kfree(wusbhc->port);
}
