2017-11-07 16:58:41 +03:00
// SPDX-License-Identifier: GPL-2.0
2014-10-02 06:54:16 +04:00
/*
2015-04-01 18:02:02 +03:00
* Greybus manifest parsing
2014-10-02 06:54:16 +04:00
*
2015-03-27 23:06:24 +03:00
* Copyright 2014 - 2015 Google Inc .
* Copyright 2014 - 2015 Linaro Ltd .
2014-10-02 06:54:16 +04:00
*/
2019-08-25 08:54:27 +03:00
# include <linux/greybus.h>
2014-10-02 06:54:16 +04:00
2015-03-24 14:38:13 +03:00
static const char * get_descriptor_type_string ( u8 type )
{
2016-09-27 12:42:08 +03:00
switch ( type ) {
2015-03-24 14:38:13 +03:00
case GREYBUS_TYPE_INVALID :
return " invalid " ;
case GREYBUS_TYPE_STRING :
return " string " ;
case GREYBUS_TYPE_INTERFACE :
return " interface " ;
case GREYBUS_TYPE_CPORT :
return " cport " ;
2015-04-01 18:01:59 +03:00
case GREYBUS_TYPE_BUNDLE :
return " bundle " ;
2015-03-24 14:38:13 +03:00
default :
WARN_ON ( 1 ) ;
return " unknown " ;
}
}
2014-10-02 06:54:16 +04:00
/*
* We scan the manifest once to identify where all the descriptors
* are . The result is a list of these manifest_desc structures . We
* then pick through them for what we ' re looking for ( starting with
2015-04-01 18:02:02 +03:00
* the interface descriptor ) . As each is processed we remove it from
2014-10-02 06:54:16 +04:00
* the list . When we ' re done the list should ( probably ) be empty .
*/
struct manifest_desc {
struct list_head links ;
size_t size ;
void * data ;
enum greybus_descriptor_type type ;
} ;
static void release_manifest_descriptor ( struct manifest_desc * descriptor )
{
list_del ( & descriptor - > links ) ;
kfree ( descriptor ) ;
}
2014-12-24 02:16:50 +03:00
static void release_manifest_descriptors ( struct gb_interface * intf )
2014-10-02 06:54:16 +04:00
{
struct manifest_desc * descriptor ;
struct manifest_desc * next ;
2014-12-24 02:16:50 +03:00
list_for_each_entry_safe ( descriptor , next , & intf - > manifest_descs , links )
2014-10-02 06:54:16 +04:00
release_manifest_descriptor ( descriptor ) ;
}
2015-11-25 17:59:25 +03:00
static void release_cport_descriptors ( struct list_head * head , u8 bundle_id )
{
struct manifest_desc * desc , * tmp ;
struct greybus_descriptor_cport * desc_cport ;
list_for_each_entry_safe ( desc , tmp , head , links ) {
desc_cport = desc - > data ;
if ( desc - > type ! = GREYBUS_TYPE_CPORT )
continue ;
if ( desc_cport - > bundle = = bundle_id )
release_manifest_descriptor ( desc ) ;
}
}
2015-11-16 22:23:25 +03:00
static struct manifest_desc * get_next_bundle_desc ( struct gb_interface * intf )
{
struct manifest_desc * descriptor ;
struct manifest_desc * next ;
list_for_each_entry_safe ( descriptor , next , & intf - > manifest_descs , links )
if ( descriptor - > type = = GREYBUS_TYPE_BUNDLE )
return descriptor ;
return NULL ;
}
2014-10-02 06:54:16 +04:00
/*
* Validate the given descriptor . Its reported size must fit within
2014-11-21 08:56:30 +03:00
* the number of bytes remaining , and it must have a recognized
2014-10-02 06:54:16 +04:00
* type . Check that the reported size is at least as big as what
* we expect to see . ( It could be bigger , perhaps for a new version
* of the format . )
*
2015-06-10 01:42:53 +03:00
* Returns the ( non - zero ) number of bytes consumed by the descriptor ,
* or a negative errno .
2014-10-02 06:54:16 +04:00
*/
2014-12-24 02:16:50 +03:00
static int identify_descriptor ( struct gb_interface * intf ,
struct greybus_descriptor * desc , size_t size )
2014-10-02 06:54:16 +04:00
{
struct greybus_descriptor_header * desc_header = & desc - > header ;
struct manifest_desc * descriptor ;
2015-03-27 23:06:24 +03:00
size_t desc_size ;
2014-10-02 06:54:16 +04:00
size_t expected_size ;
if ( size < sizeof ( * desc_header ) ) {
2019-08-25 08:54:24 +03:00
dev_err ( & intf - > dev , " manifest too small (%zu < %zu) \n " , size ,
sizeof ( * desc_header ) ) ;
2014-10-02 06:54:16 +04:00
return - EINVAL ; /* Must at least have header */
}
2015-03-27 23:06:24 +03:00
desc_size = le16_to_cpu ( desc_header - > size ) ;
if ( desc_size > size ) {
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " descriptor too big (%zu > %zu) \n " ,
2019-08-25 08:54:24 +03:00
desc_size , size ) ;
2014-10-02 06:54:16 +04:00
return - EINVAL ;
}
2015-03-24 14:38:13 +03:00
/* Descriptor needs to at least have a header */
expected_size = sizeof ( * desc_header ) ;
2014-10-02 06:54:16 +04:00
switch ( desc_header - > type ) {
case GREYBUS_TYPE_STRING :
expected_size + = sizeof ( struct greybus_descriptor_string ) ;
2015-03-24 14:38:13 +03:00
expected_size + = desc - > string . length ;
2015-04-28 17:21:35 +03:00
/* String descriptors are padded to 4 byte boundaries */
expected_size = ALIGN ( expected_size , 4 ) ;
2014-10-02 06:54:16 +04:00
break ;
2014-10-02 21:30:02 +04:00
case GREYBUS_TYPE_INTERFACE :
2015-04-01 18:02:02 +03:00
expected_size + = sizeof ( struct greybus_descriptor_interface ) ;
2014-10-02 21:30:02 +04:00
break ;
2015-04-01 18:02:00 +03:00
case GREYBUS_TYPE_BUNDLE :
expected_size + = sizeof ( struct greybus_descriptor_bundle ) ;
break ;
2014-10-02 06:54:16 +04:00
case GREYBUS_TYPE_CPORT :
2015-03-24 14:38:13 +03:00
expected_size + = sizeof ( struct greybus_descriptor_cport ) ;
2014-10-02 06:54:16 +04:00
break ;
case GREYBUS_TYPE_INVALID :
default :
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " invalid descriptor type (%u) \n " ,
2019-08-25 08:54:24 +03:00
desc_header - > type ) ;
2014-10-02 06:54:16 +04:00
return - EINVAL ;
}
2015-03-24 14:38:13 +03:00
if ( desc_size < expected_size ) {
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " %s descriptor too small (%zu < %zu) \n " ,
2019-08-25 08:54:24 +03:00
get_descriptor_type_string ( desc_header - > type ) ,
desc_size , expected_size ) ;
2015-03-24 14:38:13 +03:00
return - EINVAL ;
}
2015-04-29 08:32:08 +03:00
/* Descriptor bigger than what we expect */
if ( desc_size > expected_size ) {
2016-02-11 15:52:46 +03:00
dev_warn ( & intf - > dev , " %s descriptor size mismatch (want %zu got %zu) \n " ,
2019-08-25 08:54:24 +03:00
get_descriptor_type_string ( desc_header - > type ) ,
expected_size , desc_size ) ;
2015-04-29 08:32:08 +03:00
}
2014-10-02 06:54:16 +04:00
descriptor = kzalloc ( sizeof ( * descriptor ) , GFP_KERNEL ) ;
if ( ! descriptor )
return - ENOMEM ;
descriptor - > size = desc_size ;
2015-06-10 01:42:53 +03:00
descriptor - > data = ( char * ) desc + sizeof ( * desc_header ) ;
2014-10-02 06:54:16 +04:00
descriptor - > type = desc_header - > type ;
2014-12-24 02:16:50 +03:00
list_add_tail ( & descriptor - > links , & intf - > manifest_descs ) ;
2014-10-02 06:54:16 +04:00
2015-06-10 01:42:53 +03:00
/* desc_size is positive and is known to fit in a signed int */
2015-03-27 23:06:24 +03:00
2014-10-02 06:54:16 +04:00
return desc_size ;
}
/*
* Find the string descriptor having the given id , validate it , and
* allocate a duplicate copy of it . The duplicate has an extra byte
* which guarantees the returned string is NUL - terminated .
*
* String index 0 is valid ( it represents " no string " ) , and for
* that a null pointer is returned .
*
* Otherwise returns a pointer to a newly - allocated copy of the
* descriptor string , or an error - coded pointer on failure .
*/
2014-12-24 02:16:50 +03:00
static char * gb_string_get ( struct gb_interface * intf , u8 string_id )
2014-10-02 06:54:16 +04:00
{
struct greybus_descriptor_string * desc_string ;
struct manifest_desc * descriptor ;
bool found = false ;
char * string ;
/* A zero string id means no string (but no error) */
if ( ! string_id )
return NULL ;
2014-12-24 02:16:50 +03:00
list_for_each_entry ( descriptor , & intf - > manifest_descs , links ) {
2014-10-02 06:54:16 +04:00
if ( descriptor - > type ! = GREYBUS_TYPE_STRING )
continue ;
2014-10-06 17:58:44 +04:00
desc_string = descriptor - > data ;
2014-10-02 06:54:16 +04:00
if ( desc_string - > id = = string_id ) {
found = true ;
break ;
}
}
if ( ! found )
return ERR_PTR ( - ENOENT ) ;
/* Allocate an extra byte so we can guarantee it's NUL-terminated */
2015-06-10 01:42:53 +03:00
string = kmemdup ( & desc_string - > string , desc_string - > length + 1 ,
2019-08-25 08:54:24 +03:00
GFP_KERNEL ) ;
2014-10-02 06:54:16 +04:00
if ( ! string )
return ERR_PTR ( - ENOMEM ) ;
string [ desc_string - > length ] = ' \0 ' ;
/* Ok we've used this string, so we're done with it */
release_manifest_descriptor ( descriptor ) ;
return string ;
}
2014-10-02 06:54:18 +04:00
/*
2015-06-10 01:42:53 +03:00
* Find cport descriptors in the manifest associated with the given
* bundle , and set up data structures for the functions that use
* them . Returns the number of cports set up for the bundle , or 0
* if there is an error .
2014-10-02 06:54:18 +04:00
*/
2015-06-10 01:42:54 +03:00
static u32 gb_manifest_parse_cports ( struct gb_bundle * bundle )
2014-10-02 06:54:18 +04:00
{
2015-06-10 01:42:54 +03:00
struct gb_interface * intf = bundle - > intf ;
2016-01-21 19:34:09 +03:00
struct greybus_descriptor_cport * desc_cport ;
2016-01-21 19:34:10 +03:00
struct manifest_desc * desc , * next , * tmp ;
2016-01-21 19:34:09 +03:00
LIST_HEAD ( list ) ;
2015-06-10 01:42:55 +03:00
u8 bundle_id = bundle - > id ;
2015-07-21 11:10:27 +03:00
u16 cport_id ;
2014-10-02 06:54:18 +04:00
u32 count = 0 ;
2016-01-21 19:34:09 +03:00
int i ;
2014-10-02 06:54:18 +04:00
2015-06-10 01:42:55 +03:00
/* Set up all cport descriptors associated with this bundle */
list_for_each_entry_safe ( desc , next , & intf - > manifest_descs , links ) {
if ( desc - > type ! = GREYBUS_TYPE_CPORT )
continue ;
desc_cport = desc - > data ;
if ( desc_cport - > bundle ! = bundle_id )
continue ;
2014-10-02 06:54:18 +04:00
2015-06-13 19:02:09 +03:00
cport_id = le16_to_cpu ( desc_cport - > id ) ;
if ( cport_id > CPORT_ID_MAX )
2015-07-21 11:10:27 +03:00
goto exit ;
2015-06-13 19:02:09 +03:00
2016-06-11 05:31:01 +03:00
/* Nothing else should have its cport_id as control cport id */
if ( cport_id = = GB_CONTROL_CPORT_ID ) {
dev_err ( & bundle - > dev , " invalid cport id found (%02u) \n " ,
cport_id ) ;
goto exit ;
}
2016-01-21 19:34:10 +03:00
/*
* Found one , move it to our temporary list after checking for
* duplicates .
*/
list_for_each_entry ( tmp , & list , links ) {
desc_cport = tmp - > data ;
2016-02-03 08:31:19 +03:00
if ( cport_id = = le16_to_cpu ( desc_cport - > id ) ) {
2016-01-21 19:34:10 +03:00
dev_err ( & bundle - > dev ,
2019-08-25 08:54:24 +03:00
" duplicate CPort %u found \n " , cport_id ) ;
2016-01-21 19:34:10 +03:00
goto exit ;
}
}
2016-02-12 19:18:03 +03:00
list_move_tail ( & desc - > links , & list ) ;
2016-01-21 19:34:09 +03:00
count + + ;
}
2015-06-22 14:12:30 +03:00
2016-01-21 19:34:09 +03:00
if ( ! count )
return 0 ;
2014-10-02 06:54:18 +04:00
2016-01-21 19:34:09 +03:00
bundle - > cport_desc = kcalloc ( count , sizeof ( * bundle - > cport_desc ) ,
2019-08-25 08:54:24 +03:00
GFP_KERNEL ) ;
2016-01-21 19:34:09 +03:00
if ( ! bundle - > cport_desc )
goto exit ;
bundle - > num_cports = count ;
i = 0 ;
list_for_each_entry_safe ( desc , next , & list , links ) {
desc_cport = desc - > data ;
memcpy ( & bundle - > cport_desc [ i + + ] , desc_cport ,
2019-08-25 08:54:24 +03:00
sizeof ( * desc_cport ) ) ;
2015-06-10 01:42:55 +03:00
2014-10-02 06:54:18 +04:00
/* Release the cport descriptor */
2015-06-10 01:42:55 +03:00
release_manifest_descriptor ( desc ) ;
2014-10-02 06:54:18 +04:00
}
return count ;
2015-07-21 11:10:27 +03:00
exit :
2016-01-21 19:34:09 +03:00
release_cport_descriptors ( & list , bundle_id ) ;
2015-09-07 13:31:20 +03:00
/*
* Free all cports for this bundle to avoid ' excess descriptors '
* warnings .
*/
2015-11-25 17:59:25 +03:00
release_cport_descriptors ( & intf - > manifest_descs , bundle_id ) ;
2015-09-07 13:31:20 +03:00
2015-06-12 18:21:09 +03:00
return 0 ; /* Error; count should also be 0 */
2014-10-02 06:54:18 +04:00
}
2014-10-02 06:54:17 +04:00
/*
2014-12-13 01:10:17 +03:00
* Find bundle descriptors in the manifest and set up their data
* structures . Returns the number of bundles set up for the
2015-04-01 18:02:00 +03:00
* given interface .
2014-10-02 06:54:17 +04:00
*/
2014-12-20 01:56:31 +03:00
static u32 gb_manifest_parse_bundles ( struct gb_interface * intf )
2014-10-02 06:54:17 +04:00
{
2015-06-10 01:42:56 +03:00
struct manifest_desc * desc ;
2015-06-12 18:21:12 +03:00
struct gb_bundle * bundle ;
struct gb_bundle * bundle_next ;
2014-10-02 06:54:17 +04:00
u32 count = 0 ;
2015-09-07 13:31:19 +03:00
u8 bundle_id ;
2015-11-25 17:59:26 +03:00
u8 class ;
2014-10-02 06:54:17 +04:00
2015-11-16 22:23:25 +03:00
while ( ( desc = get_next_bundle_desc ( intf ) ) ) {
2015-04-01 18:02:00 +03:00
struct greybus_descriptor_bundle * desc_bundle ;
2015-06-10 01:42:56 +03:00
2014-12-13 01:10:17 +03:00
/* Found one. Set up its bundle structure*/
2015-06-10 01:42:56 +03:00
desc_bundle = desc - > data ;
2015-09-07 13:31:19 +03:00
bundle_id = desc_bundle - > id ;
2015-11-25 17:59:26 +03:00
class = desc_bundle - > class ;
/* Done with this bundle descriptor */
release_manifest_descriptor ( desc ) ;
2015-06-22 14:12:27 +03:00
2015-11-25 17:59:26 +03:00
/* Ignore any legacy control bundles */
2015-09-07 13:31:19 +03:00
if ( bundle_id = = GB_CONTROL_BUNDLE_ID ) {
2015-11-25 17:59:26 +03:00
dev_dbg ( & intf - > dev , " %s - ignoring control bundle \n " ,
2019-08-25 08:54:24 +03:00
__func__ ) ;
2015-11-25 17:59:26 +03:00
release_cport_descriptors ( & intf - > manifest_descs ,
2019-08-25 08:54:24 +03:00
bundle_id ) ;
2015-11-25 17:59:26 +03:00
continue ;
2015-06-22 14:12:27 +03:00
}
2015-06-22 14:12:30 +03:00
/* Nothing else should have its class set to control class */
2015-11-25 17:59:26 +03:00
if ( class = = GREYBUS_CLASS_CONTROL ) {
2015-07-21 11:10:27 +03:00
dev_err ( & intf - > dev ,
2015-12-07 17:05:38 +03:00
" bundle %u cannot use control class \n " ,
2015-09-07 13:31:19 +03:00
bundle_id ) ;
2015-07-21 11:10:27 +03:00
goto cleanup ;
}
2015-06-22 14:12:30 +03:00
2015-11-25 17:59:26 +03:00
bundle = gb_bundle_create ( intf , bundle_id , class ) ;
2014-12-13 01:10:17 +03:00
if ( ! bundle )
2015-06-12 18:21:12 +03:00
goto cleanup ;
2014-10-02 06:54:18 +04:00
2015-09-07 13:31:19 +03:00
/*
* Now go set up this bundle ' s functions and cports .
*
* A ' bundle ' represents a device in greybus . It may require
* multiple cports for its functioning . If we fail to setup any
* cport of a bundle , we better reject the complete bundle as
* the device may not be able to function properly then .
*
* But , failing to setup a cport of bundle X doesn ' t mean that
* the device corresponding to bundle Y will not work properly .
* Bundles should be treated as separate independent devices .
*
* While parsing manifest for an interface , treat bundles as
* separate entities and don ' t reject entire interface and its
* bundles on failing to initialize a cport . But make sure the
* bundle which needs the cport , gets destroyed properly .
*/
if ( ! gb_manifest_parse_cports ( bundle ) ) {
gb_bundle_destroy ( bundle ) ;
continue ;
}
2015-07-21 11:10:27 +03:00
count + + ;
2014-10-02 06:54:17 +04:00
}
return count ;
2015-06-12 18:21:12 +03:00
cleanup :
/* An error occurred; undo any changes we've made */
list_for_each_entry_safe ( bundle , bundle_next , & intf - > bundles , links ) {
gb_bundle_destroy ( bundle ) ;
count - - ;
}
return 0 ; /* Error; count should also be 0 */
2014-10-02 06:54:17 +04:00
}
2015-04-01 18:02:02 +03:00
static bool gb_manifest_parse_interface ( struct gb_interface * intf ,
struct manifest_desc * interface_desc )
2014-10-02 06:54:16 +04:00
{
2015-04-01 18:02:02 +03:00
struct greybus_descriptor_interface * desc_intf = interface_desc - > data ;
2016-04-13 20:19:04 +03:00
struct gb_control * control = intf - > control ;
2016-04-13 20:18:55 +03:00
char * str ;
2014-10-02 06:54:16 +04:00
/* Handle the strings first--they can fail */
2016-04-13 20:18:55 +03:00
str = gb_string_get ( intf , desc_intf - > vendor_stringid ) ;
if ( IS_ERR ( str ) )
2014-10-03 23:14:25 +04:00
return false ;
2016-04-13 20:19:04 +03:00
control - > vendor_string = str ;
2014-10-03 23:14:25 +04:00
2016-04-13 20:18:55 +03:00
str = gb_string_get ( intf , desc_intf - > product_stringid ) ;
if ( IS_ERR ( str ) )
2014-11-13 15:44:32 +03:00
goto out_free_vendor_string ;
2016-04-13 20:19:04 +03:00
control - > product_string = str ;
2014-10-02 06:54:16 +04:00
2016-05-15 21:37:49 +03:00
/* Assign feature flags communicated via manifest */
intf - > features = desc_intf - > features ;
2015-04-01 18:02:02 +03:00
/* Release the interface descriptor, now that we're done with it */
release_manifest_descriptor ( interface_desc ) ;
2014-10-02 06:54:16 +04:00
2014-12-13 01:10:17 +03:00
/* An interface must have at least one bundle descriptor */
2014-12-20 01:56:31 +03:00
if ( ! gb_manifest_parse_bundles ( intf ) ) {
2015-07-21 11:10:28 +03:00
dev_err ( & intf - > dev , " manifest bundle descriptors not valid \n " ) ;
2014-10-03 23:14:25 +04:00
goto out_err ;
2014-10-02 06:54:17 +04:00
}
2014-10-03 23:14:25 +04:00
return true ;
out_err :
2016-04-13 20:19:04 +03:00
kfree ( control - > product_string ) ;
control - > product_string = NULL ;
2014-11-13 15:44:32 +03:00
out_free_vendor_string :
2016-04-13 20:19:04 +03:00
kfree ( control - > vendor_string ) ;
control - > vendor_string = NULL ;
2014-10-03 23:14:25 +04:00
return false ;
2014-10-02 06:54:16 +04:00
}
/*
2015-06-10 01:42:53 +03:00
* Parse a buffer containing an interface manifest .
2014-10-02 06:54:16 +04:00
*
* If we find anything wrong with the content / format of the buffer
* we reject it .
*
* The first requirement is that the manifest ' s version is
* one we can parse .
*
* We make an initial pass through the buffer and identify all of
* the descriptors it contains , keeping track for each its type
* and the location size of its data in the buffer .
*
2015-06-10 01:42:53 +03:00
* Next we scan the descriptors , looking for an interface descriptor ;
2014-10-02 06:54:16 +04:00
* there must be exactly one of those . When found , we record the
* information it contains , and then remove that descriptor ( and any
* string descriptors it refers to ) from further consideration .
*
2014-12-20 01:56:31 +03:00
* After that we look for the interface ' s bundles - - there must be at
2014-10-02 06:54:16 +04:00
* least one of those .
*
2014-10-03 23:14:25 +04:00
* Returns true if parsing was successful , false otherwise .
2014-10-02 06:54:16 +04:00
*/
2014-12-20 01:56:31 +03:00
bool gb_manifest_parse ( struct gb_interface * intf , void * data , size_t size )
2014-10-02 06:54:16 +04:00
{
struct greybus_manifest * manifest ;
struct greybus_manifest_header * header ;
struct greybus_descriptor * desc ;
struct manifest_desc * descriptor ;
2015-04-01 18:02:02 +03:00
struct manifest_desc * interface_desc = NULL ;
2014-10-02 06:54:16 +04:00
u16 manifest_size ;
u32 found = 0 ;
2014-11-13 15:44:30 +03:00
bool result ;
2014-10-02 06:54:16 +04:00
2014-11-14 14:55:03 +03:00
/* Manifest descriptor list should be empty here */
2014-12-24 02:16:50 +03:00
if ( WARN_ON ( ! list_empty ( & intf - > manifest_descs ) ) )
2014-11-14 14:55:03 +03:00
return false ;
2014-10-02 06:54:16 +04:00
/* we have to have at _least_ the manifest header */
2015-06-10 01:42:53 +03:00
if ( size < sizeof ( * header ) ) {
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " short manifest (%zu < %zu) \n " ,
2019-08-25 08:54:24 +03:00
size , sizeof ( * header ) ) ;
2014-10-03 23:14:25 +04:00
return false ;
2014-10-02 06:54:16 +04:00
}
/* Make sure the size is right */
manifest = data ;
header = & manifest - > header ;
manifest_size = le16_to_cpu ( header - > size ) ;
if ( manifest_size ! = size ) {
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " manifest size mismatch (%zu != %u) \n " ,
2019-08-25 08:54:24 +03:00
size , manifest_size ) ;
2014-10-03 23:14:25 +04:00
return false ;
2014-10-02 06:54:16 +04:00
}
/* Validate major/minor number */
if ( header - > version_major > GREYBUS_VERSION_MAJOR ) {
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " manifest version too new (%u.%u > %u.%u) \n " ,
2019-08-25 08:54:24 +03:00
header - > version_major , header - > version_minor ,
GREYBUS_VERSION_MAJOR , GREYBUS_VERSION_MINOR ) ;
2014-10-03 23:14:25 +04:00
return false ;
2014-10-02 06:54:16 +04:00
}
/* OK, find all the descriptors */
2015-11-24 05:29:10 +03:00
desc = manifest - > descriptors ;
2014-10-02 06:54:16 +04:00
size - = sizeof ( * header ) ;
while ( size ) {
int desc_size ;
2014-12-24 02:16:50 +03:00
desc_size = identify_descriptor ( intf , desc , size ) ;
2015-03-24 14:38:14 +03:00
if ( desc_size < 0 ) {
2014-10-06 21:46:36 +04:00
result = false ;
2014-10-03 23:14:25 +04:00
goto out ;
2014-10-02 06:54:16 +04:00
}
desc = ( struct greybus_descriptor * ) ( ( char * ) desc + desc_size ) ;
size - = desc_size ;
2014-11-15 01:37:56 +03:00
}
2014-10-02 06:54:16 +04:00
2015-04-01 18:02:02 +03:00
/* There must be a single interface descriptor */
2014-12-24 02:16:50 +03:00
list_for_each_entry ( descriptor , & intf - > manifest_descs , links ) {
2015-04-01 18:02:02 +03:00
if ( descriptor - > type = = GREYBUS_TYPE_INTERFACE )
2014-11-15 01:37:56 +03:00
if ( ! found + + )
2015-04-01 18:02:02 +03:00
interface_desc = descriptor ;
2014-11-15 01:37:56 +03:00
}
if ( found ! = 1 ) {
2016-02-11 15:52:46 +03:00
dev_err ( & intf - > dev , " manifest must have 1 interface descriptor (%u found) \n " ,
2019-08-25 08:54:24 +03:00
found ) ;
2014-11-15 01:37:56 +03:00
result = false ;
goto out ;
2014-10-02 06:54:16 +04:00
}
2015-04-01 18:02:02 +03:00
/* Parse the manifest, starting with the interface descriptor */
result = gb_manifest_parse_interface ( intf , interface_desc ) ;
2014-10-02 06:54:16 +04:00
/*
* We really should have no remaining descriptors , but we
* don ' t know what newer format manifests might leave .
*/
2014-12-24 02:16:50 +03:00
if ( result & & ! list_empty ( & intf - > manifest_descs ) )
2016-02-11 15:52:46 +03:00
dev_info ( & intf - > dev , " excess descriptors in interface manifest \n " ) ;
2014-10-03 23:14:25 +04:00
out :
2014-12-24 02:16:50 +03:00
release_manifest_descriptors ( intf ) ;
2014-10-02 06:54:16 +04:00
2014-10-06 21:46:36 +04:00
return result ;
2014-10-02 06:54:16 +04:00
}