diff options
-rw-r--r-- | drivers/usb/gadget/inode.c | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index ea8e3160d05e..e5ce4f0bb7cc 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -933,28 +933,24 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req) | |||
933 | static void ep0_complete (struct usb_ep *ep, struct usb_request *req) | 933 | static void ep0_complete (struct usb_ep *ep, struct usb_request *req) |
934 | { | 934 | { |
935 | struct dev_data *dev = ep->driver_data; | 935 | struct dev_data *dev = ep->driver_data; |
936 | unsigned long flags; | ||
936 | int free = 1; | 937 | int free = 1; |
937 | 938 | ||
938 | /* for control OUT, data must still get to userspace */ | 939 | /* for control OUT, data must still get to userspace */ |
940 | spin_lock_irqsave(&dev->lock, flags); | ||
939 | if (!dev->setup_in) { | 941 | if (!dev->setup_in) { |
940 | dev->setup_out_error = (req->status != 0); | 942 | dev->setup_out_error = (req->status != 0); |
941 | if (!dev->setup_out_error) | 943 | if (!dev->setup_out_error) |
942 | free = 0; | 944 | free = 0; |
943 | dev->setup_out_ready = 1; | 945 | dev->setup_out_ready = 1; |
944 | ep0_readable (dev); | 946 | ep0_readable (dev); |
945 | } else { | ||
946 | unsigned long flags; | ||
947 | |||
948 | spin_lock_irqsave(&dev->lock, flags); | ||
949 | if (dev->state == STATE_DEV_SETUP) | ||
950 | dev->state = STATE_DEV_CONNECTED; | ||
951 | spin_unlock_irqrestore(&dev->lock, flags); | ||
952 | } | 947 | } |
953 | 948 | ||
954 | /* clean up as appropriate */ | 949 | /* clean up as appropriate */ |
955 | if (free && req->buf != &dev->rbuf) | 950 | if (free && req->buf != &dev->rbuf) |
956 | clean_req (ep, req); | 951 | clean_req (ep, req); |
957 | req->complete = epio_complete; | 952 | req->complete = epio_complete; |
953 | spin_unlock_irqrestore(&dev->lock, flags); | ||
958 | } | 954 | } |
959 | 955 | ||
960 | static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) | 956 | static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) |
@@ -1036,6 +1032,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1036 | spin_lock_irq (&dev->lock); | 1032 | spin_lock_irq (&dev->lock); |
1037 | if (retval) | 1033 | if (retval) |
1038 | goto done; | 1034 | goto done; |
1035 | |||
1036 | if (dev->state != STATE_DEV_SETUP) { | ||
1037 | retval = -ECANCELED; | ||
1038 | goto done; | ||
1039 | } | ||
1040 | dev->state = STATE_DEV_CONNECTED; | ||
1041 | |||
1039 | if (dev->setup_out_error) | 1042 | if (dev->setup_out_error) |
1040 | retval = -EIO; | 1043 | retval = -EIO; |
1041 | else { | 1044 | else { |
@@ -1187,6 +1190,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1187 | if (dev->setup_in) { | 1190 | if (dev->setup_in) { |
1188 | retval = setup_req (dev->gadget->ep0, dev->req, len); | 1191 | retval = setup_req (dev->gadget->ep0, dev->req, len); |
1189 | if (retval == 0) { | 1192 | if (retval == 0) { |
1193 | dev->state = STATE_DEV_CONNECTED; | ||
1190 | spin_unlock_irq (&dev->lock); | 1194 | spin_unlock_irq (&dev->lock); |
1191 | if (copy_from_user (dev->req->buf, buf, len)) | 1195 | if (copy_from_user (dev->req->buf, buf, len)) |
1192 | retval = -EFAULT; | 1196 | retval = -EFAULT; |