Mailing List archive

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

[linux-dvb] Re: [PATCH] skystar2 filters rewritten(?!)



Vincenzo Di Massa wrote:
Hi souldn't pid_rc be an array?
Oops, fixed ;) Thanks!

Il gio, 2003-12-04 alle 08:13, Niklas Peinecke ha scritto:

Hi,

here is the patch against todays CVS. I hope, we're all happy with the rewrite now (well, at leat happy enough to merge this in). I incorporated the changes made by Wolfgang yesterday [see his against-patch.dif] and rewrote the ref counters to have 8 bits instead of only 3.

IMHO it should be save to include this into CVS now, but I'm open for further suggestions.

Niklas

? against-patch.dif
? skystar2.c_20031204
? skystar2.c_20031204_wt
? skystar2_hwfilter.diff
? skystar2_hwfilter20031203.diff
? skystar2_hwfilter20031204.diff
? skystar2_myfilters.c
? skystar2_old.c
Index: skystar2.c
===================================================================
RCS file: /cvs/linuxtv/dvb-kernel/linux/drivers/media/dvb/b2c2/skystar2.c,v
retrieving revision 1.18
diff -p -u -r1.18 skystar2.c
--- skystar2.c	3 Dec 2003 18:50:49 -0000	1.18
+++ skystar2.c	4 Dec 2003 10:44:35 -0000
@@ -5,13 +5,16 @@
  * Copyright (C) 2003  Vadim Catana, skystar@moldova.cc
  *
  * FIX: DiSEqC Tone Burst in flexcop_diseqc_ioctl()
+ * FIX: FULL soft DiSEqC for skystar2 (rev 193) VP310 equipped 
  * 	 Vincenzo Di Massa, hawk.it at tiscalinet.it
  * 	
  * IMP: Converted to Linux coding style
  * 	 Roberto Ragusa, r.ragusa at libero.it
  *
- * FIX: FULL soft DiSEqC for skystar2 (rev 193) VP310 equipped
- *       Vincenzo Di Massa, hawk.it at tiscalinet.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
@@ -51,11 +54,16 @@
 #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
 
+#define N_HW_FILTERS		(6+32)
+#define N_PID_SLOTS		256
+
 struct dmaq {
 
 	u32 bus_addr;
@@ -100,7 +108,11 @@ struct adapter {
 
 	spinlock_t lock;
 
-	u16 pids[0x27];
+	u16 pids[N_HW_FILTERS];
+	u16 pid_list[N_PID_SLOTS];
+	u8  pid_rc[N_PID_SLOTS];					// ref counters for the pids
+	u16 pid_count;
+	u16 whole_band_width;
 	u32 mac_filter;
 };
 
@@ -224,7 +236,7 @@ static u32 flex_i2c_read(struct adapter 
 	u32 bytes_to_transfer;
 	u8 *start;
 
-	dprintk("%s:\n", __FUNCTION__);
+	ddprintk("%s:\n", __FUNCTION__);
 
 	start = buf;
 
@@ -253,7 +265,7 @@ static u32 flex_i2c_write(struct adapter
 	u32 bytes_to_transfer;
 	u8 *start;
 
-	dprintk("%s:\n", __FUNCTION__);
+	ddprintk("%s:\n", __FUNCTION__);
 
 	start = buf;
 
@@ -284,11 +296,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 */
@@ -602,13 +614,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? */
@@ -933,83 +945,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);
+	u32 mask=( 0x00000001 << id );
 
-	if (op == 0) {
-		write_reg_op(adapter, 0x208, 2, ~0x00000004, 0);
-
-	} else {
+	dprintk("%s: id=%d op=%d\n", __FUNCTION__, id, op);
 
-		write_reg_op(adapter, 0x208, 1, 0, 0x00000004);
-	}
-}
-
-static void filter_enable_pmt_filter(struct adapter *adapter, u32 op)
-{
-	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);
-	}
+	if (op == 0) write_reg_op(adapter, 0x208, 2, ~mask, 0);
+	else write_reg_op(adapter, 0x208, 1, 0, mask);
 }
 
-static void filter_enable_emm_fFilter(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);
+	u32 adr=0x300+((id&6)<<1);
 
-	if (op == 0) {
-		write_reg_op(adapter, 0x208, 2, ~0x00000010, 0);
+	dprintk("%s: id=%d  addr=%x %c  pid=%d\n", __FUNCTION__, id, adr, (id&1)? 'h':'l', pid);
 
-	} else {
-
-		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)
@@ -1051,6 +1011,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;
@@ -1091,29 +1070,6 @@ 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;
-	}
-
-	return 0;
-}
-
 static void pid_set_group_pid(struct adapter * adapter, u32 pid)
 {
 	u32 value;
@@ -1142,120 +1098,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;
@@ -1265,6 +1108,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)
@@ -1284,10 +1128,29 @@ 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 < N_HW_FILTERS; i++)
+		adapter->pids[i] = 0x1FFF;
+	adapter->pid_count=0;
+	adapter->whole_bandwidth = 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__);
@@ -1297,175 +1160,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) {
+		if (adapter->whole_bandwidth == 0)
+			open_whole_bandwidth(adapter);
+		++adapter->whole_bandwidth;
 		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]==pid) {
+			adapter->pid_rc[i]++; // increment ref counter
 			return 1;
 		}
+	
+	if(adapter->pid_count==N_PID_SLOTS) return -1; // no more pids can be added
+	adapter->pid_list[adapter->pid_count]=pid;      // register pid
+	adapter->pid_rc[adapter->pid_count]=1;
+	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) {
+		if (adapter->whole_bandwidth == 0)
+			open_whole_bandwidth(adapter);
+		adapter->whole_bandwidth++;
 	}
-
-	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->whole_bandwith <= 0) return -1;	// cannot remove a pid that was not added ;)
+		adapter->whole_bandwidth--;
+		if (adapter->whole_bandwidth == 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]==pid) {
+			adapter->pid_rc[i]--;
+			if(adapter->pid_rc[i]<=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];
+					adapter->pid_rc[j]=adapter->pid_rc[j+1];
+				}
+				// close filter and take care to reverse the effect of open_whole_bandwidth
+				if (remove_hw_pid(adapter,pid)==-1) {
+					if (adapter->whole_bandwidth > 0)
+						--adapter->whole_bandwidth;
+					if (adapter->whole_bandwidth == 0)
+						 close_whole_bandwidth(adapter);
+				}
+			}
 
 			return 1;
 		}
 	}
-
 	return -1;
 }
 
+
 /* dma & irq */
 static void ctrl_enable_smc(struct adapter *adapter, u32 op)
 {
@@ -1745,7 +1600,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);
 
@@ -1795,7 +1651,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)
@@ -1827,9 +1683,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;
@@ -1871,7 +1727,7 @@ static irqreturn_t isr(int irq, void *de
 
 	u32 value;
 
-	dprintk("%s:\n", __FUNCTION__);
+	ddprintk("%s:\n", __FUNCTION__);
 
 	spin_lock_irq(&tmp->lock);
 
@@ -1915,7 +1771,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 {
 
@@ -1941,7 +1797,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 {
 
@@ -2080,16 +1936,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);
 
@@ -2101,25 +1948,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);
 
@@ -2456,8 +2303,8 @@ static int skystar2_probe(struct pci_dev
 	dvbdemux = &adapter->demux;
 
 	dvbdemux->priv = (void *) adapter;
-	dvbdemux->filternum = 256;
-	dvbdemux->feednum = 256;
+	dvbdemux->filternum = N_PID_SLOTS;
+	dvbdemux->feednum = N_PID_SLOTS;
 	dvbdemux->start_feed = dvb_start_feed;
 	dvbdemux->stop_feed = dvb_stop_feed;
 	dvbdemux->write_to_decoder = 0;
@@ -2551,7 +2398,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(enable_hw_filters, "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