aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2009-07-01 19:24:47 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-09-12 11:18:33 -0400
commit8e113595edf0741b45ba10ba88cb5d077787c155 (patch)
tree3b2d7b940445989586ad198d2c5c974432d97618 /drivers/media
parent35f02a681b72ece756cf005e17f305a72329c140 (diff)
V4L/DVB (12379): uvcvideo: Multiple streaming interfaces support
Restructure the UVC descriptors parsing code to handle multiple streaming interfaces. The driver now creates a uvc_video_chain instance for each chain detected in the UVC control interface descriptors, and tries to register one video device per streaming endpoint. Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c82
-rw-r--r--drivers/media/video/uvc/uvc_driver.c466
-rw-r--r--drivers/media/video/uvc/uvc_v4l2.c80
-rw-r--r--drivers/media/video/uvc/uvc_video.c2
-rw-r--r--drivers/media/video/uvc/uvcvideo.h59
5 files changed, 411 insertions, 278 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 70043b1704fb..c3225a561748 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -729,7 +729,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
729 } 729 }
730} 730}
731 731
732struct uvc_control *uvc_find_control(struct uvc_video_device *video, 732struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
733 __u32 v4l2_id, struct uvc_control_mapping **mapping) 733 __u32 v4l2_id, struct uvc_control_mapping **mapping)
734{ 734{
735 struct uvc_control *ctrl = NULL; 735 struct uvc_control *ctrl = NULL;
@@ -742,17 +742,17 @@ struct uvc_control *uvc_find_control(struct uvc_video_device *video,
742 v4l2_id &= V4L2_CTRL_ID_MASK; 742 v4l2_id &= V4L2_CTRL_ID_MASK;
743 743
744 /* Find the control. */ 744 /* Find the control. */
745 __uvc_find_control(video->processing, v4l2_id, mapping, &ctrl, next); 745 __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
746 if (ctrl && !next) 746 if (ctrl && !next)
747 return ctrl; 747 return ctrl;
748 748
749 list_for_each_entry(entity, &video->iterms, chain) { 749 list_for_each_entry(entity, &chain->iterms, chain) {
750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 750 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
751 if (ctrl && !next) 751 if (ctrl && !next)
752 return ctrl; 752 return ctrl;
753 } 753 }
754 754
755 list_for_each_entry(entity, &video->extensions, chain) { 755 list_for_each_entry(entity, &chain->extensions, chain) {
756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next); 756 __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
757 if (ctrl && !next) 757 if (ctrl && !next)
758 return ctrl; 758 return ctrl;
@@ -765,7 +765,7 @@ struct uvc_control *uvc_find_control(struct uvc_video_device *video,
765 return ctrl; 765 return ctrl;
766} 766}
767 767
768int uvc_query_v4l2_ctrl(struct uvc_video_device *video, 768int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
769 struct v4l2_queryctrl *v4l2_ctrl) 769 struct v4l2_queryctrl *v4l2_ctrl)
770{ 770{
771 struct uvc_control *ctrl; 771 struct uvc_control *ctrl;
@@ -775,7 +775,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
775 __u8 *data; 775 __u8 *data;
776 int ret; 776 int ret;
777 777
778 ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping); 778 ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
779 if (ctrl == NULL) 779 if (ctrl == NULL)
780 return -EINVAL; 780 return -EINVAL;
781 781
@@ -793,9 +793,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
793 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; 793 v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
794 794
795 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { 795 if (ctrl->info->flags & UVC_CONTROL_GET_DEF) {
796 ret = uvc_query_ctrl(video->dev, UVC_GET_DEF, ctrl->entity->id, 796 ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
797 video->dev->intfnum, ctrl->info->selector, data, 797 chain->dev->intfnum, ctrl->info->selector,
798 ctrl->info->size); 798 data, ctrl->info->size);
799 if (ret < 0) 799 if (ret < 0)
800 goto out; 800 goto out;
801 v4l2_ctrl->default_value = 801 v4l2_ctrl->default_value =
@@ -831,25 +831,25 @@ int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
831 } 831 }
832 832
833 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { 833 if (ctrl->info->flags & UVC_CONTROL_GET_MIN) {
834 ret = uvc_query_ctrl(video->dev, UVC_GET_MIN, ctrl->entity->id, 834 ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
835 video->dev->intfnum, ctrl->info->selector, data, 835 chain->dev->intfnum, ctrl->info->selector,
836 ctrl->info->size); 836 data, ctrl->info->size);
837 if (ret < 0) 837 if (ret < 0)
838 goto out; 838 goto out;
839 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data); 839 v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, data);
840 } 840 }
841 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { 841 if (ctrl->info->flags & UVC_CONTROL_GET_MAX) {
842 ret = uvc_query_ctrl(video->dev, UVC_GET_MAX, ctrl->entity->id, 842 ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
843 video->dev->intfnum, ctrl->info->selector, data, 843 chain->dev->intfnum, ctrl->info->selector,
844 ctrl->info->size); 844 data, ctrl->info->size);
845 if (ret < 0) 845 if (ret < 0)
846 goto out; 846 goto out;
847 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data); 847 v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, data);
848 } 848 }
849 if (ctrl->info->flags & UVC_CONTROL_GET_RES) { 849 if (ctrl->info->flags & UVC_CONTROL_GET_RES) {
850 ret = uvc_query_ctrl(video->dev, UVC_GET_RES, ctrl->entity->id, 850 ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
851 video->dev->intfnum, ctrl->info->selector, data, 851 chain->dev->intfnum, ctrl->info->selector,
852 ctrl->info->size); 852 data, ctrl->info->size);
853 if (ret < 0) 853 if (ret < 0)
854 goto out; 854 goto out;
855 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data); 855 v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, data);
@@ -886,9 +886,9 @@ out:
886 * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the 886 * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release the
887 * control lock. 887 * control lock.
888 */ 888 */
889int uvc_ctrl_begin(struct uvc_video_device *video) 889int uvc_ctrl_begin(struct uvc_video_chain *chain)
890{ 890{
891 return mutex_lock_interruptible(&video->ctrl_mutex) ? -ERESTARTSYS : 0; 891 return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
892} 892}
893 893
894static int uvc_ctrl_commit_entity(struct uvc_device *dev, 894static int uvc_ctrl_commit_entity(struct uvc_device *dev,
@@ -938,34 +938,34 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
938 return 0; 938 return 0;
939} 939}
940 940
941int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback) 941int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
942{ 942{
943 struct uvc_entity *entity; 943 struct uvc_entity *entity;
944 int ret = 0; 944 int ret = 0;
945 945
946 /* Find the control. */ 946 /* Find the control. */
947 ret = uvc_ctrl_commit_entity(video->dev, video->processing, rollback); 947 ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
948 if (ret < 0) 948 if (ret < 0)
949 goto done; 949 goto done;
950 950
951 list_for_each_entry(entity, &video->iterms, chain) { 951 list_for_each_entry(entity, &chain->iterms, chain) {
952 ret = uvc_ctrl_commit_entity(video->dev, entity, rollback); 952 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
953 if (ret < 0) 953 if (ret < 0)
954 goto done; 954 goto done;
955 } 955 }
956 956
957 list_for_each_entry(entity, &video->extensions, chain) { 957 list_for_each_entry(entity, &chain->extensions, chain) {
958 ret = uvc_ctrl_commit_entity(video->dev, entity, rollback); 958 ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
959 if (ret < 0) 959 if (ret < 0)
960 goto done; 960 goto done;
961 } 961 }
962 962
963done: 963done:
964 mutex_unlock(&video->ctrl_mutex); 964 mutex_unlock(&chain->ctrl_mutex);
965 return ret; 965 return ret;
966} 966}
967 967
968int uvc_ctrl_get(struct uvc_video_device *video, 968int uvc_ctrl_get(struct uvc_video_chain *chain,
969 struct v4l2_ext_control *xctrl) 969 struct v4l2_ext_control *xctrl)
970{ 970{
971 struct uvc_control *ctrl; 971 struct uvc_control *ctrl;
@@ -974,13 +974,13 @@ int uvc_ctrl_get(struct uvc_video_device *video,
974 unsigned int i; 974 unsigned int i;
975 int ret; 975 int ret;
976 976
977 ctrl = uvc_find_control(video, xctrl->id, &mapping); 977 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
978 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) 978 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
979 return -EINVAL; 979 return -EINVAL;
980 980
981 if (!ctrl->loaded) { 981 if (!ctrl->loaded) {
982 ret = uvc_query_ctrl(video->dev, UVC_GET_CUR, ctrl->entity->id, 982 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
983 video->dev->intfnum, ctrl->info->selector, 983 chain->dev->intfnum, ctrl->info->selector,
984 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 984 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
985 ctrl->info->size); 985 ctrl->info->size);
986 if (ret < 0) 986 if (ret < 0)
@@ -1005,7 +1005,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
1005 return 0; 1005 return 0;
1006} 1006}
1007 1007
1008int uvc_ctrl_set(struct uvc_video_device *video, 1008int uvc_ctrl_set(struct uvc_video_chain *chain,
1009 struct v4l2_ext_control *xctrl) 1009 struct v4l2_ext_control *xctrl)
1010{ 1010{
1011 struct uvc_control *ctrl; 1011 struct uvc_control *ctrl;
@@ -1013,7 +1013,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
1013 s32 value = xctrl->value; 1013 s32 value = xctrl->value;
1014 int ret; 1014 int ret;
1015 1015
1016 ctrl = uvc_find_control(video, xctrl->id, &mapping); 1016 ctrl = uvc_find_control(chain, xctrl->id, &mapping);
1017 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) 1017 if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0)
1018 return -EINVAL; 1018 return -EINVAL;
1019 1019
@@ -1028,8 +1028,8 @@ int uvc_ctrl_set(struct uvc_video_device *video,
1028 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1028 memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1029 0, ctrl->info->size); 1029 0, ctrl->info->size);
1030 } else { 1030 } else {
1031 ret = uvc_query_ctrl(video->dev, UVC_GET_CUR, 1031 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
1032 ctrl->entity->id, video->dev->intfnum, 1032 ctrl->entity->id, chain->dev->intfnum,
1033 ctrl->info->selector, 1033 ctrl->info->selector,
1034 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 1034 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
1035 ctrl->info->size); 1035 ctrl->info->size);
@@ -1058,7 +1058,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
1058 * Dynamic controls 1058 * Dynamic controls
1059 */ 1059 */
1060 1060
1061int uvc_xu_ctrl_query(struct uvc_video_device *video, 1061int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
1062 struct uvc_xu_control *xctrl, int set) 1062 struct uvc_xu_control *xctrl, int set)
1063{ 1063{
1064 struct uvc_entity *entity; 1064 struct uvc_entity *entity;
@@ -1068,7 +1068,7 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
1068 int ret; 1068 int ret;
1069 1069
1070 /* Find the extension unit. */ 1070 /* Find the extension unit. */
1071 list_for_each_entry(entity, &video->extensions, chain) { 1071 list_for_each_entry(entity, &chain->extensions, chain) {
1072 if (entity->id == xctrl->unit) 1072 if (entity->id == xctrl->unit)
1073 break; 1073 break;
1074 } 1074 }
@@ -1107,7 +1107,7 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
1107 (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR))) 1107 (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR)))
1108 return -EINVAL; 1108 return -EINVAL;
1109 1109
1110 if (mutex_lock_interruptible(&video->ctrl_mutex)) 1110 if (mutex_lock_interruptible(&chain->ctrl_mutex))
1111 return -ERESTARTSYS; 1111 return -ERESTARTSYS;
1112 1112
1113 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1113 memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
@@ -1120,8 +1120,8 @@ int uvc_xu_ctrl_query(struct uvc_video_device *video,
1120 goto out; 1120 goto out;
1121 } 1121 }
1122 1122
1123 ret = uvc_query_ctrl(video->dev, set ? UVC_SET_CUR : UVC_GET_CUR, 1123 ret = uvc_query_ctrl(chain->dev, set ? UVC_SET_CUR : UVC_GET_CUR,
1124 xctrl->unit, video->dev->intfnum, xctrl->selector, 1124 xctrl->unit, chain->dev->intfnum, xctrl->selector,
1125 data, xctrl->size); 1125 data, xctrl->size);
1126 if (ret < 0) 1126 if (ret < 0)
1127 goto out; 1127 goto out;
@@ -1137,7 +1137,7 @@ out:
1137 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 1137 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
1138 xctrl->size); 1138 xctrl->size);
1139 1139
1140 mutex_unlock(&video->ctrl_mutex); 1140 mutex_unlock(&chain->ctrl_mutex);
1141 return ret; 1141 return ret;
1142} 1142}
1143 1143
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index 81bf67126abf..8756be569154 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -276,8 +276,20 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
276 return NULL; 276 return NULL;
277} 277}
278 278
279static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev, int id)
280{
281 struct uvc_streaming *stream;
282
283 list_for_each_entry(stream, &dev->streams, list) {
284 if (stream->header.bTerminalLink == id)
285 return stream;
286 }
287
288 return NULL;
289}
290
279/* ------------------------------------------------------------------------ 291/* ------------------------------------------------------------------------
280 * Descriptors handling 292 * Descriptors parsing
281 */ 293 */
282 294
283static int uvc_parse_format(struct uvc_device *dev, 295static int uvc_parse_format(struct uvc_device *dev,
@@ -1160,101 +1172,36 @@ next_descriptor:
1160} 1172}
1161 1173
1162/* ------------------------------------------------------------------------ 1174/* ------------------------------------------------------------------------
1163 * USB probe and disconnect 1175 * UVC device scan
1164 */ 1176 */
1165 1177
1166/* 1178/*
1167 * Unregister the video devices.
1168 */
1169static void uvc_unregister_video(struct uvc_device *dev)
1170{
1171 struct uvc_streaming *streaming;
1172
1173 list_for_each_entry(streaming, &dev->streams, list) {
1174 if (streaming->vdev == NULL)
1175 continue;
1176
1177 if (streaming->vdev->minor == -1)
1178 video_device_release(streaming->vdev);
1179 else
1180 video_unregister_device(streaming->vdev);
1181 streaming->vdev = NULL;
1182 }
1183}
1184
1185static int uvc_register_video(struct uvc_device *dev,
1186 struct uvc_streaming *stream)
1187{
1188 struct video_device *vdev;
1189 struct uvc_entity *term;
1190 int ret;
1191
1192 if (uvc_trace_param & UVC_TRACE_PROBE) {
1193 uvc_printk(KERN_INFO, "Found a valid video chain (");
1194 list_for_each_entry(term, &dev->video.iterms, chain) {
1195 printk("%d", term->id);
1196 if (term->chain.next != &dev->video.iterms)
1197 printk(",");
1198 }
1199 printk(" -> %d).\n", dev->video.oterm->id);
1200 }
1201
1202 /* Initialize the streaming interface with default streaming
1203 * parameters.
1204 */
1205 ret = uvc_video_init(stream);
1206 if (ret < 0) {
1207 uvc_printk(KERN_ERR, "Failed to initialize the device "
1208 "(%d).\n", ret);
1209 return ret;
1210 }
1211
1212 /* Register the device with V4L. */
1213 vdev = video_device_alloc();
1214 if (vdev == NULL)
1215 return -1;
1216
1217 /* We already hold a reference to dev->udev. The video device will be
1218 * unregistered before the reference is released, so we don't need to
1219 * get another one.
1220 */
1221 vdev->parent = &dev->intf->dev;
1222 vdev->minor = -1;
1223 vdev->fops = &uvc_fops;
1224 vdev->release = video_device_release;
1225 strlcpy(vdev->name, dev->name, sizeof vdev->name);
1226
1227 /* Set the driver data before calling video_register_device, otherwise
1228 * uvc_v4l2_open might race us.
1229 */
1230 stream->vdev = vdev;
1231 video_set_drvdata(vdev, stream);
1232
1233 if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) {
1234 stream->vdev = NULL;
1235 video_device_release(vdev);
1236 return -1;
1237 }
1238
1239 return 0;
1240}
1241
1242/*
1243 * Scan the UVC descriptors to locate a chain starting at an Output Terminal 1179 * Scan the UVC descriptors to locate a chain starting at an Output Terminal
1244 * and containing the following units: 1180 * and containing the following units:
1245 * 1181 *
1246 * - one Output Terminal (USB Streaming or Display) 1182 * - one or more Output Terminals (USB Streaming or Display)
1247 * - zero or one Processing Unit 1183 * - zero or one Processing Unit
1248 * - zero, one or mode single-input Selector Units 1184 * - zero, one or more single-input Selector Units
1249 * - zero or one multiple-input Selector Units, provided all inputs are 1185 * - zero or one multiple-input Selector Units, provided all inputs are
1250 * connected to input terminals 1186 * connected to input terminals
1251 * - zero, one or mode single-input Extension Units 1187 * - zero, one or mode single-input Extension Units
1252 * - one or more Input Terminals (Camera, External or USB Streaming) 1188 * - one or more Input Terminals (Camera, External or USB Streaming)
1253 * 1189 *
1254 * A side forward scan is made on each detected entity to check for additional 1190 * The terminal and units must match on of the following structures:
1255 * extension units. 1191 *
1192 * ITT_*(0) -> +---------+ +---------+ +---------+ -> TT_STREAMING(0)
1193 * ... | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} | ...
1194 * ITT_*(n) -> +---------+ +---------+ +---------+ -> TT_STREAMING(n)
1195 *
1196 * +---------+ +---------+ -> OTT_*(0)
1197 * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} | ...
1198 * +---------+ +---------+ -> OTT_*(n)
1199 *
1200 * The Processing Unit and Extension Units can be in any order. Additional
1201 * Extension Units connected to the main chain as single-unit branches are
1202 * also supported. Single-input Selector Units are ignored.
1256 */ 1203 */
1257static int uvc_scan_chain_entity(struct uvc_video_device *video, 1204static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1258 struct uvc_entity *entity) 1205 struct uvc_entity *entity)
1259{ 1206{
1260 switch (UVC_ENTITY_TYPE(entity)) { 1207 switch (UVC_ENTITY_TYPE(entity)) {
@@ -1268,20 +1215,20 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1268 return -1; 1215 return -1;
1269 } 1216 }
1270 1217
1271 list_add_tail(&entity->chain, &video->extensions); 1218 list_add_tail(&entity->chain, &chain->extensions);
1272 break; 1219 break;
1273 1220
1274 case UVC_VC_PROCESSING_UNIT: 1221 case UVC_VC_PROCESSING_UNIT:
1275 if (uvc_trace_param & UVC_TRACE_PROBE) 1222 if (uvc_trace_param & UVC_TRACE_PROBE)
1276 printk(" <- PU %d", entity->id); 1223 printk(" <- PU %d", entity->id);
1277 1224
1278 if (video->processing != NULL) { 1225 if (chain->processing != NULL) {
1279 uvc_trace(UVC_TRACE_DESCR, "Found multiple " 1226 uvc_trace(UVC_TRACE_DESCR, "Found multiple "
1280 "Processing Units in chain.\n"); 1227 "Processing Units in chain.\n");
1281 return -1; 1228 return -1;
1282 } 1229 }
1283 1230
1284 video->processing = entity; 1231 chain->processing = entity;
1285 break; 1232 break;
1286 1233
1287 case UVC_VC_SELECTOR_UNIT: 1234 case UVC_VC_SELECTOR_UNIT:
@@ -1292,13 +1239,13 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1292 if (entity->selector.bNrInPins == 1) 1239 if (entity->selector.bNrInPins == 1)
1293 break; 1240 break;
1294 1241
1295 if (video->selector != NULL) { 1242 if (chain->selector != NULL) {
1296 uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector " 1243 uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector "
1297 "Units in chain.\n"); 1244 "Units in chain.\n");
1298 return -1; 1245 return -1;
1299 } 1246 }
1300 1247
1301 video->selector = entity; 1248 chain->selector = entity;
1302 break; 1249 break;
1303 1250
1304 case UVC_ITT_VENDOR_SPECIFIC: 1251 case UVC_ITT_VENDOR_SPECIFIC:
@@ -1307,7 +1254,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1307 if (uvc_trace_param & UVC_TRACE_PROBE) 1254 if (uvc_trace_param & UVC_TRACE_PROBE)
1308 printk(" <- IT %d\n", entity->id); 1255 printk(" <- IT %d\n", entity->id);
1309 1256
1310 list_add_tail(&entity->chain, &video->iterms); 1257 list_add_tail(&entity->chain, &chain->iterms);
1311 break; 1258 break;
1312 1259
1313 case UVC_TT_STREAMING: 1260 case UVC_TT_STREAMING:
@@ -1320,14 +1267,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1320 return -1; 1267 return -1;
1321 } 1268 }
1322 1269
1323 if (video->sterm != NULL) { 1270 list_add_tail(&entity->chain, &chain->iterms);
1324 uvc_trace(UVC_TRACE_DESCR, "Found multiple streaming "
1325 "entities in chain.\n");
1326 return -1;
1327 }
1328
1329 list_add_tail(&entity->chain, &video->iterms);
1330 video->sterm = entity;
1331 break; 1271 break;
1332 1272
1333 default: 1273 default:
@@ -1339,7 +1279,7 @@ static int uvc_scan_chain_entity(struct uvc_video_device *video,
1339 return 0; 1279 return 0;
1340} 1280}
1341 1281
1342static int uvc_scan_chain_forward(struct uvc_video_device *video, 1282static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
1343 struct uvc_entity *entity, struct uvc_entity *prev) 1283 struct uvc_entity *entity, struct uvc_entity *prev)
1344{ 1284{
1345 struct uvc_entity *forward; 1285 struct uvc_entity *forward;
@@ -1350,28 +1290,51 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
1350 found = 0; 1290 found = 0;
1351 1291
1352 while (1) { 1292 while (1) {
1353 forward = uvc_entity_by_reference(video->dev, entity->id, 1293 forward = uvc_entity_by_reference(chain->dev, entity->id,
1354 forward); 1294 forward);
1355 if (forward == NULL) 1295 if (forward == NULL)
1356 break; 1296 break;
1357 1297 if (forward == prev)
1358 if (UVC_ENTITY_TYPE(forward) != UVC_VC_EXTENSION_UNIT ||
1359 forward == prev)
1360 continue; 1298 continue;
1361 1299
1362 if (forward->extension.bNrInPins != 1) { 1300 switch (UVC_ENTITY_TYPE(forward)) {
1363 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has " 1301 case UVC_VC_EXTENSION_UNIT:
1364 "more than 1 input pin.\n", entity->id); 1302 if (forward->extension.bNrInPins != 1) {
1365 return -1; 1303 uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
1366 } 1304 "has more than 1 input pin.\n",
1305 entity->id);
1306 return -EINVAL;
1307 }
1308
1309 list_add_tail(&forward->chain, &chain->extensions);
1310 if (uvc_trace_param & UVC_TRACE_PROBE) {
1311 if (!found)
1312 printk(" (->");
1313
1314 printk(" XU %d", forward->id);
1315 found = 1;
1316 }
1317 break;
1318
1319 case UVC_OTT_VENDOR_SPECIFIC:
1320 case UVC_OTT_DISPLAY:
1321 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1322 case UVC_TT_STREAMING:
1323 if (UVC_ENTITY_IS_ITERM(forward)) {
1324 uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
1325 "terminal %u.\n", forward->id);
1326 return -EINVAL;
1327 }
1367 1328
1368 list_add_tail(&forward->chain, &video->extensions); 1329 list_add_tail(&forward->chain, &chain->oterms);
1369 if (uvc_trace_param & UVC_TRACE_PROBE) { 1330 if (uvc_trace_param & UVC_TRACE_PROBE) {
1370 if (!found) 1331 if (!found)
1371 printk(" (-> XU"); 1332 printk(" (->");
1372 1333
1373 printk(" %d", forward->id); 1334 printk(" OT %d", forward->id);
1374 found = 1; 1335 found = 1;
1336 }
1337 break;
1375 } 1338 }
1376 } 1339 }
1377 if (found) 1340 if (found)
@@ -1380,7 +1343,7 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
1380 return 0; 1343 return 0;
1381} 1344}
1382 1345
1383static int uvc_scan_chain_backward(struct uvc_video_device *video, 1346static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
1384 struct uvc_entity *entity) 1347 struct uvc_entity *entity)
1385{ 1348{
1386 struct uvc_entity *term; 1349 struct uvc_entity *term;
@@ -1405,10 +1368,10 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
1405 if (uvc_trace_param & UVC_TRACE_PROBE) 1368 if (uvc_trace_param & UVC_TRACE_PROBE)
1406 printk(" <- IT"); 1369 printk(" <- IT");
1407 1370
1408 video->selector = entity; 1371 chain->selector = entity;
1409 for (i = 0; i < entity->selector.bNrInPins; ++i) { 1372 for (i = 0; i < entity->selector.bNrInPins; ++i) {
1410 id = entity->selector.baSourceID[i]; 1373 id = entity->selector.baSourceID[i];
1411 term = uvc_entity_by_id(video->dev, id); 1374 term = uvc_entity_by_id(chain->dev, id);
1412 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) { 1375 if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
1413 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " 1376 uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
1414 "input %d isn't connected to an " 1377 "input %d isn't connected to an "
@@ -1419,8 +1382,8 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
1419 if (uvc_trace_param & UVC_TRACE_PROBE) 1382 if (uvc_trace_param & UVC_TRACE_PROBE)
1420 printk(" %d", term->id); 1383 printk(" %d", term->id);
1421 1384
1422 list_add_tail(&term->chain, &video->iterms); 1385 list_add_tail(&term->chain, &chain->iterms);
1423 uvc_scan_chain_forward(video, term, entity); 1386 uvc_scan_chain_forward(chain, term, entity);
1424 } 1387 }
1425 1388
1426 if (uvc_trace_param & UVC_TRACE_PROBE) 1389 if (uvc_trace_param & UVC_TRACE_PROBE)
@@ -1433,100 +1396,129 @@ static int uvc_scan_chain_backward(struct uvc_video_device *video,
1433 return id; 1396 return id;
1434} 1397}
1435 1398
1436static int uvc_scan_chain(struct uvc_video_device *video) 1399static int uvc_scan_chain(struct uvc_video_chain *chain,
1400 struct uvc_entity *oterm)
1437{ 1401{
1438 struct uvc_entity *entity, *prev; 1402 struct uvc_entity *entity, *prev;
1439 int id; 1403 int id;
1440 1404
1441 entity = video->oterm; 1405 entity = oterm;
1406 list_add_tail(&entity->chain, &chain->oterms);
1442 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id); 1407 uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
1443 1408
1444 if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
1445 video->sterm = entity;
1446
1447 id = entity->output.bSourceID; 1409 id = entity->output.bSourceID;
1448 while (id != 0) { 1410 while (id != 0) {
1449 prev = entity; 1411 prev = entity;
1450 entity = uvc_entity_by_id(video->dev, id); 1412 entity = uvc_entity_by_id(chain->dev, id);
1451 if (entity == NULL) { 1413 if (entity == NULL) {
1452 uvc_trace(UVC_TRACE_DESCR, "Found reference to " 1414 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1453 "unknown entity %d.\n", id); 1415 "unknown entity %d.\n", id);
1454 return -1; 1416 return -EINVAL;
1417 }
1418
1419 if (entity->chain.next || entity->chain.prev) {
1420 uvc_trace(UVC_TRACE_DESCR, "Found reference to "
1421 "entity %d already in chain.\n", id);
1422 return -EINVAL;
1455 } 1423 }
1456 1424
1457 /* Process entity */ 1425 /* Process entity */
1458 if (uvc_scan_chain_entity(video, entity) < 0) 1426 if (uvc_scan_chain_entity(chain, entity) < 0)
1459 return -1; 1427 return -EINVAL;
1460 1428
1461 /* Forward scan */ 1429 /* Forward scan */
1462 if (uvc_scan_chain_forward(video, entity, prev) < 0) 1430 if (uvc_scan_chain_forward(chain, entity, prev) < 0)
1463 return -1; 1431 return -EINVAL;
1464 1432
1465 /* Stop when a terminal is found. */ 1433 /* Stop when a terminal is found. */
1466 if (!UVC_ENTITY_IS_UNIT(entity)) 1434 if (UVC_ENTITY_IS_TERM(entity))
1467 break; 1435 break;
1468 1436
1469 /* Backward scan */ 1437 /* Backward scan */
1470 id = uvc_scan_chain_backward(video, entity); 1438 id = uvc_scan_chain_backward(chain, entity);
1471 if (id < 0) 1439 if (id < 0)
1472 return id; 1440 return id;
1473 } 1441 }
1474 1442
1475 if (video->sterm == NULL) { 1443 return 0;
1476 uvc_trace(UVC_TRACE_DESCR, "No streaming entity found in " 1444}
1477 "chain.\n"); 1445
1478 return -1; 1446static unsigned int uvc_print_terms(struct list_head *terms, char *buffer)
1447{
1448 struct uvc_entity *term;
1449 unsigned int nterms = 0;
1450 char *p = buffer;
1451
1452 list_for_each_entry(term, terms, chain) {
1453 p += sprintf(p, "%u", term->id);
1454 if (term->chain.next != terms) {
1455 p += sprintf(p, ",");
1456 if (++nterms >= 4) {
1457 p += sprintf(p, "...");
1458 break;
1459 }
1460 }
1479 } 1461 }
1480 1462
1481 return 0; 1463 return p - buffer;
1464}
1465
1466static const char *uvc_print_chain(struct uvc_video_chain *chain)
1467{
1468 static char buffer[43];
1469 char *p = buffer;
1470
1471 p += uvc_print_terms(&chain->iterms, p);
1472 p += sprintf(p, " -> ");
1473 uvc_print_terms(&chain->oterms, p);
1474
1475 return buffer;
1482} 1476}
1483 1477
1484/* 1478/*
1485 * Scan the device for video chains and register video devices. 1479 * Scan the device for video chains and register video devices.
1486 * 1480 *
1487 * The driver currently supports a single video device per control interface 1481 * Chains are scanned starting at their output terminals and walked backwards.
1488 * only. The terminal and units must match the following structure:
1489 *
1490 * ITT_* -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING
1491 * TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
1492 *
1493 * The Extension Units, if present, must have a single input pin. The
1494 * Processing Unit and Extension Units can be in any order. Additional
1495 * Extension Units connected to the main chain as single-unit branches are
1496 * also supported.
1497 */ 1482 */
1498static int uvc_scan_device(struct uvc_device *dev) 1483static int uvc_scan_device(struct uvc_device *dev)
1499{ 1484{
1485 struct uvc_video_chain *chain;
1500 struct uvc_entity *term; 1486 struct uvc_entity *term;
1501 int found = 0;
1502 1487
1503 /* Check if the control interface matches the structure we expect. */
1504 list_for_each_entry(term, &dev->entities, list) { 1488 list_for_each_entry(term, &dev->entities, list) {
1505 struct uvc_streaming *stream; 1489 if (!UVC_ENTITY_IS_OTERM(term))
1506
1507 if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term))
1508 continue; 1490 continue;
1509 1491
1510 memset(&dev->video, 0, sizeof dev->video); 1492 /* If the terminal is already included in a chain, skip it.
1511 mutex_init(&dev->video.ctrl_mutex); 1493 * This can happen for chains that have multiple output
1512 INIT_LIST_HEAD(&dev->video.iterms); 1494 * terminals, where all output terminals beside the first one
1513 INIT_LIST_HEAD(&dev->video.extensions); 1495 * will be inserted in the chain in forward scans.
1514 dev->video.oterm = term; 1496 */
1515 dev->video.dev = dev; 1497 if (term->chain.next || term->chain.prev)
1516 if (uvc_scan_chain(&dev->video) < 0)
1517 continue; 1498 continue;
1518 1499
1519 list_for_each_entry(stream, &dev->streams, list) { 1500 chain = kzalloc(sizeof(*chain), GFP_KERNEL);
1520 if (stream->header.bTerminalLink == 1501 if (chain == NULL)
1521 dev->video.sterm->id) { 1502 return -ENOMEM;
1522 uvc_register_video(dev, stream); 1503
1523 found = 1; 1504 INIT_LIST_HEAD(&chain->iterms);
1524 break; 1505 INIT_LIST_HEAD(&chain->oterms);
1525 } 1506 INIT_LIST_HEAD(&chain->extensions);
1507 mutex_init(&chain->ctrl_mutex);
1508 chain->dev = dev;
1509
1510 if (uvc_scan_chain(chain, term) < 0) {
1511 kfree(chain);
1512 continue;
1526 } 1513 }
1514
1515 uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",
1516 uvc_print_chain(chain));
1517
1518 list_add_tail(&chain->list, &dev->chains);
1527 } 1519 }
1528 1520
1529 if (!found) { 1521 if (list_empty(&dev->chains)) {
1530 uvc_printk(KERN_INFO, "No valid video chain found.\n"); 1522 uvc_printk(KERN_INFO, "No valid video chain found.\n");
1531 return -1; 1523 return -1;
1532 } 1524 }
@@ -1534,6 +1526,133 @@ static int uvc_scan_device(struct uvc_device *dev)
1534 return 0; 1526 return 0;
1535} 1527}
1536 1528
1529/* ------------------------------------------------------------------------
1530 * Video device registration and unregistration
1531 */
1532
1533/*
1534 * Unregister the video devices.
1535 */
1536static void uvc_unregister_video(struct uvc_device *dev)
1537{
1538 struct uvc_streaming *stream;
1539
1540 list_for_each_entry(stream, &dev->streams, list) {
1541 if (stream->vdev == NULL)
1542 continue;
1543
1544 if (stream->vdev->minor == -1)
1545 video_device_release(stream->vdev);
1546 else
1547 video_unregister_device(stream->vdev);
1548 stream->vdev = NULL;
1549 }
1550}
1551
1552static int uvc_register_video(struct uvc_device *dev,
1553 struct uvc_streaming *stream)
1554{
1555 struct video_device *vdev;
1556 int ret;
1557
1558 /* Initialize the streaming interface with default streaming
1559 * parameters.
1560 */
1561 ret = uvc_video_init(stream);
1562 if (ret < 0) {
1563 uvc_printk(KERN_ERR, "Failed to initialize the device "
1564 "(%d).\n", ret);
1565 return ret;
1566 }
1567
1568 /* Register the device with V4L. */
1569 vdev = video_device_alloc();
1570 if (vdev == NULL) {
1571 uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n",
1572 ret);
1573 return -ENOMEM;
1574 }
1575
1576 /* We already hold a reference to dev->udev. The video device will be
1577 * unregistered before the reference is released, so we don't need to
1578 * get another one.
1579 */
1580 vdev->parent = &dev->intf->dev;
1581 vdev->minor = -1;
1582 vdev->fops = &uvc_fops;
1583 vdev->release = video_device_release;
1584 strlcpy(vdev->name, dev->name, sizeof vdev->name);
1585
1586 /* Set the driver data before calling video_register_device, otherwise
1587 * uvc_v4l2_open might race us.
1588 */
1589 stream->vdev = vdev;
1590 video_set_drvdata(vdev, stream);
1591
1592 ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
1593 if (ret < 0) {
1594 uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
1595 ret);
1596 stream->vdev = NULL;
1597 video_device_release(vdev);
1598 return ret;
1599 }
1600
1601 return 0;
1602}
1603
1604/*
1605 * Register all video devices in all chains.
1606 */
1607static int uvc_register_terms(struct uvc_device *dev,
1608 struct uvc_video_chain *chain, struct list_head *terms)
1609{
1610 struct uvc_streaming *stream;
1611 struct uvc_entity *term;
1612 int ret;
1613
1614 list_for_each_entry(term, terms, chain) {
1615 if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
1616 continue;
1617
1618 stream = uvc_stream_by_id(dev, term->id);
1619 if (stream == NULL) {
1620 uvc_printk(KERN_INFO, "No streaming interface found "
1621 "for terminal %u.", term->id);
1622 continue;
1623 }
1624
1625 stream->chain = chain;
1626 ret = uvc_register_video(dev, stream);
1627 if (ret < 0)
1628 return ret;
1629 }
1630
1631 return 0;
1632}
1633
1634static int uvc_register_chains(struct uvc_device *dev)
1635{
1636 struct uvc_video_chain *chain;
1637 int ret;
1638
1639 list_for_each_entry(chain, &dev->chains, list) {
1640 ret = uvc_register_terms(dev, chain, &chain->iterms);
1641 if (ret < 0)
1642 return ret;
1643
1644 ret = uvc_register_terms(dev, chain, &chain->oterms);
1645 if (ret < 0)
1646 return ret;
1647 }
1648
1649 return 0;
1650}
1651
1652/* ------------------------------------------------------------------------
1653 * USB probe, disconnect, suspend and resume
1654 */
1655
1537/* 1656/*
1538 * Delete the UVC device. 1657 * Delete the UVC device.
1539 * 1658 *
@@ -1555,7 +1674,7 @@ void uvc_delete(struct kref *kref)
1555 struct uvc_device *dev = container_of(kref, struct uvc_device, kref); 1674 struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
1556 struct list_head *p, *n; 1675 struct list_head *p, *n;
1557 1676
1558 /* Unregister the video device. */ 1677 /* Unregister the video devices. */
1559 uvc_unregister_video(dev); 1678 uvc_unregister_video(dev);
1560 usb_put_intf(dev->intf); 1679 usb_put_intf(dev->intf);
1561 usb_put_dev(dev->udev); 1680 usb_put_dev(dev->udev);
@@ -1563,6 +1682,12 @@ void uvc_delete(struct kref *kref)
1563 uvc_status_cleanup(dev); 1682 uvc_status_cleanup(dev);
1564 uvc_ctrl_cleanup_device(dev); 1683 uvc_ctrl_cleanup_device(dev);
1565 1684
1685 list_for_each_safe(p, n, &dev->chains) {
1686 struct uvc_video_chain *chain;
1687 chain = list_entry(p, struct uvc_video_chain, list);
1688 kfree(chain);
1689 }
1690
1566 list_for_each_safe(p, n, &dev->entities) { 1691 list_for_each_safe(p, n, &dev->entities) {
1567 struct uvc_entity *entity; 1692 struct uvc_entity *entity;
1568 entity = list_entry(p, struct uvc_entity, list); 1693 entity = list_entry(p, struct uvc_entity, list);
@@ -1603,6 +1728,7 @@ static int uvc_probe(struct usb_interface *intf,
1603 return -ENOMEM; 1728 return -ENOMEM;
1604 1729
1605 INIT_LIST_HEAD(&dev->entities); 1730 INIT_LIST_HEAD(&dev->entities);
1731 INIT_LIST_HEAD(&dev->chains);
1606 INIT_LIST_HEAD(&dev->streams); 1732 INIT_LIST_HEAD(&dev->streams);
1607 kref_init(&dev->kref); 1733 kref_init(&dev->kref);
1608 atomic_set(&dev->users, 0); 1734 atomic_set(&dev->users, 0);
@@ -1644,10 +1770,14 @@ static int uvc_probe(struct usb_interface *intf,
1644 if (uvc_ctrl_init_device(dev) < 0) 1770 if (uvc_ctrl_init_device(dev) < 0)
1645 goto error; 1771 goto error;
1646 1772
1647 /* Scan the device for video chains and register video devices. */ 1773 /* Scan the device for video chains. */
1648 if (uvc_scan_device(dev) < 0) 1774 if (uvc_scan_device(dev) < 0)
1649 goto error; 1775 goto error;
1650 1776
1777 /* Register video devices. */
1778 if (uvc_register_chains(dev) < 0)
1779 goto error;
1780
1651 /* Save our data pointer in the interface data. */ 1781 /* Save our data pointer in the interface data. */
1652 usb_set_intfdata(intf, dev); 1782 usb_set_intfdata(intf, dev);
1653 1783
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c
index 7e847bbaf2a4..9e7351569b5d 100644
--- a/drivers/media/video/uvc/uvc_v4l2.c
+++ b/drivers/media/video/uvc/uvc_v4l2.c
@@ -40,7 +40,7 @@
40 * table for the controls that can be mapped directly, and handle the others 40 * table for the controls that can be mapped directly, and handle the others
41 * manually. 41 * manually.
42 */ 42 */
43static int uvc_v4l2_query_menu(struct uvc_video_device *video, 43static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
44 struct v4l2_querymenu *query_menu) 44 struct v4l2_querymenu *query_menu)
45{ 45{
46 struct uvc_menu_info *menu_info; 46 struct uvc_menu_info *menu_info;
@@ -49,7 +49,7 @@ static int uvc_v4l2_query_menu(struct uvc_video_device *video,
49 u32 index = query_menu->index; 49 u32 index = query_menu->index;
50 u32 id = query_menu->id; 50 u32 id = query_menu->id;
51 51
52 ctrl = uvc_find_control(video, query_menu->id, &mapping); 52 ctrl = uvc_find_control(chain, query_menu->id, &mapping);
53 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) 53 if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU)
54 return -EINVAL; 54 return -EINVAL;
55 55
@@ -451,7 +451,7 @@ static int uvc_v4l2_open(struct file *file)
451 } 451 }
452 } 452 }
453 453
454 handle->video = &stream->dev->video; 454 handle->chain = stream->chain;
455 handle->stream = stream; 455 handle->stream = stream;
456 handle->state = UVC_HANDLE_PASSIVE; 456 handle->state = UVC_HANDLE_PASSIVE;
457 file->private_data = handle; 457 file->private_data = handle;
@@ -498,7 +498,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
498{ 498{
499 struct video_device *vdev = video_devdata(file); 499 struct video_device *vdev = video_devdata(file);
500 struct uvc_fh *handle = (struct uvc_fh *)file->private_data; 500 struct uvc_fh *handle = (struct uvc_fh *)file->private_data;
501 struct uvc_video_device *video = handle->video; 501 struct uvc_video_chain *chain = handle->chain;
502 struct uvc_streaming *stream = handle->stream; 502 struct uvc_streaming *stream = handle->stream;
503 long ret = 0; 503 long ret = 0;
504 504
@@ -525,7 +525,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
525 525
526 /* Get, Set & Query control */ 526 /* Get, Set & Query control */
527 case VIDIOC_QUERYCTRL: 527 case VIDIOC_QUERYCTRL:
528 return uvc_query_v4l2_ctrl(video, arg); 528 return uvc_query_v4l2_ctrl(chain, arg);
529 529
530 case VIDIOC_G_CTRL: 530 case VIDIOC_G_CTRL:
531 { 531 {
@@ -535,12 +535,12 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
535 memset(&xctrl, 0, sizeof xctrl); 535 memset(&xctrl, 0, sizeof xctrl);
536 xctrl.id = ctrl->id; 536 xctrl.id = ctrl->id;
537 537
538 ret = uvc_ctrl_begin(video); 538 ret = uvc_ctrl_begin(chain);
539 if (ret < 0) 539 if (ret < 0)
540 return ret; 540 return ret;
541 541
542 ret = uvc_ctrl_get(video, &xctrl); 542 ret = uvc_ctrl_get(chain, &xctrl);
543 uvc_ctrl_rollback(video); 543 uvc_ctrl_rollback(chain);
544 if (ret >= 0) 544 if (ret >= 0)
545 ctrl->value = xctrl.value; 545 ctrl->value = xctrl.value;
546 break; 546 break;
@@ -555,21 +555,21 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
555 xctrl.id = ctrl->id; 555 xctrl.id = ctrl->id;
556 xctrl.value = ctrl->value; 556 xctrl.value = ctrl->value;
557 557
558 ret = uvc_ctrl_begin(video); 558 uvc_ctrl_begin(chain);
559 if (ret < 0) 559 if (ret < 0)
560 return ret; 560 return ret;
561 561
562 ret = uvc_ctrl_set(video, &xctrl); 562 ret = uvc_ctrl_set(chain, &xctrl);
563 if (ret < 0) { 563 if (ret < 0) {
564 uvc_ctrl_rollback(video); 564 uvc_ctrl_rollback(chain);
565 return ret; 565 return ret;
566 } 566 }
567 ret = uvc_ctrl_commit(video); 567 ret = uvc_ctrl_commit(chain);
568 break; 568 break;
569 } 569 }
570 570
571 case VIDIOC_QUERYMENU: 571 case VIDIOC_QUERYMENU:
572 return uvc_v4l2_query_menu(video, arg); 572 return uvc_v4l2_query_menu(chain, arg);
573 573
574 case VIDIOC_G_EXT_CTRLS: 574 case VIDIOC_G_EXT_CTRLS:
575 { 575 {
@@ -577,20 +577,20 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
577 struct v4l2_ext_control *ctrl = ctrls->controls; 577 struct v4l2_ext_control *ctrl = ctrls->controls;
578 unsigned int i; 578 unsigned int i;
579 579
580 ret = uvc_ctrl_begin(video); 580 ret = uvc_ctrl_begin(chain);
581 if (ret < 0) 581 if (ret < 0)
582 return ret; 582 return ret;
583 583
584 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 584 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
585 ret = uvc_ctrl_get(video, ctrl); 585 ret = uvc_ctrl_get(chain, ctrl);
586 if (ret < 0) { 586 if (ret < 0) {
587 uvc_ctrl_rollback(video); 587 uvc_ctrl_rollback(chain);
588 ctrls->error_idx = i; 588 ctrls->error_idx = i;
589 return ret; 589 return ret;
590 } 590 }
591 } 591 }
592 ctrls->error_idx = 0; 592 ctrls->error_idx = 0;
593 ret = uvc_ctrl_rollback(video); 593 ret = uvc_ctrl_rollback(chain);
594 break; 594 break;
595 } 595 }
596 596
@@ -601,14 +601,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
601 struct v4l2_ext_control *ctrl = ctrls->controls; 601 struct v4l2_ext_control *ctrl = ctrls->controls;
602 unsigned int i; 602 unsigned int i;
603 603
604 ret = uvc_ctrl_begin(video); 604 ret = uvc_ctrl_begin(chain);
605 if (ret < 0) 605 if (ret < 0)
606 return ret; 606 return ret;
607 607
608 for (i = 0; i < ctrls->count; ++ctrl, ++i) { 608 for (i = 0; i < ctrls->count; ++ctrl, ++i) {
609 ret = uvc_ctrl_set(video, ctrl); 609 ret = uvc_ctrl_set(chain, ctrl);
610 if (ret < 0) { 610 if (ret < 0) {
611 uvc_ctrl_rollback(video); 611 uvc_ctrl_rollback(chain);
612 ctrls->error_idx = i; 612 ctrls->error_idx = i;
613 return ret; 613 return ret;
614 } 614 }
@@ -617,31 +617,31 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
617 ctrls->error_idx = 0; 617 ctrls->error_idx = 0;
618 618
619 if (cmd == VIDIOC_S_EXT_CTRLS) 619 if (cmd == VIDIOC_S_EXT_CTRLS)
620 ret = uvc_ctrl_commit(video); 620 ret = uvc_ctrl_commit(chain);
621 else 621 else
622 ret = uvc_ctrl_rollback(video); 622 ret = uvc_ctrl_rollback(chain);
623 break; 623 break;
624 } 624 }
625 625
626 /* Get, Set & Enum input */ 626 /* Get, Set & Enum input */
627 case VIDIOC_ENUMINPUT: 627 case VIDIOC_ENUMINPUT:
628 { 628 {
629 const struct uvc_entity *selector = video->selector; 629 const struct uvc_entity *selector = chain->selector;
630 struct v4l2_input *input = arg; 630 struct v4l2_input *input = arg;
631 struct uvc_entity *iterm = NULL; 631 struct uvc_entity *iterm = NULL;
632 u32 index = input->index; 632 u32 index = input->index;
633 int pin = 0; 633 int pin = 0;
634 634
635 if (selector == NULL || 635 if (selector == NULL ||
636 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 636 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
637 if (index != 0) 637 if (index != 0)
638 return -EINVAL; 638 return -EINVAL;
639 iterm = list_first_entry(&video->iterms, 639 iterm = list_first_entry(&chain->iterms,
640 struct uvc_entity, chain); 640 struct uvc_entity, chain);
641 pin = iterm->id; 641 pin = iterm->id;
642 } else if (pin < selector->selector.bNrInPins) { 642 } else if (pin < selector->selector.bNrInPins) {
643 pin = selector->selector.baSourceID[index]; 643 pin = selector->selector.baSourceID[index];
644 list_for_each_entry(iterm, video->iterms.next, chain) { 644 list_for_each_entry(iterm, chain->iterms.next, chain) {
645 if (iterm->id == pin) 645 if (iterm->id == pin)
646 break; 646 break;
647 } 647 }
@@ -662,14 +662,14 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
662 { 662 {
663 u8 input; 663 u8 input;
664 664
665 if (video->selector == NULL || 665 if (chain->selector == NULL ||
666 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 666 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
667 *(int *)arg = 0; 667 *(int *)arg = 0;
668 break; 668 break;
669 } 669 }
670 670
671 ret = uvc_query_ctrl(video->dev, UVC_GET_CUR, 671 ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
672 video->selector->id, video->dev->intfnum, 672 chain->selector->id, chain->dev->intfnum,
673 UVC_SU_INPUT_SELECT_CONTROL, &input, 1); 673 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
674 if (ret < 0) 674 if (ret < 0)
675 return ret; 675 return ret;
@@ -685,18 +685,18 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
685 if ((ret = uvc_acquire_privileges(handle)) < 0) 685 if ((ret = uvc_acquire_privileges(handle)) < 0)
686 return ret; 686 return ret;
687 687
688 if (video->selector == NULL || 688 if (chain->selector == NULL ||
689 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) { 689 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
690 if (input != 1) 690 if (input != 1)
691 return -EINVAL; 691 return -EINVAL;
692 break; 692 break;
693 } 693 }
694 694
695 if (input == 0 || input > video->selector->selector.bNrInPins) 695 if (input == 0 || input > chain->selector->selector.bNrInPins)
696 return -EINVAL; 696 return -EINVAL;
697 697
698 return uvc_query_ctrl(video->dev, UVC_SET_CUR, 698 return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
699 video->selector->id, video->dev->intfnum, 699 chain->selector->id, chain->dev->intfnum,
700 UVC_SU_INPUT_SELECT_CONTROL, &input, 1); 700 UVC_SU_INPUT_SELECT_CONTROL, &input, 1);
701 } 701 }
702 702
@@ -1019,10 +1019,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1019 } 1019 }
1020 1020
1021 case UVCIOC_CTRL_GET: 1021 case UVCIOC_CTRL_GET:
1022 return uvc_xu_ctrl_query(video, arg, 0); 1022 return uvc_xu_ctrl_query(chain, arg, 0);
1023 1023
1024 case UVCIOC_CTRL_SET: 1024 case UVCIOC_CTRL_SET:
1025 return uvc_xu_ctrl_query(video, arg, 1); 1025 return uvc_xu_ctrl_query(chain, arg, 1);
1026 1026
1027 default: 1027 default:
1028 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg, 1028 if ((ret = v4l_compat_translate_ioctl(file, cmd, arg,
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index acbd73ac6bf4..5b757f32d997 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -128,7 +128,7 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream,
128 if (data == NULL) 128 if (data == NULL)
129 return -ENOMEM; 129 return -ENOMEM;
130 130
131 if ((video->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF) 131 if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF)
132 return -EIO; 132 return -EIO;
133 133
134 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, 134 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h
index 3cd9041e22a1..e7958aa454ce 100644
--- a/drivers/media/video/uvc/uvcvideo.h
+++ b/drivers/media/video/uvc/uvcvideo.h
@@ -80,9 +80,11 @@ struct uvc_xu_control {
80#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0) 80#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
81#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0) 81#define UVC_ENTITY_IS_TERM(entity) (((entity)->type & 0xff00) != 0)
82#define UVC_ENTITY_IS_ITERM(entity) \ 82#define UVC_ENTITY_IS_ITERM(entity) \
83 (((entity)->type & 0x8000) == UVC_TERM_INPUT) 83 (UVC_ENTITY_IS_TERM(entity) && \
84 ((entity)->type & 0x8000) == UVC_TERM_INPUT)
84#define UVC_ENTITY_IS_OTERM(entity) \ 85#define UVC_ENTITY_IS_OTERM(entity) \
85 (((entity)->type & 0x8000) == UVC_TERM_OUTPUT) 86 (UVC_ENTITY_IS_TERM(entity) && \
87 ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
86 88
87 89
88/* ------------------------------------------------------------------------ 90/* ------------------------------------------------------------------------
@@ -402,10 +404,24 @@ struct uvc_video_queue {
402 struct list_head irqqueue; 404 struct list_head irqqueue;
403}; 405};
404 406
407struct uvc_video_chain {
408 struct uvc_device *dev;
409 struct list_head list;
410
411 struct list_head iterms; /* Input terminals */
412 struct list_head oterms; /* Output terminals */
413 struct uvc_entity *processing; /* Processing unit */
414 struct uvc_entity *selector; /* Selector unit */
415 struct list_head extensions; /* Extension units */
416
417 struct mutex ctrl_mutex;
418};
419
405struct uvc_streaming { 420struct uvc_streaming {
406 struct list_head list; 421 struct list_head list;
407 struct uvc_device *dev; 422 struct uvc_device *dev;
408 struct video_device *vdev; 423 struct video_device *vdev;
424 struct uvc_video_chain *chain;
409 atomic_t active; 425 atomic_t active;
410 426
411 struct usb_interface *intf; 427 struct usb_interface *intf;
@@ -446,18 +462,6 @@ struct uvc_streaming {
446 __u8 last_fid; 462 __u8 last_fid;
447}; 463};
448 464
449struct uvc_video_device {
450 struct uvc_device *dev;
451
452 struct list_head iterms; /* Input terminals */
453 struct uvc_entity *oterm; /* Output terminal */
454 struct uvc_entity *sterm; /* USB streaming terminal */
455 struct uvc_entity *processing;
456 struct uvc_entity *selector;
457 struct list_head extensions;
458 struct mutex ctrl_mutex;
459};
460
461enum uvc_device_state { 465enum uvc_device_state {
462 UVC_DEV_DISCONNECTED = 1, 466 UVC_DEV_DISCONNECTED = 1,
463}; 467};
@@ -480,8 +484,7 @@ struct uvc_device {
480 __u32 clock_frequency; 484 __u32 clock_frequency;
481 485
482 struct list_head entities; 486 struct list_head entities;
483 487 struct list_head chains;
484 struct uvc_video_device video;
485 488
486 /* Video Streaming interfaces */ 489 /* Video Streaming interfaces */
487 struct list_head streams; 490 struct list_head streams;
@@ -500,7 +503,7 @@ enum uvc_handle_state {
500}; 503};
501 504
502struct uvc_fh { 505struct uvc_fh {
503 struct uvc_video_device *video; 506 struct uvc_video_chain *chain;
504 struct uvc_streaming *stream; 507 struct uvc_streaming *stream;
505 enum uvc_handle_state state; 508 enum uvc_handle_state state;
506}; 509};
@@ -618,9 +621,9 @@ extern int uvc_status_suspend(struct uvc_device *dev);
618extern int uvc_status_resume(struct uvc_device *dev); 621extern int uvc_status_resume(struct uvc_device *dev);
619 622
620/* Controls */ 623/* Controls */
621extern struct uvc_control *uvc_find_control(struct uvc_video_device *video, 624extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
622 __u32 v4l2_id, struct uvc_control_mapping **mapping); 625 __u32 v4l2_id, struct uvc_control_mapping **mapping);
623extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video, 626extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
624 struct v4l2_queryctrl *v4l2_ctrl); 627 struct v4l2_queryctrl *v4l2_ctrl);
625 628
626extern int uvc_ctrl_add_info(struct uvc_control_info *info); 629extern int uvc_ctrl_add_info(struct uvc_control_info *info);
@@ -630,23 +633,23 @@ extern void uvc_ctrl_cleanup_device(struct uvc_device *dev);
630extern int uvc_ctrl_resume_device(struct uvc_device *dev); 633extern int uvc_ctrl_resume_device(struct uvc_device *dev);
631extern void uvc_ctrl_init(void); 634extern void uvc_ctrl_init(void);
632 635
633extern int uvc_ctrl_begin(struct uvc_video_device *video); 636extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
634extern int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback); 637extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback);
635static inline int uvc_ctrl_commit(struct uvc_video_device *video) 638static inline int uvc_ctrl_commit(struct uvc_video_chain *chain)
636{ 639{
637 return __uvc_ctrl_commit(video, 0); 640 return __uvc_ctrl_commit(chain, 0);
638} 641}
639static inline int uvc_ctrl_rollback(struct uvc_video_device *video) 642static inline int uvc_ctrl_rollback(struct uvc_video_chain *chain)
640{ 643{
641 return __uvc_ctrl_commit(video, 1); 644 return __uvc_ctrl_commit(chain, 1);
642} 645}
643 646
644extern int uvc_ctrl_get(struct uvc_video_device *video, 647extern int uvc_ctrl_get(struct uvc_video_chain *chain,
645 struct v4l2_ext_control *xctrl); 648 struct v4l2_ext_control *xctrl);
646extern int uvc_ctrl_set(struct uvc_video_device *video, 649extern int uvc_ctrl_set(struct uvc_video_chain *chain,
647 struct v4l2_ext_control *xctrl); 650 struct v4l2_ext_control *xctrl);
648 651
649extern int uvc_xu_ctrl_query(struct uvc_video_device *video, 652extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
650 struct uvc_xu_control *ctrl, int set); 653 struct uvc_xu_control *ctrl, int set);
651 654
652/* Utility functions */ 655/* Utility functions */