aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2009-11-25 10:00:30 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-05 15:42:13 -0500
commit8ca5a639f4f3eb8958a7e270fcff7516374637a5 (patch)
treec4d79ad0d56913cfedff5c9018d2f32b2f7cc2a1 /drivers
parent4057ac6ca9a77c4275b34b5925ab5c99557913b1 (diff)
V4L/DVB (13506): uvcvideo: Factorize common field in uvc_entity structure
The bNrInPins and baSourceID fields are common among all entities (some of use bSourceID but this is conceptually the same). Move those two fields out of entity type-specific unions into the uvc_entity structure top level. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/uvc/uvc_driver.c119
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c6
-rw-r--r--drivers/media/video/uvc/uvcvideo.h9
3 files changed, 57 insertions, 77 deletions
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index e7ce898ad70..c31bc50113b 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -249,29 +249,9 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
249 entity = list_entry(&dev->entities, struct uvc_entity, list); 249 entity = list_entry(&dev->entities, struct uvc_entity, list);
250 250
251 list_for_each_entry_continue(entity, &dev->entities, list) { 251 list_for_each_entry_continue(entity, &dev->entities, list) {
252 switch (UVC_ENTITY_TYPE(entity)) { 252 for (i = 0; i < entity->bNrInPins; ++i)
253 case UVC_TT_STREAMING: 253 if (entity->baSourceID[i] == id)
254 if (entity->output.bSourceID == id)
255 return entity;
256 break;
257
258 case UVC_VC_PROCESSING_UNIT:
259 if (entity->processing.bSourceID == id)
260 return entity; 254 return entity;
261 break;
262
263 case UVC_VC_SELECTOR_UNIT:
264 for (i = 0; i < entity->selector.bNrInPins; ++i)
265 if (entity->selector.baSourceID[i] == id)
266 return entity;
267 break;
268
269 case UVC_VC_EXTENSION_UNIT:
270 for (i = 0; i < entity->extension.bNrInPins; ++i)
271 if (entity->extension.baSourceID[i] == id)
272 return entity;
273 break;
274 }
275 } 255 }
276 256
277 return NULL; 257 return NULL;
@@ -785,6 +765,28 @@ error:
785 return ret; 765 return ret;
786} 766}
787 767
768static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
769 unsigned int num_pads, unsigned int extra_size)
770{
771 struct uvc_entity *entity;
772 unsigned int num_inputs;
773 unsigned int size;
774
775 num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
776 size = sizeof(*entity) + extra_size + num_inputs;
777 entity = kzalloc(size, GFP_KERNEL);
778 if (entity == NULL)
779 return NULL;
780
781 entity->id = id;
782 entity->type = type;
783
784 entity->bNrInPins = num_inputs;
785 entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;
786
787 return entity;
788}
789
788/* Parse vendor-specific extensions. */ 790/* Parse vendor-specific extensions. */
789static int uvc_parse_vendor_control(struct uvc_device *dev, 791static int uvc_parse_vendor_control(struct uvc_device *dev,
790 const unsigned char *buffer, int buflen) 792 const unsigned char *buffer, int buflen)
@@ -836,21 +838,18 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
836 break; 838 break;
837 } 839 }
838 840
839 unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL); 841 unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
842 p + 1, 2*n);
840 if (unit == NULL) 843 if (unit == NULL)
841 return -ENOMEM; 844 return -ENOMEM;
842 845
843 unit->id = buffer[3];
844 unit->type = UVC_VC_EXTENSION_UNIT;
845 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 846 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
846 unit->extension.bNumControls = buffer[20]; 847 unit->extension.bNumControls = buffer[20];
847 unit->extension.bNrInPins = buffer[21]; 848 memcpy(unit->baSourceID, &buffer[22], p);
848 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
849 memcpy(unit->extension.baSourceID, &buffer[22], p);
850 unit->extension.bControlSize = buffer[22+p]; 849 unit->extension.bControlSize = buffer[22+p];
851 unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; 850 unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
852 unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit 851 unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
853 + p + n; 852 + n;
854 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n); 853 memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);
855 854
856 if (buffer[24+p+2*n] != 0) 855 if (buffer[24+p+2*n] != 0)
@@ -947,13 +946,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
947 return -EINVAL; 946 return -EINVAL;
948 } 947 }
949 948
950 term = kzalloc(sizeof *term + n + p, GFP_KERNEL); 949 term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
950 1, n + p);
951 if (term == NULL) 951 if (term == NULL)
952 return -ENOMEM; 952 return -ENOMEM;
953 953
954 term->id = buffer[3];
955 term->type = type | UVC_TERM_INPUT;
956
957 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) { 954 if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
958 term->camera.bControlSize = n; 955 term->camera.bControlSize = n;
959 term->camera.bmControls = (__u8 *)term + sizeof *term; 956 term->camera.bmControls = (__u8 *)term + sizeof *term;
@@ -1008,13 +1005,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1008 return 0; 1005 return 0;
1009 } 1006 }
1010 1007
1011 term = kzalloc(sizeof *term, GFP_KERNEL); 1008 term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
1009 1, 0);
1012 if (term == NULL) 1010 if (term == NULL)
1013 return -ENOMEM; 1011 return -ENOMEM;
1014 1012
1015 term->id = buffer[3]; 1013 memcpy(term->baSourceID, &buffer[7], 1);
1016 term->type = type | UVC_TERM_OUTPUT;
1017 term->output.bSourceID = buffer[7];
1018 1014
1019 if (buffer[8] != 0) 1015 if (buffer[8] != 0)
1020 usb_string(udev, buffer[8], term->name, 1016 usb_string(udev, buffer[8], term->name,
@@ -1035,15 +1031,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1035 return -EINVAL; 1031 return -EINVAL;
1036 } 1032 }
1037 1033
1038 unit = kzalloc(sizeof *unit + p, GFP_KERNEL); 1034 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
1039 if (unit == NULL) 1035 if (unit == NULL)
1040 return -ENOMEM; 1036 return -ENOMEM;
1041 1037
1042 unit->id = buffer[3]; 1038 memcpy(unit->baSourceID, &buffer[5], p);
1043 unit->type = buffer[2];
1044 unit->selector.bNrInPins = buffer[4];
1045 unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
1046 memcpy(unit->selector.baSourceID, &buffer[5], p);
1047 1039
1048 if (buffer[5+p] != 0) 1040 if (buffer[5+p] != 0)
1049 usb_string(udev, buffer[5+p], unit->name, 1041 usb_string(udev, buffer[5+p], unit->name,
@@ -1065,13 +1057,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1065 return -EINVAL; 1057 return -EINVAL;
1066 } 1058 }
1067 1059
1068 unit = kzalloc(sizeof *unit + n, GFP_KERNEL); 1060 unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
1069 if (unit == NULL) 1061 if (unit == NULL)
1070 return -ENOMEM; 1062 return -ENOMEM;
1071 1063
1072 unit->id = buffer[3]; 1064 memcpy(unit->baSourceID, &buffer[4], 1);
1073 unit->type = buffer[2];
1074 unit->processing.bSourceID = buffer[4];
1075 unit->processing.wMaxMultiplier = 1065 unit->processing.wMaxMultiplier =
1076 get_unaligned_le16(&buffer[5]); 1066 get_unaligned_le16(&buffer[5]);
1077 unit->processing.bControlSize = buffer[7]; 1067 unit->processing.bControlSize = buffer[7];
@@ -1100,19 +1090,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
1100 return -EINVAL; 1090 return -EINVAL;
1101 } 1091 }
1102 1092
1103 unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL); 1093 unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
1104 if (unit == NULL) 1094 if (unit == NULL)
1105 return -ENOMEM; 1095 return -ENOMEM;
1106 1096
1107 unit->id = buffer[3];
1108 unit->type = buffer[2];
1109 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16); 1097 memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
1110 unit->extension.bNumControls = buffer[20]; 1098 unit->extension.bNumControls = buffer[20];
1111 unit->extension.bNrInPins = buffer[21]; 1099 memcpy(unit->baSourceID, &buffer[22], p);
1112 unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
1113 memcpy(unit->extension.baSourceID, &buffer[22], p);
1114 unit->extension.bControlSize = buffer[22+p]; 1100 unit->extension.bControlSize = buffer[22+p];
1115 unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p; 1101 unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
1116 memcpy(unit->extension.bmControls, &buffer[23+p], n); 1102 memcpy(unit->extension.bmControls, &buffer[23+p], n);
1117 1103
1118 if (buffer[23+p+n] != 0) 1104 if (buffer[23+p+n] != 0)
@@ -1218,7 +1204,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1218 if (uvc_trace_param & UVC_TRACE_PROBE) 1204 if (uvc_trace_param & UVC_TRACE_PROBE)
1219 printk(" <- XU %d", entity->id); 1205 printk(" <- XU %d", entity->id);
1220 1206
1221 if (entity->extension.bNrInPins != 1) { 1207 if (entity->bNrInPins != 1) {
1222 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more " 1208 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
1223 "than 1 input pin.\n", entity->id); 1209 "than 1 input pin.\n", entity->id);
1224 return -1; 1210 return -1;
@@ -1244,7 +1230,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1244 printk(" <- SU %d", entity->id); 1230 printk(" <- SU %d", entity->id);
1245 1231
1246 /* Single-input selector units are ignored. */ 1232 /* Single-input selector units are ignored. */
1247 if (entity->selector.bNrInPins == 1) 1233 if (entity->bNrInPins == 1)
1248 break; 1234 break;
1249 1235
1250 if (chain->selector != NULL) { 1236 if (chain->selector != NULL) {
@@ -1305,7 +1291,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1305 1291
1306 switch (UVC_ENTITY_TYPE(forward)) { 1292 switch (UVC_ENTITY_TYPE(forward)) {
1307 case UVC_VC_EXTENSION_UNIT: 1293 case UVC_VC_EXTENSION_UNIT:
1308 if (forward->extension.bNrInPins != 1) { 1294 if (forward->bNrInPins != 1) {
1309 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d " 1295 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
1310 "has more than 1 input pin.\n", 1296 "has more than 1 input pin.\n",
1311 entity->id); 1297 entity->id);
@@ -1358,17 +1344,14 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1358 1344
1359 switch (UVC_ENTITY_TYPE(entity)) { 1345 switch (UVC_ENTITY_TYPE(entity)) {
1360 case UVC_VC_EXTENSION_UNIT: 1346 case UVC_VC_EXTENSION_UNIT:
1361 id = entity->extension.baSourceID[0];
1362 break;
1363
1364 case UVC_VC_PROCESSING_UNIT: 1347 case UVC_VC_PROCESSING_UNIT:
1365 id = entity->processing.bSourceID; 1348 id = entity->baSourceID[0];
1366 break; 1349 break;
1367 1350
1368 case UVC_VC_SELECTOR_UNIT: 1351 case UVC_VC_SELECTOR_UNIT:
1369 /* Single-input selector units are ignored. */ 1352 /* Single-input selector units are ignored. */
1370 if (entity->selector.bNrInPins == 1) { 1353 if (entity->bNrInPins == 1) {
1371 id = entity->selector.baSourceID[0]; 1354 id = entity->baSourceID[0];
1372 break; 1355 break;
1373 } 1356 }
1374 1357
@@ -1376,8 +1359,8 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1376 printk(" <- IT"); 1359 printk(" <- IT");
1377 1360
1378 chain->selector = entity; 1361 chain->selector = entity;
1379 for (i = 0; i < entity->selector.bNrInPins; ++i) { 1362 for (i = 0; i < entity->bNrInPins; ++i) {
1380 id = entity->selector.baSourceID[i]; 1363 id = entity->baSourceID[i];
1381 term = uvc_entity_by_id(chain->dev, id); 1364 term = uvc_entity_by_id(chain->dev, id);
1382 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { 1365 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1383 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " 1366 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
@@ -1406,7 +1389,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1406 case UVC_OTT_DISPLAY: 1389 case UVC_OTT_DISPLAY:
1407 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT: 1390 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1408 case UVC_TT_STREAMING: 1391 case UVC_TT_STREAMING:
1409 id = UVC_ENTITY_IS_OTERM(entity) ? entity->output.bSourceID : 0; 1392 id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
1410 break; 1393 break;
1411 } 1394 }
1412 1395
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 9e1f2c208ed..23239a4adef 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -625,8 +625,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
625 break; 625 break;
626 } 626 }
627 pin = iterm->id; 627 pin = iterm->id;
628 } else if (pin < selector->selector.bNrInPins) { 628 } else if (pin < selector->bNrInPins) {
629 pin = selector->selector.baSourceID[index]; 629 pin = selector->baSourceID[index];
630 list_for_each_entry(iterm, &chain->entities, chain) { 630 list_for_each_entry(iterm, &chain->entities, chain) {
631 if (!UVC_ENTITY_IS_ITERM(iterm)) 631 if (!UVC_ENTITY_IS_ITERM(iterm))
632 continue; 632 continue;
@@ -680,7 +680,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
680 break; 680 break;
681 } 681 }
682 682
683 if (input == 0 || input > chain->selector->selector.bNrInPins) 683 if (input == 0 || input > chain->selector->bNrInPins)
684 return -EINVAL; 684 return -EINVAL;
685 685
686 return uvc_query_ctrl(chain->dev, UVC_SET_CUR, 686 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 9e6948fb3e6..7ec9a04ced5 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -293,11 +293,9 @@ struct uvc_entity {
293 } media; 293 } media;
294 294
295 struct { 295 struct {
296 __u8 bSourceID;
297 } output; 296 } output;
298 297
299 struct { 298 struct {
300 __u8 bSourceID;
301 __u16 wMaxMultiplier; 299 __u16 wMaxMultiplier;
302 __u8 bControlSize; 300 __u8 bControlSize;
303 __u8 *bmControls; 301 __u8 *bmControls;
@@ -305,21 +303,20 @@ struct uvc_entity {
305 } processing; 303 } processing;
306 304
307 struct { 305 struct {
308 __u8 bNrInPins;
309 __u8 *baSourceID;
310 } selector; 306 } selector;
311 307
312 struct { 308 struct {
313 __u8 guidExtensionCode[16]; 309 __u8 guidExtensionCode[16];
314 __u8 bNumControls; 310 __u8 bNumControls;
315 __u8 bNrInPins;
316 __u8 *baSourceID;
317 __u8 bControlSize; 311 __u8 bControlSize;
318 __u8 *bmControls; 312 __u8 *bmControls;
319 __u8 *bmControlsType; 313 __u8 *bmControlsType;
320 } extension; 314 } extension;
321 }; 315 };
322 316
317 __u8 bNrInPins;
318 __u8 *baSourceID;
319
323 unsigned int ncontrols; 320 unsigned int ncontrols;
324 struct uvc_control *controls; 321 struct uvc_control *controls;
325}; 322};