diff options
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/gspca/gspca.c | 146 |
1 files changed, 74 insertions, 72 deletions
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c index 2ffb00ab0811..a566fd394895 100644 --- a/drivers/media/video/gspca/gspca.c +++ b/drivers/media/video/gspca/gspca.c | |||
@@ -42,8 +42,8 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); | |||
42 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); | 42 | MODULE_DESCRIPTION("GSPCA USB Camera Driver"); |
43 | MODULE_LICENSE("GPL"); | 43 | MODULE_LICENSE("GPL"); |
44 | 44 | ||
45 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 6) | 45 | #define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 1, 7) |
46 | static const char version[] = "2.1.6"; | 46 | static const char version[] = "2.1.7"; |
47 | 47 | ||
48 | static int video_nr = -1; | 48 | static int video_nr = -1; |
49 | 49 | ||
@@ -558,11 +558,6 @@ static void gspca_stream_off(struct gspca_dev *gspca_dev) | |||
558 | gspca_set_alt0(gspca_dev); | 558 | gspca_set_alt0(gspca_dev); |
559 | gspca_dev->sd_desc->stop0(gspca_dev); | 559 | gspca_dev->sd_desc->stop0(gspca_dev); |
560 | PDEBUG(D_STREAM, "stream off OK"); | 560 | PDEBUG(D_STREAM, "stream off OK"); |
561 | } else { | ||
562 | destroy_urbs(gspca_dev); | ||
563 | atomic_inc(&gspca_dev->nevent); | ||
564 | wake_up_interruptible(&gspca_dev->wq); | ||
565 | PDEBUG(D_ERR|D_STREAM, "stream off no device ??"); | ||
566 | } | 561 | } |
567 | } | 562 | } |
568 | 563 | ||
@@ -680,9 +675,6 @@ static int try_fmt_vid_cap(struct gspca_dev *gspca_dev, | |||
680 | w = fmt->fmt.pix.width; | 675 | w = fmt->fmt.pix.width; |
681 | h = fmt->fmt.pix.height; | 676 | h = fmt->fmt.pix.height; |
682 | 677 | ||
683 | /* (luvcview problem) */ | ||
684 | if (fmt->fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) | ||
685 | fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG; | ||
686 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 678 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
687 | if (gspca_debug & D_CONF) | 679 | if (gspca_debug & D_CONF) |
688 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); | 680 | PDEBUG_MODE("try fmt cap", fmt->fmt.pix.pixelformat, w, h); |
@@ -816,7 +808,7 @@ static int dev_close(struct inode *inode, struct file *file) | |||
816 | return -ERESTARTSYS; | 808 | return -ERESTARTSYS; |
817 | gspca_dev->users--; | 809 | gspca_dev->users--; |
818 | 810 | ||
819 | /* if the file did capture, free the streaming resources */ | 811 | /* if the file did the capture, free the streaming resources */ |
820 | if (gspca_dev->capt_file == file) { | 812 | if (gspca_dev->capt_file == file) { |
821 | mutex_lock(&gspca_dev->usb_lock); | 813 | mutex_lock(&gspca_dev->usb_lock); |
822 | if (gspca_dev->streaming) | 814 | if (gspca_dev->streaming) |
@@ -981,7 +973,7 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
981 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 973 | if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
982 | return -EINVAL; | 974 | return -EINVAL; |
983 | switch (rb->memory) { | 975 | switch (rb->memory) { |
984 | case GSPCA_MEMORY_READ: | 976 | case GSPCA_MEMORY_READ: /* (internal call) */ |
985 | case V4L2_MEMORY_MMAP: | 977 | case V4L2_MEMORY_MMAP: |
986 | case V4L2_MEMORY_USERPTR: | 978 | case V4L2_MEMORY_USERPTR: |
987 | break; | 979 | break; |
@@ -991,33 +983,46 @@ static int vidioc_reqbufs(struct file *file, void *priv, | |||
991 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 983 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
992 | return -ERESTARTSYS; | 984 | return -ERESTARTSYS; |
993 | 985 | ||
994 | /* only one file may do capture */ | 986 | if (gspca_dev->memory != GSPCA_MEMORY_NO |
995 | if ((gspca_dev->capt_file != NULL && gspca_dev->capt_file != file) | 987 | && gspca_dev->memory != rb->memory) { |
996 | || gspca_dev->streaming) { | ||
997 | ret = -EBUSY; | 988 | ret = -EBUSY; |
998 | goto out; | 989 | goto out; |
999 | } | 990 | } |
1000 | 991 | ||
1001 | if (rb->count == 0) { /* unrequest */ | 992 | /* only one file may do the capture */ |
1002 | for (i = 0; i < gspca_dev->nframes; i++) { | 993 | if (gspca_dev->capt_file != NULL |
1003 | if (gspca_dev->frame[i].vma_use_count) { | 994 | && gspca_dev->capt_file != file) { |
1004 | ret = -EBUSY; | 995 | ret = -EBUSY; |
1005 | goto out; | 996 | goto out; |
1006 | } | 997 | } |
1007 | } | 998 | |
1008 | frame_free(gspca_dev); | 999 | /* if allocated, the buffers must not be mapped */ |
1009 | gspca_dev->capt_file = NULL; | 1000 | for (i = 0; i < gspca_dev->nframes; i++) { |
1010 | } else { | 1001 | if (gspca_dev->frame[i].vma_use_count) { |
1011 | if (gspca_dev->nframes != 0) { | ||
1012 | ret = -EBUSY; | 1002 | ret = -EBUSY; |
1013 | goto out; | 1003 | goto out; |
1014 | } | 1004 | } |
1015 | gspca_dev->memory = rb->memory; | 1005 | } |
1016 | ret = frame_alloc(gspca_dev, rb->count); | 1006 | |
1017 | if (ret == 0) { | 1007 | /* stop streaming */ |
1018 | rb->count = gspca_dev->nframes; | 1008 | if (gspca_dev->streaming) { |
1019 | gspca_dev->capt_file = file; | 1009 | mutex_lock(&gspca_dev->usb_lock); |
1020 | } | 1010 | gspca_stream_off(gspca_dev); |
1011 | mutex_unlock(&gspca_dev->usb_lock); | ||
1012 | } | ||
1013 | |||
1014 | /* free the previous allocated buffers, if any */ | ||
1015 | if (gspca_dev->nframes != 0) { | ||
1016 | frame_free(gspca_dev); | ||
1017 | gspca_dev->capt_file = NULL; | ||
1018 | } | ||
1019 | if (rb->count == 0) /* unrequest */ | ||
1020 | goto out; | ||
1021 | gspca_dev->memory = rb->memory; | ||
1022 | ret = frame_alloc(gspca_dev, rb->count); | ||
1023 | if (ret == 0) { | ||
1024 | rb->count = gspca_dev->nframes; | ||
1025 | gspca_dev->capt_file = file; | ||
1021 | } | 1026 | } |
1022 | out: | 1027 | out: |
1023 | mutex_unlock(&gspca_dev->queue_lock); | 1028 | mutex_unlock(&gspca_dev->queue_lock); |
@@ -1059,10 +1064,6 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1059 | ret = -EINVAL; | 1064 | ret = -EINVAL; |
1060 | goto out; | 1065 | goto out; |
1061 | } | 1066 | } |
1062 | if (gspca_dev->capt_file != file) { | ||
1063 | ret = -EINVAL; | ||
1064 | goto out; | ||
1065 | } | ||
1066 | if (!gspca_dev->streaming) { | 1067 | if (!gspca_dev->streaming) { |
1067 | ret = gspca_init_transfer(gspca_dev); | 1068 | ret = gspca_init_transfer(gspca_dev); |
1068 | if (ret < 0) | 1069 | if (ret < 0) |
@@ -1086,7 +1087,7 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1086 | enum v4l2_buf_type buf_type) | 1087 | enum v4l2_buf_type buf_type) |
1087 | { | 1088 | { |
1088 | struct gspca_dev *gspca_dev = priv; | 1089 | struct gspca_dev *gspca_dev = priv; |
1089 | int ret; | 1090 | int i, ret; |
1090 | 1091 | ||
1091 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1092 | if (buf_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1092 | return -EINVAL; | 1093 | return -EINVAL; |
@@ -1094,18 +1095,23 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1094 | return 0; | 1095 | return 0; |
1095 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | 1096 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) |
1096 | return -ERESTARTSYS; | 1097 | return -ERESTARTSYS; |
1098 | |||
1099 | /* stop streaming */ | ||
1097 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { | 1100 | if (mutex_lock_interruptible(&gspca_dev->usb_lock)) { |
1098 | ret = -ERESTARTSYS; | 1101 | ret = -ERESTARTSYS; |
1099 | goto out; | 1102 | goto out; |
1100 | } | 1103 | } |
1101 | if (gspca_dev->capt_file != file) { | ||
1102 | ret = -EINVAL; | ||
1103 | goto out2; | ||
1104 | } | ||
1105 | gspca_stream_off(gspca_dev); | 1104 | gspca_stream_off(gspca_dev); |
1106 | ret = 0; | ||
1107 | out2: | ||
1108 | mutex_unlock(&gspca_dev->usb_lock); | 1105 | mutex_unlock(&gspca_dev->usb_lock); |
1106 | |||
1107 | /* empty the application queues */ | ||
1108 | for (i = 0; i < gspca_dev->nframes; i++) | ||
1109 | gspca_dev->frame[i].v4l2_buf.flags &= ~BUF_ALL_FLAGS; | ||
1110 | gspca_dev->fr_i = gspca_dev->fr_o = gspca_dev->fr_q = 0; | ||
1111 | gspca_dev->last_packet_type = DISCARD_PACKET; | ||
1112 | gspca_dev->sequence = 0; | ||
1113 | atomic_set(&gspca_dev->nevent, 0); | ||
1114 | ret = 0; | ||
1109 | out: | 1115 | out: |
1110 | mutex_unlock(&gspca_dev->queue_lock); | 1116 | mutex_unlock(&gspca_dev->queue_lock); |
1111 | return ret; | 1117 | return ret; |
@@ -1364,14 +1370,17 @@ static int vidioc_dqbuf(struct file *file, void *priv, | |||
1364 | return -EINVAL; | 1370 | return -EINVAL; |
1365 | if (v4l2_buf->memory != gspca_dev->memory) | 1371 | if (v4l2_buf->memory != gspca_dev->memory) |
1366 | return -EINVAL; | 1372 | return -EINVAL; |
1367 | if (!gspca_dev->streaming) | 1373 | |
1374 | /* if not streaming, be sure the application will not loop forever */ | ||
1375 | if (!(file->f_flags & O_NONBLOCK) | ||
1376 | && !gspca_dev->streaming && gspca_dev->users == 1) | ||
1368 | return -EINVAL; | 1377 | return -EINVAL; |
1369 | if (gspca_dev->capt_file != file) { | ||
1370 | ret = -EINVAL; | ||
1371 | goto out; | ||
1372 | } | ||
1373 | 1378 | ||
1374 | /* only one read */ | 1379 | /* only the capturing file may dequeue */ |
1380 | if (gspca_dev->capt_file != file) | ||
1381 | return -EINVAL; | ||
1382 | |||
1383 | /* only one dequeue / read at a time */ | ||
1375 | if (mutex_lock_interruptible(&gspca_dev->read_lock)) | 1384 | if (mutex_lock_interruptible(&gspca_dev->read_lock)) |
1376 | return -ERESTARTSYS; | 1385 | return -ERESTARTSYS; |
1377 | 1386 | ||
@@ -1416,24 +1425,23 @@ static int vidioc_qbuf(struct file *file, void *priv, | |||
1416 | if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 1425 | if (v4l2_buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1417 | return -EINVAL; | 1426 | return -EINVAL; |
1418 | 1427 | ||
1428 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1429 | return -ERESTARTSYS; | ||
1430 | |||
1419 | index = v4l2_buf->index; | 1431 | index = v4l2_buf->index; |
1420 | if ((unsigned) index >= gspca_dev->nframes) { | 1432 | if ((unsigned) index >= gspca_dev->nframes) { |
1421 | PDEBUG(D_FRAM, | 1433 | PDEBUG(D_FRAM, |
1422 | "qbuf idx %d >= %d", index, gspca_dev->nframes); | 1434 | "qbuf idx %d >= %d", index, gspca_dev->nframes); |
1423 | return -EINVAL; | 1435 | ret = -EINVAL; |
1436 | goto out; | ||
1424 | } | 1437 | } |
1425 | frame = &gspca_dev->frame[index]; | 1438 | if (v4l2_buf->memory != gspca_dev->memory) { |
1426 | |||
1427 | if (v4l2_buf->memory != frame->v4l2_buf.memory) { | ||
1428 | PDEBUG(D_FRAM, "qbuf bad memory type"); | 1439 | PDEBUG(D_FRAM, "qbuf bad memory type"); |
1429 | return -EINVAL; | 1440 | ret = -EINVAL; |
1441 | goto out; | ||
1430 | } | 1442 | } |
1431 | if (gspca_dev->capt_file != file) | ||
1432 | return -EINVAL; | ||
1433 | |||
1434 | if (mutex_lock_interruptible(&gspca_dev->queue_lock)) | ||
1435 | return -ERESTARTSYS; | ||
1436 | 1443 | ||
1444 | frame = &gspca_dev->frame[index]; | ||
1437 | if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) { | 1445 | if (frame->v4l2_buf.flags & BUF_ALL_FLAGS) { |
1438 | PDEBUG(D_FRAM, "qbuf bad state"); | 1446 | PDEBUG(D_FRAM, "qbuf bad state"); |
1439 | ret = -EINVAL; | 1447 | ret = -EINVAL; |
@@ -1492,9 +1500,6 @@ static int read_alloc(struct gspca_dev *gspca_dev, | |||
1492 | v4l2_buf.memory = GSPCA_MEMORY_READ; | 1500 | v4l2_buf.memory = GSPCA_MEMORY_READ; |
1493 | for (i = 0; i < gspca_dev->nbufread; i++) { | 1501 | for (i = 0; i < gspca_dev->nbufread; i++) { |
1494 | v4l2_buf.index = i; | 1502 | v4l2_buf.index = i; |
1495 | /*fixme: ugly!*/ | ||
1496 | gspca_dev->frame[i].v4l2_buf.flags |= | ||
1497 | V4L2_BUF_FLAG_MAPPED; | ||
1498 | ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); | 1503 | ret = vidioc_qbuf(file, gspca_dev, &v4l2_buf); |
1499 | if (ret != 0) { | 1504 | if (ret != 0) { |
1500 | PDEBUG(D_STREAM, "read qbuf err: %d", ret); | 1505 | PDEBUG(D_STREAM, "read qbuf err: %d", ret); |
@@ -1522,17 +1527,13 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) | |||
1522 | if (!gspca_dev->present) | 1527 | if (!gspca_dev->present) |
1523 | return POLLERR; | 1528 | return POLLERR; |
1524 | 1529 | ||
1525 | /* if not streaming, the user would use read() */ | 1530 | /* if reqbufs is not done, the user would use read() */ |
1526 | if (!gspca_dev->streaming) { | 1531 | if (gspca_dev->nframes == 0) { |
1527 | if (gspca_dev->memory != GSPCA_MEMORY_NO) { | 1532 | if (gspca_dev->memory != GSPCA_MEMORY_NO) |
1528 | ret = POLLERR; /* not the 1st time */ | 1533 | return POLLERR; /* not the 1st time */ |
1529 | goto out; | ||
1530 | } | ||
1531 | ret = read_alloc(gspca_dev, file); | 1534 | ret = read_alloc(gspca_dev, file); |
1532 | if (ret != 0) { | 1535 | if (ret != 0) |
1533 | ret = POLLERR; | 1536 | return POLLERR; |
1534 | goto out; | ||
1535 | } | ||
1536 | } | 1537 | } |
1537 | 1538 | ||
1538 | if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) | 1539 | if (mutex_lock_interruptible(&gspca_dev->queue_lock) != 0) |
@@ -1542,6 +1543,7 @@ static unsigned int dev_poll(struct file *file, poll_table *wait) | |||
1542 | goto out; | 1543 | goto out; |
1543 | } | 1544 | } |
1544 | 1545 | ||
1546 | /* check the next incoming buffer */ | ||
1545 | i = gspca_dev->fr_o; | 1547 | i = gspca_dev->fr_o; |
1546 | i = gspca_dev->fr_queue[i]; | 1548 | i = gspca_dev->fr_queue[i]; |
1547 | if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) | 1549 | if (gspca_dev->frame[i].v4l2_buf.flags & V4L2_BUF_FLAG_DONE) |