return 0;
 }
 
-int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
+static int __uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
+       struct uvc_control *ctrl,
+       struct uvc_control_mapping *mapping,
        struct v4l2_queryctrl *v4l2_ctrl)
 {
-       struct uvc_control *ctrl;
-       struct uvc_control_mapping *mapping;
        struct uvc_menu_info *menu;
        unsigned int i;
-       int ret;
-
-       ret = mutex_lock_interruptible(&chain->ctrl_mutex);
-       if (ret < 0)
-               return -ERESTARTSYS;
-
-       ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
-       if (ctrl == NULL) {
-               ret = -EINVAL;
-               goto done;
-       }
 
        memset(v4l2_ctrl, 0, sizeof *v4l2_ctrl);
        v4l2_ctrl->id = mapping->id;
                v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 
        if (!ctrl->cached) {
-               ret = uvc_ctrl_populate_cache(chain, ctrl);
+               int ret = uvc_ctrl_populate_cache(chain, ctrl);
                if (ret < 0)
-                       goto done;
+                       return ret;
        }
 
        if (ctrl->info.flags & UVC_CTRL_FLAG_GET_DEF) {
                        }
                }
 
-               goto done;
+               return 0;
 
        case V4L2_CTRL_TYPE_BOOLEAN:
                v4l2_ctrl->minimum = 0;
                v4l2_ctrl->maximum = 1;
                v4l2_ctrl->step = 1;
-               goto done;
+               return 0;
 
        case V4L2_CTRL_TYPE_BUTTON:
                v4l2_ctrl->minimum = 0;
                v4l2_ctrl->maximum = 0;
                v4l2_ctrl->step = 0;
-               goto done;
+               return 0;
 
        default:
                break;
                v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
                                  uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
 
+       return 0;
+}
+
+int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
+       struct v4l2_queryctrl *v4l2_ctrl)
+{
+       struct uvc_control *ctrl;
+       struct uvc_control_mapping *mapping;
+       int ret;
+
+       ret = mutex_lock_interruptible(&chain->ctrl_mutex);
+       if (ret < 0)
+               return -ERESTARTSYS;
+
+       ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
+       if (ctrl == NULL) {
+               ret = -EINVAL;
+               goto done;
+       }
+
+       ret = __uvc_query_v4l2_ctrl(chain, ctrl, mapping, v4l2_ctrl);
 done:
        mutex_unlock(&chain->ctrl_mutex);
        return ret;
        return ret;
 }
 
-int uvc_ctrl_get(struct uvc_video_chain *chain,
-       struct v4l2_ext_control *xctrl)
+static int __uvc_ctrl_get(struct uvc_video_chain *chain,
+       struct uvc_control *ctrl, struct uvc_control_mapping *mapping,
+       s32 *value)
 {
-       struct uvc_control *ctrl;
-       struct uvc_control_mapping *mapping;
        struct uvc_menu_info *menu;
        unsigned int i;
        int ret;
 
-       ctrl = uvc_find_control(chain, xctrl->id, &mapping);
-       if (ctrl == NULL || (ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
+       if ((ctrl->info.flags & UVC_CTRL_FLAG_GET_CUR) == 0)
                return -EINVAL;
 
        if (!ctrl->loaded) {
                ctrl->loaded = 1;
        }
 
-       xctrl->value = mapping->get(mapping, UVC_GET_CUR,
+       *value = mapping->get(mapping, UVC_GET_CUR,
                uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT));
 
        if (mapping->v4l2_type == V4L2_CTRL_TYPE_MENU) {
                menu = mapping->menu_info;
                for (i = 0; i < mapping->menu_count; ++i, ++menu) {
-                       if (menu->value == xctrl->value) {
-                               xctrl->value = i;
+                       if (menu->value == *value) {
+                               *value = i;
                                break;
                        }
                }
        return 0;
 }
 
+int uvc_ctrl_get(struct uvc_video_chain *chain,
+       struct v4l2_ext_control *xctrl)
+{
+       struct uvc_control *ctrl;
+       struct uvc_control_mapping *mapping;
+
+       ctrl = uvc_find_control(chain, xctrl->id, &mapping);
+       if (ctrl == NULL)
+               return -EINVAL;
+
+       return __uvc_ctrl_get(chain, ctrl, mapping, &xctrl->value);
+}
+
 int uvc_ctrl_set(struct uvc_video_chain *chain,
        struct v4l2_ext_control *xctrl)
 {