2017-11-03 11:28:30 +01:00
// SPDX-License-Identifier: GPL-2.0
2013-11-07 08:41:26 +01:00
/*
* u_f . h
*
* Utility definitions for USB functions
*
* Copyright ( c ) 2013 Samsung Electronics Co . , Ltd .
* http : //www.samsung.com
*
2018-12-13 14:24:57 +01:00
* Author : Andrzej Pietrasiewicz < andrzejtp2010 @ gmail . com >
2013-11-07 08:41:26 +01:00
*/
# ifndef __U_F_H__
# define __U_F_H__
2015-11-10 17:52:05 +00:00
# include <linux/usb/gadget.h>
2020-08-25 09:05:08 -04:00
# include <linux/overflow.h>
2015-11-10 17:52:05 +00:00
2014-05-08 14:06:21 +02:00
/* Variable Length Array Macros **********************************************/
# define vla_group(groupname) size_t groupname##__next = 0
# define vla_group_size(groupname) groupname##__next
# define vla_item(groupname, type, name, n) \
size_t groupname # # _ # # name # # __offset = ( { \
2020-08-25 09:05:08 -04:00
size_t offset = 0 ; \
if ( groupname # # __next ! = SIZE_MAX ) { \
size_t align_mask = __alignof__ ( type ) - 1 ; \
size_t size = array_size ( n , sizeof ( type ) ) ; \
2020-08-26 22:21:19 +03:00
offset = ( groupname # # __next + align_mask ) & \
~ align_mask ; \
2020-08-25 09:05:08 -04:00
if ( check_add_overflow ( offset , size , \
& groupname # # __next ) ) { \
groupname # # __next = SIZE_MAX ; \
offset = 0 ; \
} \
} \
2014-05-08 14:06:21 +02:00
offset ; \
} )
# define vla_item_with_sz(groupname, type, name, n) \
2020-08-25 09:05:08 -04:00
size_t groupname # # _ # # name # # __sz = array_size ( n , sizeof ( type ) ) ; \
size_t groupname # # _ # # name # # __offset = ( { \
size_t offset = 0 ; \
if ( groupname # # __next ! = SIZE_MAX ) { \
size_t align_mask = __alignof__ ( type ) - 1 ; \
2020-08-26 22:21:19 +03:00
offset = ( groupname # # __next + align_mask ) & \
~ align_mask ; \
2020-08-25 09:05:08 -04:00
if ( check_add_overflow ( offset , groupname # # _ # # name # # __sz , \
& groupname # # __next ) ) { \
groupname # # __next = SIZE_MAX ; \
offset = 0 ; \
} \
} \
offset ; \
2014-05-08 14:06:21 +02:00
} )
# define vla_ptr(ptr, groupname, name) \
( ( void * ) ( ( char * ) ptr + groupname # # _ # # name # # __offset ) )
2013-11-07 08:41:26 +01:00
struct usb_ep ;
struct usb_request ;
2016-08-08 21:30:06 +01:00
/**
* 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
*
* 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 ( ) .
*/
2016-08-23 18:24:49 +01:00
struct usb_request * alloc_ep_req ( struct usb_ep * ep , size_t len ) ;
2016-08-08 21:30:06 +01:00
/* Frees a usb_request previously allocated by alloc_ep_req() */
2015-11-10 17:52:05 +00:00
static inline void free_ep_req ( struct usb_ep * ep , struct usb_request * req )
{
2018-03-23 17:00:38 +00:00
WARN_ON ( req - > buf = = NULL ) ;
2015-11-10 17:52:05 +00:00
kfree ( req - > buf ) ;
2018-03-23 17:00:38 +00:00
req - > buf = NULL ;
2015-11-10 17:52:05 +00:00
usb_ep_free_request ( ep , req ) ;
}
2013-11-07 08:41:26 +01:00
# endif /* __U_F_H__ */