mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-11 16:29:05 +00:00
[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>
This commit is contained in:
parent
2add87a950
commit
7635acd2d9
@ -159,7 +159,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
|
|||||||
} else if (fc->feedcount == onoff && !onoff) {
|
} else if (fc->feedcount == onoff && !onoff) {
|
||||||
if (!fc->pid_filtering) {
|
if (!fc->pid_filtering) {
|
||||||
deb_ts("disabling full TS transfer\n");
|
deb_ts("disabling full TS transfer\n");
|
||||||
flexcop_pid_group_filter(fc, 0x1fe0,0);
|
flexcop_pid_group_filter(fc, 0, 0x1fe0);
|
||||||
flexcop_pid_group_filter_ctrl(fc,0);
|
flexcop_pid_group_filter_ctrl(fc,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
|
|||||||
flexcop_pid_group_filter(fc, 0,0);
|
flexcop_pid_group_filter(fc, 0,0);
|
||||||
flexcop_pid_group_filter_ctrl(fc,1);
|
flexcop_pid_group_filter_ctrl(fc,1);
|
||||||
} else if (fc->pid_filtering && fc->feedcount <= max_pid_filter) {
|
} else if (fc->pid_filtering && fc->feedcount <= max_pid_filter) {
|
||||||
flexcop_pid_group_filter(fc, 0x1fe0,0);
|
flexcop_pid_group_filter(fc, 0,0x1fe0);
|
||||||
flexcop_pid_group_filter_ctrl(fc,0);
|
flexcop_pid_group_filter_ctrl(fc,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,10 +189,13 @@ void flexcop_hw_filter_init(struct flexcop_device *fc)
|
|||||||
for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
|
for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
|
||||||
flexcop_pid_control(fc,i,0x1fff,0);
|
flexcop_pid_control(fc,i,0x1fff,0);
|
||||||
|
|
||||||
flexcop_pid_group_filter(fc, 0x1fe0,0);
|
flexcop_pid_group_filter(fc, 0, 0x1fe0);
|
||||||
|
flexcop_pid_group_filter_ctrl(fc,0);
|
||||||
|
|
||||||
v = fc->read_ibi_reg(fc,pid_filter_308);
|
v = fc->read_ibi_reg(fc,pid_filter_308);
|
||||||
v.pid_filter_308.EMM_filter_4 = 1;
|
v.pid_filter_308.EMM_filter_4 = 1;
|
||||||
v.pid_filter_308.EMM_filter_6 = 0;
|
v.pid_filter_308.EMM_filter_6 = 0;
|
||||||
fc->write_ibi_reg(fc,pid_filter_308,v);
|
fc->write_ibi_reg(fc,pid_filter_308,v);
|
||||||
|
|
||||||
|
flexcop_null_filter_ctrl(fc, 1);
|
||||||
}
|
}
|
||||||
|
@ -282,6 +282,51 @@ static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_
|
|||||||
return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len);
|
return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
|
||||||
|
{
|
||||||
|
u8 *b;
|
||||||
|
int l;
|
||||||
|
|
||||||
|
deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);
|
||||||
|
|
||||||
|
if (fc_usb->tmp_buffer_length > 0) {
|
||||||
|
memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);
|
||||||
|
fc_usb->tmp_buffer_length += buffer_length;
|
||||||
|
b = fc_usb->tmp_buffer;
|
||||||
|
l = fc_usb->tmp_buffer_length;
|
||||||
|
} else {
|
||||||
|
b=buffer;
|
||||||
|
l=buffer_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (l >= 190) {
|
||||||
|
if (*b == 0xff)
|
||||||
|
switch (*(b+1) & 0x03) {
|
||||||
|
case 0x01: /* media packet */
|
||||||
|
if ( *(b+2) == 0x47 )
|
||||||
|
flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1);
|
||||||
|
else
|
||||||
|
deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );
|
||||||
|
|
||||||
|
b += 190;
|
||||||
|
l -= 190;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
deb_ts("wrong packet type\n");
|
||||||
|
l = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deb_ts("wrong header\n");
|
||||||
|
l = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l>0)
|
||||||
|
memcpy(fc_usb->tmp_buffer, b, l);
|
||||||
|
fc_usb->tmp_buffer_length = l;
|
||||||
|
}
|
||||||
|
|
||||||
static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
|
static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
|
||||||
{
|
{
|
||||||
struct flexcop_usb *fc_usb = urb->context;
|
struct flexcop_usb *fc_usb = urb->context;
|
||||||
@ -297,7 +342,7 @@ static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs)
|
|||||||
if (urb->iso_frame_desc[i].actual_length > 0) {
|
if (urb->iso_frame_desc[i].actual_length > 0) {
|
||||||
deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
|
deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
|
||||||
|
|
||||||
flexcop_pass_dmx_data(fc_usb->fc_dev,
|
flexcop_usb_process_frame(fc_usb,
|
||||||
urb->transfer_buffer + urb->iso_frame_desc[i].offset,
|
urb->transfer_buffer + urb->iso_frame_desc[i].offset,
|
||||||
urb->iso_frame_desc[i].actual_length);
|
urb->iso_frame_desc[i].actual_length);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,9 @@ struct flexcop_usb {
|
|||||||
struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
|
struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
|
||||||
|
|
||||||
struct flexcop_device *fc_dev;
|
struct flexcop_device *fc_dev;
|
||||||
|
|
||||||
|
u8 tmp_buffer[1023+190];
|
||||||
|
int tmp_buffer_length;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user