aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/pwc/pwc-if.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pwc/pwc-if.c')
-rw-r--r--drivers/media/video/pwc/pwc-if.c68
1 files changed, 22 insertions, 46 deletions
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index f3dc89da4c4e..bd1519a4ecb4 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -287,14 +287,13 @@ static int pwc_allocate_buffers(struct pwc_device *pdev)
287 /* create frame buffers, and make circular ring */ 287 /* create frame buffers, and make circular ring */
288 for (i = 0; i < default_fbufs; i++) { 288 for (i = 0; i < default_fbufs; i++) {
289 if (pdev->fbuf[i].data == NULL) { 289 if (pdev->fbuf[i].data == NULL) {
290 kbuf = vmalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */ 290 kbuf = vzalloc(PWC_FRAME_SIZE); /* need vmalloc since frame buffer > 128K */
291 if (kbuf == NULL) { 291 if (kbuf == NULL) {
292 PWC_ERROR("Failed to allocate frame buffer %d.\n", i); 292 PWC_ERROR("Failed to allocate frame buffer %d.\n", i);
293 return -ENOMEM; 293 return -ENOMEM;
294 } 294 }
295 PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf); 295 PWC_DEBUG_MEMORY("Allocated frame buffer %d at %p.\n", i, kbuf);
296 pdev->fbuf[i].data = kbuf; 296 pdev->fbuf[i].data = kbuf;
297 memset(kbuf, 0, PWC_FRAME_SIZE);
298 } 297 }
299 } 298 }
300 299
@@ -899,10 +898,13 @@ int pwc_isoc_init(struct pwc_device *pdev)
899 /* link */ 898 /* link */
900 for (i = 0; i < MAX_ISO_BUFS; i++) { 899 for (i = 0; i < MAX_ISO_BUFS; i++) {
901 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL); 900 ret = usb_submit_urb(pdev->sbuf[i].urb, GFP_KERNEL);
902 if (ret) 901 if (ret) {
903 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret); 902 PWC_ERROR("isoc_init() submit_urb %d failed with error %d\n", i, ret);
904 else 903 pdev->iso_init = 1;
905 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb); 904 pwc_isoc_cleanup(pdev);
905 return ret;
906 }
907 PWC_DEBUG_MEMORY("URB 0x%p submitted.\n", pdev->sbuf[i].urb);
906 } 908 }
907 909
908 /* All is done... */ 910 /* All is done... */
@@ -958,7 +960,7 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
958 /* Stop camera, but only if we are sure the camera is still there (unplug 960 /* Stop camera, but only if we are sure the camera is still there (unplug
959 is signalled by EPIPE) 961 is signalled by EPIPE)
960 */ 962 */
961 if (pdev->error_status && pdev->error_status != EPIPE) { 963 if (pdev->error_status != EPIPE) {
962 PWC_DEBUG_OPEN("Setting alternate interface 0.\n"); 964 PWC_DEBUG_OPEN("Setting alternate interface 0.\n");
963 usb_set_interface(pdev->udev, 0, 0); 965 usb_set_interface(pdev->udev, 0, 0);
964 } 966 }
@@ -967,36 +969,6 @@ void pwc_isoc_cleanup(struct pwc_device *pdev)
967 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n"); 969 PWC_DEBUG_OPEN("<< pwc_isoc_cleanup()\n");
968} 970}
969 971
970int pwc_try_video_mode(struct pwc_device *pdev, int width, int height, int new_fps, int new_compression, int new_snapshot)
971{
972 int ret, start;
973
974 /* Stop isoc stuff */
975 pwc_isoc_cleanup(pdev);
976 /* Reset parameters */
977 pwc_reset_buffers(pdev);
978 /* Try to set video mode... */
979 start = ret = pwc_set_video_mode(pdev, width, height, new_fps, new_compression, new_snapshot);
980 if (ret) {
981 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 1 failed.\n");
982 /* That failed... restore old mode (we know that worked) */
983 start = pwc_set_video_mode(pdev, pdev->view.x, pdev->view.y, pdev->vframes, pdev->vcompression, pdev->vsnapshot);
984 if (start) {
985 PWC_DEBUG_FLOW("pwc_set_video_mode attempt 2 failed.\n");
986 }
987 }
988 if (start == 0)
989 {
990 if (pwc_isoc_init(pdev) < 0)
991 {
992 PWC_WARNING("Failed to restart ISOC transfers in pwc_try_video_mode.\n");
993 ret = -EAGAIN; /* let's try again, who knows if it works a second time */
994 }
995 }
996 pdev->drop_frames++; /* try to avoid garbage during switch */
997 return ret; /* Return original error code */
998}
999
1000/********* 972/*********
1001 * sysfs 973 * sysfs
1002 *********/ 974 *********/
@@ -1176,7 +1148,7 @@ static int pwc_video_open(struct file *file)
1176 /* Set some defaults */ 1148 /* Set some defaults */
1177 pdev->vsnapshot = 0; 1149 pdev->vsnapshot = 0;
1178 1150
1179 /* Start iso pipe for video; first try the last used video size 1151 /* Set video size, first try the last used video size
1180 (or the default one); if that fails try QCIF/10 or QSIF/10; 1152 (or the default one); if that fails try QCIF/10 or QSIF/10;
1181 it that fails too, give up. 1153 it that fails too, give up.
1182 */ 1154 */
@@ -1203,15 +1175,6 @@ static int pwc_video_open(struct file *file)
1203 return i; 1175 return i;
1204 } 1176 }
1205 1177
1206 i = pwc_isoc_init(pdev);
1207 if (i) {
1208 PWC_DEBUG_OPEN("Failed to init ISOC stuff = %d.\n", i);
1209 pwc_isoc_cleanup(pdev);
1210 pwc_free_buffers(pdev);
1211 mutex_unlock(&pdev->modlock);
1212 return i;
1213 }
1214
1215 /* Initialize the webcam to sane value */ 1178 /* Initialize the webcam to sane value */
1216 pwc_set_brightness(pdev, 0x7fff); 1179 pwc_set_brightness(pdev, 0x7fff);
1217 pwc_set_agc(pdev, 1, 0); 1180 pwc_set_agc(pdev, 1, 0);
@@ -1326,6 +1289,11 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1326 goto err_out; 1289 goto err_out;
1327 } 1290 }
1328 1291
1292 /* Start the stream (if not already started) */
1293 rv = pwc_isoc_init(pdev);
1294 if (rv)
1295 goto err_out;
1296
1329 /* In case we're doing partial reads, we don't have to wait for a frame */ 1297 /* In case we're doing partial reads, we don't have to wait for a frame */
1330 if (pdev->image_read_pos == 0) { 1298 if (pdev->image_read_pos == 0) {
1331 /* Do wait queueing according to the (doc)book */ 1299 /* Do wait queueing according to the (doc)book */
@@ -1395,6 +1363,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1395{ 1363{
1396 struct video_device *vdev = file->private_data; 1364 struct video_device *vdev = file->private_data;
1397 struct pwc_device *pdev; 1365 struct pwc_device *pdev;
1366 int ret;
1398 1367
1399 if (vdev == NULL) 1368 if (vdev == NULL)
1400 return -EFAULT; 1369 return -EFAULT;
@@ -1402,6 +1371,13 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1402 if (pdev == NULL) 1371 if (pdev == NULL)
1403 return -EFAULT; 1372 return -EFAULT;
1404 1373
1374 /* Start the stream (if not already started) */
1375 mutex_lock(&pdev->modlock);
1376 ret = pwc_isoc_init(pdev);
1377 mutex_unlock(&pdev->modlock);
1378 if (ret)
1379 return ret;
1380
1405 poll_wait(file, &pdev->frameq, wait); 1381 poll_wait(file, &pdev->frameq, wait);
1406 if (pdev->error_status) 1382 if (pdev->error_status)
1407 return POLLERR; 1383 return POLLERR;