aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-vbi.c
diff options
context:
space:
mode:
authorAndy Walls <awalls@md.metrocast.net>2010-12-18 08:48:17 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:17:10 -0500
commitb0c45686c8e8aecc7b0cd04d9b6af48d74418d53 (patch)
treed817077c5820d2ecec94d9cecf508a1e5df51513 /drivers/media/video/ivtv/ivtv-vbi.c
parent754f9969c323559a12bce1475f3c1e6574129856 (diff)
[media] ivtv: ivtv_write_vbi() should use copy_from_user() for user data buffers
ivtv_write_vbi() is used for both VBI data that came from the driver internally and VBI data that came from the user. However, it did not use copy_from_user() for reading the VBI data from the user buffers. This change adds a new version of the function, ivtv_write_vbi_from_user(), that uses copy_from_user() to read the VBI data provided via user buffers. This should resolve a sparse build warning reported by Dave Gilbert. Reported-by: Dr. David Alan Gilbert <linux at treblig.org> Signed-off-by: Andy Walls <awalls@md.metrocast.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-vbi.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c109
1 files changed, 73 insertions, 36 deletions
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index e1c347e5ebd8..7275f2d6597e 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -92,54 +92,91 @@ static int odd_parity(u8 c)
92 return c & 1; 92 return c & 1;
93} 93}
94 94
95void ivtv_write_vbi(struct ivtv *itv, const struct v4l2_sliced_vbi_data *sliced, size_t cnt) 95static void ivtv_write_vbi_line(struct ivtv *itv,
96 const struct v4l2_sliced_vbi_data *d,
97 struct vbi_cc *cc, int *found_cc)
96{ 98{
97 struct vbi_info *vi = &itv->vbi; 99 struct vbi_info *vi = &itv->vbi;
98 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
99 int found_cc = 0;
100 size_t i;
101
102 for (i = 0; i < cnt; i++) {
103 const struct v4l2_sliced_vbi_data *d = sliced + i;
104 100
105 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) { 101 if (d->id == V4L2_SLICED_CAPTION_525 && d->line == 21) {
106 if (d->field) { 102 if (d->field) {
107 cc.even[0] = d->data[0]; 103 cc->even[0] = d->data[0];
108 cc.even[1] = d->data[1]; 104 cc->even[1] = d->data[1];
109 } else { 105 } else {
110 cc.odd[0] = d->data[0]; 106 cc->odd[0] = d->data[0];
111 cc.odd[1] = d->data[1]; 107 cc->odd[1] = d->data[1];
112 }
113 found_cc = 1;
114 } 108 }
115 else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) { 109 *found_cc = 1;
116 struct vbi_vps vps; 110 } else if (d->id == V4L2_SLICED_VPS && d->line == 16 && d->field == 0) {
117 111 struct vbi_vps vps;
118 vps.data[0] = d->data[2]; 112
119 vps.data[1] = d->data[8]; 113 vps.data[0] = d->data[2];
120 vps.data[2] = d->data[9]; 114 vps.data[1] = d->data[8];
121 vps.data[3] = d->data[10]; 115 vps.data[2] = d->data[9];
122 vps.data[4] = d->data[11]; 116 vps.data[3] = d->data[10];
123 if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) { 117 vps.data[4] = d->data[11];
124 vi->vps_payload = vps; 118 if (memcmp(&vps, &vi->vps_payload, sizeof(vps))) {
125 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags); 119 vi->vps_payload = vps;
126 } 120 set_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags);
127 } 121 }
128 else if (d->id == V4L2_SLICED_WSS_625 && d->line == 23 && d->field == 0) { 122 } else if (d->id == V4L2_SLICED_WSS_625 &&
129 int wss = d->data[0] | d->data[1] << 8; 123 d->line == 23 && d->field == 0) {
124 int wss = d->data[0] | d->data[1] << 8;
130 125
131 if (vi->wss_payload != wss) { 126 if (vi->wss_payload != wss) {
132 vi->wss_payload = wss; 127 vi->wss_payload = wss;
133 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags); 128 set_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags);
134 }
135 } 129 }
136 } 130 }
137 if (found_cc && vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) { 131}
138 vi->cc_payload[vi->cc_payload_idx++] = cc; 132
133static void ivtv_write_vbi_cc_lines(struct ivtv *itv, const struct vbi_cc *cc)
134{
135 struct vbi_info *vi = &itv->vbi;
136
137 if (vi->cc_payload_idx < ARRAY_SIZE(vi->cc_payload)) {
138 memcpy(&vi->cc_payload[vi->cc_payload_idx], cc,
139 sizeof(struct vbi_cc));
140 vi->cc_payload_idx++;
139 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags); 141 set_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags);
140 } 142 }
141} 143}
142 144
145static void ivtv_write_vbi(struct ivtv *itv,
146 const struct v4l2_sliced_vbi_data *sliced,
147 size_t cnt)
148{
149 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
150 int found_cc = 0;
151 size_t i;
152
153 for (i = 0; i < cnt; i++)
154 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
155
156 if (found_cc)
157 ivtv_write_vbi_cc_lines(itv, &cc);
158}
159
160void ivtv_write_vbi_from_user(struct ivtv *itv,
161 const struct v4l2_sliced_vbi_data __user *sliced,
162 size_t cnt)
163{
164 struct vbi_cc cc = { .odd = { 0x80, 0x80 }, .even = { 0x80, 0x80 } };
165 int found_cc = 0;
166 size_t i;
167 struct v4l2_sliced_vbi_data d;
168
169 for (i = 0; i < cnt; i++) {
170 if (copy_from_user(&d, sliced + i,
171 sizeof(struct v4l2_sliced_vbi_data)))
172 break;
173 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc);
174 }
175
176 if (found_cc)
177 ivtv_write_vbi_cc_lines(itv, &cc);
178}
179
143static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp) 180static void copy_vbi_data(struct ivtv *itv, int lines, u32 pts_stamp)
144{ 181{
145 int line = 0; 182 int line = 0;