summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
diff options
context:
space:
mode:
authorFelix Domke <devnull@localhost>2003-04-03 15:46:55 +0000
committerFelix Domke <devnull@localhost>2003-04-03 15:46:55 +0000
commit372936a07e6c4b583102e572c1240715afa2134c (patch)
treef2a506d334d907f6cc48a4687dd4671e2187b955 /linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
parent7d46bcfeabdc39c07fd7db949c7916844eacf09a (diff)
downloadmediapointer-dvb-s2-372936a07e6c4b583102e572c1240715afa2134c.tar.gz
mediapointer-dvb-s2-372936a07e6c4b583102e572c1240715afa2134c.tar.bz2
- added usb semaphore, should fix usb_submit_urb-failures
- some statistics (with DEBUG > 2)
Diffstat (limited to 'linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c')
-rw-r--r--linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c135
1 files changed, 93 insertions, 42 deletions
diff --git a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 31413dfa3..8b110fb16 100644
--- a/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -45,14 +45,14 @@
DEBUG:
define it to > 3 for really hardcore debugging. you probably don't want
- this unless the device doesn't load at all.
+ this unless the device doesn't load at all. > 2 for bandwidth statistics.
*/
static int debug = 1;
#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
-#define ISO_BUF_COUNT 5
+#define ISO_BUF_COUNT 4
#define FRAMES_PER_ISO_BUF 4
#define ISO_FRAME_SIZE 912
#define TTUSB_MAXCHANNEL 32
@@ -73,6 +73,8 @@ struct ttusb {
/* our semaphore, for channel allocation/deallocation */
struct semaphore sem;
+ /* and one for USB access. */
+ struct semaphore semusb;
struct dvb_adapter *adapter;
struct usb_device *dev;
@@ -87,8 +89,6 @@ struct ttusb {
void *iso_buffer;
dma_addr_t iso_dma_handle;
- wait_queue_head_t wq;
-
struct urb *iso_urb [ISO_BUF_COUNT];
int running_feed_count;
@@ -101,11 +101,14 @@ struct ttusb {
int mux_state; // 0..2 - MuxSyncWord, 3 - nMuxPacks, 4 - muxpack
u8 mux_npacks;
- u8 muxpack[256+4];
+ u8 muxpack[256+8];
int muxpack_ptr, muxpack_len;
int insync;
+ u16 cc; /* MuxCounter - will increment on EVERY MUX PACKET */
+ /* (including stuffing. yes. really.) */
+
u8 last_result[32];
struct ttusb_channel
@@ -131,7 +134,7 @@ struct ttusb {
#define DEBUG 0
static
int ttusb_cmd (struct ttusb *ttusb,
- const u8 *data, int len)
+ const u8 *data, int len, int needresult)
{
int actual_len;
int err;
@@ -143,25 +146,33 @@ int ttusb_cmd (struct ttusb *ttusb,
printk(" %02x", data[i]);
printk("\n");
#endif
+
+ if (down_interruptible (&ttusb->semusb) < 0)
+ return -EAGAIN;
+
err = usb_bulk_msg (ttusb->dev, ttusb->bulk_out_pipe,
(u8*)data, len, &actual_len, HZ);
if (err != 0)
{
dprintk ("%s: usb_bulk_msg(send) failed, err == %i!\n",
__FUNCTION__, err);
+ up(&ttusb->semusb);
return err;
}
if (actual_len != len)
{
dprintk("%s: only wrote %d of %d bytes\n", __FUNCTION__, actual_len, len);
+ up(&ttusb->semusb);
return -1;
}
err = usb_bulk_msg (ttusb->dev, ttusb->bulk_in_pipe,
ttusb->last_result, 32, &actual_len, HZ);
+
if (err != 0)
{
printk("%s: failed, receive error %d\n", __FUNCTION__, err);
+ up(&ttusb->semusb);
return err;
}
#if DEBUG >= 3
@@ -171,6 +182,8 @@ int ttusb_cmd (struct ttusb *ttusb,
printk(" %02x", ttusb->last_result[i]);
printk("\n");
#endif
+ if (!needresult)
+ up(&ttusb->semusb);
return 0;
}
@@ -179,6 +192,7 @@ int ttusb_result (struct ttusb *ttusb,
u8 *data, int len)
{
memcpy(data, ttusb->last_result, len);
+ up(&ttusb->semusb);
return 0;
}
@@ -204,13 +218,14 @@ int ttusb_i2c_msg (struct ttusb *ttusb,
for (i=0; i<snd_len; i++)
b [7+i] = snd_buf [i];
- err = ttusb_cmd (ttusb, b, snd_len + 7);
+ err = ttusb_cmd (ttusb, b, snd_len + 7, 1);
if (err)
return -EREMOTEIO;
+ err = ttusb_result (ttusb, b, 0x20);
+
if (rcv_len > 0) {
- err = ttusb_result (ttusb, b, 0x20);
if (err || b [0] != 0x55 || b [1] != id)
{
@@ -292,7 +307,7 @@ int ttusb_boot_dsp (struct ttusb *ttusb)
b [1] = ++ttusb->c;
- err = ttusb_cmd (ttusb, b, 32);
+ err = ttusb_cmd (ttusb, b, 32, 0);
if (err)
goto done;
}
@@ -302,7 +317,7 @@ int ttusb_boot_dsp (struct ttusb *ttusb)
b [2] = 0x13;
b [3] = 0;
- err = ttusb_cmd (ttusb, b, 4);
+ err = ttusb_cmd (ttusb, b, 4, 0);
if (err)
goto done;
@@ -311,7 +326,7 @@ int ttusb_boot_dsp (struct ttusb *ttusb)
b [2] = 0x14;
b [3] = 0;
- err = ttusb_cmd (ttusb, b, 4);
+ err = ttusb_cmd (ttusb, b, 4, 0);
done:
if (err) {
@@ -332,7 +347,7 @@ int ttusb_set_channel (struct ttusb *ttusb, int chan_id, int filter_type,
u8 b [] = { 0xaa, ++ttusb->c, 0x22, 4, chan_id, filter_type,
(pid >> 8) & 0xff, pid & 0xff};
- err = ttusb_cmd (ttusb, b, sizeof(b));
+ err = ttusb_cmd (ttusb, b, sizeof(b), 0);
return err;
}
@@ -344,7 +359,7 @@ int ttusb_del_channel (struct ttusb *ttusb, int channel_id)
/* DelChannel */
u8 b [] = { 0xaa, ++ttusb->c, 0x23, 1, channel_id };
- err = ttusb_cmd (ttusb, b, sizeof(b));
+ err = ttusb_cmd (ttusb, b, sizeof(b), 0);
return err;
}
@@ -363,7 +378,7 @@ int ttusb_set_filter (struct ttusb *ttusb, int filter_id, int associated_chan,
mask[4], mask[5], mask[6], mask[7],
mask[8], mask[9], mask[10], mask[11]};
- err = ttusb_cmd (ttusb, b, sizeof(b));
+ err = ttusb_cmd (ttusb, b, sizeof(b), 0);
return err;
}
@@ -375,7 +390,7 @@ int ttusb_del_filter (struct ttusb *ttusb, int filter_id)
/* DelFilter */
u8 b [] = { 0xaa, ++ttusb->c, 0x25, 1, filter_id };
- err = ttusb_cmd (ttusb, b, sizeof(b));
+ err = ttusb_cmd (ttusb, b, sizeof(b), 0);
return err;
}
#endif
@@ -391,28 +406,29 @@ int ttusb_init_controller (struct ttusb *ttusb)
u8 b4 [] = { 0x55, ttusb->c, 0x31, 4, 0x10, 0x02, 0x01, 0x00, 0x1e };
u8 get_version [] = {0xaa, ++ttusb->c, 0x17, 5, 0, 0, 0, 0, 0};
+ u8 get_dsp_version [0x20] = {0xaa, ++ttusb->c, 0x26, 28, 0, 0, 0, 0, 0};
int err;
/* reset board */
- if ((err = ttusb_cmd (ttusb, b0, sizeof (b0))))
+ if ((err = ttusb_cmd (ttusb, b0, sizeof (b0), 0)))
return err;
/* reset board (again?) */
- if ((err = ttusb_cmd (ttusb, b1, sizeof (b1))))
+ if ((err = ttusb_cmd (ttusb, b1, sizeof (b1), 0)))
return err;
ttusb_boot_dsp (ttusb);
/* set i2c bit rate */
- if ((err = ttusb_cmd (ttusb, b2, sizeof (b2))))
+ if ((err = ttusb_cmd (ttusb, b2, sizeof (b2), 0)))
return err;
- if ((err = ttusb_cmd (ttusb, b3, sizeof (b3))))
+ if ((err = ttusb_cmd (ttusb, b3, sizeof (b3), 1)))
return err;
err = ttusb_result(ttusb, b4, sizeof(b4));
- if ((err = ttusb_cmd (ttusb, get_version, sizeof (get_version))))
+ if ((err = ttusb_cmd (ttusb, get_version, sizeof (get_version), 1)))
return err;
if ((err = ttusb_result(ttusb, get_version, sizeof(get_version))))
@@ -431,6 +447,16 @@ int ttusb_init_controller (struct ttusb *ttusb)
get_version[7], get_version[8]);
}
+
+ err = ttusb_cmd (ttusb, get_dsp_version, sizeof (get_dsp_version), 1);
+ if (err)
+ return err;
+
+ err = ttusb_result(ttusb, get_dsp_version, sizeof(get_dsp_version));
+ if (err)
+ return err;
+ printk("%s: dsp-version: %c%c%c\n", __FUNCTION__,
+ get_dsp_version[4], get_dsp_version[5], get_dsp_version[6]);
return 0;
}
@@ -450,7 +476,7 @@ int ttusb_send_diseqc (struct ttusb *ttusb, const struct dvb_diseqc_master_cmd *
memcpy(b+5, cmd->msg, cmd->msg_len);
/* Diseqc */
- if ((err = ttusb_cmd (ttusb, b, 4 + b[3]))) {
+ if ((err = ttusb_cmd (ttusb, b, 4 + b[3], 0))) {
dprintk ("%s: usb_bulk_msg() failed, return value %i!\n",
__FUNCTION__, err);
}
@@ -468,7 +494,7 @@ int ttusb_update_lnb (struct ttusb *ttusb)
int err;
/* SetLNB */
- if ((err = ttusb_cmd (ttusb, b, sizeof (b)))) {
+ if ((err = ttusb_cmd (ttusb, b, sizeof (b), 0))) {
dprintk ("%s: usb_bulk_msg() failed, return value %i!\n",
__FUNCTION__, err);
}
@@ -522,7 +548,7 @@ void ttusb_set_led_freq (struct ttusb *ttusb, u8 freq)
u8 b [] = { 0xaa, ++ttusb->c, 0x19, 1, freq };
int err, actual_len;
- err = ttusb_cmd (ttusb, b, sizeof (b));
+ err = ttusb_cmd (ttusb, b, sizeof (b), 0);
if (err) {
dprintk ("%s: usb_bulk_msg() failed, return value %i!\n",
__FUNCTION__, err);
@@ -538,21 +564,27 @@ static void ttusb_handle_ts_data(struct ttusb_channel *channel, const u8 *data,
static void ttusb_handle_sec_data(struct ttusb_channel *channel, const u8 *data, int len);
#endif
+int numpkt=0, lastj, numts, numstuff, numsec, numinvalid;
+
static
void ttusb_process_muxpack(struct ttusb *ttusb, const u8 *muxpack, int len)
{
- u16 csum=0;
+ u16 csum=0, cc;
int i;
-
for (i = 0; i < len; i+=2)
csum ^= le16_to_cpup((u16*)(muxpack+i));
-
- if (csum) {
- printk ("%s: muxpack with incorrect checksum, ignoring\n",
- __FUNCTION__);
+ if (csum)
+ {
+ printk("%s: muxpack with incorrect checksum, ignoring\n", __FUNCTION__);
+ numinvalid++;
return;
}
+ cc=(muxpack[len-4]<<8)|muxpack[len-3];
+ cc&=0x7FFF;
+ if (cc != ttusb->cc)
+ printk("%s: cc discontinuity (%d frames missing)\n", __FUNCTION__, (cc - ttusb->cc)&0x7FFF);
+ ttusb->cc = (cc+1) & 0x7FFF;
if (muxpack[0] & 0x80) {
#ifdef TTUSB_HWSECTIONS
/* section data */
@@ -572,6 +604,7 @@ void ttusb_process_muxpack(struct ttusb *ttusb, const u8 *muxpack, int len)
#warning TODO: pusi
printk("cc: %04x\n", (data[0]<<8)|data[1]);
#endif
+ numsec++;
} else if (muxpack[0] == 0x47) {
#ifdef TTUSB_HWSECTIONS
/* we have TS data here! */
@@ -581,9 +614,14 @@ void ttusb_process_muxpack(struct ttusb *ttusb, const u8 *muxpack, int len)
if (ttusb->channel[channel].active && (pid == ttusb->channel[channel].pid))
ttusb_handle_ts_data(ttusb->channel+channel, muxpack, 188);
#endif
+ numts++;
dvb_dmx_swfilter_packets(&ttusb->dvb_demux, muxpack, 1);
} else if (muxpack[0] != 0)
+ {
+ numinvalid++;
printk("illegal muxpack type %02x\n", muxpack[0]);
+ } else
+ numstuff++;
}
static
@@ -634,7 +672,7 @@ void ttusb_process_frame(struct ttusb *ttusb, u8 *data, int len)
avail = ttusb->muxpack_len - ttusb->muxpack_ptr;
memcpy(ttusb->muxpack + ttusb->muxpack_ptr, data, avail);
ttusb->muxpack_ptr += avail;
- if (ttusb->muxpack_ptr > 260)
+ if (ttusb->muxpack_ptr > 264)
BUG();
data+=avail;
len-=avail;
@@ -689,30 +727,46 @@ void ttusb_process_frame(struct ttusb *ttusb, u8 *data, int len)
}
}
-
static
void ttusb_iso_irq (struct urb *urb)
{
struct ttusb *ttusb = urb->context;
-
+
if (! ttusb->iso_streaming)
return;
+
#if 0
- printk ("%s: (write urb %i) status %d, errcount == %d, length == %i\n",
- __FUNCTION__, ttusb->write_urb,
+ printk ("%s: status %d, errcount == %d, length == %i\n",
+ __FUNCTION__,
urb->status, urb->error_count, urb->actual_length);
#endif
if (! urb->status) {
int i;
- for (i=0; i < FRAMES_PER_ISO_BUF; ++i) {
+ for (i=0; i < urb->number_of_packets; ++i) {
struct iso_packet_descriptor *d;
+ u8 *data;
+ int len;
+ numpkt++;
+ if ((jiffies - lastj) >= HZ)
+ {
+#if DEBUG > 2
+ printk("frames/s: %d (ts: %d, stuff %d, sec: %d, invalid: %d, all: %d)\n", numpkt*HZ/(jiffies - lastj),
+ numts, numstuff, numsec, numinvalid,
+ numts + numstuff + numsec + numinvalid);
+#endif
+ numts = numstuff = numsec = numinvalid=0;
+ lastj = jiffies;
+ numpkt = 0;
+ }
d = &urb->iso_frame_desc[i];
- ttusb_process_frame(ttusb, urb->transfer_buffer + d->offset, d->actual_length);
+ data = urb->transfer_buffer + d->offset;
+ len = d->actual_length;
+ d->actual_length = 0;
+ d->status = 0;
+ ttusb_process_frame(ttusb, data, len);
}
}
-
- wake_up_interruptible (&ttusb->wq);
}
@@ -952,10 +1006,8 @@ int ttusb_setup_interfaces (struct ttusb *ttusb)
return 0;
}
-
static u8 stc_firmware[8192];
-
static
int stc_open (struct inode *inode, struct file *file)
{
@@ -1035,7 +1087,7 @@ void* ttusb_probe (struct usb_device *udev, unsigned int ifnum,
ttusb->c = 0;
ttusb->mux_state = 0;
sema_init (&ttusb->sem, 0);
- init_waitqueue_head (&ttusb->wq);
+ sema_init (&ttusb->semusb, 1);
ttusb_setup_interfaces (ttusb);
@@ -1108,7 +1160,6 @@ void ttusb_disconnect (struct usb_device *udev, void *data)
struct ttusb *ttusb = data;
ttusb->disconnecting = 1;
- wake_up_interruptible (&ttusb->wq);
ttusb_stop_iso_xfer (ttusb);