Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Johannes Stezenbach and committed by
Linus Torvalds
7635acd2 2add87a9

+55 -4
+6 -3
drivers/media/dvb/b2c2/flexcop-hw-filter.c
··· 159 159 } else if (fc->feedcount == onoff && !onoff) { 160 160 if (!fc->pid_filtering) { 161 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 163 flexcop_pid_group_filter_ctrl(fc,0); 164 164 } 165 165 ··· 175 175 flexcop_pid_group_filter(fc, 0,0); 176 176 flexcop_pid_group_filter_ctrl(fc,1); 177 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 179 flexcop_pid_group_filter_ctrl(fc,0); 180 180 } 181 181 ··· 189 189 for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) 190 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 195 v = fc->read_ibi_reg(fc,pid_filter_308); 195 196 v.pid_filter_308.EMM_filter_4 = 1; 196 197 v.pid_filter_308.EMM_filter_6 = 0; 197 198 fc->write_ibi_reg(fc,pid_filter_308,v); 199 + 200 + flexcop_null_filter_ctrl(fc, 1); 198 201 }
+46 -1
drivers/media/dvb/b2c2/flexcop-usb.c
··· 282 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 330 static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) 286 331 { 287 332 struct flexcop_usb *fc_usb = urb->context; ··· 342 297 if (urb->iso_frame_desc[i].actual_length > 0) { 343 298 deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); 344 299 345 - flexcop_pass_dmx_data(fc_usb->fc_dev, 300 + flexcop_usb_process_frame(fc_usb, 346 301 urb->transfer_buffer + urb->iso_frame_desc[i].offset, 347 302 urb->iso_frame_desc[i].actual_length); 348 303 }
+3
drivers/media/dvb/b2c2/flexcop-usb.h
··· 21 21 struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; 22 22 23 23 struct flexcop_device *fc_dev; 24 + 25 + u8 tmp_buffer[1023+190]; 26 + int tmp_buffer_length; 24 27 }; 25 28 26 29 #if 0