diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2010-09-29 15:00:08 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-10-20 23:18:23 -0400 |
commit | 071c8bb827c80a68510a1cdb7e8bebbda1a494d6 (patch) | |
tree | d2bd4add49795a09ff038a492e8901dbe1b3470f | |
parent | 8fb91b33c6bfa3ac5e4ad76920b7bcd7bdbbb6d0 (diff) |
[media] uvcvideo: Embed uvc_control_info inside struct uvc_control
Now that control information structures are not shared between control
instances, embed a uvc_control_info instance inside the uvc_control
structure instead of storing a pointer.
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/uvc/uvc_ctrl.c | 130 | ||||
-rw-r--r-- | drivers/media/video/uvc/uvcvideo.h | 11 |
2 files changed, 68 insertions, 73 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index 531a3e1a6d17..97a2395671b5 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -643,7 +643,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { | |||
643 | 643 | ||
644 | static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) | 644 | static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) |
645 | { | 645 | { |
646 | return ctrl->uvc_data + id * ctrl->info->size; | 646 | return ctrl->uvc_data + id * ctrl->info.size; |
647 | } | 647 | } |
648 | 648 | ||
649 | static inline int uvc_test_bit(const __u8 *data, int bit) | 649 | static inline int uvc_test_bit(const __u8 *data, int bit) |
@@ -766,10 +766,10 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
766 | 766 | ||
767 | for (i = 0; i < entity->ncontrols; ++i) { | 767 | for (i = 0; i < entity->ncontrols; ++i) { |
768 | ctrl = &entity->controls[i]; | 768 | ctrl = &entity->controls[i]; |
769 | if (ctrl->info == NULL) | 769 | if (!ctrl->initialized) |
770 | continue; | 770 | continue; |
771 | 771 | ||
772 | list_for_each_entry(map, &ctrl->info->mappings, list) { | 772 | list_for_each_entry(map, &ctrl->info.mappings, list) { |
773 | if ((map->id == v4l2_id) && !next) { | 773 | if ((map->id == v4l2_id) && !next) { |
774 | *control = ctrl; | 774 | *control = ctrl; |
775 | *mapping = map; | 775 | *mapping = map; |
@@ -816,36 +816,36 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, | |||
816 | { | 816 | { |
817 | int ret; | 817 | int ret; |
818 | 818 | ||
819 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 819 | if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { |
820 | ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, | 820 | ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, |
821 | chain->dev->intfnum, ctrl->info->selector, | 821 | chain->dev->intfnum, ctrl->info.selector, |
822 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), | 822 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), |
823 | ctrl->info->size); | 823 | ctrl->info.size); |
824 | if (ret < 0) | 824 | if (ret < 0) |
825 | return ret; | 825 | return ret; |
826 | } | 826 | } |
827 | 827 | ||
828 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { | 828 | if (ctrl->info.flags & UVC_CONTROL_GET_MIN) { |
829 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, | 829 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, |
830 | chain->dev->intfnum, ctrl->info->selector, | 830 | chain->dev->intfnum, ctrl->info.selector, |
831 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), | 831 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), |
832 | ctrl->info->size); | 832 | ctrl->info.size); |
833 | if (ret < 0) | 833 | if (ret < 0) |
834 | return ret; | 834 | return ret; |
835 | } | 835 | } |
836 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { | 836 | if (ctrl->info.flags & UVC_CONTROL_GET_MAX) { |
837 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, | 837 | ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, |
838 | chain->dev->intfnum, ctrl->info->selector, | 838 | chain->dev->intfnum, ctrl->info.selector, |
839 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), | 839 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), |
840 | ctrl->info->size); | 840 | ctrl->info.size); |
841 | if (ret < 0) | 841 | if (ret < 0) |
842 | return ret; | 842 | return ret; |
843 | } | 843 | } |
844 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) { | 844 | if (ctrl->info.flags & UVC_CONTROL_GET_RES) { |
845 | ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, | 845 | ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, |
846 | chain->dev->intfnum, ctrl->info->selector, | 846 | chain->dev->intfnum, ctrl->info.selector, |
847 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), | 847 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), |
848 | ctrl->info->size); | 848 | ctrl->info.size); |
849 | if (ret < 0) | 849 | if (ret < 0) |
850 | return ret; | 850 | return ret; |
851 | } | 851 | } |
@@ -873,9 +873,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
873 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); | 873 | strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); |
874 | v4l2_ctrl->flags = 0; | 874 | v4l2_ctrl->flags = 0; |
875 | 875 | ||
876 | if (!(ctrl->info->flags & UVC_CONTROL_GET_CUR)) | 876 | if (!(ctrl->info.flags & UVC_CONTROL_GET_CUR)) |
877 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; | 877 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; |
878 | if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) | 878 | if (!(ctrl->info.flags & UVC_CONTROL_SET_CUR)) |
879 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; | 879 | v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; |
880 | 880 | ||
881 | if (!ctrl->cached) { | 881 | if (!ctrl->cached) { |
@@ -884,7 +884,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
884 | return ret; | 884 | return ret; |
885 | } | 885 | } |
886 | 886 | ||
887 | if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { | 887 | if (ctrl->info.flags & UVC_CONTROL_GET_DEF) { |
888 | v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, | 888 | v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, |
889 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); | 889 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); |
890 | } | 890 | } |
@@ -921,15 +921,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | |||
921 | break; | 921 | break; |
922 | } | 922 | } |
923 | 923 | ||
924 | if (ctrl->info->flags & UVC_CONTROL_GET_MIN) | 924 | if (ctrl->info.flags & UVC_CONTROL_GET_MIN) |
925 | v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, | 925 | v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, |
926 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); | 926 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); |
927 | 927 | ||
928 | if (ctrl->info->flags & UVC_CONTROL_GET_MAX) | 928 | if (ctrl->info.flags & UVC_CONTROL_GET_MAX) |
929 | v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, | 929 | v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, |
930 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); | 930 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); |
931 | 931 | ||
932 | if (ctrl->info->flags & UVC_CONTROL_GET_RES) | 932 | if (ctrl->info.flags & UVC_CONTROL_GET_RES) |
933 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, | 933 | v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, |
934 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); | 934 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); |
935 | 935 | ||
@@ -978,14 +978,14 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, | |||
978 | 978 | ||
979 | for (i = 0; i < entity->ncontrols; ++i) { | 979 | for (i = 0; i < entity->ncontrols; ++i) { |
980 | ctrl = &entity->controls[i]; | 980 | ctrl = &entity->controls[i]; |
981 | if (ctrl->info == NULL) | 981 | if (!ctrl->initialized) |
982 | continue; | 982 | continue; |
983 | 983 | ||
984 | /* Reset the loaded flag for auto-update controls that were | 984 | /* Reset the loaded flag for auto-update controls that were |
985 | * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent | 985 | * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent |
986 | * uvc_ctrl_get from using the cached value. | 986 | * uvc_ctrl_get from using the cached value. |
987 | */ | 987 | */ |
988 | if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) | 988 | if (ctrl->info.flags & UVC_CONTROL_AUTO_UPDATE) |
989 | ctrl->loaded = 0; | 989 | ctrl->loaded = 0; |
990 | 990 | ||
991 | if (!ctrl->dirty) | 991 | if (!ctrl->dirty) |
@@ -993,16 +993,16 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, | |||
993 | 993 | ||
994 | if (!rollback) | 994 | if (!rollback) |
995 | ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, | 995 | ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, |
996 | dev->intfnum, ctrl->info->selector, | 996 | dev->intfnum, ctrl->info.selector, |
997 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 997 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
998 | ctrl->info->size); | 998 | ctrl->info.size); |
999 | else | 999 | else |
1000 | ret = 0; | 1000 | ret = 0; |
1001 | 1001 | ||
1002 | if (rollback || ret < 0) | 1002 | if (rollback || ret < 0) |
1003 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1003 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1004 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1004 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1005 | ctrl->info->size); | 1005 | ctrl->info.size); |
1006 | 1006 | ||
1007 | ctrl->dirty = 0; | 1007 | ctrl->dirty = 0; |
1008 | 1008 | ||
@@ -1040,14 +1040,14 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, | |||
1040 | int ret; | 1040 | int ret; |
1041 | 1041 | ||
1042 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1042 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1043 | if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) | 1043 | if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) |
1044 | return -EINVAL; | 1044 | return -EINVAL; |
1045 | 1045 | ||
1046 | if (!ctrl->loaded) { | 1046 | if (!ctrl->loaded) { |
1047 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, | 1047 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, |
1048 | chain->dev->intfnum, ctrl->info->selector, | 1048 | chain->dev->intfnum, ctrl->info.selector, |
1049 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1049 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1050 | ctrl->info->size); | 1050 | ctrl->info.size); |
1051 | if (ret < 0) | 1051 | if (ret < 0) |
1052 | return ret; | 1052 | return ret; |
1053 | 1053 | ||
@@ -1082,7 +1082,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1082 | int ret; | 1082 | int ret; |
1083 | 1083 | ||
1084 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); | 1084 | ctrl = uvc_find_control(chain, xctrl->id, &mapping); |
1085 | if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) | 1085 | if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_SET_CUR) == 0) |
1086 | return -EINVAL; | 1086 | return -EINVAL; |
1087 | 1087 | ||
1088 | /* Clamp out of range values. */ | 1088 | /* Clamp out of range values. */ |
@@ -1128,16 +1128,16 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1128 | * needs to be loaded from the device to perform the read-modify-write | 1128 | * needs to be loaded from the device to perform the read-modify-write |
1129 | * operation. | 1129 | * operation. |
1130 | */ | 1130 | */ |
1131 | if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { | 1131 | if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) { |
1132 | if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { | 1132 | if ((ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) { |
1133 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1133 | memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1134 | 0, ctrl->info->size); | 1134 | 0, ctrl->info.size); |
1135 | } else { | 1135 | } else { |
1136 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, | 1136 | ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, |
1137 | ctrl->entity->id, chain->dev->intfnum, | 1137 | ctrl->entity->id, chain->dev->intfnum, |
1138 | ctrl->info->selector, | 1138 | ctrl->info.selector, |
1139 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1139 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1140 | ctrl->info->size); | 1140 | ctrl->info.size); |
1141 | if (ret < 0) | 1141 | if (ret < 0) |
1142 | return ret; | 1142 | return ret; |
1143 | } | 1143 | } |
@@ -1149,7 +1149,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, | |||
1149 | if (!ctrl->dirty) { | 1149 | if (!ctrl->dirty) { |
1150 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), | 1150 | memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), |
1151 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), | 1151 | uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), |
1152 | ctrl->info->size); | 1152 | ctrl->info.size); |
1153 | } | 1153 | } |
1154 | 1154 | ||
1155 | mapping->set(mapping, value, | 1155 | mapping->set(mapping, value, |
@@ -1189,10 +1189,10 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1189 | /* Find the control. */ | 1189 | /* Find the control. */ |
1190 | for (i = 0; i < entity->ncontrols; ++i) { | 1190 | for (i = 0; i < entity->ncontrols; ++i) { |
1191 | ctrl = &entity->controls[i]; | 1191 | ctrl = &entity->controls[i]; |
1192 | if (ctrl->info == NULL) | 1192 | if (!ctrl->initialized) |
1193 | continue; | 1193 | continue; |
1194 | 1194 | ||
1195 | if (ctrl->info->selector == xctrl->selector) { | 1195 | if (ctrl->info.selector == xctrl->selector) { |
1196 | found = 1; | 1196 | found = 1; |
1197 | break; | 1197 | break; |
1198 | } | 1198 | } |
@@ -1205,11 +1205,11 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, | |||
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | /* Validate control data size. */ | 1207 | /* Validate control data size. */ |
1208 | if (ctrl->info->size != xctrl->size) | 1208 | if (ctrl->info.size != xctrl->size) |
1209 | return -EINVAL; | 1209 | return -EINVAL; |
1210 | 1210 | ||
1211 | if ((set && !(ctrl->info->flags & UVC_CONTROL_SET_CUR)) || | 1211 | if ((set && !(ctrl->info.flags & UVC_CONTROL_SET_CUR)) || |
1212 | (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR))) | 1212 | (!set && !(ctrl->info.flags & UVC_CONTROL_GET_CUR))) |
1213 | return -EINVAL; | 1213 | return -EINVAL; |
1214 | 1214 | ||
1215 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) | 1215 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) |
@@ -1272,13 +1272,13 @@ int uvc_ctrl_resume_device(struct uvc_device *dev) | |||
1272 | for (i = 0; i < entity->ncontrols; ++i) { | 1272 | for (i = 0; i < entity->ncontrols; ++i) { |
1273 | ctrl = &entity->controls[i]; | 1273 | ctrl = &entity->controls[i]; |
1274 | 1274 | ||
1275 | if (ctrl->info == NULL || !ctrl->modified || | 1275 | if (!ctrl->initialized || !ctrl->modified || |
1276 | (ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) | 1276 | (ctrl->info.flags & UVC_CONTROL_RESTORE) == 0) |
1277 | continue; | 1277 | continue; |
1278 | 1278 | ||
1279 | printk(KERN_INFO "restoring control %pUl/%u/%u\n", | 1279 | printk(KERN_INFO "restoring control %pUl/%u/%u\n", |
1280 | ctrl->info->entity, ctrl->info->index, | 1280 | ctrl->info.entity, ctrl->info.index, |
1281 | ctrl->info->selector); | 1281 | ctrl->info.selector); |
1282 | ctrl->dirty = 1; | 1282 | ctrl->dirty = 1; |
1283 | } | 1283 | } |
1284 | 1284 | ||
@@ -1361,31 +1361,26 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, | |||
1361 | { | 1361 | { |
1362 | int ret = 0; | 1362 | int ret = 0; |
1363 | 1363 | ||
1364 | /* Clone the control info struct for this device's instance */ | 1364 | memcpy(&ctrl->info, info, sizeof(*info)); |
1365 | ctrl->info = kmemdup(info, sizeof(*info), GFP_KERNEL); | 1365 | INIT_LIST_HEAD(&ctrl->info.mappings); |
1366 | if (ctrl->info == NULL) { | ||
1367 | ret = -ENOMEM; | ||
1368 | goto done; | ||
1369 | } | ||
1370 | INIT_LIST_HEAD(&ctrl->info->mappings); | ||
1371 | 1366 | ||
1372 | /* Allocate an array to save control values (cur, def, max, etc.) */ | 1367 | /* Allocate an array to save control values (cur, def, max, etc.) */ |
1373 | ctrl->uvc_data = kzalloc(ctrl->info->size * UVC_CTRL_DATA_LAST + 1, | 1368 | ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1, |
1374 | GFP_KERNEL); | 1369 | GFP_KERNEL); |
1375 | if (ctrl->uvc_data == NULL) { | 1370 | if (ctrl->uvc_data == NULL) { |
1376 | ret = -ENOMEM; | 1371 | ret = -ENOMEM; |
1377 | goto done; | 1372 | goto done; |
1378 | } | 1373 | } |
1379 | 1374 | ||
1375 | ctrl->initialized = 1; | ||
1376 | |||
1380 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " | 1377 | uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " |
1381 | "entity %u\n", ctrl->info->entity, ctrl->info->selector, | 1378 | "entity %u\n", ctrl->info.entity, ctrl->info.selector, |
1382 | dev->udev->devpath, ctrl->entity->id); | 1379 | dev->udev->devpath, ctrl->entity->id); |
1383 | 1380 | ||
1384 | done: | 1381 | done: |
1385 | if (ret < 0) { | 1382 | if (ret < 0) |
1386 | kfree(ctrl->uvc_data); | 1383 | kfree(ctrl->uvc_data); |
1387 | kfree(ctrl->info); | ||
1388 | } | ||
1389 | return ret; | 1384 | return ret; |
1390 | } | 1385 | } |
1391 | 1386 | ||
@@ -1418,11 +1413,11 @@ static int __uvc_ctrl_add_mapping(struct uvc_device *dev, | |||
1418 | if (map->set == NULL) | 1413 | if (map->set == NULL) |
1419 | map->set = uvc_set_le_value; | 1414 | map->set = uvc_set_le_value; |
1420 | 1415 | ||
1421 | map->ctrl = ctrl->info; | 1416 | map->ctrl = &ctrl->info; |
1422 | list_add_tail(&map->list, &ctrl->info->mappings); | 1417 | list_add_tail(&map->list, &ctrl->info.mappings); |
1423 | uvc_trace(UVC_TRACE_CONTROL, | 1418 | uvc_trace(UVC_TRACE_CONTROL, |
1424 | "Adding mapping '%s' to control %pUl/%u.\n", | 1419 | "Adding mapping '%s' to control %pUl/%u.\n", |
1425 | map->name, ctrl->info->entity, ctrl->info->selector); | 1420 | map->name, ctrl->info.entity, ctrl->info.selector); |
1426 | 1421 | ||
1427 | return 0; | 1422 | return 0; |
1428 | } | 1423 | } |
@@ -1453,8 +1448,8 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | |||
1453 | 1448 | ||
1454 | for (i = 0; i < entity->ncontrols; ++i) { | 1449 | for (i = 0; i < entity->ncontrols; ++i) { |
1455 | ctrl = &entity->controls[i]; | 1450 | ctrl = &entity->controls[i]; |
1456 | if (ctrl->info != NULL && | 1451 | if (ctrl->initialized && |
1457 | ctrl->info->selector == mapping->selector) { | 1452 | ctrl->info.selector == mapping->selector) { |
1458 | found = 1; | 1453 | found = 1; |
1459 | break; | 1454 | break; |
1460 | } | 1455 | } |
@@ -1469,7 +1464,7 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | |||
1469 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) | 1464 | if (mutex_lock_interruptible(&chain->ctrl_mutex)) |
1470 | return -ERESTARTSYS; | 1465 | return -ERESTARTSYS; |
1471 | 1466 | ||
1472 | list_for_each_entry(map, &ctrl->info->mappings, list) { | 1467 | list_for_each_entry(map, &ctrl->info.mappings, list) { |
1473 | if (mapping->id == map->id) { | 1468 | if (mapping->id == map->id) { |
1474 | uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " | 1469 | uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " |
1475 | "control id 0x%08x already exists.\n", | 1470 | "control id 0x%08x already exists.\n", |
@@ -1601,12 +1596,12 @@ static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl) | |||
1601 | } | 1596 | } |
1602 | } | 1597 | } |
1603 | 1598 | ||
1604 | if (ctrl->info == NULL) | 1599 | if (!ctrl->initialized) |
1605 | return; | 1600 | return; |
1606 | 1601 | ||
1607 | for (; mapping < mend; ++mapping) { | 1602 | for (; mapping < mend; ++mapping) { |
1608 | if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && | 1603 | if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && |
1609 | ctrl->info->selector == mapping->selector) | 1604 | ctrl->info.selector == mapping->selector) |
1610 | __uvc_ctrl_add_mapping(dev, ctrl, mapping); | 1605 | __uvc_ctrl_add_mapping(dev, ctrl, mapping); |
1611 | } | 1606 | } |
1612 | } | 1607 | } |
@@ -1676,7 +1671,7 @@ static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev, | |||
1676 | { | 1671 | { |
1677 | struct uvc_control_mapping *mapping, *nm; | 1672 | struct uvc_control_mapping *mapping, *nm; |
1678 | 1673 | ||
1679 | list_for_each_entry_safe(mapping, nm, &ctrl->info->mappings, list) { | 1674 | list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) { |
1680 | list_del(&mapping->list); | 1675 | list_del(&mapping->list); |
1681 | kfree(mapping->menu_info); | 1676 | kfree(mapping->menu_info); |
1682 | kfree(mapping); | 1677 | kfree(mapping); |
@@ -1693,12 +1688,11 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev) | |||
1693 | for (i = 0; i < entity->ncontrols; ++i) { | 1688 | for (i = 0; i < entity->ncontrols; ++i) { |
1694 | struct uvc_control *ctrl = &entity->controls[i]; | 1689 | struct uvc_control *ctrl = &entity->controls[i]; |
1695 | 1690 | ||
1696 | if (ctrl->info == NULL) | 1691 | if (!ctrl->initialized) |
1697 | continue; | 1692 | continue; |
1698 | 1693 | ||
1699 | uvc_ctrl_cleanup_mappings(dev, ctrl); | 1694 | uvc_ctrl_cleanup_mappings(dev, ctrl); |
1700 | kfree(ctrl->uvc_data); | 1695 | kfree(ctrl->uvc_data); |
1701 | kfree(ctrl->info); | ||
1702 | } | 1696 | } |
1703 | 1697 | ||
1704 | kfree(entity->controls); | 1698 | kfree(entity->controls); |
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 39e9e36e8839..7d67d95de838 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -236,14 +236,15 @@ struct uvc_control_mapping { | |||
236 | 236 | ||
237 | struct uvc_control { | 237 | struct uvc_control { |
238 | struct uvc_entity *entity; | 238 | struct uvc_entity *entity; |
239 | struct uvc_control_info *info; | 239 | struct uvc_control_info info; |
240 | 240 | ||
241 | __u8 index; /* Used to match the uvc_control entry with a | 241 | __u8 index; /* Used to match the uvc_control entry with a |
242 | uvc_control_info. */ | 242 | uvc_control_info. */ |
243 | __u8 dirty : 1, | 243 | __u8 dirty:1, |
244 | loaded : 1, | 244 | loaded:1, |
245 | modified : 1, | 245 | modified:1, |
246 | cached : 1; | 246 | cached:1, |
247 | initialized:1; | ||
247 | 248 | ||
248 | __u8 *uvc_data; | 249 | __u8 *uvc_data; |
249 | }; | 250 | }; |