/*
 * WUSB Wire Adapter
 * Data transfer and URB enqueing
 *
 * 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.
 *
 *
 * How transfers work: get a buffer, break it up in segments (segment
 * size is a multiple of the maxpacket size). For each segment issue a
 * segment request (struct wa_xfer_*), then send the data buffer if
 * out or nothing if in (all over the DTO endpoint).
 *
 * For each submitted segment request, a notification will come over
 * the NEP endpoint and a transfer result (struct xfer_result) will
 * arrive in the DTI URB. Read it, get the xfer ID, see if there is
 * data coming (inbound transfer), schedule a read and handle it.
 *
 * Sounds simple, it is a pain to implement.
 *
 *
 * ENTRY POINTS
 *
 *   FIXME
 *
 * LIFE CYCLE / STATE DIAGRAM
 *
 *   FIXME
 *
 * THIS CODE IS DISGUSTING
 *
 *   Warned you are; it's my second try and still not happy with it.
 *
 * NOTES:
 *
 *   - No iso
 *
 *   - Supports DMA xfers, control, bulk and maybe interrupt
 *
 *   - Does not recycle unused rpipes
 *
 *     An rpipe is assigned to an endpoint the first time it is used,
 *     and then it's there, assigned, until the endpoint is disabled
 *     (destroyed [{h,d}wahc_op_ep_disable()]. The assignment of the
 *     rpipe to the endpoint is done under the wa->rpipe_sem semaphore
 *     (should be a mutex).
 *
 *     Two methods it could be done:
 *
 *     (a) set up a timer every time an rpipe's use count drops to 1
 *         (which means unused) or when a transfer ends. Reset the
 *         timer when a xfer is queued. If the timer expires, release
 *         the rpipe [see rpipe_ep_disable()].
 *
 *     (b) when looking for free rpipes to attach [rpipe_get_by_ep()],
 *         when none are found go over the list, check their endpoint
 *         and their activity record (if no last-xfer-done-ts in the
 *         last x seconds) take it
 *
 *     However, due to the fact that we have a set of limited
 *     resources (max-segments-at-the-same-time per xfer,
 *     xfers-per-ripe, blocks-per-rpipe, rpipes-per-host), at the end
 *     we are going to have to rebuild all this based on an scheduler,
 *     to where we have a list of transactions to do and based on the
 *     availability of the different required components (blocks,
 *     rpipes, segment slots, etc), we go scheduling them. Painful.
 */
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/hash.h>
#include <linux/ratelimit.h>
#include <linux/export.h>
#include <linux/scatterlist.h>

#include "wa-hc.h"
#include "wusbhc.h"

enum {
	/* [WUSB] section 8.3.3 allocates 7 bits for the segment index. */
	WA_SEGS_MAX = 128,
};

enum wa_seg_status {
	WA_SEG_NOTREADY,
	WA_SEG_READY,
	WA_SEG_DELAYED,
	WA_SEG_SUBMITTED,
	WA_SEG_PENDING,
	WA_SEG_DTI_PENDING,
	WA_SEG_DONE,
	WA_SEG_ERROR,
	WA_SEG_ABORTED,
};

static void wa_xfer_delayed_run(struct wa_rpipe *);
static int __wa_xfer_delayed_run(struct wa_rpipe *rpipe, int *dto_waiting);

/*
 * Life cycle governed by 'struct urb' (the refcount of the struct is
 * that of the 'struct urb' and usb_free_urb() would free the whole
 * struct).
 */
struct wa_seg {
	struct urb tr_urb;		/* transfer request urb. */
	struct urb *isoc_pack_desc_urb;	/* for isoc packet descriptor. */
	struct urb *dto_urb;		/* for data output. */
	struct list_head list_node;	/* for rpipe->req_list */
	struct wa_xfer *xfer;		/* out xfer */
	u8 index;			/* which segment we are */
	int isoc_frame_count;	/* number of isoc frames in this segment. */
	int isoc_frame_offset;	/* starting frame offset in the xfer URB. */
	/* Isoc frame that the current transfer buffer corresponds to. */
	int isoc_frame_index;
	int isoc_size;	/* size of all isoc frames sent by this seg. */
	enum wa_seg_status status;
	ssize_t result;			/* bytes xfered or error */
	struct wa_xfer_hdr xfer_hdr;
};

static inline void wa_seg_init(struct wa_seg *seg)
{
	usb_init_urb(&seg->tr_urb);

	/* set the remaining memory to 0. */
	memset(((void *)seg) + sizeof(seg->tr_urb), 0,
		sizeof(*seg) - sizeof(seg->tr_urb));
}

/*
 * Protected by xfer->lock
 *
 */
struct wa_xfer {
	struct kref refcnt;
	struct list_head list_node;
	spinlock_t lock;
	u32 id;

	struct wahc *wa;		/* Wire adapter we are plugged to */
	struct usb_host_endpoint *ep;
	struct urb *urb;		/* URB we are transferring for */
	struct wa_seg **seg;		/* transfer segments */
	u8 segs, segs_submitted, segs_done;
	unsigned is_inbound:1;
	unsigned is_dma:1;
	size_t seg_size;
	int result;

	gfp_t gfp;			/* allocation mask */

	struct wusb_dev *wusb_dev;	/* for activity timestamps */
};

static void __wa_populate_dto_urb_isoc(struct wa_xfer *xfer,
	struct wa_seg *seg, int curr_iso_frame);
static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer,
		int starting_index, enum wa_seg_status status);

static inline void wa_xfer_init(struct wa_xfer *xfer)
{
	kref_init(&xfer->refcnt);
	INIT_LIST_HEAD(&xfer->list_node);
	spin_lock_init(&xfer->lock);
}

/*
 * Destroy a transfer structure
 *
 * Note that freeing xfer->seg[cnt]->tr_urb will free the containing
 * xfer->seg[cnt] memory that was allocated by __wa_xfer_setup_segs.
 */
static void wa_xfer_destroy(struct kref *_xfer)
{
	struct wa_xfer *xfer = container_of(_xfer, struct wa_xfer, refcnt);
	if (xfer->seg) {
		unsigned cnt;
		for (cnt = 0; cnt < xfer->segs; cnt++) {
			struct wa_seg *seg = xfer->seg[cnt];
			if (seg) {
				usb_free_urb(seg->isoc_pack_desc_urb);
				if (seg->dto_urb) {
					kfree(seg->dto_urb->sg);
					usb_free_urb(seg->dto_urb);
				}
				usb_free_urb(&seg->tr_urb);
			}
		}
		kfree(xfer->seg);
	}
	kfree(xfer);
}

static void wa_xfer_get(struct wa_xfer *xfer)
{
	kref_get(&xfer->refcnt);
}

static void wa_xfer_put(struct wa_xfer *xfer)
{
	kref_put(&xfer->refcnt, wa_xfer_destroy);
}

/*
 * Try to get exclusive access to the DTO endpoint resource.  Return true
 * if successful.
 */
static inline int __wa_dto_try_get(struct wahc *wa)
{
	return (test_and_set_bit(0, &wa->dto_in_use) == 0);
}

/* Release the DTO endpoint resource. */
static inline void __wa_dto_put(struct wahc *wa)
{
	clear_bit_unlock(0, &wa->dto_in_use);
}

/* Service RPIPEs that are waiting on the DTO resource. */
static void wa_check_for_delayed_rpipes(struct wahc *wa)
{
	unsigned long flags;
	int dto_waiting = 0;
	struct wa_rpipe *rpipe;

	spin_lock_irqsave(&wa->rpipe_lock, flags);
	while (!list_empty(&wa->rpipe_delayed_list) && !dto_waiting) {
		rpipe = list_first_entry(&wa->rpipe_delayed_list,
				struct wa_rpipe, list_node);
		__wa_xfer_delayed_run(rpipe, &dto_waiting);
		/* remove this RPIPE from the list if it is not waiting. */
		if (!dto_waiting) {
			pr_debug("%s: RPIPE %d serviced and removed from delayed list.\n",
				__func__,
				le16_to_cpu(rpipe->descr.wRPipeIndex));
			list_del_init(&rpipe->list_node);
		}
	}
	spin_unlock_irqrestore(&wa->rpipe_lock, flags);
}

/* add this RPIPE to the end of the delayed RPIPE list. */
static void wa_add_delayed_rpipe(struct wahc *wa, struct wa_rpipe *rpipe)
{
	unsigned long flags;

	spin_lock_irqsave(&wa->rpipe_lock, flags);
	/* add rpipe to the list if it is not already on it. */
	if (list_empty(&rpipe->list_node)) {
		pr_debug("%s: adding RPIPE %d to the delayed list.\n",
			__func__, le16_to_cpu(rpipe->descr.wRPipeIndex));
		list_add_tail(&rpipe->list_node, &wa->rpipe_delayed_list);
	}
	spin_unlock_irqrestore(&wa->rpipe_lock, flags);
}

/*
 * xfer is referenced
 *
 * xfer->lock has to be unlocked
 *
 * We take xfer->lock for setting the result; this is a barrier
 * against drivers/usb/core/hcd.c:unlink1() being called after we call
 * usb_hcd_giveback_urb() and wa_urb_dequeue() trying to get a
 * reference to the transfer.
 */
static void wa_xfer_giveback(struct wa_xfer *xfer)
{
	unsigned long flags;

	spin_lock_irqsave(&xfer->wa->xfer_list_lock, flags);
	list_del_init(&xfer->list_node);
	usb_hcd_unlink_urb_from_ep(&(xfer->wa->wusb->usb_hcd), xfer->urb);
	spin_unlock_irqrestore(&xfer->wa->xfer_list_lock, flags);
	/* FIXME: segmentation broken -- kills DWA */
	wusbhc_giveback_urb(xfer->wa->wusb, xfer->urb, xfer->result);
	wa_put(xfer->wa);
	wa_xfer_put(xfer);
}

/*
 * xfer is referenced
 *
 * xfer->lock has to be unlocked
 */
static void wa_xfer_completion(struct wa_xfer *xfer)
{
	if (xfer->wusb_dev)
		wusb_dev_put(xfer->wusb_dev);
	rpipe_put(xfer->ep->hcpriv);
	wa_xfer_giveback(xfer);
}

/*
 * Initialize a transfer's ID
 *
 * We need to use a sequential number; if we use the pointer or the
 * hash of the pointer, it can repeat over sequential transfers and
 * then it will confuse the HWA....wonder why in hell they put a 32
 * bit handle in there then.
 */
static void wa_xfer_id_init(struct wa_xfer *xfer)
{
	xfer->id = atomic_add_return(1, &xfer->wa->xfer_id_count);
}

/* Return the xfer's ID. */
static inline u32 wa_xfer_id(struct wa_xfer *xfer)
{
	return xfer->id;
}

/* Return the xfer's ID in transport format (little endian). */
static inline __le32 wa_xfer_id_le32(struct wa_xfer *xfer)
{
	return cpu_to_le32(xfer->id);
}

/*
 * If transfer is done, wrap it up and return true
 *
 * xfer->lock has to be locked
 */
static unsigned __wa_xfer_is_done(struct wa_xfer *xfer)
{
	struct device *dev = &xfer->wa->usb_iface->dev;
	unsigned result, cnt;
	struct wa_seg *seg;
	struct urb *urb = xfer->urb;
	unsigned found_short = 0;

	result = xfer->segs_done == xfer->segs_submitted;
	if (result == 0)
		goto out;
	urb->actual_length = 0;
	for (cnt = 0; cnt < xfer->segs; cnt++) {
		seg = xfer->seg[cnt];
		switch (seg->status) {
		case WA_SEG_DONE:
			if (found_short && seg->result > 0) {
				dev_dbg(dev, "xfer %p ID %08X#%u: bad short segments (%zu)\n",
					xfer, wa_xfer_id(xfer), cnt,
					seg->result);
				urb->status = -EINVAL;
				goto out;
			}
			urb->actual_length += seg->result;
			if (!(usb_pipeisoc(xfer->urb->pipe))
				&& seg->result < xfer->seg_size
			    && cnt != xfer->segs-1)
				found_short = 1;
			dev_dbg(dev, "xfer %p ID %08X#%u: DONE short %d "
				"result %zu urb->actual_length %d\n",
				xfer, wa_xfer_id(xfer), seg->index, found_short,
				seg->result, urb->actual_length);
			break;
		case WA_SEG_ERROR:
			xfer->result = seg->result;
			dev_dbg(dev, "xfer %p ID %08X#%u: ERROR result %zi(0x%08zX)\n",
				xfer, wa_xfer_id(xfer), seg->index, seg->result,
				seg->result);
			goto out;
		case WA_SEG_ABORTED:
			xfer->result = seg->result;
			dev_dbg(dev, "xfer %p ID %08X#%u: ABORTED result %zi(0x%08zX)\n",
				xfer, wa_xfer_id(xfer), seg->index, seg->result,
				seg->result);
			goto out;
		default:
			dev_warn(dev, "xfer %p ID %08X#%u: is_done bad state %d\n",
				 xfer, wa_xfer_id(xfer), cnt, seg->status);
			xfer->result = -EINVAL;
			goto out;
		}
	}
	xfer->result = 0;
out:
	return result;
}

/*
 * Mark the given segment as done.  Return true if this completes the xfer.
 * This should only be called for segs that have been submitted to an RPIPE.
 * Delayed segs are not marked as submitted so they do not need to be marked
 * as done when cleaning up.
 *
 * xfer->lock has to be locked
 */
static unsigned __wa_xfer_mark_seg_as_done(struct wa_xfer *xfer,
	struct wa_seg *seg, enum wa_seg_status status)
{
	seg->status = status;
	xfer->segs_done++;

	/* check for done. */
	return __wa_xfer_is_done(xfer);
}

/*
 * Search for a transfer list ID on the HCD's URB list
 *
 * For 32 bit architectures, we use the pointer itself; for 64 bits, a
 * 32-bit hash of the pointer.
 *
 * @returns NULL if not found.
 */
static struct wa_xfer *wa_xfer_get_by_id(struct wahc *wa, u32 id)
{
	unsigned long flags;
	struct wa_xfer *xfer_itr;
	spin_lock_irqsave(&wa->xfer_list_lock, flags);
	list_for_each_entry(xfer_itr, &wa->xfer_list, list_node) {
		if (id == xfer_itr->id) {
			wa_xfer_get(xfer_itr);
			goto out;
		}
	}
	xfer_itr = NULL;
out:
	spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
	return xfer_itr;
}

struct wa_xfer_abort_buffer {
	struct urb urb;
	struct wahc *wa;
	struct wa_xfer_abort cmd;
};

static void __wa_xfer_abort_cb(struct urb *urb)
{
	struct wa_xfer_abort_buffer *b = urb->context;
	struct wahc *wa = b->wa;

	/*
	 * If the abort request URB failed, then the HWA did not get the abort
	 * command.  Forcibly clean up the xfer without waiting for a Transfer
	 * Result from the HWA.
	 */
	if (urb->status < 0) {
		struct wa_xfer *xfer;
		struct device *dev = &wa->usb_iface->dev;

		xfer = wa_xfer_get_by_id(wa, le32_to_cpu(b->cmd.dwTransferID));
		dev_err(dev, "%s: Transfer Abort request failed. result: %d\n",
			__func__, urb->status);
		if (xfer) {
			unsigned long flags;
			int done;
			struct wa_rpipe *rpipe = xfer->ep->hcpriv;

			dev_err(dev, "%s: cleaning up xfer %p ID 0x%08X.\n",
				__func__, xfer, wa_xfer_id(xfer));
			spin_lock_irqsave(&xfer->lock, flags);
			/* mark all segs as aborted. */
			wa_complete_remaining_xfer_segs(xfer, 0,
				WA_SEG_ABORTED);
			done = __wa_xfer_is_done(xfer);
			spin_unlock_irqrestore(&xfer->lock, flags);
			if (done)
				wa_xfer_completion(xfer);
			wa_xfer_delayed_run(rpipe);
			wa_xfer_put(xfer);
		} else {
			dev_err(dev, "%s: xfer ID 0x%08X already gone.\n",
				 __func__, le32_to_cpu(b->cmd.dwTransferID));
		}
	}

	wa_put(wa);	/* taken in __wa_xfer_abort */
	usb_put_urb(&b->urb);
}

/*
 * Aborts an ongoing transaction
 *
 * Assumes the transfer is referenced and locked and in a submitted
 * state (mainly that there is an endpoint/rpipe assigned).
 *
 * The callback (see above) does nothing but freeing up the data by
 * putting the URB. Because the URB is allocated at the head of the
 * struct, the whole space we allocated is kfreed. *
 */
static int __wa_xfer_abort(struct wa_xfer *xfer)
{
	int result = -ENOMEM;
	struct device *dev = &xfer->wa->usb_iface->dev;
	struct wa_xfer_abort_buffer *b;
	struct wa_rpipe *rpipe = xfer->ep->hcpriv;

	b = kmalloc(sizeof(*b), GFP_ATOMIC);
	if (b == NULL)
		goto error_kmalloc;
	b->cmd.bLength =  sizeof(b->cmd);
	b->cmd.bRequestType = WA_XFER_ABORT;
	b->cmd.wRPipe = rpipe->descr.wRPipeIndex;
	b->cmd.dwTransferID = wa_xfer_id_le32(xfer);
	b->wa = wa_get(xfer->wa);

	usb_init_urb(&b->urb);
	usb_fill_bulk_urb(&b->urb, xfer->wa->usb_dev,
		usb_sndbulkpipe(xfer->wa->usb_dev,
				xfer->wa->dto_epd->bEndpointAddress),
		&b->cmd, sizeof(b->cmd), __wa_xfer_abort_cb, b);
	result = usb_submit_urb(&b->urb, GFP_ATOMIC);
	if (result < 0)
		goto error_submit;
	return result;				/* callback frees! */


error_submit:
	wa_put(xfer->wa);
	if (printk_ratelimit())
		dev_err(dev, "xfer %p: Can't submit abort request: %d\n",
			xfer, result);
	kfree(b);
error_kmalloc:
	return result;

}

/*
 * Calculate the number of isoc frames starting from isoc_frame_offset
 * that will fit a in transfer segment.
 */
static int __wa_seg_calculate_isoc_frame_count(struct wa_xfer *xfer,
	int isoc_frame_offset, int *total_size)
{
	int segment_size = 0, frame_count = 0;
	int index = isoc_frame_offset;
	struct usb_iso_packet_descriptor *iso_frame_desc =
		xfer->urb->iso_frame_desc;

	while ((index < xfer->urb->number_of_packets)
		&& ((segment_size + iso_frame_desc[index].length)
				<= xfer->seg_size)) {
		/*
		 * For Alereon HWA devices, only include an isoc frame in an
		 * out segment if it is physically contiguous with the previous
		 * frame.  This is required because those devices expect
		 * the isoc frames to be sent as a single USB transaction as
		 * opposed to one transaction per frame with standard HWA.
		 */
		if ((xfer->wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC)
			&& (xfer->is_inbound == 0)
			&& (index > isoc_frame_offset)
			&& ((iso_frame_desc[index - 1].offset +
				iso_frame_desc[index - 1].length) !=
				iso_frame_desc[index].offset))
			break;

		/* this frame fits. count it. */
		++frame_count;
		segment_size += iso_frame_desc[index].length;

		/* move to the next isoc frame. */
		++index;
	}

	*total_size = segment_size;
	return frame_count;
}

/*
 *
 * @returns < 0 on error, transfer segment request size if ok
 */
static ssize_t __wa_xfer_setup_sizes(struct wa_xfer *xfer,
				     enum wa_xfer_type *pxfer_type)
{
	ssize_t result;
	struct device *dev = &xfer->wa->usb_iface->dev;
	size_t maxpktsize;
	struct urb *urb = xfer->urb;
	struct wa_rpipe *rpipe = xfer->ep->hcpriv;

	switch (rpipe->descr.bmAttribute & 0x3) {
	case USB_ENDPOINT_XFER_CONTROL:
		*pxfer_type = WA_XFER_TYPE_CTL;
		result = sizeof(struct wa_xfer_ctl);
		break;
	case USB_ENDPOINT_XFER_INT:
	case USB_ENDPOINT_XFER_BULK:
		*pxfer_type = WA_XFER_TYPE_BI;
		result = sizeof(struct wa_xfer_bi);
		break;
	case USB_ENDPOINT_XFER_ISOC:
		*pxfer_type = WA_XFER_TYPE_ISO;
		result = sizeof(struct wa_xfer_hwaiso);
		break;
	default:
		/* never happens */
		BUG();
		result = -EINVAL;	/* shut gcc up */
	}
	xfer->is_inbound = urb->pipe & USB_DIR_IN ? 1 : 0;
	xfer->is_dma = urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? 1 : 0;

	maxpktsize = le16_to_cpu(rpipe->descr.wMaxPacketSize);
	xfer->seg_size = le16_to_cpu(rpipe->descr.wBlocks)
		* 1 << (xfer->wa->wa_descr->bRPipeBlockSize - 1);
	/* Compute the segment size and make sure it is a multiple of
	 * the maxpktsize (WUSB1.0[8.3.3.1])...not really too much of
	 * a check (FIXME) */
	if (xfer->seg_size < maxpktsize) {
		dev_err(dev,
			"HW BUG? seg_size %zu smaller than maxpktsize %zu\n",
			xfer->seg_size, maxpktsize);
		result = -EINVAL;
		goto error;
	}
	xfer->seg_size = (xfer->seg_size / maxpktsize) * maxpktsize;
	if ((rpipe->descr.bmAttribute & 0x3) == USB_ENDPOINT_XFER_ISOC) {
		int index = 0;

		xfer->segs = 0;
		/*
		 * loop over urb->number_of_packets to determine how many
		 * xfer segments will be needed to send the isoc frames.
		 */
		while (index < urb->number_of_packets) {
			int seg_size; /* don't care. */
			index += __wa_seg_calculate_isoc_frame_count(xfer,
					index, &seg_size);
			++xfer->segs;
		}
	} else {
		xfer->segs = DIV_ROUND_UP(urb->transfer_buffer_length,
						xfer->seg_size);
		if (xfer->segs == 0 && *pxfer_type == WA_XFER_TYPE_CTL)
			xfer->segs = 1;
	}

	if (xfer->segs > WA_SEGS_MAX) {
		dev_err(dev, "BUG? oops, number of segments %zu bigger than %d\n",
			(urb->transfer_buffer_length/xfer->seg_size),
			WA_SEGS_MAX);
		result = -EINVAL;
		goto error;
	}
error:
	return result;
}

static void __wa_setup_isoc_packet_descr(
		struct wa_xfer_packet_info_hwaiso *packet_desc,
		struct wa_xfer *xfer,
		struct wa_seg *seg) {
	struct usb_iso_packet_descriptor *iso_frame_desc =
		xfer->urb->iso_frame_desc;
	int frame_index;

	/* populate isoc packet descriptor. */
	packet_desc->bPacketType = WA_XFER_ISO_PACKET_INFO;
	packet_desc->wLength = cpu_to_le16(sizeof(*packet_desc) +
		(sizeof(packet_desc->PacketLength[0]) *
			seg->isoc_frame_count));
	for (frame_index = 0; frame_index < seg->isoc_frame_count;
		++frame_index) {
		int offset_index = frame_index + seg->isoc_frame_offset;
		packet_desc->PacketLength[frame_index] =
			cpu_to_le16(iso_frame_desc[offset_index].length);
	}
}


/* Fill in the common request header and xfer-type specific data. */
static void __wa_xfer_setup_hdr0(struct wa_xfer *xfer,
				 struct wa_xfer_hdr *xfer_hdr0,
				 enum wa_xfer_type xfer_type,
				 size_t xfer_hdr_size)
{
	struct wa_rpipe *rpipe = xfer->ep->hcpriv;
	struct wa_seg *seg = xfer->seg[0];

	xfer_hdr0 = &seg->xfer_hdr;
	xfer_hdr0->bLength = xfer_hdr_size;
	xfer_hdr0->bRequestType = xfer_type;
	xfer_hdr0->wRPipe = rpipe->descr.wRPipeIndex;
	xfer_hdr0->dwTransferID = wa_xfer_id_le32(xfer);
	xfer_hdr0->bTransferSegment = 0;
	switch (xfer_type) {
	case WA_XFER_TYPE_CTL: {
		struct wa_xfer_ctl *xfer_ctl =
			container_of(xfer_hdr0, struct wa_xfer_ctl, hdr);
		xfer_ctl->bmAttribute = xfer->is_inbound ? 1 : 0;
		memcpy(&xfer_ctl->baSetupData, xfer->urb->setup_packet,
		       sizeof(xfer_ctl->baSetupData));
		break;
	}
	case WA_XFER_TYPE_BI:
		break;
	case WA_XFER_TYPE_ISO: {
		struct wa_xfer_hwaiso *xfer_iso =
			container_of(xfer_hdr0, struct wa_xfer_hwaiso, hdr);
		struct wa_xfer_packet_info_hwaiso *packet_desc =
			((void *)xfer_iso) + xfer_hdr_size;

		/* populate the isoc section of the transfer request. */
		xfer_iso->dwNumOfPackets = cpu_to_le32(seg->isoc_frame_count);
		/* populate isoc packet descriptor. */
		__wa_setup_isoc_packet_descr(packet_desc, xfer, seg);
		break;
	}
	default:
		BUG();
	};
}

/*
 * Callback for the OUT data phase of the segment request
 *
 * Check wa_seg_tr_cb(); most comments also apply here because this
 * function does almost the same thing and they work closely
 * together.
 *
 * If the seg request has failed but this DTO phase has succeeded,
 * wa_seg_tr_cb() has already failed the segment and moved the
 * status to WA_SEG_ERROR, so this will go through 'case 0' and
 * effectively do nothing.
 */
static void wa_seg_dto_cb(struct urb *urb)
{
	struct wa_seg *seg = urb->context;
	struct wa_xfer *xfer = seg->xfer;
	struct wahc *wa;
	struct device *dev;
	struct wa_rpipe *rpipe;
	unsigned long flags;
	unsigned rpipe_ready = 0;
	int data_send_done = 1, release_dto = 0, holding_dto = 0;
	u8 done = 0;
	int result;

	/* free the sg if it was used. */
	kfree(urb->sg);
	urb->sg = NULL;

	spin_lock_irqsave(&xfer->lock, flags);
	wa = xfer->wa;
	dev = &wa->usb_iface->dev;
	if (usb_pipeisoc(xfer->urb->pipe)) {
		/* Alereon HWA sends all isoc frames in a single transfer. */
		if (wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC)
			seg->isoc_frame_index += seg->isoc_frame_count;
		else
			seg->isoc_frame_index += 1;
		if (seg->isoc_frame_index < seg->isoc_frame_count) {
			data_send_done = 0;
			holding_dto = 1; /* checked in error cases. */
			/*
			 * if this is the last isoc frame of the segment, we
			 * can release DTO after sending this frame.
			 */
			if ((seg->isoc_frame_index + 1) >=
				seg->isoc_frame_count)
				release_dto = 1;
		}
		dev_dbg(dev, "xfer 0x%08X#%u: isoc frame = %d, holding_dto = %d, release_dto = %d.\n",
			wa_xfer_id(xfer), seg->index, seg->isoc_frame_index,
			holding_dto, release_dto);
	}
	spin_unlock_irqrestore(&xfer->lock, flags);

	switch (urb->status) {
	case 0:
		spin_lock_irqsave(&xfer->lock, flags);
		seg->result += urb->actual_length;
		if (data_send_done) {
			dev_dbg(dev, "xfer 0x%08X#%u: data out done (%zu bytes)\n",
				wa_xfer_id(xfer), seg->index, seg->result);
			if (seg->status < WA_SEG_PENDING)
				seg->status = WA_SEG_PENDING;
		} else {
			/* should only hit this for isoc xfers. */
			/*
			 * Populate the dto URB with the next isoc frame buffer,
			 * send the URB and release DTO if we no longer need it.
			 */
			 __wa_populate_dto_urb_isoc(xfer, seg,
				seg->isoc_frame_offset + seg->isoc_frame_index);

			/* resubmit the URB with the next isoc frame. */
			/* take a ref on resubmit. */
			wa_xfer_get(xfer);
			result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC);
			if (result < 0) {
				dev_err(dev, "xfer 0x%08X#%u: DTO submit failed: %d\n",
				       wa_xfer_id(xfer), seg->index, result);
				spin_unlock_irqrestore(&xfer->lock, flags);
				goto error_dto_submit;
			}
		}
		spin_unlock_irqrestore(&xfer->lock, flags);
		if (release_dto) {
			__wa_dto_put(wa);
			wa_check_for_delayed_rpipes(wa);
		}
		break;
	case -ECONNRESET:	/* URB unlinked; no need to do anything */
	case -ENOENT:		/* as it was done by the who unlinked us */
		if (holding_dto) {
			__wa_dto_put(wa);
			wa_check_for_delayed_rpipes(wa);
		}
		break;
	default:		/* Other errors ... */
		dev_err(dev, "xfer 0x%08X#%u: data out error %d\n",
			wa_xfer_id(xfer), seg->index, urb->status);
		goto error_default;
	}

	/* taken when this URB was submitted. */
	wa_xfer_put(xfer);
	return;

error_dto_submit:
	/* taken on resubmit attempt. */
	wa_xfer_put(xfer);
error_default:
	spin_lock_irqsave(&xfer->lock, flags);
	rpipe = xfer->ep->hcpriv;
	if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
		    EDC_ERROR_TIMEFRAME)){
		dev_err(dev, "DTO: URB max acceptable errors exceeded, resetting device\n");
		wa_reset_all(wa);
	}
	if (seg->status != WA_SEG_ERROR) {
		seg->result = urb->status;
		__wa_xfer_abort(xfer);
		rpipe_ready = rpipe_avail_inc(rpipe);
		done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR);
	}
	spin_unlock_irqrestore(&xfer->lock, flags);
	if (holding_dto) {
		__wa_dto_put(wa);
		wa_check_for_delayed_rpipes(wa);
	}
	if (done)
		wa_xfer_completion(xfer);
	if (rpipe_ready)
		wa_xfer_delayed_run(rpipe);
	/* taken when this URB was submitted. */
	wa_xfer_put(xfer);
}

/*
 * Callback for the isoc packet descriptor phase of the segment request
 *
 * Check wa_seg_tr_cb(); most comments also apply here because this
 * function does almost the same thing and they work closely
 * together.
 *
 * If the seg request has failed but this phase has succeeded,
 * wa_seg_tr_cb() has already failed the segment and moved the
 * status to WA_SEG_ERROR, so this will go through 'case 0' and
 * effectively do nothing.
 */
static void wa_seg_iso_pack_desc_cb(struct urb *urb)
{
	struct wa_seg *seg = urb->context;
	struct wa_xfer *xfer = seg->xfer;
	struct wahc *wa;
	struct device *dev;
	struct wa_rpipe *rpipe;
	unsigned long flags;
	unsigned rpipe_ready = 0;
	u8 done = 0;

	switch (urb->status) {
	case 0:
		spin_lock_irqsave(&xfer->lock, flags);
		wa = xfer->wa;
		dev = &wa->usb_iface->dev;
		dev_dbg(dev, "iso xfer %08X#%u: packet descriptor done\n",
			wa_xfer_id(xfer), seg->index);
		if (xfer->is_inbound && seg->status < WA_SEG_PENDING)
			seg->status = WA_SEG_PENDING;
		spin_unlock_irqrestore(&xfer->lock, flags);
		break;
	case -ECONNRESET:	/* URB unlinked; no need to do anything */
	case -ENOENT:		/* as it was done by the who unlinked us */
		break;
	default:		/* Other errors ... */
		spin_lock_irqsave(&xfer->lock, flags);
		wa = xfer->wa;
		dev = &wa->usb_iface->dev;
		rpipe = xfer->ep->hcpriv;
		pr_err_ratelimited("iso xfer %08X#%u: packet descriptor error %d\n",
				wa_xfer_id(xfer), seg->index, urb->status);
		if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
			    EDC_ERROR_TIMEFRAME)){
			dev_err(dev, "iso xfer: URB max acceptable errors exceeded, resetting device\n");
			wa_reset_all(wa);
		}
		if (seg->status != WA_SEG_ERROR) {
			usb_unlink_urb(seg->dto_urb);
			seg->result = urb->status;
			__wa_xfer_abort(xfer);
			rpipe_ready = rpipe_avail_inc(rpipe);
			done = __wa_xfer_mark_seg_as_done(xfer, seg,
					WA_SEG_ERROR);
		}
		spin_unlock_irqrestore(&xfer->lock, flags);
		if (done)
			wa_xfer_completion(xfer);
		if (rpipe_ready)
			wa_xfer_delayed_run(rpipe);
	}
	/* taken when this URB was submitted. */
	wa_xfer_put(xfer);
}

/*
 * Callback for the segment request
 *
 * If successful transition state (unless already transitioned or
 * outbound transfer); otherwise, take a note of the error, mark this
 * segment done and try completion.
 *
 * Note we don't access until we are sure that the transfer hasn't
 * been cancelled (ECONNRESET, ENOENT), which could mean that
 * seg->xfer could be already gone.
 *
 * We have to check before setting the status to WA_SEG_PENDING
 * because sometimes the xfer result callback arrives before this
 * callback (geeeeeeze), so it might happen that we are already in
 * another state. As well, we don't set it if the transfer is not inbound,
 * as in that case, wa_seg_dto_cb will do it when the OUT data phase
 * finishes.
 */
static void wa_seg_tr_cb(struct urb *urb)
{
	struct wa_seg *seg = urb->context;
	struct wa_xfer *xfer = seg->xfer;
	struct wahc *wa;
	struct device *dev;
	struct wa_rpipe *rpipe;
	unsigned long flags;
	unsigned rpipe_ready;
	u8 done = 0;

	switch (urb->status) {
	case 0:
		spin_lock_irqsave(&xfer->lock, flags);
		wa = xfer->wa;
		dev = &wa->usb_iface->dev;
		dev_dbg(dev, "xfer %p ID 0x%08X#%u: request done\n",
			xfer, wa_xfer_id(xfer), seg->index);
		if (xfer->is_inbound &&
			seg->status < WA_SEG_PENDING &&
			!(usb_pipeisoc(xfer->urb->pipe)))
			seg->status = WA_SEG_PENDING;
		spin_unlock_irqrestore(&xfer->lock, flags);
		break;
	case -ECONNRESET:	/* URB unlinked; no need to do anything */
	case -ENOENT:		/* as it was done by the who unlinked us */
		break;
	default:		/* Other errors ... */
		spin_lock_irqsave(&xfer->lock, flags);
		wa = xfer->wa;
		dev = &wa->usb_iface->dev;
		rpipe = xfer->ep->hcpriv;
		if (printk_ratelimit())
			dev_err(dev, "xfer %p ID 0x%08X#%u: request error %d\n",
				xfer, wa_xfer_id(xfer), seg->index,
				urb->status);
		if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
			    EDC_ERROR_TIMEFRAME)){
			dev_err(dev, "DTO: URB max acceptable errors "
				"exceeded, resetting device\n");
			wa_reset_all(wa);
		}
		usb_unlink_urb(seg->isoc_pack_desc_urb);
		usb_unlink_urb(seg->dto_urb);
		seg->result = urb->status;
		__wa_xfer_abort(xfer);
		rpipe_ready = rpipe_avail_inc(rpipe);
		done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_ERROR);
		spin_unlock_irqrestore(&xfer->lock, flags);
		if (done)
			wa_xfer_completion(xfer);
		if (rpipe_ready)
			wa_xfer_delayed_run(rpipe);
	}
	/* taken when this URB was submitted. */
	wa_xfer_put(xfer);
}

/*
 * Allocate an SG list to store bytes_to_transfer bytes and copy the
 * subset of the in_sg that matches the buffer subset
 * we are about to transfer.
 */
static struct scatterlist *wa_xfer_create_subset_sg(struct scatterlist *in_sg,
	const unsigned int bytes_transferred,
	const unsigned int bytes_to_transfer, int *out_num_sgs)
{
	struct scatterlist *out_sg;
	unsigned int bytes_processed = 0, offset_into_current_page_data = 0,
		nents;
	struct scatterlist *current_xfer_sg = in_sg;
	struct scatterlist *current_seg_sg, *last_seg_sg;

	/* skip previously transferred pages. */
	while ((current_xfer_sg) &&
			(bytes_processed < bytes_transferred)) {
		bytes_processed += current_xfer_sg->length;

		/* advance the sg if current segment starts on or past the
			next page. */
		if (bytes_processed <= bytes_transferred)
			current_xfer_sg = sg_next(current_xfer_sg);
	}

	/* the data for the current segment starts in current_xfer_sg.
		calculate the offset. */
	if (bytes_processed > bytes_transferred) {
		offset_into_current_page_data = current_xfer_sg->length -
			(bytes_processed - bytes_transferred);
	}

	/* calculate the number of pages needed by this segment. */
	nents = DIV_ROUND_UP((bytes_to_transfer +
		offset_into_current_page_data +
		current_xfer_sg->offset),
		PAGE_SIZE);

	out_sg = kmalloc((sizeof(struct scatterlist) * nents), GFP_ATOMIC);
	if (out_sg) {
		sg_init_table(out_sg, nents);

		/* copy the portion of the incoming SG that correlates to the
		 * data to be transferred by this segment to the segment SG. */
		last_seg_sg = current_seg_sg = out_sg;
		bytes_processed = 0;

		/* reset nents and calculate the actual number of sg entries
			needed. */
		nents = 0;
		while ((bytes_processed < bytes_to_transfer) &&
				current_seg_sg && current_xfer_sg) {
			unsigned int page_len = min((current_xfer_sg->length -
				offset_into_current_page_data),
				(bytes_to_transfer - bytes_processed));

			sg_set_page(current_seg_sg, sg_page(current_xfer_sg),
				page_len,
				current_xfer_sg->offset +
				offset_into_current_page_data);

			bytes_processed += page_len;

			last_seg_sg = current_seg_sg;
			current_seg_sg = sg_next(current_seg_sg);
			current_xfer_sg = sg_next(current_xfer_sg);

			/* only the first page may require additional offset. */
			offset_into_current_page_data = 0;
			nents++;
		}

		/* update num_sgs and terminate the list since we may have
		 *  concatenated pages. */
		sg_mark_end(last_seg_sg);
		*out_num_sgs = nents;
	}

	return out_sg;
}

/*
 * Populate DMA buffer info for the isoc dto urb.
 */
static void __wa_populate_dto_urb_isoc(struct wa_xfer *xfer,
	struct wa_seg *seg, int curr_iso_frame)
{
	seg->dto_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	seg->dto_urb->sg = NULL;
	seg->dto_urb->num_sgs = 0;
	/* dto urb buffer address pulled from iso_frame_desc. */
	seg->dto_urb->transfer_dma = xfer->urb->transfer_dma +
		xfer->urb->iso_frame_desc[curr_iso_frame].offset;
	/* The Alereon HWA sends a single URB with all isoc segs. */
	if (xfer->wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC)
		seg->dto_urb->transfer_buffer_length = seg->isoc_size;
	else
		seg->dto_urb->transfer_buffer_length =
			xfer->urb->iso_frame_desc[curr_iso_frame].length;
}

/*
 * Populate buffer ptr and size, DMA buffer or SG list for the dto urb.
 */
static int __wa_populate_dto_urb(struct wa_xfer *xfer,
	struct wa_seg *seg, size_t buf_itr_offset, size_t buf_itr_size)
{
	int result = 0;

	if (xfer->is_dma) {
		seg->dto_urb->transfer_dma =
			xfer->urb->transfer_dma + buf_itr_offset;
		seg->dto_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		seg->dto_urb->sg = NULL;
		seg->dto_urb->num_sgs = 0;
	} else {
		/* do buffer or SG processing. */
		seg->dto_urb->transfer_flags &=
			~URB_NO_TRANSFER_DMA_MAP;
		/* this should always be 0 before a resubmit. */
		seg->dto_urb->num_mapped_sgs = 0;

		if (xfer->urb->transfer_buffer) {
			seg->dto_urb->transfer_buffer =
				xfer->urb->transfer_buffer +
				buf_itr_offset;
			seg->dto_urb->sg = NULL;
			seg->dto_urb->num_sgs = 0;
		} else {
			seg->dto_urb->transfer_buffer = NULL;

			/*
			 * allocate an SG list to store seg_size bytes
			 * and copy the subset of the xfer->urb->sg that
			 * matches the buffer subset we are about to
			 * read.
			 */
			seg->dto_urb->sg = wa_xfer_create_subset_sg(
				xfer->urb->sg,
				buf_itr_offset, buf_itr_size,
				&(seg->dto_urb->num_sgs));
			if (!(seg->dto_urb->sg))
				result = -ENOMEM;
		}
	}
	seg->dto_urb->transfer_buffer_length = buf_itr_size;

	return result;
}

/*
 * Allocate the segs array and initialize each of them
 *
 * The segments are freed by wa_xfer_destroy() when the xfer use count
 * drops to zero; however, because each segment is given the same life
 * cycle as the USB URB it contains, it is actually freed by
 * usb_put_urb() on the contained USB URB (twisted, eh?).
 */
static int __wa_xfer_setup_segs(struct wa_xfer *xfer, size_t xfer_hdr_size)
{
	int result, cnt, isoc_frame_offset = 0;
	size_t alloc_size = sizeof(*xfer->seg[0])
		- sizeof(xfer->seg[0]->xfer_hdr) + xfer_hdr_size;
	struct usb_device *usb_dev = xfer->wa->usb_dev;
	const struct usb_endpoint_descriptor *dto_epd = xfer->wa->dto_epd;
	struct wa_seg *seg;
	size_t buf_itr, buf_size, buf_itr_size;

	result = -ENOMEM;
	xfer->seg = kcalloc(xfer->segs, sizeof(xfer->seg[0]), GFP_ATOMIC);
	if (xfer->seg == NULL)
		goto error_segs_kzalloc;
	buf_itr = 0;
	buf_size = xfer->urb->transfer_buffer_length;
	for (cnt = 0; cnt < xfer->segs; cnt++) {
		size_t iso_pkt_descr_size = 0;
		int seg_isoc_frame_count = 0, seg_isoc_size = 0;

		/*
		 * Adjust the size of the segment object to contain space for
		 * the isoc packet descriptor buffer.
		 */
		if (usb_pipeisoc(xfer->urb->pipe)) {
			seg_isoc_frame_count =
				__wa_seg_calculate_isoc_frame_count(xfer,
					isoc_frame_offset, &seg_isoc_size);

			iso_pkt_descr_size =
				sizeof(struct wa_xfer_packet_info_hwaiso) +
				(seg_isoc_frame_count * sizeof(__le16));
		}
		seg = xfer->seg[cnt] = kmalloc(alloc_size + iso_pkt_descr_size,
						GFP_ATOMIC);
		if (seg == NULL)
			goto error_seg_kmalloc;
		wa_seg_init(seg);
		seg->xfer = xfer;
		seg->index = cnt;
		usb_fill_bulk_urb(&seg->tr_urb, usb_dev,
				  usb_sndbulkpipe(usb_dev,
						  dto_epd->bEndpointAddress),
				  &seg->xfer_hdr, xfer_hdr_size,
				  wa_seg_tr_cb, seg);
		buf_itr_size = min(buf_size, xfer->seg_size);

		if (usb_pipeisoc(xfer->urb->pipe)) {
			seg->isoc_frame_count = seg_isoc_frame_count;
			seg->isoc_frame_offset = isoc_frame_offset;
			seg->isoc_size = seg_isoc_size;
			/* iso packet descriptor. */
			seg->isoc_pack_desc_urb =
					usb_alloc_urb(0, GFP_ATOMIC);
			if (seg->isoc_pack_desc_urb == NULL)
				goto error_iso_pack_desc_alloc;
			/*
			 * The buffer for the isoc packet descriptor starts
			 * after the transfer request header in the
			 * segment object memory buffer.
			 */
			usb_fill_bulk_urb(
				seg->isoc_pack_desc_urb, usb_dev,
				usb_sndbulkpipe(usb_dev,
					dto_epd->bEndpointAddress),
				(void *)(&seg->xfer_hdr) +
					xfer_hdr_size,
				iso_pkt_descr_size,
				wa_seg_iso_pack_desc_cb, seg);

			/* adjust starting frame offset for next seg. */
			isoc_frame_offset += seg_isoc_frame_count;
		}

		if (xfer->is_inbound == 0 && buf_size > 0) {
			/* outbound data. */
			seg->dto_urb = usb_alloc_urb(0, GFP_ATOMIC);
			if (seg->dto_urb == NULL)
				goto error_dto_alloc;
			usb_fill_bulk_urb(
				seg->dto_urb, usb_dev,
				usb_sndbulkpipe(usb_dev,
						dto_epd->bEndpointAddress),
				NULL, 0, wa_seg_dto_cb, seg);

			if (usb_pipeisoc(xfer->urb->pipe)) {
				/*
				 * Fill in the xfer buffer information for the
				 * first isoc frame.  Subsequent frames in this
				 * segment will be filled in and sent from the
				 * DTO completion routine, if needed.
				 */
				__wa_populate_dto_urb_isoc(xfer, seg,
					seg->isoc_frame_offset);
			} else {
				/* fill in the xfer buffer information. */
				result = __wa_populate_dto_urb(xfer, seg,
							buf_itr, buf_itr_size);
				if (result < 0)
					goto error_seg_outbound_populate;

				buf_itr += buf_itr_size;
				buf_size -= buf_itr_size;
			}
		}
		seg->status = WA_SEG_READY;
	}
	return 0;

	/*
	 * Free the memory for the current segment which failed to init.
	 * Use the fact that cnt is left at were it failed.  The remaining
	 * segments will be cleaned up by wa_xfer_destroy.
	 */
error_seg_outbound_populate:
	usb_free_urb(xfer->seg[cnt]->dto_urb);
error_dto_alloc:
	usb_free_urb(xfer->seg[cnt]->isoc_pack_desc_urb);
error_iso_pack_desc_alloc:
	kfree(xfer->seg[cnt]);
	xfer->seg[cnt] = NULL;
error_seg_kmalloc:
error_segs_kzalloc:
	return result;
}

/*
 * Allocates all the stuff needed to submit a transfer
 *
 * Breaks the whole data buffer in a list of segments, each one has a
 * structure allocated to it and linked in xfer->seg[index]
 *
 * FIXME: merge setup_segs() and the last part of this function, no
 *        need to do two for loops when we could run everything in a
 *        single one
 */
static int __wa_xfer_setup(struct wa_xfer *xfer, struct urb *urb)
{
	int result;
	struct device *dev = &xfer->wa->usb_iface->dev;
	enum wa_xfer_type xfer_type = 0; /* shut up GCC */
	size_t xfer_hdr_size, cnt, transfer_size;
	struct wa_xfer_hdr *xfer_hdr0, *xfer_hdr;

	result = __wa_xfer_setup_sizes(xfer, &xfer_type);
	if (result < 0)
		goto error_setup_sizes;
	xfer_hdr_size = result;
	result = __wa_xfer_setup_segs(xfer, xfer_hdr_size);
	if (result < 0) {
		dev_err(dev, "xfer %p: Failed to allocate %d segments: %d\n",
			xfer, xfer->segs, result);
		goto error_setup_segs;
	}
	/* Fill the first header */
	xfer_hdr0 = &xfer->seg[0]->xfer_hdr;
	wa_xfer_id_init(xfer);
	__wa_xfer_setup_hdr0(xfer, xfer_hdr0, xfer_type, xfer_hdr_size);

	/* Fill remaining headers */
	xfer_hdr = xfer_hdr0;
	if (xfer_type == WA_XFER_TYPE_ISO) {
		xfer_hdr0->dwTransferLength =
			cpu_to_le32(xfer->seg[0]->isoc_size);
		for (cnt = 1; cnt < xfer->segs; cnt++) {
			struct wa_xfer_packet_info_hwaiso *packet_desc;
			struct wa_seg *seg = xfer->seg[cnt];
			struct wa_xfer_hwaiso *xfer_iso;

			xfer_hdr = &seg->xfer_hdr;
			xfer_iso = container_of(xfer_hdr,
						struct wa_xfer_hwaiso, hdr);
			packet_desc = ((void *)xfer_hdr) + xfer_hdr_size;
			/*
			 * Copy values from the 0th header. Segment specific
			 * values are set below.
			 */
			memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
			xfer_hdr->bTransferSegment = cnt;
			xfer_hdr->dwTransferLength =
				cpu_to_le32(seg->isoc_size);
			xfer_iso->dwNumOfPackets =
					cpu_to_le32(seg->isoc_frame_count);
			__wa_setup_isoc_packet_descr(packet_desc, xfer, seg);
			seg->status = WA_SEG_READY;
		}
	} else {
		transfer_size = urb->transfer_buffer_length;
		xfer_hdr0->dwTransferLength = transfer_size > xfer->seg_size ?
			cpu_to_le32(xfer->seg_size) :
			cpu_to_le32(transfer_size);
		transfer_size -=  xfer->seg_size;
		for (cnt = 1; cnt < xfer->segs; cnt++) {
			xfer_hdr = &xfer->seg[cnt]->xfer_hdr;
			memcpy(xfer_hdr, xfer_hdr0, xfer_hdr_size);
			xfer_hdr->bTransferSegment = cnt;
			xfer_hdr->dwTransferLength =
				transfer_size > xfer->seg_size ?
					cpu_to_le32(xfer->seg_size)
					: cpu_to_le32(transfer_size);
			xfer->seg[cnt]->status = WA_SEG_READY;
			transfer_size -=  xfer->seg_size;
		}
	}
	xfer_hdr->bTransferSegment |= 0x80;	/* this is the last segment */
	result = 0;
error_setup_segs:
error_setup_sizes:
	return result;
}

/*
 *
 *
 * rpipe->seg_lock is held!
 */
static int __wa_seg_submit(struct wa_rpipe *rpipe, struct wa_xfer *xfer,
			   struct wa_seg *seg, int *dto_done)
{
	int result;

	/* default to done unless we encounter a multi-frame isoc segment. */
	*dto_done = 1;

	/*
	 * Take a ref for each segment urb so the xfer cannot disappear until
	 * all of the callbacks run.
	 */
	wa_xfer_get(xfer);
	/* submit the transfer request. */
	seg->status = WA_SEG_SUBMITTED;
	result = usb_submit_urb(&seg->tr_urb, GFP_ATOMIC);
	if (result < 0) {
		pr_err("%s: xfer %p#%u: REQ submit failed: %d\n",
		       __func__, xfer, seg->index, result);
		wa_xfer_put(xfer);
		goto error_tr_submit;
	}
	/* submit the isoc packet descriptor if present. */
	if (seg->isoc_pack_desc_urb) {
		wa_xfer_get(xfer);
		result = usb_submit_urb(seg->isoc_pack_desc_urb, GFP_ATOMIC);
		seg->isoc_frame_index = 0;
		if (result < 0) {
			pr_err("%s: xfer %p#%u: ISO packet descriptor submit failed: %d\n",
			       __func__, xfer, seg->index, result);
			wa_xfer_put(xfer);
			goto error_iso_pack_desc_submit;
		}
	}
	/* submit the out data if this is an out request. */
	if (seg->dto_urb) {
		struct wahc *wa = xfer->wa;
		wa_xfer_get(xfer);
		result = usb_submit_urb(seg->dto_urb, GFP_ATOMIC);
		if (result < 0) {
			pr_err("%s: xfer %p#%u: DTO submit failed: %d\n",
			       __func__, xfer, seg->index, result);
			wa_xfer_put(xfer);
			goto error_dto_submit;
		}
		/*
		 * If this segment contains more than one isoc frame, hold
		 * onto the dto resource until we send all frames.
		 * Only applies to non-Alereon devices.
		 */
		if (((wa->quirks & WUSB_QUIRK_ALEREON_HWA_CONCAT_ISOC) == 0)
			&& (seg->isoc_frame_count > 1))
			*dto_done = 0;
	}
	rpipe_avail_dec(rpipe);
	return 0;

error_dto_submit:
	usb_unlink_urb(seg->isoc_pack_desc_urb);
error_iso_pack_desc_submit:
	usb_unlink_urb(&seg->tr_urb);
error_tr_submit:
	seg->status = WA_SEG_ERROR;
	seg->result = result;
	*dto_done = 1;
	return result;
}

/*
 * Execute more queued request segments until the maximum concurrent allowed.
 * Return true if the DTO resource was acquired and released.
 *
 * The ugly unlock/lock sequence on the error path is needed as the
 * xfer->lock normally nests the seg_lock and not viceversa.
 */
static int __wa_xfer_delayed_run(struct wa_rpipe *rpipe, int *dto_waiting)
{
	int result, dto_acquired = 0, dto_done = 0;
	struct device *dev = &rpipe->wa->usb_iface->dev;
	struct wa_seg *seg;
	struct wa_xfer *xfer;
	unsigned long flags;

	*dto_waiting = 0;

	spin_lock_irqsave(&rpipe->seg_lock, flags);
	while (atomic_read(&rpipe->segs_available) > 0
	      && !list_empty(&rpipe->seg_list)
	      && (dto_acquired = __wa_dto_try_get(rpipe->wa))) {
		seg = list_first_entry(&(rpipe->seg_list), struct wa_seg,
				 list_node);
		list_del(&seg->list_node);
		xfer = seg->xfer;
		/*
		 * Get a reference to the xfer in case the callbacks for the
		 * URBs submitted by __wa_seg_submit attempt to complete
		 * the xfer before this function completes.
		 */
		wa_xfer_get(xfer);
		result = __wa_seg_submit(rpipe, xfer, seg, &dto_done);
		/* release the dto resource if this RPIPE is done with it. */
		if (dto_done)
			__wa_dto_put(rpipe->wa);
		dev_dbg(dev, "xfer %p ID %08X#%u submitted from delayed [%d segments available] %d\n",
			xfer, wa_xfer_id(xfer), seg->index,
			atomic_read(&rpipe->segs_available), result);
		if (unlikely(result < 0)) {
			int done;

			spin_unlock_irqrestore(&rpipe->seg_lock, flags);
			spin_lock_irqsave(&xfer->lock, flags);
			__wa_xfer_abort(xfer);
			/*
			 * This seg was marked as submitted when it was put on
			 * the RPIPE seg_list.  Mark it done.
			 */
			xfer->segs_done++;
			done = __wa_xfer_is_done(xfer);
			spin_unlock_irqrestore(&xfer->lock, flags);
			if (done)
				wa_xfer_completion(xfer);
			spin_lock_irqsave(&rpipe->seg_lock, flags);
		}
		wa_xfer_put(xfer);
	}
	/*
	 * Mark this RPIPE as waiting if dto was not acquired, there are
	 * delayed segs and no active transfers to wake us up later.
	 */
	if (!dto_acquired && !list_empty(&rpipe->seg_list)
		&& (atomic_read(&rpipe->segs_available) ==
			le16_to_cpu(rpipe->descr.wRequests)))
		*dto_waiting = 1;

	spin_unlock_irqrestore(&rpipe->seg_lock, flags);

	return dto_done;
}

static void wa_xfer_delayed_run(struct wa_rpipe *rpipe)
{
	int dto_waiting;
	int dto_done = __wa_xfer_delayed_run(rpipe, &dto_waiting);

	/*
	 * If this RPIPE is waiting on the DTO resource, add it to the tail of
	 * the waiting list.
	 * Otherwise, if the WA DTO resource was acquired and released by
	 *  __wa_xfer_delayed_run, another RPIPE may have attempted to acquire
	 * DTO and failed during that time.  Check the delayed list and process
	 * any waiters.  Start searching from the next RPIPE index.
	 */
	if (dto_waiting)
		wa_add_delayed_rpipe(rpipe->wa, rpipe);
	else if (dto_done)
		wa_check_for_delayed_rpipes(rpipe->wa);
}

/*
 *
 * xfer->lock is taken
 *
 * On failure submitting we just stop submitting and return error;
 * wa_urb_enqueue_b() will execute the completion path
 */
static int __wa_xfer_submit(struct wa_xfer *xfer)
{
	int result, dto_acquired = 0, dto_done = 0, dto_waiting = 0;
	struct wahc *wa = xfer->wa;
	struct device *dev = &wa->usb_iface->dev;
	unsigned cnt;
	struct wa_seg *seg;
	unsigned long flags;
	struct wa_rpipe *rpipe = xfer->ep->hcpriv;
	size_t maxrequests = le16_to_cpu(rpipe->descr.wRequests);
	u8 available;
	u8 empty;

	spin_lock_irqsave(&wa->xfer_list_lock, flags);
	list_add_tail(&xfer->list_node, &wa->xfer_list);
	spin_unlock_irqrestore(&wa->xfer_list_lock, flags);

	BUG_ON(atomic_read(&rpipe->segs_available) > maxrequests);
	result = 0;
	spin_lock_irqsave(&rpipe->seg_lock, flags);
	for (cnt = 0; cnt < xfer->segs; cnt++) {
		int delay_seg = 1;

		available = atomic_read(&rpipe->segs_available);
		empty = list_empty(&rpipe->seg_list);
		seg = xfer->seg[cnt];
		if (available && empty) {
			/*
			 * Only attempt to acquire DTO if we have a segment
			 * to send.
			 */
			dto_acquired = __wa_dto_try_get(rpipe->wa);
			if (dto_acquired) {
				delay_seg = 0;
				result = __wa_seg_submit(rpipe, xfer, seg,
							&dto_done);
				dev_dbg(dev, "xfer %p ID 0x%08X#%u: available %u empty %u submitted\n",
					xfer, wa_xfer_id(xfer), cnt, available,
					empty);
				if (dto_done)
					__wa_dto_put(rpipe->wa);

				if (result < 0) {
					__wa_xfer_abort(xfer);
					goto error_seg_submit;
				}
			}
		}

		if (delay_seg) {
			dev_dbg(dev, "xfer %p ID 0x%08X#%u: available %u empty %u delayed\n",
				xfer, wa_xfer_id(xfer), cnt, available,  empty);
			seg->status = WA_SEG_DELAYED;
			list_add_tail(&seg->list_node, &rpipe->seg_list);
		}
		xfer->segs_submitted++;
	}
error_seg_submit:
	/*
	 * Mark this RPIPE as waiting if dto was not acquired, there are
	 * delayed segs and no active transfers to wake us up later.
	 */
	if (!dto_acquired && !list_empty(&rpipe->seg_list)
		&& (atomic_read(&rpipe->segs_available) ==
			le16_to_cpu(rpipe->descr.wRequests)))
		dto_waiting = 1;
	spin_unlock_irqrestore(&rpipe->seg_lock, flags);

	if (dto_waiting)
		wa_add_delayed_rpipe(rpipe->wa, rpipe);
	else if (dto_done)
		wa_check_for_delayed_rpipes(rpipe->wa);

	return result;
}

/*
 * Second part of a URB/transfer enqueuement
 *
 * Assumes this comes from wa_urb_enqueue() [maybe through
 * wa_urb_enqueue_run()]. At this point:
 *
 * xfer->wa	filled and refcounted
 * xfer->ep	filled with rpipe refcounted if
 *              delayed == 0
 * xfer->urb 	filled and refcounted (this is the case when called
 *              from wa_urb_enqueue() as we come from usb_submit_urb()
 *              and when called by wa_urb_enqueue_run(), as we took an
 *              extra ref dropped by _run() after we return).
 * xfer->gfp	filled
 *
 * If we fail at __wa_xfer_submit(), then we just check if we are done
 * and if so, we run the completion procedure. However, if we are not
 * yet done, we do nothing and wait for the completion handlers from
 * the submitted URBs or from the xfer-result path to kick in. If xfer
 * result never kicks in, the xfer will timeout from the USB code and
 * dequeue() will be called.
 */
static int wa_urb_enqueue_b(struct wa_xfer *xfer)
{
	int result;
	unsigned long flags;
	struct urb *urb = xfer->urb;
	struct wahc *wa = xfer->wa;
	struct wusbhc *wusbhc = wa->wusb;
	struct wusb_dev *wusb_dev;
	unsigned done;

	result = rpipe_get_by_ep(wa, xfer->ep, urb, xfer->gfp);
	if (result < 0) {
		pr_err("%s: error_rpipe_get\n", __func__);
		goto error_rpipe_get;
	}
	result = -ENODEV;
	/* FIXME: segmentation broken -- kills DWA */
	mutex_lock(&wusbhc->mutex);		/* get a WUSB dev */
	if (urb->dev == NULL) {
		mutex_unlock(&wusbhc->mutex);
		pr_err("%s: error usb dev gone\n", __func__);
		goto error_dev_gone;
	}
	wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev);
	if (wusb_dev == NULL) {
		mutex_unlock(&wusbhc->mutex);
		dev_err(&(urb->dev->dev), "%s: error wusb dev gone\n",
			__func__);
		goto error_dev_gone;
	}
	mutex_unlock(&wusbhc->mutex);

	spin_lock_irqsave(&xfer->lock, flags);
	xfer->wusb_dev = wusb_dev;
	result = urb->status;
	if (urb->status != -EINPROGRESS) {
		dev_err(&(urb->dev->dev), "%s: error_dequeued\n", __func__);
		goto error_dequeued;
	}

	result = __wa_xfer_setup(xfer, urb);
	if (result < 0) {
		dev_err(&(urb->dev->dev), "%s: error_xfer_setup\n", __func__);
		goto error_xfer_setup;
	}
	/*
	 * Get a xfer reference since __wa_xfer_submit starts asynchronous
	 * operations that may try to complete the xfer before this function
	 * exits.
	 */
	wa_xfer_get(xfer);
	result = __wa_xfer_submit(xfer);
	if (result < 0) {
		dev_err(&(urb->dev->dev), "%s: error_xfer_submit\n", __func__);
		goto error_xfer_submit;
	}
	spin_unlock_irqrestore(&xfer->lock, flags);
	wa_xfer_put(xfer);
	return 0;

	/*
	 * this is basically wa_xfer_completion() broken up wa_xfer_giveback()
	 * does a wa_xfer_put() that will call wa_xfer_destroy() and undo
	 * setup().
	 */
error_xfer_setup:
error_dequeued:
	spin_unlock_irqrestore(&xfer->lock, flags);
	/* FIXME: segmentation broken, kills DWA */
	if (wusb_dev)
		wusb_dev_put(wusb_dev);
error_dev_gone:
	rpipe_put(xfer->ep->hcpriv);
error_rpipe_get:
	xfer->result = result;
	return result;

error_xfer_submit:
	done = __wa_xfer_is_done(xfer);
	xfer->result = result;
	spin_unlock_irqrestore(&xfer->lock, flags);
	if (done)
		wa_xfer_completion(xfer);
	wa_xfer_put(xfer);
	/* return success since the completion routine will run. */
	return 0;
}

/*
 * Execute the delayed transfers in the Wire Adapter @wa
 *
 * We need to be careful here, as dequeue() could be called in the
 * middle.  That's why we do the whole thing under the
 * wa->xfer_list_lock. If dequeue() jumps in, it first locks xfer->lock
 * and then checks the list -- so as we would be acquiring in inverse
 * order, we move the delayed list to a separate list while locked and then
 * submit them without the list lock held.
 */
void wa_urb_enqueue_run(struct work_struct *ws)
{
	struct wahc *wa = container_of(ws, struct wahc, xfer_enqueue_work);
	struct wa_xfer *xfer, *next;
	struct urb *urb;
	LIST_HEAD(tmp_list);

	/* Create a copy of the wa->xfer_delayed_list while holding the lock */
	spin_lock_irq(&wa->xfer_list_lock);
	list_cut_position(&tmp_list, &wa->xfer_delayed_list,
			wa->xfer_delayed_list.prev);
	spin_unlock_irq(&wa->xfer_list_lock);

	/*
	 * enqueue from temp list without list lock held since wa_urb_enqueue_b
	 * can take xfer->lock as well as lock mutexes.
	 */
	list_for_each_entry_safe(xfer, next, &tmp_list, list_node) {
		list_del_init(&xfer->list_node);

		urb = xfer->urb;
		if (wa_urb_enqueue_b(xfer) < 0)
			wa_xfer_giveback(xfer);
		usb_put_urb(urb);	/* taken when queuing */
	}
}
EXPORT_SYMBOL_GPL(wa_urb_enqueue_run);

/*
 * Process the errored transfers on the Wire Adapter outside of interrupt.
 */
void wa_process_errored_transfers_run(struct work_struct *ws)
{
	struct wahc *wa = container_of(ws, struct wahc, xfer_error_work);
	struct wa_xfer *xfer, *next;
	LIST_HEAD(tmp_list);

	pr_info("%s: Run delayed STALL processing.\n", __func__);

	/* Create a copy of the wa->xfer_errored_list while holding the lock */
	spin_lock_irq(&wa->xfer_list_lock);
	list_cut_position(&tmp_list, &wa->xfer_errored_list,
			wa->xfer_errored_list.prev);
	spin_unlock_irq(&wa->xfer_list_lock);

	/*
	 * run rpipe_clear_feature_stalled from temp list without list lock
	 * held.
	 */
	list_for_each_entry_safe(xfer, next, &tmp_list, list_node) {
		struct usb_host_endpoint *ep;
		unsigned long flags;
		struct wa_rpipe *rpipe;

		spin_lock_irqsave(&xfer->lock, flags);
		ep = xfer->ep;
		rpipe = ep->hcpriv;
		spin_unlock_irqrestore(&xfer->lock, flags);

		/* clear RPIPE feature stalled without holding a lock. */
		rpipe_clear_feature_stalled(wa, ep);

		/* complete the xfer. This removes it from the tmp list. */
		wa_xfer_completion(xfer);

		/* check for work. */
		wa_xfer_delayed_run(rpipe);
	}
}
EXPORT_SYMBOL_GPL(wa_process_errored_transfers_run);

/*
 * Submit a transfer to the Wire Adapter in a delayed way
 *
 * The process of enqueuing involves possible sleeps() [see
 * enqueue_b(), for the rpipe_get() and the mutex_lock()]. If we are
 * in an atomic section, we defer the enqueue_b() call--else we call direct.
 *
 * @urb: We own a reference to it done by the HCI Linux USB stack that
 *       will be given up by calling usb_hcd_giveback_urb() or by
 *       returning error from this function -> ergo we don't have to
 *       refcount it.
 */
int wa_urb_enqueue(struct wahc *wa, struct usb_host_endpoint *ep,
		   struct urb *urb, gfp_t gfp)
{
	int result;
	struct device *dev = &wa->usb_iface->dev;
	struct wa_xfer *xfer;
	unsigned long my_flags;
	unsigned cant_sleep = irqs_disabled() | in_atomic();

	if ((urb->transfer_buffer == NULL)
	    && (urb->sg == NULL)
	    && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
	    && urb->transfer_buffer_length != 0) {
		dev_err(dev, "BUG? urb %p: NULL xfer buffer & NODMA\n", urb);
		dump_stack();
	}

	spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
	result = usb_hcd_link_urb_to_ep(&(wa->wusb->usb_hcd), urb);
	spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
	if (result < 0)
		goto error_link_urb;

	result = -ENOMEM;
	xfer = kzalloc(sizeof(*xfer), gfp);
	if (xfer == NULL)
		goto error_kmalloc;

	result = -ENOENT;
	if (urb->status != -EINPROGRESS)	/* cancelled */
		goto error_dequeued;		/* before starting? */
	wa_xfer_init(xfer);
	xfer->wa = wa_get(wa);
	xfer->urb = urb;
	xfer->gfp = gfp;
	xfer->ep = ep;
	urb->hcpriv = xfer;

	dev_dbg(dev, "xfer %p urb %p pipe 0x%02x [%d bytes] %s %s %s\n",
		xfer, urb, urb->pipe, urb->transfer_buffer_length,
		urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP ? "dma" : "nodma",
		urb->pipe & USB_DIR_IN ? "inbound" : "outbound",
		cant_sleep ? "deferred" : "inline");

	if (cant_sleep) {
		usb_get_urb(urb);
		spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
		list_add_tail(&xfer->list_node, &wa->xfer_delayed_list);
		spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
		queue_work(wusbd, &wa->xfer_enqueue_work);
	} else {
		result = wa_urb_enqueue_b(xfer);
		if (result < 0) {
			/*
			 * URB submit/enqueue failed.  Clean up, return an
			 * error and do not run the callback.  This avoids
			 * an infinite submit/complete loop.
			 */
			dev_err(dev, "%s: URB enqueue failed: %d\n",
			   __func__, result);
			wa_put(xfer->wa);
			wa_xfer_put(xfer);
			spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
			usb_hcd_unlink_urb_from_ep(&(wa->wusb->usb_hcd), urb);
			spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
			return result;
		}
	}
	return 0;

error_dequeued:
	kfree(xfer);
error_kmalloc:
	spin_lock_irqsave(&wa->xfer_list_lock, my_flags);
	usb_hcd_unlink_urb_from_ep(&(wa->wusb->usb_hcd), urb);
	spin_unlock_irqrestore(&wa->xfer_list_lock, my_flags);
error_link_urb:
	return result;
}
EXPORT_SYMBOL_GPL(wa_urb_enqueue);

/*
 * Dequeue a URB and make sure uwb_hcd_giveback_urb() [completion
 * handler] is called.
 *
 * Until a transfer goes successfully through wa_urb_enqueue() it
 * needs to be dequeued with completion calling; when stuck in delayed
 * or before wa_xfer_setup() is called, we need to do completion.
 *
 *  not setup  If there is no hcpriv yet, that means that that enqueue
 *             still had no time to set the xfer up. Because
 *             urb->status should be other than -EINPROGRESS,
 *             enqueue() will catch that and bail out.
 *
 * If the transfer has gone through setup, we just need to clean it
 * up. If it has gone through submit(), we have to abort it [with an
 * asynch request] and then make sure we cancel each segment.
 *
 */
int wa_urb_dequeue(struct wahc *wa, struct urb *urb, int status)
{
	unsigned long flags, flags2;
	struct wa_xfer *xfer;
	struct wa_seg *seg;
	struct wa_rpipe *rpipe;
	unsigned cnt, done = 0, xfer_abort_pending;
	unsigned rpipe_ready = 0;
	int result;

	/* check if it is safe to unlink. */
	spin_lock_irqsave(&wa->xfer_list_lock, flags);
	result = usb_hcd_check_unlink_urb(&(wa->wusb->usb_hcd), urb, status);
	if ((result == 0) && urb->hcpriv) {
		/*
		 * Get a xfer ref to prevent a race with wa_xfer_giveback
		 * cleaning up the xfer while we are working with it.
		 */
		wa_xfer_get(urb->hcpriv);
	}
	spin_unlock_irqrestore(&wa->xfer_list_lock, flags);
	if (result)
		return result;

	xfer = urb->hcpriv;
	if (xfer == NULL)
		return -ENOENT;
	spin_lock_irqsave(&xfer->lock, flags);
	pr_debug("%s: DEQUEUE xfer id 0x%08X\n", __func__, wa_xfer_id(xfer));
	rpipe = xfer->ep->hcpriv;
	if (rpipe == NULL) {
		pr_debug("%s: xfer %p id 0x%08X has no RPIPE.  %s",
			__func__, xfer, wa_xfer_id(xfer),
			"Probably already aborted.\n" );
		result = -ENOENT;
		goto out_unlock;
	}
	/*
	 * Check for done to avoid racing with wa_xfer_giveback and completing
	 * twice.
	 */
	if (__wa_xfer_is_done(xfer)) {
		pr_debug("%s: xfer %p id 0x%08X already done.\n", __func__,
			xfer, wa_xfer_id(xfer));
		result = -ENOENT;
		goto out_unlock;
	}
	/* Check the delayed list -> if there, release and complete */
	spin_lock_irqsave(&wa->xfer_list_lock, flags2);
	if (!list_empty(&xfer->list_node) && xfer->seg == NULL)
		goto dequeue_delayed;
	spin_unlock_irqrestore(&wa->xfer_list_lock, flags2);
	if (xfer->seg == NULL)  	/* still hasn't reached */
		goto out_unlock;	/* setup(), enqueue_b() completes */
	/* Ok, the xfer is in flight already, it's been setup and submitted.*/
	xfer_abort_pending = __wa_xfer_abort(xfer) >= 0;
	/*
	 * grab the rpipe->seg_lock here to prevent racing with
	 * __wa_xfer_delayed_run.
	 */
	spin_lock(&rpipe->seg_lock);
	for (cnt = 0; cnt < xfer->segs; cnt++) {
		seg = xfer->seg[cnt];
		pr_debug("%s: xfer id 0x%08X#%d status = %d\n",
			__func__, wa_xfer_id(xfer), cnt, seg->status);
		switch (seg->status) {
		case WA_SEG_NOTREADY:
		case WA_SEG_READY:
			printk(KERN_ERR "xfer %p#%u: dequeue bad state %u\n",
			       xfer, cnt, seg->status);
			WARN_ON(1);
			break;
		case WA_SEG_DELAYED:
			/*
			 * delete from rpipe delayed list.  If no segments on
			 * this xfer have been submitted, __wa_xfer_is_done will
			 * trigger a giveback below.  Otherwise, the submitted
			 * segments will be completed in the DTI interrupt.
			 */
			seg->status = WA_SEG_ABORTED;
			seg->result = -ENOENT;
			list_del(&seg->list_node);
			xfer->segs_done++;
			break;
		case WA_SEG_DONE:
		case WA_SEG_ERROR:
		case WA_SEG_ABORTED:
			break;
			/*
			 * The buf_in data for a segment in the
			 * WA_SEG_DTI_PENDING state is actively being read.
			 * Let wa_buf_in_cb handle it since it will be called
			 * and will increment xfer->segs_done.  Cleaning up
			 * here could cause wa_buf_in_cb to access the xfer
			 * after it has been completed/freed.
			 */
		case WA_SEG_DTI_PENDING:
			break;
			/*
			 * In the states below, the HWA device already knows
			 * about the transfer.  If an abort request was sent,
			 * allow the HWA to process it and wait for the
			 * results.  Otherwise, the DTI state and seg completed
			 * counts can get out of sync.
			 */
		case WA_SEG_SUBMITTED:
		case WA_SEG_PENDING:
			/*
			 * Check if the abort was successfully sent.  This could
			 * be false if the HWA has been removed but we haven't
			 * gotten the disconnect notification yet.
			 */
			if (!xfer_abort_pending) {
				seg->status = WA_SEG_ABORTED;
				rpipe_ready = rpipe_avail_inc(rpipe);
				xfer->segs_done++;
			}
			break;
		}
	}
	spin_unlock(&rpipe->seg_lock);
	xfer->result = urb->status;	/* -ENOENT or -ECONNRESET */
	done = __wa_xfer_is_done(xfer);
	spin_unlock_irqrestore(&xfer->lock, flags);
	if (done)
		wa_xfer_completion(xfer);
	if (rpipe_ready)
		wa_xfer_delayed_run(rpipe);
	wa_xfer_put(xfer);
	return result;

out_unlock:
	spin_unlock_irqrestore(&xfer->lock, flags);
	wa_xfer_put(xfer);
	return result;

dequeue_delayed:
	list_del_init(&xfer->list_node);
	spin_unlock_irqrestore(&wa->xfer_list_lock, flags2);
	xfer->result = urb->status;
	spin_unlock_irqrestore(&xfer->lock, flags);
	wa_xfer_giveback(xfer);
	wa_xfer_put(xfer);
	usb_put_urb(urb);		/* we got a ref in enqueue() */
	return 0;
}
EXPORT_SYMBOL_GPL(wa_urb_dequeue);

/*
 * Translation from WA status codes (WUSB1.0 Table 8.15) to errno
 * codes
 *
 * Positive errno values are internal inconsistencies and should be
 * flagged louder. Negative are to be passed up to the user in the
 * normal way.
 *
 * @status: USB WA status code -- high two bits are stripped.
 */
static int wa_xfer_status_to_errno(u8 status)
{
	int errno;
	u8 real_status = status;
	static int xlat[] = {
		[WA_XFER_STATUS_SUCCESS] = 		0,
		[WA_XFER_STATUS_HALTED] = 		-EPIPE,
		[WA_XFER_STATUS_DATA_BUFFER_ERROR] = 	-ENOBUFS,
		[WA_XFER_STATUS_BABBLE] = 		-EOVERFLOW,
		[WA_XFER_RESERVED] = 			EINVAL,
		[WA_XFER_STATUS_NOT_FOUND] =		0,
		[WA_XFER_STATUS_INSUFFICIENT_RESOURCE] = -ENOMEM,
		[WA_XFER_STATUS_TRANSACTION_ERROR] = 	-EILSEQ,
		[WA_XFER_STATUS_ABORTED] =		-ENOENT,
		[WA_XFER_STATUS_RPIPE_NOT_READY] = 	EINVAL,
		[WA_XFER_INVALID_FORMAT] = 		EINVAL,
		[WA_XFER_UNEXPECTED_SEGMENT_NUMBER] = 	EINVAL,
		[WA_XFER_STATUS_RPIPE_TYPE_MISMATCH] = 	EINVAL,
	};
	status &= 0x3f;

	if (status == 0)
		return 0;
	if (status >= ARRAY_SIZE(xlat)) {
		printk_ratelimited(KERN_ERR "%s(): BUG? "
			       "Unknown WA transfer status 0x%02x\n",
			       __func__, real_status);
		return -EINVAL;
	}
	errno = xlat[status];
	if (unlikely(errno > 0)) {
		printk_ratelimited(KERN_ERR "%s(): BUG? "
			       "Inconsistent WA status: 0x%02x\n",
			       __func__, real_status);
		errno = -errno;
	}
	return errno;
}

/*
 * If a last segment flag and/or a transfer result error is encountered,
 * no other segment transfer results will be returned from the device.
 * Mark the remaining submitted or pending xfers as completed so that
 * the xfer will complete cleanly.
 *
 * xfer->lock must be held
 *
 */
static void wa_complete_remaining_xfer_segs(struct wa_xfer *xfer,
		int starting_index, enum wa_seg_status status)
{
	int index;
	struct wa_rpipe *rpipe = xfer->ep->hcpriv;

	for (index = starting_index; index < xfer->segs_submitted; index++) {
		struct wa_seg *current_seg = xfer->seg[index];

		BUG_ON(current_seg == NULL);

		switch (current_seg->status) {
		case WA_SEG_SUBMITTED:
		case WA_SEG_PENDING:
		case WA_SEG_DTI_PENDING:
			rpipe_avail_inc(rpipe);
		/*
		 * do not increment RPIPE avail for the WA_SEG_DELAYED case
		 * since it has not been submitted to the RPIPE.
		 */
		case WA_SEG_DELAYED:
			xfer->segs_done++;
			current_seg->status = status;
			break;
		case WA_SEG_ABORTED:
			break;
		default:
			WARN(1, "%s: xfer 0x%08X#%d. bad seg status = %d\n",
				__func__, wa_xfer_id(xfer), index,
				current_seg->status);
			break;
		}
	}
}

/* Populate the given urb based on the current isoc transfer state. */
static int __wa_populate_buf_in_urb_isoc(struct wahc *wa,
	struct urb *buf_in_urb, struct wa_xfer *xfer, struct wa_seg *seg)
{
	int urb_start_frame = seg->isoc_frame_index + seg->isoc_frame_offset;
	int seg_index, total_len = 0, urb_frame_index = urb_start_frame;
	struct usb_iso_packet_descriptor *iso_frame_desc =
						xfer->urb->iso_frame_desc;
	const int dti_packet_size = usb_endpoint_maxp(wa->dti_epd);
	int next_frame_contiguous;
	struct usb_iso_packet_descriptor *iso_frame;

	BUG_ON(buf_in_urb->status == -EINPROGRESS);

	/*
	 * If the current frame actual_length is contiguous with the next frame
	 * and actual_length is a multiple of the DTI endpoint max packet size,
	 * combine the current frame with the next frame in a single URB.  This
	 * reduces the number of URBs that must be submitted in that case.
	 */
	seg_index = seg->isoc_frame_index;
	do {
		next_frame_contiguous = 0;

		iso_frame = &iso_frame_desc[urb_frame_index];
		total_len += iso_frame->actual_length;
		++urb_frame_index;
		++seg_index;

		if (seg_index < seg->isoc_frame_count) {
			struct usb_iso_packet_descriptor *next_iso_frame;

			next_iso_frame = &iso_frame_desc[urb_frame_index];

			if ((iso_frame->offset + iso_frame->actual_length) ==
				next_iso_frame->offset)
				next_frame_contiguous = 1;
		}
	} while (next_frame_contiguous
			&& ((iso_frame->actual_length % dti_packet_size) == 0));

	/* this should always be 0 before a resubmit. */
	buf_in_urb->num_mapped_sgs	= 0;
	buf_in_urb->transfer_dma = xfer->urb->transfer_dma +
		iso_frame_desc[urb_start_frame].offset;
	buf_in_urb->transfer_buffer_length = total_len;
	buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
	buf_in_urb->transfer_buffer = NULL;
	buf_in_urb->sg = NULL;
	buf_in_urb->num_sgs = 0;
	buf_in_urb->context = seg;

	/* return the number of frames included in this URB. */
	return seg_index - seg->isoc_frame_index;
}

/* Populate the given urb based on the current transfer state. */
static int wa_populate_buf_in_urb(struct urb *buf_in_urb, struct wa_xfer *xfer,
	unsigned int seg_idx, unsigned int bytes_transferred)
{
	int result = 0;
	struct wa_seg *seg = xfer->seg[seg_idx];

	BUG_ON(buf_in_urb->status == -EINPROGRESS);
	/* this should always be 0 before a resubmit. */
	buf_in_urb->num_mapped_sgs	= 0;

	if (xfer->is_dma) {
		buf_in_urb->transfer_dma = xfer->urb->transfer_dma
			+ (seg_idx * xfer->seg_size);
		buf_in_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
		buf_in_urb->transfer_buffer = NULL;
		buf_in_urb->sg = NULL;
		buf_in_urb->num_sgs = 0;
	} else {
		/* do buffer or SG processing. */
		buf_in_urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP;

		if (xfer->urb->transfer_buffer) {
			buf_in_urb->transfer_buffer =
				xfer->urb->transfer_buffer
				+ (seg_idx * xfer->seg_size);
			buf_in_urb->sg = NULL;
			buf_in_urb->num_sgs = 0;
		} else {
			/* allocate an SG list to store seg_size bytes
				and copy the subset of the xfer->urb->sg
				that matches the buffer subset we are
				about to read. */
			buf_in_urb->sg = wa_xfer_create_subset_sg(
				xfer->urb->sg,
				seg_idx * xfer->seg_size,
				bytes_transferred,
				&(buf_in_urb->num_sgs));

			if (!(buf_in_urb->sg)) {
				buf_in_urb->num_sgs	= 0;
				result = -ENOMEM;
			}
			buf_in_urb->transfer_buffer = NULL;
		}
	}
	buf_in_urb->transfer_buffer_length = bytes_transferred;
	buf_in_urb->context = seg;

	return result;
}

/*
 * Process a xfer result completion message
 *
 * inbound transfers: need to schedule a buf_in_urb read
 *
 * FIXME: this function needs to be broken up in parts
 */
static void wa_xfer_result_chew(struct wahc *wa, struct wa_xfer *xfer,
		struct wa_xfer_result *xfer_result)
{
	int result;
	struct device *dev = &wa->usb_iface->dev;
	unsigned long flags;
	unsigned int seg_idx;
	struct wa_seg *seg;
	struct wa_rpipe *rpipe;
	unsigned done = 0;
	u8 usb_status;
	unsigned rpipe_ready = 0;
	unsigned bytes_transferred = le32_to_cpu(xfer_result->dwTransferLength);
	struct urb *buf_in_urb = &(wa->buf_in_urbs[0]);

	spin_lock_irqsave(&xfer->lock, flags);
	seg_idx = xfer_result->bTransferSegment & 0x7f;
	if (unlikely(seg_idx >= xfer->segs))
		goto error_bad_seg;
	seg = xfer->seg[seg_idx];
	rpipe = xfer->ep->hcpriv;
	usb_status = xfer_result->bTransferStatus;
	dev_dbg(dev, "xfer %p ID 0x%08X#%u: bTransferStatus 0x%02x (seg status %u)\n",
		xfer, wa_xfer_id(xfer), seg_idx, usb_status, seg->status);
	if (seg->status == WA_SEG_ABORTED
	    || seg->status == WA_SEG_ERROR)	/* already handled */
		goto segment_aborted;
	if (seg->status == WA_SEG_SUBMITTED)	/* ops, got here */
		seg->status = WA_SEG_PENDING;	/* before wa_seg{_dto}_cb() */
	if (seg->status != WA_SEG_PENDING) {
		if (printk_ratelimit())
			dev_err(dev, "xfer %p#%u: Bad segment state %u\n",
				xfer, seg_idx, seg->status);
		seg->status = WA_SEG_PENDING;	/* workaround/"fix" it */
	}
	if (usb_status & 0x80) {
		seg->result = wa_xfer_status_to_errno(usb_status);
		dev_err(dev, "DTI: xfer %p 0x%08X:#%u failed (0x%02x)\n",
			xfer, xfer->id, seg->index, usb_status);
		seg->status = ((usb_status & 0x7F) == WA_XFER_STATUS_ABORTED) ?
			WA_SEG_ABORTED : WA_SEG_ERROR;
		goto error_complete;
	}
	/* FIXME: we ignore warnings, tally them for stats */
	if (usb_status & 0x40) 		/* Warning?... */
		usb_status = 0;		/* ... pass */
	/*
	 * If the last segment bit is set, complete the remaining segments.
	 * When the current segment is completed, either in wa_buf_in_cb for
	 * transfers with data or below for no data, the xfer will complete.
	 */
	if (xfer_result->bTransferSegment & 0x80)
		wa_complete_remaining_xfer_segs(xfer, seg->index + 1,
			WA_SEG_DONE);
	if (usb_pipeisoc(xfer->urb->pipe)
		&& (le32_to_cpu(xfer_result->dwNumOfPackets) > 0)) {
		/* set up WA state to read the isoc packet status next. */
		wa->dti_isoc_xfer_in_progress = wa_xfer_id(xfer);
		wa->dti_isoc_xfer_seg = seg_idx;
		wa->dti_state = WA_DTI_ISOC_PACKET_STATUS_PENDING;
	} else if (xfer->is_inbound && !usb_pipeisoc(xfer->urb->pipe)
			&& (bytes_transferred > 0)) {
		/* IN data phase: read to buffer */
		seg->status = WA_SEG_DTI_PENDING;
		result = wa_populate_buf_in_urb(buf_in_urb, xfer, seg_idx,
			bytes_transferred);
		if (result < 0)
			goto error_buf_in_populate;
		++(wa->active_buf_in_urbs);
		result = usb_submit_urb(buf_in_urb, GFP_ATOMIC);
		if (result < 0) {
			--(wa->active_buf_in_urbs);
			goto error_submit_buf_in;
		}
	} else {
		/* OUT data phase or no data, complete it -- */
		seg->result = bytes_transferred;
		rpipe_ready = rpipe_avail_inc(rpipe);
		done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_DONE);
	}
	spin_unlock_irqrestore(&xfer->lock, flags);
	if (done)
		wa_xfer_completion(xfer);
	if (rpipe_ready)
		wa_xfer_delayed_run(rpipe);
	return;

error_submit_buf_in:
	if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
		dev_err(dev, "DTI: URB max acceptable errors "
			"exceeded, resetting device\n");
		wa_reset_all(wa);
	}
	if (printk_ratelimit())
		dev_err(dev, "xfer %p#%u: can't submit DTI data phase: %d\n",
			xfer, seg_idx, result);
	seg->result = result;
	kfree(buf_in_urb->sg);
	buf_in_urb->sg = NULL;
error_buf_in_populate:
	__wa_xfer_abort(xfer);
	seg->status = WA_SEG_ERROR;
error_complete:
	xfer->segs_done++;
	rpipe_ready = rpipe_avail_inc(rpipe);
	wa_complete_remaining_xfer_segs(xfer, seg->index + 1, seg->status);
	done = __wa_xfer_is_done(xfer);
	/*
	 * queue work item to clear STALL for control endpoints.
	 * Otherwise, let endpoint_reset take care of it.
	 */
	if (((usb_status & 0x3f) == WA_XFER_STATUS_HALTED) &&
		usb_endpoint_xfer_control(&xfer->ep->desc) &&
		done) {

		dev_info(dev, "Control EP stall.  Queue delayed work.\n");
		spin_lock(&wa->xfer_list_lock);
		/* move xfer from xfer_list to xfer_errored_list. */
		list_move_tail(&xfer->list_node, &wa->xfer_errored_list);
		spin_unlock(&wa->xfer_list_lock);
		spin_unlock_irqrestore(&xfer->lock, flags);
		queue_work(wusbd, &wa->xfer_error_work);
	} else {
		spin_unlock_irqrestore(&xfer->lock, flags);
		if (done)
			wa_xfer_completion(xfer);
		if (rpipe_ready)
			wa_xfer_delayed_run(rpipe);
	}

	return;

error_bad_seg:
	spin_unlock_irqrestore(&xfer->lock, flags);
	wa_urb_dequeue(wa, xfer->urb, -ENOENT);
	if (printk_ratelimit())
		dev_err(dev, "xfer %p#%u: bad segment\n", xfer, seg_idx);
	if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS, EDC_ERROR_TIMEFRAME)) {
		dev_err(dev, "DTI: URB max acceptable errors "
			"exceeded, resetting device\n");
		wa_reset_all(wa);
	}
	return;

segment_aborted:
	/* nothing to do, as the aborter did the completion */
	spin_unlock_irqrestore(&xfer->lock, flags);
}

/*
 * Process a isochronous packet status message
 *
 * inbound transfers: need to schedule a buf_in_urb read
 */
static int wa_process_iso_packet_status(struct wahc *wa, struct urb *urb)
{
	struct device *dev = &wa->usb_iface->dev;
	struct wa_xfer_packet_status_hwaiso *packet_status;
	struct wa_xfer_packet_status_len_hwaiso *status_array;
	struct wa_xfer *xfer;
	unsigned long flags;
	struct wa_seg *seg;
	struct wa_rpipe *rpipe;
	unsigned done = 0, dti_busy = 0, data_frame_count = 0, seg_index;
	unsigned first_frame_index = 0, rpipe_ready = 0;
	int expected_size;

	/* We have a xfer result buffer; check it */
	dev_dbg(dev, "DTI: isoc packet status %d bytes at %p\n",
		urb->actual_length, urb->transfer_buffer);
	packet_status = (struct wa_xfer_packet_status_hwaiso *)(wa->dti_buf);
	if (packet_status->bPacketType != WA_XFER_ISO_PACKET_STATUS) {
		dev_err(dev, "DTI Error: isoc packet status--bad type 0x%02x\n",
			packet_status->bPacketType);
		goto error_parse_buffer;
	}
	xfer = wa_xfer_get_by_id(wa, wa->dti_isoc_xfer_in_progress);
	if (xfer == NULL) {
		dev_err(dev, "DTI Error: isoc packet status--unknown xfer 0x%08x\n",
			wa->dti_isoc_xfer_in_progress);
		goto error_parse_buffer;
	}
	spin_lock_irqsave(&xfer->lock, flags);
	if (unlikely(wa->dti_isoc_xfer_seg >= xfer->segs))
		goto error_bad_seg;
	seg = xfer->seg[wa->dti_isoc_xfer_seg];
	rpipe = xfer->ep->hcpriv;
	expected_size = sizeof(*packet_status) +
			(sizeof(packet_status->PacketStatus[0]) *
			seg->isoc_frame_count);
	if (urb->actual_length != expected_size) {
		dev_err(dev, "DTI Error: isoc packet status--bad urb length (%d bytes vs %d needed)\n",
			urb->actual_length, expected_size);
		goto error_bad_seg;
	}
	if (le16_to_cpu(packet_status->wLength) != expected_size) {
		dev_err(dev, "DTI Error: isoc packet status--bad length %u\n",
			le16_to_cpu(packet_status->wLength));
		goto error_bad_seg;
	}
	/* write isoc packet status and lengths back to the xfer urb. */
	status_array = packet_status->PacketStatus;
	xfer->urb->start_frame =
		wa->wusb->usb_hcd.driver->get_frame_number(&wa->wusb->usb_hcd);
	for (seg_index = 0; seg_index < seg->isoc_frame_count; ++seg_index) {
		struct usb_iso_packet_descriptor *iso_frame_desc =
			xfer->urb->iso_frame_desc;
		const int xfer_frame_index =
			seg->isoc_frame_offset + seg_index;

		iso_frame_desc[xfer_frame_index].status =
			wa_xfer_status_to_errno(
			le16_to_cpu(status_array[seg_index].PacketStatus));
		iso_frame_desc[xfer_frame_index].actual_length =
			le16_to_cpu(status_array[seg_index].PacketLength);
		/* track the number of frames successfully transferred. */
		if (iso_frame_desc[xfer_frame_index].actual_length > 0) {
			/* save the starting frame index for buf_in_urb. */
			if (!data_frame_count)
				first_frame_index = seg_index;
			++data_frame_count;
		}
	}

	if (xfer->is_inbound && data_frame_count) {
		int result, total_frames_read = 0, urb_index = 0;
		struct urb *buf_in_urb;

		/* IN data phase: read to buffer */
		seg->status = WA_SEG_DTI_PENDING;

		/* start with the first frame with data. */
		seg->isoc_frame_index = first_frame_index;
		/* submit up to WA_MAX_BUF_IN_URBS read URBs. */
		do {
			int urb_frame_index, urb_frame_count;
			struct usb_iso_packet_descriptor *iso_frame_desc;

			buf_in_urb = &(wa->buf_in_urbs[urb_index]);
			urb_frame_count = __wa_populate_buf_in_urb_isoc(wa,
				buf_in_urb, xfer, seg);
			/* advance frame index to start of next read URB. */
			seg->isoc_frame_index += urb_frame_count;
			total_frames_read += urb_frame_count;

			++(wa->active_buf_in_urbs);
			result = usb_submit_urb(buf_in_urb, GFP_ATOMIC);

			/* skip 0-byte frames. */
			urb_frame_index =
				seg->isoc_frame_offset + seg->isoc_frame_index;
			iso_frame_desc =
				&(xfer->urb->iso_frame_desc[urb_frame_index]);
			while ((seg->isoc_frame_index <
						seg->isoc_frame_count) &&
				 (iso_frame_desc->actual_length == 0)) {
				++(seg->isoc_frame_index);
				++iso_frame_desc;
			}
			++urb_index;

		} while ((result == 0) && (urb_index < WA_MAX_BUF_IN_URBS)
				&& (seg->isoc_frame_index <
						seg->isoc_frame_count));

		if (result < 0) {
			--(wa->active_buf_in_urbs);
			dev_err(dev, "DTI Error: Could not submit buf in URB (%d)",
				result);
			wa_reset_all(wa);
		} else if (data_frame_count > total_frames_read)
			/* If we need to read more frames, set DTI busy. */
			dti_busy = 1;
	} else {
		/* OUT transfer or no more IN data, complete it -- */
		rpipe_ready = rpipe_avail_inc(rpipe);
		done = __wa_xfer_mark_seg_as_done(xfer, seg, WA_SEG_DONE);
	}
	spin_unlock_irqrestore(&xfer->lock, flags);
	if (dti_busy)
		wa->dti_state = WA_DTI_BUF_IN_DATA_PENDING;
	else
		wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;
	if (done)
		wa_xfer_completion(xfer);
	if (rpipe_ready)
		wa_xfer_delayed_run(rpipe);
	wa_xfer_put(xfer);
	return dti_busy;

error_bad_seg:
	spin_unlock_irqrestore(&xfer->lock, flags);
	wa_xfer_put(xfer);
error_parse_buffer:
	return dti_busy;
}

/*
 * Callback for the IN data phase
 *
 * If successful transition state; otherwise, take a note of the
 * error, mark this segment done and try completion.
 *
 * Note we don't access until we are sure that the transfer hasn't
 * been cancelled (ECONNRESET, ENOENT), which could mean that
 * seg->xfer could be already gone.
 */
static void wa_buf_in_cb(struct urb *urb)
{
	struct wa_seg *seg = urb->context;
	struct wa_xfer *xfer = seg->xfer;
	struct wahc *wa;
	struct device *dev;
	struct wa_rpipe *rpipe;
	unsigned rpipe_ready = 0, isoc_data_frame_count = 0;
	unsigned long flags;
	int resubmit_dti = 0, active_buf_in_urbs;
	u8 done = 0;

	/* free the sg if it was used. */
	kfree(urb->sg);
	urb->sg = NULL;

	spin_lock_irqsave(&xfer->lock, flags);
	wa = xfer->wa;
	dev = &wa->usb_iface->dev;
	--(wa->active_buf_in_urbs);
	active_buf_in_urbs = wa->active_buf_in_urbs;

	if (usb_pipeisoc(xfer->urb->pipe)) {
		struct usb_iso_packet_descriptor *iso_frame_desc =
			xfer->urb->iso_frame_desc;
		int	seg_index;

		/*
		 * Find the next isoc frame with data and count how many
		 * frames with data remain.
		 */
		seg_index = seg->isoc_frame_index;
		while (seg_index < seg->isoc_frame_count) {
			const int urb_frame_index =
				seg->isoc_frame_offset + seg_index;

			if (iso_frame_desc[urb_frame_index].actual_length > 0) {
				/* save the index of the next frame with data */
				if (!isoc_data_frame_count)
					seg->isoc_frame_index = seg_index;
				++isoc_data_frame_count;
			}
			++seg_index;
		}
	}
	spin_unlock_irqrestore(&xfer->lock, flags);

	switch (urb->status) {
	case 0:
		spin_lock_irqsave(&xfer->lock, flags);

		seg->result += urb->actual_length;
		if (isoc_data_frame_count > 0) {
			int result, urb_frame_count;

			/* submit a read URB for the next frame with data. */
			urb_frame_count = __wa_populate_buf_in_urb_isoc(wa, urb,
				 xfer, seg);
			/* advance index to start of next read URB. */
			seg->isoc_frame_index += urb_frame_count;
			++(wa->active_buf_in_urbs);
			result = usb_submit_urb(urb, GFP_ATOMIC);
			if (result < 0) {
				--(wa->active_buf_in_urbs);
				dev_err(dev, "DTI Error: Could not submit buf in URB (%d)",
					result);
				wa_reset_all(wa);
			}
			/*
			 * If we are in this callback and
			 * isoc_data_frame_count > 0, it means that the dti_urb
			 * submission was delayed in wa_dti_cb.  Once
			 * we submit the last buf_in_urb, we can submit the
			 * delayed dti_urb.
			 */
			  resubmit_dti = (isoc_data_frame_count ==
							urb_frame_count);
		} else if (active_buf_in_urbs == 0) {
			rpipe = xfer->ep->hcpriv;
			dev_dbg(dev,
				"xfer %p 0x%08X#%u: data in done (%zu bytes)\n",
				xfer, wa_xfer_id(xfer), seg->index,
				seg->result);
			rpipe_ready = rpipe_avail_inc(rpipe);
			done = __wa_xfer_mark_seg_as_done(xfer, seg,
					WA_SEG_DONE);
		}
		spin_unlock_irqrestore(&xfer->lock, flags);
		if (done)
			wa_xfer_completion(xfer);
		if (rpipe_ready)
			wa_xfer_delayed_run(rpipe);
		break;
	case -ECONNRESET:	/* URB unlinked; no need to do anything */
	case -ENOENT:		/* as it was done by the who unlinked us */
		break;
	default:		/* Other errors ... */
		/*
		 * Error on data buf read.  Only resubmit DTI if it hasn't
		 * already been done by previously hitting this error or by a
		 * successful completion of the previous buf_in_urb.
		 */
		resubmit_dti = wa->dti_state != WA_DTI_TRANSFER_RESULT_PENDING;
		spin_lock_irqsave(&xfer->lock, flags);
		rpipe = xfer->ep->hcpriv;
		if (printk_ratelimit())
			dev_err(dev, "xfer %p 0x%08X#%u: data in error %d\n",
				xfer, wa_xfer_id(xfer), seg->index,
				urb->status);
		if (edc_inc(&wa->nep_edc, EDC_MAX_ERRORS,
			    EDC_ERROR_TIMEFRAME)){
			dev_err(dev, "DTO: URB max acceptable errors "
				"exceeded, resetting device\n");
			wa_reset_all(wa);
		}
		seg->result = urb->status;
		rpipe_ready = rpipe_avail_inc(rpipe);
		if (active_buf_in_urbs == 0)
			done = __wa_xfer_mark_seg_as_done(xfer, seg,
				WA_SEG_ERROR);
		else
			__wa_xfer_abort(xfer);
		spin_unlock_irqrestore(&xfer->lock, flags);
		if (done)
			wa_xfer_completion(xfer);
		if (rpipe_ready)
			wa_xfer_delayed_run(rpipe);
	}

	if (resubmit_dti) {
		int result;

		wa->dti_state = WA_DTI_TRANSFER_RESULT_PENDING;

		result = usb_submit_urb(wa->dti_urb, GFP_ATOMIC);
		if (result < 0) {
			dev_err(dev, "DTI Error: Could not submit DTI URB (%d)\n",
				result);
			wa_reset_all(wa);
		}
	}
}

/*
 * Handle an incoming transfer result buffer
 *
 * Given a transfer result buffer, it completes the transfer (possibly
 * scheduling and buffer in read) and then resubmits the DTI URB for a
 * new transfer result read.
 *
 *
 * The xfer_result DTI URB state machine
 *
 * States: OFF | RXR (Read-Xfer-Result) | RBI (Read-Buffer-In)
 *
 * We start in OFF mode, the first xfer_result notification [through
 * wa_handle_notif_xfer()] moves us to RXR by posting the DTI-URB to
 * read.
 *
 * We receive a buffer -- if it is not a xfer_result, we complain and
 * repost the DTI-URB. If it is a xfer_result then do the xfer seg
 * request accounting. If it is an IN segment, we move to RBI and post
 * a BUF-IN-URB to the right buffer. The BUF-IN-URB callback will
 * repost the DTI-URB and move to RXR state. if there was no IN
 * segment, it will repost the DTI-URB.
 *
 * We go back to OFF when we detect a ENOENT or ESHUTDOWN (or too many
 * errors) in the URBs.
 */
static void wa_dti_cb(struct urb *urb)
{
	int result, dti_busy = 0;
	struct wahc *wa = urb->context;
	struct device *dev = &wa->usb_iface->dev;
	u32 xfer_id;
	u8 usb_status;

	BUG_ON(wa->dti_urb != urb);
	switch (wa->dti_urb->status) {
	case 0:
		if (wa->dti_state == WA_DTI_TRANSFER_RESULT_PENDING) {
			struct wa_xfer_result *xfer_result;
			struct wa_xfer *xfer;

			/* We have a xfer result buffer; check it */
			dev_dbg(dev, "DTI: xfer result %d bytes at %p\n",
				urb->actual_length, urb->transfer_buffer);
			if (urb->actual_length != sizeof(*xfer_result)) {
				dev_err(dev, "DTI Error: xfer result--bad size xfer result (%d bytes vs %zu needed)\n",
					urb->actual_length,
					sizeof(*xfer_result));
				break;
			}
			xfer_result = (struct wa_xfer_result *)(wa->dti_buf);
			if (xfer_result->hdr.bLength != sizeof(*xfer_result)) {
				dev_err(dev, "DTI Error: xfer result--bad header length %u\n",
					xfer_result->hdr.bLength);
				break;
			}
			if (xfer_result->hdr.bNotifyType != WA_XFER_RESULT) {
				dev_err(dev, "DTI Error: xfer result--bad header type 0x%02x\n",
					xfer_result->hdr.bNotifyType);
				break;
			}
			xfer_id = le32_to_cpu(xfer_result->dwTransferID);
			usb_status = xfer_result->bTransferStatus & 0x3f;
			if (usb_status == WA_XFER_STATUS_NOT_FOUND) {
				/* taken care of already */
				dev_dbg(dev, "%s: xfer 0x%08X#%u not found.\n",
					__func__, xfer_id,
					xfer_result->bTransferSegment & 0x7f);
				break;
			}
			xfer = wa_xfer_get_by_id(wa, xfer_id);
			if (xfer == NULL) {
				/* FIXME: transaction not found. */
				dev_err(dev, "DTI Error: xfer result--unknown xfer 0x%08x (status 0x%02x)\n",
					xfer_id, usb_status);
				break;
			}
			wa_xfer_result_chew(wa, xfer, xfer_result);
			wa_xfer_put(xfer);
		} else if (wa->dti_state == WA_DTI_ISOC_PACKET_STATUS_PENDING) {
			dti_busy = wa_process_iso_packet_status(wa, urb);
		} else {
			dev_err(dev, "DTI Error: unexpected EP state = %d\n",
				wa->dti_state);
		}
		break;
	case -ENOENT:		/* (we killed the URB)...so, no broadcast */
	case -ESHUTDOWN:	/* going away! */
		dev_dbg(dev, "DTI: going down! %d\n", urb->status);
		goto out;
	default:
		/* Unknown error */
		if (edc_inc(&wa->dti_edc, EDC_MAX_ERRORS,
			    EDC_ERROR_TIMEFRAME)) {
			dev_err(dev, "DTI: URB max acceptable errors "
				"exceeded, resetting device\n");
			wa_reset_all(wa);
			goto out;
		}
		if (printk_ratelimit())
			dev_err(dev, "DTI: URB error %d\n", urb->status);
		break;
	}

	/* Resubmit the DTI URB if we are not busy processing isoc in frames. */
	if (!dti_busy) {
		result = usb_submit_urb(wa->dti_urb, GFP_ATOMIC);
		if (result < 0) {
			dev_err(dev, "DTI Error: Could not submit DTI URB (%d)\n",
				result);
			wa_reset_all(wa);
		}
	}
out:
	return;
}

/*
 * Initialize the DTI URB for reading transfer result notifications and also
 * the buffer-in URB, for reading buffers. Then we just submit the DTI URB.
 */
int wa_dti_start(struct wahc *wa)
{
	const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;
	struct device *dev = &wa->usb_iface->dev;
	int result = -ENOMEM, index;

	if (wa->dti_urb != NULL)	/* DTI URB already started */
		goto out;

	wa->dti_urb = usb_alloc_urb(0, GFP_KERNEL);
	if (wa->dti_urb == NULL) {
		dev_err(dev, "Can't allocate DTI URB\n");
		goto error_dti_urb_alloc;
	}
	usb_fill_bulk_urb(
		wa->dti_urb, wa->usb_dev,
		usb_rcvbulkpipe(wa->usb_dev, 0x80 | dti_epd->bEndpointAddress),
		wa->dti_buf, wa->dti_buf_size,
		wa_dti_cb, wa);

	/* init the buf in URBs */
	for (index = 0; index < WA_MAX_BUF_IN_URBS; ++index) {
		usb_fill_bulk_urb(
			&(wa->buf_in_urbs[index]), wa->usb_dev,
			usb_rcvbulkpipe(wa->usb_dev,
				0x80 | dti_epd->bEndpointAddress),
			NULL, 0, wa_buf_in_cb, wa);
	}
	result = usb_submit_urb(wa->dti_urb, GFP_KERNEL);
	if (result < 0) {
		dev_err(dev, "DTI Error: Could not submit DTI URB (%d) resetting\n",
			result);
		goto error_dti_urb_submit;
	}
out:
	return 0;

error_dti_urb_submit:
	usb_put_urb(wa->dti_urb);
	wa->dti_urb = NULL;
error_dti_urb_alloc:
	return result;
}
EXPORT_SYMBOL_GPL(wa_dti_start);
/*
 * Transfer complete notification
 *
 * Called from the notif.c code. We get a notification on EP2 saying
 * that some endpoint has some transfer result data available. We are
 * about to read it.
 *
 * To speed up things, we always have a URB reading the DTI URB; we
 * don't really set it up and start it until the first xfer complete
 * notification arrives, which is what we do here.
 *
 * Follow up in wa_dti_cb(), as that's where the whole state
 * machine starts.
 *
 * @wa shall be referenced
 */
void wa_handle_notif_xfer(struct wahc *wa, struct wa_notif_hdr *notif_hdr)
{
	struct device *dev = &wa->usb_iface->dev;
	struct wa_notif_xfer *notif_xfer;
	const struct usb_endpoint_descriptor *dti_epd = wa->dti_epd;

	notif_xfer = container_of(notif_hdr, struct wa_notif_xfer, hdr);
	BUG_ON(notif_hdr->bNotifyType != WA_NOTIF_TRANSFER);

	if ((0x80 | notif_xfer->bEndpoint) != dti_epd->bEndpointAddress) {
		/* FIXME: hardcoded limitation, adapt */
		dev_err(dev, "BUG: DTI ep is %u, not %u (hack me)\n",
			notif_xfer->bEndpoint, dti_epd->bEndpointAddress);
		goto error;
	}

	/* attempt to start the DTI ep processing. */
	if (wa_dti_start(wa) < 0)
		goto error;

	return;

error:
	wa_reset_all(wa);
}
