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