diff options
Diffstat (limited to 'drivers/usb/host/u132-hcd.c')
-rw-r--r-- | drivers/usb/host/u132-hcd.c | 390 |
1 files changed, 227 insertions, 163 deletions
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index e98df2ee990..ac283b09a63 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | #include <linux/platform_device.h> | 53 | #include <linux/platform_device.h> |
54 | #include <linux/pci_ids.h> | 54 | #include <linux/mutex.h> |
55 | #include <asm/io.h> | 55 | #include <asm/io.h> |
56 | #include <asm/irq.h> | 56 | #include <asm/irq.h> |
57 | #include <asm/system.h> | 57 | #include <asm/system.h> |
@@ -83,7 +83,7 @@ static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); | |||
83 | * u132_module_lock exists to protect access to global variables | 83 | * u132_module_lock exists to protect access to global variables |
84 | * | 84 | * |
85 | */ | 85 | */ |
86 | static struct semaphore u132_module_lock; | 86 | static struct mutex u132_module_lock; |
87 | static int u132_exiting = 0; | 87 | static int u132_exiting = 0; |
88 | static int u132_instances = 0; | 88 | static int u132_instances = 0; |
89 | static struct list_head u132_static_list; | 89 | static struct list_head u132_static_list; |
@@ -183,7 +183,7 @@ struct u132_ring { | |||
183 | struct u132 { | 183 | struct u132 { |
184 | struct kref kref; | 184 | struct kref kref; |
185 | struct list_head u132_list; | 185 | struct list_head u132_list; |
186 | struct semaphore sw_lock; | 186 | struct mutex sw_lock; |
187 | struct semaphore scheduler_lock; | 187 | struct semaphore scheduler_lock; |
188 | struct u132_platform_data *board; | 188 | struct u132_platform_data *board; |
189 | struct platform_device *platform_dev; | 189 | struct platform_device *platform_dev; |
@@ -258,10 +258,10 @@ static void u132_hcd_delete(struct kref *kref) | |||
258 | struct platform_device *pdev = u132->platform_dev; | 258 | struct platform_device *pdev = u132->platform_dev; |
259 | struct usb_hcd *hcd = u132_to_hcd(u132); | 259 | struct usb_hcd *hcd = u132_to_hcd(u132); |
260 | u132->going += 1; | 260 | u132->going += 1; |
261 | down(&u132_module_lock); | 261 | mutex_lock(&u132_module_lock); |
262 | list_del_init(&u132->u132_list); | 262 | list_del_init(&u132->u132_list); |
263 | u132_instances -= 1; | 263 | u132_instances -= 1; |
264 | up(&u132_module_lock); | 264 | mutex_unlock(&u132_module_lock); |
265 | dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" | 265 | dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" |
266 | "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); | 266 | "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); |
267 | usb_put_hcd(hcd); | 267 | usb_put_hcd(hcd); |
@@ -492,20 +492,20 @@ static void u132_hcd_monitor_work(struct work_struct *work) | |||
492 | return; | 492 | return; |
493 | } else { | 493 | } else { |
494 | int retval; | 494 | int retval; |
495 | down(&u132->sw_lock); | 495 | mutex_lock(&u132->sw_lock); |
496 | retval = read_roothub_info(u132); | 496 | retval = read_roothub_info(u132); |
497 | if (retval) { | 497 | if (retval) { |
498 | struct usb_hcd *hcd = u132_to_hcd(u132); | 498 | struct usb_hcd *hcd = u132_to_hcd(u132); |
499 | u132_disable(u132); | 499 | u132_disable(u132); |
500 | u132->going = 1; | 500 | u132->going = 1; |
501 | up(&u132->sw_lock); | 501 | mutex_unlock(&u132->sw_lock); |
502 | usb_hc_died(hcd); | 502 | usb_hc_died(hcd); |
503 | ftdi_elan_gone_away(u132->platform_dev); | 503 | ftdi_elan_gone_away(u132->platform_dev); |
504 | u132_monitor_put_kref(u132); | 504 | u132_monitor_put_kref(u132); |
505 | return; | 505 | return; |
506 | } else { | 506 | } else { |
507 | u132_monitor_requeue_work(u132, 500); | 507 | u132_monitor_requeue_work(u132, 500); |
508 | up(&u132->sw_lock); | 508 | mutex_unlock(&u132->sw_lock); |
509 | return; | 509 | return; |
510 | } | 510 | } |
511 | } | 511 | } |
@@ -518,9 +518,8 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
518 | unsigned long irqs; | 518 | unsigned long irqs; |
519 | struct usb_hcd *hcd = u132_to_hcd(u132); | 519 | struct usb_hcd *hcd = u132_to_hcd(u132); |
520 | urb->error_count = 0; | 520 | urb->error_count = 0; |
521 | urb->status = status; | ||
522 | urb->hcpriv = NULL; | ||
523 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 521 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
522 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
524 | endp->queue_next += 1; | 523 | endp->queue_next += 1; |
525 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { | 524 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { |
526 | endp->active = 0; | 525 | endp->active = 0; |
@@ -542,7 +541,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
542 | u132_ring_queue_work(u132, ring, 0); | 541 | u132_ring_queue_work(u132, ring, 0); |
543 | up(&u132->scheduler_lock); | 542 | up(&u132->scheduler_lock); |
544 | u132_endp_put_kref(u132, endp); | 543 | u132_endp_put_kref(u132, endp); |
545 | usb_hcd_giveback_urb(hcd, urb); | 544 | usb_hcd_giveback_urb(hcd, urb, status); |
546 | return; | 545 | return; |
547 | } | 546 | } |
548 | 547 | ||
@@ -558,9 +557,8 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
558 | unsigned long irqs; | 557 | unsigned long irqs; |
559 | struct usb_hcd *hcd = u132_to_hcd(u132); | 558 | struct usb_hcd *hcd = u132_to_hcd(u132); |
560 | urb->error_count = 0; | 559 | urb->error_count = 0; |
561 | urb->status = status; | ||
562 | urb->hcpriv = NULL; | ||
563 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 560 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
561 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
564 | endp->queue_next += 1; | 562 | endp->queue_next += 1; |
565 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { | 563 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { |
566 | endp->active = 0; | 564 | endp->active = 0; |
@@ -575,7 +573,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
575 | endp->active = 0; | 573 | endp->active = 0; |
576 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 574 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
577 | kfree(urbq); | 575 | kfree(urbq); |
578 | } usb_hcd_giveback_urb(hcd, urb); | 576 | } usb_hcd_giveback_urb(hcd, urb, status); |
579 | return; | 577 | return; |
580 | } | 578 | } |
581 | 579 | ||
@@ -645,12 +643,12 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
645 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 643 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
646 | return; | 644 | return; |
647 | } else if (u132->going > 0) { | 645 | } else if (u132->going > 0) { |
648 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 646 | dev_err(&u132->platform_dev->dev, "device is being removed " |
649 | "%p status=%d\n", urb, urb->status); | 647 | "urb=%p\n", urb); |
650 | up(&u132->scheduler_lock); | 648 | up(&u132->scheduler_lock); |
651 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 649 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
652 | return; | 650 | return; |
653 | } else if (urb->status == -EINPROGRESS) { | 651 | } else if (!urb->unlinked) { |
654 | struct u132_ring *ring = endp->ring; | 652 | struct u132_ring *ring = endp->ring; |
655 | u8 *u = urb->transfer_buffer + urb->actual_length; | 653 | u8 *u = urb->transfer_buffer + urb->actual_length; |
656 | u8 *b = buf; | 654 | u8 *b = buf; |
@@ -716,10 +714,10 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
716 | return; | 714 | return; |
717 | } | 715 | } |
718 | } else { | 716 | } else { |
719 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 717 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
720 | "s=%d\n", urb, urb->status); | 718 | "unlinked=%d\n", urb, urb->unlinked); |
721 | up(&u132->scheduler_lock); | 719 | up(&u132->scheduler_lock); |
722 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 720 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
723 | return; | 721 | return; |
724 | } | 722 | } |
725 | } | 723 | } |
@@ -744,12 +742,12 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
744 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 742 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
745 | return; | 743 | return; |
746 | } else if (u132->going > 0) { | 744 | } else if (u132->going > 0) { |
747 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 745 | dev_err(&u132->platform_dev->dev, "device is being removed " |
748 | "%p status=%d\n", urb, urb->status); | 746 | "urb=%p\n", urb); |
749 | up(&u132->scheduler_lock); | 747 | up(&u132->scheduler_lock); |
750 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 748 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
751 | return; | 749 | return; |
752 | } else if (urb->status == -EINPROGRESS) { | 750 | } else if (!urb->unlinked) { |
753 | struct u132_ring *ring = endp->ring; | 751 | struct u132_ring *ring = endp->ring; |
754 | urb->actual_length += len; | 752 | urb->actual_length += len; |
755 | endp->toggle_bits = toggle_bits; | 753 | endp->toggle_bits = toggle_bits; |
@@ -768,10 +766,10 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
768 | return; | 766 | return; |
769 | } | 767 | } |
770 | } else { | 768 | } else { |
771 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 769 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
772 | "s=%d\n", urb, urb->status); | 770 | "unlinked=%d\n", urb, urb->unlinked); |
773 | up(&u132->scheduler_lock); | 771 | up(&u132->scheduler_lock); |
774 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 772 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
775 | return; | 773 | return; |
776 | } | 774 | } |
777 | } | 775 | } |
@@ -797,12 +795,12 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
797 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 795 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
798 | return; | 796 | return; |
799 | } else if (u132->going > 0) { | 797 | } else if (u132->going > 0) { |
800 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 798 | dev_err(&u132->platform_dev->dev, "device is being removed " |
801 | "%p status=%d\n", urb, urb->status); | 799 | "urb=%p\n", urb); |
802 | up(&u132->scheduler_lock); | 800 | up(&u132->scheduler_lock); |
803 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 801 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
804 | return; | 802 | return; |
805 | } else if (urb->status == -EINPROGRESS) { | 803 | } else if (!urb->unlinked) { |
806 | struct u132_ring *ring = endp->ring; | 804 | struct u132_ring *ring = endp->ring; |
807 | u8 *u = urb->transfer_buffer + urb->actual_length; | 805 | u8 *u = urb->transfer_buffer + urb->actual_length; |
808 | u8 *b = buf; | 806 | u8 *b = buf; |
@@ -871,10 +869,10 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
871 | return; | 869 | return; |
872 | } | 870 | } |
873 | } else { | 871 | } else { |
874 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 872 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
875 | "s=%d\n", urb, urb->status); | 873 | "unlinked=%d\n", urb, urb->unlinked); |
876 | up(&u132->scheduler_lock); | 874 | up(&u132->scheduler_lock); |
877 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 875 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
878 | return; | 876 | return; |
879 | } | 877 | } |
880 | } | 878 | } |
@@ -898,20 +896,20 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
898 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 896 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
899 | return; | 897 | return; |
900 | } else if (u132->going > 0) { | 898 | } else if (u132->going > 0) { |
901 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 899 | dev_err(&u132->platform_dev->dev, "device is being removed " |
902 | "%p status=%d\n", urb, urb->status); | 900 | "urb=%p\n", urb); |
903 | up(&u132->scheduler_lock); | 901 | up(&u132->scheduler_lock); |
904 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 902 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
905 | return; | 903 | return; |
906 | } else if (urb->status == -EINPROGRESS) { | 904 | } else if (!urb->unlinked) { |
907 | up(&u132->scheduler_lock); | 905 | up(&u132->scheduler_lock); |
908 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 906 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
909 | return; | 907 | return; |
910 | } else { | 908 | } else { |
911 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 909 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
912 | "s=%d\n", urb, urb->status); | 910 | "unlinked=%d\n", urb, urb->unlinked); |
913 | up(&u132->scheduler_lock); | 911 | up(&u132->scheduler_lock); |
914 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 912 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
915 | return; | 913 | return; |
916 | } | 914 | } |
917 | } | 915 | } |
@@ -936,12 +934,12 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
936 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 934 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
937 | return; | 935 | return; |
938 | } else if (u132->going > 0) { | 936 | } else if (u132->going > 0) { |
939 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 937 | dev_err(&u132->platform_dev->dev, "device is being removed " |
940 | "%p status=%d\n", urb, urb->status); | 938 | "urb=%p\n", urb); |
941 | up(&u132->scheduler_lock); | 939 | up(&u132->scheduler_lock); |
942 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 940 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
943 | return; | 941 | return; |
944 | } else if (urb->status == -EINPROGRESS) { | 942 | } else if (!urb->unlinked) { |
945 | struct u132_ring *ring = endp->ring; | 943 | struct u132_ring *ring = endp->ring; |
946 | u8 *u = urb->transfer_buffer; | 944 | u8 *u = urb->transfer_buffer; |
947 | u8 *b = buf; | 945 | u8 *b = buf; |
@@ -980,10 +978,10 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
980 | return; | 978 | return; |
981 | } | 979 | } |
982 | } else { | 980 | } else { |
983 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 981 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
984 | "s=%d\n", urb, urb->status); | 982 | "unlinked=%d\n", urb, urb->unlinked); |
985 | up(&u132->scheduler_lock); | 983 | up(&u132->scheduler_lock); |
986 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 984 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
987 | return; | 985 | return; |
988 | } | 986 | } |
989 | } | 987 | } |
@@ -1007,20 +1005,20 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, | |||
1007 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1005 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1008 | return; | 1006 | return; |
1009 | } else if (u132->going > 0) { | 1007 | } else if (u132->going > 0) { |
1010 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1008 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1011 | "%p status=%d\n", urb, urb->status); | 1009 | "urb=%p\n", urb); |
1012 | up(&u132->scheduler_lock); | 1010 | up(&u132->scheduler_lock); |
1013 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1011 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1014 | return; | 1012 | return; |
1015 | } else if (urb->status == -EINPROGRESS) { | 1013 | } else if (!urb->unlinked) { |
1016 | up(&u132->scheduler_lock); | 1014 | up(&u132->scheduler_lock); |
1017 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1015 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1018 | return; | 1016 | return; |
1019 | } else { | 1017 | } else { |
1020 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1018 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1021 | "s=%d\n", urb, urb->status); | 1019 | "unlinked=%d\n", urb, urb->unlinked); |
1022 | up(&u132->scheduler_lock); | 1020 | up(&u132->scheduler_lock); |
1023 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1021 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1024 | return; | 1022 | return; |
1025 | } | 1023 | } |
1026 | } | 1024 | } |
@@ -1045,12 +1043,12 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1045 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1043 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1046 | return; | 1044 | return; |
1047 | } else if (u132->going > 0) { | 1045 | } else if (u132->going > 0) { |
1048 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1046 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1049 | "%p status=%d\n", urb, urb->status); | 1047 | "urb=%p\n", urb); |
1050 | up(&u132->scheduler_lock); | 1048 | up(&u132->scheduler_lock); |
1051 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1049 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1052 | return; | 1050 | return; |
1053 | } else if (urb->status == -EINPROGRESS) { | 1051 | } else if (!urb->unlinked) { |
1054 | if (usb_pipein(urb->pipe)) { | 1052 | if (usb_pipein(urb->pipe)) { |
1055 | int retval; | 1053 | int retval; |
1056 | struct u132_ring *ring = endp->ring; | 1054 | struct u132_ring *ring = endp->ring; |
@@ -1077,10 +1075,10 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1077 | return; | 1075 | return; |
1078 | } | 1076 | } |
1079 | } else { | 1077 | } else { |
1080 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1078 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1081 | "s=%d\n", urb, urb->status); | 1079 | "unlinked=%d\n", urb, urb->unlinked); |
1082 | up(&u132->scheduler_lock); | 1080 | up(&u132->scheduler_lock); |
1083 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1081 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1084 | return; | 1082 | return; |
1085 | } | 1083 | } |
1086 | } | 1084 | } |
@@ -1106,22 +1104,22 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, | |||
1106 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1104 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1107 | return; | 1105 | return; |
1108 | } else if (u132->going > 0) { | 1106 | } else if (u132->going > 0) { |
1109 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1107 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1110 | "%p status=%d\n", urb, urb->status); | 1108 | "urb=%p\n", urb); |
1111 | up(&u132->scheduler_lock); | 1109 | up(&u132->scheduler_lock); |
1112 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1110 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1113 | return; | 1111 | return; |
1114 | } else if (urb->status == -EINPROGRESS) { | 1112 | } else if (!urb->unlinked) { |
1115 | u132->addr[0].address = 0; | 1113 | u132->addr[0].address = 0; |
1116 | endp->usb_addr = udev->usb_addr; | 1114 | endp->usb_addr = udev->usb_addr; |
1117 | up(&u132->scheduler_lock); | 1115 | up(&u132->scheduler_lock); |
1118 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1116 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1119 | return; | 1117 | return; |
1120 | } else { | 1118 | } else { |
1121 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1119 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1122 | "s=%d\n", urb, urb->status); | 1120 | "unlinked=%d\n", urb, urb->unlinked); |
1123 | up(&u132->scheduler_lock); | 1121 | up(&u132->scheduler_lock); |
1124 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1122 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1125 | return; | 1123 | return; |
1126 | } | 1124 | } |
1127 | } | 1125 | } |
@@ -1145,12 +1143,12 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1145 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1143 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1146 | return; | 1144 | return; |
1147 | } else if (u132->going > 0) { | 1145 | } else if (u132->going > 0) { |
1148 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1146 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1149 | "%p status=%d\n", urb, urb->status); | 1147 | "urb=%p\n", urb); |
1150 | up(&u132->scheduler_lock); | 1148 | up(&u132->scheduler_lock); |
1151 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1149 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1152 | return; | 1150 | return; |
1153 | } else if (urb->status == -EINPROGRESS) { | 1151 | } else if (!urb->unlinked) { |
1154 | int retval; | 1152 | int retval; |
1155 | struct u132_ring *ring = endp->ring; | 1153 | struct u132_ring *ring = endp->ring; |
1156 | up(&u132->scheduler_lock); | 1154 | up(&u132->scheduler_lock); |
@@ -1162,10 +1160,10 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1162 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1160 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1163 | return; | 1161 | return; |
1164 | } else { | 1162 | } else { |
1165 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1163 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1166 | "s=%d\n", urb, urb->status); | 1164 | "unlinked=%d\n", urb, urb->unlinked); |
1167 | up(&u132->scheduler_lock); | 1165 | up(&u132->scheduler_lock); |
1168 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1166 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1169 | return; | 1167 | return; |
1170 | } | 1168 | } |
1171 | } | 1169 | } |
@@ -1189,20 +1187,20 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
1189 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1187 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1190 | return; | 1188 | return; |
1191 | } else if (u132->going > 0) { | 1189 | } else if (u132->going > 0) { |
1192 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1190 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1193 | "%p status=%d\n", urb, urb->status); | 1191 | "urb=%p\n", urb); |
1194 | up(&u132->scheduler_lock); | 1192 | up(&u132->scheduler_lock); |
1195 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1193 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1196 | return; | 1194 | return; |
1197 | } else if (urb->status == -EINPROGRESS) { | 1195 | } else if (!urb->unlinked) { |
1198 | up(&u132->scheduler_lock); | 1196 | up(&u132->scheduler_lock); |
1199 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1197 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1200 | return; | 1198 | return; |
1201 | } else { | 1199 | } else { |
1202 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1200 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1203 | "s=%d\n", urb, urb->status); | 1201 | "unlinked=%d\n", urb, urb->unlinked); |
1204 | up(&u132->scheduler_lock); | 1202 | up(&u132->scheduler_lock); |
1205 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1203 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1206 | return; | 1204 | return; |
1207 | } | 1205 | } |
1208 | } | 1206 | } |
@@ -1227,12 +1225,12 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1227 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1225 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1228 | return; | 1226 | return; |
1229 | } else if (u132->going > 0) { | 1227 | } else if (u132->going > 0) { |
1230 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1228 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1231 | "%p status=%d\n", urb, urb->status); | 1229 | "urb=%p\n", urb); |
1232 | up(&u132->scheduler_lock); | 1230 | up(&u132->scheduler_lock); |
1233 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1231 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1234 | return; | 1232 | return; |
1235 | } else if (urb->status == -EINPROGRESS) { | 1233 | } else if (!urb->unlinked) { |
1236 | int retval; | 1234 | int retval; |
1237 | struct u132_ring *ring = endp->ring; | 1235 | struct u132_ring *ring = endp->ring; |
1238 | u8 *u = urb->transfer_buffer; | 1236 | u8 *u = urb->transfer_buffer; |
@@ -1251,10 +1249,10 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1251 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1249 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1252 | return; | 1250 | return; |
1253 | } else { | 1251 | } else { |
1254 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1252 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1255 | "s=%d\n", urb, urb->status); | 1253 | "unlinked=%d\n", urb, urb->unlinked); |
1256 | up(&u132->scheduler_lock); | 1254 | up(&u132->scheduler_lock); |
1257 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1255 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1258 | return; | 1256 | return; |
1259 | } | 1257 | } |
1260 | } | 1258 | } |
@@ -1279,12 +1277,12 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1279 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1277 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1280 | return; | 1278 | return; |
1281 | } else if (u132->going > 0) { | 1279 | } else if (u132->going > 0) { |
1282 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1280 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1283 | "%p status=%d\n", urb, urb->status); | 1281 | "urb=%p\n", urb); |
1284 | up(&u132->scheduler_lock); | 1282 | up(&u132->scheduler_lock); |
1285 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1283 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1286 | return; | 1284 | return; |
1287 | } else if (urb->status == -EINPROGRESS) { | 1285 | } else if (!urb->unlinked) { |
1288 | int retval; | 1286 | int retval; |
1289 | struct u132_ring *ring = endp->ring; | 1287 | struct u132_ring *ring = endp->ring; |
1290 | up(&u132->scheduler_lock); | 1288 | up(&u132->scheduler_lock); |
@@ -1296,10 +1294,10 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1296 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1294 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1297 | return; | 1295 | return; |
1298 | } else { | 1296 | } else { |
1299 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1297 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1300 | "s=%d\n", urb, urb->status); | 1298 | "unlinked=%d\n", urb, urb->unlinked); |
1301 | up(&u132->scheduler_lock); | 1299 | up(&u132->scheduler_lock); |
1302 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1300 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1303 | return; | 1301 | return; |
1304 | } | 1302 | } |
1305 | } | 1303 | } |
@@ -1519,12 +1517,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) | |||
1519 | } | 1517 | } |
1520 | } | 1518 | } |
1521 | } | 1519 | } |
1520 | #ifdef CONFIG_PM | ||
1522 | 1521 | ||
1523 | static void port_power(struct u132 *u132, int pn, int is_on) | 1522 | static void port_power(struct u132 *u132, int pn, int is_on) |
1524 | { | 1523 | { |
1525 | u132->port[pn].power = is_on; | 1524 | u132->port[pn].power = is_on; |
1526 | } | 1525 | } |
1527 | 1526 | ||
1527 | #endif | ||
1528 | |||
1528 | static void u132_power(struct u132 *u132, int is_on) | 1529 | static void u132_power(struct u132 *u132, int is_on) |
1529 | { | 1530 | { |
1530 | struct usb_hcd *hcd = u132_to_hcd(u132) | 1531 | struct usb_hcd *hcd = u132_to_hcd(u132) |
@@ -1801,10 +1802,10 @@ static void u132_hcd_stop(struct usb_hcd *hcd) | |||
1801 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 1802 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
1802 | "ed\n", hcd); | 1803 | "ed\n", hcd); |
1803 | } else { | 1804 | } else { |
1804 | down(&u132->sw_lock); | 1805 | mutex_lock(&u132->sw_lock); |
1805 | msleep(100); | 1806 | msleep(100); |
1806 | u132_power(u132, 0); | 1807 | u132_power(u132, 0); |
1807 | up(&u132->sw_lock); | 1808 | mutex_unlock(&u132->sw_lock); |
1808 | } | 1809 | } |
1809 | } | 1810 | } |
1810 | 1811 | ||
@@ -1826,7 +1827,7 @@ static int u132_hcd_start(struct usb_hcd *hcd) | |||
1826 | (pdev->dev.platform_data))->vendor; | 1827 | (pdev->dev.platform_data))->vendor; |
1827 | u16 device = ((struct u132_platform_data *) | 1828 | u16 device = ((struct u132_platform_data *) |
1828 | (pdev->dev.platform_data))->device; | 1829 | (pdev->dev.platform_data))->device; |
1829 | down(&u132->sw_lock); | 1830 | mutex_lock(&u132->sw_lock); |
1830 | msleep(10); | 1831 | msleep(10); |
1831 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { | 1832 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { |
1832 | u132->flags = OHCI_QUIRK_AMD756; | 1833 | u132->flags = OHCI_QUIRK_AMD756; |
@@ -1841,7 +1842,7 @@ static int u132_hcd_start(struct usb_hcd *hcd) | |||
1841 | u132->going = 1; | 1842 | u132->going = 1; |
1842 | } | 1843 | } |
1843 | msleep(100); | 1844 | msleep(100); |
1844 | up(&u132->sw_lock); | 1845 | mutex_unlock(&u132->sw_lock); |
1845 | return retval; | 1846 | return retval; |
1846 | } else { | 1847 | } else { |
1847 | dev_err(&u132->platform_dev->dev, "platform_device missing\n"); | 1848 | dev_err(&u132->platform_dev->dev, "platform_device missing\n"); |
@@ -1861,32 +1862,44 @@ static int u132_hcd_reset(struct usb_hcd *hcd) | |||
1861 | return -ESHUTDOWN; | 1862 | return -ESHUTDOWN; |
1862 | } else { | 1863 | } else { |
1863 | int retval; | 1864 | int retval; |
1864 | down(&u132->sw_lock); | 1865 | mutex_lock(&u132->sw_lock); |
1865 | retval = u132_init(u132); | 1866 | retval = u132_init(u132); |
1866 | if (retval) { | 1867 | if (retval) { |
1867 | u132_disable(u132); | 1868 | u132_disable(u132); |
1868 | u132->going = 1; | 1869 | u132->going = 1; |
1869 | } | 1870 | } |
1870 | up(&u132->sw_lock); | 1871 | mutex_unlock(&u132->sw_lock); |
1871 | return retval; | 1872 | return retval; |
1872 | } | 1873 | } |
1873 | } | 1874 | } |
1874 | 1875 | ||
1875 | static int create_endpoint_and_queue_int(struct u132 *u132, | 1876 | static int create_endpoint_and_queue_int(struct u132 *u132, |
1876 | struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb, | 1877 | struct u132_udev *udev, struct urb *urb, |
1877 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, | 1878 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, |
1878 | gfp_t mem_flags) | 1879 | gfp_t mem_flags) |
1879 | { | 1880 | { |
1880 | struct u132_ring *ring; | 1881 | struct u132_ring *ring; |
1881 | unsigned long irqs; | 1882 | unsigned long irqs; |
1882 | u8 endp_number = ++u132->num_endpoints; | 1883 | int rc; |
1883 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 1884 | u8 endp_number; |
1884 | kmalloc(sizeof(struct u132_endp), mem_flags); | 1885 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); |
1886 | |||
1885 | if (!endp) { | 1887 | if (!endp) { |
1886 | return -ENOMEM; | 1888 | return -ENOMEM; |
1887 | } | 1889 | } |
1890 | |||
1891 | spin_lock_init(&endp->queue_lock.slock); | ||
1892 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1893 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
1894 | if (rc) { | ||
1895 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
1896 | kfree(endp); | ||
1897 | return rc; | ||
1898 | } | ||
1899 | |||
1900 | endp_number = ++u132->num_endpoints; | ||
1901 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
1888 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 1902 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1889 | spin_lock_init(&endp->queue_lock.slock); | ||
1890 | INIT_LIST_HEAD(&endp->urb_more); | 1903 | INIT_LIST_HEAD(&endp->urb_more); |
1891 | ring = endp->ring = &u132->ring[0]; | 1904 | ring = endp->ring = &u132->ring[0]; |
1892 | if (ring->curr_endp) { | 1905 | if (ring->curr_endp) { |
@@ -1902,7 +1915,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1902 | endp->delayed = 0; | 1915 | endp->delayed = 0; |
1903 | endp->endp_number = endp_number; | 1916 | endp->endp_number = endp_number; |
1904 | endp->u132 = u132; | 1917 | endp->u132 = u132; |
1905 | endp->hep = hep; | 1918 | endp->hep = urb->ep; |
1906 | endp->pipetype = usb_pipetype(urb->pipe); | 1919 | endp->pipetype = usb_pipetype(urb->pipe); |
1907 | u132_endp_init_kref(u132, endp); | 1920 | u132_endp_init_kref(u132, endp); |
1908 | if (usb_pipein(urb->pipe)) { | 1921 | if (usb_pipein(urb->pipe)) { |
@@ -1921,7 +1934,6 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1921 | u132_udev_get_kref(u132, udev); | 1934 | u132_udev_get_kref(u132, udev); |
1922 | } | 1935 | } |
1923 | urb->hcpriv = u132; | 1936 | urb->hcpriv = u132; |
1924 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1925 | endp->delayed = 1; | 1937 | endp->delayed = 1; |
1926 | endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); | 1938 | endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); |
1927 | endp->udev_number = address; | 1939 | endp->udev_number = address; |
@@ -1936,8 +1948,8 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1936 | return 0; | 1948 | return 0; |
1937 | } | 1949 | } |
1938 | 1950 | ||
1939 | static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | 1951 | static int queue_int_on_old_endpoint(struct u132 *u132, |
1940 | struct usb_host_endpoint *hep, struct urb *urb, | 1952 | struct u132_udev *udev, struct urb *urb, |
1941 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 1953 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
1942 | u8 usb_endp, u8 address) | 1954 | u8 usb_endp, u8 address) |
1943 | { | 1955 | { |
@@ -1961,21 +1973,33 @@ static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | |||
1961 | } | 1973 | } |
1962 | 1974 | ||
1963 | static int create_endpoint_and_queue_bulk(struct u132 *u132, | 1975 | static int create_endpoint_and_queue_bulk(struct u132 *u132, |
1964 | struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb, | 1976 | struct u132_udev *udev, struct urb *urb, |
1965 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, | 1977 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, |
1966 | gfp_t mem_flags) | 1978 | gfp_t mem_flags) |
1967 | { | 1979 | { |
1968 | int ring_number; | 1980 | int ring_number; |
1969 | struct u132_ring *ring; | 1981 | struct u132_ring *ring; |
1970 | unsigned long irqs; | 1982 | unsigned long irqs; |
1971 | u8 endp_number = ++u132->num_endpoints; | 1983 | int rc; |
1972 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 1984 | u8 endp_number; |
1973 | kmalloc(sizeof(struct u132_endp), mem_flags); | 1985 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); |
1986 | |||
1974 | if (!endp) { | 1987 | if (!endp) { |
1975 | return -ENOMEM; | 1988 | return -ENOMEM; |
1976 | } | 1989 | } |
1990 | |||
1991 | spin_lock_init(&endp->queue_lock.slock); | ||
1992 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1993 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
1994 | if (rc) { | ||
1995 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
1996 | kfree(endp); | ||
1997 | return rc; | ||
1998 | } | ||
1999 | |||
2000 | endp_number = ++u132->num_endpoints; | ||
2001 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
1977 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 2002 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1978 | spin_lock_init(&endp->queue_lock.slock); | ||
1979 | INIT_LIST_HEAD(&endp->urb_more); | 2003 | INIT_LIST_HEAD(&endp->urb_more); |
1980 | endp->dequeueing = 0; | 2004 | endp->dequeueing = 0; |
1981 | endp->edset_flush = 0; | 2005 | endp->edset_flush = 0; |
@@ -1983,7 +2007,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
1983 | endp->delayed = 0; | 2007 | endp->delayed = 0; |
1984 | endp->endp_number = endp_number; | 2008 | endp->endp_number = endp_number; |
1985 | endp->u132 = u132; | 2009 | endp->u132 = u132; |
1986 | endp->hep = hep; | 2010 | endp->hep = urb->ep; |
1987 | endp->pipetype = usb_pipetype(urb->pipe); | 2011 | endp->pipetype = usb_pipetype(urb->pipe); |
1988 | u132_endp_init_kref(u132, endp); | 2012 | u132_endp_init_kref(u132, endp); |
1989 | if (usb_pipein(urb->pipe)) { | 2013 | if (usb_pipein(urb->pipe)) { |
@@ -2012,7 +2036,6 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2012 | } | 2036 | } |
2013 | ring->length += 1; | 2037 | ring->length += 1; |
2014 | urb->hcpriv = u132; | 2038 | urb->hcpriv = u132; |
2015 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2016 | endp->udev_number = address; | 2039 | endp->udev_number = address; |
2017 | endp->usb_addr = usb_addr; | 2040 | endp->usb_addr = usb_addr; |
2018 | endp->usb_endp = usb_endp; | 2041 | endp->usb_endp = usb_endp; |
@@ -2026,7 +2049,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2026 | } | 2049 | } |
2027 | 2050 | ||
2028 | static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | 2051 | static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, |
2029 | struct usb_host_endpoint *hep, struct urb *urb, | 2052 | struct urb *urb, |
2030 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 2053 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
2031 | u8 usb_endp, u8 address) | 2054 | u8 usb_endp, u8 address) |
2032 | { | 2055 | { |
@@ -2048,19 +2071,32 @@ static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | |||
2048 | } | 2071 | } |
2049 | 2072 | ||
2050 | static int create_endpoint_and_queue_control(struct u132 *u132, | 2073 | static int create_endpoint_and_queue_control(struct u132 *u132, |
2051 | struct usb_host_endpoint *hep, struct urb *urb, | 2074 | struct urb *urb, |
2052 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, | 2075 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, |
2053 | gfp_t mem_flags) | 2076 | gfp_t mem_flags) |
2054 | { | 2077 | { |
2055 | struct u132_ring *ring; | 2078 | struct u132_ring *ring; |
2056 | u8 endp_number = ++u132->num_endpoints; | 2079 | unsigned long irqs; |
2057 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 2080 | int rc; |
2058 | kmalloc(sizeof(struct u132_endp), mem_flags); | 2081 | u8 endp_number; |
2082 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); | ||
2083 | |||
2059 | if (!endp) { | 2084 | if (!endp) { |
2060 | return -ENOMEM; | 2085 | return -ENOMEM; |
2061 | } | 2086 | } |
2087 | |||
2088 | spin_lock_init(&endp->queue_lock.slock); | ||
2089 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2090 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
2091 | if (rc) { | ||
2092 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
2093 | kfree(endp); | ||
2094 | return rc; | ||
2095 | } | ||
2096 | |||
2097 | endp_number = ++u132->num_endpoints; | ||
2098 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
2062 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 2099 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
2063 | spin_lock_init(&endp->queue_lock.slock); | ||
2064 | INIT_LIST_HEAD(&endp->urb_more); | 2100 | INIT_LIST_HEAD(&endp->urb_more); |
2065 | ring = endp->ring = &u132->ring[0]; | 2101 | ring = endp->ring = &u132->ring[0]; |
2066 | if (ring->curr_endp) { | 2102 | if (ring->curr_endp) { |
@@ -2076,11 +2112,10 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2076 | endp->delayed = 0; | 2112 | endp->delayed = 0; |
2077 | endp->endp_number = endp_number; | 2113 | endp->endp_number = endp_number; |
2078 | endp->u132 = u132; | 2114 | endp->u132 = u132; |
2079 | endp->hep = hep; | 2115 | endp->hep = urb->ep; |
2080 | u132_endp_init_kref(u132, endp); | 2116 | u132_endp_init_kref(u132, endp); |
2081 | u132_endp_get_kref(u132, endp); | 2117 | u132_endp_get_kref(u132, endp); |
2082 | if (usb_addr == 0) { | 2118 | if (usb_addr == 0) { |
2083 | unsigned long irqs; | ||
2084 | u8 address = u132->addr[usb_addr].address; | 2119 | u8 address = u132->addr[usb_addr].address; |
2085 | struct u132_udev *udev = &u132->udev[address]; | 2120 | struct u132_udev *udev = &u132->udev[address]; |
2086 | endp->udev_number = address; | 2121 | endp->udev_number = address; |
@@ -2094,7 +2129,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2094 | udev->endp_number_in[usb_endp] = endp_number; | 2129 | udev->endp_number_in[usb_endp] = endp_number; |
2095 | udev->endp_number_out[usb_endp] = endp_number; | 2130 | udev->endp_number_out[usb_endp] = endp_number; |
2096 | urb->hcpriv = u132; | 2131 | urb->hcpriv = u132; |
2097 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2098 | endp->queue_size = 1; | 2132 | endp->queue_size = 1; |
2099 | endp->queue_last = 0; | 2133 | endp->queue_last = 0; |
2100 | endp->queue_next = 0; | 2134 | endp->queue_next = 0; |
@@ -2103,7 +2137,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2103 | u132_endp_queue_work(u132, endp, 0); | 2137 | u132_endp_queue_work(u132, endp, 0); |
2104 | return 0; | 2138 | return 0; |
2105 | } else { /*(usb_addr > 0) */ | 2139 | } else { /*(usb_addr > 0) */ |
2106 | unsigned long irqs; | ||
2107 | u8 address = u132->addr[usb_addr].address; | 2140 | u8 address = u132->addr[usb_addr].address; |
2108 | struct u132_udev *udev = &u132->udev[address]; | 2141 | struct u132_udev *udev = &u132->udev[address]; |
2109 | endp->udev_number = address; | 2142 | endp->udev_number = address; |
@@ -2117,7 +2150,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2117 | udev->endp_number_in[usb_endp] = endp_number; | 2150 | udev->endp_number_in[usb_endp] = endp_number; |
2118 | udev->endp_number_out[usb_endp] = endp_number; | 2151 | udev->endp_number_out[usb_endp] = endp_number; |
2119 | urb->hcpriv = u132; | 2152 | urb->hcpriv = u132; |
2120 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2121 | endp->queue_size = 1; | 2153 | endp->queue_size = 1; |
2122 | endp->queue_last = 0; | 2154 | endp->queue_last = 0; |
2123 | endp->queue_next = 0; | 2155 | endp->queue_next = 0; |
@@ -2129,7 +2161,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2129 | } | 2161 | } |
2130 | 2162 | ||
2131 | static int queue_control_on_old_endpoint(struct u132 *u132, | 2163 | static int queue_control_on_old_endpoint(struct u132 *u132, |
2132 | struct usb_host_endpoint *hep, struct urb *urb, | 2164 | struct urb *urb, |
2133 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 2165 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
2134 | u8 usb_endp) | 2166 | u8 usb_endp) |
2135 | { | 2167 | { |
@@ -2229,8 +2261,8 @@ static int queue_control_on_old_endpoint(struct u132 *u132, | |||
2229 | } | 2261 | } |
2230 | } | 2262 | } |
2231 | 2263 | ||
2232 | static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | 2264 | static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, |
2233 | struct urb *urb, gfp_t mem_flags) | 2265 | gfp_t mem_flags) |
2234 | { | 2266 | { |
2235 | struct u132 *u132 = hcd_to_u132(hcd); | 2267 | struct u132 *u132 = hcd_to_u132(hcd); |
2236 | if (irqs_disabled()) { | 2268 | if (irqs_disabled()) { |
@@ -2245,8 +2277,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2245 | , u132->going); | 2277 | , u132->going); |
2246 | return -ENODEV; | 2278 | return -ENODEV; |
2247 | } else if (u132->going > 0) { | 2279 | } else if (u132->going > 0) { |
2248 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 2280 | dev_err(&u132->platform_dev->dev, "device is being removed " |
2249 | "%p status=%d\n", urb, urb->status); | 2281 | "urb=%p\n", urb); |
2250 | return -ESHUTDOWN; | 2282 | return -ESHUTDOWN; |
2251 | } else { | 2283 | } else { |
2252 | u8 usb_addr = usb_pipedevice(urb->pipe); | 2284 | u8 usb_addr = usb_pipedevice(urb->pipe); |
@@ -2255,16 +2287,24 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2255 | if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { | 2287 | if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { |
2256 | u8 address = u132->addr[usb_addr].address; | 2288 | u8 address = u132->addr[usb_addr].address; |
2257 | struct u132_udev *udev = &u132->udev[address]; | 2289 | struct u132_udev *udev = &u132->udev[address]; |
2258 | struct u132_endp *endp = hep->hcpriv; | 2290 | struct u132_endp *endp = urb->ep->hcpriv; |
2259 | urb->actual_length = 0; | 2291 | urb->actual_length = 0; |
2260 | if (endp) { | 2292 | if (endp) { |
2261 | unsigned long irqs; | 2293 | unsigned long irqs; |
2262 | int retval; | 2294 | int retval; |
2263 | spin_lock_irqsave(&endp->queue_lock.slock, | 2295 | spin_lock_irqsave(&endp->queue_lock.slock, |
2264 | irqs); | 2296 | irqs); |
2265 | retval = queue_int_on_old_endpoint(u132, udev, | 2297 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2266 | hep, urb, usb_dev, endp, usb_addr, | 2298 | if (retval == 0) { |
2267 | usb_endp, address); | 2299 | retval = queue_int_on_old_endpoint( |
2300 | u132, udev, urb, | ||
2301 | usb_dev, endp, | ||
2302 | usb_addr, usb_endp, | ||
2303 | address); | ||
2304 | if (retval) | ||
2305 | usb_hcd_unlink_urb_from_ep( | ||
2306 | hcd, urb); | ||
2307 | } | ||
2268 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2308 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2269 | irqs); | 2309 | irqs); |
2270 | if (retval) { | 2310 | if (retval) { |
@@ -2279,8 +2319,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2279 | return -EINVAL; | 2319 | return -EINVAL; |
2280 | } else { /*(endp == NULL) */ | 2320 | } else { /*(endp == NULL) */ |
2281 | return create_endpoint_and_queue_int(u132, udev, | 2321 | return create_endpoint_and_queue_int(u132, udev, |
2282 | hep, urb, usb_dev, usb_addr, usb_endp, | 2322 | urb, usb_dev, usb_addr, |
2283 | address, mem_flags); | 2323 | usb_endp, address, mem_flags); |
2284 | } | 2324 | } |
2285 | } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | 2325 | } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { |
2286 | dev_err(&u132->platform_dev->dev, "the hardware does no" | 2326 | dev_err(&u132->platform_dev->dev, "the hardware does no" |
@@ -2289,16 +2329,24 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2289 | } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { | 2329 | } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { |
2290 | u8 address = u132->addr[usb_addr].address; | 2330 | u8 address = u132->addr[usb_addr].address; |
2291 | struct u132_udev *udev = &u132->udev[address]; | 2331 | struct u132_udev *udev = &u132->udev[address]; |
2292 | struct u132_endp *endp = hep->hcpriv; | 2332 | struct u132_endp *endp = urb->ep->hcpriv; |
2293 | urb->actual_length = 0; | 2333 | urb->actual_length = 0; |
2294 | if (endp) { | 2334 | if (endp) { |
2295 | unsigned long irqs; | 2335 | unsigned long irqs; |
2296 | int retval; | 2336 | int retval; |
2297 | spin_lock_irqsave(&endp->queue_lock.slock, | 2337 | spin_lock_irqsave(&endp->queue_lock.slock, |
2298 | irqs); | 2338 | irqs); |
2299 | retval = queue_bulk_on_old_endpoint(u132, udev, | 2339 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2300 | hep, urb, usb_dev, endp, usb_addr, | 2340 | if (retval == 0) { |
2301 | usb_endp, address); | 2341 | retval = queue_bulk_on_old_endpoint( |
2342 | u132, udev, urb, | ||
2343 | usb_dev, endp, | ||
2344 | usb_addr, usb_endp, | ||
2345 | address); | ||
2346 | if (retval) | ||
2347 | usb_hcd_unlink_urb_from_ep( | ||
2348 | hcd, urb); | ||
2349 | } | ||
2302 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2350 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2303 | irqs); | 2351 | irqs); |
2304 | if (retval) { | 2352 | if (retval) { |
@@ -2311,10 +2359,10 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2311 | return -EINVAL; | 2359 | return -EINVAL; |
2312 | } else | 2360 | } else |
2313 | return create_endpoint_and_queue_bulk(u132, | 2361 | return create_endpoint_and_queue_bulk(u132, |
2314 | udev, hep, urb, usb_dev, usb_addr, | 2362 | udev, urb, usb_dev, usb_addr, |
2315 | usb_endp, address, mem_flags); | 2363 | usb_endp, address, mem_flags); |
2316 | } else { | 2364 | } else { |
2317 | struct u132_endp *endp = hep->hcpriv; | 2365 | struct u132_endp *endp = urb->ep->hcpriv; |
2318 | u16 urb_size = 8; | 2366 | u16 urb_size = 8; |
2319 | u8 *b = urb->setup_packet; | 2367 | u8 *b = urb->setup_packet; |
2320 | int i = 0; | 2368 | int i = 0; |
@@ -2337,9 +2385,16 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2337 | int retval; | 2385 | int retval; |
2338 | spin_lock_irqsave(&endp->queue_lock.slock, | 2386 | spin_lock_irqsave(&endp->queue_lock.slock, |
2339 | irqs); | 2387 | irqs); |
2340 | retval = queue_control_on_old_endpoint(u132, | 2388 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2341 | hep, urb, usb_dev, endp, usb_addr, | 2389 | if (retval == 0) { |
2342 | usb_endp); | 2390 | retval = queue_control_on_old_endpoint( |
2391 | u132, urb, usb_dev, | ||
2392 | endp, usb_addr, | ||
2393 | usb_endp); | ||
2394 | if (retval) | ||
2395 | usb_hcd_unlink_urb_from_ep( | ||
2396 | hcd, urb); | ||
2397 | } | ||
2343 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2398 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2344 | irqs); | 2399 | irqs); |
2345 | if (retval) { | 2400 | if (retval) { |
@@ -2352,7 +2407,7 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2352 | return -EINVAL; | 2407 | return -EINVAL; |
2353 | } else | 2408 | } else |
2354 | return create_endpoint_and_queue_control(u132, | 2409 | return create_endpoint_and_queue_control(u132, |
2355 | hep, urb, usb_dev, usb_addr, usb_endp, | 2410 | urb, usb_dev, usb_addr, usb_endp, |
2356 | mem_flags); | 2411 | mem_flags); |
2357 | } | 2412 | } |
2358 | } | 2413 | } |
@@ -2371,8 +2426,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2371 | list_del(scan); | 2426 | list_del(scan); |
2372 | endp->queue_size -= 1; | 2427 | endp->queue_size -= 1; |
2373 | urb->error_count = 0; | 2428 | urb->error_count = 0; |
2374 | urb->hcpriv = NULL; | 2429 | usb_hcd_giveback_urb(hcd, urb, 0); |
2375 | usb_hcd_giveback_urb(hcd, urb); | ||
2376 | return 0; | 2430 | return 0; |
2377 | } else | 2431 | } else |
2378 | continue; | 2432 | continue; |
@@ -2387,10 +2441,17 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2387 | } | 2441 | } |
2388 | 2442 | ||
2389 | static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | 2443 | static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, |
2390 | struct urb *urb) | 2444 | struct urb *urb, int status) |
2391 | { | 2445 | { |
2392 | unsigned long irqs; | 2446 | unsigned long irqs; |
2447 | int rc; | ||
2448 | |||
2393 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 2449 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
2450 | rc = usb_hcd_check_unlink_urb(u132_to_hcd(u132), urb, status); | ||
2451 | if (rc) { | ||
2452 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
2453 | return rc; | ||
2454 | } | ||
2394 | if (endp->queue_size == 0) { | 2455 | if (endp->queue_size == 0) { |
2395 | dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" | 2456 | dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" |
2396 | "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, | 2457 | "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, |
@@ -2406,11 +2467,10 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2406 | endp->edset_flush = 1; | 2467 | endp->edset_flush = 1; |
2407 | u132_endp_queue_work(u132, endp, 0); | 2468 | u132_endp_queue_work(u132, endp, 0); |
2408 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2469 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2409 | urb->hcpriv = NULL; | ||
2410 | return 0; | 2470 | return 0; |
2411 | } else { | 2471 | } else { |
2412 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2472 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2413 | u132_hcd_abandon_urb(u132, endp, urb, urb->status); | 2473 | u132_hcd_abandon_urb(u132, endp, urb, status); |
2414 | return 0; | 2474 | return 0; |
2415 | } | 2475 | } |
2416 | } else { | 2476 | } else { |
@@ -2435,6 +2495,8 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2435 | } | 2495 | } |
2436 | if (urb_slot) { | 2496 | if (urb_slot) { |
2437 | struct usb_hcd *hcd = u132_to_hcd(u132); | 2497 | struct usb_hcd *hcd = u132_to_hcd(u132); |
2498 | |||
2499 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
2438 | endp->queue_size -= 1; | 2500 | endp->queue_size -= 1; |
2439 | if (list_empty(&endp->urb_more)) { | 2501 | if (list_empty(&endp->urb_more)) { |
2440 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2502 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
@@ -2449,8 +2511,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2449 | irqs); | 2511 | irqs); |
2450 | kfree(urbq); | 2512 | kfree(urbq); |
2451 | } urb->error_count = 0; | 2513 | } urb->error_count = 0; |
2452 | urb->hcpriv = NULL; | 2514 | usb_hcd_giveback_urb(hcd, urb, status); |
2453 | usb_hcd_giveback_urb(hcd, urb); | ||
2454 | return 0; | 2515 | return 0; |
2455 | } else if (list_empty(&endp->urb_more)) { | 2516 | } else if (list_empty(&endp->urb_more)) { |
2456 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " | 2517 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " |
@@ -2464,7 +2525,10 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2464 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2525 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2465 | return -EINVAL; | 2526 | return -EINVAL; |
2466 | } else { | 2527 | } else { |
2467 | int retval = dequeue_from_overflow_chain(u132, endp, | 2528 | int retval; |
2529 | |||
2530 | usb_hcd_unlink_urb_from_ep(u132_to_hcd(u132), urb); | ||
2531 | retval = dequeue_from_overflow_chain(u132, endp, | ||
2468 | urb); | 2532 | urb); |
2469 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2533 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2470 | return retval; | 2534 | return retval; |
@@ -2472,7 +2536,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2472 | } | 2536 | } |
2473 | } | 2537 | } |
2474 | 2538 | ||
2475 | static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 2539 | static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
2476 | { | 2540 | { |
2477 | struct u132 *u132 = hcd_to_u132(hcd); | 2541 | struct u132 *u132 = hcd_to_u132(hcd); |
2478 | if (u132->going > 2) { | 2542 | if (u132->going > 2) { |
@@ -2487,11 +2551,11 @@ static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
2487 | if (usb_pipein(urb->pipe)) { | 2551 | if (usb_pipein(urb->pipe)) { |
2488 | u8 endp_number = udev->endp_number_in[usb_endp]; | 2552 | u8 endp_number = udev->endp_number_in[usb_endp]; |
2489 | struct u132_endp *endp = u132->endp[endp_number - 1]; | 2553 | struct u132_endp *endp = u132->endp[endp_number - 1]; |
2490 | return u132_endp_urb_dequeue(u132, endp, urb); | 2554 | return u132_endp_urb_dequeue(u132, endp, urb, status); |
2491 | } else { | 2555 | } else { |
2492 | u8 endp_number = udev->endp_number_out[usb_endp]; | 2556 | u8 endp_number = udev->endp_number_out[usb_endp]; |
2493 | struct u132_endp *endp = u132->endp[endp_number - 1]; | 2557 | struct u132_endp *endp = u132->endp[endp_number - 1]; |
2494 | return u132_endp_urb_dequeue(u132, endp, urb); | 2558 | return u132_endp_urb_dequeue(u132, endp, urb, status); |
2495 | } | 2559 | } |
2496 | } | 2560 | } |
2497 | } | 2561 | } |
@@ -2801,7 +2865,7 @@ static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2801 | return -ESHUTDOWN; | 2865 | return -ESHUTDOWN; |
2802 | } else { | 2866 | } else { |
2803 | int retval = 0; | 2867 | int retval = 0; |
2804 | down(&u132->sw_lock); | 2868 | mutex_lock(&u132->sw_lock); |
2805 | switch (typeReq) { | 2869 | switch (typeReq) { |
2806 | case ClearHubFeature: | 2870 | case ClearHubFeature: |
2807 | switch (wValue) { | 2871 | switch (wValue) { |
@@ -2864,7 +2928,7 @@ static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2864 | stall:retval = -EPIPE; | 2928 | stall:retval = -EPIPE; |
2865 | break; | 2929 | break; |
2866 | } | 2930 | } |
2867 | up(&u132->sw_lock); | 2931 | mutex_unlock(&u132->sw_lock); |
2868 | return retval; | 2932 | return retval; |
2869 | } | 2933 | } |
2870 | } | 2934 | } |
@@ -3000,7 +3064,7 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3000 | dev_err(&u132->platform_dev->dev, "removing device u132" | 3064 | dev_err(&u132->platform_dev->dev, "removing device u132" |
3001 | ".%d\n", u132->sequence_num); | 3065 | ".%d\n", u132->sequence_num); |
3002 | msleep(100); | 3066 | msleep(100); |
3003 | down(&u132->sw_lock); | 3067 | mutex_lock(&u132->sw_lock); |
3004 | u132_monitor_cancel_work(u132); | 3068 | u132_monitor_cancel_work(u132); |
3005 | while (rings-- > 0) { | 3069 | while (rings-- > 0) { |
3006 | struct u132_ring *ring = &u132->ring[rings]; | 3070 | struct u132_ring *ring = &u132->ring[rings]; |
@@ -3013,7 +3077,7 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3013 | u132->going += 1; | 3077 | u132->going += 1; |
3014 | printk(KERN_INFO "removing device u132.%d\n", | 3078 | printk(KERN_INFO "removing device u132.%d\n", |
3015 | u132->sequence_num); | 3079 | u132->sequence_num); |
3016 | up(&u132->sw_lock); | 3080 | mutex_unlock(&u132->sw_lock); |
3017 | usb_remove_hcd(hcd); | 3081 | usb_remove_hcd(hcd); |
3018 | u132_u132_put_kref(u132); | 3082 | u132_u132_put_kref(u132); |
3019 | return 0; | 3083 | return 0; |
@@ -3033,7 +3097,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3033 | u132->platform_dev = pdev; | 3097 | u132->platform_dev = pdev; |
3034 | u132->power = 0; | 3098 | u132->power = 0; |
3035 | u132->reset = 0; | 3099 | u132->reset = 0; |
3036 | init_MUTEX(&u132->sw_lock); | 3100 | mutex_init(&u132->sw_lock); |
3037 | init_MUTEX(&u132->scheduler_lock); | 3101 | init_MUTEX(&u132->scheduler_lock); |
3038 | while (rings-- > 0) { | 3102 | while (rings-- > 0) { |
3039 | struct u132_ring *ring = &u132->ring[rings]; | 3103 | struct u132_ring *ring = &u132->ring[rings]; |
@@ -3043,7 +3107,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3043 | ring->curr_endp = NULL; | 3107 | ring->curr_endp = NULL; |
3044 | INIT_DELAYED_WORK(&ring->scheduler, | 3108 | INIT_DELAYED_WORK(&ring->scheduler, |
3045 | u132_hcd_ring_work_scheduler); | 3109 | u132_hcd_ring_work_scheduler); |
3046 | } down(&u132->sw_lock); | 3110 | } mutex_lock(&u132->sw_lock); |
3047 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); | 3111 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); |
3048 | while (ports-- > 0) { | 3112 | while (ports-- > 0) { |
3049 | struct u132_port *port = &u132->port[ports]; | 3113 | struct u132_port *port = &u132->port[ports]; |
@@ -3073,7 +3137,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3073 | while (endps-- > 0) { | 3137 | while (endps-- > 0) { |
3074 | u132->endp[endps] = NULL; | 3138 | u132->endp[endps] = NULL; |
3075 | } | 3139 | } |
3076 | up(&u132->sw_lock); | 3140 | mutex_unlock(&u132->sw_lock); |
3077 | return; | 3141 | return; |
3078 | } | 3142 | } |
3079 | 3143 | ||
@@ -3111,10 +3175,10 @@ static int __devinit u132_probe(struct platform_device *pdev) | |||
3111 | int retval = 0; | 3175 | int retval = 0; |
3112 | struct u132 *u132 = hcd_to_u132(hcd); | 3176 | struct u132 *u132 = hcd_to_u132(hcd); |
3113 | hcd->rsrc_start = 0; | 3177 | hcd->rsrc_start = 0; |
3114 | down(&u132_module_lock); | 3178 | mutex_lock(&u132_module_lock); |
3115 | list_add_tail(&u132->u132_list, &u132_static_list); | 3179 | list_add_tail(&u132->u132_list, &u132_static_list); |
3116 | u132->sequence_num = ++u132_instances; | 3180 | u132->sequence_num = ++u132_instances; |
3117 | up(&u132_module_lock); | 3181 | mutex_unlock(&u132_module_lock); |
3118 | u132_u132_init_kref(u132); | 3182 | u132_u132_init_kref(u132); |
3119 | u132_initialise(u132, pdev); | 3183 | u132_initialise(u132, pdev); |
3120 | hcd->product_desc = "ELAN U132 Host Controller"; | 3184 | hcd->product_desc = "ELAN U132 Host Controller"; |
@@ -3216,7 +3280,7 @@ static int __init u132_hcd_init(void) | |||
3216 | INIT_LIST_HEAD(&u132_static_list); | 3280 | INIT_LIST_HEAD(&u132_static_list); |
3217 | u132_instances = 0; | 3281 | u132_instances = 0; |
3218 | u132_exiting = 0; | 3282 | u132_exiting = 0; |
3219 | init_MUTEX(&u132_module_lock); | 3283 | mutex_init(&u132_module_lock); |
3220 | if (usb_disabled()) | 3284 | if (usb_disabled()) |
3221 | return -ENODEV; | 3285 | return -ENODEV; |
3222 | printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, | 3286 | printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, |
@@ -3232,9 +3296,9 @@ static void __exit u132_hcd_exit(void) | |||
3232 | { | 3296 | { |
3233 | struct u132 *u132; | 3297 | struct u132 *u132; |
3234 | struct u132 *temp; | 3298 | struct u132 *temp; |
3235 | down(&u132_module_lock); | 3299 | mutex_lock(&u132_module_lock); |
3236 | u132_exiting += 1; | 3300 | u132_exiting += 1; |
3237 | up(&u132_module_lock); | 3301 | mutex_unlock(&u132_module_lock); |
3238 | list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { | 3302 | list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { |
3239 | platform_device_unregister(u132->platform_dev); | 3303 | platform_device_unregister(u132->platform_dev); |
3240 | } platform_driver_unregister(&u132_platform_driver); | 3304 | } platform_driver_unregister(&u132_platform_driver); |