]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
greybus: gbuf: implement gbuf_kill_gbuf()
authorGreg Kroah-Hartman <greg@kroah.com>
Mon, 27 Oct 2014 05:31:01 +0000 (13:31 +0800)
committerGreg Kroah-Hartman <greg@kroah.com>
Mon, 27 Oct 2014 05:45:24 +0000 (13:45 +0800)
Hook up gbuf_kill_gbuf() by implementing yet-another-host-controller
callback and a gbuf-specific pointer to hold the tracking data the hcd
needs in order to be able to abort a transfer.

Signed-off-by: Greg Kroah-Hartman <greg@kroah.com>
Reviewed-by: Alex Elder <elder@linaro.org>
drivers/staging/greybus/es1-ap-usb.c
drivers/staging/greybus/gbuf.c
drivers/staging/greybus/greybus.h

index bd416b4849bd68a44103d7bac9a69a174f7928a0..a2072944325df30e44068e898e0ed4850dc2c50d 100644 (file)
@@ -224,6 +224,8 @@ static int submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
        if (!urb)
                return -ENOMEM;
 
+       gbuf->hcd_data = urb;
+
        usb_fill_bulk_urb(urb, udev,
                          usb_sndbulkpipe(udev, es1->cport_out_endpoint),
                          buffer, gbuf->transfer_buffer_length + 1,
@@ -232,12 +234,24 @@ static int submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
        return retval;
 }
 
+static int abort_gbuf(struct gbuf *gbuf)
+{
+       struct urb *urb = gbuf->hcd_data;
+
+       if (!urb)
+               return -EINVAL;
+
+       usb_kill_urb(urb);
+       return 0;
+}
+
 static struct greybus_host_driver es1_driver = {
        .hd_priv_size           = sizeof(struct es1_ap_dev),
        .alloc_gbuf_data        = alloc_gbuf_data,
        .free_gbuf_data         = free_gbuf_data,
        .submit_svc             = submit_svc,
        .submit_gbuf            = submit_gbuf,
+       .abort_gbuf             = abort_gbuf,
 };
 
 /* Common function to report consistent warnings based on URB status */
@@ -387,6 +401,7 @@ static void cport_out_callback(struct urb *urb)
 
        /* Record whether the transfer was successful */
        gbuf->status = check_urb_status(urb);
+       gbuf->hcd_data = NULL;
 
        /*
         * See if this was an urb in our pool, if so mark it "free", otherwise
index 9b435af27cca297e0ce046b8af43ba02f098d84e..726a1f4bac41d9f4fef53a6e501d65eae66e774e 100644 (file)
@@ -106,8 +106,12 @@ int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
 
 int greybus_kill_gbuf(struct gbuf *gbuf)
 {
-       // FIXME - implement
-       return -ENOMEM;
+       struct greybus_host_device *hd = gbuf->connection->hd;
+
+       if (gbuf->status != -EINPROGRESS)
+               return -EINVAL;
+
+       return hd->driver->abort_gbuf(gbuf);
 }
 
 #define MAX_CPORTS     1024
index f287f3b0a3e553b2ddfcd760706f4b53eb14e75f..8b6ea0544598dd994895dffdf9f70a2309256b74 100644 (file)
@@ -134,6 +134,7 @@ struct gbuf {
        bool outbound;                  /* AP-relative data direction */
 
        void *context;
+       void *hcd_data;                 /* for the HCD to track the gbuf */
        gbuf_complete_t complete;
 };
 
@@ -169,6 +170,7 @@ struct greybus_host_driver {
        int (*submit_svc)(struct svc_msg *svc_msg,
                            struct greybus_host_device *hd);
        int (*submit_gbuf)(struct gbuf *gbuf, gfp_t gfp_mask);
+       int (*abort_gbuf)(struct gbuf *gbuf);
 };
 
 struct greybus_host_device {