diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-04-07 05:15:40 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-07 05:15:40 -0400 |
commit | 5e34437840d33554f69380584311743b39e8fbeb (patch) | |
tree | e081135619ee146af5efb9ee883afca950df5757 /drivers/media/video/v4l2-ioctl.c | |
parent | 77d05632baee21b1cef8730d7c06aa69601e4dca (diff) | |
parent | d508afb437daee7cf07da085b635c44a4ebf9b38 (diff) |
Merge branch 'linus' into core/softlockup
Conflicts:
kernel/sysctl.c
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
-rw-r--r-- | drivers/media/video/v4l2-ioctl.c | 192 |
1 files changed, 87 insertions, 105 deletions
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 52d687b165e0..f41c6f506f42 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | 18 | ||
19 | #define __OLD_VIDIOC_ /* To allow fixing old calls */ | 19 | #define __OLD_VIDIOC_ /* To allow fixing old calls */ |
20 | #include <linux/videodev.h> | ||
20 | #include <linux/videodev2.h> | 21 | #include <linux/videodev2.h> |
21 | 22 | ||
22 | #ifdef CONFIG_VIDEO_V4L1 | 23 | #ifdef CONFIG_VIDEO_V4L1 |
@@ -24,7 +25,7 @@ | |||
24 | #endif | 25 | #endif |
25 | #include <media/v4l2-common.h> | 26 | #include <media/v4l2-common.h> |
26 | #include <media/v4l2-ioctl.h> | 27 | #include <media/v4l2-ioctl.h> |
27 | #include <linux/video_decoder.h> | 28 | #include <media/v4l2-chip-ident.h> |
28 | 29 | ||
29 | #define dbgarg(cmd, fmt, arg...) \ | 30 | #define dbgarg(cmd, fmt, arg...) \ |
30 | do { \ | 31 | do { \ |
@@ -100,25 +101,27 @@ const char *v4l2_norm_to_name(v4l2_std_id id) | |||
100 | } | 101 | } |
101 | EXPORT_SYMBOL(v4l2_norm_to_name); | 102 | EXPORT_SYMBOL(v4l2_norm_to_name); |
102 | 103 | ||
104 | /* Returns frame period for the given standard */ | ||
105 | void v4l2_video_std_frame_period(int id, struct v4l2_fract *frameperiod) | ||
106 | { | ||
107 | if (id & V4L2_STD_525_60) { | ||
108 | frameperiod->numerator = 1001; | ||
109 | frameperiod->denominator = 30000; | ||
110 | } else { | ||
111 | frameperiod->numerator = 1; | ||
112 | frameperiod->denominator = 25; | ||
113 | } | ||
114 | } | ||
115 | EXPORT_SYMBOL(v4l2_video_std_frame_period); | ||
116 | |||
103 | /* Fill in the fields of a v4l2_standard structure according to the | 117 | /* Fill in the fields of a v4l2_standard structure according to the |
104 | 'id' and 'transmission' parameters. Returns negative on error. */ | 118 | 'id' and 'transmission' parameters. Returns negative on error. */ |
105 | int v4l2_video_std_construct(struct v4l2_standard *vs, | 119 | int v4l2_video_std_construct(struct v4l2_standard *vs, |
106 | int id, const char *name) | 120 | int id, const char *name) |
107 | { | 121 | { |
108 | u32 index = vs->index; | 122 | vs->id = id; |
109 | 123 | v4l2_video_std_frame_period(id, &vs->frameperiod); | |
110 | memset(vs, 0, sizeof(struct v4l2_standard)); | 124 | vs->framelines = (id & V4L2_STD_525_60) ? 525 : 625; |
111 | vs->index = index; | ||
112 | vs->id = id; | ||
113 | if (id & V4L2_STD_525_60) { | ||
114 | vs->frameperiod.numerator = 1001; | ||
115 | vs->frameperiod.denominator = 30000; | ||
116 | vs->framelines = 525; | ||
117 | } else { | ||
118 | vs->frameperiod.numerator = 1; | ||
119 | vs->frameperiod.denominator = 25; | ||
120 | vs->framelines = 625; | ||
121 | } | ||
122 | strlcpy(vs->name, name, sizeof(vs->name)); | 125 | strlcpy(vs->name, name, sizeof(vs->name)); |
123 | return 0; | 126 | return 0; |
124 | } | 127 | } |
@@ -273,19 +276,6 @@ static const char *v4l2_ioctls[] = { | |||
273 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) | 276 | #define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) |
274 | 277 | ||
275 | static const char *v4l2_int_ioctls[] = { | 278 | static const char *v4l2_int_ioctls[] = { |
276 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | ||
277 | [_IOC_NR(DECODER_GET_CAPABILITIES)] = "DECODER_GET_CAPABILITIES", | ||
278 | [_IOC_NR(DECODER_GET_STATUS)] = "DECODER_GET_STATUS", | ||
279 | [_IOC_NR(DECODER_SET_NORM)] = "DECODER_SET_NORM", | ||
280 | [_IOC_NR(DECODER_SET_INPUT)] = "DECODER_SET_INPUT", | ||
281 | [_IOC_NR(DECODER_SET_OUTPUT)] = "DECODER_SET_OUTPUT", | ||
282 | [_IOC_NR(DECODER_ENABLE_OUTPUT)] = "DECODER_ENABLE_OUTPUT", | ||
283 | [_IOC_NR(DECODER_SET_PICTURE)] = "DECODER_SET_PICTURE", | ||
284 | [_IOC_NR(DECODER_SET_GPIO)] = "DECODER_SET_GPIO", | ||
285 | [_IOC_NR(DECODER_INIT)] = "DECODER_INIT", | ||
286 | [_IOC_NR(DECODER_SET_VBI_BYPASS)] = "DECODER_SET_VBI_BYPASS", | ||
287 | [_IOC_NR(DECODER_DUMP)] = "DECODER_DUMP", | ||
288 | #endif | ||
289 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", | 279 | [_IOC_NR(AUDC_SET_RADIO)] = "AUDC_SET_RADIO", |
290 | 280 | ||
291 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", | 281 | [_IOC_NR(TUNER_SET_TYPE_ADDR)] = "TUNER_SET_TYPE_ADDR", |
@@ -654,8 +644,6 @@ static long __video_do_ioctl(struct file *file, | |||
654 | if (cmd == VIDIOCGMBUF) { | 644 | if (cmd == VIDIOCGMBUF) { |
655 | struct video_mbuf *p = arg; | 645 | struct video_mbuf *p = arg; |
656 | 646 | ||
657 | memset(p, 0, sizeof(*p)); | ||
658 | |||
659 | if (!ops->vidiocgmbuf) | 647 | if (!ops->vidiocgmbuf) |
660 | return ret; | 648 | return ret; |
661 | ret = ops->vidiocgmbuf(file, fh, p); | 649 | ret = ops->vidiocgmbuf(file, fh, p); |
@@ -682,7 +670,6 @@ static long __video_do_ioctl(struct file *file, | |||
682 | case VIDIOC_QUERYCAP: | 670 | case VIDIOC_QUERYCAP: |
683 | { | 671 | { |
684 | struct v4l2_capability *cap = (struct v4l2_capability *)arg; | 672 | struct v4l2_capability *cap = (struct v4l2_capability *)arg; |
685 | memset(cap, 0, sizeof(*cap)); | ||
686 | 673 | ||
687 | if (!ops->vidioc_querycap) | 674 | if (!ops->vidioc_querycap) |
688 | break; | 675 | break; |
@@ -725,16 +712,8 @@ static long __video_do_ioctl(struct file *file, | |||
725 | case VIDIOC_ENUM_FMT: | 712 | case VIDIOC_ENUM_FMT: |
726 | { | 713 | { |
727 | struct v4l2_fmtdesc *f = arg; | 714 | struct v4l2_fmtdesc *f = arg; |
728 | enum v4l2_buf_type type; | ||
729 | unsigned int index; | ||
730 | |||
731 | index = f->index; | ||
732 | type = f->type; | ||
733 | memset(f, 0, sizeof(*f)); | ||
734 | f->index = index; | ||
735 | f->type = type; | ||
736 | 715 | ||
737 | switch (type) { | 716 | switch (f->type) { |
738 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | 717 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: |
739 | if (ops->vidioc_enum_fmt_vid_cap) | 718 | if (ops->vidioc_enum_fmt_vid_cap) |
740 | ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); | 719 | ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); |
@@ -771,8 +750,6 @@ static long __video_do_ioctl(struct file *file, | |||
771 | { | 750 | { |
772 | struct v4l2_format *f = (struct v4l2_format *)arg; | 751 | struct v4l2_format *f = (struct v4l2_format *)arg; |
773 | 752 | ||
774 | memset(f->fmt.raw_data, 0, sizeof(f->fmt.raw_data)); | ||
775 | |||
776 | /* FIXME: Should be one dump per type */ | 753 | /* FIXME: Should be one dump per type */ |
777 | dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); | 754 | dbgarg(cmd, "type=%s\n", prt_names(f->type, v4l2_type_names)); |
778 | 755 | ||
@@ -1088,7 +1065,6 @@ static long __video_do_ioctl(struct file *file, | |||
1088 | return -EINVAL; | 1065 | return -EINVAL; |
1089 | 1066 | ||
1090 | v4l2_video_std_construct(p, curr_id, descr); | 1067 | v4l2_video_std_construct(p, curr_id, descr); |
1091 | p->index = index; | ||
1092 | 1068 | ||
1093 | dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " | 1069 | dbgarg(cmd, "index=%d, id=0x%Lx, name=%s, fps=%d/%d, " |
1094 | "framelines=%d\n", p->index, | 1070 | "framelines=%d\n", p->index, |
@@ -1153,12 +1129,9 @@ static long __video_do_ioctl(struct file *file, | |||
1153 | case VIDIOC_ENUMINPUT: | 1129 | case VIDIOC_ENUMINPUT: |
1154 | { | 1130 | { |
1155 | struct v4l2_input *p = arg; | 1131 | struct v4l2_input *p = arg; |
1156 | int i = p->index; | ||
1157 | 1132 | ||
1158 | if (!ops->vidioc_enum_input) | 1133 | if (!ops->vidioc_enum_input) |
1159 | break; | 1134 | break; |
1160 | memset(p, 0, sizeof(*p)); | ||
1161 | p->index = i; | ||
1162 | 1135 | ||
1163 | ret = ops->vidioc_enum_input(file, fh, p); | 1136 | ret = ops->vidioc_enum_input(file, fh, p); |
1164 | if (!ret) | 1137 | if (!ret) |
@@ -1197,12 +1170,9 @@ static long __video_do_ioctl(struct file *file, | |||
1197 | case VIDIOC_ENUMOUTPUT: | 1170 | case VIDIOC_ENUMOUTPUT: |
1198 | { | 1171 | { |
1199 | struct v4l2_output *p = arg; | 1172 | struct v4l2_output *p = arg; |
1200 | int i = p->index; | ||
1201 | 1173 | ||
1202 | if (!ops->vidioc_enum_output) | 1174 | if (!ops->vidioc_enum_output) |
1203 | break; | 1175 | break; |
1204 | memset(p, 0, sizeof(*p)); | ||
1205 | p->index = i; | ||
1206 | 1176 | ||
1207 | ret = ops->vidioc_enum_output(file, fh, p); | 1177 | ret = ops->vidioc_enum_output(file, fh, p); |
1208 | if (!ret) | 1178 | if (!ret) |
@@ -1378,13 +1348,10 @@ static long __video_do_ioctl(struct file *file, | |||
1378 | case VIDIOC_G_AUDIO: | 1348 | case VIDIOC_G_AUDIO: |
1379 | { | 1349 | { |
1380 | struct v4l2_audio *p = arg; | 1350 | struct v4l2_audio *p = arg; |
1381 | __u32 index = p->index; | ||
1382 | 1351 | ||
1383 | if (!ops->vidioc_g_audio) | 1352 | if (!ops->vidioc_g_audio) |
1384 | break; | 1353 | break; |
1385 | 1354 | ||
1386 | memset(p, 0, sizeof(*p)); | ||
1387 | p->index = index; | ||
1388 | ret = ops->vidioc_g_audio(file, fh, p); | 1355 | ret = ops->vidioc_g_audio(file, fh, p); |
1389 | if (!ret) | 1356 | if (!ret) |
1390 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " | 1357 | dbgarg(cmd, "index=%d, name=%s, capability=0x%x, " |
@@ -1426,7 +1393,7 @@ static long __video_do_ioctl(struct file *file, | |||
1426 | 1393 | ||
1427 | if (!ops->vidioc_g_audout) | 1394 | if (!ops->vidioc_g_audout) |
1428 | break; | 1395 | break; |
1429 | dbgarg(cmd, "Enum for index=%d\n", p->index); | 1396 | |
1430 | ret = ops->vidioc_g_audout(file, fh, p); | 1397 | ret = ops->vidioc_g_audout(file, fh, p); |
1431 | if (!ret) | 1398 | if (!ret) |
1432 | dbgarg2("index=%d, name=%s, capability=%d, " | 1399 | dbgarg2("index=%d, name=%s, capability=%d, " |
@@ -1479,15 +1446,10 @@ static long __video_do_ioctl(struct file *file, | |||
1479 | case VIDIOC_G_CROP: | 1446 | case VIDIOC_G_CROP: |
1480 | { | 1447 | { |
1481 | struct v4l2_crop *p = arg; | 1448 | struct v4l2_crop *p = arg; |
1482 | __u32 type; | ||
1483 | 1449 | ||
1484 | if (!ops->vidioc_g_crop) | 1450 | if (!ops->vidioc_g_crop) |
1485 | break; | 1451 | break; |
1486 | 1452 | ||
1487 | type = p->type; | ||
1488 | memset(p, 0, sizeof(*p)); | ||
1489 | p->type = type; | ||
1490 | |||
1491 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1453 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1492 | ret = ops->vidioc_g_crop(file, fh, p); | 1454 | ret = ops->vidioc_g_crop(file, fh, p); |
1493 | if (!ret) | 1455 | if (!ret) |
@@ -1508,16 +1470,11 @@ static long __video_do_ioctl(struct file *file, | |||
1508 | case VIDIOC_CROPCAP: | 1470 | case VIDIOC_CROPCAP: |
1509 | { | 1471 | { |
1510 | struct v4l2_cropcap *p = arg; | 1472 | struct v4l2_cropcap *p = arg; |
1511 | __u32 type; | ||
1512 | 1473 | ||
1513 | /*FIXME: Should also show v4l2_fract pixelaspect */ | 1474 | /*FIXME: Should also show v4l2_fract pixelaspect */ |
1514 | if (!ops->vidioc_cropcap) | 1475 | if (!ops->vidioc_cropcap) |
1515 | break; | 1476 | break; |
1516 | 1477 | ||
1517 | type = p->type; | ||
1518 | memset(p, 0, sizeof(*p)); | ||
1519 | p->type = type; | ||
1520 | |||
1521 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1478 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1522 | ret = ops->vidioc_cropcap(file, fh, p); | 1479 | ret = ops->vidioc_cropcap(file, fh, p); |
1523 | if (!ret) { | 1480 | if (!ret) { |
@@ -1533,8 +1490,6 @@ static long __video_do_ioctl(struct file *file, | |||
1533 | if (!ops->vidioc_g_jpegcomp) | 1490 | if (!ops->vidioc_g_jpegcomp) |
1534 | break; | 1491 | break; |
1535 | 1492 | ||
1536 | memset(p, 0, sizeof(*p)); | ||
1537 | |||
1538 | ret = ops->vidioc_g_jpegcomp(file, fh, p); | 1493 | ret = ops->vidioc_g_jpegcomp(file, fh, p); |
1539 | if (!ret) | 1494 | if (!ret) |
1540 | dbgarg(cmd, "quality=%d, APPn=%d, " | 1495 | dbgarg(cmd, "quality=%d, APPn=%d, " |
@@ -1575,7 +1530,6 @@ static long __video_do_ioctl(struct file *file, | |||
1575 | 1530 | ||
1576 | if (!ops->vidioc_encoder_cmd) | 1531 | if (!ops->vidioc_encoder_cmd) |
1577 | break; | 1532 | break; |
1578 | memset(&p->raw, 0, sizeof(p->raw)); | ||
1579 | ret = ops->vidioc_encoder_cmd(file, fh, p); | 1533 | ret = ops->vidioc_encoder_cmd(file, fh, p); |
1580 | if (!ret) | 1534 | if (!ret) |
1581 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); | 1535 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); |
@@ -1587,7 +1541,6 @@ static long __video_do_ioctl(struct file *file, | |||
1587 | 1541 | ||
1588 | if (!ops->vidioc_try_encoder_cmd) | 1542 | if (!ops->vidioc_try_encoder_cmd) |
1589 | break; | 1543 | break; |
1590 | memset(&p->raw, 0, sizeof(p->raw)); | ||
1591 | ret = ops->vidioc_try_encoder_cmd(file, fh, p); | 1544 | ret = ops->vidioc_try_encoder_cmd(file, fh, p); |
1592 | if (!ret) | 1545 | if (!ret) |
1593 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); | 1546 | dbgarg(cmd, "cmd=%d, flags=%x\n", p->cmd, p->flags); |
@@ -1596,23 +1549,18 @@ static long __video_do_ioctl(struct file *file, | |||
1596 | case VIDIOC_G_PARM: | 1549 | case VIDIOC_G_PARM: |
1597 | { | 1550 | { |
1598 | struct v4l2_streamparm *p = arg; | 1551 | struct v4l2_streamparm *p = arg; |
1599 | __u32 type = p->type; | ||
1600 | |||
1601 | memset(p, 0, sizeof(*p)); | ||
1602 | p->type = type; | ||
1603 | 1552 | ||
1604 | if (ops->vidioc_g_parm) { | 1553 | if (ops->vidioc_g_parm) { |
1554 | ret = check_fmt(ops, p->type); | ||
1555 | if (ret) | ||
1556 | break; | ||
1605 | ret = ops->vidioc_g_parm(file, fh, p); | 1557 | ret = ops->vidioc_g_parm(file, fh, p); |
1606 | } else { | 1558 | } else { |
1607 | struct v4l2_standard s; | ||
1608 | |||
1609 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1559 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1610 | return -EINVAL; | 1560 | return -EINVAL; |
1611 | 1561 | ||
1612 | v4l2_video_std_construct(&s, vfd->current_norm, | 1562 | v4l2_video_std_frame_period(vfd->current_norm, |
1613 | v4l2_norm_to_name(vfd->current_norm)); | 1563 | &p->parm.capture.timeperframe); |
1614 | |||
1615 | p->parm.capture.timeperframe = s.frameperiod; | ||
1616 | ret = 0; | 1564 | ret = 0; |
1617 | } | 1565 | } |
1618 | 1566 | ||
@@ -1625,6 +1573,10 @@ static long __video_do_ioctl(struct file *file, | |||
1625 | 1573 | ||
1626 | if (!ops->vidioc_s_parm) | 1574 | if (!ops->vidioc_s_parm) |
1627 | break; | 1575 | break; |
1576 | ret = check_fmt(ops, p->type); | ||
1577 | if (ret) | ||
1578 | break; | ||
1579 | |||
1628 | dbgarg(cmd, "type=%d\n", p->type); | 1580 | dbgarg(cmd, "type=%d\n", p->type); |
1629 | ret = ops->vidioc_s_parm(file, fh, p); | 1581 | ret = ops->vidioc_s_parm(file, fh, p); |
1630 | break; | 1582 | break; |
@@ -1632,14 +1584,10 @@ static long __video_do_ioctl(struct file *file, | |||
1632 | case VIDIOC_G_TUNER: | 1584 | case VIDIOC_G_TUNER: |
1633 | { | 1585 | { |
1634 | struct v4l2_tuner *p = arg; | 1586 | struct v4l2_tuner *p = arg; |
1635 | __u32 index = p->index; | ||
1636 | 1587 | ||
1637 | if (!ops->vidioc_g_tuner) | 1588 | if (!ops->vidioc_g_tuner) |
1638 | break; | 1589 | break; |
1639 | 1590 | ||
1640 | memset(p, 0, sizeof(*p)); | ||
1641 | p->index = index; | ||
1642 | |||
1643 | ret = ops->vidioc_g_tuner(file, fh, p); | 1591 | ret = ops->vidioc_g_tuner(file, fh, p); |
1644 | if (!ret) | 1592 | if (!ret) |
1645 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1593 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
@@ -1676,8 +1624,6 @@ static long __video_do_ioctl(struct file *file, | |||
1676 | if (!ops->vidioc_g_frequency) | 1624 | if (!ops->vidioc_g_frequency) |
1677 | break; | 1625 | break; |
1678 | 1626 | ||
1679 | memset(p->reserved, 0, sizeof(p->reserved)); | ||
1680 | |||
1681 | ret = ops->vidioc_g_frequency(file, fh, p); | 1627 | ret = ops->vidioc_g_frequency(file, fh, p); |
1682 | if (!ret) | 1628 | if (!ret) |
1683 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", | 1629 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
@@ -1698,12 +1644,13 @@ static long __video_do_ioctl(struct file *file, | |||
1698 | case VIDIOC_G_SLICED_VBI_CAP: | 1644 | case VIDIOC_G_SLICED_VBI_CAP: |
1699 | { | 1645 | { |
1700 | struct v4l2_sliced_vbi_cap *p = arg; | 1646 | struct v4l2_sliced_vbi_cap *p = arg; |
1701 | __u32 type = p->type; | ||
1702 | 1647 | ||
1703 | if (!ops->vidioc_g_sliced_vbi_cap) | 1648 | if (!ops->vidioc_g_sliced_vbi_cap) |
1704 | break; | 1649 | break; |
1705 | memset(p, 0, sizeof(*p)); | 1650 | |
1706 | p->type = type; | 1651 | /* Clear up to type, everything after type is zerod already */ |
1652 | memset(p, 0, offsetof(struct v4l2_sliced_vbi_cap, type)); | ||
1653 | |||
1707 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); | 1654 | dbgarg(cmd, "type=%s\n", prt_names(p->type, v4l2_type_names)); |
1708 | ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); | 1655 | ret = ops->vidioc_g_sliced_vbi_cap(file, fh, p); |
1709 | if (!ret) | 1656 | if (!ret) |
@@ -1745,16 +1692,13 @@ static long __video_do_ioctl(struct file *file, | |||
1745 | 1692 | ||
1746 | if (!ops->vidioc_g_chip_ident) | 1693 | if (!ops->vidioc_g_chip_ident) |
1747 | break; | 1694 | break; |
1695 | p->ident = V4L2_IDENT_NONE; | ||
1696 | p->revision = 0; | ||
1748 | ret = ops->vidioc_g_chip_ident(file, fh, p); | 1697 | ret = ops->vidioc_g_chip_ident(file, fh, p); |
1749 | if (!ret) | 1698 | if (!ret) |
1750 | dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); | 1699 | dbgarg(cmd, "chip_ident=%u, revision=0x%x\n", p->ident, p->revision); |
1751 | break; | 1700 | break; |
1752 | } | 1701 | } |
1753 | case VIDIOC_G_CHIP_IDENT_OLD: | ||
1754 | printk(KERN_ERR "VIDIOC_G_CHIP_IDENT has been deprecated and will disappear in 2.6.30.\n"); | ||
1755 | printk(KERN_ERR "It is a debugging ioctl and must not be used in applications!\n"); | ||
1756 | return -EINVAL; | ||
1757 | |||
1758 | case VIDIOC_S_HW_FREQ_SEEK: | 1702 | case VIDIOC_S_HW_FREQ_SEEK: |
1759 | { | 1703 | { |
1760 | struct v4l2_hw_freq_seek *p = arg; | 1704 | struct v4l2_hw_freq_seek *p = arg; |
@@ -1774,8 +1718,6 @@ static long __video_do_ioctl(struct file *file, | |||
1774 | if (!ops->vidioc_enum_framesizes) | 1718 | if (!ops->vidioc_enum_framesizes) |
1775 | break; | 1719 | break; |
1776 | 1720 | ||
1777 | memset(p, 0, sizeof(*p)); | ||
1778 | |||
1779 | ret = ops->vidioc_enum_framesizes(file, fh, p); | 1721 | ret = ops->vidioc_enum_framesizes(file, fh, p); |
1780 | dbgarg(cmd, | 1722 | dbgarg(cmd, |
1781 | "index=%d, pixelformat=%d, type=%d ", | 1723 | "index=%d, pixelformat=%d, type=%d ", |
@@ -1807,8 +1749,6 @@ static long __video_do_ioctl(struct file *file, | |||
1807 | if (!ops->vidioc_enum_frameintervals) | 1749 | if (!ops->vidioc_enum_frameintervals) |
1808 | break; | 1750 | break; |
1809 | 1751 | ||
1810 | memset(p, 0, sizeof(*p)); | ||
1811 | |||
1812 | ret = ops->vidioc_enum_frameintervals(file, fh, p); | 1752 | ret = ops->vidioc_enum_frameintervals(file, fh, p); |
1813 | dbgarg(cmd, | 1753 | dbgarg(cmd, |
1814 | "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ", | 1754 | "index=%d, pixelformat=%d, width=%d, height=%d, type=%d ", |
@@ -1857,6 +1797,45 @@ static long __video_do_ioctl(struct file *file, | |||
1857 | return ret; | 1797 | return ret; |
1858 | } | 1798 | } |
1859 | 1799 | ||
1800 | /* In some cases, only a few fields are used as input, i.e. when the app sets | ||
1801 | * "index" and then the driver fills in the rest of the structure for the thing | ||
1802 | * with that index. We only need to copy up the first non-input field. */ | ||
1803 | static unsigned long cmd_input_size(unsigned int cmd) | ||
1804 | { | ||
1805 | /* Size of structure up to and including 'field' */ | ||
1806 | #define CMDINSIZE(cmd, type, field) \ | ||
1807 | case VIDIOC_##cmd: \ | ||
1808 | return offsetof(struct v4l2_##type, field) + \ | ||
1809 | sizeof(((struct v4l2_##type *)0)->field); | ||
1810 | |||
1811 | switch (cmd) { | ||
1812 | CMDINSIZE(ENUM_FMT, fmtdesc, type); | ||
1813 | CMDINSIZE(G_FMT, format, type); | ||
1814 | CMDINSIZE(QUERYBUF, buffer, type); | ||
1815 | CMDINSIZE(G_PARM, streamparm, type); | ||
1816 | CMDINSIZE(ENUMSTD, standard, index); | ||
1817 | CMDINSIZE(ENUMINPUT, input, index); | ||
1818 | CMDINSIZE(G_CTRL, control, id); | ||
1819 | CMDINSIZE(G_TUNER, tuner, index); | ||
1820 | CMDINSIZE(QUERYCTRL, queryctrl, id); | ||
1821 | CMDINSIZE(QUERYMENU, querymenu, index); | ||
1822 | CMDINSIZE(ENUMOUTPUT, output, index); | ||
1823 | CMDINSIZE(G_MODULATOR, modulator, index); | ||
1824 | CMDINSIZE(G_FREQUENCY, frequency, tuner); | ||
1825 | CMDINSIZE(CROPCAP, cropcap, type); | ||
1826 | CMDINSIZE(G_CROP, crop, type); | ||
1827 | CMDINSIZE(ENUMAUDIO, audio, index); | ||
1828 | CMDINSIZE(ENUMAUDOUT, audioout, index); | ||
1829 | CMDINSIZE(ENCODER_CMD, encoder_cmd, flags); | ||
1830 | CMDINSIZE(TRY_ENCODER_CMD, encoder_cmd, flags); | ||
1831 | CMDINSIZE(G_SLICED_VBI_CAP, sliced_vbi_cap, type); | ||
1832 | CMDINSIZE(ENUM_FRAMESIZES, frmsizeenum, pixel_format); | ||
1833 | CMDINSIZE(ENUM_FRAMEINTERVALS, frmivalenum, height); | ||
1834 | default: | ||
1835 | return _IOC_SIZE(cmd); | ||
1836 | } | ||
1837 | } | ||
1838 | |||
1860 | long video_ioctl2(struct file *file, | 1839 | long video_ioctl2(struct file *file, |
1861 | unsigned int cmd, unsigned long arg) | 1840 | unsigned int cmd, unsigned long arg) |
1862 | { | 1841 | { |
@@ -1875,13 +1854,7 @@ long video_ioctl2(struct file *file, | |||
1875 | cmd == VIDIOC_TRY_EXT_CTRLS); | 1854 | cmd == VIDIOC_TRY_EXT_CTRLS); |
1876 | 1855 | ||
1877 | /* Copy arguments into temp kernel buffer */ | 1856 | /* Copy arguments into temp kernel buffer */ |
1878 | switch (_IOC_DIR(cmd)) { | 1857 | if (_IOC_DIR(cmd) != _IOC_NONE) { |
1879 | case _IOC_NONE: | ||
1880 | parg = NULL; | ||
1881 | break; | ||
1882 | case _IOC_READ: | ||
1883 | case _IOC_WRITE: | ||
1884 | case (_IOC_WRITE | _IOC_READ): | ||
1885 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { | 1858 | if (_IOC_SIZE(cmd) <= sizeof(sbuf)) { |
1886 | parg = sbuf; | 1859 | parg = sbuf; |
1887 | } else { | 1860 | } else { |
@@ -1893,10 +1866,19 @@ long video_ioctl2(struct file *file, | |||
1893 | } | 1866 | } |
1894 | 1867 | ||
1895 | err = -EFAULT; | 1868 | err = -EFAULT; |
1896 | if (_IOC_DIR(cmd) & _IOC_WRITE) | 1869 | if (_IOC_DIR(cmd) & _IOC_WRITE) { |
1897 | if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd))) | 1870 | unsigned long n = cmd_input_size(cmd); |
1871 | |||
1872 | if (copy_from_user(parg, (void __user *)arg, n)) | ||
1898 | goto out; | 1873 | goto out; |
1899 | break; | 1874 | |
1875 | /* zero out anything we don't copy from userspace */ | ||
1876 | if (n < _IOC_SIZE(cmd)) | ||
1877 | memset((u8 *)parg + n, 0, _IOC_SIZE(cmd) - n); | ||
1878 | } else { | ||
1879 | /* read-only ioctl */ | ||
1880 | memset(parg, 0, _IOC_SIZE(cmd)); | ||
1881 | } | ||
1900 | } | 1882 | } |
1901 | 1883 | ||
1902 | if (is_ext_ctrl) { | 1884 | if (is_ext_ctrl) { |