|
@@ -215,6 +215,7 @@ struct ffs_io_data {
|
|
|
|
|
|
struct mm_struct *mm;
|
|
|
struct work_struct work;
|
|
|
+ struct work_struct cancellation_work;
|
|
|
|
|
|
struct usb_ep *ep;
|
|
|
struct usb_request *req;
|
|
@@ -1072,22 +1073,31 @@ ffs_epfile_open(struct inode *inode, struct file *file)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static void ffs_aio_cancel_worker(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct ffs_io_data *io_data = container_of(work, struct ffs_io_data,
|
|
|
+ cancellation_work);
|
|
|
+
|
|
|
+ ENTER();
|
|
|
+
|
|
|
+ usb_ep_dequeue(io_data->ep, io_data->req);
|
|
|
+}
|
|
|
+
|
|
|
static int ffs_aio_cancel(struct kiocb *kiocb)
|
|
|
{
|
|
|
struct ffs_io_data *io_data = kiocb->private;
|
|
|
- struct ffs_epfile *epfile = kiocb->ki_filp->private_data;
|
|
|
+ struct ffs_data *ffs = io_data->ffs;
|
|
|
int value;
|
|
|
|
|
|
ENTER();
|
|
|
|
|
|
- spin_lock_irq(&epfile->ffs->eps_lock);
|
|
|
-
|
|
|
- if (likely(io_data && io_data->ep && io_data->req))
|
|
|
- value = usb_ep_dequeue(io_data->ep, io_data->req);
|
|
|
- else
|
|
|
+ if (likely(io_data && io_data->ep && io_data->req)) {
|
|
|
+ INIT_WORK(&io_data->cancellation_work, ffs_aio_cancel_worker);
|
|
|
+ queue_work(ffs->io_completion_wq, &io_data->cancellation_work);
|
|
|
+ value = -EINPROGRESS;
|
|
|
+ } else {
|
|
|
value = -EINVAL;
|
|
|
-
|
|
|
- spin_unlock_irq(&epfile->ffs->eps_lock);
|
|
|
+ }
|
|
|
|
|
|
return value;
|
|
|
}
|