From: ddl Date: Thu, 5 Sep 2013 09:10:49 +0000 (+0800) Subject: uvc: sync bitland X-Git-Tag: firefly_0821_release~6655 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=33beae0b04329b641e43a63b5ce4a71f911668b4;p=firefly-linux-kernel-4.4.55.git uvc: sync bitland --- diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c old mode 100644 new mode 100755 index 1b9f12696a9b..0abe14569993 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c @@ -390,9 +390,9 @@ checks: /* ddl@rock-chips.com: It is timeout */ if (ret == 0) { ret = -EINVAL; - printk(KERN_ERR "uvcvideo: uvc_dequeue_buffer is timeout!!"); + printk(KERN_ERR "uvcvideo: uvc_dequeue_buffer is timeout!!\n"); } else { - printk(KERN_ERR "uvcvideo: uvc_dequeue_buffer is failed!!(ret:%d)",ret); + printk(KERN_ERR "uvcvideo: uvc_dequeue_buffer is failed!!(ret:%d)\n",ret); } goto done; } diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index c7a054fa6554..b596442d32e8 100755 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c @@ -750,6 +750,8 @@ static void uvc_video_complete_fun (struct urb *urb) struct uvc_buffer *buf = NULL; unsigned long flags; int ret; + int i; + atomic_t *urb_state=NULL; switch (urb->status) { case 0: @@ -769,14 +771,33 @@ static void uvc_video_complete_fun (struct urb *urb) return; } + for (i = 0; i < UVC_URBS; ++i) { + if (stream->urb[i] == urb) { + urb_state = &stream->urb_state[i]; + break; + } + } + + if (urb_state == NULL) { + printk("urb(%p) cann't be finded in stream->urb(%p, %p, %p, %p, %p)\n", + urb,stream->urb[0],stream->urb[1],stream->urb[2],stream->urb[3],stream->urb[4]); + BUG(); + } + + if (atomic_read(urb_state)==UrbDeactive) { + printk(KERN_DEBUG "urb is deactive, this urb complete cancel!"); + uvc_queue_cancel(queue, urb->status == -ESHUTDOWN); + return; + } + spin_lock_irqsave(&queue->irqlock, flags); if (!list_empty(&queue->irqqueue)) buf = list_first_entry(&queue->irqqueue, struct uvc_buffer, queue); - spin_unlock_irqrestore(&queue->irqlock, flags); - + spin_unlock_irqrestore(&queue->irqlock, flags); + stream->decode(urb, stream, buf); - + if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) { uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n", ret); @@ -784,18 +805,9 @@ static void uvc_video_complete_fun (struct urb *urb) } static void uvc_video_complete_tasklet(unsigned long data) { - struct urb *urb = (struct urb*)data; - struct uvc_streaming *stream = urb->context; - struct tasklet_struct *tasklet = NULL; - int i; + struct urb *urb = (struct urb*)data; - uvc_video_complete_fun(urb); - for (i = 0; i < UVC_URBS; ++i) { - if (stream->urb[i] == urb) { - tasklet = stream->tasklet[i]; - break; - } - } + uvc_video_complete_fun(urb); return; } @@ -804,15 +816,17 @@ static void uvc_video_complete(struct urb *urb) int i; struct uvc_streaming *stream = urb->context; struct tasklet_struct *tasklet = NULL; + atomic_t *urb_state; for (i = 0; i < UVC_URBS; ++i) { if (stream->urb[i] == urb) { tasklet = stream->tasklet[i]; + urb_state = &stream->urb_state[i]; break; } } - if (tasklet != NULL) { + if ((tasklet != NULL)&&(atomic_read(urb_state)==UrbActive)) { tasklet_schedule(tasklet); } else { uvc_video_complete_fun(urb); @@ -903,8 +917,9 @@ static void uvc_uninit_video(struct uvc_streaming *stream, int free_buffers) urb = stream->urb[i]; if (urb == NULL) continue; - - /* ddl@rock-chips.com: Tasklet must be kill before kill urb in uninit */ + else + atomic_set(&stream->urb_state[i],UrbDeactive); + if (stream->tasklet[i]) { tasklet_kill(stream->tasklet[i]); kfree(stream->tasklet[i]); @@ -969,6 +984,7 @@ static int uvc_init_video_isoc(struct uvc_streaming *stream, stream->urb[i] = urb; /* ddl@rock-chips.com */ + atomic_set(&stream->urb_state[i],UrbActive); stream->tasklet[i] = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL); if (stream->tasklet[i] == NULL) { uvc_printk(KERN_ERR, "device %s requested tasklet memory fail!\n", diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index 4abb2f2f0a2b..a85879cacb3b 100755 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h @@ -452,7 +452,10 @@ struct uvc_video_chain { struct mutex ctrl_mutex; /* Protects ctrl.info */ }; - +enum uvc_urb_state { + UrbActive, + UrbDeactive +}; struct uvc_streaming { struct list_head list; struct uvc_device *dev; @@ -501,6 +504,8 @@ struct uvc_streaming { __u8 last_fid; struct tasklet_struct *tasklet[UVC_URBS]; /* ddl@rock-chips.com */ + atomic_t urb_state[UVC_URBS]; + unsigned int flags; };