// SPDX-License-Identifier: GPL-2.0
/*
 * WUSB Wire Adapter
 * Data transfer and URB enqueing
 *
 * Copyright (C) 2005-2006 Intel Corporation
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *
 * 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, seg_index = 0;
			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);
			/* skip done segs. */
			while (seg_index < xfer->segs) {
				struct wa_seg *seg = xfer->seg[seg_index];

				if ((seg->status == WA_SEG_DONE) ||
					(seg->status == WA_SEG_ERROR)) {
					++seg_index;
				} else {
					break;
				}
			}
			/* mark remaining segs as aborted. */
			wa_complete_remaining_xfer_segs(xfer, seg_index,
				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));
		}
		result = -ENOMEM;
		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.
		 */
		/* fall through */
		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;
	rpipe = xfer->ep->hcpriv;

	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) {
			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);
		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)
		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);
}
