Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Re: [PATCH?] proposed rewrite of skystar2 filters
Il mer, 2003-12-03 alle 09:22, Niklas Peinecke ha scritto:
> Wolfgang Thiel wrote:
> > On Tue, Dec 02, 2003 at 08:15:18PM +0100, Holger Waechtler wrote:
> >
> >>Wolfgang Thiel wrote:
> >>
> >>>On Tue, Dec 02, 2003 at 12:12:02PM +0100, Niklas Peinecke wrote:
> >>
> >>...
> >>
> >>do you think the patch is ready for CVS? Don't have a skystar2 here, so
> >>I can't test it myself...
> >>
> >
> > No. His patch isn't ready, IMHO. It's very nice, but I don't think it's
> > ready: as soon as adding hw_filters=0 (and making this the default, and
> > only requesting his code with hw_filters=1), this patch is fine, and should
> > be added to CVS, but not now, when there is no option 'hw_filters=0' yet.
> >
> > Just my 2 cents,
> > Wolfgang
> >
> >
> OK, here is another patch. I incorporated the enable_hw_filters
> parameter and also implemented ref counting for every pid. I defaulted
> it to 1 (see my previous post for the reason). Setting it to 0 disables
> the filters alltogether by just calling open_whole_bandwidth (I'm not
> sure if this is what you were intending, feel free to make any changes
> you like).
>
> Also there are now _two_ ref counters for open_whole_bandwidth: one
> triggered by overflow (i.e. all hw filters in use) and one by special
> pid 0x2000. This is necessary to avoid the situation that you can close
> down the ts (opened by overflow) by removing a 0x2000 that was not added.
>
> Niklas
Hi Niklas,
in your code you do refcounting in this way:
// check if the pid is already present
for(i=0; i<adapter->pid_count; i++)
if((adapter->pid_list[i]&0x1fff)==pid) {
adapter->pid_list[i]=((((adapter->pid_list[i]>>13)+1)<<13)|pid);
// we do ref counting in the high 3 bits
return 1;
}
I think it is best to:
// check if the pid is already present
for(i=0; i<adapter->pid_count; i++)
if((adapter->pid_list[i]&0x1fff)==pid) {
if (((adapter->pid_list[i]&0xe000)>>13)==7)
return -1; // This is unlikely to happen, but we only have 7 slots. What should we do? Ignoring it sounds incorrect to me!
adapter->pid_list[i]=((((adapter->pid_list[i]>>13)+1)<<13)|pid);
// we do ref counting in the high 3 bits
return 1;
}
>
> ______________________________________________________________________
>
> Index: skystar2.c
> ===================================================================
> RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/b2c2/skystar2.c,v
> retrieving revision 1.17
> diff -p -u -r1.17 skystar2.c
> --- skystar2.c 1 Dec 2003 08:28:49 -0000 1.17
> +++ skystar2.c 3 Dec 2003 09:13:16 -0000
> @@ -9,6 +9,10 @@
> *
> * IMP: Converted to Linux coding style
> * Roberto Ragusa, r.ragusa at libero.it
> + *
> + * Added hardware filtering support,
> + * Niklas Peinecke, peinecke at gdv.uni-hannover.de
> + * Wolfgang Thiel, w-thiel at gmx.net
> *
> * This program is free software; you can redistribute it and/or
> * modify it under the terms of the GNU Lesser General Public License
> @@ -46,7 +50,9 @@
> #include "dvb_functions.h"
>
> static int debug = 0;
> -#define dprintk(x...) do { if (debug) printk(x); } while (0)
> +#define dprintk(x...) do { if (debug>=1) printk(x); } while (0)
> +#define ddprintk(x...) do { if (debug>=2) printk(x); } while (0)
> +static int enable_hw_filters=1;
>
> #define SIZE_OF_BUF_DMA1 0x3AC00
> #define SIZE_OF_BUF_DMA2 0x758
> @@ -95,7 +101,11 @@ struct adapter {
>
> spinlock_t lock;
>
> - u16 pids[0x27];
> + u16 pids[38];
> + u16 pid_list[256];
> + u16 pid_count;
> + u8 wb_opened_ov; // ref counter for open_whole_bandwidth by overflow
> + u8 wb_opened_sp; // ref counter for open_whole_bandwidth by special pid 0x2000
> u32 mac_filter;
> };
>
> @@ -219,7 +229,7 @@ static u32 flex_i2c_read(struct adapter
> u32 bytes_to_transfer;
> u8 *start;
>
> - dprintk("%s:\n", __FUNCTION__);
> + ddprintk("%s:\n", __FUNCTION__);
>
> start = buf;
>
> @@ -248,7 +258,7 @@ static u32 flex_i2c_write(struct adapter
> u32 bytes_to_transfer;
> u8 *start;
>
> - dprintk("%s:\n", __FUNCTION__);
> + ddprintk("%s:\n", __FUNCTION__);
>
> start = buf;
>
> @@ -279,11 +289,11 @@ static int master_xfer(struct dvb_i2c_bu
> if (down_interruptible(&tmp->i2c_sem))
> return -ERESTARTSYS;
>
> - dprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
> + ddprintk("%s: %d messages to transfer\n", __FUNCTION__, num);
>
> for (i = 0; i < num; i++)
> {
> - dprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
> + ddprintk("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n", i,
> msgs[i].flags, msgs[i].addr, msgs[i].buf[0], msgs[i].len);
>
> /* allow only the mt312 and stv0299 frontends to access the bus */
> @@ -597,13 +607,13 @@ static void sram_init(struct adapter *ad
>
> adapter->dw_sram_type = tmp & 0x30000;
>
> - dprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
> + ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
>
> } else {
>
> adapter->dw_sram_type = 0x10000;
>
> - dprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
> + ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type);
> }
>
> /* return value is never used? */
> @@ -928,83 +938,31 @@ static char eeprom_set_mac_addr(struct a
> */
>
> /* PID filter */
> -static void filter_enable_stream1_filter(struct adapter *adapter, u32 op)
> -{
> - dprintk("%s: op=%x\n", __FUNCTION__, op);
> -
> - if (op == 0) {
> - write_reg_op(adapter, 0x208, 2, ~0x00000001, 0);
> -
> - } else {
> -
> - write_reg_op(adapter, 0x208, 1, 0, 0x00000001);
> - }
> -}
> -
> -static void filter_enable_stream2_filter(struct adapter *adapter, u32 op)
> -{
> - dprintk("%s: op=%x\n", __FUNCTION__, op);
> -
> - if (op == 0) {
> - write_reg_op(adapter, 0x208, 2, ~0x00000002, 0);
> -
> - } else {
>
> - write_reg_op(adapter, 0x208, 1, 0, 0x00000002);
> - }
> -}
> -
> -static void filter_enable_pcr_filter(struct adapter *adapter, u32 op)
> +/* every flexcop has 6 "lower" hw PID filters */
> +/* these are enabled by setting bits 0-5 of 0x208 */
> +/* we do not check for id>5 here! */
> +static void filter_enable_hw_filter(struct adapter *adapter,u8 id,u8 op)
> {
> - dprintk("%s: op=%x\n", __FUNCTION__, op);
> -
> - if (op == 0) {
> - write_reg_op(adapter, 0x208, 2, ~0x00000004, 0);
> + u32 mask=( 0x00000001 << id );
>
> - } else {
> + dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
>
> - write_reg_op(adapter, 0x208, 1, 0, 0x00000004);
> - }
> + if (op == 0) write_reg_op(adapter, 0x208, 2, ~mask, 0);
> + else write_reg_op(adapter, 0x208, 1, 0, mask);
> }
>
> -static void filter_enable_pmt_filter(struct adapter *adapter, u32 op)
> +/* this sets the PID that should pass the specified filter */
> +static void pid_set_hw_pid(struct adapter * adapter,u8 id,u32 pid)
> {
> - dprintk("%s: op=%x\n", __FUNCTION__, op);
> -
> - if (op == 0) {
> - write_reg_op(adapter, 0x208, 2, ~0x00000008, 0);
> -
> - } else {
> -
> - write_reg_op(adapter, 0x208, 1, 0, 0x00000008);
> - }
> -}
> -
> -static void filter_enable_emm_fFilter(struct adapter *adapter, u32 op)
> -{
> - dprintk("%s: op=%x\n", __FUNCTION__, op);
> + u32 adr=0x300+((id&6)<<1);
>
> - if (op == 0) {
> - write_reg_op(adapter, 0x208, 2, ~0x00000010, 0);
> -
> - } else {
> + dprintk("%s: id=%d addr=%x %c pid=%d\n", __FUNCTION__, id, adr, (id&1)? 'h':'l', pid);
>
> - write_reg_op(adapter, 0x208, 1, 0, 0x00000010);
> - }
> + if((id&1)==0) write_reg_op(adapter,adr,3,0xffff8000,pid&0x1fff);
> + else write_reg_op(adapter,adr,3,0x8000ffff,(pid&0x1fff)<<16);
> }
>
> -static void filter_enable_ecm_filter(struct adapter *adapter, u32 op)
> -{
> - dprintk("%s: op=%x\n", __FUNCTION__, op);
> -
> - if (op == 0) {
> - write_reg_op(adapter, 0x208, 2, ~0x00000020, 0);
> -
> - } else {
> -
> - write_reg_op(adapter, 0x208, 1, 0, 0x00000020);
> - }
> -}
>
> /*
> static void filter_enable_null_filter(struct adapter *adapter, u32 op)
> @@ -1046,6 +1004,25 @@ static void ctrl_enable_mac(struct adapt
> }
> }
>
> +/* select data filter nr. id for setup */
> +static void filter_select_data_filter(struct adapter *adapter,u8 id)
> +{
> + write_reg_op(adapter,0x310,3,0xffffffe0,id&0x1f);
> +}
> +
> +/* enable data filter; 0: disable, 1: enable */
> +static void filter_enable_data_filter(struct adapter *adapter,u8 op)
> +{
> + if(op==0) write_reg_op(adapter,0x314,2,0xffff9fff,0);
> + else write_reg_op(adapter,0x314,3,0xffff9fff,0x00004000);
> +}
> +
> +/* set PID for data filter */
> +static void pid_set_data_pid(struct adapter *adapter,u32 pid)
> +{
> + write_reg_op(adapter,0x314,3,0xffffe000,pid & 0x1fff);
> +}
> +
> static int ca_set_mac_dst_addr_filter(struct adapter *adapter, u8 * mac)
> {
> u32 tmp1, tmp2;
> @@ -1086,28 +1063,22 @@ static void check_null_filter_enable(str
> }
> */
>
> -static void init_pids_info(struct adapter *adapter)
> -{
> - int i;
> -
> - for (i = 0; i < 0x27; i++)
> - adapter->pids[i] = 0x1FFF;
> -}
> -
> +/*
> static int check_pid(struct adapter *adapter, u16 pid)
> {
> u32 i;
>
> if (pid == 0x1FFF)
> return 0;
> -
> - for (i = 0; i < 0x27; i++) {
> - if (adapter->pids[i] == pid || adapter->pids[i] == 0x2000)
> - return 1;
> - }
> +
> + if(pid==0x2000 && adapter->wb_opened!=0) return 1; // do we need this?
> +
> + for(i=0; i<adapter->pid_count; i++)
> + if(adapter->pid_list[i]==pid) return 1;
>
> return 0;
> }
> +*/
>
> static void pid_set_group_pid(struct adapter * adapter, u32 pid)
> {
> @@ -1137,120 +1108,7 @@ static void pid_set_group_mask(struct ad
> /* return value; */
> }
>
> -static void pid_set_stream1_pid(struct adapter * adapter, u32 pid)
> -{
> - u32 value;
> -
> - dprintk("%s: pid=%x\n", __FUNCTION__, pid);
> -
> - value = (pid & 0x3FFF) | (read_reg_dw(adapter, 0x300) & 0xFFFFC000);
> -
> - write_reg_dw(adapter, 0x300, value);
> -
> - /* return value is never used? */
> -/* return value; */
> -}
> -
> -static void pid_set_stream2_pid(struct adapter * adapter, u32 pid)
> -{
> - u32 value;
> -
> - dprintk("%s: pid=%x\n", __FUNCTION__, pid);
> -
> - value = ((pid & 0x3FFF) << 0x10) | (read_reg_dw(adapter, 0x300) & 0xFFFF);
> -
> - write_reg_dw(adapter, 0x300, value);
> -
> - /* return value is never used? */
> -/* return value; */
> -}
> -
> -static void pid_set_pcr_pid(struct adapter * adapter, u32 pid)
> -{
> - u32 value;
> -
> - dprintk("%s: pid=%x\n", __FUNCTION__, pid);
> -
> - value = (pid & 0x3FFF) | (read_reg_dw(adapter, 0x304) & 0xFFFFC000);
> -
> - write_reg_dw(adapter, 0x304, value);
> -
> - /* return value is never used? */
> -/* return value; */
> -}
> -
> -static void pid_set_pmt_pid(struct adapter * adapter, u32 pid)
> -{
> - u32 value;
> -
> - dprintk("%s: pid=%x\n", __FUNCTION__, pid);
> -
> - value = ((pid & 0x3FFF) << 0x10) | (read_reg_dw(adapter, 0x304) & 0x3FFF);
> -
> - write_reg_dw(adapter, 0x304, value);
> -
> - /* return value is never used? */
> -/* return value; */
> -}
> -
> -static void pid_set_emm_pid(struct adapter * adapter, u32 pid)
> -{
> - u32 value;
> -
> - dprintk("%s: pid=%x\n", __FUNCTION__, pid);
> -
> - value = (pid & 0xFFFF) | (read_reg_dw(adapter, 0x308) & 0xFFFF0000);
> -
> - write_reg_dw(adapter, 0x308, value);
> -
> - /* return value is never used? */
> -/* return value; */
> -}
> -
> -static void pid_set_ecm_pid(struct adapter * adapter, u32 pid)
> -{
> - u32 value;
> -
> - dprintk("%s: pid=%x\n", __FUNCTION__, pid);
> -
> - value = (pid << 0x10) | (read_reg_dw(adapter, 0x308) & 0xFFFF);
> -
> - write_reg_dw(adapter, 0x308, value);
> -
> - /* return value is never used? */
> -/* return value; */
> -}
> -
> -static int pid_get_stream1_pid(struct adapter * adapter)
> -{
> - return read_reg_dw(adapter, 0x300) & 0x00001FFF;
> -}
> -
> -static int pid_get_stream2_pid(struct adapter * adapter)
> -{
> - return (read_reg_dw(adapter, 0x300) >> 0x10)& 0x00001FFF;
> -}
> -
> -static int pid_get_pcr_pid(struct adapter * adapter)
> -{
> - return read_reg_dw(adapter, 0x304) & 0x00001FFF;
> -}
> -
> -static int pid_get_pmt_pid(struct adapter * adapter)
> -{
> - return (read_reg_dw(adapter, 0x304) >> 0x10)& 0x00001FFF;
> -}
> -
> -static int pid_get_emm_pid(struct adapter * adapter)
> -{
> - return read_reg_dw(adapter, 0x308) & 0x00001FFF;
> -}
> -
> -static int pid_get_ecm_pid(struct adapter * adapter)
> -{
> - return (read_reg_dw(adapter, 0x308) >> 0x10)& 0x00001FFF;
> -}
> -
> +/*
> static int pid_get_group_pid(struct adapter * adapter)
> {
> return read_reg_dw(adapter, 0x30C) & 0x00001FFF;
> @@ -1260,6 +1118,7 @@ static int pid_get_group_mask(struct ada
> {
> return (read_reg_dw(adapter, 0x30C) >> 0x10)& 0x00001FFF;
> }
> +*/
>
> /*
> static void reset_hardware_pid_filter(struct adapter *adapter)
> @@ -1279,10 +1138,30 @@ static void reset_hardware_pid_filter(st
> filter_enable_ecm_filter(adapter, 0);
>
> pid_set_emm_pid(adapter, 0x1FFF);
> - filter_enable_emm_fFilter(adapter, 0);
> + filter_enable_emm_filter(adapter, 0);
> }
> */
>
> +static void init_pids(struct adapter *adapter)
> +{
> + int i;
> +
> + for (i = 0; i < 0x27; i++)
> + adapter->pids[i] = 0x1FFF;
> + adapter->pid_count=0;
> + adapter->wb_opened_ov=0;
> + adapter->wb_opened_sp=0;
> +
> + pid_set_group_pid(adapter, 0);
> + pid_set_group_mask(adapter, 0x1FE0);
> + pid_set_hw_pid(adapter,0,0x1FFF);
> + pid_set_hw_pid(adapter,1,0x1FFF);
> + pid_set_hw_pid(adapter,2,0x1FFF);
> + pid_set_hw_pid(adapter,3,0x1FFF);
> + pid_set_hw_pid(adapter,4,0x1FFF);
> + pid_set_hw_pid(adapter,5,0x1FFF);
> +}
> +
> static void open_whole_bandwidth(struct adapter *adapter)
> {
> dprintk("%s:\n", __FUNCTION__);
> @@ -1292,175 +1171,167 @@ static void open_whole_bandwidth(struct
> pid_set_group_mask(adapter, 0);
>
> filter_enable_mask_filter(adapter, 1);
> -
> }
>
> -static int add_hw_pid(struct adapter *adapter, u32 pid)
> +static void close_whole_bandwidth(struct adapter *adapter)
> {
> - dprintk("%s: pid=%d\n", __FUNCTION__, pid);
> -
> - if (pid <= 0x1F)
> - return 1;
> -
> - if ((pid_get_group_mask(adapter) == 0) && (pid_get_group_pid(adapter) == 0))
> - return 0;
> -
> - if (pid_get_stream1_pid(adapter) == 0x1FFF) {
> - pid_set_stream1_pid(adapter, pid & 0xFFFF);
> -
> - filter_enable_stream1_filter(adapter, 1);
> -
> - return 1;
> - }
> -
> - if (pid_get_stream2_pid(adapter) == 0x1FFF) {
> - pid_set_stream2_pid(adapter, (pid & 0xFFFF));
> -
> - filter_enable_stream2_filter(adapter, 1);
> -
> - return 1;
> - }
> -
> - if (pid_get_pcr_pid(adapter) == 0x1FFF) {
> - pid_set_pcr_pid(adapter, (pid & 0xFFFF));
> -
> - filter_enable_pcr_filter(adapter, 1);
> -
> - return 1;
> - }
> -
> - if ((pid_get_pmt_pid(adapter) & 0x1FFF) == 0x1FFF) {
> - pid_set_pmt_pid(adapter, (pid & 0xFFFF));
> -
> - filter_enable_pmt_filter(adapter, 1);
> -
> - return 1;
> - }
> -
> - if ((pid_get_emm_pid(adapter) & 0x1FFF) == 0x1FFF) {
> - pid_set_emm_pid(adapter, (pid & 0xFFFF));
> -
> - filter_enable_emm_fFilter(adapter, 1);
> -
> - return 1;
> - }
> + dprintk("%s:\n", __FUNCTION__);
> +
> + pid_set_group_pid(adapter, 0);
>
> - if ((pid_get_ecm_pid(adapter) & 0x1FFF) == 0x1FFF) {
> - pid_set_ecm_pid(adapter, (pid & 0xFFFF));
> + pid_set_group_mask(adapter, 0x1fe0);
>
> - filter_enable_ecm_filter(adapter, 1);
> + filter_enable_mask_filter(adapter, 1);
> +}
>
> - return 1;
> +/* this tries to add the specified PID to be let through the
> + hw filters. return 1 on success.
> + if this cannot be done (all filter in use), returns -1
> + for PID <= 0x1f there is always success reported, since
> + these are let through by the group filters anyway. */
> +static int add_hw_pid(struct adapter *adapter, u32 pid)
> +{
> + int num,i;
> +
> + if(pid<=0x1f) return 1;
> +
> + if(adapter->b2c2_revision==0xc0 || adapter->b2c2_revision==0xc3)
> + num=38; // FlexCop IIb & III have 6+32 hw filters
> + else num=6; // FlexCop II has 6 hw filters, every other should have at least 6
> +
> + for (i=0; i<num; i++) {
> + if (adapter->pids[i] == 0x1fff) { // find a free pid slot
> + adapter->pids[i]=pid;
> + if(i<6) {
> + pid_set_hw_pid(adapter,i,pid);
> + filter_enable_hw_filter(adapter,i,1);
> + return 1;
> + } else {
> + filter_select_data_filter(adapter,i-6);
> + pid_set_data_pid(adapter,pid);
> + filter_enable_data_filter(adapter,1);
> + return 1;
> + }
> + }
> }
> -
> return -1;
> }
>
> +/* returns -1 if the pid was not present in the filters */
> static int remove_hw_pid(struct adapter *adapter, u32 pid)
> {
> - dprintk("%s: pid=%d\n", __FUNCTION__, pid);
> -
> - if (pid <= 0x1F)
> - return 1;
> -
> - if (pid_get_stream1_pid(adapter) == pid) {
> - pid_set_stream1_pid(adapter, 0x1FFF);
> -
> - return 1;
> - }
> -
> - if (pid_get_stream2_pid(adapter) == pid) {
> - pid_set_stream2_pid(adapter, 0x1FFF);
> -
> - filter_enable_stream2_filter(adapter, 0);
> -
> - return 1;
> - }
> -
> - if (pid_get_pcr_pid(adapter) == pid) {
> - pid_set_pcr_pid(adapter, 0x1FFF);
> -
> - filter_enable_pcr_filter(adapter, 0);
> -
> - return 1;
> - }
> -
> - if (pid_get_pmt_pid(adapter) == pid) {
> - pid_set_pmt_pid(adapter, 0x1FFF);
> -
> - filter_enable_pmt_filter(adapter, 0);
> -
> - return 1;
> - }
> -
> - if (pid_get_emm_pid(adapter) == pid) {
> - pid_set_emm_pid(adapter, 0x1FFF);
> -
> - filter_enable_emm_fFilter(adapter, 0);
> -
> - return 1;
> - }
> -
> - if (pid_get_ecm_pid(adapter) == pid) {
> - pid_set_ecm_pid(adapter, 0x1FFF);
> -
> - filter_enable_ecm_filter(adapter, 0);
> -
> - return 1;
> + int num,i;
> +
> + if(pid<=0x1f) return 1;
> +
> + if(adapter->b2c2_revision==0xc0 || adapter->b2c2_revision==0xc3)
> + num=38; // FlexCop IIb & III have 6+32 hw filters
> + else num=6; // FlexCop II has 6 hw filters, every other should have at least 6
> +
> + for(i=0; i<num; i++) {
> + if (adapter->pids[i] == pid) { // find the pid slot
> + adapter->pids[i]=0x1fff;
> + if(i<6) {
> + pid_set_hw_pid(adapter,i,pid);
> + filter_enable_hw_filter(adapter,i,0);
> + return 1;
> + } else {
> + filter_select_data_filter(adapter,i-6);
> + pid_set_data_pid(adapter,pid);
> + filter_enable_data_filter(adapter,0);
> + return 1;
> + }
> + }
> }
> -
> return -1;
> }
>
> -static int add_pid(struct adapter *adapter, u32 pid)
> +/* Adds a PID to the filters.
> + If there are no more hw filters available, open the whole
> + ts stream to pass by.
> + Adding a pid more than once has no effect.
> + If pid==0x2000, open whole ts stream also.
> + Returns 1 on success, -1 on error */
> +static int add_pid(struct adapter *adapter,u32 pid)
> {
> int i;
> -
> +
> dprintk("%s: pid=%d\n", __FUNCTION__, pid);
> -
> - if (pid > 0x1FFE && pid != 0x2000)
> - return -1;
> -
> - if (check_pid(adapter, pid) == 1)
> +
> + if(pid==0x2000) {
> + open_whole_bandwidth(adapter);
> + adapter->wb_opened_sp++;
> + // opened by special pid 0x2000
> return 1;
> -
> - for (i = 0; i < 0x27; i++) {
> - if (adapter->pids[i] == 0x1FFF) // find free pid filter
> - {
> - adapter->pids[i] = pid;
> -
> - if (pid == 0x2000 || add_hw_pid(adapter, pid) < 0)
> - open_whole_bandwidth(adapter);
> -
> + }
> +
> + if (pid > 0x1ffe) return -1;
> +
> + // check if the pid is already present
> + for(i=0; i<adapter->pid_count; i++)
> + if((adapter->pid_list[i]&0x1fff)==pid) {
> + adapter->pid_list[i]=((((adapter->pid_list[i]>>13)+1)<<13)|pid);
> + // we do ref counting in the high 3 bits
> return 1;
> }
> +
> + if(adapter->pid_count==256) return -1; // no more pids can be added
> + adapter->pid_list[adapter->pid_count]=pid; // register pid
> + adapter->pid_count++;
> +
> + // setup a filter for the pid
> + // if there are no filters left, let the whole ts pass
> + if(add_hw_pid(adapter,pid)==-1) {
> + open_whole_bandwidth(adapter);
> + adapter->wb_opened_ov++;
> + // opened by overflow
> }
> -
> - return -1;
> +
> + return 1;
> }
>
> +/* Removes a PID from the filters. */
> static int remove_pid(struct adapter *adapter, u32 pid)
> {
> - u32 i;
> -
> - dprintk("%s: pid=%d\n", __FUNCTION__, pid);
> -
> - if (pid > 0x1FFE)
> - return -1;
> -
> - for (i = 0; i < 0x27; i++) {
> - if (adapter->pids[i] == pid) {
> - adapter->pids[i] = 0x1FFF;
> -
> - remove_hw_pid(adapter, pid);
> + int i,j,num;
> +
> + if(pid==0x2000) {
> + if(adapter->wb_opened_sp==0) return -1; // cannot remove a pid that was not added ;)
> + adapter->wb_opened_sp--;
> + if(adapter->wb_opened_sp==0 && adapter->wb_opened_ov==0) close_whole_bandwidth(adapter);
> + return 1;
> + }
> +
> + if (pid > 0x1ffe && pid != 0x2000) return -1;
> +
> + // check if the pid is present
> + for (i=0; i<adapter->pid_count; i++) {
> + if((adapter->pid_list[i]&0x1fff)==pid) {
> + num=(adapter->pid_list[i]>>13)-1;
> + if(num<0) {
> + // remove from the list
> + adapter->pid_count--;
> + for(j=i; j<adapter->pid_count; j++) {
> + adapter->pid_list[j]=adapter->pid_list[j+1];
> + }
> + // close filter and take care to reverse the effect of open_whole_bandwidth
> + if(remove_hw_pid(adapter,pid)==-1) {
> + adapter->wb_opened_ov--;
> + if(adapter->wb_opened_sp==0 && adapter->wb_opened_ov==0) close_whole_bandwidth(adapter);
> + }
> + }
> + else {
> + adapter->pid_list[i]=((((adapter->pid_list[i]>>13)-1)<<13)|pid);
> + // we do ref counting in the high 3 bits
> + }
>
> return 1;
> }
> }
> -
> return -1;
> }
>
> +
> /* dma & irq */
> static void ctrl_enable_smc(struct adapter *adapter, u32 op)
> {
> @@ -1740,7 +1611,8 @@ static void open_stream(struct adapter *
>
> filter_enable_mask_filter(adapter, 1);
>
> - add_pid(adapter, pid);
> + if(enable_hw_filters==1) add_pid(adapter, pid);
> + else open_whole_bandwidth(adapter);
>
> dprintk("%s: adapter->dma_status=%x\n", __FUNCTION__, adapter->dma_status);
>
> @@ -1790,7 +1662,7 @@ static void close_stream(struct adapter
> dma_start_stop0x2102(adapter, dma_mask, 0);
> }
> }
> - remove_pid(adapter, pid);
> + if(enable_hw_filters==1) remove_pid(adapter, pid);
> }
>
> static void interrupt_service_dma1(struct adapter *adapter)
> @@ -1822,9 +1694,9 @@ static void interrupt_service_dma1(struc
> n_num_new_bytes_transferred = (adapter->dmaq1.buffer_size - adapter->dmaq1.tail) + n_cur_dma_counter;
> }
>
> - dprintk("%s: n_cur_dma_counter = %d\n" , __FUNCTION__, n_cur_dma_counter);
> - dprintk("%s: dmaq1.tail = %d\n" , __FUNCTION__, adapter->dmaq1.tail);
> - dprintk("%s: bytes_transferred = %d\n" , __FUNCTION__, n_num_new_bytes_transferred);
> + ddprintk("%s: n_cur_dma_counter = %d\n" , __FUNCTION__, n_cur_dma_counter);
> + ddprintk("%s: dmaq1.tail = %d\n" , __FUNCTION__, adapter->dmaq1.tail);
> + ddprintk("%s: bytes_transferred = %d\n" , __FUNCTION__, n_num_new_bytes_transferred);
>
> if (n_num_new_bytes_transferred < dw_default_packet_size)
> return;
> @@ -1866,7 +1738,7 @@ static irqreturn_t isr(int irq, void *de
>
> u32 value;
>
> - dprintk("%s:\n", __FUNCTION__);
> + ddprintk("%s:\n", __FUNCTION__);
>
> spin_lock_irq(&tmp->lock);
>
> @@ -1910,7 +1782,7 @@ static void init_dma_queue(struct adapte
>
> adapter->dma_status = adapter->dma_status | 0x10000000;
>
> - dprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1);
> + ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq1.buffer, SIZE_OF_BUF_DMA1);
>
> } else {
>
> @@ -1936,7 +1808,7 @@ static void init_dma_queue(struct adapte
>
> adapter->dma_status = adapter->dma_status | 0x20000000;
>
> - dprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2);
> + ddprintk("%s: allocated dma buffer at 0x%p, length=%d\n", __FUNCTION__, adapter->dmaq2.buffer, (int) SIZE_OF_BUF_DMA2);
>
> } else {
>
> @@ -2075,16 +1947,7 @@ static int driver_initialize(struct pci_
> write_reg_dw(adapter, 0x210, 0xB2FF);
> write_reg_dw(adapter, 0x208, 0x40);
>
> - init_pids_info(adapter);
> -
> - pid_set_group_pid(adapter, 0);
> - pid_set_group_mask(adapter, 0x1FE0);
> - pid_set_stream1_pid(adapter, 0x1FFF);
> - pid_set_stream2_pid(adapter, 0x1FFF);
> - pid_set_pmt_pid(adapter, 0x1FFF);
> - pid_set_pcr_pid(adapter, 0x1FFF);
> - pid_set_ecm_pid(adapter, 0x1FFF);
> - pid_set_emm_pid(adapter, 0x1FFF);
> + init_pids(adapter);
>
> init_dma_queue(adapter);
>
> @@ -2096,25 +1959,25 @@ static int driver_initialize(struct pci_
>
> adapter->b2c2_revision = (read_reg_dw(adapter, 0x204) >> 0x18);
>
> - switch(adapter->b2c2_revision) {
> - case 0x82:
> - printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
> - break;
> - case 0xC3:
> - printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
> - break;
> - case 0xC0:
> - printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
> - break;
> - default:
> - printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
> - printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev. 192).\n", __FILE__);
> - free_adapter_object(adapter);
> - pci_set_drvdata(pdev, NULL);
> - release_region(pci_resource_start(pdev,1), pci_resource_len(pdev,1));
> - release_mem_region(pci_resource_start(pdev,0), pci_resource_len(pdev,0));
> - return -ENODEV;
> - }
> + switch(adapter->b2c2_revision) {
> + case 0x82:
> + printk("%s: FlexCopII(rev.130) chip found\n", __FILE__);
> + break;
> + case 0xC3:
> + printk("%s: FlexCopIIB(rev.195) chip found\n", __FILE__);
> + break;
> + case 0xC0:
> + printk("%s: FlexCopIII(rev.192) chip found\n", __FILE__);
> + break;
> + default:
> + printk("%s: The revision of the FlexCop chip on your card is %d\n", __FILE__, adapter->b2c2_revision);
> + printk("%s: This driver works only with FlexCopII(rev.130), FlexCopIIB(rev.195) and FlexCopIII(rev. 192).\n", __FILE__);
> + free_adapter_object(adapter);
> + pci_set_drvdata(pdev, NULL);
> + release_region(pci_resource_start(pdev,1), pci_resource_len(pdev,1));
> + release_mem_region(pci_resource_start(pdev,0), pci_resource_len(pdev,0));
> + return -ENODEV;
> + }
>
> tmp = read_reg_dw(adapter, 0x204);
>
> @@ -2537,7 +2400,9 @@ module_init(skystar2_init);
> module_exit(skystar2_cleanup);
>
> MODULE_PARM(debug,"i");
> -MODULE_PARM_DESC(debug, "enable verbose debug messages");
> +MODULE_PARM_DESC(debug, "enable verbose debug messages: supported values: 1 and 2");
> +MODULE_PARM(enable_hw_filters,"i");
> +MODULE_PARM_DESC(debug, "enable hardware filters, if disabled the whole ts is passed through");
>
> MODULE_DESCRIPTION("Technisat SkyStar2 DVB PCI Driver");
> MODULE_LICENSE("GPL");
--
Vincenzo Di Massa <hawk78_it@yahoo.it>
--
Info:
To unsubscribe send a mail to ecartis@linuxtv.org with "unsubscribe linux-dvb" as subject.
Home |
Main Index |
Thread Index