usb: gadget: align buffer size when allocating for OUT endpoint
authorFelipe F. Tonello <eu@felipetonello.com>
Mon, 8 Aug 2016 20:30:06 +0000 (21:30 +0100)
committerFelipe Balbi <felipe.balbi@linux.intel.com>
Thu, 25 Aug 2016 09:13:14 +0000 (12:13 +0300)
Using usb_ep_align() makes sure that the buffer size for OUT endpoints is
always aligned with wMaxPacketSize (512 usually). This makes sure
that no buffer has the wrong size, which can cause nasty bugs.

Signed-off-by: Felipe F. Tonello <eu@felipetonello.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
drivers/usb/gadget/u_f.c
drivers/usb/gadget/u_f.h

index 6811761fec647acc8a0805b2a210ce82747f65b0..907f8144813c31a467eae81b04ee6db8a8f481f2 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "u_f.h"
+#include <linux/usb/ch9.h>
 
 struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len)
 {
@@ -20,6 +21,8 @@ struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len)
        req = usb_ep_alloc_request(ep, GFP_ATOMIC);
        if (req) {
                req->length = len ?: default_len;
+               if (usb_endpoint_dir_out(ep->desc))
+                       req->length = usb_ep_align(ep, req->length);
                req->buf = kmalloc(req->length, GFP_ATOMIC);
                if (!req->buf) {
                        usb_ep_free_request(ep, req);
index 21b75710c4a4386bb0a3c76d71643f0d43b473bf..69a1d10df04f7cd66f19f8e479358f8b7e486d60 100644 (file)
 struct usb_ep;
 struct usb_request;
 
-/* Requests allocated via alloc_ep_req() must be freed by free_ep_req(). */
+/**
+ * alloc_ep_req - returns a usb_request allocated by the gadget driver and
+ * allocates the request's buffer.
+ *
+ * @ep: the endpoint to allocate a usb_request
+ * @len: usb_requests's buffer suggested size
+ * @default_len: used if @len is not provided, ie, is 0
+ *
+ * In case @ep direction is OUT, the @len will be aligned to ep's
+ * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use
+ * usb_requests's length (req->length) to refer to the allocated buffer size.
+ * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req().
+ */
 struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len, int default_len);
+
+/* Frees a usb_request previously allocated by alloc_ep_req() */
 static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
 {
        kfree(req->buf);