diff options
Diffstat (limited to 'drivers/usb/gadget/function/f_fs.c')
-rw-r--r-- | drivers/usb/gadget/function/f_fs.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c index 9990944a7245..8b342587f8ad 100644 --- a/drivers/usb/gadget/function/f_fs.c +++ b/drivers/usb/gadget/function/f_fs.c | |||
@@ -46,7 +46,8 @@ | |||
46 | static void ffs_data_get(struct ffs_data *ffs); | 46 | static void ffs_data_get(struct ffs_data *ffs); |
47 | static void ffs_data_put(struct ffs_data *ffs); | 47 | static void ffs_data_put(struct ffs_data *ffs); |
48 | /* Creates new ffs_data object. */ | 48 | /* Creates new ffs_data object. */ |
49 | static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc)); | 49 | static struct ffs_data *__must_check ffs_data_new(const char *dev_name) |
50 | __attribute__((malloc)); | ||
50 | 51 | ||
51 | /* Opened counter handling. */ | 52 | /* Opened counter handling. */ |
52 | static void ffs_data_opened(struct ffs_data *ffs); | 53 | static void ffs_data_opened(struct ffs_data *ffs); |
@@ -780,11 +781,12 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep, | |||
780 | struct usb_request *req) | 781 | struct usb_request *req) |
781 | { | 782 | { |
782 | struct ffs_io_data *io_data = req->context; | 783 | struct ffs_io_data *io_data = req->context; |
784 | struct ffs_data *ffs = io_data->ffs; | ||
783 | 785 | ||
784 | ENTER(); | 786 | ENTER(); |
785 | 787 | ||
786 | INIT_WORK(&io_data->work, ffs_user_copy_worker); | 788 | INIT_WORK(&io_data->work, ffs_user_copy_worker); |
787 | schedule_work(&io_data->work); | 789 | queue_work(ffs->io_completion_wq, &io_data->work); |
788 | } | 790 | } |
789 | 791 | ||
790 | static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile) | 792 | static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile) |
@@ -1500,7 +1502,7 @@ ffs_fs_mount(struct file_system_type *t, int flags, | |||
1500 | if (unlikely(ret < 0)) | 1502 | if (unlikely(ret < 0)) |
1501 | return ERR_PTR(ret); | 1503 | return ERR_PTR(ret); |
1502 | 1504 | ||
1503 | ffs = ffs_data_new(); | 1505 | ffs = ffs_data_new(dev_name); |
1504 | if (unlikely(!ffs)) | 1506 | if (unlikely(!ffs)) |
1505 | return ERR_PTR(-ENOMEM); | 1507 | return ERR_PTR(-ENOMEM); |
1506 | ffs->file_perms = data.perms; | 1508 | ffs->file_perms = data.perms; |
@@ -1610,6 +1612,7 @@ static void ffs_data_put(struct ffs_data *ffs) | |||
1610 | BUG_ON(waitqueue_active(&ffs->ev.waitq) || | 1612 | BUG_ON(waitqueue_active(&ffs->ev.waitq) || |
1611 | waitqueue_active(&ffs->ep0req_completion.wait) || | 1613 | waitqueue_active(&ffs->ep0req_completion.wait) || |
1612 | waitqueue_active(&ffs->wait)); | 1614 | waitqueue_active(&ffs->wait)); |
1615 | destroy_workqueue(ffs->io_completion_wq); | ||
1613 | kfree(ffs->dev_name); | 1616 | kfree(ffs->dev_name); |
1614 | kfree(ffs); | 1617 | kfree(ffs); |
1615 | } | 1618 | } |
@@ -1642,7 +1645,7 @@ static void ffs_data_closed(struct ffs_data *ffs) | |||
1642 | ffs_data_put(ffs); | 1645 | ffs_data_put(ffs); |
1643 | } | 1646 | } |
1644 | 1647 | ||
1645 | static struct ffs_data *ffs_data_new(void) | 1648 | static struct ffs_data *ffs_data_new(const char *dev_name) |
1646 | { | 1649 | { |
1647 | struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); | 1650 | struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL); |
1648 | if (unlikely(!ffs)) | 1651 | if (unlikely(!ffs)) |
@@ -1650,6 +1653,12 @@ static struct ffs_data *ffs_data_new(void) | |||
1650 | 1653 | ||
1651 | ENTER(); | 1654 | ENTER(); |
1652 | 1655 | ||
1656 | ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name); | ||
1657 | if (!ffs->io_completion_wq) { | ||
1658 | kfree(ffs); | ||
1659 | return NULL; | ||
1660 | } | ||
1661 | |||
1653 | refcount_set(&ffs->ref, 1); | 1662 | refcount_set(&ffs->ref, 1); |
1654 | atomic_set(&ffs->opened, 0); | 1663 | atomic_set(&ffs->opened, 0); |
1655 | ffs->state = FFS_READ_DESCRIPTORS; | 1664 | ffs->state = FFS_READ_DESCRIPTORS; |