aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Stezenbach <js@linuxtv.org>2005-05-17 00:54:12 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-17 10:59:24 -0400
commit7635acd2d927578495c692056d0e7dabd06afc89 (patch)
tree308c33b31f2c749f12c4ddc9a44211a816e3125b
parent2add87a95068d6457d4e5824d0417d39007665a4 (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.c9
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.c47
-rw-r--r--drivers/media/dvb/b2c2/flexcop-usb.h3
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
285static 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
285static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) 330static 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