diff options
author | Felix Domke <devnull@localhost> | 2003-04-03 15:46:55 +0000 |
---|---|---|
committer | Felix Domke <devnull@localhost> | 2003-04-03 15:46:55 +0000 |
commit | 372936a07e6c4b583102e572c1240715afa2134c (patch) | |
tree | f2a506d334d907f6cc48a4687dd4671e2187b955 /linux/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |
parent | 7d46bcfeabdc39c07fd7db949c7916844eacf09a (diff) | |
download | mediapointer-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.c | 135 |
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); |