diff -Naur test-for-latech/arch/arm/config.in testqf-for-latech/arch/arm/config.in
--- test-for-latech/arch/arm/config.in	2004-06-11 07:42:31.000000000 -0400
+++ testqf-for-latech/arch/arm/config.in	2004-06-11 07:49:18.000000000 -0400
@@ -654,4 +654,15 @@
 dep_bool '  Kernel low-level debugging functions' CONFIG_DEBUG_LL $CONFIG_DEBUG_KERNEL
 dep_bool '    Kernel low-level debugging messages via footbridge serial port' CONFIG_DEBUG_DC21285_PORT $CONFIG_DEBUG_LL $CONFIG_FOOTBRIDGE
 dep_bool '    Kernel low-level debugging messages via UART2' CONFIG_DEBUG_CLPS711X_UART2 $CONFIG_DEBUG_LL $CONFIG_ARCH_CLPS711X
+
+#dep_bool 'modular DWCS scheduler' CONFIG_DWCS $CONFIG_PROC_FS
+#dep_bool '    DFS Support' CONFIG_DWCS_DFS $CONFIG_DWCS
+
+bool 'Quality of Service Support (Q-Fabric)' CONFIG_QFABRIC
+if [ "$CONFIG_QFABRIC" = "y" ]
+	define_bool CONFIG_DWCS
+	define_bool CONFIG_DWCS_DFS
+	define_bool CONFIG_PROC_FS
+fi	
+
 endmenu
diff -Naur test-for-latech/arch/arm/kernel/calls.S testqf-for-latech/arch/arm/kernel/calls.S
--- test-for-latech/arch/arm/kernel/calls.S	2004-06-11 07:42:31.000000000 -0400
+++ testqf-for-latech/arch/arm/kernel/calls.S	2004-06-11 07:49:18.000000000 -0400
@@ -253,6 +253,28 @@
 		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_lremovexattr */
 		.long	SYMBOL_NAME(sys_ni_syscall) /* sys_fremovexattr */
 		.long	SYMBOL_NAME(sys_tkill)
+   		.long SYMBOL_NAME(sys_load_scheduler)	
+   		.long SYMBOL_NAME(sys_unload_scheduler)	
+	   	.long SYMBOL_NAME(sys_DWCS_scheduler)	
+		.long SYMBOL_NAME(sys_update_utilization)
+		.long SYMBOL_NAME(sys_admission_control)
+		.long SYMBOL_NAME(sys_start_ecalls)
+		.long SYMBOL_NAME(sys_end_ecalls)
+		.long SYMBOL_NAME(sys_register_ecall)
+		.long SYMBOL_NAME(sys_do_downcall)
+		.long SYMBOL_NAME(sys_run_event_handler)
+		.long SYMBOL_NAME(sys_upcall_scheduler)
+		.long SYMBOL_NAME(sys_wake_up_ecalls)
+		.long SYMBOL_NAME(sys_download_code)
+		.long SYMBOL_NAME(sys_kecho_load)
+		.long SYMBOL_NAME(sys_KECho_syscall_echo)
+		.long SYMBOL_NAME(sys_KECho_syscall_cm)
+		.long SYMBOL_NAME(sys_KECho_syscall_cg)
+		.long SYMBOL_NAME(sys_KECho_syscall_atl)
+		.long SYMBOL_NAME(sys_KECho_sw_callback)
+		.long SYMBOL_NAME(sys_getsyscalls)
+		.long SYMBOL_NAME(sys_qos_configure)
+		.long SYMBOL_NAME(sys_change_clock)
 		/*
 		 * Please check 2.5 _before_ adding calls here,
 		 * and copy changes to rmk@arm.linux.org.uk.  Thanks.
diff -Naur test-for-latech/arch/arm/kernel/init_task.c testqf-for-latech/arch/arm/kernel/init_task.c
--- test-for-latech/arch/arm/kernel/init_task.c	2004-06-11 07:42:31.000000000 -0400
+++ testqf-for-latech/arch/arm/kernel/init_task.c	2004-06-11 07:49:18.000000000 -0400
@@ -13,6 +13,9 @@
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
 struct mm_struct init_mm = INIT_MM(init_mm);
+#ifdef CONFIG_DWCS
+struct dwcs_struct init_dwcs = INIT_DWCS; /* --FS-- Check linux/sched.h */
+#endif
 
 /*
  * Initial task structure.
diff -Naur test-for-latech/arch/arm/kernel/process.c testqf-for-latech/arch/arm/kernel/process.c
--- test-for-latech/arch/arm/kernel/process.c	2004-06-11 07:42:31.000000000 -0400
+++ testqf-for-latech/arch/arm/kernel/process.c	2004-06-11 07:49:18.000000000 -0400
@@ -369,6 +369,9 @@
 pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
 {
 	pid_t __ret;
+#ifdef CONFIG_QFABRIC
+	struct task_struct *p;
+#endif
 
 	__asm__ __volatile__(
 	"orr	r0, %1, %2	@ kernel_thread sys_clone
@@ -385,6 +388,12 @@
         : "=r" (__ret)
         : "Ir" (flags), "I" (CLONE_VM), "r" (fn), "r" (arg)
 	: "r0", "r1", "lr");
+#ifdef CONFIG_QFABRIC
+#ifdef CONFIG_X86
+	p = find_task_by_pid(retval);
+	p->kthread = 1;
+#endif
+#endif
 	return __ret;
 }
 
diff -Naur test-for-latech/arch/i386/config.in testqf-for-latech/arch/i386/config.in
--- test-for-latech/arch/i386/config.in	2004-06-11 07:42:22.000000000 -0400
+++ testqf-for-latech/arch/i386/config.in	2004-06-11 07:49:01.000000000 -0400
@@ -425,4 +425,12 @@
    bool '  Compile the kernel with frame pointers' CONFIG_FRAME_POINTER
 fi
 
+#dep_bool 'modular DWCS scheduler' CONFIG_DWCS $CONFIG_PROC_FS
+
+bool 'Quality of Service Support (Q-Fabric)' CONFIG_QFABRIC
+if [ "$CONFIG_QFABRIC" = "y" ]; then
+   define_bool CONFIG_DWCS y
+   define_bool CONFIG_PROC_FS y
+fi
+
 endmenu
diff -Naur test-for-latech/arch/i386/kernel/entry.S testqf-for-latech/arch/i386/kernel/entry.S
--- test-for-latech/arch/i386/kernel/entry.S	2004-06-11 07:42:23.000000000 -0400
+++ testqf-for-latech/arch/i386/kernel/entry.S	2004-06-11 07:49:01.000000000 -0400
@@ -202,6 +202,9 @@
 	call *SYMBOL_NAME(sys_call_table)(,%eax,4)
 	movl %eax,EAX(%esp)		# save the return value
 ENTRY(ret_from_sys_call)
+#ifdef CONFIG_QFABRIC
+	call SYMBOL_NAME(inc_syscall_counter)
+#endif
 	cli				# need_resched and signals atomic test
 	cmpl $0,need_resched(%ebx)
 	jne reschedule
@@ -259,6 +262,85 @@
 	call SYMBOL_NAME(schedule)    # test
 	jmp ret_from_sys_call
 
+#ifdef CONFIG_QFABRIC
+ENTRY(fast_system_call)
+	pushl %eax			# save orig_eax
+	SAVE_ALL
+	call *SYMBOL_NAME(fast_sys_call_table)(,%eax,4)
+	movl %eax,EAX(%esp)		# save the return value
+	cmpl $0,%eax
+	jnz handle_return_value
+	RESTORE_ALL
+
+handle_return_value:
+	cmpl $-1,%eax
+	jz not_installed
+	testl $8,%eax
+	jnz do_slow_call
+	GET_CURRENT(%ebx)
+	testl $1,%eax
+	jnz do_bh
+cont1:
+	testl $2,%eax
+	jnz do_reschedule
+cont2:
+	testl $4,%eax
+	jnz handle_signal
+cont3:
+	RESTORE_ALL
+
+not_installed:
+	RESTORE_ALL
+
+do_slow_call:
+	GET_CURRENT(%ebx)
+	testb $0x20,flags(%ebx)		# PF_TRACESYS
+	jne tracesys
+	movl ORIG_EAX(%esp),%eax
+	call *SYMBOL_NAME(sys_call_table)(,%eax,4)
+	movl %eax,EAX(%esp)		# save the return value
+	ALIGN
+	.globl ret_from_sys_call
+	.globl ret_from_intr
+
+do_bh:
+#ifdef CONFIG_SMP
+	movl processor(%ebx),%eax
+	shll $CONFIG_X86_L1_CACHE_SHIFT,%eax
+	movl SYMBOL_NAME(irq_stat)(,%eax),%ecx		# softirq_active
+	testl SYMBOL_NAME(irq_stat)+4(,%eax),%ecx	# softirq_mask
+#else
+	movl SYMBOL_NAME(irq_stat),%ecx		# softirq_active
+	testl SYMBOL_NAME(irq_stat)+4,%ecx	# softirq_mask
+#endif
+        jne do_handle_bh
+	jmp cont1
+
+do_handle_bh:
+	call SYMBOL_NAME(do_softirq)
+	jmp cont1
+
+do_reschedule:
+	movl EFLAGS(%esp),%eax
+	movb CS(%esp),%al
+	testl $(VM_MASK | 3),%eax
+	je cont2
+	cmpl $0,need_resched(%ebx)
+	je cont2
+	call SYMBOL_NAME(schedule)
+	jmp ret_from_sys_call
+
+handle_signal:
+	cmpl $0,sigpending(%ebx)
+	je cont3
+	testl $(VM_MASK),EFLAGS(%esp)
+	movl %esp,%eax
+	jne v86_signal_return
+	xorl %edx,%edx
+	call SYMBOL_NAME(do_signal)
+	jmp cont3
+#endif
+
 ENTRY(divide_error)
 	pushl $0		# no error code
 	pushl $ SYMBOL_NAME(do_divide_error)
@@ -639,7 +721,300 @@
 	.long SYMBOL_NAME(sys_ni_syscall)	/* 240 reserved for futex */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_setaffinity */
 	.long SYMBOL_NAME(sys_ni_syscall)	/* reserved for sched_getaffinity */
-
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+	.long SYMBOL_NAME(sys_ni_syscall)
+   	.long SYMBOL_NAME(sys_update_utilization)
+    	.long SYMBOL_NAME(sys_admission_control)
+   	.long SYMBOL_NAME(sys_start_ecalls)	
+    	.long SYMBOL_NAME(sys_end_ecalls)	
+    	.long SYMBOL_NAME(sys_register_ecall)	
+    	.long SYMBOL_NAME(sys_do_downcall)	
+    	.long SYMBOL_NAME(sys_run_event_handler)
+    	.long SYMBOL_NAME(sys_upcall_scheduler)
+    	.long SYMBOL_NAME(sys_wake_up_ecalls)	
+    	.long SYMBOL_NAME(sys_download_code)	
+  	.long SYMBOL_NAME(sys_kecho_load)	
+    	.long SYMBOL_NAME(sys_KECho_syscall_echo)
+    	.long SYMBOL_NAME(sys_KECho_syscall_cm)	
+    	.long SYMBOL_NAME(sys_KECho_syscall_cg)	
+    	.long SYMBOL_NAME(sys_KECho_syscall_atl)
+    	.long SYMBOL_NAME(sys_KECho_sw_callback)
+    	.long SYMBOL_NAME(sys_getsyscalls)      
+ 	.long SYMBOL_NAME(sys_qos_configure) 
+ 	.long SYMBOL_NAME(sys_change_clock) 
+#ifdef CONFIG_NET_QSOCKET
+ 	.long SYMBOL_NAME(sys_qsocketcall)	
+#endif
+ 
 	.rept NR_syscalls-(.-sys_call_table)/4
 		.long SYMBOL_NAME(sys_ni_syscall)
 	.endr
+
+.data
+ENTRY(fast_sys_call_table)
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 0 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_fast_read)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 5 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 10 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 15 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 20 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 25 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 30 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 35 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+   	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 40 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 45 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 50 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 55 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 60 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 65 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 70 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 75 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 80 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 85 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 90 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 95 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 100 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 105 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 110 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+   	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 115 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 120 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 125 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 130 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 135 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 140 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 145 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 150 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 155 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 160 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 165 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 170 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 175 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 180 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 185 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 190 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 195 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 200 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 205 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 210 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 215 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 220 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 225 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	/* 230 */
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_fast_do_downcall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+   	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_ni_syscall)	
+    	.long SYMBOL_NAME(sys_fast_KECho_syscall_echo)	
+    	.long SYMBOL_NAME(sys_fast_KECho_syscall_cm)	
+    	.long SYMBOL_NAME(sys_fast_KECho_syscall_cg)	
+    	.long SYMBOL_NAME(sys_fast_KECho_syscall_atl)	
+    
+ 	.rept NR_syscalls-(.-fast_sys_call_table)/4
+ 		.long SYMBOL_NAME(sys_ni_syscall)
+ 	.endr
diff -Naur test-for-latech/arch/i386/kernel/i8259.c testqf-for-latech/arch/i386/kernel/i8259.c
--- test-for-latech/arch/i386/kernel/i8259.c	2004-06-11 07:42:23.000000000 -0400
+++ testqf-for-latech/arch/i386/kernel/i8259.c	2004-06-11 07:49:01.000000000 -0400
@@ -456,8 +456,14 @@
 	 */
 	for (i = 0; i < NR_IRQS; i++) {
 		int vector = FIRST_EXTERNAL_VECTOR + i;
+#ifdef CONFIG_QFABRIC
+		if ((vector != SYSCALL_VECTOR) && 
+		  (vector != FAST_SYSCALL_VECTOR))
+		    	set_intr_gate(vector, interrupt[i]);
+#else
 		if (vector != SYSCALL_VECTOR) 
 			set_intr_gate(vector, interrupt[i]);
+#endif
 	}
 
 #ifdef CONFIG_SMP
diff -Naur test-for-latech/arch/i386/kernel/init_task.c testqf-for-latech/arch/i386/kernel/init_task.c
--- test-for-latech/arch/i386/kernel/init_task.c	2004-06-11 07:42:23.000000000 -0400
+++ testqf-for-latech/arch/i386/kernel/init_task.c	2004-06-11 07:49:01.000000000 -0400
@@ -10,6 +10,9 @@
 static struct files_struct init_files = INIT_FILES;
 static struct signal_struct init_signals = INIT_SIGNALS;
 struct mm_struct init_mm = INIT_MM(init_mm);
+#ifdef CONFIG_DWCS
+struct dwcs_struct init_dwcs = INIT_DWCS; /* --RW-- Check linux/sched.h */
+#endif
 
 /*
  * Initial task structure.
diff -Naur test-for-latech/arch/i386/kernel/process.c testqf-for-latech/arch/i386/kernel/process.c
--- test-for-latech/arch/i386/kernel/process.c	2004-06-11 07:42:23.000000000 -0400
+++ testqf-for-latech/arch/i386/kernel/process.c	2004-06-11 07:49:01.000000000 -0400
@@ -488,6 +488,9 @@
 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
 {
 	long retval, d0;
+#ifdef CONFIG_QFABRIC
+	struct task_struct *p;
+#endif
 
 	__asm__ __volatile__(
 		"movl %%esp,%%esi\n\t"
@@ -508,6 +511,10 @@
 		 "r" (arg), "r" (fn),
 		 "b" (flags | CLONE_VM)
 		: "memory");
+#ifdef CONFIG_QFABRIC
+	p = find_task_by_pid(retval);
+	p->kthread = 1;
+#endif
 	return retval;
 }
 
diff -Naur test-for-latech/arch/i386/kernel/ptrace.c testqf-for-latech/arch/i386/kernel/ptrace.c
--- test-for-latech/arch/i386/kernel/ptrace.c	2004-06-11 07:42:23.000000000 -0400
+++ testqf-for-latech/arch/i386/kernel/ptrace.c	2004-06-11 07:49:01.000000000 -0400
@@ -452,3 +452,11 @@
 		current->exit_code = 0;
 	}
 }
+
+#ifdef CONFIG_QFABRIC
+asmlinkage void inc_syscall_counter()
+{
+	current->syscall_counter++;
+}
+EXPORT_SYMBOL(inc_syscall_counter);
+#endif
diff -Naur test-for-latech/arch/i386/kernel/traps.c testqf-for-latech/arch/i386/kernel/traps.c
--- test-for-latech/arch/i386/kernel/traps.c	2004-06-11 07:42:22.000000000 -0400
+++ testqf-for-latech/arch/i386/kernel/traps.c	2004-06-11 07:49:01.000000000 -0400
@@ -51,6 +51,9 @@
 #include <linux/module.h>
 
 asmlinkage int system_call(void);
+#ifdef CONFIG_QFABRIC
+asmlinkage int fast_system_call(void);
+#endif
 asmlinkage void lcall7(void);
 asmlinkage void lcall27(void);
 
@@ -985,6 +988,9 @@
 	set_trap_gate(19,&simd_coprocessor_error);
 
 	set_system_gate(SYSCALL_VECTOR,&system_call);
+#ifdef CONFIG_QFABRIC
+	set_system_gate(FAST_SYSCALL_VECTOR,&fast_system_call);
+#endif
 
 	/*
 	 * default LDT is a single-entry callgate to lcall7 for iBCS
diff -Naur test-for-latech/arch/i386/lib/usercopy.c testqf-for-latech/arch/i386/lib/usercopy.c
--- test-for-latech/arch/i386/lib/usercopy.c	2004-06-11 07:42:22.000000000 -0400
+++ testqf-for-latech/arch/i386/lib/usercopy.c	2004-06-11 07:49:01.000000000 -0400
@@ -27,6 +27,12 @@
 unsigned long
 __generic_copy_from_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	if (access_ok(VERIFY_READ, from, n))
 	{
 		if(n<512)
@@ -53,6 +59,12 @@
 unsigned long
 __generic_copy_from_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	prefetchw(to);
 	if (access_ok(VERIFY_READ, from, n))
 		__copy_user_zeroing(to,from,n);
diff -Naur test-for-latech/Documentation/Configure.help testqf-for-latech/Documentation/Configure.help
--- test-for-latech/Documentation/Configure.help	2004-06-11 07:42:36.000000000 -0400
+++ testqf-for-latech/Documentation/Configure.help	2004-06-11 07:49:26.000000000 -0400
@@ -20527,6 +20527,36 @@
 
   "Area6" will work for most boards. For ADX, select "Area5".
 
+#modular DWCS process scheduler
+#CONFIG_DWCS
+#  This option includes a kernel loadable module dwcs.o which implements
+#  a Dynamic Window-Constrained Scheduler instead of the regular Linux
+#  scheduler. Loading the module is not enough, you have to switch 
+#  scheduling to the new scheduler.
+
+#  To find out more about the scheduler, or to find out more about how
+#  to use it visit: http://www.cc.gatech.edu/~west/dwcs.html
+
+#  This scheduler is for hacking purposes only, it seems to be stable on
+#  uniprocessor machines, but not on SMP boxes. You've been warned. This
+#  is still very experimental code, play with it _only_ if you know what
+#  you are doing.
+
+#DWCS /proc interface
+#CONFIG_PROC_DWCS
+#  This option enables a pseudo file /proc/dwcs reading which will give
+#  you a snapshot of the current operating parameters of the DWCS 
+#  scheduler. The file exists only when the scheduler is loaded.
+
+Quality of Service Support (Q-Fabric)
+CONFIG_QFABRIC
+  If you say Y here, Artemis-enabled kernel extensions can be used by 
+  applications. Artemis is a QoS infrastructure based on a distributed
+  event notification mechanism (called KECho). Saying Y here only adds
+  the necessary modifications to the kernel to support Artemis. The 
+  actual Artemis modules are not part of the kernel, but are made 
+  available in a software package available at http://www.cc.gatech.edu/~chris.
+
 #
 # m68k-specific kernel options
 # Documented by Chris Lawrence <mailto:quango@themall.net> et al.
diff -Naur test-for-latech/fs/read_write.c testqf-for-latech/fs/read_write.c
--- test-for-latech/fs/read_write.c	2004-06-11 07:39:57.000000000 -0400
+++ testqf-for-latech/fs/read_write.c	2004-06-11 07:47:19.000000000 -0400
@@ -425,3 +425,9 @@
 bad_file:
 	return ret;
 }
+
+asmlinkage int sys_fast_read(int fd,
+	void *buffer, int len)
+{
+        return 0;
+}
diff -Naur test-for-latech/include/asm-arm/current.h testqf-for-latech/include/asm-arm/current.h
--- test-for-latech/include/asm-arm/current.h	2004-06-11 07:40:29.000000000 -0400
+++ testqf-for-latech/include/asm-arm/current.h	2004-06-11 07:47:34.000000000 -0400
@@ -1,14 +1,32 @@
 #ifndef _ASMARM_CURRENT_H
 #define _ASMARM_CURRENT_H
 
+#ifdef CONFIG_QFABRIC
+extern int ECalls_current_flag;
+extern struct task_struct *ECalls_current;
+#endif
+
 static inline struct task_struct *get_current(void) __attribute__ (( __const__ ));
 
-static inline struct task_struct *get_current(void)
+static inline struct task_struct *original_get_current(void) __attribute__ (( __const__ ));
+
+static inline struct task_struct *original_get_current(void)
 {
 	register unsigned long sp asm ("sp");
 	return (struct task_struct *)(sp & ~0x1fff);
 }
 
+#define original_current original_get_current()
+
+static inline struct task_struct *get_current(void)
+{
+#ifdef CONFIG_QFABRIC
+	if (ECalls_current_flag == 1)
+		return ECalls_current;
+#endif
+	return original_get_current();
+}
+
 #define current (get_current())
 
 #endif /* _ASMARM_CURRENT_H */
diff -Naur test-for-latech/include/asm-arm/errno.h testqf-for-latech/include/asm-arm/errno.h
--- test-for-latech/include/asm-arm/errno.h	2004-06-11 07:40:29.000000000 -0400
+++ testqf-for-latech/include/asm-arm/errno.h	2004-06-11 07:47:34.000000000 -0400
@@ -129,4 +129,8 @@
 #define	ENOMEDIUM	123	/* No medium found */
 #define	EMEDIUMTYPE	124	/* Wrong medium type */
 
+#ifdef CONFIG_QFABRIC
+#define EADMISSION	125	/* Task admission denied. */
+#endif
+
 #endif
diff -Naur test-for-latech/include/asm-arm/socket.h testqf-for-latech/include/asm-arm/socket.h
--- test-for-latech/include/asm-arm/socket.h	2004-06-11 07:40:29.000000000 -0400
+++ testqf-for-latech/include/asm-arm/socket.h	2004-06-11 07:47:34.000000000 -0400
@@ -45,6 +45,11 @@
 
 #define SO_ACCEPTCONN		30
 
+#ifdef CONFIG_QFABRIC
+#define SO_QOS_PRIORITY		1000
+#define SO_QOS_DEADLINE		1001
+#endif
+
 /* Nast libc5 fixup - bletch */
 #if defined(__KERNEL__)
 /* Socket types. */
diff -Naur test-for-latech/include/asm-arm/uaccess.h testqf-for-latech/include/asm-arm/uaccess.h
--- test-for-latech/include/asm-arm/uaccess.h	2004-06-11 07:40:29.000000000 -0400
+++ testqf-for-latech/include/asm-arm/uaccess.h	2004-06-11 07:47:34.000000000 -0400
@@ -23,6 +23,11 @@
  * on our cache or tlb entries.
  */
 
+#ifdef CONFIG_QFABRIC
+extern mm_segment_t kernel_get_fs(void);
+extern int kernel_access_ok(int type, const void *addr, size_t size);
+#endif
+
 struct exception_table_entry
 {
 	unsigned long insn, fixup;
@@ -32,12 +37,28 @@
 extern unsigned long search_exception_table(unsigned long);
 
 #define get_ds()	(KERNEL_DS)
+#ifdef CONFIG_QFABRIC
+#ifdef MODULE
+#define get_fs()	(current->addr_limit)
+#else
+#define get_fs()	kernel_get_fs()
+#endif
+#else
 #define get_fs()	(current->addr_limit)
+#endif
 #define segment_eq(a,b)	((a) == (b))
 
 #include <asm/proc/uaccess.h>
 
+#ifdef CONFIG_QFABRIC
+#ifdef MODULE
+#define access_ok(type,addr,size)	(__range_ok(addr,size) == 0)
+#else
+#define access_ok(type,addr,size)	kernel_access_ok(type,addr,size)
+#endif
+#else
 #define access_ok(type,addr,size)	(__range_ok(addr,size) == 0)
+#endif
 
 static inline int verify_area(int type, const void * addr, unsigned long size)
 {
@@ -143,6 +164,12 @@
 
 static __inline__ unsigned long copy_from_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	if (access_ok(VERIFY_READ, from, n))
 		__do_copy_from_user(to, from, n);
 	else /* security hole - plug it */
@@ -152,12 +179,24 @@
 
 static __inline__ unsigned long __copy_from_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	__do_copy_from_user(to, from, n);
 	return n;
 }
 
 static __inline__ unsigned long copy_to_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	if (access_ok(VERIFY_WRITE, to, n))
 		__do_copy_to_user(to, from, n);
 	return n;
@@ -165,6 +204,12 @@
 
 static __inline__ unsigned long __copy_to_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	__do_copy_to_user(to, from, n);
 	return n;
 }
diff -Naur test-for-latech/include/asm-arm/unistd.h testqf-for-latech/include/asm-arm/unistd.h
--- test-for-latech/include/asm-arm/unistd.h	2004-06-11 07:40:27.000000000 -0400
+++ testqf-for-latech/include/asm-arm/unistd.h	2004-06-11 07:47:34.000000000 -0400
@@ -259,6 +259,44 @@
 #define __NR_fremovexattr		(__NR_SYSCALL_BASE+237)
 #endif
 #define __NR_tkill			(__NR_SYSCALL_BASE+238)
+/* DWCS related calls. */
+#define __NR_load_scheduler     	(__NR_SYSCALL_BASE+239)	/* Added by Rich West --RW--.  */
+#define __NR_unload_scheduler      	(__NR_SYSCALL_BASE+240)	/* Added by Rich West --RW--.  */
+#define __NR_DWCS_scheduler         	(__NR_SYSCALL_BASE+241)	/* Added by Rich West --RW--.  */
+#define __NR_update_utilization       	(__NR_SYSCALL_BASE+242)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_admission_control        	(__NR_SYSCALL_BASE+243)	/* Added by C. Poellabauer --CP--.  */
+
+/* Additional syscalls added for the ECalls mechanism. */
+#define __NR_start_ecalls             	(__NR_SYSCALL_BASE+244)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_end_ecalls               	(__NR_SYSCALL_BASE+245)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_register_ecall           	(__NR_SYSCALL_BASE+246)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_do_downcall              	(__NR_SYSCALL_BASE+247)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_run_event_handler        	(__NR_SYSCALL_BASE+248)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_upcall_scheduler         	(__NR_SYSCALL_BASE+249)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_wake_up_ecalls           	(__NR_SYSCALL_BASE+250)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_download_code           	(__NR_SYSCALL_BASE+251)	/* Added by C. Poellabauer --CP--.  */
+
+/* Syscalls for user-level usage of KECho. */
+#define __NR_kecho_load		      	(__NR_SYSCALL_BASE+252)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_echo       	(__NR_SYSCALL_BASE+253)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_cm         	(__NR_SYSCALL_BASE+254)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_cg         	(__NR_SYSCALL_BASE+255)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_atl        	(__NR_SYSCALL_BASE+256)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_sw_callback        	(__NR_SYSCALL_BASE+257)	/* Added by C. Poellabauer --CP--.  */
+
+/* Syscalls for measurment purposes. */
+#define __NR_getsyscalls              	(__NR_SYSCALL_BASE+258)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_qos_configure            	(__NR_SYSCALL_BASE+259)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_change_clock            	(__NR_SYSCALL_BASE+260)	/* Added by C. Poellabauer --CP--.  */
+
+/* Fast system call definitions. */
+#define __NR_fast_read                	(__NR_SYSCALL_BASE+3)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_do_downcall         	(__NR_SYSCALL_BASE+247)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_echo    (__NR_SYSCALL_BASE+253)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_cm      (__NR_SYSCALL_BASE+254)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_cg      (__NR_SYSCALL_BASE+255)	/* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_atl     (__NR_SYSCALL_BASE+256)	/* Added by C. Poellabauer --CP--.  */
+
 /*
  * Please check 2.5 _before_ adding calls here,
  * and copy changes to rmk@arm.linux.org.uk.  Thanks.
diff -Naur test-for-latech/include/asm-i386/current.h testqf-for-latech/include/asm-i386/current.h
--- test-for-latech/include/asm-i386/current.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/current.h	2004-06-11 07:47:30.000000000 -0400
@@ -3,13 +3,35 @@
 
 struct task_struct;
 
+#ifdef CONFIG_QFABRIC
+extern int ECalls_current_flag;
+extern struct task_struct *ECalls_current;
+
+static inline struct task_struct * original_get_current(void)
+{
+	struct task_struct *current;
+
+	__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));
+	return current;
+}
+
+#define original_current original_get_current()
+
+static inline struct task_struct * get_current(void)
+{
+	if (ECalls_current_flag == 1) 
+		return ECalls_current;
+	return original_get_current();
+}
+#else
 static inline struct task_struct * get_current(void)
 {
 	struct task_struct *current;
 	__asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL));
 	return current;
- }
- 
+}
+#endif
+
 #define current get_current()
 
 #endif /* !(_I386_CURRENT_H) */
diff -Naur test-for-latech/include/asm-i386/errno.h testqf-for-latech/include/asm-i386/errno.h
--- test-for-latech/include/asm-i386/errno.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/errno.h	2004-06-11 07:47:30.000000000 -0400
@@ -129,4 +129,8 @@
 #define	ENOMEDIUM	123	/* No medium found */
 #define	EMEDIUMTYPE	124	/* Wrong medium type */
 
+#ifdef CONFIG_DWCS
+#define EADMISSION	125	/* Task admission denied. */
+#endif
+
 #endif
diff -Naur test-for-latech/include/asm-i386/hw_irq.h testqf-for-latech/include/asm-i386/hw_irq.h
--- test-for-latech/include/asm-i386/hw_irq.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/hw_irq.h	2004-06-11 07:47:30.000000000 -0400
@@ -23,6 +23,9 @@
 #define FIRST_EXTERNAL_VECTOR	0x20
 
 #define SYSCALL_VECTOR		0x80
+#ifdef CONFIG_QFABRIC
+#define FAST_SYSCALL_VECTOR	0x60
+#endif
 
 /*
  * Vectors 0x20-0x2f are used for ISA interrupts.
diff -Naur test-for-latech/include/asm-i386/ptrace.h testqf-for-latech/include/asm-i386/ptrace.h
--- test-for-latech/include/asm-i386/ptrace.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/ptrace.h	2004-06-11 07:47:30.000000000 -0400
@@ -1,6 +1,7 @@
 #ifndef _I386_PTRACE_H
 #define _I386_PTRACE_H
 
+#ifndef QFABRIC_DCG
 #define EBX 0
 #define ECX 1
 #define EDX 2
@@ -19,6 +20,7 @@
 #define UESP 15
 #define SS   16
 #define FRAME_SIZE 17
+#endif
 
 /* this struct defines the way the registers are stored on the 
    stack during a system call. */
diff -Naur test-for-latech/include/asm-i386/socket.h testqf-for-latech/include/asm-i386/socket.h
--- test-for-latech/include/asm-i386/socket.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/socket.h	2004-06-11 07:47:30.000000000 -0400
@@ -45,6 +45,11 @@
 
 #define SO_ACCEPTCONN		30
 
+#ifdef CONFIG_QFABRIC
+#define	SO_QOS_PRIORITY		1000
+#define SO_QOS_DEADLINE		1001
+#endif
+
 /* Nasty libc5 fixup - bletch */
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 /* Socket types. */
diff -Naur test-for-latech/include/asm-i386/uaccess.h testqf-for-latech/include/asm-i386/uaccess.h
--- test-for-latech/include/asm-i386/uaccess.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/uaccess.h	2004-06-11 07:47:30.000000000 -0400
@@ -7,10 +7,21 @@
 #include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/prefetch.h>
+#ifdef CONFIG_QFABRIC
+#include <asm/current.h>
+#endif
 #include <asm/page.h>
 
 #define VERIFY_READ 0
 #define VERIFY_WRITE 1
+#ifdef CONFIG_QFABRIC
+#ifndef NR_THREADS
+#define NR_THREADS 512
+#endif
+
+extern mm_segment_t kernel_get_fs(void);
+extern int kernel_access_ok(int type, const void *addr, size_t size);
+#endif
 
 /*
  * The fs value determines whether argument validity checking should be
@@ -27,7 +38,15 @@
 #define USER_DS		MAKE_MM_SEG(PAGE_OFFSET)
 
 #define get_ds()	(KERNEL_DS)
+#ifdef CONFIG_QFABRIC
+#ifdef MODULE
+#define get_fs()	(current->addr_limit)
+#else
+#define get_fs()	kernel_get_fs()
+#endif
+#else
 #define get_fs()	(current->addr_limit)
+#endif
 #define set_fs(x)	(current->addr_limit = (x))
 
 #define segment_eq(a,b)	((a).seg == (b).seg)
@@ -35,7 +54,7 @@
 extern int __verify_write(const void *, unsigned long);
 
 #define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg))
-
+			
 /*
  * Uhhuh, this needs 33-bit arithmetic. We have a carry..
  */
@@ -46,6 +65,24 @@
 		:"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \
 	flag; })
 
+#ifdef CONFIG_QFABRIC 
+#ifdef MODULE
+#ifdef CONFIG_X86_WP_WORKS_OK
+
+#define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
+
+#else
+
+#define access_ok(type,addr,size) ( (__range_ok(addr,size) == 0) && \
+			 ((type) == VERIFY_READ || boot_cpu_data.wp_works_ok || \
+			 segment_eq(get_fs(),KERNEL_DS) || \
+			  __verify_write((void *)(addr),(size))))
+
+#endif
+#else
+#define access_ok(type,addr,size) kernel_access_ok(type,addr,size)
+#endif
+#else
 #ifdef CONFIG_X86_WP_WORKS_OK
 
 #define access_ok(type,addr,size) (__range_ok(addr,size) == 0)
@@ -58,6 +95,7 @@
 			  __verify_write((void *)(addr),(size))))
 
 #endif
+#endif
 
 static inline int verify_area(int type, const void * addr, unsigned long size)
 {
@@ -149,12 +187,12 @@
 
 #define __put_user_check(x,ptr,size)			\
 ({							\
-	long __pu_err = -EFAULT;					\
+	long __pu_err = -EFAULT;			\
 	__typeof__(*(ptr)) *__pu_addr = (ptr);		\
 	if (access_ok(VERIFY_WRITE,__pu_addr,size))	\
 		__put_user_size((x),__pu_addr,(size),__pu_err);	\
 	__pu_err;					\
-})							
+})	
 
 #define __put_user_u64(x, addr, err)				\
 	__asm__ __volatile__(					\
@@ -308,6 +346,12 @@
 static inline unsigned long
 __generic_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	__copy_user_zeroing(to,from,n);
 	return n;
 }
@@ -315,6 +359,12 @@
 static inline unsigned long
 __generic_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	__copy_user(to,from,n);
 	return n;
 }
@@ -546,6 +596,12 @@
 static inline unsigned long
 __constant_copy_to_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	prefetch(from);
 	if (access_ok(VERIFY_WRITE, to, n))
 		__constant_copy_user(to,from,n);
@@ -555,6 +611,12 @@
 static inline unsigned long
 __constant_copy_from_user(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	if (access_ok(VERIFY_READ, from, n))
 		__constant_copy_user_zeroing(to,from,n);
 	else
@@ -565,6 +627,12 @@
 static inline unsigned long
 __constant_copy_to_user_nocheck(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	__constant_copy_user(to,from,n);
 	return n;
 }
@@ -572,6 +640,12 @@
 static inline unsigned long
 __constant_copy_from_user_nocheck(void *to, const void *from, unsigned long n)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->uaccess_flag == 1) {
+		memcpy(to, from, n);
+		return 0;
+	}
+#endif
 	__constant_copy_user_zeroing(to,from,n);
 	return n;
 }
diff -Naur test-for-latech/include/asm-i386/unistd.h testqf-for-latech/include/asm-i386/unistd.h
--- test-for-latech/include/asm-i386/unistd.h	2004-06-11 07:40:12.000000000 -0400
+++ testqf-for-latech/include/asm-i386/unistd.h	2004-06-11 07:47:29.000000000 -0400
@@ -1,5 +1,12 @@
 #ifndef _ASM_I386_UNISTD_H_
 #define _ASM_I386_UNISTD_H_
+#ifdef CONFIG_QFABRIC
+#include <linux/config.h>
+#endif
+
+#ifdef CONFIG_DWCS
+#define __NR_SYSCALL_BASE	0x00
+#endif
 
 /*
  * This file contains the system call numbers.
@@ -248,6 +255,45 @@
 #define __NR_sched_setaffinity	241
 #define __NR_sched_getaffinity	242
 
+/* Additional syscalls added for the dionisys resource manager. */
+#define __NR_load_scheduler     243     /* Added by Rich West --RW--.  */
+#define __NR_unload_scheduler   244     /* Added by Rich West --RW--.  */
+#define __NR_DWCS_scheduler     245     /* Added by Rich West --RW--.  */
+#define __NR_update_utilization 246     /* Added by C. Poellabauer --CP--.  */
+#define __NR_admission_control  247     /* Added by C. Poellabauer --CP--.  */
+/* Additional syscalls added for the ECalls mechanism. */
+#define __NR_start_ecalls       248     /* Added by C. Poellabauer --CP--.  */
+#define __NR_end_ecalls         249     /* Added by C. Poellabauer --CP--.  */
+#define __NR_register_ecall     250     /* Added by C. Poellabauer --CP--.  */
+#define __NR_do_downcall        251     /* Added by C. Poellabauer --CP--.  */
+#define __NR_run_event_handler  252     /* Added by C. Poellabauer --CP--.  */
+#define __NR_upcall_scheduler   253     /* Added by C. Poellabauer --CP--.  */
+#define __NR_wake_up_ecalls     254     /* Added by C. Poellabauer --CP--.  */
+#define __NR_download_code      255     /* Added by C. Poellabauer --CP--.  */
+
+/* Syscalls for user-level usage of KECho. */
+#define __NR_kecho_load		256 /* --CP-- */
+#define __NR_KECho_syscall_echo 257     /* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_cm   258     /* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_cg   259     /* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_syscall_atl  260     /* Added by C. Poellabauer --CP--.  */
+#define __NR_KECho_sw_callback  261     /* Added by C. Poellabauer --CP--.  */
+
+#define __NR_getsyscalls        262     /* Added by C. Poellabauer --CP--.  */
+#define __NR_qos_configure	263     /* Added by C. Poellabauer --CP--.  */
+#define __NR_change_clock	264     /* Added by C. Poellabauer --CP--.  */
+
+/* QSocket changes. */
+#define __NR_qsocketcall	265
+
+/* Fast system call definitions. */
+#define __NR_fast_read            3     /* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_do_downcall   251     /* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_echo 257 /* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_cm   258 /* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_cg   259 /* Added by C. Poellabauer --CP--.  */
+#define __NR_fast_KECho_syscall_atl  260 /* Added by C. Poellabauer --CP--.  */
+
 /* user-visible error numbers are in the range -1 - -124: see <asm-i386/errno.h> */
 
 #define __syscall_return(type, res) \
@@ -337,6 +383,71 @@
 __syscall_return(type,__res); \
 }
 
+/* Fast system calls. */
+#define _fast_syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x60" \
+	: "=a" (__res) \
+	: "0" (__NR_##name)); \
+__syscall_return(type,__res); \
+}
+
+#define _fast_syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x60" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"b" ((long)(arg1))); \
+__syscall_return(type,__res); \
+}
+
+#define _fast_syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x60" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
+__syscall_return(type,__res); \
+}
+
+#define _fast_syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x60" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+		  "d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+
+#define _fast_syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x60" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4))); \
+__syscall_return(type,__res); \
+} 
+
+#define _fast_syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x60" \
+	: "=a" (__res) \
+	: "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+	  "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+
 #ifdef __KERNEL_SYSCALLS__
 
 /*
diff -Naur test-for-latech/include/linux/ecalls.h testqf-for-latech/include/linux/ecalls.h
--- test-for-latech/include/linux/ecalls.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/ecalls.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,239 @@
+#ifndef	__ECALLS__H__
+#define	__ECALLS__H__
+
+#include <linux/ecalls-types.h>
+#include <string.h>
+
+/* system call: start_ecalls. */
+_syscall1(int, start_ecalls,
+	  int, flag);
+
+/* system call: end_ecalls. */
+_syscall0(int, end_ecalls);
+
+/* system call: register_ecall. */
+_syscall4(int, register_ecall,
+          char *, service,
+	  int, len,
+          struct ecall_down *, downcall,
+          struct ecall_up *, upcall);
+
+/* system call: download code. */
+_syscall5(int, download_code,
+	  char *, hookname,
+	  char *, parameter1,
+	  int, parameter2,
+	  int, parameter3,
+	  char *, code);
+
+/* system call: do_downcall. */
+_syscall3(int, do_downcall,
+          struct ecall_down *, downcall,
+	  void *, data,
+	  int, len);
+
+#ifdef CONFIG_X86
+/* fast system call: fast_do_downcall. */
+_fast_syscall3(int, fast_do_downcall,
+	  struct ecall_down *, downcall,
+	  void *, data,
+ 	  int, len);
+#endif
+
+/* Start ECalls. */
+int ECalls_start(int flag)
+{
+  start_ecalls(flag);
+
+  return 0;
+}
+
+/* End ECalls. */
+int ECalls_cancel(struct ecall_down *downcall, struct ecall_up *upcall)
+{
+  end_ecalls();
+
+  return 0;
+}
+
+/* Initialize downcall data structure. */
+int init_downcall(char *service_name, struct ecall_down *downcall, 
+	void *down_ptr)
+{
+  if (down_ptr != NULL) {
+    if (downcall->size1 > 0) {
+      if (downcall->size2 > 0) {
+        downcall->flag = (unsigned long) down_ptr;
+        downcall->bitpattern = downcall->flag + sizeof(int);
+        downcall->front = 0;
+        downcall->back = 0;
+        downcall->data = (unsigned long) downcall->bitpattern + 
+	  sizeof(unsigned long)*
+	  downcall->size2;
+        downcall->total_size = downcall->size1;
+        downcall->service_name = strdup(service_name);
+        downcall->string_len = strlen(service_name);
+      } else {
+        downcall->flag = (unsigned long) down_ptr;
+        downcall->bitpattern = 0;
+        downcall->front = (unsigned long) downcall->flag + sizeof(int);
+        downcall->back = (unsigned long) downcall->back + sizeof(int);
+        downcall->total_size = downcall->size1;
+        downcall->service_name = strdup(service_name);
+        downcall->string_len = strlen(service_name);
+      }
+    } else {
+      downcall->flag = 0;
+      downcall->bitpattern = 0;
+      downcall->front = 0;
+      downcall->back = 0;
+      downcall->data = 0;
+      downcall->total_size = sizeof(int);
+      downcall->service_name = strdup(service_name);
+      downcall->string_len = strlen(service_name);
+    }
+  } else {
+    downcall->flag = 0;
+    downcall->bitpattern = 0;
+    downcall->front = 0;
+    downcall->back = 0;
+    downcall->data = 0;
+    downcall->total_size = sizeof(int);
+    downcall->service_name = strdup(service_name);
+    downcall->string_len = strlen(service_name);
+  } 
+  return 0;
+}
+
+/* Initialize upcall data structure. */
+int init_upcall(char *service_name, struct ecall_up *upcall, void *up_ptr)
+{
+  if (up_ptr != NULL) {
+    if (upcall->size1 > 0) {
+      if (upcall->size2 > 0) {
+        upcall->flag = (unsigned long) up_ptr;
+        upcall->bitpattern = (unsigned long) upcall->flag + sizeof(int);
+        upcall->front = 0;
+        upcall->back = 0;
+        upcall->data = (unsigned long)upcall->bitpattern + 
+		sizeof(unsigned long)*upcall->size2;
+        upcall->total_size = upcall->size1;
+        upcall->service_name = strdup(service_name);
+        upcall->string_len = strlen(service_name);
+      } else {
+        upcall->flag = (unsigned long) up_ptr;
+        upcall->bitpattern = 0;
+        upcall->front = (unsigned long) upcall->flag + sizeof(int);
+        upcall->back = (unsigned long) upcall->back + sizeof(int);
+        upcall->total_size = upcall->size1;
+        upcall->service_name = strdup(service_name);
+        upcall->string_len = strlen(service_name);
+      }
+    } else {
+      upcall->flag = 0;
+      upcall->bitpattern = 0;
+      upcall->front = 0;
+      upcall->back = 0;
+      upcall->data = 0;
+      upcall->total_size = 0;
+    }
+  } else {
+    upcall->flag = 0;
+    upcall->bitpattern = 0;
+    upcall->front = 0;
+    upcall->back = 0;
+    upcall->data = 0;
+    upcall->total_size = 0;
+  }
+  return 0;
+}
+
+/* Initialize ECalls. */
+int ECalls_init(char *service_name, struct ecall_down *downcall,
+  struct ecall_up *upcall, int signal, int pid, void *u_handler, 
+  void *k_handler)
+{
+  if (service_name == NULL) return -1;
+
+  upcall->service_name = strdup(service_name);
+  upcall->string_len = strlen(service_name);
+  upcall->signal = signal;
+  upcall->process_id = pid; 
+  upcall->handler_function = u_handler;
+  upcall->kernel_function = k_handler;
+  upcall->kfct_string_len = 0;
+  if (upcall->kernel_function != NULL)
+    upcall->kfct_string_len = strlen(upcall->kernel_function);
+  return 0;
+}
+
+/* Unregister ECalls. */
+int ECalls_unsubscribe(char *service_name) 
+{
+  register_ecall(service_name, 
+    strlen(service_name),NULL, NULL);
+  return 0;
+}
+
+/* Register ECalls. */
+int ECalls_subscribe(char *service_name,
+  struct ecall_down *downcall, void *down_ptr, 
+  struct ecall_up *upcall, void *up_ptr)
+{
+  int id;
+
+  if (service_name == NULL) return -1;
+
+  if (downcall != NULL) 
+    init_downcall(service_name, downcall, down_ptr);
+
+  if (upcall != NULL) 
+    init_upcall(service_name, upcall, up_ptr);
+
+  if ((id = register_ecall(service_name,
+    strlen(service_name),downcall,upcall)) < 0)
+    return -1;
+
+  if (downcall != NULL) { 
+    if (downcall->total_size > 0)
+      downcall->service_id = id;
+  }
+
+  if (upcall != NULL) { 
+    if (upcall->total_size > 0)
+      upcall->service_id = id;
+  }
+
+  return 0;
+}
+
+/* Submit Event. */
+int ECalls_submit_event(struct ecall_down *downcall, void *event, int len,
+	int type)
+{
+  if ((type == DEFERRED) || (type == NORMAL)) {
+    (*(int *)downcall->flag)++;
+  }
+  else if (type == SYSCALL) {
+    do_downcall(downcall, event, len);
+  }
+#ifdef CONFIG_X86
+  else if (type == IMMEDIATE) {
+    (*(int *)downcall->flag)++;
+    fast_do_downcall(downcall, event, len);
+  }
+#endif
+
+  return 0;
+}
+
+/* Download extension code. */
+int ECalls_download(char *hookname, char *parameter1, int parameter2, 
+	int parameter3, char *code)
+{
+  download_code(hookname, parameter1, parameter2, parameter3, code);
+
+  return 0;
+}
+
+#endif /* __ECALLS__H__ */
diff -Naur test-for-latech/include/linux/ecalls-types.h testqf-for-latech/include/linux/ecalls-types.h
--- test-for-latech/include/linux/ecalls-types.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/ecalls-types.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,70 @@
+#ifndef	__ECALLS_TYPES__H__
+#define	__ECALLS_TYPES__H__
+
+#include <sys/syscall.h>
+#include <linux/a.out.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <malloc.h>
+#include <unistd.h>
+
+#define DEF_EVENT_NUM 32
+#define DEF_EVENT_SIZE sizeof(int)
+#define DEF_MEM_SIZE 512
+#define FLAG_ONLY 0
+#define GENERAL_EVENTS 1
+#define PRIORITY_EVENTS 2
+#define NORMAL 0
+#define SYSCALL 1
+#define IMMEDIATE 2
+#define DEFERRED 3
+
+struct ecall_down {
+	int service_id;
+	unsigned long flag;
+	unsigned long bitpattern;
+	unsigned long front;
+	unsigned long back;
+	unsigned long data;
+	char *service_name;
+        int string_len;
+	int total_size;
+	int size1;
+	int size2;
+};
+typedef struct ecall_down *t_downcall_data;
+
+struct ecall_up {
+	int service_id;
+	unsigned long flag;
+	unsigned long bitpattern;
+	unsigned long front;
+	unsigned long back;
+	unsigned long data;
+	char *service_name;
+        int string_len;
+        int kfct_string_len;
+	int total_size;
+	int process_id;
+	int signal;
+    	void *handler_function;
+    	char *kernel_function;
+	int size1;
+	int size2;
+};
+typedef struct ecall_up *t_upcall_data;
+
+extern int ECalls_start(int);
+extern int ECalls_end(struct ecall_down *, struct ecall_up *);
+extern int init_downcall(char *, struct ecall_down *, void *);
+extern int init_upcall(char *, struct ecall_up *, void *);
+extern int ECalls_subscribe(char *, struct ecall_down *, void *,
+		struct ecall_up *, void *);
+extern int ECalls_cancel(struct ecall_down *, struct ecall_up *);
+extern int ECalls_submit_event(struct ecall_down *, void *, int,
+	int);
+extern int ECalls_init(char *, struct ecall_down *,
+  struct ecall_up *, int, int, void *, void *);
+#endif /* __ECALLS_TYPES__H__ */
diff -Naur test-for-latech/include/linux/fastcalls.h testqf-for-latech/include/linux/fastcalls.h
--- test-for-latech/include/linux/fastcalls.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/fastcalls.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,13 @@
+#ifndef	__FASTCALLS__H__
+#define	__FASTCALLS__H__
+
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <errno.h>
+
+_fast_syscall3(int, fast_read,
+	  int, fd,
+	  void *, buffer,
+ 	  int, len);
+
+#endif /* __FASTCALLS__H__ */
diff -Naur test-for-latech/include/linux/libqsocket.h testqf-for-latech/include/linux/libqsocket.h
--- test-for-latech/include/linux/libqsocket.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/libqsocket.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,28 @@
+#include <stdio.h>
+#include <dlfcn.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/syscall.h>
+#include <linux/unistd.h>
+#include <linux/net.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/qos_conf.h>
+#include <errno.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <qsocket.h>
+
+
+int qsocket(int, int, int, struct qos_params *);
+int qclose(int);
+int qchange(int, struct qos_params*);
+int qsendto(int fd, void *buff, size_t len, unsigned int flags,
+			struct sockaddr *addr, int addr_len,
+			struct packet_flags *pflags);
+int qsend(int fd, void *buff, size_t len, unsigned int flags,
+			struct packet_flags *pflags);
+int qinfo(int fd, struct qsocket_info *info);
+int qchannel(int fd, int server);
+int qinit(struct qos_params *params);
diff -Naur test-for-latech/include/linux/netdevice.h testqf-for-latech/include/linux/netdevice.h
--- test-for-latech/include/linux/netdevice.h	2004-06-11 07:40:03.000000000 -0400
+++ testqf-for-latech/include/linux/netdevice.h	2004-06-11 07:47:24.000000000 -0400
@@ -431,6 +431,10 @@
 	/* this will get initialized at each interface type init routine */
 	struct divert_blk	*divert;
 #endif /* CONFIG_NET_DIVERT */
+#ifdef CONFIG_QFABRIC
+	int rte_list;
+	int rte_list_len;
+#endif
 };
 
 
@@ -579,6 +583,9 @@
 #define HAVE_NETIF_RX 1
 extern int		netif_rx(struct sk_buff *skb);
 extern int		dev_ioctl(unsigned int cmd, void *);
+#ifdef CONFIG_QFABRIC
+extern int		dev_ioctl2(unsigned int cmd, void *, int flag);
+#endif
 extern int		dev_change_flags(struct net_device *, unsigned);
 extern void		dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
 
diff -Naur test-for-latech/include/linux/net.h testqf-for-latech/include/linux/net.h
--- test-for-latech/include/linux/net.h	2004-06-11 07:40:06.000000000 -0400
+++ testqf-for-latech/include/linux/net.h	2004-06-11 07:47:24.000000000 -0400
@@ -44,7 +44,9 @@
 #define SYS_GETSOCKOPT	15		/* sys_getsockopt(2)		*/
 #define SYS_SENDMSG	16		/* sys_sendmsg(2)		*/
 #define SYS_RECVMSG	17		/* sys_recvmsg(2)		*/
-
+#ifdef CONFIG_QFABRIC
+#define SYS_RTSOCKET    18		/* sys_rtsocket			*/
+#endif
 
 typedef enum {
   SS_FREE = 0,				/* not allocated		*/
@@ -76,6 +78,12 @@
 
 	short			type;
 	unsigned char		passcred;
+
+#ifdef CONFIG_QFABRIC
+	int 			rt_sock;
+	int			deadline;
+	int 			rt_flags;
+#endif
 };
 
 #define SOCK_INODE(S)	((S)->inode)
@@ -134,8 +142,15 @@
 extern int	sock_unregister(int family);
 extern struct socket *sock_alloc(void);
 extern int	sock_create(int family, int type, int proto, struct socket **);
+#ifdef CONFIG_QFABRIC
+extern int	make_rt_sock(struct socket *);
+#endif
 extern void	sock_release(struct socket *);
 extern int   	sock_sendmsg(struct socket *, struct msghdr *m, int len);
+#ifdef CONFIG_QFABRIC
+extern int   	rt_sock_sendmsg(struct socket *, struct msghdr *m, int len,
+	int deadline, int flags);
+#endif
 extern int	sock_recvmsg(struct socket *, struct msghdr *m, int len, int flags);
 extern int	sock_readv_writev(int type, struct inode * inode, struct file * file,
 				  const struct iovec * iov, long count, long size);
diff -Naur test-for-latech/include/linux/pkt_cls.h testqf-for-latech/include/linux/pkt_cls.h
--- test-for-latech/include/linux/pkt_cls.h	2004-06-11 07:40:08.000000000 -0400
+++ testqf-for-latech/include/linux/pkt_cls.h	2004-06-11 07:47:28.000000000 -0400
@@ -158,4 +158,16 @@
 
 #define TCA_TCINDEX_MAX        TCA_TCINDEX_POLICE
 
+enum
+{
+	TCA_SOCKET_UNSPEC,
+	TCA_SOCKET_CLASSID,
+	TCA_SOCKET_PROCESSID,
+	TCA_SOCKET_FDID,
+	TCA_SOCKET_INODEID,
+	TCA_SOCKET_POLICE,
+};
+
+#define TCA_SOCKET_MAX TCA_SOCKET_POLICE
+
 #endif
diff -Naur test-for-latech/include/linux/pkt_sched.h testqf-for-latech/include/linux/pkt_sched.h
--- test-for-latech/include/linux/pkt_sched.h	2004-06-11 07:40:08.000000000 -0400
+++ testqf-for-latech/include/linux/pkt_sched.h	2004-06-11 07:47:28.000000000 -0400
@@ -93,6 +93,26 @@
 	__u32	limit;	/* Queue length: bytes for bfifo, packets for pfifo */
 };
 
+/* DWCS section */
+struct tc_dwcs_qopt
+{
+	__u32 limit;
+};
+
+enum
+{
+	TCA_DWCS_UNSPEC,
+	TCA_DWCS_DEADLINE,
+	TCA_DWCS_OLN,
+	TCA_DWCS_OLD,
+#define DWCS_FLAG1	0x00000002
+#define DWCS_FLAG2	0x00000004
+	TCA_DWCS_FLAGS,
+	TCA_DWCS_POLICE,
+};
+
+#define TCA_DWCS_MAX TCA_DWCS_POLICE
+
 /* PRIO section */
 
 #define TCQ_PRIO_BANDS	16
diff -Naur test-for-latech/include/linux/qfabric.h testqf-for-latech/include/linux/qfabric.h
--- test-for-latech/include/linux/qfabric.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/qfabric.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,75 @@
+#ifndef	__QFABRIC__H__
+#define	__QFABRIC__H__
+
+#ifdef __KERNEL__
+#include <linux/socket.h>
+
+extern struct socket *look_up_pseudofd(int fd, struct socket *fd_array[]);
+extern int get_pseudofd(struct socket *sock, struct socket *fd_array[]);
+extern int release_pseudofd(int fd, struct socket *fd_array[]);
+extern void initialize_qfabric(void);
+
+#else
+
+#ifndef CONFIG_QFABRIC
+#define CONFIG_QFABRIC
+#endif
+
+#include <sys/syscall.h>
+#include <linux/a.out.h>
+#include <linux/module.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+extern int query_module(const char *, int, void *, size_t, size_t);
+extern int qfabric_config(char *app_id, char *group_id);
+
+/* system call: kecho_load. */
+_syscall2(int, kecho_load,
+          char *, module_name,
+	  int, argument);
+
+_syscall1(int, KECho_syscall_echo,
+          void *, echo_data);
+
+#ifdef CONFIG_X86
+_fast_syscall1(int, fast_KECho_syscall_echo,
+          void *, echo_data);
+#endif
+
+_syscall1(int, KECho_syscall_cm,
+          void *, cm_data);
+
+#ifdef CONFIG_X86
+_fast_syscall1(int, fast_KECho_syscall_cm,
+          void *, cm_data);
+#endif
+
+_syscall1(int, KECho_syscall_cg,
+          void *, cm_data);
+
+#ifdef CONFIG_X86
+_fast_syscall1(int, fast_KECho_syscall_cg,
+          void *, cm_data);
+#endif
+
+_syscall1(int, KECho_syscall_atl,
+          void *, atl_data);
+
+#ifdef CONFIG_X86
+_fast_syscall1(int, fast_KECho_syscall_atl,
+          void *, atl_data);
+#endif
+
+_syscall2(int, qos_configure,
+	  char *, app_id,
+	  char *, group_id);
+
+#endif /* __KERNEL__ */
+#endif /* __QFABRIC__H__ */
diff -Naur test-for-latech/include/linux/qf_api.h testqf-for-latech/include/linux/qf_api.h
--- test-for-latech/include/linux/qf_api.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/qf_api.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,24 @@
+#ifndef	__QFAPI__H__
+#define	__QFAPI__H__
+
+#include <sys/syscall.h>
+#include <linux/a.out.h>
+#include <linux/module.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+_syscall2(int, change_clock,
+	  int, flag,
+	  int, value);
+
+_syscall2(int, qos_configure,
+	  char *, app_id,
+	  char *, group_id);
+
+#endif 
diff -Naur test-for-latech/include/linux/qos_conf.h testqf-for-latech/include/linux/qos_conf.h
--- test-for-latech/include/linux/qos_conf.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/qos_conf.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,63 @@
+/*File          :qos_conf.h
+ *Written by    :Rabin Patra & Vibha Rathi
+ *Date          :12 July 2001
+ *
+ *Definations for:
+ *1.struct qos_request
+ *2.struct qos_msg
+ *3.struct qos_syscall_msg
+ */
+
+
+#ifndef __QOS_CONF_H__
+#define __QOS_CONF_H__ 1
+
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#define QOS_QDISC_ADD           10
+#define QOS_QDISC_CHANGE        11
+#define QOS_QDISC_DELETE        12
+
+#define QOS_CLASS_ADD           14
+#define QOS_CLASS_CHANGE        15
+#define QOS_CLASS_DELETE        16
+
+#define QOS_FILTER_ADD          18
+#define QOS_FILTER_CHANGE       19
+#define QOS_FILTER_DELETE       20
+
+#define	QOS_MAX_MSG		16
+
+#define QOS_MAX_ATTRS		128
+
+struct qos_request {
+        struct nlmsghdr         n;
+        struct tcmsg            t;
+        char                    buff[4096];
+};
+
+struct qos_msg{
+        struct qos_request req;
+        int action;
+};
+
+struct qos_syscall_msg {
+        struct qos_msg         *msglist;
+        int                     no_of_msgs;
+};
+
+/*qos_get_all_args:
+ *function to copy from user to kernel space
+ */
+extern int 	qos_get_all_args(struct qos_syscall_msg *,struct qos_syscall_msg *);
+
+/*qos_do_conf:
+ *function which does the qos_configuration for one nessage
+ */
+extern int 	qos_do_conf(struct qos_msg *);
+
+
+
+
+#endif
diff -Naur test-for-latech/include/linux/qsocket.h testqf-for-latech/include/linux/qsocket.h
--- test-for-latech/include/linux/qsocket.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/qsocket.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,177 @@
+/*File          :qsocket.c
+ *Written by    :Rabin Patra & Vibha Rathi
+ *Date          :12 July 2001
+ *
+ *Definations for
+ *1.struct qos_param
+ */
+
+#include <linux/netdevice.h>
+//#include <asm/types.h>
+//#include <linux/pkt_sched.h>
+//#include <net/pkt_cls.h>
+
+#ifndef __QSOCKET_H__
+#define __QSOCKET_H__ 
+
+/*
+ * Only SYS_QSEND is used actually
+ */
+
+#define SYS_QSOCKET     	1               /* sys_qsocket(2)      */
+#define SYS_QBIND        	2               /* sys_qbind(2)        */
+#define SYS_QCONNECT     	3               /* sys_qconnect(2)     */
+#define SYS_QLISTEN      	4               /* sys_qlisten(2)      */
+#define SYS_QACCEPT      	5               /* sys_qaccept(2)      */
+#define SYS_QGETSOCKNAME 	6               /* sys_qgetsockname(2) */
+#define SYS_QGETPEERNAME 	7               /* sys_qgetpeername(2) */
+#define SYS_QSOCKETPAIR 	8               /* sys_qsocketpair(2)  */
+#define SYS_QSEND     		9               /* sys_qsend(2)        */
+#define SYS_QSHUTDOWN 		10
+#define SYS_QCHANGE		11
+#define SYS_QSENDTO		12
+#define SYS_QINFO		16				
+#define SYS_QRECVMSG	 	17		/* sys_qrecvmesg	*/
+#define SYS_QINIT		20
+
+#define	MAX_QOS_PARAM_SIZE	128
+
+struct qos_param{
+	void * 	data;
+	int 	len;
+}; 
+
+#ifndef IFNAMSIZ
+#define IFNAMSIZ 16
+#endif
+
+#ifndef DWCS_VIOLATION
+/* --RW-- */
+#define DWCS_VIOLATION  	0x00000001 /* Window-constraint violation. */
+#define DWCS_WORK_CONS		0x00000002 /* Does task support work-conservation? */
+#define DWCS_NON_DROPPABLE 	0x00000008 /* Set when process is non-preemptive */
+#define DWCS_NON_PREEMPTIVE 0x00000004		/* Set when process is non-preemptive */
+#endif
+
+#define APP_MAX 128
+
+#ifdef NEW_VERSION
+
+struct qos_params
+{
+	int qos_on;
+	int disable;
+	char dev[IFNAMSIZ];
+	char name[IFNAMSIZ];
+	char *app_id;
+	void *attributes;
+};
+
+#else
+
+struct qos_params
+{
+	int qos_on;
+	int disable;
+	char dev[IFNAMSIZ];
+	char name[IFNAMSIZ];
+	char *app_id;
+	void *attributes;
+	int ipg;
+	int old;
+	int oln;
+	int flags; 		/*work conserving or non work conserving*/
+	int attribute; 	/*is the stream droppable or not?*/
+	int server;
+	int use_cpu;
+	int use_net;
+};
+
+#endif
+
+struct packet_flags
+{
+	int drop_flag;
+	int urgent_flag;
+	int fragments;
+};
+
+
+struct qsocket_info
+{
+	unsigned int input_qlen;
+	unsigned int output_qlen;
+	unsigned int missed_deadlines;
+	unsigned int cpu_time;
+	unsigned int delay_jif;
+	unsigned int sent_packets;
+};
+
+#ifdef __KERNEL__
+
+struct qops
+{
+	char id[IFNAMSIZ];
+	int (*create)(struct net_device *dev, void *attributes);
+	int (*add_stream)(struct Qdisc *q, void *attributes, int sock_fd);
+	int (*remove_stream)(struct Qdisc *q, int sock_fd);
+	int (*change_stream)(struct Qdisc *q, void *attributes, int i_ino);
+	int (*get_stream_info)(struct Qdisc *q, int i_ino, void *info);
+};
+
+struct qop_list
+{
+	struct qops *op;
+	struct qop_list *next;
+};
+
+extern struct qop_list *qop_base;
+
+static inline void register_qops(struct qops *ops)
+{
+	/*add to list*/
+	struct qop_list *temp = kmalloc(sizeof(struct qop_list), GFP_KERNEL);
+
+	if(ops == NULL)
+		printk("null passed damint\n");
+
+	temp->op = ops;
+	
+	temp->next = qop_base;
+	qop_base = temp;
+
+	
+	printk(KERN_INFO "Registering qops = %s\n", qop_base->op->id);
+
+}
+
+
+static inline void unregister_qops(struct qops *ops)
+{
+	/*remove from list*/
+}
+
+struct socket_head
+{
+  struct socket_filter *ht[256];       /* a hash table for socket_filters */
+};
+
+
+struct socket_filter
+{
+  struct socket_filter	*next;
+  u32			id;
+  u32                   pid;          /* the pid, and               */
+  unsigned long         fd;           /* the fd to monitor for; or  */
+  unsigned long         i_ino;        /* the inode to monitor for   */
+  struct tcf_result	res;
+#ifdef CONFIG_NET_CLS_POLICE
+  struct tcf_police	*police;
+#endif
+};
+
+
+#endif
+
+#endif
+
diff -Naur test-for-latech/include/linux/sch_dwcs.h testqf-for-latech/include/linux/sch_dwcs.h
--- test-for-latech/include/linux/sch_dwcs.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/linux/sch_dwcs.h	2004-06-11 07:47:29.000000000 -0400
@@ -0,0 +1,161 @@
+/* 
+ * net/sched/sch_dwcs.h   DWCS algorithm scheduler.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Gregory Losik <gregor@cc.gatech.edu>
+ *              Richard West <west@cc.gatech.edu>
+ *              Christian Poellabauer <chris@cc.gatech.edu>
+ *
+ * Changes:     J.D. Hollis <jdhollis@cc.gatech.edu>
+ *              cleaned up the formatting and added some comments
+ *
+ */
+ 
+
+#define TRUE	1
+#define FALSE	0
+#define MAX_CONNS       255    // GL: Technically it should be 2^16 but lets risk it...
+
+#define DWCS_VIOLATION  	0x00000001 			/* Window-constraint violation. */
+#define DWCS_WORK_CONS		0x00000002 			/* Does task support work-conservation? */
+#define DWCS_NON_DROPPABLE	0x00000008 	
+
+
+
+#include <linux/notifier.h>
+
+
+/* Scheduler attributes. Not all members are necessary for all scheduling policies. */
+typedef struct dwcs_class_attr {
+	// int cd;                    /* Class descriptor. */
+	// unsigned cnt;              /* Number pkts queued for this class. */
+
+	/* JDH: w, s, and f might not be needed as we've got a DWCS qdisc now */
+	double w;                     /* Weight. (For SFQ) */
+	double s;                     /* Start tag. (For SFQ) */
+	double f;                     /* Finish tag. (For SFQ) */
+
+	/* these are the actual, user-definable attributes */
+	long deadline;
+	long readytime;/* ok this requires a little explanation
+					  this is to maintain a specific throughput from the class
+					  thus a stream with packets to send, on an idle network
+					  won't send packets until the ready time has elasped for the 
+					  stream
+				   */
+
+	unsigned long ipg;            /* Inter-packet/msg gap. */
+	unsigned oln;                 /* Original loss numerator. */
+	unsigned old;                 /* Original loss denominator. */
+	
+	/* statistics */
+	unsigned cln;                 /* Current loss numerator. */
+	unsigned cld;                 /* Current loss denominator. */
+	long clt;                     /* Current loss tolerance. */
+	unsigned late;                /* Stats - number late pkts. */
+	unsigned sent;                /* Stats - number pkts sent. */
+	unsigned violations;          /* Stats - number loss tolerance violations. */
+	unsigned long delay;          /* Cumulative delay for this class. */
+	int t;                        /* Simulated time to process pkt. */
+	unsigned window;              /* Packet window size. */
+	unsigned wlate;               /* Count of late pkts in a time window. */
+	unsigned long bytes;          /* Total bytes serviced for this class. */
+	// long start_time;              /* Real-time this class started. */
+	
+	/* GL: since there is no per packet flag, it needs to be per stream... */
+	int droppable;                /* TRUE if packets may be dropped. */
+	unsigned int flags;           /* Flags as specified by user */
+} dwcs_class_attr_t;
+
+
+/* Deadline heap attributes. */
+struct dl_heap {
+	long deadline;                /* Packet deadline. */
+	// int stream;                   /* Stream number. */
+	u32 stream;                   /* Stream number. */
+};
+
+struct sl_heap
+{
+	long readytime;
+	u32 stream;
+};
+
+
+/* Loss tolerance heap attributes. */
+struct lt_heap {
+	int stream;                   /* Stream number. */
+	long deadline;                /* Packet deadline. */
+	int cln;                      /* Current loss numerator. */
+	int cld;                      /* Current loss denominator. */
+	int oln;                      /* Original loss numerator. */
+	int wlate;                    /* Late packets in window. */
+	unsigned long arr_time;       /* Packet arrival time. */
+	long clt;                     /* Current loss tolerance. */
+};
+
+struct dwcs_sched_data;
+ 
+struct dwcs_class
+{
+  struct dwcs_class           *next;          /* hash table link */
+  struct dwcs_class           *next_alive;    /* next class with backlog in this priority band */
+
+  /* Parameters */
+  u32                         classid;        /* the major:minor class id */
+  unsigned char		      priority;       /* class priority */
+  unsigned int		      *socket_num;    /* to be a socket number.... */
+#ifdef CONFIG_NET_CLS_POLICE
+  unsigned char	              police;
+#endif
+  struct Qdisc                *qdisc;         /* Ptr to DWCS discipline that class belongs to */
+  struct Qdisc                *q;             /* Elementary queueing discipline */
+  
+  /* Variables */
+  struct tcf_proto            *filter_list;
+  int		              refcnt;         /* used by _get() and _put() reference tracking */
+  int                         filters;        /* for keeping track the number of filters */
+  struct tc_stats             stats;          /* ??? used by _NET_ESTIMATOR */
+
+  /* DWCS  specific parameters */
+  struct dwcs_class_attr      attr;         /* Low level attributes of a class */
+};
+
+
+
+
+struct dwcs_sched_data
+{
+	struct dwcs_class         *classes[ 16 ]; /* Hash table of all classes. This is where all new calsses get inserted in */
+	struct dwcs_class         *link;           /* Default class for case when filters don't match */
+	unsigned                  classcount;     /* the counder for total # of classes; q->classes[i] has the actual list */
+
+
+	/* DWCS specific attributes */
+	struct dwcs_class         	*next_class;    /* next class from which we will try to dequeue (to be deleted) */
+
+	struct lt_heap          	ltheap[MAX_CONNS];    /* Loss-Tolerance Heap */
+	int                       	ltheap_size;
+	struct dl_heap            	dlheap[MAX_CONNS];    /* Deadline Heap */
+	int                       	dlheap_size;
+	struct sl_heap				slheap[MAX_CONNS];
+	int 						slheap_size;
+	struct timer_list 			wd_timer;	/* Watchdog timer */	
+	
+
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *ent;
+#endif
+
+#ifdef CONFIG_NET_CLS_POLICE
+	struct dwcs_class	    *rx_class;
+#endif
+
+};
+
+
+ 
diff -Naur test-for-latech/include/linux/sched.h testqf-for-latech/include/linux/sched.h
--- test-for-latech/include/linux/sched.h	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/include/linux/sched.h	2004-06-11 07:47:24.000000000 -0400
@@ -46,6 +46,10 @@
 
 #define CLONE_SIGNAL	(CLONE_SIGHAND | CLONE_THREAD)
 
+#ifdef CONFIG_QFABRIC
+#define MAX_UTILIZATION 1000000
+#endif
+
 /*
  * These are the constant used to fake the fixed-point load-average
  * counting. Some notes:
@@ -119,13 +123,56 @@
 #define SCHED_FIFO		1
 #define SCHED_RR		2
 
+#ifdef CONFIG_DWCS
+/* --RW-- */
+#define SCHED_DWCS		3
+#endif
+
+/* --CP-- */
+#ifdef CONFIG_QFABRIC
+#define SCHED_UPCALL_OTHER	4
+#define SCHED_UPCALL_FIFO	5
+#define SCHED_UPCALL_RR		6
+extern struct wait_queue *global_wait_queue;
+extern int upcall_sched_active;
+extern int ECalls_current_flag;
+extern struct task_struct *ECalls_current;
+#endif
+
+#ifdef CONFIG_DWCS
+/* --RW-- */
+#define DWCS_VIOLATION  0x00000001 /* Window-constraint violation. */
+#define DWCS_WORK_CONS	0x00000002 /* Does task support work-conservation? */
+#define DWCS_NON_PREEMPTIVE 0x00000004 /* Set when process is non-preemptive */
+#endif
+
 /*
  * This is an additional bit set when we want to
  * yield the CPU for one re-schedule..
  */
 #define SCHED_YIELD		0x10
 
-struct sched_param {
+#ifdef CONFIG_QFABRIC
+#define NR_TASKS 512
+#define MAX_FDS 1024
+#endif
+
+#if defined(CONFIG_DWCS)||defined(CONFIG_QFABRIC)
+struct dwcs_sched_param {
+	int pid;		/* --FS-- The pid for which ioctl is done. */
+	int policy;		/* --FS-- The selected policy, -1 for unset. */
+  int sched_priority;
+  unsigned long period;		/* --RW-- Request period. Used for setting
+				          DWCS deadlines. */
+  unsigned int own;		/* --RW-- Original window numerator. */
+  unsigned int owd;		/* --RW-- Original window denominator. */
+  unsigned int flags;		/* --RW-- Right now, work-conserving or not. */
+  unsigned long service_time;	/* --RW-- Time to service a process 
+				          every period. */
+};
+#endif
+
+struct sched_param{
 	int sched_priority;
 };
 
@@ -284,6 +331,70 @@
 extern struct user_struct root_user;
 #define INIT_USER (&root_user)
 
+/* --RW-- */
+#ifdef CONFIG_DWCS
+struct dwcs_struct {
+  int cd;			/* Class descriptor. */
+  unsigned long deadline;	
+  unsigned long period;		/* Request period. */
+  unsigned int own;		/* Original window numerator. */
+  unsigned int owd;		/* Original window denominator. */
+  unsigned int cwn;		/* Current window numerator. */
+  unsigned int cwd;		/* Current window denominator. */
+  unsigned int flags;		/* Bitwise flags for future work. */
+  unsigned long ready_time;	/* Time when task can be serviced. */
+  unsigned long service_time;	/* Time to service a process every period. */
+  unsigned long time_serviced;	/* How much time process has been serviced
+				 * so far, in the current processing period.
+				 */
+   /* Energy saving attributes */
+    int cpu_speedup;              /* Describes how much the clockrate can be lowered due
+				     to not max. utilization of the processor scaled by 
+				     100, e.g. if this proc. can be run at half 
+				     clockspeed it is 200 (clockrate * 100 / 
+				     cpu_speedup) */
+
+  /* Statistical attributes. */
+  unsigned int wlate;		/* Count of late tasks in a time window. */
+  unsigned long late;		/* Cumulative missed deadlines. */
+  unsigned long on_time;	/* Cumulative met deadlines. */
+  unsigned long violations;	/* Cumulative window-constraint violations. */
+};
+#endif
+
+/* --RW-- */
+#ifdef CONFIG_DWCS
+#define INIT_DWCS {			\
+		0,			\
+		(unsigned long)(-1),	\
+		(unsigned long)(-1),	\
+		1,			\
+		10,			\
+		1,			\
+		10, 			\
+		DWCS_WORK_CONS,		\
+		0,			\
+		1,			\
+		0,			\
+		0,			\
+		0,			\
+		0,			\
+		0 }
+#endif
+/* End of --RW-- */
+
+/* Artemis */
+#ifdef CONFIG_QFABRIC
+struct qfabric_struct {
+	void *fdqfabric;
+	int orig_weight;
+	int weight;
+	int sw_pending;
+	unsigned long sleep_queue;
+	wait_queue_head_t kecho_queue;
+};
+#endif
+
 struct task_struct {
 	/*
 	 * offsets of these are hardcoded elsewhere - touch with care
@@ -409,6 +520,10 @@
 	int (*notifier)(void *priv);
 	void *notifier_data;
 	sigset_t *notifier_mask;
+
+#ifdef CONFIG_DWCS
+	struct dwcs_struct *dwcs_params;  /* --RW-- */
+#endif
 	
 /* Thread group tracking */
    	u32 parent_exec_id;
@@ -418,6 +533,17 @@
 
 /* journalling filesystem info */
 	void *journal_info;
+
+/* Artemis */
+#ifdef CONFIG_QFABRIC
+	struct qfabric_struct *qfabric;
+	int kthread;
+	int suser_flag;
+	int uaccess_flag;
+	int ecalls_flag;
+/* Useful Measurement Stuff */
+	long syscall_counter;
+#endif
 };
 
 /*
@@ -470,6 +596,7 @@
  *  INIT_TASK is used to set up the first task table, touch at
  * your own risk!. Base=0, limit=0x1fffff (=2MB)
  */
+#ifdef CONFIG_DWCS
 #define INIT_TASK(tsk)	\
 {									\
     state:		0,						\
@@ -509,10 +636,54 @@
     sig:		&init_signals,					\
     pending:		{ NULL, &tsk.pending.head, {{0}}},		\
     blocked:		{{0}},						\
+    dwcs_params:        &init_dwcs,					\
     alloc_lock:		SPIN_LOCK_UNLOCKED,				\
     journal_info:	NULL,						\
 }
-
+#else
+#define INIT_TASK(tsk)	\
+{									\
+    state:		0,						\
+    flags:		0,						\
+    sigpending:		0,						\
+    addr_limit:		KERNEL_DS,					\
+    exec_domain:	&default_exec_domain,				\
+    lock_depth:		-1,						\
+    counter:		DEF_COUNTER,					\
+    nice:		DEF_NICE,					\
+    policy:		SCHED_OTHER,					\
+    mm:			NULL,						\
+    active_mm:		&init_mm,					\
+    cpus_runnable:	-1,						\
+    cpus_allowed:	-1,						\
+    run_list:		LIST_HEAD_INIT(tsk.run_list),			\
+    next_task:		&tsk,						\
+    prev_task:		&tsk,						\
+    p_opptr:		&tsk,						\
+    p_pptr:		&tsk,						\
+    thread_group:	LIST_HEAD_INIT(tsk.thread_group),		\
+    wait_chldexit:	__WAIT_QUEUE_HEAD_INITIALIZER(tsk.wait_chldexit),\
+    real_timer:		{						\
+	function:		it_real_fn				\
+    },									\
+    cap_effective:	CAP_INIT_EFF_SET,				\
+    cap_inheritable:	CAP_INIT_INH_SET,				\
+    cap_permitted:	CAP_FULL_SET,					\
+    keep_capabilities:	0,						\
+    rlim:		INIT_RLIMITS,					\
+    user:		INIT_USER,					\
+    comm:		"swapper",					\
+    thread:		INIT_THREAD,					\
+    fs:			&init_fs,					\
+    files:		&init_files,					\
+    sigmask_lock:	SPIN_LOCK_UNLOCKED,				\
+    sig:		&init_signals,					\
+    pending:		{ NULL, &tsk.pending.head, {{0}}},		\
+    blocked:		{{0}},						\
+    alloc_lock:		SPIN_LOCK_UNLOCKED,				\
+    journal_info:	NULL,						\
+}
+#endif
 
 #ifndef INIT_TASK_SIZE
 # define INIT_TASK_SIZE	2048*sizeof(long)
@@ -718,6 +889,9 @@
  */
 static inline int suser(void)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->suser_flag == 1) return 1;
+#endif
 	if (!issecure(SECURE_NOROOT) && current->euid == 0) { 
 		current->flags |= PF_SUPERPRIV;
 		return 1;
@@ -727,6 +901,9 @@
 
 static inline int fsuser(void)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->suser_flag == 1) return 1;
+#endif
 	if (!issecure(SECURE_NOROOT) && current->fsuid == 0) {
 		current->flags |= PF_SUPERPRIV;
 		return 1;
@@ -742,6 +919,9 @@
 
 static inline int capable(int cap)
 {
+#ifdef CONFIG_QFABRIC
+	if (current->suser_flag == 1) return 1;
+#endif
 #if 1 /* ok now */
 	if (cap_raised(current->cap_effective, cap))
 #else
@@ -884,6 +1064,25 @@
 #define for_each_thread(task) \
 	for (task = next_thread(current) ; task != current ; task = next_thread(task))
 
+
+
+/*
+ * GANEV: This typedef and the external aligned_data symbol declaration
+ *        are needed so that the "aligned_data" will be visible outside
+ *        the kernel to loadable schedulers like DWCS.
+ */
+#ifdef CONFIG_DWCS
+typedef union {
+	struct schedule_data {
+		struct task_struct * curr;
+		cycles_t last_schedule;
+	} schedule_data;
+	char __pad [SMP_CACHE_BYTES];
+} aligned_data_t;
+
+extern aligned_data_t aligned_data[NR_CPUS];
+#endif
+
 #define next_thread(p) \
 	list_entry((p)->thread_group.next, struct task_struct, thread_group)
 
@@ -945,5 +1144,4 @@
 }
 
 #endif /* __KERNEL__ */
-
 #endif
diff -Naur test-for-latech/include/linux/skbuff.h testqf-for-latech/include/linux/skbuff.h
--- test-for-latech/include/linux/skbuff.h	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/include/linux/skbuff.h	2004-06-11 07:47:24.000000000 -0400
@@ -193,6 +193,10 @@
 	unsigned char	*tail;			/* Tail pointer					*/
 	unsigned char 	*end;			/* End pointer					*/
 
+	int 		drop_flag;
+	int 		urgent_flag;
+	int		fragments;
+
 	void 		(*destructor)(struct sk_buff *);	/* Destruct function		*/
 #ifdef CONFIG_NETFILTER
 	/* Can be used for communication between hooks. */
@@ -215,6 +219,10 @@
 #ifdef CONFIG_NET_SCHED
        __u32           tc_index;               /* traffic control index */
 #endif
+#ifdef CONFIG_QFABRIC
+	int deadline;
+	int flags;
+#endif
 };
 
 #define SK_WMEM_MAX	65535
diff -Naur test-for-latech/include/linux/sys.h testqf-for-latech/include/linux/sys.h
--- test-for-latech/include/linux/sys.h	2004-06-11 07:40:04.000000000 -0400
+++ testqf-for-latech/include/linux/sys.h	2004-06-11 07:47:24.000000000 -0400
@@ -4,7 +4,7 @@
 /*
  * system call entry points ... but not all are defined
  */
-#define NR_syscalls 256
+#define NR_syscalls 280
 
 /*
  * These are system calls that will be removed at some time
diff -Naur test-for-latech/include/net/bpf.h testqf-for-latech/include/net/bpf.h
--- test-for-latech/include/net/bpf.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/bpf.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,463 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence 
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *      This product includes software developed by the University of
+ *      California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *      @(#)bpf.h       7.1 (Berkeley) 5/7/91
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/bpf/net/Attic/bpf.h,v 1.52.2.6 2002/06/07 04:31:57 guy Exp $ (LBL)
+ */
+
+#ifndef BPF_MAJOR_VERSION
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* BSD style release date */
+#define BPF_RELEASE 199606
+
+typedef	int bpf_int32;
+typedef	u_int bpf_u_int32;
+
+/*
+ * Alignment macros.  BPF_WORDALIGN rounds up to the next 
+ * even multiple of BPF_ALIGNMENT. 
+ */
+#ifndef __NetBSD__
+#define BPF_ALIGNMENT sizeof(bpf_int32)
+#else
+#define BPF_ALIGNMENT sizeof(long)
+#endif
+#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
+
+#define BPF_MAXINSNS 512
+#define BPF_MAXBUFSIZE 0x8000
+#define BPF_MINBUFSIZE 32
+
+/*
+ *  Structure for BIOCSETF.
+ */
+struct bpf_program {
+	u_int bf_len;
+	struct bpf_insn *bf_insns;
+};
+ 
+/*
+ * Struct returned by BIOCGSTATS.
+ */
+struct bpf_stat {
+	u_int bs_recv;		/* number of packets received */
+	u_int bs_drop;		/* number of packets dropped */
+};
+
+/*
+ * Struct return by BIOCVERSION.  This represents the version number of 
+ * the filter language described by the instruction encodings below.
+ * bpf understands a program iff kernel_major == filter_major &&
+ * kernel_minor >= filter_minor, that is, if the value returned by the
+ * running kernel has the same major number and a minor number equal
+ * equal to or less than the filter being downloaded.  Otherwise, the
+ * results are undefined, meaning an error may be returned or packets
+ * may be accepted haphazardly.
+ * It has nothing to do with the source code version.
+ */
+struct bpf_version {
+	u_short bv_major;
+	u_short bv_minor;
+};
+/* Current version number of filter architecture. */
+#define BPF_MAJOR_VERSION 1
+#define BPF_MINOR_VERSION 1
+
+/*
+ * BPF ioctls
+ *
+ * The first set is for compatibility with Sun's pcc style
+ * header files.  If your using gcc, we assume that you
+ * have run fixincludes so the latter set should work.
+ */
+#if (defined(sun) || defined(ibm032)) && !defined(__GNUC__)
+#define	BIOCGBLEN	_IOR(B,102, u_int)
+#define	BIOCSBLEN	_IOWR(B,102, u_int)
+#define	BIOCSETF	_IOW(B,103, struct bpf_program)
+#define	BIOCFLUSH	_IO(B,104)
+#define BIOCPROMISC	_IO(B,105)
+#define	BIOCGDLT	_IOR(B,106, u_int)
+#define BIOCGETIF	_IOR(B,107, struct ifreq)
+#define BIOCSETIF	_IOW(B,108, struct ifreq)
+#define BIOCSRTIMEOUT	_IOW(B,109, struct timeval)
+#define BIOCGRTIMEOUT	_IOR(B,110, struct timeval)
+#define BIOCGSTATS	_IOR(B,111, struct bpf_stat)
+#define BIOCIMMEDIATE	_IOW(B,112, u_int)
+#define BIOCVERSION	_IOR(B,113, struct bpf_version)
+#define BIOCSTCPF	_IOW(B,114, struct bpf_program)
+#define BIOCSUDPF	_IOW(B,115, struct bpf_program)
+#else
+#define	BIOCGBLEN	_IOR('B',102, u_int)
+#define	BIOCSBLEN	_IOWR('B',102, u_int)
+#define	BIOCSETF	_IOW('B',103, struct bpf_program)
+#define	BIOCFLUSH	_IO('B',104)
+#define BIOCPROMISC	_IO('B',105)
+#define	BIOCGDLT	_IOR('B',106, u_int)
+#define BIOCGETIF	_IOR('B',107, struct ifreq)
+#define BIOCSETIF	_IOW('B',108, struct ifreq)
+#define BIOCSRTIMEOUT	_IOW('B',109, struct timeval)
+#define BIOCGRTIMEOUT	_IOR('B',110, struct timeval)
+#define BIOCGSTATS	_IOR('B',111, struct bpf_stat)
+#define BIOCIMMEDIATE	_IOW('B',112, u_int)
+#define BIOCVERSION	_IOR('B',113, struct bpf_version)
+#define BIOCSTCPF	_IOW('B',114, struct bpf_program)
+#define BIOCSUDPF	_IOW('B',115, struct bpf_program)
+#endif
+
+/*
+ * Structure prepended to each packet.
+ */
+struct bpf_hdr {
+	struct timeval	bh_tstamp;	/* time stamp */
+	bpf_u_int32	bh_caplen;	/* length of captured portion */
+	bpf_u_int32	bh_datalen;	/* original length of packet */
+	u_short		bh_hdrlen;	/* length of bpf header (this struct
+					   plus alignment padding) */
+};
+/*
+ * Because the structure above is not a multiple of 4 bytes, some compilers
+ * will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
+ * Only the kernel needs to know about it; applications use bh_hdrlen.
+ */
+#if defined(KERNEL) || defined(_KERNEL)
+#define SIZEOF_BPF_HDR 18
+#endif
+
+/*
+ * Data-link level type codes.
+ */
+
+/*
+ * These are the types that are the same on all platforms; on other
+ * platforms, a <net/bpf.h> should be supplied that defines the additional
+ * DLT_* codes appropriately for that platform (the BSDs, for example,
+ * should not just pick up this version of "bpf.h"; they should also define
+ * the additional DLT_* codes used by their kernels, as well as the values
+ * defined here - and, if the values they use for particular DLT_ types
+ * differ from those here, they should use their values, not the ones
+ * here).
+ */
+#define DLT_NULL	0	/* no link-layer encapsulation */
+#define DLT_EN10MB	1	/* Ethernet (10Mb) */
+#define DLT_EN3MB	2	/* Experimental Ethernet (3Mb) */
+#define DLT_AX25	3	/* Amateur Radio AX.25 */
+#define DLT_PRONET	4	/* Proteon ProNET Token Ring */
+#define DLT_CHAOS	5	/* Chaos */
+#define DLT_IEEE802	6	/* IEEE 802 Networks */
+#define DLT_ARCNET	7	/* ARCNET */
+#define DLT_SLIP	8	/* Serial Line IP */
+#define DLT_PPP		9	/* Point-to-point Protocol */
+#define DLT_FDDI	10	/* FDDI */
+
+/*
+ * These are values from the traditional libpcap "bpf.h".
+ * Ports of this to particular platforms should replace these definitions
+ * with the ones appropriate to that platform, if the values are
+ * different on that platform.
+ */
+#define DLT_ATM_RFC1483	11	/* LLC/SNAP encapsulated atm */
+#define DLT_RAW		12	/* raw IP */
+
+/*
+ * These are values from BSD/OS's "bpf.h".
+ * These are not the same as the values from the traditional libpcap
+ * "bpf.h"; however, these values shouldn't be generated by any
+ * OS other than BSD/OS, so the correct values to use here are the
+ * BSD/OS values.
+ *
+ * Platforms that have already assigned these values to other
+ * DLT_ codes, however, should give these codes the values
+ * from that platform, so that programs that use these codes will
+ * continue to compile - even though they won't correctly read
+ * files of these types.
+ */
+#ifdef __NetBSD__
+#ifndef DLT_SLIP_BSDOS
+#define DLT_SLIP_BSDOS	13	/* BSD/OS Serial Line IP */
+#define DLT_PPP_BSDOS	14	/* BSD/OS Point-to-point Protocol */
+#endif
+#else
+#define DLT_SLIP_BSDOS	15	/* BSD/OS Serial Line IP */
+#define DLT_PPP_BSDOS	16	/* BSD/OS Point-to-point Protocol */
+#endif
+
+#define DLT_ATM_CLIP	19	/* Linux Classical-IP over ATM */
+
+/*
+ * These values are defined by NetBSD; other platforms should refrain from
+ * using them for other purposes, so that NetBSD savefiles with link
+ * types of 50 or 51 can be read as this type on all platforms.
+ */
+#define DLT_PPP_SERIAL	50	/* PPP over serial with HDLC encapsulation */
+#define DLT_PPP_ETHER	51	/* PPP over Ethernet */
+
+/*
+ * Values between 100 and 103 are used in capture file headers as
+ * link-layer types corresponding to DLT_ types that differ
+ * between platforms; don't use those values for new DLT_ new types.
+ */
+
+/*
+ * This value was defined by libpcap 0.5; platforms that have defined
+ * it with a different value should define it here with that value -
+ * a link type of 104 in a save file will be mapped to DLT_C_HDLC,
+ * whatever value that happens to be, so programs will correctly
+ * handle files with that link type regardless of the value of
+ * DLT_C_HDLC.
+ *
+ * The name DLT_C_HDLC was used by BSD/OS; we use that name for source
+ * compatibility with programs written for BSD/OS.
+ *
+ * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
+ * for source compatibility with programs written for libpcap 0.5.
+ */
+#define DLT_C_HDLC	104	/* Cisco HDLC */
+#define DLT_CHDLC	DLT_C_HDLC
+
+#define DLT_IEEE802_11	105	/* IEEE 802.11 wireless */
+
+/*
+ * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
+ * except when it isn't.  (I.e., sometimes it's just raw IP, and
+ * sometimes it isn't.)  We currently handle it as DLT_LINUX_SLL,
+ * so that we don't have to worry about the link-layer header.)
+ */
+
+/*
+ * Reserved for Frame Relay; BSD/OS has a DLT_FR, with a value of 11,
+ * but that collides with other values.  DLT_FR and DLT_FRELAY packets
+ * start with the Frame Relay header (DLCI, etc.).
+ */
+#define DLT_FRELAY	107
+
+/*
+ * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
+ * that the AF_ type in the link-layer header is in network byte order.
+ *
+ * OpenBSD defines it as 12, but that collides with DLT_RAW, so we
+ * define it as 108 here.  If OpenBSD picks up this file, it should
+ * define DLT_LOOP as 12 in its version, as per the comment above -
+ * and should not use 108 as a DLT_ value.
+ */
+#define DLT_LOOP	108
+
+/*
+ * Values between 109 and 112 are used in capture file headers as
+ * link-layer types corresponding to DLT_ types that might differ
+ * between platforms; don't use those values for new DLT_ types
+ * other than the corresponding DLT_ types.
+ */
+
+/*
+ * This is for Linux cooked sockets.
+ */
+#define DLT_LINUX_SLL	113
+
+/*
+ * Apple LocalTalk hardware.
+ */
+#define DLT_LTALK	114
+
+/*
+ * Acorn Econet.
+ */
+#define DLT_ECONET	115
+
+/*
+ * Reserved for use with OpenBSD ipfilter.
+ */
+#define DLT_IPFILTER	116
+
+/*
+ * Reserved for use in capture-file headers as a link-layer type
+ * corresponding to OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD,
+ * but that's DLT_LANE8023 in SuSE 6.3, so we can't use 17 for it
+ * in capture-file headers.
+ */
+#define DLT_PFLOG	117
+
+/*
+ * Registered for Cisco-internal use.
+ */
+#define DLT_CISCO_IOS	118
+
+/*
+ * Reserved for 802.11 cards using the Prism II chips, with a link-layer
+ * header including Prism monitor mode information plus an 802.11
+ * header.
+ */
+#define DLT_PRISM_HEADER	119
+
+/*
+ * Reserved for Aironet 802.11 cards, with an Aironet link-layer header
+ * (see Doug Ambrisko's FreeBSD patches).
+ */
+#define DLT_AIRONET_HEADER	120
+
+/*
+ * Reserved for Siemens HiPath HDLC.
+ */
+#define DLT_HHDLC		121
+
+/*
+ * Reserved for RFC 2625 IP-over-Fibre Channel, as per a request from
+ * Don Lee <donlee@cray.com>.
+ *
+ * This is not for use with raw Fibre Channel, where the link-layer
+ * header starts with a Fibre Channel frame header; it's for IP-over-FC,
+ * where the link-layer header starts with an RFC 2625 Network_Header
+ * field.
+ */
+#define DLT_IP_OVER_FC		122
+
+/*
+ * Reserved for capturing on Solaris with SunATM.
+ */
+#define DLT_SUNATM		123	/* Solaris+SunATM */
+
+/*
+ * The instruction encodings.
+ */
+/* instruction classes */
+#define BPF_CLASS(code) ((code) & 0x07)
+#define		BPF_LD		0x00
+#define		BPF_LDX		0x01
+#define		BPF_ST		0x02
+#define		BPF_STX		0x03
+#define		BPF_ALU		0x04
+#define		BPF_JMP		0x05
+#define		BPF_RET		0x06
+#define		BPF_MISC	0x07
+
+/* ld/ldx fields */
+#define BPF_SIZE(code)	((code) & 0x18)
+#define		BPF_W		0x00
+#define		BPF_H		0x08
+#define		BPF_B		0x10
+#define BPF_MODE(code)	((code) & 0xe0)
+#define		BPF_IMM 	0x00
+#define		BPF_ABS		0x20
+#define		BPF_IND		0x40
+#define		BPF_MEM		0x60
+#define		BPF_LEN		0x80
+#define		BPF_MSH		0xa0
+
+/* alu/jmp fields */
+#define BPF_OP(code)	((code) & 0xf0)
+#define		BPF_ADD		0x00
+#define		BPF_SUB		0x10
+#define		BPF_MUL		0x20
+#define		BPF_DIV		0x30
+#define		BPF_OR		0x40
+#define		BPF_AND		0x50
+#define		BPF_LSH		0x60
+#define		BPF_RSH		0x70
+#define		BPF_NEG		0x80
+#define		BPF_JA		0x00
+#define		BPF_JEQ		0x10
+#define		BPF_JGT		0x20
+#define		BPF_JGE		0x30
+#define		BPF_JSET	0x40
+#define BPF_SRC(code)	((code) & 0x08)
+#define		BPF_K		0x00
+#define		BPF_X		0x08
+
+/* ret - BPF_K and BPF_X also apply */
+#define BPF_RVAL(code)	((code) & 0x18)
+#define		BPF_A		0x10
+
+/* misc */
+#define BPF_MISCOP(code) ((code) & 0xf8)
+#define		BPF_TAX		0x00
+#define		BPF_TXA		0x80
+
+/*
+ * The instruction data structure.
+ */
+struct bpf_insn {
+	u_short	code;
+	u_char 	jt;
+	u_char 	jf;
+	bpf_int32 k;
+};
+
+/*
+ * Macros for insn array initializers.
+ */
+#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
+#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
+
+#if defined(BSD) && (defined(KERNEL) || defined(_KERNEL))
+/*
+ * Systems based on non-BSD kernels don't have ifnet's (or they don't mean
+ * anything if it is in <net/if.h>) and won't work like this.
+ */
+# if __STDC__
+extern void bpf_tap(struct ifnet *, u_char *, u_int);
+extern void bpf_mtap(struct ifnet *, struct mbuf *);
+extern void bpfattach(struct ifnet *, u_int, u_int);
+extern void bpfilterattach(int);
+# else
+extern void bpf_tap();
+extern void bpf_mtap();
+extern void bpfattach();
+extern void bpfilterattach();
+# endif /* __STDC__ */
+#endif /* BSD && (_KERNEL || KERNEL) */
+#if __STDC__ || defined(__cplusplus)
+extern int bpf_validate(struct bpf_insn *, int);
+extern u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+#else
+extern int bpf_validate();
+extern u_int bpf_filter();
+#endif
+
+/*
+ * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
+ */
+#define BPF_MEMWORDS 16
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff -Naur test-for-latech/include/net/dwcs.h testqf-for-latech/include/net/dwcs.h
--- test-for-latech/include/net/dwcs.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/dwcs.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,39 @@
+
+void watchdog(unsigned long arg)
+{
+	struct net_device *dev = (struct net_device*) arg;
+	if(dev)
+	{
+		netif_schedule(dev);
+	}
+}
+
+
+
+void dwcs_init_timer(struct timer_list *wd_timer, struct net_device *dev)
+{
+	init_timer(wd_timer);
+	wd_timer->function = watchdog;
+	wd_timer->data = (unsigned long)dev;  
+}
+
+/*
+ * Helper function to return the address of the class
+ * by providing the classid (that includes major and minor ids),
+ * Returns NULL, if no class is found.
+ */
+static __inline__ struct dwcs_class *
+dwcs_class_lookup ( struct dwcs_sched_data *q,
+					u32 classid )
+{
+	struct dwcs_class  *cl;
+
+	for ( cl = q->classes[dwcs_hash ( classid )]; cl; cl = cl->next )
+		if ( cl->classid == classid )
+		{
+			return cl;
+		}
+
+	return NULL;
+}
+
diff -Naur test-for-latech/include/net/ethernet.h testqf-for-latech/include/net/ethernet.h
--- test-for-latech/include/net/ethernet.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/ethernet.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,76 @@
+/* Copyright (C) 1997, 1999, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Based on the FreeBSD version of this file. Curiously, that file
+   lacks a copyright in the header. */
+
+#ifndef __NET_ETHERNET_H
+#define __NET_ETHERNET_H 1
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <linux/if_ether.h>     /* IEEE 802.3 Ethernet constants */
+
+__BEGIN_DECLS
+
+/* This is a name for the 48 bit ethernet address available on many
+   systems.  */
+struct ether_addr
+{
+  u_int8_t ether_addr_octet[ETH_ALEN];
+} __attribute__ ((__packed__));
+
+/* 10Mb/s ethernet header */
+struct ether_header
+{
+  u_int8_t  ether_dhost[ETH_ALEN];	/* destination eth addr	*/
+  u_int8_t  ether_shost[ETH_ALEN];	/* source ether addr	*/
+  u_int16_t ether_type;		        /* packet type ID field	*/
+} __attribute__ ((__packed__));
+
+/* Ethernet protocol ID's */
+#define	ETHERTYPE_PUP		0x0200          /* Xerox PUP */
+#define	ETHERTYPE_IP		0x0800		/* IP */
+#define	ETHERTYPE_ARP		0x0806		/* Address resolution */
+#define	ETHERTYPE_REVARP	0x8035		/* Reverse ARP */
+
+#define	ETHER_ADDR_LEN	ETH_ALEN                 /* size of ethernet addr */
+#define	ETHER_TYPE_LEN	2                        /* bytes in type field */
+#define	ETHER_CRC_LEN	4                        /* bytes in CRC field */
+#define	ETHER_HDR_LEN	ETH_HLEN                 /* total octets in header */
+#define	ETHER_MIN_LEN	(ETH_ZLEN + ETHER_CRC_LEN) /* min packet length */
+#define	ETHER_MAX_LEN	(ETH_FRAME_LEN + ETHER_CRC_LEN) /* max packet length */
+
+/* make sure ethenet length is valid */
+#define	ETHER_IS_VALID_LEN(foo)	\
+	((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
+
+/*
+ * The ETHERTYPE_NTRAILER packet types starting at ETHERTYPE_TRAIL have
+ * (type-ETHERTYPE_TRAIL)*512 bytes of data followed
+ * by an ETHER type (as given above) and then the (variable-length) header.
+ */
+#define	ETHERTYPE_TRAIL		0x1000		/* Trailer packet */
+#define	ETHERTYPE_NTRAILER	16
+
+#define	ETHERMTU	ETH_DATA_LEN
+#define	ETHERMIN	(ETHER_MIN_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN)
+
+__END_DECLS
+
+#endif	/* net/ethernet.h */
diff -Naur test-for-latech/include/net/if_arp.h testqf-for-latech/include/net/if_arp.h
--- test-for-latech/include/net/if_arp.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/if_arp.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,173 @@
+/* Definitions for Address Resolution Protocol.
+   Copyright (C) 1997, 1999, 2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Based on the 4.4BSD and Linux version of this file.  */
+
+#ifndef _NET_IF_ARP_H
+
+#define _NET_IF_ARP_H 1
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+__BEGIN_DECLS
+
+/* Some internals from deep down in the kernel.  */
+#define MAX_ADDR_LEN	7
+
+
+/* This structure defines an ethernet arp header.  */
+
+/* ARP protocol opcodes. */
+#define	ARPOP_REQUEST	1		/* ARP request.  */
+#define	ARPOP_REPLY	2		/* ARP reply.  */
+#define	ARPOP_RREQUEST	3		/* RARP request.  */
+#define	ARPOP_RREPLY	4		/* RARP reply.  */
+#define	ARPOP_InREQUEST	8		/* InARP request.  */
+#define	ARPOP_InREPLY	9		/* InARP reply.  */
+#define	ARPOP_NAK	10		/* (ATM)ARP NAK.  */
+
+/* See RFC 826 for protocol description.  ARP packets are variable
+   in size; the arphdr structure defines the fixed-length portion.
+   Protocol type values are the same as those for 10 Mb/s Ethernet.
+   It is followed by the variable-sized fields ar_sha, arp_spa,
+   arp_tha and arp_tpa in that order, according to the lengths
+   specified.  Field names used correspond to RFC 826.  */
+
+struct arphdr
+  {
+    unsigned short int ar_hrd;		/* Format of hardware address.  */
+    unsigned short int ar_pro;		/* Format of protocol address.  */
+    unsigned char ar_hln;		/* Length of hardware address.  */
+    unsigned char ar_pln;		/* Length of protocol address.  */
+    unsigned short int ar_op;		/* ARP opcode (command).  */
+#if 0
+    /* Ethernet looks like this : This bit is variable sized
+       however...  */
+    unsigned char __ar_sha[ETH_ALEN];	/* Sender hardware address.  */
+    unsigned char __ar_sip[4];		/* Sender IP address.  */
+    unsigned char __ar_tha[ETH_ALEN];	/* Target hardware address.  */
+    unsigned char __ar_tip[4];		/* Target IP address.  */
+#endif
+  };
+
+
+/* ARP protocol HARDWARE identifiers. */
+#define ARPHRD_NETROM	0		/* From KA9Q: NET/ROM pseudo. */
+#define ARPHRD_ETHER 	1		/* Ethernet 10/100Mbps.  */
+#define	ARPHRD_EETHER	2		/* Experimental Ethernet.  */
+#define	ARPHRD_AX25	3		/* AX.25 Level 2.  */
+#define	ARPHRD_PRONET	4		/* PROnet token ring.  */
+#define	ARPHRD_CHAOS	5		/* Chaosnet.  */
+#define	ARPHRD_IEEE802	6		/* IEEE 802.2 Ethernet/TR/TB.  */
+#define	ARPHRD_ARCNET	7		/* ARCnet.  */
+#define	ARPHRD_APPLETLK	8		/* APPLEtalk.  */
+#define	ARPHRD_DLCI	15		/* Frame Relay DLCI.  */
+#define	ARPHRD_ATM	19		/* ATM.  */
+#define	ARPHRD_METRICOM	23		/* Metricom STRIP (new IANA id).  */
+
+/* Dummy types for non ARP hardware */
+#define ARPHRD_SLIP	256
+#define ARPHRD_CSLIP	257
+#define ARPHRD_SLIP6	258
+#define ARPHRD_CSLIP6	259
+#define ARPHRD_RSRVD	260		/* Notional KISS type.  */
+#define ARPHRD_ADAPT	264
+#define ARPHRD_ROSE	270
+#define ARPHRD_X25	271		/* CCITT X.25.  */
+#define ARPHDR_HWX25	272		/* Boards with X.25 in firmware.  */
+#define ARPHRD_PPP	512
+#define ARPHRD_CISCO	513		/* Cisco HDLC.  */
+#define ARPHRD_HDLC	ARPHRD_CISCO
+#define ARPHRD_LAPB	516		/* LAPB.  */
+#define ARPHRD_DDCMP	517		/* Digital's DDCMP.  */
+#define	ARPHRD_RAWHDLC	518		/* Raw HDLC.  */
+
+#define ARPHRD_TUNNEL	768		/* IPIP tunnel.  */
+#define ARPHRD_TUNNEL6	769		/* IPIP6 tunnel.  */
+#define ARPHRD_FRAD	770             /* Frame Relay Access Device.  */
+#define ARPHRD_SKIP	771		/* SKIP vif.  */
+#define ARPHRD_LOOPBACK	772		/* Loopback device.  */
+#define ARPHRD_LOCALTLK 773		/* Localtalk device.  */
+#define ARPHRD_FDDI	774		/* Fiber Distributed Data Interface. */
+#define ARPHRD_BIF	775             /* AP1000 BIF.  */
+#define ARPHRD_SIT	776		/* sit0 device - IPv6-in-IPv4.  */
+#define ARPHRD_IPDDP	777		/* IP-in-DDP tunnel.  */
+#define ARPHRD_IPGRE	778		/* GRE over IP.  */
+#define ARPHRD_PIMREG	779		/* PIMSM register interface.  */
+#define ARPHRD_HIPPI	780		/* High Performance Parallel I'face. */
+#define ARPHRD_ASH	781		/* (Nexus Electronics) Ash.  */
+#define ARPHRD_ECONET	782		/* Acorn Econet.  */
+#define ARPHRD_IRDA	783		/* Linux-IrDA.  */
+#define ARPHRD_FCPP	784		/* Point to point fibrechanel.  */
+#define ARPHRD_FCAL	785		/* Fibrechanel arbitrated loop.  */
+#define ARPHRD_FCPL	786		/* Fibrechanel public loop.  */
+#define ARPHRD_FCPFABRIC 787		/* Fibrechanel fabric.  */
+#define ARPHRD_IEEE802_TR 800		/* Magic type ident for TR.  */
+#define ARPHRD_IEEE80211 801		/* IEEE 802.11.  */
+
+/* ARP ioctl request.  */
+struct arpreq
+  {
+    struct sockaddr arp_pa;		/* Protocol address.  */
+    struct sockaddr arp_ha;		/* Hardware address.  */
+    int arp_flags;			/* Flags.  */
+    struct sockaddr arp_netmask;	/* Netmask (only for proxy arps).  */
+    char arp_dev[16];
+  };
+
+struct arpreq_old
+  {
+    struct sockaddr arp_pa;		/* Protocol address.  */
+    struct sockaddr arp_ha;		/* Hardware address.  */
+    int arp_flags;			/* Flags.  */
+    struct sockaddr arp_netmask;	/* Netmask (only for proxy arps).  */
+  };
+
+/* ARP Flag values.  */
+#define ATF_COM		0x02		/* Completed entry (ha valid).  */
+#define	ATF_PERM	0x04		/* Permanent entry.  */
+#define	ATF_PUBL	0x08		/* Publish entry.  */
+#define	ATF_USETRAILERS	0x10		/* Has requested trailers.  */
+#define ATF_NETMASK     0x20            /* Want to use a netmask (only
+					   for proxy entries).  */
+#define ATF_DONTPUB	0x40		/* Don't answer this addresses.  */
+#define ATF_MAGIC	0x80		/* Automatically added entry.  */
+
+
+/* Support for the user space arp daemon, arpd.  */
+#define ARPD_UPDATE	0x01
+#define ARPD_LOOKUP	0x02
+#define ARPD_FLUSH	0x03
+
+struct arpd_request
+  {
+    unsigned short int req;		/* Request type.  */
+    u_int32_t ip;			/* IP address of entry.  */
+    unsigned long int dev;		/* Device entry is tied to.  */
+    unsigned long int stamp;
+    unsigned long int updated;
+    unsigned char ha[MAX_ADDR_LEN];	/* Hardware address.  */
+  };
+
+__END_DECLS
+
+#endif	/* net/if_arp.h */
diff -Naur test-for-latech/include/net/if.h testqf-for-latech/include/net/if.h
--- test-for-latech/include/net/if.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/if.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,203 @@
+/* net/if.h -- declarations for inquiring about network interfaces
+   Copyright (C) 1997,98,99,2000,2001 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _NET_IF_H
+#define _NET_IF_H	1
+
+#include <features.h>
+
+#ifdef __USE_MISC
+# include <sys/types.h>
+# include <sys/socket.h>
+#endif
+
+
+/* Length of interface name.  */
+#define IF_NAMESIZE	16
+
+struct if_nameindex
+  {
+    unsigned int if_index;	/* 1, 2, ... */
+    char *if_name;		/* null terminated name: "eth0", ... */
+  };
+
+
+#ifdef __USE_MISC
+/* Standard interface flags. */
+enum
+  {
+    IFF_UP = 0x1,		/* Interface is up.  */
+# define IFF_UP	IFF_UP
+    IFF_BROADCAST = 0x2,	/* Broadcast address valid.  */
+# define IFF_BROADCAST	IFF_BROADCAST
+    IFF_DEBUG = 0x4,		/* Turn on debugging.  */
+# define IFF_DEBUG	IFF_DEBUG
+    IFF_LOOPBACK = 0x8,		/* Is a loopback net.  */
+# define IFF_LOOPBACK	IFF_LOOPBACK
+    IFF_POINTOPOINT = 0x10,	/* Interface is point-to-point link.  */
+# define IFF_POINTOPOINT IFF_POINTOPOINT
+    IFF_NOTRAILERS = 0x20,	/* Avoid use of trailers.  */
+# define IFF_NOTRAILERS	IFF_NOTRAILERS
+    IFF_RUNNING = 0x40,		/* Resources allocated.  */
+# define IFF_RUNNING	IFF_RUNNING
+    IFF_NOARP = 0x80,		/* No address resolution protocol.  */
+# define IFF_NOARP	IFF_NOARP
+    IFF_PROMISC = 0x100,	/* Receive all packets.  */
+# define IFF_PROMISC	IFF_PROMISC
+
+    /* Not supported */
+    IFF_ALLMULTI = 0x200,	/* Receive all multicast packets.  */
+# define IFF_ALLMULTI	IFF_ALLMULTI
+
+    IFF_MASTER = 0x400,		/* Master of a load balancer.  */
+# define IFF_MASTER	IFF_MASTER
+    IFF_SLAVE = 0x800,		/* Slave of a load balancer.  */
+# define IFF_SLAVE	IFF_SLAVE
+
+    IFF_MULTICAST = 0x1000,	/* Supports multicast.  */
+# define IFF_MULTICAST	IFF_MULTICAST
+
+    IFF_PORTSEL = 0x2000,	/* Can set media type.  */
+# define IFF_PORTSEL	IFF_PORTSEL
+    IFF_AUTOMEDIA = 0x4000	/* Auto media select active.  */
+# define IFF_AUTOMEDIA	IFF_AUTOMEDIA
+  };
+
+/* The ifaddr structure contains information about one address of an
+   interface.  They are maintained by the different address families,
+   are allocated and attached when an address is set, and are linked
+   together so all addresses for an interface can be located.  */
+
+struct ifaddr
+  {
+    struct sockaddr ifa_addr;	/* Address of interface.  */
+    union
+      {
+	struct sockaddr	ifu_broadaddr;
+	struct sockaddr	ifu_dstaddr;
+      } ifa_ifu;
+    struct iface *ifa_ifp;	/* Back-pointer to interface.  */
+    struct ifaddr *ifa_next;	/* Next address for interface.  */
+  };
+
+# define ifa_broadaddr	ifa_ifu.ifu_broadaddr	/* broadcast address	*/
+# define ifa_dstaddr	ifa_ifu.ifu_dstaddr	/* other end of link	*/
+
+/* Device mapping structure. I'd just gone off and designed a
+   beautiful scheme using only loadable modules with arguments for
+   driver options and along come the PCMCIA people 8)
+
+   Ah well. The get() side of this is good for WDSETUP, and it'll be
+   handy for debugging things. The set side is fine for now and being
+   very small might be worth keeping for clean configuration.  */
+
+struct ifmap
+  {
+    unsigned long int mem_start;
+    unsigned long int mem_end;
+    unsigned short int base_addr;
+    unsigned char irq;
+    unsigned char dma;
+    unsigned char port;
+    /* 3 bytes spare */
+  };
+
+/* Interface request structure used for socket ioctl's.  All interface
+   ioctl's must have parameter definitions which begin with ifr_name.
+   The remainder may be interface specific.  */
+
+struct ifreq
+  {
+# define IFHWADDRLEN	6
+# define IFNAMSIZ	IF_NAMESIZE
+    union
+      {
+	char ifrn_name[IFNAMSIZ];	/* Interface name, e.g. "en0".  */
+      } ifr_ifrn;
+
+    union
+      {
+	struct sockaddr ifru_addr;
+	struct sockaddr ifru_dstaddr;
+	struct sockaddr ifru_broadaddr;
+	struct sockaddr ifru_netmask;
+	struct sockaddr ifru_hwaddr;
+	short int ifru_flags;
+	int ifru_ivalue;
+	int ifru_mtu;
+	struct ifmap ifru_map;
+	char ifru_slave[IFNAMSIZ];	/* Just fits the size */
+	char ifru_newname[IFNAMSIZ];
+	__caddr_t ifru_data;
+      } ifr_ifru;
+  };
+# define ifr_name	ifr_ifrn.ifrn_name	/* interface name 	*/
+# define ifr_hwaddr	ifr_ifru.ifru_hwaddr	/* MAC address 		*/
+# define ifr_addr	ifr_ifru.ifru_addr	/* address		*/
+# define ifr_dstaddr	ifr_ifru.ifru_dstaddr	/* other end of p-p lnk	*/
+# define ifr_broadaddr	ifr_ifru.ifru_broadaddr	/* broadcast address	*/
+# define ifr_netmask	ifr_ifru.ifru_netmask	/* interface net mask	*/
+# define ifr_flags	ifr_ifru.ifru_flags	/* flags		*/
+# define ifr_metric	ifr_ifru.ifru_ivalue	/* metric		*/
+# define ifr_mtu	ifr_ifru.ifru_mtu	/* mtu			*/
+# define ifr_map	ifr_ifru.ifru_map	/* device map		*/
+# define ifr_slave	ifr_ifru.ifru_slave	/* slave device		*/
+# define ifr_data	ifr_ifru.ifru_data	/* for use by interface	*/
+# define ifr_ifindex	ifr_ifru.ifru_ivalue    /* interface index      */
+# define ifr_bandwidth	ifr_ifru.ifru_ivalue	/* link bandwidth	*/
+# define ifr_qlen	ifr_ifru.ifru_ivalue	/* queue length		*/
+# define ifr_newname	ifr_ifru.ifru_newname	/* New name		*/
+# define _IOT_ifreq	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(char),16,0,0)
+# define _IOT_ifreq_short _IOT(_IOTS(char),IFNAMSIZ,_IOTS(short),1,0,0)
+# define _IOT_ifreq_int	_IOT(_IOTS(char),IFNAMSIZ,_IOTS(int),1,0,0)
+
+
+/* Structure used in SIOCGIFCONF request.  Used to retrieve interface
+   configuration for machine (useful for programs which must know all
+   networks accessible).  */
+
+struct ifconf
+  {
+    int	ifc_len;			/* Size of buffer.  */
+    union
+      {
+	__caddr_t ifcu_buf;
+	struct ifreq *ifcu_req;
+      } ifc_ifcu;
+  };
+# define ifc_buf	ifc_ifcu.ifcu_buf	/* Buffer address.  */
+# define ifc_req	ifc_ifcu.ifcu_req	/* Array of structures.  */
+# define _IOT_ifconf _IOT(_IOTS(struct ifconf),1,0,0,0,0) /* not right */
+#endif	/* Misc.  */
+
+__BEGIN_DECLS
+
+/* Convert an interface name to an index, and vice versa.  */
+extern unsigned int if_nametoindex (__const char *__ifname) __THROW;
+extern char *if_indextoname (unsigned int __ifindex, char *__ifname) __THROW;
+
+/* Return a list of all interfaces and their indices.  */
+extern struct if_nameindex *if_nameindex (void) __THROW;
+
+/* Free the data returned from if_nameindex.  */
+extern void if_freenameindex (struct if_nameindex *__ptr) __THROW;
+
+__END_DECLS
+
+#endif /* net/if.h */
diff -Naur test-for-latech/include/net/if_packet.h testqf-for-latech/include/net/if_packet.h
--- test-for-latech/include/net/if_packet.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/if_packet.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,37 @@
+/* Definitions for use with Linux SOCK_PACKET sockets.
+   Copyright (C) 1997, 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef __IF_PACKET_H
+#define __IF_PACKET_H
+
+#include <features.h>
+#include <bits/sockaddr.h>
+
+/* This is the SOCK_PACKET address structure as used in Linux 2.0.
+   From Linux 2.1 the AF_PACKET interface is preferred and you should
+   consider using it in place of this one.  */
+
+struct sockaddr_pkt
+  {
+    __SOCKADDR_COMMON (spkt_);
+    unsigned char spkt_device[14];
+    unsigned short spkt_protocol;
+  };
+
+#endif
diff -Naur test-for-latech/include/net/if_ppp.h testqf-for-latech/include/net/if_ppp.h
--- test-for-latech/include/net/if_ppp.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/if_ppp.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,169 @@
+/*	From: if_ppp.h,v 1.3 1995/06/12 11:36:50 paulus Exp */
+
+/*
+ * if_ppp.h - Point-to-Point Protocol definitions.
+ *
+ * Copyright (c) 1989 Carnegie Mellon University. 
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
+ * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ *  ==FILEVERSION 960926==
+ *
+ *  NOTE TO MAINTAINERS:
+ *     If you modify this file at all, please set the above date.
+ *     if_ppp.h is shipped with a PPP distribution as well as with the kernel;
+ *     if everyone increases the FILEVERSION number above, then scripts
+ *     can do the right thing when deciding whether to install a new if_ppp.h
+ *     file.  Don't change the format of that line otherwise, so the
+ *     installation script can recognize it.
+ */
+
+
+#ifndef __NET_IF_PPP_H
+#define __NET_IF_PPP_H 1
+
+#include <sys/types.h>
+#include <sys/cdefs.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <net/ppp_defs.h>
+
+__BEGIN_DECLS
+
+/*
+ * Packet sizes
+ */
+
+#define	PPP_MTU		1500	/* Default MTU (size of Info field) */
+#define PPP_MAXMRU	65000	/* Largest MRU we allow */
+#define PPP_VERSION	"2.2.0"
+#define PPP_MAGIC	0x5002	/* Magic value for the ppp structure */
+#define PROTO_IPX	0x002b	/* protocol numbers */
+#define PROTO_DNA_RT    0x0027  /* DNA Routing */
+
+
+/*
+ * Bit definitions for flags.
+ */
+
+#define SC_COMP_PROT	0x00000001	/* protocol compression (output) */
+#define SC_COMP_AC	0x00000002	/* header compression (output) */
+#define	SC_COMP_TCP	0x00000004	/* TCP (VJ) compression (output) */
+#define SC_NO_TCP_CCID	0x00000008	/* disable VJ connection-id comp. */
+#define SC_REJ_COMP_AC	0x00000010	/* reject adrs/ctrl comp. on input */
+#define SC_REJ_COMP_TCP	0x00000020	/* reject TCP (VJ) comp. on input */
+#define SC_CCP_OPEN	0x00000040	/* Look at CCP packets */
+#define SC_CCP_UP	0x00000080	/* May send/recv compressed packets */
+#define SC_ENABLE_IP	0x00000100	/* IP packets may be exchanged */
+#define SC_COMP_RUN	0x00001000	/* compressor has been inited */
+#define SC_DECOMP_RUN	0x00002000	/* decompressor has been inited */
+#define SC_DEBUG	0x00010000	/* enable debug messages */
+#define SC_LOG_INPKT	0x00020000	/* log contents of good pkts recvd */
+#define SC_LOG_OUTPKT	0x00040000	/* log contents of pkts sent */
+#define SC_LOG_RAWIN	0x00080000	/* log all chars received */
+#define SC_LOG_FLUSH	0x00100000	/* log all chars flushed */
+#define	SC_MASK		0x0fE0ffff	/* bits that user can change */
+
+/* state bits */
+#define	SC_ESCAPED	0x80000000	/* saw a PPP_ESCAPE */
+#define	SC_FLUSH	0x40000000	/* flush input until next PPP_FLAG */
+#define SC_VJ_RESET	0x20000000	/* Need to reset the VJ decompressor */
+#define SC_XMIT_BUSY	0x10000000	/* ppp_write_wakeup is active */
+#define SC_RCV_ODDP	0x08000000	/* have rcvd char with odd parity */
+#define SC_RCV_EVNP	0x04000000	/* have rcvd char with even parity */
+#define SC_RCV_B7_1	0x02000000	/* have rcvd char with bit 7 = 1 */
+#define SC_RCV_B7_0	0x01000000	/* have rcvd char with bit 7 = 0 */
+#define SC_DC_FERROR	0x00800000	/* fatal decomp error detected */
+#define SC_DC_ERROR	0x00400000	/* non-fatal decomp error detected */
+
+/*
+ * Ioctl definitions.
+ */
+
+struct npioctl {
+    int		protocol;	/* PPP protocol, e.g. PPP_IP */
+    enum NPmode	mode;
+};
+
+/* Structure describing a CCP configuration option, for PPPIOCSCOMPRESS */
+struct ppp_option_data {
+	u_int8_t  *ptr;
+	u_int32_t length;
+	int	  transmit;
+};
+
+struct ifpppstatsreq {
+  struct ifreq	   b;
+  struct ppp_stats stats;			/* statistic information */
+};
+
+struct ifpppcstatsreq {
+  struct ifreq		b;
+  struct ppp_comp_stats stats;
+};
+
+#define ifr__name       b.ifr_ifrn.ifrn_name
+#define stats_ptr       b.ifr_ifru.ifru_data
+
+/*
+ * Ioctl definitions.
+ */
+
+#define	PPPIOCGFLAGS	_IOR('t', 90, int)	/* get configuration flags */
+#define	PPPIOCSFLAGS	_IOW('t', 89, int)	/* set configuration flags */
+#define	PPPIOCGASYNCMAP	_IOR('t', 88, int)	/* get async map */
+#define	PPPIOCSASYNCMAP	_IOW('t', 87, int)	/* set async map */
+#define	PPPIOCGUNIT	_IOR('t', 86, int)	/* get ppp unit number */
+#define	PPPIOCGRASYNCMAP _IOR('t', 85, int)	/* get receive async map */
+#define	PPPIOCSRASYNCMAP _IOW('t', 84, int)	/* set receive async map */
+#define	PPPIOCGMRU	_IOR('t', 83, int)	/* get max receive unit */
+#define	PPPIOCSMRU	_IOW('t', 82, int)	/* set max receive unit */
+#define	PPPIOCSMAXCID	_IOW('t', 81, int)	/* set VJ max slot ID */
+#define PPPIOCGXASYNCMAP _IOR('t', 80, ext_accm) /* get extended ACCM */
+#define PPPIOCSXASYNCMAP _IOW('t', 79, ext_accm) /* set extended ACCM */
+#define PPPIOCXFERUNIT	_IO('t', 78)		/* transfer PPP unit */
+#define PPPIOCSCOMPRESS	_IOW('t', 77, struct ppp_option_data)
+#define PPPIOCGNPMODE	_IOWR('t', 76, struct npioctl) /* get NP mode */
+#define PPPIOCSNPMODE	_IOW('t', 75, struct npioctl)  /* set NP mode */
+#define PPPIOCGDEBUG	_IOR('t', 65, int)	/* Read debug level */
+#define PPPIOCSDEBUG	_IOW('t', 64, int)	/* Set debug level */
+#define PPPIOCGIDLE	_IOR('t', 63, struct ppp_idle) /* get idle time */
+
+#define SIOCGPPPSTATS   (SIOCDEVPRIVATE + 0)
+#define SIOCGPPPVER     (SIOCDEVPRIVATE + 1)  /* NEVER change this!! */
+#define SIOCGPPPCSTATS  (SIOCDEVPRIVATE + 2)
+
+#if !defined(ifr_mtu)
+#define ifr_mtu	ifr_ifru.ifru_metric
+#endif
+
+__END_DECLS
+
+#endif /* net/if_ppp.h */
diff -Naur test-for-latech/include/net/if_shaper.h testqf-for-latech/include/net/if_shaper.h
--- test-for-latech/include/net/if_shaper.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/if_shaper.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,59 @@
+/* Copyright (C) 1998 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _NET_IF_SHAPER_H
+#define _NET_IF_SHAPER_H 1
+
+#include <features.h>
+#include <sys/types.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+
+__BEGIN_DECLS
+
+#define SHAPER_QLEN	10
+/*
+ *	This is a bit speed dependant (read it shouldnt be a constant!)
+ *
+ *	5 is about right for 28.8 upwards. Below that double for every
+ *	halving of speed or so. - ie about 20 for 9600 baud.
+ */
+#define SHAPER_LATENCY	(5 * HZ)
+#define SHAPER_MAXSLIP	2
+#define SHAPER_BURST	(HZ / 50)	/* Good for >128K then */
+
+#define SHAPER_SET_DEV		0x0001
+#define SHAPER_SET_SPEED	0x0002
+#define SHAPER_GET_DEV		0x0003
+#define SHAPER_GET_SPEED	0x0004
+
+struct shaperconf
+{
+  u_int16_t ss_cmd;
+  union
+  {
+    char ssu_name[14];
+    u_int32_t ssu_speed;
+  } ss_u;
+#define ss_speed ss_u.ssu_speed
+#define ss_name ss_u.ssu_name
+};
+
+__END_DECLS
+
+#endif /* net/if_shaper.h */
diff -Naur test-for-latech/include/net/if_slip.h testqf-for-latech/include/net/if_slip.h
--- test-for-latech/include/net/if_slip.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/if_slip.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,25 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _NET_IF_SLIP_H
+#define _NET_IF_SLIP_H 1
+
+/* We can use the kernel header.  */
+#include <linux/if_slip.h>
+
+#endif	/* net/if_slip.h.  */
diff -Naur test-for-latech/include/net/pkt_cls.h testqf-for-latech/include/net/pkt_cls.h
--- test-for-latech/include/net/pkt_cls.h	2004-06-11 07:40:23.000000000 -0400
+++ testqf-for-latech/include/net/pkt_cls.h	2004-06-11 07:47:33.000000000 -0400
@@ -81,7 +81,7 @@
 
 extern int register_tcf_proto_ops(struct tcf_proto_ops *ops);
 extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
-
+extern struct tcf_proto_ops cls_socket_ops;
 
 
 #endif
diff -Naur test-for-latech/include/net/pkt_sched.h testqf-for-latech/include/net/pkt_sched.h
--- test-for-latech/include/net/pkt_sched.h	2004-06-11 07:40:22.000000000 -0400
+++ testqf-for-latech/include/net/pkt_sched.h	2004-06-11 07:47:33.000000000 -0400
@@ -16,6 +16,17 @@
 #include <asm/msr.h>
 #endif
 
+#ifdef CONFIG_QFABRIC
+#define MAX_EVENTS 4096
+#define MAX_DEVS 5
+
+struct rte_list {
+	struct sk_buff *skb;
+	int deadline;
+	int flags;
+};
+#endif
+
 struct rtattr;
 struct Qdisc;
 
@@ -432,7 +443,15 @@
 int tc_filter_init(void);
 int pktsched_init(void);
 
+struct Qdisc_ops *qdisc_lookup_ops_string(char *kind);
+u32 qdisc_alloc_handle(struct net_device *dev);
+int qdisc_graft(struct net_device *dev, struct Qdisc *parent, u32 classid,
+			struct Qdisc *new, struct Qdisc **old);
+
 extern int qdisc_restart(struct net_device *dev);
+#ifdef CONFIG_QFABRIC
+extern int qdisc_restart_rte(struct net_device *dev);
+#endif
 
 static inline void qdisc_run(struct net_device *dev)
 {
@@ -441,6 +460,15 @@
 		/* NOTHING */;
 }
 
+#ifdef CONFIG_QFABRIC
+static inline void qdisc_run_rte(struct net_device *dev)
+{
+	while (!netif_queue_stopped(dev) &&
+	       qdisc_restart_rte(dev)<0)
+		/* NOTHING */;
+}
+#endif
+
 /* Calculate maximal size of packet seen by hard_start_xmit
    routine of this device.
  */
@@ -450,4 +478,12 @@
 	return dev->hard_header ? mtu + dev->hard_header_len : mtu;
 }
 
+#ifdef CONFIG_QFABRIC
+extern int rte_enqueue(struct net_device *dev, struct sk_buff *skb);
+extern struct sk_buff *rte_dequeue(struct net_device *dev);
+extern int rte_requeue(struct sk_buff *skb, struct net_device *dev);
+extern int rte_init(struct net_device *dev);
+extern int rte_avail;
+#endif
+
 #endif
diff -Naur test-for-latech/include/net/ppp-comp.h testqf-for-latech/include/net/ppp-comp.h
--- test-for-latech/include/net/ppp-comp.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/ppp-comp.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1 @@
+#include <linux/ppp-comp.h>
diff -Naur test-for-latech/include/net/ppp_defs.h testqf-for-latech/include/net/ppp_defs.h
--- test-for-latech/include/net/ppp_defs.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/ppp_defs.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,10 @@
+#ifndef _NET_PPP_DEFS_H
+#define _NET_PPP_DEFS_H 1
+
+#define __need_time_t
+#include <time.h>
+
+#include <asm/types.h>
+#include <linux/ppp_defs.h>
+
+#endif /* net/ppp_defs.h */
diff -Naur test-for-latech/include/net/route.h testqf-for-latech/include/net/route.h
--- test-for-latech/include/net/route.h	2004-06-11 07:40:22.000000000 -0400
+++ testqf-for-latech/include/net/route.h	2004-06-11 07:47:33.000000000 -0400
@@ -1,188 +1,145 @@
-/*
- * INET		An implementation of the TCP/IP protocol suite for the LINUX
- *		operating system.  INET  is implemented using the  BSD Socket
- *		interface as the means of communication with the user level.
- *
- *		Definitions for the IP router.
- *
- * Version:	@(#)route.h	1.0.4	05/27/93
- *
- * Authors:	Ross Biro, <bir7@leland.Stanford.Edu>
- *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Fixes:
- *		Alan Cox	:	Reformatted. Added ip_rt_local()
- *		Alan Cox	:	Support for TCP parameters.
- *		Alexey Kuznetsov:	Major changes for new routing code.
- *		Mike McLagan    :	Routing by source
- *		Robert Olsson   :	Added rt_cache statistics
- *
- *		This program is free software; you can redistribute it and/or
- *		modify it under the terms of the GNU General Public License
- *		as published by the Free Software Foundation; either version
- *		2 of the License, or (at your option) any later version.
- */
-#ifndef _ROUTE_H
-#define _ROUTE_H
-
-#include <linux/config.h>
-#include <net/dst.h>
-#include <net/inetpeer.h>
-#include <linux/in_route.h>
-#include <linux/rtnetlink.h>
-#include <linux/route.h>
-#include <linux/ip.h>
-#include <linux/cache.h>
+/* Copyright (C) 1997, 2002 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
-#ifndef __KERNEL__
-#warning This file is not supposed to be used outside of kernel.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Based on the 4.4BSD and Linux version of this file.  */
+
+#ifndef _NET_ROUTE_H
+#define _NET_ROUTE_H	1
+
+#include <features.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <bits/wordsize.h>
+
+
+/* This structure gets passed by the SIOCADDRT and SIOCDELRT calls. */
+struct rtentry
+  {
+    unsigned long int rt_pad1;
+    struct sockaddr rt_dst;		/* Target address.  */
+    struct sockaddr rt_gateway;		/* Gateway addr (RTF_GATEWAY).  */
+    struct sockaddr rt_genmask;		/* Target network mask (IP).  */
+    unsigned short int rt_flags;
+    short int rt_pad2;
+    unsigned long int rt_pad3;
+    unsigned char rt_tos;
+    unsigned char rt_class;
+#if __WORDSIZE == 64
+    short int rt_pad4[3];
+#else
+    short int rt_pad4;
 #endif
+    short int rt_metric;		/* +1 for binary compatibility!  */
+    char *rt_dev;			/* Forcing the device at add.  */
+    unsigned long int rt_mtu;		/* Per route MTU/Window.  */
+    unsigned long int rt_window;	/* Window clamping.  */
+    unsigned short int rt_irtt;		/* Initial RTT.  */
+  };
+/* Compatibility hack.  */
+#define rt_mss	rt_mtu
+
+
+struct in6_rtmsg
+  {
+    struct in6_addr rtmsg_dst;
+    struct in6_addr rtmsg_src;
+    struct in6_addr rtmsg_gateway;
+    u_int32_t rtmsg_type;
+    u_int16_t rtmsg_dst_len;
+    u_int16_t rtmsg_src_len;
+    u_int32_t rtmsg_metric;
+    unsigned long int rtmsg_info;
+    u_int32_t rtmsg_flags;
+    int rtmsg_ifindex;
+  };
+
+
+#define	RTF_UP		0x0001		/* Route usable.  */
+#define	RTF_GATEWAY	0x0002		/* Destination is a gateway.  */
+
+#define	RTF_HOST	0x0004		/* Host entry (net otherwise).  */
+#define RTF_REINSTATE	0x0008		/* Reinstate route after timeout.  */
+#define	RTF_DYNAMIC	0x0010		/* Created dyn. (by redirect).  */
+#define	RTF_MODIFIED	0x0020		/* Modified dyn. (by redirect).  */
+#define RTF_MTU		0x0040		/* Specific MTU for this route.  */
+#define RTF_MSS		RTF_MTU		/* Compatibility.  */
+#define RTF_WINDOW	0x0080		/* Per route window clamping.  */
+#define RTF_IRTT	0x0100		/* Initial round trip time.  */
+#define RTF_REJECT	0x0200		/* Reject route.  */
+#define	RTF_STATIC	0x0400		/* Manually injected route.  */
+#define	RTF_XRESOLVE	0x0800		/* External resolver.  */
+#define RTF_NOFORWARD   0x1000		/* Forwarding inhibited.  */
+#define RTF_THROW	0x2000		/* Go to next class.  */
+#define RTF_NOPMTUDISC  0x4000		/* Do not send packets with DF.  */
+
+/* for IPv6 */
+#define RTF_DEFAULT	0x00010000	/* default - learned via ND	*/
+#define RTF_ALLONLINK	0x00020000	/* fallback, no routers on link	*/
+#define RTF_ADDRCONF	0x00040000	/* addrconf route - RA		*/
+
+#define RTF_LINKRT	0x00100000	/* link specific - device match	*/
+#define RTF_NONEXTHOP	0x00200000	/* route with no nexthop	*/
+
+#define RTF_CACHE	0x01000000	/* cache entry			*/
+#define RTF_FLOW	0x02000000	/* flow significant route	*/
+#define RTF_POLICY	0x04000000	/* policy route			*/
+
+#define RTCF_VALVE	0x00200000
+#define RTCF_MASQ	0x00400000
+#define RTCF_NAT	0x00800000
+#define RTCF_DOREDIRECT 0x01000000
+#define RTCF_LOG	0x02000000
+#define RTCF_DIRECTSRC	0x04000000
+
+#define RTF_LOCAL	0x80000000
+#define RTF_INTERFACE	0x40000000
+#define RTF_MULTICAST	0x20000000
+#define RTF_BROADCAST	0x10000000
+#define RTF_NAT		0x08000000
+
+#define RTF_ADDRCLASSMASK	0xF8000000
+#define RT_ADDRCLASS(flags)	((__u_int32_t) flags >> 23)
+
+#define RT_TOS(tos)		((tos) & IPTOS_TOS_MASK)
+
+#define RT_LOCALADDR(flags)	((flags & RTF_ADDRCLASSMASK) \
+				 == (RTF_LOCAL|RTF_INTERFACE))
+
+#define RT_CLASS_UNSPEC		0
+#define RT_CLASS_DEFAULT	253
+
+#define RT_CLASS_MAIN		254
+#define RT_CLASS_LOCAL		255
+#define RT_CLASS_MAX		255
+
+
+#define RTMSG_ACK		NLMSG_ACK
+#define RTMSG_OVERRUN		NLMSG_OVERRUN
+
+#define RTMSG_NEWDEVICE		0x11
+#define RTMSG_DELDEVICE		0x12
+#define RTMSG_NEWROUTE		0x21
+#define RTMSG_DELROUTE		0x22
+#define RTMSG_NEWRULE		0x31
+#define RTMSG_DELRULE		0x32
+#define RTMSG_CONTROL		0x40
 
-#define RTO_ONLINK	0x01
+#define RTMSG_AR_FAILED		0x51	/* Address Resolution failed.  */
 
-#define RTO_CONN	0
-/* RTO_CONN is not used (being alias for 0), but preserved not to break
- * some modules referring to it. */
-
-#define RT_CONN_FLAGS(sk)   (RT_TOS(sk->protinfo.af_inet.tos) | sk->localroute)
-
-struct rt_key
-{
-	__u32			dst;
-	__u32			src;
-	int			iif;
-	int			oif;
-#ifdef CONFIG_IP_ROUTE_FWMARK
-	__u32			fwmark;
-#endif
-	__u8			tos;
-	__u8			scope;
-};
-
-struct inet_peer;
-struct rtable
-{
-	union
-	{
-		struct dst_entry	dst;
-		struct rtable		*rt_next;
-	} u;
-
-	unsigned		rt_flags;
-	unsigned		rt_type;
-
-	__u32			rt_dst;	/* Path destination	*/
-	__u32			rt_src;	/* Path source		*/
-	int			rt_iif;
-
-	/* Info on neighbour */
-	__u32			rt_gateway;
-
-	/* Cache lookup keys */
-	struct rt_key		key;
-
-	/* Miscellaneous cached information */
-	__u32			rt_spec_dst; /* RFC1122 specific destination */
-	struct inet_peer	*peer; /* long-living peer info */
-
-#ifdef CONFIG_IP_ROUTE_NAT
-	__u32			rt_src_map;
-	__u32			rt_dst_map;
-#endif
-};
-
-struct ip_rt_acct
-{
-	__u32 	o_bytes;
-	__u32 	o_packets;
-	__u32 	i_bytes;
-	__u32 	i_packets;
-};
-
-struct rt_cache_stat 
-{
-        unsigned int in_hit;
-        unsigned int in_slow_tot;
-        unsigned int in_slow_mc;
-        unsigned int in_no_route;
-        unsigned int in_brd;
-        unsigned int in_martian_dst;
-        unsigned int in_martian_src;
-        unsigned int out_hit;
-        unsigned int out_slow_tot;
-        unsigned int out_slow_mc;
-        unsigned int gc_total;
-        unsigned int gc_ignored;
-        unsigned int gc_goal_miss;
-        unsigned int gc_dst_overflow;
-} ____cacheline_aligned_in_smp;
-
-extern struct ip_rt_acct *ip_rt_acct;
-
-struct in_device;
-extern void		ip_rt_init(void);
-extern void		ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
-				       u32 src, u8 tos, struct net_device *dev);
-extern void		ip_rt_advice(struct rtable **rp, int advice);
-extern void		rt_cache_flush(int how);
-extern int		ip_route_output_key(struct rtable **, const struct rt_key *key);
-extern int		ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
-extern unsigned short	ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
-extern void		ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu);
-extern void		ip_rt_send_redirect(struct sk_buff *skb);
-
-extern unsigned		inet_addr_type(u32 addr);
-extern void		ip_rt_multicast_event(struct in_device *);
-extern int		ip_rt_ioctl(unsigned int cmd, void *arg);
-extern void		ip_rt_get_source(u8 *src, struct rtable *rt);
-extern int		ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);
-
-/* Deprecated: use ip_route_output_key directly */
-static inline int ip_route_output(struct rtable **rp,
-				      u32 daddr, u32 saddr, u32 tos, int oif)
-{
-	struct rt_key key = { dst:daddr, src:saddr, oif:oif, tos:tos };
-
-	return ip_route_output_key(rp, &key);
-}
-
-
-static inline void ip_rt_put(struct rtable * rt)
-{
-	if (rt)
-		dst_release(&rt->u.dst);
-}
-
-#define IPTOS_RT_MASK	(IPTOS_TOS_MASK & ~3)
-
-extern __u8 ip_tos2prio[16];
-
-static inline char rt_tos2priority(u8 tos)
-{
-	return ip_tos2prio[IPTOS_TOS(tos)>>1];
-}
-
-static inline int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32 tos, int oif)
-{
-	int err;
-	err = ip_route_output(rp, dst, src, tos, oif);
-	if (err || (dst && src))
-		return err;
-	dst = (*rp)->rt_dst;
-	src = (*rp)->rt_src;
-	ip_rt_put(*rp);
-	*rp = NULL;
-	return ip_route_output(rp, dst, src, tos, oif);
-}
-
-extern void rt_bind_peer(struct rtable *rt, int create);
-
-static inline struct inet_peer *rt_get_peer(struct rtable *rt)
-{
-	if (rt->peer)
-		return rt->peer;
-
-	rt_bind_peer(rt, 0);
-	return rt->peer;
-}
-
-#endif	/* _ROUTE_H */
+#endif /* net/route.h */
diff -Naur test-for-latech/include/net/sock.h testqf-for-latech/include/net/sock.h
--- test-for-latech/include/net/sock.h	2004-06-11 07:40:22.000000000 -0400
+++ testqf-for-latech/include/net/sock.h	2004-06-11 07:47:33.000000000 -0400
@@ -678,6 +678,21 @@
   	int			(*backlog_rcv) (struct sock *sk,
 						struct sk_buff *skb);  
 	void                    (*destruct)(struct sock *sk);
+
+	int 			drop_flag;
+	int			urgent_flag;
+	int			fragments;
+#ifdef CONFIG_QFABRIC
+	int 			owner;
+	int 			kecho;
+	void  			*kecho_ptr;
+	short			readable;
+	short			writable;
+	int			fd;
+	int 			counter;
+	long			qos_priority;
+	long			qos_deadline;
+#endif
 };
 
 /* The per-socket spinlock must be held here. */
diff -Naur test-for-latech/include/net/tcp.h testqf-for-latech/include/net/tcp.h
--- test-for-latech/include/net/tcp.h	2004-06-11 07:40:22.000000000 -0400
+++ testqf-for-latech/include/net/tcp.h	2004-06-11 07:47:33.000000000 -0400
@@ -520,6 +520,10 @@
 		struct tcp_v6_open_req v6_req;
 #endif
 	} af;
+#ifdef CONFIG_QFABRIC
+	int	priority;
+	long	deadline_msec;
+#endif
 };
 
 /* SLAB cache for open requests. */
@@ -1590,6 +1594,94 @@
 	req->dl_next = NULL;
 }
 
+#ifdef CONFIG_QFABRIC
+static inline struct sock *tcp_acceptq_queue_prio(struct sock *sk, 
+		struct open_request *req, struct sock *child, int drop)
+{
+	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+	struct open_request *ptr, *prev;
+	struct sock *tmp;
+
+	req->sk = child;
+	sk->qos_priority = req->priority;
+	sk->qos_deadline = req->deadline_msec;
+	child->qos_priority = req->priority;
+	child->qos_deadline = req->deadline_msec;
+
+	if (!tp->accept_queue_tail) {
+		tp->accept_queue = req;
+		tp->accept_queue_tail = req;
+		req->dl_next = NULL;
+	} else {
+		ptr = tp->accept_queue;
+		prev = ptr;
+		if (req->priority >= 0) {
+			while ((ptr != NULL)&&(ptr->priority >= req->priority)) 
+			{
+				prev = ptr;
+				ptr = ptr->dl_next;
+			}
+			if (ptr == NULL) {
+				if ((drop == 1) && (!tcp_acceptq_is_full(sk))) {
+				    tp->accept_queue_tail = req;
+				    req->dl_next = NULL;
+				} else	{
+					tcp_openreq_free(req);
+					return child;
+				}
+			} else {
+				req->dl_next = ptr;
+				prev->dl_next = req;
+				if ((drop == 1) && (tcp_acceptq_is_full(sk))) {
+			            while (ptr != NULL) {
+					ptr = ptr->dl_next;
+					if (ptr != NULL) prev = prev->dl_next;
+				    }
+				    tmp = prev->dl_next->sk;
+				    tcp_openreq_free(prev->dl_next);
+				    prev->dl_next = NULL;
+				    return tmp;
+				}
+			}
+		} else if (req->deadline_msec != -1) {
+			while ((ptr != NULL) && 
+				(ptr->deadline_msec <= req->deadline_msec)) {
+				prev = ptr;
+				ptr = ptr->dl_next;
+			}
+			if (ptr == NULL) {
+				if ((drop == 1) && (!tcp_acceptq_is_full(sk))) {
+					tp->accept_queue_tail = req;
+					req->dl_next = NULL;
+				} else	{
+					tcp_openreq_free(req);
+					return child;
+				}
+			} else {
+				req->dl_next = ptr;
+				prev->dl_next = req;
+				if ((drop == 1) && (tcp_acceptq_is_full(sk))) {
+			            while (ptr != NULL) {
+					ptr = ptr->dl_next;
+					if (ptr != NULL) prev = prev->dl_next;
+				    }
+				    tmp = prev->dl_next->sk;
+				    tcp_openreq_free(prev->dl_next);
+				    prev->dl_next = NULL;
+				    return tmp;
+				}
+			}
+		} else {
+			tp->accept_queue_tail->dl_next = req;
+			tp->accept_queue_tail = req;
+			req->dl_next = NULL;
+		}
+	}
+	tcp_acceptq_added(sk);
+	return NULL;
+}
+#endif
+
 struct tcp_listen_opt
 {
 	u8			max_qlen_log;	/* log_2 of maximal queued SYNs */
@@ -1665,6 +1757,10 @@
 	req->acked = 0;
 	req->ecn_ok = 0;
 	req->rmt_port = skb->h.th->source;
+#ifdef CONFIG_QFABRIC
+	req->priority = -1;
+	req->deadline_msec = -1;
+#endif 
 }
 
 #define TCP_MEM_QUANTUM	((int)PAGE_SIZE)
diff -Naur test-for-latech/include/net/utils.h testqf-for-latech/include/net/utils.h
--- test-for-latech/include/net/utils.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/include/net/utils.h	2004-06-11 07:47:33.000000000 -0400
@@ -0,0 +1,19 @@
+static __inline__ int socket_hash(u32 handle)
+{
+  return handle&0xFF;
+}
+
+
+static __inline__ struct socket *socki_lookup(struct inode *inode)
+{
+	return &inode->u.socket_i;
+}
+
+static __inline__ unsigned dwcs_hash(u32 h)
+{
+    h ^= h>>8;
+    h ^= h>>4;
+    return h&0xF;
+}
+
+
diff -Naur test-for-latech/kernel/diffs testqf-for-latech/kernel/diffs
--- test-for-latech/kernel/diffs	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/kernel/diffs	2004-06-11 07:47:23.000000000 -0400
@@ -0,0 +1,923 @@
+51a52,56
+> #ifdef CONFIG_DWCS_DFS
+> #include <linux/slab.h>
+> #endif
+> 
+> //#define DWCS_DEBUG_ON 1
+81a87,90
+> MODULE_AUTHOR("Georgia Tech -- CoC");
+> MODULE_DESCRIPTION("DWCS Scheduler");
+> MODULE_LICENSE("GPL");
+> 
+117a127,139
+> 
+> #ifdef CONFIG_DWCS_DFS
+> #define MAX_LONG (unsigned long)4294967295
+> unsigned int start_time;
+> struct task_struct *dwcs_hyper_period_task = NULL;
+> unsigned long int dwcs_hyper_period_old_violations = 0;
+> unsigned long int dwcs_hyper_period_old_misses = 0;
+> unsigned long int dwcs_hyper_period_old_idles = 0;
+> unsigned long int dwcs_hyper_period_violations = 0;
+> unsigned long int dwcs_hyper_period_misses = 0;
+> unsigned long int dwcs_hyper_period_idles = 0;
+> int dwcs_hyper_period_task_iterations = 0;
+> int dwcs_hyper_period_task_count = 0;
+118a141,142
+> 
+> #ifdef CONFIG_ARCH_ADIFCC
+122a147,153
+> #endif
+> 
+> #ifdef CONFIG_ARCH_SA1100
+> int current_sa1100_freq;
+> unsigned int sa1100_freq[12] = {59000, 73700, 88500, 103200, 118000, 132700, 147500, 162200, 176900, 191700, 206400, 221200};
+> #endif
+> #endif
+123a155,160
+> /* Needed for delayed runqueue insertion */
+> static int first_dwcs_task = 1;
+> #ifdef CONFIG_DWCS_DFS
+> static int hyper_period_recalc_needed = 0;
+> 
+> #endif
+131a169,188
+> #ifdef DWCS_DEBUG_ON
+> struct proc_dir_entry *proc_dwcs_debug_control;
+> struct proc_dir_entry *proc_dwcs_debug_write;
+> struct proc_dir_entry *proc_time;
+> #endif
+> #ifdef CONFIG_DWCS_DFS
+> struct proc_dir_entry *proc_dwcs_dfs;
+> #endif
+> #ifdef DWCS_DEBUG_ON
+> extern unsigned long dwcs_timer_max_time;
+> extern long dwcs_max_counter;
+> extern long dwcs_pid;
+> extern unsigned long dwcs_sched_max_time;
+> 
+> int DWCS_DEBUG;
+> char *debug_area;
+> int deb_pos;
+> int debug_count;
+> #endif
+> 
+174a232
+> #ifdef CONFIG_DWCS_DFS
+194a253,452
+> #endif
+> 
+> #ifdef CONFIG_DWCS_DFS
+> static int clk2mhz (int n) 
+> {
+> 	switch(n) {
+> 		case 4 : return 400;
+> 		case 5 : return 466;
+> 		case 6 : return 533;
+> 		case 7 : return 600;
+> 		case 8 : return 666;
+> 		case 9 : return 733;
+> 		default: return -1;
+> 	}
+> 
+> 	return 400;
+> }
+> #endif
+> 
+> 
+> #ifdef CONFIG_DWCS_DFS
+> static unsigned long euclid (unsigned long m, unsigned long n) 
+> {
+> 	unsigned long r;
+> 
+> 	r = m % n;
+> 	if (!r) {
+> 		return n;
+> 	}
+> 	return euclid (n, r);
+> }
+> #endif
+> 
+> 
+> #ifdef CONFIG_DWCS_DFS
+> static unsigned long least_common_period (unsigned long x, unsigned long y)
+> {
+> 	return ((x * y) / euclid (x, y));	
+> }
+> #endif
+> 
+> 
+> #ifdef CONFIG_DWCS_DFS
+> static int find_smallest (unsigned long *period, int size)
+> {
+> 	int i;
+> 	int index = -1;
+> 	unsigned long smallest = MAX_LONG;
+> 
+> 	for (i = 0; i < size; i++) {
+> 		if (period[i] < smallest) {
+> 			index = i;
+> 			smallest = period[i];
+> 		}
+> 	}
+> 
+> 	return index;
+> }
+> #endif			
+> 
+> 
+> #ifdef CONFIG_DWCS_DFS
+> static void find_hyper_period_task (void)
+> {
+> 	int i;
+> 	int lcp;
+> 	unsigned long largest_period;
+> 	unsigned long *period;
+> 	int dwcs_task_count;
+> 	int smallest_index;
+> 	struct task_struct *temp;
+> 
+> 	dwcs_task_count = 0;
+> 	largest_period = 0;
+> 	for_each_task (temp) {
+> 		if ((int)temp->dwcs_params->period > 0) {
+> 			dwcs_task_count++;
+> 			if ((int)temp->dwcs_params->period > largest_period) {
+> 				dwcs_hyper_period_task = temp;
+> 				largest_period = temp->dwcs_params->period;
+> 			}
+> 		}
+> 	}
+> 	if (dwcs_task_count == 1)
+> 		start_time = jiffies;
+> 
+> 	period = kmalloc (dwcs_task_count * sizeof (unsigned long), GFP_KERNEL);
+> 	for (i = 0; i < dwcs_task_count; i++)
+> 		period[i] = MAX_LONG;
+> 	i = 0;
+> 	for_each_task (temp) {
+> 		if ((int)temp->dwcs_params->period > 0) {
+> 			period[i] = temp->dwcs_params->period;
+> 			i++;
+> 		}
+> 	}
+> 
+> 	lcp = 1;
+> 	for (i = 0; i < dwcs_task_count; i++) {
+> 		smallest_index = find_smallest (period, dwcs_task_count);
+> 		lcp = least_common_period (lcp, period[smallest_index]);
+> 		period[smallest_index] = MAX_LONG;
+> 	}
+> 
+> 	dwcs_hyper_period_task_iterations = lcp / largest_period;
+> 	dwcs_hyper_period_task_count = 0;
+> 	
+> 
+> 	printk (KERN_DEBUG "Hyper Task PID = %d\tLeast Common Period = %d\n", dwcs_hyper_period_task->pid, lcp);
+> 
+> 	kfree (period);
+> 
+> 	hyper_period_recalc_needed = 0;
+> }
+> #endif
+> 
+> 
+> #ifdef CONFIG_DWCS_DFS
+> void dwcs_dfs_measurements (struct task_struct *p)
+> {
+> 	int misses;
+> 	int violations;
+> 	int idles;
+> 	static int freq_change;
+> 	volatile unsigned int cclkcfg;
+> 
+> 	if (hyper_period_recalc_needed)
+> 		find_hyper_period_task();
+> 
+> 				/* Make any scaling adjustments */
+> 	misses = dwcs_hyper_period_misses - dwcs_hyper_period_old_misses;
+> 	violations = dwcs_hyper_period_violations - dwcs_hyper_period_old_violations;
+> 	idles = dwcs_hyper_period_idles - dwcs_hyper_period_old_idles;
+> 
+> 	freq_change = 0;
+> 	if (violations > 0) {
+> #ifdef CONFIG_ARCH_ADIFCC
+> 		get_80200_CCLKCFG(cclkcfg);
+> 		if (cclkcfg < 9) {
+> 		/*	cclkcfg += violations;	*/
+> 			cclkcfg++;
+> 			if (cclkcfg > 9)
+> 				cclkcfg = 9;
+> 			set_80200_CCLKCFG(cclkcfg);
+> 			freq_change = 1;
+> 		}
+> #endif
+> #ifdef CONFIG_ARCH_SA1100
+> 		if (current_sa1100_freq < 12) {
+> 			current_sa1100_freq++;
+> 			cpufreq_set (sa1100_freq[current_sa1100_freq]);
+> 			freq_change = 1;
+> 		}	
+> #endif
+> 	}
+> 	else if ((misses > 0) && (violations == 0)) {
+> #ifdef CONFIG_ARCH_ADIFCC
+> 	/*
+> 		get_80200_CCLKCFG(cclkcfg);
+> 		if (cclkcfg < 9) {
+> 			cclkcfg++;
+> 			set_80200_CCLKCFG(cclkcfg); 
+> 			freq_change = 1;
+> 		}
+> 	*/
+> #endif
+> #ifdef CONFIG_ARCH_SA1100
+> 
+> #endif
+> 	}
+> 	else if ((violations == 0) && (misses == 0)) {
+> #ifdef CONFIG_ARCH_ADIFCC
+> 		get_80200_CCLKCFG(cclkcfg);
+> 		if (cclkcfg > 4) {
+> 			cclkcfg--;
+> 			set_80200_CCLKCFG(cclkcfg);
+> 			freq_change = 1;
+> 		}
+> #endif
+> #ifdef CONFIG_ARCH_SA1100
+> 		if (current_sa1100_freq > 0) {
+> 			current_sa1100_freq--;
+> 			cpufreq_set (sa1100_freq[current_sa1100_freq]);
+> 			freq_change = 1;
+> 		}
+> #endif
+> 	}
+> 
+> 	if (freq_change) {
+> 		printk (KERN_DEBUG "%lu\t %d\t %d\t %d\t %d\t %d\n", 
+> 				jiffies - start_time, clk2mhz(cclkcfg), violations, misses, idles, utilization);
+> 	}
+> 						
+> 	dwcs_hyper_period_old_violations = dwcs_hyper_period_violations;
+> 	dwcs_hyper_period_old_idles = dwcs_hyper_period_idles;
+> 	dwcs_hyper_period_old_misses = dwcs_hyper_period_misses;
+> 
+> }
+> #endif
+> 
+196c454,540
+< /* calculates max. possble slowdown and calls do_set_slowest_cpuspeed */
+---
+> #ifdef CONFIG_DWCS_DFS
+> void dwcs_dfs_theoretical (void)
+> {
+> #ifdef CONFIG_ARCH_ADIFCC
+> 	unsigned int freq_matrix[6][6] = {{1000,  857,  749,  666,  599,  545},
+> 			    	 	  {1166, 1000,  874,  777,  699,  636},
+> 			    	 	  {1333, 1142, 1000,  888,  799,  727},
+> 			    	 	  {1500, 1285, 1125, 1000,  899,  818},
+> 			    	 	  {1666, 1428, 1250, 1111, 1000,  909},
+> 			    	 	  {1832, 1570, 1373, 1221, 1099, 1000}};
+> 	volatile unsigned int cclkcfg;
+> #endif
+> #ifdef CONFIG_ARCH_SA1100
+> 	unsigned int freq_matrix[12][12] = {
+> 		{1000,  792,  649,  552,  480,  425,  381,  343,  314,  289,  268,  268},
+> 		{1262, 1000,  820,  697,  606,  536,  481,  433,  396,  365,  339,  339},
+> 		{1538, 1219, 1000,  850,  739,  654,  587,  528,  483,  445,  413,  413},
+> 		{1809, 1433, 1175, 1000,  869,  769,  690,  621,  568,  524,  486,  486},
+> 		{2080, 1648, 1351, 1149, 1000,  884,  793,  714,  653,  602,  559,  559},
+> 		{2352, 1863, 1528, 1299, 1130, 1000,  897,  807,  739,  681,  632,  632},
+> 		{2621, 2077, 1703, 1448, 1260, 1114, 1000,  899,  823,  759,  704,  704},
+> 		{2913, 2308, 1893, 1609, 1400, 1238, 1111, 1000,  915,  844,  783,  783},
+> 		{3182, 2521, 2067, 1758, 1529, 1353, 1213, 1092, 1000,  922,  855,  855},
+> 		{3451, 2734, 2242, 1907, 1659, 1467, 1316, 1184, 1084, 1000,  928,  928},
+> 		{3719, 2947, 2416, 2055, 1787, 1581, 1418, 1276, 1168, 1077, 1000, 1000},
+> 		{3719, 2947, 2416, 2055, 1787, 1581, 1418, 1276, 1168, 1077,  999, 1000}};
+> 
+> #endif
+> 
+> 	
+> 	int i;
+> 	int closest_freq = -1;
+> 	int smallest_difference;
+> 	int current_freq;
+> 	int k_entries;
+> 
+> 	smallest_difference = MAX_UTILIZATION;
+> 
+> #ifdef CONFIG_ARCH_SA1100
+> 	current_freq = 11;
+> 	k_entries = 12;
+> #endif
+> #ifdef CONFIG_ARCH_ADIFCC
+> 	current_freq = 5;
+> 	k_entries = 6;
+> #endif
+> 	
+> 	for (i = 0; i < k_entries; i++) {
+> 		int temp_utilization;
+> 		 
+> 		temp_utilization = (utilization * freq_matrix[current_freq][i]);
+> 		temp_utilization = temp_utilization / 1000;
+> 		temp_utilization = (MAX_UTILIZATION - reserved_utilization) - temp_utilization;
+> 		if ((temp_utilization >= 0) && (temp_utilization < smallest_difference)) {
+> 			smallest_difference = temp_utilization;
+> 			closest_freq = i;
+> 		}
+> 		/*
+> 		printk (KERN_DEBUG "U = %d\t M = %d\t TU = %d\t SD = %d\n", utilization, freq_matrix[current_freq][i],
+> 				temp_utilization, smallest_difference);
+> 		*/
+> 	}
+> 
+> 	if (closest_freq > 0) {
+> #ifdef CONFIG_ARCH_ADIFCC
+> 		closest_freq += 4;
+> 		get_80200_CCLKCFG(cclkcfg);
+> 		if ((unsigned)closest_freq != cclkcfg) {
+> 			cclkcfg = (unsigned) closest_freq;
+> 			set_80200_CCLKCFG (cclkcfg);
+> 			printk (KERN_DEBUG "%ld\t %ld\n", JIFFIES - start_time, clk2mhz (cclkcfg));
+> 		}
+> #endif
+> #ifdef CONFIG_ARCH_SA1100
+> 		if (cpufreq_get(0) != sa1100_freq[closest_freq]) {
+> 			cpufreq_set (sa1100_freq[closest_freq]);
+> 		}
+> #endif
+> 	}
+> 
+> 	return;
+> }
+> #endif
+> 
+> 
+> #ifdef CONFIG_DWCS_DFS
+> /* calculates max. possible slowdown and calls do_set_slowest_cpuspeed */
+205a550
+> #endif
+241a587,640
+> #ifdef DWCS_DEBUG_ON
+> static int proc_dwcs_debug_c_read(char *page, char **start, off_t off,				  int count, int *eof, void *data){
+>   int len;
+>   MOD_INC_USE_COUNT;
+>   len = sprintf(page, "%d\n", DWCS_DEBUG);
+>   MOD_DEC_USE_COUNT;
+>   return len;
+> }
+> 
+> static int proc_dwcs_debug_c_write(struct file *file, const char *buffer, unsigned long count, void *data){
+>   unsigned char value;
+>   MOD_INC_USE_COUNT;
+> 
+>   if(copy_from_user(&value, buffer, 1)){
+>     MOD_DEC_USE_COUNT;
+>     return -EFAULT;
+>   }
+>   if(value == '0'){
+>     if(DWCS_DEBUG == 1){
+>       kfree(debug_area);
+>     }
+>     DWCS_DEBUG = 0;
+>     printk("Disabling verbose debugging!\n");
+>   }
+>   else if(value == '1'){
+>       DWCS_DEBUG = 1;
+>       deb_pos = 0;
+>       debug_count = 0;
+>       debug_area = (char *)kmalloc(50*sizeof(char *)*100, GFP_KERNEL);
+>       memset(debug_area, '\0', sizeof(debug_area));
+>       printk("Enabling verbose debugging!\n");
+>   }
+> 
+>   MOD_DEC_USE_COUNT;
+> 
+>   return 1;
+> }
+> 
+> int proc_dwcs_debug_info_read(char *buf, char **start, off_t offset, int len, int *eof, void *data){
+>   len = 0;
+>   len += sprintf(buf+len,  "pid   deadline   current time   period   own   owd   cwn   cwd   flags   ready_time   service_time   time_serviced   wlate   late   on_time   violation\n");
+>   /* len += sprintf(buf+len, "%s\n", debug_area); */
+>   len += strlen(strncat(buf+len, debug_area, 500*100*sizeof(char *)));
+>   return len;
+> }
+> 
+> int proc_time_read(char *buf, char **start, off_t offset, int len, int *eof, void *data){
+>   len = 0;
+>   len += sprintf(buf+len, "pid %ld\ntimer time %lu\ncounter %lu\nsched %lu\n", dwcs_pid, dwcs_timer_max_time, dwcs_max_counter, dwcs_sched_max_time);
+>   dwcs_sched_max_time = 0;
+>   return len;
+> }
+> #endif
+> 		  
+279a679,695
+> #ifdef CONFIG_DWCS_DFS
+> static int proc_dwcs_dfs_read (char *page, char **start, off_t off,
+> 					int count, int *eof, void *data)
+> {
+> 	int len;
+> 	volatile unsigned int cclkcfg;
+> 	
+> 	MOD_INC_USE_COUNT;
+> 	get_80200_CCLKCFG(cclkcfg);
+> 	len = sprintf (page, "\tFrequency = %d\n\tMisses = %ld\n\tViolations = %ld\n\tIdles = %ld\n", 
+> 			cclkcfg, dwcs_hyper_period_misses, dwcs_hyper_period_violations, dwcs_hyper_period_idles);
+> 	MOD_DEC_USE_COUNT;
+> 	return len;
+> }
+> #endif
+> 
+> 
+340a757,903
+> 
+> 
+> 
+> static void runqueue_insert (struct dwcs_sched_param sp, int first_dwcs_process)
+> {
+> #ifdef CONFIG_DWCS_DFS
+> 	volatile unsigned int cclkcfg;
+> #endif
+> 	struct task_struct *p;
+> 
+> 
+> 	if (sp.pid < 0)
+> 		goto runqueue_out_nounlock;
+> 
+> 	/*
+> 	 * We play safe to avoid deadlocks.
+> 	 */
+> 	read_lock_irq(&tasklist_lock);
+> 	spin_lock(&runqueue_lock);
+> 
+> 	p = find_task_by_pid(sp.pid);
+> 
+> #ifdef CONFIG_QFABRIC
+> 	if ((DWCS_module_loaded) && (DWCS_admission_control)) {
+> 		printk (KERN_DEBUG "Requesting admission!\n");
+> 		/* --FS-- is this shortcut leagl? */
+> 		if (DWCS_request_admission(p, &sp) < 0)
+> 			goto runqueue_out_unlock;
+> 	}
+> #endif
+> 
+> 	if (!p)
+> 		goto runqueue_out_unlock;
+> 	if (sp.policy < 0)
+> 		sp.policy = p->policy;
+> 	else {
+> 		if (sp.policy != SCHED_FIFO && sp.policy != SCHED_RR &&
+> 		    sp.policy != SCHED_OTHER && sp.policy != SCHED_DWCS)
+> 			goto runqueue_out_unlock;
+> 	}
+> 
+> 		/* Begin of DWCS specific handling */
+> 	if (sp.policy == SCHED_DWCS) {
+> 		/* --CP--
+> 		 * Set flag for computation of utilization.
+> 		 */
+> 		DWCS_update_utilization = 1;
+> 
+> 		/* Check ranges of scheduling parameters. */
+> 		/* The following should never be true, since `own' and `owd'
+> 		 * are `unsigned'. */
+> 		if ((sp.own < 0) || (sp.owd < 0))
+> 			goto runqueue_out_unlock;
+> 
+> 		/* Restrict who can set scheduling parameters. */
+> 		if (!capable(CAP_SYS_NICE))
+> 			goto runqueue_out_unlock;
+> 
+> 		/*
+> 		 * --RW--
+> 		 * Should really set p->policy = SCHED_DWCS, so that
+> 		 * sched_setparam() works with DWCS. But, if we no
+> 		 * longer use DWCS, we need to set p->policy to SCHED_OTHER.
+> 		 */
+> 		p->dwcs_params->period = sp.period;
+> 		p->dwcs_params->own    = sp.own;
+> 		p->dwcs_params->owd    = sp.owd;
+> 		if (sp.period == (unsigned long)-1) {
+> 			p->dwcs_params->deadline   = (unsigned long)-1;
+> 			p->dwcs_params->flags     |= DWCS_WORK_CONS;
+> 			p->dwcs_params->ready_time = 0;
+> 		}
+> 		else {
+> 			if (first_dwcs_process) {
+> 				p->dwcs_params->deadline   = jiffies + sp.period;
+> 				p->dwcs_params->ready_time = jiffies;
+> 			}
+> 			else {
+> #ifdef CONFIG_DWCS_DFS
+> 				unsigned long new_ready_time;
+> 				
+> 	                        new_ready_time = dwcs_hyper_period_task->dwcs_params->deadline;
+> 	                        while ((new_ready_time - sp.period) > JIFFIES)
+> 		                	new_ready_time -= sp.period;
+> 	                        p->dwcs_params->ready_time = new_ready_time;
+> 	                        p->dwcs_params->deadline = new_ready_time + sp.period;
+> 				hyper_period_recalc_needed = 1;
+> #else
+> 	                        p->dwcs_params->ready_time = jiffies;
+> 	                        p->dwcs_params->deadline = p->dwcs_params->ready_time 
+> 					+ sp.period;
+> #endif
+> 			}			
+> 			if (sp.flags & DWCS_WORK_CONS)
+> 				p->dwcs_params->flags   |= DWCS_WORK_CONS;
+> 			else
+> 				p->dwcs_params->flags   &= ~DWCS_WORK_CONS;
+> 		}
+> 
+> 		if (sp.flags & DWCS_NON_PREEMPTIVE)
+> 			p->dwcs_params->flags |= DWCS_NON_PREEMPTIVE;
+> 		else if (sp.flags == 0) 
+> 			p->dwcs_params->flags &= ~(DWCS_WORK_CONS | DWCS_NON_PREEMPTIVE);
+> 
+> 		p->dwcs_params->service_time = sp.service_time;
+> 		p->dwcs_params->cwn          = sp.own;
+> 		p->dwcs_params->cwd          = sp.owd;
+> 
+> 		if (task_on_runqueue(p))
+> 			move_first_runqueue(p);
+> 		current->need_resched = 1;
+> 			
+> 
+> 		goto runqueue_out_unlock;
+> 	}
+> 	/* End of DWCS specific handling */
+> 
+> 	/*
+> 	 * Valid priorities for SCHED_FIFO and SCHED_RR are 1..99, valid
+> 	 * priority for SCHED_OTHER is 0.
+> 	 */
+> 	if (sp.sched_priority < 0 || sp.sched_priority > 99)
+> 		goto runqueue_out_unlock;
+> 	if ((sp.policy == SCHED_OTHER) != (sp.sched_priority == 0))
+> 		goto runqueue_out_unlock;
+> 
+> 	if ((sp.policy == SCHED_FIFO || sp.policy == SCHED_RR) && !capable(CAP_SYS_NICE))
+> 		goto runqueue_out_unlock;
+> 	if ((current->euid != p->euid) && (current->euid != p->uid) && !capable(CAP_SYS_NICE))
+> 		goto runqueue_out_unlock;
+> 
+> 	p->policy = sp.policy;
+> 	p->rt_priority = sp.sched_priority;
+> 	if (task_on_runqueue(p))
+> 		move_first_runqueue(p);
+> 
+> 	current->need_resched = 1;
+> runqueue_out_unlock:
+> 	spin_unlock(&runqueue_lock);
+> 	read_unlock_irq(&tasklist_lock);
+> 
+> runqueue_out_nounlock:
+> 	return;
+> }
+> 
+> 
+> 
+349d911
+< 	printk(KERN_DEBUG "IOCTL called\n");
+377d938
+< 
+388,389c949,950
+< 	case 1: /* set the schedule paramteres for given pid */
+< 		retval = -EFAULT;
+---
+> 		/* Here is where the new DWCS tasks come to be added to the runqueue */
+> 	case 1: 
+391,411c952,959
+< 			goto out_nounlock;
+< 
+< 		retval = -EINVAL;
+< 		if (sp.pid < 0)
+< 			goto out_nounlock;
+< 
+< 		/*
+< 		 * We play safe to avoid deadlocks.
+< 		 */
+< 		read_lock_irq(&tasklist_lock);
+< 		spin_lock(&runqueue_lock);
+< 
+< 		p = find_task_by_pid(sp.pid);
+< 
+< #ifdef CONFIG_QFABRIC
+< 		if ((DWCS_module_loaded) && (DWCS_admission_control)) {
+< 			retval = -EADMISSION;
+< 			/* --FS-- is this shortcut leagl? */
+< 			if (DWCS_request_admission(p, &sp) < 0)
+< 				goto out_unlock;
+< 		}
+---
+> 			return -EINVAL;	
+> 	
+> 		
+> 			/* If this is the first DWCS task, add it to the runqueue immediately */
+> 		if (first_dwcs_task) {
+> 			runqueue_insert (sp, 1);
+> #ifdef CONFIG_DWCS_DFS
+> 			find_hyper_period_task();	
+413,424c961,962
+< 
+< 		retval = -ESRCH;
+< 		if (!p)
+< 			goto out_unlock;
+< 
+< 		if (sp.policy < 0)
+< 			sp.policy = p->policy;
+< 		else {
+< 			retval = -EINVAL;
+< 			if (sp.policy != SCHED_FIFO && sp.policy != SCHED_RR &&
+< 			    sp.policy != SCHED_OTHER && sp.policy != SCHED_DWCS)
+< 				goto out_unlock;
+---
+> 			first_dwcs_task = 0;
+> 			return 0;
+426,486c964,968
+< 
+< 		/* Begin of DWCS specific handling */
+< 		if (sp.policy == SCHED_DWCS) {
+< 
+< 			/* --CP--
+< 			 * Set flag for computation of utilization.
+< 			 */
+< 			DWCS_update_utilization = 1;
+< 
+< 			/* Check ranges of scheduling parameters. */
+< 			retval = -EINVAL;
+< 
+< 			/* The following should never be true, since `own' and `owd'
+< 			 * are `unsigned'. */
+< 			if ((sp.own < 0) || (sp.owd < 0))
+< 				goto out_unlock;
+< 
+< 			/* Restrict who can set scheduling parameters. */
+< 			retval = -EPERM;
+< 			if (!capable(CAP_SYS_NICE))
+< 				goto out_unlock;
+< 
+< 			retval = 0;
+< 			/*
+< 			 * --RW--
+< 			 * Should really set p->policy = SCHED_DWCS, so that
+< 			 * sched_setparam() works with DWCS. But, if we no
+< 			 * longer use DWCS, we need to set p->policy to SCHED_OTHER.
+< 			 */
+< 			p->dwcs_params->period = sp.period;
+< 			p->dwcs_params->own    = sp.own;
+< 			p->dwcs_params->owd    = sp.owd;
+< 			if (sp.period == (unsigned long)-1) {
+< 				p->dwcs_params->deadline   = (unsigned long)-1;
+< 				p->dwcs_params->flags     |= DWCS_WORK_CONS;
+< 				p->dwcs_params->ready_time = 0;
+< 			}
+< 			else {
+< 				p->dwcs_params->deadline   = jiffies + sp.period;
+< 				p->dwcs_params->ready_time = jiffies;
+< 				if (sp.flags & DWCS_WORK_CONS)
+< 					p->dwcs_params->flags   |= DWCS_WORK_CONS;
+< 				else
+< 					p->dwcs_params->flags   &= ~DWCS_WORK_CONS;
+< 			}
+< 
+< 			if (sp.flags & DWCS_NON_PREEMPTIVE)
+< 				p->dwcs_params->flags     |= DWCS_NON_PREEMPTIVE;
+< 			else if (sp.flags == 0) /* Reset. */
+< 				p->dwcs_params->flags     &= ~(DWCS_WORK_CONS |
+< 							       DWCS_NON_PREEMPTIVE);
+< 
+< 			p->dwcs_params->service_time = sp.service_time;
+< 			p->dwcs_params->cwn          = sp.own;
+< 			p->dwcs_params->cwd          = sp.owd;
+< 
+< 			if (task_on_runqueue(p))
+< 				move_first_runqueue(p);
+< 			current->need_resched = 1;
+< 
+< 			goto out_unlock;
+---
+> 			/* If it is not the first DWCS task, delay its entry */
+> 		else {
+> 			runqueue_insert (sp, 0);
+> 			
+> 			return 0;
+488,521c970
+< 		/* End of DWCS specific handling */
+< 
+< 		/*
+< 		 * Valid priorities for SCHED_FIFO and SCHED_RR are 1..99, valid
+< 		 * priority for SCHED_OTHER is 0.
+< 		 */
+< 		retval = -EINVAL;
+< 		if (sp.sched_priority < 0 || sp.sched_priority > 99)
+< 			goto out_unlock;
+< 		if ((sp.policy == SCHED_OTHER) != (sp.sched_priority == 0))
+< 			goto out_unlock;
+< 
+< 		retval = -EPERM;
+< 		if ((sp.policy == SCHED_FIFO || sp.policy == SCHED_RR) &&
+< 		    !capable(CAP_SYS_NICE))
+< 			goto out_unlock;
+< 		if ((current->euid != p->euid) && (current->euid != p->uid) &&
+< 		    !capable(CAP_SYS_NICE))
+< 			goto out_unlock;
+< 
+< 		retval = 0;
+< 		p->policy = sp.policy;
+< 		p->rt_priority = sp.sched_priority;
+< 		if (task_on_runqueue(p))
+< 			move_first_runqueue(p);
+< 
+< 		current->need_resched = 1;
+< 
+< out_unlock:
+< 		spin_unlock(&runqueue_lock);
+< 		read_unlock_irq(&tasklist_lock);
+< 
+< out_nounlock:
+< 		return retval;
+---
+> 		
+547a997
+>  	DWCS_admission_control = 1;	
+570a1021,1049
+> #ifdef DWCS_DEBUG_ON
+> 	proc_dwcs_debug_control = create_proc_entry("debugging_control", 0644, 
+> 		proc_dwcs_dir);
+> 	proc_dwcs_debug_control->owner = THIS_MODULE;
+> 	proc_dwcs_debug_control->write_proc = proc_dwcs_debug_c_write;
+> 	proc_dwcs_debug_control->read_proc = proc_dwcs_debug_c_read;
+> 	
+> 	proc_dwcs_debug_write = create_proc_read_entry("debug_info", 0444, 
+> 		proc_dwcs_dir, proc_dwcs_debug_info_read, NULL);
+> 	proc_dwcs_debug_write->owner = THIS_MODULE;
+> 	proc_time = create_proc_read_entry("time", 0444, proc_dwcs_dir, proc_time_read,
+> 		NULL);
+> 	proc_time->owner = THIS_MODULE;
+> #endif
+> 
+> #ifdef CONFIG_DWCS_DFS
+> 	proc_dwcs_dfs = create_proc_entry("dfs", 0444, proc_dwcs_dir);
+> 	proc_dwcs_dfs->owner = THIS_MODULE;
+> 	proc_dwcs_dfs->read_proc = proc_dwcs_dfs_read;
+> 
+> #ifdef CONFIG_ARCH_SA1100
+> 	current_sa1100_freq = 0;
+> 	do {
+> 		if (cpufreq_get(0) == sa1100_freq[current_sa1100_freq]) break;
+> 		current_sa1100_freq++;
+> 	} while (current_sa1100_freq < 16);
+> #endif	
+> #endif
+> 	
+588a1068,1077
+> 	utilization = 0;
+> 
+> #ifdef DWCS_DEBUG_ON
+> 	if (DWCS_DEBUG) {
+> 		kfree(debug_area);
+> 	}
+> 	remove_proc_entry("time", proc_dwcs_dir);
+> 	remove_proc_entry("debug_info", proc_dwcs_dir);
+> 	remove_proc_entry("debugging_control", proc_dwcs_dir);
+> #endif
+593a1083,1085
+> #ifdef CONFIG_DWCS_DFS
+> 	remove_proc_entry("dfs", proc_dwcs_dir);
+> #endif
+681,683c1173,1178
+< 			/* printk (KERN_DEBUG "(%d) Deadline missed!\n",
+< 			   p->dwcs_params->cd); */
+< 
+---
+> 			/*
+> 			printk (KERN_DEBUG "(%d) Deadline missed! %d\n", p->dwcs_params->cd, JIFFIES - p->dwcs_params->deadline);
+> 			*/
+> #ifdef CONFIG_DWCS_DFS
+> 			dwcs_hyper_period_misses++;
+> #endif
+693,694c1188,1193
+< 					/*printk (KERN_DEBUG "(%d) VIOLATION!\n",
+< 					  p->dwcs_params->cd);*/
+---
+> #ifdef CONFIG_DWCS_DFS
+> 					dwcs_hyper_period_violations++;
+> #endif
+> 					/*
+> 					printk (KERN_DEBUG "(%d) VIOLATION!\n", p->dwcs_params->cd);
+> 					*/
+699a1199
+> 			p->dwcs_params->ready_time += p->dwcs_params->period;
+775c1275
+< 			if (p->dwcs_params->deadline != (unsigned long)-1)
+---
+> 			if (p->dwcs_params->deadline != (unsigned long)-1) {
+776a1277,1288
+> #ifdef CONFIG_DWCS_DFS
+> 				/*
+> 				if (p == dwcs_hyper_period_task) {
+> 					dwcs_hyper_period_task_count++;
+> 					if (dwcs_hyper_period_task_count == dwcs_hyper_period_task_iterations) {
+> 						dwcs_dfs_measurements (p);
+> 						dwcs_hyper_period_task_count = 0;
+> 					}
+> 				}
+> 				*/
+> #endif
+> 			}
+784,787c1296
+< 		if (((p->dwcs_params->on_time +
+< 		      p->dwcs_params->late) %
+< 		     p->dwcs_params->owd) == 0) {
+< 
+---
+> 		if (((p->dwcs_params->on_time + p->dwcs_params->late) % p->dwcs_params->owd) == 0) {
+789a1299,1301
+> #ifdef CONFIG_DWCS_DFS
+> 				dwcs_hyper_period_violations++;
+> #endif
+794a1307,1311
+> 	}
+> #ifdef DWCS_DEBUG_ON
+> 	if (DWCS_DEBUG && (p->dwcs_params->deadline != -1) && (debug_count < 50)) {
+> 		char tmp[100];
+> 		sprintf(tmp, "%d   %ld   %ld   %ld   %d   %d   %d   %d   %d   %ld   %ld   %ld   %d   %ld   %ld   %ld\n", p->pid, p->dwcs_params->deadline, JIFFIES, p->dwcs_params->period, p->dwcs_params->own, p->dwcs_params->owd, p->dwcs_params->cwn, p->dwcs_params->cwd, p->dwcs_params->flags, p->dwcs_params->ready_time, p->dwcs_params->service_time, p->dwcs_params->time_serviced, p->dwcs_params->wlate, p->dwcs_params->late, p->dwcs_params->on_time, p->dwcs_params->violations);
+795a1313
+> 		strcat(debug_area, tmp);
+796a1315
+> #endif
+828c1347
+< 	if ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+---
+> 	/* if ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+831a1351,1353
+> 	*/
+> 	if ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+> 		(p->dwcs_params->deadline == (unsigned long) -1)) {
+894c1416
+< 	    ((utilization - old_utilization + new_utilization) > MAX_UTILIZATION))
+---
+> 	    ((utilization - old_utilization + new_utilization) > (MAX_UTILIZATION - reserved_utilization)))
+897d1418
+< 
+915a1437,1440
+> 		printk (KERN_DEBUG "Utilization now %d\n", utilization);
+> #ifdef CONFIG_DWCS_DFS
+> 		dwcs_dfs_theoretical();
+> #endif
+917a1443,1449
+> #ifdef CONFIG_DWCS_DFS
+> 			/*
+> 			if (tptr == dwcs_hyper_period_task) {
+> 				find_hyper_period_task();
+> 			}
+> 			*/
+> #endif
+921a1454,1456
+> #ifdef CONFIG_DWCS_DFS			
+> 			dwcs_dfs_theoretical();
+> #endif
+939a1475
+> 
+1032a1569
+> 	
+1096c1633
+< 		if (can_schedule(p, this_cpu))
+---
+> 		if (can_schedule(p, this_cpu)) {
+1097a1635,1642
+> 		}
+> #ifdef DWCS_DEBUG_ON
+> 		else {
+> 			char tmp[100];
+> 			sprintf(tmp, "no csc\n%d   %ld   %ld   %ld   %d   %d   %d   %d   %d   %ld   %ld   %ld   %d   %ld   %ld   %ld\n", p->pid, p->dwcs_params->deadline, JIFFIES, p->dwcs_params->period, p->dwcs_params->own, p->dwcs_params->owd, p->dwcs_params->cwn, p->dwcs_params->cwd, p->dwcs_params->flags, p->dwcs_params->ready_time, p->dwcs_params->service_time, p->dwcs_params->time_serviced, p->dwcs_params->wlate, p->dwcs_params->late, p->dwcs_params->on_time, p->dwcs_params->violations);
+> 			strcat(debug_area, tmp);
+> 		}
+> #endif
+1113a1659,1666
+> #ifdef DWCS_DEBUG_ON
+> 	if (DWCS_DEBUG && (debug_count < 50)) {
+> 		char tmp[5];
+> 		debug_count++;
+> 		sprintf(tmp, "%d\n", p->pid);
+> 		strcat(debug_area, tmp);
+> 	}
+> #endif
+1140a1694,1698
+> #ifdef CONFIG_DWCS_DFS
+> 	if (next == idle_task(this_cpu)) {
+> 		dwcs_hyper_period_idles++;
+> 	}
+> #endif
+1147a1706
+> /*
+1161d1719
+< 		/* set to default processor speed */
+1164c1722
+< 
+---
+> */
+1172d1729
+< 
diff -Naur test-for-latech/kernel/dwcs.c testqf-for-latech/kernel/dwcs.c
--- test-for-latech/kernel/dwcs.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/kernel/dwcs.c	2004-06-11 07:47:23.000000000 -0400
@@ -0,0 +1,1933 @@
+/*
+ *   linux/dwcs/dwcs.c
+ *
+ *   Copyright (C) 1999 Rich West
+ *
+ *   1999-10-26 Modified by Ivan Ganev <ganev@cc.gatech.edu> (along with a
+ *              bunch of other files) to make DWCS SMP-safe.
+ */
+
+/*
+ *   DWCS kernel-loadable module.
+ */
+
+/* Required definitions. */
+#ifndef MODULE
+#define MODULE
+#endif
+#ifndef __KERNEL__
+#define __KERNEL__
+#endif
+
+/* Various required header files. */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/utsname.h>
+#include <linux/tqueue.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/unistd.h>
+#include <asm/segment.h>
+
+#include <linux/mm.h>
+#include <linux/kernel_stat.h>
+#include <linux/fdreg.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/smp_lock.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+
+#include <linux/timex.h>
+#include <linux/signal.h>
+
+#ifdef CONFIG_DWCS_DFS
+#include <linux/slab.h>
+#include <linux/cpufreq.h>
+#endif
+
+//#define DWCS_DEBUG_ON 1
+
+#if HZ < 200
+#define TICK_SCALE(x)	((x) >> 2)
+#elif HZ < 400
+#define TICK_SCALE(x)	((x) >> 1)
+#elif HZ < 800
+#define TICK_SCALE(x)	(x)
+#elif HZ < 1600
+#define TICK_SCALE(x)	((x) << 1)
+#else
+#define TICK_SCALE(x)	((x) << 2)
+#endif
+
+#define NICE_TO_TICKS(nice)	(TICK_SCALE(20-(nice))+1)
+
+/*
+ * GANEV: nasty bug here... definitions for idle_task and can_schedule
+ *        depend ALOT on whether we're an SMP kernel or not...
+ */
+#ifdef CONFIG_SMP
+#define idle_task(cpu) (init_tasks[cpu_number_map(cpu)])
+#define can_schedule(p,cpu)	((p)->cpus_runnable & \
+				(p)->cpus_allowed & (1 << cpu))
+#else
+#define idle_task(cpu) (&init_task)
+#define can_schedule(p,cpu) (1)
+#endif
+
+#define LIMIT (PAGE_SIZE-80)   /* Set limit on amount of data in /proc/dwcs. */
+
+MODULE_AUTHOR("Georgia Tech -- CoC");
+MODULE_DESCRIPTION("DWCS Scheduler");
+MODULE_LICENSE("GPL");
+
+/* Prototypes. */
+int init_module(void);
+void cleanup_module(void);
+void my_printk(char *string);
+void (*_dummy_update_utilization)(void);
+void (*_dummy_request_admission)(void);
+
+extern void (*DWCS_scheduler)(struct task_struct **, struct task_struct **);
+void DWCS_schedule(struct task_struct **, struct task_struct **);
+void do_update_utilization(int flag, struct task_struct *tptr);
+int DWCS_request_admission(struct task_struct *tptr,struct dwcs_sched_param *param);
+
+extern void *sys_call_table[];
+extern int DWCS_module_loaded;
+extern struct list_head runqueue_head;
+extern int DWCS_update_utilization;
+extern int utilization;
+extern int nr_running;
+extern unsigned long volatile jiffies_sim;
+//#ifdef CONFIG_QFABRIC
+extern int DWCS_admission_control;
+extern int call_admission_control(struct task_struct *, struct sched_param *);
+//#endif
+
+/* Power saving related definitions */
+#define DWCS_EM_NORMAL                0x00000000 /* No DFS,DVS done by dwcs */
+#define DWCS_EM_AVERAGE_CONSERVATIVE  0x00000001 /* Averaging proc. speed without missed deadlines */
+#define DWCS_EM_AVERAGE_AGGRESSIVE    0x00000002 /* Averaging proc. speed with max missed deadlines */
+#define DWCS_EM_ADAPTIVE_CONSERVATIVE 0x00000003 /* Individual proc. speed without missed deadlines */
+#define DWCS_EM_ADAPTIVE_AGGRESSIVE   0x00000004 /* Individual proc. speed with max missed deadlines */
+int energy_mode; /* Initially non power saving mode */
+int reserved_utilization = MAX_UTILIZATION / 10; /* How much of MAX_UTILIZATION should be reserved for non DWCS proc. */
+int av_cons_utilization(void); /* Calculates the utilization if no deadline is missed */
+int av_aggr_utilization(void); /* Calculates the utilization with max possible missed deadlines */
+int ad_cons_utilization(void);
+int ad_aggr_utilization(void);
+
+#ifdef CONFIG_DWCS_DFS
+#define DWCS_MODE_VMI 0
+#define DWCS_MODE_THEORETICAL 1
+#endif
+#define MAX_PER (unsigned long)999999
+unsigned int start_time;
+struct task_struct *dwcs_hyper_period_task = NULL;
+unsigned long int dwcs_hyper_period_old_violations = 0;
+unsigned long int dwcs_hyper_period_old_misses = 0;
+unsigned long int dwcs_hyper_period_old_idles = 0;
+unsigned long int dwcs_hyper_period_violations = 0;
+unsigned long int dwcs_hyper_period_misses = 0;
+unsigned long int dwcs_hyper_period_idles = 0;
+int dwcs_hyper_period_task_iterations = 0;
+int dwcs_hyper_period_task_count = 0;
+static int hyper_period_recalc_needed = 0;
+#ifdef CONFIG_DWCS_DFS
+void set_slowest_cpuspeed(struct task_struct *); /* Sets cpu to slowest speed possible */
+
+#ifdef CONFIG_ARCH_ADIFCC
+#define get_80200_CCLKCFG(out)   asm volatile("mrc P14, 0, %0, c6, c0, 0" : \
+                                                  "=r"(out))
+#define set_80200_CCLKCFG(val)   asm volatile("mcr P14, 0, %0, c6, c0, 0" : \
+                                                  : "r"(val))
+#endif
+
+#ifdef CONFIG_ARCH_SA1100
+int current_sa1100_freq;
+unsigned int sa1100_freq[12] = {59000, 73700, 88500, 103200, 118000, 132700, 147500, 162200, 176900, 191700, 206400, 221200};
+#endif
+#endif
+
+/* Variable to determine which mode the scheduler is running in */
+int DWCS_module_mode;
+
+/* Needed for delayed runqueue insertion */
+static int first_dwcs_task = 1;
+#ifdef CONFIG_DWCS_DFS
+struct proc_dir_entry *proc_dwcs_dfs;
+struct proc_dir_entry *proc_dwcs_mode;
+struct proc_dir_entry *proc_freq_entry;
+#endif
+
+struct proc_dir_entry *proc_dwcs_dir;
+struct proc_dir_entry *proc_dwcs_enabled;
+struct proc_dir_entry *proc_dwcs_info;
+struct proc_dir_entry *proc_dwcs_energy_mode;
+struct proc_dir_entry *proc_dwcs_control;
+#ifdef DWCS_DEBUG_ON
+struct proc_dir_entry *proc_dwcs_debug_control;
+struct proc_dir_entry *proc_dwcs_debug_write;
+struct proc_dir_entry *proc_time;
+
+extern unsigned long dwcs_timer_max_time;
+extern long dwcs_max_counter;
+extern long dwcs_pid;
+extern unsigned long dwcs_sched_max_time;
+
+int DWCS_DEBUG;
+char *debug_area;
+int deb_pos;
+int debug_count;
+#endif
+
+
+#ifdef SIM_MODE
+#define JIFFIES jiffies_sim
+#else
+#define JIFFIES jiffies
+#endif
+
+#define DWCS_SERVICED_THIS_PERIOD 0x10000000
+
+
+/*
+ * Careful!
+ *
+ * This has to add the process to the _beginning_ of the
+ * run-queue, not the end. See the comment about "This is
+ * subtle" in the scheduler proper..
+ */
+static inline void add_to_runqueue(struct task_struct * p)
+{
+	list_add(&p->run_list, &runqueue_head);
+	nr_running++;
+}
+
+static inline void move_last_runqueue(struct task_struct * p)
+{
+	list_del(&p->run_list);
+	list_add_tail(&p->run_list, &runqueue_head);
+}
+
+static inline void move_first_runqueue(struct task_struct * p)
+{
+	list_del(&p->run_list);
+	list_add(&p->run_list, &runqueue_head);
+}
+
+#ifdef CONFIG_DWCS_DFS
+/* Resets cpu to default clockrate */
+void set_default_cpuspeed(void)
+{
+#ifdef CONFIG_ARCH_ADIFCC
+	set_80200_CCLKCFG(9);
+#endif
+#ifdef CONFIG_ARCH_SA1100
+	cpufreq_set (sa1100_freq[10]);
+#endif
+}
+#endif
+
+#ifdef CONFIG_DWCS_DFS
+/* Calculates real clockrate and changes cpu register */
+void do_set_slowest_cpuspeed(int speedup)
+{
+#ifdef CONFIG_ARCH_ADIFCC
+	int clockrate = 733;
+	clockrate = clockrate * 100 / speedup;
+	if (clockrate < 400)
+		set_80200_CCLKCFG(4);
+	else if (clockrate < 466)
+		set_80200_CCLKCFG(5);
+	else if (clockrate < 533)
+		set_80200_CCLKCFG(6);
+	else if (clockrate < 600)
+		set_80200_CCLKCFG(7);
+	else if (clockrate < 666)
+		set_80200_CCLKCFG(8);
+	else
+		set_80200_CCLKCFG(9);
+#endif
+#ifdef CONFIG_ARCH_SA1100
+	int clockrate = 206;
+	clockrate = clockrate * 100 / speedup;
+	if (clockrate < 59)
+		cpufreq_set (sa1100_freq[0]);
+	else if (clockrate < 73)
+		cpufreq_set (sa1100_freq[1]);
+	else if (clockrate < 88)
+		cpufreq_set (sa1100_freq[2]);
+	else if (clockrate < 103)
+		cpufreq_set (sa1100_freq[3]);
+	else if (clockrate < 118)
+		cpufreq_set (sa1100_freq[4]);
+	else if (clockrate < 132)
+		cpufreq_set (sa1100_freq[5]);
+	else if (clockrate < 147)
+		cpufreq_set (sa1100_freq[6]);
+	else if (clockrate < 162)
+		cpufreq_set (sa1100_freq[7]);
+	else if (clockrate < 176)
+		cpufreq_set (sa1100_freq[8]);
+	else if (clockrate < 191)
+		cpufreq_set (sa1100_freq[9]);
+	else if (clockrate < 207)
+		cpufreq_set (sa1100_freq[10]);
+	else 
+		cpufreq_set (sa1100_freq[11]);
+#endif
+}
+#endif
+
+#ifdef CONFIG_DWCS_DFS
+static int clk2mhz (int n) 
+{
+	switch(n) {
+		case 4 : return 400;
+		case 5 : return 466;
+		case 6 : return 533;
+		case 7 : return 600;
+		case 8 : return 666;
+		case 9 : return 733;
+		default: return -1;
+	}
+
+	return 400;
+}
+#endif
+
+static unsigned long euclid (unsigned long m, unsigned long n) 
+{
+	unsigned long r;
+
+	r = m % n;
+	if (!r) {
+		return n;
+	}
+	return euclid (n, r);
+}
+
+static unsigned long least_common_period (unsigned long x, unsigned long y)
+{
+	return ((x * y) / euclid (x, y));	
+}
+
+static int find_smallest (unsigned long *period, int size)
+{
+	int i;
+	int index = -1;
+	unsigned long smallest = MAX_PER;
+
+	for (i = 0; i < size; i++) {
+		if (period[i] < smallest) {
+			index = i;
+			smallest = period[i];
+		}
+	}
+
+	return index;
+}
+
+static void find_hyper_period_task (int flag)
+{
+	int i;
+	int lcp;
+	unsigned long largest_period;
+	unsigned long *period;
+	int dwcs_task_count;
+	int smallest_index;
+	struct task_struct *temp;
+
+	dwcs_hyper_period_task = NULL;
+	dwcs_task_count = 0;
+	largest_period = 0;
+	for_each_task (temp) {
+	    if ((flag == 1) && (current == temp)) {
+	    } else {
+		if ((temp->dwcs_params->deadline != (unsigned long)-1) && 
+			((int)temp->dwcs_params->period > 0)) {
+			dwcs_task_count++;
+			if ((int)temp->dwcs_params->period > largest_period) {
+				dwcs_hyper_period_task = temp;
+				largest_period = temp->dwcs_params->period;
+			}
+		}
+	    }
+	}
+
+   	if (dwcs_task_count == 0) {
+		printk (KERN_DEBUG "No Hyper Period Task\n");
+		first_dwcs_task = 1;
+		hyper_period_recalc_needed = 0;
+		return;
+	}
+
+	if (dwcs_task_count == 1)
+		start_time = jiffies;
+
+	period = kmalloc (dwcs_task_count * sizeof (unsigned long), GFP_KERNEL);
+	for (i = 0; i < dwcs_task_count; i++)
+		period[i] = MAX_PER;
+	i = 0;
+	for_each_task (temp) {
+		if ((temp->dwcs_params->deadline != (unsigned int)-1) && 
+			((int)temp->dwcs_params->period > 0)) {
+			period[i] = temp->dwcs_params->period;
+			i++;
+		}
+	}
+
+	lcp = 1;
+	for (i = 0; i < dwcs_task_count; i++) {
+		smallest_index = find_smallest (period, dwcs_task_count);
+		lcp = least_common_period (lcp, period[smallest_index]);
+		period[smallest_index] = MAX_PER;
+	}
+
+	dwcs_hyper_period_task_iterations = lcp / largest_period;
+	dwcs_hyper_period_task_count = 0;
+	
+	printk (KERN_DEBUG "Hyper Task PID = %d\tLeast Common Period = %d\n", dwcs_hyper_period_task->pid, lcp);
+
+	kfree (period);
+
+	hyper_period_recalc_needed = 0;
+}
+
+
+#ifdef CONFIG_DWCS_DFS
+void dwcs_dfs_measurements (struct task_struct *p)
+{
+	int misses;
+	int violations;
+	int idles;
+	static int freq_change;
+	volatile unsigned int cclkcfg;
+	siginfo_t si;
+
+	misses = dwcs_hyper_period_misses - dwcs_hyper_period_old_misses;
+	violations = dwcs_hyper_period_violations - dwcs_hyper_period_old_violations;
+	idles = dwcs_hyper_period_idles - dwcs_hyper_period_old_idles;
+
+	freq_change = 0;
+
+#ifdef CONFIG_ARCH_ADIFCC
+	if (violations > 0) {
+		get_80200_CCLKCFG(cclkcfg);
+		if (cclkcfg < 9) {
+			cclkcfg++;
+			if (cclkcfg > 9)
+				cclkcfg = 9;
+			set_80200_CCLKCFG(cclkcfg);
+			freq_change = 1;
+		}
+	} else if ((misses > 0) && (violations == 0)) {
+	} else if ((violations == 0) && (misses == 0)) {
+		get_80200_CCLKCFG(cclkcfg);
+		if (cclkcfg > 4) {
+			cclkcfg--;
+			set_80200_CCLKCFG(cclkcfg);
+			freq_change = 1;
+		}
+	}
+#endif
+#ifdef CONFIG_ARCH_SA1100
+	if ((violations > 0) || (idles < 1)) {
+		if (current_sa1100_freq < 11) {
+			current_sa1100_freq++;
+			si.si_signo = SIGUSR1;
+			si.si_errno = 0;
+			si.si_code = SI_KERNEL;
+			send_sig_info(SIGUSR1, &si, p);
+			//cpufreq_set (sa1100_freq[current_sa1100_freq]);
+			freq_change = 1;
+		}	
+	} else if ((misses == 0) && (violations == 0) && (idles > 0)) {
+		if (current_sa1100_freq > 0) {
+			current_sa1100_freq++;
+			si.si_signo = SIGUSR1;
+			si.si_errno = 0;
+			si.si_code = SI_KERNEL;
+			send_sig_info(SIGUSR2, &si, p);
+			current_sa1100_freq--;
+			//cpufreq_set (sa1100_freq[current_sa1100_freq]);
+			freq_change = 1;
+		}
+	}	
+#endif
+
+	if (freq_change) {
+		printk (KERN_DEBUG "%lu\t %d\t %d\t %d\t %d\t %d\n", 
+				jiffies - start_time, clk2mhz(cclkcfg), violations, 
+				misses, idles, utilization);
+	}
+						
+	dwcs_hyper_period_old_violations = dwcs_hyper_period_violations;
+	dwcs_hyper_period_old_idles = dwcs_hyper_period_idles;
+	dwcs_hyper_period_old_misses = dwcs_hyper_period_misses;
+
+}
+#endif
+
+
+#ifdef CONFIG_DWCS_DFS
+void dwcs_dfs_theoretical (void)
+{
+#ifdef CONFIG_ARCH_ADIFCC
+	unsigned int freq_matrix[6][6] = {{1000,  857,  749,  666,  599,  545},
+			    	 	  {1166, 1000,  874,  777,  699,  636},
+			    	 	  {1333, 1142, 1000,  888,  799,  727},
+			    	 	  {1500, 1285, 1125, 1000,  899,  818},
+			    	 	  {1666, 1428, 1250, 1111, 1000,  909},
+			    	 	  {1832, 1570, 1373, 1221, 1099, 1000}};
+	volatile unsigned int cclkcfg;
+#endif
+#ifdef CONFIG_ARCH_SA1100
+	unsigned int freq_matrix[12][12] = {
+		{1000,  792,  649,  552,  480,  425,  381,  343,  314,  289,  268,  268},
+		{1262, 1000,  820,  697,  606,  536,  481,  433,  396,  365,  339,  339},
+		{1538, 1219, 1000,  850,  739,  654,  587,  528,  483,  445,  413,  413},
+		{1809, 1433, 1175, 1000,  869,  769,  690,  621,  568,  524,  486,  486},
+		{2080, 1648, 1351, 1149, 1000,  884,  793,  714,  653,  602,  559,  559},
+		{2352, 1863, 1528, 1299, 1130, 1000,  897,  807,  739,  681,  632,  632},
+		{2621, 2077, 1703, 1448, 1260, 1114, 1000,  899,  823,  759,  704,  704},
+		{2913, 2308, 1893, 1609, 1400, 1238, 1111, 1000,  915,  844,  783,  783},
+		{3182, 2521, 2067, 1758, 1529, 1353, 1213, 1092, 1000,  922,  855,  855},
+		{3451, 2734, 2242, 1907, 1659, 1467, 1316, 1184, 1084, 1000,  928,  928},
+		{3719, 2947, 2416, 2055, 1787, 1581, 1418, 1276, 1168, 1077, 1000, 1000},
+		{3719, 2947, 2416, 2055, 1787, 1581, 1418, 1276, 1168, 1077,  999, 1000}};
+
+#endif
+
+	
+	int i;
+	int closest_freq = -1;
+	int smallest_difference;
+	int current_freq;
+	int k_entries;
+
+	if (hyper_period_recalc_needed) {
+		find_hyper_period_task(0);
+	}
+
+	smallest_difference = MAX_UTILIZATION;
+
+#ifdef CONFIG_ARCH_SA1100
+	current_freq = 11;
+	k_entries = 12;
+#endif
+#ifdef CONFIG_ARCH_ADIFCC
+	current_freq = 5;
+	k_entries = 6;
+#endif
+	
+	for (i = 0; i < k_entries; i++) {
+		int temp_utilization;
+		 
+		temp_utilization = (utilization * freq_matrix[current_freq][i]);
+		temp_utilization = temp_utilization / 1000;
+		temp_utilization = (MAX_UTILIZATION - reserved_utilization) - temp_utilization;
+		if ((temp_utilization >= 0) && (temp_utilization < smallest_difference)) {
+			smallest_difference = temp_utilization;
+			closest_freq = i;
+		}
+		printk (KERN_DEBUG "U = %d\t M = %d\t TU = %d\t SD = %d\n", utilization, freq_matrix[current_freq][i],
+				temp_utilization, smallest_difference);
+	}
+
+	if (closest_freq > 0) {
+#ifdef CONFIG_ARCH_ADIFCC
+		closest_freq += 4;
+		get_80200_CCLKCFG(cclkcfg);
+		if ((unsigned)closest_freq != cclkcfg) {
+			cclkcfg = (unsigned) closest_freq;
+			set_80200_CCLKCFG (cclkcfg);
+			printk (KERN_DEBUG "%ld\t %ld\n", JIFFIES - start_time, clk2mhz (cclkcfg));
+		}
+#endif
+#ifdef CONFIG_ARCH_SA1100
+		if (cpufreq_get(0) != sa1100_freq[closest_freq]) {
+			cpufreq_set (sa1100_freq[closest_freq]);
+		}
+#endif
+	}
+
+	return;
+}
+#endif
+
+#ifdef CONFIG_DWCS_DFS
+/* calculates max. possible slowdown and calls do_set_slowest_cpuspeed */
+void set_slowest_cpuspeed(struct task_struct *p)
+{
+	int max_slowdown;
+	max_slowdown = 100 * (p->dwcs_params->deadline - JIFFIES) / p->dwcs_params->service_time;
+	if (max_slowdown < p->dwcs_params->cpu_speedup) {
+		p->dwcs_params->cpu_speedup = max_slowdown;
+	}
+	do_set_slowest_cpuspeed(p->dwcs_params->cpu_speedup);
+}
+#endif
+
+static int proc_dwcs_enabled_read (char *page, char **start, off_t off,
+				   int count, int *eof, void *data)
+{
+  int len;
+  MOD_INC_USE_COUNT;
+  len = sprintf(page, "%d\n", DWCS_module_loaded);
+  MOD_DEC_USE_COUNT;
+  return len;
+}
+
+static int proc_dwcs_enabled_write (struct file *file, const char *buffer,
+				    unsigned long count, void *data)
+{
+	unsigned char value;
+	MOD_INC_USE_COUNT;
+
+	if (copy_from_user(&value, buffer, 1)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+
+	if (value == '0') {
+		DWCS_module_loaded = 0;
+		printk (KERN_DEBUG "Disabling DWCS!\n");
+	}
+	else if (value == '1') {
+		DWCS_module_loaded = 1;
+		printk (KERN_DEBUG "Enabling DWCS!\n");
+	}
+
+	MOD_DEC_USE_COUNT;
+
+	return 1;
+}
+
+#ifdef CONFIG_DWCS_DFS
+static int proc_dwcs_mode_read (char *page, char **start, off_t off, int count, 
+		int *eof, void *data)
+{
+	int len;
+
+	MOD_INC_USE_COUNT;
+	len = sprintf(page, "%d\n", DWCS_module_mode);
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+static int proc_dwcs_mode_write (struct file *file, const char *buffer, unsigned long
+		counter, void *data)
+{
+	unsigned char value;
+	
+	MOD_INC_USE_COUNT;
+	if (copy_from_user(&value, buffer, 1)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+
+	if (value == '0') {
+		DWCS_module_mode = DWCS_MODE_VMI;
+		printk (KERN_DEBUG "DWCS mode now VMI!\n");
+		find_hyper_period_task(0);
+	} else if (value == '1') {
+		DWCS_module_mode = DWCS_MODE_THEORETICAL;
+		printk (KERN_DEBUG "DWCS mode now theoretical!\n");
+		dwcs_dfs_theoretical();
+	}
+
+	MOD_DEC_USE_COUNT;
+
+	return 1;
+}
+#endif
+
+#ifdef DWCS_DEBUG_ON
+static int proc_dwcs_debug_c_read(char *page, char **start, off_t off,				  int count, int *eof, void *data){
+  int len;
+  MOD_INC_USE_COUNT;
+  len = sprintf(page, "%d\n", DWCS_DEBUG);
+  MOD_DEC_USE_COUNT;
+  return len;
+}
+
+static int proc_dwcs_debug_c_write(struct file *file, const char *buffer, unsigned long count, void *data){
+  unsigned char value;
+  MOD_INC_USE_COUNT;
+
+  if(copy_from_user(&value, buffer, 1)){
+    MOD_DEC_USE_COUNT;
+    return -EFAULT;
+  }
+  if(value == '0'){
+    if(DWCS_DEBUG == 1){
+      kfree(debug_area);
+    }
+    DWCS_DEBUG = 0;
+    printk("Disabling verbose debugging!\n");
+  }
+  else if(value == '1'){
+      DWCS_DEBUG = 1;
+      deb_pos = 0;
+      debug_count = 0;
+      debug_area = (char *)kmalloc(50*sizeof(char *)*100, GFP_KERNEL);
+      memset(debug_area, '\0', sizeof(debug_area));
+      printk("Enabling verbose debugging!\n");
+  }
+
+  MOD_DEC_USE_COUNT;
+
+  return 1;
+}
+
+int proc_dwcs_debug_info_read(char *buf, char **start, off_t offset, int len, int *eof, void *data){
+  len = 0;
+  len += sprintf(buf+len,  "pid   deadline   current time   period   own   owd   cwn   cwd   flags   ready_time   service_time   time_serviced   wlate   late   on_time   violation\n");
+  /* len += sprintf(buf+len, "%s\n", debug_area); */
+  len += strlen(strncat(buf+len, debug_area, 500*100*sizeof(char *)));
+  memset(debug_area, '\0', sizeof(debug_area));
+  debug_count = 0;
+  return len;
+}
+
+int proc_time_read(char *buf, char **start, off_t offset, int len, int *eof, void *data){
+  len = 0;
+  len += sprintf(buf+len, "pid %ld\ntimer time %lu\ncounter %lu\nsched %lu\n", dwcs_pid, dwcs_timer_max_time, dwcs_max_counter, dwcs_sched_max_time);
+  dwcs_sched_max_time = 0;
+  return len;
+}
+#endif
+		  
+int proc_dwcs_info_read (char *buf, char **start, off_t offset, int len,
+			 int *eof, void *data)
+{
+
+	struct list_head *tmp;
+	struct task_struct * p;
+
+	len = 0;
+
+	len += sprintf (buf+len, "  pid name     deadline   period     own   "
+			"owd   cwn   cwd   viols      late       on-time    "
+			"flags srv-time(x10mS) state\n");
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (len > LIMIT)
+			return len;
+
+		len += sprintf (buf+len,
+				"%5d %-8.8s %-10ld %-10ld %-5d %-5d %-5d %-5d "
+				"%-10lu %-10lu %-10lu %-5x %-15lu %-5ld\n",
+				p->pid,
+				p->comm,
+				p->dwcs_params->deadline,
+				p->dwcs_params->period,
+				p->dwcs_params->own,
+				p->dwcs_params->owd,
+				p->dwcs_params->cwn,
+				p->dwcs_params->cwd,
+				p->dwcs_params->violations,
+				p->dwcs_params->late,
+				p->dwcs_params->on_time,
+				p->dwcs_params->flags,
+				p->dwcs_params->service_time,
+				p->state);
+	}
+	return len;
+}
+
+#ifdef CONFIG_DWCS_DFS
+static int proc_dwcs_dfs_read (char *page, char **start, off_t off,
+					int count, int *eof, void *data)
+{
+	int len;
+#ifdef CONFIG_ARCH_ADIFCC
+	volatile unsigned int cclkcfg = 0;
+#endif
+	
+	MOD_INC_USE_COUNT;
+#ifdef CONFIG_ARCH_ADIFCC
+	get_80200_CCLKCFG(cclkcfg);
+	len = sprintf (page, "\tFreq.level = %d\n\tMisses = %ld\n\tViolations = %ld\n\tIdles = %ld\n\tUtilization = %d\n", 
+			cclkcfg, 
+			dwcs_hyper_period_misses, dwcs_hyper_period_violations, 
+			dwcs_hyper_period_idles, utilization);
+#endif
+#ifdef CONFIG_ARCH_SA1100
+	len = sprintf (page, "\tFreq.level = %d\n\tFrequency=%d\n\tMisses = %ld\n\tViolations = %ld\n\tIdles = %ld\n\tUtilization = %d\n", 
+			current_sa1100_freq, (int)sa1100_freq[current_sa1100_freq],
+			dwcs_hyper_period_misses, dwcs_hyper_period_violations, 
+			dwcs_hyper_period_idles, utilization);
+
+#endif
+	MOD_DEC_USE_COUNT;
+	return len;
+}
+#endif
+
+
+static int proc_dwcs_energy_mode_read (char *page, char **start, off_t off,
+				       int count, int *eof, void *data)
+{
+	int len;
+	MOD_INC_USE_COUNT;
+	len = sprintf(page, "%d\n", energy_mode);
+	MOD_DEC_USE_COUNT;
+	return len;
+}
+
+static int proc_dwcs_energy_mode_write (struct file *file, const char *buffer,
+					unsigned long count, void *data)
+{
+	unsigned char value;
+	MOD_INC_USE_COUNT;
+
+	if (copy_from_user(&value, buffer, 1)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+
+	if ((value >= '0') && (value < '5')) {
+		energy_mode = value - '0';
+		printk (KERN_DEBUG "Changed DWCS energy mode to %d!\n", energy_mode);
+	}
+
+	MOD_DEC_USE_COUNT;
+
+	return 1;
+}
+
+static int proc_dwcs_control_read(struct file *file, char *buf, size_t nbytes,
+				  loff_t *ppos)
+{
+	int len, left;
+	char msg[255];
+
+	MOD_INC_USE_COUNT;
+	len = sprintf(msg, "%s", "This node provides an ioctl to read and set the schedule parameters of processes using dwcs\n");
+
+	if (!access_ok(VERIFY_WRITE, buf, len)) {
+		MOD_DEC_USE_COUNT;
+		return -EINVAL;
+	}
+
+	left = len - *ppos;
+	if (nbytes > left) nbytes = left;
+	if (nbytes == 0) {
+		MOD_DEC_USE_COUNT;
+		return 0;
+	}
+	if (copy_to_user(buf, msg + *ppos, nbytes)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+
+	MOD_DEC_USE_COUNT;
+	*ppos += nbytes;
+	return nbytes;
+}
+
+static void runqueue_insert (struct dwcs_sched_param sp, int first_dwcs_process)
+{
+	struct task_struct *p;
+
+
+	if (sp.pid < 0)
+		goto runqueue_out_nounlock;
+
+	/*
+	 * We play safe to avoid deadlocks.
+	 */
+	read_lock_irq(&tasklist_lock);
+	spin_lock(&runqueue_lock);
+
+	p = find_task_by_pid(sp.pid);
+
+	if ((DWCS_module_loaded) && (DWCS_admission_control)) {
+		if (DWCS_request_admission(p, &sp) < 0)
+			goto runqueue_out_unlock;
+	}
+
+	if (!p)
+		goto runqueue_out_unlock;
+	if (sp.policy < 0)
+		sp.policy = p->policy;
+	else {
+		if (sp.policy != SCHED_FIFO && sp.policy != SCHED_RR &&
+		    sp.policy != SCHED_OTHER && sp.policy != SCHED_DWCS)
+			goto runqueue_out_unlock;
+	}
+
+		/* Begin of DWCS specific handling */
+	if (sp.policy == SCHED_DWCS) {
+		/* --CP--
+		 * Set flag for computation of utilization.
+		 */
+		DWCS_update_utilization = 1;
+
+		/* Check ranges of scheduling parameters. */
+		/* The following should never be true, since `own' and `owd'
+		 * are `unsigned'. */
+		if ((sp.own < 0) || (sp.owd < 0))
+			goto runqueue_out_unlock;
+
+		/* Restrict who can set scheduling parameters. */
+		if (!capable(CAP_SYS_NICE))
+			goto runqueue_out_unlock;
+
+		/*
+		 * --RW--
+		 * Should really set p->policy = SCHED_DWCS, so that
+		 * sched_setparam() works with DWCS. But, if we no
+		 * longer use DWCS, we need to set p->policy to SCHED_OTHER.
+		 */
+	
+		p->dwcs_params->period = sp.period;
+		p->dwcs_params->own    = sp.own;
+		p->dwcs_params->owd    = sp.owd;
+		if (sp.period == (unsigned long)-1) {
+			p->dwcs_params->deadline   = (unsigned long)-1;
+			p->dwcs_params->flags     |= DWCS_WORK_CONS;
+			p->dwcs_params->ready_time = 0;
+		}
+		else {
+			if (first_dwcs_process) {
+				p->dwcs_params->deadline   = jiffies + sp.period;
+				p->dwcs_params->ready_time = jiffies;
+			}
+			else {
+#ifdef CONFIG_DWCS_DFS
+				unsigned long new_ready_time;
+				
+	                        new_ready_time = dwcs_hyper_period_task->dwcs_params->deadline;
+	                        while ((new_ready_time - sp.period) > JIFFIES)
+		                	new_ready_time -= sp.period;
+	                        p->dwcs_params->ready_time = new_ready_time;
+	                        p->dwcs_params->deadline = new_ready_time + sp.period;
+				hyper_period_recalc_needed = 1;
+#else
+	                        p->dwcs_params->ready_time = jiffies;
+	                        p->dwcs_params->deadline = p->dwcs_params->ready_time 
+					+ sp.period;
+#endif
+			}			
+			if (sp.flags & DWCS_WORK_CONS)
+				p->dwcs_params->flags   |= DWCS_WORK_CONS;
+			else
+				p->dwcs_params->flags   &= ~DWCS_WORK_CONS;
+		}
+
+		if (sp.flags & DWCS_NON_PREEMPTIVE)
+			p->dwcs_params->flags |= DWCS_NON_PREEMPTIVE;
+		else if (sp.flags == 0) 
+			p->dwcs_params->flags &= ~(DWCS_WORK_CONS | DWCS_NON_PREEMPTIVE);
+
+		p->dwcs_params->service_time = sp.service_time;
+		p->dwcs_params->cwn          = sp.own;
+		p->dwcs_params->cwd          = sp.owd;
+
+		if (task_on_runqueue(p))
+			move_first_runqueue(p);
+		current->need_resched = 1;
+			
+
+		goto runqueue_out_unlock;
+	}
+	/* End of DWCS specific handling */
+
+	/*
+	 * Valid priorities for SCHED_FIFO and SCHED_RR are 1..99, valid
+	 * priority for SCHED_OTHER is 0.
+	 */
+	if (sp.sched_priority < 0 || sp.sched_priority > 99)
+		goto runqueue_out_unlock;
+	if ((sp.policy == SCHED_OTHER) != (sp.sched_priority == 0))
+		goto runqueue_out_unlock;
+
+	if ((sp.policy == SCHED_FIFO || sp.policy == SCHED_RR) && !capable(CAP_SYS_NICE))
+		goto runqueue_out_unlock;
+	if ((current->euid != p->euid) && (current->euid != p->uid) && !capable(CAP_SYS_NICE))
+		goto runqueue_out_unlock;
+
+	p->policy = sp.policy;
+	p->rt_priority = sp.sched_priority;
+	if (task_on_runqueue(p))
+		move_first_runqueue(p);
+
+	current->need_resched = 1;
+runqueue_out_unlock:
+	spin_unlock(&runqueue_lock);
+	read_unlock_irq(&tasklist_lock);
+
+runqueue_out_nounlock:
+	return;
+}
+
+static int proc_dwcs_control_ioctl(struct inode *inode, struct file *file, 
+				   unsigned int cmd, unsigned long arg)
+{
+	struct dwcs_sched_param sp;
+	struct task_struct *p;
+	int retval = 0;
+
+
+	switch (_IOC_NR(cmd)) {
+	case 0: /* return the schedule parameters for given pid */
+		retval = -EFAULT;
+		if (copy_from_user(&sp, (unsigned long *)arg, 
+			sizeof(struct dwcs_sched_param)))
+			goto out_nounlock_0;
+		retval = -EINVAL;
+		if (sp.pid < 0)
+			goto out_nounlock_0;
+		/*
+		 * We play safe to avoid deadlocks.
+		 */
+		read_lock_irq(&tasklist_lock);
+		spin_lock(&runqueue_lock);
+		p = find_task_by_pid(sp.pid);
+
+		if (!p)
+			goto out_unlock_0;
+
+		sp.policy = p->policy;
+		sp.sched_priority = p->rt_priority;
+		sp.period = p->dwcs_params->period;
+		sp.own = p->dwcs_params->own;
+		sp.owd = p->dwcs_params->owd;
+		sp.flags = p->dwcs_params->flags;
+		sp.service_time = p->dwcs_params->service_time;
+
+		copy_to_user((unsigned long *)arg, &sp, sizeof(struct dwcs_sched_param));
+
+		retval = 0;
+
+out_unlock_0:
+		spin_unlock(&runqueue_lock);
+		read_unlock_irq(&tasklist_lock);
+
+out_nounlock_0:
+		return retval;
+
+
+	case 1: 
+		if(copy_from_user(&sp, (unsigned long *)arg, 
+			sizeof(struct dwcs_sched_param)))
+			return -EINVAL;	
+
+		if (first_dwcs_task) {
+			runqueue_insert(sp, 1);
+			find_hyper_period_task(0);
+			first_dwcs_task = 0;
+			return 0;
+		}
+		else {
+			read_lock_irq(&tasklist_lock);
+			p = find_task_by_pid(sp.pid);
+			if ((p) && (p->dwcs_params->period != (unsigned long)-1)) {
+				printk (KERN_DEBUG "Task exists! Update parameters!\n");
+				p->dwcs_params->period = sp.period;
+				p->dwcs_params->own = sp.own;
+				p->dwcs_params->owd = sp.owd;
+				p->dwcs_params->flags = sp.flags;
+				p->dwcs_params->service_time = sp.service_time;
+				spin_unlock(&runqueue_lock);
+				read_unlock_irq(&tasklist_lock);
+
+				do_update_utilization(0, NULL);
+				find_hyper_period_task(0);
+			} else {
+				read_unlock_irq(&tasklist_lock);
+				printk(KERN_DEBUG "New task...\n");
+				runqueue_insert(sp, 0);
+			}
+	
+			return 0;
+		}
+
+	default:
+		return -ENOIOCTLCMD;
+	}
+}
+
+static struct file_operations proc_dwcs_control_operations = {
+	read:	proc_dwcs_control_read,
+	ioctl:	proc_dwcs_control_ioctl,
+};
+
+#ifdef CONFIG_DWCS_DFS
+static int proc_read_freq(char *page, char **start, off_t off, int count,
+	int *eof, void *data) {
+	int len;
+	int clk_rate = 0;
+#ifdef CONFIG_ARCH_ADIFCC
+	int cclkcfg = 0;
+#endif
+	
+	MOD_INC_USE_COUNT;
+#ifdef CONFIG_ARCH_SA1100
+	clk_rate = (int) cpufreq_get (0);
+#endif
+#ifdef CONFIG_ARCH_ADIFCC
+	get_80200_CCLKCFG(cclkcfg);
+	clk_rate = (int) cclkcfg;
+#endif
+	len = sprintf(page, "%d\n", clk_rate);
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+static int proc_write_freq(struct file *file, const char *buffer,
+	unsigned long count, void *data) {
+	int clk_rate;
+	unsigned char kbuffer;
+	
+	MOD_INC_USE_COUNT;
+	if (copy_from_user(&kbuffer, buffer, 1)) {
+		MOD_DEC_USE_COUNT;
+		return -EFAULT;
+	}
+
+#ifdef CONFIG_ARCH_SA1100
+	if (kbuffer == '0') { clk_rate = sa1100_freq[0]; 
+		current_sa1100_freq = 0; }
+	else if (kbuffer == '1') { clk_rate = sa1100_freq[1]; 
+		current_sa1100_freq = 1; }
+	else if (kbuffer == '2') { clk_rate = sa1100_freq[2]; 
+		current_sa1100_freq = 2; }
+	else if (kbuffer == '3') { clk_rate = sa1100_freq[3]; 
+		current_sa1100_freq = 3; }
+	else if (kbuffer == '4') { clk_rate = sa1100_freq[4]; 
+		current_sa1100_freq = 4; }
+	else if (kbuffer == '5') { clk_rate = sa1100_freq[5]; 
+		current_sa1100_freq = 5; }
+	else if (kbuffer == '6') { clk_rate = sa1100_freq[6]; 
+		current_sa1100_freq = 6; }
+	else if (kbuffer == '7') { clk_rate = sa1100_freq[7]; 
+		current_sa1100_freq = 7; }
+	else if (kbuffer == '8') { clk_rate = sa1100_freq[8]; 
+		current_sa1100_freq = 8; }
+	else if (kbuffer == '9') { clk_rate = sa1100_freq[9]; 
+		current_sa1100_freq = 9; }
+	else if (kbuffer == 'A') { clk_rate = sa1100_freq[10]; 
+		current_sa1100_freq = 10; }
+	else if (kbuffer == 'B') { clk_rate = sa1100_freq[11]; 
+		current_sa1100_freq = 11; }
+	else {	
+		MOD_DEC_USE_COUNT;
+		return 1;
+	}
+	printk (KERN_DEBUG "[IPAQ-FREQ] Frequency now %d KHz!\n", clk_rate);
+	cpufreq_set((unsigned int) clk_rate);
+#endif
+#ifdef CONFIG_ARCH_ADIFCC
+	if (kbuffer == '4') { clk_rate = 4;
+	} else if (kbuffer == '5') { clk_rate = 5; 
+	} else if (kbuffer == '6') { clk_rate = 6; 
+	} else if (kbuffer == '7') { clk_rate = 7; 
+	} else if (kbuffer == '8') { clk_rate = 8; 
+	} else if (kbuffer == '9') { clk_rate = 9; 
+	} else {
+		printk("Invalid CCLKCF setting!\n");
+		MOD_DEC_USE_COUNT;
+		return 1;
+	}
+	if (clk_rate < 4 || clk_rate > 9) {
+		printk("Invalid cclkcfg setting: %d (Valid = 4,5,6,7,8,9)\n", 
+			clk_rate);
+	} else {
+		set_80200_CCLKCFG(cclkcfg);
+		get_80200_CCLKCFG(cclkcfg);
+		printk("Clock rate now %d (%d MHz)\n", cclkcfg, ((cclkcfg+2)*200)/3);
+	}
+#endif
+	MOD_DEC_USE_COUNT;
+	return 1;
+}
+#endif
+
+/* Initialize module. */
+int init_module(void)
+{
+	/* Store original dummy functions for system calls. */
+	_dummy_update_utilization    = sys_call_table[__NR_update_utilization-
+		__NR_SYSCALL_BASE];
+	_dummy_request_admission     = sys_call_table[__NR_admission_control-
+		__NR_SYSCALL_BASE];
+
+	/* Redirect  syscall table entries to the syscall fns in this module. */
+	DWCS_scheduler = DWCS_schedule;
+	sys_call_table[__NR_update_utilization-__NR_SYSCALL_BASE] = do_update_utilization;
+	sys_call_table[__NR_admission_control-__NR_SYSCALL_BASE] = DWCS_request_admission;
+	DWCS_admission_control = 1;
+
+	proc_dwcs_dir = proc_mkdir("dwcs", NULL);
+	proc_dwcs_dir->owner = THIS_MODULE;
+
+	proc_dwcs_enabled = create_proc_entry("enabled", 0644, proc_dwcs_dir);
+	proc_dwcs_enabled->owner = THIS_MODULE;
+	proc_dwcs_enabled->read_proc = proc_dwcs_enabled_read;
+	proc_dwcs_enabled->write_proc = proc_dwcs_enabled_write;
+
+	proc_dwcs_info = create_proc_read_entry("info", 0444, proc_dwcs_dir,
+						proc_dwcs_info_read, NULL);
+	proc_dwcs_info->owner = THIS_MODULE;
+
+	proc_dwcs_energy_mode = create_proc_entry("energy_mode", 0644, proc_dwcs_dir);
+	proc_dwcs_energy_mode->owner = THIS_MODULE;
+	proc_dwcs_energy_mode->read_proc = proc_dwcs_energy_mode_read;
+	proc_dwcs_energy_mode->write_proc = proc_dwcs_energy_mode_write;
+
+	proc_dwcs_control = create_proc_entry("control", 0444, proc_dwcs_dir);
+	proc_dwcs_control->owner = THIS_MODULE;
+	proc_dwcs_control->proc_fops = &proc_dwcs_control_operations;
+
+#ifdef DWCS_DEBUG_ON
+	proc_dwcs_debug_control = create_proc_entry("debugging_control", 0644,
+		proc_dwcs_dir);
+	proc_dwcs_debug_control->owner = THIS_MODULE;
+	proc_dwcs_debug_control->write_proc = proc_dwcs_debug_c_write;
+	proc_dwcs_debug_control->read_proc = proc_dwcs_debug_c_read;
+
+	proc_dwcs_debug_write = create_proc_read_entry("debug_info", 0444,
+		proc_dwcs_dir, proc_dwcs_debug_info_read, NULL);
+	proc_dwcs_debug_write->owner = THIS_MODULE;
+	proc_time = create_proc_read_entry("time", 0444, proc_dwcs_dir, proc_time_read,
+		NULL);
+	proc_time->owner = THIS_MODULE;
+#endif
+
+#ifdef CONFIG_DWCS_DFS
+	DWCS_module_mode = DWCS_MODE_VMI;
+	//DWCS_module_mode = DWCS_MODE_THEORETICAL;
+	proc_dwcs_mode = create_proc_entry("mode", 0444, proc_dwcs_dir);
+	proc_dwcs_mode->owner = THIS_MODULE;
+	proc_dwcs_mode->read_proc = proc_dwcs_mode_read;
+	proc_dwcs_mode->write_proc = proc_dwcs_mode_write;
+	proc_dwcs_dfs = create_proc_entry("dfs", 0444, proc_dwcs_dir);
+	proc_dwcs_dfs->owner = THIS_MODULE;
+	proc_dwcs_dfs->read_proc = proc_dwcs_dfs_read;
+	proc_freq_entry = create_proc_entry("cpu_freq", 0644, proc_dwcs_dir);
+	proc_freq_entry->owner = THIS_MODULE;
+	proc_freq_entry->read_proc = proc_read_freq;
+	proc_freq_entry->write_proc = proc_write_freq;
+
+#ifdef CONFIG_ARCH_SA1100
+	current_sa1100_freq = 0;
+	do {
+		if (cpufreq_get(0) == sa1100_freq[current_sa1100_freq]) break;
+		current_sa1100_freq++;
+	} while (current_sa1100_freq < 12);
+#endif
+#endif
+	DWCS_module_loaded = 1;
+
+	//if (start_khtread(send_data
+
+	return 0;
+}
+
+
+/* Remove module. */
+void cleanup_module(void)
+{
+	if (DWCS_module_loaded)
+		printk (KERN_DEBUG "Disabling DWCS!\n");
+
+	DWCS_admission_control = 0;
+	DWCS_module_loaded = 0;
+	utilization = 0;
+
+	/* Restore original dummy functions for system calls. */
+	DWCS_scheduler = NULL;
+	sys_call_table[__NR_update_utilization-__NR_SYSCALL_BASE] = 
+		_dummy_update_utilization;
+	sys_call_table[__NR_admission_control-__NR_SYSCALL_BASE] =
+		_dummy_request_admission;
+
+#ifdef DWCS_DEBUG_ON
+	if (DWCS_DEBUG) {
+		kfree(debug_area);
+	}
+	remove_proc_entry("time", proc_dwcs_dir);
+	remove_proc_entry("debug_info", proc_dwcs_dir);
+	remove_proc_entry("debugging_control", proc_dwcs_dir);
+#endif
+
+	remove_proc_entry("control", proc_dwcs_dir);
+	remove_proc_entry("energy_mode", proc_dwcs_dir);
+	remove_proc_entry("info", proc_dwcs_dir);
+	remove_proc_entry("enabled", proc_dwcs_dir);
+#ifdef CONFIG_DWCS_DFS
+	remove_proc_entry("dfs", proc_dwcs_dir);
+	remove_proc_entry("mode", proc_dwcs_dir);
+	remove_proc_entry("cpu_freq", proc_dwcs_dir);
+#endif
+	remove_proc_entry("dwcs", NULL);
+}
+
+
+/*
+ * This is the function that decides how desirable a process is..
+ * You can weigh different processes against each other depending
+ * on what CPU they've run on lately etc to try to handle cache
+ * and TLB miss penalties.
+ *
+ * Return values:
+ *	 -1000: never select this
+ *	     0: out of time, recalculate counters (but it might still be
+ *		selected)
+ *	   +ve: "goodness" value (the larger, the better)
+ *	 +1000: realtime process, select this.
+ */
+
+static inline int goodness (struct task_struct * p,
+			    int this_cpu, struct mm_struct *this_mm)
+{
+	int weight;
+
+	/*
+	 * select the current process after every other
+	 * runnable process, but before the idle thread.
+	 * Also, dont trigger a counter recalculation.
+	 */
+	weight = -1;
+	if (p->policy & SCHED_YIELD)
+		goto out;
+
+	/*
+	 * Non-RT process - normal case first.
+	 */
+	if (p->policy == SCHED_OTHER) {
+		/*
+		 * Give the process a first-approximation goodness value
+		 * according to the number of clock-ticks it has left.
+		 *
+		 * Don't do any other calculations if the time slice is
+		 * over..
+		 */
+		weight = p->counter;
+		if (!weight)
+			goto out;
+
+#ifdef CONFIG_SMP
+		/* Give a largish advantage to the same processor...   */
+		/* (this is equivalent to penalizing other processors) */
+		if (p->processor == this_cpu)
+			weight += PROC_CHANGE_PENALTY;
+#endif
+
+		/* .. and a slight advantage to the current MM */
+		if (p->mm == this_mm || !p->mm)
+			weight += 1;
+		weight += 20 - p->nice;
+		goto out;
+	}
+
+	/*
+	 * Realtime process, select the first one on the
+	 * runqueue (taking priorities within processes
+	 * into account).
+	 */
+	weight = 1000 + p->rt_priority;
+#ifdef CONFIG_QFABRIC
+	if (p->qfabric != NULL) {
+		if (p->qfabric->weight > 0) {
+			weight  = -1000;
+			p->qfabric->weight--;
+		} else
+			p->qfabric->weight = p->qfabric->orig_weight;
+	}
+#endif
+out:
+	return weight;
+}
+
+static void update_service_constraints (struct task_struct * p,
+					int check_deadlines)
+{
+
+	if (check_deadlines) {
+		while (JIFFIES > p->dwcs_params->deadline) {
+			/* printk (KERN_DEBUG "(%d) Deadline missed!\n",
+			   p->dwcs_params->cd); */
+
+#ifdef CONFIG_DWCS_DFS
+			dwcs_hyper_period_misses++;
+#endif
+			/* Statistics. */
+			p->dwcs_params->late++;
+			p->dwcs_params->wlate++;
+			if (((p->dwcs_params->on_time +
+			      p->dwcs_params->late) %
+			     p->dwcs_params->owd) == 0) {
+
+				if (p->dwcs_params->wlate > p->dwcs_params->own) {
+					p->dwcs_params->violations++;
+#ifdef CONFIG_DWCS_DFS
+					dwcs_hyper_period_violations++;
+#endif
+					/*printk (KERN_DEBUG "(%d) VIOLATION!\n",
+					  p->dwcs_params->cd);*/
+				}
+				p->dwcs_params->wlate = 0;
+			}
+
+			p->dwcs_params->deadline += p->dwcs_params->period;
+			p->dwcs_params->ready_time += p->dwcs_params->period;
+
+			if (p->dwcs_params->cwn > 0) {
+				p->dwcs_params->cwn--;
+				p->dwcs_params->cwd--;
+				if ((p->dwcs_params->cwd == 0) && (p->dwcs_params->cwn == 0)) {
+					p->dwcs_params->cwn = p->dwcs_params->own;
+					p->dwcs_params->cwd = p->dwcs_params->owd;
+				}
+			}
+			else { /* p->dwcs_params->cwn == 0. */
+				if (p->dwcs_params->owd > 0) {
+					/*
+					 * NOTE: This is not pure EDF if we got here,
+					 * since if it were, x/y = 0/0 and, therefore,
+					 * p->dwcs_params->owd = 0.
+					 *
+					 * Now, we have a window-constraint violation.
+					 * These next instructions will eventually
+					 * avoid starvation of p.
+					 */
+				/* CP: changed s.t. windowsize is always the same */
+					//p->dwcs_params->cwd++;
+					p->dwcs_params->cwd--;
+					if ((p->dwcs_params->cwd == 0) && 
+						(p->dwcs_params->cwn == 0)) {
+						p->dwcs_params->cwn = p->dwcs_params->own;
+						p->dwcs_params->cwd = p->dwcs_params->owd;
+					}
+					//p->dwcs_params->flags |= DWCS_VIOLATION;
+				}
+			}
+		}
+	}
+
+	else {
+
+		/* Service time (and time serviced) is at the resolution of
+		 * jiffies right now. That is, it is currently some multiple the
+		 * clock interrupt resolution (10mS on Intels).
+		 */
+		p->dwcs_params->time_serviced++;
+
+		/* Adjust service attributes only when a process is serviced in
+		   its entirety "on-time". */
+		if (p->dwcs_params->time_serviced == p->dwcs_params->service_time) {
+
+			if ((p->dwcs_params->cwd > p->dwcs_params->cwn) &&
+			    (p->dwcs_params->deadline  != (unsigned long)-1))
+				p->dwcs_params->cwd--;
+			/* --FS-- missing case of x == y added */
+			else if ((p->dwcs_params->cwd == p->dwcs_params->cwn) &&
+				 (p->dwcs_params->cwd > 0) &&
+				 (p->dwcs_params->deadline  != (unsigned long)-1)) {
+				p->dwcs_params->cwd--;
+				p->dwcs_params->cwn--;
+			}
+
+			if (((p->dwcs_params->cwd == 0) && (p->dwcs_params->cwn == 0)) ||
+			    (p->dwcs_params->flags & DWCS_VIOLATION)) {
+				p->dwcs_params->cwn = p->dwcs_params->own;
+				p->dwcs_params->cwd = p->dwcs_params->owd;
+				p->dwcs_params->flags &= ~DWCS_VIOLATION;
+			}
+		}
+
+		/* Disable any possible servicing of this task until its next
+		   request period if it does not support work-conservation. */
+		if ((!(p->dwcs_params->flags & DWCS_WORK_CONS)) &&
+		    (p->dwcs_params->time_serviced == p->dwcs_params->service_time))
+			p->dwcs_params->ready_time += p->dwcs_params->period;
+		else
+			if (p->dwcs_params->deadline != (unsigned long)-1) {
+				if (p->dwcs_params->time_serviced == p->dwcs_params->service_time) {
+					p->dwcs_params->flags |= DWCS_SERVICED_THIS_PERIOD;
+
+					/* The following line tells us when it's safe to
+					   reset the DWCS_SERVICED_THIS_PERIOD flag. */
+					p->dwcs_params->ready_time += p->dwcs_params->period;
+				}
+			}
+
+		if (p->dwcs_params->time_serviced == p->dwcs_params->service_time) {
+			if (p->dwcs_params->deadline != (unsigned long)-1)
+				p->dwcs_params->deadline += p->dwcs_params->period;
+#ifdef CONFIG_DWCS_DFS
+				if (p == dwcs_hyper_period_task) {
+					dwcs_hyper_period_task_count++;
+					if (dwcs_hyper_period_task_count == dwcs_hyper_period_task_iterations) {
+						if (hyper_period_recalc_needed) {
+							find_hyper_period_task(0);
+						}
+						if (DWCS_module_mode == DWCS_MODE_VMI) {
+							dwcs_dfs_measurements(p);
+						}
+						dwcs_hyper_period_task_count = 0;
+					}
+				}
+#endif
+			p->dwcs_params->time_serviced = 0;
+		}
+
+		/* Statistics. */
+		p->dwcs_params->on_time++;
+
+		if (((p->dwcs_params->on_time +
+		      p->dwcs_params->late) %
+		     p->dwcs_params->owd) == 0) {
+
+			if (p->dwcs_params->wlate > p->dwcs_params->own) {
+				p->dwcs_params->violations++;
+#ifdef CONFIG_DWCS_DFS
+				dwcs_hyper_period_violations++;
+#endif
+				/*printk (KERN_DEBUG "(%d) VIOLATION!\n",
+				  p->dwcs_params->cd);*/
+			}
+			p->dwcs_params->wlate = 0;
+		}
+
+	}
+#ifdef DWCS_DEBUG_ON
+	if (DWCS_DEBUG && (p->dwcs_params->deadline != -1) && (debug_count < 50)) {
+		char tmp[100];
+		sprintf(tmp, "%d   %ld   %ld   %ld   %d   %d   %d   %d   %d   %ld   %ld   %ld   %d   %ld   %ld   %ld\n", p->pid, p->dwcs_params->deadline, JIFFIES, p->dwcs_params->period, p->dwcs_params->own, p->dwcs_params->owd, p->dwcs_params->cwn, p->dwcs_params->cwd, p->dwcs_params->flags, p->dwcs_params->ready_time, p->dwcs_params->service_time, p->dwcs_params->time_serviced, p->dwcs_params->wlate, p->dwcs_params->late, p->dwcs_params->on_time, p->dwcs_params->violations);
+
+		strcat(debug_area, tmp);
+		debug_count++;
+	}
+#endif
+}
+
+
+struct task_struct *
+compare_service_constraints (struct task_struct * p,
+			     struct task_struct * next,
+			     struct task_struct * prev,
+			     int weight_of_p) {
+
+	if ((next->dwcs_params->flags & DWCS_NON_PREEMPTIVE) &&
+	    (next->dwcs_params->time_serviced < next->dwcs_params->service_time) &&
+	    (next->dwcs_params->time_serviced > 0))
+		return next;
+
+	if ((p->dwcs_params->ready_time > JIFFIES) &&
+	    (!(p->dwcs_params->flags & DWCS_WORK_CONS)))
+		return next;
+
+	/* In aggressive energy_mode ignore dwcs tasks handled owd-own times already */
+	if ((energy_mode == DWCS_EM_AVERAGE_AGGRESSIVE) &&
+	    (p->policy == SCHED_DWCS) &&
+	    (p->dwcs_params->cwd == p->dwcs_params->cwn))
+		return next;
+
+
+	/*
+	 * Search run queue for highest priority i.e. lowest
+	 * window-constrained, EDF task and set to `next' task for
+	 * service in the run queue.
+	 */
+
+	if ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+	    (p->dwcs_params->deadline == (unsigned long)-1) &&
+	    (p->dwcs_params->cwn == next->dwcs_params->cwn) &&
+	    (p->dwcs_params->cwd == next->dwcs_params->cwd)) {
+
+		int this_cpu = prev->processor;
+		int weight_of_next = goodness(next, this_cpu, prev->active_mm);
+
+		/*
+		 * NOTE: For non-time-constrained tasks.
+		 *
+		 * We could've decided not do deal with `weights'. In that
+		 * case, a non-blocking process could hog the CPU even if
+		 * other processes are in the runqueue and have the same DWCS
+		 * service constraints. To be more `fair' even though we're
+		 * supposed to be real-time, we let the process that has the
+		 * largest weight have the CPU if two processes have the same DWCS
+		 * service constraints. This behaviour is in keeping with
+		 * the default Linux scheduler's behaviour.
+		 */
+		if (weight_of_p > weight_of_next)
+			next = p;
+	}
+	else {
+		/* --FS-- Moved serviced_this_period comparison to first place */
+		if ((p->dwcs_params->deadline != (unsigned long)-1) &&
+		    (!(p->dwcs_params->flags & DWCS_SERVICED_THIS_PERIOD)) &&
+		    (next->dwcs_params->flags & DWCS_SERVICED_THIS_PERIOD))
+			next = p;
+		else
+		if ((p->dwcs_params->deadline < next->dwcs_params->deadline) ||
+		    ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+		     (p->dwcs_params->cwn * next->dwcs_params->cwd <
+		      next->dwcs_params->cwn * p->dwcs_params->cwd)) ||
+		    ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+		     (p->dwcs_params->cwn == 0) && (next->dwcs_params->cwn == 0) &&
+		     (p->dwcs_params->cwd > next->dwcs_params->cwd)) ||
+		    ((p->dwcs_params->deadline == next->dwcs_params->deadline) &&
+		     (p->dwcs_params->cwn * next->dwcs_params->cwd ==
+		      next->dwcs_params->cwn * p->dwcs_params->cwd) &&
+		     ((p->dwcs_params->cwn > 0 && p->dwcs_params->cwd > 0)))) {
+			// ||
+		      //(p->dwcs_params->cwn < 0 && p->dwcs_params->cwd < 0)) &&
+		     //(p->dwcs_params->cwn < next->dwcs_params->cwn))) {
+			next = p;
+		}
+  }
+
+	return next;
+}
+
+int DWCS_request_admission(struct task_struct *tptr, struct dwcs_sched_param *param)
+{
+	int old_utilization;
+	int new_utilization;
+
+	new_utilization = MAX_UTILIZATION * (param->owd - param->own) \
+		* param->service_time \
+		/ (param->period * param->owd);
+	old_utilization = MAX_UTILIZATION \
+		* (tptr->dwcs_params->owd - tptr->dwcs_params->own) \
+		* tptr->dwcs_params->service_time \
+		/ (tptr->dwcs_params->period * tptr->dwcs_params->owd);
+
+	if ((new_utilization > old_utilization) &&
+	    ((utilization - old_utilization + new_utilization) > (MAX_UTILIZATION - reserved_utilization))) {
+		return -EADMISSION;
+	}
+
+	return 1;
+}
+
+/* flag = 0 (recompute all), 1 (remove task) */
+void do_update_utilization(int flag, struct task_struct *tptr)
+{
+	struct task_struct *ptr;
+
+	if (flag == 0) {
+		utilization = 0;
+		for_each_task(ptr) {
+			if (ptr->dwcs_params->period != (unsigned long)-1) {
+				utilization += MAX_UTILIZATION \
+					* (ptr->dwcs_params->owd - ptr->dwcs_params->own) \
+					* ptr->dwcs_params->service_time \
+					/ (ptr->dwcs_params->period * ptr->dwcs_params->owd);
+			}
+		}
+#ifdef CONFIG_DWCS_DFS
+		if (DWCS_module_mode == DWCS_MODE_THEORETICAL)
+			dwcs_dfs_theoretical();
+#endif
+	} else if (flag == 1) {
+		if (tptr->dwcs_params->deadline != (unsigned long)-1) {
+			find_hyper_period_task(1);
+			utilization -= MAX_UTILIZATION \
+				* (tptr->dwcs_params->owd - tptr->dwcs_params->own) \
+				* tptr->dwcs_params->service_time \
+				/ (tptr->dwcs_params->period * tptr->dwcs_params->owd);
+#ifdef CONFIG_DWCS_DFS
+			if (DWCS_module_mode == DWCS_MODE_THEORETICAL)
+				dwcs_dfs_theoretical();
+#endif
+		}
+	} 
+}
+
+int av_cons_utilization()
+{
+	int utilization = 0;
+	struct list_head *tmp;
+	struct task_struct *p;
+
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (p->dwcs_params->period != (unsigned long)-1) {
+			utilization += MAX_UTILIZATION
+				* p->dwcs_params->service_time
+				/ p->dwcs_params->period;
+		}
+	}
+	return utilization;
+}
+
+int av_aggr_utilization()
+{
+	int utilization = 0;
+	struct list_head *tmp;
+	struct task_struct *p;
+
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (p->dwcs_params->period != (unsigned long)-1) {
+			utilization += MAX_UTILIZATION
+				* (p->dwcs_params->owd - p->dwcs_params->own)
+				* p->dwcs_params->service_time
+				/ (p->dwcs_params->period * p->dwcs_params->owd);
+		}
+	}
+	return utilization;
+}
+
+int ad_cons_utilization()
+{
+	int utilization = 0;
+	struct list_head *tmp;
+	struct task_struct *p;
+
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (p->dwcs_params->period != (unsigned long)-1) {
+			utilization += MAX_UTILIZATION
+				* (p->dwcs_params->service_time * p->dwcs_params->cpu_speedup / 100)
+				/ p->dwcs_params->period;
+		}
+	}
+	return utilization;
+}
+
+int ad_aggr_utilization()
+{
+	int utilization = 0;
+	struct list_head *tmp;
+	struct task_struct *p;
+
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (p->dwcs_params->period != (unsigned long)-1) {
+			utilization += MAX_UTILIZATION
+				* (p->dwcs_params->owd - p->dwcs_params->own)
+				* (p->dwcs_params->service_time * p->dwcs_params->cpu_speedup / 100)
+				/ (p->dwcs_params->period * p->dwcs_params->owd);
+		}
+	}
+	return utilization;
+}
+
+/*
+ *  'schedule()' is the scheduler function. It's a very simple and nice
+ * scheduler: it's not perfect, but certainly works for most things.
+ *
+ * The goto is "interesting".
+ *
+ *   NOTE!!  Task 0 is the 'idle' task, which gets called when no other
+ * tasks can run. It can not be killed, and it cannot sleep. The 'state'
+ * information in task[0] is never used.
+ */
+
+void DWCS_schedule(struct task_struct **prv,
+		   struct task_struct **nxt)
+{
+	struct schedule_data * sched_data;
+	struct task_struct *prev, *next, *p;
+#ifdef CONFIG_QFABRIC
+	struct task_struct *old_p;
+#endif
+	struct list_head *tmp;
+	int this_cpu, c;
+
+#ifdef CONFIG_QFABRIC
+	asmlinkage void (*upcall_sched)(struct task_struct **,
+					struct task_struct **,
+					int *,
+					int);
+#endif
+
+	jiffies_sim++;
+
+	spin_lock_prefetch(&runqueue_lock);
+
+	BUG_ON(!current->active_mm);
+need_resched_back:
+	prev = current;
+	this_cpu = prev->processor;
+
+	if (unlikely(in_interrupt())) {
+		printk("Scheduling in interrupt\n");
+		BUG();
+	}
+
+	release_kernel_lock(prev, this_cpu);
+
+	/*
+	 * 'sched_data' is protected by the fact that we can run
+	 * only one process per CPU.
+	 */
+	sched_data = & aligned_data[this_cpu].schedule_data;
+
+	spin_lock_irq(&runqueue_lock);
+
+	/* move an exhausted RR process to be last.. */
+	if (unlikely(prev->policy == SCHED_RR))
+		if (!prev->counter) {
+			prev->counter = NICE_TO_TICKS(prev->nice);
+			move_last_runqueue(prev);
+		}
+
+	switch (prev->state) {
+	case TASK_INTERRUPTIBLE:
+		if (signal_pending(prev)) {
+			prev->state = TASK_RUNNING;
+			break;
+		}
+	default:
+		del_from_runqueue(prev);
+	case TASK_RUNNING:;
+	}
+	prev->need_resched = 0;
+
+	/*
+	 * this is the scheduler proper:
+	 */
+
+repeat_schedule:
+	/*
+	 * Default process to select..
+	 */
+	next = idle_task(this_cpu);
+	c = -1000;
+
+	if ((prev->state == TASK_RUNNING) && (prev->dwcs_params->ready_time <= JIFFIES)) {
+		prev->dwcs_params->flags &= ~DWCS_SERVICED_THIS_PERIOD;
+		c = goodness(prev, this_cpu, prev->active_mm);
+		next = prev;
+	}
+
+	/*
+	 * GANEV: update service constraints here...
+	 */
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (can_schedule(p, this_cpu)) {
+			update_service_constraints(p, 1);
+		}
+#ifdef DWCS_DEBUG_ON
+		else if (DWCS_DEBUG && (debug_count < 50)) {
+			char tmp[100];
+			sprintf(tmp, "no csc\n%d   %ld   %ld   %ld   %d   %d   %d   %d   %d   %ld   %ld   %ld   %d   %ld   %ld   %ld\n", p->pid, p->dwcs_params->deadline, JIFFIES, p->dwcs_params->period, p->dwcs_params->own, p->dwcs_params->owd, p->dwcs_params->cwn, p->dwcs_params->cwd, p->dwcs_params->flags, p->dwcs_params->ready_time, p->dwcs_params->service_time, p->dwcs_params->time_serviced, p->dwcs_params->wlate, p->dwcs_params->late, p->dwcs_params->on_time, p->dwcs_params->violations);
+			strcat(debug_area, tmp);
+			debug_count++;
+		}
+#endif
+	}
+	if (DWCS_update_utilization == 1) {
+		do_update_utilization(0, NULL);
+		DWCS_update_utilization = 0;
+	}
+
+	list_for_each(tmp, &runqueue_head) {
+		p = list_entry(tmp, struct task_struct, run_list);
+		if (can_schedule(p, this_cpu)) {
+			int weight = goodness(p, this_cpu, prev->active_mm);
+			if (weight > c)
+				c = weight;
+			next = compare_service_constraints(p,next,prev,weight);
+		}
+	}
+#ifdef DWCS_DEBUG_ON
+/*
+	if (DWCS_DEBUG && (debug_count < 50)) {
+		char tmp[5];
+		debug_count++;
+		sprintf(tmp, "%d\n", p->pid);
+		strcat(debug_area, tmp);
+	}
+*/
+#endif
+
+#ifdef CONFIG_QFABRIC
+	if (upcall_sched_active) {
+		upcall_sched = sys_call_table[__NR_upcall_scheduler-__NR_SYSCALL_BASE];
+		old_p = next;
+		upcall_sched(&old_p, &next, &c, utilization);
+	}
+#endif
+
+	/* Do we need to re-calculate counters? */
+	if (unlikely(!c)) {
+		struct task_struct *p;
+
+		spin_unlock_irq(&runqueue_lock);
+		read_lock(&tasklist_lock);
+		for_each_task(p)
+			p->counter = (p->counter >> 1) + NICE_TO_TICKS(p->nice);
+		read_unlock(&tasklist_lock);
+		spin_lock_irq(&runqueue_lock);
+		goto repeat_schedule;
+	}
+
+	/*
+	 * from this point on nothing can prevent us from
+	 * switching to the next task, save this fact in
+	 * sched_data.
+	 */
+#ifdef CONFIG_DWCS_DFS
+	if (next == idle_task(this_cpu)) {
+		dwcs_hyper_period_idles++;
+	}
+#endif
+	sched_data->curr = next;
+	task_set_cpu(next, this_cpu);
+	spin_unlock_irq(&runqueue_lock);
+
+	update_service_constraints(next, 0);
+
+	/* --FS-- if next process is a dwcs proc. do powermgmnt */
+	/*
+	if ((next->dwcs_params->period != (unsigned long)-1) && (energy_mode != 0)){
+		int utilization = MAX_UTILIZATION;
+		if (energy_mode == DWCS_EM_AVERAGE_CONSERVATIVE) {
+			utilization = av_cons_utilization();
+		}
+		else if (energy_mode == DWCS_EM_AVERAGE_AGGRESSIVE) {
+			utilization = av_aggr_utilization();
+		}
+		if (utilization < MAX_UTILIZATION / 100)
+		  utilization = MAX_UTILIZATION / 100;
+		next->dwcs_params->cpu_speedup = (MAX_UTILIZATION - reserved_utilization) * 100 / utilization;
+#ifdef CONFIG_DWCS_DFS
+		set_slowest_cpuspeed(next);
+#endif
+	} else {
+		set_default_cpuspeed();
+	}
+*/
+
+	/* --FS-- do this check early since we can't jump to
+	 * same_process in dwcs_switch */
+	if (unlikely(prev == next) && (current->need_resched)) {
+		/* We won't go through the normal tail, so do this by hand */
+		prev->policy &= ~SCHED_YIELD;
+		goto same_process;
+	}
+
+	*prv = prev;
+	*nxt = next;
+
+	return;
+
+same_process:
+	reacquire_kernel_lock(current);
+	goto need_resched_back;
+
+}
diff -Naur test-for-latech/kernel/ecalls.c testqf-for-latech/kernel/ecalls.c
--- test-for-latech/kernel/ecalls.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/kernel/ecalls.c	2004-06-11 07:47:23.000000000 -0400
@@ -0,0 +1,240 @@
+/*
+ *  linux/kernel/ecalls.c
+ *
+ *  Copyright (C) 1999/2000  Christian Poellabauer
+ */
+
+#include <linux/mm.h>
+#include <linux/utsname.h>
+#include <linux/mman.h>
+#include <linux/smp_lock.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/prctl.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+
+//#include <sys/syscall.h>
+#include <asm/unistd.h>
+
+#define MAX_LENGTH 32
+#define NR_THREADS 512
+
+extern void *sys_call_table[];
+#ifdef CONFIG_QFABRIC
+#ifdef CONFIG_X86
+#define __NR_SYSCALL_BASE 0
+extern void *fast_sys_call_table[];
+#endif
+#endif
+extern atomic_t access_lock;
+extern int sysctl_max_syn_backlog;
+
+struct ecall_down {
+	int shmid;	
+	void *shmaddr;
+};
+typedef struct ecall_down *t_downcall_data;
+
+struct ecall_up {
+	int shmid;	
+	void *shmaddr;
+};
+typedef struct ecall_up *t_upcall_data;
+
+/* Start ecall mechanism. */
+asmlinkage int sys_start_ecalls(void)
+{
+#ifdef CONFIG_QFABRIC
+	return request_module("ecalls");
+#endif
+	return 1;
+}
+
+/* End ecall mechanism. */
+asmlinkage int sys_end_ecalls(void)
+{
+	return 1;
+}
+
+/* Register ECall. */
+asmlinkage int sys_register_ecall(char *service, int len,
+	struct ecall_down *downcall, struct ecall_up *upcall)
+{
+        return -ENOSYS;
+}
+
+/* Do Downcall. */
+asmlinkage int sys_do_downcall(struct ecall_down *downcall, 
+	void *data, int len)
+{
+        return -ENOSYS;
+}
+
+/* Event handler function. */
+asmlinkage void sys_run_event_handler(void)
+{
+        return;
+}
+
+/* Fast event handler function. */
+asmlinkage int sys_fast_do_downcall(struct ecall_down *downcall,
+	void *data, int len)
+{
+        return -ENOSYS;
+}
+
+/* Call upcall scheduler. */
+asmlinkage int sys_upcall_scheduler(void) 
+{
+        return -ENOSYS;
+}
+
+/* Dummy sys_wake_up_ecalls. */
+asmlinkage int sys_wake_up_ecalls(void) 
+{
+        return -ENOSYS;
+}
+
+/* Dummy code download function. */
+asmlinkage int sys_download_code(void) 
+{
+        return -ENOSYS;
+}
+
+/* Set sock->readable or sock->writeable. */
+int set_sock_ecalls(struct socket *sock, int readable, int writable, int kecho,
+		    void *ptr, int fd, int pid) 
+{
+#ifdef CONFIG_QFABRIC
+	if (readable == 1) 
+		sock->sk->readable = 1;
+	else
+		sock->sk->readable = 0;
+	if (writable == 1)
+		sock->sk->writable = 1;
+	else
+		sock->sk->writable = 0;
+	if (kecho == 1)
+		sock->sk->kecho = 1;
+	else
+		sock->sk->kecho = 0;
+	sock->sk->kecho_ptr = ptr;
+	if (fd != -1)  
+	  sock->sk->fd = fd;
+	if (pid != -1)  
+	  sock->sk->owner = pid;
+#endif
+        return 0;
+}
+
+void call_event_handler(void) 
+{
+#ifdef CONFIG_QFABRIC
+  void (*ECalls_event_handler)(void);
+
+  ECalls_event_handler = sys_call_table[__NR_run_event_handler-__NR_SYSCALL_BASE];
+  ECalls_event_handler();
+#endif
+}
+
+void call_upcall_sched(struct task_struct **ts1, struct task_struct **ts2,
+	int *weight)
+{
+#ifdef CONFIG_QFABRIC
+  void (*upcall_sched)(struct task_struct **ts1, 
+		struct task_struct **ts2, int *weight);
+ 
+  upcall_sched = sys_call_table[__NR_upcall_scheduler-__NR_SYSCALL_BASE];
+  upcall_sched(ts1, ts2, weight);
+#endif
+}
+
+int call_admission_control(struct task_struct *ts1, struct sched_param *pa1)
+{
+#ifdef CONFIG_QFABRIC
+  int (*request_task_admission)(struct task_struct *ts1, 
+		struct sched_param *pa1);
+
+  request_task_admission = sys_call_table[__NR_admission_control-__NR_SYSCALL_BASE];
+  return (request_task_admission(ts1, pa1));
+#else
+  return -1;
+#endif
+}
+
+void call_update_util(int flag, struct task_struct *ts1)
+{
+#ifdef CONFIG_QFABRIC
+  void (*update_utilization)(int, struct task_struct *);
+  
+  update_utilization = sys_call_table[__NR_update_utilization-__NR_SYSCALL_BASE];
+  update_utilization(1, current);
+#endif
+}
+
+void call_wake_up(int i1, int i2, int i3, int i4, void *ptr)
+{
+#ifdef CONFIG_QFABRIC
+  void (*wake_up_using_ecalls)(int, int, int, int, void *);
+
+  wake_up_using_ecalls = sys_call_table[__NR_wake_up_ecalls-__NR_SYSCALL_BASE];
+  wake_up_using_ecalls(i1, i2, i3, i4, ptr);
+#endif
+}
+
+int get_sock_info(void *pointer, int flag)
+{
+#ifdef CONFIG_QFABRIC
+  struct sock *sk;
+
+  sk = (struct sock *) pointer;
+
+  if (flag == 0)
+    return sk->rcvbuf;
+  if (flag == 1)
+    return sk->rmem_alloc.counter;
+  if (flag == 2)
+    return sk->receive_queue.qlen;
+  if (flag == 3)
+    return sk->ack_backlog;
+  if (flag == 4)
+    return sysctl_max_syn_backlog;
+  if (flag == 5)
+    return tcp_synq_is_full(sk);
+  if (flag == 6)
+    return sk->socket->state;
+  if (flag == 7)
+    return sk->counter;
+  if (flag == 8)
+    return sk->rmem_alloc.counter;
+  if (flag == 9)
+    return sk->wmem_alloc.counter;
+#endif
+  return -1;
+}
+
+int set_sock_info(void *pointer, int flag, int value)
+{
+#ifdef CONFIG_QFABRIC
+  struct sock *sk;
+
+  sk = (struct sock *) pointer;
+
+  if (flag == 0)
+    sk->rcvbuf = value;
+  if (flag == 3)
+    sk->max_ack_backlog = value;
+  if (flag == 4)
+    sysctl_max_syn_backlog = value;
+  return 0;
+#endif
+  return -1;
+}
diff -Naur test-for-latech/kernel/exit.c testqf-for-latech/kernel/exit.c
--- test-for-latech/kernel/exit.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/exit.c	2004-06-11 07:47:23.000000000 -0400
@@ -5,6 +5,9 @@
  */
 
 #include <linux/config.h>
+#ifdef CONFIG_QFABRIC
+#include <linux/init.h>
+#endif
 #include <linux/slab.h>
 #include <linux/interrupt.h>
 #include <linux/smp_lock.h>
@@ -23,10 +26,19 @@
 
 extern void sem_exit (void);
 extern struct task_struct *child_reaper;
+#ifdef CONFIG_DWCS
+#include <linux/unistd.h>
+extern void *sys_call_table[];
+extern int DWCS_module_loaded;
+#endif
 
 int getrusage(struct task_struct *, int, struct rusage *);
 
+#ifdef CONFIG_QFABRIC
+void release_task(struct task_struct * p)
+#else
 static void release_task(struct task_struct * p)
+#endif
 {
 	if (p != current) {
 #ifdef CONFIG_SMP
@@ -449,6 +461,23 @@
 	tsk->flags |= PF_EXITING;
 	del_timer_sync(&tsk->real_timer);
 
+	/* 
+	 * Set flag for computation of utilization.
+	 */
+#ifdef CONFIG_DWCS
+	if (DWCS_module_loaded) {
+	  void (*update_utilization)(int, struct task_struct *);
+	  update_utilization = sys_call_table[__NR_update_utilization-__NR_SYSCALL_BASE];
+	  update_utilization(1, current);
+	}
+#endif
+#ifdef CONFIG_QFABRIC
+	if (tsk->qfabric != NULL) {
+	  kfree(tsk->qfabric->fdqfabric);
+	  kfree(tsk->qfabric);
+	}
+#endif
+
 fake_volatile:
 #ifdef CONFIG_BSD_PROCESS_ACCT
 	acct_process(code);
diff -Naur test-for-latech/kernel/fork.c testqf-for-latech/kernel/fork.c
--- test-for-latech/kernel/fork.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/fork.c	2004-06-11 07:47:23.000000000 -0400
@@ -690,9 +690,46 @@
 		goto bad_fork_cleanup_sighand;
 	if (copy_namespace(clone_flags, p))
 		goto bad_fork_cleanup_mm;
+
+#ifdef CONFIG_DWCS
+	/* --RW--
+	 * Initialize the dwcs_params structure, in case the DWCS
+	 * scheduler is in operation.
+	 */
+	p->dwcs_params = kmalloc(sizeof(struct dwcs_struct), GFP_ATOMIC);
+	if (!p->dwcs_params) {
+	  retval = -ENOMEM;
+	  goto bad_fork_cleanup_namespace;
+	}
+	
+	p->dwcs_params->cd            = p->pid;
+	/* Default = no deadline */
+	p->dwcs_params->deadline      = (unsigned long) -1; 
+	p->dwcs_params->period        = (unsigned long) -1; 
+	/* `period' is a multiple of jiffies. */
+	p->dwcs_params->own           = 1;
+	p->dwcs_params->owd           = 10;
+	p->dwcs_params->cwn           = 1;
+	p->dwcs_params->cwd           = 10;
+	p->dwcs_params->flags         = DWCS_WORK_CONS;
+	p->dwcs_params->ready_time    = 0;
+	p->dwcs_params->service_time  = 1; /* x 10mS for each clock tick. */
+	p->dwcs_params->time_serviced = 0;
+	p->dwcs_params->wlate         = 0;
+	p->dwcs_params->late          = 0;
+	p->dwcs_params->on_time       = 0;
+	p->dwcs_params->violations    = 0;
+	/* End of --RW-- */
+#endif
+
+
 	retval = copy_thread(0, clone_flags, stack_start, stack_size, p, regs);
 	if (retval)
+#ifdef CONFIG_DWCS
+	  	goto bad_fork_cleanup_dwcs;
+#else
 		goto bad_fork_cleanup_namespace;
+#endif
 	p->semundo = NULL;
 	
 	/* Our parent execution domain becomes current domain
@@ -700,6 +737,15 @@
 	   
 	p->parent_exec_id = p->self_exec_id;
 
+#ifdef CONFIG_QFABRIC
+	p->qfabric = NULL;
+        p->kthread = 0;
+        p->suser_flag = 0;
+        p->uaccess_flag = 0;
+        p->ecalls_flag = 0;
+        p->syscall_counter = 0;
+#endif
+
 	/* ok, now we should be set up.. */
 	p->swappable = 1;
 	p->exit_signal = clone_flags & CSIGNAL;
@@ -758,7 +804,10 @@
 
 fork_out:
 	return retval;
-
+#ifdef CONFIG_DWCS
+bad_fork_cleanup_dwcs:
+       kfree(p->dwcs_params);
+#endif
 bad_fork_cleanup_namespace:
 	exit_namespace(p);
 bad_fork_cleanup_mm:
diff -Naur test-for-latech/kernel/ksyms.c testqf-for-latech/kernel/ksyms.c
--- test-for-latech/kernel/ksyms.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/ksyms.c	2004-06-11 07:47:23.000000000 -0400
@@ -39,6 +39,12 @@
 #include <linux/poll.h>
 #include <linux/mmzone.h>
 #include <linux/mm.h>
+#ifdef CONFIG_QFABRIC
+#include <linux/shm.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/sched.h>
+#endif
 #include <linux/capability.h>
 #include <linux/highuid.h>
 #include <linux/brlock.h>
@@ -47,6 +53,11 @@
 #include <linux/in6.h>
 #include <linux/completion.h>
 #include <linux/seq_file.h>
+#ifdef CONFIG_QFABRIC
+#include <net/sock.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+#endif
 #include <asm/checksum.h>
 
 #if defined(CONFIG_PROC_FS)
@@ -56,9 +67,57 @@
 #include <linux/kmod.h>
 #endif
 
+//#define DWCS_DEBUG_ON 1
+
+#ifdef CONFIG_QFABRIC
+#define NR_THREADS 512
+ 
+extern int get_pseudofd(struct socket *sock, struct socket *fd_array[]);
+extern int release_pseudofd(int fd, struct socket *fd_array[]);
+extern struct socket *look_up_pseudofd(int fd, struct socket *fd_array[]);
+extern int poll_socket(struct socket *socket);
+extern int sys_recvmsg(int fd, struct msghdr *msg, unsigned int flags);
+extern long sys_sched_yield(void);
+extern void initialize_qfabric(void);
+extern int ECalls_active;
+#endif
+
+#ifdef CONFIG_DWCS
+extern int DWCS_module_loaded;	        /* --RW-- */
+extern void (*DWCS_scheduler)(struct task_struct **, struct task_struct **);    /* --FS-- */
+extern struct list_head runqueue_head;  /* --FS-- */
+extern int DWCS_admission_control;      /* --CP-- */
+extern int DWCS_update_utilization;	/* --CP-- */
+extern int utilization;			/* --CP-- */
+#ifdef DWCS_DEBUG_ON
+extern unsigned long dwcs_timer_max_time;
+extern long dwcs_max_counter;
+extern long dwcs_pid;
+extern unsigned long dwcs_sched_max_time;
+#endif
+#endif
+#ifdef CONFIG_QFABRIC
+extern int security_off;		/* --CP-- */
+extern int SOCKWATCH_module_loaded;     /* --CP-- */
+extern int set_sock_ecalls(struct socket *, int, int, int, void*); /* --CP-- */
+extern int get_sock_info(void *, int);  /* --CP-- */
+extern int set_sock_info(void *, int, int); /* --CP-- */
+extern int wake_up_process(struct task_struct * tsk);
+extern struct socket *sockfd_lookup(int fd, int *err);
+extern unsigned long total_forks;
+extern struct page *grab_cache_page_ex(struct address_space *mapping, 
+		unsigned long index, struct page **cached_page);
+#endif
+extern unsigned long volatile jiffies_sim; 
+
 extern void set_device_ro(kdev_t dev,int flag);
 
 extern void *sys_call_table;
+#ifdef CONFIG_QFABRIC
+#ifdef CONFIG_X86
+extern void *fast_sys_call_table;
+#endif
+#endif
 
 extern struct timezone sys_tz;
 extern int request_dma(unsigned int dmanr, char * deviceID);
@@ -80,6 +139,33 @@
 EXPORT_SYMBOL(inter_module_put);
 EXPORT_SYMBOL(try_inc_mod_count);
 
+/* --RW--
+ * Dionisys and DWCS module symbols.
+ */
+#ifdef CONFIG_DWCS
+EXPORT_SYMBOL(DWCS_module_loaded);
+EXPORT_SYMBOL(DWCS_scheduler);  /* --FS-- */
+EXPORT_SYMBOL(init_tasks);  /* --CP-- */
+#ifdef DWCS_DEBUG_ON
+EXPORT_SYMBOL(dwcs_timer_max_time);
+EXPORT_SYMBOL(dwcs_max_counter);
+EXPORT_SYMBOL(dwcs_pid);
+EXPORT_SYMBOL(dwcs_sched_max_time);
+#endif
+
+/*
+EXPORT_SYMBOL(do_bottom_half);
+*/
+EXPORT_SYMBOL(jiffies_sim);
+/*
+ * GANEV: exported various symbols so that they would be accessible to
+ *        loadable kernel schedulers like DWCS.
+ */
+EXPORT_SYMBOL(aligned_data);
+EXPORT_SYMBOL(runqueue_head);	/* --FS-- */
+EXPORT_SYMBOL(runqueue_lock);
+#endif
+
 /* process memory management */
 EXPORT_SYMBOL(do_mmap_pgoff);
 EXPORT_SYMBOL(do_munmap);
@@ -394,6 +480,9 @@
 #ifdef CONFIG_SMP
 /* Various random spinlocks we want to export */
 EXPORT_SYMBOL(tqueue_lock);
+#ifdef CONFIG_DWCS
+EXPORT_SYMBOL(global_irq_lock);		/* --RW-- */
+#endif
 
 /* Big-Reader lock implementation */
 EXPORT_SYMBOL(__brlock_array);
@@ -440,7 +529,6 @@
 EXPORT_SYMBOL(complete_and_exit);
 EXPORT_SYMBOL(__wake_up);
 EXPORT_SYMBOL(__wake_up_sync);
-EXPORT_SYMBOL(wake_up_process);
 EXPORT_SYMBOL(sleep_on);
 EXPORT_SYMBOL(sleep_on_timeout);
 EXPORT_SYMBOL(interruptible_sleep_on);
@@ -480,6 +568,11 @@
 #ifndef __mips__
 EXPORT_SYMBOL(sys_call_table);
 #endif
+#ifdef CONFIG_QFABRIC
+#ifdef CONFIG_X86
+EXPORT_SYMBOL(fast_sys_call_table);
+#endif
+#endif
 EXPORT_SYMBOL(machine_restart);
 EXPORT_SYMBOL(machine_halt);
 EXPORT_SYMBOL(machine_power_off);
@@ -570,3 +663,43 @@
 
 EXPORT_SYMBOL(tasklist_lock);
 EXPORT_SYMBOL(pidhash);
+
+/* --CP-- */
+#ifdef CONFIG_QFABRIC
+EXPORT_SYMBOL(get_pseudofd);
+EXPORT_SYMBOL(release_pseudofd);
+EXPORT_SYMBOL(look_up_pseudofd);
+EXPORT_SYMBOL(poll_socket);
+EXPORT_SYMBOL(sys_shmat);
+EXPORT_SYMBOL(sys_recvmsg);
+EXPORT_SYMBOL(upcall_sched_active);
+#endif
+#ifdef CONFIG_DWCS
+EXPORT_SYMBOL(DWCS_update_utilization);
+EXPORT_SYMBOL(DWCS_admission_control);
+EXPORT_SYMBOL(utilization);
+#endif
+#ifdef CONFIG_QFABRIC
+EXPORT_SYMBOL(security_off);
+EXPORT_SYMBOL(ECalls_current_flag);
+EXPORT_SYMBOL(ECalls_current);
+EXPORT_SYMBOL(global_wait_queue);
+//EXPORT_SYMBOL(sys_sched_yield);
+EXPORT_SYMBOL(SOCKWATCH_module_loaded);
+EXPORT_SYMBOL(set_sock_ecalls);
+EXPORT_SYMBOL(get_sock_info);
+EXPORT_SYMBOL(set_sock_info);
+EXPORT_SYMBOL(sockfd_lookup);
+EXPORT_SYMBOL(initialize_qfabric);
+EXPORT_SYMBOL(ECalls_active);
+EXPORT_SYMBOL(avenrun);
+EXPORT_SYMBOL(nr_free_pages);
+EXPORT_SYMBOL(swapper_space);
+EXPORT_SYMBOL(si_swapinfo);
+EXPORT_SYMBOL(page_cache_size);
+EXPORT_SYMBOL(nr_inactive_pages);
+EXPORT_SYMBOL(nr_active_pages);
+EXPORT_SYMBOL(total_forks);
+EXPORT_SYMBOL(grab_cache_page_ex);
+#endif
+EXPORT_SYMBOL(wake_up_process);
diff -Naur test-for-latech/kernel/Makefile testqf-for-latech/kernel/Makefile
--- test-for-latech/kernel/Makefile	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/Makefile	2004-06-11 07:47:23.000000000 -0400
@@ -14,12 +14,16 @@
 obj-y     = sched.o dma.o fork.o exec_domain.o panic.o printk.o \
 	    module.o exit.o itimer.o info.o time.o softirq.o resource.o \
 	    sysctl.o acct.o capability.o ptrace.o timer.o user.o \
-	    signal.o sys.o kmod.o context.o
+	    signal.o sys.o kmod.o context.o ecalls.o qfabric.o
 
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += ksyms.o
 obj-$(CONFIG_PM) += pm.o
 
+ifeq ($(CONFIG_DWCS),y)
+obj-m += dwcs.o
+endif
+
 ifneq ($(CONFIG_IA64),y)
 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
 # needed for x86 only.  Why this used to be enabled for all architectures is beyond
diff -Naur test-for-latech/kernel/qfabric.c testqf-for-latech/kernel/qfabric.c
--- test-for-latech/kernel/qfabric.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/kernel/qfabric.c	2004-06-11 07:47:23.000000000 -0400
@@ -0,0 +1,190 @@
+/*
+ *  linux/kernel/qfabric.c
+ *
+ *  Copyright (C) 1999/2000  Christian Poellabauer
+ */
+
+#include <linux/mm.h>
+#include <linux/utsname.h>
+#include <linux/mman.h>
+#include <linux/smp_lock.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+#include <linux/prctl.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/sched.h>
+#include <linux/socket.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/segment.h>
+#include <asm/unistd.h>
+
+//#include <sys/syscall.h>
+
+#define MAX_LENGTH 32
+#define NR_THREADS 512
+
+extern void *sys_call_table[];
+extern atomic_t access_lock;
+
+/* Load Kernel ECho modules. */
+asmlinkage int sys_kecho_load(char * module_name, int argument)
+{
+        char k_module_name[MAX_LENGTH];
+
+        /* Copy argument into kernel space. */
+        copy_from_user(k_module_name, module_name, MAX_LENGTH);
+
+        /* Load requested module. */
+        return request_module(k_module_name);
+}
+
+#ifdef CONFIG_QFABRIC
+/* Look up pseudo fd number. */
+struct socket *look_up_pseudofd(int fd, struct socket *fd_array[])
+{
+	return fd_array[fd];
+}
+
+/* Get pseudofd */
+int get_pseudofd(struct socket *sock, struct socket *fd_array[]) 
+{
+	int i = 0;
+
+	while ((i < MAX_FDS) && (fd_array[i] != NULL)) i++;
+
+        if (i == MAX_FDS) return -1;
+
+       	fd_array[i] = sock;
+
+      	return i;
+}
+
+/* Release pseudo fd. */
+int release_pseudofd(int i, struct socket *fd_array[]) 
+{
+       	fd_array[i] = NULL;
+
+ 	return 0;
+}
+
+/* Poll socket for incoming data. */
+int poll_socket(struct socket *socket) 
+{
+	struct sock *sock;
+
+    	sock = socket->sk;
+	if ((sock == NULL) || (sock->receive_queue.next == NULL) ||
+         (sock->receive_queue.next->len <= 0) ||
+         (sock->receive_queue.next->len > sock->receive_queue.next->truesize))
+     		return 0;
+	else	
+		return 1;
+}
+
+extern mm_segment_t kernel_get_fs(void)
+{
+	return current->addr_limit;
+}
+
+#ifdef CONFIG_X86_WP_WORKS_OK
+
+extern int kernel_access_ok(int type, const void *addr, size_t size) 
+{
+	if (__range_ok(addr,size) == 0) 
+		return 1;
+	return 0;
+}
+
+#else
+#ifdef CONFIG_ARM
+extern int kernel_access_ok(int type, const void *addr, size_t size) 
+{
+	if (__range_ok(addr,size) == 0) 
+		return 1;
+	return 0;
+}
+#else
+#ifndef CONFIG_IA64
+extern int kernel_access_ok(int type, const void *addr, size_t size)
+{
+ 	if ((__range_ok(addr,size) == 0) && 
+		 ((type) == VERIFY_READ || boot_cpu_data.wp_works_ok || 
+			 segment_eq(get_fs(),KERNEL_DS) || 
+			  __verify_write((void *)(addr),(size))))
+		return 1;
+	return 0;
+}
+#endif
+#endif
+#endif /* CPU */
+
+/* Initialize qfabric data structure. */
+void initialize_qfabric(void)
+{
+	if (current->qfabric == NULL) {
+ 		current->qfabric = (struct qfabric_struct *)
+		  kmalloc(sizeof(struct qfabric_struct), GFP_KERNEL); 
+		current->qfabric->fdqfabric = kmalloc (MAX_FDS, GFP_KERNEL);
+		memset(current->qfabric->fdqfabric, 0, MAX_FDS);
+		init_waitqueue_head(&current->qfabric->kecho_queue);
+		current->qfabric->weight = 0;
+		current->qfabric->orig_weight = 0;
+		current->qfabric->sw_pending = 0;
+	}
+}
+#endif
+/* KECho System Call API:  */
+asmlinkage int sys_KECho_syscall_echo(void *echo_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_fast_KECho_syscall_echo(void *echo_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_KECho_syscall_cm(void *cm_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_fast_KECho_syscall_cm(void *cm_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_KECho_syscall_cg(void *cg_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_fast_KECho_syscall_cg(void *cg_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_KECho_syscall_atl(void *atl_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_fast_KECho_syscall_atl(void *atl_data) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_KECho_sw_callback(int fd, int pid, void *ptr) 
+{
+        return -ENOSYS;
+}
+
+asmlinkage int sys_qos_configure(void)
+{
+        return -ENOSYS;
+}
diff -Naur test-for-latech/kernel/sched.c testqf-for-latech/kernel/sched.c
--- test-for-latech/kernel/sched.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/sched.c	2004-06-11 07:47:23.000000000 -0400
@@ -33,6 +33,20 @@
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
 
+//#define DWCS_DEBUG_ON 1
+
+#ifdef CONFIG_DWCS
+#include <linux/sched.h>
+#include <asm/unistd.h>
+#endif
+
+#ifdef CONFIG_QFABRIC
+extern void call_event_handler(void);
+extern void call_upcall_sched(struct task_struct **,
+	struct task_struct **, int *);
+extern int call_admission_control(struct task_struct *, struct sched_param *);
+#endif
+
 extern void timer_bh(void);
 extern void tqueue_bh(void);
 extern void immediate_bh(void);
@@ -41,10 +55,21 @@
  * scheduler variables
  */
 
+#ifdef CONFIG_QFABRIC
+atomic_t access_lock;
+atomic_t access_lock2;
+struct socket *fd_array[MAX_FDS];
+int ECalls_active = 0;
+
+struct wait_queue *global_wait_queue = NULL;
+#endif
+
 unsigned securebits = SECUREBITS_DEFAULT; /* systemwide security settings */
 
 extern void mem_use(void);
 
+unsigned long volatile jiffies_sim = 0; /* --RW-- */
+
 /*
  * Scheduling quanta.
  *
@@ -70,6 +95,31 @@
 
 #define NICE_TO_TICKS(nice)	(TICK_SCALE(20-(nice))+1)
 
+#ifdef CONFIG_DWCS
+#define MAX_TASKS 128
+/* 
+ * Module variables for DWCS scheduling and ECalls.
+ */
+#ifdef DWCS_DEBUG_ON
+unsigned long dwcs_sched_max_time = 0;
+unsigned long dwcs_old_time = 0;
+long dwcs_pid = -2;
+#endif
+int DWCS_module_loaded = 0;	/* Not initially loaded. */
+void (*DWCS_scheduler)(struct task_struct **, struct task_struct **) = NULL;
+int DWCS_update_utilization = 1;/* Initially set. */
+int utilization = 0;
+int DWCS_admission_control = 0; /* Not initially active. */
+#endif
+#ifdef CONFIG_QFABRIC
+int upcall_sched_active = 0;    /* Not initially active. */
+int security_off = 0;	        /* Not initially active. */
+int ECalls_current_flag = 0;    /* Not initially set. */
+struct task_struct *ECalls_current;
+int SOCKWATCH_module_loaded = 0;
+
+#endif
+extern void *sys_call_table[];
 
 /*
  *	Init task must be ok at boot for the ix86 as we will check its signals
@@ -92,19 +142,27 @@
 spinlock_t runqueue_lock __cacheline_aligned = SPIN_LOCK_UNLOCKED;  /* inner */
 rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;	/* outer */
 
-static LIST_HEAD(runqueue_head);
+LIST_HEAD(runqueue_head);
 
 /*
  * We align per-CPU scheduling data on cacheline boundaries,
  * to prevent cacheline ping-pong.
+ *
+ * GANEV: moved the data type description into a "typedef" in <linux/sched.h>
+ *        to make it accessible from a separately compiled loadable kernel
+ *        module.
  */
+#ifdef CONFIG_DWCS
+aligned_data_t aligned_data[NR_CPUS] __cacheline_aligned = { {{&init_task,0}}};
+#else
 static union {
 	struct schedule_data {
-		struct task_struct * curr;
+		struct task_struct *curr;
 		cycles_t last_schedule;
 	} schedule_data;
 	char __pad [SMP_CACHE_BYTES];
-} aligned_data [NR_CPUS] __cacheline_aligned = { {{&init_task,0}}};
+} aligned_data [NR_CPUS] __cacheline_aligned = { {{&init_task, 0}}};
+#endif
 
 #define cpu_curr(cpu) aligned_data[(cpu)].schedule_data.curr
 #define last_schedule(cpu) aligned_data[(cpu)].schedule_data.last_schedule
@@ -189,6 +247,15 @@
 	 * into account).
 	 */
 	weight = 1000 + p->rt_priority;
+#ifdef CONFIG_QFABRIC
+	if (p->qfabric != NULL) {
+	  if (p->qfabric->weight > 0) {
+	    weight  = -1000;
+	    p->qfabric->weight--;
+	  } else
+	    p->qfabric->weight = p->qfabric->orig_weight;
+	}
+#endif
 out:
 	return weight;
 }
@@ -536,6 +603,97 @@
 	__schedule_tail(prev);
 }
 
+/* --RW-- */
+#ifdef CONFIG_DWCS
+void dwcs_switch (struct task_struct *prev, struct task_struct *next) {
+
+  /* GANEV/FS: added definitions for "sched_data" which is needed in the
+   *           conditional below. */
+  int this_cpu;
+#ifdef CONFIG_SMP
+  struct schedule_data * sched_data;
+#endif
+  
+  this_cpu = prev->processor;
+
+  /* We might have switched CPUs: */
+#ifdef CONFIG_SMP
+  sched_data = & aligned_data[this_cpu].schedule_data;
+#endif
+
+
+	if (unlikely(prev == next)) {
+		/* We won't go through the normal tail, so do this by hand */
+		prev->policy &= ~SCHED_YIELD;
+		goto same_process;
+	}
+
+#ifdef CONFIG_SMP
+ 	/*
+ 	 * maintain the per-process 'last schedule' value.
+ 	 * (this has to be recalculated even if we reschedule to
+ 	 * the same process) Currently this is only used on SMP,
+	 * and it's approximate, so we do not have to maintain
+	 * it while holding the runqueue spinlock.
+ 	 */
+ 	sched_data->last_schedule = get_cycles();
+
+	/*
+	 * We drop the scheduler lock early (it's a global spinlock),
+	 * thus we have to lock the previous process from getting
+	 * rescheduled during switch_to().
+	 */
+
+#endif /* CONFIG_SMP */
+
+	kstat.context_swtch++;
+	/*
+	 * there are 3 processes which are affected by a context switch:
+	 *
+	 * prev == .... ==> (last => next)
+	 *
+	 * It's the 'much more previous' 'prev' that is on next's stack,
+	 * but prev is set to (the just run) 'last' process by switch_to().
+	 * This might sound slightly confusing but makes tons of sense.
+	 */
+	prepare_to_switch();
+	{
+		struct mm_struct *mm = next->mm;
+		struct mm_struct *oldmm = prev->active_mm;
+		if (!mm) {
+			BUG_ON(next->active_mm);
+			next->active_mm = oldmm;
+			atomic_inc(&oldmm->mm_count);
+			enter_lazy_tlb(oldmm, next, this_cpu);
+		} else {
+			BUG_ON(next->active_mm != mm);
+			switch_mm(oldmm, mm, next, this_cpu);
+		}
+
+		if (!prev->mm) {
+			prev->active_mm = NULL;
+			mmdrop(oldmm);
+		}
+	}
+
+	/*
+	 * This just switches the register state and the
+	 * stack.
+	 */
+	switch_to(prev, next, prev);
+	__schedule_tail(prev);
+
+same_process:
+	reacquire_kernel_lock(current);
+	/* --FS-- this check is moved to kernel/dwcs.c:schedule()
+	* if (current->need_resched)
+	*	goto need_resched_back;
+	*/
+	return;
+}  
+#endif
+
+
 /*
  *  'schedule()' is the scheduler function. It's a very simple and nice
  * scheduler: it's not perfect, but certainly works for most things.
@@ -550,10 +708,56 @@
 {
 	struct schedule_data * sched_data;
 	struct task_struct *prev, *next, *p;
+#ifdef CONFIG_QFABRIC
+	struct task_struct *old_p;
+#endif
 	struct list_head *tmp;
 	int this_cpu, c;
 
+#ifdef DWCS_DEBUG_ON
+	if (dwcs_old_time == 0) {
+		dwcs_old_time = jiffies;
+	} else {
+		unsigned long tmp;
+		tmp = jiffies - dwcs_old_time;
+		dwcs_old_time = jiffies;
+		if (dwcs_sched_max_time < tmp) {
+			dwcs_sched_max_time = tmp;
+			dwcs_pid = current->pid;
+		}
+	}
+#endif
 
+	/*
+	 * POELLABAUER: check if the current process created any
+	 * events via ECalls and if so process them.
+	 */
+#ifdef CONFIG_QFABRIC
+	if ((ECalls_active > 0) && (current->ecalls_flag))
+		call_event_handler();
+#endif
+
+  	/* --RW--
+         * First, check to see if the DWCS module is loaded.
+         * If so, call the DWCS scheduler instead.
+         */
+  	
+  	/*
+ 	 * GANEV: modified the scheduler function pointer to accept
+  	 *        two "struct task_struct *" parameters for the automatic
+  	 *        "prev" and "nexxt" variables, and pass back the chosen
+  	 *        task to run in them. Global variables to do this work no
+  	 *        longer if we want to be SMP-safe...
+  	 */
+
+#ifdef CONFIG_DWCS	
+  	if (DWCS_module_loaded && DWCS_scheduler) {
+  	  DWCS_scheduler(&prev, &next);
+  	  dwcs_switch(prev,next);
+  	  return;
+  	}
+#endif
+  	
 	spin_lock_prefetch(&runqueue_lock);
 
 	BUG_ON(!current->active_mm);
@@ -614,6 +818,16 @@
 		}
 	}
 
+        /* --CP-- */
+#ifdef CONFIG_DWCS
+#ifdef CONFIG_QFABRIC
+  	if (upcall_sched_active) {
+	  old_p = next;
+	  call_upcall_sched(&old_p, &next, &c);
+	}
+#endif
+#endif
+
 	/* Do we need to re-calculate counters? */
 	if (unlikely(!c)) {
 		struct task_struct *p;
@@ -930,10 +1144,10 @@
 	else {
 		retval = -EINVAL;
 		if (policy != SCHED_FIFO && policy != SCHED_RR &&
-				policy != SCHED_OTHER)
-			goto out_unlock;
+		    policy != SCHED_OTHER)
+		  goto out_unlock;
 	}
-	
+
 	/*
 	 * Valid priorities for SCHED_FIFO and SCHED_RR are 1..99, valid
 	 * priority for SCHED_OTHER is 0.
diff -Naur test-for-latech/kernel/signal.c testqf-for-latech/kernel/signal.c
--- test-for-latech/kernel/signal.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/signal.c	2004-06-11 07:47:23.000000000 -0400
@@ -52,7 +52,7 @@
 {
 	unsigned long i, *s, *m, x;
 	int sig = 0;
-	
+
 	s = tsk->pending.signal.sig;
 	m = mask->sig;
 	switch (_NSIG_WORDS) {
@@ -64,6 +64,22 @@
 			}
 		break;
 
+#ifdef CONFIG_QFABRIC
+	case 2: if (test_bit(SIGSTOP, &s[0]) == 1)
+			sig = SIGSTOP;
+		else if (test_bit(SIGKILL, &s[0]) == 1)
+			sig = SIGKILL;
+		else {
+			if ((x = s[1] &~ m[1]) != 0)
+				sig = _NSIG_BPW + 1;
+			else if ((x = s[0] &~ m[0]) != 0)
+				sig = 1;
+			else
+				break;
+			sig += ffz(~x);
+			break;
+		}
+#else
 	case 2: if ((x = s[0] &~ m[0]) != 0)
 			sig = 1;
 		else if ((x = s[1] &~ m[1]) != 0)
@@ -72,6 +88,7 @@
 			break;
 		sig += ffz(~x);
 		break;
+#endif
 
 	case 1: if ((x = *s &~ *m) != 0)
 			sig = ffz(~x) + 1;
diff -Naur test-for-latech/kernel/sys.c testqf-for-latech/kernel/sys.c
--- test-for-latech/kernel/sys.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/sys.c	2004-06-11 07:47:23.000000000 -0400
@@ -1279,6 +1279,47 @@
 	return error;
 }
 
+/* --RW-- 
+ * Replace this with the proper scheduler, when the 
+ * corresponding module is loaded. 
+ */
+asmlinkage void sys_load_scheduler (void)
+{
+ 	return;
+}
+ 
+asmlinkage void sys_unload_scheduler (void)
+{
+	return;
+}
+ 
+asmlinkage void sys_DWCS_scheduler (void)
+{
+	return;
+}
+
+asmlinkage void sys_update_utilization (void)
+{
+	return;
+}
+
+asmlinkage void sys_admission_control (void)
+{
+	return;
+}
+
+asmlinkage long sys_getsyscalls (void)
+{
+#ifdef CONFIG_QFABRIC
+	return current->syscall_counter;
+#endif
+}
+
+asmlinkage void sys_change_clock (void)
+{
+	return;
+}
+
 EXPORT_SYMBOL(notifier_chain_register);
 EXPORT_SYMBOL(notifier_chain_unregister);
 EXPORT_SYMBOL(notifier_call_chain);
diff -Naur test-for-latech/kernel/timer.c testqf-for-latech/kernel/timer.c
--- test-for-latech/kernel/timer.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/kernel/timer.c	2004-06-11 07:47:23.000000000 -0400
@@ -25,6 +25,12 @@
 
 #include <asm/uaccess.h>
 
+//#define DWCS_DEBUG_ON 1
+
+#ifdef CONFIG_DWCS
+extern int DWCS_module_loaded;
+#endif
+
 /*
  * Timekeeping variables
  */
@@ -63,6 +69,12 @@
 
 unsigned long event;
 
+#ifdef DWCS_DEBUG_ON
+unsigned long dwcs_timer_max_time = 0;
+unsigned long dwcs_timer_old_time = 0;
+long dwcs_max_counter = 0;
+#endif
+
 extern int do_setitimer(int, struct itimerval *, struct itimerval *);
 
 unsigned long volatile jiffies;
@@ -597,8 +609,27 @@
 	struct task_struct *p = current;
 	int cpu = smp_processor_id(), system = user_tick ^ 1;
 
+#ifdef DWCS_DEBUG_ON
+	if (dwcs_timer_old_time == 0) {
+		dwcs_timer_old_time = jiffies;
+	} else {
+		unsigned long tmp;
+		tmp = jiffies - dwcs_timer_old_time;
+		dwcs_timer_old_time = jiffies;
+		if (dwcs_timer_max_time < tmp) {
+			dwcs_timer_max_time = tmp;
+		}
+	}
+#endif
+
 	update_one_process(p, user_tick, system, cpu);
-	if (p->pid) {
+	//if (p->pid) {
+	if (1) {
+#ifdef DWCS_DEBUG_ON
+		if (p->counter > dwcs_max_counter) {
+			dwcs_max_counter = p->counter;
+		}
+#endif
 		if (--p->counter <= 0) {
 			p->counter = 0;
 			p->need_resched = 1;
@@ -695,6 +726,11 @@
 
 	update_process_times(user_mode(regs));
 #endif
+#ifdef CONFIG_DWCS
+	if (DWCS_module_loaded == 1) {
+	  	current->need_resched = 1;
+	}
+#endif
 	mark_bh(TIMER_BH);
 	if (TQ_ACTIVE(tq_timer))
 		mark_bh(TQUEUE_BH);
diff -Naur test-for-latech/Makefile testqf-for-latech/Makefile
--- test-for-latech/Makefile	2004-06-11 07:39:56.000000000 -0400
+++ testqf-for-latech/Makefile	2004-06-11 07:47:19.000000000 -0400
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 19
-EXTRAVERSION =
+EXTRAVERSION = -qfabric
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
diff -Naur test-for-latech/mm/filemap.c testqf-for-latech/mm/filemap.c
--- test-for-latech/mm/filemap.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/mm/filemap.c	2004-06-11 07:47:23.000000000 -0400
@@ -2883,6 +2883,14 @@
 	return page;
 }
 
+#ifdef CONFIG_QFABRIC
+struct page *grab_cache_page_ex(struct address_space *mapping, 
+				unsigned long index, struct page **cached_page)
+{
+	return __grab_cache_page(mapping, index, cached_page);
+}
+#endif
+
 inline void remove_suid(struct inode *inode)
 {
 	unsigned int mode;
diff -Naur test-for-latech/mm/mlock.c testqf-for-latech/mm/mlock.c
--- test-for-latech/mm/mlock.c	2004-06-11 07:40:02.000000000 -0400
+++ testqf-for-latech/mm/mlock.c	2004-06-11 07:47:23.000000000 -0400
@@ -12,6 +12,10 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 
+#ifdef CONFIG_QFABRIC
+extern int security_off;
+#endif
+
 static inline int mlock_fixup_all(struct vm_area_struct * vma, int newflags)
 {
 	spin_lock(&vma->vm_mm->page_table_lock);
@@ -151,8 +155,14 @@
 	struct vm_area_struct * vma, * next;
 	int error;
 
+#ifdef CONFIG_QFABRIC
+	if (security_off != 1)
+		if (on && !capable(CAP_IPC_LOCK))
+			return -EPERM;
+#else
 	if (on && !capable(CAP_IPC_LOCK))
 		return -EPERM;
+#endif
 	len = PAGE_ALIGN(len);
 	end = start + len;
 	if (end < start)
diff -Naur test-for-latech/net/Config.in testqf-for-latech/net/Config.in
--- test-for-latech/net/Config.in	2004-06-11 07:40:47.000000000 -0400
+++ testqf-for-latech/net/Config.in	2004-06-11 07:47:57.000000000 -0400
@@ -94,6 +94,12 @@
 #bool 'Network code profiler' CONFIG_NET_PROFILE
 endmenu
 
+#mainmenu_option next_comment
+#comment 'QSockets'
+if [ "$CONFIG_NET_CLS_SOCKET" = "y" ]; then
+  bool ' QSocket support' CONFIG_NET_QSOCKET
+fi
+
 mainmenu_option next_comment
 comment 'Network testing'
 tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN
diff -Naur test-for-latech/net/core/dev.c testqf-for-latech/net/core/dev.c
--- test-for-latech/net/core/dev.c	2004-06-11 07:40:49.000000000 -0400
+++ testqf-for-latech/net/core/dev.c	2004-06-11 07:47:57.000000000 -0400
@@ -1,4 +1,4 @@
-/*
+ /*
  * 	NET3	Protocol independent device support routines.
  *
  *		This program is free software; you can redistribute it and/or
@@ -977,6 +977,7 @@
 {
 	struct net_device *dev = skb->dev;
 	struct Qdisc  *q;
+	int rt_data = 0;
 
 	if (skb_shinfo(skb)->frag_list &&
 	    !(dev->features&NETIF_F_FRAGLIST) &&
@@ -1009,14 +1010,16 @@
 
 	/* Grab device queue */
 	spin_lock_bh(&dev->queue_lock);
-	q = dev->qdisc;
-	if (q->enqueue) {
-		int ret = q->enqueue(skb, q);
+	if (rt_data != 1) {
+		q = dev->qdisc;
+		if (q->enqueue) {
+			int ret = q->enqueue(skb, q);
 
-		qdisc_run(dev);
+			qdisc_run(dev);
 
-		spin_unlock_bh(&dev->queue_lock);
-		return ret == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : ret;
+			spin_unlock_bh(&dev->queue_lock);
+			return ret == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : ret;
+		}
 	}
 
 	/* The device has no queue. Common case for software devices:
@@ -1621,7 +1624,7 @@
  *	Thus we will need a 'compatibility mode'.
  */
 
-static int dev_ifconf(char *arg)
+static int dev_ifconf2(char *arg, int flag)
 {
 	struct ifconf ifc;
 	struct net_device *dev;
@@ -1633,9 +1636,12 @@
 	/*
 	 *	Fetch the caller's info block. 
 	 */
-	
-	if (copy_from_user(&ifc, arg, sizeof(struct ifconf)))
-		return -EFAULT;
+
+	if (flag == 0) {	
+		if (copy_from_user(&ifc, arg, sizeof(struct ifconf)))
+			return -EFAULT;
+	} else
+		memcpy(&ifc, arg, sizeof(struct ifconf));
 
 	pos = ifc.ifc_buf;
 	len = ifc.ifc_len;
@@ -1667,8 +1673,11 @@
 	 */
 	ifc.ifc_len = total;
 
-	if (copy_to_user(arg, &ifc, sizeof(struct ifconf)))
-		return -EFAULT; 
+	if (flag == 0) {
+		if (copy_to_user(arg, &ifc, sizeof(struct ifconf)))
+			return -EFAULT; 
+	} else 
+		memcpy(arg, &ifc, sizeof(struct ifconf));
 
 	/* 
 	 * 	Both BSD and Solaris return 0 here, so we do too.
@@ -1676,6 +1685,11 @@
 	return 0;
 }
 
+static int dev_ifconf(char *arg)
+{
+	return dev_ifconf2(arg, 0);
+}
+
 /*
  *	This is invoked by the /proc filesystem handler to display a device
  *	in detail.
@@ -1956,7 +1970,7 @@
  *	Perform the SIOCxIFxxx calls. 
  */
  
-static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
+static int dev_ifsioc2(struct ifreq *ifr, unsigned int cmd, int flag)
 {
 	struct net_device *dev;
 	int err;
@@ -2123,6 +2137,11 @@
 	return -EINVAL;
 }
 
+static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
+{
+	return dev_ifsioc2(ifr, cmd, 0);
+}
+
 /*
  *	This function handles all "interface"-type I/O control requests. The actual
  *	'doing' part of this is dev_ifsioc above.
@@ -2139,7 +2158,7 @@
  *	positive or a negative errno code on error.
  */
 
-int dev_ioctl(unsigned int cmd, void *arg)
+int dev_ioctl2(unsigned int cmd, void *arg, int flag)
 {
 	struct ifreq ifr;
 	int ret;
@@ -2152,7 +2171,10 @@
 	   
 	if (cmd == SIOCGIFCONF) {
 		rtnl_shlock();
-		ret = dev_ifconf((char *) arg);
+		if (flag == 1)
+			ret = dev_ifconf2((char *) arg, 1);
+		else
+			ret = dev_ifconf((char *) arg);
 		rtnl_shunlock();
 		return ret;
 	}
@@ -2160,8 +2182,11 @@
 		return dev_ifname((struct ifreq *)arg);
 	}
 
-	if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
-		return -EFAULT;
+	if (flag == 0) {
+		if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
+			return -EFAULT;
+	} else
+		memcpy(&ifr, arg, sizeof(struct ifreq));
 
 	ifr.ifr_name[IFNAMSIZ-1] = 0;
 
@@ -2192,13 +2217,19 @@
 		case SIOCGIFTXQLEN:
 			dev_load(ifr.ifr_name);
 			read_lock(&dev_base_lock);
-			ret = dev_ifsioc(&ifr, cmd);
+			if (flag == 1)
+				ret = dev_ifsioc2(&ifr, cmd, 1);
+			else
+				ret = dev_ifsioc(&ifr, cmd);
 			read_unlock(&dev_base_lock);
 			if (!ret) {
 				if (colon)
 					*colon = ':';
-				if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+				if (flag == 0) {
+				  if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
 					return -EFAULT;
+				} else 
+				  memcpy(arg, &ifr, sizeof(struct ifreq));
 			}
 			return ret;
 
@@ -2217,14 +2248,20 @@
 			dev_load(ifr.ifr_name);
 			dev_probe_lock();
 			rtnl_lock();
-			ret = dev_ifsioc(&ifr, cmd);
+			if (flag == 1)
+				ret = dev_ifsioc2(&ifr, cmd, 1);
+			else
+				ret = dev_ifsioc(&ifr, cmd);
 			rtnl_unlock();
 			dev_probe_unlock();
 			if (!ret) {
 				if (colon)
 					*colon = ':';
-				if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+				if (flag == 0) {
+				  if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
 					return -EFAULT;
+				} else 
+				  memcpy(arg, &ifr, sizeof(struct ifreq));
 			}
 			return ret;
 
@@ -2258,7 +2295,10 @@
 			dev_load(ifr.ifr_name);
 			dev_probe_lock();
 			rtnl_lock();
-			ret = dev_ifsioc(&ifr, cmd);
+			if (flag == 1)
+				ret = dev_ifsioc2(&ifr, cmd, 1);
+			else
+				ret = dev_ifsioc(&ifr, cmd);
 			rtnl_unlock();
 			dev_probe_unlock();
 			return ret;
@@ -2281,11 +2321,18 @@
 				dev_load(ifr.ifr_name);
 				dev_probe_lock();
 				rtnl_lock();
-				ret = dev_ifsioc(&ifr, cmd);
+				if (flag == 1)
+					ret = dev_ifsioc2(&ifr, cmd, 1);
+				else
+					ret = dev_ifsioc(&ifr, cmd);
 				rtnl_unlock();
 				dev_probe_unlock();
-				if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
+				if (flag == 0) {
+				  if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq)))
 					return -EFAULT;
+				} else {
+				  memcpy(arg, &ifr, sizeof(struct ifreq));
+				}
 				return ret;
 			}
 #ifdef WIRELESS_EXT
@@ -2301,11 +2348,17 @@
 				dev_load(ifr.ifr_name);
 				rtnl_lock();
 				/* Follow me in net/core/wireless.c */
-				ret = wireless_process_ioctl(&ifr, cmd);
+				if (flag == 1)
+					ret = wireless_process_ioctl2(&ifr, cmd, 1);
+				else 
+					ret = wireless_process_ioctl(&ifr, cmd);
 				rtnl_unlock();
+				if (flag == 0) {
 				if (!ret && IW_IS_GET(cmd) &&
 				    copy_to_user(arg, &ifr, sizeof(struct ifreq)))
 					return -EFAULT;
+				} else
+					memcpy(arg, &ifr, sizeof(struct ifreq));
 				return ret;
 			}
 #endif	/* WIRELESS_EXT */
@@ -2313,6 +2366,10 @@
 	}
 }
 
+int dev_ioctl(unsigned int cmd, void *arg)
+{
+	return dev_ioctl2(cmd, arg, 0);
+}
 
 /**
  *	dev_new_index	-	allocate an ifindex
diff -Naur test-for-latech/net/core/filter.c testqf-for-latech/net/core/filter.c
--- test-for-latech/net/core/filter.c	2004-06-11 07:40:49.000000000 -0400
+++ testqf-for-latech/net/core/filter.c	2004-06-11 07:47:57.000000000 -0400
@@ -325,9 +325,21 @@
 				continue;
 
 			case BPF_RET|BPF_K:
+/*
+#ifdef CONFIG_QFABRIC
+				wake_up_interruptible((wait_queue_head_t *)
+						&global_wait_queue);
+#endif
+*/
 				return ((unsigned int)fentry->k);
 
 			case BPF_RET|BPF_A:
+/*
+#ifdef CONFIG_QFABRIC
+				wake_up_interruptible((wait_queue_head_t *)
+						&global_wait_queue);
+#endif
+*/
 				return ((unsigned int)A);
 
 			case BPF_ST:
diff -Naur test-for-latech/net/core/skbuff.c testqf-for-latech/net/core/skbuff.c
--- test-for-latech/net/core/skbuff.c	2004-06-11 07:40:49.000000000 -0400
+++ testqf-for-latech/net/core/skbuff.c	2004-06-11 07:47:57.000000000 -0400
@@ -204,6 +204,11 @@
 	skb->cloned = 0;
 	skb->data_len = 0;
 
+#ifdef CONFIG_QFABRIC
+	skb->deadline = -1;
+	skb->flags = 0;
+#endif
+
 	atomic_set(&skb->users, 1); 
 	atomic_set(&(skb_shinfo(skb)->dataref), 1);
 	skb_shinfo(skb)->nr_frags = 0;
diff -Naur test-for-latech/net/core/sock.c testqf-for-latech/net/core/sock.c
--- test-for-latech/net/core/sock.c	2004-06-11 07:40:49.000000000 -0400
+++ testqf-for-latech/net/core/sock.c	2004-06-11 07:47:57.000000000 -0400
@@ -119,6 +119,17 @@
 #include <linux/skbuff.h>
 #include <net/sock.h>
 #include <linux/ipsec.h>
+#include <linux/sched.h>
+#ifdef CONFIG_QFABRIC
+//#include <sys/syscall.h>   /* --CP-- */
+#include <asm/unistd.h>
+
+extern void *sys_call_table[];
+extern void call_wake_up(int, int, int, int, void*);
+
+extern int request_socket_deadline(struct sock *sk);
+extern int request_socket_rt_flags(struct sock *sk);
+#endif
 
 #ifdef CONFIG_FILTER
 #include <linux/filter.h>
@@ -435,6 +446,16 @@
 		
   	switch(optname) 
   	{
+#ifdef CONFIG_QFABRIC
+		case SO_QOS_PRIORITY:
+			v.val = sk->qos_priority;
+			break;
+
+		case SO_QOS_DEADLINE:
+			v.val = sk->qos_deadline;
+			break;
+#endif
+
 		case SO_DEBUG:		
 			v.val = sk->debug;
 			break;
@@ -672,6 +693,12 @@
 		struct sk_buff * skb = alloc_skb(size, priority);
 		if (skb) {
 			skb_set_owner_w(skb, sk);
+#ifdef CONFIG_QFABRIC
+			if (sk->socket != NULL) {
+				skb->deadline = request_socket_deadline(sk);
+				skb->flags = request_socket_rt_flags(sk);
+			}
+#endif
 			return skb;
 		}
 	}
@@ -1117,7 +1144,7 @@
 void sock_def_wakeup(struct sock *sk)
 {
 	read_lock(&sk->callback_lock);
-	if (sk->sleep && waitqueue_active(sk->sleep))
+	if (sk->sleep && waitqueue_active(sk->sleep)) 
 		wake_up_interruptible_all(sk->sleep);
 	read_unlock(&sk->callback_lock);
 }
@@ -1133,15 +1160,29 @@
 
 void sock_def_readable(struct sock *sk, int len)
 {
+#ifdef CONFIG_QFABRIC
+	struct task_struct *tsk;
+#endif
 	read_lock(&sk->callback_lock);
 	if (sk->sleep && waitqueue_active(sk->sleep))
 		wake_up_interruptible(sk->sleep);
+#ifdef CONFIG_QFABRIC
+	if (sk->readable > 0) {
+		if ((tsk = find_task_by_pid(sk->owner)) != NULL)
+			if ((tsk->state >= 0) && (tsk->state < 2)) 
+				call_wake_up(sk->fd,sk->owner,0,sk->kecho,
+					sk->kecho_ptr);
+	}
+#endif
 	sk_wake_async(sk,1,POLL_IN);
 	read_unlock(&sk->callback_lock);
 }
 
 void sock_def_write_space(struct sock *sk)
 {
+#ifdef CONFIG_QFABRIC
+	struct task_struct *tsk;
+#endif
 	read_lock(&sk->callback_lock);
 
 	/* Do not wake up a writer until he can make "significant"
@@ -1154,6 +1195,13 @@
 		/* Should agree with poll, otherwise some programs break */
 		if (sock_writeable(sk))
 			sk_wake_async(sk, 2, POLL_OUT);
+#ifdef CONFIG_QFABRIC
+		if (sk->writable > 0)
+			if ((tsk = find_task_by_pid(sk->owner)) != NULL)
+				if ((tsk->state >= 0) && (tsk->state < 2))
+					call_wake_up(sk->fd,sk->owner,1,sk->kecho,
+						sk->kecho_ptr);
+#endif
 	}
 
 	read_unlock(&sk->callback_lock);
diff -Naur test-for-latech/net/core/wireless.c testqf-for-latech/net/core/wireless.c
--- test-for-latech/net/core/wireless.c	2004-06-11 07:40:49.000000000 -0400
+++ testqf-for-latech/net/core/wireless.c	2004-06-11 07:47:57.000000000 -0400
@@ -673,7 +673,7 @@
  * (dev_ioctl() in net/core/dev.c).
  * Check the type of IOCTL and call the appropriate wrapper...
  */
-int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
+int wireless_process_ioctl2(struct ifreq *ifr, unsigned int cmd, int flag)
 {
 	struct net_device *dev;
 	iw_handler	handler;
@@ -731,3 +731,8 @@
 	/* Not reached */
 	return -EINVAL;
 }
+
+int wireless_process_ioctl(struct ifreq *ifr, unsigned int cmd)
+{
+  return wireless_process_ioctl2(ifr, cmd, 0);
+}
diff -Naur test-for-latech/net/ipv4/tcp.c testqf-for-latech/net/ipv4/tcp.c
--- test-for-latech/net/ipv4/tcp.c	2004-06-11 07:40:50.000000000 -0400
+++ testqf-for-latech/net/ipv4/tcp.c	2004-06-11 07:47:57.000000000 -0400
@@ -1511,6 +1511,10 @@
 		 * handling. FIXME: Need to check this doesnt impact 1003.1g
 		 * and move it down to the bottom of the loop
 		 */
+
+#ifdef CONFIG_QFABRIC
+		if (sk->kecho != 1) 	
+#endif
 		if (signal_pending(current)) {
 			if (copied)
 				break;
@@ -1590,6 +1594,9 @@
 		if (tp->ucopy.task == user_recv) {
 			/* Install new reader */
 			if (user_recv == NULL && !(flags&(MSG_TRUNC|MSG_PEEK))) {
+#ifdef CONFIG_QFABRIC
+				if (sk->kecho != 1) 	
+#endif
 				user_recv = current;
 				tp->ucopy.task = user_recv;
 				tp->ucopy.iov = msg->msg_iov;
diff -Naur test-for-latech/net/ipv4/tcp_ipv4.c testqf-for-latech/net/ipv4/tcp_ipv4.c
--- test-for-latech/net/ipv4/tcp_ipv4.c	2004-06-11 07:40:50.000000000 -0400
+++ testqf-for-latech/net/ipv4/tcp_ipv4.c	2004-06-11 07:47:57.000000000 -0400
@@ -1521,7 +1521,12 @@
 	tcp_openreq_free(req); 
 drop:
 	TCP_INC_STATS_BH(TcpAttemptFails);
+/* --CP-- */
+#ifdef CONFIG_QFABRIC
+	return -ENOTCONN; /* send reset */
+#else
 	return 0;
+#endif
 }
 
 
diff -Naur test-for-latech/net/Makefile testqf-for-latech/net/Makefile
--- test-for-latech/net/Makefile	2004-06-11 07:40:47.000000000 -0400
+++ testqf-for-latech/net/Makefile	2004-06-11 07:47:57.000000000 -0400
@@ -7,7 +7,8 @@
 
 O_TARGET :=	network.o
 
-mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core
+mod-subdirs :=	ipv4/netfilter ipv6/netfilter ipx irda bluetooth atm netlink sched core \
+		qsocket
 export-objs :=	netsyms.o
 
 subdir-y :=	core ethernet
@@ -15,6 +16,7 @@
 
 
 subdir-$(CONFIG_NET)		+= 802 sched netlink
+subdir-$(CONFIG_NET_QSOCKET)	+= qsocket
 subdir-$(CONFIG_INET)		+= ipv4
 subdir-$(CONFIG_NETFILTER)	+= ipv4/netfilter
 subdir-$(CONFIG_UNIX)		+= unix
diff -Naur test-for-latech/net/netsyms.c testqf-for-latech/net/netsyms.c
--- test-for-latech/net/netsyms.c	2004-06-11 07:40:47.000000000 -0400
+++ testqf-for-latech/net/netsyms.c	2004-06-11 07:47:57.000000000 -0400
@@ -28,6 +28,7 @@
 #include <linux/hippidevice.h>
 #endif
 #include <net/pkt_sched.h>
+#include <net/pkt_cls.h>
 #include <net/scm.h>
 #include <linux/if_bridge.h>
 #include <linux/if_vlan.h>
@@ -35,6 +36,9 @@
 #ifdef CONFIG_NET_DIVERT
 #include <linux/divert.h>
 #endif /* CONFIG_NET_DIVERT */
+#ifdef CONFIG_NET_QSOCKET
+#include <linux/qsocket.h>
+#endif
 
 #ifdef CONFIG_NET
 extern __u32 sysctl_wmem_max;
@@ -106,11 +110,17 @@
 EXPORT_SYMBOL(memcpy_fromiovec);
 EXPORT_SYMBOL(memcpy_tokerneliovec);
 EXPORT_SYMBOL(sock_create);
+#ifdef CONFIG_QFABRIC
+EXPORT_SYMBOL(make_rt_sock);
+#endif
 EXPORT_SYMBOL(sock_alloc);
 EXPORT_SYMBOL(sock_release);
 EXPORT_SYMBOL(sock_setsockopt);
 EXPORT_SYMBOL(sock_getsockopt);
 EXPORT_SYMBOL(sock_sendmsg);
+#ifdef CONFIG_QFABRIC
+EXPORT_SYMBOL(rt_sock_sendmsg);
+#endif
 EXPORT_SYMBOL(sock_recvmsg);
 EXPORT_SYMBOL(sk_alloc);
 EXPORT_SYMBOL(sk_free);
@@ -500,6 +510,9 @@
 EXPORT_SYMBOL(dev_load);
 #endif
 EXPORT_SYMBOL(dev_ioctl);
+#ifdef CONFIG_QFABRIC
+EXPORT_SYMBOL(dev_ioctl2);
+#endif
 EXPORT_SYMBOL(dev_queue_xmit);
 #ifdef CONFIG_NET_HW_FLOWCONTROL
 EXPORT_SYMBOL(netdev_dropping);
@@ -548,6 +561,9 @@
 EXPORT_SYMBOL(qdisc_get_rtab);
 EXPORT_SYMBOL(qdisc_put_rtab);
 EXPORT_SYMBOL(qdisc_copy_stats);
+EXPORT_SYMBOL(qdisc_lookup_ops_string);
+EXPORT_SYMBOL(qdisc_alloc_handle);
+EXPORT_SYMBOL(qdisc_graft);
 #ifdef CONFIG_NET_ESTIMATOR
 EXPORT_SYMBOL(qdisc_new_estimator);
 EXPORT_SYMBOL(qdisc_kill_estimator);
@@ -562,6 +578,9 @@
 #ifdef CONFIG_NET_CLS
 EXPORT_SYMBOL(register_tcf_proto_ops);
 EXPORT_SYMBOL(unregister_tcf_proto_ops);
+#ifdef CONFIG_NET_CLS_SOCKET
+EXPORT_SYMBOL(cls_socket_ops);
+#endif
 #endif
 #ifdef CONFIG_NETFILTER
 #include <linux/netfilter.h>
@@ -588,4 +607,13 @@
 EXPORT_SYMBOL(net_call_rx_atomic);
 EXPORT_SYMBOL(softnet_data);
 
+#ifdef CONFIG_NET_QSOCKET
+EXPORT_SYMBOL(qop_base);
+#endif
+
+#ifdef CONFIG_QFABRIC
+EXPORT_SYMBOL(tcp_mem_schedule);
+EXPORT_SYMBOL(tcp_memory_pressure);
+#endif
+
 #endif  /* CONFIG_NET */
diff -Naur test-for-latech/net/qsocket/dwcs.h testqf-for-latech/net/qsocket/dwcs.h
--- test-for-latech/net/qsocket/dwcs.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/qsocket/dwcs.h	2004-06-11 07:48:02.000000000 -0400
@@ -0,0 +1,110 @@
+
+void watchdog(unsigned long arg)
+{
+	struct net_device *dev = (struct net_device*) arg;
+	if(dev)
+	{
+		netif_schedule(dev);
+	}
+}
+
+
+
+void dwcs_init_timer(struct timer_list *wd_timer, struct net_device *dev)
+{
+	init_timer(wd_timer);
+	wd_timer->function = watchdog;
+	wd_timer->data = (unsigned long)dev;  
+}
+
+
+/*
+** dwcs_link_class() inserts the class in qdisc's linked list.
+** It should be executed atomically.
+*/
+static void dwcs_link_class(struct dwcs_class *this)
+{
+	struct dwcs_sched_data *q = (struct dwcs_sched_data*)this->qdisc->data;
+	unsigned h                = dwcs_hash(this->classid);
+
+	this->next    = q->classes[h];
+	q->classes[h] = this;
+
+}
+
+/*
+ * Helper function to return the address of the class
+ * by providing the classid (that includes major and minor ids),
+ * Returns NULL, if no class is found.
+ */
+static __inline__ struct dwcs_class *
+dwcs_class_lookup ( struct dwcs_sched_data *q,
+					u32 classid )
+{
+	struct dwcs_class  *cl;
+
+	for ( cl = q->classes[dwcs_hash ( classid )]; cl; cl = cl->next )
+		if ( cl->classid == classid )
+		{
+			return cl;
+		}
+
+	return NULL;
+}
+
+
+
+static int q_dwcs_init(struct Qdisc *sch)
+{
+	struct dwcs_sched_data *q = (void*)sch->data;
+	
+	q->dlheap_size = 0;
+	q->ltheap_size = 0;
+	q->slheap_size = 0;
+	
+	q->link = (struct dwcs_class*) kmalloc(sizeof(struct dwcs_class), GFP_KERNEL);
+	if(q->link == NULL)
+	{
+		return -ENOBUFS;
+	}	
+	memset(q->link, 0, sizeof(struct dwcs_class));
+	
+	q->link->filter_list = NULL;
+	q->link->refcnt = 1;
+	q->link->classid = sch->handle;
+	q->link->qdisc = sch;
+
+	if(!(q->link->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)))
+	{
+		printk("no op qdisc \n");
+		q->link->q = &noop_qdisc;
+	}
+
+	if(sch->dev == NULL)
+		printk("dev == NULL : qsocket\n");
+	else 
+		dwcs_init_timer(&q->wd_timer, sch->dev);
+
+	
+	q->link->attr.ipg = 1;
+	q->link->attr.oln = 0;
+	q->link->attr.old = 1;
+	q->link->attr.flags = 0;
+	q->link->attr.cln  = 0;             /* Current loss numerator. */
+	q->link->attr.cld  = 0;             /* Current loss denominator. */
+	q->link->attr.droppable = FALSE;    /* TRUE if packets can be dropped */
+	q->link->attr.cln  = q->link->attr.oln;
+	q->link->attr.cld  = q->link->attr.old;
+	q->link->attr.clt  = (100 * q->link->attr.oln / q->link->attr.old);
+	q->link->attr.deadline = -1;
+	q->link->attr.readytime = -1;
+	
+	memset(q->classes, 0, sizeof(struct dwcs_class*) * 16);
+	
+	dwcs_link_class(q->link);
+	q->classcount = 1;
+
+	return 0;
+	
+}
+
diff -Naur test-for-latech/net/qsocket/Makefile testqf-for-latech/net/qsocket/Makefile
--- test-for-latech/net/qsocket/Makefile	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/qsocket/Makefile	2004-06-11 07:48:02.000000000 -0400
@@ -0,0 +1,7 @@
+#Makefile for qsocket 
+
+O_TARGET := qsocket.o
+
+obj-$(CONFIG_NET_QSOCKET) += qsock.o
+
+include $(TOPDIR)/Rules.make
diff -Naur test-for-latech/net/qsocket/qsock.c testqf-for-latech/net/qsocket/qsock.c
--- test-for-latech/net/qsocket/qsock.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/qsocket/qsock.c	2004-06-11 07:48:02.000000000 -0400
@@ -0,0 +1,1115 @@
+/* Mohammed Hasan Abbasi <habbasi@cc.gatech.edu>
+   Qsocket.c - implementation for the Qsocket api calls
+   API list:
+   qsocket(int, int, int, struct qos_params*)
+   qchange(int, struct qos_params*)
+   qshutdown(int)
+
+   qsocket() creates a socket and associates it with a class
+   it expects to be called after qos_conf()
+
+   qchange() takes a socket and associates it with a class in much the
+   same way that qsocket does. Only change is that it can take a socket
+   already associated with a class, delete the class, and add a new one.
+
+   qhutdown will simply delete the socket, the class etc etc.
+
+   Based on code snippetes from the file sch_dwcs.c,
+
+
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kmod.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/smp_lock.h>
+#include <linux/socket.h>
+#include <linux/file.h>
+#include <linux/net.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/wanrouter.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/cache.h>
+#include <linux/module.h>
+#include <linux/unistd.h>
+#include <linux/inet.h>
+#include <linux/netfilter.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/netdevice.h>
+#include <linux/stat.h>
+#include <linux/utsname.h>
+#include <linux/mm.h>
+#include <linux/fcntl.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <asm/current.h>
+#include <asm/uaccess.h>
+
+//#include <sys/syscall.h>
+#include <asm/unistd.h>
+#include <asm/uaccess.h>
+
+#include <net/ip.h>
+#include <net/sock.h>
+#include <net/tcp.h>
+#include <net/udp.h>
+#include <net/scm.h>
+#include <net/pkt_sched.h>
+#include <net/protocol.h>
+#include <linux/sch_dwcs.h>
+#include <linux/sched.h>
+#include <linux/qsocket.h>
+
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#define SLEEP_TIME HZ
+#define PORT_START 5100
+#define PORT_RANGE 100
+#define  MAX_SOCK_ADDR	128
+#define QERROR(code) do {err = code; goto err_out;}while(0);
+
+#define SYS_QCHANNEL 	13
+
+/* Global variables. */
+//static char hostname[MAXHOSTNAMELEN];
+
+extern void * sys_call_table[];
+int (*orig_qsocketcall)(int, unsigned long*);
+int (*socketcall)(int, unsigned long*);
+//int (*qos_conf)(int, int, int, char *, struct socket *, void *);
+int (*pidcall)(void);
+int (*sched_setscheduler)(pid_t, int, struct sched_param *);
+
+#include "utils.h"
+#include "dwcs.h"
+
+/*this is just for compatibility with teh newer version so that it can be compiled by just dropping it in*/
+struct qop_list *qop_base;
+
+/*
+static char *strdup(char *s)
+{
+  char *p;
+
+  p = (char *)kmalloc(strlen(s)+1, GFP_KERNEL);
+  if (p != NULL)
+    strcpy(p,s);
+  return p;
+}
+*/
+
+/*
+static void my_gethostname()
+{
+	down_read(&uts_sem);
+	memset(hostname, '\0', MAXHOSTNAMELEN);
+	memcpy(hostname, system_utsname.nodename, strlen(system_utsname.nodename));
+	if (memchr(hostname, '.', MAXHOSTNAMELEN) == NULL) {
+		strcat (hostname, ".");
+		strcat (hostname, system_utsname.domainname);
+	}
+	up_read(&uts_sem);
+}
+*/
+
+static int register_identifier(int server, int use_cpu, int use_net, char *app_id, int fd, struct dwcs_class *cl)
+{
+	//call qos_register
+//	struct sock *sk;
+	struct socket *sock;
+	int err = 0;
+	
+	
+	sock = sockfd_lookup(fd, &err);
+	if(!sock)
+	{
+		goto out;
+	}
+	
+	printk("calling qos_register\n");
+//	qos_register(server, use_cpu, use_net, app_id, sock, cl);
+	
+	sockfd_put(sock);
+  out:
+	return err;
+}
+
+static inline void unregister_identifier(int fd)
+{
+	//call qos_register
+//	struct sock *sk;
+	struct socket *sock;
+	int err = 0;
+	
+	
+	sock = sockfd_lookup(fd, &err);
+	if(!sock)
+	{
+		goto out;
+	}
+	
+	printk("calling qos_unregister\n");
+//	qos_unregister(sock);
+	
+	sockfd_put(sock);
+  out:
+	return;
+}
+
+
+
+static struct Qdisc * qsock_init_qdisc(struct net_device *dev)
+{
+	/*at some future time we can allow init to set up specific QDiscs and stuff*/
+
+	/*Start by adding a new DWCS QDisc as the root on this device
+	 *if there is already a qdisc installed there .. return 
+	 *The DWCS QDisc will have a default best effort queue class in it
+	 */
+
+	/******************************************
+	 * dev->qdisc is the pointer to the root - this should be null
+	 * 
+	 ******************************************/
+
+	int err = 0;
+	struct Qdisc *sch;
+	struct Qdisc *old_sch = NULL;
+	struct Qdisc *parent = NULL;
+	struct Qdisc_ops *ops;
+	int size;
+	int handle = 0; // = TC_H_MAKE(1, 0);
+	
+	ops = qdisc_lookup_ops_string("dwcs");
+	
+	if(ops == NULL)
+	{
+		char module_name[4+IFNAMSIZ+1];
+		sprintf(module_name, "sch_%s", "dwcs");
+		request_module(module_name);
+		ops = qdisc_lookup_ops_string("dwcs");
+	}
+
+	if(ops == NULL)
+	{
+		return NULL;
+	}
+	
+	size = sizeof(*sch) + ops->priv_size;
+	
+	sch = kmalloc(size, GFP_KERNEL);
+	if(sch == NULL)
+	{
+		return NULL;
+	}
+	
+	if(ops != qdisc_lookup_ops_string("dwcs"))
+	{
+		kfree(sch);
+		return NULL;
+	}
+	
+	skb_queue_head_init(&sch->q);
+
+	sch->ops = ops;
+	
+	sch->enqueue = ops->enqueue;
+	sch->dequeue = ops->dequeue;
+	sch->dev = dev;
+	
+	atomic_set(&sch->refcnt, 1);
+	sch->stats.lock = &dev->queue_lock;
+
+	handle = qdisc_alloc_handle(dev);
+	if(handle == 0)
+	{
+		kfree(sch);
+		return NULL;
+	}
+
+	sch->handle = handle;
+	/*initialize the dwcs qdisc here*/
+	if((err = q_dwcs_init(sch)) < 0)
+	{
+		kfree(sch);
+		return NULL;
+	}
+	ops->init(sch, NULL);
+	
+	if(qdisc_graft(dev, parent, 0, sch, &old_sch) < 0)
+	{
+		kfree(sch);
+		return NULL;
+	}
+
+// 	write_lock(&qdisc_tree_lock);
+// 	sch->next = dev->qdisc_list;
+// 	dev->qdisc_list = sch;
+// 	write_unlock(&qdisc_tree_lock);
+
+	return sch;
+	
+}
+
+asmlinkage long sys_qsocket(int family, int type, int protocol,
+			 struct qos_params *args, unsigned long *a)
+{
+
+	//a heck of a lot of definitions
+	//at some future time I will cut these down to a bare min
+
+	//network device to attach the qdisc to - we can later modify this 
+	//to attach to ALL the registered network devices .. probably
+	// a better option. 
+
+    struct net_device *temp = dev_base;
+	
+	//a kernel copy of the parameters passed in from user space
+    struct qos_params params;
+	
+	//the qdisc we are going to work on
+    struct Qdisc *qdisc = NULL;
+
+	//class ops for the qdisc
+    struct Qdisc_class_ops *cops = NULL;
+
+	//sched data for this qdisc
+    struct dwcs_sched_data *q = NULL;
+
+	//a dwcs class
+    struct dwcs_class *cl = NULL;
+    struct dwcs_class *temp_cl = NULL;
+
+	//the socket filter
+    struct socket_filter *fh = NULL;
+
+	//socket head - this contains all the socket filters
+	//attached to a class
+    struct socket_head *head = NULL;
+
+	//tcp protos - these contain the pointer to a list
+	// of all the filters
+    struct tcf_proto *tp = NULL;
+
+	//operations allowed for a filter
+	struct tcf_proto_ops *t = NULL;
+
+
+    int hash;
+    int i = 0;
+    int x = 0;
+    int err = 0;
+    int sockfd = 0;
+    struct socket *sock;
+    
+	//check if the argument set is null?
+    if(args == NULL)
+		QERROR(-EINVAL);
+	//copy the parameters from the user space. The name has to be copied separately
+    if(copy_from_user(&params, args, sizeof(struct qos_params)))
+		QERROR(-EFAULT);
+	
+    if(copy_from_user(params.dev, args->dev, sizeof(char) * IFNAMSIZ))
+		QERROR(-EFAULT);
+
+    if (params.disable == 1) {
+	sockfd = create_socket(a);
+	sock = sockfd_lookup(sockfd, &err);
+	sock->sk->reuse = 1;
+    	if (params.qos_on == 1) {
+    		//qos_conf = sys_call_table[__NR_qos_conf];
+		//qos_conf(0, 0, 0, params.app_id, sock, NULL);
+	}
+	return sockfd;
+    }
+
+	//find the device
+	//in a future implementation it might be necessary
+	//to attach the qdisc to all the devices
+    for(; temp != NULL; temp = temp->next)
+		if(!strcmp(params.dev, temp->name))
+		break;	   
+	//get the root qdisc and perform the operation on this
+    
+    qdisc = temp->qdisc;
+ 	/*clean up*/
+
+    cops = qdisc->ops->cl_ops;	
+		
+    if(qdisc == NULL)
+    {
+		qdisc = qsock_init_qdisc(temp);
+		if(qdisc == NULL)
+			QERROR(-EINVAL);
+    }
+
+    if(strcmp("dwcs", qdisc->ops->id))
+    {
+		qdisc = qsock_init_qdisc(temp);
+		if(qdisc == NULL || strcmp("dwcs", qdisc->ops->id))
+			QERROR(-EINVAL);
+    }
+
+    cops = qdisc->ops->cl_ops;
+
+	//create class and add it to teh queue. 
+	
+    q = (struct dwcs_sched_data *)qdisc->data;
+	
+    cl = (struct dwcs_class*) kmalloc(sizeof(struct dwcs_class), GFP_KERNEL);
+    if(cl == NULL)
+		QERROR(-EFAULT);
+	
+    memset(cl, 0, sizeof(struct dwcs_class));
+
+    cl->refcnt = 1;
+    if(!(cl->q = qdisc_create_dflt(qdisc->dev, &pfifo_qdisc_ops)))
+		cl->q = &noop_qdisc;
+
+    cl->qdisc = qdisc;
+    cl->attr.ipg = params.ipg;
+    cl->attr.oln = params.oln;
+    cl->attr.old = params.old;
+    cl->attr.flags = params.flags;
+    cl->attr.droppable = params.attribute;	   /* TRUE if packets can be dropped */
+	cl->attr.deadline = -1;
+	cl->attr.readytime = -1;
+	cl->attr.delay = 0;
+    cl->attr.cln  = 0;		   /* Current loss numerator. */
+    cl->attr.cld  = 0;		   /* Current loss denominator. */
+    cl->attr.cln  = cl->attr.oln;
+    cl->attr.cld  = cl->attr.old;
+    cl->attr.clt  = (100 * cl->attr.oln / cl->attr.old );
+	//attach class to qdisc
+
+	x = 0;
+	
+    for(i = 0; i < 16; i ++)
+    {
+		struct dwcs_class *c;
+		c = q->classes[i];
+		for(; c != NULL; c = c->next)
+		{
+			if(x <= TC_H_MIN(c->classid))
+				x = TC_H_MIN(c->classid);
+		}
+    }
+
+
+    cl->classid = TC_H_MAKE(qdisc->handle, (x+2)); //generate a proper value here	
+
+    hash = dwcs_hash(cl->classid);
+
+	//add the class to the queieing discpline
+	//should delay this until everything is done
+	//this will prevent spurious class constructions
+
+	dwcs_link_class(cl);
+	
+
+    q->classcount++;
+	
+	//ok now the class has been added to teh qdisc
+	//next step is to add the filter
+	//We will create the socket LAST
+	//go that its possible to revert changes without creating anything
+	//for the time being I won't do the error handling
+	//some time later we will have to modify this to support rollback
+	//which means deleting the class and the filter 
+
+	//we need some way of getting our hands on the priority
+	//for the tcf
+
+	//get the class
+
+
+    t = &cls_socket_ops; 
+    if(t == NULL)
+		QERROR(-EINVAL);
+	
+
+	//now we have our hands on the tcf_proto_ops
+    tp = (struct tcf_proto *) kmalloc(sizeof(struct tcf_proto), GFP_KERNEL);
+    memset(tp, 0, sizeof(*tp));
+    tp->ops = t;
+    tp->protocol = __constant_htons(ETH_P_ALL);	// protocol; //this should be IP
+    tp->prio = TC_H_MAKE(0xC0000000U,0U);  
+    tp->q = qdisc; //points to the parent qdisc
+    tp->classify = t->classify;
+    tp->classid = cl->classid; //points to the class which we just created
+	tp->root = NULL;
+	
+    err = t->init(tp);
+    if (err) 
+		QERROR(err);
+
+	//get the filter handle
+    if(fh == NULL)
+    {
+		if(tp->root == NULL)
+		{
+			head = kmalloc(sizeof(struct socket_head), GFP_KERNEL); 
+			if(head == NULL)
+				QERROR(-ENOBUFS);
+			memset(head, 0, sizeof(*head));
+			tp->root = head;
+		}
+
+		fh = kmalloc(sizeof(struct socket_filter), GFP_KERNEL);
+		if(fh == NULL)
+			return -ENOBUFS;
+		memset(fh, 0, sizeof(*fh));
+
+		fh->id = cl->classid;
+		fh->res.classid = cl->classid;
+		fh->pid = pidcall();
+		fh->res.class = (unsigned long)cl;
+		sockfd = create_socket(a);
+		fh->fd = sockfd;
+
+		//ok now we must create the socket!!
+
+		if(sockfd < 0)
+			QERROR(sockfd);
+
+		read_lock(&tasklist_lock);
+		{
+			struct task_struct *ts = find_task_by_pid( fh->pid );
+			struct file *fl = NULL;
+
+			if ( ts  && (fl=fcheck_files(ts->files,fh->fd) ) )
+			{
+				if ( fl->f_dentry && fl->f_dentry->d_inode )
+				{
+					fh->i_ino = fl->f_dentry->d_inode->i_ino;
+				}
+			}
+		}
+
+		read_unlock(&tasklist_lock);
+
+
+		write_lock(&qdisc_tree_lock);
+		spin_lock_bh(&temp->queue_lock);
+
+		fh->next = head->ht[socket_hash(0)];
+		wmb();
+		head->ht[socket_hash(0)] = fh;
+
+ 		q = (struct dwcs_sched_data*) qdisc->data;
+
+ 		temp_cl = q->link;
+ 		tp->next = temp_cl->filter_list;
+ 		temp_cl->filter_list = tp;
+		temp_cl->filters++;
+		spin_unlock_bh(&temp->queue_lock);
+		write_unlock(&qdisc_tree_lock);
+    }
+	else
+		QERROR(-EEXIST);
+
+	register_identifier(params.server, params.use_cpu, params.use_net, params.app_id, sockfd, cl);
+	
+
+    return sockfd;
+
+  err_out:
+
+	if(cl)
+		kfree(cl);
+
+	if(tp)
+		kfree(tp);
+
+	if(head)	
+		kfree(head);
+
+	if(fh)
+		kfree(fh);
+	
+	return err;
+}
+
+asmlinkage long sys_qshutdown(int fd, int how, unsigned long *a)
+{
+    struct net_device *dev = dev_base;
+	int err = 0;
+    struct Qdisc *qdisc;
+    struct Qdisc *leaf;
+    struct Qdisc_class_ops *cops;
+    struct dwcs_sched_data *sch_dwcs;
+    struct dwcs_class *cl, *link;
+    struct socket_filter *fh = NULL;
+    struct socket_head *head = NULL;
+    struct tcf_proto *tp = NULL;
+    int i_ino = 0;
+
+
+
+//	unregister_identifier(fd);
+//	printk("registered\n");
+	
+    read_lock(&tasklist_lock);
+    {
+		struct task_struct *ts = find_task_by_pid(pidcall() );
+		struct file *fl = NULL;
+
+		if ( ts	 && (fl=fcheck_files(ts->files, fd) ) )
+		{
+			
+		    if ( fl->f_dentry && fl->f_dentry->d_inode )
+		    {
+				i_ino = fl->f_dentry->d_inode->i_ino;
+		    }
+		}
+    }
+    read_unlock(&tasklist_lock);
+
+
+	err = socketcall(SYS_SHUTDOWN, a);
+
+    if(i_ino == 0)
+		return -EINVAL;
+
+
+    for(; dev !=NULL; dev = dev->next)
+    {
+		qdisc = dev->qdisc;
+		if(qdisc == NULL)
+		    continue;
+	
+		leaf = qdisc;
+
+
+		if(strcmp("dwcs", leaf->ops->id))
+		    continue;
+	
+
+		sch_dwcs = (struct dwcs_sched_data*) leaf->data;
+	
+		link = sch_dwcs->link;
+
+		for(tp = link->filter_list; tp; tp = tp->next)
+		{
+			if(tp->ops)
+			{
+				if(!strcmp("socket", tp->ops->kind))
+				{
+					head = tp->root;
+					if(head)
+						fh = head->ht[socket_hash(0)];
+					if(fh == NULL)
+					{
+						continue;
+					}
+					for(; fh; fh = fh->next)
+						if(fh->i_ino == i_ino)
+							goto out;
+				}
+			}
+		}
+	  out:
+		if(fh == NULL)
+		{
+		    return -EINVAL;
+		}
+		
+		//decrease ref count for the root class
+		if ( ( cl = ( void * ) fh->res.class ) == NULL )
+		{
+			if ( TC_H_MAJ ( fh->res.classid ) )
+				cl = dwcs_class_lookup ( sch_dwcs, fh->res.classid );
+		
+		}
+		
+
+		if(cl == NULL)
+		{
+			printk(KERN_ERR "cl == NULL\n");
+			return -EINVAL;
+		}
+
+
+		cops = leaf->ops->cl_ops;
+		
+		//sadly this has to be done
+		//because of the way that the classifier is used
+		//only the 0th entry is ever used	
+		fh->id = 0;
+		tp->ops->destroy(tp);
+		if(cl->filters)
+			cl->filters = 0;
+		link->filters--;
+		err = cops->delete(leaf, (unsigned long)cl);
+		return err;
+    }
+    return err;
+}
+
+asmlinkage long sys_qchange(int fd, struct qos_params *args, unsigned long *a)
+{
+
+    struct net_device *dev = dev_base;
+    struct Qdisc *qdisc;
+    struct Qdisc *leaf;
+    struct dwcs_sched_data *sch_dwcs;
+    struct dwcs_class *cl, *link;
+    struct socket_filter *fh = NULL;
+    struct socket_head *head = NULL;
+    struct tcf_proto *tp = NULL;
+    int i_ino = 0;
+	int ipg = 0, oln = 0, old = 0;
+	struct qos_params params;
+	
+	//check if teh argument set is null?
+    if(args == NULL)
+    {
+		return -EINVAL;
+    }
+
+	//copy the parameters from the user space. The name has to be copied seperatly
+    if(copy_from_user(&params, args, sizeof(struct qos_params)))
+		return -EFAULT;
+		
+    if(copy_from_user(params.dev, args->dev, sizeof(char) * IFNAMSIZ))
+    {
+		return -EFAULT;
+    }
+
+	//find the device
+	//in a future implementation it might be necessary
+	//to attach the qdisc to all the devices
+    for(; dev != NULL; dev = dev->next)
+		if(!strcmp(params.dev, dev->name))
+			break;	 
+
+	if(dev == NULL)
+		return -EINVAL;
+	
+    ipg = params.ipg;
+    oln = params.oln;
+    old = params.old;
+    
+    if(ipg == 0 || old == 0)
+		return -1;
+
+    
+    read_lock(&tasklist_lock);
+    {
+		struct task_struct *ts = find_task_by_pid(pidcall() );
+		struct file *fl = NULL;
+
+		if ( ts	 && (fl=fcheck_files(ts->files, fd) ) )
+		{
+			
+		    if ( fl->f_dentry && fl->f_dentry->d_inode )
+		    {
+				i_ino = fl->f_dentry->d_inode->i_ino;
+		    }
+		}
+    }
+    read_unlock(&tasklist_lock);
+
+    if(i_ino == 0)
+		return -EINVAL;
+
+
+	qdisc = dev->qdisc;
+	if(qdisc == NULL)
+		return -EINVAL;
+	
+	leaf = qdisc;
+
+
+	if(strcmp("dwcs", leaf->ops->id))
+		return -EINVAL;
+	
+
+	sch_dwcs = (struct dwcs_sched_data*) leaf->data;
+	
+	link = sch_dwcs->link;
+
+	for(tp = link->filter_list; tp; tp = tp->next)
+	{
+		if(tp->ops)
+		{
+			if(!strcmp("socket", tp->ops->kind))
+			{
+				head = tp->root;
+				if(head)
+					fh = head->ht[socket_hash(0)];
+				if(fh == NULL)
+				{
+					continue;
+				}
+				for(; fh; fh = fh->next)
+					if(fh->i_ino == i_ino)
+						goto out;
+			}
+		}
+	}
+  out:
+	if(fh == NULL)
+	{
+		return -EINVAL;
+	}
+		
+	//decrease ref count for the root class
+	if ( ( cl = ( void * ) fh->res.class ) == NULL )
+	{
+		if ( TC_H_MAJ ( fh->res.classid ) )
+			cl = dwcs_class_lookup ( sch_dwcs, fh->res.classid );
+		
+	}
+		
+
+	if(cl == NULL)
+	{
+		printk(KERN_ERR "cl == NULL\n");
+		return -EINVAL;
+	}
+
+
+	cl->attr.ipg = ipg;
+	cl->attr.oln = oln;
+	cl->attr.old = old;
+	cl->attr.flags = params.flags;
+	cl->attr.cln  = 0;	       /* Current loss numerator. */
+	cl->attr.cld  = 0;	       /* Current loss denominator. */
+	cl->attr.droppable = params.attribute;    /* TRUE if packets can be dropped */
+	cl->attr.cln  = cl->attr.oln;
+	cl->attr.cld  = cl->attr.old;
+	cl->attr.clt  = (100 * cl->attr.oln / cl->attr.old );			
+	return 0;
+}
+
+
+asmlinkage long sys_qsendto(int fd, void *buff, size_t len, unsigned int flags,
+							struct sockaddr *addr, int addr_len,
+							struct packet_flags *pflags, unsigned long *user_args)
+{
+	struct socket *sock;
+	char address[MAX_SOCK_ADDR];
+	int err;
+	struct msghdr msg;
+	struct iovec iov;
+	struct sock *sk;
+	struct packet_flags kpflags;
+	
+	sock = sockfd_lookup(fd, &err);
+	if (!sock){
+                 goto out;
+        }
+	iov.iov_base=buff;
+	iov.iov_len=len;
+	msg.msg_name=NULL;
+	msg.msg_iov=&iov;
+	msg.msg_iovlen=1;
+	msg.msg_control=NULL;
+	msg.msg_controllen=0;
+	msg.msg_namelen=addr_len;
+
+	if(addr)
+	{
+		err = move_addr_to_kernel(addr, addr_len, address);
+		if (err < 0)
+			goto out_put;
+		msg.msg_name=address;
+	}
+	if (sock->file->f_flags & O_NONBLOCK)
+		flags |= MSG_DONTWAIT;
+	msg.msg_flags = flags;
+
+/*qsocket specific stuff*/
+	sk = sock->sk;
+
+	if((err = copy_from_user(&kpflags, pflags, sizeof(kpflags))))
+		goto out_put;
+	sk->drop_flag = kpflags.drop_flag;
+	sk->urgent_flag = kpflags.urgent_flag;
+
+	if(kpflags.fragments != 0)
+	{
+		//application is defining its own fragmentation behaviour
+		//a value of 2 means that this is the last fragment
+		sk->fragments = kpflags.fragments;
+	}
+	else
+	{
+		sk->fragments = 0;
+	}
+
+	err = sock_sendmsg(sock, &msg, len);
+
+out_put:
+	sockfd_put(sock);
+out:
+	return err;
+}
+
+
+asmlinkage long sys_qsend(int fd, void *buff, size_t len, unsigned int flags,
+							struct packet_flags *pflags, unsigned long *user_args)
+{
+	return sys_qsendto(fd, buff, len, flags, NULL, 0, pflags, user_args);
+}
+
+asmlinkage long sys_qchannel(int fd, int server)
+{
+	struct socket *sock;
+	int err = 0;
+	
+	
+	sock = sockfd_lookup(fd, &err);
+	if(!sock)
+	{
+		goto out;
+	}
+	
+	printk("calling qos_changerole\n");
+//	qos_changerole(sock, server);
+	
+	sockfd_put(sock);
+  out:
+	return err;
+
+
+	return 0;
+}
+
+
+
+asmlinkage long sys_qinfo(int fd, struct qsocket_info *info)
+{
+	struct qsocket_info kinfo;
+	struct socket *sock;
+	struct sock* sk;
+	struct net_device *dev = dev_base;
+	struct Qdisc *qdisc = NULL, *leaf = NULL;
+	struct dwcs_sched_data *sch_dwcs = NULL;
+	struct dwcs_class *cl = NULL, *link = NULL;
+	struct socket_filter *fh = NULL;
+	struct socket_head *head = NULL;
+	struct tcf_proto *tp = NULL;
+	int i_ino = 0;
+	struct task_struct *ts;
+	int err = 0;
+	
+	//if(copy_from_user(&kinfo, info, sizeof(*info)))
+	//return -EFAULT;
+	
+	sock = sockfd_lookup(fd, &err);
+	if (!sock)
+	{
+		goto out;
+	}
+	sk = sock->sk;
+	
+
+	memset(&kinfo, 0, sizeof(kinfo));
+	
+
+	kinfo.input_qlen = sk->receive_queue.qlen;
+	
+//atomic_read(&sk->rmem_alloc);
+	//debug
+//	printk(KERN_INFO "input qlen = %ld\n", skb_queue_len(&sk->receive_queue));
+
+    read_lock(&tasklist_lock);
+    {
+		struct file *fl = NULL;
+		ts = find_task_by_pid(pidcall() );
+		if ( ts	 && (fl=fcheck_files(ts->files, fd) ) )
+		{
+			
+		    if ( fl->f_dentry && fl->f_dentry->d_inode )
+		    {
+				i_ino = fl->f_dentry->d_inode->i_ino;
+		    }
+		}
+    }
+	kinfo.cpu_time = (unsigned long) ts->times.tms_utime + 
+		(unsigned long) ts->times.tms_stime + 
+		ts->times.tms_cutime + ts->times.tms_cstime;
+	//debug
+//	printk(KERN_INFO "taks time = %ld, %ld\n", ts->times.tms_utime, ts->times.tms_stime);
+//	printk(KERN_INFO "cpu time = %ld, %ld\n", ts->per_cpu_stime[0], ts->per_cpu_utime[0]);
+
+    read_unlock(&tasklist_lock);
+
+	
+    for(; dev !=NULL; dev = dev->next)
+    {
+		qdisc = dev->qdisc;
+		if(qdisc == NULL)
+		    continue;
+	
+		leaf = qdisc;
+
+
+		if(strcmp("dwcs", leaf->ops->id))
+		    continue;
+	
+
+		sch_dwcs = (struct dwcs_sched_data*) leaf->data;
+	
+		link = sch_dwcs->link;
+
+		for(tp = link->filter_list; tp; tp = tp->next)
+		{
+			if(tp->ops)
+			{
+				if(!strcmp("socket", tp->ops->kind))
+				{
+					head = tp->root;
+					if(head)
+						fh = head->ht[socket_hash(0)];
+					if(fh == NULL)
+					{
+						continue;
+					}
+					for(; fh; fh = fh->next)
+						if(fh->i_ino == i_ino)
+							goto loop_out;
+				}
+			}
+		}
+	  loop_out:
+		if(fh == NULL)
+		{
+			// return -EINVAL;
+			goto out_put;
+		}
+		
+		//decrease ref count for the root class
+		if ( ( cl = ( void * ) fh->res.class ) == NULL )
+		{
+			if ( TC_H_MAJ ( fh->res.classid ) )
+				cl = dwcs_class_lookup ( sch_dwcs, fh->res.classid );
+		
+		}
+		
+
+		if(cl == NULL)
+		{
+			printk(KERN_ERR "cl == NULL\n");
+			goto out_put;
+		}
+
+		kinfo.output_qlen = cl->q->q.qlen;
+		kinfo.missed_deadlines = cl->attr.late;
+		kinfo.delay_jif = cl->attr.delay;
+		kinfo.sent_packets = cl->attr.sent;
+		err = 0;
+		goto out_put;
+    }
+	
+	
+out_put:
+	sockfd_put(sock);
+	if(info != NULL)
+	{
+		copy_to_user(info, &kinfo, sizeof(kinfo));
+	}
+
+out:
+	return err;
+}
+
+
+
+asmlinkage long sys_qsocketcall(int call, unsigned long *args)
+{
+    unsigned long a[10];
+    int err;
+
+    if((call<1||call>SYS_QRECVMSG))
+		return -EINVAL;
+
+    switch(call) 
+    {
+		case SYS_QSOCKET:
+			if(copy_from_user(a, args, 4*sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qsocket(a[0],a[1],a[2], (struct qos_params*) a[3], args);
+			break;
+		case SYS_QSHUTDOWN:
+			if(copy_from_user(a, args, 2*sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qshutdown(a[0],a[1], args);
+			break;
+		case SYS_QCHANGE: 
+			if(copy_from_user(a, args, 2*sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qchange(a[0], (struct qos_params*) a[1], args);
+			break;
+		case SYS_QSENDTO:
+			if(copy_from_user(a, args, 7*sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qsendto(a[0], (void*)a[1], a[2], a[3], (struct sockaddr*)a[4],
+							  a[5], (struct packet_flags*)a[6], args);
+			break;	    
+		case SYS_QSEND:
+			if(copy_from_user(a, args, 5*sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qsend(a[0], (void*)a[1], a[2], a[3],
+							  (struct packet_flags*)a[4], args);
+			break;	    
+		case SYS_QINFO:
+			if(copy_from_user(a, args, 2 * sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qinfo(a[0], (struct qsocket_info*)a[1]);
+			break;
+		case SYS_QCHANNEL:
+			if(copy_from_user(a, args, 2 * sizeof(unsigned long)))
+				return -EFAULT;
+			err = sys_qchannel(a[0], a[1]);
+			break;
+		default:
+			err = socketcall(call, args);
+			break;
+    }
+    return err;
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+    orig_qsocketcall = sys_call_table[__NR_qsocketcall];
+    socketcall = sys_call_table[__NR_socketcall];
+    //qos_conf = sys_call_table[__NR_qos_conf];
+    pidcall = sys_call_table[__NR_getpid];
+    sys_call_table[__NR_qsocketcall] = sys_qsocketcall;
+
+    return 0;
+}
+
+void cleanup_module(void)
+{
+    sys_call_table[__NR_qsocketcall] = orig_qsocketcall;	
+}
+#endif
+
+
+#ifdef CONFIG_X86
+void qsocket_init(void)
+{
+	socketcall = sys_call_table[__NR_socketcall];
+	pidcall = sys_call_table[__NR_getpid];
+	sched_setscheduler = sys_call_table[__NR_sched_setscheduler];
+	//qos_conf = sys_call_table[__NR_qos_conf];
+}
+#endif
+MODULE_LICENSE("GPL");
+
diff -Naur test-for-latech/net/qsocket/sch_dwcs.h testqf-for-latech/net/qsocket/sch_dwcs.h
--- test-for-latech/net/qsocket/sch_dwcs.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/qsocket/sch_dwcs.h	2004-06-11 07:48:02.000000000 -0400
@@ -0,0 +1,163 @@
+/* 
+ * net/sched/sch_dwcs.h   DWCS algorithm scheduler.
+ *
+ *              This program is free software; you can redistribute it and/or
+ *              modify it under the terms of the GNU General Public License
+ *              as published by the Free Software Foundation; either version
+ *              2 of the License, or (at your option) any later version.
+ *
+ * Authors:     Gregory Losik <gregor@cc.gatech.edu>
+ *              Richard West <west@cc.gatech.edu>
+ *              Christian Poellabauer <chris@cc.gatech.edu>
+ *
+ * Changes:     J.D. Hollis <jdhollis@cc.gatech.edu>
+ *              cleaned up the formatting and added some comments
+ *
+ */
+ 
+
+#define TRUE	1
+#define FALSE	0
+#define MAX_CONNS       255    // GL: Technically it should be 2^16 but lets risk it...
+
+#define DWCS_VIOLATION  	0x00000001 			/* Window-constraint violation. */
+#define DWCS_WORK_CONS		0x00000002 			/* Does task support work-conservation? */
+#define DWCS_NON_DROPPABLE	0x00000008 	
+
+
+
+#include <linux/notifier.h>
+
+
+/* Scheduler attributes. Not all members are necessary for all scheduling policies. */
+typedef struct dwcs_class_attr {
+	// int cd;                    /* Class descriptor. */
+	// unsigned cnt;              /* Number pkts queued for this class. */
+
+	/* JDH: w, s, and f might not be needed as we've got a DWCS qdisc now */
+	double w;                     /* Weight. (For SFQ) */
+	double s;                     /* Start tag. (For SFQ) */
+	double f;                     /* Finish tag. (For SFQ) */
+
+	/* these are the actual, user-definable attributes */
+	long deadline;
+	long readytime;/* ok this requires a little explanation
+					  this is to maintain a specific throughput from the class
+					  thus a stream with packets to send, on an idle network
+					  won't send packets until the ready time has elasped for the 
+					  stream
+				   */
+
+	unsigned long ipg;            /* Inter-packet/msg gap. */
+	unsigned oln;                 /* Original loss numerator. */
+	unsigned old;                 /* Original loss denominator. */
+	
+	/* statistics */
+	unsigned cln;                 /* Current loss numerator. */
+	unsigned cld;                 /* Current loss denominator. */
+	long clt;                    /* Current loss tolerance. - not a float anymore
+								  * it indicates the percentage of loss tolerance instead of a fraction.
+								  *essentially multiplied by a 100 */
+	unsigned late;                /* Stats - number late pkts. */
+	unsigned sent;                /* Stats - number pkts sent. */
+	unsigned violations;          /* Stats - number loss tolerance violations. */
+	unsigned long delay;          /* Cumulative delay for this class. */
+	int t;                        /* Simulated time to process pkt. */
+	unsigned window;              /* Packet window size. */
+	unsigned wlate;               /* Count of late pkts in a time window. */
+	unsigned long bytes;          /* Total bytes serviced for this class. */
+	// long start_time;              /* Real-time this class started. */
+	
+	/* GL: since there is no per packet flag, it needs to be per stream... */
+	int droppable;                /* TRUE if packets may be dropped. */
+	unsigned int flags;           /* Flags as specified by user */
+} dwcs_class_attr_t;
+
+
+/* Deadline heap attributes. */
+struct dl_heap {
+	long deadline;                /* Packet deadline. */
+	// int stream;                   /* Stream number. */
+	u32 stream;                   /* Stream number. */
+};
+
+struct sl_heap
+{
+	long readytime;
+	u32 stream;
+};
+
+
+/* Loss tolerance heap attributes. */
+struct lt_heap {
+	int stream;                   /* Stream number. */
+	long deadline;                /* Packet deadline. */
+	int cln;                      /* Current loss numerator. */
+	int cld;                      /* Current loss denominator. */
+	int oln;                      /* Original loss numerator. */
+	int wlate;                    /* Late packets in window. */
+	unsigned long arr_time;       /* Packet arrival time. */
+	long clt;                    /* Current loss tolerance. */
+};
+
+struct dwcs_sched_data;
+ 
+struct dwcs_class
+{
+  struct dwcs_class           *next;          /* hash table link */
+  struct dwcs_class           *next_alive;    /* next class with backlog in this priority band */
+
+  /* Parameters */
+  u32                         classid;        /* the major:minor class id */
+  unsigned char		      priority;       /* class priority */
+  unsigned int		      *socket_num;    /* to be a socket number.... */
+#ifdef CONFIG_NET_CLS_POLICE
+  unsigned char	              police;
+#endif
+  struct Qdisc                *qdisc;         /* Ptr to DWCS discipline that class belongs to */
+  struct Qdisc                *q;             /* Elementary queueing discipline */
+  
+  /* Variables */
+  struct tcf_proto            *filter_list;
+  int		              refcnt;         /* used by _get() and _put() reference tracking */
+  int                         filters;        /* for keeping track the number of filters */
+  struct tc_stats             stats;          /* ??? used by _NET_ESTIMATOR */
+
+  /* DWCS  specific parameters */
+  struct dwcs_class_attr      attr;         /* Low level attributes of a class */
+};
+
+
+
+
+struct dwcs_sched_data
+{
+	struct dwcs_class         *classes[ 16 ]; /* Hash table of all classes. This is where all new calsses get inserted in */
+	struct dwcs_class         *link;           /* Default class for case when filters don't match */
+	unsigned                  classcount;     /* the counder for total # of classes; q->classes[i] has the actual list */
+
+
+	/* DWCS specific attributes */
+	struct dwcs_class         	*next_class;    /* next class from which we will try to dequeue (to be deleted) */
+
+	struct lt_heap          	ltheap[MAX_CONNS];    /* Loss-Tolerance Heap */
+	int                       	ltheap_size;
+	struct dl_heap            	dlheap[MAX_CONNS];    /* Deadline Heap */
+	int                       	dlheap_size;
+	struct sl_heap				slheap[MAX_CONNS];
+	int 						slheap_size;
+	struct timer_list 			wd_timer;	/* Watchdog timer */	
+	
+
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry *ent;
+#endif
+
+#ifdef CONFIG_NET_CLS_POLICE
+	struct dwcs_class	    *rx_class;
+#endif
+
+};
+
+
+ 
diff -Naur test-for-latech/net/qsocket/utils.h testqf-for-latech/net/qsocket/utils.h
--- test-for-latech/net/qsocket/utils.h	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/qsocket/utils.h	2004-06-11 07:48:02.000000000 -0400
@@ -0,0 +1,69 @@
+static __inline__ int socket_hash(u32 handle)
+{
+  return handle&0xFF;
+}
+
+
+static __inline__ struct socket *socki_lookup(struct inode *inode)
+{
+	return &inode->u.socket_i;
+}
+
+/**
+ *	sockfd_lookup	- 	Go from a file number to its socket slot
+ *	@fd: file handle
+ *	@err: pointer to an error code return
+ *
+ *	The file handle passed in is locked and the socket it is bound
+ *	too is returned. If an error occurs the err pointer is overwritten
+ *	with a negative errno code and NULL is returned. The function checks
+ *	for both invalid handles and passing a handle which is not a socket.
+ *
+ *	On a success the socket object pointer is returned.
+ */
+
+static struct socket *sockfd_lookup(int fd, int *err)
+{
+	struct file *file;
+	struct inode *inode;
+	struct socket *sock;
+
+	if (!(file = fget(fd)))
+	{
+		*err = -EBADF;
+		return NULL;
+	}
+
+	inode = file->f_dentry->d_inode;
+	if (!inode->i_sock || !(sock = socki_lookup(inode)))
+	{
+		*err = -ENOTSOCK;
+		fput(file);
+		return NULL;
+	}
+
+	if (sock->file != file) {
+		printk(KERN_ERR "socki_lookup: socket file changed!\n");
+		sock->file = file;
+	}
+	return sock;
+}
+
+static  __inline__ void sockfd_put(struct socket *sock)
+{
+	fput(sock->file);
+}
+
+
+static __inline__ unsigned dwcs_hash(u32 h)
+{
+    h ^= h>>8;
+    h ^= h>>4;
+    return h&0xF;
+}
+
+static inline int create_socket(unsigned long *args)
+{
+      return socketcall(SYS_SOCKET, args);
+}
+
diff -Naur test-for-latech/net/sched/cls_api.c testqf-for-latech/net/sched/cls_api.c
--- test-for-latech/net/sched/cls_api.c	2004-06-11 07:40:56.000000000 -0400
+++ testqf-for-latech/net/sched/cls_api.c	2004-06-11 07:48:00.000000000 -0400
@@ -42,6 +42,21 @@
 /* Protects list of registered TC modules. It is pure SMP lock. */
 static rwlock_t cls_mod_lock = RW_LOCK_UNLOCKED;
 
+struct tcf_proto_ops * tcf_proto_lookup_ops_string(const char *kind)
+{
+	struct tcf_proto_ops *t = NULL;
+
+	if (kind) {
+		read_lock(&cls_mod_lock);
+		for (t = tcf_proto_base; t; t = t->next) {
+			if (strcmp(kind, t->kind) == 0)
+				break;
+		}
+		read_unlock(&cls_mod_lock);
+	}
+	return t;
+}
+
 /* Find classifier type by string name */
 
 struct tcf_proto_ops * tcf_proto_lookup_ops(struct rtattr *kind)
@@ -448,6 +463,10 @@
           register_tcf_proto_ops(&cls_##name##_ops); \
 	}
 
+#ifdef CONFIG_NET_CLS_SOCKET
+	INIT_TC_FILTER(socket);
+#endif
+
 #ifdef CONFIG_NET_CLS_U32
 	INIT_TC_FILTER(u32);
 #endif
diff -Naur test-for-latech/net/sched/cls_socket.c testqf-for-latech/net/sched/cls_socket.c
--- test-for-latech/net/sched/cls_socket.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/sched/cls_socket.c	2004-06-11 07:48:00.000000000 -0400
@@ -0,0 +1,544 @@
+/*
+ * net/sched/cls_socket.c	Classifier mapping of open sockets to traffic class.
+ *
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ *
+ * Authors:	Gregory Losik, <gregory.losik@gtri.gatech.edu>
+ *              This clasifier is similar to other provided classifiers, but 
+ *              is implemented for the different use purposes.  One can 
+ *              use it to classify packets based on the packets associated 
+ *              PID and FD, or simply by provided INODE number. 
+ *
+ * Changes:
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/notifier.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+
+#include <linux/fs.h>                   /* for inode struct */
+#include <linux/net.h>                  /* for socket struct */
+#include <linux/file.h>                 /* for fcheck_task() */
+#include <linux/qsocket.h>
+
+/*
+struct socket_head
+{
+  struct socket_filter *ht[256];       
+};
+
+
+struct socket_filter
+{
+  struct socket_filter	*next;
+  u32			id;
+  u32                   pid;          
+  unsigned long         fd;           
+  unsigned long         i_ino;       
+  struct tcf_result	res;
+#ifdef CONFIG_NET_CLS_POLICE
+  struct tcf_police	*police;
+#endif
+};
+*/
+
+/* 
+ * The hash table for storing socket_filter structures in socket_head->ht 
+ */
+static __inline__ int socket_hash(u32 handle)
+{
+  return handle&0xFF;
+}
+
+
+
+/*
+ * Used to match a packet to a class based on certain properties of 
+ * the packet.  Socket filter determines the inode from which the
+ * packet was sent, and then compares this inode number to filter's
+ * inode # that it monitors for.
+ */
+static int socket_classify(struct sk_buff *skb, struct tcf_proto *tp,
+			  struct tcf_result *res)
+{
+	struct socket_head *head = (struct socket_head*)tp->root;
+	struct socket_filter *f = NULL;
+	unsigned long i_ino = 0;
+#ifdef CONFIG_IP_FIREWALL
+	u32 id = skb->fwmark;
+#else
+	u32 id = 0;
+#endif
+
+	{
+	  /* we try to get the inode, given the pointer to sk_buff */
+	  struct sock *sk = NULL;
+	  struct socket *sket = NULL;
+	  struct inode *node = NULL;
+	  
+	  if (skb && (sk=skb->sk) && (sket=sk->socket) && (node=sket->inode) && node )
+	    i_ino = node->i_ino;
+	}
+
+	/* tying to access socket_filter structure(s) of a current filter, and 
+	 * determine if it matches inode number */
+	if (head == NULL)
+	  goto old_method;
+
+
+
+	
+	for (f=head->ht[socket_hash(id)]; f; f=f->next) {
+	  if (f->i_ino == i_ino) {
+	    *res = f->res;
+#ifdef CONFIG_NET_CLS_POLICE
+	    if (f->police)
+	      return tcf_police(skb, f->police);
+#endif
+//	    printk(KERN_INFO __FUNCTION__ "classified successfully to classid = %d\n", res->classid);
+	    
+	    return 0;
+	  }
+	}
+	return -1;
+
+old_method:
+	/*
+	if (id && (TC_H_MAJ(id) == 0 ||
+		     !(TC_H_MAJ(id^tp->q->handle)))) {
+		res->classid = id;
+		res->class = 0;
+		return 0;
+	}
+	*/
+	return -1;
+}
+
+
+
+
+/*
+ * Returns the internal ID corresponding to the handle.  The internal
+ * id is the address of the socket_filter structure.
+ */
+static unsigned long socket_get(struct tcf_proto *tp, u32 handle)
+{
+	struct socket_head *head = (struct socket_head*)tp->root;
+	struct socket_filter *f;
+
+	if (head == NULL) {
+	  return 0;
+	}
+
+	for (f=head->ht[socket_hash(handle)]; f; f=f->next) {
+	         if (f->id == handle) {
+			return (unsigned long)f;
+		 }
+	}
+
+	return 0;
+}
+
+
+/*
+ * The put function on a filter is used to de-reference a filter that was 
+ * previouslly referenced using the get function.  In our case, we don't 
+ * keep track of references and therefore can ignore this function.
+ */
+static void socket_put(struct tcf_proto *tp, unsigned long f)
+{
+}
+
+
+/*
+ * The init function on a filter is used to initialize the parameters for 
+ * a filter.
+ */
+static int socket_init(struct tcf_proto *tp)
+{
+  MOD_INC_USE_COUNT;
+ return 0;
+}
+
+
+/*
+ * The destory function on a filter is used to remove a filter.  We 
+ * find the filter structure and then if the filter was bounded to 
+ * a class, we unbind it, so that class knows about it.  Finally we
+ * free the memory allocated by the filter stucture.
+ */
+static void socket_destroy(struct tcf_proto *tp)
+{
+	struct socket_head *head = (struct socket_head*)xchg(&tp->root, NULL);
+	struct socket_filter *f;
+	int h;
+
+	if (head == NULL) {
+		MOD_DEC_USE_COUNT;
+		return;
+	}
+
+	for (h=0; h<256; h++) {
+		while ((f=head->ht[h]) != NULL) {
+			unsigned long cl;
+			head->ht[h] = f->next;
+
+			if ((cl = __cls_set_class(&f->res.class, 0)) != 0)
+				tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+#ifdef CONFIG_NET_CLS_POLICE
+			tcf_police_release(f->police);
+#endif
+			kfree(f);
+		}
+	}
+	kfree(head);
+	MOD_DEC_USE_COUNT;
+}
+
+
+
+/*
+ * The delete function on a filter is used to delete a particular element of the 
+ * filter.  Similar to destroy() we call unbind on a class.
+ */
+static int socket_delete(struct tcf_proto *tp, unsigned long arg)
+{
+	struct socket_head *head = (struct socket_head*)tp->root;
+	struct socket_filter *f = (struct socket_filter*)arg;
+	struct socket_filter **fp;
+
+	if (head == NULL || f == NULL)
+		return -EINVAL;
+
+	for (fp=&head->ht[socket_hash(f->id)]; *fp; fp = &(*fp)->next) {
+		if (*fp == f) {
+			unsigned long cl;
+
+			*fp = f->next;
+			//synchronize_bh();
+
+			if ((cl = __cls_set_class(&f->res.class, 0)) != 0)
+				tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+#ifdef CONFIG_NET_CLS_POLICE
+			tcf_police_release(f->police);
+#endif
+			kfree(f);
+			return 0;
+		}
+	}
+	return -EINVAL;
+}
+
+
+
+
+/*
+ * The change function on a filter is used to change the properties 
+ * of a filter. This is similar to the change function on classes and 
+ * queuing disciplines.
+ */
+static int socket_change(struct tcf_proto *tp, unsigned long base,
+		     u32 handle,
+		     struct rtattr **tca,
+		     unsigned long *arg)
+{
+	struct socket_head *head = (struct socket_head*)tp->root;
+	struct socket_filter *f;
+	struct rtattr *opt = tca[TCA_OPTIONS-1];
+	struct rtattr *tb[TCA_SOCKET_MAX];
+	int    err;
+
+	if (!opt)
+		return handle ? -EINVAL : 0;
+
+	if (rtattr_parse(tb, TCA_SOCKET_MAX, RTA_DATA(opt), RTA_PAYLOAD(opt)) < 0)
+		return -EINVAL;
+
+
+	if ((f = (struct socket_filter*)*arg) != NULL) {
+		/* Node exists: adjust only classid */
+
+		if (f->id != handle && handle)
+		  return -EINVAL;
+		if (tb[TCA_SOCKET_CLASSID-1]) {
+		  unsigned long cl;
+
+		  f->res.classid = *(u32*)RTA_DATA(tb[TCA_SOCKET_CLASSID-1]);
+		  cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid);
+		  cl = __cls_set_class(&f->res.class, cl);
+		  if (cl)
+		    tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
+		}
+
+		if (tb[TCA_SOCKET_PROCESSID-1]) {
+		  err = -EINVAL;
+		  if (RTA_PAYLOAD(tb[TCA_SOCKET_PROCESSID-1]) != 4)
+		    goto errout;
+		f->pid = *(u32*)RTA_DATA(tb[TCA_SOCKET_PROCESSID-1]);
+		}
+
+		if (tb[TCA_SOCKET_FDID-1]) {
+		  err = -EINVAL;
+		  if (RTA_PAYLOAD(tb[TCA_SOCKET_FDID-1]) != 4)
+		    goto errout;
+		  f->fd = *(u32*)RTA_DATA(tb[TCA_SOCKET_FDID-1]);
+		}
+
+		if (tb[TCA_SOCKET_INODEID-1]) {
+		  err = -EINVAL;
+		  if (RTA_PAYLOAD(tb[TCA_SOCKET_INODEID-1]) != 4)
+		    goto errout;
+		  f->i_ino = *(unsigned long*)RTA_DATA(tb[TCA_SOCKET_INODEID-1]);
+		}
+
+
+#ifdef CONFIG_NET_CLS_POLICE
+		if (tb[TCA_SOCKET_POLICE-1]) {
+		  struct tcf_police *police = tcf_police_locate(tb[TCA_SOCKET_POLICE-1], tca[TCA_RATE-1]);
+		  
+		  police = xchg(&f->police, police);
+		  //synchronize_bh();
+		  
+		  tcf_police_release(police);
+		}
+#endif
+		return 0;
+	}
+
+
+	if (!handle)
+		return -EINVAL;
+
+	if (head == NULL) {
+		head = kmalloc(sizeof(struct socket_head), GFP_KERNEL);
+		if (head == NULL)
+			return -ENOBUFS;
+		memset(head, 0, sizeof(*head));
+
+		tp->root = head;
+		//synchronize_bh();
+	}
+
+	f = kmalloc(sizeof(struct socket_filter), GFP_KERNEL);
+	if (f == NULL)
+		return -ENOBUFS;
+	memset(f, 0, sizeof(*f));
+
+	f->id = handle;
+
+	if (tb[TCA_SOCKET_CLASSID-1]) {
+		err = -EINVAL;
+		if (RTA_PAYLOAD(tb[TCA_SOCKET_CLASSID-1]) != 4)
+			goto errout;
+		f->res.classid = *(u32*)RTA_DATA(tb[TCA_SOCKET_CLASSID-1]);
+		__cls_set_class(&f->res.class, tp->q->ops->cl_ops->bind_tcf(tp->q, base, f->res.classid));
+	}
+
+	if (tb[TCA_SOCKET_PROCESSID-1]) {
+		err = -EINVAL;
+		if (RTA_PAYLOAD(tb[TCA_SOCKET_PROCESSID-1]) != 4)
+		      goto errout;
+		f->pid = *(u32*)RTA_DATA(tb[TCA_SOCKET_PROCESSID-1]);
+	}
+
+	if (tb[TCA_SOCKET_FDID-1]) {
+	  err = -EINVAL;
+	  if (RTA_PAYLOAD(tb[TCA_SOCKET_FDID-1]) != 4)
+	    goto errout;
+	  f->fd = *(u32*)RTA_DATA(tb[TCA_SOCKET_FDID-1]);
+	}
+
+	if (tb[TCA_SOCKET_INODEID-1]) {
+	  err = -EINVAL;
+	  if (RTA_PAYLOAD(tb[TCA_SOCKET_INODEID-1]) != 4)
+	    goto errout;
+	  f->i_ino = *(unsigned long*)RTA_DATA(tb[TCA_SOCKET_INODEID-1]);
+	}
+
+#ifdef CONFIG_NET_CLS_POLICE
+	if (tb[TCA_SOCKET_POLICE-1])
+		f->police = tcf_police_locate(tb[TCA_SOCKET_POLICE-1], tca[TCA_RATE-1]);
+#endif
+
+
+	/* Determine inode by having pid and fd */
+
+	read_lock(&tasklist_lock);
+	if( !f->i_ino && f->pid ) {
+	  struct task_struct *ts = find_task_by_pid( f->pid );
+	  struct file *fl = NULL;
+
+	  if ( ts  && (fl=fcheck_files(ts->files,f->fd) ) ) {
+	    if ( fl->f_dentry && fl->f_dentry->d_inode ) {
+	      f->i_ino = fl->f_dentry->d_inode->i_ino;
+	    }
+	  }
+	}
+	read_unlock(&tasklist_lock);
+
+	f->next = head->ht[socket_hash(handle)];
+	wmb();
+	head->ht[socket_hash(handle)] = f;
+
+	*arg = (unsigned long)f;
+	return 0;
+
+errout:
+	if (f)
+		kfree(f);
+	return err;
+}
+
+
+
+/*
+ * The walk function on a filter is used to iterate over all the elments of a 
+ * filter and invoke a callback function for each of the elements.  This is 
+ * usually used to obtain diagnostic data for all the elements of a filter.
+ */
+static void socket_walk(struct tcf_proto *tp, struct tcf_walker *arg)
+{
+	struct socket_head *head = (struct socket_head*)tp->root;
+	int h;
+
+	if (head == NULL)
+		arg->stop = 1;
+
+	if (arg->stop)
+		return;
+
+	for (h = 0; h < 256; h++) {
+		struct socket_filter *f;
+
+		for (f = head->ht[h]; f; f = f->next) {
+			if (arg->count < arg->skip) {
+				arg->count++;
+				continue;
+			}
+			if (arg->fn(tp, (unsigned long)f, arg) < 0) {
+				arg->stop = 1;
+				break;
+			}
+			arg->count++;
+		}
+	}
+}
+
+
+
+/*
+ * The dump function on a class is used to dump diagnostic data about 
+ * the filter and one or more of its elements.
+ */
+#ifdef CONFIG_RTNETLINK
+static int socket_dump(struct tcf_proto *tp, unsigned long fh,
+		   struct sk_buff *skb, struct tcmsg *t)
+{
+	struct socket_filter *f = (struct socket_filter*)fh;
+	unsigned char	 *b = skb->tail;
+	struct rtattr *rta;
+
+
+	if (f == NULL)
+		return skb->len;
+
+
+	t->tcm_handle = f->id;
+
+       if (!f->res.classid
+#ifdef CONFIG_NET_CLS_POLICE
+           && !f->police
+#endif
+           )
+		return skb->len;
+
+	rta = (struct rtattr*)b;
+	RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+	if (f->res.classid)
+		RTA_PUT(skb, TCA_SOCKET_CLASSID, 4, &f->res.classid);
+#ifdef CONFIG_NET_CLS_POLICE
+	if (f->police) {
+		struct rtattr * p_rta = (struct rtattr*)skb->tail;
+
+		RTA_PUT(skb, TCA_SOCKET_POLICE, 0, NULL);
+
+		if (tcf_police_dump(skb, f->police) < 0)
+			goto rtattr_failure;
+
+		p_rta->rta_len = skb->tail - (u8*)p_rta;
+	}
+#endif
+
+	rta->rta_len = skb->tail - b;
+#ifdef CONFIG_NET_CLS_POLICE
+	if (f->police) {
+		RTA_PUT(skb, TCA_STATS, sizeof(struct tc_stats), &f->police->stats);
+	}
+#endif
+	return skb->len;
+
+rtattr_failure:
+	skb_trim(skb, b - skb->data);
+	return -1;
+}
+#endif
+
+
+
+struct tcf_proto_ops cls_socket_ops = {
+	NULL,
+	"socket",
+	socket_classify,
+	socket_init,
+	socket_destroy,
+
+	socket_get,
+	socket_put,
+	socket_change,
+	socket_delete,
+	socket_walk,
+#ifdef CONFIG_RTNETLINK
+	socket_dump
+#else
+	NULL
+#endif
+};
+
+#ifdef MODULE
+int init_module(void)
+{
+	return register_tcf_proto_ops(&cls_socket_ops);
+}
+
+void cleanup_module(void) 
+{
+	unregister_tcf_proto_ops(&cls_socket_ops);
+}
+#endif
diff -Naur test-for-latech/net/sched/Config.in testqf-for-latech/net/sched/Config.in
--- test-for-latech/net/sched/Config.in	2004-06-11 07:40:56.000000000 -0400
+++ testqf-for-latech/net/sched/Config.in	2004-06-11 07:48:00.000000000 -0400
@@ -1,6 +1,7 @@
 #
 # Traffic control configuration.
-# 
+#
+tristate '  DWCS packet scheduler' CONFIG_NET_SCH_DWCS 
 tristate '  CBQ packet scheduler' CONFIG_NET_SCH_CBQ
 tristate '  CSZ packet scheduler' CONFIG_NET_SCH_CSZ
 #tristate '  H-PFQ packet scheduler' CONFIG_NET_SCH_HPFQ
@@ -24,6 +25,7 @@
 fi
 bool '  Packet classifier API' CONFIG_NET_CLS
 if [ "$CONFIG_NET_CLS" = "y" ]; then
+   bool '    Socket classifier' CONFIG_NET_CLS_SOCKET
    tristate '    TC index classifier' CONFIG_NET_CLS_TCINDEX
    tristate '    Routing table based classifier' CONFIG_NET_CLS_ROUTE4
    if [ "$CONFIG_NET_CLS_ROUTE4" != "n" ]; then
diff -Naur test-for-latech/net/sched/heap.c testqf-for-latech/net/sched/heap.c
--- test-for-latech/net/sched/heap.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/sched/heap.c	2004-06-11 07:48:00.000000000 -0400
@@ -0,0 +1,286 @@
+/*********************************************/
+/* Project:      Packet Scheduler            */
+/* File:         heap.c                      */
+/* Date:         10/17/1998                  */ 
+/* Author:       cp (chris@cc.gatech.edu)    */
+/* Contents:     heap functions              */
+
+/* Changes:
+ * J.D. Hollis, <jdhollis@cc.gatech.edu>
+ * updated HCompare() to newest version of DWCS 
+ * algorithm
+ */
+
+#include <linux/sch_dwcs.h>
+
+#define FLOOR(x)	(int)(x)
+
+/* Return parent element of i in heap array. */
+int HParent(int i) {
+
+  return (FLOOR(i/2));
+}
+
+/* Return left child element. */
+int HLeft(int i) {
+ 
+  return (2*i);
+}
+
+/* Return right child element. */
+int HRight(int i) {
+  
+  return (2*i+1);
+}
+
+/* Reorder heap. */
+void HHeapify(struct dl_heap heap[], int i, int size) {
+
+  int l, r;
+  int smallest;
+  struct dl_heap tmp;
+
+  l = HLeft(i);
+  r = HRight(i);
+ 
+  if ((l <= size) && (heap[l-1].deadline < heap[i-1].deadline))
+    smallest = l;
+  else
+    smallest = i;
+  
+  if ((r <= size) && (heap[r-1].deadline < heap[smallest-1].deadline))
+    smallest = r;
+
+  if (smallest != i) {
+    tmp = heap[i-1];
+    heap[i-1] = heap[smallest-1];
+    heap[smallest-1] = tmp;     
+    HHeapify(heap, smallest, size);
+  }
+}
+
+/* Insert element into heap. */
+void HInsert(struct dl_heap heap[], int stream, int value, int size) {
+  
+  int i = size;
+
+  while ((i > 1) && (heap[HParent(i)-1].deadline > value)) {
+    heap[i-1] = heap[HParent(i)-1];
+    i = HParent(i);
+  }  
+  heap[i-1].deadline = value;
+  heap[i-1].stream = stream;
+}
+
+/* Remove first element and reorders heap. */
+void HExtractMin(struct dl_heap heap[], int size) {
+
+  heap[0] = heap[size];   
+  heap[size].deadline = 0;   
+  heap[size].stream = 0; 
+  HHeapify(heap, 1, size);  
+}
+
+/* Remove element from heap. */
+void HDelete(struct dl_heap heap[], int stream, int size) {
+
+  int i=1;
+
+  while ((i < size+1) && (heap[i-1].stream != stream)) 
+    i++;
+  if (heap[i-1].stream == stream) {  
+    heap[i-1] = heap[size];   
+    heap[size].deadline = 0;   
+    heap[size].stream = 0; 
+    HHeapify(heap, i, size); 
+  } 
+}
+
+/*************************************************/
+/* Heap functions for loss-tolerance sorted heap */
+
+/* Compare two elements in the heap structure. */
+
+/* JDH: ok, cleaned up this function so that's it a little more readable
+ * and updated the ordering to fit the new DWCS algorithm:
+ * - earliest deadline first
+ * - equal deadlines, order lowest window-constraint first
+ * - equal deadlines and zero window-constraints, order highest window-
+ *   denominator first
+ * - equal deadlines and equal non-zero window-constraints, order lowest
+ *   window numerator first
+ * - all other cases: first-come-first-serve
+ */
+int HCompare(struct lt_heap heap1, struct lt_heap heap2) {
+
+  if (heap1.deadline > heap2.deadline)
+    return TRUE;
+  else if (heap1.deadline == heap2.deadline) {
+    if (heap1.clt > heap2.clt)
+      return TRUE;
+    else if (heap1.clt == heap2.clt) {
+      if (heap2.clt == 0.0)  {
+	if (heap1.cld < heap2.cld)
+	  return TRUE;
+      } else if (heap2.clt > 0.0) {
+	if (heap1.cln > heap2.cln)
+	  return TRUE;
+      }
+    } 
+  } else if ((heap2.clt == heap1.clt) &&
+	     (heap2.cld == heap1.cld) &&
+	     (heap2.cln == heap1.cln) &&
+	     (heap2.deadline == heap1.deadline)) {
+    if ((heap2.oln - heap2.wlate) < (heap1.oln - heap1.wlate))
+      return TRUE;
+    else if ((heap2.oln - heap2.wlate) == (heap1.oln - heap1.wlate) &&
+	     (heap2.arr_time < heap1.arr_time))
+      return TRUE;
+  }
+
+  return FALSE;
+
+}
+
+
+/* Reorder heap. */
+void HHeapify2(struct lt_heap heap[], int i, int size) {
+
+  int l, r;
+  int smallest;
+  struct lt_heap tmp_heap;
+
+  l = HLeft(i);
+  r = HRight(i);
+ 
+  if ((l <= size) && (HCompare(heap[i-1],heap[l-1]) == TRUE))
+     smallest = l;
+  else
+    smallest = i;
+  
+  if ((r <= size) && (HCompare(heap[smallest-1],heap[r-1]) == TRUE))
+    smallest = r;
+
+  if (smallest != i) {
+    tmp_heap = heap[i-1];
+    heap[i-1] = heap[smallest-1];
+    heap[smallest-1] = tmp_heap;     
+    HHeapify2(heap, smallest, size);
+  }
+}
+
+/* Insert element into heap. */
+void HInsert2(struct lt_heap heap[], struct lt_heap tmp_heap, int size) {
+  
+  int i = size;
+
+  while (i > 1) {
+
+    if (HCompare(heap[HParent(i)-1], tmp_heap)) {
+          heap[i-1] = heap[HParent(i)-1];
+          i = HParent(i);
+    }
+    else
+      break;
+  }  
+  heap[i-1] = tmp_heap;
+}
+
+/* Remove first element and reorder heap. */
+void HExtractMin2(struct lt_heap heap[], int size) {
+
+  heap[0] = heap[size];
+  heap[size].clt = 0.0;   
+  heap[size].stream = 0; 
+  heap[size].deadline = 0; 
+  heap[size].cln = 0; 
+  heap[size].cld = 0; 
+  heap[size].oln = 0; 
+  heap[size].arr_time = 0; 
+  heap[size].wlate = 0; 
+  HHeapify2(heap, 1, size);  
+}
+
+/* Remove element from heap. */
+void HDelete2(struct lt_heap heap[], int stream, int size) {
+
+  int i=1;
+
+  while ((i < size+1) && (heap[i-1].stream != stream)) 
+    i++;
+  if (heap[i-1].stream == stream) {  
+    heap[i-1] = heap[size];   
+    heap[size].clt = 0.0;   
+    heap[size].stream = 0; 
+    heap[size].deadline = 0; 
+    heap[size].cln = 0; 
+    heap[size].cld = 0; 
+    heap[size].oln = 0; 
+    heap[size].arr_time = 0; 
+    heap[size].wlate = 0; 
+    HHeapify2(heap, i, size); 
+  } 
+}
+
+/* Reorder heap. */
+void HHeapify3(struct sl_heap heap[], int i, int size) {
+
+  int l, r;
+  int smallest;
+  struct sl_heap tmp;
+
+  l = HLeft(i);
+  r = HRight(i);
+ 
+  if ((l <= size) && (heap[l-1].readytime < heap[i-1].readytime))
+    smallest = l;
+  else
+    smallest = i;
+  
+  if ((r <= size) && (heap[r-1].readytime < heap[smallest-1].readytime))
+    smallest = r;
+
+  if (smallest != i) {
+    tmp = heap[i-1];
+    heap[i-1] = heap[smallest-1];
+    heap[smallest-1] = tmp;     
+    HHeapify3(heap, smallest, size);
+  }
+}
+
+/* Insert element into heap. */
+void HInsert3(struct sl_heap heap[], int stream, int value, int size) {
+  
+  int i = size;
+
+  while ((i > 1) && (heap[HParent(i)-1].readytime > value)) {
+    heap[i-1] = heap[HParent(i)-1];
+    i = HParent(i);
+  }  
+  heap[i-1].readytime = value;
+  heap[i-1].stream = stream;
+}
+
+/* Remove first element and reorders heap. */
+void HExtractMin3(struct sl_heap heap[], int size) {
+
+  heap[0] = heap[size];   
+  heap[size].readytime = 0;   
+  heap[size].stream = 0; 
+  HHeapify3(heap, 1, size);  
+}
+
+/* Remove element from heap. */
+void HDelete3(struct sl_heap heap[], int stream, int size) {
+
+  int i=1;
+
+  while ((i < size+1) && (heap[i-1].stream != stream)) 
+    i++;
+  if (heap[i-1].stream == stream) {  
+    heap[i-1] = heap[size];   
+    heap[size].readytime = 0;   
+    heap[size].stream = 0; 
+    HHeapify3(heap, i, size); 
+  } 
+}
diff -Naur test-for-latech/net/sched/Makefile testqf-for-latech/net/sched/Makefile
--- test-for-latech/net/sched/Makefile	2004-06-11 07:40:56.000000000 -0400
+++ testqf-for-latech/net/sched/Makefile	2004-06-11 07:48:00.000000000 -0400
@@ -30,5 +30,7 @@
 obj-$(CONFIG_NET_CLS_RSVP6)	+= cls_rsvp6.o
 obj-$(CONFIG_NET_CLS_ROUTE4)	+= cls_route.o
 obj-$(CONFIG_NET_CLS_FW)	+= cls_fw.o
+obj-$(CONFIG_NET_CLS_SOCKET)	+= cls_socket.o
+obj-$(CONFIG_NET_SCH_DWCS)	+= sch_dwcs.o
 
 include $(TOPDIR)/Rules.make
diff -Naur test-for-latech/net/sched/sch_api.c testqf-for-latech/net/sched/sch_api.c
--- test-for-latech/net/sched/sch_api.c	2004-06-11 07:40:56.000000000 -0400
+++ testqf-for-latech/net/sched/sch_api.c	2004-06-11 07:48:00.000000000 -0400
@@ -200,6 +200,21 @@
 	return NULL;
 }
 
+struct Qdisc_ops *qdisc_lookup_ops_string(char *kind)
+{
+	struct Qdisc_ops *q = NULL;
+
+	if (kind) {
+		read_lock(&qdisc_mod_lock);
+		for (q = qdisc_base; q; q = q->next) {
+			if (strcmp(kind, q->id) == 0)
+				break;
+		}
+		read_unlock(&qdisc_mod_lock);
+	}
+	return q;
+}
+
 struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
 {
 	unsigned long cl;
@@ -1202,6 +1217,10 @@
 	INIT_QDISC(pfifo);
 	INIT_QDISC(bfifo);
 
+#ifdef CONFIG_NET_SCH_DWCS
+	INIT_QDISC(dwcs);
+#endif
+
 #ifdef CONFIG_NET_SCH_CBQ
 	INIT_QDISC(cbq);
 #endif
diff -Naur test-for-latech/net/sched/sch_dwcs.c testqf-for-latech/net/sched/sch_dwcs.c
--- test-for-latech/net/sched/sch_dwcs.c	1969-12-31 19:00:00.000000000 -0500
+++ testqf-for-latech/net/sched/sch_dwcs.c	2004-06-11 07:48:00.000000000 -0400
@@ -0,0 +1,1851 @@
+
+/* 
+ * net/sched/sch_dwcs.c   DWCS algorithm scheduler.
+ * 
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
+ * 
+ * Authors:	Gregory Losik <gregor@cc.gatech.edu>
+ *              Christian Poellabauer <chris@cc.gatech.edu>
+ * 		Hasan Abbasi <habbasi@cc.gatech.edu>
+ *		plus a bunch of other students during their
+ *		summer projects/independent projects/etc.
+ *
+ * Known issues: 1) PROC_MONITORING is not inserting new object under /proc FS.
+ *               2) Assumes there are no more then MAX_CONNS classes.  heap.c needs 
+ *                  to be changed to allow greater number.  Max can be 2^16.
+ *               3) The functionality of enabling packet dropping was not tested.
+ * 
+ * Modification: (Hasan Abbasi <habbasi@cc.gatech.edu>
+ * 		1) Fixed bug in dwcs_delete. The root class of the discipline 
+ * 			could be deleted which caused a seg-fault in the kernel
+ * 		2) Modified the dump function to return proper values instead of 
+ * 			limit.
+ * 		3) Added dump_class to display class information. (Same as dump).
+ *		4) Modified the scheduler to wake up the device at the minimum ready time
+ *		   	this required adding two function to the sch_api.c file. 
+ *			However the functions have been kept very generic and can be used by all qdiscs
+ *		5)  Add Best effor queuing to the default class. If the deadline of the the stream
+ *			is -1, insert it into the default class (same with non classified packets).
+ *			Modify the default class to exhibit queue like behaviour. Not so hard to do actually. 
+ *		7) Modified the enqueue functions to handle slow streams. Normally the deadline for an empty queue was modified
+ *			in such a way that a slow stream was not actually deadline constrained at the kernel level. This has been fixed
+ *
+ *		8) Added support for sending fragmented data at the scheduler level. This is tricky and relies on the usage of qsockets. 
+ * 			When multiple fragments are to be sent with the same deadline we don't want to update teh deadline until the last 
+ *			fragment for a data packet has been sent. 
+ * 
+ *		9) FIXME: Add a new structure to support setting up qdics without using rtattrs. This will make life soo much simpler when
+ *			we generalize qsockets.
+ * 		
+ */
+
+#define GREGORY					/* debugging message to get generall list of data */
+#define GREGORY_DETAILS			/* low leve debuggin message */
+#define GREGORY_TRACE			/* tells the association between sk_buff and classes */
+
+
+#define OVRHD           0		// GL: Not sure what it is... ????
+#define DROP_ON         1		// GL: Not sure what it is... ???? lets remove it.
+#define PROC_MONITORING			// GL: Define this to have /proc/ entry for status monitoring.
+
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/socket.h>
+#include <linux/sockios.h>
+#include <linux/in.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/if_ether.h>
+#include <linux/inet.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/notifier.h>
+#include <net/ip.h>
+#include <net/route.h>
+#include <linux/skbuff.h>
+#include <net/sock.h>
+#include <net/pkt_sched.h>
+#include <linux/proc_fs.h>
+#include <linux/unistd.h>
+
+//#include <sys/syscall.h>
+#include <asm/unistd.h>
+#include <asm/uaccess.h>
+
+
+#include "heap.c"
+
+extern void * sys_call_table[];
+
+int (*pidcall)(void);
+
+
+
+#ifdef PROC_MONITORING
+int                 proc_read_dwcs ( char *,
+									 char **,
+									 off_t,
+									 int,
+									 int *,
+									 void * );
+
+// struct proc_dir_entry proc_dwcs;
+#endif
+
+static __inline__ struct dwcs_class *dwcs_class_lookup ( struct
+														 dwcs_sched_data *,
+														 u32 );
+static void         dwcs_destroy_class ( struct dwcs_class * );
+static void         dwcs_link_class ( struct dwcs_class * );
+static void         dwcs_destroy_filters ( struct dwcs_class * );
+
+
+static inline unsigned long tvtojiffies(struct timeval *value)
+{
+	unsigned long sec = (unsigned) value->tv_sec;
+	unsigned long usec = (unsigned) value->tv_usec;
+
+	if (sec > (ULONG_MAX / HZ))
+		return ULONG_MAX;
+	usec += 1000000 / HZ - 1;
+	usec /= 1000000 / HZ;
+	return HZ*sec+usec;
+}
+
+
+/* 
+** the hash function for indexing dwcs_sched_data->classes[] array.  It
+** _must_ return a value in [0,16] range.
+*/
+static __inline__ unsigned
+dwcs_hash ( u32 h )
+{
+	h ^= h >> 8;
+	h ^= h >> 4;
+	return h & 0xF;
+}
+
+void watchdog(unsigned long arg)
+{
+	struct net_device *dev = (struct net_device *) arg;
+	if (dev)
+	{
+		netif_schedule(dev);
+	}
+}
+
+void dwcs_init_timer(struct timer_list *wd_timer, struct net_device *dev)
+{
+	init_timer(wd_timer);
+	wd_timer->function = watchdog;
+	wd_timer->data = (unsigned long) dev;
+}
+
+/* 
+ * The drop function is used to drop a packet from the
+ * queue.
+ */
+static int
+dwcs_drop ( struct Qdisc *sch )
+{
+	struct sk_buff     *skb;
+
+	skb = __skb_dequeue_tail ( &sch->q );
+	if ( skb )
+	{
+		sch->stats.backlog -= skb->len;
+		printk(KERN_ERR "dropping packet\n");
+		kfree_skb ( skb );
+		return 1;
+	}
+	return 0;
+
+}
+
+
+/*
+ * The reset function of a queuing discipline is used to reset the 
+ * queuing discipline to its innitial state.  It clears all queuing 
+ * disciplines, timers are stopped, etc.
+ */
+static void
+dwcs_reset ( struct Qdisc *sch )
+{
+	skb_queue_purge ( &sch->q );
+	sch->stats.backlog = 0;
+}
+
+
+/*
+ * No documentation on ..._reclassify() was found, but it relates
+ * to "policer"
+ */
+static struct dwcs_class *
+dwcs_reclassify ( struct sk_buff *skb,
+				  struct dwcs_class *this )
+{
+	return NULL;
+}
+
+
+
+/*
+ * A helper function that tries to return the address of a
+ * class to which "skb" should belong.  Returns NULL
+ * if can not be determined, and then packet usually gets 
+ * dropped, or assigned to some "default" class.
+ */
+static struct dwcs_class *
+dwcs_classify ( struct sk_buff *skb,
+				struct Qdisc *sch )
+{
+
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *head = q->link;
+	struct dwcs_class  *cl = NULL;
+	struct tcf_result   res;
+	int                 result = 0;
+
+	/*
+	 * tc_classify() calls each filter in a list, in order of priority and protocol id, 
+	 * * and returns the result in 'res' structure 
+	 */
+	if ( !head->filter_list
+		 || ( result = tc_classify ( skb, head->filter_list, &res ) ) < 0 )
+		goto fallback;
+
+	if ( ( cl = ( void * ) res.class ) == NULL )
+	{
+		if ( TC_H_MAJ ( res.classid ) )
+			cl = dwcs_class_lookup ( q, res.classid );
+
+		if ( cl == NULL )
+			goto fallback;
+
+	}
+
+	return cl;
+
+  fallback:
+	return head;
+}
+
+
+/*
+ * The enqueue function enqueues a packet with the queueing discipline.
+ * In our case, we basically first call classifier function, which in 
+ * turn does most of the work and returns the pointer of a class
+ * on which packet should be enqueued.
+ */
+static int
+dwcs_enqueue ( struct sk_buff *skb,
+			   struct Qdisc *sch )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  	*cl;
+	struct sock			*sk = NULL;
+	int		 			ret =  NET_XMIT_POLICED;
+	
+	cl = dwcs_classify ( skb, sch );
+
+#ifdef CONFIG_NET_CLS_POLICE
+	q->rx_class = cl;
+#endif
+
+	if ( cl )
+	{
+#ifdef CONFIG_NET_CLS_POLICE
+		cl->q->__parent = sch;
+#endif
+		if(skb)
+		{
+			sk = skb->sk;
+			skb->urgent_flag = jiffies;
+			if(sk)
+			{
+				skb->drop_flag = sk->drop_flag;
+			
+				if(sk->fragments == 0)
+				{
+					//initial fragment
+					skb->fragments = 0;
+					sk->fragments = 1;
+				}
+				else if(sk->fragments == 1)
+				{
+					skb->fragments = 1;
+				}
+				else
+					skb->fragments = 0;
+			}
+		
+		}
+
+		if(cl == q->link)
+		{
+			/*link class - this is the best effort class - the packet didn't ge
+			 *classified
+			 */
+			if((ret = cl->q->enqueue (skb, cl->q)) == 0)
+			{
+				/*queue the packet into the default class*/
+				
+				sch->q.qlen ++;
+				sch->stats.packets++;
+				sch->stats.bytes += skb->len;
+
+				/*we donot put the class into any of the heaps*/
+				mod_timer ( &q->wd_timer, jiffies );
+				
+				return 0;
+				
+			}
+			else
+			{
+				sch->stats.drops++;
+
+				kfree_skb ( skb );
+				if(cl != NULL);
+				{
+					cl->stats.drops++;
+				}
+				return ret;
+				
+			}
+	
+		}
+		else 
+		{
+			
+			if ((ret = cl->q->enqueue ( skb, cl->q )) == 0)
+			{
+				
+				sch->q.qlen++;
+				sch->stats.packets++;
+				sch->stats.bytes += skb->len;
+
+				/*
+				 * DWCS specific initialization 
+				 */
+				if ( cl->q->q.qlen == 1 )
+				{				// is it a head packet?
+					struct lt_heap      tmp_heap;
+
+					if(cl->attr.deadline == -1)
+					{
+						cl->attr.deadline = jiffies + cl->attr.ipg;	// GL: init deadline attribute
+					}
+				
+					if(cl->attr.readytime == -1)
+					{
+						cl->attr.readytime = jiffies;
+					}
+
+					while(cl->attr.deadline < jiffies)
+					{
+						cl->attr.late++;
+						cl->attr.wlate++;
+						if ( cl->attr.sent + cl->attr.late == cl->attr.window )
+						{
+							cl->attr.window += cl->attr.old;
+							if ( cl->attr.wlate > cl->attr.oln )
+							{
+								cl->attr.violations++;
+							}
+							cl->attr.wlate = 0;
+						}
+						cl->attr.deadline += ( cl->attr.ipg + OVRHD );
+						cl->attr.readytime += (cl->attr.ipg + OVRHD );
+						if ( cl->attr.cln > 0 )
+						{
+							cl->attr.cln--;
+							cl->attr.cld--;
+							if ( ( cl->attr.cld == 0 )
+								 && ( cl->attr.cln == 0 ) )
+							{
+								cl->attr.cln = cl->attr.oln;
+								cl->attr.cld = cl->attr.old;
+							}
+						}
+						else
+						{
+							if ( cl->attr.oln == 0 )
+								cl->attr.cld += cl->attr.old;
+							else
+							{
+								cl->attr.cln = 2 * ( cl->attr.oln ) - 1;
+								cl->attr.cld =
+									2 * ( cl->attr.old ) + ( cl->attr.cld -
+															 1 );
+							}
+						}
+						cl->attr.clt =
+							( cl->attr.cld == 0) ? 0.0 : ( float ) cl->attr.cln / cl->attr.cld;
+						
+					}
+					
+
+					if ( cl->attr.flags != DWCS_WORK_CONS )
+					{
+						/*
+						 * Insert head packet into deadline heap if deadline constrained 
+						 */
+						q->slheap_size++;
+						HInsert3 ( q->slheap, cl->classid,
+								   cl->attr.readytime,
+								   q->slheap_size );
+
+					}
+					else
+					{
+						q->dlheap_size++;
+						HInsert ( q->dlheap, cl->classid,
+								  cl->attr.deadline,
+								  q->dlheap_size );
+
+						/*
+						 * Insert head packet into loss-tolerance heap. 
+						 */
+						tmp_heap.clt = cl->attr.clt;
+						tmp_heap.stream = cl->classid;
+						tmp_heap.deadline = cl->attr.deadline;
+						tmp_heap.cln = cl->attr.cln;
+						tmp_heap.cld = cl->attr.cld;
+						tmp_heap.oln = cl->attr.oln;
+						// tmp_heap.old      = cl->attr.old;
+						tmp_heap.wlate = cl->attr.wlate;
+
+						/*
+						 * this one is tvtojiffies() from kernel/itimer.c 
+						 */
+						tmp_heap.arr_time = tvtojiffies(&(skb->stamp));
+
+						q->ltheap_size++;
+						HInsert2 ( q->ltheap, tmp_heap,
+								   q->ltheap_size );
+					}
+				}
+
+/*MHA: If there are any packets in the sleep heap
+ * set the timer to go off at the minimum ready time
+ * this gurantees that the packet will be sent 
+ * after ready time but before deadline
+ * even on a non busy link 
+ */
+	
+				if ( q->slheap_size > 0)
+					mod_timer ( &q->wd_timer, q->slheap[0].readytime );
+
+				return 0;
+			}
+			else
+			{
+				sch->stats.drops++;
+				if(cl == NULL)
+					kfree_skb ( skb );
+				if(cl != NULL);
+				{
+					cl->stats.drops++;
+				}
+
+				return ret;
+			}
+		}
+		
+	}
+	
+	/*
+	 * The dwcs_classify() has failed to classify the packet,
+	 * so we are dropping it. Theoretically, this should never 
+	 * happen in our case because we have default class for 
+	 * this: q->link.  However if this class gets explicitly 
+	 * deleted, by the user, we need to drop the packet.
+	 */
+	sch->stats.drops++;
+	if(cl == NULL)
+		kfree_skb ( skb );
+	if(cl != NULL);
+	{
+		cl->stats.drops++;
+	}
+
+	return ret;
+}
+
+
+
+/*
+ * The requeue function of a queuing discipline requeues a packet for 
+ * transmission.  After dequeueing the packet, if for some reason, the 
+ * packet is not transmitted, the packet needs to be put back in the 
+ * queue at the same position from where it was dequeued.
+ *
+ * (needs to be finished since it doesn't run filters/classifiers, 
+ *  but then I also never seen this function beeing called by a kernel.)
+ */
+static int
+dwcs_requeue ( struct sk_buff *skb,
+			   struct Qdisc *sch )
+{
+	printk(KERN_ERR "in dwcs_requeue\n");
+	kfree_skb(skb);
+	return NET_XMIT_CN;
+
+}
+
+
+
+
+/*
+ * The dequeue function dequeues a packet for sending.  It returns the next 
+ * packet that needs to be sent out on the output interface.  This packet 
+ * is determined by the scheduler in the queuing discipline.
+ * In our case we currently have something simmmilar to round-ribin 
+ * scheduling algorithm, but this will be replaced by DWCS.
+ */
+static struct sk_buff *
+dwcs_dequeue ( struct Qdisc *sch )
+{
+	struct sk_buff     *skb = NULL;
+	struct sk_buff     *result = NULL;
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+
+	struct lt_heap      tmp_heap;
+	int                 flag;
+	int                 not_drop_flag = FALSE;
+	u32                 classid = 0;
+	u32                 min_classid_index = 0;
+	struct dwcs_class  *cl = NULL;
+	struct dwcs_class  *tmp_cl = NULL;
+	struct dwcs_class  *sl_cl = NULL;
+	u32					qlen;
+	struct sl_heap      temp_slheap;
+
+
+	result = NULL;
+
+
+	/*
+	 * are there any packets to send? 
+	 */
+	if ( !sch->q.qlen )
+		return result;
+
+	qlen = sch->q.qlen;
+	
+/* MHA: Move all sleeping streams from the sleep heap 
+ * to the deadline and lt heaps
+ * but only if the readytime is less then jiffies 
+ * (ready time has elapsed)
+ */
+
+	while ( q->slheap_size > 0 && ( jiffies >= q->slheap[0].readytime ) )
+	{
+		temp_slheap = q->slheap[0];
+		sl_cl = dwcs_class_lookup ( q, q->slheap[0].stream );
+
+		if ( sl_cl != NULL )
+		{
+			q->dlheap_size++;
+			HInsert ( q->dlheap, q->slheap[0].stream,
+					  sl_cl->attr.deadline, q->dlheap_size );
+			skb = skb_peek ( &sl_cl->q->q );	// gets the pointer to a packet at the head.
+			tmp_heap.clt = sl_cl->attr.clt;
+			tmp_heap.stream = sl_cl->classid;
+			tmp_heap.deadline = sl_cl->attr.deadline;
+			tmp_heap.cln = sl_cl->attr.cln;
+			tmp_heap.cld = sl_cl->attr.cld;
+			tmp_heap.oln = sl_cl->attr.oln;
+			// tmp_heap.old      = tmp_cl->attr.old;
+			tmp_heap.wlate = sl_cl->attr.wlate;
+
+			tmp_heap.arr_time = tvtojiffies(&(skb->stamp));
+
+			q->ltheap_size++;
+			HInsert2 ( q->ltheap, tmp_heap, q->ltheap_size );
+
+			q->slheap_size--;
+			HExtractMin3 ( q->slheap, q->slheap_size );
+		}
+		else
+		{
+			q->slheap_size--;
+			HExtractMin3 ( q->slheap, q->slheap_size );
+		}
+	}
+	skb = NULL;
+	result = NULL;
+	sl_cl = NULL;
+
+/*MHA: the flag is a bit suspect. I think its an 
+ *artifact of some older code
+ */
+	flag = TRUE;
+	while ( flag )
+	{
+
+/*Check to see if the deadline of the heap can be met
+ * if the deadline cannot be met
+ * we can either drop the packet or perhaps still send it late
+ */
+
+		if ( ( q->dlheap_size > 0 ) && ( jiffies > q->dlheap[0].deadline ) )
+		{
+			classid = q->dlheap[0].stream;
+			printk(KERN_ERR " Missed deadline - deadline = %ld jiffies = %ld\n", q->dlheap[0].deadline, jiffies);
+
+			cl = dwcs_class_lookup ( q, classid );
+			if(cl)
+			{
+					
+				while ( cl && ( jiffies > cl->attr.deadline ) )
+				{
+					/*Update the deadline missed statistics - this is a bit strange and 
+					 *requires an explanation. For each ipg that jiffies is greater
+					 *then deadline by - we need to update teh deadline missed stats
+					 *since this is stream based
+					 */
+					cl->attr.late++;
+					cl->attr.wlate++;
+					if ( cl->attr.sent + cl->attr.late == cl->attr.window )
+					{
+						cl->attr.window += cl->attr.old;
+						if ( cl->attr.wlate > cl->attr.oln )
+						{
+							cl->attr.violations++;
+						}
+						cl->attr.wlate = 0;
+					}
+					cl->attr.deadline += ( cl->attr.ipg + OVRHD );
+					cl->attr.readytime += (cl->attr.ipg + OVRHD );
+					if ( cl->attr.cln > 0 )
+					{
+						cl->attr.cln--;
+						cl->attr.cld--;
+						if ( ( cl->attr.cld == 0 )
+							 && ( cl->attr.cln == 0 ) )
+						{
+							cl->attr.cln = cl->attr.oln;
+							cl->attr.cld = cl->attr.old;
+						}
+					}
+					else
+					{
+						if ( cl->attr.oln == 0 )
+							cl->attr.cld += cl->attr.old;
+						else
+						{
+							cl->attr.cln = 2 * ( cl->attr.oln ) - 1;
+							cl->attr.cld =
+								2 * ( cl->attr.old ) + ( cl->attr.cld -
+														 1 );
+						}
+					}
+				}				// end of "while ( (cl) && ( jiffies > cl->attr.deadline ) ) {"
+
+				cl->attr.clt =
+					( cl->attr.cld == 0) ? 0.0 : ( float ) cl->attr.cln / cl->attr.cld;
+				
+#ifdef DROP_ON
+				if(cl->attr.droppable !=  DWCS_NON_DROPPABLE)
+				{
+					/*ok this is if the stream supports dropppable packets
+					 *this needs to be added to the dwcs parameters obviously
+					 *There are three possible scenarios
+					 *	1) Stream is nondroppable packet is non droppable - don't drop anything
+					 *	2) Stream is nondroppable packet is droppable - erm.. don't know what to do
+					 *	3) Stream is droppable packet is non droppable - don't drop the packet
+					 *	4) Stream is droppable packet is droppable - drop away
+					 */
+					skb = skb_peek ( &cl->q->q );	// gets the pointer to a packet at the head.
+
+					if(skb && skb->drop_flag == DWCS_NON_DROPPABLE)
+					{
+						dwcs_drop ( cl->q );
+						printk("dropped late packet\n");
+						sch->q.qlen --;
+						q->ltheap_size--;
+						HDelete2 ( q->ltheap, classid, q->ltheap_size );
+						q->dlheap_size--;
+						HExtractMin ( q->dlheap, q->dlheap_size );
+						not_drop_flag = FALSE;
+						cl->attr.deadline += cl->attr.ipg;	// GL: init deadline attribute
+						cl->attr.readytime += ( cl->attr.ipg + OVRHD );
+
+						/*
+						 * insert new packet into both heaps. 
+						 */
+						if ( cl->q->q.qlen > 0 )
+						{
+							if ( cl->attr.flags != DWCS_WORK_CONS )
+							{
+
+								q->slheap_size++;
+								HInsert3 ( q->slheap, classid,
+										   cl->attr.readytime,
+										   q->slheap_size );
+							}
+							else
+							{
+								skb = skb_peek ( &cl->q->q );	// gets the pointer to a packet at the head.
+								if(skb != NULL)
+								{
+									
+									q->dlheap_size++;
+									q->ltheap_size++;
+
+									HInsert ( q->dlheap, classid, cl->attr.deadline,
+											  q->dlheap_size );
+									tmp_heap.clt = cl->attr.clt;
+									tmp_heap.stream = classid;
+									tmp_heap.deadline = cl->attr.deadline;
+									tmp_heap.cln = cl->attr.cln;
+									tmp_heap.cld = cl->attr.cld;
+									tmp_heap.oln = cl->attr.oln;
+									// tmp_heap.old      = cl->attr.old;
+									tmp_heap.wlate = cl->attr.wlate;
+									tmp_heap.arr_time = tvtojiffies(&(skb->stamp));
+									HInsert2 ( q->ltheap, tmp_heap, q->ltheap_size );
+								}
+							}
+						}
+					}
+					else
+					{
+						not_drop_flag = TRUE;
+						flag = FALSE;
+					}
+				}
+				else
+				{
+					not_drop_flag = TRUE;
+					flag = FALSE;
+				}
+#else
+				not_drop_flag = TRUE;
+				flag = FALSE;
+#endif
+			}
+		}
+		else
+		{
+			flag = FALSE;
+	
+			if ( not_drop_flag == TRUE )
+			{
+				cl = dwcs_class_lookup(q, q->dlheap[0].stream);
+				q->dlheap_size --;
+				q->ltheap_size --;
+				HExtractMin ( q->dlheap, q->dlheap_size );
+				HDelete2 ( q->ltheap, classid, q->ltheap_size );
+				skb = skb_peek ( &cl->q->q );	// gets the pointer to a packet at the head.
+				if(skb != NULL)
+				{
+
+					cl->attr.deadline += cl->attr.ipg;	// GL: init deadline attribute ???? do we need it???
+					cl->attr.readytime += cl->attr.ipg;
+					q->dlheap_size ++;
+					q->ltheap_size ++;
+					HInsert ( q->dlheap, classid, cl->attr.deadline,
+							  q->dlheap_size );
+					tmp_heap.clt = cl->attr.clt;
+					tmp_heap.stream = classid;
+					tmp_heap.deadline = cl->attr.deadline;
+					tmp_heap.cln = cl->attr.cln;
+					tmp_heap.cld = cl->attr.cld;
+					tmp_heap.oln = cl->attr.oln;
+					// tmp_heap.old      = cl->attr.old;
+					tmp_heap.wlate = cl->attr.wlate;
+					/*
+					 * this one is tvtojiffies() from kernel/itimer.c 
+					 */
+					tmp_heap.arr_time = tvtojiffies(&(skb->stamp));
+					HInsert2 ( q->ltheap, tmp_heap, q->ltheap_size );
+				}
+				skb = NULL;
+				
+			}
+			not_drop_flag = FALSE;
+		}					// end of " } else { "
+
+
+		/*
+		 * Send first element in loss tolerance heap. 
+		 */
+
+		if ( q->ltheap_size > 0 )
+		{
+			min_classid_index = q->ltheap[0].stream;
+			tmp_cl = dwcs_class_lookup ( q, min_classid_index );
+		}
+		else
+		{
+			tmp_cl = NULL;
+		}
+
+		if ( tmp_cl && ( tmp_cl->q->q.qlen > 0 ) )
+		{
+			if ( ( tmp_cl->attr.cld > tmp_cl->attr.cln )
+				 && ( tmp_cl->attr.deadline != -1 ) )
+				tmp_cl->attr.cld--;
+		
+			if ( ( tmp_cl->attr.cld == 0 ) && ( tmp_cl->attr.cln == 0 ) )
+			{
+				tmp_cl->attr.cln = tmp_cl->attr.oln;
+				tmp_cl->attr.cld = tmp_cl->attr.old;
+			}
+
+			tmp_cl->attr.clt = ( tmp_cl->attr.cld == 0 ) ? 0.0 :
+				( float ) tmp_cl->attr.cln / tmp_cl->attr.cld;
+
+			tmp_cl->attr.sent++;
+			if ( tmp_cl->attr.sent + tmp_cl->attr.late ==
+				 tmp_cl->attr.window )
+			{
+				tmp_cl->attr.window += tmp_cl->attr.old;
+				if ( tmp_cl->attr.wlate > tmp_cl->attr.oln )
+				{
+					tmp_cl->attr.violations++;
+				}
+				tmp_cl->attr.wlate = 0;
+			}
+
+
+			/*
+			 * Original implementation would send the packet now.
+			 * * We instead deque the packet from class's internal
+			 * * queue, and save the pointer to it.  
+			 */
+			result = tmp_cl->q->dequeue ( tmp_cl->q );
+				
+			if(result)
+			{
+
+				tmp_cl->attr.bytes += result->len;	/* Length of actuall data */
+				// DStats ( .... );
+
+				/*
+				 * Remove sent packet from deadline heap 
+				 */
+				q->dlheap_size--;
+				HDelete ( q->dlheap, min_classid_index,
+						  q->dlheap_size );
+				
+				q->ltheap_size--;
+				HExtractMin2 ( q->ltheap, q->ltheap_size );
+
+				/*
+				 * Insert next packet in stream if queue non-empty 
+				 */
+				if ( tmp_cl->q->q.qlen > 0 )
+				{
+
+					skb = skb_peek(&tmp_cl->q->q);
+					
+					if(result->fragments == 0 || result->fragments == 1)
+					{
+						if(!(skb && skb->fragments == 1))
+						{
+							tmp_cl->attr.deadline += ( tmp_cl->attr.ipg + OVRHD );
+							tmp_cl->attr.readytime += ( tmp_cl->attr.ipg + OVRHD );
+						}
+					}
+					else
+					{
+						tmp_cl->attr.deadline += ( tmp_cl->attr.ipg + OVRHD );
+						tmp_cl->attr.readytime += ( tmp_cl->attr.ipg + OVRHD );
+					}
+
+					if ( tmp_cl->attr.flags != DWCS_WORK_CONS )
+					{
+						q->slheap_size++;
+						HInsert3 ( q->slheap, min_classid_index,
+								   tmp_cl->attr.readytime,
+								   q->slheap_size );
+
+					}
+					else
+					{
+						skb = skb_peek(&tmp_cl->q->q);
+						if(!skb)
+							printk("SKB == NULL\n");
+						
+						q->dlheap_size++;
+						HInsert ( q->dlheap, min_classid_index,
+								  tmp_cl->attr.deadline,
+								  q->dlheap_size );
+						
+						q->ltheap_size++;
+
+						tmp_heap.clt = tmp_cl->attr.clt;
+						tmp_heap.stream = min_classid_index;
+						tmp_heap.deadline = tmp_cl->attr.deadline;
+						tmp_heap.cln = tmp_cl->attr.cln;
+						tmp_heap.cld = tmp_cl->attr.cld;
+						tmp_heap.oln = tmp_cl->attr.oln;
+						tmp_heap.wlate = tmp_cl->attr.wlate;
+						/*
+						 * this one is tvtojiffies() from kernel/itimer.c 
+						 */
+						if(skb)
+							tmp_heap.arr_time = tvtojiffies(&(skb->stamp));
+
+						HInsert2 ( q->ltheap, tmp_heap, q->ltheap_size );
+					}
+				}
+				
+			}
+
+		}					// end of "if ((tmp_cl->attr.cld > tmp_cl->attr.cln) && (tmp_cl->attr.deadline != -1)) "
+
+	}							// end of "while (flag)"
+	
+
+
+	if ( result )
+	{
+		tmp_cl->attr.delay += (jiffies - result->urgent_flag);
+		sch->q.qlen--;
+	}
+	else
+	{
+		if(q->link && q->link->q && q->link->q->q.qlen > 0)
+			result = q->link->q->dequeue ( q->link->q );
+		if(result)
+		{
+			q->link->attr.sent ++;
+			q->link->attr.delay += (jiffies - result->urgent_flag);
+			sch->q.qlen --;
+		}
+	}
+
+	if ( q->slheap_size > 0)
+		mod_timer ( &q->wd_timer, q->slheap[0].readytime );
+
+
+	return result;
+}
+
+
+
+/*
+ * The init function of a queuing discipline is used to initialize and configure 
+ * the parameters of a queuing discipline when it is created.
+ */
+static int
+dwcs_init ( struct Qdisc *sch,
+			struct rtattr *opt )
+{
+	struct dwcs_sched_data *q = ( void * ) sch->data;
+	struct rtattr      *tb[TCA_DWCS_MAX];
+
+	MOD_INC_USE_COUNT;			/* indicate that the module is in use */
+
+	/*
+	 * initialization of DWCS two heaps 
+	 */
+	if ( opt == NULL )
+		return 0;
+
+	q->dlheap_size = 0;
+	q->ltheap_size = 0;
+
+	/*
+	 * initialize default class "q->link" 
+	 */
+	q->link =
+		( struct dwcs_class * ) kmalloc ( sizeof ( struct dwcs_class ),
+										  GFP_KERNEL );
+	if ( q->link == NULL )
+		return -ENOBUFS;
+
+	q->link->filter_list = NULL;
+	q->link->refcnt = 1;
+	q->link->classid = sch->handle;
+	q->link->qdisc = sch;
+	if ( !( q->link->q = qdisc_create_dflt ( sch->dev, &pfifo_qdisc_ops ) ) )
+		q->link->q = &noop_qdisc;
+
+
+	/*
+	 * Process passed parameters here - We apply them to a 
+	 * * default class: 'sch->data->link' 
+	 */
+	if ( opt == NULL ||
+		 rtattr_parse ( tb, TCA_DWCS_MAX, RTA_DATA ( opt ),
+						RTA_PAYLOAD ( opt ) ) )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_DEADLINE - 1] &&
+		 RTA_PAYLOAD ( tb[TCA_DWCS_DEADLINE - 1] ) != 4 )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_OLN - 1] && RTA_PAYLOAD ( tb[TCA_DWCS_OLN - 1] ) != 4 )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_OLD - 1] && RTA_PAYLOAD ( tb[TCA_DWCS_OLD - 1] ) != 4 )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_FLAGS - 1] &&
+		 RTA_PAYLOAD ( tb[TCA_DWCS_FLAGS - 1] ) != 4 )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_DEADLINE - 1] )
+		q->link->attr.ipg =
+			*( long * ) RTA_DATA ( tb[TCA_DWCS_DEADLINE - 1] );
+	// q->link->attr.deadline = *(long*)RTA_DATA(tb[TCA_DWCS_DEADLINE-1]);
+	if ( tb[TCA_DWCS_OLN - 1] )
+		q->link->attr.oln =
+			*( unsigned int * ) RTA_DATA ( tb[TCA_DWCS_OLN - 1] );
+	if ( tb[TCA_DWCS_OLD - 1] )
+	{
+		q->link->attr.old =
+			*( unsigned int * ) RTA_DATA ( tb[TCA_DWCS_OLD - 1] );
+		if ( q->link->attr.old == 0 )
+			return -EINVAL;
+	}
+	/*
+	 * process optional DWCS parameters 
+	 */
+	if ( tb[TCA_DWCS_FLAGS - 1] )
+		q->link->attr.flags =
+			*( unsigned int * ) RTA_DATA ( tb[TCA_DWCS_FLAGS - 1] );
+	q->link->attr.cln = 0;		/* Current loss numerator. */
+	q->link->attr.cld = 0;		/* Current loss denominator. */
+	q->link->attr.droppable = FALSE;	/* TRUE if packets can be dropped */
+	q->link->attr.cln = q->link->attr.oln;
+	q->link->attr.cld = q->link->attr.old;
+	q->link->attr.clt = ( ( float ) q->link->attr.oln ) / q->link->attr.old;
+
+
+	/*
+	 * now, even though the q->link is our static, always existing class for
+	 * * unmatched packets, we still add it to q->classes[] array for consistency.
+	 * * q->classes[] is array/hash of all existing classes.
+	 */
+	dwcs_link_class ( q->link );
+
+	q->classcount = 1;			/* number of classes; one is always created as default */
+
+
+	/*
+	 * if (opt == NULL) {
+	 * if (sch->ops == &bdwcs_qdisc_ops)
+	 * q->limit = sch->dev->tx_queue_len*sch->dev->mtu;
+	 * else 
+	 * q->limit = sch->dev->tx_queue_len;
+	 * } else {
+	 * struct tc_dwcs_qopt *ctl = RTA_DATA(opt);
+	 * if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
+	 * return -EINVAL;
+	 * q->limit = ctl->limit;
+	 * }
+	 */
+
+	if(sch->dev == NULL)
+		printk("dev == NULL\n");
+	else 
+		dwcs_init_timer ( &q->wd_timer, sch->dev );
+
+
+#ifdef PROC_MONITORING
+	/*
+	 * Create /proc/ file entry 
+	 */
+	// proc_register(&proc_root, &proc_dwcs);
+	q->ent = create_proc_entry ( "net/sch_dwcs", 0, 0 );
+	q->ent->read_proc = proc_read_dwcs;
+#endif
+
+	return 0;
+}
+
+
+int
+dwcs_copy_xstats ( struct sk_buff *skb,
+				   struct tc_stats *st )
+{
+	RTA_PUT ( skb, TCA_XSTATS, sizeof ( *st ), st );
+	return 0;
+
+  rtattr_failure:
+	return -1;
+}
+
+
+
+/*
+ * The dump function is used to dump diagnostic data associated with a 
+ * queuing discipline.
+ */
+#ifdef CONFIG_RTNETLINK
+static int
+dwcs_dump ( struct Qdisc *sch,
+			struct sk_buff *skb )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	int                 ipg = 0,
+		oln = 0,
+		old = 0;
+	struct rtattr      *rta = NULL;
+	unsigned char      *b = skb->tail;
+
+	rta = ( struct rtattr * ) b;
+
+#ifdef GREGORY_DETAILS
+	/*
+	 * tell how many classes there are 
+	 */
+	{
+		struct dwcs_class  *tmp = NULL;
+		int                 count = 0,
+			i,
+			f_count = 0;
+		struct tcf_proto   *ptr = NULL;
+
+
+		for ( i = 0; i < 16; i++ )
+		{
+			tmp = q->classes[i];
+			while ( tmp )
+			{
+				count++;
+				tmp = tmp->next;
+			}
+		}
+
+		/*
+		 * Count how many filters there are 
+		 */
+		if ( q->link )
+			for ( ptr = q->link->filter_list; ptr; ptr = ptr->next )
+			{
+				f_count++;
+			}
+
+	}
+#endif
+
+	//opt.limit = q->limit;
+	//RTA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
+
+	if ( q->link )
+	{
+		ipg = q->link->attr.ipg;
+		oln = q->link->attr.oln;
+		old = q->link->attr.old;
+	}
+
+	RTA_PUT ( skb, TCA_OPTIONS, 0, NULL );
+	RTA_PUT ( skb, TCA_DWCS_DEADLINE, sizeof ( ipg ), &ipg );
+	RTA_PUT ( skb, TCA_DWCS_OLD, sizeof ( oln ), &old );
+	RTA_PUT ( skb, TCA_DWCS_OLN, sizeof ( oln ), &oln );
+
+	rta->rta_len = skb->tail - b;
+	spin_lock_bh ( &sch->dev->queue_lock );
+	if ( dwcs_copy_xstats ( skb, &q->link->stats ) )
+	{
+		spin_unlock_bh ( &sch->dev->queue_lock );
+		goto rtattr_failure;
+	}
+	spin_unlock_bh ( &sch->dev->queue_lock );
+
+	return skb->len;
+
+
+
+	return skb->len;
+
+  rtattr_failure:
+	skb_trim ( skb, b - skb->data );
+	return -1;
+}
+#endif
+
+
+
+
+/*
+ * The destroy function of a queuing discipline is used to remove 
+ * the queuing discipline.  It also removes all the classes and 
+ * filters associated with queuing discipline.
+ */
+static void
+dwcs_destroy ( struct Qdisc *sch )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl;
+	unsigned            h;
+
+
+	del_timer ( &q->wd_timer );
+
+#ifdef CONFIG_NET_CLS_POLICE
+	q->rx_class = NULL;
+#endif
+	for ( h = 0; h < 16; h++ )
+	{
+		for ( cl = q->classes[h]; cl; cl = cl->next )
+			dwcs_destroy_filters ( cl );
+	}
+
+	for ( h = 0; h < 16; h++ )
+	{
+		for ( cl = q->classes[h]; cl; cl = cl->next )
+			dwcs_destroy_class ( cl );
+	}
+
+#ifdef PROC_MONITORING
+	/*
+	 * Remove /proc/ file entry 
+	 */
+	// proc_unregister(&proc_root, proc_dwcs.low_ino);
+#endif
+
+	MOD_DEC_USE_COUNT;			/* indicate that the module is NOT in use */
+}
+
+
+
+
+/*
+*************************************************************
+**
+** Section for definition of class related functions.
+**
+*************************************************************
+*/
+
+
+
+/*
+** ..._graft() is to attach a new queuing discipline to a class
+*/
+static int
+dwcs_graft ( struct Qdisc *sch,
+			 unsigned long arg,
+			 struct Qdisc *new,
+			 struct Qdisc **old )
+{
+	/*
+	 * for DWCS, we can not have a _graft() function.  This is because
+	 * * when we dequeue() we frequently need to know which is the next 
+	 * * packet of class that is going to be dequeued.  If queue is not FIFO, 
+	 * * current API doesn't allow us to access the next packet.  Therefore,
+	 * * we use FIFO queues in DWCS classes and don't allow this to be changed.
+	 */
+	return -ENOENT;
+}
+
+
+/*
+**  ..._leaf() - is not described in QoS API specifications...???
+*/
+static struct Qdisc *
+dwcs_leaf ( struct Qdisc *sch,
+			unsigned long arg )
+{
+	struct dwcs_class  *cl = ( struct dwcs_class * ) arg;
+
+	return cl ? cl->q : NULL;
+}
+
+
+
+/*
+ * Helper function to return the address of the class
+ * by providing the classid (that includes major and minor ids),
+ * Returns NULL, if no class is found.
+ */
+static __inline__ struct dwcs_class *
+dwcs_class_lookup ( struct dwcs_sched_data *q,
+					u32 classid )
+{
+	struct dwcs_class  *cl;
+
+	for ( cl = q->classes[dwcs_hash ( classid )]; cl; cl = cl->next )
+		if ( cl->classid == classid )
+		{
+			return cl;
+		}
+
+	return NULL;
+}
+
+
+
+/*
+** ..._get() returns the internal ID of a class in form of a
+** pointer to corresponding dwcs class structure.
+*/
+static unsigned long
+dwcs_get ( struct Qdisc *sch,
+		   u32 classid )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl;
+
+	cl = dwcs_class_lookup ( q, classid );
+
+	if ( cl )
+	{
+		cl->refcnt++;
+		return ( unsigned long ) cl;
+	}
+	return 0;
+}
+
+
+static void
+dwcs_destroy_filters ( struct dwcs_class *cl )
+{
+	struct tcf_proto   *tp;
+
+	while ( ( tp = cl->filter_list ) != NULL )
+	{
+		cl->filter_list = tp->next;
+		tp->ops->destroy ( tp );
+	}
+}
+
+
+
+/*
+** ..._put() - invoked when a class previously referenced using the get() function 
+** is de-referenced.  It decrements the usage count of the class.
+*/
+static void
+dwcs_put ( struct Qdisc *sch,
+		   unsigned long arg )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl = ( struct dwcs_class * ) arg;
+
+
+	if ( --cl->refcnt == 0 )
+	{
+#ifdef CONFIG_NET_CLS_POLICE
+		if ( q->rx_class == cl )
+			q->rx_class = NULL;
+#endif
+		dwcs_destroy_class ( cl );
+	}
+	return;
+}
+
+
+/*
+** dwcs_link_class() inserts the class in qdisc's linked list.
+** It should be executed atomically.
+*/
+static void
+dwcs_link_class ( struct dwcs_class *this )
+{
+	struct dwcs_sched_data *q =
+		( struct dwcs_sched_data * ) this->qdisc->data;
+	unsigned            h = dwcs_hash ( this->classid );
+
+	this->next = q->classes[h];
+	q->classes[h] = this;
+
+}
+
+
+/*
+** dwcs_unlink_class() inserts the class in qdisc's linked list.
+** It should be executed atomically.
+*/
+static void
+dwcs_unlink_class ( struct dwcs_class *this )
+{
+	struct dwcs_sched_data *q =
+		( struct dwcs_sched_data * ) this->qdisc->data;
+	struct dwcs_class  *cl,
+		**clp;
+
+	/*
+	 * find the previous class in linked list 
+	 */
+	for ( clp = &q->classes[dwcs_hash ( this->classid )];
+		  ( cl = *clp ) != NULL; clp = &cl->next )
+	{
+		if ( cl == this )
+		{
+			*clp = cl->next;
+			cl->next = NULL;
+			break;
+		}
+	}
+}
+
+
+/*
+** ..._change() - is used to change the properties associated with a class.
+** It is also used to create classes at times.
+*/
+static int
+dwcs_change_class ( struct Qdisc *sch,
+					u32 classid,
+					u32 parentid,
+					struct rtattr **tca,
+					unsigned long *arg )
+{
+	int                 err;
+	struct rtattr      *opt = tca[TCA_OPTIONS - 1];
+	struct rtattr      *tb[TCA_DWCS_MAX];
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl = ( struct dwcs_class * ) *arg;
+
+
+	/*
+	 * Process passed parameters here - We apply them to 
+	 * * a class that is about to be created. 
+	 */
+//  if (opt==NULL ||
+	if ( rtattr_parse
+		 ( tb, TCA_DWCS_MAX, RTA_DATA ( opt ), RTA_PAYLOAD ( opt ) ) )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_DEADLINE - 1] &&
+		 RTA_PAYLOAD ( tb[TCA_DWCS_DEADLINE - 1] ) != 4 )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_OLN - 1] && RTA_PAYLOAD ( tb[TCA_DWCS_OLN - 1] ) != 4 )
+		return -EINVAL;
+
+
+	if ( tb[TCA_DWCS_OLD - 1] && RTA_PAYLOAD ( tb[TCA_DWCS_OLD - 1] ) != 4 )
+		return -EINVAL;
+
+	if ( tb[TCA_DWCS_FLAGS - 1] &&
+		 RTA_PAYLOAD ( tb[TCA_DWCS_FLAGS - 1] ) != 4 )
+		return -EINVAL;
+
+
+	/*
+	 * #ifdef CONFIG_NET_CLS_POLICE
+	 * if (tb[TCA_DWCS_POLICE-1] &&
+	 * RTA_PAYLOAD(tb[TCA_DWCS_POLICE-1]) < sizeof(struct tc_cbq_police))
+	 * return -EINVAL;
+	 * #endif
+	 */
+
+
+
+	/*
+	 * We don't support dynamic parameter changes. 
+	 * *  So, if classid exists, return error. Otherwise, 
+	 * *  create a new class.
+	 */
+	if ( cl || dwcs_class_lookup ( q, classid ) )
+	{							// double check
+		return -EINVAL;
+	}
+
+	if ( parentid == TC_H_ROOT )
+		return -EINVAL;
+
+	/*
+	 * make sure the parent exists 
+	 */
+	/*
+	 * parent = &q->link;
+	 * if (parentid) {
+	 * parent = dwcs_class_lookup(q, parentid);
+	 * err = -EINVAL;
+	 * if (parent == NULL)
+	 * goto failure;
+	 * }
+	 */
+
+	/*
+	 * allocate memory for a class 
+	 */
+	err = -ENOBUFS;
+	cl = kmalloc ( sizeof ( struct dwcs_class ), GFP_KERNEL );
+	if ( cl == NULL )
+		goto failure;
+
+	memset ( cl, 0, sizeof ( struct dwcs_class ) );
+
+	cl->refcnt = 1;
+	if ( !( cl->q = qdisc_create_dflt ( sch->dev, &pfifo_qdisc_ops ) ) )
+		cl->q = &noop_qdisc;
+	cl->classid = classid;
+	cl->qdisc = sch;
+
+	/*
+	 * DWCS parameters provided by the user 
+	 */
+	if ( tb[TCA_DWCS_DEADLINE - 1] )
+		cl->attr.ipg = *( long * ) RTA_DATA ( tb[TCA_DWCS_DEADLINE - 1] );
+	// cl->attr.deadline = *(long*)RTA_DATA(tb[TCA_DWCS_DEADLINE-1]);
+	if ( tb[TCA_DWCS_OLN - 1] )
+		cl->attr.oln = *( unsigned int * ) RTA_DATA ( tb[TCA_DWCS_OLN - 1] );
+	if ( tb[TCA_DWCS_OLD - 1] )
+	{
+		cl->attr.old =
+			*( unsigned int * ) RTA_DATA ( tb[TCA_DWCS_OLD - 1] );
+		if ( cl->attr.old == 0 )
+			return -EINVAL;
+	}
+	/*
+	 * process optional DWCS parameters 
+	 */
+	if ( tb[TCA_DWCS_FLAGS - 1] )
+		cl->attr.flags =
+			*( unsigned int * ) RTA_DATA ( tb[TCA_DWCS_FLAGS - 1] );
+	/*
+	 * initialization of internal DWCS attributes 
+	 */
+	cl->attr.cln = 0;			/* Current loss numerator. */
+	cl->attr.cld = 0;			/* Current loss denominator. */
+	cl->attr.droppable = FALSE;	/* TRUE if packets can be dropped */
+	cl->attr.cln = cl->attr.oln;
+	cl->attr.cld = cl->attr.old;
+	cl->attr.clt = ( ( float ) cl->attr.oln ) / cl->attr.old;
+
+
+
+	dwcs_link_class ( cl );		/* atomicaly inserts the class in a liked list */
+	q->classcount++;
+
+	*arg = ( unsigned long ) cl;
+	return 0;
+
+  failure:
+	return err;
+}
+
+
+/*
+ * a helper function to free the memory allocated by the class.  It assumes that
+ * the class has been removed from a linked list.
+ */
+static void
+dwcs_destroy_class ( struct dwcs_class *cl )
+{
+	dwcs_destroy_filters ( cl );
+	qdisc_destroy ( cl->q );
+#ifdef CONFIG_NET_ESTIMATOR
+	qdisc_kill_estimator ( &cl->stats );
+#endif
+	kfree ( cl );
+}
+
+
+
+
+/*
+** ..._delete() - is used to delete the class.
+*/
+static int
+dwcs_delete ( struct Qdisc *sch,
+			  unsigned long arg )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl = ( struct dwcs_class * ) arg;
+
+	if ( cl->filters || cl == ( struct dwcs_class * ) &q->link )
+		return -EBUSY;
+
+	q->classcount--;
+	dwcs_unlink_class ( cl );	/* remove the class from the linked list */
+
+	dwcs_destroy_class ( cl );
+
+	return ( 0 );
+}
+
+
+
+/*
+** ..._walk() is used to iterate over all the classes of queuing discipline 
+** and invokes a callback function for each of the classes.
+*/
+static void
+dwcs_walk ( struct Qdisc *sch,
+			struct qdisc_walker *arg )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	unsigned            h;
+
+	if ( arg->stop )
+		return;
+
+	for ( h = 0; h < 16; h++ )
+	{
+		struct dwcs_class  *cl;
+
+		for ( cl = q->classes[h]; cl; cl = cl->next )
+		{
+			if ( arg->count < arg->skip )
+			{
+				arg->count++;
+				continue;
+			}
+			if ( arg->fn ( sch, ( unsigned long ) cl, arg ) < 0 )
+			{
+				arg->stop = 1;
+				return;
+			}
+			arg->count++;
+		}
+	}
+}
+
+
+
+/*
+** ..._find_tcf() - used to return the anchor to the list of filters that 
+** are associated to a class.
+*/
+static struct tcf_proto **
+dwcs_find_tcf ( struct Qdisc *sch,
+				unsigned long arg )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl = ( struct dwcs_class * ) arg;
+
+	if ( cl == NULL )
+		cl = q->link;
+
+	return &cl->filter_list;
+}
+
+
+
+
+/*
+** ..._bind_tcf() - used to attach an instance of a filter to a class.
+** We increment the class counter for the number of filters.
+*/
+static unsigned long
+dwcs_bind_filter ( struct Qdisc *sch,
+				   unsigned long parent,
+				   u32 classid )
+{
+	struct dwcs_sched_data *q = ( struct dwcs_sched_data * ) sch->data;
+	struct dwcs_class  *cl;
+
+
+	cl = dwcs_class_lookup ( q, classid );
+
+	if ( cl )
+	{
+		cl->filters++;
+		return ( unsigned long ) cl;
+	}
+	return 0;
+}
+
+
+
+/*
+** ..._unbind() - is used to remove an instance of a filter attached to a class.
+** We need to decrement the counter for the number of filters.
+*/
+static void
+dwcs_unbind_filter ( struct Qdisc *sch,
+					 unsigned long arg )
+{
+	struct dwcs_class  *cl = ( struct dwcs_class * ) arg;
+
+
+	cl->filters--;
+}
+
+
+static int
+dwcs_dump_attr ( struct sk_buff *skb,
+				 struct dwcs_class *cl )
+{
+	int                 ipg = 0,
+		oln = 0,
+		old = 0;
+	struct rtattr      *rta = NULL;
+	unsigned char      *b = skb->tail;
+
+	rta = ( struct rtattr * ) b;
+
+	if ( cl )
+	{
+		ipg = cl->attr.ipg;
+		oln = cl->attr.oln;
+		old = cl->attr.old;
+	}
+
+	RTA_PUT ( skb, TCA_OPTIONS, 0, NULL );
+	RTA_PUT ( skb, TCA_DWCS_DEADLINE, sizeof ( ipg ), &ipg );
+	RTA_PUT ( skb, TCA_DWCS_OLD, sizeof ( oln ), &old );
+	RTA_PUT ( skb, TCA_DWCS_OLN, sizeof ( oln ), &oln );
+
+	return skb->len;
+
+  rtattr_failure:
+	return -1;
+
+}
+
+/*
+** ..._dump_class() - is used to dump diagnostic data about the class.
+*/
+static int
+dwcs_dump_class ( struct Qdisc *sch,
+				  unsigned long arg,
+				  struct sk_buff *skb,
+				  struct tcmsg *tcm )
+{
+
+	struct dwcs_class  *cl = ( struct dwcs_class * ) arg;
+	unsigned char      *b = skb->tail;
+	struct rtattr      *rta = ( struct rtattr * ) b;
+
+
+	if ( !cl )
+		return -1;
+
+	tcm->tcm_handle = TC_H_MAKE ( TC_H_MAJ ( sch->handle ), arg - 1 );
+	tcm->tcm_handle = cl->classid;
+	if ( dwcs_dump_attr ( skb, cl ) < 0 )
+		goto rtattr_failure;
+
+	rta->rta_len = skb->tail - b;
+
+	return skb->len;
+
+  rtattr_failure:
+	skb_trim ( skb, b - skb->data );
+	return -1;
+
+	/*
+	 * Magic will go here 
+	 */
+	return -1;
+
+}
+
+
+static struct Qdisc_class_ops dwcs_class_ops = {
+	dwcs_graft,
+	dwcs_leaf,
+	dwcs_get,
+	dwcs_put,
+	dwcs_change_class,
+	dwcs_delete,
+	dwcs_walk,
+
+	dwcs_find_tcf,
+	dwcs_bind_filter,
+	dwcs_unbind_filter,
+
+#ifdef CONFIG_RTNETLINK
+	dwcs_dump_class,
+#endif
+
+};
+
+struct Qdisc_ops    dwcs_qdisc_ops = {
+	NULL,
+	&dwcs_class_ops,
+	"dwcs",
+	sizeof ( struct dwcs_sched_data ),
+
+	dwcs_enqueue,
+	dwcs_dequeue,
+	dwcs_requeue,
+	dwcs_drop,
+
+	dwcs_init,
+	dwcs_reset,
+	dwcs_destroy,
+	dwcs_init,					/* technically, should be dwcs_change() */
+
+#ifdef CONFIG_RTNETLINK
+	dwcs_dump,
+#endif
+};
+
+/*
+ * If we are compiling this as a module, then we need to define the
+ * following two functions.
+ */
+#ifdef MODULE
+int
+init_module ( void )
+{
+	pidcall = sys_call_table[__NR_getpid];
+	return register_qdisc ( &dwcs_qdisc_ops );
+}
+
+void
+cleanup_module ( void )
+{
+	unregister_qdisc ( &dwcs_qdisc_ops );
+}
+#endif
+
+
+
+
+/* -------------------------------------------------------
+ *  If specified, we create /proc/ entry for monitoring 
+ *  the scheduler.
+ */
+#ifdef PROC_MONITORING
+
+/* Create an entry in /proc for accessing DWCS state information. */
+
+/*
+struct proc_dir_entry proc_dwcs = {
+        0,                 // low_ino: the inode -- dynamic 
+        8, "sch_dwcs",     // len of name and name 
+        S_IFREG | S_IRUGO, // mode
+        1, 0, 0,           // nlinks, owner, group
+        0, NULL,           // size - unused; operations - use default ops
+        &proc_read_dwcs,   // function used to read data
+	// nothing more
+    };
+*/
+
+int
+proc_read_dwcs ( char *buf,
+				 char **start,
+				 off_t offset,
+				 int length,
+				 int *eof,
+				 void *data )
+{
+	int                 len;
+
+	/*
+	 * Display runqueue statistics. 
+	 */
+	len = sprintf ( buf, "Jiffies=%lu Current=%d Prev=%d Next=%d\n\n",
+					jiffies, -1, -1, -1 );
+	len -= offset;
+	if ( len > length )
+		len = length;
+	else
+		len = 0;
+
+	*start = buf + offset;
+	*eof = 1;
+
+	return len;
+}
+#endif
+MODULE_LICENSE("GPL");
diff -Naur test-for-latech/net/socket.c testqf-for-latech/net/socket.c
--- test-for-latech/net/socket.c	2004-06-11 07:40:47.000000000 -0400
+++ testqf-for-latech/net/socket.c	2004-06-11 07:47:56.000000000 -0400
@@ -457,6 +457,9 @@
 	sock->ops = NULL;
 	sock->sk = NULL;
 	sock->file = NULL;
+#ifdef CONFIG_QFABRIC
+	sock->rt_sock = 0;
+#endif
 
 	sockets_in_use[smp_processor_id()].counter++;
 	return sock;
@@ -498,6 +501,24 @@
 	sock->file=NULL;
 }
 
+#ifdef CONFIG_QFABRIC
+int rt_sock_sendmsg(struct socket *sock, struct msghdr *msg, int size, int deadline,
+	int flags)
+{
+	int err;
+	struct scm_cookie scm;
+
+	sock->deadline = deadline;
+	sock->rt_flags = flags;
+	err = scm_send(sock, msg, &scm);
+	if (err >= 0) {
+		err = sock->ops->sendmsg(sock, msg, size, &scm);
+		scm_destroy(&scm);
+	}
+	return err;
+}
+#endif
+
 int sock_sendmsg(struct socket *sock, struct msghdr *msg, int size)
 {
 	int err;
@@ -819,6 +840,13 @@
 	return 0;
 }
 
+#ifdef CONFIG_QFABRIC
+int make_rt_sock(struct socket *sock) 
+{
+	sock->rt_sock = 1;	
+	return 0;
+}
+#endif
 
 int sock_create(int family, int type, int protocol, struct socket **res)
 {
@@ -855,7 +883,7 @@
 	 * Otherwise module support will break!
 	 */
 	if (net_families[family]==NULL)
-	{
+{
 		char module_name[30];
 		sprintf(module_name,"net-pf-%d",family);
 		request_module(module_name);
@@ -883,6 +911,9 @@
 	}
 
 	sock->type  = type;
+#ifdef CONFIG_QFABRIC
+	sock->rt_sock  = 0;
+#endif
 
 	if ((i = net_families[family]->create(sock, protocol)) < 0) 
 	{
@@ -909,6 +940,15 @@
 	retval = sock_map_fd(sock);
 	if (retval < 0)
 		goto out_release;
+#ifdef CONFIG_QFABRIC
+	sock->sk->fd = retval;
+	sock->sk->owner = current->pid;
+	sock->sk->kecho = 0;
+	sock->sk->readable = 0;
+	sock->sk->writable = 0;
+	sock->sk->counter = 0;
+	sock->rt_sock = 0;
+#endif
 
 out:
 	/* It may be already another descriptor 8) Not kernel problem. */
@@ -919,6 +959,37 @@
 	return retval;
 }
 
+#ifdef CONFIG_QFABRIC
+asmlinkage long sys_rtsocket(int family, int type, int protocol)
+{
+	int retval;
+	struct socket *sock;
+
+	retval = sock_create(family, type, protocol, &sock);
+	if (retval < 0)
+		goto out;
+
+	retval = sock_map_fd(sock);
+	if (retval < 0)
+		goto out_release;
+	sock->sk->fd = retval;
+	sock->sk->owner = current->pid;
+	sock->sk->kecho = 0;
+	sock->sk->readable = 0;
+	sock->sk->writable = 0;
+	sock->sk->counter = 0;
+	sock->rt_sock = 1;
+
+out:
+	/* It may be already another descriptor 8) Not kernel problem. */
+	return retval;
+
+out_release:
+	sock_release(sock);
+	return retval;
+}
+#endif
+
 /*
  *	Create a pair of connected sockets.
  */
@@ -1063,6 +1134,13 @@
 	if (err < 0)
 		goto out_release;
 
+#ifdef CONFIG_QFABRIC
+	sock->sk->fd = err;
+	sock->sk->owner = current->pid;
+	sock->sk->readable = 0;
+	sock->sk->writable = 0;
+#endif
+
 	if (upeer_sockaddr) {
 		if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 2)<0) {
 			err = -ECONNABORTED;
@@ -1258,6 +1336,9 @@
 		if(err2<0)
 			err=err2;
 	}
+#ifdef CONFIG_QFABRIC
+	if (err > 0) sock->sk->counter++;
+#endif
 	sockfd_put(sock);			
 out:
 	return err;
@@ -1553,6 +1634,11 @@
 		case SYS_SOCKET:
 			err = sys_socket(a0,a1,a[2]);
 			break;
+#ifdef CONFIG_QFABRIC
+		case SYS_RTSOCKET:
+			err = sys_rtsocket(a0,a1,a[2]);
+			break;
+#endif
 		case SYS_BIND:
 			err = sys_bind(a0,(struct sockaddr *)a1, a[2]);
 			break;
@@ -1662,6 +1748,10 @@
 extern void bluez_init(void);
 #endif
 
+#ifdef CONFIG_X86
+extern void qsocket_init(void);
+#endif
+
 void __init sock_init(void)
 {
 	int i;
@@ -1725,6 +1815,11 @@
 #ifdef CONFIG_BLUEZ
 	bluez_init();
 #endif
+#ifdef CONFIG_X86
+#ifdef CONFIG_NET_QSOCKET
+	qsocket_init();
+#endif
+#endif
 }
 
 int socket_get_info(char *buffer, char **start, off_t offset, int length)
@@ -1753,3 +1848,28 @@
 		len = 0;
 	return len;
 }
+
+#ifdef CONFIG_QFABRIC
+int set_socket_deadline(struct sock *sk, int deadline) 
+{
+	sk->socket->deadline = deadline;
+	return 0;
+}
+
+int request_socket_deadline(struct sock *sk)
+{
+	return sk->socket->deadline;
+}
+
+int set_socket_rt_flags(struct sock *sk, int flags)
+{
+	sk->socket->rt_flags = flags;
+	return 0;
+}
+
+int request_socket_rt_flags(struct sock *sk)
+{
+	return sk->socket->rt_flags;
+}
+#endif
+
