mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
uvc: sync bitland
This commit is contained in:
4
drivers/media/video/uvc/uvc_queue.c
Normal file → Executable file
4
drivers/media/video/uvc/uvc_queue.c
Normal file → Executable file
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user