summaryrefslogtreecommitdiff
path: root/drivers/usb/wusbcore/wa-hc.h
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-hc.h
parent8114fabc94cc94e4eb50050a99f7ee5573fa37d9 (diff)
downloadlinux-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-hc.h')
-rw-r--r--drivers/usb/wusbcore/wa-hc.h10
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h
index b44aca3..41afaa6 100644
--- a/drivers/usb/wusbcore/wa-hc.h
+++ b/drivers/usb/wusbcore/wa-hc.h
@@ -117,6 +117,7 @@ struct wa_rpipe {
struct wahc *wa;
spinlock_t seg_lock;
struct list_head seg_list;
+ struct list_head list_node;
atomic_t segs_available;
u8 buffer[1]; /* For reads/writes on USB */
};
@@ -183,7 +184,8 @@ struct wahc {
u16 rpipes;
unsigned long *rpipe_bm; /* rpipe usage bitmap */
- spinlock_t rpipe_bm_lock; /* protect rpipe_bm */
+ struct list_head rpipe_delayed_list; /* delayed RPIPES. */
+ spinlock_t rpipe_lock; /* protect rpipe_bm and delayed list */
struct mutex rpipe_mutex; /* assigning resources to endpoints */
/*
@@ -201,6 +203,8 @@ struct wahc {
void *dti_buf;
size_t dti_buf_size;
+ unsigned long dto_in_use; /* protect dto endoint serialization. */
+
s32 status; /* For reading status */
struct list_head xfer_list;
@@ -253,7 +257,8 @@ static inline void wa_nep_disarm(struct wahc *wa)
/* RPipes */
static inline void wa_rpipe_init(struct wahc *wa)
{
- spin_lock_init(&wa->rpipe_bm_lock);
+ INIT_LIST_HEAD(&wa->rpipe_delayed_list);
+ spin_lock_init(&wa->rpipe_lock);
mutex_init(&wa->rpipe_mutex);
}
@@ -270,6 +275,7 @@ static inline void wa_init(struct wahc *wa)
spin_lock_init(&wa->xfer_list_lock);
INIT_WORK(&wa->xfer_enqueue_work, wa_urb_enqueue_run);
INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run);
+ wa->dto_in_use = 0;
atomic_set(&wa->xfer_id_count, 1);
}