diff options
Diffstat (limited to 'drivers/usb/gadget')
-rw-r--r-- | drivers/usb/gadget/dummy_hcd.c | 91 | ||||
-rw-r--r-- | drivers/usb/gadget/file_storage.c | 93 | ||||
-rw-r--r-- | drivers/usb/gadget/serial.c | 2 |
3 files changed, 114 insertions, 72 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 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index ea09aaa3cab6..0cea9782d7d4 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -224,6 +224,7 @@ | |||
224 | #include <linux/fs.h> | 224 | #include <linux/fs.h> |
225 | #include <linux/init.h> | 225 | #include <linux/init.h> |
226 | #include <linux/kernel.h> | 226 | #include <linux/kernel.h> |
227 | #include <linux/kref.h> | ||
227 | #include <linux/kthread.h> | 228 | #include <linux/kthread.h> |
228 | #include <linux/limits.h> | 229 | #include <linux/limits.h> |
229 | #include <linux/list.h> | 230 | #include <linux/list.h> |
@@ -238,7 +239,6 @@ | |||
238 | #include <linux/string.h> | 239 | #include <linux/string.h> |
239 | #include <linux/suspend.h> | 240 | #include <linux/suspend.h> |
240 | #include <linux/utsname.h> | 241 | #include <linux/utsname.h> |
241 | #include <linux/wait.h> | ||
242 | 242 | ||
243 | #include <linux/usb_ch9.h> | 243 | #include <linux/usb_ch9.h> |
244 | #include <linux/usb_gadget.h> | 244 | #include <linux/usb_gadget.h> |
@@ -250,7 +250,7 @@ | |||
250 | 250 | ||
251 | #define DRIVER_DESC "File-backed Storage Gadget" | 251 | #define DRIVER_DESC "File-backed Storage Gadget" |
252 | #define DRIVER_NAME "g_file_storage" | 252 | #define DRIVER_NAME "g_file_storage" |
253 | #define DRIVER_VERSION "20 October 2004" | 253 | #define DRIVER_VERSION "28 November 2005" |
254 | 254 | ||
255 | static const char longname[] = DRIVER_DESC; | 255 | static const char longname[] = DRIVER_DESC; |
256 | static const char shortname[] = DRIVER_NAME; | 256 | static const char shortname[] = DRIVER_NAME; |
@@ -335,8 +335,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
335 | #define MAX_LUNS 8 | 335 | #define MAX_LUNS 8 |
336 | 336 | ||
337 | /* Arggh! There should be a module_param_array_named macro! */ | 337 | /* Arggh! There should be a module_param_array_named macro! */ |
338 | static char *file[MAX_LUNS] = {NULL, }; | 338 | static char *file[MAX_LUNS]; |
339 | static int ro[MAX_LUNS] = {0, }; | 339 | static int ro[MAX_LUNS]; |
340 | 340 | ||
341 | static struct { | 341 | static struct { |
342 | int num_filenames; | 342 | int num_filenames; |
@@ -587,7 +587,7 @@ enum fsg_buffer_state { | |||
587 | struct fsg_buffhd { | 587 | struct fsg_buffhd { |
588 | void *buf; | 588 | void *buf; |
589 | dma_addr_t dma; | 589 | dma_addr_t dma; |
590 | volatile enum fsg_buffer_state state; | 590 | enum fsg_buffer_state state; |
591 | struct fsg_buffhd *next; | 591 | struct fsg_buffhd *next; |
592 | 592 | ||
593 | /* The NetChip 2280 is faster, and handles some protocol faults | 593 | /* The NetChip 2280 is faster, and handles some protocol faults |
@@ -596,9 +596,9 @@ struct fsg_buffhd { | |||
596 | unsigned int bulk_out_intended_length; | 596 | unsigned int bulk_out_intended_length; |
597 | 597 | ||
598 | struct usb_request *inreq; | 598 | struct usb_request *inreq; |
599 | volatile int inreq_busy; | 599 | int inreq_busy; |
600 | struct usb_request *outreq; | 600 | struct usb_request *outreq; |
601 | volatile int outreq_busy; | 601 | int outreq_busy; |
602 | }; | 602 | }; |
603 | 603 | ||
604 | enum fsg_state { | 604 | enum fsg_state { |
@@ -631,13 +631,16 @@ struct fsg_dev { | |||
631 | /* filesem protects: backing files in use */ | 631 | /* filesem protects: backing files in use */ |
632 | struct rw_semaphore filesem; | 632 | struct rw_semaphore filesem; |
633 | 633 | ||
634 | /* reference counting: wait until all LUNs are released */ | ||
635 | struct kref ref; | ||
636 | |||
634 | struct usb_ep *ep0; // Handy copy of gadget->ep0 | 637 | struct usb_ep *ep0; // Handy copy of gadget->ep0 |
635 | struct usb_request *ep0req; // For control responses | 638 | struct usb_request *ep0req; // For control responses |
636 | volatile unsigned int ep0_req_tag; | 639 | unsigned int ep0_req_tag; |
637 | const char *ep0req_name; | 640 | const char *ep0req_name; |
638 | 641 | ||
639 | struct usb_request *intreq; // For interrupt responses | 642 | struct usb_request *intreq; // For interrupt responses |
640 | volatile int intreq_busy; | 643 | int intreq_busy; |
641 | struct fsg_buffhd *intr_buffhd; | 644 | struct fsg_buffhd *intr_buffhd; |
642 | 645 | ||
643 | unsigned int bulk_out_maxpacket; | 646 | unsigned int bulk_out_maxpacket; |
@@ -667,7 +670,6 @@ struct fsg_dev { | |||
667 | struct fsg_buffhd *next_buffhd_to_drain; | 670 | struct fsg_buffhd *next_buffhd_to_drain; |
668 | struct fsg_buffhd buffhds[NUM_BUFFERS]; | 671 | struct fsg_buffhd buffhds[NUM_BUFFERS]; |
669 | 672 | ||
670 | wait_queue_head_t thread_wqh; | ||
671 | int thread_wakeup_needed; | 673 | int thread_wakeup_needed; |
672 | struct completion thread_notifier; | 674 | struct completion thread_notifier; |
673 | struct task_struct *thread_task; | 675 | struct task_struct *thread_task; |
@@ -694,7 +696,6 @@ struct fsg_dev { | |||
694 | unsigned int nluns; | 696 | unsigned int nluns; |
695 | struct lun *luns; | 697 | struct lun *luns; |
696 | struct lun *curlun; | 698 | struct lun *curlun; |
697 | struct completion lun_released; | ||
698 | }; | 699 | }; |
699 | 700 | ||
700 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 701 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
@@ -1073,11 +1074,13 @@ static int populate_config_buf(struct usb_gadget *gadget, | |||
1073 | 1074 | ||
1074 | /* These routines may be called in process context or in_irq */ | 1075 | /* These routines may be called in process context or in_irq */ |
1075 | 1076 | ||
1077 | /* Caller must hold fsg->lock */ | ||
1076 | static void wakeup_thread(struct fsg_dev *fsg) | 1078 | static void wakeup_thread(struct fsg_dev *fsg) |
1077 | { | 1079 | { |
1078 | /* Tell the main thread that something has happened */ | 1080 | /* Tell the main thread that something has happened */ |
1079 | fsg->thread_wakeup_needed = 1; | 1081 | fsg->thread_wakeup_needed = 1; |
1080 | wake_up_all(&fsg->thread_wqh); | 1082 | if (fsg->thread_task) |
1083 | wake_up_process(fsg->thread_task); | ||
1081 | } | 1084 | } |
1082 | 1085 | ||
1083 | 1086 | ||
@@ -1164,11 +1167,12 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1164 | usb_ep_fifo_flush(ep); | 1167 | usb_ep_fifo_flush(ep); |
1165 | 1168 | ||
1166 | /* Hold the lock while we update the request and buffer states */ | 1169 | /* Hold the lock while we update the request and buffer states */ |
1170 | smp_wmb(); | ||
1167 | spin_lock(&fsg->lock); | 1171 | spin_lock(&fsg->lock); |
1168 | bh->inreq_busy = 0; | 1172 | bh->inreq_busy = 0; |
1169 | bh->state = BUF_STATE_EMPTY; | 1173 | bh->state = BUF_STATE_EMPTY; |
1170 | spin_unlock(&fsg->lock); | ||
1171 | wakeup_thread(fsg); | 1174 | wakeup_thread(fsg); |
1175 | spin_unlock(&fsg->lock); | ||
1172 | } | 1176 | } |
1173 | 1177 | ||
1174 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1178 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -1185,11 +1189,12 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
1185 | usb_ep_fifo_flush(ep); | 1189 | usb_ep_fifo_flush(ep); |
1186 | 1190 | ||
1187 | /* Hold the lock while we update the request and buffer states */ | 1191 | /* Hold the lock while we update the request and buffer states */ |
1192 | smp_wmb(); | ||
1188 | spin_lock(&fsg->lock); | 1193 | spin_lock(&fsg->lock); |
1189 | bh->outreq_busy = 0; | 1194 | bh->outreq_busy = 0; |
1190 | bh->state = BUF_STATE_FULL; | 1195 | bh->state = BUF_STATE_FULL; |
1191 | spin_unlock(&fsg->lock); | ||
1192 | wakeup_thread(fsg); | 1196 | wakeup_thread(fsg); |
1197 | spin_unlock(&fsg->lock); | ||
1193 | } | 1198 | } |
1194 | 1199 | ||
1195 | 1200 | ||
@@ -1206,11 +1211,12 @@ static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1206 | usb_ep_fifo_flush(ep); | 1211 | usb_ep_fifo_flush(ep); |
1207 | 1212 | ||
1208 | /* Hold the lock while we update the request and buffer states */ | 1213 | /* Hold the lock while we update the request and buffer states */ |
1214 | smp_wmb(); | ||
1209 | spin_lock(&fsg->lock); | 1215 | spin_lock(&fsg->lock); |
1210 | fsg->intreq_busy = 0; | 1216 | fsg->intreq_busy = 0; |
1211 | bh->state = BUF_STATE_EMPTY; | 1217 | bh->state = BUF_STATE_EMPTY; |
1212 | spin_unlock(&fsg->lock); | ||
1213 | wakeup_thread(fsg); | 1218 | wakeup_thread(fsg); |
1219 | spin_unlock(&fsg->lock); | ||
1214 | } | 1220 | } |
1215 | 1221 | ||
1216 | #else | 1222 | #else |
@@ -1261,8 +1267,8 @@ static void received_cbi_adsc(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
1261 | fsg->cbbuf_cmnd_size = req->actual; | 1267 | fsg->cbbuf_cmnd_size = req->actual; |
1262 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); | 1268 | memcpy(fsg->cbbuf_cmnd, req->buf, fsg->cbbuf_cmnd_size); |
1263 | 1269 | ||
1264 | spin_unlock(&fsg->lock); | ||
1265 | wakeup_thread(fsg); | 1270 | wakeup_thread(fsg); |
1271 | spin_unlock(&fsg->lock); | ||
1266 | } | 1272 | } |
1267 | 1273 | ||
1268 | #else | 1274 | #else |
@@ -1514,8 +1520,8 @@ static int fsg_setup(struct usb_gadget *gadget, | |||
1514 | 1520 | ||
1515 | /* Use this for bulk or interrupt transfers, not ep0 */ | 1521 | /* Use this for bulk or interrupt transfers, not ep0 */ |
1516 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | 1522 | static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, |
1517 | struct usb_request *req, volatile int *pbusy, | 1523 | struct usb_request *req, int *pbusy, |
1518 | volatile enum fsg_buffer_state *state) | 1524 | enum fsg_buffer_state *state) |
1519 | { | 1525 | { |
1520 | int rc; | 1526 | int rc; |
1521 | 1527 | ||
@@ -1523,8 +1529,11 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1523 | dump_msg(fsg, "bulk-in", req->buf, req->length); | 1529 | dump_msg(fsg, "bulk-in", req->buf, req->length); |
1524 | else if (ep == fsg->intr_in) | 1530 | else if (ep == fsg->intr_in) |
1525 | dump_msg(fsg, "intr-in", req->buf, req->length); | 1531 | dump_msg(fsg, "intr-in", req->buf, req->length); |
1532 | |||
1533 | spin_lock_irq(&fsg->lock); | ||
1526 | *pbusy = 1; | 1534 | *pbusy = 1; |
1527 | *state = BUF_STATE_BUSY; | 1535 | *state = BUF_STATE_BUSY; |
1536 | spin_unlock_irq(&fsg->lock); | ||
1528 | rc = usb_ep_queue(ep, req, GFP_KERNEL); | 1537 | rc = usb_ep_queue(ep, req, GFP_KERNEL); |
1529 | if (rc != 0) { | 1538 | if (rc != 0) { |
1530 | *pbusy = 0; | 1539 | *pbusy = 0; |
@@ -1544,14 +1553,23 @@ static void start_transfer(struct fsg_dev *fsg, struct usb_ep *ep, | |||
1544 | 1553 | ||
1545 | static int sleep_thread(struct fsg_dev *fsg) | 1554 | static int sleep_thread(struct fsg_dev *fsg) |
1546 | { | 1555 | { |
1547 | int rc; | 1556 | int rc = 0; |
1548 | 1557 | ||
1549 | /* Wait until a signal arrives or we are woken up */ | 1558 | /* Wait until a signal arrives or we are woken up */ |
1550 | rc = wait_event_interruptible(fsg->thread_wqh, | 1559 | for (;;) { |
1551 | fsg->thread_wakeup_needed); | 1560 | try_to_freeze(); |
1561 | set_current_state(TASK_INTERRUPTIBLE); | ||
1562 | if (signal_pending(current)) { | ||
1563 | rc = -EINTR; | ||
1564 | break; | ||
1565 | } | ||
1566 | if (fsg->thread_wakeup_needed) | ||
1567 | break; | ||
1568 | schedule(); | ||
1569 | } | ||
1570 | __set_current_state(TASK_RUNNING); | ||
1552 | fsg->thread_wakeup_needed = 0; | 1571 | fsg->thread_wakeup_needed = 0; |
1553 | try_to_freeze(); | 1572 | return rc; |
1554 | return (rc ? -EINTR : 0); | ||
1555 | } | 1573 | } |
1556 | 1574 | ||
1557 | 1575 | ||
@@ -1788,6 +1806,7 @@ static int do_write(struct fsg_dev *fsg) | |||
1788 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) | 1806 | if (bh->state == BUF_STATE_EMPTY && !get_some_more) |
1789 | break; // We stopped early | 1807 | break; // We stopped early |
1790 | if (bh->state == BUF_STATE_FULL) { | 1808 | if (bh->state == BUF_STATE_FULL) { |
1809 | smp_rmb(); | ||
1791 | fsg->next_buffhd_to_drain = bh->next; | 1810 | fsg->next_buffhd_to_drain = bh->next; |
1792 | bh->state = BUF_STATE_EMPTY; | 1811 | bh->state = BUF_STATE_EMPTY; |
1793 | 1812 | ||
@@ -2356,6 +2375,7 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2356 | 2375 | ||
2357 | /* Throw away the data in a filled buffer */ | 2376 | /* Throw away the data in a filled buffer */ |
2358 | if (bh->state == BUF_STATE_FULL) { | 2377 | if (bh->state == BUF_STATE_FULL) { |
2378 | smp_rmb(); | ||
2359 | bh->state = BUF_STATE_EMPTY; | 2379 | bh->state = BUF_STATE_EMPTY; |
2360 | fsg->next_buffhd_to_drain = bh->next; | 2380 | fsg->next_buffhd_to_drain = bh->next; |
2361 | 2381 | ||
@@ -3021,6 +3041,7 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3021 | if ((rc = sleep_thread(fsg)) != 0) | 3041 | if ((rc = sleep_thread(fsg)) != 0) |
3022 | return rc; | 3042 | return rc; |
3023 | } | 3043 | } |
3044 | smp_rmb(); | ||
3024 | rc = received_cbw(fsg, bh); | 3045 | rc = received_cbw(fsg, bh); |
3025 | bh->state = BUF_STATE_EMPTY; | 3046 | bh->state = BUF_STATE_EMPTY; |
3026 | 3047 | ||
@@ -3642,11 +3663,19 @@ static DEVICE_ATTR(file, 0444, show_file, NULL); | |||
3642 | 3663 | ||
3643 | /*-------------------------------------------------------------------------*/ | 3664 | /*-------------------------------------------------------------------------*/ |
3644 | 3665 | ||
3666 | static void fsg_release(struct kref *ref) | ||
3667 | { | ||
3668 | struct fsg_dev *fsg = container_of(ref, struct fsg_dev, ref); | ||
3669 | |||
3670 | kfree(fsg->luns); | ||
3671 | kfree(fsg); | ||
3672 | } | ||
3673 | |||
3645 | static void lun_release(struct device *dev) | 3674 | static void lun_release(struct device *dev) |
3646 | { | 3675 | { |
3647 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3676 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
3648 | 3677 | ||
3649 | complete(&fsg->lun_released); | 3678 | kref_put(&fsg->ref, fsg_release); |
3650 | } | 3679 | } |
3651 | 3680 | ||
3652 | static void fsg_unbind(struct usb_gadget *gadget) | 3681 | static void fsg_unbind(struct usb_gadget *gadget) |
@@ -3660,14 +3689,12 @@ static void fsg_unbind(struct usb_gadget *gadget) | |||
3660 | clear_bit(REGISTERED, &fsg->atomic_bitflags); | 3689 | clear_bit(REGISTERED, &fsg->atomic_bitflags); |
3661 | 3690 | ||
3662 | /* Unregister the sysfs attribute files and the LUNs */ | 3691 | /* Unregister the sysfs attribute files and the LUNs */ |
3663 | init_completion(&fsg->lun_released); | ||
3664 | for (i = 0; i < fsg->nluns; ++i) { | 3692 | for (i = 0; i < fsg->nluns; ++i) { |
3665 | curlun = &fsg->luns[i]; | 3693 | curlun = &fsg->luns[i]; |
3666 | if (curlun->registered) { | 3694 | if (curlun->registered) { |
3667 | device_remove_file(&curlun->dev, &dev_attr_ro); | 3695 | device_remove_file(&curlun->dev, &dev_attr_ro); |
3668 | device_remove_file(&curlun->dev, &dev_attr_file); | 3696 | device_remove_file(&curlun->dev, &dev_attr_file); |
3669 | device_unregister(&curlun->dev); | 3697 | device_unregister(&curlun->dev); |
3670 | wait_for_completion(&fsg->lun_released); | ||
3671 | curlun->registered = 0; | 3698 | curlun->registered = 0; |
3672 | } | 3699 | } |
3673 | } | 3700 | } |
@@ -3846,6 +3873,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3846 | curlun->dev.release = lun_release; | 3873 | curlun->dev.release = lun_release; |
3847 | device_create_file(&curlun->dev, &dev_attr_ro); | 3874 | device_create_file(&curlun->dev, &dev_attr_ro); |
3848 | device_create_file(&curlun->dev, &dev_attr_file); | 3875 | device_create_file(&curlun->dev, &dev_attr_file); |
3876 | kref_get(&fsg->ref); | ||
3849 | } | 3877 | } |
3850 | 3878 | ||
3851 | if (file[i] && *file[i]) { | 3879 | if (file[i] && *file[i]) { |
@@ -4061,7 +4089,7 @@ static int __init fsg_alloc(void) | |||
4061 | return -ENOMEM; | 4089 | return -ENOMEM; |
4062 | spin_lock_init(&fsg->lock); | 4090 | spin_lock_init(&fsg->lock); |
4063 | init_rwsem(&fsg->filesem); | 4091 | init_rwsem(&fsg->filesem); |
4064 | init_waitqueue_head(&fsg->thread_wqh); | 4092 | kref_init(&fsg->ref); |
4065 | init_completion(&fsg->thread_notifier); | 4093 | init_completion(&fsg->thread_notifier); |
4066 | 4094 | ||
4067 | the_fsg = fsg; | 4095 | the_fsg = fsg; |
@@ -4069,13 +4097,6 @@ static int __init fsg_alloc(void) | |||
4069 | } | 4097 | } |
4070 | 4098 | ||
4071 | 4099 | ||
4072 | static void fsg_free(struct fsg_dev *fsg) | ||
4073 | { | ||
4074 | kfree(fsg->luns); | ||
4075 | kfree(fsg); | ||
4076 | } | ||
4077 | |||
4078 | |||
4079 | static int __init fsg_init(void) | 4100 | static int __init fsg_init(void) |
4080 | { | 4101 | { |
4081 | int rc; | 4102 | int rc; |
@@ -4085,7 +4106,7 @@ static int __init fsg_init(void) | |||
4085 | return rc; | 4106 | return rc; |
4086 | fsg = the_fsg; | 4107 | fsg = the_fsg; |
4087 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) | 4108 | if ((rc = usb_gadget_register_driver(&fsg_driver)) != 0) |
4088 | fsg_free(fsg); | 4109 | kref_put(&fsg->ref, fsg_release); |
4089 | return rc; | 4110 | return rc; |
4090 | } | 4111 | } |
4091 | module_init(fsg_init); | 4112 | module_init(fsg_init); |
@@ -4103,6 +4124,6 @@ static void __exit fsg_cleanup(void) | |||
4103 | wait_for_completion(&fsg->thread_notifier); | 4124 | wait_for_completion(&fsg->thread_notifier); |
4104 | 4125 | ||
4105 | close_all_backing_files(fsg); | 4126 | close_all_backing_files(fsg); |
4106 | fsg_free(fsg); | 4127 | kref_put(&fsg->ref, fsg_release); |
4107 | } | 4128 | } |
4108 | module_exit(fsg_cleanup); | 4129 | module_exit(fsg_cleanup); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index b35ac6d334f8..65e084a2c87e 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -890,10 +890,12 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
890 | /* wait for write buffer to drain, or */ | 890 | /* wait for write buffer to drain, or */ |
891 | /* at most GS_CLOSE_TIMEOUT seconds */ | 891 | /* at most GS_CLOSE_TIMEOUT seconds */ |
892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { | 892 | if (gs_buf_data_avail(port->port_write_buf) > 0) { |
893 | spin_unlock_irqrestore(&port->port_lock, flags); | ||
893 | wait_cond_interruptible_timeout(port->port_write_wait, | 894 | wait_cond_interruptible_timeout(port->port_write_wait, |
894 | port->port_dev == NULL | 895 | port->port_dev == NULL |
895 | || gs_buf_data_avail(port->port_write_buf) == 0, | 896 | || gs_buf_data_avail(port->port_write_buf) == 0, |
896 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); | 897 | &port->port_lock, flags, GS_CLOSE_TIMEOUT * HZ); |
898 | spin_lock_irqsave(&port->port_lock, flags); | ||
897 | } | 899 | } |
898 | 900 | ||
899 | /* free disconnected port on final close */ | 901 | /* free disconnected port on final close */ |