aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c191
1 files changed, 155 insertions, 36 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index dfe0aedc60fd..206eee7542db 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -25,8 +25,7 @@
25#include "ivtv-queue.h" 25#include "ivtv-queue.h"
26#include "ivtv-fileops.h" 26#include "ivtv-fileops.h"
27#include "ivtv-vbi.h" 27#include "ivtv-vbi.h"
28#include "ivtv-audio.h" 28#include "ivtv-routing.h"
29#include "ivtv-video.h"
30#include "ivtv-streams.h" 29#include "ivtv-streams.h"
31#include "ivtv-yuv.h" 30#include "ivtv-yuv.h"
32#include "ivtv-ioctl.h" 31#include "ivtv-ioctl.h"
@@ -164,7 +163,7 @@ void ivtv_set_osd_alpha(struct ivtv *itv)
164{ 163{
165 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3, 164 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
166 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state); 165 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
167 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_color_key_state, itv->osd_color_key); 166 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_chroma_key_state, itv->osd_chroma_key);
168} 167}
169 168
170int ivtv_set_speed(struct ivtv *itv, int speed) 169int ivtv_set_speed(struct ivtv *itv, int speed)
@@ -427,7 +426,7 @@ static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fm
427 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 426 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
428 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 427 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
429 return -EINVAL; 428 return -EINVAL;
430 fmt->fmt.win.chromakey = itv->osd_color_key; 429 fmt->fmt.win.chromakey = itv->osd_chroma_key;
431 fmt->fmt.win.global_alpha = itv->osd_global_alpha; 430 fmt->fmt.win.global_alpha = itv->osd_global_alpha;
432 break; 431 break;
433 432
@@ -547,7 +546,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
547 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 546 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
548 return -EINVAL; 547 return -EINVAL;
549 if (set_fmt) { 548 if (set_fmt) {
550 itv->osd_color_key = fmt->fmt.win.chromakey; 549 itv->osd_chroma_key = fmt->fmt.win.chromakey;
551 itv->osd_global_alpha = fmt->fmt.win.global_alpha; 550 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
552 ivtv_set_osd_alpha(itv); 551 ivtv_set_osd_alpha(itv);
553 } 552 }
@@ -584,9 +583,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
584 583
585 /* set raw VBI format */ 584 /* set raw VBI format */
586 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 585 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
587 if (set_fmt && streamtype == IVTV_ENC_STREAM_TYPE_VBI && 586 if (set_fmt && atomic_read(&itv->capturing) > 0) {
588 itv->vbi.sliced_in->service_set &&
589 atomic_read(&itv->capturing) > 0) {
590 return -EBUSY; 587 return -EBUSY;
591 } 588 }
592 if (set_fmt) { 589 if (set_fmt) {
@@ -624,7 +621,7 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
624 return 0; 621 return 0;
625 if (set == 0) 622 if (set == 0)
626 return -EINVAL; 623 return -EINVAL;
627 if (atomic_read(&itv->capturing) > 0 && itv->vbi.sliced_in->service_set == 0) { 624 if (atomic_read(&itv->capturing) > 0) {
628 return -EBUSY; 625 return -EBUSY;
629 } 626 }
630 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 627 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
@@ -677,13 +674,21 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
677 case VIDIOC_INT_S_AUDIO_ROUTING: { 674 case VIDIOC_INT_S_AUDIO_ROUTING: {
678 struct v4l2_routing *route = arg; 675 struct v4l2_routing *route = arg;
679 676
680 ivtv_audio_set_route(itv, route); 677 ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
681 break; 678 break;
682 } 679 }
683 680
684 case VIDIOC_INT_RESET: 681 case VIDIOC_INT_RESET: {
685 ivtv_reset_ir_gpio(itv); 682 u32 val = *(u32 *)arg;
683
684 if ((val == 0 && itv->options.newi2c) || (val & 0x01)) {
685 ivtv_reset_ir_gpio(itv);
686 }
687 if (val & 0x02) {
688 itv->video_dec_func(itv, cmd, 0);
689 }
686 break; 690 break;
691 }
687 692
688 default: 693 default:
689 return -EINVAL; 694 return -EINVAL;
@@ -694,6 +699,7 @@ static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
694int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) 699int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
695{ 700{
696 struct ivtv_open_id *id = NULL; 701 struct ivtv_open_id *id = NULL;
702 u32 data[CX2341X_MBOX_MAX_DATA];
697 703
698 if (filp) id = (struct ivtv_open_id *)filp->private_data; 704 if (filp) id = (struct ivtv_open_id *)filp->private_data;
699 705
@@ -898,6 +904,9 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
898 IVTV_DEBUG_INFO("Input unchanged\n"); 904 IVTV_DEBUG_INFO("Input unchanged\n");
899 break; 905 break;
900 } 906 }
907 if (atomic_read(&itv->capturing) > 0) {
908 return -EBUSY;
909 }
901 IVTV_DEBUG_INFO("Changing input from %d to %d\n", 910 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
902 itv->active_input, inp); 911 itv->active_input, inp);
903 912
@@ -1127,12 +1136,14 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1127 memset(&enc->raw, 0, sizeof(enc->raw)); 1136 memset(&enc->raw, 0, sizeof(enc->raw));
1128 switch (enc->cmd) { 1137 switch (enc->cmd) {
1129 case V4L2_ENC_CMD_START: 1138 case V4L2_ENC_CMD_START:
1139 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1130 enc->flags = 0; 1140 enc->flags = 0;
1131 if (try) 1141 if (try)
1132 return 0; 1142 return 0;
1133 return ivtv_start_capture(id); 1143 return ivtv_start_capture(id);
1134 1144
1135 case V4L2_ENC_CMD_STOP: 1145 case V4L2_ENC_CMD_STOP:
1146 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1136 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; 1147 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1137 if (try) 1148 if (try)
1138 return 0; 1149 return 0;
@@ -1140,6 +1151,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1140 return 0; 1151 return 0;
1141 1152
1142 case V4L2_ENC_CMD_PAUSE: 1153 case V4L2_ENC_CMD_PAUSE:
1154 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1143 enc->flags = 0; 1155 enc->flags = 0;
1144 if (try) 1156 if (try)
1145 return 0; 1157 return 0;
@@ -1152,6 +1164,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1152 break; 1164 break;
1153 1165
1154 case V4L2_ENC_CMD_RESUME: 1166 case V4L2_ENC_CMD_RESUME:
1167 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1155 enc->flags = 0; 1168 enc->flags = 0;
1156 if (try) 1169 if (try)
1157 return 0; 1170 return 0;
@@ -1163,6 +1176,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1163 ivtv_unmute(itv); 1176 ivtv_unmute(itv);
1164 break; 1177 break;
1165 default: 1178 default:
1179 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1166 return -EINVAL; 1180 return -EINVAL;
1167 } 1181 }
1168 break; 1182 break;
@@ -1170,22 +1184,58 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1170 1184
1171 case VIDIOC_G_FBUF: { 1185 case VIDIOC_G_FBUF: {
1172 struct v4l2_framebuffer *fb = arg; 1186 struct v4l2_framebuffer *fb = arg;
1187 int pixfmt;
1188 static u32 pixel_format[16] = {
1189 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1190 V4L2_PIX_FMT_RGB565,
1191 V4L2_PIX_FMT_RGB555,
1192 V4L2_PIX_FMT_RGB444,
1193 V4L2_PIX_FMT_RGB32,
1194 0,
1195 0,
1196 0,
1197 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1198 V4L2_PIX_FMT_YUV565,
1199 V4L2_PIX_FMT_YUV555,
1200 V4L2_PIX_FMT_YUV444,
1201 V4L2_PIX_FMT_YUV32,
1202 0,
1203 0,
1204 0,
1205 };
1173 1206
1174 memset(fb, 0, sizeof(*fb)); 1207 memset(fb, 0, sizeof(*fb));
1175 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1208 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1176 return -EINVAL; 1209 return -EINVAL;
1177 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | 1210 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1178 V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA; 1211 V4L2_FBUF_CAP_GLOBAL_ALPHA;
1179 fb->fmt.pixelformat = itv->osd_pixelformat; 1212 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1213 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1214 pixfmt = (data[0] >> 3) & 0xf;
1215 fb->fmt.pixelformat = pixel_format[pixfmt];
1180 fb->fmt.width = itv->osd_rect.width; 1216 fb->fmt.width = itv->osd_rect.width;
1181 fb->fmt.height = itv->osd_rect.height; 1217 fb->fmt.height = itv->osd_rect.height;
1182 fb->base = (void *)itv->osd_video_pbase; 1218 fb->base = (void *)itv->osd_video_pbase;
1219 if (itv->osd_chroma_key_state)
1220 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1183 if (itv->osd_global_alpha_state) 1221 if (itv->osd_global_alpha_state)
1184 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; 1222 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1185 if (itv->osd_local_alpha_state) 1223 pixfmt &= 7;
1186 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA; 1224 /* no local alpha for RGB565 or unknown formats */
1187 if (itv->osd_color_key_state) 1225 if (pixfmt == 1 || pixfmt > 4)
1188 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; 1226 break;
1227 /* 16-bit formats have inverted local alpha */
1228 if (pixfmt == 2 || pixfmt == 3)
1229 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1230 else
1231 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
1232 if (itv->osd_local_alpha_state) {
1233 /* 16-bit formats have inverted local alpha */
1234 if (pixfmt == 2 || pixfmt == 3)
1235 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
1236 else
1237 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1238 }
1189 break; 1239 break;
1190 } 1240 }
1191 1241
@@ -1195,12 +1245,22 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1195 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1245 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1196 return -EINVAL; 1246 return -EINVAL;
1197 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; 1247 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1198 itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; 1248 itv->osd_local_alpha_state =
1199 itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; 1249 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1250 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1200 ivtv_set_osd_alpha(itv); 1251 ivtv_set_osd_alpha(itv);
1201 break; 1252 break;
1202 } 1253 }
1203 1254
1255 case VIDIOC_OVERLAY: {
1256 int *on = arg;
1257
1258 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1259 return -EINVAL;
1260 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
1261 break;
1262 }
1263
1204 case VIDIOC_LOG_STATUS: 1264 case VIDIOC_LOG_STATUS:
1205 { 1265 {
1206 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; 1266 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
@@ -1209,6 +1269,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1209 int i; 1269 int i;
1210 1270
1211 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); 1271 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
1272 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1212 if (itv->hw_flags & IVTV_HW_TVEEPROM) { 1273 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1213 struct tveeprom tv; 1274 struct tveeprom tv;
1214 1275
@@ -1217,32 +1278,72 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1217 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); 1278 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1218 ivtv_get_input(itv, itv->active_input, &vidin); 1279 ivtv_get_input(itv, itv->active_input, &vidin);
1219 ivtv_get_audio_input(itv, itv->audio_input, &audin); 1280 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1220 IVTV_INFO("Video Input: %s\n", vidin.name); 1281 IVTV_INFO("Video Input: %s\n", vidin.name);
1221 IVTV_INFO("Audio Input: %s\n", audin.name); 1282 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1283 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1222 if (has_output) { 1284 if (has_output) {
1223 struct v4l2_output vidout; 1285 struct v4l2_output vidout;
1224 struct v4l2_audioout audout; 1286 struct v4l2_audioout audout;
1225 int mode = itv->output_mode; 1287 int mode = itv->output_mode;
1226 static const char * const output_modes[] = { 1288 static const char * const output_modes[5] = {
1227 "None", 1289 "None",
1228 "MPEG Streaming", 1290 "MPEG Streaming",
1229 "YUV Streaming", 1291 "YUV Streaming",
1230 "YUV Frames", 1292 "YUV Frames",
1231 "Passthrough", 1293 "Passthrough",
1232 }; 1294 };
1295 static const char * const audio_modes[5] = {
1296 "Stereo",
1297 "Left",
1298 "Right",
1299 "Mono",
1300 "Swapped"
1301 };
1302 static const char * const alpha_mode[4] = {
1303 "None",
1304 "Global",
1305 "Local",
1306 "Global and Local"
1307 };
1308 static const char * const pixel_format[16] = {
1309 "ARGB Indexed",
1310 "RGB 5:6:5",
1311 "ARGB 1:5:5:5",
1312 "ARGB 1:4:4:4",
1313 "ARGB 8:8:8:8",
1314 "5",
1315 "6",
1316 "7",
1317 "AYUV Indexed",
1318 "YUV 5:6:5",
1319 "AYUV 1:5:5:5",
1320 "AYUV 1:4:4:4",
1321 "AYUV 8:8:8:8",
1322 "13",
1323 "14",
1324 "15",
1325 };
1233 1326
1234 ivtv_get_output(itv, itv->active_output, &vidout); 1327 ivtv_get_output(itv, itv->active_output, &vidout);
1235 ivtv_get_audio_output(itv, 0, &audout); 1328 ivtv_get_audio_output(itv, 0, &audout);
1236 IVTV_INFO("Video Output: %s\n", vidout.name); 1329 IVTV_INFO("Video Output: %s\n", vidout.name);
1237 IVTV_INFO("Audio Output: %s\n", audout.name); 1330 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1331 audio_modes[itv->audio_stereo_mode],
1332 audio_modes[itv->audio_bilingual_mode]);
1238 if (mode < 0 || mode > OUT_PASSTHROUGH) 1333 if (mode < 0 || mode > OUT_PASSTHROUGH)
1239 mode = OUT_NONE; 1334 mode = OUT_NONE;
1240 IVTV_INFO("Output Mode: %s\n", output_modes[mode]); 1335 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1336 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1337 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1338 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1339 data[0] & 1 ? "On" : "Off",
1340 alpha_mode[(data[0] >> 1) & 0x3],
1341 pixel_format[(data[0] >> 3) & 0xf]);
1241 } 1342 }
1242 IVTV_INFO("Tuner: %s\n", 1343 IVTV_INFO("Tuner: %s\n",
1243 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); 1344 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1244 cx2341x_log_status(&itv->params, itv->name); 1345 cx2341x_log_status(&itv->params, itv->name);
1245 IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags); 1346 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1246 for (i = 0; i < IVTV_MAX_STREAMS; i++) { 1347 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1247 struct ivtv_stream *s = &itv->streams[i]; 1348 struct ivtv_stream *s = &itv->streams[i];
1248 1349
@@ -1252,7 +1353,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void
1252 (s->buffers - s->q_free.buffers) * 100 / s->buffers, 1353 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1253 (s->buffers * s->buf_size) / 1024, s->buffers); 1354 (s->buffers * s->buf_size) / 1024, s->buffers);
1254 } 1355 }
1255 IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); 1356 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
1256 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); 1357 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1257 break; 1358 break;
1258 } 1359 }
@@ -1288,6 +1389,8 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1288 ivtv_release_stream(s); 1389 ivtv_release_stream(s);
1289 return -EBUSY; 1390 return -EBUSY;
1290 } 1391 }
1392 /* Mark that this file handle started the UDMA_YUV mode */
1393 id->yuv_frames = 1;
1291 if (args->y_source == NULL) 1394 if (args->y_source == NULL)
1292 return 0; 1395 return 0;
1293 return ivtv_yuv_prep_frame(itv, args); 1396 return ivtv_yuv_prep_frame(itv, args);
@@ -1396,9 +1499,9 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1396 int try = (cmd == VIDEO_TRY_COMMAND); 1499 int try = (cmd == VIDEO_TRY_COMMAND);
1397 1500
1398 if (try) 1501 if (try)
1399 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n"); 1502 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
1400 else 1503 else
1401 IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n"); 1504 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
1402 return ivtv_video_command(itv, id, vc, try); 1505 return ivtv_video_command(itv, id, vc, try);
1403 } 1506 }
1404 1507
@@ -1429,11 +1532,15 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1429 return 0; 1532 return 0;
1430 if (nonblocking) 1533 if (nonblocking)
1431 return -EAGAIN; 1534 return -EAGAIN;
1432 /* wait for event */ 1535 /* Wait for event. Note that serialize_lock is locked,
1536 so to allow other processes to access the driver while
1537 we are waiting unlock first and later lock again. */
1538 mutex_unlock(&itv->serialize_lock);
1433 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE); 1539 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
1434 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0) 1540 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
1435 schedule(); 1541 schedule();
1436 finish_wait(&itv->event_waitq, &wait); 1542 finish_wait(&itv->event_waitq, &wait);
1543 mutex_lock(&itv->serialize_lock);
1437 if (signal_pending(current)) { 1544 if (signal_pending(current)) {
1438 /* return if a signal was received */ 1545 /* return if a signal was received */
1439 IVTV_DEBUG_INFO("User stopped wait for event\n"); 1546 IVTV_DEBUG_INFO("User stopped wait for event\n");
@@ -1470,6 +1577,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1470 case VIDIOC_S_AUDOUT: 1577 case VIDIOC_S_AUDOUT:
1471 case VIDIOC_S_EXT_CTRLS: 1578 case VIDIOC_S_EXT_CTRLS:
1472 case VIDIOC_S_FBUF: 1579 case VIDIOC_S_FBUF:
1580 case VIDIOC_OVERLAY:
1473 ret = v4l2_prio_check(&itv->prio, &id->prio); 1581 ret = v4l2_prio_check(&itv->prio, &id->prio);
1474 if (ret) 1582 if (ret)
1475 return ret; 1583 return ret;
@@ -1523,6 +1631,7 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1523 case VIDIOC_TRY_ENCODER_CMD: 1631 case VIDIOC_TRY_ENCODER_CMD:
1524 case VIDIOC_G_FBUF: 1632 case VIDIOC_G_FBUF:
1525 case VIDIOC_S_FBUF: 1633 case VIDIOC_S_FBUF:
1634 case VIDIOC_OVERLAY:
1526 if (ivtv_debug & IVTV_DBGFLG_IOCTL) { 1635 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1527 printk(KERN_INFO "ivtv%d ioctl: ", itv->num); 1636 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1528 v4l_printk_ioctl(cmd); 1637 v4l_printk_ioctl(cmd);
@@ -1563,12 +1672,9 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1563 return 0; 1672 return 0;
1564} 1673}
1565 1674
1566int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 1675static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
1567 unsigned long arg) 1676 unsigned int cmd, unsigned long arg)
1568{ 1677{
1569 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1570 struct ivtv *itv = id->itv;
1571
1572 /* Filter dvb ioctls that cannot be handled by video_usercopy */ 1678 /* Filter dvb ioctls that cannot be handled by video_usercopy */
1573 switch (cmd) { 1679 switch (cmd) {
1574 case VIDEO_SELECT_SOURCE: 1680 case VIDEO_SELECT_SOURCE:
@@ -1603,3 +1709,16 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1603 } 1709 }
1604 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl); 1710 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
1605} 1711}
1712
1713int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1714 unsigned long arg)
1715{
1716 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1717 struct ivtv *itv = id->itv;
1718 int res;
1719
1720 mutex_lock(&itv->serialize_lock);
1721 res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
1722 mutex_unlock(&itv->serialize_lock);
1723 return res;
1724}