summaryrefslogtreecommitdiff
path: root/drivers/usb/wusbcore/wa-rpipe.c
diff options
context:
space:
mode:
authorThomas Pugliese <thomas.pugliese@gmail.com>2013-10-07 15:53:57 (GMT)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-19 12:19:21 (GMT)
commit679ee475a1c19243c8f50a5a76f6b7519b24c1a3 (patch)
treea1cee61ed77804e87b138621bc77f90cc24db11c /drivers/usb/wusbcore/wa-rpipe.c
parent8114fabc94cc94e4eb50050a99f7ee5573fa37d9 (diff)
downloadlinux-fsl-qoriq-679ee475a1c19243c8f50a5a76f6b7519b24c1a3.tar.xz
usb: wusbcore: serialize access to the HWA data out endpoint
This patch serializes access to the HWA data transfer out (DTO) endpoint. This prevents a situation where two transfer requests being sent concurrently to separate downstream endpoints could interleave their transfer request and transfer data packets causing data corruption. The transfer processing code will now attempt to acquire the DTO resource before sending a transfer to the HWA. If it cannot acquire the resource, the RPIPE that the transfer is assigned to will be placed on a waiting list. When the DTO resource is released, the actor releasing the resource will serivce the RPIPEs that are waiting. Signed-off-by: Thomas Pugliese <thomas.pugliese@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/wusbcore/wa-rpipe.c')
-rw-r--r--drivers/usb/wusbcore/wa-rpipe.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c
index 554b16b..50de1d2 100644
--- a/drivers/usb/wusbcore/wa-rpipe.c
+++ b/drivers/usb/wusbcore/wa-rpipe.c
@@ -143,17 +143,18 @@ static void rpipe_init(struct wa_rpipe *rpipe)
kref_init(&rpipe->refcnt);
spin_lock_init(&rpipe->seg_lock);
INIT_LIST_HEAD(&rpipe->seg_list);
+ INIT_LIST_HEAD(&rpipe->list_node);
}
static unsigned rpipe_get_idx(struct wahc *wa, unsigned rpipe_idx)
{
unsigned long flags;
- spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
+ spin_lock_irqsave(&wa->rpipe_lock, flags);
rpipe_idx = find_next_zero_bit(wa->rpipe_bm, wa->rpipes, rpipe_idx);
if (rpipe_idx < wa->rpipes)
set_bit(rpipe_idx, wa->rpipe_bm);
- spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
+ spin_unlock_irqrestore(&wa->rpipe_lock, flags);
return rpipe_idx;
}
@@ -162,9 +163,9 @@ static void rpipe_put_idx(struct wahc *wa, unsigned rpipe_idx)
{
unsigned long flags;
- spin_lock_irqsave(&wa->rpipe_bm_lock, flags);
+ spin_lock_irqsave(&wa->rpipe_lock, flags);
clear_bit(rpipe_idx, wa->rpipe_bm);
- spin_unlock_irqrestore(&wa->rpipe_bm_lock, flags);
+ spin_unlock_irqrestore(&wa->rpipe_lock, flags);
}
void rpipe_destroy(struct kref *_rpipe)