summaryrefslogtreecommitdiffstats
path: root/drivers/usb/wusbcore/wa-rpipe.c
diff options
context:
space:
mode:
authorThomas Pugliese <thomas.pugliese@gmail.com>2013-10-07 10:53:57 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-19 05:19:21 -0700
commit679ee475a1c19243c8f50a5a76f6b7519b24c1a3 (patch)
treea1cee61ed77804e87b138621bc77f90cc24db11c /drivers/usb/wusbcore/wa-rpipe.c
parent8114fabc94cc94e4eb50050a99f7ee5573fa37d9 (diff)
downloadlinux-679ee475a1c19243c8f50a5a76f6b7519b24c1a3.tar.gz
linux-679ee475a1c19243c8f50a5a76f6b7519b24c1a3.tar.bz2
linux-679ee475a1c19243c8f50a5a76f6b7519b24c1a3.zip
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 554b16bd22f1..50de1d2c7b72 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)