aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx/em28xx-video.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/em28xx/em28xx-video.c')
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c124
1 files changed, 73 insertions, 51 deletions
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index b43edc3fa23e..5b17ca9cad11 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -234,6 +234,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
234 int minor = iminor(inode); 234 int minor = iminor(inode);
235 int errCode = 0; 235 int errCode = 0;
236 struct em28xx *h,*dev = NULL; 236 struct em28xx *h,*dev = NULL;
237 struct em28xx_fh *fh;
237 238
238 list_for_each_entry(h, &em28xx_devlist, devlist) { 239 list_for_each_entry(h, &em28xx_devlist, devlist) {
239 if (h->vdev->minor == minor) { 240 if (h->vdev->minor == minor) {
@@ -251,19 +252,17 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
251 em28xx_videodbg("open minor=%d type=%s users=%d\n", 252 em28xx_videodbg("open minor=%d type=%s users=%d\n",
252 minor,v4l2_type_names[dev->type],dev->users); 253 minor,v4l2_type_names[dev->type],dev->users);
253 254
254 mutex_lock(&dev->lock); 255 fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL);
255 256
256 if (dev->users) { 257 if (!fh) {
257 em28xx_warn("this driver can be opened only once\n"); 258 em28xx_errdev("em28xx-video.c: Out of memory?!\n");
258 mutex_unlock(&dev->lock); 259 return -ENOMEM;
259 return -EBUSY;
260 } 260 }
261 mutex_lock(&dev->lock);
262 fh->dev = dev;
263 filp->private_data = fh;
261 264
262 spin_lock_init(&dev->queue_lock); 265 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
263 init_waitqueue_head(&dev->wait_frame);
264 init_waitqueue_head(&dev->wait_stream);
265
266 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
267 em28xx_set_alternate(dev); 266 em28xx_set_alternate(dev);
268 267
269 dev->width = norm_maxw(dev); 268 dev->width = norm_maxw(dev);
@@ -277,26 +276,16 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp)
277 em28xx_capture_start(dev, 1); 276 em28xx_capture_start(dev, 1);
278 em28xx_resolution_set(dev); 277 em28xx_resolution_set(dev);
279 278
280 /* device needs to be initialized before isoc transfer */
281 video_mux(dev, 0);
282 279
283 /* start the transfer */ 280 /* start the transfer */
284 errCode = em28xx_init_isoc(dev); 281 errCode = em28xx_init_isoc(dev);
285 if (errCode) 282 if (errCode)
286 goto err; 283 goto err;
287 284
285 em28xx_empty_framequeues(dev);
288 } 286 }
289 287
290 dev->users++; 288 dev->users++;
291 filp->private_data = dev;
292 dev->io = IO_NONE;
293 dev->stream = STREAM_OFF;
294 dev->num_frames = 0;
295
296 /* prepare queues */
297 em28xx_empty_framequeues(dev);
298
299 dev->state |= DEV_INITIALIZED;
300 289
301err: 290err:
302 mutex_unlock(&dev->lock); 291 mutex_unlock(&dev->lock);
@@ -333,34 +322,41 @@ static void em28xx_release_resources(struct em28xx *dev)
333 */ 322 */
334static int em28xx_v4l2_close(struct inode *inode, struct file *filp) 323static int em28xx_v4l2_close(struct inode *inode, struct file *filp)
335{ 324{
336 int errCode; 325 struct em28xx_fh *fh = filp->private_data;
337 struct em28xx *dev=filp->private_data; 326 struct em28xx *dev = fh->dev;
327 int errCode;
338 328
339 em28xx_videodbg("users=%d\n", dev->users); 329 em28xx_videodbg("users=%d\n", dev->users);
340 330
341 mutex_lock(&dev->lock); 331 mutex_lock(&dev->lock);
332 if (fh->reader == 1)
333 fh->reader = 0;
342 334
343 em28xx_uninit_isoc(dev); 335 if (dev->users == 1) {
336 dev->reader = 0;
344 337
345 em28xx_release_buffers(dev); 338 em28xx_uninit_isoc(dev);
339 em28xx_release_buffers(dev);
346 340
347 /* the device is already disconnect, free the remaining resources */ 341 /* the device is already disconnect,
348 if (dev->state & DEV_DISCONNECTED) { 342 free the remaining resources */
349 em28xx_release_resources(dev); 343 if (dev->state & DEV_DISCONNECTED) {
350 mutex_unlock(&dev->lock); 344 em28xx_release_resources(dev);
351 kfree(dev); 345 mutex_unlock(&dev->lock);
352 return 0; 346 kfree(dev);
353 } 347 return 0;
348 }
354 349
355 /* set alternate 0 */ 350 /* set alternate 0 */
356 dev->alt = 0; 351 dev->alt = 0;
357 em28xx_videodbg("setting alternate 0\n"); 352 em28xx_videodbg("setting alternate 0\n");
358 errCode = usb_set_interface(dev->udev, 0, 0); 353 errCode = usb_set_interface(dev->udev, 0, 0);
359 if (errCode < 0) { 354 if (errCode < 0) {
360 em28xx_errdev ("cannot change alternate number to 0 (error=%i)\n", 355 em28xx_errdev("cannot change alternate number to "
361 errCode); 356 "0 (error=%i)\n", errCode);
357 }
362 } 358 }
363 359 kfree(fh);
364 dev->users--; 360 dev->users--;
365 wake_up_interruptible_nr(&dev->open, 1); 361 wake_up_interruptible_nr(&dev->open, 1);
366 mutex_unlock(&dev->lock); 362 mutex_unlock(&dev->lock);
@@ -378,13 +374,19 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
378 struct em28xx_frame_t *f, *i; 374 struct em28xx_frame_t *f, *i;
379 unsigned long lock_flags; 375 unsigned long lock_flags;
380 int ret = 0; 376 int ret = 0;
381 struct em28xx *dev = filp->private_data; 377 struct em28xx_fh *fh = filp->private_data;
378 struct em28xx *dev = fh->dev;
382 379
383 mutex_lock(&dev->lock); 380 mutex_lock(&dev->lock);
384 381
385 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 382 if (dev->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
386 em28xx_videodbg("V4l2_Buf_type_videocapture is set\n"); 383 em28xx_videodbg("V4l2_Buf_type_videocapture is set\n");
384
385 if (dev->reader > 0 && fh->reader == 0) {
386 mutex_unlock(&dev->lock);
387 return -EBUSY;
387 } 388 }
389
388 if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 390 if (dev->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
389 em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n"); 391 em28xx_videodbg("V4L2_BUF_TYPE_VBI_CAPTURE is set\n");
390 em28xx_videodbg("not supported yet! ...\n"); 392 em28xx_videodbg("not supported yet! ...\n");
@@ -423,6 +425,9 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
423 " the device again to choose the read method\n"); 425 " the device again to choose the read method\n");
424 mutex_unlock(&dev->lock); 426 mutex_unlock(&dev->lock);
425 return -EINVAL; 427 return -EINVAL;
428 } else {
429 dev->reader = 1;
430 fh->reader = 1;
426 } 431 }
427 432
428 if (dev->io == IO_NONE) { 433 if (dev->io == IO_NONE) {
@@ -491,7 +496,8 @@ em28xx_v4l2_read(struct file *filp, char __user * buf, size_t count,
491static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) 496static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait)
492{ 497{
493 unsigned int mask = 0; 498 unsigned int mask = 0;
494 struct em28xx *dev = filp->private_data; 499 struct em28xx_fh *fh = filp->private_data;
500 struct em28xx *dev = fh->dev;
495 501
496 mutex_lock(&dev->lock); 502 mutex_lock(&dev->lock);
497 503
@@ -559,15 +565,23 @@ static struct vm_operations_struct em28xx_vm_ops = {
559 */ 565 */
560static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) 566static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
561{ 567{
562 unsigned long size = vma->vm_end - vma->vm_start, 568 struct em28xx_fh *fh = filp->private_data;
563 start = vma->vm_start; 569 struct em28xx *dev = fh->dev;
564 void *pos; 570 unsigned long size = vma->vm_end - vma->vm_start;
565 u32 i; 571 unsigned long start = vma->vm_start;
566 572 void *pos;
567 struct em28xx *dev = filp->private_data; 573 u32 i;
568 574
569 mutex_lock(&dev->lock); 575 mutex_lock(&dev->lock);
570 576
577 if (dev->reader > 0 && fh->reader == 0) {
578 mutex_unlock(&dev->lock);
579 return -EBUSY;
580 } else {
581 dev->reader = 1;
582 fh->reader = 1;
583 }
584
571 if (dev->state & DEV_DISCONNECTED) { 585 if (dev->state & DEV_DISCONNECTED) {
572 em28xx_videodbg("mmap: device not present\n"); 586 em28xx_videodbg("mmap: device not present\n");
573 mutex_unlock(&dev->lock); 587 mutex_unlock(&dev->lock);
@@ -918,6 +932,7 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
918 struct em28xx *dev, unsigned int cmd, void *arg, 932 struct em28xx *dev, unsigned int cmd, void *arg,
919 v4l2_kioctl driver_ioctl) 933 v4l2_kioctl driver_ioctl)
920{ 934{
935 struct em28xx_fh *fh = filp->private_data;
921 int ret; 936 int ret;
922 937
923 switch (cmd) { 938 switch (cmd) {
@@ -1227,6 +1242,8 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1227 return ret; 1242 return ret;
1228 } 1243 }
1229 } 1244 }
1245
1246 fh->reader = 0;
1230 em28xx_empty_framequeues(dev); 1247 em28xx_empty_framequeues(dev);
1231 mutex_unlock(&dev->lock); 1248 mutex_unlock(&dev->lock);
1232 1249
@@ -1248,7 +1265,8 @@ static int em28xx_do_ioctl(struct inode *inode, struct file *filp,
1248static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp, 1265static int em28xx_video_do_ioctl(struct inode *inode, struct file *filp,
1249 unsigned int cmd, void *arg) 1266 unsigned int cmd, void *arg)
1250{ 1267{
1251 struct em28xx *dev = filp->private_data; 1268 struct em28xx_fh *fh = filp->private_data;
1269 struct em28xx *dev = fh->dev;
1252 1270
1253 if (!dev) 1271 if (!dev)
1254 return -ENODEV; 1272 return -ENODEV;
@@ -1456,7 +1474,8 @@ static int em28xx_v4l2_ioctl(struct inode *inode, struct file *filp,
1456 unsigned int cmd, unsigned long arg) 1474 unsigned int cmd, unsigned long arg)
1457{ 1475{
1458 int ret = 0; 1476 int ret = 0;
1459 struct em28xx *dev = filp->private_data; 1477 struct em28xx_fh *fh = filp->private_data;
1478 struct em28xx *dev = fh->dev;
1460 1479
1461 if (dev->state & DEV_DISCONNECTED) { 1480 if (dev->state & DEV_DISCONNECTED) {
1462 em28xx_errdev("v4l2 ioctl: device not present\n"); 1481 em28xx_errdev("v4l2 ioctl: device not present\n");
@@ -1503,7 +1522,10 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
1503 1522
1504 dev->udev = udev; 1523 dev->udev = udev;
1505 mutex_init(&dev->lock); 1524 mutex_init(&dev->lock);
1525 spin_lock_init(&dev->queue_lock);
1506 init_waitqueue_head(&dev->open); 1526 init_waitqueue_head(&dev->open);
1527 init_waitqueue_head(&dev->wait_frame);
1528 init_waitqueue_head(&dev->wait_stream);
1507 1529
1508 dev->em28xx_write_regs = em28xx_write_regs; 1530 dev->em28xx_write_regs = em28xx_write_regs;
1509 dev->em28xx_read_reg = em28xx_read_reg; 1531 dev->em28xx_read_reg = em28xx_read_reg;