diff options
Diffstat (limited to 'drivers/usb/gadget/dummy_hcd.c')
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index c655d46c8aed..9734cb76dd6c 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -138,7 +138,7 @@ static const char *const ep_name [] = { | |||
138 | /* or like sa1100: two fixed function endpoints */ | 138 | /* or like sa1100: two fixed function endpoints */ |
139 | "ep1out-bulk", "ep2in-bulk", | 139 | "ep1out-bulk", "ep2in-bulk", |
140 | }; | 140 | }; |
141 | #define DUMMY_ENDPOINTS (sizeof(ep_name)/sizeof(char *)) | 141 | #define DUMMY_ENDPOINTS ARRAY_SIZE(ep_name) |
142 | 142 | ||
143 | /*-------------------------------------------------------------------------*/ | 143 | /*-------------------------------------------------------------------------*/ |
144 | 144 | ||
@@ -896,7 +896,7 @@ dummy_gadget_release (struct device *dev) | |||
896 | #endif | 896 | #endif |
897 | } | 897 | } |
898 | 898 | ||
899 | static int dummy_udc_probe (struct platform_device *dev) | 899 | static int dummy_udc_probe (struct platform_device *pdev) |
900 | { | 900 | { |
901 | struct dummy *dum = the_controller; | 901 | struct dummy *dum = the_controller; |
902 | int rc; | 902 | int rc; |
@@ -909,7 +909,7 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); | 909 | dum->gadget.is_otg = (dummy_to_hcd(dum)->self.otg_port != 0); |
910 | 910 | ||
911 | strcpy (dum->gadget.dev.bus_id, "gadget"); | 911 | strcpy (dum->gadget.dev.bus_id, "gadget"); |
912 | dum->gadget.dev.parent = &dev->dev; | 912 | dum->gadget.dev.parent = &pdev->dev; |
913 | dum->gadget.dev.release = dummy_gadget_release; | 913 | dum->gadget.dev.release = dummy_gadget_release; |
914 | rc = device_register (&dum->gadget.dev); | 914 | rc = device_register (&dum->gadget.dev); |
915 | if (rc < 0) | 915 | if (rc < 0) |
@@ -919,47 +919,47 @@ static int dummy_udc_probe (struct platform_device *dev) | |||
919 | usb_bus_get (&dummy_to_hcd (dum)->self); | 919 | usb_bus_get (&dummy_to_hcd (dum)->self); |
920 | #endif | 920 | #endif |
921 | 921 | ||
922 | platform_set_drvdata (dev, dum); | 922 | platform_set_drvdata (pdev, dum); |
923 | device_create_file (&dum->gadget.dev, &dev_attr_function); | 923 | device_create_file (&dum->gadget.dev, &dev_attr_function); |
924 | return rc; | 924 | return rc; |
925 | } | 925 | } |
926 | 926 | ||
927 | static int dummy_udc_remove (struct platform_device *dev) | 927 | static int dummy_udc_remove (struct platform_device *pdev) |
928 | { | 928 | { |
929 | struct dummy *dum = platform_get_drvdata (dev); | 929 | struct dummy *dum = platform_get_drvdata (pdev); |
930 | 930 | ||
931 | platform_set_drvdata (dev, NULL); | 931 | platform_set_drvdata (pdev, NULL); |
932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); | 932 | device_remove_file (&dum->gadget.dev, &dev_attr_function); |
933 | device_unregister (&dum->gadget.dev); | 933 | device_unregister (&dum->gadget.dev); |
934 | return 0; | 934 | return 0; |
935 | } | 935 | } |
936 | 936 | ||
937 | static int dummy_udc_suspend (struct platform_device *dev, pm_message_t state) | 937 | static int dummy_udc_suspend (struct platform_device *pdev, pm_message_t state) |
938 | { | 938 | { |
939 | struct dummy *dum = platform_get_drvdata(dev); | 939 | struct dummy *dum = platform_get_drvdata(pdev); |
940 | 940 | ||
941 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 941 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
942 | spin_lock_irq (&dum->lock); | 942 | spin_lock_irq (&dum->lock); |
943 | dum->udc_suspended = 1; | 943 | dum->udc_suspended = 1; |
944 | set_link_state (dum); | 944 | set_link_state (dum); |
945 | spin_unlock_irq (&dum->lock); | 945 | spin_unlock_irq (&dum->lock); |
946 | 946 | ||
947 | dev->dev.power.power_state = state; | 947 | pdev->dev.power.power_state = state; |
948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 948 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
949 | return 0; | 949 | return 0; |
950 | } | 950 | } |
951 | 951 | ||
952 | static int dummy_udc_resume (struct platform_device *dev) | 952 | static int dummy_udc_resume (struct platform_device *pdev) |
953 | { | 953 | { |
954 | struct dummy *dum = platform_get_drvdata(dev); | 954 | struct dummy *dum = platform_get_drvdata(pdev); |
955 | 955 | ||
956 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 956 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
957 | spin_lock_irq (&dum->lock); | 957 | spin_lock_irq (&dum->lock); |
958 | dum->udc_suspended = 0; | 958 | dum->udc_suspended = 0; |
959 | set_link_state (dum); | 959 | set_link_state (dum); |
960 | spin_unlock_irq (&dum->lock); | 960 | spin_unlock_irq (&dum->lock); |
961 | 961 | ||
962 | dev->dev.power.power_state = PMSG_ON; | 962 | pdev->dev.power.power_state = PMSG_ON; |
963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); | 963 | usb_hcd_poll_rh_status (dummy_to_hcd (dum)); |
964 | return 0; | 964 | return 0; |
965 | } | 965 | } |
@@ -1576,7 +1576,7 @@ static int dummy_hub_status (struct usb_hcd *hcd, char *buf) | |||
1576 | dum = hcd_to_dummy (hcd); | 1576 | dum = hcd_to_dummy (hcd); |
1577 | 1577 | ||
1578 | spin_lock_irqsave (&dum->lock, flags); | 1578 | spin_lock_irqsave (&dum->lock, flags); |
1579 | if (hcd->state != HC_STATE_RUNNING) | 1579 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
1580 | goto done; | 1580 | goto done; |
1581 | 1581 | ||
1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { | 1582 | if (dum->resuming && time_after_eq (jiffies, dum->re_timeout)) { |
@@ -1623,7 +1623,7 @@ static int dummy_hub_control ( | |||
1623 | int retval = 0; | 1623 | int retval = 0; |
1624 | unsigned long flags; | 1624 | unsigned long flags; |
1625 | 1625 | ||
1626 | if (hcd->state != HC_STATE_RUNNING) | 1626 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) |
1627 | return -ETIMEDOUT; | 1627 | return -ETIMEDOUT; |
1628 | 1628 | ||
1629 | dum = hcd_to_dummy (hcd); | 1629 | dum = hcd_to_dummy (hcd); |
@@ -1756,9 +1756,12 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
1756 | { | 1756 | { |
1757 | struct dummy *dum = hcd_to_dummy (hcd); | 1757 | struct dummy *dum = hcd_to_dummy (hcd); |
1758 | 1758 | ||
1759 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
1760 | |||
1759 | spin_lock_irq (&dum->lock); | 1761 | spin_lock_irq (&dum->lock); |
1760 | dum->rh_state = DUMMY_RH_SUSPENDED; | 1762 | dum->rh_state = DUMMY_RH_SUSPENDED; |
1761 | set_link_state (dum); | 1763 | set_link_state (dum); |
1764 | hcd->state = HC_STATE_SUSPENDED; | ||
1762 | spin_unlock_irq (&dum->lock); | 1765 | spin_unlock_irq (&dum->lock); |
1763 | return 0; | 1766 | return 0; |
1764 | } | 1767 | } |
@@ -1766,14 +1769,23 @@ static int dummy_bus_suspend (struct usb_hcd *hcd) | |||
1766 | static int dummy_bus_resume (struct usb_hcd *hcd) | 1769 | static int dummy_bus_resume (struct usb_hcd *hcd) |
1767 | { | 1770 | { |
1768 | struct dummy *dum = hcd_to_dummy (hcd); | 1771 | struct dummy *dum = hcd_to_dummy (hcd); |
1772 | int rc = 0; | ||
1773 | |||
1774 | dev_dbg (&hcd->self.root_hub->dev, "%s\n", __FUNCTION__); | ||
1769 | 1775 | ||
1770 | spin_lock_irq (&dum->lock); | 1776 | spin_lock_irq (&dum->lock); |
1771 | dum->rh_state = DUMMY_RH_RUNNING; | 1777 | if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { |
1772 | set_link_state (dum); | 1778 | dev_warn (&hcd->self.root_hub->dev, "HC isn't running!\n"); |
1773 | if (!list_empty(&dum->urbp_list)) | 1779 | rc = -ENODEV; |
1774 | mod_timer (&dum->timer, jiffies); | 1780 | } else { |
1781 | dum->rh_state = DUMMY_RH_RUNNING; | ||
1782 | set_link_state (dum); | ||
1783 | if (!list_empty(&dum->urbp_list)) | ||
1784 | mod_timer (&dum->timer, jiffies); | ||
1785 | hcd->state = HC_STATE_RUNNING; | ||
1786 | } | ||
1775 | spin_unlock_irq (&dum->lock); | 1787 | spin_unlock_irq (&dum->lock); |
1776 | return 0; | 1788 | return rc; |
1777 | } | 1789 | } |
1778 | 1790 | ||
1779 | /*-------------------------------------------------------------------------*/ | 1791 | /*-------------------------------------------------------------------------*/ |
@@ -1899,14 +1911,14 @@ static const struct hc_driver dummy_hcd = { | |||
1899 | .bus_resume = dummy_bus_resume, | 1911 | .bus_resume = dummy_bus_resume, |
1900 | }; | 1912 | }; |
1901 | 1913 | ||
1902 | static int dummy_hcd_probe (struct platform_device *dev) | 1914 | static int dummy_hcd_probe(struct platform_device *pdev) |
1903 | { | 1915 | { |
1904 | struct usb_hcd *hcd; | 1916 | struct usb_hcd *hcd; |
1905 | int retval; | 1917 | int retval; |
1906 | 1918 | ||
1907 | dev_info(&dev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); | 1919 | dev_info(&pdev->dev, "%s, driver " DRIVER_VERSION "\n", driver_desc); |
1908 | 1920 | ||
1909 | hcd = usb_create_hcd (&dummy_hcd, &dev->dev, dev->dev.bus_id); | 1921 | hcd = usb_create_hcd(&dummy_hcd, &pdev->dev, pdev->dev.bus_id); |
1910 | if (!hcd) | 1922 | if (!hcd) |
1911 | return -ENOMEM; | 1923 | return -ENOMEM; |
1912 | the_controller = hcd_to_dummy (hcd); | 1924 | the_controller = hcd_to_dummy (hcd); |
@@ -1919,36 +1931,43 @@ static int dummy_hcd_probe (struct platform_device *dev) | |||
1919 | return retval; | 1931 | return retval; |
1920 | } | 1932 | } |
1921 | 1933 | ||
1922 | static int dummy_hcd_remove (struct platform_device *dev) | 1934 | static int dummy_hcd_remove (struct platform_device *pdev) |
1923 | { | 1935 | { |
1924 | struct usb_hcd *hcd; | 1936 | struct usb_hcd *hcd; |
1925 | 1937 | ||
1926 | hcd = platform_get_drvdata (dev); | 1938 | hcd = platform_get_drvdata (pdev); |
1927 | usb_remove_hcd (hcd); | 1939 | usb_remove_hcd (hcd); |
1928 | usb_put_hcd (hcd); | 1940 | usb_put_hcd (hcd); |
1929 | the_controller = NULL; | 1941 | the_controller = NULL; |
1930 | return 0; | 1942 | return 0; |
1931 | } | 1943 | } |
1932 | 1944 | ||
1933 | static int dummy_hcd_suspend (struct platform_device *dev, pm_message_t state) | 1945 | static int dummy_hcd_suspend (struct platform_device *pdev, pm_message_t state) |
1934 | { | 1946 | { |
1935 | struct usb_hcd *hcd; | 1947 | struct usb_hcd *hcd; |
1948 | struct dummy *dum; | ||
1949 | int rc = 0; | ||
1936 | 1950 | ||
1937 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1951 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
1938 | hcd = platform_get_drvdata (dev); | ||
1939 | 1952 | ||
1940 | hcd->state = HC_STATE_SUSPENDED; | 1953 | hcd = platform_get_drvdata (pdev); |
1941 | return 0; | 1954 | dum = hcd_to_dummy (hcd); |
1955 | if (dum->rh_state == DUMMY_RH_RUNNING) { | ||
1956 | dev_warn(&pdev->dev, "Root hub isn't suspended!\n"); | ||
1957 | rc = -EBUSY; | ||
1958 | } else | ||
1959 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1960 | return rc; | ||
1942 | } | 1961 | } |
1943 | 1962 | ||
1944 | static int dummy_hcd_resume (struct platform_device *dev) | 1963 | static int dummy_hcd_resume (struct platform_device *pdev) |
1945 | { | 1964 | { |
1946 | struct usb_hcd *hcd; | 1965 | struct usb_hcd *hcd; |
1947 | 1966 | ||
1948 | dev_dbg (&dev->dev, "%s\n", __FUNCTION__); | 1967 | dev_dbg (&pdev->dev, "%s\n", __FUNCTION__); |
1949 | hcd = platform_get_drvdata (dev); | ||
1950 | hcd->state = HC_STATE_RUNNING; | ||
1951 | 1968 | ||
1969 | hcd = platform_get_drvdata (pdev); | ||
1970 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
1952 | usb_hcd_poll_rh_status (hcd); | 1971 | usb_hcd_poll_rh_status (hcd); |
1953 | return 0; | 1972 | return 0; |
1954 | } | 1973 | } |