diff options
author | Thomas Pugliese <thomas.pugliese@gmail.com> | 2013-10-07 19:53:57 +0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-19 16:19:21 +0400 |
commit | 679ee475a1c19243c8f50a5a76f6b7519b24c1a3 (patch) | |
tree | a1cee61ed77804e87b138621bc77f90cc24db11c /drivers/usb/wusbcore/wa-hc.h | |
parent | 8114fabc94cc94e4eb50050a99f7ee5573fa37d9 (diff) | |
download | linux-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.h | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h index b44aca3f25dd..41afaa6d01d2 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); } |