aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2010-11-16 09:39:25 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-12-29 05:16:52 -0500
commit3751e288bcf3d77652ef979edc0b3ea8b21d8b97 (patch)
treed0a628cd8c555f186ef402bdd936ad27b7c0c82d
parenta931910d3be6f63464befb2dde94ec58a6eaf5c1 (diff)
[media] pwc: do not start isoc stream on /dev/video open
pwc was starting streaming on /dev/video# open rather then on STREAM_ON. Now that the v4l1 compat code is removed from the pwc driver there is no reason left to do this. So this patch changes the pwc driver to delay starting the isoc stream (and thus using valuable usb bandwidth) until the application does a STREAM_ON Signed-off-by: Hans de Goede <hdegoede@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/pwc/pwc-ctrl.c7
-rw-r--r--drivers/media/video/pwc/pwc-if.c54
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c13
-rw-r--r--drivers/media/video/pwc/pwc.h1
4 files changed, 27 insertions, 48 deletions
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c
index 6b8fbddc0747..1593f8deb810 100644
--- a/drivers/media/video/pwc/pwc-ctrl.c
+++ b/drivers/media/video/pwc/pwc-ctrl.c
@@ -1386,11 +1386,16 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg)
1386 { 1386 {
1387 ARG_DEF(int, qual) 1387 ARG_DEF(int, qual)
1388 1388
1389 if (pdev->iso_init) {
1390 ret = -EBUSY;
1391 break;
1392 }
1393
1389 ARG_IN(qual) 1394 ARG_IN(qual)
1390 if (ARGR(qual) < 0 || ARGR(qual) > 3) 1395 if (ARGR(qual) < 0 || ARGR(qual) > 3)
1391 ret = -EINVAL; 1396 ret = -EINVAL;
1392 else 1397 else
1393 ret = pwc_try_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot); 1398 ret = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, ARGR(qual), pdev->vsnapshot);
1394 if (ret >= 0) 1399 if (ret >= 0)
1395 pdev->vcompression = ARGR(qual); 1400 pdev->vcompression = ARGR(qual);
1396 break; 1401 break;
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index b821065e3870..6f8b682b9245 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -966,36 +966,6 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
966 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); 966 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
967} 967}
968 968
969int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
970{
971 int ret, start;
972
973 /* Stop isoc stuff */
974 pwc_isoc_cleanup(pdev);
975 /* Reset parameters */
976 pwc_reset_buffers(pdev);
977 /* Try to set video mode... */
978 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
979 if (ret) {
980 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n");
981 /* That failed... restore old mode (we know that worked) */
982 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
983 if (start) {
984 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n");
985 }
986 }
987 if (start == 0)
988 {
989 if (pwc_isoc_init(pdev) < 0)
990 {
991 PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
992 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
993 }
994 }
995 pdev->drop_frames++; /* try to avoid garbage during switch */
996 return ret; /* Return original error code */
997}
998
999/********* 969/*********
1000 * sysfs 970 * sysfs
1001 *********/ 971 *********/
@@ -1175,7 +1145,7 @@ static int pwc_video_open(struct file *file)
1175 /* Set some defaults */ 1145 /* Set some defaults */
1176 pdev->vsnapshot = 0; 1146 pdev->vsnapshot = 0;
1177 1147
1178 /* Start iso pipe for video; first try the last used video size 1148 /* Set video size, first try the last used video size
1179 (or the default one); if that fails try QCIF/10 or QSIF/10; 1149 (or the default one); if that fails try QCIF/10 or QSIF/10;
1180 it that fails too, give up. 1150 it that fails too, give up.
1181 */ 1151 */
@@ -1202,15 +1172,6 @@ static int pwc_video_open(struct file *file)
1202 return i; 1172 return i;
1203 } 1173 }
1204 1174
1205 i = pwc_isoc_init(pdev);
1206 if (i) {
1207 PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i);
1208 pwc_isoc_cleanup(pdev);
1209 pwc_free_buffers(pdev);
1210 mutex_unlock(&pdev->modlock);
1211 return i;
1212 }
1213
1214 /* Initialize the webcam to sane value */ 1175 /* Initialize the webcam to sane value */
1215 pwc_set_brightness(pdev, 0x7fff); 1176 pwc_set_brightness(pdev, 0x7fff);
1216 pwc_set_agc(pdev, 1, 0); 1177 pwc_set_agc(pdev, 1, 0);
@@ -1325,6 +1286,11 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1325 goto err_out; 1286 goto err_out;
1326 } 1287 }
1327 1288
1289 /* Start the stream (if not already started) */
1290 rv = pwc_isoc_init(pdev);
1291 if (rv)
1292 goto err_out;
1293
1328 /* In case we're doing partial reads, we don't have to wait for a frame */ 1294 /* In case we're doing partial reads, we don't have to wait for a frame */
1329 if (pdev->image_read_pos == 0) { 1295 if (pdev->image_read_pos == 0) {
1330 /* Do wait queueing according to the (doc)book */ 1296 /* Do wait queueing according to the (doc)book */
@@ -1394,6 +1360,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1394{ 1360{
1395 struct video_device *vdev = file->private_data; 1361 struct video_device *vdev = file->private_data;
1396 struct pwc_device *pdev; 1362 struct pwc_device *pdev;
1363 int ret;
1397 1364
1398 if (vdev == NULL) 1365 if (vdev == NULL)
1399 return -EFAULT; 1366 return -EFAULT;
@@ -1401,6 +1368,13 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1401 if (pdev == NULL) 1368 if (pdev == NULL)
1402 return -EFAULT; 1369 return -EFAULT;
1403 1370
1371 /* Start the stream (if not already started) */
1372 mutex_lock(&pdev->modlock);
1373 ret = pwc_isoc_init(pdev);
1374 mutex_unlock(&pdev->modlock);
1375 if (ret)
1376 return ret;
1377
1404 poll_wait(file, &pdev->frameq, wait); 1378 poll_wait(file, &pdev->frameq, wait);
1405 if (pdev->error_status) 1379 if (pdev->error_status)
1406 return POLLERR; 1380 return POLLERR;
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 7061a03f5cf1..2ef1668638f9 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -309,7 +309,10 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
309 pixelformat != V4L2_PIX_FMT_PWC2) 309 pixelformat != V4L2_PIX_FMT_PWC2)
310 return -EINVAL; 310 return -EINVAL;
311 311
312 PWC_DEBUG_IOCTL("Try to change format to: width=%d height=%d fps=%d " 312 if (pdev->iso_init)
313 return -EBUSY;
314
315 PWC_DEBUG_IOCTL("Trying to set format to: width=%d height=%d fps=%d "
313 "compression=%d snapshot=%d format=%c%c%c%c\n", 316 "compression=%d snapshot=%d format=%c%c%c%c\n",
314 f->fmt.pix.width, f->fmt.pix.height, fps, 317 f->fmt.pix.width, f->fmt.pix.height, fps,
315 compression, snapshot, 318 compression, snapshot,
@@ -318,14 +321,14 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
318 (pixelformat>>16)&255, 321 (pixelformat>>16)&255,
319 (pixelformat>>24)&255); 322 (pixelformat>>24)&255);
320 323
321 ret = pwc_try_video_mode(pdev, 324 ret = pwc_set_video_mode(pdev,
322 f->fmt.pix.width, 325 f->fmt.pix.width,
323 f->fmt.pix.height, 326 f->fmt.pix.height,
324 fps, 327 fps,
325 compression, 328 compression,
326 snapshot); 329 snapshot);
327 330
328 PWC_DEBUG_IOCTL("pwc_try_video_mode(), return=%d\n", ret); 331 PWC_DEBUG_IOCTL("pwc_set_video_mode(), return=%d\n", ret);
329 332
330 if (ret) 333 if (ret)
331 return ret; 334 return ret;
@@ -882,9 +885,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
882 885
883 case VIDIOC_STREAMON: 886 case VIDIOC_STREAMON:
884 { 887 {
885 /* WARNING: pwc_try_video_mode() called pwc_isoc_init */ 888 return pwc_isoc_init(pdev);
886 pwc_isoc_init(pdev);
887 return 0;
888 } 889 }
889 890
890 case VIDIOC_STREAMOFF: 891 case VIDIOC_STREAMOFF:
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 36a9c83b5f5d..16bbc6df9b07 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -275,7 +275,6 @@ extern int pwc_trace;
275extern int pwc_mbufs; 275extern int pwc_mbufs;
276 276
277/** functions in pwc-if.c */ 277/** functions in pwc-if.c */
278int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot);
279int pwc_handle_frame(struct pwc_device *pdev); 278int pwc_handle_frame(struct pwc_device *pdev);
280void pwc_next_image(struct pwc_device *pdev); 279void pwc_next_image(struct pwc_device *pdev);
281int pwc_isoc_init(struct pwc_device *pdev); 280int pwc_isoc_init(struct pwc_device *pdev);