diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2009-11-25 10:00:30 -0500 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-12-05 15:42:13 -0500 |
commit | 8ca5a639f4f3eb8958a7e270fcff7516374637a5 (patch) | |
tree | c4d79ad0d56913cfedff5c9018d2f32b2f7cc2a1 /drivers/media | |
parent | 4057ac6ca9a77c4275b34b5925ab5c99557913b1 (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/media')
-rw-r--r-- | drivers/media/video/uvc/uvc_driver.c | 119 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvc_v4l2.c | 6 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 9 |
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 e7ce898ad706..c31bc50113bc 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 | ||
768 | static 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. */ |
789 | static int uvc_parse_vendor_control(struct uvc_device *dev, | 791 | static 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 9e1f2c208ed8..23239a4adefe 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 9e6948fb3e61..7ec9a04ced50 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 | }; |