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 <[EMAIL PROTECTED]>



-- 
Info:
To unsubscribe send a mail to [EMAIL PROTECTED] with "unsubscribe linux-dvb" as 
subject.

Reply via email to