diff options
author | Johannes Stezenbach <js@linuxtv.org> | 2005-05-17 00:54:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-05-17 10:59:24 -0400 |
commit | 7635acd2d927578495c692056d0e7dabd06afc89 (patch) | |
tree | 308c33b31f2c749f12c4ddc9a44211a816e3125b | |
parent | 2add87a95068d6457d4e5824d0417d39007665a4 (diff) |
[PATCH] dvb: flexcop: fix USB transfer handling
- driver receives many null TS packets (pid=0x1fff). They occupy the
limited USB bandwidth and this leads to loss of video packets. Enabling the
null packet filter fixes this.
- packets that flexcop sends to USB have a 2 byte header that has to be
removed.
- sometimes a TS packet is split between different urbs. These parts have
to be combined in a temporary buffer.
Signed-off-by: Vadim Catana <skystar@moldova.cc>
Signed-off-by: Patrick Boettcher <pb@linuxtv.org>
Signed-off-by: Johannes Stezenbach <js@linuxtv.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-hw-filter.c | 9 | ||||
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-usb.c | 47 | ||||
-rw-r--r-- | drivers/media/dvb/b2c2/flexcop-usb.h | 3 |
3 files changed, 55 insertions, 4 deletions
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c index db983d704ff7..7a5399b569c7 100644 --- a/drivers/media/dvb/b2c2/flexcop-hw-filter.c +++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c | |||
@@ -159,7 +159,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d | |||
159 | } else if (fc->feedcount == onoff && !onoff) { | 159 | } else if (fc->feedcount == onoff && !onoff) { |
160 | if (!fc->pid_filtering) { | 160 | if (!fc->pid_filtering) { |
161 | deb_ts("disabling full TS transfer\n"); | 161 | deb_ts("disabling full TS transfer\n"); |
162 | flexcop_pid_group_filter(fc, 0x1fe0,0); | 162 | flexcop_pid_group_filter(fc, 0, 0x1fe0); |
163 | flexcop_pid_group_filter_ctrl(fc,0); | 163 | flexcop_pid_group_filter_ctrl(fc,0); |
164 | } | 164 | } |
165 | 165 | ||
@@ -175,7 +175,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d | |||
175 | flexcop_pid_group_filter(fc, 0,0); | 175 | flexcop_pid_group_filter(fc, 0,0); |
176 | flexcop_pid_group_filter_ctrl(fc,1); | 176 | flexcop_pid_group_filter_ctrl(fc,1); |
177 | } else if (fc->pid_filtering && fc->feedcount <= max_pid_filter) { | 177 | } else if (fc->pid_filtering && fc->feedcount <= max_pid_filter) { |
178 | flexcop_pid_group_filter(fc, 0x1fe0,0); | 178 | flexcop_pid_group_filter(fc, 0,0x1fe0); |
179 | flexcop_pid_group_filter_ctrl(fc,0); | 179 | flexcop_pid_group_filter_ctrl(fc,0); |
180 | } | 180 | } |
181 | 181 | ||
@@ -189,10 +189,13 @@ void flexcop_hw_filter_init(struct flexcop_device *fc) | |||
189 | for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) | 189 | for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) |
190 | flexcop_pid_control(fc,i,0x1fff,0); | 190 | flexcop_pid_control(fc,i,0x1fff,0); |
191 | 191 | ||
192 | flexcop_pid_group_filter(fc, 0x1fe0,0); | 192 | flexcop_pid_group_filter(fc, 0, 0x1fe0); |
193 | flexcop_pid_group_filter_ctrl(fc,0); | ||
193 | 194 | ||
194 | v = fc->read_ibi_reg(fc,pid_filter_308); | 195 | v = fc->read_ibi_reg(fc,pid_filter_308); |
195 | v.pid_filter_308.EMM_filter_4 = 1; | 196 | v.pid_filter_308.EMM_filter_4 = 1; |
196 | v.pid_filter_308.EMM_filter_6 = 0; | 197 | v.pid_filter_308.EMM_filter_6 = 0; |
197 | fc->write_ibi_reg(fc,pid_filter_308,v); | 198 | fc->write_ibi_reg(fc,pid_filter_308,v); |
199 | |||
200 | flexcop_null_filter_ctrl(fc, 1); | ||
198 | } | 201 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c index 5fa68febf3a6..98470ce9a054 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.c +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -282,6 +282,51 @@ static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_ | |||
282 | return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len); | 282 | return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len); |
283 | } | 283 | } |
284 | 284 | ||
285 | static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) | ||
286 | { | ||
287 | u8 *b; | ||
288 | int l; | ||
289 | |||
290 | deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length); | ||
291 | |||
292 | if (fc_usb->tmp_buffer_length > 0) { | ||
293 | memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length); | ||
294 | fc_usb->tmp_buffer_length += buffer_length; | ||
295 | b = fc_usb->tmp_buffer; | ||
296 | l = fc_usb->tmp_buffer_length; | ||
297 | } else { | ||
298 | b=buffer; | ||
299 | l=buffer_length; | ||
300 | } | ||
301 | |||
302 | while (l >= 190) { | ||
303 | if (*b == 0xff) | ||
304 | switch (*(b+1) & 0x03) { | ||
305 | case 0x01: /* media packet */ | ||
306 | if ( *(b+2) == 0x47 ) | ||
307 | flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1); | ||
308 | else | ||
309 | deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) ); | ||
310 | |||
311 | b += 190; | ||
312 | l -= 190; | ||
313 | break; | ||
314 | default: | ||
315 | deb_ts("wrong packet type\n"); | ||
316 | l = 0; | ||
317 | break; | ||
318 | } | ||
319 | else { | ||
320 | deb_ts("wrong header\n"); | ||
321 | l = 0; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | if (l>0) | ||
326 | memcpy(fc_usb->tmp_buffer, b, l); | ||
327 | fc_usb->tmp_buffer_length = l; | ||
328 | } | ||
329 | |||
285 | static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) | 330 | static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) |
286 | { | 331 | { |
287 | struct flexcop_usb *fc_usb = urb->context; | 332 | struct flexcop_usb *fc_usb = urb->context; |
@@ -297,7 +342,7 @@ static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) | |||
297 | if (urb->iso_frame_desc[i].actual_length > 0) { | 342 | if (urb->iso_frame_desc[i].actual_length > 0) { |
298 | deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); | 343 | deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); |
299 | 344 | ||
300 | flexcop_pass_dmx_data(fc_usb->fc_dev, | 345 | flexcop_usb_process_frame(fc_usb, |
301 | urb->transfer_buffer + urb->iso_frame_desc[i].offset, | 346 | urb->transfer_buffer + urb->iso_frame_desc[i].offset, |
302 | urb->iso_frame_desc[i].actual_length); | 347 | urb->iso_frame_desc[i].actual_length); |
303 | } | 348 | } |
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h index bfcec25ff2d9..630e647a2caa 100644 --- a/drivers/media/dvb/b2c2/flexcop-usb.h +++ b/drivers/media/dvb/b2c2/flexcop-usb.h | |||
@@ -21,6 +21,9 @@ struct flexcop_usb { | |||
21 | struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; | 21 | struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; |
22 | 22 | ||
23 | struct flexcop_device *fc_dev; | 23 | struct flexcop_device *fc_dev; |
24 | |||
25 | u8 tmp_buffer[1023+190]; | ||
26 | int tmp_buffer_length; | ||
24 | }; | 27 | }; |
25 | 28 | ||
26 | #if 0 | 29 | #if 0 |