Skip to content

Commit

Permalink
V4L/DVB: dvb: fix smscore_getbuffer() logic
Browse files Browse the repository at this point in the history
Drivers shouldn't sleep while holding a spinlock. A previous workaround
were to release the spinlock before callinc schedule().

This patch uses a different approach: it just waits for the
siano hardware to answer.

Signed-off-by: Richard Zidlicky <rz@linux-m68k.org>
Cc: stable@kernel.org
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Richard Zidlicky authored and Mauro Carvalho Chehab committed Sep 28, 2010
1 parent 970d14c commit 3cdadc5
Showing 1 changed file with 12 additions and 19 deletions.
31 changes: 12 additions & 19 deletions drivers/media/dvb/siano/smscoreapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1098,33 +1098,26 @@ EXPORT_SYMBOL_GPL(smscore_onresponse);
*
* @return pointer to descriptor on success, NULL on error.
*/
struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)

struct smscore_buffer_t *get_entry(struct smscore_device_t *coredev)
{
struct smscore_buffer_t *cb = NULL;
unsigned long flags;

DEFINE_WAIT(wait);

spin_lock_irqsave(&coredev->bufferslock, flags);

/* 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)) {
spin_unlock_irqrestore(&coredev->bufferslock, flags);
schedule();
spin_lock_irqsave(&coredev->bufferslock, flags);
if (!list_empty(&coredev->buffers)) {
cb = (struct smscore_buffer_t *) coredev->buffers.next;
list_del(&cb->entry);
}
spin_unlock_irqrestore(&coredev->bufferslock, flags);
return cb;
}

finish_wait(&coredev->buffer_mng_waitq, &wait);

cb = (struct smscore_buffer_t *) coredev->buffers.next;
list_del(&cb->entry);
struct smscore_buffer_t *smscore_getbuffer(struct smscore_device_t *coredev)
{
struct smscore_buffer_t *cb = NULL;

spin_unlock_irqrestore(&coredev->bufferslock, flags);
wait_event(coredev->buffer_mng_waitq, (cb = get_entry(coredev)));

return cb;
}
Expand Down

0 comments on commit 3cdadc5

Please sign in to comment.