aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/isp1760-hcd.c
diff options
context:
space:
mode:
authorArvid Brodin <arvid.brodin@enea.com>2011-11-23 12:10:41 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-26 23:02:47 -0500
commite08f6a2790aaf3563e7800399321c0fb9a6c6636 (patch)
treefd15cb23fc0f36fd687d3ec585af27c7d6721c80 /drivers/usb/host/isp1760-hcd.c
parentc8421147926fcacf53081a36438a0bed394da9f5 (diff)
usb/isp1760: Simpler queue head list code.
Small code refactoring to ease the real fix in patch #2. Signed-off-by: Arvid Brodin <arvid.brodin@enea.com> Tested-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/usb/host/isp1760-hcd.c')
-rw-r--r--drivers/usb/host/isp1760-hcd.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c
index 27dfab80ed8f..a760fbf18ebe 100644
--- a/drivers/usb/host/isp1760-hcd.c
+++ b/drivers/usb/host/isp1760-hcd.c
@@ -32,6 +32,13 @@ static struct kmem_cache *qtd_cachep;
32static struct kmem_cache *qh_cachep; 32static struct kmem_cache *qh_cachep;
33static struct kmem_cache *urb_listitem_cachep; 33static struct kmem_cache *urb_listitem_cachep;
34 34
35enum queue_head_types {
36 QH_CONTROL,
37 QH_BULK,
38 QH_INTERRUPT,
39 QH_END
40};
41
35struct isp1760_hcd { 42struct isp1760_hcd {
36 u32 hcs_params; 43 u32 hcs_params;
37 spinlock_t lock; 44 spinlock_t lock;
@@ -40,7 +47,7 @@ struct isp1760_hcd {
40 struct slotinfo int_slots[32]; 47 struct slotinfo int_slots[32];
41 int int_done_map; 48 int int_done_map;
42 struct memory_chunk memory_pool[BLOCKS]; 49 struct memory_chunk memory_pool[BLOCKS];
43 struct list_head controlqhs, bulkqhs, interruptqhs; 50 struct list_head qh_list[QH_END];
44 51
45 /* periodic schedule support */ 52 /* periodic schedule support */
46#define DEFAULT_I_TDPS 1024 53#define DEFAULT_I_TDPS 1024
@@ -406,12 +413,12 @@ static int priv_init(struct usb_hcd *hcd)
406{ 413{
407 struct isp1760_hcd *priv = hcd_to_priv(hcd); 414 struct isp1760_hcd *priv = hcd_to_priv(hcd);
408 u32 hcc_params; 415 u32 hcc_params;
416 int i;
409 417
410 spin_lock_init(&priv->lock); 418 spin_lock_init(&priv->lock);
411 419
412 INIT_LIST_HEAD(&priv->interruptqhs); 420 for (i = 0; i < QH_END; i++)
413 INIT_LIST_HEAD(&priv->controlqhs); 421 INIT_LIST_HEAD(&priv->qh_list[i]);
414 INIT_LIST_HEAD(&priv->bulkqhs);
415 422
416 /* 423 /*
417 * hw default: 1K periodic list heads, one per frame. 424 * hw default: 1K periodic list heads, one per frame.
@@ -933,6 +940,7 @@ void schedule_ptds(struct usb_hcd *hcd)
933 struct usb_host_endpoint *ep; 940 struct usb_host_endpoint *ep;
934 LIST_HEAD(urb_list); 941 LIST_HEAD(urb_list);
935 struct urb_listitem *urb_listitem, *urb_listitem_next; 942 struct urb_listitem *urb_listitem, *urb_listitem_next;
943 int i;
936 944
937 if (!hcd) { 945 if (!hcd) {
938 WARN_ON(1); 946 WARN_ON(1);
@@ -944,8 +952,8 @@ void schedule_ptds(struct usb_hcd *hcd)
944 /* 952 /*
945 * check finished/retired xfers, transfer payloads, call urb_done() 953 * check finished/retired xfers, transfer payloads, call urb_done()
946 */ 954 */
947 ep_queue = &priv->interruptqhs; 955 for (i = 0; i < QH_END; i++) {
948 while (ep_queue) { 956 ep_queue = &priv->qh_list[i];
949 list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) { 957 list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) {
950 ep = list_entry(qh->qtd_list.next, struct isp1760_qtd, 958 ep = list_entry(qh->qtd_list.next, struct isp1760_qtd,
951 qtd_list)->urb->ep; 959 qtd_list)->urb->ep;
@@ -959,13 +967,6 @@ void schedule_ptds(struct usb_hcd *hcd)
959 } 967 }
960 } 968 }
961 } 969 }
962
963 if (ep_queue == &priv->interruptqhs)
964 ep_queue = &priv->controlqhs;
965 else if (ep_queue == &priv->controlqhs)
966 ep_queue = &priv->bulkqhs;
967 else
968 ep_queue = NULL;
969 } 970 }
970 971
971 list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list, 972 list_for_each_entry_safe(urb_listitem, urb_listitem_next, &urb_list,
@@ -998,17 +999,10 @@ void schedule_ptds(struct usb_hcd *hcd)
998 * 999 *
999 * I'm sure this scheme could be improved upon! 1000 * I'm sure this scheme could be improved upon!
1000 */ 1001 */
1001 ep_queue = &priv->controlqhs; 1002 for (i = 0; i < QH_END; i++) {
1002 while (ep_queue) { 1003 ep_queue = &priv->qh_list[i];
1003 list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list) 1004 list_for_each_entry_safe(qh, qh_next, ep_queue, qh_list)
1004 enqueue_qtds(hcd, qh); 1005 enqueue_qtds(hcd, qh);
1005
1006 if (ep_queue == &priv->controlqhs)
1007 ep_queue = &priv->interruptqhs;
1008 else if (ep_queue == &priv->interruptqhs)
1009 ep_queue = &priv->bulkqhs;
1010 else
1011 ep_queue = NULL;
1012 } 1006 }
1013} 1007}
1014 1008
@@ -1543,16 +1537,16 @@ static int isp1760_urb_enqueue(struct usb_hcd *hcd, struct urb *urb,
1543 1537
1544 switch (usb_pipetype(urb->pipe)) { 1538 switch (usb_pipetype(urb->pipe)) {
1545 case PIPE_CONTROL: 1539 case PIPE_CONTROL:
1546 ep_queue = &priv->controlqhs; 1540 ep_queue = &priv->qh_list[QH_CONTROL];
1547 break; 1541 break;
1548 case PIPE_BULK: 1542 case PIPE_BULK:
1549 ep_queue = &priv->bulkqhs; 1543 ep_queue = &priv->qh_list[QH_BULK];
1550 break; 1544 break;
1551 case PIPE_INTERRUPT: 1545 case PIPE_INTERRUPT:
1552 if (urb->interval < 0) 1546 if (urb->interval < 0)
1553 return -EINVAL; 1547 return -EINVAL;
1554 /* FIXME: Check bandwidth */ 1548 /* FIXME: Check bandwidth */
1555 ep_queue = &priv->interruptqhs; 1549 ep_queue = &priv->qh_list[QH_INTERRUPT];
1556 break; 1550 break;
1557 case PIPE_ISOCHRONOUS: 1551 case PIPE_ISOCHRONOUS:
1558 dev_err(hcd->self.controller, "%s: isochronous USB packets " 1552 dev_err(hcd->self.controller, "%s: isochronous USB packets "