Commit e08f6a27 authored by Arvid Brodin's avatar Arvid Brodin Committed by Greg Kroah-Hartman

usb/isp1760: Simpler queue head list code.

Small code refactoring to ease the real fix in patch #2.
Signed-off-by: default avatarArvid Brodin <arvid.brodin@enea.com>
Tested-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent c8421147
......@@ -32,6 +32,13 @@ static struct kmem_cache *qtd_cachep;
static struct kmem_cache *qh_cachep;
static struct kmem_cache *urb_listitem_cachep;
enum queue_head_types {
QH_CONTROL,
QH_BULK,
QH_INTERRUPT,
QH_END
};
struct isp1760_hcd {
u32 hcs_params;
spinlock_t lock;
......@@ -40,7 +47,7 @@ struct isp1760_hcd {
struct slotinfo int_slots[32];
int int_done_map;
struct memory_chunk memory_pool[BLOCKS];
struct list_head controlqhs, bulkqhs, interruptqhs;
struct list_head qh_list[QH_END];
/* periodic schedule support */
#define DEFAULT_I_TDPS 1024
......@@ -406,12 +413,12 @@ static int priv_init(struct usb_hcd *hcd)
{
struct isp1760_hcd *priv = hcd_to_priv(hcd);
u32 hcc_params;
int i;
spin_lock_init(&priv->lock);
INIT_LIST_HEAD(&priv->interruptqhs);
INIT_LIST_HEAD(&priv->controlqhs);
INIT_LIST_HEAD(&priv->bulkqhs);
for (i = 0; i < QH_END; i++)
INIT_LIST_HEAD(&priv->qh_list[i]);
/*
* hw default: 1K periodic list heads, one per frame.
......@@ -933,6 +940,7 @@ void schedule_ptds(struct usb_hcd *hcd)
struct usb_host_endpoint *ep;
LIST_HEAD(urb_list);
struct urb_listitem *urb_listitem, *urb_listitem_next;
int i;
if (!hcd) {
WARN_ON(1);
......@@ -944,8 +952,8 @@ void schedule_ptds(struct usb_hcd *hcd)
/*
* check finished/retired xfers, transfer payloads, call urb_done()
*/
ep_queue = &priv->interruptqhs;
while (ep_queue) {
for (i = 0; i < QH_END; i++) {
ep_queue = &priv->qh_list[i];
list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) {
ep = list_entry(qh->qtd_list.next, struct isp1760_qtd,
qtd_list)->urb->ep;
......@@ -959,13 +967,6 @@ void schedule_ptds(struct usb_hcd *hcd)
}
}
}
if (ep_queue == &priv->interruptqhs)
ep_queue = &priv->controlqhs;
else if (ep_queue == &priv->controlqhs)
ep_queue = &priv->bulkqhs;
else
ep_queue = NULL;
}
list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list,
......@@ -998,17 +999,10 @@ void schedule_ptds(struct usb_hcd *hcd)
*
* I'm sure this scheme could be improved upon!
*/
ep_queue = &priv->controlqhs;
while (ep_queue) {
for (i = 0; i < QH_END; i++) {
ep_queue = &priv->qh_list[i];
list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list)
enqueue_qtds(hcd, qh);
if (ep_queue == &priv->controlqhs)
ep_queue = &priv->interruptqhs;
else if (ep_queue == &priv->interruptqhs)
ep_queue = &priv->bulkqhs;
else
ep_queue = NULL;
}
}
......@@ -1543,16 +1537,16 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
switch (usb_pipetype(urb->pipe)) {
case PIPE_CONTROL:
ep_queue = &priv->controlqhs;
ep_queue = &priv->qh_list[QH_CONTROL];
break;
case PIPE_BULK:
ep_queue = &priv->bulkqhs;
ep_queue = &priv->qh_list[QH_BULK];
break;
case PIPE_INTERRUPT:
if (urb->interval < 0)
return -EINVAL;
/* FIXME: Check bandwidth */
ep_queue = &priv->interruptqhs;
ep_queue = &priv->qh_list[QH_INTERRUPT];
break;
case PIPE_ISOCHRONOUS:
dev_err(hcd->self.controller, "%s: isochronous USB packets "
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment