Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * u_f.h
0004  *
0005  * Utility definitions for USB functions
0006  *
0007  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
0008  *      http://www.samsung.com
0009  *
0010  * Author: Andrzej Pietrasiewicz <andrzejtp2010@gmail.com>
0011  */
0012 
0013 #ifndef __U_F_H__
0014 #define __U_F_H__
0015 
0016 #include <linux/usb/gadget.h>
0017 #include <linux/overflow.h>
0018 
0019 /* Variable Length Array Macros **********************************************/
0020 #define vla_group(groupname) size_t groupname##__next = 0
0021 #define vla_group_size(groupname) groupname##__next
0022 
0023 #define vla_item(groupname, type, name, n) \
0024     size_t groupname##_##name##__offset = ({                   \
0025         size_t offset = 0;                         \
0026         if (groupname##__next != SIZE_MAX) {                   \
0027             size_t align_mask = __alignof__(type) - 1;         \
0028             size_t size = array_size(n, sizeof(type));         \
0029             offset = (groupname##__next + align_mask) &        \
0030                   ~align_mask;                     \
0031             if (check_add_overflow(offset, size,               \
0032                            &groupname##__next)) {          \
0033                 groupname##__next = SIZE_MAX;              \
0034                 offset = 0;                    \
0035             }                              \
0036         }                                  \
0037         offset;                                \
0038     })
0039 
0040 #define vla_item_with_sz(groupname, type, name, n) \
0041     size_t groupname##_##name##__sz = array_size(n, sizeof(type));          \
0042     size_t groupname##_##name##__offset = ({                    \
0043         size_t offset = 0;                      \
0044         if (groupname##__next != SIZE_MAX) {                \
0045             size_t align_mask = __alignof__(type) - 1;      \
0046             offset = (groupname##__next + align_mask) &     \
0047                   ~align_mask;                  \
0048             if (check_add_overflow(offset, groupname##_##name##__sz,\
0049                             &groupname##__next)) {  \
0050                 groupname##__next = SIZE_MAX;           \
0051                 offset = 0;                 \
0052             }                           \
0053         }                               \
0054         offset;                             \
0055     })
0056 
0057 #define vla_ptr(ptr, groupname, name) \
0058     ((void *) ((char *)ptr + groupname##_##name##__offset))
0059 
0060 struct usb_ep;
0061 struct usb_request;
0062 
0063 /**
0064  * alloc_ep_req - returns a usb_request allocated by the gadget driver and
0065  * allocates the request's buffer.
0066  *
0067  * @ep: the endpoint to allocate a usb_request
0068  * @len: usb_requests's buffer suggested size
0069  *
0070  * In case @ep direction is OUT, the @len will be aligned to ep's
0071  * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use
0072  * usb_requests's length (req->length) to refer to the allocated buffer size.
0073  * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req().
0074  */
0075 struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len);
0076 
0077 /* Frees a usb_request previously allocated by alloc_ep_req() */
0078 static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
0079 {
0080     WARN_ON(req->buf == NULL);
0081     kfree(req->buf);
0082     req->buf = NULL;
0083     usb_ep_free_request(ep, req);
0084 }
0085 
0086 #endif /* __U_F_H__ */