aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/v4l2-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/v4l2-ioctl.c')
-rw-r--r--drivers/media/video/v4l2-ioctl.c192
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}
101EXPORT_SYMBOL(v4l2_norm_to_name); 102EXPORT_SYMBOL(v4l2_norm_to_name);
102 103
104/* Returns frame period for the given standard */
105void 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}
115EXPORT_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. */
105int v4l2_video_std_construct(struct v4l2_standard *vs, 119int 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
275static const char *v4l2_int_ioctls[] = { 278static 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. */
1803static 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
1860long video_ioctl2(struct file *file, 1839long 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) {