diff options
author | Alan Stern <stern@rowland.harvard.edu> | 2006-05-22 12:26:31 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-06-21 18:04:12 -0400 |
commit | 83196b52053068f0240371ad2efd9d6ad685bbeb (patch) | |
tree | 61ce5b727519780633f1cc4cfaaebc7087a1f8d2 | |
parent | 212a4b4ed1ea9a969f3f967b3e3a8075ad1cb4de (diff) |
[PATCH] gadgetfs: fix AIO interface bugs
This patch (as691) fixes a few errors in the AIO interface for the
gadgetfs driver. Now requests will complete properly instead of hanging.
Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/gadget/inode.c | 11 |
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 0eb010a3f5bc..57bf24810f9b 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -528,7 +528,7 @@ struct kiocb_priv { | |||
528 | struct usb_request *req; | 528 | struct usb_request *req; |
529 | struct ep_data *epdata; | 529 | struct ep_data *epdata; |
530 | void *buf; | 530 | void *buf; |
531 | char __user *ubuf; | 531 | char __user *ubuf; /* NULL for writes */ |
532 | unsigned actual; | 532 | unsigned actual; |
533 | }; | 533 | }; |
534 | 534 | ||
@@ -566,7 +566,6 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb) | |||
566 | status = priv->actual; | 566 | status = priv->actual; |
567 | kfree(priv->buf); | 567 | kfree(priv->buf); |
568 | kfree(priv); | 568 | kfree(priv); |
569 | aio_put_req(iocb); | ||
570 | return status; | 569 | return status; |
571 | } | 570 | } |
572 | 571 | ||
@@ -580,8 +579,8 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) | |||
580 | spin_lock(&epdata->dev->lock); | 579 | spin_lock(&epdata->dev->lock); |
581 | priv->req = NULL; | 580 | priv->req = NULL; |
582 | priv->epdata = NULL; | 581 | priv->epdata = NULL; |
583 | if (NULL == iocb->ki_retry | 582 | if (priv->ubuf == NULL |
584 | || unlikely(0 == req->actual) | 583 | || unlikely(req->actual == 0) |
585 | || unlikely(kiocbIsCancelled(iocb))) { | 584 | || unlikely(kiocbIsCancelled(iocb))) { |
586 | kfree(req->buf); | 585 | kfree(req->buf); |
587 | kfree(priv); | 586 | kfree(priv); |
@@ -618,7 +617,7 @@ ep_aio_rwtail( | |||
618 | char __user *ubuf | 617 | char __user *ubuf |
619 | ) | 618 | ) |
620 | { | 619 | { |
621 | struct kiocb_priv *priv = (void *) &iocb->private; | 620 | struct kiocb_priv *priv; |
622 | struct usb_request *req; | 621 | struct usb_request *req; |
623 | ssize_t value; | 622 | ssize_t value; |
624 | 623 | ||
@@ -670,7 +669,7 @@ fail: | |||
670 | kfree(priv); | 669 | kfree(priv); |
671 | put_ep(epdata); | 670 | put_ep(epdata); |
672 | } else | 671 | } else |
673 | value = -EIOCBQUEUED; | 672 | value = (ubuf ? -EIOCBRETRY : -EIOCBQUEUED); |
674 | return value; | 673 | return value; |
675 | } | 674 | } |
676 | 675 | ||