diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-13 12:37:40 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-13 12:37:40 -0500 |
commit | 121a8cdd79e2c68ae78c7633f2a46ee65a177ff6 (patch) | |
tree | 03793bef35f590718ebc6ae6110eb0c507ae60bf | |
parent | a1016ce33ce23296ad030e5276fcfdf9cb27cb6a (diff) | |
parent | 15a3838b101b292c2e40824d843a4d8871ac4010 (diff) |
Merge branch 'for-next/gadget' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-next/gadget' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (50 commits)
usb: renesas_usbhs: show error reason on usbhsh_urb_enqueu()
usb: renesas_usbhs: add force packet remove method
usb: renesas_usbhs: care usb_hcd_giveback_urb() status
usb: renesas_usbhs: add usbhsh_is_running()
usb: renesas_usbhs: disable attch irq after device attached
usb: renesas_usbhs: care pipe sequence
usb: renesas_usbhs: add usbhs_pipe_attach() method
usb: renesas_usbhs: add usbhsh_endpoint_detach_all() for error case
usb: renesas_usbhs: modify device attach method
usb: renesas_usbhs: pop packet when urb dequeued
usb: renesas_usbhs: add lost error value when enqueue
usb: gadget: mv_udc: replace some debug info
usb: gadget: mv_udc: refine suspend/resume function
usb: gadget: mv_udc: refine the clock relative code
usb: gadget: mv_udc: disable ISR when stopped
usb: gadget: mv_udc: add otg relative code
usb: gadget: Use kcalloc instead of kzalloc to allocate array
usb: renesas_usbhs: remove the_controller_link
usb: renesas_usbhs: add test-mode support
usb: renesas_usbhs: call usbhsg_queue_pop() when pipe disable.
...
49 files changed, 1134 insertions, 595 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 3d849122b5b1..a7e4ac1202d6 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -535,6 +535,20 @@ Why: In 3.0, we can now autodetect internal 3G device and already have | |||
535 | information log when acer-wmi initial. | 535 | information log when acer-wmi initial. |
536 | Who: Lee, Chun-Yi <jlee@novell.com> | 536 | Who: Lee, Chun-Yi <jlee@novell.com> |
537 | 537 | ||
538 | --------------------------- | ||
539 | |||
540 | What: /sys/devices/platform/_UDC_/udc/_UDC_/is_dualspeed file and | ||
541 | is_dualspeed line in /sys/devices/platform/ci13xxx_*/udc/device file. | ||
542 | When: 3.8 | ||
543 | Why: The is_dualspeed file is superseded by maximum_speed in the same | ||
544 | directory and is_dualspeed line in device file is superseded by | ||
545 | max_speed line in the same file. | ||
546 | |||
547 | The maximum_speed/max_speed specifies maximum speed supported by UDC. | ||
548 | To check if dualspeeed is supported, check if the value is >= 3. | ||
549 | Various possible speeds are defined in <linux/usb/ch9.h>. | ||
550 | Who: Michal Nazarewicz <mina86@mina86.com> | ||
551 | |||
538 | ---------------------------- | 552 | ---------------------------- |
539 | 553 | ||
540 | What: The XFS nodelaylog mount option | 554 | What: The XFS nodelaylog mount option |
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index 026c53cf1645..36c61e80f323 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c | |||
@@ -2087,7 +2087,7 @@ int __devinit dwc3_gadget_init(struct dwc3 *dwc) | |||
2087 | dev_set_name(&dwc->gadget.dev, "gadget"); | 2087 | dev_set_name(&dwc->gadget.dev, "gadget"); |
2088 | 2088 | ||
2089 | dwc->gadget.ops = &dwc3_gadget_ops; | 2089 | dwc->gadget.ops = &dwc3_gadget_ops; |
2090 | dwc->gadget.is_dualspeed = true; | 2090 | dwc->gadget.max_speed = USB_SPEED_SUPER; |
2091 | dwc->gadget.speed = USB_SPEED_UNKNOWN; | 2091 | dwc->gadget.speed = USB_SPEED_UNKNOWN; |
2092 | dwc->gadget.dev.parent = dwc->dev; | 2092 | dwc->gadget.dev.parent = dwc->dev; |
2093 | 2093 | ||
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 71108c26c562..93f6c808f570 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -235,7 +235,6 @@ config USB_R8A66597 | |||
235 | 235 | ||
236 | config USB_RENESAS_USBHS_UDC | 236 | config USB_RENESAS_USBHS_UDC |
237 | tristate 'Renesas USBHS controller' | 237 | tristate 'Renesas USBHS controller' |
238 | depends on SUPERH || ARCH_SHMOBILE | ||
239 | depends on USB_RENESAS_USBHS | 238 | depends on USB_RENESAS_USBHS |
240 | select USB_GADGET_DUALSPEED | 239 | select USB_GADGET_DUALSPEED |
241 | help | 240 | help |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index 45f422ac103f..e9a2c5c44454 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -1959,7 +1959,7 @@ static int amd5536_start(struct usb_gadget_driver *driver, | |||
1959 | u32 tmp; | 1959 | u32 tmp; |
1960 | 1960 | ||
1961 | if (!driver || !bind || !driver->setup | 1961 | if (!driver || !bind || !driver->setup |
1962 | || driver->speed < USB_SPEED_HIGH) | 1962 | || driver->max_speed < USB_SPEED_HIGH) |
1963 | return -EINVAL; | 1963 | return -EINVAL; |
1964 | if (!dev) | 1964 | if (!dev) |
1965 | return -ENODEV; | 1965 | return -ENODEV; |
@@ -3349,7 +3349,7 @@ static int udc_probe(struct udc *dev) | |||
3349 | dev_set_name(&dev->gadget.dev, "gadget"); | 3349 | dev_set_name(&dev->gadget.dev, "gadget"); |
3350 | dev->gadget.dev.release = gadget_release; | 3350 | dev->gadget.dev.release = gadget_release; |
3351 | dev->gadget.name = name; | 3351 | dev->gadget.name = name; |
3352 | dev->gadget.is_dualspeed = 1; | 3352 | dev->gadget.max_speed = USB_SPEED_HIGH; |
3353 | 3353 | ||
3354 | /* init registers, interrupts, ... */ | 3354 | /* init registers, interrupts, ... */ |
3355 | startup_registers(dev); | 3355 | startup_registers(dev); |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 8efe0fa9228d..ac41f71bf9ca 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1633,7 +1633,7 @@ static int at91_start(struct usb_gadget_driver *driver, | |||
1633 | unsigned long flags; | 1633 | unsigned long flags; |
1634 | 1634 | ||
1635 | if (!driver | 1635 | if (!driver |
1636 | || driver->speed < USB_SPEED_FULL | 1636 | || driver->max_speed < USB_SPEED_FULL |
1637 | || !bind | 1637 | || !bind |
1638 | || !driver->setup) { | 1638 | || !driver->setup) { |
1639 | DBG("bad parameter.\n"); | 1639 | DBG("bad parameter.\n"); |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 271a9d873608..e2fb6d583bd9 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1038,7 +1038,7 @@ static struct usba_udc the_udc = { | |||
1038 | .gadget = { | 1038 | .gadget = { |
1039 | .ops = &usba_udc_ops, | 1039 | .ops = &usba_udc_ops, |
1040 | .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), | 1040 | .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), |
1041 | .is_dualspeed = 1, | 1041 | .max_speed = USB_SPEED_HIGH, |
1042 | .name = "atmel_usba_udc", | 1042 | .name = "atmel_usba_udc", |
1043 | .dev = { | 1043 | .dev = { |
1044 | .init_name = "gadget", | 1044 | .init_name = "gadget", |
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index 9a0c3979ff43..27e313718422 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -182,6 +182,16 @@ static inline int hw_ep_bit(int num, int dir) | |||
182 | return num + (dir ? 16 : 0); | 182 | return num + (dir ? 16 : 0); |
183 | } | 183 | } |
184 | 184 | ||
185 | static int ep_to_bit(int n) | ||
186 | { | ||
187 | int fill = 16 - hw_ep_max / 2; | ||
188 | |||
189 | if (n >= hw_ep_max / 2) | ||
190 | n += fill; | ||
191 | |||
192 | return n; | ||
193 | } | ||
194 | |||
185 | /** | 195 | /** |
186 | * hw_aread: reads from register bitfield | 196 | * hw_aread: reads from register bitfield |
187 | * @addr: address relative to bus map | 197 | * @addr: address relative to bus map |
@@ -440,12 +450,13 @@ static int hw_ep_get_halt(int num, int dir) | |||
440 | /** | 450 | /** |
441 | * hw_test_and_clear_setup_status: test & clear setup status (execute without | 451 | * hw_test_and_clear_setup_status: test & clear setup status (execute without |
442 | * interruption) | 452 | * interruption) |
443 | * @n: bit number (endpoint) | 453 | * @n: endpoint number |
444 | * | 454 | * |
445 | * This function returns setup status | 455 | * This function returns setup status |
446 | */ | 456 | */ |
447 | static int hw_test_and_clear_setup_status(int n) | 457 | static int hw_test_and_clear_setup_status(int n) |
448 | { | 458 | { |
459 | n = ep_to_bit(n); | ||
449 | return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n)); | 460 | return hw_ctest_and_clear(CAP_ENDPTSETUPSTAT, BIT(n)); |
450 | } | 461 | } |
451 | 462 | ||
@@ -641,12 +652,13 @@ static int hw_register_write(u16 addr, u32 data) | |||
641 | /** | 652 | /** |
642 | * hw_test_and_clear_complete: test & clear complete status (execute without | 653 | * hw_test_and_clear_complete: test & clear complete status (execute without |
643 | * interruption) | 654 | * interruption) |
644 | * @n: bit number (endpoint) | 655 | * @n: endpoint number |
645 | * | 656 | * |
646 | * This function returns complete status | 657 | * This function returns complete status |
647 | */ | 658 | */ |
648 | static int hw_test_and_clear_complete(int n) | 659 | static int hw_test_and_clear_complete(int n) |
649 | { | 660 | { |
661 | n = ep_to_bit(n); | ||
650 | return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n)); | 662 | return hw_ctest_and_clear(CAP_ENDPTCOMPLETE, BIT(n)); |
651 | } | 663 | } |
652 | 664 | ||
@@ -754,8 +766,11 @@ static ssize_t show_device(struct device *dev, struct device_attribute *attr, | |||
754 | 766 | ||
755 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", | 767 | n += scnprintf(buf + n, PAGE_SIZE - n, "speed = %d\n", |
756 | gadget->speed); | 768 | gadget->speed); |
769 | n += scnprintf(buf + n, PAGE_SIZE - n, "max_speed = %d\n", | ||
770 | gadget->max_speed); | ||
771 | /* TODO: Scheduled for removal in 3.8. */ | ||
757 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", | 772 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_dualspeed = %d\n", |
758 | gadget->is_dualspeed); | 773 | gadget_is_dualspeed(gadget)); |
759 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", | 774 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_otg = %d\n", |
760 | gadget->is_otg); | 775 | gadget->is_otg); |
761 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", | 776 | n += scnprintf(buf + n, PAGE_SIZE - n, "is_a_peripheral = %d\n", |
@@ -798,7 +813,7 @@ static ssize_t show_driver(struct device *dev, struct device_attribute *attr, | |||
798 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", | 813 | n += scnprintf(buf + n, PAGE_SIZE - n, "function = %s\n", |
799 | (driver->function ? driver->function : "")); | 814 | (driver->function ? driver->function : "")); |
800 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", | 815 | n += scnprintf(buf + n, PAGE_SIZE - n, "max speed = %d\n", |
801 | driver->speed); | 816 | driver->max_speed); |
802 | 817 | ||
803 | return n; | 818 | return n; |
804 | } | 819 | } |
@@ -2563,9 +2578,7 @@ static int ci13xxx_start(struct usb_gadget_driver *driver, | |||
2563 | if (driver == NULL || | 2578 | if (driver == NULL || |
2564 | bind == NULL || | 2579 | bind == NULL || |
2565 | driver->setup == NULL || | 2580 | driver->setup == NULL || |
2566 | driver->disconnect == NULL || | 2581 | driver->disconnect == NULL) |
2567 | driver->suspend == NULL || | ||
2568 | driver->resume == NULL) | ||
2569 | return -EINVAL; | 2582 | return -EINVAL; |
2570 | else if (udc == NULL) | 2583 | else if (udc == NULL) |
2571 | return -ENODEV; | 2584 | return -ENODEV; |
@@ -2693,8 +2706,6 @@ static int ci13xxx_stop(struct usb_gadget_driver *driver) | |||
2693 | driver->unbind == NULL || | 2706 | driver->unbind == NULL || |
2694 | driver->setup == NULL || | 2707 | driver->setup == NULL || |
2695 | driver->disconnect == NULL || | 2708 | driver->disconnect == NULL || |
2696 | driver->suspend == NULL || | ||
2697 | driver->resume == NULL || | ||
2698 | driver != udc->driver) | 2709 | driver != udc->driver) |
2699 | return -EINVAL; | 2710 | return -EINVAL; |
2700 | 2711 | ||
@@ -2793,7 +2804,7 @@ static irqreturn_t udc_irq(void) | |||
2793 | isr_statistics.pci++; | 2804 | isr_statistics.pci++; |
2794 | udc->gadget.speed = hw_port_is_high_speed() ? | 2805 | udc->gadget.speed = hw_port_is_high_speed() ? |
2795 | USB_SPEED_HIGH : USB_SPEED_FULL; | 2806 | USB_SPEED_HIGH : USB_SPEED_FULL; |
2796 | if (udc->suspended) { | 2807 | if (udc->suspended && udc->driver->resume) { |
2797 | spin_unlock(udc->lock); | 2808 | spin_unlock(udc->lock); |
2798 | udc->driver->resume(&udc->gadget); | 2809 | udc->driver->resume(&udc->gadget); |
2799 | spin_lock(udc->lock); | 2810 | spin_lock(udc->lock); |
@@ -2807,7 +2818,8 @@ static irqreturn_t udc_irq(void) | |||
2807 | isr_tr_complete_handler(udc); | 2818 | isr_tr_complete_handler(udc); |
2808 | } | 2819 | } |
2809 | if (USBi_SLI & intr) { | 2820 | if (USBi_SLI & intr) { |
2810 | if (udc->gadget.speed != USB_SPEED_UNKNOWN) { | 2821 | if (udc->gadget.speed != USB_SPEED_UNKNOWN && |
2822 | udc->driver->suspend) { | ||
2811 | udc->suspended = 1; | 2823 | udc->suspended = 1; |
2812 | spin_unlock(udc->lock); | 2824 | spin_unlock(udc->lock); |
2813 | udc->driver->suspend(&udc->gadget); | 2825 | udc->driver->suspend(&udc->gadget); |
@@ -2871,7 +2883,7 @@ static int udc_probe(struct ci13xxx_udc_driver *driver, struct device *dev, | |||
2871 | 2883 | ||
2872 | udc->gadget.ops = &usb_gadget_ops; | 2884 | udc->gadget.ops = &usb_gadget_ops; |
2873 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 2885 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
2874 | udc->gadget.is_dualspeed = 1; | 2886 | udc->gadget.max_speed = USB_SPEED_HIGH; |
2875 | udc->gadget.is_otg = 0; | 2887 | udc->gadget.is_otg = 0; |
2876 | udc->gadget.name = driver->name; | 2888 | udc->gadget.name = driver->name; |
2877 | 2889 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.h b/drivers/usb/gadget/ci13xxx_udc.h index 23707775cb43..f4871e1fac59 100644 --- a/drivers/usb/gadget/ci13xxx_udc.h +++ b/drivers/usb/gadget/ci13xxx_udc.h | |||
@@ -127,7 +127,7 @@ struct ci13xxx { | |||
127 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ | 127 | struct ci13xxx_ep ci13xxx_ep[ENDPT_MAX]; /* extended endpts */ |
128 | u32 ep0_dir; /* ep0 direction */ | 128 | u32 ep0_dir; /* ep0 direction */ |
129 | #define ep0out ci13xxx_ep[0] | 129 | #define ep0out ci13xxx_ep[0] |
130 | #define ep0in ci13xxx_ep[16] | 130 | #define ep0in ci13xxx_ep[hw_ep_max / 2] |
131 | u8 remote_wakeup; /* Is remote wakeup feature | 131 | u8 remote_wakeup; /* Is remote wakeup feature |
132 | enabled by the host? */ | 132 | enabled by the host? */ |
133 | u8 suspended; /* suspended by the host */ | 133 | u8 suspended; /* suspended by the host */ |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f71b0787983f..a95de6a4a134 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1535,9 +1535,9 @@ composite_resume(struct usb_gadget *gadget) | |||
1535 | 1535 | ||
1536 | static struct usb_gadget_driver composite_driver = { | 1536 | static struct usb_gadget_driver composite_driver = { |
1537 | #ifdef CONFIG_USB_GADGET_SUPERSPEED | 1537 | #ifdef CONFIG_USB_GADGET_SUPERSPEED |
1538 | .speed = USB_SPEED_SUPER, | 1538 | .max_speed = USB_SPEED_SUPER, |
1539 | #else | 1539 | #else |
1540 | .speed = USB_SPEED_HIGH, | 1540 | .max_speed = USB_SPEED_HIGH, |
1541 | #endif | 1541 | #endif |
1542 | 1542 | ||
1543 | .unbind = composite_unbind, | 1543 | .unbind = composite_unbind, |
@@ -1584,8 +1584,8 @@ int usb_composite_probe(struct usb_composite_driver *driver, | |||
1584 | driver->iProduct = driver->name; | 1584 | driver->iProduct = driver->name; |
1585 | composite_driver.function = (char *) driver->name; | 1585 | composite_driver.function = (char *) driver->name; |
1586 | composite_driver.driver.name = driver->name; | 1586 | composite_driver.driver.name = driver->name; |
1587 | composite_driver.speed = min((u8)composite_driver.speed, | 1587 | composite_driver.max_speed = |
1588 | (u8)driver->max_speed); | 1588 | min_t(u8, composite_driver.max_speed, driver->max_speed); |
1589 | composite = driver; | 1589 | composite = driver; |
1590 | composite_gadget_bind = bind; | 1590 | composite_gadget_bind = bind; |
1591 | 1591 | ||
diff --git a/drivers/usb/gadget/dbgp.c b/drivers/usb/gadget/dbgp.c index 6256420089f3..19d7bb0df75a 100644 --- a/drivers/usb/gadget/dbgp.c +++ b/drivers/usb/gadget/dbgp.c | |||
@@ -404,7 +404,7 @@ fail: | |||
404 | 404 | ||
405 | static struct usb_gadget_driver dbgp_driver = { | 405 | static struct usb_gadget_driver dbgp_driver = { |
406 | .function = "dbgp", | 406 | .function = "dbgp", |
407 | .speed = USB_SPEED_HIGH, | 407 | .max_speed = USB_SPEED_HIGH, |
408 | .unbind = dbgp_unbind, | 408 | .unbind = dbgp_unbind, |
409 | .setup = dbgp_setup, | 409 | .setup = dbgp_setup, |
410 | .disconnect = dbgp_disconnect, | 410 | .disconnect = dbgp_disconnect, |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index ab8f1b488d54..db815c2da7ed 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -823,19 +823,18 @@ static int dummy_pullup (struct usb_gadget *_gadget, int value) | |||
823 | 823 | ||
824 | if (value && dum->driver) { | 824 | if (value && dum->driver) { |
825 | if (mod_data.is_super_speed) | 825 | if (mod_data.is_super_speed) |
826 | dum->gadget.speed = dum->driver->speed; | 826 | dum->gadget.speed = dum->driver->max_speed; |
827 | else if (mod_data.is_high_speed) | 827 | else if (mod_data.is_high_speed) |
828 | dum->gadget.speed = min_t(u8, USB_SPEED_HIGH, | 828 | dum->gadget.speed = min_t(u8, USB_SPEED_HIGH, |
829 | dum->driver->speed); | 829 | dum->driver->max_speed); |
830 | else | 830 | else |
831 | dum->gadget.speed = USB_SPEED_FULL; | 831 | dum->gadget.speed = USB_SPEED_FULL; |
832 | dummy_udc_udpate_ep0(dum); | 832 | dummy_udc_udpate_ep0(dum); |
833 | 833 | ||
834 | if (dum->gadget.speed < dum->driver->speed) | 834 | if (dum->gadget.speed < dum->driver->max_speed) |
835 | dev_dbg(udc_dev(dum), "This device can perform faster" | 835 | dev_dbg(udc_dev(dum), "This device can perform faster" |
836 | " if you connect it to a %s port...\n", | 836 | " if you connect it to a %s port...\n", |
837 | (dum->driver->speed == USB_SPEED_SUPER ? | 837 | usb_speed_string(dum->driver->max_speed)); |
838 | "SuperSpeed" : "HighSpeed")); | ||
839 | } | 838 | } |
840 | dum_hcd = gadget_to_dummy_hcd(_gadget); | 839 | dum_hcd = gadget_to_dummy_hcd(_gadget); |
841 | 840 | ||
@@ -898,7 +897,7 @@ static int dummy_udc_start(struct usb_gadget *g, | |||
898 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); | 897 | struct dummy_hcd *dum_hcd = gadget_to_dummy_hcd(g); |
899 | struct dummy *dum = dum_hcd->dum; | 898 | struct dummy *dum = dum_hcd->dum; |
900 | 899 | ||
901 | if (driver->speed == USB_SPEED_UNKNOWN) | 900 | if (driver->max_speed == USB_SPEED_UNKNOWN) |
902 | return -EINVAL; | 901 | return -EINVAL; |
903 | 902 | ||
904 | /* | 903 | /* |
@@ -977,7 +976,7 @@ static int dummy_udc_probe (struct platform_device *pdev) | |||
977 | 976 | ||
978 | dum->gadget.name = gadget_name; | 977 | dum->gadget.name = gadget_name; |
979 | dum->gadget.ops = &dummy_ops; | 978 | dum->gadget.ops = &dummy_ops; |
980 | dum->gadget.is_dualspeed = 1; | 979 | dum->gadget.max_speed = USB_SPEED_SUPER; |
981 | 980 | ||
982 | dev_set_name(&dum->gadget.dev, "gadget"); | 981 | dev_set_name(&dum->gadget.dev, "gadget"); |
983 | dum->gadget.dev.parent = &pdev->dev; | 982 | dum->gadget.dev.parent = &pdev->dev; |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 596a0b464e61..38bcbfb91f62 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -152,7 +152,7 @@ ep_matches ( | |||
152 | switch (type) { | 152 | switch (type) { |
153 | case USB_ENDPOINT_XFER_INT: | 153 | case USB_ENDPOINT_XFER_INT: |
154 | /* INT: limit 64 bytes full speed, 1024 high/super speed */ | 154 | /* INT: limit 64 bytes full speed, 1024 high/super speed */ |
155 | if (!gadget->is_dualspeed && max > 64) | 155 | if (!gadget_is_dualspeed(gadget) && max > 64) |
156 | return 0; | 156 | return 0; |
157 | /* FALLTHROUGH */ | 157 | /* FALLTHROUGH */ |
158 | 158 | ||
@@ -160,12 +160,12 @@ ep_matches ( | |||
160 | /* ISO: limit 1023 bytes full speed, 1024 high/super speed */ | 160 | /* ISO: limit 1023 bytes full speed, 1024 high/super speed */ |
161 | if (ep->maxpacket < max) | 161 | if (ep->maxpacket < max) |
162 | return 0; | 162 | return 0; |
163 | if (!gadget->is_dualspeed && max > 1023) | 163 | if (!gadget_is_dualspeed(gadget) && max > 1023) |
164 | return 0; | 164 | return 0; |
165 | 165 | ||
166 | /* BOTH: "high bandwidth" works only at high speed */ | 166 | /* BOTH: "high bandwidth" works only at high speed */ |
167 | if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { | 167 | if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { |
168 | if (!gadget->is_dualspeed) | 168 | if (!gadget_is_dualspeed(gadget)) |
169 | return 0; | 169 | return 0; |
170 | /* configure your hardware with enough buffering!! */ | 170 | /* configure your hardware with enough buffering!! */ |
171 | } | 171 | } |
diff --git a/drivers/usb/gadget/f_fs.c b/drivers/usb/gadget/f_fs.c index acb38004eec0..da9d04815ea5 100644 --- a/drivers/usb/gadget/f_fs.c +++ b/drivers/usb/gadget/f_fs.c | |||
@@ -1408,7 +1408,7 @@ static int ffs_epfiles_create(struct ffs_data *ffs) | |||
1408 | ENTER(); | 1408 | ENTER(); |
1409 | 1409 | ||
1410 | count = ffs->eps_count; | 1410 | count = ffs->eps_count; |
1411 | epfiles = kzalloc(count * sizeof *epfiles, GFP_KERNEL); | 1411 | epfiles = kcalloc(count, sizeof(*epfiles), GFP_KERNEL); |
1412 | if (!epfiles) | 1412 | if (!epfiles) |
1413 | return -ENOMEM; | 1413 | return -ENOMEM; |
1414 | 1414 | ||
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c index c39d58860fa0..a18ebeed82b5 100644 --- a/drivers/usb/gadget/f_mass_storage.c +++ b/drivers/usb/gadget/f_mass_storage.c | |||
@@ -1873,17 +1873,14 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1873 | common->lun, lun); | 1873 | common->lun, lun); |
1874 | 1874 | ||
1875 | /* Check the LUN */ | 1875 | /* Check the LUN */ |
1876 | if (common->lun < common->nluns) { | 1876 | curlun = common->curlun; |
1877 | curlun = &common->luns[common->lun]; | 1877 | if (curlun) { |
1878 | common->curlun = curlun; | ||
1879 | if (common->cmnd[0] != REQUEST_SENSE) { | 1878 | if (common->cmnd[0] != REQUEST_SENSE) { |
1880 | curlun->sense_data = SS_NO_SENSE; | 1879 | curlun->sense_data = SS_NO_SENSE; |
1881 | curlun->sense_data_info = 0; | 1880 | curlun->sense_data_info = 0; |
1882 | curlun->info_valid = 0; | 1881 | curlun->info_valid = 0; |
1883 | } | 1882 | } |
1884 | } else { | 1883 | } else { |
1885 | common->curlun = NULL; | ||
1886 | curlun = NULL; | ||
1887 | common->bad_lun_okay = 0; | 1884 | common->bad_lun_okay = 0; |
1888 | 1885 | ||
1889 | /* | 1886 | /* |
@@ -1929,6 +1926,17 @@ static int check_command(struct fsg_common *common, int cmnd_size, | |||
1929 | return 0; | 1926 | return 0; |
1930 | } | 1927 | } |
1931 | 1928 | ||
1929 | /* wrapper of check_command for data size in blocks handling */ | ||
1930 | static int check_command_size_in_blocks(struct fsg_common *common, | ||
1931 | int cmnd_size, enum data_direction data_dir, | ||
1932 | unsigned int mask, int needs_medium, const char *name) | ||
1933 | { | ||
1934 | if (common->curlun) | ||
1935 | common->data_size_from_cmnd <<= common->curlun->blkbits; | ||
1936 | return check_command(common, cmnd_size, data_dir, | ||
1937 | mask, needs_medium, name); | ||
1938 | } | ||
1939 | |||
1932 | static int do_scsi_command(struct fsg_common *common) | 1940 | static int do_scsi_command(struct fsg_common *common) |
1933 | { | 1941 | { |
1934 | struct fsg_buffhd *bh; | 1942 | struct fsg_buffhd *bh; |
@@ -2011,9 +2019,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2011 | 2019 | ||
2012 | case READ_6: | 2020 | case READ_6: |
2013 | i = common->cmnd[4]; | 2021 | i = common->cmnd[4]; |
2014 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << | 2022 | common->data_size_from_cmnd = (i == 0) ? 256 : i; |
2015 | common->curlun->blkbits; | 2023 | reply = check_command_size_in_blocks(common, 6, |
2016 | reply = check_command(common, 6, DATA_DIR_TO_HOST, | 2024 | DATA_DIR_TO_HOST, |
2017 | (7<<1) | (1<<4), 1, | 2025 | (7<<1) | (1<<4), 1, |
2018 | "READ(6)"); | 2026 | "READ(6)"); |
2019 | if (reply == 0) | 2027 | if (reply == 0) |
@@ -2022,9 +2030,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2022 | 2030 | ||
2023 | case READ_10: | 2031 | case READ_10: |
2024 | common->data_size_from_cmnd = | 2032 | common->data_size_from_cmnd = |
2025 | get_unaligned_be16(&common->cmnd[7]) << | 2033 | get_unaligned_be16(&common->cmnd[7]); |
2026 | common->curlun->blkbits; | 2034 | reply = check_command_size_in_blocks(common, 10, |
2027 | reply = check_command(common, 10, DATA_DIR_TO_HOST, | 2035 | DATA_DIR_TO_HOST, |
2028 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2036 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2029 | "READ(10)"); | 2037 | "READ(10)"); |
2030 | if (reply == 0) | 2038 | if (reply == 0) |
@@ -2033,9 +2041,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2033 | 2041 | ||
2034 | case READ_12: | 2042 | case READ_12: |
2035 | common->data_size_from_cmnd = | 2043 | common->data_size_from_cmnd = |
2036 | get_unaligned_be32(&common->cmnd[6]) << | 2044 | get_unaligned_be32(&common->cmnd[6]); |
2037 | common->curlun->blkbits; | 2045 | reply = check_command_size_in_blocks(common, 12, |
2038 | reply = check_command(common, 12, DATA_DIR_TO_HOST, | 2046 | DATA_DIR_TO_HOST, |
2039 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2047 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2040 | "READ(12)"); | 2048 | "READ(12)"); |
2041 | if (reply == 0) | 2049 | if (reply == 0) |
@@ -2134,9 +2142,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2134 | 2142 | ||
2135 | case WRITE_6: | 2143 | case WRITE_6: |
2136 | i = common->cmnd[4]; | 2144 | i = common->cmnd[4]; |
2137 | common->data_size_from_cmnd = (i == 0 ? 256 : i) << | 2145 | common->data_size_from_cmnd = (i == 0) ? 256 : i; |
2138 | common->curlun->blkbits; | 2146 | reply = check_command_size_in_blocks(common, 6, |
2139 | reply = check_command(common, 6, DATA_DIR_FROM_HOST, | 2147 | DATA_DIR_FROM_HOST, |
2140 | (7<<1) | (1<<4), 1, | 2148 | (7<<1) | (1<<4), 1, |
2141 | "WRITE(6)"); | 2149 | "WRITE(6)"); |
2142 | if (reply == 0) | 2150 | if (reply == 0) |
@@ -2145,9 +2153,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2145 | 2153 | ||
2146 | case WRITE_10: | 2154 | case WRITE_10: |
2147 | common->data_size_from_cmnd = | 2155 | common->data_size_from_cmnd = |
2148 | get_unaligned_be16(&common->cmnd[7]) << | 2156 | get_unaligned_be16(&common->cmnd[7]); |
2149 | common->curlun->blkbits; | 2157 | reply = check_command_size_in_blocks(common, 10, |
2150 | reply = check_command(common, 10, DATA_DIR_FROM_HOST, | 2158 | DATA_DIR_FROM_HOST, |
2151 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2159 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2152 | "WRITE(10)"); | 2160 | "WRITE(10)"); |
2153 | if (reply == 0) | 2161 | if (reply == 0) |
@@ -2156,9 +2164,9 @@ static int do_scsi_command(struct fsg_common *common) | |||
2156 | 2164 | ||
2157 | case WRITE_12: | 2165 | case WRITE_12: |
2158 | common->data_size_from_cmnd = | 2166 | common->data_size_from_cmnd = |
2159 | get_unaligned_be32(&common->cmnd[6]) << | 2167 | get_unaligned_be32(&common->cmnd[6]); |
2160 | common->curlun->blkbits; | 2168 | reply = check_command_size_in_blocks(common, 12, |
2161 | reply = check_command(common, 12, DATA_DIR_FROM_HOST, | 2169 | DATA_DIR_FROM_HOST, |
2162 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2170 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2163 | "WRITE(12)"); | 2171 | "WRITE(12)"); |
2164 | if (reply == 0) | 2172 | if (reply == 0) |
@@ -2273,6 +2281,10 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
2273 | if (common->data_size == 0) | 2281 | if (common->data_size == 0) |
2274 | common->data_dir = DATA_DIR_NONE; | 2282 | common->data_dir = DATA_DIR_NONE; |
2275 | common->lun = cbw->Lun; | 2283 | common->lun = cbw->Lun; |
2284 | if (common->lun >= 0 && common->lun < common->nluns) | ||
2285 | common->curlun = &common->luns[common->lun]; | ||
2286 | else | ||
2287 | common->curlun = NULL; | ||
2276 | common->tag = cbw->Tag; | 2288 | common->tag = cbw->Tag; |
2277 | return 0; | 2289 | return 0; |
2278 | } | 2290 | } |
@@ -2763,7 +2775,7 @@ static struct fsg_common *fsg_common_init(struct fsg_common *common, | |||
2763 | * Create the LUNs, open their backing files, and register the | 2775 | * Create the LUNs, open their backing files, and register the |
2764 | * LUN devices in sysfs. | 2776 | * LUN devices in sysfs. |
2765 | */ | 2777 | */ |
2766 | curlun = kzalloc(nluns * sizeof *curlun, GFP_KERNEL); | 2778 | curlun = kcalloc(nluns, sizeof(*curlun), GFP_KERNEL); |
2767 | if (unlikely(!curlun)) { | 2779 | if (unlikely(!curlun)) { |
2768 | rc = -ENOMEM; | 2780 | rc = -ENOMEM; |
2769 | goto error_release; | 2781 | goto error_release; |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 11b5196284ae..e0f30fc70e45 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -2297,19 +2297,17 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2297 | DBG(fsg, "using LUN %d from CBW, " | 2297 | DBG(fsg, "using LUN %d from CBW, " |
2298 | "not LUN %d from CDB\n", | 2298 | "not LUN %d from CDB\n", |
2299 | fsg->lun, lun); | 2299 | fsg->lun, lun); |
2300 | } else | 2300 | } |
2301 | fsg->lun = lun; // Use LUN from the command | ||
2302 | 2301 | ||
2303 | /* Check the LUN */ | 2302 | /* Check the LUN */ |
2304 | if (fsg->lun < fsg->nluns) { | 2303 | curlun = fsg->curlun; |
2305 | fsg->curlun = curlun = &fsg->luns[fsg->lun]; | 2304 | if (curlun) { |
2306 | if (fsg->cmnd[0] != REQUEST_SENSE) { | 2305 | if (fsg->cmnd[0] != REQUEST_SENSE) { |
2307 | curlun->sense_data = SS_NO_SENSE; | 2306 | curlun->sense_data = SS_NO_SENSE; |
2308 | curlun->sense_data_info = 0; | 2307 | curlun->sense_data_info = 0; |
2309 | curlun->info_valid = 0; | 2308 | curlun->info_valid = 0; |
2310 | } | 2309 | } |
2311 | } else { | 2310 | } else { |
2312 | fsg->curlun = curlun = NULL; | ||
2313 | fsg->bad_lun_okay = 0; | 2311 | fsg->bad_lun_okay = 0; |
2314 | 2312 | ||
2315 | /* INQUIRY and REQUEST SENSE commands are explicitly allowed | 2313 | /* INQUIRY and REQUEST SENSE commands are explicitly allowed |
@@ -2351,6 +2349,16 @@ static int check_command(struct fsg_dev *fsg, int cmnd_size, | |||
2351 | return 0; | 2349 | return 0; |
2352 | } | 2350 | } |
2353 | 2351 | ||
2352 | /* wrapper of check_command for data size in blocks handling */ | ||
2353 | static int check_command_size_in_blocks(struct fsg_dev *fsg, int cmnd_size, | ||
2354 | enum data_direction data_dir, unsigned int mask, | ||
2355 | int needs_medium, const char *name) | ||
2356 | { | ||
2357 | if (fsg->curlun) | ||
2358 | fsg->data_size_from_cmnd <<= fsg->curlun->blkbits; | ||
2359 | return check_command(fsg, cmnd_size, data_dir, | ||
2360 | mask, needs_medium, name); | ||
2361 | } | ||
2354 | 2362 | ||
2355 | static int do_scsi_command(struct fsg_dev *fsg) | 2363 | static int do_scsi_command(struct fsg_dev *fsg) |
2356 | { | 2364 | { |
@@ -2425,26 +2433,27 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2425 | 2433 | ||
2426 | case READ_6: | 2434 | case READ_6: |
2427 | i = fsg->cmnd[4]; | 2435 | i = fsg->cmnd[4]; |
2428 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits; | 2436 | fsg->data_size_from_cmnd = (i == 0) ? 256 : i; |
2429 | if ((reply = check_command(fsg, 6, DATA_DIR_TO_HOST, | 2437 | if ((reply = check_command_size_in_blocks(fsg, 6, |
2438 | DATA_DIR_TO_HOST, | ||
2430 | (7<<1) | (1<<4), 1, | 2439 | (7<<1) | (1<<4), 1, |
2431 | "READ(6)")) == 0) | 2440 | "READ(6)")) == 0) |
2432 | reply = do_read(fsg); | 2441 | reply = do_read(fsg); |
2433 | break; | 2442 | break; |
2434 | 2443 | ||
2435 | case READ_10: | 2444 | case READ_10: |
2436 | fsg->data_size_from_cmnd = | 2445 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
2437 | get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits; | 2446 | if ((reply = check_command_size_in_blocks(fsg, 10, |
2438 | if ((reply = check_command(fsg, 10, DATA_DIR_TO_HOST, | 2447 | DATA_DIR_TO_HOST, |
2439 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2448 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2440 | "READ(10)")) == 0) | 2449 | "READ(10)")) == 0) |
2441 | reply = do_read(fsg); | 2450 | reply = do_read(fsg); |
2442 | break; | 2451 | break; |
2443 | 2452 | ||
2444 | case READ_12: | 2453 | case READ_12: |
2445 | fsg->data_size_from_cmnd = | 2454 | fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); |
2446 | get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits; | 2455 | if ((reply = check_command_size_in_blocks(fsg, 12, |
2447 | if ((reply = check_command(fsg, 12, DATA_DIR_TO_HOST, | 2456 | DATA_DIR_TO_HOST, |
2448 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2457 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2449 | "READ(12)")) == 0) | 2458 | "READ(12)")) == 0) |
2450 | reply = do_read(fsg); | 2459 | reply = do_read(fsg); |
@@ -2529,26 +2538,27 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2529 | 2538 | ||
2530 | case WRITE_6: | 2539 | case WRITE_6: |
2531 | i = fsg->cmnd[4]; | 2540 | i = fsg->cmnd[4]; |
2532 | fsg->data_size_from_cmnd = (i == 0 ? 256 : i) << fsg->curlun->blkbits; | 2541 | fsg->data_size_from_cmnd = (i == 0) ? 256 : i; |
2533 | if ((reply = check_command(fsg, 6, DATA_DIR_FROM_HOST, | 2542 | if ((reply = check_command_size_in_blocks(fsg, 6, |
2543 | DATA_DIR_FROM_HOST, | ||
2534 | (7<<1) | (1<<4), 1, | 2544 | (7<<1) | (1<<4), 1, |
2535 | "WRITE(6)")) == 0) | 2545 | "WRITE(6)")) == 0) |
2536 | reply = do_write(fsg); | 2546 | reply = do_write(fsg); |
2537 | break; | 2547 | break; |
2538 | 2548 | ||
2539 | case WRITE_10: | 2549 | case WRITE_10: |
2540 | fsg->data_size_from_cmnd = | 2550 | fsg->data_size_from_cmnd = get_unaligned_be16(&fsg->cmnd[7]); |
2541 | get_unaligned_be16(&fsg->cmnd[7]) << fsg->curlun->blkbits; | 2551 | if ((reply = check_command_size_in_blocks(fsg, 10, |
2542 | if ((reply = check_command(fsg, 10, DATA_DIR_FROM_HOST, | 2552 | DATA_DIR_FROM_HOST, |
2543 | (1<<1) | (0xf<<2) | (3<<7), 1, | 2553 | (1<<1) | (0xf<<2) | (3<<7), 1, |
2544 | "WRITE(10)")) == 0) | 2554 | "WRITE(10)")) == 0) |
2545 | reply = do_write(fsg); | 2555 | reply = do_write(fsg); |
2546 | break; | 2556 | break; |
2547 | 2557 | ||
2548 | case WRITE_12: | 2558 | case WRITE_12: |
2549 | fsg->data_size_from_cmnd = | 2559 | fsg->data_size_from_cmnd = get_unaligned_be32(&fsg->cmnd[6]); |
2550 | get_unaligned_be32(&fsg->cmnd[6]) << fsg->curlun->blkbits; | 2560 | if ((reply = check_command_size_in_blocks(fsg, 12, |
2551 | if ((reply = check_command(fsg, 12, DATA_DIR_FROM_HOST, | 2561 | DATA_DIR_FROM_HOST, |
2552 | (1<<1) | (0xf<<2) | (0xf<<6), 1, | 2562 | (1<<1) | (0xf<<2) | (0xf<<6), 1, |
2553 | "WRITE(12)")) == 0) | 2563 | "WRITE(12)")) == 0) |
2554 | reply = do_write(fsg); | 2564 | reply = do_write(fsg); |
@@ -2715,7 +2725,17 @@ static int get_next_command(struct fsg_dev *fsg) | |||
2715 | memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); | 2725 | memcpy(fsg->cmnd, fsg->cbbuf_cmnd, fsg->cmnd_size); |
2716 | fsg->cbbuf_cmnd_size = 0; | 2726 | fsg->cbbuf_cmnd_size = 0; |
2717 | spin_unlock_irq(&fsg->lock); | 2727 | spin_unlock_irq(&fsg->lock); |
2728 | |||
2729 | /* Use LUN from the command */ | ||
2730 | fsg->lun = fsg->cmnd[1] >> 5; | ||
2718 | } | 2731 | } |
2732 | |||
2733 | /* Update current lun */ | ||
2734 | if (fsg->lun >= 0 && fsg->lun < fsg->nluns) | ||
2735 | fsg->curlun = &fsg->luns[fsg->lun]; | ||
2736 | else | ||
2737 | fsg->curlun = NULL; | ||
2738 | |||
2719 | return rc; | 2739 | return rc; |
2720 | } | 2740 | } |
2721 | 2741 | ||
@@ -3584,7 +3604,7 @@ static void fsg_resume(struct usb_gadget *gadget) | |||
3584 | /*-------------------------------------------------------------------------*/ | 3604 | /*-------------------------------------------------------------------------*/ |
3585 | 3605 | ||
3586 | static struct usb_gadget_driver fsg_driver = { | 3606 | static struct usb_gadget_driver fsg_driver = { |
3587 | .speed = USB_SPEED_SUPER, | 3607 | .max_speed = USB_SPEED_SUPER, |
3588 | .function = (char *) fsg_string_product, | 3608 | .function = (char *) fsg_string_product, |
3589 | .unbind = fsg_unbind, | 3609 | .unbind = fsg_unbind, |
3590 | .disconnect = fsg_disconnect, | 3610 | .disconnect = fsg_disconnect, |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index f75c56a259a9..b95697c03d07 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -2336,7 +2336,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver, | |||
2336 | if (!udc_controller) | 2336 | if (!udc_controller) |
2337 | return -ENODEV; | 2337 | return -ENODEV; |
2338 | 2338 | ||
2339 | if (!driver || driver->speed < USB_SPEED_FULL | 2339 | if (!driver || driver->max_speed < USB_SPEED_FULL |
2340 | || !bind || !driver->disconnect || !driver->setup) | 2340 | || !bind || !driver->disconnect || !driver->setup) |
2341 | return -EINVAL; | 2341 | return -EINVAL; |
2342 | 2342 | ||
@@ -2350,7 +2350,7 @@ static int fsl_qe_start(struct usb_gadget_driver *driver, | |||
2350 | /* hook up the driver */ | 2350 | /* hook up the driver */ |
2351 | udc_controller->driver = driver; | 2351 | udc_controller->driver = driver; |
2352 | udc_controller->gadget.dev.driver = &driver->driver; | 2352 | udc_controller->gadget.dev.driver = &driver->driver; |
2353 | udc_controller->gadget.speed = (enum usb_device_speed)(driver->speed); | 2353 | udc_controller->gadget.speed = driver->max_speed; |
2354 | spin_unlock_irqrestore(&udc_controller->lock, flags); | 2354 | spin_unlock_irqrestore(&udc_controller->lock, flags); |
2355 | 2355 | ||
2356 | retval = bind(&udc_controller->gadget); | 2356 | retval = bind(&udc_controller->gadget); |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index dd28ef3def71..d7ea6c076ce9 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -1934,7 +1934,7 @@ static int fsl_start(struct usb_gadget_driver *driver, | |||
1934 | if (!udc_controller) | 1934 | if (!udc_controller) |
1935 | return -ENODEV; | 1935 | return -ENODEV; |
1936 | 1936 | ||
1937 | if (!driver || driver->speed < USB_SPEED_FULL | 1937 | if (!driver || driver->max_speed < USB_SPEED_FULL |
1938 | || !bind || !driver->disconnect || !driver->setup) | 1938 | || !bind || !driver->disconnect || !driver->setup) |
1939 | return -EINVAL; | 1939 | return -EINVAL; |
1940 | 1940 | ||
@@ -2525,7 +2525,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2525 | 2525 | ||
2526 | /* Setup gadget structure */ | 2526 | /* Setup gadget structure */ |
2527 | udc_controller->gadget.ops = &fsl_gadget_ops; | 2527 | udc_controller->gadget.ops = &fsl_gadget_ops; |
2528 | udc_controller->gadget.is_dualspeed = 1; | 2528 | udc_controller->gadget.max_speed = USB_SPEED_HIGH; |
2529 | udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; | 2529 | udc_controller->gadget.ep0 = &udc_controller->eps[0].ep; |
2530 | INIT_LIST_HEAD(&udc_controller->gadget.ep_list); | 2530 | INIT_LIST_HEAD(&udc_controller->gadget.ep_list); |
2531 | udc_controller->gadget.speed = USB_SPEED_UNKNOWN; | 2531 | udc_controller->gadget.speed = USB_SPEED_UNKNOWN; |
diff --git a/drivers/usb/gadget/fusb300_udc.c b/drivers/usb/gadget/fusb300_udc.c index 74da206c8406..5831cb4a0b35 100644 --- a/drivers/usb/gadget/fusb300_udc.c +++ b/drivers/usb/gadget/fusb300_udc.c | |||
@@ -1317,7 +1317,7 @@ static int fusb300_udc_start(struct usb_gadget_driver *driver, | |||
1317 | int retval; | 1317 | int retval; |
1318 | 1318 | ||
1319 | if (!driver | 1319 | if (!driver |
1320 | || driver->speed < USB_SPEED_FULL | 1320 | || driver->max_speed < USB_SPEED_FULL |
1321 | || !bind | 1321 | || !bind |
1322 | || !driver->setup) | 1322 | || !driver->setup) |
1323 | return -EINVAL; | 1323 | return -EINVAL; |
@@ -1463,7 +1463,7 @@ static int __init fusb300_probe(struct platform_device *pdev) | |||
1463 | 1463 | ||
1464 | dev_set_name(&fusb300->gadget.dev, "gadget"); | 1464 | dev_set_name(&fusb300->gadget.dev, "gadget"); |
1465 | 1465 | ||
1466 | fusb300->gadget.is_dualspeed = 1; | 1466 | fusb300->gadget.max_speed = USB_SPEED_HIGH; |
1467 | fusb300->gadget.dev.parent = &pdev->dev; | 1467 | fusb300->gadget.dev.parent = &pdev->dev; |
1468 | fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1468 | fusb300->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1469 | fusb300->gadget.dev.release = pdev->dev.release; | 1469 | fusb300->gadget.dev.release = pdev->dev.release; |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 7f87805cddc4..5af70fcce139 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1357,7 +1357,7 @@ static int goku_start(struct usb_gadget_driver *driver, | |||
1357 | int retval; | 1357 | int retval; |
1358 | 1358 | ||
1359 | if (!driver | 1359 | if (!driver |
1360 | || driver->speed < USB_SPEED_FULL | 1360 | || driver->max_speed < USB_SPEED_FULL |
1361 | || !bind | 1361 | || !bind |
1362 | || !driver->disconnect | 1362 | || !driver->disconnect |
1363 | || !driver->setup) | 1363 | || !driver->setup) |
@@ -1796,6 +1796,7 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1796 | spin_lock_init(&dev->lock); | 1796 | spin_lock_init(&dev->lock); |
1797 | dev->pdev = pdev; | 1797 | dev->pdev = pdev; |
1798 | dev->gadget.ops = &goku_ops; | 1798 | dev->gadget.ops = &goku_ops; |
1799 | dev->gadget.max_speed = USB_SPEED_FULL; | ||
1799 | 1800 | ||
1800 | /* the "gadget" abstracts/virtualizes the controller */ | 1801 | /* the "gadget" abstracts/virtualizes the controller */ |
1801 | dev_set_name(&dev->gadget.dev, "gadget"); | 1802 | dev_set_name(&dev->gadget.dev, "gadget"); |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 2d978c0e7ced..8d1c75abd73d 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
@@ -1336,7 +1336,7 @@ static int imx_udc_start(struct usb_gadget_driver *driver, | |||
1336 | int retval; | 1336 | int retval; |
1337 | 1337 | ||
1338 | if (!driver | 1338 | if (!driver |
1339 | || driver->speed < USB_SPEED_FULL | 1339 | || driver->max_speed < USB_SPEED_FULL |
1340 | || !bind | 1340 | || !bind |
1341 | || !driver->disconnect | 1341 | || !driver->disconnect |
1342 | || !driver->setup) | 1342 | || !driver->setup) |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 6ccae2707e59..93612519b53a 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1766,9 +1766,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) | |||
1766 | 1766 | ||
1767 | static struct usb_gadget_driver gadgetfs_driver = { | 1767 | static struct usb_gadget_driver gadgetfs_driver = { |
1768 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1768 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1769 | .speed = USB_SPEED_HIGH, | 1769 | .max_speed = USB_SPEED_HIGH, |
1770 | #else | 1770 | #else |
1771 | .speed = USB_SPEED_FULL, | 1771 | .max_speed = USB_SPEED_FULL, |
1772 | #endif | 1772 | #endif |
1773 | .function = (char *) driver_desc, | 1773 | .function = (char *) driver_desc, |
1774 | .unbind = gadgetfs_unbind, | 1774 | .unbind = gadgetfs_unbind, |
@@ -1792,7 +1792,7 @@ static int gadgetfs_probe (struct usb_gadget *gadget) | |||
1792 | } | 1792 | } |
1793 | 1793 | ||
1794 | static struct usb_gadget_driver probe_driver = { | 1794 | static struct usb_gadget_driver probe_driver = { |
1795 | .speed = USB_SPEED_HIGH, | 1795 | .max_speed = USB_SPEED_HIGH, |
1796 | .unbind = gadgetfs_nop, | 1796 | .unbind = gadgetfs_nop, |
1797 | .setup = (void *)gadgetfs_nop, | 1797 | .setup = (void *)gadgetfs_nop, |
1798 | .disconnect = gadgetfs_nop, | 1798 | .disconnect = gadgetfs_nop, |
diff --git a/drivers/usb/gadget/langwell_udc.c b/drivers/usb/gadget/langwell_udc.c index c9fa3bf5b377..fa0fcc11263f 100644 --- a/drivers/usb/gadget/langwell_udc.c +++ b/drivers/usb/gadget/langwell_udc.c | |||
@@ -3267,7 +3267,7 @@ static int langwell_udc_probe(struct pci_dev *pdev, | |||
3267 | dev->gadget.ep0 = &dev->ep[0].ep; /* gadget ep0 */ | 3267 | dev->gadget.ep0 = &dev->ep[0].ep; /* gadget ep0 */ |
3268 | INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ | 3268 | INIT_LIST_HEAD(&dev->gadget.ep_list); /* ep_list */ |
3269 | dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | 3269 | dev->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ |
3270 | dev->gadget.is_dualspeed = 1; /* support dual speed */ | 3270 | dev->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ |
3271 | #ifdef OTG_TRANSCEIVER | 3271 | #ifdef OTG_TRANSCEIVER |
3272 | dev->gadget.is_otg = 1; /* support otg mode */ | 3272 | dev->gadget.is_otg = 1; /* support otg mode */ |
3273 | #endif | 3273 | #endif |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 9aa1cbbee45b..3608b3bd5732 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -1472,7 +1472,7 @@ static int m66592_start(struct usb_gadget_driver *driver, | |||
1472 | int retval; | 1472 | int retval; |
1473 | 1473 | ||
1474 | if (!driver | 1474 | if (!driver |
1475 | || driver->speed < USB_SPEED_HIGH | 1475 | || driver->max_speed < USB_SPEED_HIGH |
1476 | || !bind | 1476 | || !bind |
1477 | || !driver->setup) | 1477 | || !driver->setup) |
1478 | return -EINVAL; | 1478 | return -EINVAL; |
@@ -1653,7 +1653,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1653 | m66592->gadget.ops = &m66592_gadget_ops; | 1653 | m66592->gadget.ops = &m66592_gadget_ops; |
1654 | device_initialize(&m66592->gadget.dev); | 1654 | device_initialize(&m66592->gadget.dev); |
1655 | dev_set_name(&m66592->gadget.dev, "gadget"); | 1655 | dev_set_name(&m66592->gadget.dev, "gadget"); |
1656 | m66592->gadget.is_dualspeed = 1; | 1656 | m66592->gadget.max_speed = USB_SPEED_HIGH; |
1657 | m66592->gadget.dev.parent = &pdev->dev; | 1657 | m66592->gadget.dev.parent = &pdev->dev; |
1658 | m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1658 | m66592->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1659 | m66592->gadget.dev.release = pdev->dev.release; | 1659 | m66592->gadget.dev.release = pdev->dev.release; |
diff --git a/drivers/usb/gadget/mv_udc.h b/drivers/usb/gadget/mv_udc.h index daa75c12f336..3d8404484613 100644 --- a/drivers/usb/gadget/mv_udc.h +++ b/drivers/usb/gadget/mv_udc.h | |||
@@ -211,11 +211,14 @@ struct mv_udc { | |||
211 | softconnected:1, | 211 | softconnected:1, |
212 | force_fs:1, | 212 | force_fs:1, |
213 | clock_gating:1, | 213 | clock_gating:1, |
214 | active:1; | 214 | active:1, |
215 | stopped:1; /* stop bit is setted */ | ||
215 | 216 | ||
216 | struct work_struct vbus_work; | 217 | struct work_struct vbus_work; |
217 | struct workqueue_struct *qwork; | 218 | struct workqueue_struct *qwork; |
218 | 219 | ||
220 | struct otg_transceiver *transceiver; | ||
221 | |||
219 | struct mv_usb_platform_data *pdata; | 222 | struct mv_usb_platform_data *pdata; |
220 | 223 | ||
221 | /* some SOC has mutiple clock sources for USB*/ | 224 | /* some SOC has mutiple clock sources for USB*/ |
diff --git a/drivers/usb/gadget/mv_udc_core.c b/drivers/usb/gadget/mv_udc_core.c index 0114fd33fbe2..142a67f06638 100644 --- a/drivers/usb/gadget/mv_udc_core.c +++ b/drivers/usb/gadget/mv_udc_core.c | |||
@@ -1056,6 +1056,8 @@ static void udc_stop(struct mv_udc *udc) | |||
1056 | USBINTR_PORT_CHANGE_DETECT_EN | USBINTR_RESET_EN); | 1056 | USBINTR_PORT_CHANGE_DETECT_EN | USBINTR_RESET_EN); |
1057 | writel(tmp, &udc->op_regs->usbintr); | 1057 | writel(tmp, &udc->op_regs->usbintr); |
1058 | 1058 | ||
1059 | udc->stopped = 1; | ||
1060 | |||
1059 | /* Reset the Run the bit in the command register to stop VUSB */ | 1061 | /* Reset the Run the bit in the command register to stop VUSB */ |
1060 | tmp = readl(&udc->op_regs->usbcmd); | 1062 | tmp = readl(&udc->op_regs->usbcmd); |
1061 | tmp &= ~USBCMD_RUN_STOP; | 1063 | tmp &= ~USBCMD_RUN_STOP; |
@@ -1072,6 +1074,8 @@ static void udc_start(struct mv_udc *udc) | |||
1072 | /* Enable interrupts */ | 1074 | /* Enable interrupts */ |
1073 | writel(usbintr, &udc->op_regs->usbintr); | 1075 | writel(usbintr, &udc->op_regs->usbintr); |
1074 | 1076 | ||
1077 | udc->stopped = 0; | ||
1078 | |||
1075 | /* Set the Run bit in the command register */ | 1079 | /* Set the Run bit in the command register */ |
1076 | writel(USBCMD_RUN_STOP, &udc->op_regs->usbcmd); | 1080 | writel(USBCMD_RUN_STOP, &udc->op_regs->usbcmd); |
1077 | } | 1081 | } |
@@ -1134,11 +1138,11 @@ static int udc_reset(struct mv_udc *udc) | |||
1134 | return 0; | 1138 | return 0; |
1135 | } | 1139 | } |
1136 | 1140 | ||
1137 | static int mv_udc_enable(struct mv_udc *udc) | 1141 | static int mv_udc_enable_internal(struct mv_udc *udc) |
1138 | { | 1142 | { |
1139 | int retval; | 1143 | int retval; |
1140 | 1144 | ||
1141 | if (udc->clock_gating == 0 || udc->active) | 1145 | if (udc->active) |
1142 | return 0; | 1146 | return 0; |
1143 | 1147 | ||
1144 | dev_dbg(&udc->dev->dev, "enable udc\n"); | 1148 | dev_dbg(&udc->dev->dev, "enable udc\n"); |
@@ -1157,9 +1161,17 @@ static int mv_udc_enable(struct mv_udc *udc) | |||
1157 | return 0; | 1161 | return 0; |
1158 | } | 1162 | } |
1159 | 1163 | ||
1160 | static void mv_udc_disable(struct mv_udc *udc) | 1164 | static int mv_udc_enable(struct mv_udc *udc) |
1161 | { | 1165 | { |
1162 | if (udc->clock_gating && udc->active) { | 1166 | if (udc->clock_gating) |
1167 | return mv_udc_enable_internal(udc); | ||
1168 | |||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1172 | static void mv_udc_disable_internal(struct mv_udc *udc) | ||
1173 | { | ||
1174 | if (udc->active) { | ||
1163 | dev_dbg(&udc->dev->dev, "disable udc\n"); | 1175 | dev_dbg(&udc->dev->dev, "disable udc\n"); |
1164 | if (udc->pdata->phy_deinit) | 1176 | if (udc->pdata->phy_deinit) |
1165 | udc->pdata->phy_deinit(udc->phy_regs); | 1177 | udc->pdata->phy_deinit(udc->phy_regs); |
@@ -1168,6 +1180,12 @@ static void mv_udc_disable(struct mv_udc *udc) | |||
1168 | } | 1180 | } |
1169 | } | 1181 | } |
1170 | 1182 | ||
1183 | static void mv_udc_disable(struct mv_udc *udc) | ||
1184 | { | ||
1185 | if (udc->clock_gating) | ||
1186 | mv_udc_disable_internal(udc); | ||
1187 | } | ||
1188 | |||
1171 | static int mv_udc_get_frame(struct usb_gadget *gadget) | 1189 | static int mv_udc_get_frame(struct usb_gadget *gadget) |
1172 | { | 1190 | { |
1173 | struct mv_udc *udc; | 1191 | struct mv_udc *udc; |
@@ -1212,10 +1230,11 @@ static int mv_udc_vbus_session(struct usb_gadget *gadget, int is_active) | |||
1212 | udc = container_of(gadget, struct mv_udc, gadget); | 1230 | udc = container_of(gadget, struct mv_udc, gadget); |
1213 | spin_lock_irqsave(&udc->lock, flags); | 1231 | spin_lock_irqsave(&udc->lock, flags); |
1214 | 1232 | ||
1233 | udc->vbus_active = (is_active != 0); | ||
1234 | |||
1215 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", | 1235 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", |
1216 | __func__, udc->softconnect, udc->vbus_active); | 1236 | __func__, udc->softconnect, udc->vbus_active); |
1217 | 1237 | ||
1218 | udc->vbus_active = (is_active != 0); | ||
1219 | if (udc->driver && udc->softconnect && udc->vbus_active) { | 1238 | if (udc->driver && udc->softconnect && udc->vbus_active) { |
1220 | retval = mv_udc_enable(udc); | 1239 | retval = mv_udc_enable(udc); |
1221 | if (retval == 0) { | 1240 | if (retval == 0) { |
@@ -1244,10 +1263,11 @@ static int mv_udc_pullup(struct usb_gadget *gadget, int is_on) | |||
1244 | udc = container_of(gadget, struct mv_udc, gadget); | 1263 | udc = container_of(gadget, struct mv_udc, gadget); |
1245 | spin_lock_irqsave(&udc->lock, flags); | 1264 | spin_lock_irqsave(&udc->lock, flags); |
1246 | 1265 | ||
1266 | udc->softconnect = (is_on != 0); | ||
1267 | |||
1247 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", | 1268 | dev_dbg(&udc->dev->dev, "%s: softconnect %d, vbus_active %d\n", |
1248 | __func__, udc->softconnect, udc->vbus_active); | 1269 | __func__, udc->softconnect, udc->vbus_active); |
1249 | 1270 | ||
1250 | udc->softconnect = (is_on != 0); | ||
1251 | if (udc->driver && udc->softconnect && udc->vbus_active) { | 1271 | if (udc->driver && udc->softconnect && udc->vbus_active) { |
1252 | retval = mv_udc_enable(udc); | 1272 | retval = mv_udc_enable(udc); |
1253 | if (retval == 0) { | 1273 | if (retval == 0) { |
@@ -1407,6 +1427,20 @@ static int mv_udc_start(struct usb_gadget_driver *driver, | |||
1407 | return retval; | 1427 | return retval; |
1408 | } | 1428 | } |
1409 | 1429 | ||
1430 | if (udc->transceiver) { | ||
1431 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
1432 | if (retval) { | ||
1433 | dev_err(&udc->dev->dev, | ||
1434 | "unable to register peripheral to otg\n"); | ||
1435 | if (driver->unbind) { | ||
1436 | driver->unbind(&udc->gadget); | ||
1437 | udc->gadget.dev.driver = NULL; | ||
1438 | udc->driver = NULL; | ||
1439 | } | ||
1440 | return retval; | ||
1441 | } | ||
1442 | } | ||
1443 | |||
1410 | /* pullup is always on */ | 1444 | /* pullup is always on */ |
1411 | mv_udc_pullup(&udc->gadget, 1); | 1445 | mv_udc_pullup(&udc->gadget, 1); |
1412 | 1446 | ||
@@ -2026,6 +2060,10 @@ static irqreturn_t mv_udc_irq(int irq, void *dev) | |||
2026 | struct mv_udc *udc = (struct mv_udc *)dev; | 2060 | struct mv_udc *udc = (struct mv_udc *)dev; |
2027 | u32 status, intr; | 2061 | u32 status, intr; |
2028 | 2062 | ||
2063 | /* Disable ISR when stopped bit is set */ | ||
2064 | if (udc->stopped) | ||
2065 | return IRQ_NONE; | ||
2066 | |||
2029 | spin_lock(&udc->lock); | 2067 | spin_lock(&udc->lock); |
2030 | 2068 | ||
2031 | status = readl(&udc->op_regs->usbsts); | 2069 | status = readl(&udc->op_regs->usbsts); |
@@ -2109,7 +2147,12 @@ static int __devexit mv_udc_remove(struct platform_device *dev) | |||
2109 | destroy_workqueue(udc->qwork); | 2147 | destroy_workqueue(udc->qwork); |
2110 | } | 2148 | } |
2111 | 2149 | ||
2112 | if (udc->pdata && udc->pdata->vbus && udc->clock_gating) | 2150 | /* |
2151 | * If we have transceiver inited, | ||
2152 | * then vbus irq will not be requested in udc driver. | ||
2153 | */ | ||
2154 | if (udc->pdata && udc->pdata->vbus | ||
2155 | && udc->clock_gating && udc->transceiver == NULL) | ||
2113 | free_irq(udc->pdata->vbus->irq, &dev->dev); | 2156 | free_irq(udc->pdata->vbus->irq, &dev->dev); |
2114 | 2157 | ||
2115 | /* free memory allocated in probe */ | 2158 | /* free memory allocated in probe */ |
@@ -2182,6 +2225,11 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2182 | 2225 | ||
2183 | udc->dev = dev; | 2226 | udc->dev = dev; |
2184 | 2227 | ||
2228 | #ifdef CONFIG_USB_OTG_UTILS | ||
2229 | if (pdata->mode == MV_USB_MODE_OTG) | ||
2230 | udc->transceiver = otg_get_transceiver(); | ||
2231 | #endif | ||
2232 | |||
2185 | udc->clknum = pdata->clknum; | 2233 | udc->clknum = pdata->clknum; |
2186 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { | 2234 | for (clk_i = 0; clk_i < udc->clknum; clk_i++) { |
2187 | udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); | 2235 | udc->clk[clk_i] = clk_get(&dev->dev, pdata->clkname[clk_i]); |
@@ -2221,14 +2269,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2221 | } | 2269 | } |
2222 | 2270 | ||
2223 | /* we will acces controller register, so enable the clk */ | 2271 | /* we will acces controller register, so enable the clk */ |
2224 | udc_clock_enable(udc); | 2272 | retval = mv_udc_enable_internal(udc); |
2225 | if (pdata->phy_init) { | 2273 | if (retval) |
2226 | retval = pdata->phy_init(udc->phy_regs); | 2274 | goto err_iounmap_phyreg; |
2227 | if (retval) { | ||
2228 | dev_err(&dev->dev, "phy init error %d\n", retval); | ||
2229 | goto err_iounmap_phyreg; | ||
2230 | } | ||
2231 | } | ||
2232 | 2275 | ||
2233 | udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs | 2276 | udc->op_regs = (struct mv_op_regs __iomem *)((u32)udc->cap_regs |
2234 | + (readl(&udc->cap_regs->caplength_hciversion) | 2277 | + (readl(&udc->cap_regs->caplength_hciversion) |
@@ -2312,7 +2355,7 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2312 | udc->gadget.ep0 = &udc->eps[0].ep; /* gadget ep0 */ | 2355 | udc->gadget.ep0 = &udc->eps[0].ep; /* gadget ep0 */ |
2313 | INIT_LIST_HEAD(&udc->gadget.ep_list); /* ep_list */ | 2356 | INIT_LIST_HEAD(&udc->gadget.ep_list); /* ep_list */ |
2314 | udc->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ | 2357 | udc->gadget.speed = USB_SPEED_UNKNOWN; /* speed */ |
2315 | udc->gadget.is_dualspeed = 1; /* support dual speed */ | 2358 | udc->gadget.max_speed = USB_SPEED_HIGH; /* support dual speed */ |
2316 | 2359 | ||
2317 | /* the "gadget" abstracts/virtualizes the controller */ | 2360 | /* the "gadget" abstracts/virtualizes the controller */ |
2318 | dev_set_name(&udc->gadget.dev, "gadget"); | 2361 | dev_set_name(&udc->gadget.dev, "gadget"); |
@@ -2328,7 +2371,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2328 | eps_init(udc); | 2371 | eps_init(udc); |
2329 | 2372 | ||
2330 | /* VBUS detect: we can disable/enable clock on demand.*/ | 2373 | /* VBUS detect: we can disable/enable clock on demand.*/ |
2331 | if (pdata->vbus) { | 2374 | if (udc->transceiver) |
2375 | udc->clock_gating = 1; | ||
2376 | else if (pdata->vbus) { | ||
2332 | udc->clock_gating = 1; | 2377 | udc->clock_gating = 1; |
2333 | retval = request_threaded_irq(pdata->vbus->irq, NULL, | 2378 | retval = request_threaded_irq(pdata->vbus->irq, NULL, |
2334 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); | 2379 | mv_udc_vbus_irq, IRQF_ONESHOT, "vbus", udc); |
@@ -2354,11 +2399,9 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2354 | * If not, it means that VBUS detection is not supported, we | 2399 | * If not, it means that VBUS detection is not supported, we |
2355 | * have to enable vbus active all the time to let controller work. | 2400 | * have to enable vbus active all the time to let controller work. |
2356 | */ | 2401 | */ |
2357 | if (udc->clock_gating) { | 2402 | if (udc->clock_gating) |
2358 | if (udc->pdata->phy_deinit) | 2403 | mv_udc_disable_internal(udc); |
2359 | udc->pdata->phy_deinit(udc->phy_regs); | 2404 | else |
2360 | udc_clock_disable(udc); | ||
2361 | } else | ||
2362 | udc->vbus_active = 1; | 2405 | udc->vbus_active = 1; |
2363 | 2406 | ||
2364 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); | 2407 | retval = usb_add_gadget_udc(&dev->dev, &udc->gadget); |
@@ -2371,7 +2414,8 @@ static int __devinit mv_udc_probe(struct platform_device *dev) | |||
2371 | return 0; | 2414 | return 0; |
2372 | 2415 | ||
2373 | err_unregister: | 2416 | err_unregister: |
2374 | if (udc->pdata && udc->pdata->vbus && udc->clock_gating) | 2417 | if (udc->pdata && udc->pdata->vbus |
2418 | && udc->clock_gating && udc->transceiver == NULL) | ||
2375 | free_irq(pdata->vbus->irq, &dev->dev); | 2419 | free_irq(pdata->vbus->irq, &dev->dev); |
2376 | device_unregister(&udc->gadget.dev); | 2420 | device_unregister(&udc->gadget.dev); |
2377 | err_free_irq: | 2421 | err_free_irq: |
@@ -2387,9 +2431,7 @@ err_free_dma: | |||
2387 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, | 2431 | dma_free_coherent(&dev->dev, udc->ep_dqh_size, |
2388 | udc->ep_dqh, udc->ep_dqh_dma); | 2432 | udc->ep_dqh, udc->ep_dqh_dma); |
2389 | err_disable_clock: | 2433 | err_disable_clock: |
2390 | if (udc->pdata->phy_deinit) | 2434 | mv_udc_disable_internal(udc); |
2391 | udc->pdata->phy_deinit(udc->phy_regs); | ||
2392 | udc_clock_disable(udc); | ||
2393 | err_iounmap_phyreg: | 2435 | err_iounmap_phyreg: |
2394 | iounmap((void *)udc->phy_regs); | 2436 | iounmap((void *)udc->phy_regs); |
2395 | err_iounmap_capreg: | 2437 | err_iounmap_capreg: |
@@ -2407,7 +2449,30 @@ static int mv_udc_suspend(struct device *_dev) | |||
2407 | { | 2449 | { |
2408 | struct mv_udc *udc = the_controller; | 2450 | struct mv_udc *udc = the_controller; |
2409 | 2451 | ||
2410 | udc_stop(udc); | 2452 | /* if OTG is enabled, the following will be done in OTG driver*/ |
2453 | if (udc->transceiver) | ||
2454 | return 0; | ||
2455 | |||
2456 | if (udc->pdata->vbus && udc->pdata->vbus->poll) | ||
2457 | if (udc->pdata->vbus->poll() == VBUS_HIGH) { | ||
2458 | dev_info(&udc->dev->dev, "USB cable is connected!\n"); | ||
2459 | return -EAGAIN; | ||
2460 | } | ||
2461 | |||
2462 | /* | ||
2463 | * only cable is unplugged, udc can suspend. | ||
2464 | * So do not care about clock_gating == 1. | ||
2465 | */ | ||
2466 | if (!udc->clock_gating) { | ||
2467 | udc_stop(udc); | ||
2468 | |||
2469 | spin_lock_irq(&udc->lock); | ||
2470 | /* stop all usb activities */ | ||
2471 | stop_activity(udc, udc->driver); | ||
2472 | spin_unlock_irq(&udc->lock); | ||
2473 | |||
2474 | mv_udc_disable_internal(udc); | ||
2475 | } | ||
2411 | 2476 | ||
2412 | return 0; | 2477 | return 0; |
2413 | } | 2478 | } |
@@ -2417,20 +2482,22 @@ static int mv_udc_resume(struct device *_dev) | |||
2417 | struct mv_udc *udc = the_controller; | 2482 | struct mv_udc *udc = the_controller; |
2418 | int retval; | 2483 | int retval; |
2419 | 2484 | ||
2420 | if (udc->pdata->phy_init) { | 2485 | /* if OTG is enabled, the following will be done in OTG driver*/ |
2421 | retval = udc->pdata->phy_init(udc->phy_regs); | 2486 | if (udc->transceiver) |
2422 | if (retval) { | 2487 | return 0; |
2423 | dev_err(&udc->dev->dev, | 2488 | |
2424 | "init phy error %d when resume back\n", | 2489 | if (!udc->clock_gating) { |
2425 | retval); | 2490 | retval = mv_udc_enable_internal(udc); |
2491 | if (retval) | ||
2426 | return retval; | 2492 | return retval; |
2493 | |||
2494 | if (udc->driver && udc->softconnect) { | ||
2495 | udc_reset(udc); | ||
2496 | ep0_reset(udc); | ||
2497 | udc_start(udc); | ||
2427 | } | 2498 | } |
2428 | } | 2499 | } |
2429 | 2500 | ||
2430 | udc_reset(udc); | ||
2431 | ep0_reset(udc); | ||
2432 | udc_start(udc); | ||
2433 | |||
2434 | return 0; | 2501 | return 0; |
2435 | } | 2502 | } |
2436 | 2503 | ||
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c index d1b76368472f..4c81d540bc26 100644 --- a/drivers/usb/gadget/net2272.c +++ b/drivers/usb/gadget/net2272.c | |||
@@ -1459,7 +1459,7 @@ static int net2272_start(struct usb_gadget *_gadget, | |||
1459 | unsigned i; | 1459 | unsigned i; |
1460 | 1460 | ||
1461 | if (!driver || !driver->unbind || !driver->setup || | 1461 | if (!driver || !driver->unbind || !driver->setup || |
1462 | driver->speed != USB_SPEED_HIGH) | 1462 | driver->max_speed != USB_SPEED_HIGH) |
1463 | return -EINVAL; | 1463 | return -EINVAL; |
1464 | 1464 | ||
1465 | dev = container_of(_gadget, struct net2272, gadget); | 1465 | dev = container_of(_gadget, struct net2272, gadget); |
@@ -2235,7 +2235,7 @@ net2272_probe_init(struct device *dev, unsigned int irq) | |||
2235 | ret->irq = irq; | 2235 | ret->irq = irq; |
2236 | ret->dev = dev; | 2236 | ret->dev = dev; |
2237 | ret->gadget.ops = &net2272_ops; | 2237 | ret->gadget.ops = &net2272_ops; |
2238 | ret->gadget.is_dualspeed = 1; | 2238 | ret->gadget.max_speed = USB_SPEED_HIGH; |
2239 | 2239 | ||
2240 | /* the "gadget" abstracts/virtualizes the controller */ | 2240 | /* the "gadget" abstracts/virtualizes the controller */ |
2241 | dev_set_name(&ret->gadget.dev, "gadget"); | 2241 | dev_set_name(&ret->gadget.dev, "gadget"); |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index da2b9d0be3ca..cf1f36454d08 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -1881,7 +1881,7 @@ static int net2280_start(struct usb_gadget *_gadget, | |||
1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) | 1881 | * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE) |
1882 | * "must not be used in normal operation" | 1882 | * "must not be used in normal operation" |
1883 | */ | 1883 | */ |
1884 | if (!driver || driver->speed < USB_SPEED_HIGH | 1884 | if (!driver || driver->max_speed < USB_SPEED_HIGH |
1885 | || !driver->setup) | 1885 | || !driver->setup) |
1886 | return -EINVAL; | 1886 | return -EINVAL; |
1887 | 1887 | ||
@@ -2698,7 +2698,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2698 | spin_lock_init (&dev->lock); | 2698 | spin_lock_init (&dev->lock); |
2699 | dev->pdev = pdev; | 2699 | dev->pdev = pdev; |
2700 | dev->gadget.ops = &net2280_ops; | 2700 | dev->gadget.ops = &net2280_ops; |
2701 | dev->gadget.is_dualspeed = 1; | 2701 | dev->gadget.max_speed = USB_SPEED_HIGH; |
2702 | 2702 | ||
2703 | /* the "gadget" abstracts/virtualizes the controller */ | 2703 | /* the "gadget" abstracts/virtualizes the controller */ |
2704 | dev_set_name(&dev->gadget.dev, "gadget"); | 2704 | dev_set_name(&dev->gadget.dev, "gadget"); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 788989a10223..7db5bbe6251b 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -2110,7 +2110,7 @@ static int omap_udc_start(struct usb_gadget_driver *driver, | |||
2110 | return -ENODEV; | 2110 | return -ENODEV; |
2111 | if (!driver | 2111 | if (!driver |
2112 | // FIXME if otg, check: driver->is_otg | 2112 | // FIXME if otg, check: driver->is_otg |
2113 | || driver->speed < USB_SPEED_FULL | 2113 | || driver->max_speed < USB_SPEED_FULL |
2114 | || !bind || !driver->setup) | 2114 | || !bind || !driver->setup) |
2115 | return -EINVAL; | 2115 | return -EINVAL; |
2116 | 2116 | ||
@@ -2676,6 +2676,7 @@ omap_udc_setup(struct platform_device *odev, struct otg_transceiver *xceiv) | |||
2676 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2676 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
2677 | INIT_LIST_HEAD(&udc->iso); | 2677 | INIT_LIST_HEAD(&udc->iso); |
2678 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 2678 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
2679 | udc->gadget.max_speed = USB_SPEED_FULL; | ||
2679 | udc->gadget.name = driver_name; | 2680 | udc->gadget.name = driver_name; |
2680 | 2681 | ||
2681 | device_initialize(&udc->gadget.dev); | 2682 | device_initialize(&udc->gadget.dev); |
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c index 5048a0c07640..dd2313cce1d3 100644 --- a/drivers/usb/gadget/pch_udc.c +++ b/drivers/usb/gadget/pch_udc.c | |||
@@ -2693,7 +2693,7 @@ static int pch_udc_start(struct usb_gadget_driver *driver, | |||
2693 | struct pch_udc_dev *dev = pch_udc; | 2693 | struct pch_udc_dev *dev = pch_udc; |
2694 | int retval; | 2694 | int retval; |
2695 | 2695 | ||
2696 | if (!driver || (driver->speed == USB_SPEED_UNKNOWN) || !bind || | 2696 | if (!driver || (driver->max_speed == USB_SPEED_UNKNOWN) || !bind || |
2697 | !driver->setup || !driver->unbind || !driver->disconnect) { | 2697 | !driver->setup || !driver->unbind || !driver->disconnect) { |
2698 | dev_err(&dev->pdev->dev, | 2698 | dev_err(&dev->pdev->dev, |
2699 | "%s: invalid driver parameter\n", __func__); | 2699 | "%s: invalid driver parameter\n", __func__); |
@@ -2941,7 +2941,7 @@ static int pch_udc_probe(struct pci_dev *pdev, | |||
2941 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; | 2941 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; |
2942 | dev->gadget.dev.release = gadget_release; | 2942 | dev->gadget.dev.release = gadget_release; |
2943 | dev->gadget.name = KBUILD_MODNAME; | 2943 | dev->gadget.name = KBUILD_MODNAME; |
2944 | dev->gadget.is_dualspeed = 1; | 2944 | dev->gadget.max_speed = USB_SPEED_HIGH; |
2945 | 2945 | ||
2946 | retval = device_register(&dev->gadget.dev); | 2946 | retval = device_register(&dev->gadget.dev); |
2947 | if (retval) | 2947 | if (retval) |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 65a8834f274b..d83134b0f78a 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -1141,7 +1141,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1141 | break; | 1141 | break; |
1142 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1142 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1143 | case USB_DT_DEVICE_QUALIFIER: | 1143 | case USB_DT_DEVICE_QUALIFIER: |
1144 | if (!gadget->is_dualspeed) | 1144 | if (!gadget_is_dualspeed(gadget)) |
1145 | break; | 1145 | break; |
1146 | /* | 1146 | /* |
1147 | * assumes ep0 uses the same value for both | 1147 | * assumes ep0 uses the same value for both |
@@ -1155,7 +1155,7 @@ printer_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1155 | break; | 1155 | break; |
1156 | 1156 | ||
1157 | case USB_DT_OTHER_SPEED_CONFIG: | 1157 | case USB_DT_OTHER_SPEED_CONFIG: |
1158 | if (!gadget->is_dualspeed) | 1158 | if (!gadget_is_dualspeed(gadget)) |
1159 | break; | 1159 | break; |
1160 | /* FALLTHROUGH */ | 1160 | /* FALLTHROUGH */ |
1161 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1161 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
@@ -1535,7 +1535,7 @@ fail: | |||
1535 | /*-------------------------------------------------------------------------*/ | 1535 | /*-------------------------------------------------------------------------*/ |
1536 | 1536 | ||
1537 | static struct usb_gadget_driver printer_driver = { | 1537 | static struct usb_gadget_driver printer_driver = { |
1538 | .speed = DEVSPEED, | 1538 | .max_speed = DEVSPEED, |
1539 | 1539 | ||
1540 | .function = (char *) driver_desc, | 1540 | .function = (char *) driver_desc, |
1541 | .unbind = printer_unbind, | 1541 | .unbind = printer_unbind, |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index c090a7e3ecf8..dd470635f4f7 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -1264,7 +1264,7 @@ static int pxa25x_start(struct usb_gadget_driver *driver, | |||
1264 | int retval; | 1264 | int retval; |
1265 | 1265 | ||
1266 | if (!driver | 1266 | if (!driver |
1267 | || driver->speed < USB_SPEED_FULL | 1267 | || driver->max_speed < USB_SPEED_FULL |
1268 | || !bind | 1268 | || !bind |
1269 | || !driver->disconnect | 1269 | || !driver->disconnect |
1270 | || !driver->setup) | 1270 | || !driver->setup) |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 18b6b091f2a6..f4c44eb806c3 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -1807,7 +1807,7 @@ static int pxa27x_udc_start(struct usb_gadget_driver *driver, | |||
1807 | struct pxa_udc *udc = the_controller; | 1807 | struct pxa_udc *udc = the_controller; |
1808 | int retval; | 1808 | int retval; |
1809 | 1809 | ||
1810 | if (!driver || driver->speed < USB_SPEED_FULL || !bind | 1810 | if (!driver || driver->max_speed < USB_SPEED_FULL || !bind |
1811 | || !driver->disconnect || !driver->setup) | 1811 | || !driver->disconnect || !driver->setup) |
1812 | return -EINVAL; | 1812 | return -EINVAL; |
1813 | if (!udc) | 1813 | if (!udc) |
diff --git a/drivers/usb/gadget/r8a66597-udc.c b/drivers/usb/gadget/r8a66597-udc.c index fc719a3f8557..f5b8d215e1d5 100644 --- a/drivers/usb/gadget/r8a66597-udc.c +++ b/drivers/usb/gadget/r8a66597-udc.c | |||
@@ -1746,7 +1746,7 @@ static int r8a66597_start(struct usb_gadget *gadget, | |||
1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); | 1746 | struct r8a66597 *r8a66597 = gadget_to_r8a66597(gadget); |
1747 | 1747 | ||
1748 | if (!driver | 1748 | if (!driver |
1749 | || driver->speed < USB_SPEED_HIGH | 1749 | || driver->max_speed < USB_SPEED_HIGH |
1750 | || !driver->setup) | 1750 | || !driver->setup) |
1751 | return -EINVAL; | 1751 | return -EINVAL; |
1752 | if (!r8a66597) | 1752 | if (!r8a66597) |
@@ -1911,7 +1911,7 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
1911 | 1911 | ||
1912 | r8a66597->gadget.ops = &r8a66597_gadget_ops; | 1912 | r8a66597->gadget.ops = &r8a66597_gadget_ops; |
1913 | dev_set_name(&r8a66597->gadget.dev, "gadget"); | 1913 | dev_set_name(&r8a66597->gadget.dev, "gadget"); |
1914 | r8a66597->gadget.is_dualspeed = 1; | 1914 | r8a66597->gadget.max_speed = USB_SPEED_HIGH; |
1915 | r8a66597->gadget.dev.parent = &pdev->dev; | 1915 | r8a66597->gadget.dev.parent = &pdev->dev; |
1916 | r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; | 1916 | r8a66597->gadget.dev.dma_mask = pdev->dev.dma_mask; |
1917 | r8a66597->gadget.dev.release = pdev->dev.release; | 1917 | r8a66597->gadget.dev.release = pdev->dev.release; |
diff --git a/drivers/usb/gadget/s3c-hsotg.c b/drivers/usb/gadget/s3c-hsotg.c index c59156c0061d..69295ba9d99a 100644 --- a/drivers/usb/gadget/s3c-hsotg.c +++ b/drivers/usb/gadget/s3c-hsotg.c | |||
@@ -2586,7 +2586,7 @@ static int s3c_hsotg_start(struct usb_gadget_driver *driver, | |||
2586 | return -EINVAL; | 2586 | return -EINVAL; |
2587 | } | 2587 | } |
2588 | 2588 | ||
2589 | if (driver->speed < USB_SPEED_FULL) | 2589 | if (driver->max_speed < USB_SPEED_FULL) |
2590 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); | 2590 | dev_err(hsotg->dev, "%s: bad speed\n", __func__); |
2591 | 2591 | ||
2592 | if (!bind || !driver->setup) { | 2592 | if (!bind || !driver->setup) { |
@@ -3362,7 +3362,7 @@ static int __devinit s3c_hsotg_probe(struct platform_device *pdev) | |||
3362 | 3362 | ||
3363 | dev_set_name(&hsotg->gadget.dev, "gadget"); | 3363 | dev_set_name(&hsotg->gadget.dev, "gadget"); |
3364 | 3364 | ||
3365 | hsotg->gadget.is_dualspeed = 1; | 3365 | hsotg->gadget.max_speed = USB_SPEED_HIGH; |
3366 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; | 3366 | hsotg->gadget.ops = &s3c_hsotg_gadget_ops; |
3367 | hsotg->gadget.name = dev_name(dev); | 3367 | hsotg->gadget.name = dev_name(dev); |
3368 | 3368 | ||
diff --git a/drivers/usb/gadget/s3c-hsudc.c b/drivers/usb/gadget/s3c-hsudc.c index 787ac5baae92..6f2a0419350d 100644 --- a/drivers/usb/gadget/s3c-hsudc.c +++ b/drivers/usb/gadget/s3c-hsudc.c | |||
@@ -1142,7 +1142,7 @@ static int s3c_hsudc_start(struct usb_gadget_driver *driver, | |||
1142 | int ret; | 1142 | int ret; |
1143 | 1143 | ||
1144 | if (!driver | 1144 | if (!driver |
1145 | || driver->speed < USB_SPEED_FULL | 1145 | || driver->max_speed < USB_SPEED_FULL |
1146 | || !bind | 1146 | || !bind |
1147 | || !driver->unbind || !driver->disconnect || !driver->setup) | 1147 | || !driver->unbind || !driver->disconnect || !driver->setup) |
1148 | return -EINVAL; | 1148 | return -EINVAL; |
@@ -1310,7 +1310,7 @@ static int s3c_hsudc_probe(struct platform_device *pdev) | |||
1310 | device_initialize(&hsudc->gadget.dev); | 1310 | device_initialize(&hsudc->gadget.dev); |
1311 | dev_set_name(&hsudc->gadget.dev, "gadget"); | 1311 | dev_set_name(&hsudc->gadget.dev, "gadget"); |
1312 | 1312 | ||
1313 | hsudc->gadget.is_dualspeed = 1; | 1313 | hsudc->gadget.max_speed = USB_SPEED_HIGH; |
1314 | hsudc->gadget.ops = &s3c_hsudc_gadget_ops; | 1314 | hsudc->gadget.ops = &s3c_hsudc_gadget_ops; |
1315 | hsudc->gadget.name = dev_name(dev); | 1315 | hsudc->gadget.name = dev_name(dev); |
1316 | hsudc->gadget.dev.parent = dev; | 1316 | hsudc->gadget.dev.parent = dev; |
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index b8643771fa80..4d860e9460a4 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -1683,9 +1683,9 @@ static int s3c2410_udc_start(struct usb_gadget_driver *driver, | |||
1683 | if (udc->driver) | 1683 | if (udc->driver) |
1684 | return -EBUSY; | 1684 | return -EBUSY; |
1685 | 1685 | ||
1686 | if (!bind || !driver->setup || driver->speed < USB_SPEED_FULL) { | 1686 | if (!bind || !driver->setup || driver->max_speed < USB_SPEED_FULL) { |
1687 | printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", | 1687 | printk(KERN_ERR "Invalid driver: bind %p setup %p speed %d\n", |
1688 | bind, driver->setup, driver->speed); | 1688 | bind, driver->setup, driver->max_speed); |
1689 | return -EINVAL; | 1689 | return -EINVAL; |
1690 | } | 1690 | } |
1691 | #if defined(MODULE) | 1691 | #if defined(MODULE) |
diff --git a/drivers/usb/gadget/udc-core.c b/drivers/usb/gadget/udc-core.c index 6939e17f4580..0b0d12ccc487 100644 --- a/drivers/usb/gadget/udc-core.c +++ b/drivers/usb/gadget/udc-core.c | |||
@@ -371,14 +371,28 @@ static ssize_t usb_udc_softconn_store(struct device *dev, | |||
371 | } | 371 | } |
372 | static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); | 372 | static DEVICE_ATTR(soft_connect, S_IWUSR, NULL, usb_udc_softconn_store); |
373 | 373 | ||
374 | static ssize_t usb_udc_speed_show(struct device *dev, | 374 | #define USB_UDC_SPEED_ATTR(name, param) \ |
375 | ssize_t usb_udc_##param##_show(struct device *dev, \ | ||
376 | struct device_attribute *attr, char *buf) \ | ||
377 | { \ | ||
378 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); \ | ||
379 | return snprintf(buf, PAGE_SIZE, "%s\n", \ | ||
380 | usb_speed_string(udc->gadget->param)); \ | ||
381 | } \ | ||
382 | static DEVICE_ATTR(name, S_IRUSR, usb_udc_##param##_show, NULL) | ||
383 | |||
384 | static USB_UDC_SPEED_ATTR(current_speed, speed); | ||
385 | static USB_UDC_SPEED_ATTR(maximum_speed, max_speed); | ||
386 | |||
387 | /* TODO: Scheduled for removal in 3.8. */ | ||
388 | static ssize_t usb_udc_is_dualspeed_show(struct device *dev, | ||
375 | struct device_attribute *attr, char *buf) | 389 | struct device_attribute *attr, char *buf) |
376 | { | 390 | { |
377 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); | 391 | struct usb_udc *udc = container_of(dev, struct usb_udc, dev); |
378 | return snprintf(buf, PAGE_SIZE, "%s\n", | 392 | return snprintf(buf, PAGE_SIZE, "%d\n", |
379 | usb_speed_string(udc->gadget->speed)); | 393 | gadget_is_dualspeed(udc->gadget)); |
380 | } | 394 | } |
381 | static DEVICE_ATTR(speed, S_IRUGO, usb_udc_speed_show, NULL); | 395 | static DEVICE_ATTR(is_dualspeed, S_IRUSR, usb_udc_is_dualspeed_show, NULL); |
382 | 396 | ||
383 | #define USB_UDC_ATTR(name) \ | 397 | #define USB_UDC_ATTR(name) \ |
384 | ssize_t usb_udc_##name##_show(struct device *dev, \ | 398 | ssize_t usb_udc_##name##_show(struct device *dev, \ |
@@ -391,7 +405,6 @@ ssize_t usb_udc_##name##_show(struct device *dev, \ | |||
391 | } \ | 405 | } \ |
392 | static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL) | 406 | static DEVICE_ATTR(name, S_IRUGO, usb_udc_##name##_show, NULL) |
393 | 407 | ||
394 | static USB_UDC_ATTR(is_dualspeed); | ||
395 | static USB_UDC_ATTR(is_otg); | 408 | static USB_UDC_ATTR(is_otg); |
396 | static USB_UDC_ATTR(is_a_peripheral); | 409 | static USB_UDC_ATTR(is_a_peripheral); |
397 | static USB_UDC_ATTR(b_hnp_enable); | 410 | static USB_UDC_ATTR(b_hnp_enable); |
@@ -401,7 +414,8 @@ static USB_UDC_ATTR(a_alt_hnp_support); | |||
401 | static struct attribute *usb_udc_attrs[] = { | 414 | static struct attribute *usb_udc_attrs[] = { |
402 | &dev_attr_srp.attr, | 415 | &dev_attr_srp.attr, |
403 | &dev_attr_soft_connect.attr, | 416 | &dev_attr_soft_connect.attr, |
404 | &dev_attr_speed.attr, | 417 | &dev_attr_current_speed.attr, |
418 | &dev_attr_maximum_speed.attr, | ||
405 | 419 | ||
406 | &dev_attr_is_dualspeed.attr, | 420 | &dev_attr_is_dualspeed.attr, |
407 | &dev_attr_is_otg.attr, | 421 | &dev_attr_is_otg.attr, |
diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index f2c5bcbf2541..ac3d2eec20fe 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -1842,7 +1842,7 @@ int __init musb_gadget_setup(struct musb *musb) | |||
1842 | */ | 1842 | */ |
1843 | 1843 | ||
1844 | musb->g.ops = &musb_gadget_operations; | 1844 | musb->g.ops = &musb_gadget_operations; |
1845 | musb->g.is_dualspeed = 1; | 1845 | musb->g.max_speed = USB_SPEED_HIGH; |
1846 | musb->g.speed = USB_SPEED_UNKNOWN; | 1846 | musb->g.speed = USB_SPEED_UNKNOWN; |
1847 | 1847 | ||
1848 | /* this "gadget" abstracts/virtualizes the controller */ | 1848 | /* this "gadget" abstracts/virtualizes the controller */ |
@@ -1901,7 +1901,7 @@ static int musb_gadget_start(struct usb_gadget *g, | |||
1901 | unsigned long flags; | 1901 | unsigned long flags; |
1902 | int retval = -EINVAL; | 1902 | int retval = -EINVAL; |
1903 | 1903 | ||
1904 | if (driver->speed < USB_SPEED_HIGH) | 1904 | if (driver->max_speed < USB_SPEED_HIGH) |
1905 | goto err0; | 1905 | goto err0; |
1906 | 1906 | ||
1907 | pm_runtime_get_sync(musb->controller); | 1907 | pm_runtime_get_sync(musb->controller); |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index aa94e33e6885..e9a5b1d2615e 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -95,25 +95,15 @@ struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev) | |||
95 | /* | 95 | /* |
96 | * syscfg functions | 96 | * syscfg functions |
97 | */ | 97 | */ |
98 | void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable) | 98 | static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable) |
99 | { | 99 | { |
100 | usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0); | 100 | usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0); |
101 | } | 101 | } |
102 | 102 | ||
103 | void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable) | ||
104 | { | ||
105 | usbhs_bset(priv, SYSCFG, HSE, enable ? HSE : 0); | ||
106 | } | ||
107 | |||
108 | void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable) | ||
109 | { | ||
110 | usbhs_bset(priv, SYSCFG, USBE, enable ? USBE : 0); | ||
111 | } | ||
112 | |||
113 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) | 103 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) |
114 | { | 104 | { |
115 | u16 mask = DCFM | DRPD | DPRPU; | 105 | u16 mask = DCFM | DRPD | DPRPU | HSE | USBE; |
116 | u16 val = DCFM | DRPD; | 106 | u16 val = DCFM | DRPD | HSE | USBE; |
117 | int has_otg = usbhs_get_dparam(priv, has_otg); | 107 | int has_otg = usbhs_get_dparam(priv, has_otg); |
118 | 108 | ||
119 | if (has_otg) | 109 | if (has_otg) |
@@ -130,8 +120,8 @@ void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) | |||
130 | 120 | ||
131 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) | 121 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) |
132 | { | 122 | { |
133 | u16 mask = DCFM | DRPD | DPRPU; | 123 | u16 mask = DCFM | DRPD | DPRPU | HSE | USBE; |
134 | u16 val = DPRPU; | 124 | u16 val = DPRPU | HSE | USBE; |
135 | 125 | ||
136 | /* | 126 | /* |
137 | * if enable | 127 | * if enable |
@@ -142,6 +132,11 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) | |||
142 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); | 132 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); |
143 | } | 133 | } |
144 | 134 | ||
135 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode) | ||
136 | { | ||
137 | usbhs_write(priv, TESTMODE, mode); | ||
138 | } | ||
139 | |||
145 | /* | 140 | /* |
146 | * frame functions | 141 | * frame functions |
147 | */ | 142 | */ |
@@ -229,7 +224,7 @@ static void usbhsc_bus_init(struct usbhs_priv *priv) | |||
229 | /* | 224 | /* |
230 | * device configuration | 225 | * device configuration |
231 | */ | 226 | */ |
232 | int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum, | 227 | int usbhs_set_device_config(struct usbhs_priv *priv, int devnum, |
233 | u16 upphub, u16 hubport, u16 speed) | 228 | u16 upphub, u16 hubport, u16 speed) |
234 | { | 229 | { |
235 | struct device *dev = usbhs_priv_to_dev(priv); | 230 | struct device *dev = usbhs_priv_to_dev(priv); |
@@ -301,18 +296,25 @@ static u32 usbhsc_default_pipe_type[] = { | |||
301 | */ | 296 | */ |
302 | static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) | 297 | static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) |
303 | { | 298 | { |
299 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | ||
304 | struct device *dev = usbhs_priv_to_dev(priv); | 300 | struct device *dev = usbhs_priv_to_dev(priv); |
305 | 301 | ||
306 | if (enable) { | 302 | if (enable) { |
307 | /* enable PM */ | 303 | /* enable PM */ |
308 | pm_runtime_get_sync(dev); | 304 | pm_runtime_get_sync(dev); |
309 | 305 | ||
306 | /* enable platform power */ | ||
307 | usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); | ||
308 | |||
310 | /* USB on */ | 309 | /* USB on */ |
311 | usbhs_sys_clock_ctrl(priv, enable); | 310 | usbhs_sys_clock_ctrl(priv, enable); |
312 | } else { | 311 | } else { |
313 | /* USB off */ | 312 | /* USB off */ |
314 | usbhs_sys_clock_ctrl(priv, enable); | 313 | usbhs_sys_clock_ctrl(priv, enable); |
315 | 314 | ||
315 | /* disable platform power */ | ||
316 | usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); | ||
317 | |||
316 | /* disable PM */ | 318 | /* disable PM */ |
317 | pm_runtime_put_sync(dev); | 319 | pm_runtime_put_sync(dev); |
318 | } | 320 | } |
@@ -388,7 +390,7 @@ static void usbhsc_notify_hotplug(struct work_struct *work) | |||
388 | usbhsc_hotplug(priv); | 390 | usbhsc_hotplug(priv); |
389 | } | 391 | } |
390 | 392 | ||
391 | int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) | 393 | static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) |
392 | { | 394 | { |
393 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | 395 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); |
394 | int delay = usbhs_get_dparam(priv, detection_delay); | 396 | int delay = usbhs_get_dparam(priv, detection_delay); |
@@ -398,7 +400,8 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) | |||
398 | * To make sure safety context, | 400 | * To make sure safety context, |
399 | * use workqueue for usbhs_notify_hotplug | 401 | * use workqueue for usbhs_notify_hotplug |
400 | */ | 402 | */ |
401 | schedule_delayed_work(&priv->notify_hotplug_work, delay); | 403 | schedule_delayed_work(&priv->notify_hotplug_work, |
404 | msecs_to_jiffies(delay)); | ||
402 | return 0; | 405 | return 0; |
403 | } | 406 | } |
404 | 407 | ||
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 8729da5c3be6..d79b3e27db95 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
@@ -33,6 +33,7 @@ struct usbhs_priv; | |||
33 | #define SYSCFG 0x0000 | 33 | #define SYSCFG 0x0000 |
34 | #define BUSWAIT 0x0002 | 34 | #define BUSWAIT 0x0002 |
35 | #define DVSTCTR 0x0008 | 35 | #define DVSTCTR 0x0008 |
36 | #define TESTMODE 0x000C | ||
36 | #define CFIFO 0x0014 | 37 | #define CFIFO 0x0014 |
37 | #define CFIFOSEL 0x0020 | 38 | #define CFIFOSEL 0x0020 |
38 | #define CFIFOCTR 0x0022 | 39 | #define CFIFOCTR 0x0022 |
@@ -275,19 +276,15 @@ u16 usbhs_read(struct usbhs_priv *priv, u32 reg); | |||
275 | void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); | 276 | void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); |
276 | void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); | 277 | void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); |
277 | 278 | ||
278 | int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev); | ||
279 | |||
280 | #define usbhs_lock(p, f) spin_lock_irqsave(usbhs_priv_to_lock(p), f) | 279 | #define usbhs_lock(p, f) spin_lock_irqsave(usbhs_priv_to_lock(p), f) |
281 | #define usbhs_unlock(p, f) spin_unlock_irqrestore(usbhs_priv_to_lock(p), f) | 280 | #define usbhs_unlock(p, f) spin_unlock_irqrestore(usbhs_priv_to_lock(p), f) |
282 | 281 | ||
283 | /* | 282 | /* |
284 | * sysconfig | 283 | * sysconfig |
285 | */ | 284 | */ |
286 | void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable); | ||
287 | void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable); | ||
288 | void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable); | ||
289 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); | 285 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); |
290 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); | 286 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); |
287 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode); | ||
291 | 288 | ||
292 | /* | 289 | /* |
293 | * usb request | 290 | * usb request |
@@ -311,7 +308,7 @@ int usbhs_frame_get_num(struct usbhs_priv *priv); | |||
311 | /* | 308 | /* |
312 | * device config | 309 | * device config |
313 | */ | 310 | */ |
314 | int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum, u16 upphub, | 311 | int usbhs_set_device_config(struct usbhs_priv *priv, int devnum, u16 upphub, |
315 | u16 hubport, u16 speed); | 312 | u16 hubport, u16 speed); |
316 | 313 | ||
317 | /* | 314 | /* |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ffdf5d15085e..b51fcd80d244 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -56,7 +56,7 @@ static struct usbhs_pkt_handle usbhsf_null_handler = { | |||
56 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 56 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |
57 | void (*done)(struct usbhs_priv *priv, | 57 | void (*done)(struct usbhs_priv *priv, |
58 | struct usbhs_pkt *pkt), | 58 | struct usbhs_pkt *pkt), |
59 | void *buf, int len, int zero) | 59 | void *buf, int len, int zero, int sequence) |
60 | { | 60 | { |
61 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 61 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
62 | struct device *dev = usbhs_priv_to_dev(priv); | 62 | struct device *dev = usbhs_priv_to_dev(priv); |
@@ -90,6 +90,7 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | |||
90 | pkt->zero = zero; | 90 | pkt->zero = zero; |
91 | pkt->actual = 0; | 91 | pkt->actual = 0; |
92 | pkt->done = done; | 92 | pkt->done = done; |
93 | pkt->sequence = sequence; | ||
93 | 94 | ||
94 | usbhs_unlock(priv, flags); | 95 | usbhs_unlock(priv, flags); |
95 | /******************** spin unlock ******************/ | 96 | /******************** spin unlock ******************/ |
@@ -481,6 +482,9 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
481 | int i, ret, len; | 482 | int i, ret, len; |
482 | int is_short; | 483 | int is_short; |
483 | 484 | ||
485 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | ||
486 | pkt->sequence = -1; /* -1 sequence will be ignored */ | ||
487 | |||
484 | ret = usbhsf_fifo_select(pipe, fifo, 1); | 488 | ret = usbhsf_fifo_select(pipe, fifo, 1); |
485 | if (ret < 0) | 489 | if (ret < 0) |
486 | return 0; | 490 | return 0; |
@@ -584,6 +588,8 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | |||
584 | /* | 588 | /* |
585 | * pipe enable to prepare packet receive | 589 | * pipe enable to prepare packet receive |
586 | */ | 590 | */ |
591 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | ||
592 | pkt->sequence = -1; /* -1 sequence will be ignored */ | ||
587 | 593 | ||
588 | usbhs_pipe_enable(pipe); | 594 | usbhs_pipe_enable(pipe); |
589 | usbhsf_rx_irq_ctrl(pipe, 1); | 595 | usbhsf_rx_irq_ctrl(pipe, 1); |
@@ -641,6 +647,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
641 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" | 647 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" |
642 | */ | 648 | */ |
643 | if (0 == rcv_len) { | 649 | if (0 == rcv_len) { |
650 | pkt->zero = 1; | ||
644 | usbhsf_fifo_clear(pipe, fifo); | 651 | usbhsf_fifo_clear(pipe, fifo); |
645 | goto usbhs_fifo_read_end; | 652 | goto usbhs_fifo_read_end; |
646 | } | 653 | } |
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index 32a7b246b28d..f68609c0f489 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -59,6 +59,7 @@ struct usbhs_pkt { | |||
59 | int trans; | 59 | int trans; |
60 | int actual; | 60 | int actual; |
61 | int zero; | 61 | int zero; |
62 | int sequence; | ||
62 | }; | 63 | }; |
63 | 64 | ||
64 | struct usbhs_pkt_handle { | 65 | struct usbhs_pkt_handle { |
@@ -95,7 +96,7 @@ void usbhs_pkt_init(struct usbhs_pkt *pkt); | |||
95 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 96 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |
96 | void (*done)(struct usbhs_priv *priv, | 97 | void (*done)(struct usbhs_priv *priv, |
97 | struct usbhs_pkt *pkt), | 98 | struct usbhs_pkt *pkt), |
98 | void *buf, int len, int zero); | 99 | void *buf, int len, int zero, int sequence); |
99 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt); | 100 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt); |
100 | void usbhs_pkt_start(struct usbhs_pipe *pipe); | 101 | void usbhs_pkt_start(struct usbhs_pipe *pipe); |
101 | 102 | ||
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 053f86d70009..f382e4314362 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -50,7 +50,9 @@ static int usbhsm_autonomy_irq_vbus(struct usbhs_priv *priv, | |||
50 | { | 50 | { |
51 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | 51 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); |
52 | 52 | ||
53 | return usbhsc_drvcllbck_notify_hotplug(pdev); | 53 | renesas_usbhs_call_notify_hotplug(pdev); |
54 | |||
55 | return 0; | ||
54 | } | 56 | } |
55 | 57 | ||
56 | void usbhs_mod_autonomy_mode(struct usbhs_priv *priv) | 58 | void usbhs_mod_autonomy_mode(struct usbhs_priv *priv) |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 7f4e80338570..db2a1c6a0866 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -14,6 +14,7 @@ | |||
14 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 14 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | #include <linux/delay.h> | ||
17 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -44,7 +45,6 @@ struct usbhsg_uep { | |||
44 | struct usbhsg_gpriv { | 45 | struct usbhsg_gpriv { |
45 | struct usb_gadget gadget; | 46 | struct usb_gadget gadget; |
46 | struct usbhs_mod mod; | 47 | struct usbhs_mod mod; |
47 | struct list_head link; | ||
48 | 48 | ||
49 | struct usbhsg_uep *uep; | 49 | struct usbhsg_uep *uep; |
50 | int uep_size; | 50 | int uep_size; |
@@ -114,16 +114,6 @@ struct usbhsg_recip_handle { | |||
114 | #define usbhsg_status_clr(gp, b) (gp->status &= ~b) | 114 | #define usbhsg_status_clr(gp, b) (gp->status &= ~b) |
115 | #define usbhsg_status_has(gp, b) (gp->status & b) | 115 | #define usbhsg_status_has(gp, b) (gp->status & b) |
116 | 116 | ||
117 | /* controller */ | ||
118 | LIST_HEAD(the_controller_link); | ||
119 | |||
120 | #define usbhsg_for_each_controller(gpriv)\ | ||
121 | list_for_each_entry(gpriv, &the_controller_link, link) | ||
122 | #define usbhsg_controller_register(gpriv)\ | ||
123 | list_add_tail(&(gpriv)->link, &the_controller_link) | ||
124 | #define usbhsg_controller_unregister(gpriv)\ | ||
125 | list_del_init(&(gpriv)->link) | ||
126 | |||
127 | /* | 117 | /* |
128 | * queue push/pop | 118 | * queue push/pop |
129 | */ | 119 | */ |
@@ -164,7 +154,7 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep, | |||
164 | req->actual = 0; | 154 | req->actual = 0; |
165 | req->status = -EINPROGRESS; | 155 | req->status = -EINPROGRESS; |
166 | usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, | 156 | usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, |
167 | req->buf, req->length, req->zero); | 157 | req->buf, req->length, req->zero, -1); |
168 | usbhs_pkt_start(pipe); | 158 | usbhs_pkt_start(pipe); |
169 | 159 | ||
170 | dev_dbg(dev, "pipe %d : queue push (%d)\n", | 160 | dev_dbg(dev, "pipe %d : queue push (%d)\n", |
@@ -271,6 +261,8 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, | |||
271 | 261 | ||
272 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | 262 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
273 | 263 | ||
264 | usbhs_pkt_start(pipe); | ||
265 | |||
274 | return 0; | 266 | return 0; |
275 | } | 267 | } |
276 | 268 | ||
@@ -282,6 +274,145 @@ struct usbhsg_recip_handle req_clear_feature = { | |||
282 | }; | 274 | }; |
283 | 275 | ||
284 | /* | 276 | /* |
277 | * USB_TYPE_STANDARD / set feature functions | ||
278 | */ | ||
279 | static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv, | ||
280 | struct usbhsg_uep *uep, | ||
281 | struct usb_ctrlrequest *ctrl) | ||
282 | { | ||
283 | switch (le16_to_cpu(ctrl->wValue)) { | ||
284 | case USB_DEVICE_TEST_MODE: | ||
285 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
286 | udelay(100); | ||
287 | usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8)); | ||
288 | break; | ||
289 | default: | ||
290 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
291 | break; | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int usbhsg_recip_handler_std_set_endpoint(struct usbhs_priv *priv, | ||
298 | struct usbhsg_uep *uep, | ||
299 | struct usb_ctrlrequest *ctrl) | ||
300 | { | ||
301 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
302 | |||
303 | usbhs_pipe_stall(pipe); | ||
304 | |||
305 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | struct usbhsg_recip_handle req_set_feature = { | ||
311 | .name = "set feature", | ||
312 | .device = usbhsg_recip_handler_std_set_device, | ||
313 | .interface = usbhsg_recip_handler_std_control_done, | ||
314 | .endpoint = usbhsg_recip_handler_std_set_endpoint, | ||
315 | }; | ||
316 | |||
317 | /* | ||
318 | * USB_TYPE_STANDARD / get status functions | ||
319 | */ | ||
320 | static void __usbhsg_recip_send_complete(struct usb_ep *ep, | ||
321 | struct usb_request *req) | ||
322 | { | ||
323 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | ||
324 | |||
325 | /* free allocated recip-buffer/usb_request */ | ||
326 | kfree(ureq->pkt.buf); | ||
327 | usb_ep_free_request(ep, req); | ||
328 | } | ||
329 | |||
330 | static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, | ||
331 | unsigned short status) | ||
332 | { | ||
333 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | ||
334 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); | ||
335 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
336 | struct usb_request *req; | ||
337 | unsigned short *buf; | ||
338 | |||
339 | /* alloc new usb_request for recip */ | ||
340 | req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC); | ||
341 | if (!req) { | ||
342 | dev_err(dev, "recip request allocation fail\n"); | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | /* alloc recip data buffer */ | ||
347 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | ||
348 | if (!buf) { | ||
349 | usb_ep_free_request(&dcp->ep, req); | ||
350 | dev_err(dev, "recip data allocation fail\n"); | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* recip data is status */ | ||
355 | *buf = cpu_to_le16(status); | ||
356 | |||
357 | /* allocated usb_request/buffer will be freed */ | ||
358 | req->complete = __usbhsg_recip_send_complete; | ||
359 | req->buf = buf; | ||
360 | req->length = sizeof(*buf); | ||
361 | req->zero = 0; | ||
362 | |||
363 | /* push packet */ | ||
364 | pipe->handler = &usbhs_fifo_pio_push_handler; | ||
365 | usbhsg_queue_push(dcp, usbhsg_req_to_ureq(req)); | ||
366 | } | ||
367 | |||
368 | static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv, | ||
369 | struct usbhsg_uep *uep, | ||
370 | struct usb_ctrlrequest *ctrl) | ||
371 | { | ||
372 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
373 | unsigned short status = 1 << USB_DEVICE_SELF_POWERED; | ||
374 | |||
375 | __usbhsg_recip_send_status(gpriv, status); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int usbhsg_recip_handler_std_get_interface(struct usbhs_priv *priv, | ||
381 | struct usbhsg_uep *uep, | ||
382 | struct usb_ctrlrequest *ctrl) | ||
383 | { | ||
384 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
385 | unsigned short status = 0; | ||
386 | |||
387 | __usbhsg_recip_send_status(gpriv, status); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int usbhsg_recip_handler_std_get_endpoint(struct usbhs_priv *priv, | ||
393 | struct usbhsg_uep *uep, | ||
394 | struct usb_ctrlrequest *ctrl) | ||
395 | { | ||
396 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
397 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
398 | unsigned short status = 0; | ||
399 | |||
400 | if (usbhs_pipe_is_stall(pipe)) | ||
401 | status = 1 << USB_ENDPOINT_HALT; | ||
402 | |||
403 | __usbhsg_recip_send_status(gpriv, status); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | struct usbhsg_recip_handle req_get_status = { | ||
409 | .name = "get status", | ||
410 | .device = usbhsg_recip_handler_std_get_device, | ||
411 | .interface = usbhsg_recip_handler_std_get_interface, | ||
412 | .endpoint = usbhsg_recip_handler_std_get_endpoint, | ||
413 | }; | ||
414 | |||
415 | /* | ||
285 | * USB_TYPE handler | 416 | * USB_TYPE handler |
286 | */ | 417 | */ |
287 | static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | 418 | static int usbhsg_recip_run_handle(struct usbhs_priv *priv, |
@@ -303,8 +434,7 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | |||
303 | pipe = usbhsg_uep_to_pipe(uep); | 434 | pipe = usbhsg_uep_to_pipe(uep); |
304 | if (!pipe) { | 435 | if (!pipe) { |
305 | dev_err(dev, "wrong recip request\n"); | 436 | dev_err(dev, "wrong recip request\n"); |
306 | ret = -EINVAL; | 437 | return -EINVAL; |
307 | goto usbhsg_recip_run_handle_end; | ||
308 | } | 438 | } |
309 | 439 | ||
310 | switch (recip) { | 440 | switch (recip) { |
@@ -327,20 +457,10 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | |||
327 | } | 457 | } |
328 | 458 | ||
329 | if (func) { | 459 | if (func) { |
330 | unsigned long flags; | ||
331 | |||
332 | dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); | 460 | dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); |
333 | |||
334 | /******************** spin lock ********************/ | ||
335 | usbhs_lock(priv, flags); | ||
336 | ret = func(priv, uep, ctrl); | 461 | ret = func(priv, uep, ctrl); |
337 | usbhs_unlock(priv, flags); | ||
338 | /******************** spin unlock ******************/ | ||
339 | } | 462 | } |
340 | 463 | ||
341 | usbhsg_recip_run_handle_end: | ||
342 | usbhs_pkt_start(pipe); | ||
343 | |||
344 | return ret; | 464 | return ret; |
345 | } | 465 | } |
346 | 466 | ||
@@ -412,6 +532,12 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, | |||
412 | case USB_REQ_CLEAR_FEATURE: | 532 | case USB_REQ_CLEAR_FEATURE: |
413 | recip_handler = &req_clear_feature; | 533 | recip_handler = &req_clear_feature; |
414 | break; | 534 | break; |
535 | case USB_REQ_SET_FEATURE: | ||
536 | recip_handler = &req_set_feature; | ||
537 | break; | ||
538 | case USB_REQ_GET_STATUS: | ||
539 | recip_handler = &req_get_status; | ||
540 | break; | ||
415 | } | 541 | } |
416 | } | 542 | } |
417 | 543 | ||
@@ -439,14 +565,16 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep) | |||
439 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | 565 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
440 | struct usbhs_pkt *pkt; | 566 | struct usbhs_pkt *pkt; |
441 | 567 | ||
442 | usbhs_pipe_disable(pipe); | ||
443 | |||
444 | while (1) { | 568 | while (1) { |
445 | pkt = usbhs_pkt_pop(pipe, NULL); | 569 | pkt = usbhs_pkt_pop(pipe, NULL); |
446 | if (!pkt) | 570 | if (!pkt) |
447 | break; | 571 | break; |
572 | |||
573 | usbhsg_queue_pop(uep, usbhsg_pkt_to_ureq(pkt), -ECONNRESET); | ||
448 | } | 574 | } |
449 | 575 | ||
576 | usbhs_pipe_disable(pipe); | ||
577 | |||
450 | return 0; | 578 | return 0; |
451 | } | 579 | } |
452 | 580 | ||
@@ -681,9 +809,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
681 | * - function | 809 | * - function |
682 | * - usb module | 810 | * - usb module |
683 | */ | 811 | */ |
684 | usbhs_sys_hispeed_ctrl(priv, 1); | ||
685 | usbhs_sys_function_ctrl(priv, 1); | 812 | usbhs_sys_function_ctrl(priv, 1); |
686 | usbhs_sys_usb_ctrl(priv, 1); | ||
687 | 813 | ||
688 | /* | 814 | /* |
689 | * enable irq callback | 815 | * enable irq callback |
@@ -731,9 +857,8 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
731 | gpriv->gadget.speed = USB_SPEED_UNKNOWN; | 857 | gpriv->gadget.speed = USB_SPEED_UNKNOWN; |
732 | 858 | ||
733 | /* disable sys */ | 859 | /* disable sys */ |
734 | usbhs_sys_hispeed_ctrl(priv, 0); | 860 | usbhs_sys_set_test_mode(priv, 0); |
735 | usbhs_sys_function_ctrl(priv, 0); | 861 | usbhs_sys_function_ctrl(priv, 0); |
736 | usbhs_sys_usb_ctrl(priv, 0); | ||
737 | 862 | ||
738 | usbhsg_pipe_disable(dcp); | 863 | usbhsg_pipe_disable(dcp); |
739 | 864 | ||
@@ -755,7 +880,7 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget, | |||
755 | 880 | ||
756 | if (!driver || | 881 | if (!driver || |
757 | !driver->setup || | 882 | !driver->setup || |
758 | driver->speed < USB_SPEED_FULL) | 883 | driver->max_speed < USB_SPEED_FULL) |
759 | return -EINVAL; | 884 | return -EINVAL; |
760 | 885 | ||
761 | /* first hook up the driver ... */ | 886 | /* first hook up the driver ... */ |
@@ -866,7 +991,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
866 | gpriv->gadget.dev.parent = dev; | 991 | gpriv->gadget.dev.parent = dev; |
867 | gpriv->gadget.name = "renesas_usbhs_udc"; | 992 | gpriv->gadget.name = "renesas_usbhs_udc"; |
868 | gpriv->gadget.ops = &usbhsg_gadget_ops; | 993 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
869 | gpriv->gadget.is_dualspeed = 1; | 994 | gpriv->gadget.max_speed = USB_SPEED_HIGH; |
870 | ret = device_register(&gpriv->gadget.dev); | 995 | ret = device_register(&gpriv->gadget.dev); |
871 | if (ret < 0) | 996 | if (ret < 0) |
872 | goto err_add_udc; | 997 | goto err_add_udc; |
@@ -896,8 +1021,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
896 | } | 1021 | } |
897 | } | 1022 | } |
898 | 1023 | ||
899 | usbhsg_controller_register(gpriv); | ||
900 | |||
901 | ret = usb_add_gadget_udc(dev, &gpriv->gadget); | 1024 | ret = usb_add_gadget_udc(dev, &gpriv->gadget); |
902 | if (ret) | 1025 | if (ret) |
903 | goto err_register; | 1026 | goto err_register; |
@@ -926,8 +1049,6 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv) | |||
926 | 1049 | ||
927 | device_unregister(&gpriv->gadget.dev); | 1050 | device_unregister(&gpriv->gadget.dev); |
928 | 1051 | ||
929 | usbhsg_controller_unregister(gpriv); | ||
930 | |||
931 | kfree(gpriv->uep); | 1052 | kfree(gpriv->uep); |
932 | kfree(gpriv); | 1053 | kfree(gpriv); |
933 | } | 1054 | } |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 75659e0c735d..aa50eaaffcb6 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -45,36 +45,34 @@ | |||
45 | * | 45 | * |
46 | * +--------+ pipes are reused for each uep. | 46 | * +--------+ pipes are reused for each uep. |
47 | * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when | 47 | * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when |
48 | * +--------+ | | target device was changed | 48 | * +--------+ | | other device requested |
49 | * +- [uep 1 (bulk)] --|---+ +--------------+ | 49 | * +- [uep 1 (bulk)] --|---+ +--------------+ |
50 | * | +--------------> | pipe0 (dcp) | | 50 | * | +--------------> | pipe0 (dcp) | |
51 | * +- [uep 2 (bulk)] --|---|---+ +--------------+ | 51 | * +- [uep 2 (bulk)] -@ | +--------------+ |
52 | * | | | | pipe1 (isoc) | | 52 | * | | pipe1 (isoc) | |
53 | * +--------+ | | | +--------------+ | 53 | * +--------+ | +--------------+ |
54 | * | udev 2 |-+- [uep 0 (dcp) ] --+ +-- |------> | pipe2 (bulk) | | 54 | * | udev 2 |-+- [uep 0 (dcp) ] -@ +----------> | pipe2 (bulk) | |
55 | * +--------+ | | | | +--------------+ | 55 | * +--------+ | +--------------+ |
56 | * +- [uep 1 (int) ] --|-+ | +------> | pipe3 (bulk) | | 56 | * +- [uep 1 (int) ] ----+ +------> | pipe3 (bulk) | |
57 | * | | | | +--------------+ | 57 | * | | +--------------+ |
58 | * +--------+ | +-|---|------> | pipe4 (int) | | 58 | * +--------+ +-----|------> | pipe4 (int) | |
59 | * | udev 3 |-+- [uep 0 (dcp) ] --+ | | +--------------+ | 59 | * | udev 3 |-+- [uep 0 (dcp) ] -@ | +--------------+ |
60 | * +--------+ | | | | .... | | 60 | * +--------+ | | | .... | |
61 | * +- [uep 1 (bulk)] ------+ | | .... | | 61 | * +- [uep 1 (bulk)] -@ | | .... | |
62 | * | | | 62 | * | | |
63 | * +- [uep 2 (bulk)]-----------+ | 63 | * +- [uep 2 (bulk)]-----------+ |
64 | * | ||
65 | * @ : uep requested free pipe, but all have been used. | ||
66 | * now it is waiting for free pipe | ||
64 | */ | 67 | */ |
65 | 68 | ||
66 | 69 | ||
67 | /* | 70 | /* |
68 | * struct | 71 | * struct |
69 | */ | 72 | */ |
70 | struct usbhsh_pipe_info { | ||
71 | unsigned int usr_cnt; /* see usbhsh_endpoint_alloc() */ | ||
72 | }; | ||
73 | |||
74 | struct usbhsh_request { | 73 | struct usbhsh_request { |
75 | struct urb *urb; | 74 | struct urb *urb; |
76 | struct usbhs_pkt pkt; | 75 | struct usbhs_pkt pkt; |
77 | struct list_head ureq_link; /* see hpriv :: ureq_link_xxx */ | ||
78 | }; | 76 | }; |
79 | 77 | ||
80 | struct usbhsh_device { | 78 | struct usbhsh_device { |
@@ -83,11 +81,10 @@ struct usbhsh_device { | |||
83 | }; | 81 | }; |
84 | 82 | ||
85 | struct usbhsh_ep { | 83 | struct usbhsh_ep { |
86 | struct usbhs_pipe *pipe; | 84 | struct usbhs_pipe *pipe; /* attached pipe */ |
87 | struct usbhsh_device *udev; /* attached udev */ | 85 | struct usbhsh_device *udev; /* attached udev */ |
86 | struct usb_host_endpoint *ep; | ||
88 | struct list_head ep_list; /* list to usbhsh_device */ | 87 | struct list_head ep_list; /* list to usbhsh_device */ |
89 | |||
90 | int maxp; | ||
91 | }; | 88 | }; |
92 | 89 | ||
93 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ | 90 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ |
@@ -98,16 +95,9 @@ struct usbhsh_hpriv { | |||
98 | 95 | ||
99 | struct usbhsh_device udev[USBHSH_DEVICE_MAX]; | 96 | struct usbhsh_device udev[USBHSH_DEVICE_MAX]; |
100 | 97 | ||
101 | struct usbhsh_pipe_info *pipe_info; | ||
102 | int pipe_size; | ||
103 | |||
104 | u32 port_stat; /* USB_PORT_STAT_xxx */ | 98 | u32 port_stat; /* USB_PORT_STAT_xxx */ |
105 | 99 | ||
106 | struct completion setup_ack_done; | 100 | struct completion setup_ack_done; |
107 | |||
108 | /* see usbhsh_req_alloc/free */ | ||
109 | struct list_head ureq_link_active; | ||
110 | struct list_head ureq_link_free; | ||
111 | }; | 101 | }; |
112 | 102 | ||
113 | 103 | ||
@@ -119,17 +109,6 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
119 | #define usbhsh_priv_to_hpriv(priv) \ | 109 | #define usbhsh_priv_to_hpriv(priv) \ |
120 | container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) | 110 | container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) |
121 | 111 | ||
122 | #define __usbhsh_for_each_hpipe(start, pos, h, i) \ | ||
123 | for (i = start, pos = (h)->hpipe + i; \ | ||
124 | i < (h)->hpipe_size; \ | ||
125 | i++, pos = (h)->hpipe + i) | ||
126 | |||
127 | #define usbhsh_for_each_hpipe(pos, hpriv, i) \ | ||
128 | __usbhsh_for_each_hpipe(1, pos, hpriv, i) | ||
129 | |||
130 | #define usbhsh_for_each_hpipe_with_dcp(pos, hpriv, i) \ | ||
131 | __usbhsh_for_each_hpipe(0, pos, hpriv, i) | ||
132 | |||
133 | #define __usbhsh_for_each_udev(start, pos, h, i) \ | 112 | #define __usbhsh_for_each_udev(start, pos, h, i) \ |
134 | for (i = start, pos = (h)->udev + i; \ | 113 | for (i = start, pos = (h)->udev + i; \ |
135 | i < USBHSH_DEVICE_MAX; \ | 114 | i < USBHSH_DEVICE_MAX; \ |
@@ -152,15 +131,20 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
152 | #define usbhsh_ep_to_uep(u) ((u)->hcpriv) | 131 | #define usbhsh_ep_to_uep(u) ((u)->hcpriv) |
153 | #define usbhsh_uep_to_pipe(u) ((u)->pipe) | 132 | #define usbhsh_uep_to_pipe(u) ((u)->pipe) |
154 | #define usbhsh_uep_to_udev(u) ((u)->udev) | 133 | #define usbhsh_uep_to_udev(u) ((u)->udev) |
134 | #define usbhsh_uep_to_ep(u) ((u)->ep) | ||
135 | |||
155 | #define usbhsh_urb_to_ureq(u) ((u)->hcpriv) | 136 | #define usbhsh_urb_to_ureq(u) ((u)->hcpriv) |
156 | #define usbhsh_urb_to_usbv(u) ((u)->dev) | 137 | #define usbhsh_urb_to_usbv(u) ((u)->dev) |
157 | 138 | ||
158 | #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) | 139 | #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) |
159 | 140 | ||
160 | #define usbhsh_udev_to_usbv(h) ((h)->usbv) | 141 | #define usbhsh_udev_to_usbv(h) ((h)->usbv) |
142 | #define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) | ||
161 | 143 | ||
162 | #define usbhsh_pipe_info(p) ((p)->mod_private) | 144 | #define usbhsh_pipe_to_uep(p) ((p)->mod_private) |
163 | 145 | ||
146 | #define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) | ||
147 | #define usbhsh_device_hubport(d) ((d)->usbv->portnum) | ||
164 | #define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) | 148 | #define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) |
165 | #define usbhsh_device_nth(h, d) ((h)->udev + d) | 149 | #define usbhsh_device_nth(h, d) ((h)->udev + d) |
166 | #define usbhsh_device0(h) usbhsh_device_nth(h, 0) | 150 | #define usbhsh_device0(h) usbhsh_device_nth(h, 0) |
@@ -170,38 +154,13 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
170 | #define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) | 154 | #define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) |
171 | #define usbhsh_port_stat_get(h) ((h)->port_stat) | 155 | #define usbhsh_port_stat_get(h) ((h)->port_stat) |
172 | 156 | ||
173 | #define usbhsh_pkt_to_req(p) \ | 157 | #define usbhsh_pkt_to_ureq(p) \ |
174 | container_of((void *)p, struct usbhsh_request, pkt) | 158 | container_of((void *)p, struct usbhsh_request, pkt) |
175 | 159 | ||
176 | /* | 160 | /* |
177 | * req alloc/free | 161 | * req alloc/free |
178 | */ | 162 | */ |
179 | static void usbhsh_req_list_init(struct usbhsh_hpriv *hpriv) | 163 | static struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, |
180 | { | ||
181 | INIT_LIST_HEAD(&hpriv->ureq_link_active); | ||
182 | INIT_LIST_HEAD(&hpriv->ureq_link_free); | ||
183 | } | ||
184 | |||
185 | static void usbhsh_req_list_quit(struct usbhsh_hpriv *hpriv) | ||
186 | { | ||
187 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
188 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
189 | struct usbhsh_request *ureq, *next; | ||
190 | |||
191 | /* kfree all active ureq */ | ||
192 | list_for_each_entry_safe(ureq, next, | ||
193 | &hpriv->ureq_link_active, | ||
194 | ureq_link) { | ||
195 | dev_err(dev, "active ureq (%p) is force freed\n", ureq); | ||
196 | kfree(ureq); | ||
197 | } | ||
198 | |||
199 | /* kfree all free ureq */ | ||
200 | list_for_each_entry_safe(ureq, next, &hpriv->ureq_link_free, ureq_link) | ||
201 | kfree(ureq); | ||
202 | } | ||
203 | |||
204 | static struct usbhsh_request *usbhsh_req_alloc(struct usbhsh_hpriv *hpriv, | ||
205 | struct urb *urb, | 164 | struct urb *urb, |
206 | gfp_t mem_flags) | 165 | gfp_t mem_flags) |
207 | { | 166 | { |
@@ -209,270 +168,460 @@ static struct usbhsh_request *usbhsh_req_alloc(struct usbhsh_hpriv *hpriv, | |||
209 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 168 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
210 | struct device *dev = usbhs_priv_to_dev(priv); | 169 | struct device *dev = usbhs_priv_to_dev(priv); |
211 | 170 | ||
212 | if (list_empty(&hpriv->ureq_link_free)) { | 171 | ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); |
213 | /* | ||
214 | * create new one if there is no free ureq | ||
215 | */ | ||
216 | ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); | ||
217 | if (ureq) | ||
218 | INIT_LIST_HEAD(&ureq->ureq_link); | ||
219 | } else { | ||
220 | /* | ||
221 | * reuse "free" ureq if exist | ||
222 | */ | ||
223 | ureq = list_entry(hpriv->ureq_link_free.next, | ||
224 | struct usbhsh_request, | ||
225 | ureq_link); | ||
226 | if (ureq) | ||
227 | list_del_init(&ureq->ureq_link); | ||
228 | } | ||
229 | |||
230 | if (!ureq) { | 172 | if (!ureq) { |
231 | dev_err(dev, "ureq alloc fail\n"); | 173 | dev_err(dev, "ureq alloc fail\n"); |
232 | return NULL; | 174 | return NULL; |
233 | } | 175 | } |
234 | 176 | ||
235 | usbhs_pkt_init(&ureq->pkt); | 177 | usbhs_pkt_init(&ureq->pkt); |
236 | |||
237 | /* | ||
238 | * push it to "active" list | ||
239 | */ | ||
240 | list_add_tail(&ureq->ureq_link, &hpriv->ureq_link_active); | ||
241 | ureq->urb = urb; | 178 | ureq->urb = urb; |
179 | usbhsh_urb_to_ureq(urb) = ureq; | ||
242 | 180 | ||
243 | return ureq; | 181 | return ureq; |
244 | } | 182 | } |
245 | 183 | ||
246 | static void usbhsh_req_free(struct usbhsh_hpriv *hpriv, | 184 | static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, |
247 | struct usbhsh_request *ureq) | 185 | struct usbhsh_request *ureq) |
248 | { | 186 | { |
249 | struct usbhs_pkt *pkt = &ureq->pkt; | 187 | usbhsh_urb_to_ureq(ureq->urb) = NULL; |
188 | ureq->urb = NULL; | ||
250 | 189 | ||
251 | usbhs_pkt_init(pkt); | 190 | kfree(ureq); |
191 | } | ||
252 | 192 | ||
193 | /* | ||
194 | * status | ||
195 | */ | ||
196 | static int usbhsh_is_running(struct usbhsh_hpriv *hpriv) | ||
197 | { | ||
253 | /* | 198 | /* |
254 | * removed from "active" list, | 199 | * we can decide some device is attached or not |
255 | * and push it to "free" list | 200 | * by checking mod.irq_attch |
201 | * see | ||
202 | * usbhsh_irq_attch() | ||
203 | * usbhsh_irq_dtch() | ||
256 | */ | 204 | */ |
257 | ureq->urb = NULL; | 205 | return (hpriv->mod.irq_attch == NULL); |
258 | list_del_init(&ureq->ureq_link); | ||
259 | list_add_tail(&ureq->ureq_link, &hpriv->ureq_link_free); | ||
260 | } | 206 | } |
261 | 207 | ||
262 | /* | 208 | /* |
263 | * device control | 209 | * pipe control |
264 | */ | 210 | */ |
265 | 211 | static void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv, | |
266 | static int usbhsh_device_has_endpoint(struct usbhsh_device *udev) | 212 | struct urb *urb, |
213 | struct usbhs_pkt *pkt) | ||
267 | { | 214 | { |
268 | return !list_empty(&udev->ep_list_head); | 215 | int len = urb->actual_length; |
269 | } | 216 | int maxp = usb_endpoint_maxp(&urb->ep->desc); |
217 | int t = 0; | ||
270 | 218 | ||
271 | static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv, | 219 | /* DCP is out of sequence control */ |
272 | struct urb *urb) | 220 | if (usb_pipecontrol(urb->pipe)) |
273 | { | 221 | return; |
274 | struct usbhsh_device *udev = NULL; | ||
275 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
276 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
277 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
278 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
279 | int i; | ||
280 | 222 | ||
281 | /* | 223 | /* |
282 | * device 0 | 224 | * renesas_usbhs pipe has a limitation in a number. |
225 | * So, driver should re-use the limited pipe for each device/endpoint. | ||
226 | * DATA0/1 sequence should be saved for it. | ||
227 | * see [image of mod_host] | ||
228 | * [HARDWARE LIMITATION] | ||
283 | */ | 229 | */ |
284 | if (0 == usb_pipedevice(urb->pipe)) { | ||
285 | udev = usbhsh_device0(hpriv); | ||
286 | goto usbhsh_device_find; | ||
287 | } | ||
288 | 230 | ||
289 | /* | 231 | /* |
290 | * find unused device | 232 | * next sequence depends on actual_length |
233 | * | ||
234 | * ex) actual_length = 1147, maxp = 512 | ||
235 | * data0 : 512 | ||
236 | * data1 : 512 | ||
237 | * data0 : 123 | ||
238 | * data1 is the next sequence | ||
291 | */ | 239 | */ |
292 | usbhsh_for_each_udev(udev, hpriv, i) { | 240 | t = len / maxp; |
293 | if (usbhsh_udev_to_usbv(udev)) | 241 | if (len % maxp) |
294 | continue; | 242 | t++; |
295 | goto usbhsh_device_find; | 243 | if (pkt->zero) |
244 | t++; | ||
245 | t %= 2; | ||
246 | |||
247 | if (t) | ||
248 | usb_dotoggle(urb->dev, | ||
249 | usb_pipeendpoint(urb->pipe), | ||
250 | usb_pipeout(urb->pipe)); | ||
251 | } | ||
252 | |||
253 | static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, | ||
254 | struct urb *urb); | ||
255 | |||
256 | static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, | ||
257 | struct urb *urb) | ||
258 | { | ||
259 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
260 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
261 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); | ||
262 | struct usbhs_pipe *pipe; | ||
263 | struct usb_endpoint_descriptor *desc = &urb->ep->desc; | ||
264 | struct device *dev = usbhs_priv_to_dev(priv); | ||
265 | unsigned long flags; | ||
266 | int dir_in_req = !!usb_pipein(urb->pipe); | ||
267 | int is_dcp = usb_endpoint_xfer_control(desc); | ||
268 | int i, dir_in; | ||
269 | int ret = -EBUSY; | ||
270 | |||
271 | /******************** spin lock ********************/ | ||
272 | usbhs_lock(priv, flags); | ||
273 | |||
274 | if (unlikely(usbhsh_uep_to_pipe(uep))) { | ||
275 | dev_err(dev, "uep already has pipe\n"); | ||
276 | goto usbhsh_pipe_attach_done; | ||
296 | } | 277 | } |
297 | 278 | ||
298 | dev_err(dev, "no free usbhsh_device\n"); | 279 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { |
299 | 280 | ||
300 | return NULL; | 281 | /* check pipe type */ |
282 | if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) | ||
283 | continue; | ||
301 | 284 | ||
302 | usbhsh_device_find: | 285 | /* check pipe direction if normal pipe */ |
303 | if (usbhsh_device_has_endpoint(udev)) | 286 | if (!is_dcp) { |
304 | dev_warn(dev, "udev have old endpoint\n"); | 287 | dir_in = !!usbhs_pipe_is_dir_in(pipe); |
288 | if (0 != (dir_in - dir_in_req)) | ||
289 | continue; | ||
290 | } | ||
305 | 291 | ||
306 | /* uep will be attached */ | 292 | /* check pipe is free */ |
307 | INIT_LIST_HEAD(&udev->ep_list_head); | 293 | if (usbhsh_pipe_to_uep(pipe)) |
294 | continue; | ||
308 | 295 | ||
309 | /* | 296 | /* |
310 | * usbhsh_usbv_to_udev() | 297 | * attach pipe to uep |
311 | * usbhsh_udev_to_usbv() | 298 | * |
312 | * will be enable | 299 | * usbhs_pipe_config_update() should be called after |
313 | */ | 300 | * usbhs_set_device_config() |
314 | dev_set_drvdata(&usbv->dev, udev); | 301 | * see |
315 | udev->usbv = usbv; | 302 | * DCPMAXP/PIPEMAXP |
303 | */ | ||
304 | usbhsh_uep_to_pipe(uep) = pipe; | ||
305 | usbhsh_pipe_to_uep(pipe) = uep; | ||
316 | 306 | ||
317 | /* set device config */ | 307 | usbhs_pipe_config_update(pipe, |
318 | usbhs_set_device_speed(priv, | 308 | usbhsh_device_number(hpriv, udev), |
319 | usbhsh_device_number(hpriv, udev), | 309 | usb_endpoint_num(desc), |
320 | usbhsh_device_number(hpriv, udev), | 310 | usb_endpoint_maxp(desc)); |
321 | 0, /* FIXME no parent */ | ||
322 | usbv->speed); | ||
323 | 311 | ||
324 | dev_dbg(dev, "%s [%d](%p)\n", __func__, | 312 | dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, |
325 | usbhsh_device_number(hpriv, udev), udev); | 313 | usbhsh_device_number(hpriv, udev), |
314 | usb_endpoint_num(desc), | ||
315 | usbhs_pipe_name(pipe), | ||
316 | dir_in_req ? "in" : "out"); | ||
326 | 317 | ||
327 | return udev; | 318 | ret = 0; |
319 | break; | ||
320 | } | ||
321 | |||
322 | usbhsh_pipe_attach_done: | ||
323 | usbhs_unlock(priv, flags); | ||
324 | /******************** spin unlock ******************/ | ||
325 | |||
326 | return ret; | ||
328 | } | 327 | } |
329 | 328 | ||
330 | static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, | 329 | static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, |
331 | struct usbhsh_device *udev) | 330 | struct usbhsh_ep *uep) |
332 | { | 331 | { |
333 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 332 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
334 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 333 | struct usbhs_pipe *pipe; |
335 | struct usb_device *usbv = usbhsh_udev_to_usbv(udev); | 334 | struct device *dev = usbhs_priv_to_dev(priv); |
335 | unsigned long flags; | ||
336 | 336 | ||
337 | dev_dbg(dev, "%s [%d](%p)\n", __func__, | 337 | /******************** spin lock ********************/ |
338 | usbhsh_device_number(hpriv, udev), udev); | 338 | usbhs_lock(priv, flags); |
339 | 339 | ||
340 | if (usbhsh_device_has_endpoint(udev)) | 340 | pipe = usbhsh_uep_to_pipe(uep); |
341 | dev_warn(dev, "udev still have endpoint\n"); | ||
342 | 341 | ||
343 | /* | 342 | if (unlikely(!pipe)) { |
344 | * usbhsh_usbv_to_udev() | 343 | dev_err(dev, "uep doens't have pipe\n"); |
345 | * usbhsh_udev_to_usbv() | 344 | } else { |
346 | * will be disable | 345 | struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); |
347 | */ | 346 | struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); |
348 | dev_set_drvdata(&usbv->dev, NULL); | 347 | |
349 | udev->usbv = NULL; | 348 | /* detach pipe from uep */ |
349 | usbhsh_uep_to_pipe(uep) = NULL; | ||
350 | usbhsh_pipe_to_uep(pipe) = NULL; | ||
351 | |||
352 | dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, | ||
353 | usbhsh_device_number(hpriv, udev), | ||
354 | usb_endpoint_num(&ep->desc), | ||
355 | usbhs_pipe_name(pipe)); | ||
356 | } | ||
357 | |||
358 | usbhs_unlock(priv, flags); | ||
359 | /******************** spin unlock ******************/ | ||
350 | } | 360 | } |
351 | 361 | ||
352 | /* | 362 | /* |
353 | * end-point control | 363 | * endpoint control |
354 | */ | 364 | */ |
355 | struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | 365 | static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, |
356 | struct usbhsh_device *udev, | 366 | struct urb *urb, |
357 | struct usb_host_endpoint *ep, | 367 | gfp_t mem_flags) |
358 | int dir_in_req, | ||
359 | gfp_t mem_flags) | ||
360 | { | 368 | { |
361 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 369 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
362 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 370 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); |
371 | struct usb_host_endpoint *ep = urb->ep; | ||
363 | struct usbhsh_ep *uep; | 372 | struct usbhsh_ep *uep; |
364 | struct usbhsh_pipe_info *info; | 373 | struct device *dev = usbhs_priv_to_dev(priv); |
365 | struct usbhs_pipe *pipe, *best_pipe; | ||
366 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
367 | struct usb_endpoint_descriptor *desc = &ep->desc; | 374 | struct usb_endpoint_descriptor *desc = &ep->desc; |
368 | int type, i, dir_in; | 375 | unsigned long flags; |
369 | unsigned int min_usr; | ||
370 | |||
371 | dir_in_req = !!dir_in_req; | ||
372 | 376 | ||
373 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | 377 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); |
374 | if (!uep) { | 378 | if (!uep) { |
375 | dev_err(dev, "usbhsh_ep alloc fail\n"); | 379 | dev_err(dev, "usbhsh_ep alloc fail\n"); |
376 | return NULL; | 380 | return -ENOMEM; |
377 | } | 381 | } |
378 | 382 | ||
379 | if (usb_endpoint_xfer_control(desc)) { | 383 | /******************** spin lock ********************/ |
380 | best_pipe = usbhsh_hpriv_to_dcp(hpriv); | 384 | usbhs_lock(priv, flags); |
381 | goto usbhsh_endpoint_alloc_find_pipe; | 385 | |
386 | /* | ||
387 | * init endpoint | ||
388 | */ | ||
389 | INIT_LIST_HEAD(&uep->ep_list); | ||
390 | list_add_tail(&uep->ep_list, &udev->ep_list_head); | ||
391 | |||
392 | usbhsh_uep_to_udev(uep) = udev; | ||
393 | usbhsh_uep_to_ep(uep) = ep; | ||
394 | usbhsh_ep_to_uep(ep) = uep; | ||
395 | |||
396 | usbhs_unlock(priv, flags); | ||
397 | /******************** spin unlock ******************/ | ||
398 | |||
399 | dev_dbg(dev, "%s [%d-%d]\n", __func__, | ||
400 | usbhsh_device_number(hpriv, udev), | ||
401 | usb_endpoint_num(desc)); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, | ||
407 | struct usb_host_endpoint *ep) | ||
408 | { | ||
409 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
410 | struct device *dev = usbhs_priv_to_dev(priv); | ||
411 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); | ||
412 | unsigned long flags; | ||
413 | |||
414 | if (!uep) | ||
415 | return; | ||
416 | |||
417 | dev_dbg(dev, "%s [%d-%d]\n", __func__, | ||
418 | usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), | ||
419 | usb_endpoint_num(&ep->desc)); | ||
420 | |||
421 | if (usbhsh_uep_to_pipe(uep)) | ||
422 | usbhsh_pipe_detach(hpriv, uep); | ||
423 | |||
424 | /******************** spin lock ********************/ | ||
425 | usbhs_lock(priv, flags); | ||
426 | |||
427 | /* remove this endpoint from udev */ | ||
428 | list_del_init(&uep->ep_list); | ||
429 | |||
430 | usbhsh_uep_to_udev(uep) = NULL; | ||
431 | usbhsh_uep_to_ep(uep) = NULL; | ||
432 | usbhsh_ep_to_uep(ep) = NULL; | ||
433 | |||
434 | usbhs_unlock(priv, flags); | ||
435 | /******************** spin unlock ******************/ | ||
436 | |||
437 | kfree(uep); | ||
438 | } | ||
439 | |||
440 | static void usbhsh_endpoint_detach_all(struct usbhsh_hpriv *hpriv, | ||
441 | struct usbhsh_device *udev) | ||
442 | { | ||
443 | struct usbhsh_ep *uep, *next; | ||
444 | |||
445 | list_for_each_entry_safe(uep, next, &udev->ep_list_head, ep_list) | ||
446 | usbhsh_endpoint_detach(hpriv, usbhsh_uep_to_ep(uep)); | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * device control | ||
451 | */ | ||
452 | static int usbhsh_connected_to_rhdev(struct usb_hcd *hcd, | ||
453 | struct usbhsh_device *udev) | ||
454 | { | ||
455 | struct usb_device *usbv = usbhsh_udev_to_usbv(udev); | ||
456 | |||
457 | return hcd->self.root_hub == usbv->parent; | ||
458 | } | ||
459 | |||
460 | static int usbhsh_device_has_endpoint(struct usbhsh_device *udev) | ||
461 | { | ||
462 | return !list_empty(&udev->ep_list_head); | ||
463 | } | ||
464 | |||
465 | static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, | ||
466 | struct urb *urb) | ||
467 | { | ||
468 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
469 | struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); | ||
470 | |||
471 | /* usbhsh_device_attach() is still not called */ | ||
472 | if (!udev) | ||
473 | return NULL; | ||
474 | |||
475 | /* if it is device0, return it */ | ||
476 | if (0 == usb_pipedevice(urb->pipe)) | ||
477 | return usbhsh_device0(hpriv); | ||
478 | |||
479 | /* return attached device */ | ||
480 | return udev; | ||
481 | } | ||
482 | |||
483 | static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv, | ||
484 | struct urb *urb) | ||
485 | { | ||
486 | struct usbhsh_device *udev = NULL; | ||
487 | struct usbhsh_device *udev0 = usbhsh_device0(hpriv); | ||
488 | struct usbhsh_device *pos; | ||
489 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
490 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
491 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
492 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
493 | unsigned long flags; | ||
494 | u16 upphub, hubport; | ||
495 | int i; | ||
496 | |||
497 | /* | ||
498 | * This function should be called only while urb is pointing to device0. | ||
499 | * It will attach unused usbhsh_device to urb (usbv), | ||
500 | * and initialize device0. | ||
501 | * You can use usbhsh_device_get() to get "current" udev, | ||
502 | * and usbhsh_usbv_to_udev() is for "attached" udev. | ||
503 | */ | ||
504 | if (0 != usb_pipedevice(urb->pipe)) { | ||
505 | dev_err(dev, "%s fail: urb isn't pointing device0\n", __func__); | ||
506 | return NULL; | ||
382 | } | 507 | } |
383 | 508 | ||
509 | /******************** spin lock ********************/ | ||
510 | usbhs_lock(priv, flags); | ||
511 | |||
384 | /* | 512 | /* |
385 | * find best pipe for endpoint | 513 | * find unused device |
386 | * see | ||
387 | * HARDWARE LIMITATION | ||
388 | */ | 514 | */ |
389 | type = usb_endpoint_type(desc); | 515 | usbhsh_for_each_udev(pos, hpriv, i) { |
390 | min_usr = ~0; | 516 | if (usbhsh_udev_is_used(pos)) |
391 | best_pipe = NULL; | ||
392 | usbhs_for_each_pipe(pipe, priv, i) { | ||
393 | if (!usbhs_pipe_type_is(pipe, type)) | ||
394 | continue; | 517 | continue; |
518 | udev = pos; | ||
519 | break; | ||
520 | } | ||
395 | 521 | ||
396 | dir_in = !!usbhs_pipe_is_dir_in(pipe); | 522 | if (udev) { |
397 | if (0 != (dir_in - dir_in_req)) | 523 | /* |
398 | continue; | 524 | * usbhsh_usbv_to_udev() |
525 | * usbhsh_udev_to_usbv() | ||
526 | * will be enable | ||
527 | */ | ||
528 | dev_set_drvdata(&usbv->dev, udev); | ||
529 | udev->usbv = usbv; | ||
530 | } | ||
399 | 531 | ||
400 | info = usbhsh_pipe_info(pipe); | 532 | usbhs_unlock(priv, flags); |
533 | /******************** spin unlock ******************/ | ||
401 | 534 | ||
402 | if (min_usr > info->usr_cnt) { | 535 | if (!udev) { |
403 | min_usr = info->usr_cnt; | 536 | dev_err(dev, "no free usbhsh_device\n"); |
404 | best_pipe = pipe; | 537 | return NULL; |
405 | } | ||
406 | } | 538 | } |
407 | 539 | ||
408 | if (unlikely(!best_pipe)) { | 540 | if (usbhsh_device_has_endpoint(udev)) { |
409 | dev_err(dev, "couldn't find best pipe\n"); | 541 | dev_warn(dev, "udev have old endpoint\n"); |
410 | kfree(uep); | 542 | usbhsh_endpoint_detach_all(hpriv, udev); |
411 | return NULL; | 543 | } |
544 | |||
545 | if (usbhsh_device_has_endpoint(udev0)) { | ||
546 | dev_warn(dev, "udev0 have old endpoint\n"); | ||
547 | usbhsh_endpoint_detach_all(hpriv, udev0); | ||
412 | } | 548 | } |
413 | usbhsh_endpoint_alloc_find_pipe: | 549 | |
550 | /* uep will be attached */ | ||
551 | INIT_LIST_HEAD(&udev0->ep_list_head); | ||
552 | INIT_LIST_HEAD(&udev->ep_list_head); | ||
553 | |||
414 | /* | 554 | /* |
415 | * init uep | 555 | * set device0 config |
416 | */ | 556 | */ |
417 | uep->pipe = best_pipe; | 557 | usbhs_set_device_config(priv, |
418 | uep->maxp = usb_endpoint_maxp(desc); | 558 | 0, 0, 0, usbv->speed); |
419 | usbhsh_uep_to_udev(uep) = udev; | ||
420 | usbhsh_ep_to_uep(ep) = uep; | ||
421 | 559 | ||
422 | /* | 560 | /* |
423 | * update pipe user count | 561 | * set new device config |
424 | */ | 562 | */ |
425 | info = usbhsh_pipe_info(best_pipe); | 563 | upphub = 0; |
426 | info->usr_cnt++; | 564 | hubport = 0; |
565 | if (!usbhsh_connected_to_rhdev(hcd, udev)) { | ||
566 | /* if udev is not connected to rhdev, it means parent is Hub */ | ||
567 | struct usbhsh_device *parent = usbhsh_device_parent(udev); | ||
427 | 568 | ||
428 | /* init this endpoint, and attach it to udev */ | 569 | upphub = usbhsh_device_number(hpriv, parent); |
429 | INIT_LIST_HEAD(&uep->ep_list); | 570 | hubport = usbhsh_device_hubport(udev); |
430 | list_add_tail(&uep->ep_list, &udev->ep_list_head); | ||
431 | 571 | ||
432 | /* | 572 | dev_dbg(dev, "%s connecte to Hub [%d:%d](%p)\n", __func__, |
433 | * usbhs_pipe_config_update() should be called after | 573 | upphub, hubport, parent); |
434 | * usbhs_device_config() | 574 | } |
435 | * see | ||
436 | * DCPMAXP/PIPEMAXP | ||
437 | */ | ||
438 | usbhs_pipe_sequence_data0(uep->pipe); | ||
439 | usbhs_pipe_config_update(uep->pipe, | ||
440 | usbhsh_device_number(hpriv, udev), | ||
441 | usb_endpoint_num(desc), | ||
442 | uep->maxp); | ||
443 | 575 | ||
444 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 576 | usbhs_set_device_config(priv, |
445 | usbhsh_device_number(hpriv, udev), | 577 | usbhsh_device_number(hpriv, udev), |
446 | usbhs_pipe_name(uep->pipe), uep); | 578 | upphub, hubport, usbv->speed); |
447 | 579 | ||
448 | return uep; | 580 | dev_dbg(dev, "%s [%d](%p)\n", __func__, |
581 | usbhsh_device_number(hpriv, udev), udev); | ||
582 | |||
583 | return udev; | ||
449 | } | 584 | } |
450 | 585 | ||
451 | void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, | 586 | static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv, |
452 | struct usb_host_endpoint *ep) | 587 | struct usbhsh_device *udev) |
453 | { | 588 | { |
589 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
454 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 590 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
455 | struct device *dev = usbhs_priv_to_dev(priv); | 591 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
456 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); | 592 | struct usb_device *usbv = usbhsh_udev_to_usbv(udev); |
457 | struct usbhsh_pipe_info *info; | 593 | unsigned long flags; |
458 | 594 | ||
459 | if (!uep) | 595 | dev_dbg(dev, "%s [%d](%p)\n", __func__, |
460 | return; | 596 | usbhsh_device_number(hpriv, udev), udev); |
461 | 597 | ||
462 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 598 | if (usbhsh_device_has_endpoint(udev)) { |
463 | usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), | 599 | dev_warn(dev, "udev still have endpoint\n"); |
464 | usbhs_pipe_name(uep->pipe), uep); | 600 | usbhsh_endpoint_detach_all(hpriv, udev); |
601 | } | ||
465 | 602 | ||
466 | info = usbhsh_pipe_info(uep->pipe); | 603 | /* |
467 | info->usr_cnt--; | 604 | * There is nothing to do if it is device0. |
605 | * see | ||
606 | * usbhsh_device_attach() | ||
607 | * usbhsh_device_get() | ||
608 | */ | ||
609 | if (0 == usbhsh_device_number(hpriv, udev)) | ||
610 | return; | ||
468 | 611 | ||
469 | /* remove this endpoint from udev */ | 612 | /******************** spin lock ********************/ |
470 | list_del_init(&uep->ep_list); | 613 | usbhs_lock(priv, flags); |
471 | 614 | ||
472 | usbhsh_uep_to_udev(uep) = NULL; | 615 | /* |
473 | usbhsh_ep_to_uep(ep) = NULL; | 616 | * usbhsh_usbv_to_udev() |
617 | * usbhsh_udev_to_usbv() | ||
618 | * will be disable | ||
619 | */ | ||
620 | dev_set_drvdata(&usbv->dev, NULL); | ||
621 | udev->usbv = NULL; | ||
474 | 622 | ||
475 | kfree(uep); | 623 | usbhs_unlock(priv, flags); |
624 | /******************** spin unlock ******************/ | ||
476 | } | 625 | } |
477 | 626 | ||
478 | /* | 627 | /* |
@@ -480,11 +629,13 @@ void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, | |||
480 | */ | 629 | */ |
481 | static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | 630 | static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) |
482 | { | 631 | { |
483 | struct usbhsh_request *ureq = usbhsh_pkt_to_req(pkt); | 632 | struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); |
484 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 633 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
485 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 634 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
486 | struct urb *urb = ureq->urb; | 635 | struct urb *urb = ureq->urb; |
636 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
487 | struct device *dev = usbhs_priv_to_dev(priv); | 637 | struct device *dev = usbhs_priv_to_dev(priv); |
638 | int status = 0; | ||
488 | 639 | ||
489 | dev_dbg(dev, "%s\n", __func__); | 640 | dev_dbg(dev, "%s\n", __func__); |
490 | 641 | ||
@@ -493,29 +644,43 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | |||
493 | return; | 644 | return; |
494 | } | 645 | } |
495 | 646 | ||
647 | if (!usbhsh_is_running(hpriv)) | ||
648 | status = -ESHUTDOWN; | ||
649 | |||
496 | urb->actual_length = pkt->actual; | 650 | urb->actual_length = pkt->actual; |
497 | usbhsh_req_free(hpriv, ureq); | 651 | usbhsh_ureq_free(hpriv, ureq); |
498 | usbhsh_urb_to_ureq(urb) = NULL; | 652 | |
653 | usbhsh_endpoint_sequence_save(hpriv, urb, pkt); | ||
654 | usbhsh_pipe_detach(hpriv, uep); | ||
499 | 655 | ||
500 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 656 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
501 | usb_hcd_giveback_urb(hcd, urb, 0); | 657 | usb_hcd_giveback_urb(hcd, urb, status); |
502 | } | 658 | } |
503 | 659 | ||
504 | static int usbhsh_queue_push(struct usb_hcd *hcd, | 660 | static int usbhsh_queue_push(struct usb_hcd *hcd, |
505 | struct usbhs_pipe *pipe, | 661 | struct urb *urb, |
506 | struct urb *urb) | 662 | gfp_t mem_flags) |
507 | { | 663 | { |
508 | struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); | 664 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); |
509 | struct usbhs_pkt *pkt = &ureq->pkt; | 665 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); |
666 | struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); | ||
510 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 667 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
668 | struct usbhsh_request *ureq; | ||
511 | void *buf; | 669 | void *buf; |
512 | int len; | 670 | int len, sequence; |
513 | 671 | ||
514 | if (usb_pipeisoc(urb->pipe)) { | 672 | if (usb_pipeisoc(urb->pipe)) { |
515 | dev_err(dev, "pipe iso is not supported now\n"); | 673 | dev_err(dev, "pipe iso is not supported now\n"); |
516 | return -EIO; | 674 | return -EIO; |
517 | } | 675 | } |
518 | 676 | ||
677 | /* this ureq will be freed on usbhsh_queue_done() */ | ||
678 | ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); | ||
679 | if (unlikely(!ureq)) { | ||
680 | dev_err(dev, "ureq alloc fail\n"); | ||
681 | return -ENOMEM; | ||
682 | } | ||
683 | |||
519 | if (usb_pipein(urb->pipe)) | 684 | if (usb_pipein(urb->pipe)) |
520 | pipe->handler = &usbhs_fifo_pio_pop_handler; | 685 | pipe->handler = &usbhs_fifo_pio_pop_handler; |
521 | else | 686 | else |
@@ -524,25 +689,59 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, | |||
524 | buf = (void *)(urb->transfer_buffer + urb->actual_length); | 689 | buf = (void *)(urb->transfer_buffer + urb->actual_length); |
525 | len = urb->transfer_buffer_length - urb->actual_length; | 690 | len = urb->transfer_buffer_length - urb->actual_length; |
526 | 691 | ||
692 | sequence = usb_gettoggle(urb->dev, | ||
693 | usb_pipeendpoint(urb->pipe), | ||
694 | usb_pipeout(urb->pipe)); | ||
695 | |||
527 | dev_dbg(dev, "%s\n", __func__); | 696 | dev_dbg(dev, "%s\n", __func__); |
528 | usbhs_pkt_push(pipe, pkt, usbhsh_queue_done, | 697 | usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done, |
529 | buf, len, (urb->transfer_flags & URB_ZERO_PACKET)); | 698 | buf, len, (urb->transfer_flags & URB_ZERO_PACKET), |
699 | sequence); | ||
700 | |||
530 | usbhs_pkt_start(pipe); | 701 | usbhs_pkt_start(pipe); |
531 | 702 | ||
532 | return 0; | 703 | return 0; |
533 | } | 704 | } |
534 | 705 | ||
706 | static void usbhsh_queue_force_pop(struct usbhs_priv *priv, | ||
707 | struct usbhs_pipe *pipe) | ||
708 | { | ||
709 | struct usbhs_pkt *pkt; | ||
710 | |||
711 | while (1) { | ||
712 | pkt = usbhs_pkt_pop(pipe, NULL); | ||
713 | if (!pkt) | ||
714 | break; | ||
715 | |||
716 | /* | ||
717 | * if all packet are gone, usbhsh_endpoint_disable() | ||
718 | * will be called. | ||
719 | * then, attached device/endpoint/pipe will be detached | ||
720 | */ | ||
721 | usbhsh_queue_done(priv, pkt); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | static void usbhsh_queue_force_pop_all(struct usbhs_priv *priv) | ||
726 | { | ||
727 | struct usbhs_pipe *pos; | ||
728 | int i; | ||
729 | |||
730 | usbhs_for_each_pipe_with_dcp(pos, priv, i) | ||
731 | usbhsh_queue_force_pop(priv, pos); | ||
732 | } | ||
733 | |||
535 | /* | 734 | /* |
536 | * DCP setup stage | 735 | * DCP setup stage |
537 | */ | 736 | */ |
538 | static int usbhsh_is_request_address(struct urb *urb) | 737 | static int usbhsh_is_request_address(struct urb *urb) |
539 | { | 738 | { |
540 | struct usb_ctrlrequest *cmd; | 739 | struct usb_ctrlrequest *req; |
541 | 740 | ||
542 | cmd = (struct usb_ctrlrequest *)urb->setup_packet; | 741 | req = (struct usb_ctrlrequest *)urb->setup_packet; |
543 | 742 | ||
544 | if ((DeviceOutRequest == cmd->bRequestType << 8) && | 743 | if ((DeviceOutRequest == req->bRequestType << 8) && |
545 | (USB_REQ_SET_ADDRESS == cmd->bRequest)) | 744 | (USB_REQ_SET_ADDRESS == req->bRequest)) |
546 | return 1; | 745 | return 1; |
547 | else | 746 | else |
548 | return 0; | 747 | return 0; |
@@ -570,11 +769,15 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, | |||
570 | /* | 769 | /* |
571 | * renesas_usbhs can not use original usb address. | 770 | * renesas_usbhs can not use original usb address. |
572 | * see HARDWARE LIMITATION. | 771 | * see HARDWARE LIMITATION. |
573 | * modify usb address here. | 772 | * modify usb address here to use attached device. |
773 | * see usbhsh_device_attach() | ||
574 | */ | 774 | */ |
575 | if (usbhsh_is_request_address(urb)) { | 775 | if (usbhsh_is_request_address(urb)) { |
576 | /* FIXME */ | 776 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); |
577 | req.wValue = 1; | 777 | struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); |
778 | |||
779 | /* udev is a attached device */ | ||
780 | req.wValue = usbhsh_device_number(hpriv, udev); | ||
578 | dev_dbg(dev, "create new address - %d\n", req.wValue); | 781 | dev_dbg(dev, "create new address - %d\n", req.wValue); |
579 | } | 782 | } |
580 | 783 | ||
@@ -595,82 +798,80 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, | |||
595 | static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, | 798 | static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, |
596 | struct usbhs_pkt *pkt) | 799 | struct usbhs_pkt *pkt) |
597 | { | 800 | { |
598 | struct usbhsh_request *ureq = usbhsh_pkt_to_req(pkt); | 801 | struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); |
599 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 802 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
600 | struct urb *urb = ureq->urb; | ||
601 | 803 | ||
602 | /* this ureq was connected to urb when usbhsh_urb_enqueue() */ | 804 | /* this ureq was connected to urb when usbhsh_urb_enqueue() */ |
603 | 805 | ||
604 | usbhsh_req_free(hpriv, ureq); | 806 | usbhsh_ureq_free(hpriv, ureq); |
605 | usbhsh_urb_to_ureq(urb) = NULL; | ||
606 | } | 807 | } |
607 | 808 | ||
608 | static void usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, | 809 | static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, |
609 | struct urb *urb, | 810 | struct urb *urb, |
610 | struct usbhs_pipe *pipe) | 811 | struct usbhs_pipe *pipe, |
812 | gfp_t mem_flags) | ||
813 | |||
611 | { | 814 | { |
612 | struct usbhsh_request *ureq; | 815 | struct usbhsh_request *ureq; |
613 | struct usbhs_pkt *pkt; | ||
614 | 816 | ||
615 | /* | 817 | /* this ureq will be freed on usbhsh_data_stage_packet_done() */ |
616 | * FIXME | 818 | ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); |
617 | * | 819 | if (unlikely(!ureq)) |
618 | * data stage uses ureq which is connected to urb | 820 | return -ENOMEM; |
619 | * see usbhsh_urb_enqueue() :: alloc new request. | ||
620 | * it will be freed in usbhsh_data_stage_packet_done() | ||
621 | */ | ||
622 | ureq = usbhsh_urb_to_ureq(urb); | ||
623 | pkt = &ureq->pkt; | ||
624 | 821 | ||
625 | if (usb_pipein(urb->pipe)) | 822 | if (usb_pipein(urb->pipe)) |
626 | pipe->handler = &usbhs_dcp_data_stage_in_handler; | 823 | pipe->handler = &usbhs_dcp_data_stage_in_handler; |
627 | else | 824 | else |
628 | pipe->handler = &usbhs_dcp_data_stage_out_handler; | 825 | pipe->handler = &usbhs_dcp_data_stage_out_handler; |
629 | 826 | ||
630 | usbhs_pkt_push(pipe, pkt, | 827 | usbhs_pkt_push(pipe, &ureq->pkt, |
631 | usbhsh_data_stage_packet_done, | 828 | usbhsh_data_stage_packet_done, |
632 | urb->transfer_buffer, | 829 | urb->transfer_buffer, |
633 | urb->transfer_buffer_length, | 830 | urb->transfer_buffer_length, |
634 | (urb->transfer_flags & URB_ZERO_PACKET)); | 831 | (urb->transfer_flags & URB_ZERO_PACKET), |
832 | -1); | ||
833 | |||
834 | return 0; | ||
635 | } | 835 | } |
636 | 836 | ||
637 | /* | 837 | /* |
638 | * DCP status stage | 838 | * DCP status stage |
639 | */ | 839 | */ |
640 | static void usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, | 840 | static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, |
641 | struct urb *urb, | 841 | struct urb *urb, |
642 | struct usbhs_pipe *pipe) | 842 | struct usbhs_pipe *pipe, |
843 | gfp_t mem_flags) | ||
643 | { | 844 | { |
644 | struct usbhsh_request *ureq; | 845 | struct usbhsh_request *ureq; |
645 | struct usbhs_pkt *pkt; | ||
646 | 846 | ||
647 | /* | 847 | /* This ureq will be freed on usbhsh_queue_done() */ |
648 | * FIXME | 848 | ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); |
649 | * | 849 | if (unlikely(!ureq)) |
650 | * status stage uses allocated ureq. | 850 | return -ENOMEM; |
651 | * it will be freed on usbhsh_queue_done() | ||
652 | */ | ||
653 | ureq = usbhsh_req_alloc(hpriv, urb, GFP_KERNEL); | ||
654 | pkt = &ureq->pkt; | ||
655 | 851 | ||
656 | if (usb_pipein(urb->pipe)) | 852 | if (usb_pipein(urb->pipe)) |
657 | pipe->handler = &usbhs_dcp_status_stage_in_handler; | 853 | pipe->handler = &usbhs_dcp_status_stage_in_handler; |
658 | else | 854 | else |
659 | pipe->handler = &usbhs_dcp_status_stage_out_handler; | 855 | pipe->handler = &usbhs_dcp_status_stage_out_handler; |
660 | 856 | ||
661 | usbhs_pkt_push(pipe, pkt, | 857 | usbhs_pkt_push(pipe, &ureq->pkt, |
662 | usbhsh_queue_done, | 858 | usbhsh_queue_done, |
663 | NULL, | 859 | NULL, |
664 | urb->transfer_buffer_length, | 860 | urb->transfer_buffer_length, |
665 | 0); | 861 | 0, -1); |
862 | |||
863 | return 0; | ||
666 | } | 864 | } |
667 | 865 | ||
668 | static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, | 866 | static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, |
669 | struct usbhsh_hpriv *hpriv, | 867 | struct urb *urb, |
670 | struct usbhs_pipe *pipe, | 868 | gfp_t mflags) |
671 | struct urb *urb) | ||
672 | { | 869 | { |
870 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); | ||
871 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
872 | struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); | ||
673 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 873 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
874 | int ret; | ||
674 | 875 | ||
675 | dev_dbg(dev, "%s\n", __func__); | 876 | dev_dbg(dev, "%s\n", __func__); |
676 | 877 | ||
@@ -686,13 +887,22 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, | |||
686 | * | 887 | * |
687 | * It is pushed only when urb has buffer. | 888 | * It is pushed only when urb has buffer. |
688 | */ | 889 | */ |
689 | if (urb->transfer_buffer_length) | 890 | if (urb->transfer_buffer_length) { |
690 | usbhsh_data_stage_packet_push(hpriv, urb, pipe); | 891 | ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags); |
892 | if (ret < 0) { | ||
893 | dev_err(dev, "data stage failed\n"); | ||
894 | return ret; | ||
895 | } | ||
896 | } | ||
691 | 897 | ||
692 | /* | 898 | /* |
693 | * status stage | 899 | * status stage |
694 | */ | 900 | */ |
695 | usbhsh_status_stage_packet_push(hpriv, urb, pipe); | 901 | ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags); |
902 | if (ret < 0) { | ||
903 | dev_err(dev, "status stage failed\n"); | ||
904 | return ret; | ||
905 | } | ||
696 | 906 | ||
697 | /* | 907 | /* |
698 | * start pushed packets | 908 | * start pushed packets |
@@ -729,71 +939,82 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
729 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); | 939 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); |
730 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 940 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
731 | struct device *dev = usbhs_priv_to_dev(priv); | 941 | struct device *dev = usbhs_priv_to_dev(priv); |
732 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
733 | struct usb_host_endpoint *ep = urb->ep; | 942 | struct usb_host_endpoint *ep = urb->ep; |
734 | struct usbhsh_request *ureq; | 943 | struct usbhsh_device *new_udev = NULL; |
735 | struct usbhsh_device *udev, *new_udev = NULL; | ||
736 | struct usbhs_pipe *pipe; | ||
737 | struct usbhsh_ep *uep; | ||
738 | int is_dir_in = usb_pipein(urb->pipe); | 944 | int is_dir_in = usb_pipein(urb->pipe); |
739 | 945 | int i; | |
740 | int ret; | 946 | int ret; |
741 | 947 | ||
742 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); | 948 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
743 | 949 | ||
950 | if (!usbhsh_is_running(hpriv)) { | ||
951 | ret = -EIO; | ||
952 | dev_err(dev, "host is not running\n"); | ||
953 | goto usbhsh_urb_enqueue_error_not_linked; | ||
954 | } | ||
955 | |||
744 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 956 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
745 | if (ret) | 957 | if (ret) { |
958 | dev_err(dev, "urb link failed\n"); | ||
746 | goto usbhsh_urb_enqueue_error_not_linked; | 959 | goto usbhsh_urb_enqueue_error_not_linked; |
960 | } | ||
747 | 961 | ||
748 | /* | 962 | /* |
749 | * get udev | 963 | * attach udev if needed |
964 | * see [image of mod_host] | ||
750 | */ | 965 | */ |
751 | udev = usbhsh_usbv_to_udev(usbv); | 966 | if (!usbhsh_device_get(hpriv, urb)) { |
752 | if (!udev) { | 967 | new_udev = usbhsh_device_attach(hpriv, urb); |
753 | new_udev = usbhsh_device_alloc(hpriv, urb); | 968 | if (!new_udev) { |
754 | if (!new_udev) | 969 | ret = -EIO; |
970 | dev_err(dev, "device attach failed\n"); | ||
755 | goto usbhsh_urb_enqueue_error_not_linked; | 971 | goto usbhsh_urb_enqueue_error_not_linked; |
756 | 972 | } | |
757 | udev = new_udev; | ||
758 | } | 973 | } |
759 | 974 | ||
760 | /* | 975 | /* |
761 | * get uep | 976 | * attach endpoint if needed |
977 | * see [image of mod_host] | ||
762 | */ | 978 | */ |
763 | uep = usbhsh_ep_to_uep(ep); | 979 | if (!usbhsh_ep_to_uep(ep)) { |
764 | if (!uep) { | 980 | ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); |
765 | uep = usbhsh_endpoint_alloc(hpriv, udev, ep, | 981 | if (ret < 0) { |
766 | is_dir_in, mem_flags); | 982 | dev_err(dev, "endpoint attach failed\n"); |
767 | if (!uep) | ||
768 | goto usbhsh_urb_enqueue_error_free_device; | 983 | goto usbhsh_urb_enqueue_error_free_device; |
984 | } | ||
769 | } | 985 | } |
770 | pipe = usbhsh_uep_to_pipe(uep); | ||
771 | 986 | ||
772 | /* | 987 | /* |
773 | * alloc new request | 988 | * attach pipe to endpoint |
989 | * see [image of mod_host] | ||
774 | */ | 990 | */ |
775 | ureq = usbhsh_req_alloc(hpriv, urb, mem_flags); | 991 | for (i = 0; i < 1024; i++) { |
776 | if (unlikely(!ureq)) { | 992 | ret = usbhsh_pipe_attach(hpriv, urb); |
777 | ret = -ENOMEM; | 993 | if (ret < 0) |
994 | msleep(100); | ||
995 | else | ||
996 | break; | ||
997 | } | ||
998 | if (ret < 0) { | ||
999 | dev_err(dev, "pipe attach failed\n"); | ||
778 | goto usbhsh_urb_enqueue_error_free_endpoint; | 1000 | goto usbhsh_urb_enqueue_error_free_endpoint; |
779 | } | 1001 | } |
780 | usbhsh_urb_to_ureq(urb) = ureq; | ||
781 | 1002 | ||
782 | /* | 1003 | /* |
783 | * push packet | 1004 | * push packet |
784 | */ | 1005 | */ |
785 | if (usb_pipecontrol(urb->pipe)) | 1006 | if (usb_pipecontrol(urb->pipe)) |
786 | usbhsh_dcp_queue_push(hcd, hpriv, pipe, urb); | 1007 | ret = usbhsh_dcp_queue_push(hcd, urb, mem_flags); |
787 | else | 1008 | else |
788 | usbhsh_queue_push(hcd, pipe, urb); | 1009 | ret = usbhsh_queue_push(hcd, urb, mem_flags); |
789 | 1010 | ||
790 | return 0; | 1011 | return ret; |
791 | 1012 | ||
792 | usbhsh_urb_enqueue_error_free_endpoint: | 1013 | usbhsh_urb_enqueue_error_free_endpoint: |
793 | usbhsh_endpoint_free(hpriv, ep); | 1014 | usbhsh_endpoint_detach(hpriv, ep); |
794 | usbhsh_urb_enqueue_error_free_device: | 1015 | usbhsh_urb_enqueue_error_free_device: |
795 | if (new_udev) | 1016 | if (new_udev) |
796 | usbhsh_device_free(hpriv, new_udev); | 1017 | usbhsh_device_detach(hpriv, new_udev); |
797 | usbhsh_urb_enqueue_error_not_linked: | 1018 | usbhsh_urb_enqueue_error_not_linked: |
798 | 1019 | ||
799 | dev_dbg(dev, "%s error\n", __func__); | 1020 | dev_dbg(dev, "%s error\n", __func__); |
@@ -807,8 +1028,11 @@ static int usbhsh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
807 | struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); | 1028 | struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); |
808 | 1029 | ||
809 | if (ureq) { | 1030 | if (ureq) { |
810 | usbhsh_req_free(hpriv, ureq); | 1031 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
811 | usbhsh_urb_to_ureq(urb) = NULL; | 1032 | struct usbhs_pkt *pkt = &ureq->pkt; |
1033 | |||
1034 | usbhs_pkt_pop(pkt->pipe, pkt); | ||
1035 | usbhsh_queue_done(priv, pkt); | ||
812 | } | 1036 | } |
813 | 1037 | ||
814 | return 0; | 1038 | return 0; |
@@ -823,7 +1047,7 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, | |||
823 | 1047 | ||
824 | /* | 1048 | /* |
825 | * this function might be called manytimes by same hcd/ep | 1049 | * this function might be called manytimes by same hcd/ep |
826 | * in-endpoitn == out-endpoint if ep == dcp. | 1050 | * in-endpoint == out-endpoint if ep == dcp. |
827 | */ | 1051 | */ |
828 | if (!uep) | 1052 | if (!uep) |
829 | return; | 1053 | return; |
@@ -831,15 +1055,14 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, | |||
831 | udev = usbhsh_uep_to_udev(uep); | 1055 | udev = usbhsh_uep_to_udev(uep); |
832 | hpriv = usbhsh_hcd_to_hpriv(hcd); | 1056 | hpriv = usbhsh_hcd_to_hpriv(hcd); |
833 | 1057 | ||
834 | usbhsh_endpoint_free(hpriv, ep); | 1058 | usbhsh_endpoint_detach(hpriv, ep); |
835 | ep->hcpriv = NULL; | ||
836 | 1059 | ||
837 | /* | 1060 | /* |
838 | * if there is no endpoint, | 1061 | * if there is no endpoint, |
839 | * free device | 1062 | * free device |
840 | */ | 1063 | */ |
841 | if (!usbhsh_device_has_endpoint(udev)) | 1064 | if (!usbhsh_device_has_endpoint(udev)) |
842 | usbhsh_device_free(hpriv, udev); | 1065 | usbhsh_device_detach(hpriv, udev); |
843 | } | 1066 | } |
844 | 1067 | ||
845 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | 1068 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) |
@@ -919,6 +1142,8 @@ static int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv, | |||
919 | USB_PORT_STAT_HIGH_SPEED | | 1142 | USB_PORT_STAT_HIGH_SPEED | |
920 | USB_PORT_STAT_LOW_SPEED); | 1143 | USB_PORT_STAT_LOW_SPEED); |
921 | 1144 | ||
1145 | usbhsh_queue_force_pop_all(priv); | ||
1146 | |||
922 | usbhs_bus_send_reset(priv); | 1147 | usbhs_bus_send_reset(priv); |
923 | msleep(20); | 1148 | msleep(20); |
924 | usbhs_bus_send_sof_enable(priv); | 1149 | usbhs_bus_send_sof_enable(priv); |
@@ -1082,6 +1307,20 @@ static int usbhsh_irq_attch(struct usbhs_priv *priv, | |||
1082 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); | 1307 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); |
1083 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); | 1308 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); |
1084 | 1309 | ||
1310 | /* | ||
1311 | * attch interrupt might happen infinitely on some device | ||
1312 | * (on self power USB hub ?) | ||
1313 | * disable it here. | ||
1314 | * | ||
1315 | * usbhsh_is_running() becomes effective | ||
1316 | * according to this process. | ||
1317 | * see | ||
1318 | * usbhsh_is_running() | ||
1319 | * usbhsh_urb_enqueue() | ||
1320 | */ | ||
1321 | hpriv->mod.irq_attch = NULL; | ||
1322 | usbhs_irq_callback_update(priv, &hpriv->mod); | ||
1323 | |||
1085 | return 0; | 1324 | return 0; |
1086 | } | 1325 | } |
1087 | 1326 | ||
@@ -1096,6 +1335,24 @@ static int usbhsh_irq_dtch(struct usbhs_priv *priv, | |||
1096 | usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); | 1335 | usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); |
1097 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); | 1336 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); |
1098 | 1337 | ||
1338 | /* | ||
1339 | * enable attch interrupt again | ||
1340 | * | ||
1341 | * usbhsh_is_running() becomes invalid | ||
1342 | * according to this process. | ||
1343 | * see | ||
1344 | * usbhsh_is_running() | ||
1345 | * usbhsh_urb_enqueue() | ||
1346 | */ | ||
1347 | hpriv->mod.irq_attch = usbhsh_irq_attch; | ||
1348 | usbhs_irq_callback_update(priv, &hpriv->mod); | ||
1349 | |||
1350 | /* | ||
1351 | * usbhsh_queue_force_pop_all() should be called | ||
1352 | * after usbhsh_is_running() becomes invalid. | ||
1353 | */ | ||
1354 | usbhsh_queue_force_pop_all(priv); | ||
1355 | |||
1099 | return 0; | 1356 | return 0; |
1100 | } | 1357 | } |
1101 | 1358 | ||
@@ -1131,7 +1388,6 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv, | |||
1131 | static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | 1388 | static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) |
1132 | { | 1389 | { |
1133 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1390 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1134 | struct usbhsh_pipe_info *pipe_info = hpriv->pipe_info; | ||
1135 | struct usbhs_pipe *pipe; | 1391 | struct usbhs_pipe *pipe; |
1136 | u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); | 1392 | u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); |
1137 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | 1393 | int pipe_size = usbhs_get_dparam(priv, pipe_size); |
@@ -1140,7 +1396,6 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | |||
1140 | /* init all pipe */ | 1396 | /* init all pipe */ |
1141 | old_type = USB_ENDPOINT_XFER_CONTROL; | 1397 | old_type = USB_ENDPOINT_XFER_CONTROL; |
1142 | for (i = 0; i < pipe_size; i++) { | 1398 | for (i = 0; i < pipe_size; i++) { |
1143 | pipe_info[i].usr_cnt = 0; | ||
1144 | 1399 | ||
1145 | /* | 1400 | /* |
1146 | * data "output" will be finished as soon as possible, | 1401 | * data "output" will be finished as soon as possible, |
@@ -1174,7 +1429,7 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | |||
1174 | dir_in); | 1429 | dir_in); |
1175 | } | 1430 | } |
1176 | 1431 | ||
1177 | pipe->mod_private = pipe_info + i; | 1432 | pipe->mod_private = NULL; |
1178 | } | 1433 | } |
1179 | } | 1434 | } |
1180 | 1435 | ||
@@ -1205,9 +1460,7 @@ static int usbhsh_start(struct usbhs_priv *priv) | |||
1205 | * - host | 1460 | * - host |
1206 | * - usb module | 1461 | * - usb module |
1207 | */ | 1462 | */ |
1208 | usbhs_sys_hispeed_ctrl(priv, 1); | ||
1209 | usbhs_sys_host_ctrl(priv, 1); | 1463 | usbhs_sys_host_ctrl(priv, 1); |
1210 | usbhs_sys_usb_ctrl(priv, 1); | ||
1211 | 1464 | ||
1212 | /* | 1465 | /* |
1213 | * enable irq callback | 1466 | * enable irq callback |
@@ -1242,9 +1495,7 @@ static int usbhsh_stop(struct usbhs_priv *priv) | |||
1242 | usb_remove_hcd(hcd); | 1495 | usb_remove_hcd(hcd); |
1243 | 1496 | ||
1244 | /* disable sys */ | 1497 | /* disable sys */ |
1245 | usbhs_sys_hispeed_ctrl(priv, 0); | ||
1246 | usbhs_sys_host_ctrl(priv, 0); | 1498 | usbhs_sys_host_ctrl(priv, 0); |
1247 | usbhs_sys_usb_ctrl(priv, 0); | ||
1248 | 1499 | ||
1249 | dev_dbg(dev, "quit host\n"); | 1500 | dev_dbg(dev, "quit host\n"); |
1250 | 1501 | ||
@@ -1255,10 +1506,8 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1255 | { | 1506 | { |
1256 | struct usbhsh_hpriv *hpriv; | 1507 | struct usbhsh_hpriv *hpriv; |
1257 | struct usb_hcd *hcd; | 1508 | struct usb_hcd *hcd; |
1258 | struct usbhsh_pipe_info *pipe_info; | ||
1259 | struct usbhsh_device *udev; | 1509 | struct usbhsh_device *udev; |
1260 | struct device *dev = usbhs_priv_to_dev(priv); | 1510 | struct device *dev = usbhs_priv_to_dev(priv); |
1261 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | ||
1262 | int i; | 1511 | int i; |
1263 | 1512 | ||
1264 | /* initialize hcd */ | 1513 | /* initialize hcd */ |
@@ -1268,12 +1517,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1268 | return -ENOMEM; | 1517 | return -ENOMEM; |
1269 | } | 1518 | } |
1270 | 1519 | ||
1271 | pipe_info = kcalloc(pipe_size, sizeof(*pipe_info), GFP_KERNEL); | ||
1272 | if (!pipe_info) { | ||
1273 | dev_err(dev, "Could not allocate pipe_info\n"); | ||
1274 | goto usbhs_mod_host_probe_err; | ||
1275 | } | ||
1276 | |||
1277 | /* | 1520 | /* |
1278 | * CAUTION | 1521 | * CAUTION |
1279 | * | 1522 | * |
@@ -1293,9 +1536,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1293 | hpriv->mod.name = "host"; | 1536 | hpriv->mod.name = "host"; |
1294 | hpriv->mod.start = usbhsh_start; | 1537 | hpriv->mod.start = usbhsh_start; |
1295 | hpriv->mod.stop = usbhsh_stop; | 1538 | hpriv->mod.stop = usbhsh_stop; |
1296 | hpriv->pipe_info = pipe_info; | ||
1297 | hpriv->pipe_size = pipe_size; | ||
1298 | usbhsh_req_list_init(hpriv); | ||
1299 | usbhsh_port_stat_init(hpriv); | 1539 | usbhsh_port_stat_init(hpriv); |
1300 | 1540 | ||
1301 | /* init all device */ | 1541 | /* init all device */ |
@@ -1307,11 +1547,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1307 | dev_info(dev, "host probed\n"); | 1547 | dev_info(dev, "host probed\n"); |
1308 | 1548 | ||
1309 | return 0; | 1549 | return 0; |
1310 | |||
1311 | usbhs_mod_host_probe_err: | ||
1312 | usb_put_hcd(hcd); | ||
1313 | |||
1314 | return -ENOMEM; | ||
1315 | } | 1550 | } |
1316 | 1551 | ||
1317 | int usbhs_mod_host_remove(struct usbhs_priv *priv) | 1552 | int usbhs_mod_host_remove(struct usbhs_priv *priv) |
@@ -1319,8 +1554,6 @@ int usbhs_mod_host_remove(struct usbhs_priv *priv) | |||
1319 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1554 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1320 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 1555 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
1321 | 1556 | ||
1322 | usbhsh_req_list_quit(hpriv); | ||
1323 | |||
1324 | usb_put_hcd(hcd); | 1557 | usb_put_hcd(hcd); |
1325 | 1558 | ||
1326 | return 0; | 1559 | return 0; |
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index c74389ce2177..c2559e80d41f 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
@@ -257,6 +257,13 @@ void usbhs_pipe_stall(struct usbhs_pipe *pipe) | |||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | int usbhs_pipe_is_stall(struct usbhs_pipe *pipe) | ||
261 | { | ||
262 | u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK; | ||
263 | |||
264 | return (int)(pid == PID_STALL10 || pid == PID_STALL11); | ||
265 | } | ||
266 | |||
260 | /* | 267 | /* |
261 | * pipe setup | 268 | * pipe setup |
262 | */ | 269 | */ |
@@ -471,10 +478,27 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe) | |||
471 | return usbhsp_flags_has(pipe, IS_DIR_HOST); | 478 | return usbhsp_flags_has(pipe, IS_DIR_HOST); |
472 | } | 479 | } |
473 | 480 | ||
474 | void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int data) | 481 | void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence) |
475 | { | 482 | { |
476 | u16 mask = (SQCLR | SQSET); | 483 | u16 mask = (SQCLR | SQSET); |
477 | u16 val = (data) ? SQSET : SQCLR; | 484 | u16 val; |
485 | |||
486 | /* | ||
487 | * sequence | ||
488 | * 0 : data0 | ||
489 | * 1 : data1 | ||
490 | * -1 : no change | ||
491 | */ | ||
492 | switch (sequence) { | ||
493 | case 0: | ||
494 | val = SQCLR; | ||
495 | break; | ||
496 | case 1: | ||
497 | val = SQSET; | ||
498 | break; | ||
499 | default: | ||
500 | return; | ||
501 | } | ||
478 | 502 | ||
479 | usbhsp_pipectrl_set(pipe, mask, val); | 503 | usbhsp_pipectrl_set(pipe, mask, val); |
480 | } | 504 | } |
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 6334fc644cc0..fa18b7dc2b2a 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
@@ -87,6 +87,7 @@ int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); | |||
87 | void usbhs_pipe_enable(struct usbhs_pipe *pipe); | 87 | void usbhs_pipe_enable(struct usbhs_pipe *pipe); |
88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); | 88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); |
89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); | 89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); |
90 | int usbhs_pipe_is_stall(struct usbhs_pipe *pipe); | ||
90 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); | 91 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); |
91 | void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, | 92 | void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, |
92 | u16 epnum, u16 maxp); | 93 | u16 epnum, u16 maxp); |
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h index 1d3a67523ffc..317d8925387c 100644 --- a/include/linux/usb/gadget.h +++ b/include/linux/usb/gadget.h | |||
@@ -477,8 +477,8 @@ struct usb_gadget_ops { | |||
477 | * driver setup() requests | 477 | * driver setup() requests |
478 | * @ep_list: List of other endpoints supported by the device. | 478 | * @ep_list: List of other endpoints supported by the device. |
479 | * @speed: Speed of current connection to USB host. | 479 | * @speed: Speed of current connection to USB host. |
480 | * @is_dualspeed: True if the controller supports both high and full speed | 480 | * @max_speed: Maximal speed the UDC can handle. UDC must support this |
481 | * operation. If it does, the gadget driver must also support both. | 481 | * and all slower speeds. |
482 | * @is_otg: True if the USB device port uses a Mini-AB jack, so that the | 482 | * @is_otg: True if the USB device port uses a Mini-AB jack, so that the |
483 | * gadget driver must provide a USB OTG descriptor. | 483 | * gadget driver must provide a USB OTG descriptor. |
484 | * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable | 484 | * @is_a_peripheral: False unless is_otg, the "A" end of a USB cable |
@@ -518,7 +518,7 @@ struct usb_gadget { | |||
518 | struct usb_ep *ep0; | 518 | struct usb_ep *ep0; |
519 | struct list_head ep_list; /* of usb_ep */ | 519 | struct list_head ep_list; /* of usb_ep */ |
520 | enum usb_device_speed speed; | 520 | enum usb_device_speed speed; |
521 | unsigned is_dualspeed:1; | 521 | enum usb_device_speed max_speed; |
522 | unsigned is_otg:1; | 522 | unsigned is_otg:1; |
523 | unsigned is_a_peripheral:1; | 523 | unsigned is_a_peripheral:1; |
524 | unsigned b_hnp_enable:1; | 524 | unsigned b_hnp_enable:1; |
@@ -549,7 +549,7 @@ static inline struct usb_gadget *dev_to_usb_gadget(struct device *dev) | |||
549 | static inline int gadget_is_dualspeed(struct usb_gadget *g) | 549 | static inline int gadget_is_dualspeed(struct usb_gadget *g) |
550 | { | 550 | { |
551 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 551 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
552 | /* runtime test would check "g->is_dualspeed" ... that might be | 552 | /* runtime test would check "g->max_speed" ... that might be |
553 | * useful to work around hardware bugs, but is mostly pointless | 553 | * useful to work around hardware bugs, but is mostly pointless |
554 | */ | 554 | */ |
555 | return 1; | 555 | return 1; |
@@ -567,7 +567,7 @@ static inline int gadget_is_superspeed(struct usb_gadget *g) | |||
567 | { | 567 | { |
568 | #ifdef CONFIG_USB_GADGET_SUPERSPEED | 568 | #ifdef CONFIG_USB_GADGET_SUPERSPEED |
569 | /* | 569 | /* |
570 | * runtime test would check "g->is_superspeed" ... that might be | 570 | * runtime test would check "g->max_speed" ... that might be |
571 | * useful to work around hardware bugs, but is mostly pointless | 571 | * useful to work around hardware bugs, but is mostly pointless |
572 | */ | 572 | */ |
573 | return 1; | 573 | return 1; |
@@ -760,7 +760,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget) | |||
760 | /** | 760 | /** |
761 | * struct usb_gadget_driver - driver for usb 'slave' devices | 761 | * struct usb_gadget_driver - driver for usb 'slave' devices |
762 | * @function: String describing the gadget's function | 762 | * @function: String describing the gadget's function |
763 | * @speed: Highest speed the driver handles. | 763 | * @max_speed: Highest speed the driver handles. |
764 | * @setup: Invoked for ep0 control requests that aren't handled by | 764 | * @setup: Invoked for ep0 control requests that aren't handled by |
765 | * the hardware level driver. Most calls must be handled by | 765 | * the hardware level driver. Most calls must be handled by |
766 | * the gadget driver, including descriptor and configuration | 766 | * the gadget driver, including descriptor and configuration |
@@ -824,7 +824,7 @@ static inline int usb_gadget_disconnect(struct usb_gadget *gadget) | |||
824 | */ | 824 | */ |
825 | struct usb_gadget_driver { | 825 | struct usb_gadget_driver { |
826 | char *function; | 826 | char *function; |
827 | enum usb_device_speed speed; | 827 | enum usb_device_speed max_speed; |
828 | void (*unbind)(struct usb_gadget *); | 828 | void (*unbind)(struct usb_gadget *); |
829 | int (*setup)(struct usb_gadget *, | 829 | int (*setup)(struct usb_gadget *, |
830 | const struct usb_ctrlrequest *); | 830 | const struct usb_ctrlrequest *); |
diff --git a/include/linux/usb/renesas_usbhs.h b/include/linux/usb/renesas_usbhs.h index e5a40c318548..0d3f98879256 100644 --- a/include/linux/usb/renesas_usbhs.h +++ b/include/linux/usb/renesas_usbhs.h | |||
@@ -67,6 +67,14 @@ struct renesas_usbhs_platform_callback { | |||
67 | /* | 67 | /* |
68 | * option: | 68 | * option: |
69 | * | 69 | * |
70 | * for board specific clock control | ||
71 | */ | ||
72 | void (*power_ctrl)(struct platform_device *pdev, | ||
73 | void __iomem *base, int enable); | ||
74 | |||
75 | /* | ||
76 | * option: | ||
77 | * | ||
70 | * Phy reset for platform | 78 | * Phy reset for platform |
71 | */ | 79 | */ |
72 | void (*phy_reset)(struct platform_device *pdev); | 80 | void (*phy_reset)(struct platform_device *pdev); |
@@ -118,7 +126,7 @@ struct renesas_usbhs_driver_param { | |||
118 | * | 126 | * |
119 | * delay time from notify_hotplug callback | 127 | * delay time from notify_hotplug callback |
120 | */ | 128 | */ |
121 | int detection_delay; | 129 | int detection_delay; /* msec */ |
122 | 130 | ||
123 | /* | 131 | /* |
124 | * option: | 132 | * option: |