greybus: prepend cport byte for all gbufs
authorAlex Elder <elder@linaro.org>
Tue, 18 Nov 2014 19:26:39 +0000 (13:26 -0600)
committerGreg Kroah-Hartman <greg@kroah.com>
Tue, 18 Nov 2014 20:46:15 +0000 (12:46 -0800)
Treat communication buffers for both inbound and outbound data the
same way, prepending a "destination cport id" byte before the data
in the buffer.  Currently this is done only for outbound data
buffers.

This isn't needed for inbound data, but handling it this way
allows the free routine to work without knowing whether the
buffer was used for sending or receiving.

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

index e276f0c4e3cdb0bdc98fa3435064cd0ae0043168..062fb1a818baadeae0116221a11b730a22226ad3 100644 (file)
@@ -96,7 +96,7 @@ static void cport_out_callback(struct urb *urb);
 static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size,
                                gfp_t gfp_mask)
 {
-       u32 cport_reserve = gbuf->dest_cport_id == CPORT_ID_BAD ? 0 : 1;
+       u8 dest_cport_id = gbuf->dest_cport_id;
        u8 *buffer;
 
        if (gbuf->transfer_buffer)
@@ -107,29 +107,29 @@ static int alloc_gbuf_data(struct gbuf *gbuf, unsigned int size,
                       ES1_GBUF_MSG_SIZE);
        }
 
-       /* For ES2 we need to figure out what cport is going to what endpoint,
-        * but for ES1, it's so dirt simple, we don't have a choice...
+       /*
+        * For ES1 we need to insert a byte at the front of the data
+        * to indicate the destination CPort id.  So we allocate one
+        * extra byte to allow for that.
         *
-        * Also, do a "slow" allocation now, if we need speed, use a cache
+        * This is only needed for outbound data, but we handle
+        * buffers for inbound data the same way for consistency.
         *
-        * For ES1 outbound buffers need to insert their target
-        * CPort Id before the data; set aside an extra byte for
-        * that purpose in that case.
+        * XXX Do we need to indicate the destination device id too?
         */
-       buffer = kzalloc(cport_reserve + size, gfp_mask);
+       buffer = kzalloc(1 + size, gfp_mask);
        if (!buffer)
                return -ENOMEM;
 
        /* Insert the cport id for outbound buffers */
-       if (cport_reserve) {
-               if (gbuf->dest_cport_id > (u16)U8_MAX) {
-                       pr_err("gbuf->dest_cport_id (%hd) is out of range!\n",
-                               gbuf->dest_cport_id);
-                       kfree(buffer);
-                       return -EINVAL;
-               }
-               *buffer++ = gbuf->dest_cport_id;
+       if (dest_cport_id != CPORT_ID_BAD && dest_cport_id > (u16)U8_MAX) {
+               pr_err("dest_cport_id (%hd) is out of range!\n",
+                       gbuf->dest_cport_id);
+               kfree(buffer);
+               return -EINVAL;
        }
+       *buffer++ = gbuf->dest_cport_id;
+
        gbuf->transfer_buffer = buffer;
        gbuf->transfer_buffer_length = size;
 
@@ -145,9 +145,8 @@ static void free_gbuf_data(struct gbuf *gbuf)
        if (!transfer_buffer)
                return;
 
-       /* Account for the cport id in outbound buffers */
-       if (gbuf->dest_cport_id != CPORT_ID_BAD)
-               transfer_buffer--;      /* Back up to cport id */
+       /* Account for the prepended cport id */
+       transfer_buffer--;
        kfree(transfer_buffer);
        gbuf->transfer_buffer = NULL;
 }
@@ -222,6 +221,12 @@ static int submit_gbuf(struct gbuf *gbuf, gfp_t gfp_mask)
                return -EINVAL;
        buffer = &transfer_buffer[-1];  /* yes, we mean -1 */
 
+       /* Do one last check of the target CPort id */
+       if (*buffer == CPORT_ID_BAD) {
+               pr_err("request to submit inbound buffer\n");
+               return -EINVAL;
+       }
+
        /* Find a free urb */
        urb = next_free_urb(es1, gfp_mask);
        if (!urb)