Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cdadc50 authored by Richard Zidlicky's avatar Richard Zidlicky Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: dvb: fix smscore_getbuffer() logic



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: default avatarRichard Zidlicky <rz@linux-m68k.org>
Cc: stable@kernel.org
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 970d14c6
Loading
Loading
Loading
Loading
+12 −19
Original line number Diff line number Diff line
@@ -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)) {
	if (!list_empty(&coredev->buffers)) {
		cb = (struct smscore_buffer_t *) coredev->buffers.next;
		list_del(&cb->entry);
	}
	spin_unlock_irqrestore(&coredev->bufferslock, flags);
		schedule();
		spin_lock_irqsave(&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;
}