@@ -135,6 +135,9 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
135135{
136136 struct uvc_entity * entity ;
137137
138+ if (id == UVC_INVALID_ENTITY_ID )
139+ return NULL ;
140+
138141 list_for_each_entry (entity , & dev -> entities , list ) {
139142 if (entity -> id == id )
140143 return entity ;
@@ -778,14 +781,27 @@ static const u8 uvc_media_transport_input_guid[16] =
778781 UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT ;
779782static const u8 uvc_processing_guid [16 ] = UVC_GUID_UVC_PROCESSING ;
780783
781- static struct uvc_entity * uvc_alloc_entity (u16 type , u16 id ,
782- unsigned int num_pads , unsigned int extra_size )
784+ static struct uvc_entity * uvc_alloc_new_entity (struct uvc_device * dev , u16 type ,
785+ u16 id , unsigned int num_pads ,
786+ unsigned int extra_size )
783787{
784788 struct uvc_entity * entity ;
785789 unsigned int num_inputs ;
786790 unsigned int size ;
787791 unsigned int i ;
788792
793+ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */
794+ if (id == 0 ) {
795+ dev_err (& dev -> intf -> dev , "Found Unit with invalid ID 0\n" );
796+ id = UVC_INVALID_ENTITY_ID ;
797+ }
798+
799+ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */
800+ if (uvc_entity_by_id (dev , id )) {
801+ dev_err (& dev -> intf -> dev , "Found multiple Units with ID %u\n" , id );
802+ id = UVC_INVALID_ENTITY_ID ;
803+ }
804+
789805 extra_size = roundup (extra_size , sizeof (* entity -> pads ));
790806 if (num_pads )
791807 num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1 ;
@@ -795,7 +811,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
795811 + num_inputs ;
796812 entity = kzalloc (size , GFP_KERNEL );
797813 if (entity == NULL )
798- return NULL ;
814+ return ERR_PTR ( - ENOMEM ) ;
799815
800816 entity -> id = id ;
801817 entity -> type = type ;
@@ -907,10 +923,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
907923 break ;
908924 }
909925
910- unit = uvc_alloc_entity ( UVC_VC_EXTENSION_UNIT , buffer [ 3 ] ,
911- p + 1 , 2 * n );
912- if (unit == NULL )
913- return - ENOMEM ;
926+ unit = uvc_alloc_new_entity ( dev , UVC_VC_EXTENSION_UNIT ,
927+ buffer [ 3 ], p + 1 , 2 * n );
928+ if (IS_ERR ( unit ) )
929+ return PTR_ERR ( unit ) ;
914930
915931 memcpy (unit -> guid , & buffer [4 ], 16 );
916932 unit -> extension .bNumControls = buffer [20 ];
@@ -1019,10 +1035,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
10191035 return - EINVAL ;
10201036 }
10211037
1022- term = uvc_alloc_entity ( type | UVC_TERM_INPUT , buffer [ 3 ] ,
1023- 1 , n + p );
1024- if (term == NULL )
1025- return - ENOMEM ;
1038+ term = uvc_alloc_new_entity ( dev , type | UVC_TERM_INPUT ,
1039+ buffer [ 3 ], 1 , n + p );
1040+ if (IS_ERR ( term ) )
1041+ return PTR_ERR ( term ) ;
10261042
10271043 if (UVC_ENTITY_TYPE (term ) == UVC_ITT_CAMERA ) {
10281044 term -> camera .bControlSize = n ;
@@ -1078,10 +1094,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
10781094 return 0 ;
10791095 }
10801096
1081- term = uvc_alloc_entity ( type | UVC_TERM_OUTPUT , buffer [ 3 ] ,
1082- 1 , 0 );
1083- if (term == NULL )
1084- return - ENOMEM ;
1097+ term = uvc_alloc_new_entity ( dev , type | UVC_TERM_OUTPUT ,
1098+ buffer [ 3 ], 1 , 0 );
1099+ if (IS_ERR ( term ) )
1100+ return PTR_ERR ( term ) ;
10851101
10861102 memcpy (term -> baSourceID , & buffer [7 ], 1 );
10871103
@@ -1100,9 +1116,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
11001116 return - EINVAL ;
11011117 }
11021118
1103- unit = uvc_alloc_entity (buffer [2 ], buffer [3 ], p + 1 , 0 );
1104- if (unit == NULL )
1105- return - ENOMEM ;
1119+ unit = uvc_alloc_new_entity (dev , buffer [2 ], buffer [3 ],
1120+ p + 1 , 0 );
1121+ if (IS_ERR (unit ))
1122+ return PTR_ERR (unit );
11061123
11071124 memcpy (unit -> baSourceID , & buffer [5 ], p );
11081125
@@ -1122,9 +1139,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
11221139 return - EINVAL ;
11231140 }
11241141
1125- unit = uvc_alloc_entity ( buffer [2 ], buffer [3 ], 2 , n );
1126- if (unit == NULL )
1127- return - ENOMEM ;
1142+ unit = uvc_alloc_new_entity ( dev , buffer [2 ], buffer [3 ], 2 , n );
1143+ if (IS_ERR ( unit ) )
1144+ return PTR_ERR ( unit ) ;
11281145
11291146 memcpy (unit -> baSourceID , & buffer [4 ], 1 );
11301147 unit -> processing .wMaxMultiplier =
@@ -1151,9 +1168,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
11511168 return - EINVAL ;
11521169 }
11531170
1154- unit = uvc_alloc_entity (buffer [2 ], buffer [3 ], p + 1 , n );
1155- if (unit == NULL )
1156- return - ENOMEM ;
1171+ unit = uvc_alloc_new_entity (dev , buffer [2 ], buffer [3 ],
1172+ p + 1 , n );
1173+ if (IS_ERR (unit ))
1174+ return PTR_ERR (unit );
11571175
11581176 memcpy (unit -> guid , & buffer [4 ], 16 );
11591177 unit -> extension .bNumControls = buffer [20 ];
@@ -1293,9 +1311,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
12931311 return dev_err_probe (& dev -> intf -> dev , irq ,
12941312 "No IRQ for privacy GPIO\n" );
12951313
1296- unit = uvc_alloc_entity (UVC_EXT_GPIO_UNIT , UVC_EXT_GPIO_UNIT_ID , 0 , 1 );
1297- if (!unit )
1298- return - ENOMEM ;
1314+ unit = uvc_alloc_new_entity (dev , UVC_EXT_GPIO_UNIT ,
1315+ UVC_EXT_GPIO_UNIT_ID , 0 , 1 );
1316+ if (IS_ERR (unit ))
1317+ return PTR_ERR (unit );
12991318
13001319 unit -> gpio .gpio_privacy = gpio_privacy ;
13011320 unit -> gpio .irq = irq ;
0 commit comments