xref: /openbmc/linux/drivers/usb/gadget/u_f.h (revision aadbe812)
11efd54eaSAndrzej Pietrasiewicz /*
21efd54eaSAndrzej Pietrasiewicz  * u_f.h
31efd54eaSAndrzej Pietrasiewicz  *
41efd54eaSAndrzej Pietrasiewicz  * Utility definitions for USB functions
51efd54eaSAndrzej Pietrasiewicz  *
61efd54eaSAndrzej Pietrasiewicz  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
71efd54eaSAndrzej Pietrasiewicz  *		http://www.samsung.com
81efd54eaSAndrzej Pietrasiewicz  *
91efd54eaSAndrzej Pietrasiewicz  * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
101efd54eaSAndrzej Pietrasiewicz  *
111efd54eaSAndrzej Pietrasiewicz  * This program is free software; you can redistribute it and/or modify
121efd54eaSAndrzej Pietrasiewicz  * it under the terms of the GNU General Public License version 2 as
131efd54eaSAndrzej Pietrasiewicz  * published by the Free Software Foundation.
141efd54eaSAndrzej Pietrasiewicz  */
151efd54eaSAndrzej Pietrasiewicz 
161efd54eaSAndrzej Pietrasiewicz #ifndef __U_F_H__
171efd54eaSAndrzej Pietrasiewicz #define __U_F_H__
181efd54eaSAndrzej Pietrasiewicz 
19079fe5a6SFelipe F. Tonello #include <linux/usb/gadget.h>
20079fe5a6SFelipe F. Tonello 
2174d48466SAndrzej Pietrasiewicz /* Variable Length Array Macros **********************************************/
2274d48466SAndrzej Pietrasiewicz #define vla_group(groupname) size_t groupname##__next = 0
2374d48466SAndrzej Pietrasiewicz #define vla_group_size(groupname) groupname##__next
2474d48466SAndrzej Pietrasiewicz 
2574d48466SAndrzej Pietrasiewicz #define vla_item(groupname, type, name, n) \
2674d48466SAndrzej Pietrasiewicz 	size_t groupname##_##name##__offset = ({			       \
2774d48466SAndrzej Pietrasiewicz 		size_t align_mask = __alignof__(type) - 1;		       \
2874d48466SAndrzej Pietrasiewicz 		size_t offset = (groupname##__next + align_mask) & ~align_mask;\
2974d48466SAndrzej Pietrasiewicz 		size_t size = (n) * sizeof(type);			       \
3074d48466SAndrzej Pietrasiewicz 		groupname##__next = offset + size;			       \
3174d48466SAndrzej Pietrasiewicz 		offset;							       \
3274d48466SAndrzej Pietrasiewicz 	})
3374d48466SAndrzej Pietrasiewicz 
3474d48466SAndrzej Pietrasiewicz #define vla_item_with_sz(groupname, type, name, n) \
3574d48466SAndrzej Pietrasiewicz 	size_t groupname##_##name##__sz = (n) * sizeof(type);		       \
3674d48466SAndrzej Pietrasiewicz 	size_t groupname##_##name##__offset = ({			       \
3774d48466SAndrzej Pietrasiewicz 		size_t align_mask = __alignof__(type) - 1;		       \
3874d48466SAndrzej Pietrasiewicz 		size_t offset = (groupname##__next + align_mask) & ~align_mask;\
3974d48466SAndrzej Pietrasiewicz 		size_t size = groupname##_##name##__sz;			       \
4074d48466SAndrzej Pietrasiewicz 		groupname##__next = offset + size;			       \
4174d48466SAndrzej Pietrasiewicz 		offset;							       \
4274d48466SAndrzej Pietrasiewicz 	})
4374d48466SAndrzej Pietrasiewicz 
4474d48466SAndrzej Pietrasiewicz #define vla_ptr(ptr, groupname, name) \
4574d48466SAndrzej Pietrasiewicz 	((void *) ((char *)ptr + groupname##_##name##__offset))
4674d48466SAndrzej Pietrasiewicz 
471efd54eaSAndrzej Pietrasiewicz struct usb_ep;
481efd54eaSAndrzej Pietrasiewicz struct usb_request;
491efd54eaSAndrzej Pietrasiewicz 
50e0466156SFelipe F. Tonello /**
51e0466156SFelipe F. Tonello  * alloc_ep_req - returns a usb_request allocated by the gadget driver and
52e0466156SFelipe F. Tonello  * allocates the request's buffer.
53e0466156SFelipe F. Tonello  *
54e0466156SFelipe F. Tonello  * @ep: the endpoint to allocate a usb_request
55e0466156SFelipe F. Tonello  * @len: usb_requests's buffer suggested size
56e0466156SFelipe F. Tonello  *
57e0466156SFelipe F. Tonello  * In case @ep direction is OUT, the @len will be aligned to ep's
58e0466156SFelipe F. Tonello  * wMaxPacketSize. In order to avoid memory leaks or drops, *always* use
59e0466156SFelipe F. Tonello  * usb_requests's length (req->length) to refer to the allocated buffer size.
60e0466156SFelipe F. Tonello  * Requests allocated via alloc_ep_req() *must* be freed by free_ep_req().
61e0466156SFelipe F. Tonello  */
62aadbe812SFelipe F. Tonello struct usb_request *alloc_ep_req(struct usb_ep *ep, size_t len);
63e0466156SFelipe F. Tonello 
64e0466156SFelipe F. Tonello /* Frees a usb_request previously allocated by alloc_ep_req() */
65079fe5a6SFelipe F. Tonello static inline void free_ep_req(struct usb_ep *ep, struct usb_request *req)
66079fe5a6SFelipe F. Tonello {
67079fe5a6SFelipe F. Tonello 	kfree(req->buf);
68079fe5a6SFelipe F. Tonello 	usb_ep_free_request(ep, req);
69079fe5a6SFelipe F. Tonello }
701efd54eaSAndrzej Pietrasiewicz 
711efd54eaSAndrzej Pietrasiewicz #endif /* __U_F_H__ */
72