The patch number 11819 was added via Mauro Carvalho Chehab <mche...@redhat.com> to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward compatible with older kernels. Compatibility modifications will be removed before inclusion into the mainstream Kernel If anyone has any objections, please let us know by sending a message to: Linux Media Mailing List <linux-me...@vger.kernel.org> ------ From: Uri Shkolnik <u...@siano-ms.com> Siano: smscore - fix get_common_buffer bug get common buffers() should block operation until valid buffer is avaliable. Priority: normal Signed-off-by: Uri Shkolnik <u...@siano-ms.com> Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com> --- linux/drivers/media/dvb/siano/smscoreapi.c | 38 ++++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff -r 37969546eee8 -r 793bb3914038 linux/drivers/media/dvb/siano/smscoreapi.c --- a/linux/drivers/media/dvb/siano/smscoreapi.c Thu May 14 19:34:59 2009 +0000 +++ b/linux/drivers/media/dvb/siano/smscoreapi.c Sun May 17 08:59:37 2009 +0000 @@ -30,6 +30,7 @@ #include <linux/io.h> #include <linux/firmware.h> +#include <linux/wait.h> #include "smscoreapi.h" #include "sms-cards.h" @@ -351,6 +352,9 @@ int smscore_register_device(struct smsde init_completion(&dev->reload_start_done); init_completion(&dev->resume_done); init_completion(&dev->ir_init_done); + + /* Buffer management */ + init_waitqueue_head(&dev->buffer_mng_waitq); /* alloc common buffer */ dev->common_buffer_size = params->buffer_size * params->num_buffers; @@ -686,7 +690,9 @@ void smscore_unregister_device(struct sm * onresponse must no longer be called */ while (1) { - while ((cb = smscore_getbuffer(coredev))) { + while (!list_empty(&coredev->buffers)) { + cb = (struct smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); kfree(cb); num_buffers++; } @@ -707,8 +713,10 @@ void smscore_unregister_device(struct sm if (coredev->common_buffer) dma_free_coherent(NULL, coredev->common_buffer_size, - coredev->common_buffer, - coredev->common_buffer_phys); + coredev->common_buffer, coredev->common_buffer_phys); + + if (coredev->fw_buf != NULL) + kfree(coredev->fw_buf); list_del(&coredev->entry); kfree(coredev); @@ -1076,12 +1084,24 @@ struct smscore_buffer_t *smscore_getbuff struct smscore_buffer_t *cb = NULL; unsigned long flags; + DEFINE_WAIT(wait); + spin_lock_irqsave(&coredev->bufferslock, flags); - if (!list_empty(&coredev->buffers)) { - cb = (struct smscore_buffer_t *) coredev->buffers.next; - list_del(&cb->entry); - } + /* This function must return a valid buffer, since the buffer list is + * finite, we check that there is an available buffer, if not, we wait + * until such buffer become available. + */ + + prepare_to_wait(&coredev->buffer_mng_waitq, &wait, TASK_INTERRUPTIBLE); + + if (list_empty(&coredev->buffers)) + schedule(); + + finish_wait(&coredev->buffer_mng_waitq, &wait); + + cb = (struct smscore_buffer_t *) coredev->buffers.next; + list_del(&cb->entry); spin_unlock_irqrestore(&coredev->bufferslock, flags); @@ -1098,8 +1118,8 @@ EXPORT_SYMBOL_GPL(smscore_getbuffer); * */ void smscore_putbuffer(struct smscore_device_t *coredev, - struct smscore_buffer_t *cb) -{ + struct smscore_buffer_t *cb) { + wake_up_interruptible(&coredev->buffer_mng_waitq); list_add_locked(&cb->entry, &coredev->buffers, &coredev->bufferslock); } EXPORT_SYMBOL_GPL(smscore_putbuffer); --- Patch is available at: http://linuxtv.org/hg/v4l-dvb/rev/793bb391403831217d53ab28522958e6ee5fdf57 _______________________________________________ linuxtv-commits mailing list linuxtv-commits@linuxtv.org http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits