| @@ -1158,8 +1158,7 @@ static int new_to_user(struct v4l2_ext_control *c, · 1157 unmodified lines |
| 1158 | } | 1158 | } |
| 1159 | | 1159 | |
| 1160 | /* Copy the new value to the current value. */ | 1160 | /* Copy the new value to the current value. */ |
| 1161 | static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, | 1161 | static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, u32 ch_flags) |
| 1162 | bool update_inactive) | | |
| 1163 | { | 1162 | { |
| 1164 | bool changed = false; | 1163 | bool changed = false; |
| 1165 | | 1164 | |
| @@ -1183,8 +1182,8 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, · 17 unmodified lines |
| 1183 | ctrl->cur.val = ctrl->val; | 1182 | ctrl->cur.val = ctrl->val; |
| 1184 | break; | 1183 | break; |
| 1185 | } | 1184 | } |
| 1186 | if (update_inactive) { | 1185 | if (ch_flags & V4L2_EVENT_CTRL_CH_FLAGS) { |
| 1187 | /* Note: update_inactive can only be true for auto clusters. */ | 1186 | /* Note: CH_FLAGS is only set for auto clusters. */ |
| 1188 | ctrl->flags &= | 1187 | ctrl->flags &= |
| 1189 | ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE); | 1188 | ~(V4L2_CTRL_FLAG_INACTIVE | V4L2_CTRL_FLAG_VOLATILE); |
| 1190 | if (!is_cur_manual(ctrl->cluster[0])) { | 1189 | if (!is_cur_manual(ctrl->cluster[0])) { |
| @@ -1194,14 +1193,13 @@ static void new_to_cur(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, · 3 unmodified lines |
| 1194 | } | 1193 | } |
| 1195 | fh = NULL; | 1194 | fh = NULL; |
| 1196 | } | 1195 | } |
| 1197 | if (changed || update_inactive) { | 1196 | if (changed || ch_flags) { |
| 1198 | /* If a control was changed that was not one of the controls | 1197 | /* If a control was changed that was not one of the controls |
| 1199 | modified by the application, then send the event to all. */ | 1198 | modified by the application, then send the event to all. */ |
| 1200 | if (!ctrl->is_new) | 1199 | if (!ctrl->is_new) |
| 1201 | fh = NULL; | 1200 | fh = NULL; |
| 1202 | send_event(fh, ctrl, | 1201 | send_event(fh, ctrl, |
| 1203 | (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | | 1202 | (changed ? V4L2_EVENT_CTRL_CH_VALUE : 0) | ch_flags); |
| 1204 | (update_inactive ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); | | |
| 1205 | if (ctrl->call_notify && changed && ctrl->handler->notify) | 1203 | if (ctrl->call_notify && changed && ctrl->handler->notify) |
| 1206 | ctrl->handler->notify(ctrl, ctrl->handler->notify_priv); | 1204 | ctrl->handler->notify(ctrl, ctrl->handler->notify_priv); |
| 1207 | } | 1205 | } |
| @@ -1257,6 +1255,41 @@ static int cluster_changed(struct v4l2_ctrl *master) · 49 unmodified lines |
| 1257 | return diff; | 1255 | return diff; |
| 1258 | } | 1256 | } |
| 1259 | | 1257 | |
| | 1258 | /* Control range checking */ |
| | 1259 | static int check_range(enum v4l2_ctrl_type type, |
| | 1260 | s32 min, s32 max, u32 step, s32 def) |
| | 1261 | { |
| | 1262 | switch (type) { |
| | 1263 | case V4L2_CTRL_TYPE_BOOLEAN: |
| | 1264 | if (step != 1 || max > 1 || min < 0) |
| | 1265 | return -ERANGE; |
| | 1266 | /* fall through */ |
| | 1267 | case V4L2_CTRL_TYPE_INTEGER: |
| | 1268 | if (step <= 0 || min > max || def < min || def > max) |
| | 1269 | return -ERANGE; |
| | 1270 | return 0; |
| | 1271 | case V4L2_CTRL_TYPE_BITMASK: |
| | 1272 | if (step || min || !max || (def & ~max)) |
| | 1273 | return -ERANGE; |
| | 1274 | return 0; |
| | 1275 | case V4L2_CTRL_TYPE_MENU: |
| | 1276 | case V4L2_CTRL_TYPE_INTEGER_MENU: |
| | 1277 | if (min > max || def < min || def > max) |
| | 1278 | return -ERANGE; |
| | 1279 | /* Note: step == menu_skip_mask for menu controls. |
| | 1280 | So here we check if the default value is masked out. */ |
| | 1281 | if (step && ((1 << def) & step)) |
| | 1282 | return -EINVAL; |
| | 1283 | return 0; |
| | 1284 | case V4L2_CTRL_TYPE_STRING: |
| | 1285 | if (min > max || min < 0 || step < 1 || def) |
| | 1286 | return -ERANGE; |
| | 1287 | return 0; |
| | 1288 | default: |
| | 1289 | return 0; |
| | 1290 | } |
| | 1291 | } |
| | 1292 | |
| 1260 | /* Validate a new control */ | 1293 | /* Validate a new control */ |
| 1261 | static int validate_new(const struct v4l2_ctrl *ctrl, | 1294 | static int validate_new(const struct v4l2_ctrl *ctrl, |
| 1262 | struct v4l2_ext_control *c) | 1295 | struct v4l2_ext_control *c) |
| @@ -1529,30 +1562,21 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl, · 266 unmodified lines |
| 1529 | { | 1562 | { |
| 1530 | struct v4l2_ctrl *ctrl; | 1563 | struct v4l2_ctrl *ctrl; |
| 1531 | unsigned sz_extra = 0; | 1564 | unsigned sz_extra = 0; |
| | 1565 | int err; |
| 1532 | | 1566 | |
| 1533 | if (hdl->error) | 1567 | if (hdl->error) |
| 1534 | return NULL; | 1568 | return NULL; |
| 1535 | | 1569 | |
| 1536 | /* Sanity checks */ | 1570 | /* Sanity checks */ |
| 1537 | if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE || | 1571 | if (id == 0 || name == NULL || id >= V4L2_CID_PRIVATE_BASE || |
| 1538 | (type == V4L2_CTRL_TYPE_INTEGER && step == 0) || | | |
| 1539 | (type == V4L2_CTRL_TYPE_BITMASK && max == 0) || | | |
| 1540 | (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || | 1572 | (type == V4L2_CTRL_TYPE_MENU && qmenu == NULL) || |
| 1541 | (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL) || | 1573 | (type == V4L2_CTRL_TYPE_INTEGER_MENU && qmenu_int == NULL)) { |
| 1542 | (type == V4L2_CTRL_TYPE_STRING && max == 0)) { | | |
| 1543 | handler_set_err(hdl, -ERANGE); | | |
| 1544 | return NULL; | | |
| 1545 | } | | |
| 1546 | if (type != V4L2_CTRL_TYPE_BITMASK && max < min) { | | |
| 1547 | handler_set_err(hdl, -ERANGE); | 1574 | handler_set_err(hdl, -ERANGE); |
| 1548 | return NULL; | 1575 | return NULL; |
| 1549 | } | 1576 | } |
| 1550 | if ((type == V4L2_CTRL_TYPE_INTEGER || | 1577 | err = check_range(type, min, max, step, def); |
| 1551 | type == V4L2_CTRL_TYPE_MENU || | 1578 | if (err) { |
| 1552 | type == V4L2_CTRL_TYPE_INTEGER_MENU || | 1579 | handler_set_err(hdl, err); |
| 1553 | type == V4L2_CTRL_TYPE_BOOLEAN) && | | |
| 1554 | (def < min || def > max)) { | | |
| 1555 | handler_set_err(hdl, -ERANGE); | | |
| 1556 | return NULL; | 1580 | return NULL; |
| 1557 | } | 1581 | } |
| 1558 | if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) { | 1582 | if (type == V4L2_CTRL_TYPE_BITMASK && ((def & ~max) || min || step)) { |
| @@ -2426,8 +2450,8 @@ EXPORT_SYMBOL(v4l2_ctrl_g_ctrl_int64); · 867 unmodified lines |
| 2426 | /* Core function that calls try/s_ctrl and ensures that the new value is | 2450 | /* Core function that calls try/s_ctrl and ensures that the new value is |
| 2427 | copied to the current value on a set. | 2451 | copied to the current value on a set. |
| 2428 | Must be called with ctrl->handler->lock held. */ | 2452 | Must be called with ctrl->handler->lock held. */ |
| 2429 | static int try_or_set_cluster(struct v4l2_fh *fh, | 2453 | static int try_or_set_cluster(struct v4l2_fh *fh, struct v4l2_ctrl *master, |
| 2430 | struct v4l2_ctrl *master, bool set) | 2454 | bool set, u32 ch_flags) |
| 2431 | { | 2455 | { |
| 2432 | bool update_flag; | 2456 | bool update_flag; |
| 2433 | int ret; | 2457 | int ret; |
| @@ -2465,7 +2489,8 @@ static int try_or_set_cluster(struct v4l2_fh *fh, · 31 unmodified lines |
| 2465 | /* If OK, then make the new values permanent. */ | 2489 | /* If OK, then make the new values permanent. */ |
| 2466 | update_flag = is_cur_manual(master) != is_new_manual(master); | 2490 | update_flag = is_cur_manual(master) != is_new_manual(master); |
| 2467 | for (i = 0; i < master->ncontrols; i++) | 2491 | for (i = 0; i < master->ncontrols; i++) |
| 2468 | new_to_cur(fh, master->cluster[i], update_flag && i > 0); | 2492 | new_to_cur(fh, master->cluster[i], ch_flags | |
| | 2493 | ((update_flag && i > 0) ? V4L2_EVENT_CTRL_CH_FLAGS : 0)); |
| 2469 | return 0; | 2494 | return 0; |
| 2470 | } | 2495 | } |
| 2471 | | 2496 | |
| @@ -2592,7 +2617,7 @@ static int try_set_ext_ctrls(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, · 120 unmodified lines |
| 2592 | } while (!ret && idx); | 2617 | } while (!ret && idx); |
| 2593 | | 2618 | |
| 2594 | if (!ret) | 2619 | if (!ret) |
| 2595 | ret = try_or_set_cluster(fh, master, set); | 2620 | ret = try_or_set_cluster(fh, master, set, 0); |
| 2596 | | 2621 | |
| 2597 | /* Copy the new values back to userspace. */ | 2622 | /* Copy the new values back to userspace. */ |
| 2598 | if (!ret) { | 2623 | if (!ret) { |
| @@ -2638,10 +2663,9 @@ EXPORT_SYMBOL(v4l2_subdev_s_ext_ctrls); · 39 unmodified lines |
| 2638 | | 2663 | |
| 2639 | /* Helper function for VIDIOC_S_CTRL compatibility */ | 2664 | /* Helper function for VIDIOC_S_CTRL compatibility */ |
| 2640 | static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, | 2665 | static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, |
| 2641 | struct v4l2_ext_control *c) | 2666 | struct v4l2_ext_control *c, u32 ch_flags) |
| 2642 | { | 2667 | { |
| 2643 | struct v4l2_ctrl *master = ctrl->cluster[0]; | 2668 | struct v4l2_ctrl *master = ctrl->cluster[0]; |
| 2644 | int ret; | | |
| 2645 | int i; | 2669 | int i; |
| 2646 | | 2670 | |
| 2647 | /* String controls are not supported. The user_to_new() and | 2671 | /* String controls are not supported. The user_to_new() and |
| @@ -2651,12 +2675,6 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, · 3 unmodified lines |
| 2651 | if (ctrl->type == V4L2_CTRL_TYPE_STRING) | 2675 | if (ctrl->type == V4L2_CTRL_TYPE_STRING) |
| 2652 | return -EINVAL; | 2676 | return -EINVAL; |
| 2653 | | 2677 | |
| 2654 | ret = validate_new(ctrl, c); | | |
| 2655 | if (ret) | | |
| 2656 | return ret; | | |
| 2657 | | | |
| 2658 | v4l2_ctrl_lock(ctrl); | | |
| 2659 | | | |
| 2660 | /* Reset the 'is_new' flags of the cluster */ | 2678 | /* Reset the 'is_new' flags of the cluster */ |
| 2661 | for (i = 0; i < master->ncontrols; i++) | 2679 | for (i = 0; i < master->ncontrols; i++) |
| 2662 | if (master->cluster[i]) | 2680 | if (master->cluster[i]) |
| @@ -2670,10 +2688,22 @@ static int set_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, · 7 unmodified lines |
| 2670 | update_from_auto_cluster(master); | 2688 | update_from_auto_cluster(master); |
| 2671 | | 2689 | |
| 2672 | user_to_new(c, ctrl); | 2690 | user_to_new(c, ctrl); |
| 2673 | ret = try_or_set_cluster(fh, master, true); | 2691 | return try_or_set_cluster(fh, master, true, ch_flags); |
| 2674 | cur_to_user(c, ctrl); | 2692 | } |
| 2675 | | 2693 | |
| 2676 | v4l2_ctrl_unlock(ctrl); | 2694 | /* Helper function for VIDIOC_S_CTRL compatibility */ |
| | 2695 | static int set_ctrl_lock(struct v4l2_fh *fh, struct v4l2_ctrl *ctrl, |
| | 2696 | struct v4l2_ext_control *c) |
| | 2697 | { |
| | 2698 | int ret = validate_new(ctrl, c); |
| | 2699 | |
| | 2700 | if (!ret) { |
| | 2701 | v4l2_ctrl_lock(ctrl); |
| | 2702 | ret = set_ctrl(fh, ctrl, c, 0); |
| | 2703 | if (!ret) |
| | 2704 | cur_to_user(c, ctrl); |
| | 2705 | v4l2_ctrl_unlock(ctrl); |
| | 2706 | } |
| 2677 | return ret; | 2707 | return ret; |
| 2678 | } | 2708 | } |
| 2679 | | 2709 | |
| @@ -2691,7 +2721,7 @@ int v4l2_s_ctrl(struct v4l2_fh *fh, struct v4l2_ctrl_handler *hdl, · 11 unmodified lines |
| 2691 | return -EACCES; | 2721 | return -EACCES; |
| 2692 | | 2722 | |
| 2693 | c.value = control->value; | 2723 | c.value = control->value; |
| 2694 | ret = set_ctrl(fh, ctrl, &c); | 2724 | ret = set_ctrl_lock(fh, ctrl, &c); |
| 2695 | control->value = c.value; | 2725 | control->value = c.value; |
| 2696 | return ret; | 2726 | return ret; |
| 2697 | } | 2727 | } |
| @@ -2710,7 +2740,7 @@ int v4l2_ctrl_s_ctrl(struct v4l2_ctrl *ctrl, s32 val) · 12 unmodified lines |
| 2710 | /* It's a driver bug if this happens. */ | 2740 | /* It's a driver bug if this happens. */ |
| 2711 | WARN_ON(!type_is_int(ctrl)); | 2741 | WARN_ON(!type_is_int(ctrl)); |
| 2712 | c.value = val; | 2742 | c.value = val; |
| 2713 | return set_ctrl(NULL, ctrl, &c); | 2743 | return set_ctrl_lock(NULL, ctrl, &c); |
| 2714 | } | 2744 | } |
| 2715 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); | 2745 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl); |
| 2716 | | 2746 | |
| @@ -2721,7 +2751,7 @@ int v4l2_ctrl_s_ctrl_int64(struct v4l2_ctrl *ctrl, s64 val) · 4 unmodified lines |
| 2721 | /* It's a driver bug if this happens. */ | 2751 | /* It's a driver bug if this happens. */ |
| 2722 | WARN_ON(ctrl->type != V4L2_CTRL_TYPE_INTEGER64); | 2752 | WARN_ON(ctrl->type != V4L2_CTRL_TYPE_INTEGER64); |
| 2723 | c.value64 = val; | 2753 | c.value64 = val; |
| 2724 | return set_ctrl(NULL, ctrl, &c); | 2754 | return set_ctrl_lock(NULL, ctrl, &c); |
| 2725 | } | 2755 | } |
| 2726 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64); | 2756 | EXPORT_SYMBOL(v4l2_ctrl_s_ctrl_int64); |
| 2727 | | 2757 | |
| @@ -2741,6 +2771,41 @@ void v4l2_ctrl_notify(struct v4l2_ctrl *ctrl, v4l2_ctrl_notify_fnc notify, void · 13 unmodified lines |
| 2741 | } | 2771 | } |
| 2742 | EXPORT_SYMBOL(v4l2_ctrl_notify); | 2772 | EXPORT_SYMBOL(v4l2_ctrl_notify); |
| 2743 | | 2773 | |
| | 2774 | int v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl, |
| | 2775 | s32 min, s32 max, u32 step, s32 def) |
| | 2776 | { |
| | 2777 | int ret = check_range(ctrl->type, min, max, step, def); |
| | 2778 | struct v4l2_ext_control c; |
| | 2779 | |
| | 2780 | switch (ctrl->type) { |
| | 2781 | case V4L2_CTRL_TYPE_INTEGER: |
| | 2782 | case V4L2_CTRL_TYPE_BOOLEAN: |
| | 2783 | case V4L2_CTRL_TYPE_MENU: |
| | 2784 | case V4L2_CTRL_TYPE_INTEGER_MENU: |
| | 2785 | case V4L2_CTRL_TYPE_BITMASK: |
| | 2786 | if (ret) |
| | 2787 | return ret; |
| | 2788 | break; |
| | 2789 | default: |
| | 2790 | return -EINVAL; |
| | 2791 | } |
| | 2792 | v4l2_ctrl_lock(ctrl); |
| | 2793 | ctrl->minimum = min; |
| | 2794 | ctrl->maximum = max; |
| | 2795 | ctrl->step = step; |
| | 2796 | ctrl->default_value = def; |
| | 2797 | c.value = ctrl->cur.val; |
| | 2798 | if (validate_new(ctrl, &c)) |
| | 2799 | c.value = def; |
| | 2800 | if (c.value != ctrl->cur.val) |
| | 2801 | ret = set_ctrl(NULL, ctrl, &c, V4L2_EVENT_CTRL_CH_RANGE); |
| | 2802 | else |
| | 2803 | send_event(NULL, ctrl, V4L2_EVENT_CTRL_CH_RANGE); |
| | 2804 | v4l2_ctrl_unlock(ctrl); |
| | 2805 | return ret; |
| | 2806 | } |
| | 2807 | EXPORT_SYMBOL(v4l2_ctrl_modify_range); |
| | 2808 | |
| 2744 | static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) | 2809 | static int v4l2_ctrl_add_event(struct v4l2_subscribed_event *sev, unsigned elems) |
| 2745 | { | 2810 | { |
| 2746 | struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); | 2811 | struct v4l2_ctrl *ctrl = v4l2_ctrl_find(sev->fh->ctrl_handler, sev->id); |