All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Hunold (LinuxTV.org CVS maintainer)  <hunold@convergence.de>
To: linux-kernel@vger.kernel.org, alan@lxorguk.ukuu.org.uk,
	torvalds@osdl.org
Subject: [PATCH 5/6] [DVB] TTUSB-DEC driver update
Date: Tue, 29 Jul 2003 11:30:32 +0200	[thread overview]
Message-ID: <10594710321293@convergence.de> (raw)
In-Reply-To: <1059471031240@convergence.de>

[DVB] - Hand off all processing of urb data to a tasklet
diff -uNrwB --new-file linux-2.6.0-test2.work/drivers/media/dvb/ttusb-dec/ttusb_dec.c linux-2.6.0-test2.patch/drivers/media/dvb/ttusb-dec/ttusb_dec.c
--- linux-2.6.0-test2.work/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-07-29 09:10:18.000000000 +0200
+++ linux-2.6.0-test2.patch/drivers/media/dvb/ttusb-dec/ttusb_dec.c	2003-07-21 13:42:42.000000000 +0200
@@ -124,14 +125,10 @@
 
 	ttusb_dec_send_command(dec, 0x50, sizeof(b), b, NULL, NULL);
 
-	if (!down_interruptible(&dec->pes2ts_sem)) {
 		dvb_filter_pes2ts_init(&dec->a_pes2ts, dec->pid[DMX_PES_AUDIO],
 				       ttusb_dec_av_pes2ts_cb, dec->demux.feed);
 		dvb_filter_pes2ts_init(&dec->v_pes2ts, dec->pid[DMX_PES_VIDEO],
 				       ttusb_dec_av_pes2ts_cb, dec->demux.feed);
-
-		up(&dec->pes2ts_sem);
-	}
 }
 
 static int ttusb_dec_i2c_master_xfer(struct dvb_i2c_bus *i2c,
@@ -196,14 +193,8 @@
 				memcpy(&dec->v_pes[dec->v_pes_length],
 				       &av_pes[12], prebytes);
 
-				if (!down_interruptible(&dec->pes2ts_sem)) {
-					dvb_filter_pes2ts(&dec->v_pes2ts,
-							  dec->v_pes,
-							  dec->v_pes_length +
-							  prebytes);
-
-					up(&dec->pes2ts_sem);
-				}
+				dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
+						  dec->v_pes_length + prebytes);
 			}
 
 			if (av_pes[5] & 0x10) {
@@ -246,16 +237,10 @@
 						     postbytes);
 			memcpy(&dec->v_pes[4], &v_pes_payload_length, 2);
 
-			if (postbytes == 0) {
-				if (!down_interruptible(&dec->pes2ts_sem)) {
-					dvb_filter_pes2ts(&dec->v_pes2ts,
-							  dec->v_pes,
+			if (postbytes == 0)
+				dvb_filter_pes2ts(&dec->v_pes2ts, dec->v_pes,
 							  dec->v_pes_length);
 
-					up(&dec->pes2ts_sem);
-				}
-			}
-
 			break;
 		}
 
@@ -357,6 +342,31 @@
 	}
 }
 
+static void ttusb_dec_process_urb_frame_list(unsigned long data)
+{
+	struct ttusb_dec *dec = (struct ttusb_dec *)data;
+	struct list_head *item;
+	struct urb_frame *frame;
+	unsigned long flags;
+
+	while (1) {
+		spin_lock_irqsave(&dec->urb_frame_list_lock, flags);
+		if ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
+			frame = list_entry(item, struct urb_frame,
+					   urb_frame_list);
+			list_del(&frame->urb_frame_list);
+		} else {
+			spin_unlock_irqrestore(&dec->urb_frame_list_lock,
+					       flags);
+			return;
+		}
+		spin_unlock_irqrestore(&dec->urb_frame_list_lock, flags);
+
+		ttusb_dec_process_urb_frame(dec, frame->data, frame->length);
+		kfree(frame);
+	}
+}
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static void ttusb_dec_process_urb(struct urb *urb)
 #else
@@ -372,12 +382,28 @@
 			struct usb_iso_packet_descriptor *d;
 			u8 *b;
 			int length;
+			struct urb_frame *frame;
 
 			d = &urb->iso_frame_desc[i];
 			b = urb->transfer_buffer + d->offset;
 			length = d->actual_length;
 
-			ttusb_dec_process_urb_frame(dec, b, length);
+			if ((frame = kmalloc(sizeof(struct urb_frame),
+					     GFP_ATOMIC))) {
+				unsigned long flags;
+
+				memcpy(frame->data, b, length);
+				frame->length = length;
+
+				spin_lock_irqsave(&dec->urb_frame_list_lock,
+						     flags);
+				list_add_tail(&frame->urb_frame_list,
+					      &dec->urb_frame_list);
+				spin_unlock_irqrestore(&dec->urb_frame_list_lock,
+						       flags);
+
+				tasklet_schedule(&dec->urb_tasklet);
+			}
 		}
 	} else {
 		 /* -ENOENT is expected when unlinking urbs */
@@ -653,6 +679,14 @@
 	return 0;
 }
 
+static void ttusb_dec_init_tasklet(struct ttusb_dec *dec)
+{
+	dec->urb_frame_list_lock = SPIN_LOCK_UNLOCKED;
+	INIT_LIST_HEAD(&dec->urb_frame_list);
+	tasklet_init(&dec->urb_tasklet, ttusb_dec_process_urb_frame_list,
+		     (unsigned long)dec);
+}
+
 static void ttusb_dec_init_v_pes(struct ttusb_dec *dec)
 {
 	dprintk("%s\n", __FUNCTION__);
@@ -834,8 +868,6 @@
 		return result;
 	}
 
-	sema_init(&dec->pes2ts_sem, 1);
-
 	dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx);
 
 	return 0;
@@ -868,6 +900,20 @@
 	ttusb_dec_free_iso_urbs(dec);
 }
 
+static void ttusb_dec_exit_tasklet(struct ttusb_dec *dec)
+{
+	struct list_head *item;
+	struct urb_frame *frame;
+
+	tasklet_kill(&dec->urb_tasklet);
+
+	while ((item = dec->urb_frame_list.next) != &dec->urb_frame_list) {
+		frame = list_entry(item, struct urb_frame, urb_frame_list);
+		list_del(&frame->urb_frame_list);
+		kfree(frame);
+	}
+}
+
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
 static void *ttusb_dec_probe(struct usb_device *udev, unsigned int ifnum,
 			     const struct usb_device_id *id)
@@ -892,6 +938,7 @@
 	ttusb_dec_init_stb(dec);
 	ttusb_dec_init_dvb(dec);
 	ttusb_dec_init_v_pes(dec);
+	ttusb_dec_init_tasklet(dec);
 
 	return (void *)dec;
 }
@@ -919,6 +966,7 @@
 	ttusb_dec_init_stb(dec);
 	ttusb_dec_init_dvb(dec);
 	ttusb_dec_init_v_pes(dec);
+	ttusb_dec_init_tasklet(dec);
 
 	usb_set_intfdata(intf, (void *)dec);
 	ttusb_dec_set_streaming_interface(dec);
@@ -941,6 +989,7 @@
 
 	dprintk("%s\n", __FUNCTION__);
 
+	ttusb_dec_exit_tasklet(dec);
 	ttusb_dec_exit_usb(dec);
 	ttusb_dec_exit_dvb(dec);
 
diff -uNrwB --new-file linux-2.6.0-test2.work/drivers/media/dvb/ttusb-dec/ttusb_dec.h linux-2.6.0-test2.patch/drivers/media/dvb/ttusb-dec/ttusb_dec.h
--- linux-2.6.0-test2.work/drivers/media/dvb/ttusb-dec/ttusb_dec.h	2003-07-29 09:10:18.000000000 +0200
+++ linux-2.6.0-test2.patch/drivers/media/dvb/ttusb-dec/ttusb_dec.h	2003-07-21 13:42:42.000000000 +0200
@@ -22,7 +22,10 @@
 #ifndef _TTUSB_DEC_H
 #define _TTUSB_DEC_H
 
-#include "asm/semaphore.h"
+#include <asm/semaphore.h>
+#include <linux/interrupt.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
 #include "dmxdev.h"
 #include "dvb_demux.h"
 #include "dvb_filter.h"
@@ -77,11 +80,20 @@
 
 	struct dvb_filter_pes2ts	a_pes2ts;
 	struct dvb_filter_pes2ts	v_pes2ts;
-	struct semaphore		pes2ts_sem;
 
 	u8			v_pes[16 + MAX_AV_PES_LENGTH];
 	int			v_pes_length;
 	int			v_pes_postbytes;
+
+	struct list_head	urb_frame_list;
+	struct tasklet_struct	urb_tasklet;
+	spinlock_t		urb_frame_list_lock;
+};
+
+struct urb_frame {
+	u8			data[ISO_FRAME_SIZE];
+	int			length;
+	struct list_head	urb_frame_list;
 };
 
 #endif


  reply	other threads:[~2003-07-29  9:33 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-07-29  9:30 [PATCH 1/6] [DVB] Kconfig and Makefile updates Michael Hunold
2003-07-29  9:30 ` [PATCH 2/6] [DVB] DVB core update Michael Hunold
2003-07-29  9:30   ` [PATCH 3/6] [DVB] mt312 DVB frontend update Michael Hunold
2003-07-29  9:30     ` [PATCH 4/6] [DVB] Update MAC handling for various DVB PCI cards Michael Hunold
2003-07-29  9:30       ` Michael Hunold [this message]
2003-07-29  9:30         ` [PATCH 6/6] [DVB] Hexium saa7146 driver update Michael Hunold
2003-07-29  9:58 ` [PATCH 1/6] [DVB] Kconfig and Makefile updates Roman Zippel
2003-07-29 10:02   ` Michael Hunold

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=10594710321293@convergence.de \
    --to=hunold@convergence.de \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.