Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[linux-dvb] Re: [PATCH?] proposed rewrite of skystar2 filters



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
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");

Home | Main Index | Thread Index