From: Johannes Stezenbach <js@linuxtv.org>
To: Andrew Morton <akpm@osdl.org>
Cc: linux-kernel@vger.kernel.org, Patrick Boettcher <pb@linuxtv.org>
Subject: [DVB patch 36/51] usb: add isochronous streaming method
Date: Mon, 27 Jun 2005 14:06:36 +0200 [thread overview]
Message-ID: <20050627121416.691410000@abc> (raw)
In-Reply-To: <20050627120600.739151000@abc>
[-- Attachment #1: dvb-usb-isochronous-streaming.patch --]
[-- Type: text/plain, Size: 12515 bytes --]
From: Patrick Boettcher <pb@linuxtv.org>
Added isochronous-streaming method.
Changed memory (de)allocation behaviour accordingly.
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
drivers/media/dvb/dvb-usb/dvb-usb-common.h | 3
drivers/media/dvb/dvb-usb/dvb-usb-urb.c | 178 +++++++++++++++++++++++------
drivers/media/dvb/dvb-usb/dvb-usb.h | 24 +++
3 files changed, 167 insertions(+), 38 deletions(-)
Index: linux-2.6.12-git8/drivers/media/dvb/dvb-usb/dvb-usb-common.h
===================================================================
--- linux-2.6.12-git8.orig/drivers/media/dvb/dvb-usb/dvb-usb-common.h 2005-06-27 13:18:22.000000000 +0200
+++ linux-2.6.12-git8/drivers/media/dvb/dvb-usb/dvb-usb-common.h 2005-06-27 13:26:05.000000000 +0200
@@ -15,11 +15,12 @@ extern int dvb_usb_debug;
#define deb_info(args...) dprintk(dvb_usb_debug,0x01,args)
#define deb_xfer(args...) dprintk(dvb_usb_debug,0x02,args)
-#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
+#define deb_pll(args...) dprintk(dvb_usb_debug,0x04,args)
#define deb_ts(args...) dprintk(dvb_usb_debug,0x08,args)
#define deb_err(args...) dprintk(dvb_usb_debug,0x10,args)
#define deb_rc(args...) dprintk(dvb_usb_debug,0x20,args)
#define deb_fw(args...) dprintk(dvb_usb_debug,0x40,args)
+#define deb_mem(args...) dprintk(dvb_usb_debug,0x80,args)
/* commonly used methods */
extern int usb_cypress_load_firmware(struct usb_device *, const char *, int);
Index: linux-2.6.12-git8/drivers/media/dvb/dvb-usb/dvb-usb-urb.c
===================================================================
--- linux-2.6.12-git8.orig/drivers/media/dvb/dvb-usb/dvb-usb-urb.c 2005-06-27 13:18:22.000000000 +0200
+++ linux-2.6.12-git8/drivers/media/dvb/dvb-usb/dvb-usb-urb.c 2005-06-27 13:26:05.000000000 +0200
@@ -24,6 +24,7 @@ int dvb_usb_generic_rw(struct dvb_usb_de
if ((ret = down_interruptible(&d->usb_sem)))
return ret;
+ deb_xfer(">>> ");
debug_dump(wbuf,wlen,deb_xfer);
ret = usb_bulk_msg(d->udev,usb_sndbulkpipe(d->udev,
@@ -46,8 +47,10 @@ int dvb_usb_generic_rw(struct dvb_usb_de
if (ret)
err("recv bulk message failed: %d",ret);
- else
+ else {
+ deb_xfer("<<< ");
debug_dump(rbuf,actlen,deb_xfer);
+ }
}
up(&d->usb_sem);
@@ -61,12 +64,19 @@ int dvb_usb_generic_write(struct dvb_usb
}
EXPORT_SYMBOL(dvb_usb_generic_write);
-static void dvb_usb_bulk_urb_complete(struct urb *urb, struct pt_regs *ptregs)
+
+/* URB stuff for streaming */
+static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
{
struct dvb_usb_device *d = urb->context;
+ int ptype = usb_pipetype(urb->pipe);
+ int i;
+ u8 *b;
- deb_ts("bulk urb completed. feedcount: %d, status: %d, length: %d\n",d->feedcount,urb->status,
- urb->actual_length);
+ deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n",
+ ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount,
+ urb->status,urb->actual_length,urb->transfer_buffer_length,
+ urb->number_of_packets,urb->error_count);
switch (urb->status) {
case 0: /* success */
@@ -81,11 +91,33 @@ static void dvb_usb_bulk_urb_complete(st
break;
}
- if (d->feedcount > 0 && urb->actual_length > 0) {
- if (d->state & DVB_USB_STATE_DVB)
- dvb_dmx_swfilter(&d->demux, (u8*) urb->transfer_buffer,urb->actual_length);
- } else
- deb_ts("URB dropped because of feedcount.\n");
+ if (d->feedcount > 0) {
+ if (d->state & DVB_USB_STATE_DVB) {
+ switch (ptype) {
+ case PIPE_ISOCHRONOUS:
+ b = (u8 *) urb->transfer_buffer;
+ for (i = 0; i < urb->number_of_packets; i++) {
+ if (urb->iso_frame_desc[i].status != 0)
+ deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status);
+ else if (urb->iso_frame_desc[i].actual_length > 0) {
+ dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset,
+ urb->iso_frame_desc[i].actual_length);
+ }
+ urb->iso_frame_desc[i].status = 0;
+ urb->iso_frame_desc[i].actual_length = 0;
+ }
+ debug_dump(b,20,deb_ts);
+ break;
+ case PIPE_BULK:
+ if (urb->actual_length > 0)
+ dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length);
+ break;
+ default:
+ err("unkown endpoint type in completition handler.");
+ return;
+ }
+ }
+ }
usb_submit_urb(urb,GFP_ATOMIC);
}
@@ -94,7 +126,7 @@ int dvb_usb_urb_kill(struct dvb_usb_devi
{
int i;
for (i = 0; i < d->urbs_submitted; i++) {
- deb_info("killing URB no. %d.\n",i);
+ deb_ts("killing URB no. %d.\n",i);
/* stop the URB */
usb_kill_urb(d->urb_list[i]);
@@ -107,9 +139,9 @@ int dvb_usb_urb_submit(struct dvb_usb_de
{
int i,ret;
for (i = 0; i < d->urbs_initialized; i++) {
- deb_info("submitting URB no. %d\n",i);
+ deb_ts("submitting URB no. %d\n",i);
if ((ret = usb_submit_urb(d->urb_list[i],GFP_ATOMIC))) {
- err("could not submit URB no. %d - get them all back\n",i);
+ err("could not submit URB no. %d - get them all back",i);
dvb_usb_urb_kill(d);
return ret;
}
@@ -118,32 +150,78 @@ int dvb_usb_urb_submit(struct dvb_usb_de
return 0;
}
-static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+static int dvb_usb_free_stream_buffers(struct dvb_usb_device *d)
+{
+ if (d->state & DVB_USB_STATE_URB_BUF) {
+ while (d->buf_num) {
+ d->buf_num--;
+ deb_mem("freeing buffer %d\n",d->buf_num);
+ usb_buffer_free(d->udev, d->buf_size,
+ d->buf_list[d->buf_num], d->dma_addr[d->buf_num]);
+ }
+ kfree(d->buf_list);
+ kfree(d->dma_addr);
+ }
+
+ d->state &= ~DVB_USB_STATE_URB_BUF;
+
+ return 0;
+}
+
+static int dvb_usb_allocate_stream_buffers(struct dvb_usb_device *d, int num, unsigned long size)
{
- int i,bufsize = d->props.urb.count * d->props.urb.u.bulk.buffersize;
+ d->buf_num = 0;
+ d->buf_size = size;
+
+ deb_mem("all in all I will use %lu bytes for streaming\n",num*size);
- deb_info("allocate %d bytes as buffersize for all URBs\n",bufsize);
- /* allocate the actual buffer for the URBs */
- if ((d->buffer = usb_buffer_alloc(d->udev, bufsize, SLAB_ATOMIC, &d->dma_handle)) == NULL) {
- deb_info("not enough memory for urb-buffer allocation.\n");
+ if ((d->buf_list = kmalloc(num*sizeof(u8 *), GFP_ATOMIC)) == NULL)
+ return -ENOMEM;
+
+ if ((d->dma_addr = kmalloc(num*sizeof(dma_addr_t), GFP_ATOMIC)) == NULL) {
+ kfree(d->buf_list);
return -ENOMEM;
}
- deb_info("allocation successful\n");
- memset(d->buffer,0,bufsize);
+ memset(d->buf_list,0,num*sizeof(u8 *));
+ memset(d->dma_addr,0,num*sizeof(dma_addr_t));
d->state |= DVB_USB_STATE_URB_BUF;
+ for (d->buf_num = 0; d->buf_num < num; d->buf_num++) {
+ deb_mem("allocating buffer %d\n",d->buf_num);
+ if (( d->buf_list[d->buf_num] =
+ usb_buffer_alloc(d->udev, size, SLAB_ATOMIC,
+ &d->dma_addr[d->buf_num]) ) == NULL) {
+ deb_mem("not enough memory for urb-buffer allocation.\n");
+ dvb_usb_free_stream_buffers(d);
+ return -ENOMEM;
+ }
+ deb_mem("buffer %d: %p (dma: %d)\n",d->buf_num,d->buf_list[d->buf_num],d->dma_addr[d->buf_num]);
+ memset(d->buf_list[d->buf_num],0,size);
+ }
+ deb_mem("allocation successful\n");
+
+ return 0;
+}
+
+static int dvb_usb_bulk_urb_init(struct dvb_usb_device *d)
+{
+ int i;
+
+ if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
+ d->props.urb.u.bulk.buffersize)) < 0)
+ return i;
+
/* allocate the URBs */
for (i = 0; i < d->props.urb.count; i++) {
- if (!(d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC))) {
+ if ((d->urb_list[i] = usb_alloc_urb(0,GFP_ATOMIC)) == NULL)
return -ENOMEM;
- }
usb_fill_bulk_urb( d->urb_list[i], d->udev,
usb_rcvbulkpipe(d->udev,d->props.urb.endpoint),
- &d->buffer[i*d->props.urb.u.bulk.buffersize],
+ d->buf_list[i],
d->props.urb.u.bulk.buffersize,
- dvb_usb_bulk_urb_complete, d);
+ dvb_usb_urb_complete, d);
d->urb_list[i]->transfer_flags = 0;
d->urbs_initialized++;
@@ -151,6 +229,47 @@ static int dvb_usb_bulk_urb_init(struct
return 0;
}
+static int dvb_usb_isoc_urb_init(struct dvb_usb_device *d)
+{
+ int i,j;
+
+ if ((i = dvb_usb_allocate_stream_buffers(d,d->props.urb.count,
+ d->props.urb.u.isoc.framesize*d->props.urb.u.isoc.framesperurb)) < 0)
+ return i;
+
+ /* allocate the URBs */
+ for (i = 0; i < d->props.urb.count; i++) {
+ struct urb *urb;
+ int frame_offset = 0;
+ if ((d->urb_list[i] =
+ usb_alloc_urb(d->props.urb.u.isoc.framesperurb,GFP_ATOMIC)) == NULL)
+ return -ENOMEM;
+
+ urb = d->urb_list[i];
+
+ urb->dev = d->udev;
+ urb->context = d;
+ urb->complete = dvb_usb_urb_complete;
+ urb->pipe = usb_rcvisocpipe(d->udev,d->props.urb.endpoint);
+ urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
+ urb->interval = d->props.urb.u.isoc.interval;
+ urb->number_of_packets = d->props.urb.u.isoc.framesperurb;
+ urb->transfer_buffer_length = d->buf_size;
+ urb->transfer_buffer = d->buf_list[i];
+ urb->transfer_dma = d->dma_addr[i];
+
+ for (j = 0; j < d->props.urb.u.isoc.framesperurb; j++) {
+ urb->iso_frame_desc[j].offset = frame_offset;
+ urb->iso_frame_desc[j].length = d->props.urb.u.isoc.framesize;
+ frame_offset += d->props.urb.u.isoc.framesize;
+ }
+
+ d->urbs_initialized++;
+ }
+ return 0;
+
+}
+
int dvb_usb_urb_init(struct dvb_usb_device *d)
{
/*
@@ -174,8 +293,7 @@ int dvb_usb_urb_init(struct dvb_usb_devi
case DVB_USB_BULK:
return dvb_usb_bulk_urb_init(d);
case DVB_USB_ISOC:
- err("isochronous transfer not yet implemented in dvb-usb.");
- return -EINVAL;
+ return dvb_usb_isoc_urb_init(d);
default:
err("unkown URB-type for data transfer.");
return -EINVAL;
@@ -191,7 +309,7 @@ int dvb_usb_urb_exit(struct dvb_usb_devi
if (d->state & DVB_USB_STATE_URB_LIST) {
for (i = 0; i < d->urbs_initialized; i++) {
if (d->urb_list[i] != NULL) {
- deb_info("freeing URB no. %d.\n",i);
+ deb_mem("freeing URB no. %d.\n",i);
/* free the URBs */
usb_free_urb(d->urb_list[i]);
}
@@ -202,10 +320,6 @@ int dvb_usb_urb_exit(struct dvb_usb_devi
d->state &= ~DVB_USB_STATE_URB_LIST;
}
- if (d->state & DVB_USB_STATE_URB_BUF)
- usb_buffer_free(d->udev, d->props.urb.u.bulk.buffersize * d->props.urb.count,
- d->buffer, d->dma_handle);
-
- d->state &= ~DVB_USB_STATE_URB_BUF;
+ dvb_usb_free_stream_buffers(d);
return 0;
}
Index: linux-2.6.12-git8/drivers/media/dvb/dvb-usb/dvb-usb.h
===================================================================
--- linux-2.6.12-git8.orig/drivers/media/dvb/dvb-usb/dvb-usb.h 2005-06-27 13:18:22.000000000 +0200
+++ linux-2.6.12-git8/drivers/media/dvb/dvb-usb/dvb-usb.h 2005-06-27 13:26:05.000000000 +0200
@@ -189,6 +189,7 @@ struct dvb_usb_properties {
struct {
int framesperurb;
int framesize;
+ int interval;
} isoc;
} u;
} urb;
@@ -207,19 +208,28 @@ struct dvb_usb_properties {
* @udev: pointer to the device's struct usb_device.
* @urb_list: array of dynamically allocated struct urb for the MPEG2-TS-
* streaming.
- * @buffer: buffer used to streaming.
- * @dma_handle: dma_addr_t for buffer.
+ *
+ * @buf_num: number of buffer allocated.
+ * @buf_size: size of each buffer in buf_list.
+ * @buf_list: array containing all allocate buffers for streaming.
+ * @dma_addr: list of dma_addr_t for each buffer in buf_list.
+ *
* @urbs_initialized: number of URBs initialized.
* @urbs_submitted: number of URBs submitted.
+ *
* @feedcount: number of reqested feeds (used for streaming-activation)
* @pid_filtering: is hardware pid_filtering used or not.
+ *
* @usb_sem: semaphore of USB control messages (reading needs two messages)
* @i2c_sem: semaphore for i2c-transfers
+ *
* @i2c_adap: device's i2c_adapter if it uses I2CoverUSB
* @pll_addr: I2C address of the tuner for programming
* @pll_init: array containing the initialization buffer
* @pll_desc: pointer to the appropriate struct dvb_pll_desc
- * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod
+ *
+ * @tuner_pass_ctrl: called to (de)activate tuner passthru of the demod or the board
+ *
* @dvb_adap: device's dvb_adapter.
* @dmxdev: device's dmxdev.
* @demux: device's software demuxer.
@@ -253,8 +263,12 @@ struct dvb_usb_device {
/* usb */
struct usb_device *udev;
struct urb **urb_list;
- u8 *buffer;
- dma_addr_t dma_handle;
+
+ int buf_num;
+ unsigned long buf_size;
+ u8 **buf_list;
+ dma_addr_t *dma_addr;
+
int urbs_initialized;
int urbs_submitted;
--
next prev parent reply other threads:[~2005-06-27 13:23 UTC|newest]
Thread overview: 57+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-06-27 12:06 [DVB patch 00/51] DVB update Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 01/51] cinergyT2: endianness fix for raw remote-control keys Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 02/51] remove obsolete skystar2 driver Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 03/51] core: fix race condition in FE_READ_STATUS ioctl Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 04/51] core: add workaround for tuning problem Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 05/51] core: demux error handling fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 06/51] core: dmxdev cleanups Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 07/51] frontend: remove unused I2C ids Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 08/51] frontend: tda1004x update Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 09/51] frontend: bcm3510: fix firmware version check Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 10/51] add missing release_firmware() calls Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 11/51] frontend: tda1004x: support tda827x tuners Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 12/51] frontend: cx22702: support for cxusb Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 13/51] frontend: l64781: improve tuning Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 14/51] DVB update Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 15/51] add Pluto2 driver Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 16/51] saa7146: kj pci_module_init cleanup Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 17/51] flexcop: add big endian register definitions Johannes Stezenbach
2005-06-27 22:50 ` Andrew Morton
2005-06-27 23:14 ` Johannes Stezenbach
2005-06-28 8:51 ` Patrick Boettcher
2005-06-27 12:06 ` [DVB patch 18/51] flexcop: woraround irq stop problem Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 19/51] Twinhan DST: frontend fixes Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 20/51] Twinhan DST: frontend polarization fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 21/51] ttusb-dec: kfree cleanup Johannes Stezenbach
2005-06-27 22:54 ` Andrew Morton
2005-06-27 23:20 ` Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 22/51] ttpci: add support for Technotrend/Hauppauge DVB-S SE Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 23/51] ttpci: support for new TT DVB-T-CI Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 24/51] ttpci: fix error handling for firmware communication Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 25/51] ttpci: fix bug in timeout handling Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 26/51] ttpci: fix AUDUIO_CONTINUE ioctl Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 27/51] ttpci: budget-av / tu1216 fix for QAM128 Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 28/51] ttpci: more error handling for firmware communication Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 29/51] ttpci: error handling fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 30/51] ttpci: cleanup indentation + whitespace Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 31/51] ttpci: make av7110_fe_lock_fix() retryable Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 32/51] ttpci: kj printk fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 33/51] ttpci: add support for Hauppauge/TT DVB-C budget Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 34/51] dvb-usb: support Artect T1 with broken USB ids Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 35/51] usb: fix ADSTech Instant TV DVB-T USB2.0 support Johannes Stezenbach
2005-06-27 12:06 ` Johannes Stezenbach [this message]
2005-06-27 12:06 ` [DVB patch 37/51] frontend: add FMD1216ME PLL Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 38/51] usb: support Medion hybrid USB2.0 DVB-T/analogue box Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 39/51] usb: add module parm to disable remote control polling Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 40/51] frontend: add ALPS TDED4 PLL Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 41/51] usb: digitv-usb fixes Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 42/51] usb: dvb_usb_properties init fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 43/51] usb: cxusb DVB-T fixes Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 44/51] usb: add VideoWalker DVB-T USB ids Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 45/51] usb: digitv memcpy fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 46/51] usb doc update Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 47/51] usb Kconfig help text update Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 48/51] usb: add vp7045 IR keymap Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 49/51] usb: fix WideView USB ids Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 50/51] usb: vp7045 IR map fix Johannes Stezenbach
2005-06-27 12:06 ` [DVB patch 51/51] usb: IR input fixes Johannes Stezenbach
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=20050627121416.691410000@abc \
--to=js@linuxtv.org \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pb@linuxtv.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Powered by JetHome