|
@@ -46,7 +46,8 @@
|
|
|
static void ffs_data_get(struct ffs_data *ffs);
|
|
|
static void ffs_data_put(struct ffs_data *ffs);
|
|
|
/* Creates new ffs_data object. */
|
|
|
-static struct ffs_data *__must_check ffs_data_new(void) __attribute__((malloc));
|
|
|
+static struct ffs_data *__must_check ffs_data_new(const char *dev_name)
|
|
|
+ __attribute__((malloc));
|
|
|
|
|
|
/* Opened counter handling. */
|
|
|
static void ffs_data_opened(struct ffs_data *ffs);
|
|
@@ -780,11 +781,12 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
|
|
|
struct usb_request *req)
|
|
|
{
|
|
|
struct ffs_io_data *io_data = req->context;
|
|
|
+ struct ffs_data *ffs = io_data->ffs;
|
|
|
|
|
|
ENTER();
|
|
|
|
|
|
INIT_WORK(&io_data->work, ffs_user_copy_worker);
|
|
|
- schedule_work(&io_data->work);
|
|
|
+ queue_work(ffs->io_completion_wq, &io_data->work);
|
|
|
}
|
|
|
|
|
|
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,
|
|
|
if (unlikely(ret < 0))
|
|
|
return ERR_PTR(ret);
|
|
|
|
|
|
- ffs = ffs_data_new();
|
|
|
+ ffs = ffs_data_new(dev_name);
|
|
|
if (unlikely(!ffs))
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
ffs->file_perms = data.perms;
|
|
@@ -1610,6 +1612,7 @@ static void ffs_data_put(struct ffs_data *ffs)
|
|
|
BUG_ON(waitqueue_active(&ffs->ev.waitq) ||
|
|
|
waitqueue_active(&ffs->ep0req_completion.wait) ||
|
|
|
waitqueue_active(&ffs->wait));
|
|
|
+ destroy_workqueue(ffs->io_completion_wq);
|
|
|
kfree(ffs->dev_name);
|
|
|
kfree(ffs);
|
|
|
}
|
|
@@ -1642,7 +1645,7 @@ static void ffs_data_closed(struct ffs_data *ffs)
|
|
|
ffs_data_put(ffs);
|
|
|
}
|
|
|
|
|
|
-static struct ffs_data *ffs_data_new(void)
|
|
|
+static struct ffs_data *ffs_data_new(const char *dev_name)
|
|
|
{
|
|
|
struct ffs_data *ffs = kzalloc(sizeof *ffs, GFP_KERNEL);
|
|
|
if (unlikely(!ffs))
|
|
@@ -1650,6 +1653,12 @@ static struct ffs_data *ffs_data_new(void)
|
|
|
|
|
|
ENTER();
|
|
|
|
|
|
+ ffs->io_completion_wq = alloc_ordered_workqueue("%s", 0, dev_name);
|
|
|
+ if (!ffs->io_completion_wq) {
|
|
|
+ kfree(ffs);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
refcount_set(&ffs->ref, 1);
|
|
|
atomic_set(&ffs->opened, 0);
|
|
|
ffs->state = FFS_READ_DESCRIPTORS;
|