@@ -137,6 +137,9 @@ struct uvc_entity *uvc_entity_by_id(struct uvc_device *dev, int id)
137137{
138138 struct uvc_entity * entity ;
139139
140+ if (id == UVC_INVALID_ENTITY_ID )
141+ return NULL ;
142+
140143 list_for_each_entry (entity , & dev -> entities , list ) {
141144 if (entity -> id == id )
142145 return entity ;
@@ -795,14 +798,27 @@ static const u8 uvc_media_transport_input_guid[16] =
795798 UVC_GUID_UVC_MEDIA_TRANSPORT_INPUT ;
796799static const u8 uvc_processing_guid [16 ] = UVC_GUID_UVC_PROCESSING ;
797800
798- static struct uvc_entity * uvc_alloc_entity (u16 type , u16 id ,
799- unsigned int num_pads , unsigned int extra_size )
801+ static struct uvc_entity * uvc_alloc_new_entity (struct uvc_device * dev , u16 type ,
802+ u16 id , unsigned int num_pads ,
803+ unsigned int extra_size )
800804{
801805 struct uvc_entity * entity ;
802806 unsigned int num_inputs ;
803807 unsigned int size ;
804808 unsigned int i ;
805809
810+ /* Per UVC 1.1+ spec 3.7.2, the ID should be non-zero. */
811+ if (id == 0 ) {
812+ dev_err (& dev -> intf -> dev , "Found Unit with invalid ID 0\n" );
813+ id = UVC_INVALID_ENTITY_ID ;
814+ }
815+
816+ /* Per UVC 1.1+ spec 3.7.2, the ID is unique. */
817+ if (uvc_entity_by_id (dev , id )) {
818+ dev_err (& dev -> intf -> dev , "Found multiple Units with ID %u\n" , id );
819+ id = UVC_INVALID_ENTITY_ID ;
820+ }
821+
806822 extra_size = roundup (extra_size , sizeof (* entity -> pads ));
807823 if (num_pads )
808824 num_inputs = type & UVC_TERM_OUTPUT ? num_pads : num_pads - 1 ;
@@ -812,7 +828,7 @@ static struct uvc_entity *uvc_alloc_entity(u16 type, u16 id,
812828 + num_inputs ;
813829 entity = kzalloc (size , GFP_KERNEL );
814830 if (entity == NULL )
815- return NULL ;
831+ return ERR_PTR ( - ENOMEM ) ;
816832
817833 entity -> id = id ;
818834 entity -> type = type ;
@@ -924,10 +940,10 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
924940 break ;
925941 }
926942
927- unit = uvc_alloc_entity ( UVC_VC_EXTENSION_UNIT , buffer [ 3 ] ,
928- p + 1 , 2 * n );
929- if (unit == NULL )
930- return - ENOMEM ;
943+ unit = uvc_alloc_new_entity ( dev , UVC_VC_EXTENSION_UNIT ,
944+ buffer [ 3 ], p + 1 , 2 * n );
945+ if (IS_ERR ( unit ) )
946+ return PTR_ERR ( unit ) ;
931947
932948 memcpy (unit -> guid , & buffer [4 ], 16 );
933949 unit -> extension .bNumControls = buffer [20 ];
@@ -1036,10 +1052,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
10361052 return - EINVAL ;
10371053 }
10381054
1039- term = uvc_alloc_entity ( type | UVC_TERM_INPUT , buffer [ 3 ] ,
1040- 1 , n + p );
1041- if (term == NULL )
1042- return - ENOMEM ;
1055+ term = uvc_alloc_new_entity ( dev , type | UVC_TERM_INPUT ,
1056+ buffer [ 3 ], 1 , n + p );
1057+ if (IS_ERR ( term ) )
1058+ return PTR_ERR ( term ) ;
10431059
10441060 if (UVC_ENTITY_TYPE (term ) == UVC_ITT_CAMERA ) {
10451061 term -> camera .bControlSize = n ;
@@ -1095,10 +1111,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
10951111 return 0 ;
10961112 }
10971113
1098- term = uvc_alloc_entity ( type | UVC_TERM_OUTPUT , buffer [ 3 ] ,
1099- 1 , 0 );
1100- if (term == NULL )
1101- return - ENOMEM ;
1114+ term = uvc_alloc_new_entity ( dev , type | UVC_TERM_OUTPUT ,
1115+ buffer [ 3 ], 1 , 0 );
1116+ if (IS_ERR ( term ) )
1117+ return PTR_ERR ( term ) ;
11021118
11031119 memcpy (term -> baSourceID , & buffer [7 ], 1 );
11041120
@@ -1117,9 +1133,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
11171133 return - EINVAL ;
11181134 }
11191135
1120- unit = uvc_alloc_entity (buffer [2 ], buffer [3 ], p + 1 , 0 );
1121- if (unit == NULL )
1122- return - ENOMEM ;
1136+ unit = uvc_alloc_new_entity (dev , buffer [2 ], buffer [3 ],
1137+ p + 1 , 0 );
1138+ if (IS_ERR (unit ))
1139+ return PTR_ERR (unit );
11231140
11241141 memcpy (unit -> baSourceID , & buffer [5 ], p );
11251142
@@ -1139,9 +1156,9 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
11391156 return - EINVAL ;
11401157 }
11411158
1142- unit = uvc_alloc_entity ( buffer [2 ], buffer [3 ], 2 , n );
1143- if (unit == NULL )
1144- return - ENOMEM ;
1159+ unit = uvc_alloc_new_entity ( dev , buffer [2 ], buffer [3 ], 2 , n );
1160+ if (IS_ERR ( unit ) )
1161+ return PTR_ERR ( unit ) ;
11451162
11461163 memcpy (unit -> baSourceID , & buffer [4 ], 1 );
11471164 unit -> processing .wMaxMultiplier =
@@ -1168,9 +1185,10 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
11681185 return - EINVAL ;
11691186 }
11701187
1171- unit = uvc_alloc_entity (buffer [2 ], buffer [3 ], p + 1 , n );
1172- if (unit == NULL )
1173- return - ENOMEM ;
1188+ unit = uvc_alloc_new_entity (dev , buffer [2 ], buffer [3 ],
1189+ p + 1 , n );
1190+ if (IS_ERR (unit ))
1191+ return PTR_ERR (unit );
11741192
11751193 memcpy (unit -> guid , & buffer [4 ], 16 );
11761194 unit -> extension .bNumControls = buffer [20 ];
@@ -1315,9 +1333,10 @@ static int uvc_gpio_parse(struct uvc_device *dev)
13151333 return dev_err_probe (& dev -> intf -> dev , irq ,
13161334 "No IRQ for privacy GPIO\n" );
13171335
1318- unit = uvc_alloc_entity (UVC_EXT_GPIO_UNIT , UVC_EXT_GPIO_UNIT_ID , 0 , 1 );
1319- if (!unit )
1320- return - ENOMEM ;
1336+ unit = uvc_alloc_new_entity (dev , UVC_EXT_GPIO_UNIT ,
1337+ UVC_EXT_GPIO_UNIT_ID , 0 , 1 );
1338+ if (IS_ERR (unit ))
1339+ return PTR_ERR (unit );
13211340
13221341 unit -> gpio .gpio_privacy = gpio_privacy ;
13231342 unit -> gpio .irq = irq ;
0 commit comments