summaryrefslogtreecommitdiffstats
path: root/drivers/usb/wusbcore/wa-hc.h
diff options
context:
space:
mode:
authorThomas Pugliese <thomas.pugliese@gmail.com>2013-08-15 12:21:30 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-15 17:35:31 -0700
commit6d33f7bb8c3863e54f8bdede0a2bf97a3585ac20 (patch)
treeb183a4ab10a38356822932cffced7d96e745ebff /drivers/usb/wusbcore/wa-hc.h
parent224563b6ce034b82f8511969d9496113da34fb2c (diff)
downloadop-kernel-dev-6d33f7bb8c3863e54f8bdede0a2bf97a3585ac20.zip
op-kernel-dev-6d33f7bb8c3863e54f8bdede0a2bf97a3585ac20.tar.gz
USB: WUSBCORE: clear RPIPE stall for control endpoints
When the HWA encounters a STALL on a control endpoint, it should clear the RPIPE_STALL feature on the RPIPE before processing the next transfer request. Otherwise, all transfer requests on that endpoint after the first STALL will fail because the RPIPE is still in the halted state. This also removes the unneccessary call to spin_lock_irqsave for a nested lock that was present in the first patch. 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.h15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/usb/wusbcore/wa-hc.h b/drivers/usb/wusbcore/wa-hc.h
index d6bea3e..cf250c2 100644
--- a/drivers/usb/wusbcore/wa-hc.h
+++ b/drivers/usb/wusbcore/wa-hc.h
@@ -91,6 +91,7 @@
struct wusbhc;
struct wahc;
extern void wa_urb_enqueue_run(struct work_struct *ws);
+extern void wa_process_errored_transfers_run(struct work_struct *ws);
/**
* RPipe instance
@@ -190,8 +191,14 @@ struct wahc {
struct list_head xfer_list;
struct list_head xfer_delayed_list;
+ struct list_head xfer_errored_list;
+ /*
+ * lock for the above xfer lists. Can be taken while a xfer->lock is
+ * held but not in the reverse order.
+ */
spinlock_t xfer_list_lock;
- struct work_struct xfer_work;
+ struct work_struct xfer_enqueue_work;
+ struct work_struct xfer_error_work;
atomic_t xfer_id_count;
};
@@ -244,8 +251,10 @@ static inline void wa_init(struct wahc *wa)
edc_init(&wa->dti_edc);
INIT_LIST_HEAD(&wa->xfer_list);
INIT_LIST_HEAD(&wa->xfer_delayed_list);
+ INIT_LIST_HEAD(&wa->xfer_errored_list);
spin_lock_init(&wa->xfer_list_lock);
- INIT_WORK(&wa->xfer_work, wa_urb_enqueue_run);
+ INIT_WORK(&wa->xfer_enqueue_work, wa_urb_enqueue_run);
+ INIT_WORK(&wa->xfer_error_work, wa_process_errored_transfers_run);
atomic_set(&wa->xfer_id_count, 1);
}
@@ -269,6 +278,8 @@ static inline void rpipe_put(struct wa_rpipe *rpipe)
}
extern void rpipe_ep_disable(struct wahc *, struct usb_host_endpoint *);
+extern void rpipe_clear_feature_stalled(struct wahc *,
+ struct usb_host_endpoint *);
extern int wa_rpipes_create(struct wahc *);
extern void wa_rpipes_destroy(struct wahc *);
static inline void rpipe_avail_dec(struct wa_rpipe *rpipe)
OpenPOWER on IntegriCloud