From 06ef66081620e94fe35a518f98624b83a140096e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:10:45 -0700 Subject: [IA64] __ia64_syscall() is no longer used anywhere in the kernel. Remove it. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 12 ------------ arch/ia64/kernel/ia64_ksyms.c | 3 --- 2 files changed, 15 deletions(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index bd86fea..5b469db 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -470,18 +470,6 @@ ENTRY(load_switch_stack) br.cond.sptk.many b7 END(load_switch_stack) -GLOBAL_ENTRY(__ia64_syscall) - .regstk 6,0,0,0 - mov r15=in5 // put syscall number in place - break __BREAK_SYSCALL - movl r2=errno - cmp.eq p6,p7=-1,r10 - ;; -(p6) st4 [r2]=r8 -(p6) mov r8=-1 - br.ret.sptk.many rp -END(__ia64_syscall) - GLOBAL_ENTRY(execve) mov r15=__NR_execve // put syscall number in place break __BREAK_SYSCALL diff --git a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c index 7bbf019..0157281 100644 --- a/arch/ia64/kernel/ia64_ksyms.c +++ b/arch/ia64/kernel/ia64_ksyms.c @@ -58,9 +58,6 @@ EXPORT_SYMBOL(__strlen_user); EXPORT_SYMBOL(__strncpy_from_user); EXPORT_SYMBOL(__strnlen_user); -#include -EXPORT_SYMBOL(__ia64_syscall); - /* from arch/ia64/lib */ extern void __divsi3(void); extern void __udivsi3(void); -- cgit v1.1 From 9ec1a7ad434fa951ff845dbee3397cf6ad4f76df Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:13:33 -0700 Subject: [IA64] Use dynamic prediction for RSE-clearing branches. This by itself is good for a 1-2 cycle speed up. Effect is bigger when combined with the later patches. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 5b469db..c0f2833 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -1012,14 +1012,14 @@ rse_clear_invalid: mov loc5=0 mov loc6=0 mov loc7=0 -(pRecurse) br.call.sptk.few b0=rse_clear_invalid +(pRecurse) br.call.dptk.few b0=rse_clear_invalid ;; mov loc8=0 mov loc9=0 cmp.ne pReturn,p0=r0,in1 // if recursion count != 0, we need to do a br.ret mov loc10=0 mov loc11=0 -(pReturn) br.ret.sptk.many b0 +(pReturn) br.ret.dptk.many b0 #endif /* !CONFIG_ITANIUM */ # undef pRecurse # undef pReturn -- cgit v1.1 From 3c79c8b1d92a9ae3edf3cbcd2c43c553ee0f1d83 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:15:13 -0700 Subject: [IA64] Schedule fp-clearing insns at least 6 cycles after reading ar.bsp. Decreases syscall overhead by approximately 6 cycles. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index c0f2833..0c84bed 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -705,15 +705,15 @@ ENTRY(ia64_leave_syscall) // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) ld8 r11=[r3],PT(CR_IIP)-PT(R11) - mov f6=f0 // clear f6 + nop.i 0 ;; invala // M0|1 invalidate ALAT rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - mov f9=f0 // clear f9 + nop.i 0 ld8 r29=[r2],16 // load cr.ipsr ld8 r28=[r3],16 // load cr.iip - mov f8=f0 // clear f8 + mov r22=r0 // clear r22 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat @@ -721,15 +721,15 @@ ENTRY(ia64_leave_syscall) ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled - mov f10=f0 // clear f10 +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc - mov f11=f0 // clear f11 + mov f6=f0 // clear f6 ;; ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) ld8 r31=[r3],PT(R1)-PT(PR) // load predicates -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + mov f7=f0 // clear f7 ;; ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr ld8.fill r1=[r3],16 // load r1 @@ -737,24 +737,29 @@ ENTRY(ia64_leave_syscall) ;; srlz.d // M0 ensure interruption collection is off ld8.fill r13=[r3],16 - mov f7=f0 // clear f7 + mov f8=f0 // clear f8 ;; ld8.fill r12=[r2] // restore r12 (sp) mov.m ar.ssd=r0 // M2 clear ar.ssd - mov r22=r0 // clear r22 + mov b6=r18 // I0 restore b6 + nop.m 0 + mov f9=f0 // clear f9 + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + ;; ld8.fill r15=[r3] // restore r15 (pUStk) st1 [r14]=r17 addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 ;; (pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 mov.m ar.csd=r0 // M2 clear ar.csd - mov b6=r18 // I0 restore b6 + mov f10=f0 // clear f10 ;; mov r14=r0 // clear r14 - shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + mov f11=f0 // clear f11 (pKStk) br.cond.dpnt.many skip_rbs_switch + mov.m ar.ccv=r0 // clear ar.ccv (pNonSys) br.cond.dpnt.many dont_preserve_current_frame br.cond.sptk.many rbs_switch -- cgit v1.1 From 96e017495e6833adcbad84783e3c5eb685836bbf Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:16:07 -0700 Subject: [IA64] On return from syscall, hint b7 with __kernel_syscall_via_epc(). Why is this a good idea? Clearing b7 to 0 is guaranteed to do us no good and writing it with __kernel_syscall_via_epc() yields a 6 cycle improvement _if_ the application performs another EPC-based system- call without overwriting b7, which is not all that uncommon. Well worth the minimal cost of 1 bundle of code. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 0c84bed..6359d7f 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -692,7 +692,7 @@ ENTRY(ia64_leave_syscall) ;; (p6) ld4 r31=[r18] // load current_thread_info()->flags ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" - mov b7=r0 // clear b7 + nop.i 0 ;; ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) ld8 r18=[r2],PT(R9)-PT(B6) // load b6 @@ -754,7 +754,14 @@ ENTRY(ia64_leave_syscall) (pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 mov.m ar.csd=r0 // M2 clear ar.csd mov f10=f0 // clear f10 + + nop.m 0 + movl r14=__kernel_syscall_via_epc // X ;; + nop.m 0 + nop.m 0 + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) + mov r14=r0 // clear r14 mov f11=f0 // clear f11 (pKStk) br.cond.dpnt.many skip_rbs_switch -- cgit v1.1 From 060561ff79b01eea58e6d72abfb8e7580ff21f2a Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:17:03 -0700 Subject: [IA64] In syscall-entry, use st8 instead of stf8 to clear pt_regs.r8 Using stf8 seemed like a clever idea at the time, but stf8 forces the cache-line to be invalidated in the L1D (if it happens to be there already). This patch eliminates a guaranteed L1D cache-miss and, by itself, is good for a 1-2 cycle improvement for heavy-weight syscalls. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index d9c05d5..dc78c35 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1,7 +1,7 @@ /* * arch/ia64/kernel/ivt.S * - * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co + * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co * Stephane Eranian * David Mosberger * Copyright (C) 2000, 2002-2003 Intel Co @@ -918,7 +918,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) tnat.nz p14,p0=in6 cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 ;; - stf8 [r16]=f1 // ensure pt_regs.r8 != 0 (see handle_syscall_error) + mov r8=1 (p9) tnat.nz p10,p0=r15 adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) @@ -929,9 +929,9 @@ GLOBAL_ENTRY(ia64_syscall_setup) mov r13=r2 // establish `current' movl r1=__gp // establish kernel global pointer ;; + st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) (p14) mov in6=-1 (p8) mov in7=-1 - nop.i 0 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 movl r17=FPSR_DEFAULT -- cgit v1.1 From 87e522a0f7f8a7a5a1a880517989835c4f09c63e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:17:44 -0700 Subject: [IA64] Schedule ia64_leave_syscall() to read ar.bsp earlier Reschedule code to read ar.bsp as early as possible. To enable this, don't bother clearing some of the registers when we're returning to kernel stacks. Also, instead of trying to support the pNonSys case (which makes no sense), do a bugcheck instead (with break 0). Finally, remove a clear of r14 which is a left-over from the previous patch. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index 6359d7f..d97a07c 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -694,22 +694,22 @@ ENTRY(ia64_leave_syscall) ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" nop.i 0 ;; - ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) + mov r16=ar.bsp // M2 get existing backing store pointer ld8 r18=[r2],PT(R9)-PT(B6) // load b6 (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? ;; - mov r16=ar.bsp // M2 get existing backing store pointer + ld8 r23=[r3],PT(R11)-PT(AR_BSPSTORE) // load ar.bspstore (may be garbage) (p6) cmp4.ne.unc p6,p0=r15, r0 // any special work pending? (p6) br.cond.spnt .work_pending_syscall ;; // start restoring the state saved on the kernel stack (struct pt_regs): ld8 r9=[r2],PT(CR_IPSR)-PT(R9) ld8 r11=[r3],PT(CR_IIP)-PT(R11) - nop.i 0 +(pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! ;; invala // M0|1 invalidate ALAT rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - nop.i 0 + cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs ld8 r29=[r2],16 // load cr.ipsr ld8 r28=[r3],16 // load cr.iip @@ -717,11 +717,11 @@ ENTRY(ia64_leave_syscall) ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat - cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs +(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs (pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled -(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 + nop 0 ;; ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc @@ -735,40 +735,35 @@ ENTRY(ia64_leave_syscall) ld8.fill r1=[r3],16 // load r1 (pUStk) mov r17=1 ;; - srlz.d // M0 ensure interruption collection is off +(pUStk) st1 [r14]=r17 ld8.fill r13=[r3],16 mov f8=f0 // clear f8 ;; ld8.fill r12=[r2] // restore r12 (sp) - mov.m ar.ssd=r0 // M2 clear ar.ssd + ld8.fill r15=[r3] // restore r15 mov b6=r18 // I0 restore b6 - nop.m 0 + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 mov f9=f0 // clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch + + srlz.d // M0 ensure interruption collection is off shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + cover // B add current frame into dirty partition and set cr.ifs ;; - ld8.fill r15=[r3] // restore r15 -(pUStk) st1 [r14]=r17 - addl r3=THIS_CPU(ia64_phys_stacked_size_p8),r0 - ;; -(pUStk) ld4 r17=[r3] // r17 = cpu_data->phys_stacked_size_p8 - mov.m ar.csd=r0 // M2 clear ar.csd +(pUStk) ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 + mov r19=ar.bsp // M2 get new backing store pointer mov f10=f0 // clear f10 nop.m 0 movl r14=__kernel_syscall_via_epc // X ;; - nop.m 0 - nop.m 0 + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // clear ar.ccv mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) - mov r14=r0 // clear r14 + mov.m ar.ssd=r0 // M2 clear ar.ssd mov f11=f0 // clear f11 -(pKStk) br.cond.dpnt.many skip_rbs_switch - - - mov.m ar.ccv=r0 // clear ar.ccv -(pNonSys) br.cond.dpnt.many dont_preserve_current_frame br.cond.sptk.many rbs_switch END(ia64_leave_syscall) @@ -946,10 +941,10 @@ GLOBAL_ENTRY(ia64_leave_kernel) */ (pNonSys) br.cond.dpnt dont_preserve_current_frame -rbs_switch: cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer +rbs_switch: sub r16=r16,r18 // krbs = old bsp - size of dirty partition cmp.ne p9,p0=r0,r0 // clear p9 to skip restore of cr.ifs ;; -- cgit v1.1 From c03f058fbf685f2ff630095d2c1e98d331b81e82 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:18:22 -0700 Subject: [IA64] In ia64_leave_syscall(), fix comments and whitespace only. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 79 ++++++++++++++++++++++++------------------------ 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index d97a07c..a7542c3 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -625,7 +625,7 @@ END(ia64_ret_from_syscall) * r8-r11: restored (syscall return value(s)) * r12: restored (user-level stack pointer) * r13: restored (user-level thread pointer) - * r14: cleared + * r14: set to __kernel_syscall_via_epc * r15: restored (syscall #) * r16-r17: cleared * r18: user-level b6 @@ -646,7 +646,7 @@ END(ia64_ret_from_syscall) * pr: restored (user-level pr) * b0: restored (user-level rp) * b6: restored - * b7: cleared + * b7: set to __kernel_syscall_via_epc * ar.unat: restored (user-level ar.unat) * ar.pfs: restored (user-level ar.pfs) * ar.rsc: restored (user-level ar.rsc) @@ -708,63 +708,63 @@ ENTRY(ia64_leave_syscall) (pNonSys) break 0 // bug check: we shouldn't be here if pNonSys is TRUE! ;; invala // M0|1 invalidate ALAT - rsm psr.i | psr.ic // M2 initiate turning off of interrupt and interruption collection - cmp.eq p9,p0=r0,r0 // set p9 to indicate that we should restore cr.ifs + rsm psr.i | psr.ic // M2 turn off interrupts and interruption collection + cmp.eq p9,p0=r0,r0 // A set p9 to indicate that we should restore cr.ifs - ld8 r29=[r2],16 // load cr.ipsr - ld8 r28=[r3],16 // load cr.iip - mov r22=r0 // clear r22 + ld8 r29=[r2],16 // M0|1 load cr.ipsr + ld8 r28=[r3],16 // M0|1 load cr.iip + mov r22=r0 // A clear r22 ;; ld8 r30=[r2],16 // M0|1 load cr.ifs ld8 r25=[r3],16 // M0|1 load ar.unat (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13 ;; ld8 r26=[r2],PT(B0)-PT(AR_PFS) // M0|1 load ar.pfs -(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled +(pKStk) mov r22=psr // M2 read PSR now that interrupts are disabled nop 0 ;; - ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // load b0 - ld8 r27=[r3],PT(PR)-PT(AR_RSC) // load ar.rsc - mov f6=f0 // clear f6 + ld8 r21=[r2],PT(AR_RNAT)-PT(B0) // M0|1 load b0 + ld8 r27=[r3],PT(PR)-PT(AR_RSC) // M0|1 load ar.rsc + mov f6=f0 // F clear f6 ;; - ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // load ar.rnat (may be garbage) - ld8 r31=[r3],PT(R1)-PT(PR) // load predicates - mov f7=f0 // clear f7 + ld8 r24=[r2],PT(AR_FPSR)-PT(AR_RNAT) // M0|1 load ar.rnat (may be garbage) + ld8 r31=[r3],PT(R1)-PT(PR) // M0|1 load predicates + mov f7=f0 // F clear f7 ;; - ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // load ar.fpsr - ld8.fill r1=[r3],16 // load r1 -(pUStk) mov r17=1 + ld8 r20=[r2],PT(R12)-PT(AR_FPSR) // M0|1 load ar.fpsr + ld8.fill r1=[r3],16 // M0|1 load r1 +(pUStk) mov r17=1 // A ;; -(pUStk) st1 [r14]=r17 - ld8.fill r13=[r3],16 - mov f8=f0 // clear f8 +(pUStk) st1 [r14]=r17 // M2|3 + ld8.fill r13=[r3],16 // M0|1 + mov f8=f0 // F clear f8 ;; - ld8.fill r12=[r2] // restore r12 (sp) - ld8.fill r15=[r3] // restore r15 - mov b6=r18 // I0 restore b6 + ld8.fill r12=[r2] // M0|1 restore r12 (sp) + ld8.fill r15=[r3] // M0|1 restore r15 + mov b6=r18 // I0 restore b6 - addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 - mov f9=f0 // clear f9 -(pKStk) br.cond.dpnt.many skip_rbs_switch + addl r17=THIS_CPU(ia64_phys_stacked_size_p8),r0 // A + mov f9=f0 // F clear f9 +(pKStk) br.cond.dpnt.many skip_rbs_switch // B - srlz.d // M0 ensure interruption collection is off - shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition - cover // B add current frame into dirty partition and set cr.ifs + srlz.d // M0 ensure interruption collection is off (for cover) + shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition + cover // B add current frame into dirty partition & set cr.ifs ;; -(pUStk) ld4 r17=[r17] // r17 = cpu_data->phys_stacked_size_p8 - mov r19=ar.bsp // M2 get new backing store pointer - mov f10=f0 // clear f10 +(pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 + mov r19=ar.bsp // M2 get new backing store pointer + mov f10=f0 // F clear f10 nop.m 0 - movl r14=__kernel_syscall_via_epc // X + movl r14=__kernel_syscall_via_epc // X ;; - mov.m ar.csd=r0 // M2 clear ar.csd - mov.m ar.ccv=r0 // clear ar.ccv - mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) + mov.m ar.csd=r0 // M2 clear ar.csd + mov.m ar.ccv=r0 // M2 clear ar.ccv + mov b7=r14 // I0 clear b7 (hint with __kernel_syscall_via_epc) - mov.m ar.ssd=r0 // M2 clear ar.ssd - mov f11=f0 // clear f11 - br.cond.sptk.many rbs_switch + mov.m ar.ssd=r0 // M2 clear ar.ssd + mov f11=f0 // F clear f11 + br.cond.sptk.many rbs_switch // B END(ia64_leave_syscall) #ifdef CONFIG_IA32_SUPPORT @@ -940,7 +940,6 @@ GLOBAL_ENTRY(ia64_leave_kernel) * NOTE: alloc, loadrs, and cover can't be predicated. */ (pNonSys) br.cond.dpnt dont_preserve_current_frame - cover // add current frame into dirty partition and set cr.ifs ;; mov r19=ar.bsp // get new backing store pointer -- cgit v1.1 From f8fa5448fc9b4a7806b1297a0b57808f12fe4d43 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:19:04 -0700 Subject: [IA64] Reschedule break_fault() for better performance. This patch reorganizes break_fault() to optimistically assume that a system-call is being performed from user-space (which is almost always the case). If it turns out that (a) we're not being called due to a system call or (b) we're being called from within the kernel, we fixup the no-longer-valid assumptions in non_syscall() and .break_fixup(), respectively. With this approach, there are 3 major phases: - Phase 1: Read various control & application registers, in particular the current task pointer from AR.K6. - Phase 2: Do all memory loads (load system-call entry, load current_thread_info()->flags, prefetch kernel register-backing store) and switch to kernel register-stack. - Phase 3: Call ia64_syscall_setup() and invoke syscall-handler. Good for 26-30 cycles of improvement on break-based syscall-path. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 173 ++++++++++++++++++++++++++++++------------------- 1 file changed, 106 insertions(+), 67 deletions(-) diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index dc78c35..386087e 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -687,82 +687,118 @@ ENTRY(break_fault) * to prevent leaking bits from kernel to user level. */ DBG_FAULT(11) - mov r16=IA64_KR(CURRENT) // r16 = current task; 12 cycle read lat. - mov r17=cr.iim - mov r18=__IA64_BREAK_SYSCALL - mov r21=ar.fpsr - mov r29=cr.ipsr - mov r19=b6 - mov r25=ar.unat - mov r27=ar.rsc - mov r26=ar.pfs - mov r28=cr.iip - mov r31=pr // prepare to save predicates - mov r20=r1 - ;; + mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) + mov r29=cr.ipsr // M2 (12 cyc) + mov r31=pr // I0 (2 cyc) + + mov r17=cr.iim // M2 (2 cyc) + mov.m r27=ar.rsc // M2 (12 cyc) + mov r18=__IA64_BREAK_SYSCALL // A + + mov.m ar.rsc=0 // M2 + mov.m r21=ar.fpsr // M2 (12 cyc) + mov r19=b6 // I0 (2 cyc) + ;; + mov.m r23=ar.bspstore // M2 (12 cyc) + mov.m r24=ar.rnat // M2 (5 cyc) + mov.i r26=ar.pfs // I0 (2 cyc) + + invala // M0|1 + nop.m 0 // M + mov r20=r1 // A save r1 + + nop.m 0 + movl r30=sys_call_table // X + + mov r28=cr.iip // M2 (2 cyc) + cmp.eq p0,p7=r18,r17 // I0 is this a system call? +(p7) br.cond.spnt non_syscall // B no -> + // + // From this point on, we are definitely on the syscall-path + // and we can use (non-banked) scratch registers. + // +/////////////////////////////////////////////////////////////////////// + mov r1=r16 // A move task-pointer to "addl"-addressable reg + mov r2=r16 // A setup r2 for ia64_syscall_setup + add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - cmp.eq p0,p7=r18,r17 // is this a system call? (p7 <- false, if so) -(p7) br.cond.spnt non_syscall + adds r15=-1024,r15 // A subtract 1024 from syscall number + mov r3=NR_syscalls - 1 ;; - ld1 r17=[r16] // load current->thread.on_ustack flag - st1 [r16]=r0 // clear current->thread.on_ustack flag - add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // set r1 for MINSTATE_START_SAVE_MIN_VIRT + ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag + ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags + extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr + + shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) + addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS + cmp.leu p6,p7=r15,r3 // A syscall number in range? ;; - invala - /* adjust return address so we skip over the break instruction: */ + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS +(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point + tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? - extr.u r8=r29,41,2 // extract ei field from cr.ipsr - ;; - cmp.eq p6,p7=2,r8 // isr.ei==2? - mov r2=r1 // setup r2 for ia64_syscall_setup - ;; -(p6) mov r8=0 // clear ei to 0 -(p6) adds r28=16,r28 // switch cr.iip to next bundle cr.ipsr.ei wrapped -(p7) adds r8=1,r8 // increment ei to next slot - ;; - cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? - dep r29=r8,r29,41,2 // insert new ei into cr.ipsr + mov.m ar.bspstore=r22 // M2 switch to kernel RBS + cmp.eq p8,p9=2,r8 // A isr.ei==2? ;; - // switch from user to kernel RBS: - MINSTATE_START_SAVE_MIN_VIRT - br.call.sptk.many b7=ia64_syscall_setup - ;; - MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 - ssm psr.ic | PSR_DEFAULT_BITS - ;; - srlz.i // guarantee that interruption collection is on - mov r3=NR_syscalls - 1 - ;; -(p15) ssm psr.i // restore psr.i - // p10==true means out registers are more than 8 or r15's Nat is true -(p10) br.cond.spnt.many ia64_ret_from_syscall - ;; - movl r16=sys_call_table +(p8) mov r8=0 // A clear ei to 0 +(p7) movl r30=sys_ni_syscall // X - adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024 - movl r2=ia64_ret_from_syscall - ;; - shladd r20=r15,3,r16 // r20 = sys_call_table + 8*(syscall-1024) - cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + NR_syscalls) ? - mov rp=r2 // set the real return addr +(p8) adds r28=16,r28 // A switch cr.iip to next bundle +(p9) adds r8=1,r8 // A increment ei to next slot + nop.i 0 ;; -(p6) ld8 r20=[r20] // load address of syscall entry point -(p7) movl r20=sys_ni_syscall - add r2=TI_FLAGS+IA64_TASK_SIZE,r13 - ;; - ld4 r2=[r2] // r2 = current_thread_info()->flags - ;; - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit + mov.m r25=ar.unat // M2 (5 cyc) + dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr + adds r15=1024,r15 // A restore original syscall number + // + // If any of the above loads miss in L1D, we'll stall here until + // the data arrives. + // +/////////////////////////////////////////////////////////////////////// + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + mov b6=r30 // I0 setup syscall handler branch reg early + cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? + + and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit + mov r18=ar.bsp // M2 (12 cyc) +(pKStk) br.cond.spnt .break_fixup // B we're already in kernel-mode -- fix up RBS + ;; +.back_from_break_fixup: +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack + cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? + br.call.sptk.many b7=ia64_syscall_setup // B +1: + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + nop 0 + bsw.1 // B (6 cyc) regs are saved, switch to bank 1 ;; - cmp.eq p8,p0=r2,r0 - mov b6=r20 + + ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection + movl r3=ia64_ret_from_syscall // X ;; -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + + srlz.i // M0 ensure interruption collection is on + mov rp=r3 // I0 set the real return addr +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT + +(p15) ssm psr.i // M2 restore psr.i +(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) + br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic // NOT REACHED +/////////////////////////////////////////////////////////////////////// + // On entry, we optimistically assumed that we're coming from user-space. + // For the rare cases where a system-call is done from within the kernel, + // we fix things up at this point: +.break_fixup: + add r1=-IA64_PT_REGS_SIZE,sp // A allocate space for pt_regs structure + mov ar.rnat=r24 // M2 restore kernel's AR.RNAT + ;; + mov ar.bspstore=r23 // M2 restore kernel's AR.BSPSTORE + br.cond.sptk .back_from_break_fixup END(break_fault) .org ia64_ivt+0x3000 @@ -837,8 +873,6 @@ END(interrupt) * - r31: saved pr * - b0: original contents (to be saved) * On exit: - * - executing on bank 1 registers - * - psr.ic enabled, interrupts restored * - p10: TRUE if syscall is invoked with more than 8 out * registers or r15's Nat is true * - r1: kernel's gp @@ -846,8 +880,11 @@ END(interrupt) * - r8: -EINVAL if p10 is true * - r12: points to kernel stack * - r13: points to current task + * - r14: preserved (same as on entry) + * - p13: preserved * - p15: TRUE if interrupts need to be re-enabled * - ar.fpsr: set to kernel settings + * - b6: preserved (same as on entry) */ GLOBAL_ENTRY(ia64_syscall_setup) #if PT(B6) != 0 @@ -915,7 +952,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) (p13) mov in5=-1 ;; st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr - tnat.nz p14,p0=in6 + tnat.nz p13,p0=in6 cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 ;; mov r8=1 @@ -930,7 +967,7 @@ GLOBAL_ENTRY(ia64_syscall_setup) movl r1=__gp // establish kernel global pointer ;; st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) -(p14) mov in6=-1 +(p13) mov in6=-1 (p8) mov in7=-1 cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 @@ -1002,6 +1039,8 @@ END(dispatch_illegal_op_fault) FAULT(17) ENTRY(non_syscall) + mov ar.rsc=r27 // restore ar.rsc before SAVE_MIN_WITH_COVER + ;; SAVE_MIN_WITH_COVER // There is no particular reason for this code to be here, other than that -- cgit v1.1 From 70929a57cfea8c18de13fcea9ae6771018a98949 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:19:37 -0700 Subject: [IA64] Reschedule __kernel_syscall_via_epc(). Avoid some stalls, which is good for about 2 cycles when invoking a light-weight handler. When invoking a heavy-weight handler, this helps by about 7 cycles, with most of the improvement coming from the improved branch-prediction achieved by splitting the BBB bundle into two MIB bundles. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.S | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index facf75a..3cd3f2e 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -79,31 +79,34 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) ;; rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" LOAD_FSYSCALL_TABLE(r14) - + ;; mov r16=IA64_KR(CURRENT) // 12 cycle read latency - tnat.nz p10,p9=r15 + shladd r18=r17,3,r14 mov r19=NR_syscalls-1 ;; - shladd r18=r17,3,r14 - - srlz.d - cmp.ne p8,p0=r0,r0 // p8 <- FALSE + lfetch [r18] // M0|1 + mov r29=psr // read psr (12 cyc load latency) /* Note: if r17 is a NaT, p6 will be set to zero. */ cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? ;; -(p6) ld8 r18=[r18] mov r21=ar.fpsr - add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + tnat.nz p10,p9=r15 + mov r26=ar.pfs ;; + srlz.d +(p6) ld8 r18=[r18] + nop.i 0 + ;; + nop.m 0 (p6) mov b7=r18 -(p6) tbit.z p8,p0=r18,0 +(p6) tbit.z.unc p8,p0=r18,0 + + nop.m 0 + nop.i 0 (p8) br.dptk.many b7 -(p6) rsm psr.i mov r27=ar.rsc - mov r26=ar.pfs - ;; - mov r29=psr // read psr (12 cyc load latency) +(p6) rsm psr.i /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -111,6 +114,8 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * instead. */ #ifdef CONFIG_ITANIUM + add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry + ;; (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down ;; (p6) mov b7=r14 -- cgit v1.1 From 21bc4f9b34cc1eab3610955207f72c52495ae8ed Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:20:11 -0700 Subject: [IA64] Annotate __kernel_syscall_via_epc() with McKinley dispatch info. Two other very minor changes: use "mov.i" instead of "mov" for reading ar.pfs (for clarity; doesn't affect the code at all). Also, predicate the load of r14 for consistency. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.S | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index 3cd3f2e..272e64c 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -72,41 +72,41 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * bundle get executed. The remaining code must be safe even if * they do not get executed. */ - adds r17=-1024,r15 - mov r10=0 // default to successful syscall execution - epc + adds r17=-1024,r15 // A + mov r10=0 // A default to successful syscall execution + epc // B causes split-issue } ;; - rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be" - LOAD_FSYSCALL_TABLE(r14) + rsm psr.be // M2 (5 cyc to srlz.d) + LOAD_FSYSCALL_TABLE(r14) // X ;; - mov r16=IA64_KR(CURRENT) // 12 cycle read latency - shladd r18=r17,3,r14 - mov r19=NR_syscalls-1 + mov r16=IA64_KR(CURRENT) // M2 (12 cyc) + shladd r18=r17,3,r14 // A + mov r19=NR_syscalls-1 // A ;; lfetch [r18] // M0|1 - mov r29=psr // read psr (12 cyc load latency) - /* Note: if r17 is a NaT, p6 will be set to zero. */ - cmp.geu p6,p7=r19,r17 // (syscall > 0 && syscall < 1024+NR_syscalls)? + mov r29=psr // M2 (12 cyc) + // If r17 is a NaT, p6 will be zero + cmp.geu p6,p7=r19,r17 // A (sysnr > 0 && sysnr < 1024+NR_syscalls)? ;; - mov r21=ar.fpsr - tnat.nz p10,p9=r15 - mov r26=ar.pfs + mov r21=ar.fpsr // M2 (12 cyc) + tnat.nz p10,p9=r15 // I0 + mov.i r26=ar.pfs // I0 (would stall anyhow due to srlz.d...) ;; - srlz.d -(p6) ld8 r18=[r18] + srlz.d // M0 (forces split-issue) ensure PSR.BE==0 +(p6) ld8 r18=[r18] // M0|1 nop.i 0 ;; nop.m 0 -(p6) mov b7=r18 -(p6) tbit.z.unc p8,p0=r18,0 +(p6) mov b7=r18 // I0 +(p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) nop.m 0 nop.i 0 -(p8) br.dptk.many b7 +(p8) br.dptk.many b7 // B - mov r27=ar.rsc -(p6) rsm psr.i + mov r27=ar.rsc // M2 (12 cyc) +(p6) rsm psr.i // M2 /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -114,7 +114,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) * instead. */ #ifdef CONFIG_ITANIUM - add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry +(p6) add r14=-8,r14 // r14 <- addr of fsys_bubble_down entry ;; (p6) ld8 r14=[r14] // r14 <- fsys_bubble_down ;; -- cgit v1.1 From 1ba7be7d691f6df2557d39c5b1a2e14c32e5dd20 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:20:51 -0700 Subject: [IA64] Reschedule fsys_bubble_down(). Improvements come from eliminating srlz.i, not scheduling AR/CR-reads too early (while there are others still pending), scheduling the backing-store switch as well as possible, splitting the BBB bundle into a MIB/MBB pair. Why is it safe to eliminate the srlz.i? Observe that we used to clear bits ~PSR_PRESERVED_BITS in PSR.L. Since PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. However, PSR.BE : already is turned off in __kernel_syscall_via_epc() PSR.AC : don't care (kernel normally turns PSR.AC on) PSR.I : already turned off by the time fsys_bubble_down gets invoked PSR.DFL: always 0 (kernel never turns it on) PSR.DFH: don't care --- kernel never touches f32-f127 on its own initiative PSR.DI : always 0 (kernel never turns it on) PSR.SI : always 0 (kernel never turns it on) PSR.DB : don't care --- kernel never enables kernel-level breakpoints PSR.TB : must be 0 already; if it wasn't zero on entry to __kernel_syscall_via_epc, the branch to fsys_bubble_down will trigger a taken branch; the taken-trap-handler then converts the syscall into a break-based system-call. In other words: all the bits we're clearying are either 0 already or are don't cares! Thus, we don't have to write PSR.L at all and we don't have to do a srlz.i either. Good for another ~20 cycle improvement for EPC-based heavy-weight syscalls. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 73 ++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 40 deletions(-) diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 0d8650f..57c6556 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -549,9 +549,6 @@ GLOBAL_ENTRY(fsys_bubble_down) * - r27: ar.rsc * - r29: psr */ -# define PSR_PRESERVED_BITS (IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \ - | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \ - | IA64_PSR_IC) /* * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have * to synthesize. @@ -560,62 +557,58 @@ GLOBAL_ENTRY(fsys_bubble_down) | IA64_PSR_BN | IA64_PSR_I) invala - movl r8=PSR_ONE_BITS + movl r14=ia64_ret_from_syscall - mov r25=ar.unat // save ar.unat (5 cyc) - movl r9=PSR_PRESERVED_BITS - - mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 + nop.m 0 movl r28=__kernel_syscall_via_break ;; - mov r23=ar.bspstore // save ar.bspstore (12 cyc) - mov r31=pr // save pr (2 cyc) - mov r20=r1 // save caller's gp in r20 - ;; + mov r2=r16 // copy current task addr to addl-addressable register - and r9=r9,r29 - mov r19=b6 // save b6 (2 cyc) + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 + mov r31=pr // save pr (2 cyc) ;; - mov psr.l=r9 // slam the door (17 cyc to srlz.i) - or r29=r8,r29 // construct cr.ipsr value to save + st1 [r16]=r0 // clear current->thread.on_ustack flag addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS + add r3=TI_FLAGS+IA64_TASK_SIZE,r2 ;; - // GAS reports a spurious RAW hazard on the read of ar.rnat because it thinks - // we may be reading ar.itc after writing to psr.l. Avoid that message with - // this directive: - dv_serialize_data - mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) + ld4 r3=[r3] // r2 = current_thread_info()->flags lfetch.fault.excl.nt1 [r22] - adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2 - - // ensure previous insn group is issued before we stall for srlz.i: + nop.i 0 ;; - srlz.i // ensure new psr.l has been established - ///////////////////////////////////////////////////////////////////////////// - ////////// from this point on, execution is not interruptible anymore - ///////////////////////////////////////////////////////////////////////////// - addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack - cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 + mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 + nop.m 0 + nop.i 0 + ;; + mov r23=ar.bspstore // save ar.bspstore (12 cyc) + mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) + nop.i 0 ;; - st1 [r16]=r0 // clear current->thread.on_ustack flag mov ar.bspstore=r22 // switch to kernel RBS - mov b6=r18 // copy syscall entry-point to b6 (7 cyc) - add r3=TI_FLAGS+IA64_TASK_SIZE,r2 + movl r8=PSR_ONE_BITS // X ;; - ld4 r3=[r3] // r2 = current_thread_info()->flags + mov r25=ar.unat // save ar.unat (5 cyc) + mov r19=b6 // save b6 (2 cyc) + mov r20=r1 // save caller's gp in r20 + ;; + or r29=r8,r29 // construct cr.ipsr value to save + mov b6=r18 // copy syscall entry-point to b6 (7 cyc) + addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack + mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) - mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 + cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 br.call.sptk.many b7=ia64_syscall_setup ;; - ssm psr.i - movl r2=ia64_ret_from_syscall + mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 + mov rp=r14 // set the real return addr + nop.i 0 ;; - mov rp=r2 // set the real return addr + ssm psr.i tbit.z p8,p0=r3,TIF_SYSCALL_TRACE - ;; (p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 + + nop.m 0 (p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall + br.cond.spnt ia64_trace_syscall END(fsys_bubble_down) .rodata -- cgit v1.1 From fbf7192ba06e4b55022231e5fdb9db8ce3ad6307 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:21:26 -0700 Subject: [IA64] Annotate fsys_bubble_down() with McKinley dispatch info. This patch changes comments & formatting only. There is no code change. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 118 ++++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 44 deletions(-) diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index 57c6556..d09a5b8 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -531,84 +531,114 @@ GLOBAL_ENTRY(fsys_bubble_down) .altrp b6 .body /* - * We get here for syscalls that don't have a lightweight handler. For those, we - * need to bubble down into the kernel and that requires setting up a minimal - * pt_regs structure, and initializing the CPU state more or less as if an - * interruption had occurred. To make syscall-restarts work, we setup pt_regs - * such that cr_iip points to the second instruction in syscall_via_break. - * Decrementing the IP hence will restart the syscall via break and not - * decrementing IP will return us to the caller, as usual. Note that we preserve - * the value of psr.pp rather than initializing it from dcr.pp. This makes it - * possible to distinguish fsyscall execution from other privileged execution. + * We get here for syscalls that don't have a lightweight + * handler. For those, we need to bubble down into the kernel + * and that requires setting up a minimal pt_regs structure, + * and initializing the CPU state more or less as if an + * interruption had occurred. To make syscall-restarts work, + * we setup pt_regs such that cr_iip points to the second + * instruction in syscall_via_break. Decrementing the IP + * hence will restart the syscall via break and not + * decrementing IP will return us to the caller, as usual. + * Note that we preserve the value of psr.pp rather than + * initializing it from dcr.pp. This makes it possible to + * distinguish fsyscall execution from other privileged + * execution. * * On entry: - * - normal fsyscall handler register usage, except that we also have: + * - normal fsyscall handler register usage, except + * that we also have: * - r18: address of syscall entry point * - r21: ar.fpsr * - r26: ar.pfs * - r27: ar.rsc * - r29: psr + * + * We used to clear some PSR bits here but that requires slow + * serialization. Fortuntely, that isn't really necessary. + * The rationale is as follows: we used to clear bits + * ~PSR_PRESERVED_BITS in PSR.L. Since + * PSR_PRESERVED_BITS==PSR.{UP,MFL,MFH,PK,DT,PP,SP,RT,IC}, we + * ended up clearing PSR.{BE,AC,I,DFL,DFH,DI,DB,SI,TB}. + * However, + * + * PSR.BE : already is turned off in __kernel_syscall_via_epc() + * PSR.AC : don't care (kernel normally turns PSR.AC on) + * PSR.I : already turned off by the time fsys_bubble_down gets + * invoked + * PSR.DFL: always 0 (kernel never turns it on) + * PSR.DFH: don't care --- kernel never touches f32-f127 on its own + * initiative + * PSR.DI : always 0 (kernel never turns it on) + * PSR.SI : always 0 (kernel never turns it on) + * PSR.DB : don't care --- kernel never enables kernel-level + * breakpoints + * PSR.TB : must be 0 already; if it wasn't zero on entry to + * __kernel_syscall_via_epc, the branch to fsys_bubble_down + * will trigger a taken branch; the taken-trap-handler then + * converts the syscall into a break-based system-call. */ /* - * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. The rest we have - * to synthesize. + * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc. + * The rest we have to synthesize. */ -# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \ +# define PSR_ONE_BITS ((3 << IA64_PSR_CPL0_BIT) \ + | (0x1 << IA64_PSR_RI_BIT) \ | IA64_PSR_BN | IA64_PSR_I) - invala - movl r14=ia64_ret_from_syscall + invala // M0|1 + movl r14=ia64_ret_from_syscall // X nop.m 0 - movl r28=__kernel_syscall_via_break + movl r28=__kernel_syscall_via_break // X create cr.iip ;; - mov r2=r16 // copy current task addr to addl-addressable register - adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - mov r31=pr // save pr (2 cyc) + mov r2=r16 // A get task addr to addl-addressable register + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 // A + mov r31=pr // I0 save pr (2 cyc) ;; - st1 [r16]=r0 // clear current->thread.on_ustack flag - addl r22=IA64_RBS_OFFSET,r2 // compute base of RBS - add r3=TI_FLAGS+IA64_TASK_SIZE,r2 + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + addl r22=IA64_RBS_OFFSET,r2 // A compute base of RBS + add r3=TI_FLAGS+IA64_TASK_SIZE,r2 // A ;; - ld4 r3=[r3] // r2 = current_thread_info()->flags - lfetch.fault.excl.nt1 [r22] + ld4 r3=[r3] // M0|1 r3 = current_thread_info()->flags + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch register backing-store nop.i 0 ;; - mov ar.rsc=0 // set enforced lazy mode, pl 0, little-endian, loadrs=0 + mov ar.rsc=0 // M2 set enforced lazy mode, pl 0, LE, loadrs=0 nop.m 0 nop.i 0 ;; - mov r23=ar.bspstore // save ar.bspstore (12 cyc) - mov.m r24=ar.rnat // read ar.rnat (5 cyc lat) + mov r23=ar.bspstore // M2 (12 cyc) save ar.bspstore + mov.m r24=ar.rnat // M2 (5 cyc) read ar.rnat (dual-issues!) nop.i 0 ;; - mov ar.bspstore=r22 // switch to kernel RBS + mov ar.bspstore=r22 // M2 (6 cyc) switch to kernel RBS movl r8=PSR_ONE_BITS // X ;; - mov r25=ar.unat // save ar.unat (5 cyc) - mov r19=b6 // save b6 (2 cyc) - mov r20=r1 // save caller's gp in r20 + mov r25=ar.unat // M2 (5 cyc) save ar.unat + mov r19=b6 // I0 save b6 (2 cyc) + mov r20=r1 // A save caller's gp in r20 ;; - or r29=r8,r29 // construct cr.ipsr value to save - mov b6=r18 // copy syscall entry-point to b6 (7 cyc) - addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // compute base of memory stack + or r29=r8,r29 // A construct cr.ipsr value to save + mov b6=r18 // I0 copy syscall entry-point to b6 (7 cyc) + addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2 // A compute base of memory stack - mov r18=ar.bsp // save (kernel) ar.bsp (12 cyc) - cmp.ne pKStk,pUStk=r0,r0 // set pKStk <- 0, pUStk <- 1 - br.call.sptk.many b7=ia64_syscall_setup + mov r18=ar.bsp // M2 save (kernel) ar.bsp (12 cyc) + cmp.ne pKStk,pUStk=r0,r0 // A set pKStk <- 0, pUStk <- 1 + br.call.sptk.many b7=ia64_syscall_setup // B ;; - mov ar.rsc=0x3 // set eager mode, pl 0, little-endian, loadrs=0 - mov rp=r14 // set the real return addr + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + mov rp=r14 // I0 set the real return addr nop.i 0 ;; - ssm psr.i - tbit.z p8,p0=r3,TIF_SYSCALL_TRACE -(p10) br.cond.spnt.many ia64_ret_from_syscall // p10==true means out registers are more than 8 + ssm psr.i // M2 we're on kernel stacks now, reenable irqs + tbit.z p8,p0=r3,TIF_SYSCALL_TRACE // I0 +(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT nop.m 0 -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.spnt ia64_trace_syscall +(p8) br.call.sptk.many b6=b6 // B (ignore return address) + br.cond.spnt ia64_trace_syscall // B END(fsys_bubble_down) .rodata -- cgit v1.1 From e7e965fa1961a8ce32cbbb1bd436c655ad03973e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:22:08 -0700 Subject: [IA64] use srlz.d instead of srlz.i in ia64_leave_kernel() This patch switches the srlz.i in ia64_leave_kernel() to srlz.d. As per architecture manual, the former is needed only to ensure that the clearing of PSR.IC is seen by the VHPT for subsequent instruction fetches. However, since the remainder of the code (up to and including the RFI instruction) is mapped by a pinned TLB entry, there is no chance of an iTLB miss and we don't care whether or not the VHPT sees PSR.IC cleared. Since srlz.d is substantially cheaper than srlz.i, this should shave off a few cycles off the interrupt path (unverified though; I'm not setup to measure this at the moment). Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/entry.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index a7542c3..4517d4a 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S @@ -880,7 +880,7 @@ GLOBAL_ENTRY(ia64_leave_kernel) ldf.fill f7=[r2],PT(F11)-PT(F7) ldf.fill f8=[r3],32 ;; - srlz.i // ensure interruption collection is off + srlz.d // ensure that inter. collection is off (VHPT is don't care, since text is pinned) mov ar.ccv=r15 ;; ldf.fill f11=[r2] -- cgit v1.1 From 8e3e50168c8537807b7a6f78588cd72e21363262 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 27 Apr 2005 21:22:40 -0700 Subject: [IA64] need r29=psr *after* rsm psr.i Yanmin Zhang pointed out a sequence problem when saving the psr. David Mosberger provided this patch (which gave up a cycle). Signed-off-by: Tony Luck --- arch/ia64/kernel/gate.S | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S index 272e64c..86948ce 100644 --- a/arch/ia64/kernel/gate.S +++ b/arch/ia64/kernel/gate.S @@ -77,7 +77,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) epc // B causes split-issue } ;; - rsm psr.be // M2 (5 cyc to srlz.d) + rsm psr.be | psr.i // M2 (5 cyc to srlz.d) LOAD_FSYSCALL_TABLE(r14) // X ;; mov r16=IA64_KR(CURRENT) // M2 (12 cyc) @@ -98,15 +98,14 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) nop.i 0 ;; nop.m 0 -(p6) mov b7=r18 // I0 (p6) tbit.z.unc p8,p0=r18,0 // I0 (dual-issues with "mov b7=r18"!) - - nop.m 0 nop.i 0 + ;; +(p8) ssm psr.i +(p6) mov b7=r18 // I0 (p8) br.dptk.many b7 // B mov r27=ar.rsc // M2 (12 cyc) -(p6) rsm psr.i // M2 /* * brl.cond doesn't work as intended because the linker would convert this branch * into a branch to a PLT. Perhaps there will be a way to avoid this with some @@ -123,7 +122,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) #else BRL_COND_FSYS_BUBBLE_DOWN(p6) #endif - + ssm psr.i mov r10=-1 (p10) mov r8=EINVAL (p9) mov r8=ENOSYS -- cgit v1.1 From ebcc80c1b6629a445f7471cc1ddb48faf8a84e70 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Thu, 5 May 2005 06:40:00 -0700 Subject: [IA64] Merge audit fix for fsyscalls with syscall-optimizations Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/fsys.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S index d09a5b8..f566ff4 100644 --- a/arch/ia64/kernel/fsys.S +++ b/arch/ia64/kernel/fsys.S @@ -630,10 +630,10 @@ GLOBAL_ENTRY(fsys_bubble_down) ;; mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 mov rp=r14 // I0 set the real return addr - nop.i 0 + and r3=_TIF_SYSCALL_TRACEAUDIT,r3 // A ;; ssm psr.i // M2 we're on kernel stacks now, reenable irqs - tbit.z p8,p0=r3,TIF_SYSCALL_TRACE // I0 + cmp.eq p8,p0=r3,r0 // A (p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT nop.m 0 -- cgit v1.1 From 7f9eaedf894dbaa08c157832e9a6c9c03ffed1ed Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Tue, 10 May 2005 12:49:00 -0700 Subject: [IA64] Fix convert_to_non_syscall() so gdb inferior calls work again Fix convert_to_non_syscall() so it arranges for the kernel to be left via ia64_leave_kernel() rather than ia64_leave_syscall(). The latter no longer tolerates being called with pSys=0 and pNonSys=1. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ptrace.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index c253fd5..9e730c7 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c @@ -705,12 +705,32 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, break; } + /* + * Note: at the time of this call, the target task is blocked + * in notify_resume_user() and by clearling PRED_LEAVE_SYSCALL + * (aka, "pLvSys") we redirect execution from + * .work_pending_syscall_end to .work_processed_kernel. + */ unw_get_pr(&prev_info, &pr); - pr &= ~(1UL << PRED_SYSCALL); + pr &= ~((1UL << PRED_SYSCALL) | (1UL << PRED_LEAVE_SYSCALL)); pr |= (1UL << PRED_NON_SYSCALL); unw_set_pr(&prev_info, pr); pt->cr_ifs = (1UL << 63) | cfm; + /* + * Clear the memory that is NOT written on syscall-entry to + * ensure we do not leak kernel-state to user when execution + * resumes. + */ + pt->r2 = 0; + pt->r3 = 0; + pt->r14 = 0; + memset(&pt->r16, 0, 16*8); /* clear r16-r31 */ + memset(&pt->f6, 0, 6*16); /* clear f6-f11 */ + pt->b7 = 0; + pt->ar_ccv = 0; + pt->ar_csd = 0; + pt->ar_ssd = 0; } static int -- cgit v1.1 From 955660652af35524974cf4623c02bc99a3785949 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:02 -0700 Subject: [PATCH] skge: whietspace cleanup Cleanup whitespace around if() and switch() and end of lines Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 46 +++++++++++++++++++++++----------------------- drivers/net/skge.h | 48 ++++++++++++++++++++++++------------------------ 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 30e8d58..2d15ed3 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -170,7 +170,7 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) struct skge_port *skge = netdev_priv(dev); struct skge_hw *hw = skge->hw; - if(wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) + if (wol->wolopts != WAKE_MAGIC && wol->wolopts != 0) return -EOPNOTSUPP; if (wol->wolopts == WAKE_MAGIC && !wol_supported(hw)) @@ -247,7 +247,7 @@ static u32 skge_modes(const struct skge_hw *hw) if (iscopper(hw)) { modes |= ADVERTISED_TP; - switch(hw->chip_id) { + switch (hw->chip_id) { case CHIP_ID_GENESIS: modes &= ~(ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half @@ -279,7 +279,7 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) if (ecmd->advertising & skge_modes(hw)) return -EINVAL; } else { - switch(ecmd->speed) { + switch (ecmd->speed) { case SPEED_1000: if (hw->chip_id == CHIP_ID_YUKON_FE) return -EINVAL; @@ -393,7 +393,7 @@ static void skge_get_strings(struct net_device *dev, u32 stringset, u8 *data) { int i; - switch(stringset) { + switch (stringset) { case ETH_SS_STATS: for (i = 0; i < ARRAY_SIZE(skge_stats); i++) memcpy(data + i * ETH_GSTRING_LEN, @@ -540,9 +540,9 @@ static int skge_set_pauseparam(struct net_device *dev, skge->autoneg = ecmd->autoneg; if (ecmd->rx_pause && ecmd->tx_pause) skge->flow_control = FLOW_MODE_SYMMETRIC; - else if(ecmd->rx_pause && !ecmd->tx_pause) + else if (ecmd->rx_pause && !ecmd->tx_pause) skge->flow_control = FLOW_MODE_REM_SEND; - else if(!ecmd->rx_pause && ecmd->tx_pause) + else if (!ecmd->rx_pause && ecmd->tx_pause) skge->flow_control = FLOW_MODE_LOC_SEND; else skge->flow_control = FLOW_MODE_NONE; @@ -730,7 +730,7 @@ static int skge_phys_id(struct net_device *dev, u32 data) { struct skge_port *skge = netdev_priv(dev); - if(!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) + if (!data || data > (u32)(MAX_SCHEDULE_TIMEOUT / HZ)) data = (u32)(MAX_SCHEDULE_TIMEOUT / HZ); /* start blinking */ @@ -1960,7 +1960,7 @@ static u16 yukon_speed(const struct skge_hw *hw, u16 aux) if (hw->chip_id == CHIP_ID_YUKON_FE) return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; - switch(aux & PHY_M_PS_SPEED_MSK) { + switch (aux & PHY_M_PS_SPEED_MSK) { case PHY_M_PS_SPEED_1000: return SPEED_1000; case PHY_M_PS_SPEED_100: @@ -2299,10 +2299,10 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) local_irq_save(flags); if (!spin_trylock(&skge->tx_lock)) { - /* Collision - tell upper layer to requeue */ - local_irq_restore(flags); - return NETDEV_TX_LOCKED; - } + /* Collision - tell upper layer to requeue */ + local_irq_restore(flags); + return NETDEV_TX_LOCKED; + } if (unlikely(skge->tx_avail < skb_shinfo(skb)->nr_frags +1)) { netif_stop_queue(dev); @@ -2439,7 +2439,7 @@ static int skge_change_mtu(struct net_device *dev, int new_mtu) { int err = 0; - if(new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) + if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; dev->mtu = new_mtu; @@ -2473,7 +2473,7 @@ static void genesis_set_multicast(struct net_device *dev) memset(filter, 0xff, sizeof(filter)); else { memset(filter, 0, sizeof(filter)); - for(i = 0; list && i < count; i++, list = list->next) { + for (i = 0; list && i < count; i++, list = list->next) { u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN); u8 bit = 63 - (crc & 63); @@ -2510,7 +2510,7 @@ static void yukon_set_multicast(struct net_device *dev) int i; reg |= GM_RXCR_MCF_ENA; - for(i = 0; list && i < dev->mc_count; i++, list = list->next) { + for (i = 0; list && i < dev->mc_count; i++, list = list->next) { u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f; filter[bit/8] |= 1 << (bit%8); } @@ -2657,7 +2657,7 @@ static inline void skge_tx_intr(struct net_device *dev) struct skge_element *e; spin_lock(&skge->tx_lock); - for(e = ring->to_clean; e != ring->to_use; e = e->next) { + for (e = ring->to_clean; e != ring->to_use; e = e->next) { struct skge_tx_desc *td = e->desc; u32 control; @@ -2712,7 +2712,7 @@ static void skge_pci_clear(struct skge_hw *hw) static void skge_mac_intr(struct skge_hw *hw, int port) { - if (hw->chip_id == CHIP_ID_GENESIS) + if (hw->chip_id == CHIP_ID_GENESIS) genesis_mac_intr(hw, port); else yukon_mac_intr(hw, port); @@ -2847,7 +2847,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) if (status & IS_MAC1) skge_mac_intr(hw, 0); - + if (status & IS_MAC2) skge_mac_intr(hw, 1); @@ -2952,7 +2952,7 @@ static int skge_reset(struct skge_hw *hw) hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; hw->pmd_type = skge_read8(hw, B2_PMD_TYP); - switch(hw->chip_id) { + switch (hw->chip_id) { case CHIP_ID_GENESIS: switch (hw->phy_type) { case SK_PHY_XMAC: @@ -3288,7 +3288,7 @@ static void __devexit skge_remove(struct pci_dev *pdev) struct skge_hw *hw = pci_get_drvdata(pdev); struct net_device *dev0, *dev1; - if(!hw) + if (!hw) return; if ((dev1 = hw->dev[1])) @@ -3316,7 +3316,7 @@ static int skge_suspend(struct pci_dev *pdev, u32 state) struct skge_hw *hw = pci_get_drvdata(pdev); int i, wol = 0; - for(i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; if (dev) { @@ -3349,11 +3349,11 @@ static int skge_resume(struct pci_dev *pdev) skge_reset(hw); - for(i = 0; i < 2; i++) { + for (i = 0; i < 2; i++) { struct net_device *dev = hw->dev[i]; if (dev) { netif_device_attach(dev); - if(netif_running(dev)) + if (netif_running(dev)) skge_up(dev); } } diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 36c62b6..aad3aec 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -537,7 +537,7 @@ enum { /* Queue Register Offsets, use Q_ADDR() to access */ enum { - B8_Q_REGS = 0x0400, /* base of Queue registers */ + B8_Q_REGS = 0x0400, /* base of Queue registers */ Q_D = 0x00, /* 8*32 bit Current Descriptor */ Q_DA_L = 0x20, /* 32 bit Current Descriptor Address Low dWord */ Q_DA_H = 0x24, /* 32 bit Current Descriptor Address High dWord */ @@ -986,7 +986,7 @@ enum { LINKLED_BLINK_OFF = 0x10, LINKLED_BLINK_ON = 0x20, }; - + /* GMAC and GPHY Control Registers (YUKON only) */ enum { GMAC_CTRL = 0x0f00,/* 32 bit GMAC Control Reg */ @@ -1306,7 +1306,7 @@ enum { enum { PHY_ANE_PAR_DF = 1<<4, /* Bit 4: Parallel Detection Fault */ - PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */ + PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */ }; enum { @@ -1718,7 +1718,7 @@ enum { PHY_M_PC_EN_DET_PLUS = 3<<8, /* Energy Detect Plus (Mode 2) */ }; -#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) +#define PHY_M_PC_MDI_XMODE(x) (((x)<<5) & PHY_M_PC_MDIX_MSK) enum { PHY_M_PC_MAN_MDI = 0, /* 00 = Manual MDI configuration */ @@ -2105,7 +2105,7 @@ enum { GM_GPSR_FC_RX_DIS = 1<<2, /* Bit 2: Rx Flow-Control Mode Disabled */ GM_GPSR_PROM_EN = 1<<1, /* Bit 1: Promiscuous Mode Enabled */ }; - + /* GM_GP_CTRL 16 bit r/w General Purpose Control Register */ enum { GM_GPCR_PROM_ENA = 1<<14, /* Bit 14: Enable Promiscuous Mode */ @@ -2127,7 +2127,7 @@ enum { #define GM_GPCR_SPEED_1000 (GM_GPCR_GIGS_ENA | GM_GPCR_SPEED_100) #define GM_GPCR_AU_ALL_DIS (GM_GPCR_AU_DUP_DIS | GM_GPCR_AU_FCT_DIS|GM_GPCR_AU_SPD_DIS) - + /* GM_TX_CTRL 16 bit r/w Transmit Control Register */ enum { GM_TXCR_FORCE_JAM = 1<<15, /* Bit 15: Force Jam / Flow-Control */ @@ -2138,7 +2138,7 @@ enum { #define TX_COL_THR(x) (((x)<<10) & GM_TXCR_COL_THR_MSK) #define TX_COL_DEF 0x04 - + /* GM_RX_CTRL 16 bit r/w Receive Control Register */ enum { GM_RXCR_UCF_ENA = 1<<15, /* Bit 15: Enable Unicast filtering */ @@ -2146,7 +2146,7 @@ enum { GM_RXCR_CRC_DIS = 1<<13, /* Bit 13: Remove 4-byte CRC */ GM_RXCR_PASS_FC = 1<<12, /* Bit 12: Pass FC packets to FIFO */ }; - + /* GM_TX_PARAM 16 bit r/w Transmit Parameter Register */ enum { GM_TXPA_JAMLEN_MSK = 0x03<<14, /* Bit 15..14: Jam Length */ @@ -2171,7 +2171,7 @@ enum { GM_SMOD_JUMBO_ENA = 1<<8, /* Bit 8: Enable Jumbo (Max. Frame Len) */ GM_SMOD_IPG_MSK = 0x1f /* Bit 4..0: Inter-Packet Gap (IPG) */ }; - + #define DATA_BLIND_VAL(x) (((x)<<11) & GM_SMOD_DATABL_MSK) #define DATA_BLIND_DEF 0x04 @@ -2186,7 +2186,7 @@ enum { GM_SMI_CT_RD_VAL = 1<<4, /* Bit 4: Read Valid (Read completed) */ GM_SMI_CT_BUSY = 1<<3, /* Bit 3: Busy (Operation in progress) */ }; - + #define GM_SMI_CT_PHY_AD(x) (((x)<<11) & GM_SMI_CT_PHY_A_MSK) #define GM_SMI_CT_REG_AD(x) (((x)<<6) & GM_SMI_CT_REG_A_MSK) @@ -2195,7 +2195,7 @@ enum { GM_PAR_MIB_CLR = 1<<5, /* Bit 5: Set MIB Clear Counter Mode */ GM_PAR_MIB_TST = 1<<4, /* Bit 4: MIB Load Counter (Test Mode) */ }; - + /* Receive Frame Status Encoding */ enum { GMR_FS_LEN = 0xffff<<16, /* Bit 31..16: Rx Frame Length */ @@ -2217,12 +2217,12 @@ enum { /* * GMR_FS_ANY_ERR (analogous to XMR_FS_ANY_ERR) */ - GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | - GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | + GMR_FS_ANY_ERR = GMR_FS_CRC_ERR | GMR_FS_LONG_ERR | + GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_JABBER, /* Rx GMAC FIFO Flush Mask (default) */ RX_FF_FL_DEF_MSK = GMR_FS_CRC_ERR | GMR_FS_RX_FF_OV |GMR_FS_MII_ERR | - GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | + GMR_FS_BAD_FC | GMR_FS_GOOD_FC | GMR_FS_UN_SIZE | GMR_FS_JABBER, }; @@ -2801,7 +2801,7 @@ struct skge_hw { u32 ram_size; u32 ram_offset; - + struct tasklet_struct ext_tasklet; spinlock_t phy_lock; }; @@ -2827,7 +2827,7 @@ enum { FLOW_MODE_REM_SEND = 2, /* Symmetric or just remote */ FLOW_MODE_SYMMETRIC = 3, /* Both stations may send PAUSE */ }; - + struct skge_port { u32 msg_enable; struct skge_hw *hw; @@ -2933,24 +2933,24 @@ static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg, const u8 *hash) { - skge_xm_write16(hw, port, reg, + skge_xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8)); - skge_xm_write16(hw, port, reg+2, + skge_xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8)); - skge_xm_write16(hw, port, reg+4, + skge_xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8)); - skge_xm_write16(hw, port, reg+6, + skge_xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8)); } static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg, const u8 *addr) { - skge_xm_write16(hw, port, reg, + skge_xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8)); - skge_xm_write16(hw, port, reg, + skge_xm_write16(hw, port, reg, (u16)addr[2] | ((u16)addr[3] << 8)); - skge_xm_write16(hw, port, reg, + skge_xm_write16(hw, port, reg, (u16)addr[4] | ((u16)addr[5] << 8)); } @@ -3001,5 +3001,5 @@ static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg, skge_gma_write16(hw, port, reg+8, (u16) addr[4] | ((u16) addr[5] << 8)); } - + #endif -- cgit v1.1 From 275834d1095dcd52d0fefd0d3f7d0320552fe277 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:03 -0700 Subject: [PATCH] skge: PCI_DEVICE() macro Use PCI_DEVICE() macro. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 2d15ed3..cd4e92b 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -70,28 +70,17 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static const struct pci_device_id skge_id_table[] = { - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_SYSKONNECT, 0x9E00, /* SK-9Exx */ - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_MARVELL, 0x4320, /* Gigabit Ethernet Controller */ - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_MARVELL, 0x5005, /* Marvell (11ab), Belkin */ - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032, - PCI_ANY_ID, PCI_ANY_ID }, - { PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064, - PCI_ANY_ID, PCI_ANY_ID }, + { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940) }, + { PCI_DEVICE(PCI_VENDOR_ID_3COM, PCI_DEVICE_ID_3COM_3C940B) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) }, + { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ + { PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, + { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ + { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, + { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) }, + { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, { 0 } }; MODULE_DEVICE_TABLE(pci, skge_id_table); -- cgit v1.1 From 6b0c1480491a9e2d9d34368e09e6acddbb173515 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:04 -0700 Subject: [PATCH] skge: function amd macro name change The inlines and macro's needed some cleanup's and fixes: * change name of macro SKGEMAC_REG to SK_REG to better reflect usage and fix comments * ditto for SK_GEXM_REG -> SK_XMAC_REG and SKGEGMA_REG -> SK_GMA_REG * change skge_gm_ to just gm_ since it is just a local function and long names look ugly. * change skge_xm_ to just xm_ * fix xm_write32 to write as two u16's with correct byte order * fix xm_outaddr to correctly use offset Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 472 ++++++++++++++++++++++++++--------------------------- drivers/net/skge.h | 113 +++++-------- 2 files changed, 279 insertions(+), 306 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index cd4e92b..210029a73 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -88,8 +88,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); static int skge_up(struct net_device *dev); static int skge_down(struct net_device *dev); static void skge_tx_clean(struct skge_port *skge); -static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); -static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); +static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); +static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); static void genesis_get_stats(struct skge_port *skge, u64 *data); static void yukon_get_stats(struct skge_port *skge, u64 *data); static void yukon_init(struct skge_hw *hw, int port); @@ -632,30 +632,30 @@ static int skge_set_coalesce(struct net_device *dev, static void skge_led_on(struct skge_hw *hw, int port) { if (hw->chip_id == CHIP_ID_GENESIS) { - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); skge_write8(hw, B0_LED, LED_STAT_ON); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_TST), LED_T_ON); - skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 100); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, RX_LED_TST), LED_T_ON); + skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); switch (hw->phy_type) { case SK_PHY_BCOM: - skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); break; case SK_PHY_LONE: - skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG, + xm_phy_write(hw, port, PHY_LONE_LED_CFG, 0x0800); break; default: - skge_write8(hw, SKGEMAC_REG(port, TX_LED_TST), LED_T_ON); - skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 100); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON); + skge_write32(hw, SK_REG(port, TX_LED_VAL), 100); + skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); } } else { - skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); - skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, + gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, PHY_M_LED_MO_DUP(MO_LED_ON) | PHY_M_LED_MO_10(MO_LED_ON) | PHY_M_LED_MO_100(MO_LED_ON) | @@ -667,28 +667,28 @@ static void skge_led_on(struct skge_hw *hw, int port) static void skge_led_off(struct skge_hw *hw, int port) { if (hw->chip_id == CHIP_ID_GENESIS) { - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_OFF); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); skge_write8(hw, B0_LED, LED_STAT_OFF); - skge_write32(hw, SKGEMAC_REG(port, RX_LED_VAL), 0); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_T_OFF); + skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); switch (hw->phy_type) { case SK_PHY_BCOM: - skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); break; case SK_PHY_LONE: - skge_xm_phy_write(hw, port, PHY_LONE_LED_CFG, + xm_phy_write(hw, port, PHY_LONE_LED_CFG, PHY_L_LC_LEDT); break; default: - skge_write32(hw, SKGEMAC_REG(port, TX_LED_VAL), 0); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_T_OFF); + skge_write32(hw, SK_REG(port, TX_LED_VAL), 0); + skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF); } } else { - skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); - skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, + gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, PHY_M_LED_MO_DUP(MO_LED_OFF) | PHY_M_LED_MO_10(MO_LED_OFF) | PHY_M_LED_MO_100(MO_LED_OFF) | @@ -908,17 +908,17 @@ static void skge_link_down(struct skge_port *skge) printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name); } -static u16 skge_xm_phy_read(struct skge_hw *hw, int port, u16 reg) +static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) { int i; u16 v; - skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); - v = skge_xm_read16(hw, port, XM_PHY_DATA); + xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); + v = xm_read16(hw, port, XM_PHY_DATA); if (hw->phy_type != SK_PHY_XMAC) { for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (skge_xm_read16(hw, port, XM_MMU_CMD) + if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY) goto ready; } @@ -927,19 +927,19 @@ static u16 skge_xm_phy_read(struct skge_hw *hw, int port, u16 reg) hw->dev[port]->name); return 0; ready: - v = skge_xm_read16(hw, port, XM_PHY_DATA); + v = xm_read16(hw, port, XM_PHY_DATA); } return v; } -static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) +static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) { int i; - skge_xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); + xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); for (i = 0; i < PHY_RETRIES; i++) { - if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) + if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) goto ready; cpu_relax(); } @@ -948,10 +948,10 @@ static void skge_xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) ready: - skge_xm_write16(hw, port, XM_PHY_DATA, val); + xm_write16(hw, port, XM_PHY_DATA, val); for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (!(skge_xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) + if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) return; } printk(KERN_WARNING PFX "%s: phy write timed out\n", @@ -992,20 +992,20 @@ static void genesis_reset(struct skge_hw *hw, int port) u64 zero = 0; /* reset the statistics module */ - skge_xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); - skge_xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ - skge_xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ - skge_xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ - skge_xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ + xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); + xm_write16(hw, port, XM_IMSK, 0xffff); /* disable XMAC IRQs */ + xm_write32(hw, port, XM_MODE, 0); /* clear Mode Reg */ + xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ + xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ /* disable all PHY IRQs */ if (hw->phy_type == SK_PHY_BCOM) - skge_xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); + xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); - skge_xm_outhash(hw, port, XM_HSM, (u8 *) &zero); + xm_outhash(hw, port, XM_HSM, (u8 *) &zero); for (i = 0; i < 15; i++) - skge_xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero); - skge_xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero); + xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero); + xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero); } @@ -1033,14 +1033,14 @@ static void genesis_mac_init(struct skge_hw *hw, int port) /* initialize Rx, Tx and Link LED */ - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_ON); - skge_write8(hw, SKGEMAC_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); + skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_LINKSYNC_ON); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_START); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); + skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); /* Unreset the XMAC. */ - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_MAC_RST); /* * Perform additional initialization for external PHYs, @@ -1060,13 +1060,13 @@ static void genesis_mac_init(struct skge_hw *hw, int port) skge_read32(hw, B2_GP_IO); /* Enable GMII mode on the XMAC. */ - skge_xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); + xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); - id1 = skge_xm_phy_read(hw, port, PHY_XMAC_ID1); + id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); /* Optimize MDIO transfer by suppressing preamble. */ - skge_xm_write16(hw, port, XM_MMU_CMD, - skge_xm_read16(hw, port, XM_MMU_CMD) + xm_write16(hw, port, XM_MMU_CMD, + xm_read16(hw, port, XM_MMU_CMD) | XM_MMU_NO_PRE); if (id1 == PHY_BCOM_ID1_C0) { @@ -1075,7 +1075,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * Write magic patterns to reserved registers. */ for (i = 0; i < ARRAY_SIZE(C0hack); i++) - skge_xm_phy_write(hw, port, + xm_phy_write(hw, port, C0hack[i].reg, C0hack[i].val); } else if (id1 == PHY_BCOM_ID1_A1) { @@ -1084,7 +1084,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * Write magic patterns to reserved registers. */ for (i = 0; i < ARRAY_SIZE(A1hack); i++) - skge_xm_phy_write(hw, port, + xm_phy_write(hw, port, A1hack[i].reg, A1hack[i].val); } @@ -1092,23 +1092,23 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * Workaround BCOM Errata (#10523) for all BCom PHYs. * Disable Power Management after reset. */ - r = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); - skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); + r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); } /* Dummy read */ - skge_xm_read16(hw, port, XM_ISRC); + xm_read16(hw, port, XM_ISRC); - r = skge_xm_read32(hw, port, XM_MODE); - skge_xm_write32(hw, port, XM_MODE, r|XM_MD_CSA); + r = xm_read32(hw, port, XM_MODE); + xm_write32(hw, port, XM_MODE, r|XM_MD_CSA); /* We don't need the FCS appended to the packet. */ - r = skge_xm_read16(hw, port, XM_RX_CMD); - skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS); + r = xm_read16(hw, port, XM_RX_CMD); + xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS); /* We want short frames padded to 60 bytes. */ - r = skge_xm_read16(hw, port, XM_TX_CMD); - skge_xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD); + r = xm_read16(hw, port, XM_TX_CMD); + xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD); /* * Enable the reception of all error frames. This is is @@ -1124,19 +1124,19 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * case the XMAC will start transfering frames out of the * RX FIFO as soon as the FIFO threshold is reached. */ - r = skge_xm_read32(hw, port, XM_MODE); - skge_xm_write32(hw, port, XM_MODE, + r = xm_read32(hw, port, XM_MODE); + xm_write32(hw, port, XM_MODE, XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| XM_MD_RX_ERR|XM_MD_RX_IRLE); - skge_xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); - skge_xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); + xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); + xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); /* * Bump up the transmit threshold. This helps hold off transmit * underruns when we're blasting traffic from both ports at once. */ - skge_xm_write16(hw, port, XM_TX_THR, 512); + xm_write16(hw, port, XM_TX_THR, 512); /* Configure MAC arbiter */ skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR); @@ -1153,18 +1153,18 @@ static void genesis_mac_init(struct skge_hw *hw, int port) skge_write8(hw, B3_MA_RCINI_TX2, 0); /* Configure Rx MAC FIFO */ - skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT); - skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD); + skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_CLR); + skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_TIM_PAT); + skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_ENA_OP_MD); /* Configure Tx MAC FIFO */ - skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); - skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); + skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_CLR); + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); + skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); if (hw->dev[port]->mtu > ETH_DATA_LEN) { /* Enable frame flushing if jumbo frames used */ - skge_write16(hw, SKGEMAC_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); + skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); } else { /* enable timeout timers if normal frames */ skge_write16(hw, B3_PA_CTRL, @@ -1172,11 +1172,11 @@ static void genesis_mac_init(struct skge_hw *hw, int port) } - r = skge_xm_read16(hw, port, XM_RX_CMD); + r = xm_read16(hw, port, XM_RX_CMD); if (hw->dev[port]->mtu > ETH_DATA_LEN) - skge_xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK); + xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK); else - skge_xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); + xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); switch (hw->phy_type) { case SK_PHY_XMAC: @@ -1198,7 +1198,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) break; } - skge_xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1); + xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1); ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG; } else { ctrl2 = 0; @@ -1206,7 +1206,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) ctrl2 |= PHY_CT_DUP_MD; } - skge_xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2); + xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2); break; case SK_PHY_BCOM: @@ -1253,27 +1253,27 @@ static void genesis_mac_init(struct skge_hw *hw, int port) ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ } - skge_xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); - skge_xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); + xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); + xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); if (skge->netdev->mtu > ETH_DATA_LEN) { ctrl4 |= PHY_B_PEC_HIGH_LA; ctrl5 |= PHY_B_AC_LONG_PACK; - skge_xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); + xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); } - skge_xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); - skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); break; } spin_unlock_bh(&hw->phy_lock); /* Clear MIB counters */ - skge_xm_write16(hw, port, XM_STAT_CMD, + xm_write16(hw, port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); /* Clear two times according to Errata #3 */ - skge_xm_write16(hw, port, XM_STAT_CMD, + xm_write16(hw, port, XM_STAT_CMD, XM_SC_CLR_RXC | XM_SC_CLR_TXC); /* Start polling for link status */ @@ -1293,12 +1293,12 @@ static void genesis_stop(struct skge_port *skge) * If the transfer stucks at the MAC the STOP command will not * terminate if we don't flush the XMAC's transmit FIFO ! */ - skge_xm_write32(hw, port, XM_MODE, - skge_xm_read32(hw, port, XM_MODE)|XM_MD_FTF); + xm_write32(hw, port, XM_MODE, + xm_read32(hw, port, XM_MODE)|XM_MD_FTF); /* Reset the MAC */ - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); /* For external PHYs there must be special handling */ if (hw->phy_type != SK_PHY_XMAC) { @@ -1315,11 +1315,11 @@ static void genesis_stop(struct skge_port *skge) skge_read32(hw, B2_GP_IO); } - skge_xm_write16(hw, port, XM_MMU_CMD, - skge_xm_read16(hw, port, XM_MMU_CMD) + xm_write16(hw, port, XM_MMU_CMD, + xm_read16(hw, port, XM_MMU_CMD) & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - skge_xm_read16(hw, port, XM_MMU_CMD); + xm_read16(hw, port, XM_MMU_CMD); } @@ -1330,11 +1330,11 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data) int i; unsigned long timeout = jiffies + HZ; - skge_xm_write16(hw, port, + xm_write16(hw, port, XM_STAT_CMD, XM_SC_SNP_TXC | XM_SC_SNP_RXC); /* wait for update to complete */ - while (skge_xm_read16(hw, port, XM_STAT_CMD) + while (xm_read16(hw, port, XM_STAT_CMD) & (XM_SC_SNP_TXC | XM_SC_SNP_RXC)) { if (time_after(jiffies, timeout)) break; @@ -1342,26 +1342,26 @@ static void genesis_get_stats(struct skge_port *skge, u64 *data) } /* special case for 64 bit octet counter */ - data[0] = (u64) skge_xm_read32(hw, port, XM_TXO_OK_HI) << 32 - | skge_xm_read32(hw, port, XM_TXO_OK_LO); - data[1] = (u64) skge_xm_read32(hw, port, XM_RXO_OK_HI) << 32 - | skge_xm_read32(hw, port, XM_RXO_OK_LO); + data[0] = (u64) xm_read32(hw, port, XM_TXO_OK_HI) << 32 + | xm_read32(hw, port, XM_TXO_OK_LO); + data[1] = (u64) xm_read32(hw, port, XM_RXO_OK_HI) << 32 + | xm_read32(hw, port, XM_RXO_OK_LO); for (i = 2; i < ARRAY_SIZE(skge_stats); i++) - data[i] = skge_xm_read32(hw, port, skge_stats[i].xmac_offset); + data[i] = xm_read32(hw, port, skge_stats[i].xmac_offset); } static void genesis_mac_intr(struct skge_hw *hw, int port) { struct skge_port *skge = netdev_priv(hw->dev[port]); - u16 status = skge_xm_read16(hw, port, XM_ISRC); + u16 status = xm_read16(hw, port, XM_ISRC); pr_debug("genesis_intr status %x\n", status); if (hw->phy_type == SK_PHY_XMAC) { /* LInk down, start polling for state change */ if (status & XM_IS_INP_ASS) { - skge_xm_write16(hw, port, XM_IMSK, - skge_xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS); + xm_write16(hw, port, XM_IMSK, + xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS); mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); } else if (status & XM_IS_AND) @@ -1369,41 +1369,41 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) } if (status & XM_IS_TXF_UR) { - skge_xm_write32(hw, port, XM_MODE, XM_MD_FTF); + xm_write32(hw, port, XM_MODE, XM_MD_FTF); ++skge->net_stats.tx_fifo_errors; } if (status & XM_IS_RXF_OV) { - skge_xm_write32(hw, port, XM_MODE, XM_MD_FRF); + xm_write32(hw, port, XM_MODE, XM_MD_FRF); ++skge->net_stats.rx_fifo_errors; } } -static void skge_gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) +static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) { int i; - skge_gma_write16(hw, port, GM_SMI_DATA, val); - skge_gma_write16(hw, port, GM_SMI_CTRL, + gma_write16(hw, port, GM_SMI_DATA, val); + gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg)); for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (!(skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) + if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY)) break; } } -static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg) +static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg) { int i; - skge_gma_write16(hw, port, GM_SMI_CTRL, + gma_write16(hw, port, GM_SMI_CTRL, GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD); for (i = 0; i < PHY_RETRIES; i++) { udelay(1); - if (skge_gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) + if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL) goto ready; } @@ -1411,7 +1411,7 @@ static u16 skge_gm_phy_read(struct skge_hw *hw, int port, u16 reg) hw->dev[port]->name); return 0; ready: - return skge_gma_read16(hw, port, GM_SMI_DATA); + return gma_read16(hw, port, GM_SMI_DATA); } static void genesis_link_down(struct skge_port *skge) @@ -1421,12 +1421,12 @@ static void genesis_link_down(struct skge_port *skge) pr_debug("genesis_link_down\n"); - skge_xm_write16(hw, port, XM_MMU_CMD, - skge_xm_read16(hw, port, XM_MMU_CMD) + xm_write16(hw, port, XM_MMU_CMD, + xm_read16(hw, port, XM_MMU_CMD) & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); /* dummy read to ensure writing */ - (void) skge_xm_read16(hw, port, XM_MMU_CMD); + (void) xm_read16(hw, port, XM_MMU_CMD); skge_link_down(skge); } @@ -1439,7 +1439,7 @@ static void genesis_link_up(struct skge_port *skge) u32 mode, msk; pr_debug("genesis_link_up\n"); - cmd = skge_xm_read16(hw, port, XM_MMU_CMD); + cmd = xm_read16(hw, port, XM_MMU_CMD); /* * enabling pause frame reception is required for 1000BT @@ -1452,9 +1452,9 @@ static void genesis_link_up(struct skge_port *skge) /* Enable Pause Frame Reception */ cmd &= ~XM_MMU_IGN_PF; - skge_xm_write16(hw, port, XM_MMU_CMD, cmd); + xm_write16(hw, port, XM_MMU_CMD, cmd); - mode = skge_xm_read32(hw, port, XM_MODE); + mode = xm_read32(hw, port, XM_MODE); if (skge->flow_control == FLOW_MODE_SYMMETRIC || skge->flow_control == FLOW_MODE_LOC_SEND) { /* @@ -1468,10 +1468,10 @@ static void genesis_link_up(struct skge_port *skge) /* XM_PAUSE_DA = '010000C28001' (default) */ /* XM_MAC_PTIME = 0xffff (maximum) */ /* remember this value is defined in big endian (!) */ - skge_xm_write16(hw, port, XM_MAC_PTIME, 0xffff); + xm_write16(hw, port, XM_MAC_PTIME, 0xffff); mode |= XM_PAUSE_MODE; - skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE); + skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_ENA_PAUSE); } else { /* * disable pause frame generation is required for 1000BT @@ -1480,20 +1480,20 @@ static void genesis_link_up(struct skge_port *skge) /* Disable Pause Mode in Mode Register */ mode &= ~XM_PAUSE_MODE; - skge_write16(hw, SKGEMAC_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE); + skge_write16(hw, SK_REG(port, RX_MFF_CTRL1), MFF_DIS_PAUSE); } - skge_xm_write32(hw, port, XM_MODE, mode); + xm_write32(hw, port, XM_MODE, mode); msk = XM_DEF_MSK; if (hw->phy_type != SK_PHY_XMAC) msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ - skge_xm_write16(hw, port, XM_IMSK, msk); - skge_xm_read16(hw, port, XM_ISRC); + xm_write16(hw, port, XM_IMSK, msk); + xm_read16(hw, port, XM_ISRC); /* get MMU Command Reg. */ - cmd = skge_xm_read16(hw, port, XM_MMU_CMD); + cmd = xm_read16(hw, port, XM_MMU_CMD); if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL) cmd |= XM_MMU_GMII_FD; @@ -1502,15 +1502,15 @@ static void genesis_link_up(struct skge_port *skge) * Workaround BCOM Errata (#10523) for all BCom Phys * Enable Power Management after link up */ - skge_xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, - skge_xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, + xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) & ~PHY_B_AC_DIS_PM); - skge_xm_phy_write(hw, port, PHY_BCOM_INT_MASK, + xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); } /* enable Rx/Tx */ - skge_xm_write16(hw, port, XM_MMU_CMD, + xm_write16(hw, port, XM_MMU_CMD, cmd | XM_MMU_ENA_RX | XM_MMU_ENA_TX); skge_link_up(skge); } @@ -1520,7 +1520,7 @@ static void genesis_bcom_intr(struct skge_port *skge) { struct skge_hw *hw = skge->hw; int port = skge->port; - u16 stat = skge_xm_phy_read(hw, port, PHY_BCOM_INT_STAT); + u16 stat = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); pr_debug("genesis_bcom intr stat=%x\n", stat); @@ -1528,16 +1528,16 @@ static void genesis_bcom_intr(struct skge_port *skge) * enable and disable loopback mode if "NO HCD" occurs. */ if (stat & PHY_B_IS_NO_HDCL) { - u16 ctrl = skge_xm_phy_read(hw, port, PHY_BCOM_CTRL); - skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, + u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL); + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl | PHY_CT_LOOP); - skge_xm_phy_write(hw, port, PHY_BCOM_CTRL, + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl & ~PHY_CT_LOOP); } - stat = skge_xm_phy_read(hw, port, PHY_BCOM_STAT); + stat = xm_phy_read(hw, port, PHY_BCOM_STAT); if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) { - u16 aux = skge_xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); + u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev)) genesis_link_down(skge); @@ -1590,7 +1590,7 @@ static void skge_link_timer(unsigned long __arg) else { int i; for (i = 0; i < 3; i++) - if (skge_xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) + if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) break; if (i == 3) @@ -1610,7 +1610,7 @@ static void yukon_init(struct skge_hw *hw, int port) pr_debug("yukon_init\n"); if (skge->autoneg == AUTONEG_ENABLE) { - u16 ectrl = skge_gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); + u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL); ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK | PHY_M_EC_MAC_S_MSK); @@ -1622,15 +1622,15 @@ static void yukon_init(struct skge_hw *hw, int port) else ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); - skge_gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); + gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); } - ctrl = skge_gm_phy_read(hw, port, PHY_MARV_CTRL); + ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL); if (skge->autoneg == AUTONEG_DISABLE) ctrl &= ~PHY_CT_ANE; ctrl |= PHY_CT_RESET; - skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); + gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); ctrl = 0; ct1000 = 0; @@ -1707,10 +1707,10 @@ static void yukon_init(struct skge_hw *hw, int port) } if (hw->chip_id != CHIP_ID_YUKON_FE) - skge_gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); + gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); - skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); - skge_gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); + gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); + gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); /* Setup Phy LED's */ ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); @@ -1720,8 +1720,8 @@ static void yukon_init(struct skge_hw *hw, int port) /* on 88E3082 these bits are at 11..9 (shifted left) */ ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1; - skge_gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, - ((skge_gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR) + gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, + ((gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR) & ~PHY_M_FELP_LED1_MSK) | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL))); @@ -1735,7 +1735,7 @@ static void yukon_init(struct skge_hw *hw, int port) /* disable blink mode (LED_DUPLEX) on collisions */ ctrl |= PHY_M_LEDC_DP_CTRL; - skge_gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); + gm_phy_write(hw, port, PHY_MARV_LED_CTRL, ledctrl); if (skge->autoneg == AUTONEG_DISABLE || skge->speed == SPEED_100) { /* turn on 100 Mbps LED (LED_LINK100) */ @@ -1743,25 +1743,25 @@ static void yukon_init(struct skge_hw *hw, int port) } if (ledover) - skge_gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); + gm_phy_write(hw, port, PHY_MARV_LED_OVER, ledover); /* Enable phy interrupt on autonegotiation complete (or link up) */ if (skge->autoneg == AUTONEG_ENABLE) - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_IS_AN_COMPL); else - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); } static void yukon_reset(struct skge_hw *hw, int port) { - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */ - skge_gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ - skge_gma_write16(hw, port, GM_MC_ADDR_H2, 0); - skge_gma_write16(hw, port, GM_MC_ADDR_H3, 0); - skge_gma_write16(hw, port, GM_MC_ADDR_H4, 0); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0);/* disable PHY IRQs */ + gma_write16(hw, port, GM_MC_ADDR_H1, 0); /* clear MC hash */ + gma_write16(hw, port, GM_MC_ADDR_H2, 0); + gma_write16(hw, port, GM_MC_ADDR_H3, 0); + gma_write16(hw, port, GM_MC_ADDR_H4, 0); - skge_gma_write16(hw, port, GM_RX_CTRL, - skge_gma_read16(hw, port, GM_RX_CTRL) + gma_write16(hw, port, GM_RX_CTRL, + gma_read16(hw, port, GM_RX_CTRL) | GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA); } @@ -1779,8 +1779,8 @@ static void yukon_mac_init(struct skge_hw *hw, int port) (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); /* hard reset */ - skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), GPC_RST_SET); - skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_RST_SET); + skge_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_RST_SET); /* WA code for COMA mode -- clear PHY reset */ if (hw->chip_id == CHIP_ID_YUKON_LITE && @@ -1795,13 +1795,13 @@ static void yukon_mac_init(struct skge_hw *hw, int port) reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; /* Clear GMC reset */ - skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_SET); - skge_write32(hw, SKGEMAC_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); - skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); + skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); + skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_CLR); + skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON | GMC_RST_CLR); if (skge->autoneg == AUTONEG_DISABLE) { reg = GM_GPCR_AU_ALL_DIS; - skge_gma_write16(hw, port, GM_GP_CTRL, - skge_gma_read16(hw, port, GM_GP_CTRL) | reg); + gma_write16(hw, port, GM_GP_CTRL, + gma_read16(hw, port, GM_GP_CTRL) | reg); switch (skge->speed) { case SPEED_1000: @@ -1817,7 +1817,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) reg = GM_GPCR_SPEED_1000 | GM_GPCR_SPEED_100 | GM_GPCR_DUP_FULL; switch (skge->flow_control) { case FLOW_MODE_NONE: - skge_write32(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); + skge_write32(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); reg |= GM_GPCR_FC_TX_DIS | GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; break; case FLOW_MODE_LOC_SEND: @@ -1825,7 +1825,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) reg |= GM_GPCR_FC_RX_DIS | GM_GPCR_AU_FCT_DIS; } - skge_gma_write16(hw, port, GM_GP_CTRL, reg); + gma_write16(hw, port, GM_GP_CTRL, reg); skge_read16(hw, GMAC_IRQ_SRC); spin_lock_bh(&hw->phy_lock); @@ -1833,25 +1833,25 @@ static void yukon_mac_init(struct skge_hw *hw, int port) spin_unlock_bh(&hw->phy_lock); /* MIB clear */ - reg = skge_gma_read16(hw, port, GM_PHY_ADDR); - skge_gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); + reg = gma_read16(hw, port, GM_PHY_ADDR); + gma_write16(hw, port, GM_PHY_ADDR, reg | GM_PAR_MIB_CLR); for (i = 0; i < GM_MIB_CNT_SIZE; i++) - skge_gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i); - skge_gma_write16(hw, port, GM_PHY_ADDR, reg); + gma_read16(hw, port, GM_MIB_CNT_BASE + 8*i); + gma_write16(hw, port, GM_PHY_ADDR, reg); /* transmit control */ - skge_gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF)); + gma_write16(hw, port, GM_TX_CTRL, TX_COL_THR(TX_COL_DEF)); /* receive control reg: unicast + multicast + no FCS */ - skge_gma_write16(hw, port, GM_RX_CTRL, + gma_write16(hw, port, GM_RX_CTRL, GM_RXCR_UCF_ENA | GM_RXCR_CRC_DIS | GM_RXCR_MCF_ENA); /* transmit flow control */ - skge_gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff); + gma_write16(hw, port, GM_TX_FLOW_CTRL, 0xffff); /* transmit parameter */ - skge_gma_write16(hw, port, GM_TX_PARAM, + gma_write16(hw, port, GM_TX_PARAM, TX_JAM_LEN_VAL(TX_JAM_LEN_DEF) | TX_JAM_IPG_VAL(TX_JAM_IPG_DEF) | TX_IPG_JAM_DATA(TX_IPG_JAM_DEF)); @@ -1861,33 +1861,33 @@ static void yukon_mac_init(struct skge_hw *hw, int port) if (hw->dev[port]->mtu > 1500) reg |= GM_SMOD_JUMBO_ENA; - skge_gma_write16(hw, port, GM_SERIAL_MODE, reg); + gma_write16(hw, port, GM_SERIAL_MODE, reg); /* physical address: used for pause frames */ - skge_gm_set_addr(hw, port, GM_SRC_ADDR_1L, addr); + gma_set_addr(hw, port, GM_SRC_ADDR_1L, addr); /* virtual address for data */ - skge_gm_set_addr(hw, port, GM_SRC_ADDR_2L, addr); + gma_set_addr(hw, port, GM_SRC_ADDR_2L, addr); /* enable interrupt mask for counter overflows */ - skge_gma_write16(hw, port, GM_TX_IRQ_MSK, 0); - skge_gma_write16(hw, port, GM_RX_IRQ_MSK, 0); - skge_gma_write16(hw, port, GM_TR_IRQ_MSK, 0); + gma_write16(hw, port, GM_TX_IRQ_MSK, 0); + gma_write16(hw, port, GM_RX_IRQ_MSK, 0); + gma_write16(hw, port, GM_TR_IRQ_MSK, 0); /* Initialize Mac Fifo */ /* Configure Rx MAC FIFO */ - skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); + skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); reg = GMF_OPER_ON | GMF_RX_F_FL_ON; if (hw->chip_id == CHIP_ID_YUKON_LITE && chip_rev(hw) == CHIP_REV_YU_LITE_A3) reg &= ~GMF_RX_F_FL_ON; - skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), reg); - skge_write16(hw, SKGEMAC_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); + skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); + skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); + skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); /* Configure Tx MAC FIFO */ - skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); - skge_write16(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); + skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); + skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON); } static void yukon_stop(struct skge_port *skge) @@ -1901,14 +1901,14 @@ static void yukon_stop(struct skge_port *skge) skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); } - skge_gma_write16(hw, port, GM_GP_CTRL, - skge_gma_read16(hw, port, GM_GP_CTRL) + gma_write16(hw, port, GM_GP_CTRL, + gma_read16(hw, port, GM_GP_CTRL) & ~(GM_GPCR_RX_ENA|GM_GPCR_RX_ENA)); - skge_gma_read16(hw, port, GM_GP_CTRL); + gma_read16(hw, port, GM_GP_CTRL); /* set GPHY Control reset */ - skge_gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); - skge_gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); + gma_write32(hw, port, GPHY_CTRL, GPC_RST_SET); + gma_write32(hw, port, GMAC_CTRL, GMC_RST_SET); } static void yukon_get_stats(struct skge_port *skge, u64 *data) @@ -1917,29 +1917,29 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data) int port = skge->port; int i; - data[0] = (u64) skge_gma_read32(hw, port, GM_TXO_OK_HI) << 32 - | skge_gma_read32(hw, port, GM_TXO_OK_LO); - data[1] = (u64) skge_gma_read32(hw, port, GM_RXO_OK_HI) << 32 - | skge_gma_read32(hw, port, GM_RXO_OK_LO); + data[0] = (u64) gma_read32(hw, port, GM_TXO_OK_HI) << 32 + | gma_read32(hw, port, GM_TXO_OK_LO); + data[1] = (u64) gma_read32(hw, port, GM_RXO_OK_HI) << 32 + | gma_read32(hw, port, GM_RXO_OK_LO); for (i = 2; i < ARRAY_SIZE(skge_stats); i++) - data[i] = skge_gma_read32(hw, port, + data[i] = gma_read32(hw, port, skge_stats[i].gma_offset); } static void yukon_mac_intr(struct skge_hw *hw, int port) { struct skge_port *skge = netdev_priv(hw->dev[port]); - u8 status = skge_read8(hw, SKGEMAC_REG(port, GMAC_IRQ_SRC)); + u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); pr_debug("yukon_intr status %x\n", status); if (status & GM_IS_RX_FF_OR) { ++skge->net_stats.rx_fifo_errors; - skge_gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); + gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); } if (status & GM_IS_TX_FF_UR) { ++skge->net_stats.tx_fifo_errors; - skge_gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); + gma_write8(hw, port, TX_GMF_CTRL_T, GMF_CLI_TX_FU); } } @@ -1970,15 +1970,15 @@ static void yukon_link_up(struct skge_port *skge) /* Enable Transmit FIFO Underrun */ skge_write8(hw, GMAC_IRQ_MSK, GMAC_DEF_MSK); - reg = skge_gma_read16(hw, port, GM_GP_CTRL); + reg = gma_read16(hw, port, GM_GP_CTRL); if (skge->duplex == DUPLEX_FULL || skge->autoneg == AUTONEG_ENABLE) reg |= GM_GPCR_DUP_FULL; /* enable Rx/Tx */ reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA; - skge_gma_write16(hw, port, GM_GP_CTRL, reg); + gma_write16(hw, port, GM_GP_CTRL, reg); - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); + gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK); skge_link_up(skge); } @@ -1988,16 +1988,16 @@ static void yukon_link_down(struct skge_port *skge) int port = skge->port; pr_debug("yukon_link_down\n"); - skge_gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); - skge_gm_phy_write(hw, port, GM_GP_CTRL, - skge_gm_phy_read(hw, port, GM_GP_CTRL) + gm_phy_write(hw, port, PHY_MARV_INT_MASK, 0); + gm_phy_write(hw, port, GM_GP_CTRL, + gm_phy_read(hw, port, GM_GP_CTRL) & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); if (hw->chip_id != CHIP_ID_YUKON_FE && skge->flow_control == FLOW_MODE_REM_SEND) { /* restore Asymmetric Pause bit */ - skge_gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, - skge_gm_phy_read(hw, port, + gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, + gm_phy_read(hw, port, PHY_MARV_AUNE_ADV) | PHY_M_AN_ASP); @@ -2016,19 +2016,19 @@ static void yukon_phy_intr(struct skge_port *skge) const char *reason = NULL; u16 istatus, phystat; - istatus = skge_gm_phy_read(hw, port, PHY_MARV_INT_STAT); - phystat = skge_gm_phy_read(hw, port, PHY_MARV_PHY_STAT); + istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); + phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat); if (istatus & PHY_M_IS_AN_COMPL) { - if (skge_gm_phy_read(hw, port, PHY_MARV_AUNE_LP) + if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP) & PHY_M_AN_RF) { reason = "remote fault"; goto failed; } if (!(hw->chip_id == CHIP_ID_YUKON_FE || hw->chip_id == CHIP_ID_YUKON_EC) - && (skge_gm_phy_read(hw, port, PHY_MARV_1000T_STAT) + && (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF)) { reason = "master/slave fault"; goto failed; @@ -2064,9 +2064,9 @@ static void yukon_phy_intr(struct skge_port *skge) if (skge->flow_control == FLOW_MODE_NONE || (skge->speed < SPEED_1000 && skge->duplex == DUPLEX_HALF)) - skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); + skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF); else - skge_write8(hw, SKGEMAC_REG(port, GMAC_CTRL), GMC_PAUSE_ON); + skge_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON); yukon_link_up(skge); return; } @@ -2229,12 +2229,12 @@ static int skge_down(struct net_device *dev) yukon_stop(skge); /* Disable Force Sync bit and Enable Alloc bit */ - skge_write8(hw, SKGEMAC_REG(port, TXA_CTRL), + skge_write8(hw, SK_REG(port, TXA_CTRL), TXA_DIS_FSYNC | TXA_DIS_ALLOC | TXA_STOP_RC); /* Stop Interval Timer and Limit Counter of Tx Arbiter */ - skge_write32(hw, SKGEMAC_REG(port, TXA_ITI_INI), 0L); - skge_write32(hw, SKGEMAC_REG(port, TXA_LIM_INI), 0L); + skge_write32(hw, SK_REG(port, TXA_ITI_INI), 0L); + skge_write32(hw, SK_REG(port, TXA_LIM_INI), 0L); /* Reset PCI FIFO */ skge_write32(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_SET_RESET); @@ -2249,13 +2249,13 @@ static int skge_down(struct net_device *dev) skge_write32(hw, Q_ADDR(rxqaddr[port], Q_CSR), CSR_SET_RESET); if (hw->chip_id == CHIP_ID_GENESIS) { - skge_write8(hw, SKGEMAC_REG(port, TX_MFF_CTRL2), MFF_RST_SET); - skge_write8(hw, SKGEMAC_REG(port, RX_MFF_CTRL2), MFF_RST_SET); - skge_write8(hw, SKGEMAC_REG(port, TX_LED_CTRL), LED_STOP); - skge_write8(hw, SKGEMAC_REG(port, RX_LED_CTRL), LED_STOP); + skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_RST_SET); + skge_write8(hw, SK_REG(port, RX_MFF_CTRL2), MFF_RST_SET); + skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_STOP); + skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_STOP); } else { - skge_write8(hw, SKGEMAC_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); - skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); + skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET); + skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET); } /* turn off led's */ @@ -2451,7 +2451,7 @@ static void genesis_set_multicast(struct net_device *dev) u32 mode; u8 filter[8]; - mode = skge_xm_read32(hw, port, XM_MODE); + mode = xm_read32(hw, port, XM_MODE); mode |= XM_MD_ENA_HASH; if (dev->flags & IFF_PROMISC) mode |= XM_MD_ENA_PROM; @@ -2470,9 +2470,9 @@ static void genesis_set_multicast(struct net_device *dev) } } - skge_xm_outhash(hw, port, XM_HSM, filter); + xm_outhash(hw, port, XM_HSM, filter); - skge_xm_write32(hw, port, XM_MODE, mode); + xm_write32(hw, port, XM_MODE, mode); } static void yukon_set_multicast(struct net_device *dev) @@ -2486,7 +2486,7 @@ static void yukon_set_multicast(struct net_device *dev) memset(filter, 0, sizeof(filter)); - reg = skge_gma_read16(hw, port, GM_RX_CTRL); + reg = gma_read16(hw, port, GM_RX_CTRL); reg |= GM_RXCR_UCF_ENA; if (dev->flags & IFF_PROMISC) /* promiscious */ @@ -2506,16 +2506,16 @@ static void yukon_set_multicast(struct net_device *dev) } - skge_gma_write16(hw, port, GM_MC_ADDR_H1, + gma_write16(hw, port, GM_MC_ADDR_H1, (u16)filter[0] | ((u16)filter[1] << 8)); - skge_gma_write16(hw, port, GM_MC_ADDR_H2, + gma_write16(hw, port, GM_MC_ADDR_H2, (u16)filter[2] | ((u16)filter[3] << 8)); - skge_gma_write16(hw, port, GM_MC_ADDR_H3, + gma_write16(hw, port, GM_MC_ADDR_H3, (u16)filter[4] | ((u16)filter[5] << 8)); - skge_gma_write16(hw, port, GM_MC_ADDR_H4, + gma_write16(hw, port, GM_MC_ADDR_H4, (u16)filter[6] | ((u16)filter[7] << 8)); - skge_gma_write16(hw, port, GM_RX_CTRL, reg); + gma_write16(hw, port, GM_RX_CTRL, reg); } static inline int bad_phy_status(const struct skge_hw *hw, u32 status) @@ -2679,11 +2679,11 @@ static void skge_mac_parity(struct skge_hw *hw, int port) : (port == 0 ? "(port A)": "(port B")); if (hw->chip_id == CHIP_ID_GENESIS) - skge_write16(hw, SKGEMAC_REG(port, TX_MFF_CTRL1), + skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_CLR_PERR); else /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ - skge_write8(hw, SKGEMAC_REG(port, TX_GMF_CTRL_T), + skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); } @@ -2715,9 +2715,9 @@ static void skge_error_irq(struct skge_hw *hw) if (hw->chip_id == CHIP_ID_GENESIS) { /* clear xmac errors */ if (hwstatus & (IS_NO_STAT_M1|IS_NO_TIST_M1)) - skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); + skge_write16(hw, SK_REG(0, RX_MFF_CTRL1), MFF_CLR_INSTAT); if (hwstatus & (IS_NO_STAT_M2|IS_NO_TIST_M2)) - skge_write16(hw, SKGEMAC_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); + skge_write16(hw, SK_REG(0, RX_MFF_CTRL2), MFF_CLR_INSTAT); } else { /* Timestamp (unused) overflow */ if (hwstatus & IS_IRQ_TIST_OV) @@ -3000,8 +3000,8 @@ static int skge_reset(struct skge_hw *hw) skge_write8(hw, B0_POWER_CTRL, PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); for (i = 0; i < ports; i++) { - skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); - skge_write16(hw, SKGEMAC_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); + skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); + skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); } } @@ -3012,7 +3012,7 @@ static int skge_reset(struct skge_hw *hw) /* enable the Tx Arbiters */ for (i = 0; i < ports; i++) - skge_write8(hw, SKGEMAC_REG(i, TXA_CTRL), TXA_ENA_ARB); + skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB); /* Initialize ram interface */ skge_write16(hw, B3_RI_CTRL, RI_RST_CLR); diff --git a/drivers/net/skge.h b/drivers/net/skge.h index aad3aec..2669b80 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -488,7 +488,7 @@ enum { PA_ENA_TO_TX1 | PA_ENA_TO_TX2) -/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ +/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */ /* TXA_ITI_INI 32 bit Tx Arb Interval Timer Init Val */ /* TXA_ITI_VAL 32 bit Tx Arb Interval Timer Value */ /* TXA_LIM_INI 32 bit Tx Arb Limit Counter Init Val */ @@ -511,7 +511,7 @@ enum { /* * Bank 4 - 5 */ -/* Transmit Arbiter Registers MAC 1 and 2, use MR_ADDR() to access */ +/* Transmit Arbiter Registers MAC 1 and 2, use SK_REG() to access */ enum { TXA_ITI_INI = 0x0200,/* 32 bit Tx Arb Interval Timer Init Val*/ TXA_ITI_VAL = 0x0204,/* 32 bit Tx Arb Interval Timer Value */ @@ -2892,114 +2892,87 @@ static inline void skge_write8(const struct skge_hw *hw, int reg, u8 val) } /* MAC Related Registers inside the device. */ -#define SKGEMAC_REG(port,reg) (((port)<<7)+(reg)) - -/* PCI config space can be accessed via memory mapped space */ -#define SKGEPCI_REG(reg) ((reg)+ 0x380) - -#define SKGEXM_REG(port, reg) \ +#define SK_REG(port,reg) (((port)<<7)+(reg)) +#define SK_XMAC_REG(port, reg) \ ((BASE_XMAC_1 + (port) * (BASE_XMAC_2 - BASE_XMAC_1)) | (reg) << 1) -static inline u32 skge_xm_read32(const struct skge_hw *hw, int port, int reg) -{ - return skge_read32(hw, SKGEXM_REG(port,reg)); -} - -static inline u16 skge_xm_read16(const struct skge_hw *hw, int port, int reg) -{ - return skge_read16(hw, SKGEXM_REG(port,reg)); -} - -static inline u8 skge_xm_read8(const struct skge_hw *hw, int port, int reg) +static inline u32 xm_read32(const struct skge_hw *hw, int port, int reg) { - return skge_read8(hw, SKGEXM_REG(port,reg)); + u32 v; + v = skge_read16(hw, SK_XMAC_REG(port, reg)); + v |= (u32)skge_read16(hw, SK_XMAC_REG(port, reg+2)) << 16; + return v; } -static inline void skge_xm_write32(const struct skge_hw *hw, int port, int r, u32 v) +static inline u16 xm_read16(const struct skge_hw *hw, int port, int reg) { - skge_write32(hw, SKGEXM_REG(port,r), v); + return skge_read16(hw, SK_XMAC_REG(port,reg)); } -static inline void skge_xm_write16(const struct skge_hw *hw, int port, int r, u16 v) +static inline void xm_write32(const struct skge_hw *hw, int port, int r, u32 v) { - skge_write16(hw, SKGEXM_REG(port,r), v); + skge_write16(hw, SK_XMAC_REG(port,r), v & 0xffff); + skge_write16(hw, SK_XMAC_REG(port,r+2), v >> 16); } -static inline void skge_xm_write8(const struct skge_hw *hw, int port, int r, u8 v) +static inline void xm_write16(const struct skge_hw *hw, int port, int r, u16 v) { - skge_write8(hw, SKGEXM_REG(port,r), v); + skge_write16(hw, SK_XMAC_REG(port,r), v); } -static inline void skge_xm_outhash(const struct skge_hw *hw, int port, int reg, +static inline void xm_outhash(const struct skge_hw *hw, int port, int reg, const u8 *hash) { - skge_xm_write16(hw, port, reg, - (u16)hash[0] | ((u16)hash[1] << 8)); - skge_xm_write16(hw, port, reg+2, - (u16)hash[2] | ((u16)hash[3] << 8)); - skge_xm_write16(hw, port, reg+4, - (u16)hash[4] | ((u16)hash[5] << 8)); - skge_xm_write16(hw, port, reg+6, - (u16)hash[6] | ((u16)hash[7] << 8)); + xm_write16(hw, port, reg, (u16)hash[0] | ((u16)hash[1] << 8)); + xm_write16(hw, port, reg+2, (u16)hash[2] | ((u16)hash[3] << 8)); + xm_write16(hw, port, reg+4, (u16)hash[4] | ((u16)hash[5] << 8)); + xm_write16(hw, port, reg+6, (u16)hash[6] | ((u16)hash[7] << 8)); } -static inline void skge_xm_outaddr(const struct skge_hw *hw, int port, int reg, +static inline void xm_outaddr(const struct skge_hw *hw, int port, int reg, const u8 *addr) { - skge_xm_write16(hw, port, reg, - (u16)addr[0] | ((u16)addr[1] << 8)); - skge_xm_write16(hw, port, reg, - (u16)addr[2] | ((u16)addr[3] << 8)); - skge_xm_write16(hw, port, reg, - (u16)addr[4] | ((u16)addr[5] << 8)); + xm_write16(hw, port, reg, (u16)addr[0] | ((u16)addr[1] << 8)); + xm_write16(hw, port, reg+2, (u16)addr[2] | ((u16)addr[3] << 8)); + xm_write16(hw, port, reg+4, (u16)addr[4] | ((u16)addr[5] << 8)); } +#define SK_GMAC_REG(port,reg) \ + (BASE_GMAC_1 + (port) * (BASE_GMAC_2-BASE_GMAC_1) + (reg)) -#define SKGEGMA_REG(port,reg) \ - ((reg) + BASE_GMAC_1 + \ - (port) * (BASE_GMAC_2-BASE_GMAC_1)) - -static inline u16 skge_gma_read16(const struct skge_hw *hw, int port, int reg) -{ - return skge_read16(hw, SKGEGMA_REG(port,reg)); -} - -static inline u32 skge_gma_read32(const struct skge_hw *hw, int port, int reg) +static inline u16 gma_read16(const struct skge_hw *hw, int port, int reg) { - return (u32) skge_read16(hw, SKGEGMA_REG(port,reg)) - | ((u32)skge_read16(hw, SKGEGMA_REG(port,reg+4)) << 16); + return skge_read16(hw, SK_GMAC_REG(port,reg)); } -static inline u8 skge_gma_read8(const struct skge_hw *hw, int port, int reg) +static inline u32 gma_read32(const struct skge_hw *hw, int port, int reg) { - return skge_read8(hw, SKGEGMA_REG(port,reg)); + return (u32) skge_read16(hw, SK_GMAC_REG(port,reg)) + | ((u32)skge_read16(hw, SK_GMAC_REG(port,reg+4)) << 16); } -static inline void skge_gma_write16(const struct skge_hw *hw, int port, int r, u16 v) +static inline void gma_write16(const struct skge_hw *hw, int port, int r, u16 v) { - skge_write16(hw, SKGEGMA_REG(port,r), v); + skge_write16(hw, SK_GMAC_REG(port,r), v); } -static inline void skge_gma_write32(const struct skge_hw *hw, int port, int r, u32 v) +static inline void gma_write32(const struct skge_hw *hw, int port, int r, u32 v) { - skge_write16(hw, SKGEGMA_REG(port, r), (u16) v); - skge_write32(hw, SKGEGMA_REG(port, r+4), (u16)(v >> 16)); + skge_write16(hw, SK_GMAC_REG(port, r), (u16) v); + skge_write32(hw, SK_GMAC_REG(port, r+4), (u16)(v >> 16)); } -static inline void skge_gma_write8(const struct skge_hw *hw, int port, int r, u8 v) +static inline void gma_write8(const struct skge_hw *hw, int port, int r, u8 v) { - skge_write8(hw, SKGEGMA_REG(port,r), v); + skge_write8(hw, SK_GMAC_REG(port,r), v); } -static inline void skge_gm_set_addr(struct skge_hw *hw, int port, int reg, +static inline void gma_set_addr(struct skge_hw *hw, int port, int reg, const u8 *addr) { - skge_gma_write16(hw, port, reg, - (u16) addr[0] | ((u16) addr[1] << 8)); - skge_gma_write16(hw, port, reg+4, - (u16) addr[2] | ((u16) addr[3] << 8)); - skge_gma_write16(hw, port, reg+8, - (u16) addr[4] | ((u16) addr[5] << 8)); + gma_write16(hw, port, reg, (u16) addr[0] | ((u16) addr[1] << 8)); + gma_write16(hw, port, reg+4,(u16) addr[2] | ((u16) addr[3] << 8)); + gma_write16(hw, port, reg+8,(u16) addr[4] | ((u16) addr[5] << 8)); } #endif -- cgit v1.1 From 467b3417f9985b9a83ccebef2d4e07e3e8a9495e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:05 -0700 Subject: [PATCH] skge: use pci_read_config_word Rather than accessing PCI config space through MMIO space, use the standard PCI functions. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 210029a73..9924103 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2692,10 +2692,10 @@ static void skge_pci_clear(struct skge_hw *hw) { u16 status; - status = skge_read16(hw, SKGEPCI_REG(PCI_STATUS)); + pci_read_config_word(hw->pdev, PCI_STATUS, &status); skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON); - skge_write16(hw, SKGEPCI_REG(PCI_STATUS), - status | PCI_STATUS_ERROR_BITS); + pci_write_config_word(hw->pdev, PCI_STATUS, + status | PCI_STATUS_ERROR_BITS); skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF); } -- cgit v1.1 From 981d0377d94f4d611f1c73429c0c32b35b56855f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:06 -0700 Subject: [PATCH] skge: replace chip_rev() accessor Replace inline accessor functions for chip revision and number of ports with simple structure members. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 50 ++++++++++++++++++++++++-------------------------- drivers/net/skge.h | 12 ++---------- 2 files changed, 26 insertions(+), 36 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 9924103..deff38e 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -143,7 +143,7 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, static int wol_supported(const struct skge_hw *hw) { return !((hw->chip_id == CHIP_ID_GENESIS || - (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0))); + (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0))); } static void skge_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) @@ -1774,7 +1774,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) /* WA code for COMA mode -- set PHY reset */ if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) + hw->chip_rev == CHIP_REV_YU_LITE_A3) skge_write32(hw, B2_GP_IO, (skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9)); @@ -1784,7 +1784,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) /* WA code for COMA mode -- clear PHY reset */ if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) + hw->chip_rev == CHIP_REV_YU_LITE_A3) skge_write32(hw, B2_GP_IO, (skge_read32(hw, B2_GP_IO) | GP_DIR_9) & ~GP_IO_9); @@ -1879,7 +1879,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) skge_write16(hw, SK_REG(port, RX_GMF_FL_MSK), RX_FF_FL_DEF_MSK); reg = GMF_OPER_ON | GMF_RX_F_FL_ON; if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) + hw->chip_rev == CHIP_REV_YU_LITE_A3) reg &= ~GMF_RX_F_FL_ON; skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); @@ -1896,7 +1896,7 @@ static void yukon_stop(struct skge_port *skge) int port = skge->port; if (hw->chip_id == CHIP_ID_YUKON_LITE && - chip_rev(hw) == CHIP_REV_YU_LITE_A3) { + hw->chip_rev == CHIP_REV_YU_LITE_A3) { skge_write32(hw, B2_GP_IO, skge_read32(hw, B2_GP_IO) | GP_DIR_9 | GP_IO_9); } @@ -2178,7 +2178,7 @@ static int skge_up(struct net_device *dev) yukon_mac_init(hw, port); /* Configure RAMbuffers */ - chunk = hw->ram_size / (isdualport(hw) ? 4 : 2); + chunk = hw->ram_size / ((hw->ports + 1)*2); ram_addr = hw->ram_offset + 2 * chunk * port; skge_ramset(hw, rxqaddr[port], ram_addr, chunk); @@ -2322,7 +2322,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) * does. Looks like hardware is wrong? */ if (ip->protocol == IPPROTO_UDP - && chip_rev(hw) == 0 && hw->chip_id == CHIP_ID_YUKON) + && hw->chip_rev == 0 && hw->chip_id == CHIP_ID_YUKON) control = BMU_TCP_CHECK; else control = BMU_UDP_CHECK; @@ -2684,7 +2684,7 @@ static void skge_mac_parity(struct skge_hw *hw, int port) else /* HW-Bug #8: cleared by GMF_CLI_TX_FC instead of GMF_CLI_TX_PE */ skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), - (hw->chip_id == CHIP_ID_YUKON && chip_rev(hw) == 0) + (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) ? GMF_CLI_TX_FC : GMF_CLI_TX_PE); } @@ -2919,8 +2919,8 @@ static const char *skge_board_name(const struct skge_hw *hw) static int skge_reset(struct skge_hw *hw) { u16 ctst; - u8 t8; - int i, ports; + u8 t8, mac_cfg; + int i; ctst = skge_read16(hw, B0_CTST); @@ -2975,8 +2975,9 @@ static int skge_reset(struct skge_hw *hw) return -EOPNOTSUPP; } - hw->mac_cfg = skge_read8(hw, B2_MAC_CFG); - ports = isdualport(hw) ? 2 : 1; + mac_cfg = skge_read8(hw, B2_MAC_CFG); + hw->ports = (mac_cfg & CFG_SNG_MAC) ? 1 : 2; + hw->chip_rev = (mac_cfg & CFG_CHIP_R_MSK) >> 4; /* read the adapters RAM size */ t8 = skge_read8(hw, B2_E_0); @@ -2999,7 +3000,7 @@ static int skge_reset(struct skge_hw *hw) /* switch power to VCC (WA for VAUX problem) */ skge_write8(hw, B0_POWER_CTRL, PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); - for (i = 0; i < ports; i++) { + for (i = 0; i < hw->ports; i++) { skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); } @@ -3011,7 +3012,7 @@ static int skge_reset(struct skge_hw *hw) skge_write8(hw, B0_LED, LED_STAT_ON); /* enable the Tx Arbiters */ - for (i = 0; i < ports; i++) + for (i = 0; i < hw->ports; i++) skge_write8(hw, SK_REG(i, TXA_CTRL), TXA_ENA_ARB); /* Initialize ram interface */ @@ -3040,7 +3041,7 @@ static int skge_reset(struct skge_hw *hw) skge_write32(hw, B2_IRQM_CTRL, TIM_START); hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; - if (isdualport(hw)) + if (hw->ports > 1) hw->intr_mask |= IS_PORT_2; skge_write32(hw, B0_IMSK, hw->intr_mask); @@ -3048,7 +3049,7 @@ static int skge_reset(struct skge_hw *hw) skge_write8(hw, GMAC_IRQ_MSK, 0); spin_lock_bh(&hw->phy_lock); - for (i = 0; i < ports; i++) { + for (i = 0; i < hw->ports; i++) { if (hw->chip_id == CHIP_ID_GENESIS) genesis_reset(hw, i); else @@ -3060,7 +3061,8 @@ static int skge_reset(struct skge_hw *hw) } /* Initialize network device */ -static struct net_device *skge_devinit(struct skge_hw *hw, int port) +static struct net_device *skge_devinit(struct skge_hw *hw, int port, + int highmem) { struct skge_port *skge; struct net_device *dev = alloc_etherdev(sizeof(*skge)); @@ -3093,6 +3095,8 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port) #endif dev->irq = hw->pdev->irq; dev->features = NETIF_F_LLTX; + if (highmem) + dev->features |= NETIF_F_HIGHDMA; skge = netdev_priv(dev); skge->netdev = dev; @@ -3221,14 +3225,11 @@ static int __devinit skge_probe(struct pci_dev *pdev, printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n", pci_resource_start(pdev, 0), pdev->irq, - skge_board_name(hw), chip_rev(hw)); + skge_board_name(hw), hw->chip_rev); - if ((dev = skge_devinit(hw, 0)) == NULL) + if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) goto err_out_led_off; - if (using_dac) - dev->features |= NETIF_F_HIGHDMA; - if ((err = register_netdev(dev))) { printk(KERN_ERR PFX "%s: cannot register net device\n", pci_name(pdev)); @@ -3237,10 +3238,7 @@ static int __devinit skge_probe(struct pci_dev *pdev, skge_show_addr(dev); - if (isdualport(hw) && (dev1 = skge_devinit(hw, 1))) { - if (using_dac) - dev1->features |= NETIF_F_HIGHDMA; - + if (hw->ports > 1 && (dev1 = skge_devinit(hw, 1, using_dac))) { if (register_netdev(dev1) == 0) skge_show_addr(dev1); else { diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 2669b80..e57a535 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -2793,11 +2793,12 @@ struct skge_hw { u32 intr_mask; struct net_device *dev[2]; - u8 mac_cfg; u8 chip_id; + u8 chip_rev; u8 phy_type; u8 pmd_type; u16 phy_addr; + u8 ports; u32 ram_size; u32 ram_offset; @@ -2806,15 +2807,6 @@ struct skge_hw { spinlock_t phy_lock; }; -static inline int isdualport(const struct skge_hw *hw) -{ - return !(hw->mac_cfg & CFG_SNG_MAC); -} - -static inline u8 chip_rev(const struct skge_hw *hw) -{ - return (hw->mac_cfg & CFG_CHIP_R_MSK) >> 4; -} static inline int iscopper(const struct skge_hw *hw) { -- cgit v1.1 From 4707953454677f985289b4e4bcbea41f0cc651c2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:07 -0700 Subject: [PATCH] skge: eliminate Yukon2 hooks The Yukon chips don't support TSO, and Yukon2 will be a separate driver. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index deff38e..7be569d 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -500,14 +500,6 @@ static int skge_set_rx_csum(struct net_device *dev, u32 data) return 0; } -/* Only Yukon II supports TSO (not implemented yet) */ -static int skge_set_tso(struct net_device *dev, u32 data) -{ - if (data) - return -EOPNOTSUPP; - return 0; -} - static void skge_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *ecmd) { @@ -752,8 +744,6 @@ static struct ethtool_ops skge_ethtool_ops = { .set_pauseparam = skge_set_pauseparam, .get_coalesce = skge_get_coalesce, .set_coalesce = skge_set_coalesce, - .get_tso = ethtool_op_get_tso, - .set_tso = skge_set_tso, .get_sg = ethtool_op_get_sg, .set_sg = skge_set_sg, .get_tx_csum = ethtool_op_get_tx_csum, -- cgit v1.1 From b18f2091bc9f93548ea63752278fceaeacedab20 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:08 -0700 Subject: [PATCH] skge: remove unused declarations Get rid of definitions for chip versions and PHY chips that this driver does not support. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 12 +- drivers/net/skge.h | 402 +++-------------------------------------------------- 2 files changed, 24 insertions(+), 390 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 7be569d..8fd7981 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -636,10 +636,6 @@ static void skge_led_on(struct skge_hw *hw, int port) xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); break; - case SK_PHY_LONE: - xm_phy_write(hw, port, PHY_LONE_LED_CFG, - 0x0800); - break; default: skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON); skge_write32(hw, SK_REG(port, TX_LED_VAL), 100); @@ -670,10 +666,6 @@ static void skge_led_off(struct skge_hw *hw, int port) xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); break; - case SK_PHY_LONE: - xm_phy_write(hw, port, PHY_LONE_LED_CFG, - PHY_L_LC_LEDT); - break; default: skge_write32(hw, SK_REG(port, TX_LED_VAL), 0); skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF); @@ -1202,7 +1194,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) case SK_PHY_BCOM: ctrl1 = PHY_CT_SP1000; ctrl2 = 0; - ctrl3 = PHY_SEL_TYPE; + ctrl3 = PHY_AN_CSMA; ctrl4 = PHY_B_PEC_EN_LTR; ctrl5 = PHY_B_AC_TX_TST; @@ -1624,7 +1616,7 @@ static void yukon_init(struct skge_hw *hw, int port) ctrl = 0; ct1000 = 0; - adv = PHY_SEL_TYPE; + adv = PHY_AN_CSMA; if (skge->autoneg == AUTONEG_ENABLE) { if (iscopper(hw)) { diff --git a/drivers/net/skge.h b/drivers/net/skge.h index e57a535..6f3a4b5 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -7,31 +7,6 @@ /* PCI config registers */ #define PCI_DEV_REG1 0x40 #define PCI_DEV_REG2 0x44 -#ifndef PCI_VPD -#define PCI_VPD 0x50 -#endif - -/* PCI_OUR_REG_2 32 bit Our Register 2 */ -enum { - PCI_VPD_WR_THR = 0xff<<24, /* Bit 31..24: VPD Write Threshold */ - PCI_DEV_SEL = 0x7f<<17, /* Bit 23..17: EEPROM Device Select */ - PCI_VPD_ROM_SZ = 7 <<14, /* Bit 16..14: VPD ROM Size */ - /* Bit 13..12: reserved */ - PCI_EN_DUMMY_RD = 1<<3, /* Enable Dummy Read */ - PCI_REV_DESC = 1<<2, /* Reverse Desc. Bytes */ - PCI_USEDATA64 = 1<<0, /* Use 64Bit Data bus ext */ -}; - -/* PCI_VPD_ADR_REG 16 bit VPD Address Register */ -enum { - PCI_VPD_FLAG = 1<<15, /* starts VPD rd/wr cycle */ - PCI_VPD_ADR_MSK =0x7fffL, /* Bit 14.. 0: VPD Address Mask */ - VPD_RES_ID = 0x82, - VPD_RES_READ = 0x90, - VPD_RES_WRITE = 0x81, - VPD_RES_END = 0x78, -}; - #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ PCI_STATUS_SIG_SYSTEM_ERROR | \ @@ -39,7 +14,6 @@ enum { PCI_STATUS_REC_TARGET_ABORT | \ PCI_STATUS_PARITY) - enum csr_regs { B0_RAP = 0x0000, B0_CTST = 0x0004, @@ -288,14 +262,6 @@ enum { CHIP_REV_YU_LITE_A3 = 7, /* Chip Rev. for YUKON-Lite A3 */ }; -/* B2_LD_TEST 8 bit EPROM loader test register */ -enum { - LD_T_ON = 1<<3, /* Loader Test mode on */ - LD_T_OFF = 1<<2, /* Loader Test mode off */ - LD_T_STEP = 1<<1, /* Decrement FPROM addr. Counter */ - LD_START = 1<<0, /* Start loading FPROM */ -}; - /* B2_TI_CTRL 8 bit Timer control */ /* B2_IRQM_CTRL 8 bit IRQ Moderation Timer Control */ enum { @@ -313,16 +279,6 @@ enum { TIM_T_STEP = 1<<0, /* Test step */ }; -/* B28_DPT_INI 32 bit Descriptor Poll Timer Init Val */ -/* B28_DPT_VAL 32 bit Descriptor Poll Timer Curr Val */ -/* B28_DPT_CTRL 8 bit Descriptor Poll Timer Ctrl Reg */ -enum { - DPT_MSK = 0x00ffffffL, /* Bit 23.. 0: Desc Poll Timer Bits */ - - DPT_START = 1<<1, /* Start Descriptor Poll Timer */ - DPT_STOP = 1<<0, /* Stop Descriptor Poll Timer */ -}; - /* B2_GP_IO 32 bit General Purpose I/O Register */ enum { GP_DIR_9 = 1<<25, /* IO_9 direct, 0=In/1=Out */ @@ -348,30 +304,6 @@ enum { GP_IO_0 = 1<<0, /* IO_0 pin */ }; -/* Rx/Tx Path related Arbiter Test Registers */ -/* B3_MA_TO_TEST 16 bit MAC Arbiter Timeout Test Reg */ -/* B3_MA_RC_TEST 16 bit MAC Arbiter Recovery Test Reg */ -/* B3_PA_TEST 16 bit Packet Arbiter Test Register */ -/* Bit 15, 11, 7, and 3 are reserved in B3_PA_TEST */ -enum { - TX2_T_EV = 1<<15,/* TX2 Timeout/Recv Event occured */ - TX2_T_ON = 1<<14,/* TX2 Timeout/Recv Timer Test On */ - TX2_T_OFF = 1<<13,/* TX2 Timeout/Recv Timer Tst Off */ - TX2_T_STEP = 1<<12,/* TX2 Timeout/Recv Timer Step */ - TX1_T_EV = 1<<11,/* TX1 Timeout/Recv Event occured */ - TX1_T_ON = 1<<10,/* TX1 Timeout/Recv Timer Test On */ - TX1_T_OFF = 1<<9, /* TX1 Timeout/Recv Timer Tst Off */ - TX1_T_STEP = 1<<8, /* TX1 Timeout/Recv Timer Step */ - RX2_T_EV = 1<<7, /* RX2 Timeout/Recv Event occured */ - RX2_T_ON = 1<<6, /* RX2 Timeout/Recv Timer Test On */ - RX2_T_OFF = 1<<5, /* RX2 Timeout/Recv Timer Tst Off */ - RX2_T_STEP = 1<<4, /* RX2 Timeout/Recv Timer Step */ - RX1_T_EV = 1<<3, /* RX1 Timeout/Recv Event occured */ - RX1_T_ON = 1<<2, /* RX1 Timeout/Recv Timer Test On */ - RX1_T_OFF = 1<<1, /* RX1 Timeout/Recv Timer Tst Off */ - RX1_T_STEP = 1<<0, /* RX1 Timeout/Recv Timer Step */ -}; - /* Descriptor Bit Definition */ /* TxCtrl Transmit Buffer Control Field */ /* RxCtrl Receive Buffer Control Field */ @@ -428,14 +360,6 @@ enum { RI_RST_SET = 1<<0, /* Set RAM Interface Reset */ }; -/* B3_RI_TEST 8 bit RAM Iface Test Register */ -enum { - RI_T_EV = 1<<3, /* Timeout Event occured */ - RI_T_ON = 1<<2, /* Timeout Timer Test On */ - RI_T_OFF = 1<<1, /* Timeout Timer Test Off */ - RI_T_STEP = 1<<0, /* Timeout Timer Step */ -}; - /* MAC Arbiter Registers */ /* B3_MA_TO_CTRL 16 bit MAC Arbiter Timeout Ctrl Reg */ enum { @@ -452,19 +376,6 @@ enum { #define SK_PKT_TO_MAX 0xffff /* Maximum value */ #define SK_RI_TO_53 36 /* RAM interface timeout */ - -/* B3_MA_RC_CTRL 16 bit MAC Arbiter Recovery Ctrl Reg */ -enum { - MA_ENA_REC_TX2 = 1<<7, /* Enable Recovery Timer TX2 */ - MA_DIS_REC_TX2 = 1<<6, /* Disable Recovery Timer TX2 */ - MA_ENA_REC_TX1 = 1<<5, /* Enable Recovery Timer TX1 */ - MA_DIS_REC_TX1 = 1<<4, /* Disable Recovery Timer TX1 */ - MA_ENA_REC_RX2 = 1<<3, /* Enable Recovery Timer RX2 */ - MA_DIS_REC_RX2 = 1<<2, /* Disable Recovery Timer RX2 */ - MA_ENA_REC_RX1 = 1<<1, /* Enable Recovery Timer RX1 */ - MA_DIS_REC_RX1 = 1<<0, /* Disable Recovery Timer RX1 */ -}; - /* Packet Arbiter Registers */ /* B3_PA_CTRL 16 bit Packet Arbiter Ctrl Register */ enum { @@ -618,8 +529,7 @@ enum { enum { PHY_ADDR_XMAC = 0<<8, PHY_ADDR_BCOM = 1<<8, - PHY_ADDR_LONE = 3<<8, - PHY_ADDR_NAT = 0<<8, + /* GPHY address (bits 15..11 of SMI control reg) */ PHY_ADDR_MARV = 0, }; @@ -1151,54 +1061,6 @@ enum { PHY_MARV_FE_SPEC_2 = 0x1c,/* 16 bit r/w Specific Control Reg. 2 */ }; -/* Level One-PHY Registers, indirect addressed over XMAC */ -enum { - PHY_LONE_CTRL = 0x00,/* 16 bit r/w PHY Control Register */ - PHY_LONE_STAT = 0x01,/* 16 bit r/o PHY Status Register */ - PHY_LONE_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */ - PHY_LONE_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */ - PHY_LONE_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ - PHY_LONE_AUNE_LP = 0x05,/* 16 bit r/o Link Part Ability Reg */ - PHY_LONE_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ - PHY_LONE_NEPG = 0x07,/* 16 bit r/w Next Page Register */ - PHY_LONE_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner */ - /* Level One-specific registers */ - PHY_LONE_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */ - PHY_LONE_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */ - PHY_LONE_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Reg */ - PHY_LONE_PORT_CFG = 0x10,/* 16 bit r/w Port Configuration Reg*/ - PHY_LONE_Q_STAT = 0x11,/* 16 bit r/o Quick Status Reg */ - PHY_LONE_INT_ENAB = 0x12,/* 16 bit r/w Interrupt Enable Reg */ - PHY_LONE_INT_STAT = 0x13,/* 16 bit r/o Interrupt Status Reg */ - PHY_LONE_LED_CFG = 0x14,/* 16 bit r/w LED Configuration Reg */ - PHY_LONE_PORT_CTRL = 0x15,/* 16 bit r/w Port Control Reg */ - PHY_LONE_CIM = 0x16,/* 16 bit r/o CIM Reg */ -}; - -/* National-PHY Registers, indirect addressed over XMAC */ -enum { - PHY_NAT_CTRL = 0x00,/* 16 bit r/w PHY Control Register */ - PHY_NAT_STAT = 0x01,/* 16 bit r/w PHY Status Register */ - PHY_NAT_ID0 = 0x02,/* 16 bit r/o PHY ID0 Register */ - PHY_NAT_ID1 = 0x03,/* 16 bit r/o PHY ID1 Register */ - PHY_NAT_AUNE_ADV = 0x04,/* 16 bit r/w Auto-Neg. Advertisement */ - PHY_NAT_AUNE_LP = 0x05,/* 16 bit r/o Link Partner Ability Reg */ - PHY_NAT_AUNE_EXP = 0x06,/* 16 bit r/o Auto-Neg. Expansion Reg */ - PHY_NAT_NEPG = 0x07,/* 16 bit r/w Next Page Register */ - PHY_NAT_NEPG_LP = 0x08,/* 16 bit r/o Next Page Link Partner Reg */ - /* National-specific registers */ - PHY_NAT_1000T_CTRL = 0x09,/* 16 bit r/w 1000Base-T Control Reg */ - PHY_NAT_1000T_STAT = 0x0a,/* 16 bit r/o 1000Base-T Status Reg */ - PHY_NAT_EXT_STAT = 0x0f,/* 16 bit r/o Extended Status Register */ - PHY_NAT_EXT_CTRL1 = 0x10,/* 16 bit r/o Extended Control Reg1 */ - PHY_NAT_Q_STAT1 = 0x11,/* 16 bit r/o Quick Status Reg1 */ - PHY_NAT_10B_OP = 0x12,/* 16 bit r/o 10Base-T Operations Reg */ - PHY_NAT_EXT_CTRL2 = 0x13,/* 16 bit r/o Extended Control Reg1 */ - PHY_NAT_Q_STAT2 = 0x14,/* 16 bit r/o Quick Status Reg2 */ - - PHY_NAT_PHY_ADDR = 0x19,/* 16 bit r/o PHY Address Register */ -}; - enum { PHY_CT_RESET = 1<<15, /* Bit 15: (sc) clear all PHY related regs */ PHY_CT_LOOP = 1<<14, /* Bit 14: enable Loopback over PHY */ @@ -1253,8 +1115,29 @@ enum { PHY_MARV_ID1_Y2 = 0x0C91, /* Yukon-2 (PHY 88E1112) */ }; +/* Advertisement register bits */ enum { PHY_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ + PHY_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ + PHY_AN_RF = 1<<13, /* Bit 13: Remote Fault Bits */ + + PHY_AN_PAUSE_ASYM = 1<<11,/* Bit 11: Try for asymmetric */ + PHY_AN_PAUSE_CAP = 1<<10, /* Bit 10: Try for pause */ + PHY_AN_100BASE4 = 1<<9, /* Bit 9: Try for 100mbps 4k packets */ + PHY_AN_100FULL = 1<<8, /* Bit 8: Try for 100mbps full-duplex */ + PHY_AN_100HALF = 1<<7, /* Bit 7: Try for 100mbps half-duplex */ + PHY_AN_10FULL = 1<<6, /* Bit 6: Try for 10mbps full-duplex */ + PHY_AN_10HALF = 1<<5, /* Bit 5: Try for 10mbps half-duplex */ + PHY_AN_CSMA = 1<<0, /* Bit 0: Only selector supported */ + PHY_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ + PHY_AN_FULL = PHY_AN_100FULL | PHY_AN_10FULL | PHY_AN_CSMA, + PHY_AN_ALL = PHY_AN_10HALF | PHY_AN_10FULL | + PHY_AN_100HALF | PHY_AN_100FULL, +}; + +/* Xmac Specific */ +enum { + PHY_X_AN_NXT_PG = 1<<15, /* Bit 15: Request Next Page */ PHY_X_AN_ACK = 1<<14, /* Bit 14: (ro) Acknowledge Received */ PHY_X_AN_RFB = 3<<12,/* Bit 13..12: Remote Fault Bits */ @@ -1263,82 +1146,6 @@ enum { PHY_X_AN_FD = 1<<5, /* Bit 5: Full Duplex */ }; -enum { - PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */ - - PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ - PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */ - PHY_B_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ -}; - -enum { - PHY_L_AN_RF = 1<<13, /* Bit 13: Remote Fault */ - /* Bit 12: reserved */ - PHY_L_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ - PHY_L_AN_PC = 1<<10, /* Bit 10: Pause Capable */ - - PHY_L_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ -}; - -/* PHY_NAT_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement */ -/* PHY_NAT_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ -/* PHY_AN_NXT_PG (see XMAC) Bit 15: Request Next Page */ -enum { - PHY_N_AN_RF = 1<<13, /* Bit 13: Remote Fault */ - - PHY_N_AN_100F = 1<<11, /* Bit 11: 100Base-T2 FD Support */ - PHY_N_AN_100H = 1<<10, /* Bit 10: 100Base-T2 HD Support */ - - PHY_N_AN_SEL = 0x1f, /* Bit 4..0: Selector Field, 00001=Ethernet*/ -}; - -/* field type definition for PHY_x_AN_SEL */ -enum { - PHY_SEL_TYPE = 1, /* 00001 = Ethernet */ -}; - -enum { - PHY_ANE_LP_NP = 1<<3, /* Bit 3: Link Partner can Next Page */ - PHY_ANE_LOC_NP = 1<<2, /* Bit 2: Local PHY can Next Page */ - PHY_ANE_RX_PG = 1<<1, /* Bit 1: Page Received */ -}; - -enum { - PHY_ANE_PAR_DF = 1<<4, /* Bit 4: Parallel Detection Fault */ - - PHY_ANE_LP_CAP = 1<<0, /* Bit 0: Link Partner Auto-Neg. Cap. */ -}; - -enum { - PHY_NP_MORE = 1<<15, /* Bit 15: More, Next Pages to follow */ - PHY_NP_ACK1 = 1<<14, /* Bit 14: (ro) Ack1, for receiving a message */ - PHY_NP_MSG_VAL = 1<<13, /* Bit 13: Message Page valid */ - PHY_NP_ACK2 = 1<<12, /* Bit 12: Ack2, comply with msg content */ - PHY_NP_TOG = 1<<11, /* Bit 11: Toggle Bit, ensure sync */ - PHY_NP_MSG = 0x07ff, /* Bit 10..0: Message from/to Link Partner */ -}; - -enum { - PHY_X_EX_FD = 1<<15, /* Bit 15: Device Supports Full Duplex */ - PHY_X_EX_HD = 1<<14, /* Bit 14: Device Supports Half Duplex */ -}; - -enum { - PHY_X_RS_PAUSE = 3<<7,/* Bit 8..7: selected Pause Mode */ - PHY_X_RS_HD = 1<<6, /* Bit 6: Half Duplex Mode selected */ - PHY_X_RS_FD = 1<<5, /* Bit 5: Full Duplex Mode selected */ - PHY_X_RS_ABLMIS = 1<<4, /* Bit 4: duplex or pause cap mismatch */ - PHY_X_RS_PAUMIS = 1<<3, /* Bit 3: pause capability mismatch */ -}; - -/** Remote Fault Bits (PHY_X_AN_RFB) encoding */ -enum { - X_RFB_OK = 0<<12,/* Bit 13..12 No errors, Link OK */ - X_RFB_LF = 1<<12, /* Bit 13..12 Link Failure */ - X_RFB_OFF = 2<<12,/* Bit 13..12 Offline */ - X_RFB_AN_ERR = 3<<12,/* Bit 13..12 Auto-Negotiation Error */ -}; - /* Pause Bits (PHY_X_AN_PAUSE and PHY_X_RS_PAUSE) encoding */ enum { PHY_X_P_NO_PAUSE = 0<<7,/* Bit 8..7: no Pause Mode */ @@ -1495,166 +1302,6 @@ enum { PHY_B_RES_1000HD = 6<<8,/* Bit 10..8: 1000Base-T Half Dup. */ }; -/* - * Level One-Specific - */ -/***** PHY_LONE_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -enum { - PHY_L_1000C_TEST = 7<<13,/* Bit 15..13: Test Modes */ - PHY_L_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */ - PHY_L_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */ - PHY_L_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */ - PHY_L_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */ - PHY_L_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */ -}; - -/***** PHY_LONE_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -enum { - PHY_L_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */ - PHY_L_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */ - PHY_L_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */ - PHY_L_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status */ - PHY_L_1000S_LP_FD = 1<<11, /* Bit 11: Link Partner can FD */ - PHY_L_1000S_LP_HD = 1<<10, /* Bit 10: Link Partner can HD */ - - PHY_L_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */ - -/***** PHY_LONE_EXT_STAT 16 bit r/o Extended Status Register *****/ - PHY_L_ES_X_FD_CAP = 1<<15, /* Bit 15: 1000Base-X FD capable */ - PHY_L_ES_X_HD_CAP = 1<<14, /* Bit 14: 1000Base-X HD capable */ - PHY_L_ES_T_FD_CAP = 1<<13, /* Bit 13: 1000Base-T FD capable */ - PHY_L_ES_T_HD_CAP = 1<<12, /* Bit 12: 1000Base-T HD capable */ -}; - -/***** PHY_LONE_PORT_CFG 16 bit r/w Port Configuration Reg *****/ -enum { - PHY_L_PC_REP_MODE = 1<<15, /* Bit 15: Repeater Mode */ - - PHY_L_PC_TX_DIS = 1<<13, /* Bit 13: Tx output Disabled */ - PHY_L_PC_BY_SCR = 1<<12, /* Bit 12: Bypass Scrambler */ - PHY_L_PC_BY_45 = 1<<11, /* Bit 11: Bypass 4B5B-Decoder */ - PHY_L_PC_JAB_DIS = 1<<10, /* Bit 10: Jabber Disabled */ - PHY_L_PC_SQE = 1<<9, /* Bit 9: Enable Heartbeat */ - PHY_L_PC_TP_LOOP = 1<<8, /* Bit 8: TP Loopback */ - PHY_L_PC_SSS = 1<<7, /* Bit 7: Smart Speed Selection */ - PHY_L_PC_FIFO_SIZE = 1<<6, /* Bit 6: FIFO Size */ - PHY_L_PC_PRE_EN = 1<<5, /* Bit 5: Preamble Enable */ - PHY_L_PC_CIM = 1<<4, /* Bit 4: Carrier Integrity Mon */ - PHY_L_PC_10_SER = 1<<3, /* Bit 3: Use Serial Output */ - PHY_L_PC_ANISOL = 1<<2, /* Bit 2: Unisolate Port */ - PHY_L_PC_TEN_BIT = 1<<1, /* Bit 1: 10bit iface mode on */ - PHY_L_PC_ALTCLOCK = 1<<0, /* Bit 0: (ro) ALTCLOCK Mode on */ -}; - -/***** PHY_LONE_Q_STAT 16 bit r/o Quick Status Reg *****/ -enum { - PHY_L_QS_D_RATE = 3<<14,/* Bit 15..14: Data Rate */ - PHY_L_QS_TX_STAT = 1<<13, /* Bit 13: Transmitting */ - PHY_L_QS_RX_STAT = 1<<12, /* Bit 12: Receiving */ - PHY_L_QS_COL_STAT = 1<<11, /* Bit 11: Collision */ - PHY_L_QS_L_STAT = 1<<10, /* Bit 10: Link is up */ - PHY_L_QS_DUP_MOD = 1<<9, /* Bit 9: Full/Half Duplex */ - PHY_L_QS_AN = 1<<8, /* Bit 8: AutoNeg is On */ - PHY_L_QS_AN_C = 1<<7, /* Bit 7: AN is Complete */ - PHY_L_QS_LLE = 7<<4,/* Bit 6..4: Line Length Estim. */ - PHY_L_QS_PAUSE = 1<<3, /* Bit 3: LP advertised Pause */ - PHY_L_QS_AS_PAUSE = 1<<2, /* Bit 2: LP adv. asym. Pause */ - PHY_L_QS_ISOLATE = 1<<1, /* Bit 1: CIM Isolated */ - PHY_L_QS_EVENT = 1<<0, /* Bit 0: Event has occurred */ -}; - -/***** PHY_LONE_INT_ENAB 16 bit r/w Interrupt Enable Reg *****/ -/***** PHY_LONE_INT_STAT 16 bit r/o Interrupt Status Reg *****/ -enum { - PHY_L_IS_AN_F = 1<<13, /* Bit 13: Auto-Negotiation fault */ - PHY_L_IS_CROSS = 1<<11, /* Bit 11: Crossover used */ - PHY_L_IS_POL = 1<<10, /* Bit 10: Polarity correct. used */ - PHY_L_IS_SS = 1<<9, /* Bit 9: Smart Speed Downgrade */ - PHY_L_IS_CFULL = 1<<8, /* Bit 8: Counter Full */ - PHY_L_IS_AN_C = 1<<7, /* Bit 7: AutoNeg Complete */ - PHY_L_IS_SPEED = 1<<6, /* Bit 6: Speed Changed */ - PHY_L_IS_DUP = 1<<5, /* Bit 5: Duplex Changed */ - PHY_L_IS_LS = 1<<4, /* Bit 4: Link Status Changed */ - PHY_L_IS_ISOL = 1<<3, /* Bit 3: Isolate Occured */ - PHY_L_IS_MDINT = 1<<2, /* Bit 2: (ro) STAT: MII Int Pending */ - PHY_L_IS_INTEN = 1<<1, /* Bit 1: ENAB: Enable IRQs */ - PHY_L_IS_FORCE = 1<<0, /* Bit 0: ENAB: Force Interrupt */ -}; - -/* int. mask */ -#define PHY_L_DEF_MSK (PHY_L_IS_LS | PHY_L_IS_ISOL | PHY_L_IS_INTEN) - -/***** PHY_LONE_LED_CFG 16 bit r/w LED Configuration Reg *****/ -enum { - PHY_L_LC_LEDC = 3<<14,/* Bit 15..14: Col/Blink/On/Off */ - PHY_L_LC_LEDR = 3<<12,/* Bit 13..12: Rx/Blink/On/Off */ - PHY_L_LC_LEDT = 3<<10,/* Bit 11..10: Tx/Blink/On/Off */ - PHY_L_LC_LEDG = 3<<8,/* Bit 9..8: Giga/Blink/On/Off */ - PHY_L_LC_LEDS = 3<<6,/* Bit 7..6: 10-100/Blink/On/Off */ - PHY_L_LC_LEDL = 3<<4,/* Bit 5..4: Link/Blink/On/Off */ - PHY_L_LC_LEDF = 3<<2,/* Bit 3..2: Duplex/Blink/On/Off */ - PHY_L_LC_PSTRECH= 1<<1, /* Bit 1: Strech LED Pulses */ - PHY_L_LC_FREQ = 1<<0, /* Bit 0: 30/100 ms */ -}; - -/***** PHY_LONE_PORT_CTRL 16 bit r/w Port Control Reg *****/ -enum { - PHY_L_PC_TX_TCLK = 1<<15, /* Bit 15: Enable TX_TCLK */ - PHY_L_PC_ALT_NP = 1<<13, /* Bit 14: Alternate Next Page */ - PHY_L_PC_GMII_ALT= 1<<12, /* Bit 13: Alternate GMII driver */ - PHY_L_PC_TEN_CRS = 1<<10, /* Bit 10: Extend CRS*/ -}; - -/***** PHY_LONE_CIM 16 bit r/o CIM Reg *****/ -enum { - PHY_L_CIM_ISOL = 0xff<<8,/* Bit 15..8: Isolate Count */ - PHY_L_CIM_FALSE_CAR = 0xff, /* Bit 7..0: False Carrier Count */ -}; - -/* - * Pause Bits (PHY_L_AN_ASP and PHY_L_AN_PC) encoding - */ -enum { - PHY_L_P_NO_PAUSE= 0<<10,/* Bit 11..10: no Pause Mode */ - PHY_L_P_SYM_MD = 1<<10, /* Bit 11..10: symmetric Pause Mode */ - PHY_L_P_ASYM_MD = 2<<10,/* Bit 11..10: asymmetric Pause Mode */ - PHY_L_P_BOTH_MD = 3<<10,/* Bit 11..10: both Pause Mode */ -}; - -/* - * National-Specific - */ -/***** PHY_NAT_1000T_CTRL 16 bit r/w 1000Base-T Control Reg *****/ -enum { - PHY_N_1000C_TEST= 7<<13,/* Bit 15..13: Test Modes */ - PHY_N_1000C_MSE = 1<<12, /* Bit 12: Master/Slave Enable */ - PHY_N_1000C_MSC = 1<<11, /* Bit 11: M/S Configuration */ - PHY_N_1000C_RD = 1<<10, /* Bit 10: Repeater/DTE */ - PHY_N_1000C_AFD = 1<<9, /* Bit 9: Advertise Full Duplex */ - PHY_N_1000C_AHD = 1<<8, /* Bit 8: Advertise Half Duplex */ - PHY_N_1000C_APC = 1<<7, /* Bit 7: Asymmetric Pause Cap. */}; - - -/***** PHY_NAT_1000T_STAT 16 bit r/o 1000Base-T Status Reg *****/ -enum { - PHY_N_1000S_MSF = 1<<15, /* Bit 15: Master/Slave Fault */ - PHY_N_1000S_MSR = 1<<14, /* Bit 14: Master/Slave Result */ - PHY_N_1000S_LRS = 1<<13, /* Bit 13: Local Receiver Status */ - PHY_N_1000S_RRS = 1<<12, /* Bit 12: Remote Receiver Status*/ - PHY_N_1000S_LP_FD= 1<<11, /* Bit 11: Link Partner can FD */ - PHY_N_1000S_LP_HD= 1<<10, /* Bit 10: Link Partner can HD */ - PHY_N_1000C_LP_APC= 1<<9, /* Bit 9: LP Asym. Pause Cap. */ - PHY_N_1000S_IEC = 0xff, /* Bit 7..0: Idle Error Count */ -}; - -/***** PHY_NAT_EXT_STAT 16 bit r/o Extended Status Register *****/ -enum { - PHY_N_ES_X_FD_CAP= 1<<15, /* Bit 15: 1000Base-X FD capable */ - PHY_N_ES_X_HD_CAP= 1<<14, /* Bit 14: 1000Base-X HD capable */ - PHY_N_ES_T_FD_CAP= 1<<13, /* Bit 13: 1000Base-T FD capable */ - PHY_N_ES_T_HD_CAP= 1<<12, /* Bit 12: 1000Base-T HD capable */ -}; - /** Marvell-Specific */ enum { PHY_M_AN_NXT_PG = 1<<15, /* Request Next Page */ @@ -2540,10 +2187,6 @@ enum { }; -/* XM_PHY_ADDR 16 bit r/w PHY Address Register */ -#define XM_PHY_ADDR_SZ 0x1f /* Bit 4..0: PHY Address bits */ - - /* XM_GP_PORT 32 bit r/w General Purpose Port Register */ enum { XM_GP_ANIP = 1<<6, /* Bit 6: (ro) Auto-Neg. in progress */ @@ -2855,7 +2498,6 @@ struct skge_port { static inline u32 skge_read32(const struct skge_hw *hw, int reg) { return readl(hw->regs + reg); - } static inline u16 skge_read16(const struct skge_hw *hw, int reg) -- cgit v1.1 From c506a5090272752932be6ac0c29ffcbca38f2404 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:09 -0700 Subject: [PATCH] skge: remove Yukon2 related special cases Remove the bits and pieces added relating to Yukon II chipset. The Yukon 2 will be in a separate driver. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 54 +++++++----------------------------------------------- 1 file changed, 7 insertions(+), 47 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 8fd7981..c29e187 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -205,9 +205,6 @@ static int skge_get_settings(struct net_device *dev, if (hw->chip_id == CHIP_ID_YUKON) ecmd->supported &= ~SUPPORTED_1000baseT_Half; - else if (hw->chip_id == CHIP_ID_YUKON_FE) - ecmd->supported &= ~(SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full); } ecmd->port = PORT_TP; @@ -248,9 +245,6 @@ static u32 skge_modes(const struct skge_hw *hw) modes &= ~ADVERTISED_1000baseT_Half; break; - case CHIP_ID_YUKON_FE: - modes &= ~(ADVERTISED_1000baseT_Half|ADVERTISED_1000baseT_Full); - break; } } else { modes |= ADVERTISED_FIBRE; @@ -270,8 +264,6 @@ static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) } else { switch (ecmd->speed) { case SPEED_1000: - if (hw->chip_id == CHIP_ID_YUKON_FE) - return -EINVAL; break; case SPEED_100: case SPEED_10: @@ -540,8 +532,6 @@ static inline u32 hwkhz(const struct skge_hw *hw) { if (hw->chip_id == CHIP_ID_GENESIS) return 53215; /* or: 53.125 MHz */ - else if (hw->chip_id == CHIP_ID_YUKON_EC) - return 125000; /* or: 125.000 MHz */ else return 78215; /* or: 78.125 MHz */ } @@ -1598,11 +1588,7 @@ static void yukon_init(struct skge_hw *hw, int port) PHY_M_EC_MAC_S_MSK); ectrl |= PHY_M_EC_MAC_S(MAC_TX_CLK_25_MHZ); - /* on PHY 88E1111 there is a change for downshift control */ - if (hw->chip_id == CHIP_ID_YUKON_EC) - ectrl |= PHY_M_EC_M_DSC_2(0) | PHY_M_EC_DOWN_S_ENA; - else - ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); + ectrl |= PHY_M_EC_M_DSC(0) | PHY_M_EC_S_DSC(1); gm_phy_write(hw, port, PHY_MARV_EXT_CTRL, ectrl); } @@ -1688,8 +1674,7 @@ static void yukon_init(struct skge_hw *hw, int port) ctrl |= PHY_CT_RESET; } - if (hw->chip_id != CHIP_ID_YUKON_FE) - gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); + gm_phy_write(hw, port, PHY_MARV_1000T_CTRL, ct1000); gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, adv); gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl); @@ -1698,22 +1683,10 @@ static void yukon_init(struct skge_hw *hw, int port) ledctrl = PHY_M_LED_PULS_DUR(PULS_170MS); ledover = 0; - if (hw->chip_id == CHIP_ID_YUKON_FE) { - /* on 88E3082 these bits are at 11..9 (shifted left) */ - ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) << 1; + ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; - gm_phy_write(hw, port, PHY_MARV_FE_LED_PAR, - ((gm_phy_read(hw, port, PHY_MARV_FE_LED_PAR) - - & ~PHY_M_FELP_LED1_MSK) - | PHY_M_FELP_LED1_CTRL(LED_PAR_CTRL_ACT_BL))); - } else { - /* set Tx LED (LED_TX) to blink mode on Rx OR Tx activity */ - ledctrl |= PHY_M_LED_BLINK_RT(BLINK_84MS) | PHY_M_LEDC_TX_CTRL; - - /* turn off the Rx LED (LED_RX) */ - ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); - } + /* turn off the Rx LED (LED_RX) */ + ledover |= PHY_M_LED_MO_RX(MO_LED_OFF); /* disable blink mode (LED_DUPLEX) on collisions */ ctrl |= PHY_M_LEDC_DP_CTRL; @@ -1928,9 +1901,6 @@ static void yukon_mac_intr(struct skge_hw *hw, int port) static u16 yukon_speed(const struct skge_hw *hw, u16 aux) { - if (hw->chip_id == CHIP_ID_YUKON_FE) - return (aux & PHY_M_PS_SPEED_100) ? SPEED_100 : SPEED_10; - switch (aux & PHY_M_PS_SPEED_MSK) { case PHY_M_PS_SPEED_1000: return SPEED_1000; @@ -1975,8 +1945,7 @@ static void yukon_link_down(struct skge_port *skge) gm_phy_read(hw, port, GM_GP_CTRL) & ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA)); - if (hw->chip_id != CHIP_ID_YUKON_FE && - skge->flow_control == FLOW_MODE_REM_SEND) { + if (skge->flow_control == FLOW_MODE_REM_SEND) { /* restore Asymmetric Pause bit */ gm_phy_write(hw, port, PHY_MARV_AUNE_ADV, gm_phy_read(hw, port, @@ -2009,9 +1978,7 @@ static void yukon_phy_intr(struct skge_port *skge) goto failed; } - if (!(hw->chip_id == CHIP_ID_YUKON_FE || hw->chip_id == CHIP_ID_YUKON_EC) - && (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) - & PHY_B_1000S_MSF)) { + if (gm_phy_read(hw, port, PHY_MARV_1000T_STAT) & PHY_B_1000S_MSF) { reason = "master/slave fault"; goto failed; } @@ -2025,10 +1992,6 @@ static void yukon_phy_intr(struct skge_port *skge) ? DUPLEX_FULL : DUPLEX_HALF; skge->speed = yukon_speed(hw, phystat); - /* Tx & Rx Pause Enabled bits are at 9..8 */ - if (hw->chip_id == CHIP_ID_YUKON_XL) - phystat >>= 6; - /* We are using IEEE 802.3z/D5.0 Table 37-4 */ switch (phystat & PHY_M_PS_PAUSE_MSK) { case PHY_M_PS_PAUSE_MSK: @@ -2875,9 +2838,6 @@ static const struct { { CHIP_ID_YUKON, "Yukon" }, { CHIP_ID_YUKON_LITE, "Yukon-Lite"}, { CHIP_ID_YUKON_LP, "Yukon-LP"}, - { CHIP_ID_YUKON_XL, "Yukon-2 XL"}, - { CHIP_ID_YUKON_EC, "YUKON-2 EC"}, - { CHIP_ID_YUKON_FE, "YUKON-2 FE"}, }; static const char *skge_board_name(const struct skge_hw *hw) -- cgit v1.1 From 89bf5f231f776443a9d65da0f774aa3632534749 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:10 -0700 Subject: [PATCH] skge: remove XM phy (untested code) Remove support for the non-Broadcom genesis based boards. The code is untested, and probably won't work as is. The newer boards are all Yukon based, and only old Genesis board I can find uses Broadcom. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 355 +++++++++++++++++++++-------------------------------- 1 file changed, 138 insertions(+), 217 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index c29e187..68de7f7 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -621,16 +621,8 @@ static void skge_led_on(struct skge_hw *hw, int port) skge_write32(hw, SK_REG(port, RX_LED_VAL), 100); skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_START); - switch (hw->phy_type) { - case SK_PHY_BCOM: - xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, - PHY_B_PEC_LED_ON); - break; - default: - skge_write8(hw, SK_REG(port, TX_LED_TST), LED_T_ON); - skge_write32(hw, SK_REG(port, TX_LED_VAL), 100); - skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_START); - } + /* For Broadcom Phy only */ + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_ON); } else { gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); gm_phy_write(hw, port, PHY_MARV_LED_OVER, @@ -651,15 +643,8 @@ static void skge_led_off(struct skge_hw *hw, int port) skge_write32(hw, SK_REG(port, RX_LED_VAL), 0); skge_write8(hw, SK_REG(port, RX_LED_CTRL), LED_T_OFF); - switch (hw->phy_type) { - case SK_PHY_BCOM: - xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, - PHY_B_PEC_LED_OFF); - break; - default: - skge_write32(hw, SK_REG(port, TX_LED_VAL), 0); - skge_write8(hw, SK_REG(port, TX_LED_CTRL), LED_T_OFF); - } + /* Broadcom only */ + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, PHY_B_PEC_LED_OFF); } else { gm_phy_write(hw, port, PHY_MARV_LED_CTRL, 0); gm_phy_write(hw, port, PHY_MARV_LED_OVER, @@ -887,21 +872,21 @@ static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg) xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr); v = xm_read16(hw, port, XM_PHY_DATA); - if (hw->phy_type != SK_PHY_XMAC) { - for (i = 0; i < PHY_RETRIES; i++) { - udelay(1); - if (xm_read16(hw, port, XM_MMU_CMD) - & XM_MMU_PHY_RDY) - goto ready; - } - printk(KERN_WARNING PFX "%s: phy read timed out\n", - hw->dev[port]->name); - return 0; - ready: - v = xm_read16(hw, port, XM_PHY_DATA); + /* Need to wait for external PHY */ + for (i = 0; i < PHY_RETRIES; i++) { + udelay(1); + if (xm_read16(hw, port, XM_MMU_CMD) + & XM_MMU_PHY_RDY) + goto ready; } + printk(KERN_WARNING PFX "%s: phy read timed out\n", + hw->dev[port]->name); + return 0; + ready: + v = xm_read16(hw, port, XM_PHY_DATA); + return v; } @@ -913,7 +898,7 @@ static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val) for (i = 0; i < PHY_RETRIES; i++) { if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY)) goto ready; - cpu_relax(); + udelay(1); } printk(KERN_WARNING PFX "%s: phy write failed to come ready\n", hw->dev[port]->name); @@ -970,9 +955,8 @@ static void genesis_reset(struct skge_hw *hw, int port) xm_write16(hw, port, XM_TX_CMD, 0); /* reset TX CMD Reg */ xm_write16(hw, port, XM_RX_CMD, 0); /* reset RX CMD Reg */ - /* disable all PHY IRQs */ - if (hw->phy_type == SK_PHY_BCOM) - xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); + /* disable Broadcom PHY IRQ */ + xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); xm_outhash(hw, port, XM_HSM, (u8 *) &zero); for (i = 0; i < 15; i++) @@ -1020,54 +1004,55 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * GMII mode. */ spin_lock_bh(&hw->phy_lock); - if (hw->phy_type != SK_PHY_XMAC) { - /* Take PHY out of reset. */ - r = skge_read32(hw, B2_GP_IO); - if (port == 0) - r |= GP_DIR_0|GP_IO_0; - else - r |= GP_DIR_2|GP_IO_2; - - skge_write32(hw, B2_GP_IO, r); - skge_read32(hw, B2_GP_IO); - - /* Enable GMII mode on the XMAC. */ - xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); - - id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); - - /* Optimize MDIO transfer by suppressing preamble. */ - xm_write16(hw, port, XM_MMU_CMD, - xm_read16(hw, port, XM_MMU_CMD) - | XM_MMU_NO_PRE); - - if (id1 == PHY_BCOM_ID1_C0) { - /* - * Workaround BCOM Errata for the C0 type. - * Write magic patterns to reserved registers. - */ - for (i = 0; i < ARRAY_SIZE(C0hack); i++) - xm_phy_write(hw, port, - C0hack[i].reg, C0hack[i].val); - - } else if (id1 == PHY_BCOM_ID1_A1) { - /* - * Workaround BCOM Errata for the A1 type. - * Write magic patterns to reserved registers. - */ - for (i = 0; i < ARRAY_SIZE(A1hack); i++) - xm_phy_write(hw, port, - A1hack[i].reg, A1hack[i].val); - } + /* External Phy Handling */ + /* Take PHY out of reset. */ + r = skge_read32(hw, B2_GP_IO); + if (port == 0) + r |= GP_DIR_0|GP_IO_0; + else + r |= GP_DIR_2|GP_IO_2; + + skge_write32(hw, B2_GP_IO, r); + skge_read32(hw, B2_GP_IO); + + /* Enable GMII mode on the XMAC. */ + xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); + + id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); + + /* Optimize MDIO transfer by suppressing preamble. */ + xm_write16(hw, port, XM_MMU_CMD, + xm_read16(hw, port, XM_MMU_CMD) + | XM_MMU_NO_PRE); + + if (id1 == PHY_BCOM_ID1_C0) { /* - * Workaround BCOM Errata (#10523) for all BCom PHYs. - * Disable Power Management after reset. + * Workaround BCOM Errata for the C0 type. + * Write magic patterns to reserved registers. */ - r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); - xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); + for (i = 0; i < ARRAY_SIZE(C0hack); i++) + xm_phy_write(hw, port, + C0hack[i].reg, C0hack[i].val); + + } else if (id1 == PHY_BCOM_ID1_A1) { + /* + * Workaround BCOM Errata for the A1 type. + * Write magic patterns to reserved registers. + */ + for (i = 0; i < ARRAY_SIZE(A1hack); i++) + xm_phy_write(hw, port, + A1hack[i].reg, A1hack[i].val); } + /* + * Workaround BCOM Errata (#10523) for all BCom PHYs. + * Disable Power Management after reset. + */ + r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); + + /* Dummy read */ xm_read16(hw, port, XM_ISRC); @@ -1098,8 +1083,8 @@ static void genesis_mac_init(struct skge_hw *hw, int port) */ r = xm_read32(hw, port, XM_MODE); xm_write32(hw, port, XM_MODE, - XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| - XM_MD_RX_ERR|XM_MD_RX_IRLE); + XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| + XM_MD_RX_ERR|XM_MD_RX_IRLE); xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); @@ -1150,103 +1135,70 @@ static void genesis_mac_init(struct skge_hw *hw, int port) else xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); - switch (hw->phy_type) { - case SK_PHY_XMAC: - if (skge->autoneg == AUTONEG_ENABLE) { - ctrl1 = PHY_X_AN_FD | PHY_X_AN_HD; + /* Broadcom phy initialization */ + ctrl1 = PHY_CT_SP1000; + ctrl2 = 0; + ctrl3 = PHY_AN_CSMA; + ctrl4 = PHY_B_PEC_EN_LTR; + ctrl5 = PHY_B_AC_TX_TST; - switch (skge->flow_control) { - case FLOW_MODE_NONE: - ctrl1 |= PHY_X_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - ctrl1 |= PHY_X_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - ctrl1 |= PHY_X_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - ctrl1 |= PHY_X_P_BOTH_MD; - break; - } - - xm_phy_write(hw, port, PHY_XMAC_AUNE_ADV, ctrl1); - ctrl2 = PHY_CT_ANE | PHY_CT_RE_CFG; - } else { - ctrl2 = 0; - if (skge->duplex == DUPLEX_FULL) - ctrl2 |= PHY_CT_DUP_MD; + if (skge->autoneg == AUTONEG_ENABLE) { + /* + * Workaround BCOM Errata #1 for the C5 type. + * 1000Base-T Link Acquisition Failure in Slave Mode + * Set Repeater/DTE bit 10 of the 1000Base-T Control Register + */ + ctrl2 |= PHY_B_1000C_RD; + if (skge->advertising & ADVERTISED_1000baseT_Half) + ctrl2 |= PHY_B_1000C_AHD; + if (skge->advertising & ADVERTISED_1000baseT_Full) + ctrl2 |= PHY_B_1000C_AFD; + + /* Set Flow-control capabilities */ + switch (skge->flow_control) { + case FLOW_MODE_NONE: + ctrl3 |= PHY_B_P_NO_PAUSE; + break; + case FLOW_MODE_LOC_SEND: + ctrl3 |= PHY_B_P_ASYM_MD; + break; + case FLOW_MODE_SYMMETRIC: + ctrl3 |= PHY_B_P_SYM_MD; + break; + case FLOW_MODE_REM_SEND: + ctrl3 |= PHY_B_P_BOTH_MD; + break; } - xm_phy_write(hw, port, PHY_XMAC_CTRL, ctrl2); - break; - - case SK_PHY_BCOM: - ctrl1 = PHY_CT_SP1000; - ctrl2 = 0; - ctrl3 = PHY_AN_CSMA; - ctrl4 = PHY_B_PEC_EN_LTR; - ctrl5 = PHY_B_AC_TX_TST; - - if (skge->autoneg == AUTONEG_ENABLE) { - /* - * Workaround BCOM Errata #1 for the C5 type. - * 1000Base-T Link Acquisition Failure in Slave Mode - * Set Repeater/DTE bit 10 of the 1000Base-T Control Register - */ - ctrl2 |= PHY_B_1000C_RD; - if (skge->advertising & ADVERTISED_1000baseT_Half) - ctrl2 |= PHY_B_1000C_AHD; - if (skge->advertising & ADVERTISED_1000baseT_Full) - ctrl2 |= PHY_B_1000C_AFD; - - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - ctrl3 |= PHY_B_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - ctrl3 |= PHY_B_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - ctrl3 |= PHY_B_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - ctrl3 |= PHY_B_P_BOTH_MD; - break; - } - - /* Restart Auto-negotiation */ - ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; - } else { - if (skge->duplex == DUPLEX_FULL) - ctrl1 |= PHY_CT_DUP_MD; - - ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ - } + /* Restart Auto-negotiation */ + ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; + } else { + if (skge->duplex == DUPLEX_FULL) + ctrl1 |= PHY_CT_DUP_MD; - xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); - xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); + ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ + } - if (skge->netdev->mtu > ETH_DATA_LEN) { - ctrl4 |= PHY_B_PEC_HIGH_LA; - ctrl5 |= PHY_B_AC_LONG_PACK; + xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); + xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); - xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); - } + if (skge->netdev->mtu > ETH_DATA_LEN) { + ctrl4 |= PHY_B_PEC_HIGH_LA; + ctrl5 |= PHY_B_AC_LONG_PACK; - xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); - xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); - break; + xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); } + + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); spin_unlock_bh(&hw->phy_lock); /* Clear MIB counters */ xm_write16(hw, port, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); + XM_SC_CLR_RXC | XM_SC_CLR_TXC); /* Clear two times according to Errata #3 */ xm_write16(hw, port, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); + XM_SC_CLR_RXC | XM_SC_CLR_TXC); /* Start polling for link status */ mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); @@ -1256,6 +1208,7 @@ static void genesis_stop(struct skge_port *skge) { struct skge_hw *hw = skge->hw; int port = skge->port; + u32 reg; /* Clear Tx packet arbiter timeout IRQ */ skge_write16(hw, B3_PA_CTRL, @@ -1273,19 +1226,16 @@ static void genesis_stop(struct skge_port *skge) skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_SET_MAC_RST); /* For external PHYs there must be special handling */ - if (hw->phy_type != SK_PHY_XMAC) { - u32 reg = skge_read32(hw, B2_GP_IO); - - if (port == 0) { - reg |= GP_DIR_0; - reg &= ~GP_IO_0; - } else { - reg |= GP_DIR_2; - reg &= ~GP_IO_2; - } - skge_write32(hw, B2_GP_IO, reg); - skge_read32(hw, B2_GP_IO); + reg = skge_read32(hw, B2_GP_IO); + if (port == 0) { + reg |= GP_DIR_0; + reg &= ~GP_IO_0; + } else { + reg |= GP_DIR_2; + reg &= ~GP_IO_2; } + skge_write32(hw, B2_GP_IO, reg); + skge_read32(hw, B2_GP_IO); xm_write16(hw, port, XM_MMU_CMD, xm_read16(hw, port, XM_MMU_CMD) @@ -1329,16 +1279,6 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) u16 status = xm_read16(hw, port, XM_ISRC); pr_debug("genesis_intr status %x\n", status); - if (hw->phy_type == SK_PHY_XMAC) { - /* LInk down, start polling for state change */ - if (status & XM_IS_INP_ASS) { - xm_write16(hw, port, XM_IMSK, - xm_read16(hw, port, XM_IMSK) | XM_IS_INP_ASS); - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - } - else if (status & XM_IS_AND) - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - } if (status & XM_IS_TXF_UR) { xm_write32(hw, port, XM_MODE, XM_MD_FTF); @@ -1458,28 +1398,25 @@ static void genesis_link_up(struct skge_port *skge) xm_write32(hw, port, XM_MODE, mode); msk = XM_DEF_MSK; - if (hw->phy_type != SK_PHY_XMAC) - msk |= XM_IS_INP_ASS; /* disable GP0 interrupt bit */ + /* disable GP0 interrupt bit for external Phy */ + msk |= XM_IS_INP_ASS; xm_write16(hw, port, XM_IMSK, msk); xm_read16(hw, port, XM_ISRC); /* get MMU Command Reg. */ cmd = xm_read16(hw, port, XM_MMU_CMD); - if (hw->phy_type != SK_PHY_XMAC && skge->duplex == DUPLEX_FULL) + if (skge->duplex == DUPLEX_FULL) cmd |= XM_MMU_GMII_FD; - if (hw->phy_type == SK_PHY_BCOM) { - /* - * Workaround BCOM Errata (#10523) for all BCom Phys - * Enable Power Management after link up - */ - xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, - xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) - & ~PHY_B_AC_DIS_PM); - xm_phy_write(hw, port, PHY_BCOM_INT_MASK, - PHY_B_DEF_MSK); - } + /* + * Workaround BCOM Errata (#10523) for all BCom Phys + * Enable Power Management after link up + */ + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, + xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL) + & ~PHY_B_AC_DIS_PM); + xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); /* enable Rx/Tx */ xm_write16(hw, port, XM_MMU_CMD, @@ -1551,25 +1488,12 @@ static void skge_link_timer(unsigned long __arg) { struct skge_port *skge = (struct skge_port *) __arg; struct skge_hw *hw = skge->hw; - int port = skge->port; if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev)) return; spin_lock_bh(&hw->phy_lock); - if (hw->phy_type == SK_PHY_BCOM) - genesis_bcom_intr(skge); - else { - int i; - for (i = 0; i < 3; i++) - if (xm_read16(hw, port, XM_ISRC) & XM_IS_INP_ASS) - break; - - if (i == 3) - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - else - genesis_link_up(skge); - } + genesis_bcom_intr(skge); spin_unlock_bh(&hw->phy_lock); } @@ -2737,7 +2661,7 @@ static void skge_extirq(unsigned long data) if (hw->chip_id != CHIP_ID_GENESIS) yukon_phy_intr(skge); - else if (hw->phy_type == SK_PHY_BCOM) + else genesis_bcom_intr(skge); } } @@ -2886,9 +2810,6 @@ static int skge_reset(struct skge_hw *hw) switch (hw->chip_id) { case CHIP_ID_GENESIS: switch (hw->phy_type) { - case SK_PHY_XMAC: - hw->phy_addr = PHY_ADDR_XMAC; - break; case SK_PHY_BCOM: hw->phy_addr = PHY_ADDR_BCOM; break; -- cgit v1.1 From 31b619c5abaa5512e7b41f190f9b7903b902f29a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:11 -0700 Subject: [PATCH] skge: cleanup ethtool mode support Unify mapping of supported modes based on hardware. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 125 ++++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 60 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 68de7f7..81b8fe9 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -179,6 +179,36 @@ static int skge_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) return 0; } +/* Determine supported/adverised modes based on hardware. + * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx + */ +static u32 skge_supported_modes(const struct skge_hw *hw) +{ + u32 supported; + + if (iscopper(hw)) { + supported = SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full + | SUPPORTED_1000baseT_Half + | SUPPORTED_1000baseT_Full + | SUPPORTED_Autoneg| SUPPORTED_TP; + + if (hw->chip_id == CHIP_ID_GENESIS) + supported &= ~(SUPPORTED_10baseT_Half + | SUPPORTED_10baseT_Full + | SUPPORTED_100baseT_Half + | SUPPORTED_100baseT_Full); + + else if (hw->chip_id == CHIP_ID_YUKON) + supported &= ~SUPPORTED_1000baseT_Half; + } else + supported = SUPPORTED_1000baseT_Full | SUPPORTED_FIBRE + | SUPPORTED_Autoneg; + + return supported; +} static int skge_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd) @@ -187,35 +217,13 @@ static int skge_get_settings(struct net_device *dev, struct skge_hw *hw = skge->hw; ecmd->transceiver = XCVR_INTERNAL; + ecmd->supported = skge_supported_modes(hw); if (iscopper(hw)) { - if (hw->chip_id == CHIP_ID_GENESIS) - ecmd->supported = SUPPORTED_1000baseT_Full - | SUPPORTED_1000baseT_Half - | SUPPORTED_Autoneg | SUPPORTED_TP; - else { - ecmd->supported = SUPPORTED_10baseT_Half - | SUPPORTED_10baseT_Full - | SUPPORTED_100baseT_Half - | SUPPORTED_100baseT_Full - | SUPPORTED_1000baseT_Half - | SUPPORTED_1000baseT_Full - | SUPPORTED_Autoneg| SUPPORTED_TP; - - if (hw->chip_id == CHIP_ID_YUKON) - ecmd->supported &= ~SUPPORTED_1000baseT_Half; - - } - ecmd->port = PORT_TP; ecmd->phy_address = hw->phy_addr; - } else { - ecmd->supported = SUPPORTED_1000baseT_Full - | SUPPORTED_FIBRE - | SUPPORTED_Autoneg; - + } else ecmd->port = PORT_FIBRE; - } ecmd->advertising = skge->advertising; ecmd->autoneg = skge->autoneg; @@ -224,60 +232,57 @@ static int skge_get_settings(struct net_device *dev, return 0; } -static u32 skge_modes(const struct skge_hw *hw) -{ - u32 modes = ADVERTISED_Autoneg - | ADVERTISED_1000baseT_Full | ADVERTISED_1000baseT_Half - | ADVERTISED_100baseT_Full | ADVERTISED_100baseT_Half - | ADVERTISED_10baseT_Full | ADVERTISED_10baseT_Half; - - if (iscopper(hw)) { - modes |= ADVERTISED_TP; - switch (hw->chip_id) { - case CHIP_ID_GENESIS: - modes &= ~(ADVERTISED_100baseT_Full - | ADVERTISED_100baseT_Half - | ADVERTISED_10baseT_Full - | ADVERTISED_10baseT_Half); - break; - - case CHIP_ID_YUKON: - modes &= ~ADVERTISED_1000baseT_Half; - break; - - } - } else { - modes |= ADVERTISED_FIBRE; - modes &= ~ADVERTISED_1000baseT_Half; - } - return modes; -} - static int skge_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) { struct skge_port *skge = netdev_priv(dev); const struct skge_hw *hw = skge->hw; + u32 supported = skge_supported_modes(hw); if (ecmd->autoneg == AUTONEG_ENABLE) { - if (ecmd->advertising & skge_modes(hw)) - return -EINVAL; + ecmd->advertising = supported; + skge->duplex = -1; + skge->speed = -1; } else { - switch (ecmd->speed) { + u32 setting; + + switch(ecmd->speed) { case SPEED_1000: + if (ecmd->duplex == DUPLEX_FULL) + setting = SUPPORTED_1000baseT_Full; + else if (ecmd->duplex == DUPLEX_HALF) + setting = SUPPORTED_1000baseT_Half; + else + return -EINVAL; break; case SPEED_100: + if (ecmd->duplex == DUPLEX_FULL) + setting = SUPPORTED_100baseT_Full; + else if (ecmd->duplex == DUPLEX_HALF) + setting = SUPPORTED_100baseT_Half; + else + return -EINVAL; + break; + case SPEED_10: - if (iscopper(hw) || hw->chip_id == CHIP_ID_GENESIS) + if (ecmd->duplex == DUPLEX_FULL) + setting = SUPPORTED_10baseT_Full; + else if (ecmd->duplex == DUPLEX_HALF) + setting = SUPPORTED_10baseT_Half; + else return -EINVAL; break; default: return -EINVAL; } + + if ((setting & supported) == 0) + return -EINVAL; + + skge->speed = ecmd->speed; + skge->duplex = ecmd->duplex; } skge->autoneg = ecmd->autoneg; - skge->speed = ecmd->speed; - skge->duplex = ecmd->duplex; skge->advertising = ecmd->advertising; if (netif_running(dev)) { @@ -2973,7 +2978,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, skge->flow_control = FLOW_MODE_SYMMETRIC; skge->duplex = -1; skge->speed = -1; - skge->advertising = skge_modes(hw); + skge->advertising = skge_supported_modes(hw); hw->dev[port] = dev; -- cgit v1.1 From 45bada65c2a0bcc00729646071e66042ced64998 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:12 -0700 Subject: [PATCH] skge: make Genesis/Broadcom code work Rewrite the code for handling the Broadcom PHY to something that works. Remove link polling because Broadcom and Yukon don't need it. When I wrote initial code, didn't have a genesis chipset based board to test, so it was a non-working guess. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 516 +++++++++++++++++++++++++++-------------------------- drivers/net/skge.h | 15 +- 2 files changed, 274 insertions(+), 257 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 81b8fe9..f11e0e1 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -54,7 +54,6 @@ #define TX_WATCHDOG (5 * HZ) #define NAPI_WEIGHT 64 #define BLINK_HZ (HZ/4) -#define LINK_POLL_HZ (HZ/10) MODULE_DESCRIPTION("SysKonnect Gigabit Ethernet driver"); MODULE_AUTHOR("Stephen Hemminger "); @@ -96,6 +95,7 @@ static void yukon_init(struct skge_hw *hw, int port); static void yukon_reset(struct skge_hw *hw, int port); static void genesis_mac_init(struct skge_hw *hw, int port); static void genesis_reset(struct skge_hw *hw, int port); +static void genesis_link_up(struct skge_port *skge); static const int txqaddr[] = { Q_XA1, Q_XA2 }; static const int rxqaddr[] = { Q_R1, Q_R2 }; @@ -950,8 +950,7 @@ static void genesis_init(struct skge_hw *hw) static void genesis_reset(struct skge_hw *hw, int port) { - int i; - u64 zero = 0; + const u8 zero[8] = { 0 }; /* reset the statistics module */ xm_write32(hw, port, XM_GP_PORT, XM_GP_RES_STAT); @@ -963,20 +962,100 @@ static void genesis_reset(struct skge_hw *hw, int port) /* disable Broadcom PHY IRQ */ xm_write16(hw, port, PHY_BCOM_INT_MASK, 0xffff); - xm_outhash(hw, port, XM_HSM, (u8 *) &zero); - for (i = 0; i < 15; i++) - xm_outaddr(hw, port, XM_EXM(i), (u8 *) &zero); - xm_outhash(hw, port, XM_SRC_CHK, (u8 *) &zero); + xm_outhash(hw, port, XM_HSM, zero); } -static void genesis_mac_init(struct skge_hw *hw, int port) +/* Convert mode to MII values */ +static const u16 phy_pause_map[] = { + [FLOW_MODE_NONE] = 0, + [FLOW_MODE_LOC_SEND] = PHY_AN_PAUSE_ASYM, + [FLOW_MODE_SYMMETRIC] = PHY_AN_PAUSE_CAP, + [FLOW_MODE_REM_SEND] = PHY_AN_PAUSE_CAP | PHY_AN_PAUSE_ASYM, +}; + + +/* Check status of Broadcom phy link */ +static void bcom_check_link(struct skge_hw *hw, int port) { - struct skge_port *skge = netdev_priv(hw->dev[port]); + struct net_device *dev = hw->dev[port]; + struct skge_port *skge = netdev_priv(dev); + u16 status; + + /* read twice because of latch */ + (void) xm_phy_read(hw, port, PHY_BCOM_STAT); + status = xm_phy_read(hw, port, PHY_BCOM_STAT); + + pr_debug("bcom_check_link status=0x%x\n", status); + + if ((status & PHY_ST_LSYNC) == 0) { + u16 cmd = xm_read16(hw, port, XM_MMU_CMD); + cmd &= ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX); + xm_write16(hw, port, XM_MMU_CMD, cmd); + /* dummy read to ensure writing */ + (void) xm_read16(hw, port, XM_MMU_CMD); + + if (netif_carrier_ok(dev)) + skge_link_down(skge); + } else { + if (skge->autoneg == AUTONEG_ENABLE && + (status & PHY_ST_AN_OVER)) { + u16 lpa = xm_phy_read(hw, port, PHY_BCOM_AUNE_LP); + u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); + + if (lpa & PHY_B_AN_RF) { + printk(KERN_NOTICE PFX "%s: remote fault\n", + dev->name); + return; + } + + /* Check Duplex mismatch */ + switch(aux & PHY_B_AS_AN_RES_MSK) { + case PHY_B_RES_1000FD: + skge->duplex = DUPLEX_FULL; + break; + case PHY_B_RES_1000HD: + skge->duplex = DUPLEX_HALF; + break; + default: + printk(KERN_NOTICE PFX "%s: duplex mismatch\n", + dev->name); + return; + } + + + /* We are using IEEE 802.3z/D5.0 Table 37-4 */ + switch (aux & PHY_B_AS_PAUSE_MSK) { + case PHY_B_AS_PAUSE_MSK: + skge->flow_control = FLOW_MODE_SYMMETRIC; + break; + case PHY_B_AS_PRR: + skge->flow_control = FLOW_MODE_REM_SEND; + break; + case PHY_B_AS_PRT: + skge->flow_control = FLOW_MODE_LOC_SEND; + break; + default: + skge->flow_control = FLOW_MODE_NONE; + } + + skge->speed = SPEED_1000; + } + + if (!netif_carrier_ok(dev)) + genesis_link_up(skge); + } +} + +/* Broadcom 5400 only supports giagabit! SysKonnect did not put an additional + * Phy on for 100 or 10Mbit operation + */ +static void bcom_phy_init(struct skge_port *skge, int jumbo) +{ + struct skge_hw *hw = skge->hw; + int port = skge->port; int i; - u32 r; - u16 id1; - u16 ctrl1, ctrl2, ctrl3, ctrl4, ctrl5; + u16 id1, r, ext, ctl; /* magic workaround patterns for Broadcom */ static const struct { @@ -992,6 +1071,110 @@ static void genesis_mac_init(struct skge_hw *hw, int port) { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, }; + pr_debug("bcom_phy_init\n"); + + /* read Id from external PHY (all have the same address) */ + id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); + + /* Optimize MDIO transfer by suppressing preamble. */ + r = xm_read16(hw, port, XM_MMU_CMD); + r |= XM_MMU_NO_PRE; + xm_write16(hw, port, XM_MMU_CMD,r); + + switch(id1) { + case PHY_BCOM_ID1_C0: + /* + * Workaround BCOM Errata for the C0 type. + * Write magic patterns to reserved registers. + */ + for (i = 0; i < ARRAY_SIZE(C0hack); i++) + xm_phy_write(hw, port, + C0hack[i].reg, C0hack[i].val); + + break; + case PHY_BCOM_ID1_A1: + /* + * Workaround BCOM Errata for the A1 type. + * Write magic patterns to reserved registers. + */ + for (i = 0; i < ARRAY_SIZE(A1hack); i++) + xm_phy_write(hw, port, + A1hack[i].reg, A1hack[i].val); + break; + } + + /* + * Workaround BCOM Errata (#10523) for all BCom PHYs. + * Disable Power Management after reset. + */ + r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); + r |= PHY_B_AC_DIS_PM; + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r); + + /* Dummy read */ + xm_read16(hw, port, XM_ISRC); + + ext = PHY_B_PEC_EN_LTR; /* enable tx led */ + ctl = PHY_CT_SP1000; /* always 1000mbit */ + + if (skge->autoneg == AUTONEG_ENABLE) { + /* + * Workaround BCOM Errata #1 for the C5 type. + * 1000Base-T Link Acquisition Failure in Slave Mode + * Set Repeater/DTE bit 10 of the 1000Base-T Control Register + */ + u16 adv = PHY_B_1000C_RD; + if (skge->advertising & ADVERTISED_1000baseT_Half) + adv |= PHY_B_1000C_AHD; + if (skge->advertising & ADVERTISED_1000baseT_Full) + adv |= PHY_B_1000C_AFD; + xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, adv); + + ctl |= PHY_CT_ANE | PHY_CT_RE_CFG; + } else { + if (skge->duplex == DUPLEX_FULL) + ctl |= PHY_CT_DUP_MD; + /* Force to slave */ + xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, PHY_B_1000C_MSE); + } + + /* Set autonegotiation pause parameters */ + xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, + phy_pause_map[skge->flow_control] | PHY_AN_CSMA); + + /* Handle Jumbo frames */ + if (jumbo) { + xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, + PHY_B_AC_TX_TST | PHY_B_AC_LONG_PACK); + + ext |= PHY_B_PEC_HIGH_LA; + + } + + xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext); + xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl); + + /* Use link status change interrrupt */ + xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK); + + bcom_check_link(hw, port); +} + +static void genesis_mac_init(struct skge_hw *hw, int port) +{ + struct net_device *dev = hw->dev[port]; + struct skge_port *skge = netdev_priv(dev); + int jumbo = hw->dev[port]->mtu > ETH_DATA_LEN; + int i; + u32 r; + const u8 zero[6] = { 0 }; + + /* Clear MIB counters */ + xm_write16(hw, port, XM_STAT_CMD, + XM_SC_CLR_RXC | XM_SC_CLR_TXC); + /* Clear two times according to Errata #3 */ + xm_write16(hw, port, XM_STAT_CMD, + XM_SC_CLR_RXC | XM_SC_CLR_TXC); /* initialize Rx, Tx and Link LED */ skge_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON); @@ -1009,9 +1192,7 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * GMII mode. */ spin_lock_bh(&hw->phy_lock); - - /* External Phy Handling */ - /* Take PHY out of reset. */ + /* Take external Phy out of reset */ r = skge_read32(hw, B2_GP_IO); if (port == 0) r |= GP_DIR_0|GP_IO_0; @@ -1020,57 +1201,47 @@ static void genesis_mac_init(struct skge_hw *hw, int port) skge_write32(hw, B2_GP_IO, r); skge_read32(hw, B2_GP_IO); + spin_unlock_bh(&hw->phy_lock); - /* Enable GMII mode on the XMAC. */ + /* Enable GMII interfac */ xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD); - id1 = xm_phy_read(hw, port, PHY_XMAC_ID1); + bcom_phy_init(skge, jumbo); - /* Optimize MDIO transfer by suppressing preamble. */ - xm_write16(hw, port, XM_MMU_CMD, - xm_read16(hw, port, XM_MMU_CMD) - | XM_MMU_NO_PRE); + /* Set Station Address */ + xm_outaddr(hw, port, XM_SA, dev->dev_addr); - if (id1 == PHY_BCOM_ID1_C0) { - /* - * Workaround BCOM Errata for the C0 type. - * Write magic patterns to reserved registers. - */ - for (i = 0; i < ARRAY_SIZE(C0hack); i++) - xm_phy_write(hw, port, - C0hack[i].reg, C0hack[i].val); + /* We don't use match addresses so clear */ + for (i = 1; i < 16; i++) + xm_outaddr(hw, port, XM_EXM(i), zero); + + /* configure Rx High Water Mark (XM_RX_HI_WM) */ + xm_write16(hw, port, XM_RX_HI_WM, 1450); + + /* We don't need the FCS appended to the packet. */ + r = XM_RX_LENERR_OK | XM_RX_STRIP_FCS; + if (jumbo) + r |= XM_RX_BIG_PK_OK; - } else if (id1 == PHY_BCOM_ID1_A1) { + if (skge->duplex == DUPLEX_HALF) { /* - * Workaround BCOM Errata for the A1 type. - * Write magic patterns to reserved registers. + * If in manual half duplex mode the other side might be in + * full duplex mode, so ignore if a carrier extension is not seen + * on frames received */ - for (i = 0; i < ARRAY_SIZE(A1hack); i++) - xm_phy_write(hw, port, - A1hack[i].reg, A1hack[i].val); + r |= XM_RX_DIS_CEXT; } + xm_write16(hw, port, XM_RX_CMD, r); - /* - * Workaround BCOM Errata (#10523) for all BCom PHYs. - * Disable Power Management after reset. - */ - r = xm_phy_read(hw, port, PHY_BCOM_AUX_CTRL); - xm_phy_write(hw, port, PHY_BCOM_AUX_CTRL, r | PHY_B_AC_DIS_PM); - - - /* Dummy read */ - xm_read16(hw, port, XM_ISRC); - - r = xm_read32(hw, port, XM_MODE); - xm_write32(hw, port, XM_MODE, r|XM_MD_CSA); - - /* We don't need the FCS appended to the packet. */ - r = xm_read16(hw, port, XM_RX_CMD); - xm_write16(hw, port, XM_RX_CMD, r | XM_RX_STRIP_FCS); /* We want short frames padded to 60 bytes. */ - r = xm_read16(hw, port, XM_TX_CMD); - xm_write16(hw, port, XM_TX_CMD, r | XM_TX_AUTO_PAD); + xm_write16(hw, port, XM_TX_CMD, XM_TX_AUTO_PAD); + + /* + * Bump up the transmit threshold. This helps hold off transmit + * underruns when we're blasting traffic from both ports at once. + */ + xm_write16(hw, port, XM_TX_THR, 512); /* * Enable the reception of all error frames. This is is @@ -1086,19 +1257,22 @@ static void genesis_mac_init(struct skge_hw *hw, int port) * case the XMAC will start transfering frames out of the * RX FIFO as soon as the FIFO threshold is reached. */ - r = xm_read32(hw, port, XM_MODE); - xm_write32(hw, port, XM_MODE, - XM_MD_RX_CRCE|XM_MD_RX_LONG|XM_MD_RX_RUNT| - XM_MD_RX_ERR|XM_MD_RX_IRLE); + xm_write32(hw, port, XM_MODE, XM_DEF_MODE); - xm_outaddr(hw, port, XM_SA, hw->dev[port]->dev_addr); - xm_outaddr(hw, port, XM_EXM(0), hw->dev[port]->dev_addr); /* - * Bump up the transmit threshold. This helps hold off transmit - * underruns when we're blasting traffic from both ports at once. + * Initialize the Receive Counter Event Mask (XM_RX_EV_MSK) + * - Enable all bits excepting 'Octets Rx OK Low CntOv' + * and 'Octets Rx OK Hi Cnt Ov'. */ - xm_write16(hw, port, XM_TX_THR, 512); + xm_write32(hw, port, XM_RX_EV_MSK, XMR_DEF_MSK); + + /* + * Initialize the Transmit Counter Event Mask (XM_TX_EV_MSK) + * - Enable all bits excepting 'Octets Tx OK Low CntOv' + * and 'Octets Tx OK Hi Cnt Ov'. + */ + xm_write32(hw, port, XM_TX_EV_MSK, XMT_DEF_MSK); /* Configure MAC arbiter */ skge_write16(hw, B3_MA_TO_CTRL, MA_RST_CLR); @@ -1124,89 +1298,14 @@ static void genesis_mac_init(struct skge_hw *hw, int port) skge_write16(hw, SK_REG(port, TX_MFF_CTRL1), MFF_TX_CTRL_DEF); skge_write8(hw, SK_REG(port, TX_MFF_CTRL2), MFF_ENA_OP_MD); - if (hw->dev[port]->mtu > ETH_DATA_LEN) { + if (jumbo) { /* Enable frame flushing if jumbo frames used */ skge_write16(hw, SK_REG(port,RX_MFF_CTRL1), MFF_ENA_FLUSH); } else { /* enable timeout timers if normal frames */ skge_write16(hw, B3_PA_CTRL, - port == 0 ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); + (port == 0) ? PA_ENA_TO_TX1 : PA_ENA_TO_TX2); } - - - r = xm_read16(hw, port, XM_RX_CMD); - if (hw->dev[port]->mtu > ETH_DATA_LEN) - xm_write16(hw, port, XM_RX_CMD, r | XM_RX_BIG_PK_OK); - else - xm_write16(hw, port, XM_RX_CMD, r & ~(XM_RX_BIG_PK_OK)); - - /* Broadcom phy initialization */ - ctrl1 = PHY_CT_SP1000; - ctrl2 = 0; - ctrl3 = PHY_AN_CSMA; - ctrl4 = PHY_B_PEC_EN_LTR; - ctrl5 = PHY_B_AC_TX_TST; - - if (skge->autoneg == AUTONEG_ENABLE) { - /* - * Workaround BCOM Errata #1 for the C5 type. - * 1000Base-T Link Acquisition Failure in Slave Mode - * Set Repeater/DTE bit 10 of the 1000Base-T Control Register - */ - ctrl2 |= PHY_B_1000C_RD; - if (skge->advertising & ADVERTISED_1000baseT_Half) - ctrl2 |= PHY_B_1000C_AHD; - if (skge->advertising & ADVERTISED_1000baseT_Full) - ctrl2 |= PHY_B_1000C_AFD; - - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - ctrl3 |= PHY_B_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - ctrl3 |= PHY_B_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - ctrl3 |= PHY_B_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - ctrl3 |= PHY_B_P_BOTH_MD; - break; - } - - /* Restart Auto-negotiation */ - ctrl1 |= PHY_CT_ANE | PHY_CT_RE_CFG; - } else { - if (skge->duplex == DUPLEX_FULL) - ctrl1 |= PHY_CT_DUP_MD; - - ctrl2 |= PHY_B_1000C_MSE; /* set it to Slave */ - } - - xm_phy_write(hw, port, PHY_BCOM_1000T_CTRL, ctrl2); - xm_phy_write(hw, port, PHY_BCOM_AUNE_ADV, ctrl3); - - if (skge->netdev->mtu > ETH_DATA_LEN) { - ctrl4 |= PHY_B_PEC_HIGH_LA; - ctrl5 |= PHY_B_AC_LONG_PACK; - - xm_phy_write(hw, port,PHY_BCOM_AUX_CTRL, ctrl5); - } - - xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ctrl4); - xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl1); - spin_unlock_bh(&hw->phy_lock); - - /* Clear MIB counters */ - xm_write16(hw, port, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); - /* Clear two times according to Errata #3 */ - xm_write16(hw, port, XM_STAT_CMD, - XM_SC_CLR_RXC | XM_SC_CLR_TXC); - - /* Start polling for link status */ - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); } static void genesis_stop(struct skge_port *skge) @@ -1331,23 +1430,6 @@ static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg) return gma_read16(hw, port, GM_SMI_DATA); } -static void genesis_link_down(struct skge_port *skge) -{ - struct skge_hw *hw = skge->hw; - int port = skge->port; - - pr_debug("genesis_link_down\n"); - - xm_write16(hw, port, XM_MMU_CMD, - xm_read16(hw, port, XM_MMU_CMD) - & ~(XM_MMU_ENA_RX | XM_MMU_ENA_TX)); - - /* dummy read to ensure writing */ - (void) xm_read16(hw, port, XM_MMU_CMD); - - skge_link_down(skge); -} - static void genesis_link_up(struct skge_port *skge) { struct skge_hw *hw = skge->hw; @@ -1430,18 +1512,23 @@ static void genesis_link_up(struct skge_port *skge) } -static void genesis_bcom_intr(struct skge_port *skge) +static inline void bcom_phy_intr(struct skge_port *skge) { struct skge_hw *hw = skge->hw; int port = skge->port; - u16 stat = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); + u16 isrc; + + isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); + pr_debug("bcom_phy_interrupt status=0x%x\n", isrc); - pr_debug("genesis_bcom intr stat=%x\n", stat); + if (isrc & PHY_B_IS_PSE) + printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n", + hw->dev[port]->name); /* Workaround BCom Errata: * enable and disable loopback mode if "NO HCD" occurs. */ - if (stat & PHY_B_IS_NO_HDCL) { + if (isrc & PHY_B_IS_NO_HDCL) { u16 ctrl = xm_phy_read(hw, port, PHY_BCOM_CTRL); xm_phy_write(hw, port, PHY_BCOM_CTRL, ctrl | PHY_CT_LOOP); @@ -1449,57 +1536,9 @@ static void genesis_bcom_intr(struct skge_port *skge) ctrl & ~PHY_CT_LOOP); } - stat = xm_phy_read(hw, port, PHY_BCOM_STAT); - if (stat & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) { - u16 aux = xm_phy_read(hw, port, PHY_BCOM_AUX_STAT); - if ( !(aux & PHY_B_AS_LS) && netif_carrier_ok(skge->netdev)) - genesis_link_down(skge); - - else if (stat & PHY_B_IS_LST_CHANGE) { - if (aux & PHY_B_AS_AN_C) { - switch (aux & PHY_B_AS_AN_RES_MSK) { - case PHY_B_RES_1000FD: - skge->duplex = DUPLEX_FULL; - break; - case PHY_B_RES_1000HD: - skge->duplex = DUPLEX_HALF; - break; - } - - switch (aux & PHY_B_AS_PAUSE_MSK) { - case PHY_B_AS_PAUSE_MSK: - skge->flow_control = FLOW_MODE_SYMMETRIC; - break; - case PHY_B_AS_PRR: - skge->flow_control = FLOW_MODE_REM_SEND; - break; - case PHY_B_AS_PRT: - skge->flow_control = FLOW_MODE_LOC_SEND; - break; - default: - skge->flow_control = FLOW_MODE_NONE; - } - skge->speed = SPEED_1000; - } - genesis_link_up(skge); - } - else - mod_timer(&skge->link_check, jiffies + LINK_POLL_HZ); - } -} - -/* Perodic poll of phy status to check for link transistion */ -static void skge_link_timer(unsigned long __arg) -{ - struct skge_port *skge = (struct skge_port *) __arg; - struct skge_hw *hw = skge->hw; - - if (hw->chip_id != CHIP_ID_GENESIS || !netif_running(skge->netdev)) - return; + if (isrc & (PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) + bcom_check_link(hw, port); - spin_lock_bh(&hw->phy_lock); - genesis_bcom_intr(skge); - spin_unlock_bh(&hw->phy_lock); } /* Marvell Phy Initailization */ @@ -1547,41 +1586,12 @@ static void yukon_init(struct skge_hw *hw, int port) adv |= PHY_M_AN_10_FD; if (skge->advertising & ADVERTISED_10baseT_Half) adv |= PHY_M_AN_10_HD; - - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - adv |= PHY_B_P_NO_PAUSE; - break; - case FLOW_MODE_LOC_SEND: - adv |= PHY_B_P_ASYM_MD; - break; - case FLOW_MODE_SYMMETRIC: - adv |= PHY_B_P_SYM_MD; - break; - case FLOW_MODE_REM_SEND: - adv |= PHY_B_P_BOTH_MD; - break; - } - } else { /* special defines for FIBER (88E1011S only) */ + } else /* special defines for FIBER (88E1011S only) */ adv |= PHY_M_AN_1000X_AHD | PHY_M_AN_1000X_AFD; - /* Set Flow-control capabilities */ - switch (skge->flow_control) { - case FLOW_MODE_NONE: - adv |= PHY_M_P_NO_PAUSE_X; - break; - case FLOW_MODE_LOC_SEND: - adv |= PHY_M_P_ASYM_MD_X; - break; - case FLOW_MODE_SYMMETRIC: - adv |= PHY_M_P_SYM_MD_X; - break; - case FLOW_MODE_REM_SEND: - adv |= PHY_M_P_BOTH_MD_X; - break; - } - } + /* Set Flow-control capabilities */ + adv |= phy_pause_map[skge->flow_control]; + /* Restart Auto-negotiation */ ctrl |= PHY_CT_ANE | PHY_CT_RE_CFG; } else { @@ -2090,7 +2100,6 @@ static int skge_down(struct net_device *dev) netif_stop_queue(dev); del_timer_sync(&skge->led_blink); - del_timer_sync(&skge->link_check); /* Stop transmitter */ skge_write8(hw, Q_ADDR(txqaddr[port], Q_CSR), CSR_STOP); @@ -2325,6 +2334,8 @@ static void genesis_set_multicast(struct net_device *dev) u32 mode; u8 filter[8]; + pr_debug("genesis_set_multicast flags=%x count=%d\n", dev->flags, dev->mc_count); + mode = xm_read32(hw, port, XM_MODE); mode |= XM_MD_ENA_HASH; if (dev->flags & IFF_PROMISC) @@ -2337,16 +2348,15 @@ static void genesis_set_multicast(struct net_device *dev) else { memset(filter, 0, sizeof(filter)); for (i = 0; list && i < count; i++, list = list->next) { - u32 crc = crc32_le(~0, list->dmi_addr, ETH_ALEN); - u8 bit = 63 - (crc & 63); - + u32 crc, bit; + crc = ether_crc_le(ETH_ALEN, list->dmi_addr); + bit = ~crc & 0x3f; filter[bit/8] |= 1 << (bit%8); } } - xm_outhash(hw, port, XM_HSM, filter); - xm_write32(hw, port, XM_MODE, mode); + xm_outhash(hw, port, XM_HSM, filter); } static void yukon_set_multicast(struct net_device *dev) @@ -2667,7 +2677,7 @@ static void skge_extirq(unsigned long data) if (hw->chip_id != CHIP_ID_GENESIS) yukon_phy_intr(skge); else - genesis_bcom_intr(skge); + bcom_phy_intr(skge); } } spin_unlock(&hw->phy_lock); @@ -2986,10 +2996,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, spin_lock_init(&skge->tx_lock); - init_timer(&skge->link_check); - skge->link_check.function = skge_link_timer; - skge->link_check.data = (unsigned long) skge; - init_timer(&skge->led_blink); skge->led_blink.function = skge_blink_timer; skge->led_blink.data = (unsigned long) skge; diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 6f3a4b5..6b9a2eb 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -1225,6 +1225,16 @@ enum { PHY_B_PES_MLT3_ER = 1<<0, /* Bit 0: MLT3 code Error */ }; +/* PHY_BCOM_AUNE_ADV 16 bit r/w Auto-Negotiation Advertisement *****/ +/* PHY_BCOM_AUNE_LP 16 bit r/o Link Partner Ability Reg *****/ +enum { + PHY_B_AN_RF = 1<<13, /* Bit 13: Remote Fault */ + + PHY_B_AN_ASP = 1<<11, /* Bit 11: Asymmetric Pause */ + PHY_B_AN_PC = 1<<10, /* Bit 10: Pause Capable */ +}; + + /***** PHY_BCOM_FC_CTR 16 bit r/w False Carrier Counter *****/ enum { PHY_B_FC_CTR = 0xff, /* Bit 7..0: False Carrier Counter */ @@ -1285,7 +1295,9 @@ enum { PHY_B_IS_LST_CHANGE = 1<<1, /* Bit 1: Link Status Changed */ PHY_B_IS_CRC_ER = 1<<0, /* Bit 0: CRC Error */ }; -#define PHY_B_DEF_MSK (~(PHY_B_IS_AN_PR | PHY_B_IS_LST_CHANGE)) +#define PHY_B_DEF_MSK \ + (~(PHY_B_IS_PSE | PHY_B_IS_AN_PR | PHY_B_IS_DUP_CHANGE | \ + PHY_B_IS_LSP_CHANGE | PHY_B_IS_LST_CHANGE)) /* Pause Bits (PHY_B_AN_ASP and PHY_B_AN_PC) encoding */ enum { @@ -2489,7 +2501,6 @@ struct skge_port { dma_addr_t dma; unsigned long mem_size; - struct timer_list link_check; struct timer_list led_blink; }; -- cgit v1.1 From 7e676d9136d89d0cdf661de4b9a5f8955af94e03 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:13 -0700 Subject: [PATCH] skge: add PHY related debug messages Cleanup messages (for debug) about PHY interrrupts, because when user can't get driver working that is often the problem. Use a consistent way of enabling interrupts by port. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 56 ++++++++++++++++++++++++++++++++---------------------- drivers/net/skge.h | 4 ++-- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index f11e0e1..290d6aa 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -97,10 +97,12 @@ static void genesis_mac_init(struct skge_hw *hw, int port); static void genesis_reset(struct skge_hw *hw, int port); static void genesis_link_up(struct skge_port *skge); +/* Avoid conditionals by using array */ static const int txqaddr[] = { Q_XA1, Q_XA2 }; static const int rxqaddr[] = { Q_R1, Q_R2 }; static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; +static const u32 portirqmask[] = { IS_PORT_1, IS_PORT_2 }; /* Don't need to look at whole 16K. * last interesting register is descriptor poll timer. @@ -1382,7 +1384,9 @@ static void genesis_mac_intr(struct skge_hw *hw, int port) struct skge_port *skge = netdev_priv(hw->dev[port]); u16 status = xm_read16(hw, port, XM_ISRC); - pr_debug("genesis_intr status %x\n", status); + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", + skge->netdev->name, status); if (status & XM_IS_TXF_UR) { xm_write32(hw, port, XM_MODE, XM_MD_FTF); @@ -1446,6 +1450,7 @@ static void genesis_link_up(struct skge_port *skge) */ if (skge->flow_control == FLOW_MODE_NONE || skge->flow_control == FLOW_MODE_LOC_SEND) + /* Disable Pause Frame Reception */ cmd |= XM_MMU_IGN_PF; else /* Enable Pause Frame Reception */ @@ -1519,7 +1524,9 @@ static inline void bcom_phy_intr(struct skge_port *skge) u16 isrc; isrc = xm_phy_read(hw, port, PHY_BCOM_INT_STAT); - pr_debug("bcom_phy_interrupt status=0x%x\n", isrc); + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x\n", + skge->netdev->name, isrc); if (isrc & PHY_B_IS_PSE) printk(KERN_ERR PFX "%s: uncorrectable pair swap error\n", @@ -1823,10 +1830,14 @@ static void yukon_get_stats(struct skge_port *skge, u64 *data) static void yukon_mac_intr(struct skge_hw *hw, int port) { - struct skge_port *skge = netdev_priv(hw->dev[port]); + struct net_device *dev = hw->dev[port]; + struct skge_port *skge = netdev_priv(dev); u8 status = skge_read8(hw, SK_REG(port, GMAC_IRQ_SRC)); - pr_debug("yukon_intr status %x\n", status); + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: mac interrupt status 0x%x\n", + dev->name, status); + if (status & GM_IS_RX_FF_OR) { ++skge->net_stats.rx_fifo_errors; gma_write8(hw, port, RX_GMF_CTRL_T, GMF_CLI_RX_FO); @@ -1908,7 +1919,10 @@ static void yukon_phy_intr(struct skge_port *skge) istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT); phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT); - pr_debug("yukon phy intr istat=%x phy_stat=%x\n", istatus, phystat); + + if (netif_msg_intr(skge)) + printk(KERN_DEBUG PFX "%s: phy interrupt status 0x%x 0x%x\n", + skge->netdev->name, istatus, phystat); if (istatus & PHY_M_IS_AN_COMPL) { if (gm_phy_read(hw, port, PHY_MARV_AUNE_LP) @@ -2055,6 +2069,10 @@ static int skge_up(struct net_device *dev) skge->tx_avail = skge->tx_ring.count - 1; + /* Enable IRQ from port */ + hw->intr_mask |= portirqmask[port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + /* Initialze MAC */ if (hw->chip_id == CHIP_ID_GENESIS) genesis_mac_init(hw, port); @@ -2449,7 +2467,8 @@ static int skge_poll(struct net_device *dev, int *budget) unsigned int to_do = min(dev->quota, *budget); unsigned int work_done = 0; int done; - static const u32 irqmask[] = { IS_PORT_1, IS_PORT_2 }; + + pr_debug("skge_poll\n"); for (e = ring->to_clean; e != ring->to_use && work_done < to_do; e = e->next) { @@ -2512,10 +2531,9 @@ static int skge_poll(struct net_device *dev, int *budget) if (done) { local_irq_disable(); - hw->intr_mask |= irqmask[skge->port]; - /* Order is important since data can get interrupted */ - skge_write32(hw, B0_IMSK, hw->intr_mask); __netif_rx_complete(dev); + hw->intr_mask |= portirqmask[skge->port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); local_irq_enable(); } @@ -2697,19 +2715,14 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_NONE; status &= hw->intr_mask; - - if ((status & IS_R1_F) && netif_rx_schedule_prep(hw->dev[0])) { - status &= ~IS_R1_F; + if (status & IS_R1_F) { hw->intr_mask &= ~IS_R1_F; - skge_write32(hw, B0_IMSK, hw->intr_mask); - __netif_rx_schedule(hw->dev[0]); + netif_rx_schedule(hw->dev[0]); } - if ((status & IS_R2_F) && netif_rx_schedule_prep(hw->dev[1])) { - status &= ~IS_R2_F; + if (status & IS_R2_F) { hw->intr_mask &= ~IS_R2_F; - skge_write32(hw, B0_IMSK, hw->intr_mask); - __netif_rx_schedule(hw->dev[1]); + netif_rx_schedule(hw->dev[1]); } if (status & IS_XA1_F) @@ -2732,8 +2745,7 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) tasklet_schedule(&hw->ext_tasklet); } - if (status) - skge_write32(hw, B0_IMSK, hw->intr_mask); + skge_write32(hw, B0_IMSK, hw->intr_mask); return IRQ_HANDLED; } @@ -2918,9 +2930,7 @@ static int skge_reset(struct skge_hw *hw) skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); skge_write32(hw, B2_IRQM_CTRL, TIM_START); - hw->intr_mask = IS_HW_ERR | IS_EXT_REG | IS_PORT_1; - if (hw->ports > 1) - hw->intr_mask |= IS_PORT_2; + hw->intr_mask = IS_HW_ERR | IS_EXT_REG; skge_write32(hw, B0_IMSK, hw->intr_mask); if (hw->chip_id != CHIP_ID_GENESIS) diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 6b9a2eb..ba6dfd2 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -2317,8 +2317,8 @@ enum { }; #define XM_PAUSE_MODE (XM_MD_SPOE_E | XM_MD_SPOL_I | XM_MD_SPOH_I) -#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ - XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA | XM_MD_CAA) +#define XM_DEF_MODE (XM_MD_RX_RUNT | XM_MD_RX_IRLE | XM_MD_RX_LONG |\ + XM_MD_RX_CRCE | XM_MD_RX_ERR | XM_MD_CSA) /* XM_STAT_CMD 16 bit r/w Statistics Command Register */ enum { -- cgit v1.1 From d25f5a6774c3c567b11f8637a787603a62d102b1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:14 -0700 Subject: [PATCH] skge: handle Tx/Rx arbiter timeout Need to handle receive and transmit packet arbiter timeouts. Transmit arbiter timeouts happens when Gigabit sends to 100Mbit port on same switch and pause occurs. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 18 ++++++++++++++++++ drivers/net/skge.h | 7 +++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 290d6aa..9f24714 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -2731,6 +2731,24 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) if (status & IS_XA2_F) skge_tx_intr(hw->dev[1]); + if (status & IS_PA_TO_RX1) { + struct skge_port *skge = netdev_priv(hw->dev[0]); + ++skge->net_stats.rx_over_errors; + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX1); + } + + if (status & IS_PA_TO_RX2) { + struct skge_port *skge = netdev_priv(hw->dev[1]); + ++skge->net_stats.rx_over_errors; + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_RX2); + } + + if (status & IS_PA_TO_TX1) + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX1); + + if (status & IS_PA_TO_TX2) + skge_write16(hw, B3_PA_CTRL, PA_CLR_TO_TX2); + if (status & IS_MAC1) skge_mac_intr(hw, 0); diff --git a/drivers/net/skge.h b/drivers/net/skge.h index ba6dfd2..37323cd 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -203,8 +203,11 @@ enum { IS_XA2_F = 1<<1, /* Q_XA2 End of Frame */ IS_XA2_C = 1<<0, /* Q_XA2 Encoding Error */ - IS_PORT_1 = IS_XA1_F| IS_R1_F| IS_MAC1, - IS_PORT_2 = IS_XA2_F| IS_R2_F| IS_MAC2, + IS_TO_PORT1 = IS_PA_TO_RX1 | IS_PA_TO_TX1, + IS_TO_PORT2 = IS_PA_TO_RX2 | IS_PA_TO_TX2, + + IS_PORT_1 = IS_XA1_F| IS_R1_F | IS_TO_PORT1 | IS_MAC1, + IS_PORT_2 = IS_XA2_F| IS_R2_F | IS_TO_PORT2 | IS_MAC2, }; -- cgit v1.1 From 19a33d4e6be2b627487676a69638e189e833675f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:15 -0700 Subject: [PATCH] skge: Rx buffer optimization Optimize the receive buffer management code to replenish the buffers immediately (like tg3). Signed-off-by: Stephen Hemmminger --- drivers/net/skge.c | 265 ++++++++++++++++++++++++++++++++--------------------- drivers/net/skge.h | 1 + 2 files changed, 163 insertions(+), 103 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 9f24714..9d4ae78 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -49,6 +49,8 @@ #define DEFAULT_RX_RING_SIZE 512 #define MAX_TX_RING_SIZE 1024 #define MAX_RX_RING_SIZE 4096 +#define RX_COPY_THRESHOLD 128 +#define RX_BUF_SIZE 1536 #define PHY_RETRIES 1000 #define ETH_JUMBO_MTU 9000 #define TX_WATCHDOG (5 * HZ) @@ -746,6 +748,7 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) for (i = 0, e = ring->start, d = vaddr; i < ring->count; i++, e++, d++) { e->desc = d; + e->skb = NULL; if (i == ring->count - 1) { e->next = ring->start; d->next_offset = base; @@ -759,24 +762,23 @@ static int skge_ring_alloc(struct skge_ring *ring, void *vaddr, u64 base) return 0; } -/* Setup buffer for receiving */ -static inline int skge_rx_alloc(struct skge_port *skge, - struct skge_element *e) +static struct sk_buff *skge_rx_alloc(struct net_device *dev, unsigned int size) { - unsigned long bufsize = skge->netdev->mtu + ETH_HLEN; /* VLAN? */ - struct skge_rx_desc *rd = e->desc; - struct sk_buff *skb; - u64 map; + struct sk_buff *skb = dev_alloc_skb(size); - skb = dev_alloc_skb(bufsize + NET_IP_ALIGN); - if (unlikely(!skb)) { - printk(KERN_DEBUG PFX "%s: out of memory for receive\n", - skge->netdev->name); - return -ENOMEM; + if (likely(skb)) { + skb->dev = dev; + skb_reserve(skb, NET_IP_ALIGN); } + return skb; +} - skb->dev = skge->netdev; - skb_reserve(skb, NET_IP_ALIGN); +/* Allocate and setup a new buffer for receiving */ +static void skge_rx_setup(struct skge_port *skge, struct skge_element *e, + struct sk_buff *skb, unsigned int bufsize) +{ + struct skge_rx_desc *rd = e->desc; + u64 map; map = pci_map_single(skge->hw->pdev, skb->data, bufsize, PCI_DMA_FROMDEVICE); @@ -794,55 +796,69 @@ static inline int skge_rx_alloc(struct skge_port *skge, rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | bufsize; pci_unmap_addr_set(e, mapaddr, map); pci_unmap_len_set(e, maplen, bufsize); - return 0; } -/* Free all unused buffers in receive ring, assumes receiver stopped */ +/* Resume receiving using existing skb, + * Note: DMA address is not changed by chip. + * MTU not changed while receiver active. + */ +static void skge_rx_reuse(struct skge_element *e, unsigned int size) +{ + struct skge_rx_desc *rd = e->desc; + + rd->csum2 = 0; + rd->csum2_start = ETH_HLEN; + + wmb(); + + rd->control = BMU_OWN | BMU_STF | BMU_IRQ_EOF | BMU_TCP_CHECK | size; +} + + +/* Free all buffers in receive ring, assumes receiver stopped */ static void skge_rx_clean(struct skge_port *skge) { struct skge_hw *hw = skge->hw; struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; - for (e = ring->to_clean; e != ring->to_use; e = e->next) { + e = ring->start; + do { struct skge_rx_desc *rd = e->desc; rd->control = 0; - - pci_unmap_single(hw->pdev, - pci_unmap_addr(e, mapaddr), - pci_unmap_len(e, maplen), - PCI_DMA_FROMDEVICE); - dev_kfree_skb(e->skb); - e->skb = NULL; - } - ring->to_clean = e; + if (e->skb) { + pci_unmap_single(hw->pdev, + pci_unmap_addr(e, mapaddr), + pci_unmap_len(e, maplen), + PCI_DMA_FROMDEVICE); + dev_kfree_skb(e->skb); + e->skb = NULL; + } + } while ((e = e->next) != ring->start); } + /* Allocate buffers for receive ring - * For receive: to_use is refill location - * to_clean is next received frame. - * - * if (to_use == to_clean) - * then ring all frames in ring need buffers - * if (to_use->next == to_clean) - * then ring all frames in ring have buffers + * For receive: to_clean is next received frame. */ static int skge_rx_fill(struct skge_port *skge) { struct skge_ring *ring = &skge->rx_ring; struct skge_element *e; - int ret = 0; + unsigned int bufsize = skge->rx_buf_size; - for (e = ring->to_use; e->next != ring->to_clean; e = e->next) { - if (skge_rx_alloc(skge, e)) { - ret = 1; - break; - } + e = ring->start; + do { + struct sk_buff *skb = skge_rx_alloc(skge->netdev, bufsize); - } - ring->to_use = e; + if (!skb) + return -ENOMEM; + + skge_rx_setup(skge, e, skb, bufsize); + } while ( (e = e->next) != ring->start); - return ret; + ring->to_clean = ring->start; + return 0; } static void skge_link_up(struct skge_port *skge) @@ -2048,6 +2064,12 @@ static int skge_up(struct net_device *dev) if (netif_msg_ifup(skge)) printk(KERN_INFO PFX "%s: enabling interface\n", dev->name); + if (dev->mtu > RX_BUF_SIZE) + skge->rx_buf_size = dev->mtu + ETH_HLEN + NET_IP_ALIGN; + else + skge->rx_buf_size = RX_BUF_SIZE; + + rx_size = skge->rx_ring.count * sizeof(struct skge_rx_desc); tx_size = skge->tx_ring.count * sizeof(struct skge_tx_desc); skge->mem_size = tx_size + rx_size; @@ -2060,7 +2082,8 @@ static int skge_up(struct net_device *dev) if ((err = skge_ring_alloc(&skge->rx_ring, skge->mem, skge->dma))) goto free_pci_mem; - if (skge_rx_fill(skge)) + err = skge_rx_fill(skge); + if (err) goto free_rx_ring; if ((err = skge_ring_alloc(&skge->tx_ring, skge->mem + rx_size, @@ -2284,6 +2307,7 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) static inline void skge_tx_free(struct skge_hw *hw, struct skge_element *e) { + /* This ring element can be skb or fragment */ if (e->skb) { pci_unmap_single(hw->pdev, pci_unmap_addr(e, mapaddr), @@ -2328,16 +2352,17 @@ static void skge_tx_timeout(struct net_device *dev) static int skge_change_mtu(struct net_device *dev, int new_mtu) { int err = 0; + int running = netif_running(dev); if (new_mtu < ETH_ZLEN || new_mtu > ETH_JUMBO_MTU) return -EINVAL; - dev->mtu = new_mtu; - if (netif_running(dev)) { + if (running) skge_down(dev); + dev->mtu = new_mtu; + if (running) skge_up(dev); - } return err; } @@ -2436,28 +2461,76 @@ static void skge_rx_error(struct skge_port *skge, int slot, printk(KERN_DEBUG PFX "%s: rx err, slot %d control 0x%x status 0x%x\n", skge->netdev->name, slot, control, status); - if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) - || (control & BMU_BBC) > skge->netdev->mtu + VLAN_ETH_HLEN) + if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF)) skge->net_stats.rx_length_errors++; - else { - if (skge->hw->chip_id == CHIP_ID_GENESIS) { - if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) - skge->net_stats.rx_length_errors++; - if (status & XMR_FS_FRA_ERR) - skge->net_stats.rx_frame_errors++; - if (status & XMR_FS_FCS_ERR) - skge->net_stats.rx_crc_errors++; - } else { - if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) - skge->net_stats.rx_length_errors++; - if (status & GMR_FS_FRAGMENT) - skge->net_stats.rx_frame_errors++; - if (status & GMR_FS_CRC_ERR) - skge->net_stats.rx_crc_errors++; + else if (skge->hw->chip_id == CHIP_ID_GENESIS) { + if (status & (XMR_FS_RUNT|XMR_FS_LNG_ERR)) + skge->net_stats.rx_length_errors++; + if (status & XMR_FS_FRA_ERR) + skge->net_stats.rx_frame_errors++; + if (status & XMR_FS_FCS_ERR) + skge->net_stats.rx_crc_errors++; + } else { + if (status & (GMR_FS_LONG_ERR|GMR_FS_UN_SIZE)) + skge->net_stats.rx_length_errors++; + if (status & GMR_FS_FRAGMENT) + skge->net_stats.rx_frame_errors++; + if (status & GMR_FS_CRC_ERR) + skge->net_stats.rx_crc_errors++; + } +} + +/* Get receive buffer from descriptor. + * Handles copy of small buffers and reallocation failures + */ +static inline struct sk_buff *skge_rx_get(struct skge_port *skge, + struct skge_element *e, + unsigned int len) +{ + struct sk_buff *nskb, *skb; + + if (len < RX_COPY_THRESHOLD) { + nskb = skge_rx_alloc(skge->netdev, len + NET_IP_ALIGN); + if (unlikely(!nskb)) + return NULL; + + pci_dma_sync_single_for_cpu(skge->hw->pdev, + pci_unmap_addr(e, mapaddr), + len, PCI_DMA_FROMDEVICE); + memcpy(nskb->data, e->skb->data, len); + pci_dma_sync_single_for_device(skge->hw->pdev, + pci_unmap_addr(e, mapaddr), + len, PCI_DMA_FROMDEVICE); + + if (skge->rx_csum) { + struct skge_rx_desc *rd = e->desc; + nskb->csum = le16_to_cpu(rd->csum2); + nskb->ip_summed = CHECKSUM_HW; + } + skge_rx_reuse(e, skge->rx_buf_size); + return nskb; + } else { + nskb = skge_rx_alloc(skge->netdev, skge->rx_buf_size); + if (unlikely(!nskb)) + return NULL; + + pci_unmap_single(skge->hw->pdev, + pci_unmap_addr(e, mapaddr), + pci_unmap_len(e, maplen), + PCI_DMA_FROMDEVICE); + skb = e->skb; + if (skge->rx_csum) { + struct skge_rx_desc *rd = e->desc; + skb->csum = le16_to_cpu(rd->csum2); + skb->ip_summed = CHECKSUM_HW; } + + skge_rx_setup(skge, e, nskb, skge->rx_buf_size); + return skb; } } + static int skge_poll(struct net_device *dev, int *budget) { struct skge_port *skge = netdev_priv(dev); @@ -2466,14 +2539,12 @@ static int skge_poll(struct net_device *dev, int *budget) struct skge_element *e; unsigned int to_do = min(dev->quota, *budget); unsigned int work_done = 0; - int done; pr_debug("skge_poll\n"); - for (e = ring->to_clean; e != ring->to_use && work_done < to_do; - e = e->next) { + for (e = ring->to_clean; work_done < to_do; e = e->next) { struct skge_rx_desc *rd = e->desc; - struct sk_buff *skb = e->skb; + struct sk_buff *skb; u32 control, len, status; rmb(); @@ -2482,19 +2553,12 @@ static int skge_poll(struct net_device *dev, int *budget) break; len = control & BMU_BBC; - e->skb = NULL; - - pci_unmap_single(hw->pdev, - pci_unmap_addr(e, mapaddr), - pci_unmap_len(e, maplen), - PCI_DMA_FROMDEVICE); - status = rd->status; - if ((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) - || len > dev->mtu + VLAN_ETH_HLEN - || bad_phy_status(hw, status)) { + + if (unlikely((control & (BMU_EOF|BMU_STF)) != (BMU_STF|BMU_EOF) + || bad_phy_status(hw, status))) { skge_rx_error(skge, e - ring->start, control, status); - dev_kfree_skb(skb); + skge_rx_reuse(e, skge->rx_buf_size); continue; } @@ -2502,42 +2566,37 @@ static int skge_poll(struct net_device *dev, int *budget) printk(KERN_DEBUG PFX "%s: rx slot %td status 0x%x len %d\n", dev->name, e - ring->start, rd->status, len); - skb_put(skb, len); - skb->protocol = eth_type_trans(skb, dev); + skb = skge_rx_get(skge, e, len); + if (likely(skb)) { + skb_put(skb, len); + skb->protocol = eth_type_trans(skb, dev); - if (skge->rx_csum) { - skb->csum = le16_to_cpu(rd->csum2); - skb->ip_summed = CHECKSUM_HW; - } - - dev->last_rx = jiffies; - netif_receive_skb(skb); + dev->last_rx = jiffies; + netif_receive_skb(skb); - ++work_done; + ++work_done; + } else + skge_rx_reuse(e, skge->rx_buf_size); } ring->to_clean = e; - *budget -= work_done; - dev->quota -= work_done; - done = work_done < to_do; - - if (skge_rx_fill(skge)) - done = 0; - /* restart receiver */ wmb(); skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START | CSR_IRQ_CL_F); - if (done) { - local_irq_disable(); - __netif_rx_complete(dev); - hw->intr_mask |= portirqmask[skge->port]; - skge_write32(hw, B0_IMSK, hw->intr_mask); - local_irq_enable(); - } + *budget -= work_done; + dev->quota -= work_done; + + if (work_done >= to_do) + return 1; /* not done */ - return !done; + local_irq_disable(); + __netif_rx_complete(dev); + hw->intr_mask |= portirqmask[skge->port]; + skge_write32(hw, B0_IMSK, hw->intr_mask); + local_irq_enable(); + return 0; } static inline void skge_tx_intr(struct net_device *dev) diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 37323cd..14d0cc0 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -2503,6 +2503,7 @@ struct skge_port { void *mem; /* PCI memory for rings */ dma_addr_t dma; unsigned long mem_size; + unsigned int rx_buf_size; struct timer_list led_blink; }; -- cgit v1.1 From 747802ab478399f13ff57751c2ebd22577be4eeb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 27 Jun 2005 11:33:16 -0700 Subject: [PATCH] skge: version and copyright. Bump version and copyright year. Signed-off-by: Stephen Hemminger --- drivers/net/skge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 9d4ae78..3dbb1cb 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -7,7 +7,7 @@ * of the original driver such as link fail-over and link management because * those should be done at higher levels. * - * Copyright (C) 2004, Stephen Hemminger + * Copyright (C) 2004, 2005 Stephen Hemminger * * 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 @@ -42,7 +42,7 @@ #include "skge.h" #define DRV_NAME "skge" -#define DRV_VERSION "0.6" +#define DRV_VERSION "0.7" #define PFX DRV_NAME " " #define DEFAULT_TX_RING_SIZE 128 -- cgit v1.1 From a5fe736eaf9bae1b45317313de04b564441b94f2 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 27 Jun 2005 22:47:18 -0400 Subject: Update is_multicast_ether_addr() definition; net/ieee80211.h cleanups. --- include/linux/etherdevice.h | 2 +- include/net/ieee80211.h | 48 ++++++++++----------------------------------- 2 files changed, 11 insertions(+), 39 deletions(-) diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index a147825..8a2df4d 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -65,7 +65,7 @@ static inline int is_zero_ether_addr(const u8 *addr) */ static inline int is_multicast_ether_addr(const u8 *addr) { - return addr[0] & 0x01; + return ((addr[0] != 0xff) && (0x01 & addr[0])); } /** diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 7fe57f9..151c4f2 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -94,6 +94,8 @@ struct eapol { u16 length; } __attribute__ ((packed)); +#define IEEE80211_1ADDR_LEN 10 +#define IEEE80211_2ADDR_LEN 16 #define IEEE80211_3ADDR_LEN 24 #define IEEE80211_4ADDR_LEN 30 #define IEEE80211_FCS_LEN 4 @@ -300,23 +302,6 @@ struct ieee80211_snap_hdr { #define WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH 9 -/* Information Element IDs */ -#define WLAN_EID_SSID 0 -#define WLAN_EID_SUPP_RATES 1 -#define WLAN_EID_FH_PARAMS 2 -#define WLAN_EID_DS_PARAMS 3 -#define WLAN_EID_CF_PARAMS 4 -#define WLAN_EID_TIM 5 -#define WLAN_EID_IBSS_PARAMS 6 -#define WLAN_EID_CHALLENGE 16 -#define WLAN_EID_RSN 48 -#define WLAN_EID_GENERIC 221 - -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - - #define IEEE80211_STATMASK_SIGNAL (1<<0) #define IEEE80211_STATMASK_RSSI (1<<1) #define IEEE80211_STATMASK_NOISE (1<<2) @@ -441,6 +426,8 @@ struct ieee80211_stats { struct ieee80211_device; +#include "ieee80211_crypt.h" + #define SEC_KEY_1 (1<<0) #define SEC_KEY_2 (1<<1) #define SEC_KEY_3 (1<<2) @@ -488,15 +475,6 @@ Total: 28-2340 bytes */ -struct ieee80211_header_data { - u16 frame_ctl; - u16 duration_id; - u8 addr1[6]; - u8 addr2[6]; - u8 addr3[6]; - u16 seq_ctrl; -}; - #define BEACON_PROBE_SSID_ID_POSITION 12 /* Management Frame Information Element Types */ @@ -541,7 +519,7 @@ struct ieee80211_info_element { */ struct ieee80211_authentication { - struct ieee80211_header_data header; + struct ieee80211_hdr_3addr header; u16 algorithm; u16 transaction; u16 status; @@ -550,7 +528,7 @@ struct ieee80211_authentication { struct ieee80211_probe_response { - struct ieee80211_header_data header; + struct ieee80211_hdr_3addr header; u32 time_stamp[2]; u16 beacon_interval; u16 capability; @@ -648,12 +626,6 @@ enum ieee80211_state { #define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2],((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] -extern inline int is_broadcast_ether_addr(const u8 *addr) -{ - return ((addr[0] == 0xff) && (addr[1] == 0xff) && (addr[2] == 0xff) && \ - (addr[3] == 0xff) && (addr[4] == 0xff) && (addr[5] == 0xff)); -} - #define CFG_IEEE80211_RESERVE_FCS (1<<0) #define CFG_IEEE80211_COMPUTE_FCS (1<<1) @@ -787,21 +759,21 @@ extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mod extern inline int ieee80211_get_hdrlen(u16 fc) { - int hdrlen = 24; + int hdrlen = IEEE80211_3ADDR_LEN; switch (WLAN_FC_GET_TYPE(fc)) { case IEEE80211_FTYPE_DATA: if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = 30; /* Addr4 */ + hdrlen = IEEE80211_4ADDR_LEN; break; case IEEE80211_FTYPE_CTL: switch (WLAN_FC_GET_STYPE(fc)) { case IEEE80211_STYPE_CTS: case IEEE80211_STYPE_ACK: - hdrlen = 10; + hdrlen = IEEE80211_1ADDR_LEN; break; default: - hdrlen = 16; + hdrlen = IEEE80211_2ADDR_LEN; break; } break; -- cgit v1.1 From 5f13e7ec5c1d98f4a63a3a79e66b2b121051f5ac Mon Sep 17 00:00:00 2001 From: David Brownell Date: Mon, 16 May 2005 08:53:52 -0700 Subject: [PATCH] smc91x needs settable IRQ trigger type For boards that invert the SMC91x IRQ line (maybe an FPGA inverts it), the set_irq_type() call can't assume IRQT_RISING. These particular boards currently use OMAP-specific calls to change the trigger type, but the boards break when set_irq_type() stops being a NOP. Signed-off-by: David Brownell --- drivers/net/smc91x.c | 2 +- drivers/net/smc91x.h | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index cfb9d3c..1438fdd 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c @@ -1998,7 +1998,7 @@ static int __init smc_probe(struct net_device *dev, void __iomem *ioaddr) if (retval) goto err_out; - set_irq_type(dev->irq, IRQT_RISING); + set_irq_type(dev->irq, SMC_IRQ_TRIGGER_TYPE); #ifdef SMC_USE_PXA_DMA { diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 946528e..7089d86 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -182,6 +182,16 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insl(a, r, p, l) readsl((a) + (r), p, l) #define SMC_outsl(a, r, p, l) writesl((a) + (r), p, l) +#include +#include + +#define SMC_IRQ_TRIGGER_TYPE (( \ + machine_is_omap_h2() \ + || machine_is_omap_h3() \ + || (machine_is_omap_innovator() && !cpu_is_omap150()) \ + ) ? IRQT_FALLING : IRQT_RISING) + + #elif defined(CONFIG_SH_SH4202_MICRODEV) #define SMC_CAN_USE_8BIT 0 @@ -300,6 +310,9 @@ static inline void SMC_outsw (unsigned long a, int r, unsigned char* p, int l) #endif +#ifndef SMC_IRQ_TRIGGER_TYPE +#define SMC_IRQ_TRIGGER_TYPE IRQT_RISING +#endif #ifdef SMC_USE_PXA_DMA /* -- cgit v1.1 From cac8c81a59bd3b6815871b3172e8ccf15a3431e0 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 16 May 2005 19:15:11 +0200 Subject: [PATCH] Use pci_set_dma_mask() instead of direct assignment of DMA mask The amd8111e driver directly assigns the DMA mask to the dma_mask member of the struct pci_dev instead of using pci_set_dma_mask(). This makes the call to pci_dma_supported() redundant as pci_set_dma_mask() does this check. I do not own this device so I only compile-tested this patch. Signed-off-by: Tobias Klauser --- drivers/net/amd8111e.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/net/amd8111e.c b/drivers/net/amd8111e.c index b7dd726..8618012 100755 --- a/drivers/net/amd8111e.c +++ b/drivers/net/amd8111e.c @@ -87,6 +87,7 @@ Revision History: #include #include #include +#include #include #include @@ -2006,12 +2007,11 @@ static int __devinit amd8111e_probe_one(struct pci_dev *pdev, } /* Initialize DMA */ - if(!pci_dma_supported(pdev, 0xffffffff)){ + if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) < 0) { printk(KERN_ERR "amd8111e: DMA not supported," "exiting.\n"); - goto err_free_reg; - } else - pdev->dma_mask = 0xffffffff; + goto err_free_reg; + } reg_addr = pci_resource_start(pdev, 0); reg_len = pci_resource_len(pdev, 0); -- cgit v1.1 From 8b2af8f0ca807eb13b59dc5961d2e99fc2b1bd87 Mon Sep 17 00:00:00 2001 From: Edward Falk Date: Wed, 15 Jun 2005 14:26:39 -0700 Subject: [PATCH] Minor libata documentation patch I fleshed out libata.tmpl a bit while I was taking notes. --- Documentation/DocBook/libata.tmpl | 96 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 93 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/libata.tmpl b/Documentation/DocBook/libata.tmpl index 6df1dfd..375ae76 100644 --- a/Documentation/DocBook/libata.tmpl +++ b/Documentation/DocBook/libata.tmpl @@ -84,6 +84,14 @@ void (*port_disable) (struct ata_port *); Called from ata_bus_probe() and ata_bus_reset() error paths, as well as when unregistering from the SCSI module (rmmod, hot unplug). + This function should do whatever needs to be done to take the + port out of use. In most cases, ata_port_disable() can be used + as this hook. + + + Called from ata_bus_probe() on a failed probe. + Called from ata_bus_reset() on a failed bus reset. + Called from ata_scsi_release(). @@ -98,6 +106,13 @@ void (*dev_config) (struct ata_port *, struct ata_device *); found. Typically used to apply device-specific fixups prior to issue of SET FEATURES - XFER MODE, and prior to operation. + + Called by ata_device_add() after ata_dev_identify() determines + a device is present. + + + This entry may be specified as NULL in ata_port_operations. + @@ -135,6 +150,8 @@ void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); registers / DMA buffers. ->tf_read() is called to read the hardware registers / DMA buffers, to obtain the current set of taskfile register values. + Most drivers for taskfile-based hardware (PIO or MMIO) use + ata_tf_load() and ata_tf_read() for these hooks. @@ -147,6 +164,8 @@ void (*exec_command)(struct ata_port *ap, struct ata_taskfile *tf); causes an ATA command, previously loaded with ->tf_load(), to be initiated in hardware. + Most drivers for taskfile-based hardware use ata_exec_command() + for this hook. @@ -161,6 +180,10 @@ Allow low-level driver to filter ATA PACKET commands, returning a status indicating whether or not it is OK to use DMA for the supplied PACKET command. + + This hook may be specified as NULL, in which case libata will + assume that atapi dma can be supported. + @@ -175,6 +198,14 @@ u8 (*check_err)(struct ata_port *ap); Reads the Status/AltStatus/Error ATA shadow register from hardware. On some hardware, reading the Status register has the side effect of clearing the interrupt condition. + Most drivers for taskfile-based hardware use + ata_check_status() for this hook. + + + Note that because this is called from ata_device_add(), at + least a dummy function that clears device interrupts must be + provided for all drivers, even if the controller doesn't + actually have a taskfile status register. @@ -188,7 +219,13 @@ void (*dev_select)(struct ata_port *ap, unsigned int device); Issues the low-level hardware command(s) that causes one of N hardware devices to be considered 'selected' (active and available for use) on the ATA bus. This generally has no -meaning on FIS-based devices. + meaning on FIS-based devices. + + + Most drivers for taskfile-based hardware use + ata_std_dev_select() for this hook. Controllers which do not + support second drives on a port (such as SATA contollers) will + use ata_noop_dev_select(). @@ -204,6 +241,8 @@ void (*phy_reset) (struct ata_port *ap); for device presence (PATA and SATA), typically a soft reset (SRST) will be performed. Drivers typically use the helper functions ata_bus_reset() or sata_phy_reset() for this hook. + Many SATA drivers use sata_phy_reset() or call it from within + their own phy_reset() functions. @@ -227,6 +266,25 @@ PCI IDE DMA Status register. These hooks are typically either no-ops, or simply not implemented, in FIS-based drivers. + +Most legacy IDE drivers use ata_bmdma_setup() for the bmdma_setup() +hook. ata_bmdma_setup() will write the pointer to the PRD table to +the IDE PRD Table Address register, enable DMA in the DMA Command +register, and call exec_command() to begin the transfer. + + +Most legacy IDE drivers use ata_bmdma_start() for the bmdma_start() +hook. ata_bmdma_start() will write the ATA_DMA_START flag to the DMA +Command register. + + +Many legacy IDE drivers use ata_bmdma_stop() for the bmdma_stop() +hook. ata_bmdma_stop() clears the ATA_DMA_START flag in the DMA +command register. + + +Many legacy IDE drivers use ata_bmdma_status() as the bmdma_status() hook. + @@ -250,6 +308,10 @@ int (*qc_issue) (struct ata_queued_cmd *qc); helper function ata_qc_issue_prot() for taskfile protocol-based dispatch. More advanced drivers implement their own ->qc_issue. + + ata_qc_issue_prot() calls ->tf_load(), ->bmdma_setup(), and + ->bmdma_start() as necessary to initiate a transfer. + @@ -279,6 +341,21 @@ void (*irq_clear) (struct ata_port *); before the interrupt handler is registered, to be sure hardware is quiet. + + The second argument, dev_instance, should be cast to a pointer + to struct ata_host_set. + + + Most legacy IDE drivers use ata_interrupt() for the + irq_handler hook, which scans all ports in the host_set, + determines which queued command was active (if any), and calls + ata_host_intr(ap,qc). + + + Most legacy IDE drivers use ata_bmdma_irq_clear() for the + irq_clear() hook, which simply clears the interrupt and error + flags in the DMA status register. + @@ -292,6 +369,7 @@ void (*scr_write) (struct ata_port *ap, unsigned int sc_reg, Read and write standard SATA phy registers. Currently only used if ->phy_reset hook called the sata_phy_reset() helper function. + sc_reg is one of SCR_STATUS, SCR_CONTROL, SCR_ERROR, or SCR_ACTIVE. @@ -307,17 +385,29 @@ void (*host_stop) (struct ata_host_set *host_set); ->port_start() is called just after the data structures for each port are initialized. Typically this is used to alloc per-port DMA buffers / tables / rings, enable DMA engines, and similar - tasks. + tasks. Some drivers also use this entry point as a chance to + allocate driver-private memory for ap->private_data. + + + Many drivers use ata_port_start() as this hook or call + it from their own port_start() hooks. ata_port_start() + allocates space for a legacy IDE PRD table and returns. ->port_stop() is called after ->host_stop(). It's sole function is to release DMA/memory resources, now that they are no longer - actively being used. + actively being used. Many drivers also free driver-private + data from port at this time. + + + Many drivers use ata_port_stop() as this hook, which frees the + PRD table. ->host_stop() is called after all ->port_stop() calls have completed. The hook must finalize hardware shutdown, release DMA and other resources, etc. + This hook may be specified as NULL, in which case it is not called. -- cgit v1.1 From c903e41e67046e7f52bbc404bd5aa654d12540cc Mon Sep 17 00:00:00 2001 From: Komuro Date: Mon, 27 Jun 2005 23:23:05 -0400 Subject: drivers/net/at1700: remove incorrect comment "Allied Telesis RE1000 Plus" is not supported at all by kernel 2.6.12. Signed-off-by: komurojun-mbn@nifty.com --- drivers/net/at1700.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c index b8ab2b6..e613cc2 100644 --- a/drivers/net/at1700.c +++ b/drivers/net/at1700.c @@ -34,10 +34,6 @@ only is it difficult to detect, it also moves around in I/O space in response to inb()s from other device probes! */ -/* - 99/03/03 Allied Telesis RE1000 Plus support by T.Hagawa - 99/12/30 port to 2.3.35 by K.Takai -*/ #include #include -- cgit v1.1 From e922256ae4bb6ef954bd7e0740d9753460e0ab72 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 28 Jun 2005 00:03:37 -0400 Subject: libata: update DMA blacklist Contributions from Alan Cox and maximilian attems. --- drivers/scsi/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 36b401f..fd66f56 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1920,6 +1920,7 @@ static const char * ata_dma_blacklist [] = { "HITACHI CDR-8335", "HITACHI CDR-8435", "Toshiba CD-ROM XM-6202B", + "TOSHIBA CD-ROM XM-1702BC", "CD-532E-A", "E-IDE CD-ROM CR-840", "CD-ROM Drive/F5A", @@ -1927,7 +1928,6 @@ static const char * ata_dma_blacklist [] = { "SAMSUNG CD-ROM SC-148C", "SAMSUNG CD-ROM SC", "SanDisk SDP3B-64", - "SAMSUNG CD-ROM SN-124", "ATAPI CD-ROM DRIVE 40X MAXIMUM", "_NEC DV5800A", }; -- cgit v1.1 From 62ba2841f2a51848f7cb0499edae3f6803764f2c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 26 Jun 2005 23:27:19 +0900 Subject: [PATCH] libata: lengthen COMMRESET delay This patch lengthens the delay between DET setting and clearing for COMMRESET from 400us to 1ms. I couldn't find any requiremen regarding the duration of COMMRESET in SATA I/II specs but AHCI-1.1 10.4.2 states that it should be at least 1ms. Signed-off-by: Tejun Heo --- drivers/scsi/libata-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index fd66f56..cb535fa 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c @@ -1408,7 +1408,9 @@ void __sata_phy_reset(struct ata_port *ap) if (ap->flags & ATA_FLAG_SATA_RESET) { /* issue phy wake/reset */ scr_write_flush(ap, SCR_CONTROL, 0x301); - udelay(400); /* FIXME: a guess */ + /* Couldn't find anything in SATA I/II specs, but + * AHCI-1.1 10.4.2 says at least 1 ms. */ + mdelay(1); } scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ -- cgit v1.1 From 0a139e79976b9eb60517edec63406236a789f812 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 26 Jun 2005 23:52:50 +0900 Subject: [PATCH] libata: ahci: remove ata_port_start/stop() calls This patch removes unnecessary ata_port_start/stop() calls from ahci_port_start/stop(). Signed-off-by: Tejun Heo --- drivers/scsi/ahci.c | 22 ++++------------------ 1 file changed, 4 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 9a547ca9..c562369 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c @@ -304,26 +304,19 @@ static int ahci_port_start(struct ata_port *ap) struct device *dev = ap->host_set->dev; struct ahci_host_priv *hpriv = ap->host_set->private_data; struct ahci_port_priv *pp; - int rc; void *mem, *mmio = ap->host_set->mmio_base; void *port_mmio = ahci_port_base(mmio, ap->port_no); dma_addr_t mem_dma; - rc = ata_port_start(ap); - if (rc) - return rc; - pp = kmalloc(sizeof(*pp), GFP_KERNEL); - if (!pp) { - rc = -ENOMEM; - goto err_out; - } + if (!pp) + return -ENOMEM; memset(pp, 0, sizeof(*pp)); mem = dma_alloc_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, &mem_dma, GFP_KERNEL); if (!mem) { - rc = -ENOMEM; - goto err_out_kfree; + kfree(pp); + return -ENOMEM; } memset(mem, 0, AHCI_PORT_PRIV_DMA_SZ); @@ -373,12 +366,6 @@ static int ahci_port_start(struct ata_port *ap) readl(port_mmio + PORT_CMD); /* flush */ return 0; - -err_out_kfree: - kfree(pp); -err_out: - ata_port_stop(ap); - return rc; } @@ -404,7 +391,6 @@ static void ahci_port_stop(struct ata_port *ap) dma_free_coherent(dev, AHCI_PORT_PRIV_DMA_SZ, pp->cmd_slot, pp->cmd_slot_dma); kfree(pp); - ata_port_stop(ap); } static u32 ahci_scr_read (struct ata_port *ap, unsigned int sc_reg_in) -- cgit v1.1 From 120bb4246a99cc6e9cc976573fcbcd0ee9d544ef Mon Sep 17 00:00:00 2001 From: "jayalk@intworks.biz" Date: Mon, 21 Mar 2005 20:20:42 -0800 Subject: [PATCH] PCI Allow OutOfRange PIRQ table address I updated this to remove unnecessary variable initialization, make check_routing be inline only and not __init, switch to strtoul, and formatting fixes as per Randy Dunlap's recommendations. I updated this to change pirq_table_addr to a long, and to add a warning msg if the PIRQ table wasn't found at the specified address, as per thread with Matthew Wilcox. In our hardware situation, the BIOS is unable to store or generate it's PIRQ table in the F0000h-100000h standard range. This patch adds a pci kernel parameter, pirqaddr to allow the bootloader (or BIOS based loader) to inform the kernel where the PIRQ table got stored. A beneficial side-effect is that, if one's BIOS uses a static address each time for it's PIRQ table, then pirqaddr can be used to avoid the $pirq search through that address block each time at boot for normal PIRQ BIOSes. Signed-off-by: Jaya Kumar Signed-off-by: Greg Kroah-Hartman --- Documentation/kernel-parameters.txt | 4 +++ arch/i386/pci/common.c | 6 ++++- arch/i386/pci/irq.c | 51 +++++++++++++++++++++++++++---------- arch/i386/pci/pci.h | 1 + 4 files changed, 47 insertions(+), 15 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f44bb55..96d924e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1030,6 +1030,10 @@ running once the system is up. irqmask=0xMMMM [IA-32] Set a bit mask of IRQs allowed to be assigned automatically to PCI devices. You can make the kernel exclude IRQs of your ISA cards this way. + pirqaddr=0xAAAAA [IA-32] Specify the physical address + of the PIRQ table (normally generated + by the BIOS) if it is outside the + F0000h-100000h range. lastbus=N [IA-32] Scan all buses till bus #N. Can be useful if the kernel is unable to find your secondary buses and you want to tell it explicitly which ones they are. diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 720975e..2a2e79f 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -25,7 +25,8 @@ unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | int pci_routeirq; int pcibios_last_bus = -1; -struct pci_bus *pci_root_bus = NULL; +unsigned long pirq_table_addr; +struct pci_bus *pci_root_bus; struct pci_raw_ops *raw_pci_ops; static int pci_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) @@ -188,6 +189,9 @@ char * __devinit pcibios_setup(char *str) } else if (!strcmp(str, "biosirq")) { pci_probe |= PCI_BIOS_IRQ_SCAN; return NULL; + } else if (!strncmp(str, "pirqaddr=", 9)) { + pirq_table_addr = simple_strtoul(str+9, NULL, 0); + return NULL; } #endif #ifdef CONFIG_PCI_DIRECT diff --git a/arch/i386/pci/irq.c b/arch/i386/pci/irq.c index 83458f8..78ca1ec 100644 --- a/arch/i386/pci/irq.c +++ b/arch/i386/pci/irq.c @@ -58,6 +58,35 @@ struct irq_router_handler { int (*pcibios_enable_irq)(struct pci_dev *dev) = NULL; /* + * Check passed address for the PCI IRQ Routing Table signature + * and perform checksum verification. + */ + +static inline struct irq_routing_table * pirq_check_routing_table(u8 *addr) +{ + struct irq_routing_table *rt; + int i; + u8 sum; + + rt = (struct irq_routing_table *) addr; + if (rt->signature != PIRQ_SIGNATURE || + rt->version != PIRQ_VERSION || + rt->size % 16 || + rt->size < sizeof(struct irq_routing_table)) + return NULL; + sum = 0; + for (i=0; i < rt->size; i++) + sum += addr[i]; + if (!sum) { + DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + return rt; + } + return NULL; +} + + + +/* * Search 0xf0000 -- 0xfffff for the PCI IRQ Routing Table. */ @@ -65,23 +94,17 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) { u8 *addr; struct irq_routing_table *rt; - int i; - u8 sum; + if (pirq_table_addr) { + rt = pirq_check_routing_table((u8 *) __va(pirq_table_addr)); + if (rt) + return rt; + printk(KERN_WARNING "PCI: PIRQ table NOT found at pirqaddr\n"); + } for(addr = (u8 *) __va(0xf0000); addr < (u8 *) __va(0x100000); addr += 16) { - rt = (struct irq_routing_table *) addr; - if (rt->signature != PIRQ_SIGNATURE || - rt->version != PIRQ_VERSION || - rt->size % 16 || - rt->size < sizeof(struct irq_routing_table)) - continue; - sum = 0; - for(i=0; isize; i++) - sum += addr[i]; - if (!sum) { - DBG("PCI: Interrupt Routing Table found at 0x%p\n", rt); + rt = pirq_check_routing_table(addr); + if (rt) return rt; - } } return NULL; } diff --git a/arch/i386/pci/pci.h b/arch/i386/pci/pci.h index a8fc80c..a80f0f5 100644 --- a/arch/i386/pci/pci.h +++ b/arch/i386/pci/pci.h @@ -27,6 +27,7 @@ #define PCI_ASSIGN_ALL_BUSSES 0x4000 extern unsigned int pci_probe; +extern unsigned long pirq_table_addr; /* pci-i386.c */ -- cgit v1.1 From 881a8c120acf7ec09c90289e2996b7c70f51e996 Mon Sep 17 00:00:00 2001 From: Amit Gud Date: Tue, 12 Apr 2005 19:03:33 +0530 Subject: [PATCH] pci: remove deprecates Replace pci_find_device() with more safer pci_get_device(). Signed-off-by: Amit Gud Signed-off-by: Greg Kroah-Hartman --- drivers/char/moxa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c index 7c24fbe..95f7046 100644 --- a/drivers/char/moxa.c +++ b/drivers/char/moxa.c @@ -451,7 +451,7 @@ static int __init moxa_init(void) int n = (sizeof(moxa_pcibrds) / sizeof(moxa_pcibrds[0])) - 1; i = 0; while (i < n) { - while ((p = pci_find_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) + while ((p = pci_get_device(moxa_pcibrds[i].vendor, moxa_pcibrds[i].device, p))!=NULL) { if (pci_enable_device(p)) continue; -- cgit v1.1 From efe1ec27837d6639eae82e1f5876910ba6433c3f Mon Sep 17 00:00:00 2001 From: Amit Gud Date: Tue, 12 Apr 2005 19:04:27 +0530 Subject: [PATCH] pci: remove deprecates Replace pci_find_device() with more safer pci_get_device(). Signed-off-by: Amit Gud Signed-off-by: Greg Kroah-Hartman --- drivers/char/rio/rio_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c index 7db3370..d7d4840 100644 --- a/drivers/char/rio/rio_linux.c +++ b/drivers/char/rio/rio_linux.c @@ -1095,7 +1095,7 @@ static int __init rio_init(void) #ifdef CONFIG_PCI /* First look for the JET devices: */ - while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, + while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, pdev))) { if (pci_enable_device(pdev)) continue; @@ -1169,7 +1169,7 @@ static int __init rio_init(void) */ /* Then look for the older RIO/PCI devices: */ - while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, + while ((pdev = pci_get_device (PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_RIO, pdev))) { if (pci_enable_device(pdev)) continue; -- cgit v1.1 From c431ada45d65b305a6aab4557067e564b23ce5a5 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:45 -0700 Subject: [PATCH] acpi bridge hotadd: ACPI based root bridge hot-add When you hot-plug a (root) bridge hierarchy, it may have p2p bridges and devices attached to it that have not been configured by firmware. In this case, we need to configure the devices before starting them. This patch separates device start from device scan so that we can introduce the configuration step in the middle. I kept the existing semantics for pci_scan_bus() since there are a huge number of callers to that function. Also, I have no way of testing the changes I made to the parisc files, so this needs review by those folks. Sorry for the massive cross-post, this touches files in many different places. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 2 +- arch/i386/pci/legacy.c | 2 ++ arch/i386/pci/numa.c | 2 ++ arch/ia64/pci/pci.c | 2 +- drivers/acpi/pci_bind.c | 16 +++++++++++++++- drivers/acpi/pci_root.c | 24 +++++++++++++++++++++++- drivers/parisc/dino.c | 1 + drivers/parisc/lba_pci.c | 2 ++ drivers/pci/probe.c | 2 -- include/linux/pci.h | 8 ++++++-- 10 files changed, 53 insertions(+), 8 deletions(-) diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 2a2e79f..8732526 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -134,7 +134,7 @@ struct pci_bus * __devinit pcibios_scan_root(int busnum) printk("PCI: Probing PCI hardware (bus %02x)\n", busnum); - return pci_scan_bus(busnum, &pci_root_ops, NULL); + return pci_scan_bus_parented(NULL, busnum, &pci_root_ops, NULL); } extern u8 pci_cache_line_size; diff --git a/arch/i386/pci/legacy.c b/arch/i386/pci/legacy.c index 1492e37..149a958 100644 --- a/arch/i386/pci/legacy.c +++ b/arch/i386/pci/legacy.c @@ -45,6 +45,8 @@ static int __init pci_legacy_init(void) printk("PCI: Probing PCI hardware\n"); pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); pcibios_fixup_peer_bridges(); diff --git a/arch/i386/pci/numa.c b/arch/i386/pci/numa.c index 9e36954..adbe17a 100644 --- a/arch/i386/pci/numa.c +++ b/arch/i386/pci/numa.c @@ -115,6 +115,8 @@ static int __init pci_numa_init(void) return 0; pci_root_bus = pcibios_scan_root(0); + if (pci_root_bus) + pci_bus_add_devices(pci_root_bus); if (num_online_nodes() > 1) for_each_online_node(quad) { if (quad == 0) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index e3fc4ed..c0661d3 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -312,7 +312,7 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus) acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window, &info); - pbus = pci_scan_bus(bus, &pci_root_ops, controller); + pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller); if (pbus) pcibios_setup_root_windows(pbus, controller); diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 5d19b39..7753df1 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -129,6 +129,8 @@ acpi_pci_bind ( char *pathname = NULL; struct acpi_buffer buffer = {0, NULL}; acpi_handle handle = NULL; + struct pci_dev *dev; + struct pci_bus *bus; ACPI_FUNCTION_TRACE("acpi_pci_bind"); @@ -193,8 +195,20 @@ acpi_pci_bind ( * Locate matching device in PCI namespace. If it doesn't exist * this typically means that the device isn't currently inserted * (e.g. docking station, port replicator, etc.). + * We cannot simply search the global pci device list, since + * PCI devices are added to the global pci list when the root + * bridge start ops are run, which may not have happened yet. */ - data->dev = pci_find_slot(data->id.bus, PCI_DEVFN(data->id.device, data->id.function)); + bus = pci_find_bus(data->id.segment, data->id.bus); + if (bus) { + list_for_each_entry(dev, &bus->devices, bus_list) { + if (dev->devfn == PCI_DEVFN(data->id.device, + data->id.function)) { + data->dev = dev; + break; + } + } + } if (!data->dev) { ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device %02x:%02x:%02x.%02x not present in PCI namespace\n", diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 7e6b8e3..5d2f77f 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -46,6 +46,7 @@ ACPI_MODULE_NAME ("pci_root") static int acpi_pci_root_add (struct acpi_device *device); static int acpi_pci_root_remove (struct acpi_device *device, int type); +static int acpi_pci_root_start (struct acpi_device *device); static struct acpi_driver acpi_pci_root_driver = { .name = ACPI_PCI_ROOT_DRIVER_NAME, @@ -54,6 +55,7 @@ static struct acpi_driver acpi_pci_root_driver = { .ops = { .add = acpi_pci_root_add, .remove = acpi_pci_root_remove, + .start = acpi_pci_root_start, }, }; @@ -169,6 +171,7 @@ acpi_pci_root_add ( if (!root) return_VALUE(-ENOMEM); memset(root, 0, sizeof(struct acpi_pci_root)); + INIT_LIST_HEAD(&root->node); root->handle = device->handle; strcpy(acpi_device_name(device), ACPI_PCI_ROOT_DEVICE_NAME); @@ -298,12 +301,31 @@ acpi_pci_root_add ( root->id.bus); end: - if (result) + if (result) { + if (!list_empty(&root->node)) + list_del(&root->node); kfree(root); + } return_VALUE(result); } +static int +acpi_pci_root_start ( + struct acpi_device *device) +{ + struct acpi_pci_root *root; + + ACPI_FUNCTION_TRACE("acpi_pci_root_start"); + + list_for_each_entry(root, &acpi_pci_roots, node) { + if (root->handle == device->handle) { + pci_bus_add_devices(root->bus); + return_VALUE(0); + } + } + return_VALUE(-ENODEV); +} static int acpi_pci_root_remove ( diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c index b0d2a73..2f2dbef2 100644 --- a/drivers/parisc/dino.c +++ b/drivers/parisc/dino.c @@ -993,6 +993,7 @@ dino_driver_callback(struct parisc_device *dev) bus = pci_scan_bus_parented(&dev->dev, dino_current_bus, &dino_cfg_ops, NULL); if(bus) { + pci_bus_add_devices(bus); /* This code *depends* on scanning being single threaded * if it isn't, this global bus number count will fail */ diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c index dc83880..7fdd80b 100644 --- a/drivers/parisc/lba_pci.c +++ b/drivers/parisc/lba_pci.c @@ -1570,6 +1570,8 @@ lba_driver_probe(struct parisc_device *dev) lba_bus = lba_dev->hba.hba_bus = pci_scan_bus_parented(&dev->dev, lba_dev->hba.bus_num.start, cfg_ops, NULL); + if (lba_bus) + pci_bus_add_devices(lba_bus); /* This is in lieu of calling pci_assign_unassigned_resources() */ if (is_pdc_pat()) { diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index fd48b20..3dc00f0 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -911,8 +911,6 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, b->subordinate = pci_scan_child_bus(b); - pci_bus_add_devices(b); - return b; sys_create_link_err: diff --git a/include/linux/pci.h b/include/linux/pci.h index b5238bd..0e98449 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -734,16 +734,20 @@ void pcibios_update_irq(struct pci_dev *, int irq); /* Generic PCI functions used internally */ extern struct pci_bus *pci_find_bus(int domain, int busnr); +void pci_bus_add_devices(struct pci_bus *bus); struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) { - return pci_scan_bus_parented(NULL, bus, ops, sysdata); + struct pci_bus *root_bus; + root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); + if (root_bus) + pci_bus_add_devices(root_bus); + return root_bus; } int pci_scan_slot(struct pci_bus *bus, int devfn); struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); unsigned int pci_scan_child_bus(struct pci_bus *bus); void pci_bus_add_device(struct pci_dev *dev); -void pci_bus_add_devices(struct pci_bus *bus); void pci_name_device(struct pci_dev *dev); char *pci_class_name(u32 class); void pci_read_bridge_bases(struct pci_bus *child); -- cgit v1.1 From fab3fb0ac8c83072465b28ca859c420da6c6511c Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:45 -0700 Subject: [PATCH] acpi bridge hotadd: Fix pci_enable_device() for p2p bridges When checking if a PCI to PCI bridge should be enabled to decode memory and/or IO resources, we need to look at all device resources not just the first 6. This is needed to allow PCI bridges to pass down memory and IO accesses to child devices even when the bridge itself does not consume resources in its PCI BARs. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index c0661d3..2a14877 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -418,18 +418,24 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) u16 cmd, old_cmd; int idx; struct resource *r; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; if (!dev) return -EINVAL; pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for (idx=0; idx<6; idx++) { + for (idx=0; idxresource[idx]; + if (!(r->flags & type_mask)) + continue; + if ((idx == PCI_ROM_RESOURCE) && + (!(r->flags & IORESOURCE_ROM_ENABLE))) + continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", @@ -441,8 +447,6 @@ pcibios_enable_resources (struct pci_dev *dev, int mask) if (r->flags & IORESOURCE_MEM) cmd |= PCI_COMMAND_MEMORY; } - if (dev->resource[PCI_ROM_RESOURCE].start) - cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); -- cgit v1.1 From 71c3511c22e8e0648094672abec898b3bf84c18b Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:46 -0700 Subject: [PATCH] acpi bridge hotadd: Make pcibios_fixup_bus() hot-plug safe PCI scan code calls the arch specific pcibios_fixup_bus() each time it scans a new bridge. For root bridge hot-plug, the bridge and it's attached devices may not have been configured properly yet, so it's not safe to claim those resources at this time. This code goes away when we clean up the way pci resources are claimed (in pci_enable_device()), so this is only a stopgap fix. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 2a14877..d929858 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -373,6 +373,25 @@ void pcibios_bus_to_resource(struct pci_dev *dev, res->end = region->end + offset; } +static int __devinit is_valid_resource(struct pci_dev *dev, int idx) +{ + unsigned int i, type_mask = IORESOURCE_IO | IORESOURCE_MEM; + struct resource *devr = &dev->resource[idx]; + + if (!dev->bus) + return 0; + for (i=0; ibus->resource[i]; + + if (!busr || ((busr->flags ^ devr->flags) & type_mask)) + continue; + if ((devr->start) && (devr->start >= busr->start) && + (devr->end <= busr->end)) + return 1; + } + return 0; +} + static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) { struct pci_bus_region region; @@ -386,7 +405,8 @@ static void __devinit pcibios_fixup_device_resources(struct pci_dev *dev) region.start = dev->resource[i].start; region.end = dev->resource[i].end; pcibios_bus_to_resource(dev, &dev->resource[i], ®ion); - pci_claim_resource(dev, i); + if ((is_valid_resource(dev, i))) + pci_claim_resource(dev, i); } } -- cgit v1.1 From cc57450f5c044270d2cf1dd437c1850422262109 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:47 -0700 Subject: [PATCH] acpi bridge hotadd: Prevent duplicate bus numbers when scanning PCI bridge When hot-plugging a root bridge, as we try to assign bus numbers we may find that the hotplugged hieratchy has more PCI to PCI bridges (i.e. bus requirements) than available. Make sure we don't step over an existing bus when that happens. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 3dc00f0..6186f4d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -411,7 +411,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); - u32 buses; + u32 buses, i; u16 bctl; pci_read_config_dword(dev, PCI_PRIMARY_BUS, &buses); @@ -470,6 +470,10 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max /* Clear errors */ pci_write_config_word(dev, PCI_STATUS, 0xffff); + /* Prevent assigning a bus number that already exists. + * This can happen when a bridge is hot-plugged */ + if (pci_find_bus(pci_domain_nr(bus), max+1)) + return max; child = pci_alloc_child_bus(bus, dev, ++max); buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) @@ -501,7 +505,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max * as cards with a PCI-to-PCI bridge can be * inserted later. */ - max += CARDBUS_RESERVE_BUSNR; + for (i=0; i Date: Thu, 28 Apr 2005 00:25:48 -0700 Subject: [PATCH] acpi bridge hotadd: Take the PCI lock when modifying pci bus or device lists With root bridge and pci bridge hot-plug, new buses and devices can be added or removed at run time. Protect the pci bus and device lists with the pci lock when doing so. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6186f4d..7d171f8 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -374,8 +374,11 @@ struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_de struct pci_bus *child; child = pci_alloc_child_bus(parent, dev, busnr); - if (child) + if (child) { + spin_lock(&pci_bus_lock); list_add_tail(&child->node, &parent->children); + spin_unlock(&pci_bus_lock); + } return child; } @@ -765,7 +768,9 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) * and the bus list for fixup functions, etc. */ INIT_LIST_HEAD(&dev->global_list); + spin_lock(&pci_bus_lock); list_add_tail(&dev->bus_list, &bus->devices); + spin_unlock(&pci_bus_lock); return dev; } @@ -886,7 +891,9 @@ struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, int bus, pr_debug("PCI: Bus %04x:%02x already known\n", pci_domain_nr(b), bus); goto err_out; } + spin_lock(&pci_bus_lock); list_add_tail(&b->node, &pci_root_buses); + spin_unlock(&pci_bus_lock); memset(dev, 0, sizeof(*dev)); dev->parent = parent; @@ -928,7 +935,9 @@ class_dev_create_file_err: class_dev_reg_err: device_unregister(dev); dev_reg_err: + spin_lock(&pci_bus_lock); list_del(&b->node); + spin_unlock(&pci_bus_lock); err_out: kfree(dev); kfree(b); -- cgit v1.1 From 6ef6f0e33c4645fc8d23201ad5a6a289b4303cbb Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:49 -0700 Subject: [PATCH] acpi bridge hotadd: Link newly created pci child bus to its parent on creation When a pci child bus is created, add it to the parent's children list immediately rather than waiting till pci_bus_add_devices(). For hot-plug bridges/devices, pci_bus_add_devices() may be called much later, after they have been properly configured. In the meantime, this allows us to use the normal pci bus search functions for the hot-plug bridges/buses. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/bus.c | 11 +++++++---- drivers/pci/probe.c | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index dbd3360..fedae89 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -121,10 +121,13 @@ void __devinit pci_bus_add_devices(struct pci_bus *bus) * If there is an unattached subordinate bus, attach * it and then scan for unattached PCI devices. */ - if (dev->subordinate && list_empty(&dev->subordinate->node)) { - spin_lock(&pci_bus_lock); - list_add_tail(&dev->subordinate->node, &dev->bus->children); - spin_unlock(&pci_bus_lock); + if (dev->subordinate) { + if (list_empty(&dev->subordinate->node)) { + spin_lock(&pci_bus_lock); + list_add_tail(&dev->subordinate->node, + &dev->bus->children); + spin_unlock(&pci_bus_lock); + } pci_bus_add_devices(dev->subordinate); sysfs_create_link(&dev->subordinate->class_dev.kobj, &dev->dev.kobj, "bridge"); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 7d171f8..6a0a82f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -450,7 +450,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max return max; } - child = pci_alloc_child_bus(bus, dev, busnr); + child = pci_add_new_bus(bus, dev, busnr); if (!child) return max; child->primary = buses & 0xFF; @@ -477,7 +477,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max * This can happen when a bridge is hot-plugged */ if (pci_find_bus(pci_domain_nr(bus), max+1)) return max; - child = pci_alloc_child_bus(bus, dev, ++max); + child = pci_add_new_bus(bus, dev, ++max); buses = (buses & 0xff000000) | ((unsigned int)(child->primary) << 0) | ((unsigned int)(child->secondary) << 8) -- cgit v1.1 From 091ca9f06382e46d77213c35a97f7d0be9e350d2 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:49 -0700 Subject: [PATCH] acpi bridge hotadd: Make the PCI remove routines safe for failed hot-plug When a root bridge hierarchy is hot-plugged, resource requirements for the new devices may be greater than what the root bridge is decoding. In this case, we want to remove devices that did not get needed resources. These devices have been scanned into bus specific lists but not yet added to the global device list. Make sure the pci remove functions can handle this case. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/remove.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 96f077f..27a294b 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -18,17 +18,21 @@ static void pci_free_resources(struct pci_dev *dev) static void pci_destroy_dev(struct pci_dev *dev) { - pci_proc_detach_device(dev); - pci_remove_sysfs_dev_files(dev); - device_unregister(&dev->dev); + if (!list_empty(&dev->global_list)) { + pci_proc_detach_device(dev); + pci_remove_sysfs_dev_files(dev); + device_unregister(&dev->dev); + spin_lock(&pci_bus_lock); + list_del(&dev->global_list); + dev->global_list.next = dev->global_list.prev = NULL; + spin_unlock(&pci_bus_lock); + } /* Remove the device from the device lists, and prevent any further * list accesses from this device */ spin_lock(&pci_bus_lock); list_del(&dev->bus_list); - list_del(&dev->global_list); dev->bus_list.next = dev->bus_list.prev = NULL; - dev->global_list.next = dev->global_list.prev = NULL; spin_unlock(&pci_bus_lock); pci_free_resources(dev); -- cgit v1.1 From 542df5de56a23bf2d94b75e2b304ab0e5a5508a8 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:50 -0700 Subject: [PATCH] acpi bridge hotadd: Remove hot-plugged devices that could not be allocated resources When hot-plugging an I/O hierarchy that contains many bridges and leaf devices, it's possible that there are not enough resources to start all the device present. If we fail to assign a resource, clear the corresponding value in the pci_dev structure, so other code can take corrective action. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/setup-bus.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1ba84be..6b628de 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -72,7 +72,10 @@ pbus_assign_resources_sorted(struct pci_bus *bus) for (list = head.next; list;) { res = list->res; idx = res - &list->dev->resource[0]; - pci_assign_resource(list->dev, idx); + if (pci_assign_resource(list->dev, idx)) { + res->start = 0; + res->flags = 0; + } tmp = list; list = list->next; kfree(tmp); -- cgit v1.1 From f7d473d919627262816459f8dba70d72812be074 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:51 -0700 Subject: [PATCH] acpi bridge hotadd: Read bridge resources when fixing up the bus Read bridge io/mem/pfmem ranges when fixing up the bus so that bus resources are tracked. This is required to properly support pci end device and bridge hotplug. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/pci/pci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index d929858..720a861 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c @@ -418,6 +418,10 @@ pcibios_fixup_bus (struct pci_bus *b) { struct pci_dev *dev; + if (b->self) { + pci_read_bridge_bases(b); + pcibios_fixup_device_resources(b->self); + } list_for_each_entry(dev, &b->devices, bus_list) pcibios_fixup_device_resources(dev); -- cgit v1.1 From 3fb02738b0fd36f47710a2bf207129efd2f5daa2 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:52 -0700 Subject: [PATCH] acpi bridge hotadd: Allow ACPI .add and .start operations to be done independently Create new interfaces to recursively add an acpi namespace object to the acpi device list, and recursively start the namespace object. This is needed for ACPI based hotplug of a root bridge hierarchy where the add operation must be performed first and the start operation must be performed separately after the hot-plugged devices have been properly configured. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/container.c | 2 +- drivers/acpi/processor_core.c | 2 +- drivers/acpi/scan.c | 126 +++++++++++++++++++++++++++++++++--------- include/acpi/acpi_bus.h | 17 +++++- 4 files changed, 119 insertions(+), 28 deletions(-) diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 5a0adbf..97013dd 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c @@ -153,7 +153,7 @@ container_device_add(struct acpi_device **device, acpi_handle handle) return_VALUE(-ENODEV); } - result = acpi_bus_scan(*device); + result = acpi_bus_start(*device); return_VALUE(result); } diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index f477874..76156ac 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -723,7 +723,7 @@ int acpi_processor_device_add( return_VALUE(-ENODEV); } - acpi_bus_scan(*device); + acpi_bus_start(*device); pr = acpi_driver_data(*device); if (!pr) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e858855..337d49b 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -553,20 +553,29 @@ acpi_bus_driver_init ( * upon possible configuration and currently allocated resources. */ + ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); + return_VALUE(0); +} + +int +acpi_start_single_object ( + struct acpi_device *device) +{ + int result = 0; + struct acpi_driver *driver; + + ACPI_FUNCTION_TRACE("acpi_start_single_object"); + + if (!(driver = device->driver)) + return_VALUE(0); + if (driver->ops.start) { result = driver->ops.start(device); if (result && driver->ops.remove) driver->ops.remove(device, ACPI_BUS_REMOVAL_NORMAL); - return_VALUE(result); } - ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Driver successfully bound to device\n")); - - if (driver->ops.scan) { - driver->ops.scan(device); - } - - return_VALUE(0); + return_VALUE(result); } static int acpi_driver_attach(struct acpi_driver * drv) @@ -586,6 +595,7 @@ static int acpi_driver_attach(struct acpi_driver * drv) if (!acpi_bus_match(dev, drv)) { if (!acpi_bus_driver_init(dev, drv)) { + acpi_start_single_object(dev); atomic_inc(&drv->references); count++; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found driver [%s] for device [%s]\n", @@ -1009,8 +1019,8 @@ acpi_bus_remove ( } -int -acpi_bus_add ( +static int +acpi_add_single_object ( struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, @@ -1019,7 +1029,7 @@ acpi_bus_add ( int result = 0; struct acpi_device *device = NULL; - ACPI_FUNCTION_TRACE("acpi_bus_add"); + ACPI_FUNCTION_TRACE("acpi_add_single_object"); if (!child) return_VALUE(-EINVAL); @@ -1140,7 +1150,7 @@ acpi_bus_add ( * * TBD: Assumes LDM provides driver hot-plug capability. */ - acpi_bus_find_driver(device); + result = acpi_bus_find_driver(device); end: if (!result) @@ -1153,10 +1163,10 @@ end: return_VALUE(result); } -EXPORT_SYMBOL(acpi_bus_add); -int acpi_bus_scan (struct acpi_device *start) +static int acpi_bus_scan (struct acpi_device *start, + struct acpi_bus_ops *ops) { acpi_status status = AE_OK; struct acpi_device *parent = NULL; @@ -1229,9 +1239,20 @@ int acpi_bus_scan (struct acpi_device *start) continue; } - status = acpi_bus_add(&child, parent, chandle, type); - if (ACPI_FAILURE(status)) - continue; + if (ops->acpi_op_add) + status = acpi_add_single_object(&child, parent, + chandle, type); + else + status = acpi_bus_get_device(chandle, &child); + + if (ACPI_FAILURE(status)) + continue; + + if (ops->acpi_op_start) { + status = acpi_start_single_object(child); + if (ACPI_FAILURE(status)) + continue; + } /* * If the device is present, enabled, and functioning then @@ -1257,8 +1278,50 @@ int acpi_bus_scan (struct acpi_device *start) return_VALUE(0); } -EXPORT_SYMBOL(acpi_bus_scan); +int +acpi_bus_add ( + struct acpi_device **child, + struct acpi_device *parent, + acpi_handle handle, + int type) +{ + int result; + struct acpi_bus_ops ops; + + ACPI_FUNCTION_TRACE("acpi_bus_add"); + + result = acpi_add_single_object(child, parent, handle, type); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + result = acpi_bus_scan(*child, &ops); + } + return_VALUE(result); +} +EXPORT_SYMBOL(acpi_bus_add); + +int +acpi_bus_start ( + struct acpi_device *device) +{ + int result; + struct acpi_bus_ops ops; + + ACPI_FUNCTION_TRACE("acpi_bus_start"); + + if (!device) + return_VALUE(-EINVAL); + + result = acpi_start_single_object(device); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_start = 1; + result = acpi_bus_scan(device, &ops); + } + return_VALUE(result); +} +EXPORT_SYMBOL(acpi_bus_start); static int acpi_bus_trim(struct acpi_device *start, @@ -1331,13 +1394,19 @@ acpi_bus_scan_fixed ( /* * Enumerate all fixed-feature devices. */ - if (acpi_fadt.pwr_button == 0) - result = acpi_bus_add(&device, acpi_root, + if (acpi_fadt.pwr_button == 0) { + result = acpi_add_single_object(&device, acpi_root, NULL, ACPI_BUS_TYPE_POWER_BUTTON); + if (!result) + result = acpi_start_single_object(device); + } - if (acpi_fadt.sleep_button == 0) - result = acpi_bus_add(&device, acpi_root, + if (acpi_fadt.sleep_button == 0) { + result = acpi_add_single_object(&device, acpi_root, NULL, ACPI_BUS_TYPE_SLEEP_BUTTON); + if (!result) + result = acpi_start_single_object(device); + } return_VALUE(result); } @@ -1346,6 +1415,7 @@ acpi_bus_scan_fixed ( static int __init acpi_scan_init(void) { int result; + struct acpi_bus_ops ops; ACPI_FUNCTION_TRACE("acpi_scan_init"); @@ -1357,17 +1427,23 @@ static int __init acpi_scan_init(void) /* * Create the root device in the bus's device tree */ - result = acpi_bus_add(&acpi_root, NULL, ACPI_ROOT_OBJECT, + result = acpi_add_single_object(&acpi_root, NULL, ACPI_ROOT_OBJECT, ACPI_BUS_TYPE_SYSTEM); if (result) goto Done; + result = acpi_start_single_object(acpi_root); + /* * Enumerate devices in the ACPI namespace. */ result = acpi_bus_scan_fixed(acpi_root); - if (!result) - result = acpi_bus_scan(acpi_root); + if (!result) { + memset(&ops, 0, sizeof(ops)); + ops.acpi_op_add = 1; + ops.acpi_op_start = 1; + result = acpi_bus_scan(acpi_root, &ops); + } if (result) acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c627bc4..9ad1424 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -108,6 +108,21 @@ typedef int (*acpi_op_unbind) (struct acpi_device *device); typedef int (*acpi_op_match) (struct acpi_device *device, struct acpi_driver *driver); +struct acpi_bus_ops { + u32 acpi_op_add:1; + u32 acpi_op_remove:1; + u32 acpi_op_lock:1; + u32 acpi_op_start:1; + u32 acpi_op_stop:1; + u32 acpi_op_suspend:1; + u32 acpi_op_resume:1; + u32 acpi_op_scan:1; + u32 acpi_op_bind:1; + u32 acpi_op_unbind:1; + u32 acpi_op_match:1; + u32 reserved:21; +}; + struct acpi_device_ops { acpi_op_add add; acpi_op_remove remove; @@ -327,9 +342,9 @@ int acpi_bus_generate_event (struct acpi_device *device, u8 type, int data); int acpi_bus_receive_event (struct acpi_bus_event *event); int acpi_bus_register_driver (struct acpi_driver *driver); int acpi_bus_unregister_driver (struct acpi_driver *driver); -int acpi_bus_scan (struct acpi_device *start); int acpi_bus_add (struct acpi_device **child, struct acpi_device *parent, acpi_handle handle, int type); +int acpi_bus_start (struct acpi_device *device); int acpi_match_ids (struct acpi_device *device, char *ids); -- cgit v1.1 From 4ce448e5fae62689b06027b46f470b944e5c2193 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:53 -0700 Subject: [PATCH] acpi bridge hotadd: Export the interface to get PCI id for an ACPI handle Export an acpi interface to get PCI domain/bus/devfn information from the corresponding namespace handle. Used by acpiphp code to transpate the device handle of the hot-plugged root bridge to the corresponding pci location information. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/pci_bind.c | 11 +++++------ include/acpi/acpi_drivers.h | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c index 7753df1..5148f3c 100644 --- a/drivers/acpi/pci_bind.c +++ b/drivers/acpi/pci_bind.c @@ -61,15 +61,14 @@ acpi_pci_data_handler ( /** - * acpi_os_get_pci_id + * acpi_get_pci_id * ------------------ * This function is used by the ACPI Interpreter (a.k.a. Core Subsystem) * to resolve PCI information for ACPI-PCI devices defined in the namespace. * This typically occurs when resolving PCI operation region information. */ -#ifdef ACPI_FUTURE_USAGE acpi_status -acpi_os_get_pci_id ( +acpi_get_pci_id ( acpi_handle handle, struct acpi_pci_id *id) { @@ -78,7 +77,7 @@ acpi_os_get_pci_id ( struct acpi_device *device = NULL; struct acpi_pci_data *data = NULL; - ACPI_FUNCTION_TRACE("acpi_os_get_pci_id"); + ACPI_FUNCTION_TRACE("acpi_get_pci_id"); if (!id) return_ACPI_STATUS(AE_BAD_PARAMETER); @@ -92,7 +91,7 @@ acpi_os_get_pci_id ( } status = acpi_get_data(handle, acpi_pci_data_handler, (void**) &data); - if (ACPI_FAILURE(status) || !data || !data->dev) { + if (ACPI_FAILURE(status) || !data) { ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid ACPI-PCI context for device %s\n", acpi_device_bid(device))); @@ -115,7 +114,7 @@ acpi_os_get_pci_id ( return_ACPI_STATUS(AE_OK); } -#endif /* ACPI_FUTURE_USAGE */ +EXPORT_SYMBOL(acpi_get_pci_id); int diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h index c62e92e..4ec722d 100644 --- a/include/acpi/acpi_drivers.h +++ b/include/acpi/acpi_drivers.h @@ -68,6 +68,7 @@ void acpi_pci_irq_del_prt (int segment, int bus); struct pci_bus; +acpi_status acpi_get_pci_id (acpi_handle handle, struct acpi_pci_id *id); int acpi_pci_bind (struct acpi_device *device); int acpi_pci_unbind (struct acpi_device *device); int acpi_pci_bind_root (struct acpi_device *device, struct acpi_pci_id *id, struct pci_bus *bus); -- cgit v1.1 From 42f49a6ae5dca90cd0594475502bf1c43ff1dc07 Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:53 -0700 Subject: [PATCH] acpi hotplug: convert acpiphp to use generic resource code This patch converts acpiphp to use the generic PCI resource assignment code. It's quite large, but most of it is deleting the acpiphp_pci and acpiphp_res files. It's tested on an hp Integrity rx8620 (which won't work without this patch). Testers with other hardware welcomed. Signed-off-by: Matthew Wilcox Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/Makefile | 4 +- drivers/pci/hotplug/acpiphp.h | 47 +-- drivers/pci/hotplug/acpiphp_core.c | 9 +- drivers/pci/hotplug/acpiphp_glue.c | 455 +++++++----------------- drivers/pci/hotplug/acpiphp_pci.c | 449 ------------------------ drivers/pci/hotplug/acpiphp_res.c | 700 ------------------------------------- 6 files changed, 134 insertions(+), 1530 deletions(-) delete mode 100644 drivers/pci/hotplug/acpiphp_pci.c delete mode 100644 drivers/pci/hotplug/acpiphp_res.c diff --git a/drivers/pci/hotplug/Makefile b/drivers/pci/hotplug/Makefile index 93c120d..3e632ff 100644 --- a/drivers/pci/hotplug/Makefile +++ b/drivers/pci/hotplug/Makefile @@ -36,9 +36,7 @@ ibmphp-objs := ibmphp_core.o \ ibmphp_hpc.o acpiphp-objs := acpiphp_core.o \ - acpiphp_glue.o \ - acpiphp_pci.o \ - acpiphp_res.o + acpiphp_glue.o rpaphp-objs := rpaphp_core.o \ rpaphp_pci.o \ diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index d949987..293603e 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h @@ -7,6 +7,8 @@ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002,2003 NEC Corporation + * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) + * Copyright (C) 2003-2005 Hewlett Packard * * All rights reserved. * @@ -52,7 +54,6 @@ struct acpiphp_bridge; struct acpiphp_slot; -struct pci_resource; /* * struct slot - slot information for each *physical* slot @@ -65,15 +66,6 @@ struct slot { struct acpiphp_slot *acpi_slot; }; -/* - * struct pci_resource - describes pci resource (mem, pfmem, io, bus) - */ -struct pci_resource { - struct pci_resource * next; - u64 base; - u32 length; -}; - /** * struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters * @cache_line_size in DWORD @@ -101,10 +93,6 @@ struct acpiphp_bridge { int type; int nr_slots; - u8 seg; - u8 bus; - u8 sub; - u32 flags; /* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */ @@ -117,12 +105,6 @@ struct acpiphp_bridge { struct hpp_param hpp; spinlock_t res_lock; - - /* available resources on this bus */ - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; }; @@ -163,12 +145,6 @@ struct acpiphp_func { u8 function; /* pci function# */ u32 flags; /* see below */ - - /* resources used for this function */ - struct pci_resource *mem_head; - struct pci_resource *p_mem_head; - struct pci_resource *io_head; - struct pci_resource *bus_head; }; /** @@ -243,25 +219,6 @@ extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot); extern u32 acpiphp_get_address (struct acpiphp_slot *slot); -/* acpiphp_pci.c */ -extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn); -extern int acpiphp_configure_slot (struct acpiphp_slot *slot); -extern int acpiphp_configure_function (struct acpiphp_func *func); -extern void acpiphp_unconfigure_function (struct acpiphp_func *func); -extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge); -extern int acpiphp_init_func_resource (struct acpiphp_func *func); - -/* acpiphp_res.c */ -extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size); -extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size); -extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size); -extern int acpiphp_resource_sort_and_combine (struct pci_resource **head); -extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length); -extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to); -extern void acpiphp_free_resource (struct pci_resource **res); -extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */ -extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */ - /* variables */ extern int acpiphp_debug; diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 4539e61..60c4c38 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c @@ -7,6 +7,8 @@ * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002,2003 NEC Corporation + * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) + * Copyright (C) 2003-2005 Hewlett Packard * * All rights reserved. * @@ -53,8 +55,8 @@ int acpiphp_debug; static int num_slots; static struct acpiphp_attention_info *attention_info; -#define DRIVER_VERSION "0.4" -#define DRIVER_AUTHOR "Greg Kroah-Hartman , Takayoshi Kochi " +#define DRIVER_VERSION "0.5" +#define DRIVER_AUTHOR "Greg Kroah-Hartman , Takayoshi Kochi , Matthew Wilcox " #define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver" MODULE_AUTHOR(DRIVER_AUTHOR); @@ -281,8 +283,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 *value) /** * get_address - get pci address of a slot * @hotplug_slot: slot to get status - * @busdev: pointer to struct pci_busdev (seg, bus, dev) - * + * @value: pointer to struct pci_busdev (seg, bus, dev) */ static int get_address(struct hotplug_slot *hotplug_slot, u32 *value) { diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index e7f4129..41c3eb2 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -4,6 +4,8 @@ * Copyright (C) 2002,2003 Takayoshi Kochi (t-kochi@bq.jp.nec.com) * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) * Copyright (C) 2002,2003 NEC Corporation + * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) + * Copyright (C) 2003-2005 Hewlett Packard * * All rights reserved. * @@ -26,6 +28,16 @@ * */ +/* + * Lifetime rules for pci_dev: + * - The one in acpiphp_func has its refcount elevated by pci_get_slot() + * when the driver is loaded or when an insertion event occurs. It loses + * a refcount when its ejected or the driver unloads. + * - The one in acpiphp_bridge has its refcount elevated by pci_get_slot() + * when the bridge is scanned and it loses a refcount when the bridge + * is removed. + */ + #include #include @@ -178,21 +190,18 @@ register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) bridge->nr_slots++; - dbg("found ACPI PCI Hotplug slot at PCI %02x:%02x Slot:%d\n", - slot->bridge->bus, slot->device, slot->sun); + dbg("found ACPI PCI Hotplug slot %d at PCI %04x:%02x:%02x\n", + slot->sun, pci_domain_nr(bridge->pci_bus), + bridge->pci_bus->number, slot->device); } newfunc->slot = slot; list_add_tail(&newfunc->sibling, &slot->funcs); /* associate corresponding pci_dev */ - newfunc->pci_dev = pci_find_slot(bridge->bus, + newfunc->pci_dev = pci_get_slot(bridge->pci_bus, PCI_DEVFN(device, function)); if (newfunc->pci_dev) { - if (acpiphp_init_func_resource(newfunc) < 0) { - kfree(newfunc); - return AE_ERROR; - } slot->flags |= (SLOT_ENABLED | SLOT_POWEREDON); } @@ -227,62 +236,6 @@ static int detect_ejectable_slots(acpi_handle *bridge_handle) } -/* decode ACPI _CRS data and convert into our internal resource list - * TBD: _TRA, etc. - */ -static acpi_status -decode_acpi_resource(struct acpi_resource *resource, void *context) -{ - struct acpiphp_bridge *bridge = (struct acpiphp_bridge *) context; - struct acpi_resource_address64 address; - struct pci_resource *res; - - if (resource->id != ACPI_RSTYPE_ADDRESS16 && - resource->id != ACPI_RSTYPE_ADDRESS32 && - resource->id != ACPI_RSTYPE_ADDRESS64) - return AE_OK; - - acpi_resource_to_address64(resource, &address); - - if (address.producer_consumer == ACPI_PRODUCER && address.address_length > 0) { - dbg("resource type: %d: 0x%llx - 0x%llx\n", address.resource_type, - (unsigned long long)address.min_address_range, - (unsigned long long)address.max_address_range); - res = acpiphp_make_resource(address.min_address_range, - address.address_length); - if (!res) { - err("out of memory\n"); - return AE_OK; - } - - switch (address.resource_type) { - case ACPI_MEMORY_RANGE: - if (address.attribute.memory.cache_attribute == ACPI_PREFETCHABLE_MEMORY) { - res->next = bridge->p_mem_head; - bridge->p_mem_head = res; - } else { - res->next = bridge->mem_head; - bridge->mem_head = res; - } - break; - case ACPI_IO_RANGE: - res->next = bridge->io_head; - bridge->io_head = res; - break; - case ACPI_BUS_NUMBER_RANGE: - res->next = bridge->bus_head; - bridge->bus_head = res; - break; - default: - /* invalid type */ - kfree(res); - break; - } - } - - return AE_OK; -} - /* decode ACPI 2.0 _HPP hot plug parameters */ static void decode_hpp(struct acpiphp_bridge *bridge) { @@ -346,9 +299,6 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) /* decode ACPI 2.0 _HPP (hot plug parameters) */ decode_hpp(bridge); - /* subtract all resources already allocated */ - acpiphp_detect_pci_resource(bridge); - /* register all slot objects under this bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, bridge->handle, (u32)1, register_slot, bridge, NULL); @@ -364,16 +314,12 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) } list_add(&bridge->list, &bridge_list); - - dbg("Bridge resource:\n"); - acpiphp_dump_resource(bridge); } /* allocate and initialize host bridge data structure */ -static void add_host_bridge(acpi_handle *handle, int seg, int bus) +static void add_host_bridge(acpi_handle *handle, struct pci_bus *pci_bus) { - acpi_status status; struct acpiphp_bridge *bridge; bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); @@ -384,52 +330,19 @@ static void add_host_bridge(acpi_handle *handle, int seg, int bus) bridge->type = BRIDGE_TYPE_HOST; bridge->handle = handle; - bridge->seg = seg; - bridge->bus = bus; - bridge->pci_bus = pci_find_bus(seg, bus); + bridge->pci_bus = pci_bus; spin_lock_init(&bridge->res_lock); - /* to be overridden when we decode _CRS */ - bridge->sub = bridge->bus; - - /* decode resources */ - - status = acpi_walk_resources(handle, METHOD_NAME__CRS, - decode_acpi_resource, bridge); - - if (ACPI_FAILURE(status)) { - err("failed to decode bridge resources\n"); - kfree(bridge); - return; - } - - acpiphp_resource_sort_and_combine(&bridge->io_head); - acpiphp_resource_sort_and_combine(&bridge->mem_head); - acpiphp_resource_sort_and_combine(&bridge->p_mem_head); - acpiphp_resource_sort_and_combine(&bridge->bus_head); - - dbg("ACPI _CRS resource:\n"); - acpiphp_dump_resource(bridge); - - if (bridge->bus_head) { - bridge->bus = bridge->bus_head->base; - bridge->sub = bridge->bus_head->base + bridge->bus_head->length - 1; - } - init_bridge_misc(bridge); } /* allocate and initialize PCI-to-PCI bridge data structure */ -static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int fn) +static void add_p2p_bridge(acpi_handle *handle, struct pci_dev *pci_dev) { struct acpiphp_bridge *bridge; - u8 tmp8; - u16 tmp16; - u64 base64, limit64; - u32 base, limit, base32u, limit32u; bridge = kmalloc(sizeof(struct acpiphp_bridge), GFP_KERNEL); if (bridge == NULL) { @@ -441,133 +354,22 @@ static void add_p2p_bridge(acpi_handle *handle, int seg, int bus, int dev, int f bridge->type = BRIDGE_TYPE_P2P; bridge->handle = handle; - bridge->seg = seg; - bridge->pci_dev = pci_find_slot(bus, PCI_DEVFN(dev, fn)); - if (!bridge->pci_dev) { - err("Can't get pci_dev\n"); - kfree(bridge); - return; - } - - bridge->pci_bus = bridge->pci_dev->subordinate; + bridge->pci_dev = pci_dev_get(pci_dev); + bridge->pci_bus = pci_dev->subordinate; if (!bridge->pci_bus) { err("This is not a PCI-to-PCI bridge!\n"); - kfree(bridge); - return; + goto err; } spin_lock_init(&bridge->res_lock); - bridge->bus = bridge->pci_bus->number; - bridge->sub = bridge->pci_bus->subordinate; - - /* - * decode resources under this P2P bridge - */ - - /* I/O resources */ - pci_read_config_byte(bridge->pci_dev, PCI_IO_BASE, &tmp8); - base = tmp8; - pci_read_config_byte(bridge->pci_dev, PCI_IO_LIMIT, &tmp8); - limit = tmp8; - - switch (base & PCI_IO_RANGE_TYPE_MASK) { - case PCI_IO_RANGE_TYPE_16: - base = (base << 8) & 0xf000; - limit = ((limit << 8) & 0xf000) + 0xfff; - bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->io_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("16bit I/O range: %04x-%04x\n", - (u32)bridge->io_head->base, - (u32)(bridge->io_head->base + bridge->io_head->length - 1)); - break; - case PCI_IO_RANGE_TYPE_32: - pci_read_config_word(bridge->pci_dev, PCI_IO_BASE_UPPER16, &tmp16); - base = ((u32)tmp16 << 16) | ((base << 8) & 0xf000); - pci_read_config_word(bridge->pci_dev, PCI_IO_LIMIT_UPPER16, &tmp16); - limit = (((u32)tmp16 << 16) | ((limit << 8) & 0xf000)) + 0xfff; - bridge->io_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->io_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("32bit I/O range: %08x-%08x\n", - (u32)bridge->io_head->base, - (u32)(bridge->io_head->base + bridge->io_head->length - 1)); - break; - case 0x0f: - dbg("I/O space unsupported\n"); - break; - default: - warn("Unknown I/O range type\n"); - } - - /* Memory resources (mandatory for P2P bridge) */ - pci_read_config_word(bridge->pci_dev, PCI_MEMORY_BASE, &tmp16); - base = (tmp16 & 0xfff0) << 16; - pci_read_config_word(bridge->pci_dev, PCI_MEMORY_LIMIT, &tmp16); - limit = ((tmp16 & 0xfff0) << 16) | 0xfffff; - bridge->mem_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->mem_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("32bit Memory range: %08x-%08x\n", - (u32)bridge->mem_head->base, - (u32)(bridge->mem_head->base + bridge->mem_head->length-1)); - - /* Prefetchable Memory resources (optional) */ - pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_BASE, &tmp16); - base = tmp16; - pci_read_config_word(bridge->pci_dev, PCI_PREF_MEMORY_LIMIT, &tmp16); - limit = tmp16; - - switch (base & PCI_MEMORY_RANGE_TYPE_MASK) { - case PCI_PREF_RANGE_TYPE_32: - base = (base & 0xfff0) << 16; - limit = ((limit & 0xfff0) << 16) | 0xfffff; - bridge->p_mem_head = acpiphp_make_resource((u64)base, limit - base + 1); - if (!bridge->p_mem_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("32bit Prefetchable memory range: %08x-%08x\n", - (u32)bridge->p_mem_head->base, - (u32)(bridge->p_mem_head->base + bridge->p_mem_head->length - 1)); - break; - case PCI_PREF_RANGE_TYPE_64: - pci_read_config_dword(bridge->pci_dev, PCI_PREF_BASE_UPPER32, &base32u); - pci_read_config_dword(bridge->pci_dev, PCI_PREF_LIMIT_UPPER32, &limit32u); - base64 = ((u64)base32u << 32) | ((base & 0xfff0) << 16); - limit64 = (((u64)limit32u << 32) | ((limit & 0xfff0) << 16)) + 0xfffff; - - bridge->p_mem_head = acpiphp_make_resource(base64, limit64 - base64 + 1); - if (!bridge->p_mem_head) { - err("out of memory\n"); - kfree(bridge); - return; - } - dbg("64bit Prefetchable memory range: %08x%08x-%08x%08x\n", - (u32)(bridge->p_mem_head->base >> 32), - (u32)(bridge->p_mem_head->base & 0xffffffff), - (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) >> 32), - (u32)((bridge->p_mem_head->base + bridge->p_mem_head->length - 1) & 0xffffffff)); - break; - case 0x0f: - break; - default: - warn("Unknown prefetchale memory type\n"); - } - init_bridge_misc(bridge); + return; + err: + pci_dev_put(pci_dev); + kfree(bridge); + return; } @@ -577,14 +379,10 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) { acpi_status status; acpi_handle dummy_handle; - unsigned long *segbus = context; unsigned long tmp; - int seg, bus, device, function; + int device, function; struct pci_dev *dev; - - /* get PCI address */ - seg = (*segbus >> 8) & 0xff; - bus = *segbus & 0xff; + struct pci_bus *pci_bus = context; status = acpi_get_handle(handle, "_ADR", &dummy_handle); if (ACPI_FAILURE(status)) @@ -599,20 +397,19 @@ find_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) device = (tmp >> 16) & 0xffff; function = tmp & 0xffff; - dev = pci_find_slot(bus, PCI_DEVFN(device, function)); - - if (!dev) - return AE_OK; + dev = pci_get_slot(pci_bus, PCI_DEVFN(device, function)); - if (!dev->subordinate) - return AE_OK; + if (!dev || !dev->subordinate) + goto out; /* check if this bridge has ejectable slots */ if (detect_ejectable_slots(handle) > 0) { dbg("found PCI-to-PCI bridge at PCI %s\n", pci_name(dev)); - add_p2p_bridge(handle, seg, bus, device, function); + add_p2p_bridge(handle, dev); } + out: + pci_dev_put(dev); return AE_OK; } @@ -624,6 +421,7 @@ static int add_bridge(acpi_handle handle) unsigned long tmp; int seg, bus; acpi_handle dummy_handle; + struct pci_bus *pci_bus; /* if the bridge doesn't have _STA, we assume it is always there */ status = acpi_get_handle(handle, "_STA", &dummy_handle); @@ -653,18 +451,22 @@ static int add_bridge(acpi_handle handle) bus = 0; } + pci_bus = pci_find_bus(seg, bus); + if (!pci_bus) { + err("Can't find bus %04x:%02x\n", seg, bus); + return 0; + } + /* check if this bridge has ejectable slots */ if (detect_ejectable_slots(handle) > 0) { dbg("found PCI host-bus bridge with hot-pluggable slots\n"); - add_host_bridge(handle, seg, bus); + add_host_bridge(handle, pci_bus); return 0; } - tmp = seg << 8 | bus; - /* search P2P bridges under this host bridge */ status = acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, (u32)1, - find_p2p_bridge, &tmp, NULL); + find_p2p_bridge, pci_bus, NULL); if (ACPI_FAILURE(status)) warn("find_p2p_bridge faied (error code = 0x%x)\n",status); @@ -672,10 +474,59 @@ static int add_bridge(acpi_handle handle) return 0; } +static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) +{ + struct list_head *head; + list_for_each(head, &bridge_list) { + struct acpiphp_bridge *bridge = list_entry(head, + struct acpiphp_bridge, list); + if (bridge->handle == handle) + return bridge; + } + + return NULL; +} static void remove_bridge(acpi_handle handle) { - /* No-op for now .. */ + struct list_head *list, *tmp; + struct acpiphp_bridge *bridge; + struct acpiphp_slot *slot; + acpi_status status; + + bridge = acpiphp_handle_to_bridge(handle); + if (!bridge) { + err("Could not find bridge for handle %p\n", handle); + return; + } + + status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_bridge); + if (ACPI_FAILURE(status)) + err("failed to remove notify handler\n"); + + slot = bridge->slots; + while (slot) { + struct acpiphp_slot *next = slot->next; + list_for_each_safe (list, tmp, &slot->funcs) { + struct acpiphp_func *func; + func = list_entry(list, struct acpiphp_func, sibling); + status = acpi_remove_notify_handler(func->handle, + ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_func); + if (ACPI_FAILURE(status)) + err("failed to remove notify handler\n"); + pci_dev_put(func->pci_dev); + list_del(list); + kfree(func); + } + kfree(slot); + slot = next; + } + + pci_dev_put(bridge->pci_dev); + list_del(&bridge->list); + kfree(bridge); } @@ -782,70 +633,56 @@ static int power_off_slot(struct acpiphp_slot *slot) */ static int enable_device(struct acpiphp_slot *slot) { - u8 bus; struct pci_dev *dev; - struct pci_bus *child; + struct pci_bus *bus = slot->bridge->pci_bus; struct list_head *l; struct acpiphp_func *func; int retval = 0; - int num; + int num, max, pass; if (slot->flags & SLOT_ENABLED) goto err_exit; /* sanity check: dev should be NULL when hot-plugged in */ - dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); + dev = pci_get_slot(bus, PCI_DEVFN(slot->device, 0)); if (dev) { /* This case shouldn't happen */ err("pci_dev structure already exists.\n"); + pci_dev_put(dev); retval = -1; goto err_exit; } - /* allocate resources to device */ - retval = acpiphp_configure_slot(slot); - if (retval) - goto err_exit; - - /* returned `dev' is the *first function* only! */ - num = pci_scan_slot(slot->bridge->pci_bus, PCI_DEVFN(slot->device, 0)); - if (num) - pci_bus_add_devices(slot->bridge->pci_bus); - dev = pci_find_slot(slot->bridge->bus, PCI_DEVFN(slot->device, 0)); - - if (!dev) { + num = pci_scan_slot(bus, PCI_DEVFN(slot->device, 0)); + if (num == 0) { err("No new device found\n"); retval = -1; goto err_exit; } - if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { - pci_read_config_byte(dev, PCI_SECONDARY_BUS, &bus); - child = (struct pci_bus*) pci_add_new_bus(dev->bus, dev, bus); - pci_do_scan_bus(child); + max = bus->secondary; + for (pass = 0; pass < 2; pass++) { + list_for_each_entry(dev, &bus->devices, bus_list) { + if (PCI_SLOT(dev->devfn) != slot->device) + continue; + if (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE || + dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) + max = pci_scan_bridge(bus, dev, max, pass); + } } + pci_bus_assign_resources(bus); + pci_bus_add_devices(bus); + /* associate pci_dev to our representation */ list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - - func->pci_dev = pci_find_slot(slot->bridge->bus, - PCI_DEVFN(slot->device, + func->pci_dev = pci_get_slot(bus, PCI_DEVFN(slot->device, func->function)); - if (!func->pci_dev) - continue; - - /* configure device */ - retval = acpiphp_configure_function(func); - if (retval) - goto err_exit; } slot->flags |= SLOT_ENABLED; - dbg("Available resources:\n"); - acpiphp_dump_resource(slot->bridge); - err_exit: return retval; } @@ -866,9 +703,12 @@ static int disable_device(struct acpiphp_slot *slot) list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); + if (!func->pci_dev) + continue; - if (func->pci_dev) - acpiphp_unconfigure_function(func); + pci_remove_bus_device(func->pci_dev); + pci_dev_put(func->pci_dev); + func->pci_dev = NULL; } slot->flags &= (~SLOT_ENABLED); @@ -1116,46 +956,6 @@ int __init acpiphp_glue_init(void) */ void __exit acpiphp_glue_exit(void) { - struct list_head *l1, *l2, *n1, *n2; - struct acpiphp_bridge *bridge; - struct acpiphp_slot *slot, *next; - struct acpiphp_func *func; - acpi_status status; - - list_for_each_safe (l1, n1, &bridge_list) { - bridge = (struct acpiphp_bridge *)l1; - slot = bridge->slots; - while (slot) { - next = slot->next; - list_for_each_safe (l2, n2, &slot->funcs) { - func = list_entry(l2, struct acpiphp_func, sibling); - acpiphp_free_resource(&func->io_head); - acpiphp_free_resource(&func->mem_head); - acpiphp_free_resource(&func->p_mem_head); - acpiphp_free_resource(&func->bus_head); - status = acpi_remove_notify_handler(func->handle, - ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_func); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); - kfree(func); - } - kfree(slot); - slot = next; - } - status = acpi_remove_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY, - handle_hotplug_event_bridge); - if (ACPI_FAILURE(status)) - err("failed to remove notify handler\n"); - - acpiphp_free_resource(&bridge->io_head); - acpiphp_free_resource(&bridge->mem_head); - acpiphp_free_resource(&bridge->p_mem_head); - acpiphp_free_resource(&bridge->bus_head); - - kfree(bridge); - } - acpi_pci_unregister_driver(&acpi_pci_hp_driver); } @@ -1173,11 +973,14 @@ int __init acpiphp_get_num_slots(void) list_for_each (node, &bridge_list) { bridge = (struct acpiphp_bridge *)node; - dbg("Bus%d %dslot(s)\n", bridge->bus, bridge->nr_slots); + dbg("Bus %04x:%02x has %d slot%s\n", + pci_domain_nr(bridge->pci_bus), + bridge->pci_bus->number, bridge->nr_slots, + bridge->nr_slots == 1 ? "" : "s"); num_slots += bridge->nr_slots; } - dbg("Total %dslots\n", num_slots); + dbg("Total %d slots\n", num_slots); return num_slots; } @@ -1274,13 +1077,6 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) if (retval) goto err_exit; - acpiphp_resource_sort_and_combine(&slot->bridge->io_head); - acpiphp_resource_sort_and_combine(&slot->bridge->mem_head); - acpiphp_resource_sort_and_combine(&slot->bridge->p_mem_head); - acpiphp_resource_sort_and_combine(&slot->bridge->bus_head); - dbg("Available resources:\n"); - acpiphp_dump_resource(slot->bridge); - err_exit: up(&slot->crit_sect); return retval; @@ -1335,9 +1131,10 @@ u8 acpiphp_get_adapter_status(struct acpiphp_slot *slot) u32 acpiphp_get_address(struct acpiphp_slot *slot) { u32 address; + struct pci_bus *pci_bus = slot->bridge->pci_bus; - address = ((slot->bridge->seg) << 16) | - ((slot->bridge->bus) << 8) | + address = (pci_domain_nr(pci_bus) << 16) | + (pci_bus->number << 8) | slot->device; return address; diff --git a/drivers/pci/hotplug/acpiphp_pci.c b/drivers/pci/hotplug/acpiphp_pci.c deleted file mode 100644 index 54d97c9..0000000 --- a/drivers/pci/hotplug/acpiphp_pci.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * ACPI PCI HotPlug PCI configuration space management - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001,2002 IBM Corp. - * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) - * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (C) 2002 NEC Corporation - * - * All rights reserved. - * - * 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. - * - * This program 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to - * - */ - -#include -#include - -#include -#include -#include -#include "../pci.h" -#include "pci_hotplug.h" -#include "acpiphp.h" - -#define MY_NAME "acpiphp_pci" - - -/* allocate mem/pmem/io resource to a new function */ -static int init_config_space (struct acpiphp_func *func) -{ - u32 bar, len; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0 - }; - int count; - struct acpiphp_bridge *bridge; - struct pci_resource *res; - struct pci_bus *pbus; - int bus, device, function; - unsigned int devfn; - u16 tmp; - - bridge = func->slot->bridge; - pbus = bridge->pci_bus; - bus = bridge->bus; - device = func->slot->device; - function = func->function; - devfn = PCI_DEVFN(device, function); - - for (count = 0; address[count]; count++) { /* for 6 BARs */ - pci_bus_write_config_dword(pbus, devfn, - address[count], 0xFFFFFFFF); - pci_bus_read_config_dword(pbus, devfn, address[count], &bar); - - if (!bar) /* This BAR is not implemented */ - continue; - - dbg("Device %02x.%02x BAR %d wants %x\n", device, function, count, bar); - - if (bar & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - - len = bar & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - dbg("len in IO %x, BAR %d\n", len, count); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_io_resource(&bridge->io_head, len); - spin_unlock(&bridge->res_lock); - - if (!res) { - err("cannot allocate requested io for %02x:%02x.%d len %x\n", - bus, device, function, len); - return -1; - } - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)res->base); - res->next = func->io_head; - func->io_head = res; - - } else { - /* This is Memory */ - if (bar & PCI_BASE_ADDRESS_MEM_PREFETCH) { - /* pfmem */ - - len = bar & 0xFFFFFFF0; - len = ~len + 1; - - dbg("len in PFMEM %x, BAR %d\n", len, count); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource(&bridge->p_mem_head, len); - spin_unlock(&bridge->res_lock); - - if (!res) { - err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n", - bus, device, function, len); - return -1; - } - - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)res->base); - - if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ - dbg("inside the pfmem 64 case, count %d\n", count); - count += 1; - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)(res->base >> 32)); - } - - res->next = func->p_mem_head; - func->p_mem_head = res; - - } else { - /* regular memory */ - - len = bar & 0xFFFFFFF0; - len = ~len + 1; - - dbg("len in MEM %x, BAR %d\n", len, count); - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource(&bridge->mem_head, len); - spin_unlock(&bridge->res_lock); - - if (!res) { - err("cannot allocate requested pfmem for %02x:%02x.%d len %x\n", - bus, device, function, len); - return -1; - } - - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)res->base); - - if (bar & PCI_BASE_ADDRESS_MEM_TYPE_64) { - /* takes up another dword */ - dbg("inside mem 64 case, reg. mem, count %d\n", count); - count += 1; - pci_bus_write_config_dword(pbus, devfn, - address[count], - (u32)(res->base >> 32)); - } - - res->next = func->mem_head; - func->mem_head = res; - - } - } - } - - /* disable expansion rom */ - pci_bus_write_config_dword(pbus, devfn, PCI_ROM_ADDRESS, 0x00000000); - - /* set PCI parameters from _HPP */ - pci_bus_write_config_byte(pbus, devfn, PCI_CACHE_LINE_SIZE, - bridge->hpp.cache_line_size); - pci_bus_write_config_byte(pbus, devfn, PCI_LATENCY_TIMER, - bridge->hpp.latency_timer); - - pci_bus_read_config_word(pbus, devfn, PCI_COMMAND, &tmp); - if (bridge->hpp.enable_SERR) - tmp |= PCI_COMMAND_SERR; - if (bridge->hpp.enable_PERR) - tmp |= PCI_COMMAND_PARITY; - pci_bus_write_config_word(pbus, devfn, PCI_COMMAND, tmp); - - return 0; -} - -/* detect_used_resource - subtract resource under dev from bridge */ -static int detect_used_resource (struct acpiphp_bridge *bridge, struct pci_dev *dev) -{ - int count; - - dbg("Device %s\n", pci_name(dev)); - - for (count = 0; count < DEVICE_COUNT_RESOURCE; count++) { - struct pci_resource *res; - struct pci_resource **head; - unsigned long base = dev->resource[count].start; - unsigned long len = dev->resource[count].end - base + 1; - unsigned long flags = dev->resource[count].flags; - - if (!flags) - continue; - - dbg("BAR[%d] 0x%lx - 0x%lx (0x%lx)\n", count, base, - base + len - 1, flags); - - if (flags & IORESOURCE_IO) { - head = &bridge->io_head; - } else if (flags & IORESOURCE_PREFETCH) { - head = &bridge->p_mem_head; - } else { - head = &bridge->mem_head; - } - - spin_lock(&bridge->res_lock); - res = acpiphp_get_resource_with_base(head, base, len); - spin_unlock(&bridge->res_lock); - if (res) - kfree(res); - } - - return 0; -} - - -/** - * acpiphp_detect_pci_resource - detect resources under bridge - * @bridge: detect all resources already used under this bridge - * - * collect all resources already allocated for all devices under a bridge. - */ -int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge) -{ - struct list_head *l; - struct pci_dev *dev; - - list_for_each (l, &bridge->pci_bus->devices) { - dev = pci_dev_b(l); - detect_used_resource(bridge, dev); - } - - return 0; -} - - -/** - * acpiphp_init_slot_resource - gather resource usage information of a slot - * @slot: ACPI slot object to be checked, should have valid pci_dev member - * - * TBD: PCI-to-PCI bridge case - * use pci_dev->resource[] - */ -int acpiphp_init_func_resource (struct acpiphp_func *func) -{ - u64 base; - u32 bar, len; - u32 address[] = { - PCI_BASE_ADDRESS_0, - PCI_BASE_ADDRESS_1, - PCI_BASE_ADDRESS_2, - PCI_BASE_ADDRESS_3, - PCI_BASE_ADDRESS_4, - PCI_BASE_ADDRESS_5, - 0 - }; - int count; - struct pci_resource *res; - struct pci_dev *dev; - - dev = func->pci_dev; - dbg("Hot-pluggable device %s\n", pci_name(dev)); - - for (count = 0; address[count]; count++) { /* for 6 BARs */ - pci_read_config_dword(dev, address[count], &bar); - - if (!bar) /* This BAR is not implemented */ - continue; - - pci_write_config_dword(dev, address[count], 0xFFFFFFFF); - pci_read_config_dword(dev, address[count], &len); - - if (len & PCI_BASE_ADDRESS_SPACE_IO) { - /* This is IO */ - base = bar & 0xFFFFFFFC; - len = len & (PCI_BASE_ADDRESS_IO_MASK & 0xFFFF); - len = len & ~(len - 1); - - dbg("BAR[%d] %08x - %08x (IO)\n", count, (u32)base, (u32)base + len - 1); - - res = acpiphp_make_resource(base, len); - if (!res) - goto no_memory; - - res->next = func->io_head; - func->io_head = res; - - } else { - /* This is Memory */ - base = bar & 0xFFFFFFF0; - if (len & PCI_BASE_ADDRESS_MEM_PREFETCH) { - /* pfmem */ - - len &= 0xFFFFFFF0; - len = ~len + 1; - - if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { /* takes up another dword */ - dbg("prefetch mem 64\n"); - count += 1; - } - dbg("BAR[%d] %08x - %08x (PMEM)\n", count, (u32)base, (u32)base + len - 1); - res = acpiphp_make_resource(base, len); - if (!res) - goto no_memory; - - res->next = func->p_mem_head; - func->p_mem_head = res; - - } else { - /* regular memory */ - - len &= 0xFFFFFFF0; - len = ~len + 1; - - if (len & PCI_BASE_ADDRESS_MEM_TYPE_64) { - /* takes up another dword */ - dbg("mem 64\n"); - count += 1; - } - dbg("BAR[%d] %08x - %08x (MEM)\n", count, (u32)base, (u32)base + len - 1); - res = acpiphp_make_resource(base, len); - if (!res) - goto no_memory; - - res->next = func->mem_head; - func->mem_head = res; - - } - } - - pci_write_config_dword(dev, address[count], bar); - } -#if 1 - acpiphp_dump_func_resource(func); -#endif - - return 0; - - no_memory: - err("out of memory\n"); - acpiphp_free_resource(&func->io_head); - acpiphp_free_resource(&func->mem_head); - acpiphp_free_resource(&func->p_mem_head); - - return -1; -} - - -/** - * acpiphp_configure_slot - allocate PCI resources - * @slot: slot to be configured - * - * initializes a PCI functions on a device inserted - * into the slot - * - */ -int acpiphp_configure_slot (struct acpiphp_slot *slot) -{ - struct acpiphp_func *func; - struct list_head *l; - u8 hdr; - u32 dvid; - int retval = 0; - int is_multi = 0; - - pci_bus_read_config_byte(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, 0), - PCI_HEADER_TYPE, &hdr); - - if (hdr & 0x80) - is_multi = 1; - - list_for_each (l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, sibling); - if (is_multi || func->function == 0) { - pci_bus_read_config_dword(slot->bridge->pci_bus, - PCI_DEVFN(slot->device, - func->function), - PCI_VENDOR_ID, &dvid); - if (dvid != 0xffffffff) { - retval = init_config_space(func); - if (retval) - break; - } - } - } - - return retval; -} - -/** - * acpiphp_configure_function - configure PCI function - * @func: function to be configured - * - * initializes a PCI functions on a device inserted - * into the slot - * - */ -int acpiphp_configure_function (struct acpiphp_func *func) -{ - /* all handled by the pci core now */ - return 0; -} - -/** - * acpiphp_unconfigure_function - unconfigure PCI function - * @func: function to be unconfigured - * - */ -void acpiphp_unconfigure_function (struct acpiphp_func *func) -{ - struct acpiphp_bridge *bridge; - - /* if pci_dev is NULL, ignore it */ - if (!func->pci_dev) - return; - - pci_remove_bus_device(func->pci_dev); - - /* free all resources */ - bridge = func->slot->bridge; - - spin_lock(&bridge->res_lock); - acpiphp_move_resource(&func->io_head, &bridge->io_head); - acpiphp_move_resource(&func->mem_head, &bridge->mem_head); - acpiphp_move_resource(&func->p_mem_head, &bridge->p_mem_head); - acpiphp_move_resource(&func->bus_head, &bridge->bus_head); - spin_unlock(&bridge->res_lock); -} diff --git a/drivers/pci/hotplug/acpiphp_res.c b/drivers/pci/hotplug/acpiphp_res.c deleted file mode 100644 index f54b1fa..0000000 --- a/drivers/pci/hotplug/acpiphp_res.c +++ /dev/null @@ -1,700 +0,0 @@ -/* - * ACPI PCI HotPlug Utility functions - * - * Copyright (C) 1995,2001 Compaq Computer Corporation - * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) - * Copyright (C) 2001 IBM Corp. - * Copyright (C) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com) - * Copyright (C) 2002 Takayoshi Kochi (t-kochi@bq.jp.nec.com) - * Copyright (C) 2002 NEC Corporation - * - * All rights reserved. - * - * 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. - * - * This program 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, GOOD TITLE or - * NON INFRINGEMENT. See the GNU General Public License for more - * details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Send feedback to , - * - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include "pci_hotplug.h" -#include "acpiphp.h" - -#define MY_NAME "acpiphp_res" - - -/* - * sort_by_size - sort nodes by their length, smallest first - */ -static int sort_by_size(struct pci_resource **head) -{ - struct pci_resource *current_res; - struct pci_resource *next_res; - int out_of_order = 1; - - if (!(*head)) - return 1; - - if (!((*head)->next)) - return 0; - - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->length > (*head)->next->length)) { - out_of_order++; - current_res = *head; - *head = (*head)->next; - current_res->next = (*head)->next; - (*head)->next = current_res; - } - - current_res = *head; - - while (current_res->next && current_res->next->next) { - if (current_res->next->length > current_res->next->next->length) { - out_of_order++; - next_res = current_res->next; - current_res->next = current_res->next->next; - current_res = current_res->next; - next_res->next = current_res->next; - current_res->next = next_res; - } else - current_res = current_res->next; - } - } /* End of out_of_order loop */ - - return 0; -} - -#if 0 -/* - * sort_by_max_size - sort nodes by their length, largest first - */ -static int sort_by_max_size(struct pci_resource **head) -{ - struct pci_resource *current_res; - struct pci_resource *next_res; - int out_of_order = 1; - - if (!(*head)) - return 1; - - if (!((*head)->next)) - return 0; - - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->length < (*head)->next->length)) { - out_of_order++; - current_res = *head; - *head = (*head)->next; - current_res->next = (*head)->next; - (*head)->next = current_res; - } - - current_res = *head; - - while (current_res->next && current_res->next->next) { - if (current_res->next->length < current_res->next->next->length) { - out_of_order++; - next_res = current_res->next; - current_res->next = current_res->next->next; - current_res = current_res->next; - next_res->next = current_res->next; - current_res->next = next_res; - } else - current_res = current_res->next; - } - } /* End of out_of_order loop */ - - return 0; -} -#endif - -/** - * get_io_resource - get resource for I/O ports - * - * this function sorts the resource list by size and then - * returns the first node of "size" length that is not in the - * ISA aliasing window. If it finds a node larger than "size" - * it will split it up. - * - * size must be a power of two. - * - * difference from get_resource is handling of ISA aliasing space. - * - */ -struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - if (sort_by_size(head)) - return NULL; - - for (node = *head; node; node = node->next) { - if (node->length < size) - continue; - - if (node->base & (size - 1)) { - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = (node->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_qword - node->base)) < size) - continue; - - split_node = acpiphp_make_resource(node->base, temp_qword - node->base); - - if (!split_node) - return NULL; - - node->base = temp_qword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of non-aligned base */ - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = acpiphp_make_resource(node->base + size, node->length - size); - - if (!split_node) - return NULL; - - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - /* For IO make sure it's not in the ISA aliasing space */ - if ((node->base & 0x300L) && !(node->base & 0xfffff000)) - continue; - - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - - return node; -} - - -#if 0 -/** - * get_max_resource - get the largest resource - * - * Gets the largest node that is at least "size" big from the - * list pointed to by head. It aligns the node on top and bottom - * to "size" alignment before returning it. - */ -static struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *max; - struct pci_resource *temp; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - if (sort_by_max_size(head)) - return NULL; - - for (max = *head;max; max = max->next) { - - /* If not big enough we could probably just bail, - instead we'll continue to the next. */ - if (max->length < size) - continue; - - if (max->base & (size - 1)) { - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = (max->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((max->length - (temp_qword - max->base)) < size) - continue; - - split_node = acpiphp_make_resource(max->base, temp_qword - max->base); - - if (!split_node) - return NULL; - - max->base = temp_qword; - max->length -= split_node->length; - - /* Put it next in the list */ - split_node->next = max->next; - max->next = split_node; - } - - if ((max->base + max->length) & (size - 1)) { - /* this one isn't end aligned properly at the top - so we'll make a new entry and split it up */ - temp_qword = ((max->base + max->length) & ~(size - 1)); - - split_node = acpiphp_make_resource(temp_qword, - max->length + max->base - temp_qword); - - if (!split_node) - return NULL; - - max->length -= split_node->length; - - /* Put it in the list */ - split_node->next = max->next; - max->next = split_node; - } - - /* Make sure it didn't shrink too much when we aligned it */ - if (max->length < size) - continue; - - /* Now take it out of the list */ - temp = (struct pci_resource*) *head; - if (temp == max) { - *head = max->next; - } else { - while (temp && temp->next != max) { - temp = temp->next; - } - - temp->next = max->next; - } - - max->next = NULL; - return max; - } - - /* If we get here, we couldn't find one */ - return NULL; -} -#endif - -/** - * get_resource - get resource (mem, pfmem) - * - * this function sorts the resource list by size and then - * returns the first node of "size" length. If it finds a node - * larger than "size" it will split it up. - * - * size must be a power of two. - * - */ -struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - if (sort_by_size(head)) - return NULL; - - for (node = *head; node; node = node->next) { - dbg("%s: req_size =%x node=%p, base=%x, length=%x\n", - __FUNCTION__, size, node, (u32)node->base, node->length); - if (node->length < size) - continue; - - if (node->base & (size - 1)) { - dbg("%s: not aligned\n", __FUNCTION__); - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = (node->base | (size-1)) + 1; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_qword - node->base)) < size) - continue; - - split_node = acpiphp_make_resource(node->base, temp_qword - node->base); - - if (!split_node) - return NULL; - - node->base = temp_qword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of non-aligned base */ - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - dbg("%s: too big\n", __FUNCTION__); - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = acpiphp_make_resource(node->base + size, node->length - size); - - if (!split_node) - return NULL; - - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - dbg("%s: got one!!!\n", __FUNCTION__); - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - return node; -} - -/** - * get_resource_with_base - get resource with specific base address - * - * this function - * returns the first node of "size" length located at specified base address. - * If it finds a node larger than "size" it will split it up. - * - * size must be a power of two. - * - */ -struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size) -{ - struct pci_resource *prevnode; - struct pci_resource *node; - struct pci_resource *split_node; - u64 temp_qword; - - if (!(*head)) - return NULL; - - if (acpiphp_resource_sort_and_combine(head)) - return NULL; - - for (node = *head; node; node = node->next) { - dbg(": 1st req_base=%x req_size =%x node=%p, base=%x, length=%x\n", - (u32)base, size, node, (u32)node->base, node->length); - if (node->base > base) - continue; - - if ((node->base + node->length) < (base + size)) - continue; - - if (node->base < base) { - dbg(": split 1\n"); - /* this one isn't base aligned properly - so we'll make a new entry and split it up */ - temp_qword = base; - - /* Short circuit if adjusted size is too small */ - if ((node->length - (temp_qword - node->base)) < size) - continue; - - split_node = acpiphp_make_resource(node->base, temp_qword - node->base); - - if (!split_node) - return NULL; - - node->base = temp_qword; - node->length -= split_node->length; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } - - dbg(": 2nd req_base=%x req_size =%x node=%p, base=%x, length=%x\n", - (u32)base, size, node, (u32)node->base, node->length); - - /* Don't need to check if too small since we already did */ - if (node->length > size) { - dbg(": split 2\n"); - /* this one is longer than we need - so we'll make a new entry and split it up */ - split_node = acpiphp_make_resource(node->base + size, node->length - size); - - if (!split_node) - return NULL; - - node->length = size; - - /* Put it in the list */ - split_node->next = node->next; - node->next = split_node; - } /* End of too big on top end */ - - dbg(": got one!!!\n"); - /* If we got here, then it is the right size - Now take it out of the list */ - if (*head == node) { - *head = node->next; - } else { - prevnode = *head; - while (prevnode->next != node) - prevnode = prevnode->next; - - prevnode->next = node->next; - } - node->next = NULL; - /* Stop looping */ - break; - } - return node; -} - - -/** - * acpiphp_resource_sort_and_combine - * - * Sorts all of the nodes in the list in ascending order by - * their base addresses. Also does garbage collection by - * combining adjacent nodes. - * - * returns 0 if success - */ -int acpiphp_resource_sort_and_combine (struct pci_resource **head) -{ - struct pci_resource *node1; - struct pci_resource *node2; - int out_of_order = 1; - - if (!(*head)) - return 1; - - dbg("*head->next = %p\n",(*head)->next); - - if (!(*head)->next) - return 0; /* only one item on the list, already sorted! */ - - dbg("*head->base = 0x%x\n",(u32)(*head)->base); - dbg("*head->next->base = 0x%x\n", (u32)(*head)->next->base); - while (out_of_order) { - out_of_order = 0; - - /* Special case for swapping list head */ - if (((*head)->next) && - ((*head)->base > (*head)->next->base)) { - node1 = *head; - (*head) = (*head)->next; - node1->next = (*head)->next; - (*head)->next = node1; - out_of_order++; - } - - node1 = (*head); - - while (node1->next && node1->next->next) { - if (node1->next->base > node1->next->next->base) { - out_of_order++; - node2 = node1->next; - node1->next = node1->next->next; - node1 = node1->next; - node2->next = node1->next; - node1->next = node2; - } else - node1 = node1->next; - } - } /* End of out_of_order loop */ - - node1 = *head; - - while (node1 && node1->next) { - if ((node1->base + node1->length) == node1->next->base) { - /* Combine */ - dbg("8..\n"); - node1->length += node1->next->length; - node2 = node1->next; - node1->next = node1->next->next; - kfree(node2); - } else - node1 = node1->next; - } - - return 0; -} - - -/** - * acpiphp_make_resource - make resource structure - * @base: base address of a resource - * @length: length of a resource - */ -struct pci_resource *acpiphp_make_resource (u64 base, u32 length) -{ - struct pci_resource *res; - - res = kmalloc(sizeof(struct pci_resource), GFP_KERNEL); - if (res) { - memset(res, 0, sizeof(struct pci_resource)); - res->base = base; - res->length = length; - } - - return res; -} - - -/** - * acpiphp_move_resource - move linked resources from one to another - * @from: head of linked resource list - * @to: head of linked resource list - */ -void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to) -{ - struct pci_resource *tmp; - - while (*from) { - tmp = (*from)->next; - (*from)->next = *to; - *to = *from; - *from = tmp; - } - - /* *from = NULL is guaranteed */ -} - - -/** - * acpiphp_free_resource - free all linked resources - * @res: head of linked resource list - */ -void acpiphp_free_resource (struct pci_resource **res) -{ - struct pci_resource *tmp; - - while (*res) { - tmp = (*res)->next; - kfree(*res); - *res = tmp; - } - - /* *res = NULL is guaranteed */ -} - - -/* debug support functions; will go away sometime :) */ -static void dump_resource(struct pci_resource *head) -{ - struct pci_resource *p; - int cnt; - - p = head; - cnt = 0; - - while (p) { - dbg("[%02d] %08x - %08x\n", - cnt++, (u32)p->base, (u32)p->base + p->length - 1); - p = p->next; - } -} - -void acpiphp_dump_resource(struct acpiphp_bridge *bridge) -{ - dbg("I/O resource:\n"); - dump_resource(bridge->io_head); - dbg("MEM resource:\n"); - dump_resource(bridge->mem_head); - dbg("PMEM resource:\n"); - dump_resource(bridge->p_mem_head); - dbg("BUS resource:\n"); - dump_resource(bridge->bus_head); -} - -void acpiphp_dump_func_resource(struct acpiphp_func *func) -{ - dbg("I/O resource:\n"); - dump_resource(func->io_head); - dbg("MEM resource:\n"); - dump_resource(func->mem_head); - dbg("PMEM resource:\n"); - dump_resource(func->p_mem_head); - dbg("BUS resource:\n"); - dump_resource(func->bus_head); -} -- cgit v1.1 From 364d5094a43ff2ceff3d19e40c4199771cb6cb8f Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:54 -0700 Subject: [PATCH] acpi hotplug: clean up notify handlers on acpiphp unload A root bridge may not have directly attached hotpluggable slots under it. Instead, it may have p2p bridges with slots under it. In this case, we need to clean up the p2p bridges and slots properly too. Patch below applies on top of the original patch, and fixes this problem. Without this, acpiphp leaves behind notify handlers on module unload, and subsequent module load attempts don't work properly too. Patch was tested on an ia64 Tiger4 box. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 41c3eb2..2f72e50 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -487,18 +487,12 @@ static struct acpiphp_bridge *acpiphp_handle_to_bridge(acpi_handle handle) return NULL; } -static void remove_bridge(acpi_handle handle) +static void cleanup_bridge(struct acpiphp_bridge *bridge) { struct list_head *list, *tmp; - struct acpiphp_bridge *bridge; struct acpiphp_slot *slot; acpi_status status; - - bridge = acpiphp_handle_to_bridge(handle); - if (!bridge) { - err("Could not find bridge for handle %p\n", handle); - return; - } + acpi_handle handle = bridge->handle; status = acpi_remove_notify_handler(handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge); @@ -529,6 +523,30 @@ static void remove_bridge(acpi_handle handle) kfree(bridge); } +static acpi_status +cleanup_p2p_bridge(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + struct acpiphp_bridge *bridge; + + if (!(bridge = acpiphp_handle_to_bridge(handle))) + return AE_OK; + cleanup_bridge(bridge); + return AE_OK; +} + +static void remove_bridge(acpi_handle handle) +{ + struct acpiphp_bridge *bridge; + + bridge = acpiphp_handle_to_bridge(handle); + if (bridge) { + cleanup_bridge(bridge); + } else { + /* clean-up p2p bridges under this host bridge */ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + (u32)1, cleanup_p2p_bridge, NULL, NULL); + } +} static int power_on_slot(struct acpiphp_slot *slot) { -- cgit v1.1 From 2f523b15901f654a9448bbd47ebe1e783ec3195b Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:55 -0700 Subject: [PATCH] acpi hotplug: fix slot power-down problem with acpiphp Earlier I reported that Matthew's acpiphp rewrite had problem in powering down slot on my i386 system. The following patch is needed to get the acpiphp rewrite properly powering down the slot. Signed-off-by: Dely Sy Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 2f72e50..1501eb2 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -600,7 +600,7 @@ static int power_off_slot(struct acpiphp_slot *slot) list_for_each (l, &slot->funcs) { func = list_entry(l, struct acpiphp_func, sibling); - if (func->pci_dev && (func->flags & FUNC_HAS_PS3)) { + if (func->flags & FUNC_HAS_PS3) { status = acpi_evaluate_object(func->handle, "_PS3", NULL, NULL); if (ACPI_FAILURE(status)) { warn("%s: _PS3 failed\n", __FUNCTION__); @@ -615,7 +615,7 @@ static int power_off_slot(struct acpiphp_slot *slot) func = list_entry(l, struct acpiphp_func, sibling); /* We don't want to call _EJ0 on non-existing functions. */ - if (func->pci_dev && (func->flags & FUNC_HAS_EJ0)) { + if (func->flags & FUNC_HAS_EJ0) { /* _EJ0 method take one argument */ arg_list.count = 1; arg_list.pointer = &arg; -- cgit v1.1 From 8e7561cfbdf00fb1cee694cef0e825d0548aedbc Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:56 -0700 Subject: [PATCH] acpi hotplug: aCPI based root bridge hot-add acpiphp changes to support acpi based root bridge hot-add. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 211 +++++++++++++++++++++++++++++++++++-- 1 file changed, 202 insertions(+), 9 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 1501eb2..a6270cc 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -6,6 +6,8 @@ * Copyright (C) 2002,2003 NEC Corporation * Copyright (C) 2003-2005 Matthew Wilcox (matthew.wilcox@hp.com) * Copyright (C) 2003-2005 Hewlett Packard + * Copyright (C) 2005 Rajesh Shah (rajesh.shah@intel.com) + * Copyright (C) 2005 Intel Corporation * * All rights reserved. * @@ -304,13 +306,15 @@ static void init_bridge_misc(struct acpiphp_bridge *bridge) register_slot, bridge, NULL); /* install notify handler */ - status = acpi_install_notify_handler(bridge->handle, + if (bridge->type != BRIDGE_TYPE_HOST) { + status = acpi_install_notify_handler(bridge->handle, ACPI_SYSTEM_NOTIFY, handle_hotplug_event_bridge, bridge); - if (ACPI_FAILURE(status)) { - err("failed to register interrupt notify handler\n"); + if (ACPI_FAILURE(status)) { + err("failed to register interrupt notify handler\n"); + } } list_add(&bridge->list, &bridge_list); @@ -820,6 +824,143 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) return retval; } +static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) +{ + u16 pci_cmd, pci_bctl; + struct pci_dev *cdev; + + /* Program hpp values for this device */ + if (!(dev->hdr_type == PCI_HEADER_TYPE_NORMAL || + (dev->hdr_type == PCI_HEADER_TYPE_BRIDGE && + (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) + return; + pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, + bridge->hpp.cache_line_size); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, + bridge->hpp.latency_timer); + pci_read_config_word(dev, PCI_COMMAND, &pci_cmd); + if (bridge->hpp.enable_SERR) + pci_cmd |= PCI_COMMAND_SERR; + else + pci_cmd &= ~PCI_COMMAND_SERR; + if (bridge->hpp.enable_PERR) + pci_cmd |= PCI_COMMAND_PARITY; + else + pci_cmd &= ~PCI_COMMAND_PARITY; + pci_write_config_word(dev, PCI_COMMAND, pci_cmd); + + /* Program bridge control value and child devices */ + if ((dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { + pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, + bridge->hpp.latency_timer); + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &pci_bctl); + if (bridge->hpp.enable_SERR) + pci_bctl |= PCI_BRIDGE_CTL_SERR; + else + pci_bctl &= ~PCI_BRIDGE_CTL_SERR; + if (bridge->hpp.enable_PERR) + pci_bctl |= PCI_BRIDGE_CTL_PARITY; + else + pci_bctl &= ~PCI_BRIDGE_CTL_PARITY; + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, pci_bctl); + if (dev->subordinate) { + list_for_each_entry(cdev, &dev->subordinate->devices, + bus_list) + program_hpp(cdev, bridge); + } + } +} + +static void acpiphp_set_hpp_values(acpi_handle handle, struct pci_bus *bus) +{ + struct acpiphp_bridge bridge; + struct pci_dev *dev; + + memset(&bridge, 0, sizeof(bridge)); + bridge.handle = handle; + decode_hpp(&bridge); + list_for_each_entry(dev, &bus->devices, bus_list) + program_hpp(dev, &bridge); + +} + +/* + * Remove devices for which we could not assign resources, call + * arch specific code to fix-up the bus + */ +static void acpiphp_sanitize_bus(struct pci_bus *bus) +{ + struct pci_dev *dev; + int i; + unsigned long type_mask = IORESOURCE_IO | IORESOURCE_MEM; + + list_for_each_entry(dev, &bus->devices, bus_list) { + for (i=0; iresource[i]; + if ((res->flags & type_mask) && !res->start && + res->end) { + /* Could not assign a required resources + * for this device, remove it */ + pci_remove_bus_device(dev); + break; + } + } + } +} + +/* Program resources in newly inserted bridge */ +static int acpiphp_configure_bridge (acpi_handle handle) +{ + struct acpi_pci_id pci_id; + struct pci_bus *bus; + + if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) { + err("cannot get PCI domain and bus number for bridge\n"); + return -EINVAL; + } + bus = pci_find_bus(pci_id.segment, pci_id.bus); + if (!bus) { + err("cannot find bus %d:%d\n", + pci_id.segment, pci_id.bus); + return -EINVAL; + } + + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + acpiphp_sanitize_bus(bus); + acpiphp_set_hpp_values(handle, bus); + pci_enable_bridges(bus); + return 0; +} + +static void handle_bridge_insertion(acpi_handle handle, u32 type) +{ + struct acpi_device *device, *pdevice; + acpi_handle phandle; + + if ((type != ACPI_NOTIFY_BUS_CHECK) && + (type != ACPI_NOTIFY_DEVICE_CHECK)) { + err("unexpected notification type %d\n", type); + return; + } + + acpi_get_parent(handle, &phandle); + if (acpi_bus_get_device(phandle, &pdevice)) { + dbg("no parent device, assuming NULL\n"); + pdevice = NULL; + } + if (acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE)) { + err("cannot add bridge to acpi list\n"); + return; + } + if (!acpiphp_configure_bridge(handle) && + !acpi_bus_start(device)) + add_bridge(handle); + else + err("cannot configure and start bridge\n"); + +} + /* * ACPI event handlers */ @@ -840,8 +981,19 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont char objname[64]; struct acpi_buffer buffer = { .length = sizeof(objname), .pointer = objname }; + struct acpi_device *device; - bridge = (struct acpiphp_bridge *)context; + if (acpi_bus_get_device(handle, &device)) { + /* This bridge must have just been physically inserted */ + handle_bridge_insertion(handle, type); + return; + } + + bridge = acpiphp_handle_to_bridge(handle); + if (!bridge) { + err("cannot get bridge info\n"); + return; + } acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); @@ -941,6 +1093,47 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex } } +static int is_root_bridge(acpi_handle handle) +{ + acpi_status status; + struct acpi_device_info *info; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + int i; + + status = acpi_get_object_info(handle, &buffer); + if (ACPI_SUCCESS(status)) { + info = buffer.pointer; + if ((info->valid & ACPI_VALID_HID) && + !strcmp(PCI_ROOT_HID_STRING, + info->hardware_id.value)) { + acpi_os_free(buffer.pointer); + return 1; + } + if (info->valid & ACPI_VALID_CID) { + for (i=0; i < info->compatibility_id.count; i++) { + if (!strcmp(PCI_ROOT_HID_STRING, + info->compatibility_id.id[i].value)) { + acpi_os_free(buffer.pointer); + return 1; + } + } + } + } + return 0; +} + +static acpi_status +find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + int *count = (int *)context; + + if (is_root_bridge(handle)) { + acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, + handle_hotplug_event_bridge, NULL); + (*count)++; + } + return AE_OK ; +} static struct acpi_pci_driver acpi_pci_hp_driver = { .add = add_bridge, @@ -953,15 +1146,15 @@ static struct acpi_pci_driver acpi_pci_hp_driver = { */ int __init acpiphp_glue_init(void) { - int num; - - if (list_empty(&pci_root_buses)) - return -1; + int num = 0; - num = acpi_pci_register_driver(&acpi_pci_hp_driver); + acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, find_root_bridges, &num, NULL); if (num <= 0) return -1; + else + acpi_pci_register_driver(&acpi_pci_hp_driver); return 0; } -- cgit v1.1 From 8d50e332c8bd4f4e8cc76e8ed7326aa6f18182aa Mon Sep 17 00:00:00 2001 From: Rajesh Shah Date: Thu, 28 Apr 2005 00:25:57 -0700 Subject: [PATCH] acpi hotplug: decouple slot power state changes from physical hotplug Current acpiphp code does not distinguish between the physical presence and power state of a device/slot. That is, if a device has to be disabled, it also tries to physically ejects the device. This patch decouples power state from physical presence. You can now echo to the corresponding sysfs power control file to repeatedly enable and disable a device without having to physically re-insert it. Signed-off-by: Rajesh Shah Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 69 +++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index a6270cc..b4a9212 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -592,8 +592,6 @@ static int power_off_slot(struct acpiphp_slot *slot) acpi_status status; struct acpiphp_func *func; struct list_head *l; - struct acpi_object_list arg_list; - union acpi_object arg; int retval = 0; @@ -615,27 +613,6 @@ static int power_off_slot(struct acpiphp_slot *slot) } } - list_for_each (l, &slot->funcs) { - func = list_entry(l, struct acpiphp_func, sibling); - - /* We don't want to call _EJ0 on non-existing functions. */ - if (func->flags & FUNC_HAS_EJ0) { - /* _EJ0 method take one argument */ - arg_list.count = 1; - arg_list.pointer = &arg; - arg.type = ACPI_TYPE_INTEGER; - arg.integer.value = 1; - - status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); - if (ACPI_FAILURE(status)) { - warn("%s: _EJ0 failed\n", __FUNCTION__); - retval = -1; - goto err_exit; - } else - break; - } - } - /* TBD: evaluate _STA to check if the slot is disabled */ slot->flags &= (~SLOT_POWEREDON); @@ -782,6 +759,39 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) } /** + * acpiphp_eject_slot - physically eject the slot + */ +static int acpiphp_eject_slot(struct acpiphp_slot *slot) +{ + acpi_status status; + struct acpiphp_func *func; + struct list_head *l; + struct acpi_object_list arg_list; + union acpi_object arg; + + list_for_each (l, &slot->funcs) { + func = list_entry(l, struct acpiphp_func, sibling); + + /* We don't want to call _EJ0 on non-existing functions. */ + if ((func->flags & FUNC_HAS_EJ0)) { + /* _EJ0 method take one argument */ + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = 1; + + status = acpi_evaluate_object(func->handle, "_EJ0", &arg_list, NULL); + if (ACPI_FAILURE(status)) { + warn("%s: _EJ0 failed\n", __FUNCTION__); + return -1; + } else + break; + } + } + return 0; +} + +/** * acpiphp_check_bridge - re-enumerate devices * * Iterate over all slots under this bridge and make sure that if a @@ -804,6 +814,8 @@ static int acpiphp_check_bridge(struct acpiphp_bridge *bridge) if (retval) { err("Error occurred in disabling\n"); goto err_exit; + } else { + acpiphp_eject_slot(slot); } disabled++; } else { @@ -1041,7 +1053,6 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont } } - /** * handle_hotplug_event_func - handle ACPI event on functions (i.e. slots) * @@ -1084,7 +1095,8 @@ static void handle_hotplug_event_func(acpi_handle handle, u32 type, void *contex case ACPI_NOTIFY_EJECT_REQUEST: /* request device eject */ dbg("%s: Device eject notify on %s\n", __FUNCTION__, objname); - acpiphp_disable_slot(func->slot); + if (!(acpiphp_disable_slot(func->slot))) + acpiphp_eject_slot(func->slot); break; default: @@ -1268,7 +1280,6 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot) return retval; } - /** * acpiphp_disable_slot - power off slot */ @@ -1300,11 +1311,7 @@ int acpiphp_disable_slot(struct acpiphp_slot *slot) */ u8 acpiphp_get_power_status(struct acpiphp_slot *slot) { - unsigned int sta; - - sta = get_slot_status(slot); - - return (sta & ACPI_STA_ENABLED) ? 1 : 0; + return (slot->flags & SLOT_POWEREDON); } -- cgit v1.1 From b1bb248a5d2230a3d8ef42199c742194a8580b15 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 28 Apr 2005 00:25:58 -0700 Subject: [PATCH] ACPI based I/O APIC hot-plug: add interfaces This patch adds the following new interfaces for I/O xAPIC hotplug. The implementation of these interfaces depends on each architecture. o int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); This new interface is to add a new I/O xAPIC specified by phys_addr and gsi_base pair. phys_addr is the physical address to which the I/O xAPIC is mapped and gsi_base is global system interrupt base of the I/O xAPIC. acpi_register_ioapic returns 0 on success, or negative value on error. o int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); This new interface is to remove a I/O xAPIC specified by gsi_base. acpi_unregister_ioapic returns 0 on success, or negative value on error. Signed-off-by: Kenji Kaneshige Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/acpi/boot.c | 16 ++++++++++++++++ arch/ia64/kernel/acpi.c | 17 +++++++++++++++++ include/linux/acpi.h | 3 +++ 3 files changed, 36 insertions(+) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 9f63ae0..f5360d8 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -507,6 +507,22 @@ acpi_unmap_lsapic(int cpu) EXPORT_SYMBOL(acpi_unmap_lsapic); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +int +acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + static unsigned long __init acpi_scan_rsdp ( unsigned long start, diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 72dfd9e..ab79886 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -825,4 +825,21 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) return AE_OK; } #endif /* CONFIG_NUMA */ + +int +acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_register_ioapic); + +int +acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) +{ + /* TBD */ + return -EINVAL; +} +EXPORT_SYMBOL(acpi_unregister_ioapic); + #endif /* CONFIG_ACPI_BOOT */ diff --git a/include/linux/acpi.h b/include/linux/acpi.h index b123cc0..f5bc298 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -407,6 +407,9 @@ int acpi_map_lsapic(acpi_handle handle, int *pcpu); int acpi_unmap_lsapic(int cpu); #endif /* CONFIG_ACPI_HOTPLUG_CPU */ +int acpi_register_ioapic(acpi_handle handle, u64 phys_addr, u32 gsi_base); +int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); + extern int acpi_mp_config; extern u32 pci_mmcfg_base_addr; -- cgit v1.1 From 0e888adc41ffc02b700ade715c182a17e766af84 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 28 Apr 2005 00:25:58 -0700 Subject: [PATCH] ACPI based I/O APIC hot-plug: ia64 support This is an ia64 implementation of acpi_register_ioapic() and acpi_unregister_ioapic() interfaces. Signed-off-by: Kenji Kaneshige Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ia64/kernel/acpi.c | 21 ++++--- arch/ia64/kernel/iosapic.c | 134 ++++++++++++++++++++++++++++++++++++++------- include/asm-ia64/iosapic.h | 12 +++- 3 files changed, 135 insertions(+), 32 deletions(-) diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index ab79886..cda06f8 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c @@ -236,9 +236,7 @@ acpi_parse_iosapic (acpi_table_entry_header *header, const unsigned long end) if (BAD_MADT_ENTRY(iosapic, end)) return -EINVAL; - iosapic_init(iosapic->address, iosapic->global_irq_base); - - return 0; + return iosapic_init(iosapic->address, iosapic->global_irq_base); } @@ -772,7 +770,7 @@ EXPORT_SYMBOL(acpi_unmap_lsapic); #ifdef CONFIG_ACPI_NUMA -acpi_status __init +acpi_status __devinit acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) { struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; @@ -829,16 +827,23 @@ acpi_map_iosapic (acpi_handle handle, u32 depth, void *context, void **ret) int acpi_register_ioapic (acpi_handle handle, u64 phys_addr, u32 gsi_base) { - /* TBD */ - return -EINVAL; + int err; + + if ((err = iosapic_init(phys_addr, gsi_base))) + return err; + +#if CONFIG_ACPI_NUMA + acpi_map_iosapic(handle, 0, NULL, NULL); +#endif /* CONFIG_ACPI_NUMA */ + + return 0; } EXPORT_SYMBOL(acpi_register_ioapic); int acpi_unregister_ioapic (acpi_handle handle, u32 gsi_base) { - /* TBD */ - return -EINVAL; + return iosapic_remove(gsi_base); } EXPORT_SYMBOL(acpi_unregister_ioapic); diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 88b0143..c170be0 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c @@ -129,14 +129,13 @@ static struct iosapic { char __iomem *addr; /* base address of IOSAPIC */ unsigned int gsi_base; /* first GSI assigned to this IOSAPIC */ unsigned short num_rte; /* number of RTE in this IOSAPIC */ + int rtes_inuse; /* # of RTEs in use on this IOSAPIC */ #ifdef CONFIG_NUMA unsigned short node; /* numa node association via pxm */ #endif } iosapic_lists[NR_IOSAPICS]; -static int num_iosapic; - -static unsigned char pcat_compat __initdata; /* 8259 compatibility flag */ +static unsigned char pcat_compat __devinitdata; /* 8259 compatibility flag */ static int iosapic_kmalloc_ok; static LIST_HEAD(free_rte_list); @@ -149,7 +148,7 @@ find_iosapic (unsigned int gsi) { int i; - for (i = 0; i < num_iosapic; i++) { + for (i = 0; i < NR_IOSAPICS; i++) { if ((unsigned) (gsi - iosapic_lists[i].gsi_base) < iosapic_lists[i].num_rte) return i; } @@ -598,6 +597,7 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, rte->refcnt++; list_add_tail(&rte->rte_list, &iosapic_intr_info[vector].rtes); iosapic_intr_info[vector].count++; + iosapic_lists[index].rtes_inuse++; } else if (vector_is_shared(vector)) { struct iosapic_intr_info *info = &iosapic_intr_info[vector]; @@ -778,7 +778,7 @@ void iosapic_unregister_intr (unsigned int gsi) { unsigned long flags; - int irq, vector; + int irq, vector, index; irq_desc_t *idesc; u32 low32; unsigned long trigger, polarity; @@ -819,6 +819,9 @@ iosapic_unregister_intr (unsigned int gsi) list_del(&rte->rte_list); iosapic_intr_info[vector].count--; iosapic_free_rte(rte); + index = find_iosapic(gsi); + iosapic_lists[index].rtes_inuse--; + WARN_ON(iosapic_lists[index].rtes_inuse < 0); trigger = iosapic_intr_info[vector].trigger; polarity = iosapic_intr_info[vector].polarity; @@ -952,30 +955,86 @@ iosapic_system_init (int system_pcat_compat) } } -void __init +static inline int +iosapic_alloc (void) +{ + int index; + + for (index = 0; index < NR_IOSAPICS; index++) + if (!iosapic_lists[index].addr) + return index; + + printk(KERN_WARNING "%s: failed to allocate iosapic\n", __FUNCTION__); + return -1; +} + +static inline void +iosapic_free (int index) +{ + memset(&iosapic_lists[index], 0, sizeof(iosapic_lists[0])); +} + +static inline int +iosapic_check_gsi_range (unsigned int gsi_base, unsigned int ver) +{ + int index; + unsigned int gsi_end, base, end; + + /* check gsi range */ + gsi_end = gsi_base + ((ver >> 16) & 0xff); + for (index = 0; index < NR_IOSAPICS; index++) { + if (!iosapic_lists[index].addr) + continue; + + base = iosapic_lists[index].gsi_base; + end = base + iosapic_lists[index].num_rte - 1; + + if (gsi_base < base && gsi_end < base) + continue;/* OK */ + + if (gsi_base > end && gsi_end > end) + continue; /* OK */ + + return -EBUSY; + } + return 0; +} + +int __devinit iosapic_init (unsigned long phys_addr, unsigned int gsi_base) { - int num_rte; + int num_rte, err, index; unsigned int isa_irq, ver; char __iomem *addr; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + addr = ioremap(phys_addr, 0); + ver = iosapic_version(addr); - addr = ioremap(phys_addr, 0); - ver = iosapic_version(addr); + if ((err = iosapic_check_gsi_range(gsi_base, ver))) { + iounmap(addr); + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; + } - /* - * The MAX_REDIR register holds the highest input pin - * number (starting from 0). - * We add 1 so that we can use it for number of pins (= RTEs) - */ - num_rte = ((ver >> 16) & 0xff) + 1; + /* + * The MAX_REDIR register holds the highest input pin + * number (starting from 0). + * We add 1 so that we can use it for number of pins (= RTEs) + */ + num_rte = ((ver >> 16) & 0xff) + 1; - iosapic_lists[num_iosapic].addr = addr; - iosapic_lists[num_iosapic].gsi_base = gsi_base; - iosapic_lists[num_iosapic].num_rte = num_rte; + index = iosapic_alloc(); + iosapic_lists[index].addr = addr; + iosapic_lists[index].gsi_base = gsi_base; + iosapic_lists[index].num_rte = num_rte; #ifdef CONFIG_NUMA - iosapic_lists[num_iosapic].node = MAX_NUMNODES; + iosapic_lists[index].node = MAX_NUMNODES; #endif - num_iosapic++; + } + spin_unlock_irqrestore(&iosapic_lock, flags); if ((gsi_base == 0) && pcat_compat) { /* @@ -986,10 +1045,43 @@ iosapic_init (unsigned long phys_addr, unsigned int gsi_base) for (isa_irq = 0; isa_irq < 16; ++isa_irq) iosapic_override_isa_irq(isa_irq, isa_irq, IOSAPIC_POL_HIGH, IOSAPIC_EDGE); } + return 0; +} + +#ifdef CONFIG_HOTPLUG +int +iosapic_remove (unsigned int gsi_base) +{ + int index, err = 0; + unsigned long flags; + + spin_lock_irqsave(&iosapic_lock, flags); + { + index = find_iosapic(gsi_base); + if (index < 0) { + printk(KERN_WARNING "%s: No IOSAPIC for GSI base %u\n", + __FUNCTION__, gsi_base); + goto out; + } + + if (iosapic_lists[index].rtes_inuse) { + err = -EBUSY; + printk(KERN_WARNING "%s: IOSAPIC for GSI base %u is busy\n", + __FUNCTION__, gsi_base); + goto out; + } + + iounmap(iosapic_lists[index].addr); + iosapic_free(index); + } + out: + spin_unlock_irqrestore(&iosapic_lock, flags); + return err; } +#endif /* CONFIG_HOTPLUG */ #ifdef CONFIG_NUMA -void __init +void __devinit map_iosapic_to_node(unsigned int gsi_base, int node) { int index; diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h index 38a7a72..1093f35 100644 --- a/include/asm-ia64/iosapic.h +++ b/include/asm-ia64/iosapic.h @@ -71,8 +71,11 @@ static inline void iosapic_eoi(char __iomem *iosapic, u32 vector) } extern void __init iosapic_system_init (int pcat_compat); -extern void __init iosapic_init (unsigned long address, +extern int __devinit iosapic_init (unsigned long address, unsigned int gsi_base); +#ifdef CONFIG_HOTPLUG +extern int iosapic_remove (unsigned int gsi_base); +#endif /* CONFIG_HOTPLUG */ extern int gsi_to_vector (unsigned int gsi); extern int gsi_to_irq (unsigned int gsi); extern void iosapic_enable_intr (unsigned int vector); @@ -94,11 +97,14 @@ extern unsigned int iosapic_version (char __iomem *addr); extern void iosapic_pci_fixup (int); #ifdef CONFIG_NUMA -extern void __init map_iosapic_to_node (unsigned int, int); +extern void __devinit map_iosapic_to_node (unsigned int, int); #endif #else #define iosapic_system_init(pcat_compat) do { } while (0) -#define iosapic_init(address,gsi_base) do { } while (0) +#define iosapic_init(address,gsi_base) (-EINVAL) +#ifdef CONFIG_HOTPLUG +#define iosapic_remove(gsi_base) (-ENODEV) +#endif /* CONFIG_HOTPLUG */ #define iosapic_register_intr(gsi,polarity,trigger) (gsi) #define iosapic_unregister_intr(irq) do { } while (0) #define iosapic_override_isa_irq(isa_irq,gsi,polarity,trigger) do { } while (0) -- cgit v1.1 From a0d399a808916d22c1c222c6b5ca4e8edd6d91a9 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Thu, 28 Apr 2005 00:25:59 -0700 Subject: [PATCH] ACPI based I/O APIC hot-plug: acpiphp support This patch adds PCI based I/O xAPIC hot-add support to ACPIPHP driver. When PCI root bridge is hot-added, all PCI based I/O xAPICs under the root bridge are hot-added by this patch. Hot-remove support is TBD. Signed-off-by: Kenji Kaneshige Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/acpiphp_glue.c | 127 +++++++++++++++++++++++++++++++++++++ include/linux/pci_ids.h | 2 + 2 files changed, 129 insertions(+) diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index b4a9212..424e7de 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c @@ -552,6 +552,132 @@ static void remove_bridge(acpi_handle handle) } } +static struct pci_dev * get_apic_pci_info(acpi_handle handle) +{ + struct acpi_pci_id id; + struct pci_bus *bus; + struct pci_dev *dev; + + if (ACPI_FAILURE(acpi_get_pci_id(handle, &id))) + return NULL; + + bus = pci_find_bus(id.segment, id.bus); + if (!bus) + return NULL; + + dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function)); + if (!dev) + return NULL; + + if ((dev->class != PCI_CLASS_SYSTEM_PIC_IOAPIC) && + (dev->class != PCI_CLASS_SYSTEM_PIC_IOXAPIC)) + { + pci_dev_put(dev); + return NULL; + } + + return dev; +} + +static int get_gsi_base(acpi_handle handle, u32 *gsi_base) +{ + acpi_status status; + int result = -1; + unsigned long gsb; + struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *obj; + void *table; + + status = acpi_evaluate_integer(handle, "_GSB", NULL, &gsb); + if (ACPI_SUCCESS(status)) { + *gsi_base = (u32)gsb; + return 0; + } + + status = acpi_evaluate_object(handle, "_MAT", NULL, &buffer); + if (ACPI_FAILURE(status) || !buffer.length || !buffer.pointer) + return -1; + + obj = buffer.pointer; + if (obj->type != ACPI_TYPE_BUFFER) + goto out; + + table = obj->buffer.pointer; + switch (((acpi_table_entry_header *)table)->type) { + case ACPI_MADT_IOSAPIC: + *gsi_base = ((struct acpi_table_iosapic *)table)->global_irq_base; + result = 0; + break; + case ACPI_MADT_IOAPIC: + *gsi_base = ((struct acpi_table_ioapic *)table)->global_irq_base; + result = 0; + break; + default: + break; + } + out: + acpi_os_free(buffer.pointer); + return result; +} + +static acpi_status +ioapic_add(acpi_handle handle, u32 lvl, void *context, void **rv) +{ + acpi_status status; + unsigned long sta; + acpi_handle tmp; + struct pci_dev *pdev; + u32 gsi_base; + u64 phys_addr; + + /* Evaluate _STA if present */ + status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); + if (ACPI_SUCCESS(status) && sta != ACPI_STA_ALL) + return AE_CTRL_DEPTH; + + /* Scan only PCI bus scope */ + status = acpi_get_handle(handle, "_HID", &tmp); + if (ACPI_SUCCESS(status)) + return AE_CTRL_DEPTH; + + if (get_gsi_base(handle, &gsi_base)) + return AE_OK; + + pdev = get_apic_pci_info(handle); + if (!pdev) + return AE_OK; + + if (pci_enable_device(pdev)) { + pci_dev_put(pdev); + return AE_OK; + } + + pci_set_master(pdev); + + if (pci_request_region(pdev, 0, "I/O APIC(acpiphp)")) { + pci_disable_device(pdev); + pci_dev_put(pdev); + return AE_OK; + } + + phys_addr = pci_resource_start(pdev, 0); + if (acpi_register_ioapic(handle, phys_addr, gsi_base)) { + pci_release_region(pdev, 0); + pci_disable_device(pdev); + pci_dev_put(pdev); + return AE_OK; + } + + return AE_OK; +} + +static int acpiphp_configure_ioapics(acpi_handle handle) +{ + acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, + ACPI_UINT32_MAX, ioapic_add, NULL, NULL); + return 0; +} + static int power_on_slot(struct acpiphp_slot *slot) { acpi_status status; @@ -942,6 +1068,7 @@ static int acpiphp_configure_bridge (acpi_handle handle) acpiphp_sanitize_bus(bus); acpiphp_set_hpp_values(handle, bus); pci_enable_bridges(bus); + acpiphp_configure_ioapics(handle); return 0; } diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index bf60880..810bbbc 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -62,6 +62,8 @@ #define PCI_BASE_CLASS_SYSTEM 0x08 #define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010 +#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020 #define PCI_CLASS_SYSTEM_DMA 0x0801 #define PCI_CLASS_SYSTEM_TIMER 0x0802 #define PCI_CLASS_SYSTEM_RTC 0x0803 -- cgit v1.1 From 2311b1f2bbd36fa5f366a7448c718b2556e0f02c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Fri, 13 May 2005 17:44:10 +1000 Subject: [PATCH] PCI: fix-pci-mmap-on-ppc-and-ppc64.patch This is an updated version of Ben's fix-pci-mmap-on-ppc-and-ppc64.patch which is in 2.6.12-rc4-mm1. It fixes the patch to work on PPC iSeries, removes some debug printks at Ben's request, and incorporates your fix-pci-mmap-on-ppc-and-ppc64-fix.patch also. Originally from Benjamin Herrenschmidt This patch was discussed at length on linux-pci and so far, the last iteration of it didn't raise any comment. It's effect is a nop on architecture that don't define the new pci_resource_to_user() callback anyway. It allows architecture like ppc who put weird things inside of PCI resource structures to convert to some different value for user visible ones. It also fixes mmap'ing of IO space on those archs. Signed-off-by: Benjamin Herrenschmidt Signed-off-by: Michael Ellerman Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- arch/ppc/kernel/pci.c | 21 +++++++++++++++++++-- arch/ppc64/kernel/pci.c | 22 ++++++++++++++++++++-- drivers/pci/pci-sysfs.c | 26 +++++++++++++++++++++----- drivers/pci/proc.c | 14 ++++++++++---- include/asm-ppc/pci.h | 6 ++++++ include/asm-ppc64/pci.h | 7 +++++++ include/linux/pci.h | 14 ++++++++++++++ 7 files changed, 97 insertions(+), 13 deletions(-) diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d7b92d..70cfb6f 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -1495,7 +1495,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = hose->io_base_virt - ___IO_BASE; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -1522,7 +1522,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - _IO_BASE; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -1739,6 +1739,23 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) return result; } +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + void __init pci_init_resource(struct resource *res, unsigned long start, unsigned long end, int flags, char *name) diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index 580676f..ae6f579 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c @@ -351,7 +351,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, *offset += hose->pci_mem_offset; res_bit = IORESOURCE_MEM; } else { - io_offset = (unsigned long)hose->io_base_virt; + io_offset = (unsigned long)hose->io_base_virt - pci_io_base; *offset += io_offset; res_bit = IORESOURCE_IO; } @@ -378,7 +378,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev, /* found it! construct the final physical address */ if (mmap_state == pci_mmap_io) - *offset += hose->io_base_phys - io_offset; + *offset += hose->io_base_phys - io_offset; return rp; } @@ -944,4 +944,22 @@ int pci_read_irq_line(struct pci_dev *pci_dev) } EXPORT_SYMBOL(pci_read_irq_line); +void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end) +{ + struct pci_controller *hose = pci_bus_to_host(dev->bus); + unsigned long offset = 0; + + if (hose == NULL) + return; + + if (rsrc->flags & IORESOURCE_IO) + offset = pci_io_base - (unsigned long)hose->io_base_virt + + hose->io_base_phys; + + *start = rsrc->start + offset; + *end = rsrc->end + offset; +} + #endif /* CONFIG_PPC_MULTIPLATFORM */ diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index a15f940..cc9d653 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -60,15 +60,18 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) char * str = buf; int i; int max = 7; + u64 start, end; if (pci_dev->subordinate) max = DEVICE_COUNT_RESOURCE; for (i = 0; i < max; i++) { - str += sprintf(str,"0x%016lx 0x%016lx 0x%016lx\n", - pci_resource_start(pci_dev,i), - pci_resource_end(pci_dev,i), - pci_resource_flags(pci_dev,i)); + struct resource *res = &pci_dev->resource[i]; + pci_resource_to_user(pci_dev, i, res, &start, &end); + str += sprintf(str,"0x%016llx 0x%016llx 0x%016llx\n", + (unsigned long long)start, + (unsigned long long)end, + (unsigned long long)res->flags); } return (str - buf); } @@ -313,8 +316,21 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct device, kobj)); struct resource *res = (struct resource *)attr->private; enum pci_mmap_state mmap_type; + u64 start, end; + int i; - vma->vm_pgoff += res->start >> PAGE_SHIFT; + for (i = 0; i < PCI_ROM_RESOURCE; i++) + if (res == &pdev->resource[i]) + break; + if (i >= PCI_ROM_RESOURCE) + return -ENODEV; + + /* pci_mmap_page_range() expects the same kind of entry as coming + * from /proc/bus/pci/ which is a "user visible" value. If this is + * different from the resource itself, arch will do necessary fixup. + */ + pci_resource_to_user(pdev, i, res, &start, &end); + vma->vm_pgoff += start >> PAGE_SHIFT; mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io; return pci_mmap_page_range(pdev, vma, mmap_type, 0); diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index e68bbfb..7988fc8 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -355,14 +355,20 @@ static int show_device(struct seq_file *m, void *v) dev->device, dev->irq); /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ - for(i=0; i<7; i++) + for (i=0; i<7; i++) { + u64 start, end; + pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); seq_printf(m, LONG_FORMAT, - dev->resource[i].start | + ((unsigned long)start) | (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); - for(i=0; i<7; i++) + } + for (i=0; i<7; i++) { + u64 start, end; + pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); seq_printf(m, LONG_FORMAT, dev->resource[i].start < dev->resource[i].end ? - dev->resource[i].end - dev->resource[i].start + 1 : 0); + (unsigned long)(end - start) + 1 : 0); + } seq_putc(m, '\t'); if (drv) seq_printf(m, "%s", drv->name); diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index ce5ae6d..002e7b3 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -103,6 +103,12 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, unsigned long size, pgprot_t prot); +#define HAVE_ARCH_PCI_RESOURCE_TO_USER +extern void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end); + + #endif /* __KERNEL__ */ #endif /* __PPC_PCI_H */ diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index 6cd593f..411bf5d 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h @@ -136,6 +136,13 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file, unsigned long size, pgprot_t prot); +#ifdef CONFIG_PPC_MULTIPLATFORM +#define HAVE_ARCH_PCI_RESOURCE_TO_USER +extern void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, + u64 *start, u64 *end); +#endif /* CONFIG_PPC_MULTIPLATFORM */ + #endif /* __KERNEL__ */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 0e98449..cfa1455 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1020,6 +1020,20 @@ static inline char *pci_name(struct pci_dev *pdev) #define pci_pretty_name(dev) "" #endif + +/* Some archs don't want to expose struct resource to userland as-is + * in sysfs and /proc + */ +#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER +static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, u64 *start, u64 *end) +{ + *start = rsrc->start; + *end = rsrc->end; +} +#endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */ + + /* * The world is not perfect and supplies us with broken PCI devices. * For at least a part of these bugs we need a work-around, so both -- cgit v1.1 From e24c2d963a604d9eaa560c90371fa387d3eec8f1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 2 Jun 2005 12:55:50 -0700 Subject: [PATCH] PCI: DMA bursting advice After seeing, at best, "guesses" as to the following kind of information in several drivers, I decided that we really need a way for platforms to specifically give advice in this area for what works best with their PCI controller implementation. Basically, this new interface gives DMA bursting advice on PCI. There are three forms of the advice: 1) Burst as much as possible, it is not necessary to end bursts on some particular boundary for best performance. 2) Burst on some byte count multiple. A DMA burst to some multiple of number of bytes may be done, but it is important to end the burst on an exact multiple for best performance. The best example of this I am aware of are the PPC64 PCI controllers, where if you end a burst mid-cacheline then chip has to refetch the data and the IOMMU translations which hurts performance a lot. 3) Burst on a single byte count multiple. Bursts shall end exactly on the next multiple boundary for best performance. Sparc64 and Alpha's PCI controllers operate this way. They disconnect any device which tries to burst across a cacheline boundary. Actually, newer sparc64 PCI controllers do not have this behavior. That is why the "pdev" is passed into the interface, so I can add code later to check which PCI controller the system is using and give advice accordingly. Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/asm-alpha/pci.h | 17 +++++++++++++++++ include/asm-arm/pci.h | 8 ++++++++ include/asm-frv/pci.h | 8 ++++++++ include/asm-i386/pci.h | 8 ++++++++ include/asm-ia64/pci.h | 17 +++++++++++++++++ include/asm-mips/pci.h | 8 ++++++++ include/asm-parisc/pci.h | 17 +++++++++++++++++ include/asm-ppc/pci.h | 8 ++++++++ include/asm-ppc64/pci.h | 17 +++++++++++++++++ include/asm-sh/pci.h | 8 ++++++++ include/asm-sh64/pci.h | 8 ++++++++ include/asm-sparc/pci.h | 8 ++++++++ include/asm-sparc64/pci.h | 17 +++++++++++++++++ include/asm-v850/pci.h | 8 ++++++++ include/asm-x86_64/pci.h | 8 ++++++++ include/linux/pci.h | 9 +++++++++ 16 files changed, 174 insertions(+) diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 0c7b57b..6c71dc1 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -223,6 +223,23 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, /* Nothing to do. */ } +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_BOUNDARY; + *strategy_parameter = cacheline_size; +} + /* TODO: integrate with include/asm-generic/pci.h ? */ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) { diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index 40ffaef..bc2ec42 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -42,6 +42,14 @@ static inline void pcibios_penalize_isa_irq(int irq) #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + #define HAVE_PCI_MMAP extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h index a6a4692..1342724 100644 --- a/include/asm-frv/pci.h +++ b/include/asm-frv/pci.h @@ -57,6 +57,14 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, */ #define PCI_DMA_BUS_IS_PHYS (1) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + /* * These are pretty much arbitary with the CoMEM implementation. * We have the whole address space to ourselves. diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index fb749b8..bf07b3a 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -99,6 +99,14 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + #endif /* __KERNEL__ */ /* implement the pci_ DMA API in terms of the generic device dma_ one */ diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index a8314ee..c9f1ab4 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -82,6 +82,23 @@ extern int pcibios_prep_mwi (struct pci_dev *); #define sg_dma_len(sg) ((sg)->dma_length) #define sg_dma_address(sg) ((sg)->dma_address) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} + #define HAVE_PCI_MMAP extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index c9c576b..20b93bf 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -130,6 +130,14 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction); +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index 0763c29..f9f5bf9 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -230,6 +230,23 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x) /* export the pci_ DMA API in terms of the dma_ one */ #include +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} + extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 002e7b3..669e9de 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -69,6 +69,14 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); #define pci_unmap_len(PTR, LEN_NAME) (0) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + /* * At present there are very few 32-bit PPC machines that can have * memory above the 4GB point, and we don't support that. diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index 411bf5d..20beb10 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h @@ -78,6 +78,23 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) return 0; } +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} + extern int pci_domain_nr(struct pci_bus *bus); /* Decide whether to display the domain number in /proc */ diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 9c3b63d..7237bc6 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -96,6 +96,14 @@ static inline void pcibios_penalize_isa_irq(int irq) #define sg_dma_address(sg) (virt_to_bus((sg)->dma_address)) #define sg_dma_len(sg) ((sg)->length) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + /* Board-specific fixup routines. */ extern void pcibios_fixup(void); extern void pcibios_fixup_irqs(void); diff --git a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h index 8cc14e139..0ac15ab 100644 --- a/include/asm-sh64/pci.h +++ b/include/asm-sh64/pci.h @@ -86,6 +86,14 @@ static inline void pcibios_penalize_isa_irq(int irq) #define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + /* Board-specific fixup routines. */ extern void pcibios_fixup(void); extern void pcibios_fixup_irqs(void); diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h index d200a25..2fd65db 100644 --- a/include/asm-sparc/pci.h +++ b/include/asm-sparc/pci.h @@ -144,6 +144,14 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) #define pci_dac_dma_supported(dev, mask) (0) +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 2a0c85c..4026673 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -220,6 +220,23 @@ static inline int pci_dma_mapping_error(dma_addr_t dma_addr) return (dma_addr == PCI_DMA_ERROR_CODE); } +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_BOUNDARY; + *strategy_parameter = cacheline_size; +} + /* Return the index of the PCI controller for device PDEV. */ extern int pci_domain_nr(struct pci_bus *bus); diff --git a/include/asm-v850/pci.h b/include/asm-v850/pci.h index e419414..d26eb8d 100644 --- a/include/asm-v850/pci.h +++ b/include/asm-v850/pci.h @@ -81,6 +81,14 @@ extern void pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr, dma_addr_t dma_addr); +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 8712520..8461d6a 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h @@ -123,6 +123,14 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, flush_write_buffers(); } +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + *strat = PCI_DMA_BURST_INFINITY; + *strategy_parameter = ~0UL; +} + #define HAVE_PCI_MMAP extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, enum pci_mmap_state mmap_state, int write_combine); diff --git a/include/linux/pci.h b/include/linux/pci.h index cfa1455..9ce4f1b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -874,6 +874,15 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass #define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle) #define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr) +enum pci_dma_burst_strategy { + PCI_DMA_BURST_INFINITY, /* make bursts as large as possible, + strategy_parameter is N/A */ + PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter + byte boundaries */ + PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of + strategy_parameter byte boundaries */ +}; + #if defined(CONFIG_ISA) || defined(CONFIG_EISA) extern struct pci_dev *isa_bridge; #endif -- cgit v1.1 From bb4a61b6eaee01707f24deeefc5d7136f25f75c5 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 6 Jun 2005 23:07:46 -0700 Subject: [PATCH] PCI: fix up errors after dma bursting patch and CONFIG_PCI=n With CONFIG_PCI=n: In file included from include/linux/pci.h:917, from lib/iomap.c:6: include/asm/pci.h:104: warning: `enum pci_dma_burst_strategy' declared inside parameter list include/asm/pci.h:104: warning: its scope is only this definition or declaration, which is probably not what you want. include/asm/pci.h: In function `pci_dma_burst_advice': include/asm/pci.h:106: dereferencing pointer to incomplete type include/asm/pci.h:106: `PCI_DMA_BURST_INFINITY' undeclared (first use in this function) include/asm/pci.h:106: (Each undeclared identifier is reported only once include/asm/pci.h:106: for each function it appears in.) make[1]: *** [lib/iomap.o] Error 1 Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/asm-alpha/pci.h | 2 ++ include/asm-arm/pci.h | 2 ++ include/asm-frv/pci.h | 2 ++ include/asm-i386/pci.h | 2 ++ include/asm-ia64/pci.h | 2 ++ include/asm-mips/pci.h | 2 ++ include/asm-parisc/pci.h | 2 ++ include/asm-ppc/pci.h | 2 ++ include/asm-ppc64/pci.h | 2 ++ include/asm-sh/pci.h | 2 ++ include/asm-sh64/pci.h | 2 ++ include/asm-sparc/pci.h | 2 ++ include/asm-sparc64/pci.h | 2 ++ include/asm-v850/pci.h | 2 ++ include/asm-x86_64/pci.h | 2 ++ include/linux/pci.h | 2 ++ 16 files changed, 32 insertions(+) diff --git a/include/asm-alpha/pci.h b/include/asm-alpha/pci.h index 6c71dc1..b7806aa 100644 --- a/include/asm-alpha/pci.h +++ b/include/asm-alpha/pci.h @@ -223,6 +223,7 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, /* Nothing to do. */ } +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -239,6 +240,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_BOUNDARY; *strategy_parameter = cacheline_size; } +#endif /* TODO: integrate with include/asm-generic/pci.h ? */ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index bc2ec42..e300646 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -42,6 +42,7 @@ static inline void pcibios_penalize_isa_irq(int irq) #define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -49,6 +50,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif #define HAVE_PCI_MMAP extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, diff --git a/include/asm-frv/pci.h b/include/asm-frv/pci.h index 1342724..b4efe5e 100644 --- a/include/asm-frv/pci.h +++ b/include/asm-frv/pci.h @@ -57,6 +57,7 @@ extern void pci_free_consistent(struct pci_dev *hwdev, size_t size, */ #define PCI_DMA_BUS_IS_PHYS (1) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -64,6 +65,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif /* * These are pretty much arbitary with the CoMEM implementation. diff --git a/include/asm-i386/pci.h b/include/asm-i386/pci.h index bf07b3a..3561899 100644 --- a/include/asm-i386/pci.h +++ b/include/asm-i386/pci.h @@ -99,6 +99,7 @@ static inline void pcibios_add_platform_entries(struct pci_dev *dev) { } +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -106,6 +107,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif #endif /* __KERNEL__ */ diff --git a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h index c9f1ab4..0c4c5d8 100644 --- a/include/asm-ia64/pci.h +++ b/include/asm-ia64/pci.h @@ -82,6 +82,7 @@ extern int pcibios_prep_mwi (struct pci_dev *); #define sg_dma_len(sg) ((sg)->dma_length) #define sg_dma_address(sg) ((sg)->dma_address) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -98,6 +99,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_MULTIPLE; *strategy_parameter = cacheline_size; } +#endif #define HAVE_PCI_MMAP extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h index 20b93bf..2d323b6 100644 --- a/include/asm-mips/pci.h +++ b/include/asm-mips/pci.h @@ -130,6 +130,7 @@ extern void pci_dac_dma_sync_single_for_cpu(struct pci_dev *pdev, extern void pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, size_t len, int direction); +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -137,6 +138,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, struct resource *res); diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index f9f5bf9..ee741c1 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -230,6 +230,7 @@ extern inline void pcibios_register_hba(struct pci_hba_data *x) /* export the pci_ DMA API in terms of the dma_ one */ #include +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -246,6 +247,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_MULTIPLE; *strategy_parameter = cacheline_size; } +#endif extern void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 669e9de..db0a2a0 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -69,6 +69,7 @@ extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); #define pci_unmap_len(PTR, LEN_NAME) (0) #define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -76,6 +77,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif /* * At present there are very few 32-bit PPC machines that can have diff --git a/include/asm-ppc64/pci.h b/include/asm-ppc64/pci.h index 20beb10..d12dfce 100644 --- a/include/asm-ppc64/pci.h +++ b/include/asm-ppc64/pci.h @@ -78,6 +78,7 @@ static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) return 0; } +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -94,6 +95,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_MULTIPLE; *strategy_parameter = cacheline_size; } +#endif extern int pci_domain_nr(struct pci_bus *bus); diff --git a/include/asm-sh/pci.h b/include/asm-sh/pci.h index 7237bc6..2604488 100644 --- a/include/asm-sh/pci.h +++ b/include/asm-sh/pci.h @@ -96,6 +96,7 @@ static inline void pcibios_penalize_isa_irq(int irq) #define sg_dma_address(sg) (virt_to_bus((sg)->dma_address)) #define sg_dma_len(sg) ((sg)->length) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -103,6 +104,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif /* Board-specific fixup routines. */ extern void pcibios_fixup(void); diff --git a/include/asm-sh64/pci.h b/include/asm-sh64/pci.h index 0ac15ab..c68870e 100644 --- a/include/asm-sh64/pci.h +++ b/include/asm-sh64/pci.h @@ -86,6 +86,7 @@ static inline void pcibios_penalize_isa_irq(int irq) #define sg_dma_address(sg) ((sg)->dma_address) #define sg_dma_len(sg) ((sg)->length) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -93,6 +94,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif /* Board-specific fixup routines. */ extern void pcibios_fixup(void); diff --git a/include/asm-sparc/pci.h b/include/asm-sparc/pci.h index 2fd65db..44bb387 100644 --- a/include/asm-sparc/pci.h +++ b/include/asm-sparc/pci.h @@ -144,6 +144,7 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, u64 mask) #define pci_dac_dma_supported(dev, mask) (0) +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -151,6 +152,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif static inline void pcibios_add_platform_entries(struct pci_dev *dev) { diff --git a/include/asm-sparc64/pci.h b/include/asm-sparc64/pci.h index 4026673..84e41c1 100644 --- a/include/asm-sparc64/pci.h +++ b/include/asm-sparc64/pci.h @@ -220,6 +220,7 @@ static inline int pci_dma_mapping_error(dma_addr_t dma_addr) return (dma_addr == PCI_DMA_ERROR_CODE); } +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -236,6 +237,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_BOUNDARY; *strategy_parameter = cacheline_size; } +#endif /* Return the index of the PCI controller for device PDEV. */ diff --git a/include/asm-v850/pci.h b/include/asm-v850/pci.h index d26eb8d..8e79be0 100644 --- a/include/asm-v850/pci.h +++ b/include/asm-v850/pci.h @@ -81,6 +81,7 @@ extern void pci_free_consistent (struct pci_dev *pdev, size_t size, void *cpu_addr, dma_addr_t dma_addr); +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -88,6 +89,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif static inline void pcibios_add_platform_entries(struct pci_dev *dev) { diff --git a/include/asm-x86_64/pci.h b/include/asm-x86_64/pci.h index 8461d6a..c1961db 100644 --- a/include/asm-x86_64/pci.h +++ b/include/asm-x86_64/pci.h @@ -123,6 +123,7 @@ pci_dac_dma_sync_single_for_device(struct pci_dev *pdev, dma64_addr_t dma_addr, flush_write_buffers(); } +#ifdef CONFIG_PCI static inline void pci_dma_burst_advice(struct pci_dev *pdev, enum pci_dma_burst_strategy *strat, unsigned long *strategy_parameter) @@ -130,6 +131,7 @@ static inline void pci_dma_burst_advice(struct pci_dev *pdev, *strat = PCI_DMA_BURST_INFINITY; *strategy_parameter = ~0UL; } +#endif #define HAVE_PCI_MMAP extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, diff --git a/include/linux/pci.h b/include/linux/pci.h index 9ce4f1b..66798b4 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -985,6 +985,8 @@ static inline int pci_proc_domain(struct pci_bus *bus) } #endif +#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) + #endif /* !CONFIG_PCI */ /* these helpers provide future and backwards compatibility -- cgit v1.1 From 70549ad9cf074e12f12cdc931b29b2616dfb873a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 6 Jun 2005 23:07:46 -0700 Subject: [PATCH] PCI: clean up the MSI code a bit. Mostly just cleans up the irq handling logic to be smaller and a bit more descriptive as to what it really does. Signed-off-by: Greg Kroah-Hartman --- drivers/pci/msi.c | 88 +++++++++++++++++++++---------------------------------- drivers/pci/msi.h | 9 +++--- 2 files changed, 37 insertions(+), 60 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 30206ac..b5ab9aa6 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -28,10 +28,10 @@ static struct msi_desc* msi_desc[NR_IRQS] = { [0 ... NR_IRQS-1] = NULL }; static kmem_cache_t* msi_cachep; static int pci_msi_enable = 1; -static int last_alloc_vector = 0; -static int nr_released_vectors = 0; +static int last_alloc_vector; +static int nr_released_vectors; static int nr_reserved_vectors = NR_HP_RESERVED_VECTORS; -static int nr_msix_devices = 0; +static int nr_msix_devices; #ifndef CONFIG_X86_IO_APIC int vector_irq[NR_VECTORS] = { [0 ... NR_VECTORS - 1] = -1}; @@ -170,44 +170,30 @@ static unsigned int startup_msi_irq_wo_maskbit(unsigned int vector) return 0; /* never anything pending */ } -static void release_msi(unsigned int vector); -static void shutdown_msi_irq(unsigned int vector) -{ - release_msi(vector); -} - -#define shutdown_msi_irq_wo_maskbit shutdown_msi_irq -static void enable_msi_irq_wo_maskbit(unsigned int vector) {} -static void disable_msi_irq_wo_maskbit(unsigned int vector) {} -static void ack_msi_irq_wo_maskbit(unsigned int vector) {} -static void end_msi_irq_wo_maskbit(unsigned int vector) +static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) { - move_msi(vector); - ack_APIC_irq(); + startup_msi_irq_wo_maskbit(vector); + unmask_MSI_irq(vector); + return 0; /* never anything pending */ } -static unsigned int startup_msi_irq_w_maskbit(unsigned int vector) +static void shutdown_msi_irq(unsigned int vector) { struct msi_desc *entry; unsigned long flags; spin_lock_irqsave(&msi_lock, flags); entry = msi_desc[vector]; - if (!entry || !entry->dev) { - spin_unlock_irqrestore(&msi_lock, flags); - return 0; - } - entry->msi_attrib.state = 1; /* Mark it active */ + if (entry && entry->dev) + entry->msi_attrib.state = 0; /* Mark it not active */ spin_unlock_irqrestore(&msi_lock, flags); - - unmask_MSI_irq(vector); - return 0; /* never anything pending */ } -#define shutdown_msi_irq_w_maskbit shutdown_msi_irq -#define enable_msi_irq_w_maskbit unmask_MSI_irq -#define disable_msi_irq_w_maskbit mask_MSI_irq -#define ack_msi_irq_w_maskbit mask_MSI_irq +static void end_msi_irq_wo_maskbit(unsigned int vector) +{ + move_msi(vector); + ack_APIC_irq(); +} static void end_msi_irq_w_maskbit(unsigned int vector) { @@ -216,6 +202,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector) ack_APIC_irq(); } +static void do_nothing(unsigned int vector) +{ +} + /* * Interrupt Type for MSI-X PCI/PCI-X/PCI-Express Devices, * which implement the MSI-X Capability Structure. @@ -223,10 +213,10 @@ static void end_msi_irq_w_maskbit(unsigned int vector) static struct hw_interrupt_type msix_irq_type = { .typename = "PCI-MSI-X", .startup = startup_msi_irq_w_maskbit, - .shutdown = shutdown_msi_irq_w_maskbit, - .enable = enable_msi_irq_w_maskbit, - .disable = disable_msi_irq_w_maskbit, - .ack = ack_msi_irq_w_maskbit, + .shutdown = shutdown_msi_irq, + .enable = unmask_MSI_irq, + .disable = mask_MSI_irq, + .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, .set_affinity = set_msi_irq_affinity }; @@ -239,10 +229,10 @@ static struct hw_interrupt_type msix_irq_type = { static struct hw_interrupt_type msi_irq_w_maskbit_type = { .typename = "PCI-MSI", .startup = startup_msi_irq_w_maskbit, - .shutdown = shutdown_msi_irq_w_maskbit, - .enable = enable_msi_irq_w_maskbit, - .disable = disable_msi_irq_w_maskbit, - .ack = ack_msi_irq_w_maskbit, + .shutdown = shutdown_msi_irq, + .enable = unmask_MSI_irq, + .disable = mask_MSI_irq, + .ack = mask_MSI_irq, .end = end_msi_irq_w_maskbit, .set_affinity = set_msi_irq_affinity }; @@ -255,10 +245,10 @@ static struct hw_interrupt_type msi_irq_w_maskbit_type = { static struct hw_interrupt_type msi_irq_wo_maskbit_type = { .typename = "PCI-MSI", .startup = startup_msi_irq_wo_maskbit, - .shutdown = shutdown_msi_irq_wo_maskbit, - .enable = enable_msi_irq_wo_maskbit, - .disable = disable_msi_irq_wo_maskbit, - .ack = ack_msi_irq_wo_maskbit, + .shutdown = shutdown_msi_irq, + .enable = do_nothing, + .disable = do_nothing, + .ack = do_nothing, .end = end_msi_irq_wo_maskbit, .set_affinity = set_msi_irq_affinity }; @@ -407,7 +397,7 @@ static struct msi_desc* alloc_msi_entry(void) { struct msi_desc *entry; - entry = (struct msi_desc*) kmem_cache_alloc(msi_cachep, SLAB_KERNEL); + entry = kmem_cache_alloc(msi_cachep, SLAB_KERNEL); if (!entry) return NULL; @@ -796,18 +786,6 @@ void pci_disable_msi(struct pci_dev* dev) } } -static void release_msi(unsigned int vector) -{ - struct msi_desc *entry; - unsigned long flags; - - spin_lock_irqsave(&msi_lock, flags); - entry = msi_desc[vector]; - if (entry && entry->dev) - entry->msi_attrib.state = 0; /* Mark it not active */ - spin_unlock_irqrestore(&msi_lock, flags); -} - static int msi_free_vector(struct pci_dev* dev, int vector, int reassign) { struct msi_desc *entry; @@ -924,7 +902,7 @@ static int reroute_msix_table(int head, struct msix_entry *entries, int *nvec) /** * pci_enable_msix - configure device's MSI-X capability structure * @dev: pointer to the pci_dev data structure of MSI-X device function - * @data: pointer to an array of MSI-X entries + * @entries: pointer to an array of MSI-X entries * @nvec: number of MSI-X vectors requested for allocation by device driver * * Setup the MSI-X capability structure of device function with the number diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index bef21ae..390f185 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h @@ -41,11 +41,11 @@ static inline void move_msi(int vector) {} #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) #define PCI_MSIX_FLAGS_BITMASK (1 << 0) -#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 -#define PCI_MSIX_ENTRY_DATA_OFFSET 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 #define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR_OFFSET 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR_OFFSET 4 +#define PCI_MSIX_ENTRY_DATA_OFFSET 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET 12 #define msi_control_reg(base) (base + PCI_MSI_FLAGS) #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) @@ -64,7 +64,6 @@ static inline void move_msi(int vector) {} #define msi_enable(control, num) multi_msi_enable(control, num); \ control |= PCI_MSI_FLAGS_ENABLE -#define msix_control_reg msi_control_reg #define msix_table_offset_reg(base) (base + 0x04) #define msix_pba_offset_reg(base) (base + 0x08) #define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE -- cgit v1.1 From 4002307d2b563a6ab317ca4d7eb1d201a6673d37 Mon Sep 17 00:00:00 2001 From: Keith Moore Date: Thu, 2 Jun 2005 12:42:37 +0200 Subject: [PATCH] cpqphp: fix oops during unload without probe drivers/pci/hotplug/cpqphp_core.c calls cpqphp_event_start_thread() in one_time_init(), which is called whenever the hardware is probed. Unfortunately, cpqphp_event_stop_thread() is *always* called when the module is unloaded. If the hardware is never probed, then cpqphp_event_stop_thread() tries to manipulate a couple of uninitialized mutexes. Signed-off-by: Keith Moore Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpqphp_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index afbccfa..8c6d398 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c @@ -60,6 +60,7 @@ static void __iomem *smbios_start; static void __iomem *cpqhp_rom_start; static int power_mode; static int debug; +static int initialized; #define DRIVER_VERSION "0.9.8" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman " @@ -1271,7 +1272,6 @@ static int one_time_init(void) { int loop; int retval = 0; - static int initialized = 0; if (initialized) return 0; @@ -1441,7 +1441,8 @@ static void __exit unload_cpqphpd(void) } // Stop the notification mechanism - cpqhp_event_stop_thread(); + if (initialized) + cpqhp_event_stop_thread(); //unmap the rom address if (cpqhp_rom_start) -- cgit v1.1 From d18c3db58bc544fce6662ca7edba616ca9788a70 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: make drivers use the pci shutdown callback instead of the driver core callback. Now we can change the pci core to always set this pointer, as pci drivers should use it, not the driver core callback. Signed-off-by: Greg Kroah-Hartman --- drivers/message/fusion/mptfc.c | 4 +--- drivers/message/fusion/mptscsih.c | 10 +++++----- drivers/message/fusion/mptscsih.h | 2 +- drivers/message/fusion/mptspi.c | 4 +--- drivers/net/e100.c | 9 ++------- drivers/net/via-rhine.c | 11 ++++------- drivers/scsi/3w-9xxx.c | 8 +++----- drivers/scsi/3w-xxxx.c | 8 +++----- drivers/scsi/ipr.c | 10 ++++------ drivers/scsi/megaraid.c | 8 +++----- 10 files changed, 27 insertions(+), 47 deletions(-) diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index d8d6539..353deb2 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -364,9 +364,7 @@ static struct pci_driver mptfc_driver = { .id_table = mptfc_pci_table, .probe = mptfc_probe, .remove = __devexit_p(mptscsih_remove), - .driver = { - .shutdown = mptscsih_shutdown, - }, + .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, .resume = mptscsih_resume, diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c index a0078ae..4f973a4 100644 --- a/drivers/message/fusion/mptscsih.c +++ b/drivers/message/fusion/mptscsih.c @@ -170,7 +170,7 @@ static void mptscsih_fillbuf(char *buffer, int size, int index, int width); #endif void mptscsih_remove(struct pci_dev *); -void mptscsih_shutdown(struct device *); +void mptscsih_shutdown(struct pci_dev *); #ifdef CONFIG_PM int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); int mptscsih_resume(struct pci_dev *pdev); @@ -988,7 +988,7 @@ mptscsih_remove(struct pci_dev *pdev) #endif #endif - mptscsih_shutdown(&pdev->dev); + mptscsih_shutdown(pdev); sz1=0; @@ -1026,9 +1026,9 @@ mptscsih_remove(struct pci_dev *pdev) * */ void -mptscsih_shutdown(struct device * dev) +mptscsih_shutdown(struct pci_dev *pdev) { - MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev)); + MPT_ADAPTER *ioc = pci_get_drvdata(pdev); struct Scsi_Host *host = ioc->sh; MPT_SCSI_HOST *hd; @@ -1054,7 +1054,7 @@ mptscsih_shutdown(struct device * dev) int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) { - mptscsih_shutdown(&pdev->dev); + mptscsih_shutdown(pdev); return mpt_suspend(pdev,state); } diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h index d73aec3..5ea89bf 100644 --- a/drivers/message/fusion/mptscsih.h +++ b/drivers/message/fusion/mptscsih.h @@ -82,7 +82,7 @@ #endif extern void mptscsih_remove(struct pci_dev *); -extern void mptscsih_shutdown(struct device *); +extern void mptscsih_shutdown(struct pci_dev *); #ifdef CONFIG_PM extern int mptscsih_suspend(struct pci_dev *pdev, u32 state); extern int mptscsih_resume(struct pci_dev *pdev); diff --git a/drivers/message/fusion/mptspi.c b/drivers/message/fusion/mptspi.c index 5f9a61b..e0c0ee5 100644 --- a/drivers/message/fusion/mptspi.c +++ b/drivers/message/fusion/mptspi.c @@ -419,9 +419,7 @@ static struct pci_driver mptspi_driver = { .id_table = mptspi_pci_table, .probe = mptspi_probe, .remove = __devexit_p(mptscsih_remove), - .driver = { - .shutdown = mptscsih_shutdown, - }, + .shutdown = mptscsih_shutdown, #ifdef CONFIG_PM .suspend = mptscsih_suspend, .resume = mptscsih_resume, diff --git a/drivers/net/e100.c b/drivers/net/e100.c index cfaa6b2b..be973a1 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c @@ -2440,9 +2440,8 @@ static int e100_resume(struct pci_dev *pdev) #endif -static void e100_shutdown(struct device *dev) +static void e100_shutdown(struct pci_dev *pdev) { - struct pci_dev *pdev = container_of(dev, struct pci_dev, dev); struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); @@ -2463,11 +2462,7 @@ static struct pci_driver e100_driver = { .suspend = e100_suspend, .resume = e100_resume, #endif - - .driver = { - .shutdown = e100_shutdown, - } - + .shutdown = e100_shutdown, }; static int __init e100_init_module(void) diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index 6200cfc..16212e6 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -507,7 +507,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev); static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static struct ethtool_ops netdev_ethtool_ops; static int rhine_close(struct net_device *dev); -static void rhine_shutdown (struct device *gdev); +static void rhine_shutdown (struct pci_dev *pdev); #define RHINE_WAIT_FOR(condition) do { \ int i=1024; \ @@ -1895,9 +1895,8 @@ static void __devexit rhine_remove_one(struct pci_dev *pdev) pci_set_drvdata(pdev, NULL); } -static void rhine_shutdown (struct device *gendev) +static void rhine_shutdown (struct pci_dev *pdev) { - struct pci_dev *pdev = to_pci_dev(gendev); struct net_device *dev = pci_get_drvdata(pdev); struct rhine_private *rp = netdev_priv(dev); void __iomem *ioaddr = rp->base; @@ -1956,7 +1955,7 @@ static int rhine_suspend(struct pci_dev *pdev, pm_message_t state) pci_save_state(pdev); spin_lock_irqsave(&rp->lock, flags); - rhine_shutdown(&pdev->dev); + rhine_shutdown(pdev); spin_unlock_irqrestore(&rp->lock, flags); free_irq(dev->irq, dev); @@ -2010,9 +2009,7 @@ static struct pci_driver rhine_driver = { .suspend = rhine_suspend, .resume = rhine_resume, #endif /* CONFIG_PM */ - .driver = { - .shutdown = rhine_shutdown, - } + .shutdown = rhine_shutdown, }; diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 34dbc37..bc6e462 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -1916,9 +1916,9 @@ static void __twa_shutdown(TW_Device_Extension *tw_dev) } /* End __twa_shutdown() */ /* Wrapper for __twa_shutdown */ -static void twa_shutdown(struct device *dev) +static void twa_shutdown(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + struct Scsi_Host *host = pci_get_drvdata(pdev); TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; __twa_shutdown(tw_dev); @@ -2140,9 +2140,7 @@ static struct pci_driver twa_driver = { .id_table = twa_pci_tbl, .probe = twa_probe, .remove = twa_remove, - .driver = { - .shutdown = twa_shutdown - } + .shutdown = twa_shutdown }; /* This function is called on driver initialization */ diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index b6dc576..973c51f 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -2264,9 +2264,9 @@ static void __tw_shutdown(TW_Device_Extension *tw_dev) } /* End __tw_shutdown() */ /* Wrapper for __tw_shutdown */ -static void tw_shutdown(struct device *dev) +static void tw_shutdown(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + struct Scsi_Host *host = pci_get_drvdata(pdev); TW_Device_Extension *tw_dev = (TW_Device_Extension *)host->hostdata; __tw_shutdown(tw_dev); @@ -2451,9 +2451,7 @@ static struct pci_driver tw_driver = { .id_table = tw_pci_tbl, .probe = tw_probe, .remove = tw_remove, - .driver = { - .shutdown = tw_shutdown - } + .shutdown = tw_shutdown, }; /* This function is called on driver initialization */ diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 80d0226..babd483 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -6012,7 +6012,7 @@ static int __devinit ipr_probe(struct pci_dev *pdev, /** * ipr_shutdown - Shutdown handler. - * @dev: device struct + * @pdev: pci device struct * * This function is invoked upon system shutdown/reboot. It will issue * an adapter shutdown to the adapter to flush the write cache. @@ -6020,9 +6020,9 @@ static int __devinit ipr_probe(struct pci_dev *pdev, * Return value: * none **/ -static void ipr_shutdown(struct device *dev) +static void ipr_shutdown(struct pci_dev *pdev) { - struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(to_pci_dev(dev)); + struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); unsigned long lock_flags = 0; spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); @@ -6068,9 +6068,7 @@ static struct pci_driver ipr_driver = { .id_table = ipr_pci_table, .probe = ipr_probe, .remove = ipr_remove, - .driver = { - .shutdown = ipr_shutdown, - }, + .shutdown = ipr_shutdown, }; /** diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index ec81532..a70cdf3 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -5036,9 +5036,9 @@ megaraid_remove_one(struct pci_dev *pdev) } static void -megaraid_shutdown(struct device *dev) +megaraid_shutdown(struct pci_dev *pdev) { - struct Scsi_Host *host = pci_get_drvdata(to_pci_dev(dev)); + struct Scsi_Host *host = pci_get_drvdata(pdev); adapter_t *adapter = (adapter_t *)host->hostdata; __megaraid_shutdown(adapter); @@ -5070,9 +5070,7 @@ static struct pci_driver megaraid_pci_driver = { .id_table = megaraid_pci_tbl, .probe = megaraid_probe_one, .remove = __devexit_p(megaraid_remove_one), - .driver = { - .shutdown = megaraid_shutdown, - }, + .shutdown = megaraid_shutdown, }; static int __init megaraid_init(void) -- cgit v1.1 From 545493917dc90298e1c38f018ad893f5518928e7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: add proper MCFG table parsing to ACPI core. This patch is the first step in properly handling the MCFG PCI table. It defines the structures properly, and saves off the table so that the pci mmconfig code can access it. It moves the parsing of the table a little later in the boot process, but still before the information is needed. Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/acpi/boot.c | 41 +++++++++++++++++++++++++++++++++-------- arch/i386/pci/mmconfig.c | 12 +++++++----- arch/x86_64/pci/mmconfig.c | 16 +++++++++------- include/linux/acpi.h | 16 +++++++++++++--- 4 files changed, 62 insertions(+), 23 deletions(-) diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index f5360d8..b7808a8 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -159,9 +159,15 @@ char *__acpi_map_table(unsigned long phys, unsigned long size) #endif #ifdef CONFIG_PCI_MMCONFIG -static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) +/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ +struct acpi_table_mcfg_config *pci_mmcfg_config; +int pci_mmcfg_config_num; + +int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) { struct acpi_table_mcfg *mcfg; + unsigned long i; + int config_size; if (!phys_addr || !size) return -EINVAL; @@ -172,18 +178,38 @@ static int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) return -ENODEV; } - if (mcfg->base_reserved) { - printk(KERN_ERR PREFIX "MMCONFIG not in low 4GB of memory\n"); + /* how many config structures do we have */ + pci_mmcfg_config_num = 0; + i = size - sizeof(struct acpi_table_mcfg); + while (i >= sizeof(struct acpi_table_mcfg_config)) { + ++pci_mmcfg_config_num; + i -= sizeof(struct acpi_table_mcfg_config); + }; + if (pci_mmcfg_config_num == 0) { + printk(KERN_ERR PREFIX "MMCONFIG has no entries\n"); return -ENODEV; } - pci_mmcfg_base_addr = mcfg->base_address; + config_size = pci_mmcfg_config_num * sizeof(*pci_mmcfg_config); + pci_mmcfg_config = kmalloc(config_size, GFP_KERNEL); + if (!pci_mmcfg_config) { + printk(KERN_WARNING PREFIX + "No memory for MCFG config tables\n"); + return -ENOMEM; + } + + memcpy(pci_mmcfg_config, &mcfg->config, config_size); + for (i = 0; i < pci_mmcfg_config_num; ++i) { + if (mcfg->config[i].base_reserved) { + printk(KERN_ERR PREFIX + "MMCONFIG not in low 4GB of memory\n"); + return -ENODEV; + } + } return 0; } -#else -#define acpi_parse_mcfg NULL -#endif /* !CONFIG_PCI_MMCONFIG */ +#endif /* CONFIG_PCI_MMCONFIG */ #ifdef CONFIG_X86_LOCAL_APIC static int __init @@ -1139,7 +1165,6 @@ int __init acpi_boot_init(void) acpi_process_madt(); acpi_table_parse(ACPI_HPET, acpi_parse_hpet); - acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); return 0; } diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 021a50a..5fbaa91 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -11,11 +11,9 @@ #include #include +#include #include "pci.h" -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - #define mmcfg_virt_addr ((void __iomem *) fix_to_virt(FIX_PCIE_MCFG)) /* The base address of the last MMCONFIG device accessed */ @@ -27,7 +25,7 @@ static u32 mmcfg_last_accessed_device; static inline void pci_exp_set_dev_base(int bus, int devfn) { - u32 dev_base = pci_mmcfg_base_addr | (bus << 20) | (devfn << 12); + u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -101,7 +99,11 @@ static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) goto out; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) goto out; /* Kludge for now. Don't use mmconfig on AMD systems because diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index b693c23..09cfcc12 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -7,15 +7,13 @@ #include #include +#include #include "pci.h" #define MMCONFIG_APER_SIZE (256*1024*1024) -/* The physical address of the MMCONFIG aperture. Set from ACPI tables. */ -u32 pci_mmcfg_base_addr; - /* Static virtual mapping of the MMCONFIG aperture */ -char *pci_mmcfg_virt; +static char *pci_mmcfg_virt; static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) { @@ -77,7 +75,11 @@ static int __init pci_mmcfg_init(void) { if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 0; - if (!pci_mmcfg_base_addr) + + acpi_table_parse(ACPI_MCFG, acpi_parse_mcfg); + if ((pci_mmcfg_config_num == 0) || + (pci_mmcfg_config == NULL) || + (pci_mmcfg_config[0].base_address == 0)) return 0; /* Kludge for now. Don't use mmconfig on AMD systems because @@ -88,13 +90,13 @@ static int __init pci_mmcfg_init(void) return 0; /* RED-PEN i386 doesn't do _nocache right now */ - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_base_addr, MMCONFIG_APER_SIZE); + pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE); if (!pci_mmcfg_virt) { printk("PCI: Cannot map mmconfig aperture\n"); return 0; } - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_base_addr); + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index f5bc298..ef84836 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -342,11 +342,19 @@ struct acpi_table_ecdt { /* PCI MMCONFIG */ +/* Defined in PCI Firmware Specification 3.0 */ +struct acpi_table_mcfg_config { + u32 base_address; + u32 base_reserved; + u16 pci_segment_group_number; + u8 start_bus_number; + u8 end_bus_number; + u8 reserved[4]; +} __attribute__ ((packed)); struct acpi_table_mcfg { struct acpi_table_header header; u8 reserved[8]; - u32 base_address; - u32 base_reserved; + struct acpi_table_mcfg_config config[0]; } __attribute__ ((packed)); /* Table Handlers */ @@ -391,6 +399,7 @@ int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler); int acpi_get_table_header_early (enum acpi_table_id id, struct acpi_table_header **header); int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler handler, unsigned int max_entries); +int acpi_parse_mcfg (unsigned long phys_addr, unsigned long size); void acpi_table_print (struct acpi_table_header *header, unsigned long phys_addr); void acpi_table_print_madt_entry (acpi_table_entry_header *madt); void acpi_table_print_srat_entry (acpi_table_entry_header *srat); @@ -412,7 +421,8 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base); extern int acpi_mp_config; -extern u32 pci_mmcfg_base_addr; +extern struct acpi_table_mcfg_config *pci_mmcfg_config; +extern int pci_mmcfg_config_num; extern int sbf_port ; -- cgit v1.1 From d57e26ceb7dbf44cd08128cb6146116d4281b58b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: use the MCFG table to properly access pci devices (i386) Now that we have access to the whole MCFG table, let's properly use it for all pci device accesses (as that's what it is there for, some boxes don't put all the busses into one entry.) If, for some reason, the table is incorrect, we fallback to the "old style" of mmconfig accesses, namely, we just assume the first entry in the table is the one for us, and blindly use it. Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/mmconfig.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/arch/i386/pci/mmconfig.c b/arch/i386/pci/mmconfig.c index 5fbaa91..60f0e7a 100644 --- a/arch/i386/pci/mmconfig.c +++ b/arch/i386/pci/mmconfig.c @@ -22,10 +22,31 @@ static u32 mmcfg_last_accessed_device; /* * Functions for accessing PCI configuration space with MMCONFIG accesses */ +static u32 get_base_addr(unsigned int seg, int bus) +{ + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_config[0].base_address; + } + cfg = &pci_mmcfg_config[cfg_num]; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return cfg->base_address; + } +} -static inline void pci_exp_set_dev_base(int bus, int devfn) +static inline void pci_exp_set_dev_base(unsigned int seg, int bus, int devfn) { - u32 dev_base = pci_mmcfg_config[0].base_address | (bus << 20) | (devfn << 12); + u32 dev_base = get_base_addr(seg, bus) | (bus << 20) | (devfn << 12); if (dev_base != mmcfg_last_accessed_device) { mmcfg_last_accessed_device = dev_base; set_fixmap_nocache(FIX_PCIE_MCFG, dev_base); @@ -42,7 +63,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: @@ -71,7 +92,7 @@ static int pci_mmcfg_write(unsigned int seg, unsigned int bus, spin_lock_irqsave(&pci_config_lock, flags); - pci_exp_set_dev_base(bus, devfn); + pci_exp_set_dev_base(seg, bus, devfn); switch (len) { case 1: -- cgit v1.1 From 1cde8a16815bd85c8137d1ea556398983c597c11 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 23 Jun 2005 17:35:56 -0700 Subject: [PATCH] PCI: use the MCFG table to properly access pci devices (x86-64) Now that we have access to the whole MCFG table, let's properly use it for all pci device accesses (as that's what it is there for, some boxes don't put all the busses into one entry.) If, for some reason, the table is incorrect, we fallback to the "old style" of mmconfig accesses, namely, we just assume the first entry in the table is the one for us, and blindly use it. Signed-off-by: Greg Kroah-Hartman --- arch/x86_64/pci/mmconfig.c | 58 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 48 insertions(+), 10 deletions(-) diff --git a/arch/x86_64/pci/mmconfig.c b/arch/x86_64/pci/mmconfig.c index 09cfcc12..657e88a 100644 --- a/arch/x86_64/pci/mmconfig.c +++ b/arch/x86_64/pci/mmconfig.c @@ -13,17 +13,44 @@ #define MMCONFIG_APER_SIZE (256*1024*1024) /* Static virtual mapping of the MMCONFIG aperture */ -static char *pci_mmcfg_virt; +struct mmcfg_virt { + struct acpi_table_mcfg_config *cfg; + char *virt; +}; +static struct mmcfg_virt *pci_mmcfg_virt; -static inline char *pci_dev_base(unsigned int bus, unsigned int devfn) +static char *get_virt(unsigned int seg, int bus) { - return pci_mmcfg_virt + ((bus << 20) | (devfn << 12)); + int cfg_num = -1; + struct acpi_table_mcfg_config *cfg; + + while (1) { + ++cfg_num; + if (cfg_num >= pci_mmcfg_config_num) { + /* something bad is going on, no cfg table is found. */ + /* so we fall back to the old way we used to do this */ + /* and just rely on the first entry to be correct. */ + return pci_mmcfg_virt[0].virt; + } + cfg = pci_mmcfg_virt[cfg_num].cfg; + if (cfg->pci_segment_group_number != seg) + continue; + if ((cfg->start_bus_number <= bus) && + (cfg->end_bus_number >= bus)) + return pci_mmcfg_virt[cfg_num].virt; + } +} + +static inline char *pci_dev_base(unsigned int seg, unsigned int bus, unsigned int devfn) +{ + + return get_virt(seg, bus) + ((bus << 20) | (devfn << 12)); } static int pci_mmcfg_read(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 *value) { - char *addr = pci_dev_base(bus, devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely(!value || (bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -46,7 +73,7 @@ static int pci_mmcfg_read(unsigned int seg, unsigned int bus, static int pci_mmcfg_write(unsigned int seg, unsigned int bus, unsigned int devfn, int reg, int len, u32 value) { - char *addr = pci_dev_base(bus,devfn); + char *addr = pci_dev_base(seg, bus, devfn); if (unlikely((bus > 255) || (devfn > 255) || (reg > 4095))) return -EINVAL; @@ -73,6 +100,8 @@ static struct pci_raw_ops pci_mmcfg = { static int __init pci_mmcfg_init(void) { + int i; + if ((pci_probe & PCI_PROBE_MMCONF) == 0) return 0; @@ -90,13 +119,22 @@ static int __init pci_mmcfg_init(void) return 0; /* RED-PEN i386 doesn't do _nocache right now */ - pci_mmcfg_virt = ioremap_nocache(pci_mmcfg_config[0].base_address, MMCONFIG_APER_SIZE); - if (!pci_mmcfg_virt) { - printk("PCI: Cannot map mmconfig aperture\n"); + pci_mmcfg_virt = kmalloc(sizeof(*pci_mmcfg_virt) * pci_mmcfg_config_num, GFP_KERNEL); + if (pci_mmcfg_virt == NULL) { + printk("PCI: Can not allocate memory for mmconfig structures\n"); return 0; - } + } + for (i = 0; i < pci_mmcfg_config_num; ++i) { + pci_mmcfg_virt[i].cfg = &pci_mmcfg_config[i]; + pci_mmcfg_virt[i].virt = ioremap_nocache(pci_mmcfg_config[i].base_address, MMCONFIG_APER_SIZE); + if (!pci_mmcfg_virt[i].virt) { + printk("PCI: Cannot map mmconfig aperture for segment %d\n", + pci_mmcfg_config[i].pci_segment_group_number); + return 0; + } + printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[i].base_address); + } - printk(KERN_INFO "PCI: Using MMCONFIG at %x\n", pci_mmcfg_config[0].base_address); raw_pci_ops = &pci_mmcfg; pci_probe = (pci_probe & ~PCI_PROBE_MASK) | PCI_PROBE_MMCONF; -- cgit v1.1 From a341ad97245d01c923995cfe7deacd0c8aee6e16 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Jun 2005 20:33:49 +1000 Subject: [PATCH] ppc64: simplify nvram partition scanning code Convert nvram_create_os_partition to use list_for_each_entry instead of list_for_each, as this reduces the code size by two lines. Signed-off-by: Arnd Bergmann Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/nvram.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/ppc64/kernel/nvram.c b/arch/ppc64/kernel/nvram.c index 4e71781..4fb1a9f 100644 --- a/arch/ppc64/kernel/nvram.c +++ b/arch/ppc64/kernel/nvram.c @@ -338,9 +338,8 @@ static int nvram_remove_os_partition(void) */ static int nvram_create_os_partition(void) { - struct list_head * p; - struct nvram_partition *part = NULL; - struct nvram_partition *new_part = NULL; + struct nvram_partition *part; + struct nvram_partition *new_part; struct nvram_partition *free_part = NULL; int seq_init[2] = { 0, 0 }; loff_t tmp_index; @@ -349,8 +348,7 @@ static int nvram_create_os_partition(void) /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ - list_for_each(p, &nvram_part->partition) { - part = list_entry(p, struct nvram_partition, partition); + list_for_each_entry(part, &nvram_part->partition, partition) { if (part->header.signature != NVRAM_SIG_FREE) continue; -- cgit v1.1 From f5f1cc5437961a4bd93d615099f26780819e72d3 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 28 Jun 2005 20:55:25 +1000 Subject: [PATCH] ppc64: don't create spurious symlinks under node0 sysdev On partitioned systems we can wind up creating spurious symlinks in /sys/devices/system/node/node0 to non-present cpus. The symlinks are not broken; the problem is that we're potentially misinforming userspace that there is a relationship between node0 and cpus which are to be added later. There's no guarantee at all that a cpu which is added later will belong to node 0. Signed-off-by: Nathan Lynch Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/sysfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/arch/ppc64/kernel/sysfs.c b/arch/ppc64/kernel/sysfs.c index c8fa656..2f704a2 100644 --- a/arch/ppc64/kernel/sysfs.c +++ b/arch/ppc64/kernel/sysfs.c @@ -400,7 +400,12 @@ static int __init topology_init(void) struct cpu *c = &per_cpu(cpu_devices, cpu); #ifdef CONFIG_NUMA - parent = &node_devices[cpu_to_node(cpu)]; + /* The node to which a cpu belongs can't be known + * until the cpu is made present. + */ + parent = NULL; + if (cpu_present(cpu)) + parent = &node_devices[cpu_to_node(cpu)]; #endif /* * For now, we just see if the system supports making -- cgit v1.1 From 45891f7660c02fdd7b044a04d71b965c795e9df5 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:21 +1000 Subject: [PATCH] remove unused arch/ppc64/boot/piggyback.c piggyback is not called in arch/ppc64/boot/Makefile Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/Makefile | 5 +-- arch/ppc64/boot/piggyback.c | 83 --------------------------------------------- 2 files changed, 1 insertion(+), 87 deletions(-) delete mode 100644 arch/ppc64/boot/piggyback.c diff --git a/arch/ppc64/boot/Makefile b/arch/ppc64/boot/Makefile index d3e1d6a..683b2d4 100644 --- a/arch/ppc64/boot/Makefile +++ b/arch/ppc64/boot/Makefile @@ -52,7 +52,7 @@ obj-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.o, $(section))) src-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.c, $(section))) gz-sec = $(foreach section, $(1), $(patsubst %,$(obj)/kernel-%.gz, $(section))) -hostprogs-y := piggy addnote addRamDisk +hostprogs-y := addnote addRamDisk targets += zImage zImage.initrd imagesize.c \ $(patsubst $(obj)/%,%, $(call obj-sec, $(required) $(initrd))) \ $(patsubst $(obj)/%,%, $(call src-sec, $(required) $(initrd))) \ @@ -78,9 +78,6 @@ addsection = $(CROSS32OBJCOPY) $(1) \ quiet_cmd_addnote = ADDNOTE $@ cmd_addnote = $(CROSS32LD) $(BOOTLFLAGS) -o $@ $(obj-boot) && $(obj)/addnote $@ -quiet_cmd_piggy = PIGGY $@ - cmd_piggy = $(obj)/piggyback $(@:.o=) < $< | $(CROSS32AS) -o $@ - $(call gz-sec, $(required)): $(obj)/kernel-%.gz: % FORCE $(call if_changed,gzip) diff --git a/arch/ppc64/boot/piggyback.c b/arch/ppc64/boot/piggyback.c deleted file mode 100644 index 235c7a8..0000000 --- a/arch/ppc64/boot/piggyback.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2001 IBM Corp - * - * 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. - */ -#include -#include -#include - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - char *varname; - if (argc != 2) - { - fprintf(stderr, "usage: %s name out-file\n", - argv[0]); - exit(1); - } - - varname = strrchr(argv[1], '/'); - if (varname) - varname++; - else - varname = argv[1]; - - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", varname); - fprintf(stdout, "%s_data:\n", varname); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", varname); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", varname, pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - -- cgit v1.1 From a58dfbbb2a350808253a8b5037f5ec5b9a68516d Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:28 +1000 Subject: [PATCH] remove unused arch/ppc64/boot/mknote.c mknote is not called in arch/ppc64/boot/Makefile Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/mknote.c | 43 ------------------------------------------- 1 file changed, 43 deletions(-) delete mode 100644 arch/ppc64/boot/mknote.c diff --git a/arch/ppc64/boot/mknote.c b/arch/ppc64/boot/mknote.c deleted file mode 100644 index 120cc1d..0000000 --- a/arch/ppc64/boot/mknote.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) Cort Dougan 1999. - * - * 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. - * - * Generate a note section as per the CHRP specification. - * - */ - -#include - -#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); - -int main(void) -{ -/* header */ - /* namesz */ - PL(strlen("PowerPC")+1); - /* descrsz */ - PL(6*4); - /* type */ - PL(0x1275); - /* name */ - printf("PowerPC"); printf("%c", 0); - -/* descriptor */ - /* real-mode */ - PL(0xffffffff); - /* real-base */ - PL(0x00c00000); - /* real-size */ - PL(0xffffffff); - /* virt-base */ - PL(0xffffffff); - /* virt-size */ - PL(0xffffffff); - /* load-base */ - PL(0x4000); - return 0; -} -- cgit v1.1 From e6019db5a7f110839c62cefc073b6dc1143d6403 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:35 +1000 Subject: [PATCH] remove printk usage in arch/ppc64/boot/prom.c remove the printk usage in the zImage. we are not there, yet. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 1 - arch/ppc64/boot/prom.c | 16 ++-------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index da12ea2..677e418 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -17,7 +17,6 @@ extern void *finddevice(const char *); extern int getprop(void *, const char *, void *, int); -extern void printk(char *fmt, ...); extern void printf(const char *fmt, ...); extern int sprintf(char *buf, const char *fmt, ...); void gunzip(void *, int, unsigned char *, int *); diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index d5218b1..5e48b80 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c @@ -40,7 +40,7 @@ void *finddevice(const char *name); int getprop(void *phandle, const char *name, void *buf, int buflen); void chrpboot(int a1, int a2, void *prom); /* in main.c */ -void printk(char *fmt, ...); +int printf(char *fmt, ...); /* there is no convenient header to get this from... -- paulus */ extern unsigned long strlen(const char *); @@ -220,7 +220,7 @@ readchar(void) case 1: return ch; case -1: - printk("read(stdin) returned -1\r\n"); + printf("read(stdin) returned -1\r\n"); return -1; } } @@ -627,18 +627,6 @@ int sprintf(char * buf, const char *fmt, ...) static char sprint_buf[1024]; -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); -} - int printf(char *fmt, ...) { -- cgit v1.1 From b1bdfbd0a29d6da4dbe42736faac02c43a9afe76 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Tue, 28 Jun 2005 21:01:46 +1000 Subject: [PATCH] remove duplicate printf in arch/ppc64/boot/main.c initrd size is printed as hex, add a missing 0x remove a duplicate printf when initrd is used. remove use of kernel type to access the first bytes of the initrd memarea. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- arch/ppc64/boot/main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index 677e418..199d980 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c @@ -146,10 +146,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr) } a1 = initrd.addr; a2 = initrd.size; - printf("initial ramdisk moving 0x%lx <- 0x%lx (%lx bytes)\n\r", + printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r", initrd.addr, (unsigned long)_initrd_start, initrd.size); memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size); - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); + printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr)); } /* Eventually gunzip the kernel */ @@ -200,9 +200,6 @@ void start(unsigned long a1, unsigned long a2, void *promptr) flush_cache((void *)vmlinux.addr, vmlinux.size); - if (a1) - printf("initrd head: 0x%lx\n\r", *((u32 *)initrd.addr)); - kernel_entry = (kernel_entry_t)vmlinux.addr; #ifdef DEBUG printf( "kernel:\n\r" -- cgit v1.1 From 564c90aa07cd43dc434d46cef8a15773a23d49a2 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Jun 2005 13:46:09 +0100 Subject: [PATCH] ARM SMP: Use local_flush_tlb* where we really want to be local Signed-off-by: Russell King --- arch/arm/mm/init.c | 2 +- arch/arm/mm/mm-armv.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 6dcb23d..edffa47 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -437,7 +437,7 @@ void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc) memtable_init(mi); if (mdesc->map_io) mdesc->map_io(); - flush_tlb_all(); + local_flush_tlb_all(); /* * initialise the zones within each node diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 052ab44..c3bd503 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c @@ -682,7 +682,7 @@ void __init memtable_init(struct meminfo *mi) } flush_cache_all(); - flush_tlb_all(); + local_flush_tlb_all(); top_pmd = pmd_off_k(0xffff0000); } -- cgit v1.1 From 4b0ef3b1127776d4a2787d7530ac0c4da82c2331 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Jun 2005 13:49:16 +0100 Subject: [PATCH] ARM SMP: Add IPI support code for SMP TLB flushing Signed-off-by: Russell King --- arch/arm/kernel/smp.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 3489275..a931409 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -502,3 +502,126 @@ int __init setup_profiling_timer(unsigned int multiplier) { return -EINVAL; } + +static int +on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait, + cpumask_t mask) +{ + int ret = 0; + + preempt_disable(); + + ret = smp_call_function_on_cpu(func, info, retry, wait, mask); + if (cpu_isset(smp_processor_id(), mask)) + func(info); + + preempt_enable(); + + return ret; +} + +/**********************************************************************/ + +/* + * TLB operations + */ +struct tlb_args { + struct vm_area_struct *ta_vma; + unsigned long ta_start; + unsigned long ta_end; +}; + +static inline void ipi_flush_tlb_all(void *ignored) +{ + local_flush_tlb_all(); +} + +static inline void ipi_flush_tlb_mm(void *arg) +{ + struct mm_struct *mm = (struct mm_struct *)arg; + + local_flush_tlb_mm(mm); +} + +static inline void ipi_flush_tlb_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_page(ta->ta_vma, ta->ta_start); +} + +static inline void ipi_flush_tlb_kernel_page(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_page(ta->ta_start); +} + +static inline void ipi_flush_tlb_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); +} + +static inline void ipi_flush_tlb_kernel_range(void *arg) +{ + struct tlb_args *ta = (struct tlb_args *)arg; + + local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); +} + +void flush_tlb_all(void) +{ + on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1); +} + +void flush_tlb_mm(struct mm_struct *mm) +{ + cpumask_t mask = mm->cpu_vm_mask; + + on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask); +} + +void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = uaddr; + + on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_page(unsigned long kaddr) +{ + struct tlb_args ta; + + ta.ta_start = kaddr; + + on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1); +} + +void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) +{ + cpumask_t mask = vma->vm_mm->cpu_vm_mask; + struct tlb_args ta; + + ta.ta_vma = vma; + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask); +} + +void flush_tlb_kernel_range(unsigned long start, unsigned long end) +{ + struct tlb_args ta; + + ta.ta_start = start; + ta.ta_end = end; + + on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1); +} -- cgit v1.1 From 66b7f8a30437b8639e798f7db8e9be1da5711efa Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Mon, 25 Apr 2005 13:51:00 -0700 Subject: [IA64-SGI] pcdp: add PCDP pci interface support Resend 2 with changes per Bjorn Helgaas comments. Changes from original: + Change globals to vga_console_iobase/vga_console_membase and make them unconditional. + Address style-related comments. Patch to extend the PCDP vga setup code to support PCI io/mem translations for the legacy vga ioport and ram spaces on architectures (e.g. altix) which need them. Summary of the changes: drivers/firmware/pcdp.c drivers/firmware/pcdp.h ----------------------- + add declaration for the spec-defined PCI interface struct (pcdp_if_pci) as well as support macros. + extend setup_vga_console() to know about pcdp_if_pci and add a couple of globals to hold the io and mem translation offsets if present. arch/ia64/kernel/setup.c ------------------------ + tweek early_console_setup() to allow multiple early console setup routines to be called. include/asm-ia64/vga.h ---------------------- + make VGA_MAP_MEM vga_console_membase aware Signed-off-by: Mark Maule Signed-off-by: Tony Luck --- arch/ia64/kernel/setup.c | 12 ++++++++---- drivers/firmware/pcdp.c | 24 +++++++++++++++++++++--- drivers/firmware/pcdp.h | 33 +++++++++++++++++++++++++++++---- include/asm-ia64/vga.h | 5 ++++- 4 files changed, 62 insertions(+), 12 deletions(-) diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c index d14692e..2693e15 100644 --- a/arch/ia64/kernel/setup.c +++ b/arch/ia64/kernel/setup.c @@ -72,6 +72,8 @@ DEFINE_PER_CPU(unsigned long, ia64_phys_stacked_size_p8); unsigned long ia64_cycles_per_usec; struct ia64_boot_param *ia64_boot_param; struct screen_info screen_info; +unsigned long vga_console_iobase; +unsigned long vga_console_membase; unsigned long ia64_max_cacheline_size; unsigned long ia64_iobase; /* virtual address for I/O accesses */ @@ -273,23 +275,25 @@ io_port_init (void) static inline int __init early_console_setup (char *cmdline) { + int earlycons = 0; + #ifdef CONFIG_SERIAL_SGI_L1_CONSOLE { extern int sn_serial_console_early_setup(void); if (!sn_serial_console_early_setup()) - return 0; + earlycons++; } #endif #ifdef CONFIG_EFI_PCDP if (!efi_setup_pcdp_console(cmdline)) - return 0; + earlycons++; #endif #ifdef CONFIG_SERIAL_8250_CONSOLE if (!early_serial_console_init(cmdline)) - return 0; + earlycons++; #endif - return -1; + return (earlycons) ? 0 : -1; } static inline void diff --git a/drivers/firmware/pcdp.c b/drivers/firmware/pcdp.c index 839b44a..53c95c0 100644 --- a/drivers/firmware/pcdp.c +++ b/drivers/firmware/pcdp.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "pcdp.h" static int __init @@ -40,10 +41,27 @@ setup_serial_console(struct pcdp_uart *uart) } static int __init -setup_vga_console(struct pcdp_vga *vga) +setup_vga_console(struct pcdp_device *dev) { #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (efi_mem_type(0xA0000) == EFI_CONVENTIONAL_MEMORY) { + u8 *if_ptr; + + if_ptr = ((u8 *)dev + sizeof(struct pcdp_device)); + if (if_ptr[0] == PCDP_IF_PCI) { + struct pcdp_if_pci if_pci; + + /* struct copy since ifptr might not be correctly aligned */ + + memcpy(&if_pci, if_ptr, sizeof(if_pci)); + + if (if_pci.trans & PCDP_PCI_TRANS_IOPORT) + vga_console_iobase = if_pci.ioport_tra; + + if (if_pci.trans & PCDP_PCI_TRANS_MMIO) + vga_console_membase = if_pci.mmio_tra; + } + + if (efi_mem_type(vga_console_membase + 0xA0000) == EFI_CONVENTIONAL_MEMORY) { printk(KERN_ERR "PCDP: VGA selected, but frame buffer is not MMIO!\n"); return -ENODEV; } @@ -95,7 +113,7 @@ efi_setup_pcdp_console(char *cmdline) dev = (struct pcdp_device *) ((u8 *) dev + dev->length)) { if (dev->flags & PCDP_PRIMARY_CONSOLE) { if (dev->type == PCDP_CONSOLE_VGA) { - return setup_vga_console((struct pcdp_vga *) dev); + return setup_vga_console(dev); } } } diff --git a/drivers/firmware/pcdp.h b/drivers/firmware/pcdp.h index 1dc7c88..e72cc47 100644 --- a/drivers/firmware/pcdp.h +++ b/drivers/firmware/pcdp.h @@ -52,11 +52,34 @@ struct pcdp_uart { u32 clock_rate; u8 pci_prog_intfc; u8 flags; -}; +} __attribute__((packed)); + +#define PCDP_IF_PCI 1 + +/* pcdp_if_pci.trans */ +#define PCDP_PCI_TRANS_IOPORT 0x02 +#define PCDP_PCI_TRANS_MMIO 0x01 + +struct pcdp_if_pci { + u8 interconnect; + u8 reserved; + u16 length; + u8 segment; + u8 bus; + u8 dev; + u8 fun; + u16 dev_id; + u16 vendor_id; + u32 acpi_interrupt; + u64 mmio_tra; + u64 ioport_tra; + u8 flags; + u8 trans; +} __attribute__((packed)); struct pcdp_vga { u8 count; /* address space descriptors */ -}; +} __attribute__((packed)); /* pcdp_device.flags */ #define PCDP_PRIMARY_CONSOLE 1 @@ -66,7 +89,9 @@ struct pcdp_device { u8 flags; u16 length; u16 efi_index; -}; + /* next data is pcdp_if_pci or pcdp_if_acpi (not yet supported) */ + /* next data is device specific type (currently only pcdp_vga) */ +} __attribute__((packed)); struct pcdp { u8 signature[4]; @@ -81,4 +106,4 @@ struct pcdp { u32 num_uarts; struct pcdp_uart uart[0]; /* actual size is num_uarts */ /* remainder of table is pcdp_device structures */ -}; +} __attribute__((packed)); diff --git a/include/asm-ia64/vga.h b/include/asm-ia64/vga.h index 1f446d6..bc3349f 100644 --- a/include/asm-ia64/vga.h +++ b/include/asm-ia64/vga.h @@ -14,7 +14,10 @@ * videoram directly without any black magic. */ -#define VGA_MAP_MEM(x) ((unsigned long) ioremap((x), 0)) +extern unsigned long vga_console_iobase; +extern unsigned long vga_console_membase; + +#define VGA_MAP_MEM(x) ((unsigned long) ioremap(vga_console_membase + (x), 0)) #define vga_readb(x) (*(x)) #define vga_writeb(x,y) (*(y) = (x)) -- cgit v1.1 From a9f9de7378e3a81f7266f542f2290399a298ef52 Mon Sep 17 00:00:00 2001 From: Mark Maule Date: Tue, 26 Apr 2005 08:01:00 -0700 Subject: [IA64-SGI] altix: enable vgacon support Altix patch to enable use of vgacon driver on that platform. Depends on the PCDP generalization patch discussed at: http://marc.theaimsgroup.com/?l=linux-ia64&m=111446235101939&w=2 Signed-off-by: Mark Maule Signed-off-by: Tony Luck --- arch/ia64/configs/sn2_defconfig | 4 ++-- arch/ia64/sn/kernel/iomv.c | 6 ++++++ arch/ia64/sn/kernel/setup.c | 16 ++++++++++------ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/arch/ia64/configs/sn2_defconfig b/arch/ia64/configs/sn2_defconfig index 487d2e3..c056139 100644 --- a/arch/ia64/configs/sn2_defconfig +++ b/arch/ia64/configs/sn2_defconfig @@ -99,7 +99,7 @@ CONFIG_ACPI_DEALLOCATE_IRQ=y # Firmware Drivers # CONFIG_EFI_VARS=y -# CONFIG_EFI_PCDP is not set +CONFIG_EFI_PCDP=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set @@ -650,7 +650,7 @@ CONFIG_MMTIMER=y # # Console display driver support # -# CONFIG_VGA_CONSOLE is not set +CONFIG_VGA_CONSOLE=y CONFIG_DUMMY_CONSOLE=y # diff --git a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c index fec6d8b..7ce3cda 100644 --- a/arch/ia64/sn/kernel/iomv.c +++ b/arch/ia64/sn/kernel/iomv.c @@ -9,12 +9,16 @@ #include #include #include +#include #include #include #include #include #include +#define IS_LEGACY_VGA_IOPORT(p) \ + (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) + /** * sn_io_addr - convert an in/out port to an i/o address * @port: port to convert @@ -26,6 +30,8 @@ void *sn_io_addr(unsigned long port) { if (!IS_RUNNING_ON_SIMULATOR()) { + if (IS_LEGACY_VGA_IOPORT(port)) + port += vga_console_iobase; /* On sn2, legacy I/O ports don't point at anything */ if (port < (64 * 1024)) return NULL; diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 44bfc7f..3e5ba34 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include @@ -273,14 +274,17 @@ void __init sn_setup(char **cmdline_p) ia64_sn_plat_set_error_handling_features(); +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) /* - * If the generic code has enabled vga console support - lets - * get rid of it again. This is a kludge for the fact that ACPI - * currtently has no way of informing us if legacy VGA is available - * or not. + * If there was a primary vga adapter identified through the + * EFI PCDP table, make it the preferred console. Otherwise + * zero out conswitchp. */ -#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) - if (conswitchp == &vga_con) { + + if (vga_console_membase) { + /* usable vga ... make tty0 the preferred default console */ + add_preferred_console("tty", 0, NULL); + } else { printk(KERN_DEBUG "SGI: Disabling VGA console\n"); #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; -- cgit v1.1 From e15da40176f16050c8d92b36387a49370317e276 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Tue, 3 May 2005 12:07:00 -0700 Subject: [IA64] Recognize HP sx2000 chipset No functional change, just identify the device nicely: -IOC: Unknown (103c:12ec) 0.1 HPA 0xf8020002000 IOVA space 1024Mb at 0x40000000 +IOC: sx2000 0.1 HPA 0xf8020002000 IOVA space 1024Mb at 0x40000000 We used to create fake PCI devices for these chips, but we no longer do that. So I don't think there's any reason to touch pci_ids.h now. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- arch/ia64/hp/common/sba_iommu.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c index b8db6e3..1195759 100644 --- a/arch/ia64/hp/common/sba_iommu.c +++ b/arch/ia64/hp/common/sba_iommu.c @@ -156,10 +156,13 @@ */ #define DELAYED_RESOURCE_CNT 64 +#define PCI_DEVICE_ID_HP_SX2000_IOC 0x12ec + #define ZX1_IOC_ID ((PCI_DEVICE_ID_HP_ZX1_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX2_IOC_ID ((PCI_DEVICE_ID_HP_ZX2_IOC << 16) | PCI_VENDOR_ID_HP) #define REO_IOC_ID ((PCI_DEVICE_ID_HP_REO_IOC << 16) | PCI_VENDOR_ID_HP) #define SX1000_IOC_ID ((PCI_DEVICE_ID_HP_SX1000_IOC << 16) | PCI_VENDOR_ID_HP) +#define SX2000_IOC_ID ((PCI_DEVICE_ID_HP_SX2000_IOC << 16) | PCI_VENDOR_ID_HP) #define ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */ @@ -1726,6 +1729,7 @@ static struct ioc_iommu ioc_iommu_info[] __initdata = { { ZX1_IOC_ID, "zx1", ioc_zx1_init }, { ZX2_IOC_ID, "zx2", NULL }, { SX1000_IOC_ID, "sx1000", NULL }, + { SX2000_IOC_ID, "sx2000", NULL }, }; static struct ioc * __init -- cgit v1.1 From 458f935527372499b714bf4f8e646a68bb0f52e3 Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Wed, 4 May 2005 13:25:00 -0700 Subject: [IA64] Speed up lfetch.fault [NULL] This patch greatly speeds up the handling of lfetch.fault instructions which result in NaT consumption. Due to the NaT-page mapped at address 0, this is guaranteed to happen when lfetch.fault'ing a NULL pointer. With this patch in place, we can even define prefetch()/prefetchw() as lfetch.fault without significant performance degradation. More importantly, it allows compilers to be more aggressive with using lfetch.fault on pointers that might be NULL. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/kernel/ivt.S | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S index b28d221..3bb3a13 100644 --- a/arch/ia64/kernel/ivt.S +++ b/arch/ia64/kernel/ivt.S @@ -1243,6 +1243,25 @@ END(disabled_fp_reg) // 0x5600 Entry 26 (size 16 bundles) Nat Consumption (11,23,37,50) ENTRY(nat_consumption) DBG_FAULT(26) + + mov r16=cr.ipsr + mov r17=cr.isr + mov r31=pr // save PR + ;; + and r18=0xf,r17 // r18 = cr.ipsr.code{3:0} + tbit.z p6,p0=r17,IA64_ISR_NA_BIT + ;; + cmp.ne.or p6,p0=IA64_ISR_CODE_LFETCH,r18 + dep r16=-1,r16,IA64_PSR_ED_BIT,1 +(p6) br.cond.spnt 1f // branch if (cr.ispr.na == 0 || cr.ipsr.code{3:0} != LFETCH) + ;; + mov cr.ipsr=r16 // set cr.ipsr.na + mov pr=r31,-1 + ;; + rfi + +1: mov pr=r31,-1 + ;; FAULT(26) END(nat_consumption) -- cgit v1.1 From 8e4641b3ee8073a46995cf97e0875df25b88d776 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Mon, 9 May 2005 05:07:00 -0700 Subject: [IA64] sparse cleanup of shub_mmr.h This patch is a sparse compile cleanup of shub_mmr.h using both the defconfig and the sn2_defconfig config files. The issue with this file was the missing usage of __IA64_UL_CONST wrapper. This wrapper is defined in include/asm-ia64/types.h and wraps a long constant definition with UL or with nothing depending on its usage in the kernel. The missing wrapper caused many sparse compile errors like warning: constant 0x0x0000000010000380 so big it is long Signed-off-by: Prarit Bhargava Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/sn2/ptc_deadlock.S | 1 + include/asm-ia64/sn/shub_mmr.h | 346 +++++++++++++++++---------------- 2 files changed, 175 insertions(+), 172 deletions(-) diff --git a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S index 7947312..96cb71d 100644 --- a/arch/ia64/sn/kernel/sn2/ptc_deadlock.S +++ b/arch/ia64/sn/kernel/sn2/ptc_deadlock.S @@ -6,6 +6,7 @@ * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. */ +#include #include #define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT diff --git a/include/asm-ia64/sn/shub_mmr.h b/include/asm-ia64/sn/shub_mmr.h index 323fa0c..7de1d1d 100644 --- a/include/asm-ia64/sn/shub_mmr.h +++ b/include/asm-ia64/sn/shub_mmr.h @@ -14,96 +14,98 @@ /* Register "SH_IPI_INT" */ /* SHub Inter-Processor Interrupt Registers */ /* ==================================================================== */ -#define SH1_IPI_INT 0x0000000110000380 -#define SH2_IPI_INT 0x0000000010000380 +#define SH1_IPI_INT __IA64_UL_CONST(0x0000000110000380) +#define SH2_IPI_INT __IA64_UL_CONST(0x0000000010000380) /* SH_IPI_INT_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_IPI_INT_TYPE_SHFT 0 -#define SH_IPI_INT_TYPE_MASK 0x0000000000000007 +#define SH_IPI_INT_TYPE_SHFT 0 +#define SH_IPI_INT_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_IPI_INT_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_IPI_INT_AGT_SHFT 3 -#define SH_IPI_INT_AGT_MASK 0x0000000000000008 +#define SH_IPI_INT_AGT_SHFT 3 +#define SH_IPI_INT_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_IPI_INT_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_IPI_INT_PID_SHFT 4 -#define SH_IPI_INT_PID_MASK 0x00000000000ffff0 +#define SH_IPI_INT_PID_SHFT 4 +#define SH_IPI_INT_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_IPI_INT_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_IPI_INT_BASE_SHFT 21 -#define SH_IPI_INT_BASE_MASK 0x0003ffffffe00000 +#define SH_IPI_INT_BASE_SHFT 21 +#define SH_IPI_INT_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_IPI_INT_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_IPI_INT_IDX_SHFT 52 -#define SH_IPI_INT_IDX_MASK 0x0ff0000000000000 +#define SH_IPI_INT_IDX_SHFT 52 +#define SH_IPI_INT_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* SH_IPI_INT_SEND */ /* Description: Send Interrupt Message to PI, This generates a puls */ -#define SH_IPI_INT_SEND_SHFT 63 -#define SH_IPI_INT_SEND_MASK 0x8000000000000000 +#define SH_IPI_INT_SEND_SHFT 63 +#define SH_IPI_INT_SEND_MASK __IA64_UL_CONST(0x8000000000000000) /* ==================================================================== */ /* Register "SH_EVENT_OCCURRED" */ /* SHub Interrupt Event Occurred */ /* ==================================================================== */ -#define SH1_EVENT_OCCURRED 0x0000000110010000 -#define SH1_EVENT_OCCURRED_ALIAS 0x0000000110010008 -#define SH2_EVENT_OCCURRED 0x0000000010010000 -#define SH2_EVENT_OCCURRED_ALIAS 0x0000000010010008 +#define SH1_EVENT_OCCURRED __IA64_UL_CONST(0x0000000110010000) +#define SH1_EVENT_OCCURRED_ALIAS __IA64_UL_CONST(0x0000000110010008) +#define SH2_EVENT_OCCURRED __IA64_UL_CONST(0x0000000010010000) +#define SH2_EVENT_OCCURRED_ALIAS __IA64_UL_CONST(0x0000000010010008) /* ==================================================================== */ /* Register "SH_PI_CAM_CONTROL" */ /* CRB CAM MMR Access Control */ /* ==================================================================== */ -#define SH1_PI_CAM_CONTROL 0x0000000120050300 +#define SH1_PI_CAM_CONTROL __IA64_UL_CONST(0x0000000120050300) /* ==================================================================== */ /* Register "SH_SHUB_ID" */ /* SHub ID Number */ /* ==================================================================== */ -#define SH1_SHUB_ID 0x0000000110060580 -#define SH1_SHUB_ID_REVISION_SHFT 28 -#define SH1_SHUB_ID_REVISION_MASK 0x00000000f0000000 +#define SH1_SHUB_ID __IA64_UL_CONST(0x0000000110060580) +#define SH1_SHUB_ID_REVISION_SHFT 28 +#define SH1_SHUB_ID_REVISION_MASK __IA64_UL_CONST(0x00000000f0000000) /* ==================================================================== */ /* Register "SH_RTC" */ /* Real-time Clock */ /* ==================================================================== */ -#define SH1_RTC 0x00000001101c0000 -#define SH2_RTC 0x00000002101c0000 -#define SH_RTC_MASK 0x007fffffffffffff +#define SH1_RTC __IA64_UL_CONST(0x00000001101c0000) +#define SH2_RTC __IA64_UL_CONST(0x00000002101c0000) +#define SH_RTC_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_PIO_WRITE_STATUS_0|1" */ /* PIO Write Status for CPU 0 & 1 */ /* ==================================================================== */ -#define SH1_PIO_WRITE_STATUS_0 0x0000000120070200 -#define SH1_PIO_WRITE_STATUS_1 0x0000000120070280 -#define SH2_PIO_WRITE_STATUS_0 0x0000000020070200 -#define SH2_PIO_WRITE_STATUS_1 0x0000000020070280 -#define SH2_PIO_WRITE_STATUS_2 0x0000000020070300 -#define SH2_PIO_WRITE_STATUS_3 0x0000000020070380 +#define SH1_PIO_WRITE_STATUS_0 __IA64_UL_CONST(0x0000000120070200) +#define SH1_PIO_WRITE_STATUS_1 __IA64_UL_CONST(0x0000000120070280) +#define SH2_PIO_WRITE_STATUS_0 __IA64_UL_CONST(0x0000000020070200) +#define SH2_PIO_WRITE_STATUS_1 __IA64_UL_CONST(0x0000000020070280) +#define SH2_PIO_WRITE_STATUS_2 __IA64_UL_CONST(0x0000000020070300) +#define SH2_PIO_WRITE_STATUS_3 __IA64_UL_CONST(0x0000000020070380) /* SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK */ /* Description: Deadlock response detected */ -#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1 -#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK 0x0000000000000002 +#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1 +#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK \ + __IA64_UL_CONST(0x0000000000000002) /* SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT */ /* Description: Count of currently pending PIO writes */ -#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56 -#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK 0x3f00000000000000 +#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56 +#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK \ + __IA64_UL_CONST(0x3f00000000000000) /* ==================================================================== */ /* Register "SH_PIO_WRITE_STATUS_0_ALIAS" */ /* ==================================================================== */ -#define SH1_PIO_WRITE_STATUS_0_ALIAS 0x0000000120070208 -#define SH2_PIO_WRITE_STATUS_0_ALIAS 0x0000000020070208 +#define SH1_PIO_WRITE_STATUS_0_ALIAS __IA64_UL_CONST(0x0000000120070208) +#define SH2_PIO_WRITE_STATUS_0_ALIAS __IA64_UL_CONST(0x0000000020070208) /* ==================================================================== */ /* Register "SH_EVENT_OCCURRED" */ @@ -111,33 +113,33 @@ /* ==================================================================== */ /* SH_EVENT_OCCURRED_UART_INT */ /* Description: Pending Junk Bus UART Interrupt */ -#define SH_EVENT_OCCURRED_UART_INT_SHFT 20 -#define SH_EVENT_OCCURRED_UART_INT_MASK 0x0000000000100000 +#define SH_EVENT_OCCURRED_UART_INT_SHFT 20 +#define SH_EVENT_OCCURRED_UART_INT_MASK __IA64_UL_CONST(0x0000000000100000) /* SH_EVENT_OCCURRED_IPI_INT */ /* Description: Pending IPI Interrupt */ -#define SH_EVENT_OCCURRED_IPI_INT_SHFT 28 -#define SH_EVENT_OCCURRED_IPI_INT_MASK 0x0000000010000000 +#define SH_EVENT_OCCURRED_IPI_INT_SHFT 28 +#define SH_EVENT_OCCURRED_IPI_INT_MASK __IA64_UL_CONST(0x0000000010000000) /* SH_EVENT_OCCURRED_II_INT0 */ /* Description: Pending II 0 Interrupt */ -#define SH_EVENT_OCCURRED_II_INT0_SHFT 29 -#define SH_EVENT_OCCURRED_II_INT0_MASK 0x0000000020000000 +#define SH_EVENT_OCCURRED_II_INT0_SHFT 29 +#define SH_EVENT_OCCURRED_II_INT0_MASK __IA64_UL_CONST(0x0000000020000000) /* SH_EVENT_OCCURRED_II_INT1 */ /* Description: Pending II 1 Interrupt */ -#define SH_EVENT_OCCURRED_II_INT1_SHFT 30 -#define SH_EVENT_OCCURRED_II_INT1_MASK 0x0000000040000000 +#define SH_EVENT_OCCURRED_II_INT1_SHFT 30 +#define SH_EVENT_OCCURRED_II_INT1_MASK __IA64_UL_CONST(0x0000000040000000) /* SH2_EVENT_OCCURRED_EXTIO_INT2 */ /* Description: Pending SHUB 2 EXT IO INT2 */ -#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT 33 -#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK 0x0000000200000000 +#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT 33 +#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK __IA64_UL_CONST(0x0000000200000000) /* SH2_EVENT_OCCURRED_EXTIO_INT3 */ /* Description: Pending SHUB 2 EXT IO INT3 */ -#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT 34 -#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK 0x0000000400000000 +#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT 34 +#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK __IA64_UL_CONST(0x0000000400000000) #define SH_ALL_INT_MASK \ (SH_EVENT_OCCURRED_UART_INT_MASK | SH_EVENT_OCCURRED_IPI_INT_MASK | \ @@ -149,310 +151,310 @@ /* ==================================================================== */ /* LEDS */ /* ==================================================================== */ -#define SH1_REAL_JUNK_BUS_LED0 0x7fed00000UL -#define SH1_REAL_JUNK_BUS_LED1 0x7fed10000UL -#define SH1_REAL_JUNK_BUS_LED2 0x7fed20000UL -#define SH1_REAL_JUNK_BUS_LED3 0x7fed30000UL +#define SH1_REAL_JUNK_BUS_LED0 0x7fed00000UL +#define SH1_REAL_JUNK_BUS_LED1 0x7fed10000UL +#define SH1_REAL_JUNK_BUS_LED2 0x7fed20000UL +#define SH1_REAL_JUNK_BUS_LED3 0x7fed30000UL -#define SH2_REAL_JUNK_BUS_LED0 0xf0000000UL -#define SH2_REAL_JUNK_BUS_LED1 0xf0010000UL -#define SH2_REAL_JUNK_BUS_LED2 0xf0020000UL -#define SH2_REAL_JUNK_BUS_LED3 0xf0030000UL +#define SH2_REAL_JUNK_BUS_LED0 0xf0000000UL +#define SH2_REAL_JUNK_BUS_LED1 0xf0010000UL +#define SH2_REAL_JUNK_BUS_LED2 0xf0020000UL +#define SH2_REAL_JUNK_BUS_LED3 0xf0030000UL /* ==================================================================== */ /* Register "SH1_PTC_0" */ /* Puge Translation Cache Message Configuration Information */ /* ==================================================================== */ -#define SH1_PTC_0 0x00000001101a0000 +#define SH1_PTC_0 __IA64_UL_CONST(0x00000001101a0000) /* SH1_PTC_0_A */ /* Description: Type */ -#define SH1_PTC_0_A_SHFT 0 +#define SH1_PTC_0_A_SHFT 0 /* SH1_PTC_0_PS */ /* Description: Page Size */ -#define SH1_PTC_0_PS_SHFT 2 +#define SH1_PTC_0_PS_SHFT 2 /* SH1_PTC_0_RID */ /* Description: Region ID */ -#define SH1_PTC_0_RID_SHFT 8 +#define SH1_PTC_0_RID_SHFT 8 /* SH1_PTC_0_START */ /* Description: Start */ -#define SH1_PTC_0_START_SHFT 63 +#define SH1_PTC_0_START_SHFT 63 /* ==================================================================== */ /* Register "SH1_PTC_1" */ /* Puge Translation Cache Message Configuration Information */ /* ==================================================================== */ -#define SH1_PTC_1 0x00000001101a0080 +#define SH1_PTC_1 __IA64_UL_CONST(0x00000001101a0080) /* SH1_PTC_1_START */ /* Description: PTC_1 Start */ -#define SH1_PTC_1_START_SHFT 63 - +#define SH1_PTC_1_START_SHFT 63 /* ==================================================================== */ /* Register "SH2_PTC" */ /* Puge Translation Cache Message Configuration Information */ /* ==================================================================== */ -#define SH2_PTC 0x0000000170000000 +#define SH2_PTC __IA64_UL_CONST(0x0000000170000000) /* SH2_PTC_A */ /* Description: Type */ -#define SH2_PTC_A_SHFT 0 +#define SH2_PTC_A_SHFT 0 /* SH2_PTC_PS */ /* Description: Page Size */ -#define SH2_PTC_PS_SHFT 2 +#define SH2_PTC_PS_SHFT 2 /* SH2_PTC_RID */ /* Description: Region ID */ -#define SH2_PTC_RID_SHFT 4 +#define SH2_PTC_RID_SHFT 4 /* SH2_PTC_START */ /* Description: Start */ -#define SH2_PTC_START_SHFT 63 +#define SH2_PTC_START_SHFT 63 /* SH2_PTC_ADDR_RID */ /* Description: Region ID */ -#define SH2_PTC_ADDR_SHFT 4 -#define SH2_PTC_ADDR_MASK 0x1ffffffffffff000 +#define SH2_PTC_ADDR_SHFT 4 +#define SH2_PTC_ADDR_MASK __IA64_UL_CONST(0x1ffffffffffff000) /* ==================================================================== */ /* Register "SH_RTC1_INT_CONFIG" */ /* SHub RTC 1 Interrupt Config Registers */ /* ==================================================================== */ -#define SH1_RTC1_INT_CONFIG 0x0000000110001480 -#define SH2_RTC1_INT_CONFIG 0x0000000010001480 -#define SH_RTC1_INT_CONFIG_MASK 0x0ff3ffffffefffff -#define SH_RTC1_INT_CONFIG_INIT 0x0000000000000000 +#define SH1_RTC1_INT_CONFIG __IA64_UL_CONST(0x0000000110001480) +#define SH2_RTC1_INT_CONFIG __IA64_UL_CONST(0x0000000010001480) +#define SH_RTC1_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC1_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC1_INT_CONFIG_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_RTC1_INT_CONFIG_TYPE_SHFT 0 -#define SH_RTC1_INT_CONFIG_TYPE_MASK 0x0000000000000007 +#define SH_RTC1_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC1_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_RTC1_INT_CONFIG_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_RTC1_INT_CONFIG_AGT_SHFT 3 -#define SH_RTC1_INT_CONFIG_AGT_MASK 0x0000000000000008 +#define SH_RTC1_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC1_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_RTC1_INT_CONFIG_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_RTC1_INT_CONFIG_PID_SHFT 4 -#define SH_RTC1_INT_CONFIG_PID_MASK 0x00000000000ffff0 +#define SH_RTC1_INT_CONFIG_PID_SHFT 4 +#define SH_RTC1_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_RTC1_INT_CONFIG_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_RTC1_INT_CONFIG_BASE_SHFT 21 -#define SH_RTC1_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 +#define SH_RTC1_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC1_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_RTC1_INT_CONFIG_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_RTC1_INT_CONFIG_IDX_SHFT 52 -#define SH_RTC1_INT_CONFIG_IDX_MASK 0x0ff0000000000000 +#define SH_RTC1_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC1_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* ==================================================================== */ /* Register "SH_RTC1_INT_ENABLE" */ /* SHub RTC 1 Interrupt Enable Registers */ /* ==================================================================== */ -#define SH1_RTC1_INT_ENABLE 0x0000000110001500 -#define SH2_RTC1_INT_ENABLE 0x0000000010001500 -#define SH_RTC1_INT_ENABLE_MASK 0x0000000000000001 -#define SH_RTC1_INT_ENABLE_INIT 0x0000000000000000 +#define SH1_RTC1_INT_ENABLE __IA64_UL_CONST(0x0000000110001500) +#define SH2_RTC1_INT_ENABLE __IA64_UL_CONST(0x0000000010001500) +#define SH_RTC1_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC1_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC1_INT_ENABLE_RTC1_ENABLE */ /* Description: Enable RTC 1 Interrupt */ -#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT 0 -#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK 0x0000000000000001 +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT 0 +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) /* ==================================================================== */ /* Register "SH_RTC2_INT_CONFIG" */ /* SHub RTC 2 Interrupt Config Registers */ /* ==================================================================== */ -#define SH1_RTC2_INT_CONFIG 0x0000000110001580 -#define SH2_RTC2_INT_CONFIG 0x0000000010001580 -#define SH_RTC2_INT_CONFIG_MASK 0x0ff3ffffffefffff -#define SH_RTC2_INT_CONFIG_INIT 0x0000000000000000 +#define SH1_RTC2_INT_CONFIG __IA64_UL_CONST(0x0000000110001580) +#define SH2_RTC2_INT_CONFIG __IA64_UL_CONST(0x0000000010001580) +#define SH_RTC2_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC2_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC2_INT_CONFIG_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_RTC2_INT_CONFIG_TYPE_SHFT 0 -#define SH_RTC2_INT_CONFIG_TYPE_MASK 0x0000000000000007 +#define SH_RTC2_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC2_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_RTC2_INT_CONFIG_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_RTC2_INT_CONFIG_AGT_SHFT 3 -#define SH_RTC2_INT_CONFIG_AGT_MASK 0x0000000000000008 +#define SH_RTC2_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC2_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_RTC2_INT_CONFIG_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_RTC2_INT_CONFIG_PID_SHFT 4 -#define SH_RTC2_INT_CONFIG_PID_MASK 0x00000000000ffff0 +#define SH_RTC2_INT_CONFIG_PID_SHFT 4 +#define SH_RTC2_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_RTC2_INT_CONFIG_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_RTC2_INT_CONFIG_BASE_SHFT 21 -#define SH_RTC2_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 +#define SH_RTC2_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC2_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_RTC2_INT_CONFIG_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_RTC2_INT_CONFIG_IDX_SHFT 52 -#define SH_RTC2_INT_CONFIG_IDX_MASK 0x0ff0000000000000 +#define SH_RTC2_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC2_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* ==================================================================== */ /* Register "SH_RTC2_INT_ENABLE" */ /* SHub RTC 2 Interrupt Enable Registers */ /* ==================================================================== */ -#define SH1_RTC2_INT_ENABLE 0x0000000110001600 -#define SH2_RTC2_INT_ENABLE 0x0000000010001600 -#define SH_RTC2_INT_ENABLE_MASK 0x0000000000000001 -#define SH_RTC2_INT_ENABLE_INIT 0x0000000000000000 +#define SH1_RTC2_INT_ENABLE __IA64_UL_CONST(0x0000000110001600) +#define SH2_RTC2_INT_ENABLE __IA64_UL_CONST(0x0000000010001600) +#define SH_RTC2_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC2_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC2_INT_ENABLE_RTC2_ENABLE */ /* Description: Enable RTC 2 Interrupt */ -#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT 0 -#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK 0x0000000000000001 +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT 0 +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) /* ==================================================================== */ /* Register "SH_RTC3_INT_CONFIG" */ /* SHub RTC 3 Interrupt Config Registers */ /* ==================================================================== */ -#define SH1_RTC3_INT_CONFIG 0x0000000110001680 -#define SH2_RTC3_INT_CONFIG 0x0000000010001680 -#define SH_RTC3_INT_CONFIG_MASK 0x0ff3ffffffefffff -#define SH_RTC3_INT_CONFIG_INIT 0x0000000000000000 +#define SH1_RTC3_INT_CONFIG __IA64_UL_CONST(0x0000000110001680) +#define SH2_RTC3_INT_CONFIG __IA64_UL_CONST(0x0000000010001680) +#define SH_RTC3_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC3_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC3_INT_CONFIG_TYPE */ /* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ -#define SH_RTC3_INT_CONFIG_TYPE_SHFT 0 -#define SH_RTC3_INT_CONFIG_TYPE_MASK 0x0000000000000007 +#define SH_RTC3_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC3_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) /* SH_RTC3_INT_CONFIG_AGT */ /* Description: Agent, must be 0 for SHub */ -#define SH_RTC3_INT_CONFIG_AGT_SHFT 3 -#define SH_RTC3_INT_CONFIG_AGT_MASK 0x0000000000000008 +#define SH_RTC3_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC3_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) /* SH_RTC3_INT_CONFIG_PID */ /* Description: Processor ID, same setting as on targeted McKinley */ -#define SH_RTC3_INT_CONFIG_PID_SHFT 4 -#define SH_RTC3_INT_CONFIG_PID_MASK 0x00000000000ffff0 +#define SH_RTC3_INT_CONFIG_PID_SHFT 4 +#define SH_RTC3_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) /* SH_RTC3_INT_CONFIG_BASE */ /* Description: Optional interrupt vector area, 2MB aligned */ -#define SH_RTC3_INT_CONFIG_BASE_SHFT 21 -#define SH_RTC3_INT_CONFIG_BASE_MASK 0x0003ffffffe00000 +#define SH_RTC3_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC3_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) /* SH_RTC3_INT_CONFIG_IDX */ /* Description: Targeted McKinley interrupt vector */ -#define SH_RTC3_INT_CONFIG_IDX_SHFT 52 -#define SH_RTC3_INT_CONFIG_IDX_MASK 0x0ff0000000000000 +#define SH_RTC3_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC3_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) /* ==================================================================== */ /* Register "SH_RTC3_INT_ENABLE" */ /* SHub RTC 3 Interrupt Enable Registers */ /* ==================================================================== */ -#define SH1_RTC3_INT_ENABLE 0x0000000110001700 -#define SH2_RTC3_INT_ENABLE 0x0000000010001700 -#define SH_RTC3_INT_ENABLE_MASK 0x0000000000000001 -#define SH_RTC3_INT_ENABLE_INIT 0x0000000000000000 +#define SH1_RTC3_INT_ENABLE __IA64_UL_CONST(0x0000000110001700) +#define SH2_RTC3_INT_ENABLE __IA64_UL_CONST(0x0000000010001700) +#define SH_RTC3_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC3_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_RTC3_INT_ENABLE_RTC3_ENABLE */ /* Description: Enable RTC 3 Interrupt */ -#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT 0 -#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK 0x0000000000000001 +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT 0 +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) /* SH_EVENT_OCCURRED_RTC1_INT */ /* Description: Pending RTC 1 Interrupt */ -#define SH_EVENT_OCCURRED_RTC1_INT_SHFT 24 -#define SH_EVENT_OCCURRED_RTC1_INT_MASK 0x0000000001000000 +#define SH_EVENT_OCCURRED_RTC1_INT_SHFT 24 +#define SH_EVENT_OCCURRED_RTC1_INT_MASK __IA64_UL_CONST(0x0000000001000000) /* SH_EVENT_OCCURRED_RTC2_INT */ /* Description: Pending RTC 2 Interrupt */ -#define SH_EVENT_OCCURRED_RTC2_INT_SHFT 25 -#define SH_EVENT_OCCURRED_RTC2_INT_MASK 0x0000000002000000 +#define SH_EVENT_OCCURRED_RTC2_INT_SHFT 25 +#define SH_EVENT_OCCURRED_RTC2_INT_MASK __IA64_UL_CONST(0x0000000002000000) /* SH_EVENT_OCCURRED_RTC3_INT */ /* Description: Pending RTC 3 Interrupt */ -#define SH_EVENT_OCCURRED_RTC3_INT_SHFT 26 -#define SH_EVENT_OCCURRED_RTC3_INT_MASK 0x0000000004000000 +#define SH_EVENT_OCCURRED_RTC3_INT_SHFT 26 +#define SH_EVENT_OCCURRED_RTC3_INT_MASK __IA64_UL_CONST(0x0000000004000000) /* ==================================================================== */ /* Register "SH_IPI_ACCESS" */ /* CPU interrupt Access Permission Bits */ /* ==================================================================== */ -#define SH1_IPI_ACCESS 0x0000000110060480 -#define SH2_IPI_ACCESS0 0x0000000010060c00 -#define SH2_IPI_ACCESS1 0x0000000010060c80 -#define SH2_IPI_ACCESS2 0x0000000010060d00 -#define SH2_IPI_ACCESS3 0x0000000010060d80 +#define SH1_IPI_ACCESS __IA64_UL_CONST(0x0000000110060480) +#define SH2_IPI_ACCESS0 __IA64_UL_CONST(0x0000000010060c00) +#define SH2_IPI_ACCESS1 __IA64_UL_CONST(0x0000000010060c80) +#define SH2_IPI_ACCESS2 __IA64_UL_CONST(0x0000000010060d00) +#define SH2_IPI_ACCESS3 __IA64_UL_CONST(0x0000000010060d80) /* ==================================================================== */ /* Register "SH_INT_CMPB" */ /* RTC Compare Value for Processor B */ /* ==================================================================== */ -#define SH1_INT_CMPB 0x00000001101b0080 -#define SH2_INT_CMPB 0x00000000101b0080 -#define SH_INT_CMPB_MASK 0x007fffffffffffff -#define SH_INT_CMPB_INIT 0x0000000000000000 +#define SH1_INT_CMPB __IA64_UL_CONST(0x00000001101b0080) +#define SH2_INT_CMPB __IA64_UL_CONST(0x00000000101b0080) +#define SH_INT_CMPB_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPB_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_INT_CMPB_REAL_TIME_CMPB */ /* Description: Real Time Clock Compare */ -#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 -#define SH_INT_CMPB_REAL_TIME_CMPB_MASK 0x007fffffffffffff +#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 +#define SH_INT_CMPB_REAL_TIME_CMPB_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_INT_CMPC" */ /* RTC Compare Value for Processor C */ /* ==================================================================== */ -#define SH1_INT_CMPC 0x00000001101b0100 -#define SH2_INT_CMPC 0x00000000101b0100 -#define SH_INT_CMPC_MASK 0x007fffffffffffff -#define SH_INT_CMPC_INIT 0x0000000000000000 +#define SH1_INT_CMPC __IA64_UL_CONST(0x00000001101b0100) +#define SH2_INT_CMPC __IA64_UL_CONST(0x00000000101b0100) +#define SH_INT_CMPC_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPC_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_INT_CMPC_REAL_TIME_CMPC */ /* Description: Real Time Clock Compare */ -#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 -#define SH_INT_CMPC_REAL_TIME_CMPC_MASK 0x007fffffffffffff +#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 +#define SH_INT_CMPC_REAL_TIME_CMPC_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_INT_CMPD" */ /* RTC Compare Value for Processor D */ /* ==================================================================== */ -#define SH1_INT_CMPD 0x00000001101b0180 -#define SH2_INT_CMPD 0x00000000101b0180 -#define SH_INT_CMPD_MASK 0x007fffffffffffff -#define SH_INT_CMPD_INIT 0x0000000000000000 +#define SH1_INT_CMPD __IA64_UL_CONST(0x00000001101b0180) +#define SH2_INT_CMPD __IA64_UL_CONST(0x00000000101b0180) +#define SH_INT_CMPD_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPD_INIT __IA64_UL_CONST(0x0000000000000000) /* SH_INT_CMPD_REAL_TIME_CMPD */ /* Description: Real Time Clock Compare */ -#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 -#define SH_INT_CMPD_REAL_TIME_CMPD_MASK 0x007fffffffffffff +#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 +#define SH_INT_CMPD_REAL_TIME_CMPD_MASK __IA64_UL_CONST(0x007fffffffffffff) /* ==================================================================== */ /* Register "SH_MD_DQLP_MMR_DIR_PRIVEC0" */ /* privilege vector for acc=0 */ /* ==================================================================== */ - -#define SH1_MD_DQLP_MMR_DIR_PRIVEC0 0x0000000100030300 +#define SH1_MD_DQLP_MMR_DIR_PRIVEC0 __IA64_UL_CONST(0x0000000100030300) /* ==================================================================== */ /* Register "SH_MD_DQRP_MMR_DIR_PRIVEC0" */ /* privilege vector for acc=0 */ /* ==================================================================== */ - -#define SH1_MD_DQRP_MMR_DIR_PRIVEC0 0x0000000100050300 +#define SH1_MD_DQRP_MMR_DIR_PRIVEC0 __IA64_UL_CONST(0x0000000100050300) /* ==================================================================== */ /* Some MMRs are functionally identical (or close enough) on both SHUB1 */ @@ -484,17 +486,17 @@ /* Engine 0 Control and Status Register */ /* ========================================================================== */ -#define SH2_BT_ENG_CSR_0 0x0000000030040000 -#define SH2_BT_ENG_SRC_ADDR_0 0x0000000030040080 -#define SH2_BT_ENG_DEST_ADDR_0 0x0000000030040100 -#define SH2_BT_ENG_NOTIF_ADDR_0 0x0000000030040180 +#define SH2_BT_ENG_CSR_0 __IA64_UL_CONST(0x0000000030040000) +#define SH2_BT_ENG_SRC_ADDR_0 __IA64_UL_CONST(0x0000000030040080) +#define SH2_BT_ENG_DEST_ADDR_0 __IA64_UL_CONST(0x0000000030040100) +#define SH2_BT_ENG_NOTIF_ADDR_0 __IA64_UL_CONST(0x0000000030040180) /* ========================================================================== */ /* BTE interfaces 1-3 */ /* ========================================================================== */ -#define SH2_BT_ENG_CSR_1 0x0000000030050000 -#define SH2_BT_ENG_CSR_2 0x0000000030060000 -#define SH2_BT_ENG_CSR_3 0x0000000030070000 +#define SH2_BT_ENG_CSR_1 __IA64_UL_CONST(0x0000000030050000) +#define SH2_BT_ENG_CSR_2 __IA64_UL_CONST(0x0000000030060000) +#define SH2_BT_ENG_CSR_3 __IA64_UL_CONST(0x0000000030070000) #endif /* _ASM_IA64_SN_SHUB_MMR_H */ -- cgit v1.1 From 71a5d027c90dd7e14ddaaf22358ff5138ba89ec9 Mon Sep 17 00:00:00 2001 From: Jack Steiner Date: Tue, 10 May 2005 08:01:00 -0700 Subject: [IA64-SGI] - new macros for SGI SN simulator This patch changes some macros that are used when running kernel on the SGI simulator. Signed-off-by: Jack Steiner Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/io_init.c | 2 +- arch/ia64/sn/kernel/setup.c | 27 +++++++++++++++++++-------- include/asm-ia64/sn/simulator.h | 13 +++++++------ include/asm-ia64/sn/sn_sal.h | 10 ++++++++++ 4 files changed, 37 insertions(+), 15 deletions(-) diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 9e07f54..783eb43 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c @@ -384,7 +384,7 @@ static int __init sn_pci_init(void) extern void register_sn_procfs(void); #endif - if (!ia64_platform_is("sn2") || IS_RUNNING_ON_SIMULATOR()) + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; /* diff --git a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c index 3e5ba34..22e10d2 100644 --- a/arch/ia64/sn/kernel/setup.c +++ b/arch/ia64/sn/kernel/setup.c @@ -96,6 +96,7 @@ u8 sn_coherency_id; EXPORT_SYMBOL(sn_coherency_id); u8 sn_region_size; EXPORT_SYMBOL(sn_region_size); +int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ short physical_node_map[MAX_PHYSNODE_ID]; @@ -354,7 +355,7 @@ void __init sn_setup(char **cmdline_p) ia64_mark_idle = &snidle; - /* + /* * For the bootcpu, we do this here. All other cpus will make the * call as part of cpu_init in slave cpu initialization. */ @@ -401,7 +402,7 @@ static void __init sn_init_pdas(char **cmdline_p) nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t)); memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); - memset(nodepdaindr[cnode]->phys_cpuid, -1, + memset(nodepdaindr[cnode]->phys_cpuid, -1, sizeof(nodepdaindr[cnode]->phys_cpuid)); } @@ -431,7 +432,7 @@ static void __init sn_init_pdas(char **cmdline_p) } /* - * Initialize the per node hubdev. This includes IO Nodes and + * Initialize the per node hubdev. This includes IO Nodes and * headless/memless nodes. */ for (cnode = 0; cnode < numionodes; cnode++) { @@ -459,6 +460,14 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; + if (smp_processor_id() == 0 && IS_MEDUSA()) { + if (ia64_sn_is_fake_prom()) + sn_prom_type = 2; + else + sn_prom_type = 1; + printk("Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); + } + memset(pda, 0, sizeof(pda)); if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, &sn_hub_info->nasid_bitmask, &sn_hub_info->nasid_shift, &sn_system_size, &sn_sharing_domain_size, &sn_partition_id, @@ -524,7 +533,7 @@ void __init sn_cpu_init(void) */ { u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; - u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, + u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_2, SH2_PIO_WRITE_STATUS_3}; u64 *pio; pio = is_shub1() ? pio1 : pio2; @@ -556,6 +565,10 @@ static void __init scan_for_ionodes(void) int nasid = 0; lboard_t *brd; + /* fakeprom does not support klgraph */ + if (IS_RUNNING_ON_FAKE_PROM()) + return; + /* Setup ionodes with memory */ for (nasid = 0; nasid < MAX_PHYSNODE_ID; nasid += 2) { char *klgraph_header; @@ -567,8 +580,6 @@ static void __init scan_for_ionodes(void) cnodeid = -1; klgraph_header = __va(ia64_sn_get_klconfig_addr(nasid)); if (!klgraph_header) { - if (IS_RUNNING_ON_SIMULATOR()) - continue; BUG(); /* All nodes must have klconfig tables! */ } cnodeid = nasid_to_cnodeid(nasid); @@ -634,8 +645,8 @@ int nasid_slice_to_cpuid(int nasid, int slice) { long cpu; - - for (cpu=0; cpu < NR_CPUS; cpu++) + + for (cpu=0; cpu < NR_CPUS; cpu++) if (cpuid_to_nasid(cpu) == nasid && cpuid_to_slice(cpu) == slice) return cpu; diff --git a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h index 78eb4f8..cf770e2 100644 --- a/include/asm-ia64/sn/simulator.h +++ b/include/asm-ia64/sn/simulator.h @@ -10,16 +10,17 @@ #include -#ifdef CONFIG_IA64_SGI_SN_SIM - #define SNMAGIC 0xaeeeeeee8badbeefL -#define IS_RUNNING_ON_SIMULATOR() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;}) - -#define SIMULATOR_SLEEP() asm("nop.i 0x8beef") +#define IS_MEDUSA() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;}) +#ifdef CONFIG_IA64_SGI_SN_SIM +#define SIMULATOR_SLEEP() asm("nop.i 0x8beef") +#define IS_RUNNING_ON_SIMULATOR() (sn_prom_type) +#define IS_RUNNING_ON_FAKE_PROM() (sn_prom_type == 2) +extern int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ #else - #define IS_RUNNING_ON_SIMULATOR() (0) +#define IS_RUNNING_ON_FAKE_PROM() (0) #define SIMULATOR_SLEEP() #endif diff --git a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h index eb0395a..1455375 100644 --- a/include/asm-ia64/sn/sn_sal.h +++ b/include/asm-ia64/sn/sn_sal.h @@ -132,6 +132,8 @@ #define SALRET_INVALID_ARG (-2) #define SALRET_ERROR (-3) +#define SN_SAL_FAKE_PROM 0x02009999 + /** * sn_sal_rev_major - get the major SGI SAL revision number @@ -1105,4 +1107,12 @@ ia64_sn_bte_recovery(nasid_t nasid) return (int) rv.status; } +static inline int +ia64_sn_is_fake_prom(void) +{ + struct ia64_sal_retval rv; + SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0); + return (rv.status == 0); +} + #endif /* _ASM_IA64_SN_SN_SAL_H */ -- cgit v1.1 From 71030994a77e7689a7a792128b131ef7a10b9f74 Mon Sep 17 00:00:00 2001 From: Colin Ngam Date: Tue, 10 May 2005 09:12:00 -0700 Subject: [IA64-SGI] Fix TIO IOSPACE MMR Addres This patches provides support on Shub2 for the separate TIO IOSPACE MMR. This patch is SN specific. Signed-off-by: Colin Ngam Signed-off-by: Tony Luck --- include/asm-ia64/sn/addrs.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h index 1bfdfb4..103d745 100644 --- a/include/asm-ia64/sn/addrs.h +++ b/include/asm-ia64/sn/addrs.h @@ -216,6 +216,10 @@ #define TIO_SWIN_WIDGETNUM(x) (((x) >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK) +#define TIO_IOSPACE_ADDR(n,x) \ + /* Move in the Chiplet ID for TIO Local Block MMR */ \ + (REMOTE_ADDR(n,x) | 1UL << (NASID_SHIFT - 2)) + /* * The following macros produce the correct base virtual address for * the hub registers. The REMOTE_HUB_* macro produce @@ -233,13 +237,16 @@ #define REMOTE_HUB_ADDR(n,x) \ ((n & 1) ? \ /* TIO: */ \ - ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x))) \ - : /* SHUB: */ \ - (((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x)))\ + (is_shub2() ? \ + /* TIO on Shub2 */ \ + (volatile u64 *)(TIO_IOSPACE_ADDR(n,x)) \ + : /* TIO on shub1 */ \ + (volatile u64 *)(GLOBAL_MMR_ADDR(n,x))) \ + \ + : /* SHUB1 and SHUB2 MMRs: */ \ + (((x) & BWIN_TOP) ? ((volatile u64 *)(GLOBAL_MMR_ADDR(n,x))) \ : ((volatile u64 *)(NODE_SWIN_BASE(n,1) + 0x800000 + (x))))) - - #define HUB_L(x) (*((volatile typeof(*x) *)x)) #define HUB_S(x,d) (*((volatile typeof(*x) *)x) = (d)) -- cgit v1.1 From 92a582ed2757456ca9599f8b4ea2064f2154eb02 Mon Sep 17 00:00:00 2001 From: Prarit Bhargava Date: Tue, 10 May 2005 12:40:00 -0700 Subject: [IA64] sparse cleanup of TIOCA files This patch is a sparse compile cleanup of tioca_provider.c, sn_hwperf.h, and tioca_provider.h. Each of these files had sparse warnings when compiled. Signed-off-by: Prarit Bhargava Signed-off-by: Tony Luck --- arch/ia64/sn/pci/tioca_provider.c | 8 ++++---- include/asm-ia64/sn/sn2/sn_hwperf.h | 2 ++ include/asm-ia64/sn/tioca_provider.h | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/arch/ia64/sn/pci/tioca_provider.c b/arch/ia64/sn/pci/tioca_provider.c index 8dae9eb..05aa8c2f 100644 --- a/arch/ia64/sn/pci/tioca_provider.c +++ b/arch/ia64/sn/pci/tioca_provider.c @@ -336,7 +336,7 @@ tioca_dma_d48(struct pci_dev *pdev, uint64_t paddr) if (!ct_addr) return 0; - bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffff); + bus_addr = (dma_addr_t) (ct_addr & 0xffffffffffffUL); node_upper = ct_addr >> 48; if (node_upper > 64) { @@ -464,7 +464,7 @@ map_return: * For mappings created using the direct modes (64 or 48) there are no * resources to release. */ -void +static void tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) { int i, entry; @@ -514,7 +514,7 @@ tioca_dma_unmap(struct pci_dev *pdev, dma_addr_t bus_addr, int dir) * The mapping mode used is based on the devices dma_mask. As a last resort * use the GART mapped mode. */ -uint64_t +static uint64_t tioca_dma_map(struct pci_dev *pdev, uint64_t paddr, size_t byte_count) { uint64_t mapaddr; @@ -580,7 +580,7 @@ tioca_error_intr_handler(int irq, void *arg, struct pt_regs *pt) * On successful setup, returns the kernel version of tioca_common back to * the caller. */ -void * +static void * tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft) { struct tioca_common *tioca_common; diff --git a/include/asm-ia64/sn/sn2/sn_hwperf.h b/include/asm-ia64/sn/sn2/sn_hwperf.h index b0c4d6d..df75f4c 100644 --- a/include/asm-ia64/sn/sn2/sn_hwperf.h +++ b/include/asm-ia64/sn/sn2/sn_hwperf.h @@ -223,4 +223,6 @@ struct sn_hwperf_ioctl_args { #define SN_HWPERF_OP_RECONFIGURE 253 #define SN_HWPERF_OP_INVAL 254 +int sn_topology_open(struct inode *inode, struct file *file); +int sn_topology_release(struct inode *inode, struct file *file); #endif /* SN_HWPERF_H */ diff --git a/include/asm-ia64/sn/tioca_provider.h b/include/asm-ia64/sn/tioca_provider.h index b6acc22..5ccec60 100644 --- a/include/asm-ia64/sn/tioca_provider.h +++ b/include/asm-ia64/sn/tioca_provider.h @@ -201,6 +201,7 @@ tioca_tlbflush(struct tioca_kernel *tioca_kernel) } extern uint32_t tioca_gart_found; +extern struct list_head tioca_list; extern int tioca_init_provider(void); extern void tioca_fastwrite_enable(struct tioca_kernel *tioca_kern); #endif /* _ASM_IA64_SN_TIO_CA_AGP_PROVIDER_H */ -- cgit v1.1 From c1ffb6a8aaed45ba2dc0a8f09241b0a96f9955ba Mon Sep 17 00:00:00 2001 From: Bruce Losure Date: Tue, 24 May 2005 08:30:00 -0700 Subject: [IA64-SGI] Altix patch to tiocx, add subsys_initcall This patch fixes an ordering issue between the init code for the tiocx bus driver and tiocx-related device drivers. Also adds a new brick to the list of known FPGA bricks. Signed-off-by: Bruce Losure Signed-off-by: Tony Luck --- arch/ia64/sn/kernel/tiocx.c | 14 +++++++++----- include/asm-ia64/sn/l1.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/arch/ia64/sn/kernel/tiocx.c b/arch/ia64/sn/kernel/tiocx.c index a087b27..8716f4d 100644 --- a/arch/ia64/sn/kernel/tiocx.c +++ b/arch/ia64/sn/kernel/tiocx.c @@ -204,8 +204,8 @@ cx_device_register(nasid_t nasid, int part_num, int mfg_num, cx_dev->dev.parent = NULL; cx_dev->dev.bus = &tiocx_bus_type; cx_dev->dev.release = tiocx_bus_release; - snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d.0x%x", - cx_dev->cx_id.nasid, cx_dev->cx_id.part_num); + snprintf(cx_dev->dev.bus_id, BUS_ID_SIZE, "%d", + cx_dev->cx_id.nasid); device_register(&cx_dev->dev); get_device(&cx_dev->dev); @@ -236,7 +236,6 @@ int cx_device_unregister(struct cx_dev *cx_dev) */ static int cx_device_reload(struct cx_dev *cx_dev) { - device_remove_file(&cx_dev->dev, &dev_attr_cxdev_control); cx_device_unregister(cx_dev); return cx_device_register(cx_dev->cx_id.nasid, cx_dev->cx_id.part_num, cx_dev->cx_id.mfg_num, cx_dev->hubdev); @@ -383,6 +382,7 @@ static int is_fpga_brick(int nasid) switch (tiocx_btchar_get(nasid)) { case L1_BRICKTYPE_SA: case L1_BRICKTYPE_ATHENA: + case L1_BRICKTYPE_DAYTONA: return 1; } return 0; @@ -409,7 +409,7 @@ static int tiocx_reload(struct cx_dev *cx_dev) uint64_t cx_id; cx_id = - *(volatile int32_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + + *(volatile uint64_t *)(TIO_SWIN_BASE(nasid, TIOCX_CORELET) + WIDGET_ID); part_num = XWIDGET_PART_NUM(cx_id); mfg_num = XWIDGET_MFG_NUM(cx_id); @@ -458,6 +458,10 @@ static ssize_t store_cxdev_control(struct device *dev, struct device_attribute * switch (n) { case 1: + tio_corelet_reset(cx_dev->cx_id.nasid, TIOCX_CORELET); + tiocx_reload(cx_dev); + break; + case 2: tiocx_reload(cx_dev); break; case 3: @@ -537,7 +541,7 @@ static void __exit tiocx_exit(void) bus_unregister(&tiocx_bus_type); } -module_init(tiocx_init); +subsys_initcall(tiocx_init); module_exit(tiocx_exit); /************************************************************************ diff --git a/include/asm-ia64/sn/l1.h b/include/asm-ia64/sn/l1.h index 08050d3..2e5f0aa 100644 --- a/include/asm-ia64/sn/l1.h +++ b/include/asm-ia64/sn/l1.h @@ -33,5 +33,6 @@ #define L1_BRICKTYPE_PA 0x6a /* j */ #define L1_BRICKTYPE_IA 0x6b /* k */ #define L1_BRICKTYPE_ATHENA 0x2b /* + */ +#define L1_BRICKTYPE_DAYTONA 0x7a /* z */ #endif /* _ASM_IA64_SN_L1_H */ -- cgit v1.1 From 819c67e69c4e0062787e27dd989f5f9d00d4834e Mon Sep 17 00:00:00 2001 From: David Mosberger-Tang Date: Thu, 9 Jun 2005 22:40:00 -0700 Subject: [IA64] Replace stale KDB-code with useful MAGIC_SYSRQ code in simserial.c Patch makes it possible to use the "F4" function key to do magic sysrq in the HP Ski simulator. Signed-off-by: David Mosberger-Tang Signed-off-by: Tony Luck --- arch/ia64/hp/sim/simserial.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c index 786e707..7a8ae0f 100644 --- a/arch/ia64/hp/sim/simserial.c +++ b/arch/ia64/hp/sim/simserial.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -149,12 +150,17 @@ static void receive_chars(struct tty_struct *tty, struct pt_regs *regs) seen_esc = 2; continue; } else if ( seen_esc == 2 ) { - if ( ch == 'P' ) show_state(); /* F1 key */ -#ifdef CONFIG_KDB - if ( ch == 'S' ) - kdb(KDB_REASON_KEYBOARD, 0, (kdb_eframe_t) regs); + if ( ch == 'P' ) /* F1 */ + show_state(); +#ifdef CONFIG_MAGIC_SYSRQ + if ( ch == 'S' ) { /* F4 */ + do + ch = ia64_ssc(0, 0, 0, 0, + SSC_GETCHAR); + while (!ch); + handle_sysrq(ch, regs, NULL); + } #endif - seen_esc = 0; continue; } -- cgit v1.1 From a68db763af9b676590c3fe9ec3f17bf18015eb2f Mon Sep 17 00:00:00 2001 From: Peter Chubb Date: Thu, 23 Jun 2005 21:14:00 -0700 Subject: [IA64] Fix another IA64 preemption problem There's another problem shown up by Ingo's recent patch to make smp_processor_id() complain if it's called with preemption enabled. local_finish_flush_tlb_mm() calls activate_context() in a situation where it could be rescheduled to another processor. This patch disables preemption around the call. Signed-off-by: Peter Chubb Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 3 +++ include/asm-ia64/mmu_context.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index b49d4dd..0166a98 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -231,13 +231,16 @@ smp_flush_tlb_all (void) void smp_flush_tlb_mm (struct mm_struct *mm) { + preempt_disable(); /* this happens for the common case of a single-threaded fork(): */ if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1)) { local_finish_flush_tlb_mm(mm); + preempt_enable(); return; } + preempt_enable(); /* * We could optimize this further by using mm->cpu_vm_mask to track which CPUs * have been running in the address space. It's not clear that this is worth the diff --git a/include/asm-ia64/mmu_context.h b/include/asm-ia64/mmu_context.h index 0096e7e..e3e5fed 100644 --- a/include/asm-ia64/mmu_context.h +++ b/include/asm-ia64/mmu_context.h @@ -132,6 +132,9 @@ reload_context (mm_context_t context) ia64_srlz_i(); /* srlz.i implies srlz.d */ } +/* + * Must be called with preemption off + */ static inline void activate_context (struct mm_struct *mm) { -- cgit v1.1 From 053a7b5b7617a72d7c61b6f84196d1c0f79b9849 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 Jun 2005 19:22:25 +0100 Subject: [PATCH] ARM SMP: __xchg support This enables the existing __xchg implementation to be used on SMP. Signed-off-by: Russell King --- include/asm-arm/system.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index 3d0d286..cdf49f4 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -290,7 +290,6 @@ do { \ }) #ifdef CONFIG_SMP -#error SMP not supported #define smp_mb() mb() #define smp_rmb() rmb() @@ -304,6 +303,8 @@ do { \ #define smp_wmb() barrier() #define smp_read_barrier_depends() do { } while(0) +#endif /* CONFIG_SMP */ + #if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110) /* * On the StrongARM, "swp" is terminally broken since it bypasses the @@ -316,9 +317,16 @@ do { \ * * We choose (1) since its the "easiest" to achieve here and is not * dependent on the processor type. + * + * NOTE that this solution won't work on an SMP system, so explcitly + * forbid it here. */ +#ifdef CONFIG_SMP +#error SMP is not supported on SA1100/SA110 +#else #define swp_is_buggy #endif +#endif static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) { @@ -361,8 +369,6 @@ static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size return ret; } -#endif /* CONFIG_SMP */ - #endif /* __ASSEMBLY__ */ #define arch_align_stack(x) (x) -- cgit v1.1 From 85c1937b2693a0d4e39bb2644d720ed3703b9830 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Jun 2005 12:39:40 -0700 Subject: [EBTABLES]: Fix thinkos in ebt_log.c When converting over the skb_header_pointer(), I converted parts of this module incorrectly. Kill the 'u' union in ebt_log() and all the bogus references to it. Signed-off-by: David S. Miller --- net/bridge/netfilter/ebt_log.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index e4ae34b..662975b 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -61,8 +61,6 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, { struct ebt_log_info *info = (struct ebt_log_info *)data; char level_string[4] = "< >"; - union {struct iphdr iph; struct tcpudphdr ports; - struct arphdr arph; struct arppayload arpp;} u; level_string[1] = '0' + info->loglevel; spin_lock_bh(&ebt_log_lock); @@ -88,7 +86,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, } printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", NIPQUAD(ih->saddr), NIPQUAD(ih->daddr)); - printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos, + printk(" IP tos=0x%02X, IP proto=%d", ih->tos, ih->protocol); if (ih->protocol == IPPROTO_TCP || ih->protocol == IPPROTO_UDP) { @@ -127,7 +125,7 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, ah->ar_pln == sizeof(uint32_t)) { struct arppayload _arpp, *ap; - ap = skb_header_pointer(skb, sizeof(u.arph), + ap = skb_header_pointer(skb, sizeof(_arph), sizeof(_arpp), &_arpp); if (ap == NULL) { printk(" INCOMPLETE ARP payload"); -- cgit v1.1 From 4095ebf1e641b0f37ee1cd04c903bb85cf4ed25b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 28 Jun 2005 12:49:30 -0700 Subject: [NETFILTER]: ipt_CLUSTERIP: fix ARP mangling This patch adds mangling of ARP requests (in addition to replies), since ARP caches are made from snooping both requests and replies. Signed-off-by: Harald Welte Signed-off-by: David S. Miller --- net/ipv4/netfilter/ipt_CLUSTERIP.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 9cde8c6..6706d3a 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c @@ -30,7 +30,7 @@ #include #include -#define CLUSTERIP_VERSION "0.6" +#define CLUSTERIP_VERSION "0.7" #define DEBUG_CLUSTERIP @@ -524,8 +524,9 @@ arp_mangle(unsigned int hook, || arp->ar_pln != 4 || arp->ar_hln != ETH_ALEN) return NF_ACCEPT; - /* we only want to mangle arp replies */ - if (arp->ar_op != htons(ARPOP_REPLY)) + /* we only want to mangle arp requests and replies */ + if (arp->ar_op != htons(ARPOP_REPLY) + && arp->ar_op != htons(ARPOP_REQUEST)) return NF_ACCEPT; payload = (void *)(arp+1); -- cgit v1.1 From b3563c4fbff906991a1b4ef4609f99cca2a0de6a Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 12:54:43 -0700 Subject: [NETLINK]: Clear padding in netlink messages Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/netlink.h | 1 + include/linux/rtnetlink.h | 5 ++++- net/core/rtnetlink.c | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 3029cad..27e4d16 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -168,6 +168,7 @@ __nlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, int type, int len, int flags) nlh->nlmsg_flags = flags; nlh->nlmsg_pid = pid; nlh->nlmsg_seq = seq; + memset(NLMSG_DATA(nlh) + len, 0, NLMSG_ALIGN(size) - size); return nlh; } diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index d021888..dc26e82 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -898,7 +898,9 @@ extern void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const voi memcpy(skb_put(skb, attrlen), data, attrlen); }) #define RTA_PUT_NOHDR(skb, attrlen, data) \ - RTA_APPEND(skb, RTA_ALIGN(attrlen), data) +({ RTA_APPEND(skb, RTA_ALIGN(attrlen), data); \ + memset(skb->tail - (RTA_ALIGN(attrlen) - attrlen), 0, \ + RTA_ALIGN(attrlen) - attrlen); }) #define RTA_PUT_U8(skb, attrtype, value) \ ({ u8 _tmp = (value); \ @@ -978,6 +980,7 @@ __rta_reserve(struct sk_buff *skb, int attrtype, int attrlen) rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size)); rta->rta_type = attrtype; rta->rta_len = size; + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); return rta; } diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e013d83..879237c 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -126,6 +126,7 @@ void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data rta->rta_type = attrtype; rta->rta_len = size; memcpy(RTA_DATA(rta), data, attrlen); + memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size); } size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size) -- cgit v1.1 From 9ef1d4c7c7aca1cd436612b6ca785b726ffb8ed8 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 12:55:30 -0700 Subject: [NETLINK]: Missing initializations in dumped data Mostly missing initialization of padding fields of 1 or 2 bytes length, two instances of uninitialized nlmsgerr->msg of 16 bytes length. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/core/neighbour.c | 6 ++++++ net/core/rtnetlink.c | 1 + net/core/wireless.c | 1 + net/ipv4/ipmr.c | 10 ++++++++-- net/ipv6/addrconf.c | 1 + net/sched/act_api.c | 10 +++++++++- net/sched/cls_api.c | 2 ++ net/sched/sch_api.c | 2 ++ net/sched/sch_cbq.c | 2 ++ 9 files changed, 32 insertions(+), 3 deletions(-) diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 851eb92..1beb782 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1598,6 +1598,8 @@ static int neightbl_fill_info(struct neigh_table *tbl, struct sk_buff *skb, read_lock_bh(&tbl->lock); ndtmsg->ndtm_family = tbl->family; + ndtmsg->ndtm_pad1 = 0; + ndtmsg->ndtm_pad2 = 0; RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); RTA_PUT_MSECS(skb, NDTA_GC_INTERVAL, tbl->gc_interval); @@ -1683,6 +1685,8 @@ static int neightbl_fill_param_info(struct neigh_table *tbl, read_lock_bh(&tbl->lock); ndtmsg->ndtm_family = tbl->family; + ndtmsg->ndtm_pad1 = 0; + ndtmsg->ndtm_pad2 = 0; RTA_PUT_STRING(skb, NDTA_NAME, tbl->id); if (neightbl_fill_parms(skb, parms) < 0) @@ -1872,6 +1876,8 @@ static int neigh_fill_info(struct sk_buff *skb, struct neighbour *n, struct ndmsg *ndm = NLMSG_DATA(nlh); ndm->ndm_family = n->ops->family; + ndm->ndm_pad1 = 0; + ndm->ndm_pad2 = 0; ndm->ndm_flags = n->flags; ndm->ndm_type = n->type; ndm->ndm_ifindex = n->dev->ifindex; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 879237c..4b1bb30 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -189,6 +189,7 @@ static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags); r = NLMSG_DATA(nlh); r->ifi_family = AF_UNSPEC; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev_get_flags(dev); diff --git a/net/core/wireless.c b/net/core/wireless.c index b2fe378..3ff5639 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c @@ -1102,6 +1102,7 @@ static inline int rtnetlink_fill_iwinfo(struct sk_buff * skb, nlh = NLMSG_PUT(skb, 0, 0, type, sizeof(*r)); r = NLMSG_DATA(nlh); r->ifi_family = AF_UNSPEC; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev->flags; diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index e4f809a..7833d92 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -297,6 +297,7 @@ static int vif_delete(int vifi) static void ipmr_destroy_unres(struct mfc_cache *c) { struct sk_buff *skb; + struct nlmsgerr *e; atomic_dec(&cache_resolve_queue_len); @@ -306,7 +307,9 @@ static void ipmr_destroy_unres(struct mfc_cache *c) nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); skb_trim(skb, nlh->nlmsg_len); - ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -ETIMEDOUT; + e = NLMSG_DATA(nlh); + e->error = -ETIMEDOUT; + memset(&e->msg, 0, sizeof(e->msg)); netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); } else kfree_skb(skb); @@ -499,6 +502,7 @@ static struct mfc_cache *ipmr_cache_alloc_unres(void) static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) { struct sk_buff *skb; + struct nlmsgerr *e; /* * Play the pending entries through our router @@ -515,7 +519,9 @@ static void ipmr_cache_resolve(struct mfc_cache *uc, struct mfc_cache *c) nlh->nlmsg_type = NLMSG_ERROR; nlh->nlmsg_len = NLMSG_LENGTH(sizeof(struct nlmsgerr)); skb_trim(skb, nlh->nlmsg_len); - ((struct nlmsgerr*)NLMSG_DATA(nlh))->error = -EMSGSIZE; + e = NLMSG_DATA(nlh); + e->error = -EMSGSIZE; + memset(&e->msg, 0, sizeof(e->msg)); } err = netlink_unicast(rtnl, skb, NETLINK_CB(skb).dst_pid, MSG_DONTWAIT); } else diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a54d4ef..8140bed 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2923,6 +2923,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); r = NLMSG_DATA(nlh); r->ifi_family = AF_INET6; + r->__ifi_pad = 0; r->ifi_type = dev->type; r->ifi_index = dev->ifindex; r->ifi_flags = dev_get_flags(dev); diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 9594206..249c619 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c @@ -439,6 +439,8 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr*) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -580,6 +582,8 @@ static int tca_action_flush(struct rtattr *rta, struct nlmsghdr *n, u32 pid) nlh = NLMSG_PUT(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t)); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -687,7 +691,9 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*t), flags); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; - + t->tca__pad1 = 0; + t->tca__pad2 = 0; + x = (struct rtattr*) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); @@ -842,6 +848,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) cb->nlh->nlmsg_type, sizeof(*t)); t = NLMSG_DATA(nlh); t->tca_family = AF_UNSPEC; + t->tca__pad1 = 0; + t->tca__pad2 = 0; x = (struct rtattr *) skb->tail; RTA_PUT(skb, TCA_ACT_TAB, 0, NULL); diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 1616bf5..3b5714e 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c @@ -331,6 +331,8 @@ tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, unsigned long fh, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad1 = 0; tcm->tcm_ifindex = tp->q->dev->ifindex; tcm->tcm_parent = tp->classid; tcm->tcm_info = TC_H_MAKE(tp->prio, tp->protocol); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 97c1c75..05e6e0a 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -770,6 +770,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags); tcm = NLMSG_DATA(nlh); tcm->tcm_family = AF_UNSPEC; + tcm->tcm__pad1 = 0; + tcm->tcm__pad2 = 0; tcm->tcm_ifindex = q->dev->ifindex; tcm->tcm_parent = clid; tcm->tcm_handle = q->handle; diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index d43e3b8..baeb3111 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1563,6 +1563,8 @@ static __inline__ int cbq_dump_police(struct sk_buff *skb, struct cbq_class *cl) if (cl->police) { opt.police = cl->police; + opt.__res1 = 0; + opt.__res2 = 0; RTA_PUT(skb, TCA_CBQ_POLICE, sizeof(opt), &opt); } return skb->len; -- cgit v1.1 From 8a47077a0b5aa2649751c46e7a27884e6686ccbf Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 12:56:45 -0700 Subject: [NETLINK]: Missing padding fields in dumped structures Plug holes with padding fields and initialized them to zero. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- include/linux/pkt_cls.h | 1 + include/linux/pkt_sched.h | 9 ++++++--- include/linux/rtnetlink.h | 5 +++++ net/ipv6/addrconf.c | 3 +++ net/sched/cls_rsvp.h | 1 + net/sched/sch_cbq.c | 1 + 6 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h index 25d2d67..bd2c5a2 100644 --- a/include/linux/pkt_cls.h +++ b/include/linux/pkt_cls.h @@ -276,6 +276,7 @@ struct tc_rsvp_pinfo __u8 protocol; __u8 tunnelid; __u8 tunnelhdr; + __u8 pad; }; /* ROUTE filter */ diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 1d9da36..60ffcb9 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -221,9 +221,11 @@ struct tc_gred_qopt /* gred setup */ struct tc_gred_sopt { - __u32 DPs; - __u32 def_DP; - __u8 grio; + __u32 DPs; + __u32 def_DP; + __u8 grio; + __u8 pad1; + __u16 pad2; }; /* HTB section */ @@ -351,6 +353,7 @@ struct tc_cbq_ovl #define TC_CBQ_OVL_DROP 3 #define TC_CBQ_OVL_RCLASSIC 4 unsigned char priority2; + __u16 pad; __u32 penalty; }; diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index dc26e82..657c05a 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -363,6 +363,8 @@ enum struct rta_session { __u8 proto; + __u8 pad1; + __u16 pad2; union { struct { @@ -635,10 +637,13 @@ struct ifinfomsg struct prefixmsg { unsigned char prefix_family; + unsigned char prefix_pad1; + unsigned short prefix_pad2; int prefix_ifindex; unsigned char prefix_type; unsigned char prefix_len; unsigned char prefix_flags; + unsigned char prefix_pad3; }; enum diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 8140bed..1b2902d 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -3031,9 +3031,12 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); pmsg = NLMSG_DATA(nlh); pmsg->prefix_family = AF_INET6; + pmsg->prefix_pad1 = 0; + pmsg->prefix_pad2 = 0; pmsg->prefix_ifindex = idev->dev->ifindex; pmsg->prefix_len = pinfo->prefix_len; pmsg->prefix_type = pinfo->type; + pmsg->prefix_pad3 = 0; pmsg->prefix_flags = 0; if (pinfo->onlink) diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 232fb91..006168d 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h @@ -618,6 +618,7 @@ static int rsvp_dump(struct tcf_proto *tp, unsigned long fh, pinfo.protocol = s->protocol; pinfo.tunnelid = s->tunnelid; pinfo.tunnelhdr = f->tunnelhdr; + pinfo.pad = 0; RTA_PUT(skb, TCA_RSVP_PINFO, sizeof(pinfo), &pinfo); if (f->res.classid) RTA_PUT(skb, TCA_RSVP_CLASSID, 4, &f->res.classid); diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index baeb3111..09453f9 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c @@ -1528,6 +1528,7 @@ static __inline__ int cbq_dump_ovl(struct sk_buff *skb, struct cbq_class *cl) opt.strategy = cl->ovl_strategy; opt.priority2 = cl->priority2+1; + opt.pad = 0; opt.penalty = (cl->penalty*1000)/HZ; RTA_PUT(skb, TCA_CBQ_OVL_STRATEGY, sizeof(opt), &opt); return skb->len; -- cgit v1.1 From ae9cda5d65f3d8a495241cbdcc2d56f721c83cc3 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 28 Jun 2005 13:00:30 -0700 Subject: [IPV6]: Don't dump temporary addresses twice Each IPv6 Temporary Address (w/ CONFIG_IPV6_PRIVACY) is dumped twice to netlink. Because temporary addresses are listed in idev->addr_list, there's no need to dump idev->tempaddr separately. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- net/ipv6/addrconf.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1b2902d..77004b9 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2777,7 +2777,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, read_lock_bh(&idev->lock); switch (type) { case UNICAST_ADDR: - /* unicast address */ + /* unicast address incl. temp addr */ for (ifa = idev->addr_list; ifa; ifa = ifa->if_next, ip_idx++) { if (ip_idx < s_ip_idx) @@ -2788,19 +2788,6 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, NLM_F_MULTI)) <= 0) goto done; } - /* temp addr */ -#ifdef CONFIG_IPV6_PRIVACY - for (ifa = idev->tempaddr_list; ifa; - ifa = ifa->tmp_next, ip_idx++) { - if (ip_idx < s_ip_idx) - continue; - if ((err = inet6_fill_ifaddr(skb, ifa, - NETLINK_CB(cb->skb).pid, - cb->nlh->nlmsg_seq, RTM_NEWADDR, - NLM_F_MULTI)) <= 0) - goto done; - } -#endif break; case MULTICAST_ADDR: /* multicast address */ -- cgit v1.1 From fa0ebff62a8a25952a082641db0ed6b1cfc6c38c Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Tue, 28 Jun 2005 21:01:03 +0100 Subject: [PATCH] ARM: 2761/1: OProfile: Add call graphing support for arm Patch from Richard Purdie Add functions to generate backtraces of both kernel and user processes which allows oprofile's call graphing functionality to be used on arm. This requires unstripped binaries/libs which use a frame pointer. Signed-off-by: Richard Purdie Signed-off-by: Zwane Mwaikambo Signed-off-by: Russell King --- arch/arm/oprofile/Makefile | 2 +- arch/arm/oprofile/backtrace.c | 144 +++++++++++++++++++++++++++++++++++++++ arch/arm/oprofile/init.c | 2 + arch/arm/oprofile/op_arm_model.h | 2 + 4 files changed, 149 insertions(+), 1 deletion(-) create mode 100644 arch/arm/oprofile/backtrace.c diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile index ba1a6e9..8ffb523 100644 --- a/arch/arm/oprofile/Makefile +++ b/arch/arm/oprofile/Makefile @@ -6,6 +6,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ oprofilefs.o oprofile_stats.o \ timer_int.o ) -oprofile-y := $(DRIVER_OBJS) init.o +oprofile-y := $(DRIVER_OBJS) init.o backtrace.o oprofile-$(CONFIG_CPU_XSCALE) += common.o op_model_xscale.o diff --git a/arch/arm/oprofile/backtrace.c b/arch/arm/oprofile/backtrace.c new file mode 100644 index 0000000..ec58d3e --- /dev/null +++ b/arch/arm/oprofile/backtrace.c @@ -0,0 +1,144 @@ +/* + * Arm specific backtracing code for oprofile + * + * Copyright 2005 Openedhand Ltd. + * + * Author: Richard Purdie + * + * Based on i386 oprofile backtrace code by John Levon, David Smith + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include + + +/* + * The registers we're interested in are at the end of the variable + * length saved register structure. The fp points at the end of this + * structure so the address of this struct is: + * (struct frame_tail *)(xxx->fp)-1 + */ +struct frame_tail { + struct frame_tail *fp; + unsigned long sp; + unsigned long lr; +} __attribute__((packed)); + + +#ifdef CONFIG_FRAME_POINTER +static struct frame_tail* kernel_backtrace(struct frame_tail *tail) +{ + oprofile_add_trace(tail->lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= tail->fp) + return NULL; + + return tail->fp-1; +} +#endif + +static struct frame_tail* user_backtrace(struct frame_tail *tail) +{ + struct frame_tail buftail; + + /* hardware pte might not be valid due to dirty/accessed bit emulation + * so we use copy_from_user and benefit from exception fixups */ + if (copy_from_user(&buftail, tail, sizeof(struct frame_tail))) + return NULL; + + oprofile_add_trace(buftail.lr); + + /* frame pointers should strictly progress back up the stack + * (towards higher addresses) */ + if (tail >= buftail.fp) + return NULL; + + return buftail.fp-1; +} + +/* Compare two addresses and see if they're on the same page */ +#define CMP_ADDR_EQUAL(x,y,offset) ((((unsigned long) x) >> PAGE_SHIFT) \ + == ((((unsigned long) y) + offset) >> PAGE_SHIFT)) + +/* check that the page(s) containing the frame tail are present */ +static int pages_present(struct frame_tail *tail) +{ + struct mm_struct * mm = current->mm; + + if (!check_user_page_readable(mm, (unsigned long)tail)) + return 0; + + if (CMP_ADDR_EQUAL(tail, tail, 8)) + return 1; + + if (!check_user_page_readable(mm, ((unsigned long)tail) + 8)) + return 0; + + return 1; +} + +/* + * | | /\ Higher addresses + * | | + * --------------- stack base (address of current_thread_info) + * | thread info | + * . . + * | stack | + * --------------- saved regs->ARM_fp value if valid (frame_tail address) + * . . + * --------------- struct pt_regs stored on stack (struct pt_regs *) + * | | + * . . + * | | + * --------------- %esp + * | | + * | | \/ Lower addresses + * + * Thus, &pt_regs <-> stack base restricts the valid(ish) fp values + */ +static int valid_kernel_stack(struct frame_tail *tail, struct pt_regs *regs) +{ + unsigned long tailaddr = (unsigned long)tail; + unsigned long stack = (unsigned long)regs; + unsigned long stack_base = (stack & ~(THREAD_SIZE - 1)) + THREAD_SIZE; + + return (tailaddr > stack) && (tailaddr < stack_base); +} + +void arm_backtrace(struct pt_regs const *regs, unsigned int depth) +{ + struct frame_tail *tail; + unsigned long last_address = 0; + + tail = ((struct frame_tail *) regs->ARM_fp) - 1; + + if (!user_mode(regs)) { + +#ifdef CONFIG_FRAME_POINTER + while (depth-- && tail && valid_kernel_stack(tail, regs)) { + tail = kernel_backtrace(tail); + } +#endif + return; + } + + while (depth-- && tail && !((unsigned long) tail & 3)) { + if ((!CMP_ADDR_EQUAL(last_address, tail, 0) + || !CMP_ADDR_EQUAL(last_address, tail, 8)) + && !pages_present(tail)) + return; + last_address = (unsigned long) tail; + tail = user_backtrace(tail); + } +} + diff --git a/arch/arm/oprofile/init.c b/arch/arm/oprofile/init.c index cce3d30..d315a3a 100644 --- a/arch/arm/oprofile/init.c +++ b/arch/arm/oprofile/init.c @@ -20,6 +20,8 @@ int __init oprofile_arch_init(struct oprofile_operations *ops) ret = pmu_init(ops, &op_xscale_spec); #endif + ops->backtrace = arm_backtrace; + return ret; } diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h index 2d4caf4..2148d07 100644 --- a/arch/arm/oprofile/op_arm_model.h +++ b/arch/arm/oprofile/op_arm_model.h @@ -24,6 +24,8 @@ struct op_arm_model_spec { extern struct op_arm_model_spec op_xscale_spec; #endif +extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); + extern int __init pmu_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); extern void pmu_exit(void); #endif /* OP_ARM_MODEL_H */ -- cgit v1.1 From 072cd703b6a2a3adc14fbc2d969424c7022a7892 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 28 Jun 2005 21:01:03 +0100 Subject: [PATCH] ARM: 2762/1: S3C24XX Audio platform data Patch from Ben Dooks This provides the s3c24xx audio platform data which can be supplied from any of the board specific drivers. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- include/asm-arm/arch-s3c2410/audio.h | 49 ++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 include/asm-arm/arch-s3c2410/audio.h diff --git a/include/asm-arm/arch-s3c2410/audio.h b/include/asm-arm/arch-s3c2410/audio.h new file mode 100644 index 0000000..0d276e6 --- /dev/null +++ b/include/asm-arm/arch-s3c2410/audio.h @@ -0,0 +1,49 @@ +/* linux/include/asm-arm/arch-s3c2410/audio.h + * + * (c) 2004-2005 Simtec Electronics + * http://www.simtec.co.uk/products/SWLINUX/ + * Ben Dooks + * + * S3C24XX - Audio platfrom_device info + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Changelog: + * 20-Nov-2004 BJD Created file + * 07-Mar-2005 BJD Added suspend/resume calls +*/ + +#ifndef __ASM_ARCH_AUDIO_H +#define __ASM_ARCH_AUDIO_H __FILE__ + +/* struct s3c24xx_iis_ops + * + * called from the s3c24xx audio core to deal with the architecture + * or the codec's setup and control. + * + * the pointer to itself is passed through in case the caller wants to + * embed this in an larger structure for easy reference to it's context. +*/ + +struct s3c24xx_iis_ops { + struct module *owner; + + int (*startup)(struct s3c24xx_iis_ops *me); + void (*shutdown)(struct s3c24xx_iis_ops *me); + int (*suspend)(struct s3c24xx_iis_ops *me); + int (*resume)(struct s3c24xx_iis_ops *me); + + int (*open)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm); + int (*close)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm); + int (*prepare)(struct s3c24xx_iis_ops *me, snd_pcm_substream_t *strm, snd_pcm_runtime_t *rt); +}; + +struct s3c24xx_platdata_iis { + const char *codec_clk; + struct s3c24xx_iis_ops *ops; + int (*match_dev)(struct device *dev); +}; + +#endif /* __ASM_ARCH_AUDIO_H */ -- cgit v1.1 From f2be64b3b15f52ceb83ff26abc10705a31ae5352 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 28 Jun 2005 21:01:16 +0100 Subject: [PATCH] ARM: 2760/1: Add a warning on dynamic tick timekeeping on some platforms Patch from Tony Lindgren This patch was suggested by RMK, and adds a warning on the accuracy of timekeeping when using dynamic tick on some platforms. Depending on the timer implementation, dynamic tick may affect the accuracy of timekeeping. Currently at least OMAP is known to have accurate timekeeping with dynamic tick. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/Kconfig | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index c8d94dc..620f2ca 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -361,6 +361,11 @@ config NO_IDLE_HZ Alternatively, if you want dynamic tick automatically enabled during boot, pass "dyntick=enable" via the kernel command string. + Please note that dynamic tick may affect the accuracy of + timekeeping on some platforms depending on the implementation. + Currently at least OMAP platform is known to have accurate + timekeeping with dynamic tick. + config ARCH_DISCONTIGMEM_ENABLE bool default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) -- cgit v1.1 From 2c2910a401f1ce2ac9136171e7522e731e1a2a8c Mon Sep 17 00:00:00 2001 From: Dietmar Eggemann Date: Tue, 28 Jun 2005 13:06:23 -0700 Subject: [IPV4]: Snmpv2 Mib IP counter ipInAddrErrors support I followed Thomas' proposal to see every martian destination as a case where the ipInAddrErrors counter has to be incremented. There are two advantages by doing so: (1) The relation between the ipInReceive counter and all the other ipInXXX counters is more accurate in the case the RTN_UNICAST code check fails and (2) it makes the code in ip_route_input_slow easier. Signed-off-by: Dietmar Eggemann Signed-off-by: David S. Miller --- net/ipv4/ip_input.c | 6 +++++- net/ipv4/route.c | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index af2ec88..c703528 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -283,14 +283,18 @@ static inline int ip_rcv_finish(struct sk_buff *skb) { struct net_device *dev = skb->dev; struct iphdr *iph = skb->nh.iph; + int err; /* * Initialise the virtual path cache for the packet. It describes * how the packet travels inside Linux networking. */ if (skb->dst == NULL) { - if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) + if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) { + if (err == -EHOSTUNREACH) + IP_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); goto drop; + } } #ifdef CONFIG_NET_CLS_ROUTE diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 80cf633..12a1cf3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -1909,7 +1909,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, */ if ((err = fib_lookup(&fl, &res)) != 0) { if (!IN_DEV_FORWARD(in_dev)) - goto e_inval; + goto e_hostunreach; goto no_route; } free_res = 1; @@ -1933,7 +1933,7 @@ static int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr, } if (!IN_DEV_FORWARD(in_dev)) - goto e_inval; + goto e_hostunreach; if (res.type != RTN_UNICAST) goto martian_destination; @@ -2025,6 +2025,11 @@ martian_destination: "%u.%u.%u.%u, dev %s\n", NIPQUAD(daddr), NIPQUAD(saddr), dev->name); #endif + +e_hostunreach: + err = -EHOSTUNREACH; + goto done; + e_inval: err = -EINVAL; goto done; -- cgit v1.1 From 7a1af5d7bb94af16b980a53330436b9fadc12435 Mon Sep 17 00:00:00 2001 From: Maxime Bizon Date: Tue, 28 Jun 2005 13:21:12 -0700 Subject: [IPV4]: ipconfig.c: fix dhcp timeout behaviour I think there is a small bug in ipconfig.c in case IPCONFIG_DHCP is set and dhcp is used. When a DHCPOFFER is received, ip address is kept until we get DHCPACK. If no ack is received, ic_dynamic() returns negatively, but leaves the offered ip address in ic_myaddr. This makes the main loop in ip_auto_config() break and uses the maybe incomplete configuration. Not sure if it's the best way to do, but the following trivial patch correct this. Signed-off-by: Maxime Bizon Signed-off-by: David S. Miller --- net/ipv4/ipconfig.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f250903..d2bf8e1 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1149,8 +1149,10 @@ static int __init ic_dynamic(void) ic_rarp_cleanup(); #endif - if (!ic_got_reply) + if (!ic_got_reply) { + ic_myaddr = INADDR_NONE; return -1; + } printk("IP-Config: Got %s answer from %u.%u.%u.%u, ", ((ic_got_reply & IC_RARP) ? "RARP" -- cgit v1.1 From 2f85a42964dd43fed3a339701db046bee5a8b903 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Tue, 28 Jun 2005 13:24:23 -0700 Subject: [SCTP] Make init & delayed sack timeouts configurable by user. Signed-off-by: Vlad Yasevich Signed-off-by: Sridhar Samudrala Signed-off-by: David S. Miller --- include/linux/sysctl.h | 1 + include/net/sctp/constants.h | 18 +++--------------- include/net/sctp/structs.h | 4 ++++ net/sctp/endpointola.c | 13 +++++-------- net/sctp/protocol.c | 5 ++++- net/sctp/sysctl.c | 13 +++++++++++++ net/sctp/transport.c | 1 - 7 files changed, 30 insertions(+), 25 deletions(-) diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index ebfe125..5b5f434 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -641,6 +641,7 @@ enum { NET_SCTP_ADDIP_ENABLE = 13, NET_SCTP_PRSCTP_ENABLE = 14, NET_SCTP_SNDBUF_POLICY = 15, + NET_SCTP_SACK_TIMEOUT = 16, }; /* /proc/sys/net/bridge */ diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 4868c7f..5999e56 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -263,23 +263,11 @@ enum { SCTP_MIN_PMTU = 576 }; enum { SCTP_MAX_DUP_TSNS = 16 }; enum { SCTP_MAX_GABS = 16 }; -/* Here we define the default timers. */ +/* Heartbeat interval - 30 secs */ +#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (30 * HZ) -/* cookie timer def = ? seconds */ -#define SCTP_DEFAULT_TIMEOUT_T1_COOKIE (3 * HZ) - -/* init timer def = 3 seconds */ -#define SCTP_DEFAULT_TIMEOUT_T1_INIT (3 * HZ) - -/* shutdown timer def = 300 ms */ -#define SCTP_DEFAULT_TIMEOUT_T2_SHUTDOWN ((300 * HZ) / 1000) - -/* 0 seconds + RTO */ -#define SCTP_DEFAULT_TIMEOUT_HEARTBEAT (10 * HZ) - -/* recv timer def = 200ms (in usec) */ +/* Delayed sack timer - 200ms */ #define SCTP_DEFAULT_TIMEOUT_SACK ((200 * HZ) / 1000) -#define SCTP_DEFAULT_TIMEOUT_SACK_MAX ((500 * HZ) / 1000) /* 500 ms */ /* RTO.Initial - 3 seconds * RTO.Min - 1 second diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index dfad4d3..47727c7 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -161,6 +161,9 @@ extern struct sctp_globals { */ int sndbuf_policy; + /* Delayed SACK timeout 200ms default*/ + int sack_timeout; + /* HB.interval - 30 seconds */ int hb_interval; @@ -217,6 +220,7 @@ extern struct sctp_globals { #define sctp_sndbuf_policy (sctp_globals.sndbuf_policy) #define sctp_max_retrans_path (sctp_globals.max_retrans_path) #define sctp_max_retrans_init (sctp_globals.max_retrans_init) +#define sctp_sack_timeout (sctp_globals.sack_timeout) #define sctp_hb_interval (sctp_globals.hb_interval) #define sctp_max_instreams (sctp_globals.max_instreams) #define sctp_max_outstreams (sctp_globals.max_outstreams) diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 2ec0320..c44bf41 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -102,9 +102,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, /* Set up the base timeout information. */ ep->timeouts[SCTP_EVENT_TIMEOUT_NONE] = 0; ep->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] = - SCTP_DEFAULT_TIMEOUT_T1_COOKIE; + msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] = - SCTP_DEFAULT_TIMEOUT_T1_INIT; + msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T2_SHUTDOWN] = msecs_to_jiffies(sp->rtoinfo.srto_initial); ep->timeouts[SCTP_EVENT_TIMEOUT_T3_RTX] = 0; @@ -117,12 +117,9 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, ep->timeouts[SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD] = 5 * msecs_to_jiffies(sp->rtoinfo.srto_max); - ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = - SCTP_DEFAULT_TIMEOUT_HEARTBEAT; - ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = - SCTP_DEFAULT_TIMEOUT_SACK; - ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = - sp->autoclose * HZ; + ep->timeouts[SCTP_EVENT_TIMEOUT_HEARTBEAT] = 0; + ep->timeouts[SCTP_EVENT_TIMEOUT_SACK] = sctp_sack_timeout; + ep->timeouts[SCTP_EVENT_TIMEOUT_AUTOCLOSE] = sp->autoclose * HZ; /* Use SCTP specific send buffer space queues. */ ep->sndbuf_policy = sctp_sndbuf_policy; diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 5135e1a..e7f37fa 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c @@ -1050,7 +1050,10 @@ SCTP_STATIC __init int sctp_init(void) sctp_sndbuf_policy = 0; /* HB.interval - 30 seconds */ - sctp_hb_interval = 30 * HZ; + sctp_hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; + + /* delayed SACK timeout */ + sctp_sack_timeout = SCTP_DEFAULT_TIMEOUT_SACK; /* Implementation specific variables. */ diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c index 7fc3184..dc48934 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c @@ -47,6 +47,8 @@ static ctl_handler sctp_sysctl_jiffies_ms; static long rto_timer_min = 1; static long rto_timer_max = 86400000; /* One day */ +static long sack_timer_min = 1; +static long sack_timer_max = 500; static ctl_table sctp_table[] = { { @@ -187,6 +189,17 @@ static ctl_table sctp_table[] = { .mode = 0644, .proc_handler = &proc_dointvec }, + { + .ctl_name = NET_SCTP_SACK_TIMEOUT, + .procname = "sack_timeout", + .data = &sctp_sack_timeout, + .maxlen = sizeof(long), + .mode = 0644, + .proc_handler = &proc_doulongvec_ms_jiffies_minmax, + .strategy = &sctp_sysctl_jiffies_ms, + .extra1 = &sack_timer_min, + .extra2 = &sack_timer_max, + }, { .ctl_name = 0 } }; diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 0ec0fde..a63b691 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -103,7 +103,6 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, /* Set up the heartbeat timer. */ init_timer(&peer->hb_timer); - peer->hb_interval = SCTP_DEFAULT_TIMEOUT_HEARTBEAT; peer->hb_timer.function = sctp_generate_heartbeat_event; peer->hb_timer.data = (unsigned long)peer; -- cgit v1.1 From 50273978975ee62938b7ca612e281927cd789c13 Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 28 Jun 2005 22:42:06 +0100 Subject: [PATCH] ARM: 2763/1: S3C24XX - mark IRQ_LCD as valid Patch from Ben Dooks Fix the IRQ_LCD so that it is marked as valid since we no longer de-mux this in the main IRQ handler. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/irq.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c index b668c48..cf9f46d 100644 --- a/arch/arm/mach-s3c2410/irq.c +++ b/arch/arm/mach-s3c2410/irq.c @@ -40,8 +40,11 @@ * 04-Nov-2004 Ben Dooks * Fix standard IRQ wake for EINT0..4 and RTC * - * 22-Feb-2004 Ben Dooks + * 22-Feb-2005 Ben Dooks * Fixed edge-triggering on ADC IRQ + * + * 28-Jun-2005 Ben Dooks + * Mark IRQ_LCD valid */ #include @@ -366,7 +369,6 @@ static struct irqchip s3c_irq_eint0t4 = { #define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0)) #define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0)) #define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0)) -#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0)) static inline void s3c_irqsub_mask(unsigned int irqno, unsigned int parentbit, @@ -716,7 +718,6 @@ void __init s3c24xx_init_irq(void) case IRQ_UART0: case IRQ_UART1: case IRQ_UART2: - case IRQ_LCD: case IRQ_ADCPARENT: set_irq_chip(irqno, &s3c_irq_level_chip); set_irq_handler(irqno, do_level_IRQ); -- cgit v1.1 From 97afa0a25afb43a82954662773a9d48d61b2996a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Mon, 27 Jun 2005 22:29:31 -0700 Subject: [PATCH] cciss_ioctl() warning fix Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/cciss.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 653512b..3e9fb6e 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -786,7 +786,6 @@ static int cciss_ioctl(struct inode *inode, struct file *filep, case CCISS_GETLUNINFO: { LogvolInfo_struct luninfo; - int i; luninfo.LunID = drv->LunID; luninfo.num_opens = drv->usage_count; -- cgit v1.1 From 314b6a4d80a7a5217c86ffdca926b6f406da0e0e Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 27 Jun 2005 22:29:33 -0700 Subject: [PATCH] kexec: fix sparse warnings Signed-off-by: Alexey Dobriyan Cc: Eric Biederman Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/kexec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kernel/kexec.c b/kernel/kexec.c index 7843548..cdd4dcd 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -241,7 +241,7 @@ static int kimage_normal_alloc(struct kimage **rimage, unsigned long entry, static int kimage_crash_alloc(struct kimage **rimage, unsigned long entry, unsigned long nr_segments, - struct kexec_segment *segments) + struct kexec_segment __user *segments) { int result; struct kimage *image; @@ -650,7 +650,7 @@ static kimage_entry_t *kimage_dst_used(struct kimage *image, } } - return 0; + return NULL; } static struct page *kimage_alloc_page(struct kimage *image, @@ -696,7 +696,7 @@ static struct page *kimage_alloc_page(struct kimage *image, /* Allocate a page, if we run out of memory give up */ page = kimage_alloc_pages(gfp_mask, 0); if (!page) - return 0; + return NULL; /* If the page cannot be used file it away */ if (page_to_pfn(page) > (KEXEC_SOURCE_MEMORY_LIMIT >> PAGE_SHIFT)) { @@ -754,7 +754,7 @@ static int kimage_load_normal_segment(struct kimage *image, unsigned long maddr; unsigned long ubytes, mbytes; int result; - unsigned char *buf; + unsigned char __user *buf; result = 0; buf = segment->buf; @@ -818,7 +818,7 @@ static int kimage_load_crash_segment(struct kimage *image, unsigned long maddr; unsigned long ubytes, mbytes; int result; - unsigned char *buf; + unsigned char __user *buf; result = 0; buf = segment->buf; -- cgit v1.1 From f8b58edf3acf0dcc186b8330939000ecf709368a Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Mon, 27 Jun 2005 22:29:34 -0700 Subject: [PATCH] md: bio leak fix insert a missing bio_put when writting the md superblock. Without this we have a steady growth in the "bio" slab. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/md.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/md/md.c b/drivers/md/md.c index 3802f7a..4a0c57d 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -338,6 +338,7 @@ static int super_written(struct bio *bio, unsigned int bytes_done, int error) if (atomic_dec_and_test(&rdev->mddev->pending_writes)) wake_up(&rdev->mddev->sb_wait); + bio_put(bio); return 0; } -- cgit v1.1 From 082cf69eb82681f4eacb3a5653834c7970714bef Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 28 Jun 2005 16:35:11 +0200 Subject: [PATCH] ll_rw_blk: prevent huge request allocations Currently we cap request allocations at q->nr_requests, but we allow a batching io context to allocate up to 32 more (default setting). This can flood the queue with request allocations, with only a few batching processes. The real fix would be to limit the number of batchers, but as that isn't currently tracked, I suggest we just cap the maximum number of allocated requests to eg 50% over the limit. This was observed in real life, users typically see this as vmstat bo numbers going off the wall with seconds of no queueing afterwards. Behaviour this bursty is not beneficial. Signed-off-by: Jens Axboe Signed-off-by: Linus Torvalds --- drivers/block/ll_rw_blk.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 234fdcf..6c98cf0 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1912,6 +1912,15 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, } get_rq: + /* + * Only allow batching queuers to allocate up to 50% over the defined + * limit of requests, otherwise we could have thousands of requests + * allocated with any setting of ->nr_requests + */ + if (rl->count[rw] >= (3 * q->nr_requests / 2)) { + spin_unlock_irq(q->queue_lock); + goto out; + } rl->count[rw]++; rl->starved[rw] = 0; if (rl->count[rw] >= queue_congestion_on_threshold(q)) -- cgit v1.1 From f340c0d1a3f40fdcba69cd291530a4debc58748f Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 28 Jun 2005 16:40:42 +0200 Subject: [PATCH] Tweak idle thread setup semantics This patch tweaks idle thread setup semantics a bit: instead of setting NEED_RESCHED in init_idle(), we do an explicit schedule() before calling into cpu_idle(). This patch, while having no negative side-effects, enables wider use of cond_resched()s. (which might happen in the stock kernel too, but it's particulary important for voluntary-preempt) Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/main.c | 7 +++++++ kernel/sched.c | 9 ++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/init/main.c b/init/main.c index d324801..b5e421e 100644 --- a/init/main.c +++ b/init/main.c @@ -383,6 +383,13 @@ static void noinline rest_init(void) numa_default_policy(); unlock_kernel(); preempt_enable_no_resched(); + + /* + * The boot idle thread must execute schedule() + * at least one to get things moving: + */ + schedule(); + cpu_idle(); } diff --git a/kernel/sched.c b/kernel/sched.c index e2b0d3e..5f2182d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -4166,6 +4166,14 @@ void show_state(void) read_unlock(&tasklist_lock); } +/** + * init_idle - set up an idle thread for a given CPU + * @idle: task in question + * @cpu: cpu the idle task belongs to + * + * NOTE: this function does not set the idle thread's NEED_RESCHED + * flag, to make booting more robust. + */ void __devinit init_idle(task_t *idle, int cpu) { runqueue_t *rq = cpu_rq(cpu); @@ -4183,7 +4191,6 @@ void __devinit init_idle(task_t *idle, int cpu) #if defined(CONFIG_SMP) && defined(__ARCH_WANT_UNLOCKED_CTXSW) idle->oncpu = 1; #endif - set_tsk_need_resched(idle); spin_unlock_irqrestore(&rq->lock, flags); /* Set the preempt count _outside_ the spinlocks! */ -- cgit v1.1 From f835e471b557c45d2e5701ea5215f6e739b4eb39 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Tue, 28 Jun 2005 15:00:39 -0700 Subject: [IPV4]: Broken memory allocation in fib_trie This should help up the insertion... but the resize is more crucial. and complex and needs some thinking. Signed-off-by: Robert Olsson Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 56 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 0671569..b56e88e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -43,7 +43,7 @@ * 2 of the License, or (at your option) any later version. */ -#define VERSION "0.323" +#define VERSION "0.324" #include #include @@ -341,8 +341,10 @@ static struct leaf *leaf_new(void) static struct leaf_info *leaf_info_new(int plen) { struct leaf_info *li = kmalloc(sizeof(struct leaf_info), GFP_KERNEL); - li->plen = plen; - INIT_LIST_HEAD(&li->falh); + if(li) { + li->plen = plen; + INIT_LIST_HEAD(&li->falh); + } return li; } @@ -879,8 +881,8 @@ static struct node *trie_rebalance(struct trie *t, struct tnode *tn) return (struct node*) tn; } -static struct list_head * -fib_insert_node(struct trie *t, u32 key, int plen) +static struct list_head * +fib_insert_node(struct trie *t, int *err, u32 key, int plen) { int pos, newpos; struct tnode *tp = NULL, *tn = NULL; @@ -940,7 +942,6 @@ fib_insert_node(struct trie *t, u32 key, int plen) if(tp && IS_LEAF(tp)) BUG(); - t->revision++; /* Case 1: n is a leaf. Compare prefixes */ @@ -949,8 +950,10 @@ fib_insert_node(struct trie *t, u32 key, int plen) li = leaf_info_new(plen); - if(! li) - BUG(); + if(! li) { + *err = -ENOMEM; + goto err; + } fa_head = &li->falh; insert_leaf_info(&l->list, li); @@ -959,14 +962,19 @@ fib_insert_node(struct trie *t, u32 key, int plen) t->size++; l = leaf_new(); - if(! l) - BUG(); + if(! l) { + *err = -ENOMEM; + goto err; + } l->key = key; li = leaf_info_new(plen); - if(! li) - BUG(); + if(! li) { + tnode_free((struct tnode *) l); + *err = -ENOMEM; + goto err; + } fa_head = &li->falh; insert_leaf_info(&l->list, li); @@ -1003,9 +1011,14 @@ fib_insert_node(struct trie *t, u32 key, int plen) newpos = 0; tn = tnode_new(key, newpos, 1); /* First tnode */ } - if(!tn) - trie_bug("tnode_pfx_new failed"); + if(!tn) { + free_leaf_info(li); + tnode_free((struct tnode *) l); + *err = -ENOMEM; + goto err; + } + NODE_SET_PARENT(tn, tp); missbit=tkey_extract_bits(key, newpos, 1); @@ -1027,7 +1040,9 @@ fib_insert_node(struct trie *t, u32 key, int plen) } /* Rebalance the trie */ t->trie = trie_rebalance(t, tp); -done:; +done: + t->revision++; +err:; return fa_head; } @@ -1156,8 +1171,12 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, * Insert new entry to the list. */ - if(!fa_head) - fa_head = fib_insert_node(t, key, plen); + if(!fa_head) { + fa_head = fib_insert_node(t, &err, key, plen); + err = 0; + if(err) + goto out_free_new_fa; + } write_lock_bh(&fib_lock); @@ -1170,6 +1189,9 @@ fn_trie_insert(struct fib_table *tb, struct rtmsg *r, struct kern_rta *rta, rtmsg_fib(RTM_NEWROUTE, htonl(key), new_fa, plen, tb->tb_id, nlhdr, req); succeeded: return 0; + +out_free_new_fa: + kmem_cache_free(fn_alias_kmem, new_fa); out: fib_release_info(fi); err:; -- cgit v1.1 From 689be43945e9ca7dd704522e55af1b8a73a994d3 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Jun 2005 15:25:31 -0700 Subject: [NET]: Remove gratuitous use of skb->tail in network drivers. Many drivers use skb->tail unnecessarily. In these situations, the code roughly looks like: dev = dev_alloc_skb(...); [optional] skb_reserve(skb, ...); ... skb->tail ... But even if the skb_reserve() happens, skb->data equals skb->tail. So it doesn't make any sense to use anything other than skb->data in these cases. Another case was the s2io.c driver directly mucking with the skb->data and skb->tail pointers. It really just wanted to do an skb_reserve(), so that's what the code was changed to do instead. Another reason I'm making this change as it allows some SKB cleanups I have planned simpler to merge. In those cleanups, skb->head, skb->tail, and skb->end pointers are removed, and replaced with skb->head_room and skb->tail_room integers. Signed-off-by: David S. Miller Acked-by: Jeff Garzik --- drivers/net/3c515.c | 4 ++-- drivers/net/3c59x.c | 6 +++--- drivers/net/8139cp.c | 4 ++-- drivers/net/82596.c | 14 +++++++------- drivers/net/dl2k.c | 8 ++++---- drivers/net/eepro100.c | 8 ++++---- drivers/net/epic100.c | 6 +++--- drivers/net/fealnx.c | 8 ++++---- drivers/net/hamachi.c | 12 ++++++------ drivers/net/lance.c | 2 +- drivers/net/lasi_82596.c | 8 ++++---- drivers/net/natsemi.c | 4 ++-- drivers/net/ns83820.c | 4 ++-- drivers/net/pcnet32.c | 6 +++--- drivers/net/r8169.c | 4 ++-- drivers/net/s2io.c | 8 +++----- drivers/net/sb1250-mac.c | 4 ++-- drivers/net/sis900.c | 6 +++--- drivers/net/starfire.c | 6 +++--- drivers/net/sundance.c | 6 +++--- drivers/net/tulip/de2104x.c | 6 +++--- drivers/net/tulip/dmfe.c | 10 +++++----- drivers/net/tulip/interrupt.c | 10 +++++----- drivers/net/tulip/tulip_core.c | 2 +- drivers/net/tulip/winbond-840.c | 6 +++--- drivers/net/tulip/xircom_tulip_cb.c | 4 ++-- drivers/net/typhoon.c | 4 ++-- drivers/net/via-rhine.c | 6 +++--- drivers/net/via-velocity.c | 6 +++--- drivers/net/wan/hdlc_cisco.c | 2 +- drivers/net/yellowfin.c | 8 ++++---- 31 files changed, 95 insertions(+), 97 deletions(-) diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c index d272ea3..91d1c4c 100644 --- a/drivers/net/3c515.c +++ b/drivers/net/3c515.c @@ -822,7 +822,7 @@ static int corkscrew_open(struct net_device *dev) break; /* Bad news! */ skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[i].addr = isa_virt_to_bus(skb->tail); + vp->rx_ring[i].addr = isa_virt_to_bus(skb->data); } vp->rx_ring[i - 1].next = isa_virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */ outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr); @@ -1406,7 +1406,7 @@ static int boomerang_rx(struct net_device *dev) break; /* Bad news! */ skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[entry].addr = isa_virt_to_bus(skb->tail); + vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data); vp->rx_skbuff[entry] = skb; } vp->rx_ring[entry].status = 0; /* Clear complete bit. */ diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 80ec9aa..07746b9 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -1802,7 +1802,7 @@ vortex_open(struct net_device *dev) break; /* Bad news! */ skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); + vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); } if (i != RX_RING_SIZE) { int j; @@ -2632,7 +2632,7 @@ boomerang_rx(struct net_device *dev) pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); /* 'skb_put()' points to the start of sk_buff data area. */ memcpy(skb_put(skb, pkt_len), - vp->rx_skbuff[entry]->tail, + vp->rx_skbuff[entry]->data, pkt_len); pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); vp->rx_copy++; @@ -2678,7 +2678,7 @@ boomerang_rx(struct net_device *dev) } skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ - vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->tail, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); + vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE)); vp->rx_skbuff[entry] = skb; } vp->rx_ring[entry].status = 0; /* Clear complete bit. */ diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index e4b3c5c..7b293f0 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c @@ -596,7 +596,7 @@ rx_status_loop: mapping = cp->rx_skb[rx_tail].mapping = - pci_map_single(cp->pdev, new_skb->tail, + pci_map_single(cp->pdev, new_skb->data, buflen, PCI_DMA_FROMDEVICE); cp->rx_skb[rx_tail].skb = new_skb; @@ -1101,7 +1101,7 @@ static int cp_refill_rx (struct cp_private *cp) skb_reserve(skb, RX_OFFSET); cp->rx_skb[i].mapping = pci_map_single(cp->pdev, - skb->tail, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, cp->rx_buf_sz, PCI_DMA_FROMDEVICE); cp->rx_skb[i].skb = skb; cp->rx_ring[i].opts2 = 0; diff --git a/drivers/net/82596.c b/drivers/net/82596.c index 65f97b1..13b745b 100644 --- a/drivers/net/82596.c +++ b/drivers/net/82596.c @@ -546,11 +546,11 @@ static inline void init_rx_bufs(struct net_device *dev) rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1)); rbd->b_addr = WSWAPrbd(virt_to_bus(rbd)); rbd->skb = skb; - rbd->v_data = skb->tail; - rbd->b_data = WSWAPchar(virt_to_bus(skb->tail)); + rbd->v_data = skb->data; + rbd->b_data = WSWAPchar(virt_to_bus(skb->data)); rbd->size = PKT_BUF_SZ; #ifdef __mc68000__ - cache_clear(virt_to_phys(skb->tail), PKT_BUF_SZ); + cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ); #endif } lp->rbd_head = lp->rbds; @@ -816,10 +816,10 @@ static inline int i596_rx(struct net_device *dev) rx_in_place = 1; rbd->skb = newskb; newskb->dev = dev; - rbd->v_data = newskb->tail; - rbd->b_data = WSWAPchar(virt_to_bus(newskb->tail)); + rbd->v_data = newskb->data; + rbd->b_data = WSWAPchar(virt_to_bus(newskb->data)); #ifdef __mc68000__ - cache_clear(virt_to_phys(newskb->tail), PKT_BUF_SZ); + cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ); #endif } else @@ -840,7 +840,7 @@ memory_squeeze: skb->protocol=eth_type_trans(skb,dev); skb->len = pkt_len; #ifdef __mc68000__ - cache_clear(virt_to_phys(rbd->skb->tail), + cache_clear(virt_to_phys(rbd->skb->data), pkt_len); #endif netif_rx(skb); diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c index aa42b7a..430c628 100644 --- a/drivers/net/dl2k.c +++ b/drivers/net/dl2k.c @@ -547,7 +547,7 @@ rio_timer (unsigned long data) skb_reserve (skb, 2); np->rx_ring[entry].fraginfo = cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + (np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= @@ -618,7 +618,7 @@ alloc_list (struct net_device *dev) /* Rubicon now supports 40 bits of addressing space. */ np->rx_ring[i].fraginfo = cpu_to_le64 ( pci_map_single ( - np->pdev, skb->tail, np->rx_buf_sz, + np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); np->rx_ring[i].fraginfo |= cpu_to_le64 (np->rx_buf_sz) << 48; } @@ -906,7 +906,7 @@ receive_packet (struct net_device *dev) /* 16 byte align the IP header */ skb_reserve (skb, 2); eth_copy_and_sum (skb, - np->rx_skbuff[entry]->tail, + np->rx_skbuff[entry]->data, pkt_len, 0); skb_put (skb, pkt_len); pci_dma_sync_single_for_device(np->pdev, @@ -950,7 +950,7 @@ receive_packet (struct net_device *dev) skb_reserve (skb, 2); np->rx_ring[entry].fraginfo = cpu_to_le64 (pci_map_single - (np->pdev, skb->tail, np->rx_buf_sz, + (np->pdev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } np->rx_ring[entry].fraginfo |= diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 98b3a2f..1795425 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -1269,7 +1269,7 @@ speedo_init_rx_ring(struct net_device *dev) if (skb == NULL) break; /* OK. Just initially short of Rx bufs. */ skb->dev = dev; /* Mark as being used by this device. */ - rxf = (struct RxFD *)skb->tail; + rxf = (struct RxFD *)skb->data; sp->rx_ringp[i] = rxf; sp->rx_ring_dma[i] = pci_map_single(sp->pdev, rxf, @@ -1661,7 +1661,7 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) sp->rx_ringp[entry] = NULL; return NULL; } - rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail; + rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->data; sp->rx_ring_dma[entry] = pci_map_single(sp->pdev, rxf, PKT_BUF_SZ + sizeof(struct RxFD), PCI_DMA_FROMDEVICE); @@ -1808,10 +1808,10 @@ speedo_rx(struct net_device *dev) #if 1 || USE_IP_CSUM /* Packet is in one chunk -- we can copy + cksum. */ - eth_copy_and_sum(skb, sp->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, sp->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); #else - memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->tail, + memcpy(skb_put(skb, pkt_len), sp->rx_skbuff[entry]->data, pkt_len); #endif pci_dma_sync_single_for_device(sp->pdev, sp->rx_ring_dma[entry], diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index 81ebaed..87f5227 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c @@ -1003,7 +1003,7 @@ static void epic_init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ ep->rx_ring[i].bufaddr = pci_map_single(ep->pci_dev, - skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); ep->rx_ring[i].rxstatus = cpu_to_le32(DescOwn); } ep->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1274,7 +1274,7 @@ static int epic_rx(struct net_device *dev, int budget) ep->rx_ring[entry].bufaddr, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, ep->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, ep->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(ep->pci_dev, ep->rx_ring[entry].bufaddr, @@ -1308,7 +1308,7 @@ static int epic_rx(struct net_device *dev, int budget) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ ep->rx_ring[entry].bufaddr = pci_map_single(ep->pci_dev, - skb->tail, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, ep->rx_buf_sz, PCI_DMA_FROMDEVICE); work_done++; } ep->rx_ring[entry].rxstatus = cpu_to_le32(DescOwn); diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c index 9e0303f..55dbe9a 100644 --- a/drivers/net/fealnx.c +++ b/drivers/net/fealnx.c @@ -1107,7 +1107,7 @@ static void allocate_rx_buffers(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ np->lack_rxbuf->skbuff = skb; - np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->tail, + np->lack_rxbuf->buffer = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); np->lack_rxbuf->status = RXOWN; ++np->really_rx_count; @@ -1300,7 +1300,7 @@ static void init_ring(struct net_device *dev) ++np->really_rx_count; np->rx_ring[i].skbuff = skb; skb->dev = dev; /* Mark as being used by this device. */ - np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->tail, + np->rx_ring[i].buffer = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); np->rx_ring[i].status = RXOWN; np->rx_ring[i].control |= RXIC; @@ -1737,11 +1737,11 @@ static int netdev_rx(struct net_device *dev) #if ! defined(__alpha__) eth_copy_and_sum(skb, - np->cur_rx->skbuff->tail, pkt_len, 0); + np->cur_rx->skbuff->data, pkt_len, 0); skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), - np->cur_rx->skbuff->tail, pkt_len); + np->cur_rx->skbuff->data, pkt_len); #endif pci_dma_sync_single_for_device(np->pci_dev, np->cur_rx->buffer, diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 3d96714..d9df1d9 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c @@ -1149,7 +1149,7 @@ static void hamachi_tx_timeout(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, - skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | DescEndPacket | DescIntr | (hmp->rx_buf_sz - 2)); } @@ -1210,7 +1210,7 @@ static void hamachi_init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ hmp->rx_ring[i].addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, - skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); /* -2 because it doesn't REALLY have that first 2 bytes -KDU */ hmp->rx_ring[i].status_n_length = cpu_to_le32(DescOwn | DescEndPacket | DescIntr | (hmp->rx_buf_sz -2)); @@ -1509,7 +1509,7 @@ static int hamachi_rx(struct net_device *dev) desc->addr, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE); - buf_addr = (u8 *) hmp->rx_skbuff[entry]->tail; + buf_addr = (u8 *) hmp->rx_skbuff[entry]->data; frame_status = le32_to_cpu(get_unaligned((s32*)&(buf_addr[data_size - 12]))); if (hamachi_debug > 4) printk(KERN_DEBUG " hamachi_rx() status was %8.8x.\n", @@ -1678,7 +1678,7 @@ static int hamachi_rx(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ desc->addr = cpu_to_leXX(pci_map_single(hmp->pci_dev, - skb->tail, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, hmp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } desc->status_n_length = cpu_to_le32(hmp->rx_buf_sz); if (entry >= RX_RING_SIZE-1) @@ -1772,9 +1772,9 @@ static int hamachi_close(struct net_device *dev) readl(ioaddr + RxCurPtr) == (long)&hmp->rx_ring[i] ? '>' : ' ', i, hmp->rx_ring[i].status_n_length, hmp->rx_ring[i].addr); if (hamachi_debug > 6) { - if (*(u8*)hmp->rx_skbuff[i]->tail != 0x69) { + if (*(u8*)hmp->rx_skbuff[i]->data != 0x69) { u16 *addr = (u16 *) - hmp->rx_skbuff[i]->tail; + hmp->rx_skbuff[i]->data; int j; for (j = 0; j < 0x50; j++) diff --git a/drivers/net/lance.c b/drivers/net/lance.c index ca90f0d..b4929be 100644 --- a/drivers/net/lance.c +++ b/drivers/net/lance.c @@ -862,7 +862,7 @@ lance_init_ring(struct net_device *dev, int gfp) lp->rx_skbuff[i] = skb; if (skb) { skb->dev = dev; - rx_buff = skb->tail; + rx_buff = skb->data; } else rx_buff = kmalloc(PKT_BUF_SZ, GFP_DMA | gfp); if (rx_buff == NULL) diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 5e263fc..41bad07 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -553,14 +553,14 @@ static inline void init_rx_bufs(struct net_device *dev) if (skb == NULL) panic("%s: alloc_skb() failed", __FILE__); skb_reserve(skb, 2); - dma_addr = dma_map_single(lp->dev, skb->tail,PKT_BUF_SZ, + dma_addr = dma_map_single(lp->dev, skb->data,PKT_BUF_SZ, DMA_FROM_DEVICE); skb->dev = dev; rbd->v_next = rbd+1; rbd->b_next = WSWAPrbd(virt_to_dma(lp,rbd+1)); rbd->b_addr = WSWAPrbd(virt_to_dma(lp,rbd)); rbd->skb = skb; - rbd->v_data = skb->tail; + rbd->v_data = skb->data; rbd->b_data = WSWAPchar(dma_addr); rbd->size = PKT_BUF_SZ; } @@ -783,8 +783,8 @@ static inline int i596_rx(struct net_device *dev) rx_in_place = 1; rbd->skb = newskb; newskb->dev = dev; - dma_addr = dma_map_single(lp->dev, newskb->tail, PKT_BUF_SZ, DMA_FROM_DEVICE); - rbd->v_data = newskb->tail; + dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE); + rbd->v_data = newskb->data; rbd->b_data = WSWAPchar(dma_addr); CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); } diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index babb59e..9d6d254 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -1926,7 +1926,7 @@ static void refill_rx(struct net_device *dev) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ np->rx_dma[entry] = pci_map_single(np->pci_dev, - skb->tail, buflen, PCI_DMA_FROMDEVICE); + skb->data, buflen, PCI_DMA_FROMDEVICE); np->rx_ring[entry].addr = cpu_to_le32(np->rx_dma[entry]); } np->rx_ring[entry].cmd_status = cpu_to_le32(np->rx_buf_sz); @@ -2280,7 +2280,7 @@ static void netdev_rx(struct net_device *dev) buflen, PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, - np->rx_skbuff[entry]->tail, pkt_len, 0); + np->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(np->pci_dev, np->rx_dma[entry], diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c index cc796527..e64df4d 100644 --- a/drivers/net/ns83820.c +++ b/drivers/net/ns83820.c @@ -574,7 +574,7 @@ static inline int ns83820_add_rx_skb(struct ns83820 *dev, struct sk_buff *skb) dev->rx_info.next_empty = (next_empty + 1) % NR_RX_DESC; cmdsts = REAL_RX_BUF_SIZE | CMDSTS_INTR; - buf = pci_map_single(dev->pci_dev, skb->tail, + buf = pci_map_single(dev->pci_dev, skb->data, REAL_RX_BUF_SIZE, PCI_DMA_FROMDEVICE); build_rx_desc(dev, sg, 0, buf, cmdsts, 0); /* update link of previous rx */ @@ -604,7 +604,7 @@ static inline int rx_refill(struct net_device *ndev, int gfp) if (unlikely(!skb)) break; - res = (long)skb->tail & 0xf; + res = (long)skb->data & 0xf; res = 0x10 - res; res &= 0xf; skb_reserve(skb, res); diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c index 3213f3e..113b680 100644 --- a/drivers/net/pcnet32.c +++ b/drivers/net/pcnet32.c @@ -1602,7 +1602,7 @@ pcnet32_init_ring(struct net_device *dev) rmb(); if (lp->rx_dma_addr[i] == 0) - lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, + lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->data, PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); lp->rx_ring[i].buf_length = le16_to_cpu(2-PKT_BUF_SZ); @@ -1983,7 +1983,7 @@ pcnet32_rx(struct net_device *dev) lp->rx_skbuff[entry] = newskb; newskb->dev = dev; lp->rx_dma_addr[entry] = - pci_map_single(lp->pci_dev, newskb->tail, + pci_map_single(lp->pci_dev, newskb->data, PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); lp->rx_ring[entry].base = le32_to_cpu(lp->rx_dma_addr[entry]); rx_in_place = 1; @@ -2020,7 +2020,7 @@ pcnet32_rx(struct net_device *dev) PKT_BUF_SZ-2, PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, - (unsigned char *)(lp->rx_skbuff[entry]->tail), + (unsigned char *)(lp->rx_skbuff[entry]->data), pkt_len,0); pci_dma_sync_single_for_device(lp->pci_dev, lp->rx_dma_addr[entry], diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index ce449fe..d5afe05 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c @@ -1876,7 +1876,7 @@ static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff, skb_reserve(skb, NET_IP_ALIGN); *sk_buff = skb; - mapping = pci_map_single(pdev, skb->tail, rx_buf_sz, + mapping = pci_map_single(pdev, skb->data, rx_buf_sz, PCI_DMA_FROMDEVICE); rtl8169_map_to_asic(desc, mapping, rx_buf_sz); @@ -2336,7 +2336,7 @@ static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size, skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN); if (skb) { skb_reserve(skb, NET_IP_ALIGN); - eth_copy_and_sum(skb, sk_buff[0]->tail, pkt_size, 0); + eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0); *sk_buff = skb; rtl8169_mark_to_asic(desc, rx_buf_sz); ret = 0; diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index bb639a8..ea638b1 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -1699,11 +1699,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) #else ba = &nic->ba[ring_no][block_no][off]; skb_reserve(skb, BUF0_LEN); - tmp = (unsigned long) skb->data; - tmp += ALIGN_SIZE; - tmp &= ~ALIGN_SIZE; - skb->data = (void *) tmp; - skb->tail = (void *) tmp; + tmp = ((unsigned long) skb->data & ALIGN_SIZE); + if (tmp) + skb_reserve(skb, (ALIGN_SIZE + 1) - tmp); memset(rxdp, 0, sizeof(RxD_t)); rxdp->Buffer2_ptr = pci_map_single diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c index fd2e7c3..7abd55a 100644 --- a/drivers/net/sb1250-mac.c +++ b/drivers/net/sb1250-mac.c @@ -963,11 +963,11 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb) /* * Do not interrupt per DMA transfer. */ - dsc->dscr_a = virt_to_phys(sb_new->tail) | + dsc->dscr_a = virt_to_phys(sb_new->data) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0; #else - dsc->dscr_a = virt_to_phys(sb_new->tail) | + dsc->dscr_a = virt_to_phys(sb_new->data) | V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | M_DMA_DSCRA_INTERRUPT; #endif diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 127324f..23b713c 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -1154,7 +1154,7 @@ sis900_init_rx_ring(struct net_device *net_dev) sis_priv->rx_skbuff[i] = skb; sis_priv->rx_ring[i].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[i].bufptr = pci_map_single(sis_priv->pci_dev, - skb->tail, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); + skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); } sis_priv->dirty_rx = (unsigned int) (i - NUM_RX_DESC); @@ -1776,7 +1776,7 @@ static int sis900_rx(struct net_device *net_dev) sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[entry].bufptr = - pci_map_single(sis_priv->pci_dev, skb->tail, + pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); sis_priv->dirty_rx++; } @@ -1809,7 +1809,7 @@ static int sis900_rx(struct net_device *net_dev) sis_priv->rx_skbuff[entry] = skb; sis_priv->rx_ring[entry].cmdsts = RX_BUF_SIZE; sis_priv->rx_ring[entry].bufptr = - pci_map_single(sis_priv->pci_dev, skb->tail, + pci_map_single(sis_priv->pci_dev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); } } diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 12e2b68..88b89dc 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c @@ -1286,7 +1286,7 @@ static void init_ring(struct net_device *dev) np->rx_info[i].skb = skb; if (skb == NULL) break; - np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); + np->rx_info[i].mapping = pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ /* Grrr, we cannot offset to correctly align the IP header. */ np->rx_ring[i].rxaddr = cpu_to_dma(np->rx_info[i].mapping | RxDescValid); @@ -1572,7 +1572,7 @@ static int __netdev_rx(struct net_device *dev, int *quota) pci_dma_sync_single_for_cpu(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_info[entry].skb->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_info[entry].skb->data, pkt_len, 0); pci_dma_sync_single_for_device(np->pci_dev, np->rx_info[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); @@ -1696,7 +1696,7 @@ static void refill_rx_ring(struct net_device *dev) if (skb == NULL) break; /* Better luck next round. */ np->rx_info[entry].mapping = - pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, PCI_DMA_FROMDEVICE); + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE); skb->dev = dev; /* Mark as being used by this device. */ np->rx_ring[entry].rxaddr = cpu_to_dma(np->rx_info[entry].mapping | RxDescValid); diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 08cb717..d500a57 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c @@ -1028,7 +1028,7 @@ static void init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ np->rx_ring[i].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->tail, np->rx_buf_sz, + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); np->rx_ring[i].frag[0].length = cpu_to_le32(np->rx_buf_sz | LastFrag); } @@ -1341,7 +1341,7 @@ static void rx_poll(unsigned long data) np->rx_buf_sz, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0); pci_dma_sync_single_for_device(np->pci_dev, desc->frag[0].addr, np->rx_buf_sz, @@ -1400,7 +1400,7 @@ static void refill_rx (struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ np->rx_ring[entry].frag[0].addr = cpu_to_le32( - pci_map_single(np->pci_dev, skb->tail, + pci_map_single(np->pci_dev, skb->data, np->rx_buf_sz, PCI_DMA_FROMDEVICE)); } /* Perhaps we need not reset this field. */ diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c index dd357dd..fc353e3 100644 --- a/drivers/net/tulip/de2104x.c +++ b/drivers/net/tulip/de2104x.c @@ -446,13 +446,13 @@ static void de_rx (struct de_private *de) mapping = de->rx_skb[rx_tail].mapping = - pci_map_single(de->pdev, copy_skb->tail, + pci_map_single(de->pdev, copy_skb->data, buflen, PCI_DMA_FROMDEVICE); de->rx_skb[rx_tail].skb = copy_skb; } else { pci_dma_sync_single_for_cpu(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); skb_reserve(copy_skb, RX_OFFSET); - memcpy(skb_put(copy_skb, len), skb->tail, len); + memcpy(skb_put(copy_skb, len), skb->data, len); pci_dma_sync_single_for_device(de->pdev, mapping, len, PCI_DMA_FROMDEVICE); @@ -1269,7 +1269,7 @@ static int de_refill_rx (struct de_private *de) skb->dev = de->dev; de->rx_skb[i].mapping = pci_map_single(de->pdev, - skb->tail, de->rx_buf_sz, PCI_DMA_FROMDEVICE); + skb->data, de->rx_buf_sz, PCI_DMA_FROMDEVICE); de->rx_skb[i].skb = skb; de->rx_ring[i].opts1 = cpu_to_le32(DescOwn); diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 7b89970..74e9075 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c @@ -945,8 +945,8 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) /* Received Packet CRC check need or not */ if ( (db->dm910x_chk_mode & 1) && - (cal_CRC(skb->tail, rxlen, 1) != - (*(u32 *) (skb->tail+rxlen) ))) { /* FIXME (?) */ + (cal_CRC(skb->data, rxlen, 1) != + (*(u32 *) (skb->data+rxlen) ))) { /* FIXME (?) */ /* Found a error received packet */ dmfe_reuse_skb(db, rxptr->rx_skb_ptr); db->dm910x_chk_mode = 3; @@ -959,7 +959,7 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) /* size less than COPY_SIZE, allocate a rxlen SKB */ skb->dev = dev; skb_reserve(skb, 2); /* 16byte align */ - memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->tail, rxlen); + memcpy(skb_put(skb, rxlen), rxptr->rx_skb_ptr->data, rxlen); dmfe_reuse_skb(db, rxptr->rx_skb_ptr); } else { skb->dev = dev; @@ -1252,7 +1252,7 @@ static void dmfe_reuse_skb(struct dmfe_board_info *db, struct sk_buff * skb) if (!(rxptr->rdes0 & cpu_to_le32(0x80000000))) { rxptr->rx_skb_ptr = skb; - rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); + rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); wmb(); rxptr->rdes0 = cpu_to_le32(0x80000000); db->rx_avail_cnt++; @@ -1463,7 +1463,7 @@ static void allocate_rx_buffer(struct dmfe_board_info *db) if ( ( skb = dev_alloc_skb(RX_ALLOC_SIZE) ) == NULL ) break; rxptr->rx_skb_ptr = skb; /* FIXME (?) */ - rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->tail, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); + rxptr->rdes2 = cpu_to_le32( pci_map_single(db->pdev, skb->data, RX_ALLOC_SIZE, PCI_DMA_FROMDEVICE) ); wmb(); rxptr->rdes0 = cpu_to_le32(0x80000000); rxptr = rxptr->next_rx_desc; diff --git a/drivers/net/tulip/interrupt.c b/drivers/net/tulip/interrupt.c index afb5cda..bb35581 100644 --- a/drivers/net/tulip/interrupt.c +++ b/drivers/net/tulip/interrupt.c @@ -78,7 +78,7 @@ int tulip_refill_rx(struct net_device *dev) if (skb == NULL) break; - mapping = pci_map_single(tp->pdev, skb->tail, PKT_BUF_SZ, + mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); tp->rx_buffers[entry].mapping = mapping; @@ -199,12 +199,12 @@ int tulip_poll(struct net_device *dev, int *budget) tp->rx_buffers[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); #if ! defined(__alpha__) - eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, + eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data, pkt_len, 0); skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), - tp->rx_buffers[entry].skb->tail, + tp->rx_buffers[entry].skb->data, pkt_len); #endif pci_dma_sync_single_for_device(tp->pdev, @@ -423,12 +423,12 @@ static int tulip_rx(struct net_device *dev) tp->rx_buffers[entry].mapping, pkt_len, PCI_DMA_FROMDEVICE); #if ! defined(__alpha__) - eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->tail, + eth_copy_and_sum(skb, tp->rx_buffers[entry].skb->data, pkt_len, 0); skb_put(skb, pkt_len); #else memcpy(skb_put(skb, pkt_len), - tp->rx_buffers[entry].skb->tail, + tp->rx_buffers[entry].skb->data, pkt_len); #endif pci_dma_sync_single_for_device(tp->pdev, diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 08e0f80..d45d8f5 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -625,7 +625,7 @@ static void tulip_init_ring(struct net_device *dev) tp->rx_buffers[i].skb = skb; if (skb == NULL) break; - mapping = pci_map_single(tp->pdev, skb->tail, + mapping = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); tp->rx_buffers[i].mapping = mapping; skb->dev = dev; /* Mark as being used by this device. */ diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c index db4b32c..5b1af39 100644 --- a/drivers/net/tulip/winbond-840.c +++ b/drivers/net/tulip/winbond-840.c @@ -849,7 +849,7 @@ static void init_rxtx_rings(struct net_device *dev) if (skb == NULL) break; skb->dev = dev; /* Mark as being used by this device. */ - np->rx_addr[i] = pci_map_single(np->pci_dev,skb->tail, + np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data, skb->len,PCI_DMA_FROMDEVICE); np->rx_ring[i].buffer1 = np->rx_addr[i]; @@ -1269,7 +1269,7 @@ static int netdev_rx(struct net_device *dev) pci_dma_sync_single_for_cpu(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(skb, np->rx_skbuff[entry]->tail, pkt_len, 0); + eth_copy_and_sum(skb, np->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(np->pci_dev,np->rx_addr[entry], np->rx_skbuff[entry]->len, @@ -1315,7 +1315,7 @@ static int netdev_rx(struct net_device *dev) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ np->rx_addr[entry] = pci_map_single(np->pci_dev, - skb->tail, + skb->data, skb->len, PCI_DMA_FROMDEVICE); np->rx_ring[entry].buffer1 = np->rx_addr[entry]; } diff --git a/drivers/net/tulip/xircom_tulip_cb.c b/drivers/net/tulip/xircom_tulip_cb.c index b8a9b39..887d724 100644 --- a/drivers/net/tulip/xircom_tulip_cb.c +++ b/drivers/net/tulip/xircom_tulip_cb.c @@ -899,7 +899,7 @@ static void xircom_init_ring(struct net_device *dev) break; skb->dev = dev; /* Mark as being used by this device. */ tp->rx_ring[i].status = Rx0DescOwned; /* Owned by Xircom chip */ - tp->rx_ring[i].buffer1 = virt_to_bus(skb->tail); + tp->rx_ring[i].buffer1 = virt_to_bus(skb->data); } tp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1291,7 +1291,7 @@ xircom_rx(struct net_device *dev) if (skb == NULL) break; skb->dev = dev; /* Mark as being used by this device. */ - tp->rx_ring[entry].buffer1 = virt_to_bus(skb->tail); + tp->rx_ring[entry].buffer1 = virt_to_bus(skb->data); work_done++; } tp->rx_ring[entry].status = Rx0DescOwned; diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 8f33929..0b5ca25 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c @@ -1661,7 +1661,7 @@ typhoon_alloc_rx_skb(struct typhoon *tp, u32 idx) #endif skb->dev = tp->dev; - dma_addr = pci_map_single(tp->pdev, skb->tail, + dma_addr = pci_map_single(tp->pdev, skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); /* Since no card does 64 bit DAC, the high bits will never @@ -1721,7 +1721,7 @@ typhoon_rx(struct typhoon *tp, struct basic_ring *rxRing, volatile u32 * ready, pci_dma_sync_single_for_cpu(tp->pdev, dma_addr, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); - eth_copy_and_sum(new_skb, skb->tail, pkt_len, 0); + eth_copy_and_sum(new_skb, skb->data, pkt_len, 0); pci_dma_sync_single_for_device(tp->pdev, dma_addr, PKT_BUF_SZ, PCI_DMA_FROMDEVICE); diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c index be1c104..a56ef0d 100644 --- a/drivers/net/via-rhine.c +++ b/drivers/net/via-rhine.c @@ -990,7 +990,7 @@ static void alloc_rbufs(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ rp->rx_skbuff_dma[i] = - pci_map_single(rp->pdev, skb->tail, rp->rx_buf_sz, + pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, PCI_DMA_FROMDEVICE); rp->rx_ring[i].addr = cpu_to_le32(rp->rx_skbuff_dma[i]); @@ -1518,7 +1518,7 @@ static void rhine_rx(struct net_device *dev) PCI_DMA_FROMDEVICE); eth_copy_and_sum(skb, - rp->rx_skbuff[entry]->tail, + rp->rx_skbuff[entry]->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(rp->pdev, @@ -1561,7 +1561,7 @@ static void rhine_rx(struct net_device *dev) break; /* Better luck next round. */ skb->dev = dev; /* Mark as being used by this device. */ rp->rx_skbuff_dma[entry] = - pci_map_single(rp->pdev, skb->tail, + pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz, PCI_DMA_FROMDEVICE); rp->rx_ring[entry].addr = cpu_to_le32(rp->rx_skbuff_dma[entry]); diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index 15e7102..abc5cee 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -1335,7 +1335,7 @@ static inline int velocity_rx_copy(struct sk_buff **rx_skb, int pkt_size, if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) skb_reserve(new_skb, 2); - memcpy(new_skb->data, rx_skb[0]->tail, pkt_size); + memcpy(new_skb->data, rx_skb[0]->data, pkt_size); *rx_skb = new_skb; ret = 0; } @@ -1456,9 +1456,9 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx) * Do the gymnastics to get the buffer head for data at * 64byte alignment. */ - skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->tail & 63); + skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63); rd_info->skb->dev = vptr->dev; - rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->tail, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); + rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE); /* * Fill in the descriptor to match diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c index c1b6896..8749684 100644 --- a/drivers/net/wan/hdlc_cisco.c +++ b/drivers/net/wan/hdlc_cisco.c @@ -72,7 +72,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type, } skb_reserve(skb, 4); cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); - data = (cisco_packet*)skb->tail; + data = (cisco_packet*)skb->data; data->type = htonl(type); data->par1 = htonl(par1); diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index 9da9254..1c25065 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c @@ -786,7 +786,7 @@ static void yellowfin_init_ring(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* 16 byte align the IP header. */ yp->rx_ring[i].addr = cpu_to_le32(pci_map_single(yp->pci_dev, - skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } yp->rx_ring[i-1].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->dirty_rx = (unsigned int)(i - RX_RING_SIZE); @@ -1111,7 +1111,7 @@ static int yellowfin_rx(struct net_device *dev) pci_dma_sync_single_for_cpu(yp->pci_dev, desc->addr, yp->rx_buf_sz, PCI_DMA_FROMDEVICE); desc_status = le32_to_cpu(desc->result_status) >> 16; - buf_addr = rx_skb->tail; + buf_addr = rx_skb->data; data_size = (le32_to_cpu(desc->dbdma_cmd) - le32_to_cpu(desc->result_status)) & 0xffff; frame_status = le16_to_cpu(get_unaligned((s16*)&(buf_addr[data_size - 2]))); @@ -1185,7 +1185,7 @@ static int yellowfin_rx(struct net_device *dev) break; skb->dev = dev; skb_reserve(skb, 2); /* 16 byte align the IP header */ - eth_copy_and_sum(skb, rx_skb->tail, pkt_len, 0); + eth_copy_and_sum(skb, rx_skb->data, pkt_len, 0); skb_put(skb, pkt_len); pci_dma_sync_single_for_device(yp->pci_dev, desc->addr, yp->rx_buf_sz, @@ -1211,7 +1211,7 @@ static int yellowfin_rx(struct net_device *dev) skb->dev = dev; /* Mark as being used by this device. */ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ yp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(yp->pci_dev, - skb->tail, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); + skb->data, yp->rx_buf_sz, PCI_DMA_FROMDEVICE)); } yp->rx_ring[entry].dbdma_cmd = cpu_to_le32(CMD_STOP); yp->rx_ring[entry].result_status = 0; /* Clear complete bit. */ -- cgit v1.1 From fb3d89498d268c8dedc1ab5b15fa64f536564577 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 28 Jun 2005 15:40:02 -0700 Subject: [IPVS]: Close race conditions on ip_vs_conn_tab list modification In an smp system, it is possible for an connection timer to expire, calling ip_vs_conn_expire while the connection table is being flushed, before ct_write_lock_bh is acquired. Since the list iterator loop in ip_vs_con_flush releases and re-acquires the spinlock (even though it doesn't re-enable softirqs), it is possible for the expiration function to modify the connection list, while it is being traversed in ip_vs_conn_flush. The result is that the next pointer gets set to NULL, and subsequently dereferenced, resulting in an oops. Signed-off-by: Neil Horman Acked-by: JulianAnastasov Signed-off-by: David S. Miller --- net/ipv4/ipvs/ip_vs_conn.c | 25 ++++--------------------- 1 file changed, 4 insertions(+), 21 deletions(-) diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index fd6feb5..9f16ab3 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -548,7 +548,6 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp) { if (del_timer(&cp->timer)) mod_timer(&cp->timer, jiffies); - __ip_vs_conn_put(cp); } @@ -764,7 +763,6 @@ void ip_vs_random_dropentry(void) { int idx; struct ip_vs_conn *cp; - struct ip_vs_conn *ct; /* * Randomly scan 1/32 of the whole table every second @@ -801,21 +799,12 @@ void ip_vs_random_dropentry(void) continue; } - /* - * Drop the entry, and drop its ct if not referenced - */ - atomic_inc(&cp->refcnt); - ct_write_unlock(hash); - - if ((ct = cp->control)) - atomic_inc(&ct->refcnt); IP_VS_DBG(4, "del connection\n"); ip_vs_conn_expire_now(cp); - if (ct) { + if (cp->control) { IP_VS_DBG(4, "del conn template\n"); - ip_vs_conn_expire_now(ct); + ip_vs_conn_expire_now(cp->control); } - ct_write_lock(hash); } ct_write_unlock(hash); } @@ -829,7 +818,6 @@ static void ip_vs_conn_flush(void) { int idx; struct ip_vs_conn *cp; - struct ip_vs_conn *ct; flush_again: for (idx=0; idxrefcnt); - ct_write_unlock(idx); - if ((ct = cp->control)) - atomic_inc(&ct->refcnt); IP_VS_DBG(4, "del connection\n"); ip_vs_conn_expire_now(cp); - if (ct) { + if (cp->control) { IP_VS_DBG(4, "del conn template\n"); - ip_vs_conn_expire_now(ct); + ip_vs_conn_expire_now(cp->control); } - ct_write_lock(idx); } ct_write_unlock_bh(idx); } -- cgit v1.1 From 7fe40f73d7591b38f129fe6a9c0fa46e0b192d09 Mon Sep 17 00:00:00 2001 From: YOSHIFUJI Hideaki Date: Tue, 28 Jun 2005 15:46:24 -0700 Subject: [IPV6]: remove more unused IPV6_AUTHHDR things. Remove two more unused IPV6_AUTHHDR option things, which I failed to remove them last time, plus, mark IPV6_AUTHHDR obsolete. Signed-off-by: YOSHIFUJI Hideaki Signed-off-by: David S. Miller --- include/linux/in6.h | 2 +- include/net/ipv6.h | 1 - net/ipv6/ip6_flowlabel.c | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/include/linux/in6.h b/include/linux/in6.h index f8256c5..dcf5720 100644 --- a/include/linux/in6.h +++ b/include/linux/in6.h @@ -156,7 +156,7 @@ struct in6_flowlabel_req #define IPV6_CHECKSUM 7 #define IPV6_HOPLIMIT 8 #define IPV6_NEXTHOP 9 -#define IPV6_AUTHHDR 10 +#define IPV6_AUTHHDR 10 /* obsolete */ #define IPV6_FLOWINFO 11 #define IPV6_UNICAST_HOPS 16 diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 771b47e..6932446 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -183,7 +183,6 @@ struct ipv6_txoptions struct ipv6_opt_hdr *hopopt; struct ipv6_opt_hdr *dst0opt; struct ipv6_rt_hdr *srcrt; /* Routing Header */ - struct ipv6_opt_hdr *auth; struct ipv6_opt_hdr *dst1opt; /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */ diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index 0e5f7499..b6c73da5 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c @@ -244,7 +244,6 @@ struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, opt_space->opt_nflen = 0; } opt_space->dst1opt = fopt->dst1opt; - opt_space->auth = fopt->auth; opt_space->opt_flen = fopt->opt_flen; return opt_space; } -- cgit v1.1 From ff593c592a5d674822dce31143635b025f6415b2 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 28 Jun 2005 15:49:06 -0700 Subject: [NET]: Micro optimization in eth_header() Signed-off-by: Denis Vlasenko Signed-off-by: David S. Miller --- net/ethernet/eth.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 6617ea4..ab60ea6 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c @@ -92,10 +92,9 @@ int eth_header(struct sk_buff *skb, struct net_device *dev, unsigned short type, * Set the source hardware address. */ - if(saddr) - memcpy(eth->h_source,saddr,dev->addr_len); - else - memcpy(eth->h_source,dev->dev_addr,dev->addr_len); + if(!saddr) + saddr = dev->dev_addr; + memcpy(eth->h_source,saddr,dev->addr_len); /* * Anyway, the loopback-device should never use this function... -- cgit v1.1 From bcd61272db5e643b6d9c01c9d5085b914d9f19df Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Tue, 28 Jun 2005 15:58:50 -0700 Subject: [NET]: Add missing include to linux/netdevice.h linux/etherdevice.h can't be included standalone at the moment, which is required in order to sort the header files in the recommended alphabetic order. This patch fixes that and is needed to build spider_net. Signed-off-by: Arnd Bergmann Signed-off-by: David S. Miller --- include/linux/etherdevice.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 8a2df4d..cf3847e 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h @@ -25,6 +25,7 @@ #define _LINUX_ETHERDEVICE_H #include +#include #include #ifdef __KERNEL__ -- cgit v1.1 From 9666dae51013b064e7d77fc36b5cee98dd167ed5 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 28 Jun 2005 16:04:44 -0700 Subject: [NETFILTER]: Fix connection tracking bug in 2.6.12 In 2.6.12 we started dropping the conntrack reference when a packet leaves the IP layer. This broke connection tracking on a bridge, because bridge-netfilter defers calling some NF_IP_* hooks to the bridge layer for locally generated packets going out a bridge, where the conntrack reference is no longer available. This patch keeps the reference in this case as a temporary solution, long term we will remove the defered hook calling. No attempt is made to drop the reference in the bridge-code when it is no longer needed, tc actions could already have sent the packet anywhere. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/bridge/br_netfilter.c | 2 +- net/ipv4/ip_output.c | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 03ae4ed..2d52fee 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -844,7 +844,7 @@ static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb, * doesn't use the bridge parent of the indev by using * the BRNF_DONT_TAKE_PARENT mask. */ if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { - nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; + nf_bridge->mask |= BRNF_DONT_TAKE_PARENT; nf_bridge->physindev = (struct net_device *)in; } #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ee07aec..6ce5c32 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -188,7 +188,13 @@ static inline int ip_finish_output2(struct sk_buff *skb) skb = skb2; } - nf_reset(skb); +#ifdef CONFIG_BRIDGE_NETFILTER + /* bridge-netfilter defers calling some IP hooks to the bridge layer + * and still needs the conntrack reference. + */ + if (skb->nf_bridge == NULL) +#endif + nf_reset(skb); if (hh) { int hh_alen; -- cgit v1.1 From 12dc2fdd3e6067f5137e4a6d8af0b1a994952f52 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 28 Jun 2005 16:27:32 -0700 Subject: [NET]: drivers/net/slip.c needs linux/delay.h For msleep_interruptible(). Signed-off-by: David S. Miller --- drivers/net/slip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 16363b5..404ea42 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include "slip.h" #ifdef CONFIG_INET -- cgit v1.1 From 8d451687ca57371d303c5554b377d7f5c2ac6ae0 Mon Sep 17 00:00:00 2001 From: Wen-chien Jesse Sung Date: Tue, 28 Jun 2005 20:44:41 -0700 Subject: [PATCH] fix semaphore handling in __unregister_chrdev_region This up() should be down() instead. Signed-off-by: Wen-chien Jesse Sung Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/char_dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/char_dev.c b/fs/char_dev.c index e82aac9..a69a5d8 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -150,7 +150,7 @@ __unregister_chrdev_region(unsigned major, unsigned baseminor, int minorct) struct char_device_struct *cd = NULL, **cp; int i = major_to_index(major); - up(&chrdevs_lock); + down(&chrdevs_lock); for (cp = &chrdevs[i]; *cp; cp = &(*cp)->next) if ((*cp)->major == major && (*cp)->baseminor == baseminor && -- cgit v1.1 From 47f176fdaf8924bc83fddcf9658f2fd3ef60d573 Mon Sep 17 00:00:00 2001 From: Luca Falavigna Date: Tue, 28 Jun 2005 20:44:42 -0700 Subject: [PATCH] Using msleep() instead of HZ Use msleep() in a few places. Signed-off-by: Luca Falavigna Acked-by: Ingo Molnar Acked-by: Jeff Garzik Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/rtc.c | 16 ++++------------ kernel/irq/autoprobe.c | 9 ++++----- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index ff4f098..d8f9e94 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -78,6 +78,7 @@ #include #include #include +#include #include #include @@ -894,7 +895,6 @@ static int __init rtc_init(void) struct proc_dir_entry *ent; #if defined(__alpha__) || defined(__mips__) unsigned int year, ctrl; - unsigned long uip_watchdog; char *guess = NULL; #endif #ifdef __sparc__ @@ -1000,12 +1000,8 @@ no_irq: /* Each operating system on an Alpha uses its own epoch. Let's try to guess which one we are using now. */ - uip_watchdog = jiffies; if (rtc_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + msleep(20); spin_lock_irq(&rtc_lock); year = CMOS_READ(RTC_YEAR); @@ -1213,7 +1209,6 @@ static int rtc_proc_open(struct inode *inode, struct file *file) void rtc_get_rtc_time(struct rtc_time *rtc_tm) { - unsigned long uip_watchdog = jiffies; unsigned char ctrl; #ifdef CONFIG_MACH_DECSTATION unsigned int real_year; @@ -1221,7 +1216,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) /* * read RTC once any update in progress is done. The update - * can take just over 2ms. We wait 10 to 20ms. There is no need to + * can take just over 2ms. We wait 20ms. There is no need to * to poll-wait (up to 1s - eeccch) for the falling edge of RTC_UIP. * If you need to know *exactly* when a second has started, enable * periodic update complete interrupts, (via ioctl) and then @@ -1230,10 +1225,7 @@ void rtc_get_rtc_time(struct rtc_time *rtc_tm) */ if (rtc_is_updating() != 0) - while (jiffies - uip_watchdog < 2*HZ/100) { - barrier(); - cpu_relax(); - } + msleep(20); /* * Only the values that we read from the RTC are set. We leave diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c index 98d62d8..3467097 100644 --- a/kernel/irq/autoprobe.c +++ b/kernel/irq/autoprobe.c @@ -9,6 +9,7 @@ #include #include #include +#include /* * Autodetection depends on the fact that any interrupt that @@ -26,7 +27,7 @@ static DECLARE_MUTEX(probe_sem); */ unsigned long probe_irq_on(void) { - unsigned long val, delay; + unsigned long val; irq_desc_t *desc; unsigned int i; @@ -45,8 +46,7 @@ unsigned long probe_irq_on(void) } /* Wait for longstanding interrupts to trigger. */ - for (delay = jiffies + HZ/50; time_after(delay, jiffies); ) - /* about 20ms delay */ barrier(); + msleep(20); /* * enable any unassigned irqs @@ -68,8 +68,7 @@ unsigned long probe_irq_on(void) /* * Wait for spurious interrupts to trigger */ - for (delay = jiffies + HZ/10; time_after(delay, jiffies); ) - /* about 100ms delay */ barrier(); + msleep(100); /* * Now filter out any obviously spurious interrupts -- cgit v1.1 From 45ae36cbce9c7f55615e2b5f8faf23c7a06d0bd2 Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Tue, 28 Jun 2005 20:44:44 -0700 Subject: [PATCH] drivers/char/tipar.c: off by one array access In the setup function, the delay variable is initialized with ints[2], but ints is declared as: int ints[2]; Since the module parameter should correspond to: tipar=timeout,delay I suppose that the following patch fix the problem. Signed-off-by: Luc Van Oostenryck Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tipar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/tipar.c b/drivers/char/tipar.c index 659335d8..ec78d2f 100644 --- a/drivers/char/tipar.c +++ b/drivers/char/tipar.c @@ -396,7 +396,7 @@ static struct file_operations tipar_fops = { static int __init tipar_setup(char *str) { - int ints[2]; + int ints[3]; str = get_options(str, ARRAY_SIZE(ints), ints); -- cgit v1.1 From b36bbb6c3d5244eaf52241ec69f79494137f2db0 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 28 Jun 2005 20:44:46 -0700 Subject: [PATCH] ixp4xx/ixp2000 watchdog driver typo Fix the same typo in the ixp4xx and ixp2000 watchdog drivers. Signed-off-by: Lennert Buytenhek Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/watchdog/ixp2000_wdt.c | 2 +- drivers/char/watchdog/ixp4xx_wdt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/watchdog/ixp2000_wdt.c b/drivers/char/watchdog/ixp2000_wdt.c index 4e98c21..4b03951 100644 --- a/drivers/char/watchdog/ixp2000_wdt.c +++ b/drivers/char/watchdog/ixp2000_wdt.c @@ -162,7 +162,7 @@ ixp2000_wdt_release(struct inode *inode, struct file *file) if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { wdt_disable(); } else { - printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " "timer will not stop\n"); } diff --git a/drivers/char/watchdog/ixp4xx_wdt.c b/drivers/char/watchdog/ixp4xx_wdt.c index 82396e0..83df369 100644 --- a/drivers/char/watchdog/ixp4xx_wdt.c +++ b/drivers/char/watchdog/ixp4xx_wdt.c @@ -156,7 +156,7 @@ ixp4xx_wdt_release(struct inode *inode, struct file *file) if (test_bit(WDT_OK_TO_CLOSE, &wdt_status)) { wdt_disable(); } else { - printk(KERN_CRIT "WATCHDOG: Device closed unexpectdly - " + printk(KERN_CRIT "WATCHDOG: Device closed unexpectedly - " "timer will not stop\n"); } -- cgit v1.1 From f01b1b0baa454825ed95c28d2a6a71bbf4510836 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Tue, 28 Jun 2005 20:44:47 -0700 Subject: [PATCH] ITIMER_REAL: fix possible deadlock and race As Steven Rostedt pointed out, there are 2 problems with ITIMER_REAL timers. 1. do_setitimer() does not call del_timer_sync() in case when the timer is not pending (it_real_value() returns 0). This is wrong, the timer may still be running, and it can rearm itself. 2. It calls del_timer_sync() with tsk->sighand->siglock held. This is deadlockable, because timer's handler needs this lock too. Signed-off-by: Oleg Nesterov Acked-by: Steven Rostedt Cc: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- kernel/itimer.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/kernel/itimer.c b/kernel/itimer.c index 1dc988e..a72cb0e 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c @@ -153,11 +153,15 @@ int do_setitimer(int which, struct itimerval *value, struct itimerval *ovalue) switch (which) { case ITIMER_REAL: +again: spin_lock_irq(&tsk->sighand->siglock); interval = tsk->signal->it_real_incr; val = it_real_value(tsk->signal); - if (val) - del_timer_sync(&tsk->signal->real_timer); + /* We are sharing ->siglock with it_real_fn() */ + if (try_to_del_timer_sync(&tsk->signal->real_timer) < 0) { + spin_unlock_irq(&tsk->sighand->siglock); + goto again; + } tsk->signal->it_real_incr = timeval_to_jiffies(&value->it_interval); it_real_arm(tsk, timeval_to_jiffies(&value->it_value)); -- cgit v1.1 From bcc8ca09920755520ba8a1e2d9f72fe8ff892643 Mon Sep 17 00:00:00 2001 From: Emmanuel Colbus Date: Tue, 28 Jun 2005 20:44:49 -0700 Subject: [PATCH] Adapt drivers/char/vt_ioctl.c to non-x86 This code uses the x86 (non-AMD-ELAN) value of CLOCK_TICK_RATE instead of CLOCK_TICK_RATE itself, which is wrong for other archs. Signed-off-by: Emmanuel Colbus Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/vt_ioctl.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c index 8971484..1d44f69 100644 --- a/drivers/char/vt_ioctl.c +++ b/drivers/char/vt_ioctl.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -386,7 +387,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, if (!perm) return -EPERM; if (arg) - arg = 1193182 / arg; + arg = CLOCK_TICK_RATE / arg; kd_mksound(arg, 0); return 0; @@ -403,7 +404,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file, ticks = HZ * ((arg >> 16) & 0xffff) / 1000; count = ticks ? (arg & 0xffff) : 0; if (count) - count = 1193182 / count; + count = CLOCK_TICK_RATE / count; kd_mksound(count, ticks); return 0; } -- cgit v1.1 From b92eac01c3c6ad5dab5c74d3bc32ac8e9bf4dae7 Mon Sep 17 00:00:00 2001 From: "Stanislaw W. Gruszka" Date: Tue, 28 Jun 2005 20:44:51 -0700 Subject: [PATCH] request_firmware(): avoid race conditions Avoid race occurs when some process have open file descriptor for class device attributes and already firmware allocated memory are freed. Don't allow negative loading timeout. Signed-off-by: Stanislaw W. Gruszka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/base/firmware_class.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index 97fe13f..6522814 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c @@ -74,6 +74,8 @@ static ssize_t firmware_timeout_store(struct class *class, const char *buf, size_t count) { loading_timeout = simple_strtol(buf, NULL, 10); + if (loading_timeout < 0) + loading_timeout = 0; return count; } @@ -138,6 +140,10 @@ firmware_loading_store(struct class_device *class_dev, switch (loading) { case 1: down(&fw_lock); + if (!fw_priv->fw) { + up(&fw_lock); + break; + } vfree(fw_priv->fw->data); fw_priv->fw->data = NULL; fw_priv->fw->size = 0; @@ -178,7 +184,7 @@ firmware_data_read(struct kobject *kobj, down(&fw_lock); fw = fw_priv->fw; - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { ret_count = -ENODEV; goto out; } @@ -238,9 +244,10 @@ firmware_data_write(struct kobject *kobj, if (!capable(CAP_SYS_RAWIO)) return -EPERM; + down(&fw_lock); fw = fw_priv->fw; - if (test_bit(FW_STATUS_DONE, &fw_priv->status)) { + if (!fw || test_bit(FW_STATUS_DONE, &fw_priv->status)) { retval = -ENODEV; goto out; } @@ -418,7 +425,7 @@ request_firmware(const struct firmware **firmware_p, const char *name, fw_priv = class_get_devdata(class_dev); - if (loading_timeout) { + if (loading_timeout > 0) { fw_priv->timeout.expires = jiffies + loading_timeout * HZ; add_timer(&fw_priv->timeout); } -- cgit v1.1 From b79646e3dd51b389b2a570b454f8e2fb7a613e37 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 28 Jun 2005 20:44:53 -0700 Subject: [PATCH] hisax warning fixes drivers/isdn/hisax/hfc4s8s_l1.c:317: warning: type qualifiers ignored on function return type drivers/isdn/hisax/hfc4s8s_l1.c:329: warning: type qualifiers ignored on function return type Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/hfc4s8s_l1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index 6e7e060..5cbcfa9 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c @@ -312,7 +312,7 @@ wait_busy(hfc4s8s_hw * a) /* function to read critical counter registers that */ /* may be udpated by the chip during read */ /******************************************************/ -static volatile u_char +static u_char Read_hfc8_stable(hfc4s8s_hw * hw, int reg) { u_char ref8; @@ -324,7 +324,7 @@ Read_hfc8_stable(hfc4s8s_hw * hw, int reg) return in8; } -static volatile int +static int Read_hfc16_stable(hfc4s8s_hw * hw, int reg) { int ref16; -- cgit v1.1 From 05133fc498e788e1c1ca4e906f9e05d9779fd63b Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Tue, 28 Jun 2005 20:44:54 -0700 Subject: [PATCH] swabb.h warning fixes In file included from drivers/media/dvb/ttpci/av7110_hw.c:38: include/linux/byteorder/swabb.h:96: warning: type qualifiers ignored on function return type include/linux/byteorder/swabb.h:110: warning: type qualifiers ignored on function return type In file included from drivers/media/dvb/ttpci/av7110_v4l.c:36: include/linux/byteorder/swabb.h:96: warning: type qualifiers ignored on function return type include/linux/byteorder/swabb.h:110: warning: type qualifiers ignored on function return type In file included from drivers/media/dvb/ttpci/av7110_av.c:37: include/linux/byteorder/swabb.h:96: warning: type qualifiers ignored on function return type include/linux/byteorder/swabb.h:110: warning: type qualifiers ignored on function return type drivers/isdn/icn/icn.c:719:4: warning: #warning TODO test headroom or use skb->nb to flag ACK In file included from drivers/media/dvb/ttpci/av7110_ca.c:39: include/linux/byteorder/swabb.h:96: warning: type qualifiers ignored on function return type include/linux/byteorder/swabb.h:110: warning: type qualifiers ignored on function return type In file included from drivers/media/dvb/ttpci/av7110.c:41: include/linux/byteorder/swabb.h:96: warning: type qualifiers ignored on function return type include/linux/byteorder/swabb.h:110: warning: type qualifiers ignored on function return type Does declaring a function to return a const value actually mean something to gcc? Dunno. Kill it and replace sone `__inline__'s with `inline' too. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/byteorder/swabb.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/linux/byteorder/swabb.h b/include/linux/byteorder/swabb.h index d28d9a8..d5f2a32 100644 --- a/include/linux/byteorder/swabb.h +++ b/include/linux/byteorder/swabb.h @@ -92,29 +92,32 @@ #endif /* OPTIMIZE */ -static __inline__ __const__ __u32 __fswahw32(__u32 x) +static inline __u32 __fswahw32(__u32 x) { return __arch__swahw32(x); } -static __inline__ __u32 __swahw32p(__u32 *x) + +static inline __u32 __swahw32p(__u32 *x) { return __arch__swahw32p(x); } -static __inline__ void __swahw32s(__u32 *addr) + +static inline void __swahw32s(__u32 *addr) { __arch__swahw32s(addr); } - -static __inline__ __const__ __u32 __fswahb32(__u32 x) +static inline __u32 __fswahb32(__u32 x) { return __arch__swahb32(x); } -static __inline__ __u32 __swahb32p(__u32 *x) + +static inline __u32 __swahb32p(__u32 *x) { return __arch__swahb32p(x); } -static __inline__ void __swahb32s(__u32 *addr) + +static inline void __swahb32s(__u32 *addr) { __arch__swahb32s(addr); } -- cgit v1.1 From 687a21cee17000177b1935896b9b475acf136678 Mon Sep 17 00:00:00 2001 From: Pekka J Enberg Date: Tue, 28 Jun 2005 20:44:55 -0700 Subject: [PATCH] rename wakeup_bdflush to wakeup_pdflush Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/buffer.c | 4 ++-- include/linux/writeback.h | 2 +- mm/page-writeback.c | 2 +- mm/vmscan.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index 13e5938..561e63a 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -278,7 +278,7 @@ EXPORT_SYMBOL(thaw_bdev); */ static void do_sync(unsigned long wait) { - wakeup_bdflush(0); + wakeup_pdflush(0); sync_inodes(0); /* All mappings, inodes and their blockdevs */ DQUOT_SYNC(NULL); sync_supers(); /* Write the superblocks */ @@ -497,7 +497,7 @@ static void free_more_memory(void) struct zone **zones; pg_data_t *pgdat; - wakeup_bdflush(1024); + wakeup_pdflush(1024); yield(); for_each_pgdat(pgdat) { diff --git a/include/linux/writeback.h b/include/linux/writeback.h index d5c3fe1..542dbae 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -85,7 +85,7 @@ static inline void wait_on_inode(struct inode *inode) /* * mm/page-writeback.c */ -int wakeup_bdflush(long nr_pages); +int wakeup_pdflush(long nr_pages); void laptop_io_completion(void); void laptop_sync_completion(void); void throttle_vm_writeout(void); diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 613b99a..a6329fa 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -354,7 +354,7 @@ static void background_writeout(unsigned long _min_pages) * the whole world. Returns 0 if a pdflush thread was dispatched. Returns * -1 if all pdflush threads were busy. */ -int wakeup_bdflush(long nr_pages) +int wakeup_pdflush(long nr_pages) { if (nr_pages == 0) { struct writeback_state wbs; diff --git a/mm/vmscan.c b/mm/vmscan.c index 1fa312a..cfffe50 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -972,7 +972,7 @@ int try_to_free_pages(struct zone **zones, unsigned int gfp_mask) * writeout. So in laptop mode, write out the whole world. */ if (total_scanned > sc.swap_cluster_max + sc.swap_cluster_max/2) { - wakeup_bdflush(laptop_mode ? 0 : total_scanned); + wakeup_pdflush(laptop_mode ? 0 : total_scanned); sc.may_writepage = 1; } -- cgit v1.1 From aade0e82739f4b24c5b952de68c8d794459ad531 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 28 Jun 2005 20:44:56 -0700 Subject: [PATCH] drivers/isdn/: make some code static This patch makes some needlessly global code static. Signed-off-by: Adrian Bunk Signed-off-by: Armin Schindler Signed-off-by: Karsten Keil Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/isdn/hardware/eicon/dadapter.c | 2 +- drivers/isdn/hisax/hfc4s8s_l1.c | 4 ++-- drivers/isdn/hysdn/hycapi.c | 20 +++++++++++--------- drivers/isdn/hysdn/hysdn_boot.c | 4 ++-- drivers/isdn/hysdn/hysdn_defs.h | 12 ------------ drivers/isdn/hysdn/hysdn_init.c | 2 +- drivers/isdn/hysdn/hysdn_proclog.c | 4 +++- 7 files changed, 20 insertions(+), 28 deletions(-) diff --git a/drivers/isdn/hardware/eicon/dadapter.c b/drivers/isdn/hardware/eicon/dadapter.c index 6e548a2..8949789 100644 --- a/drivers/isdn/hardware/eicon/dadapter.c +++ b/drivers/isdn/hardware/eicon/dadapter.c @@ -44,7 +44,7 @@ static didd_adapter_change_notification_t\ Array to held adapter information -------------------------------------------------------------------------- */ static DESCRIPTOR HandleTable[NEW_MAX_DESCRIPTORS]; -dword Adapters = 0; /* Number of adapters */ +static dword Adapters = 0; /* Number of adapters */ /* -------------------------------------------------------------------------- Shadow IDI_DIMAINT and 'shadow' debug stuff diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c index 5cbcfa9..7333377a 100644 --- a/drivers/isdn/hisax/hfc4s8s_l1.c +++ b/drivers/isdn/hisax/hfc4s8s_l1.c @@ -1465,7 +1465,7 @@ hfc_hardware_enable(hfc4s8s_hw * hw, int enable, int nt_mode) /******************************************/ /* disable memory mapped ports / io ports */ /******************************************/ -void +static void release_pci_ports(hfc4s8s_hw * hw) { pci_write_config_word(hw->pdev, PCI_COMMAND, 0); @@ -1481,7 +1481,7 @@ release_pci_ports(hfc4s8s_hw * hw) /*****************************************/ /* enable memory mapped ports / io ports */ /*****************************************/ -void +static void enable_pci_ports(hfc4s8s_hw * hw) { #ifdef CONFIG_HISAX_HFC4S8S_PCIMEM diff --git a/drivers/isdn/hysdn/hycapi.c b/drivers/isdn/hysdn/hycapi.c index 8ee25b2..1fd3d4e 100644 --- a/drivers/isdn/hysdn/hycapi.c +++ b/drivers/isdn/hysdn/hycapi.c @@ -42,6 +42,8 @@ typedef struct _hycapi_appl { static hycapi_appl hycapi_applications[CAPI_MAXAPPL]; +static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb); + static inline int _hycapi_appCheck(int app_id, int ctrl_no) { if((ctrl_no <= 0) || (ctrl_no > CAPI_MAXCONTR) || (app_id <= 0) || @@ -57,7 +59,7 @@ static inline int _hycapi_appCheck(int app_id, int ctrl_no) Kernel-Capi callback reset_ctr ******************************/ -void +static void hycapi_reset_ctr(struct capi_ctr *ctrl) { hycapictrl_info *cinfo = ctrl->driverdata; @@ -73,7 +75,7 @@ hycapi_reset_ctr(struct capi_ctr *ctrl) Kernel-Capi callback remove_ctr ******************************/ -void +static void hycapi_remove_ctr(struct capi_ctr *ctrl) { int i; @@ -215,7 +217,7 @@ Error-checking is done for CAPI-compliance. The application is recorded in the internal list. *************************************************************/ -void +static void hycapi_register_appl(struct capi_ctr *ctrl, __u16 appl, capi_register_params *rp) { @@ -291,7 +293,7 @@ Release the application from the internal list an remove it's registration at controller-level ******************************************************************/ -void +static void hycapi_release_appl(struct capi_ctr *ctrl, __u16 appl) { int chk; @@ -364,7 +366,7 @@ firmware-releases that do not check the MsgLen-Indication! ***************************************************************/ -u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) +static u16 hycapi_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) { __u16 appl_id; int _len, _len2; @@ -437,8 +439,8 @@ Informations provided in the /proc/capi-entries. *********************************************************************/ -int hycapi_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *ctrl) +static int hycapi_read_proc(char *page, char **start, off_t off, + int count, int *eof, struct capi_ctr *ctrl) { hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); hysdn_card *card = cinfo->card; @@ -485,7 +487,7 @@ on capi-interface registration. **************************************************************/ -int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) +static int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) { #ifdef HYCAPI_PRINTFNAMES printk(KERN_NOTICE "hycapi_load_firmware\n"); @@ -494,7 +496,7 @@ int hycapi_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) } -char *hycapi_procinfo(struct capi_ctr *ctrl) +static char *hycapi_procinfo(struct capi_ctr *ctrl) { hycapictrl_info *cinfo = (hycapictrl_info *)(ctrl->driverdata); #ifdef HYCAPI_PRINTFNAMES diff --git a/drivers/isdn/hysdn/hysdn_boot.c b/drivers/isdn/hysdn/hysdn_boot.c index 6c04281..7bfba19 100644 --- a/drivers/isdn/hysdn/hysdn_boot.c +++ b/drivers/isdn/hysdn/hysdn_boot.c @@ -53,7 +53,7 @@ struct boot_data { /* to be called at start of POF file reading, */ /* before starting any decryption on any POF record. */ /*****************************************************/ -void +static void StartDecryption(struct boot_data *boot) { boot->Cryptor = CRYPT_STARTTERM; @@ -66,7 +66,7 @@ StartDecryption(struct boot_data *boot) /* to HI and LO boot loader and (all) seq tags, because */ /* global Cryptor is started for whole POF. */ /***************************************************************/ -void +static void DecryptBuf(struct boot_data *boot, int cnt) { uchar *bufp = boot->buf.BootBuf; diff --git a/drivers/isdn/hysdn/hysdn_defs.h b/drivers/isdn/hysdn/hysdn_defs.h index 4cee26e..432f6f9 100644 --- a/drivers/isdn/hysdn/hysdn_defs.h +++ b/drivers/isdn/hysdn/hysdn_defs.h @@ -227,7 +227,6 @@ typedef struct hycapictrl_info hycapictrl_info; /*****************/ /* exported vars */ /*****************/ -extern int cardmax; /* number of found cards */ extern hysdn_card *card_root; /* pointer to first card */ @@ -244,7 +243,6 @@ extern void hysdn_procconf_release(void); /* deinit proc config filesys */ /* hysdn_proclog.c */ extern int hysdn_proclog_init(hysdn_card *); /* init proc log entry */ extern void hysdn_proclog_release(hysdn_card *); /* deinit proc log entry */ -extern void put_log_buffer(hysdn_card *, char *); /* output log data */ extern void hysdn_addlog(hysdn_card *, char *,...); /* output data to log */ extern void hysdn_card_errlog(hysdn_card *, tErrLogEntry *, int); /* output card log */ @@ -278,16 +276,6 @@ extern unsigned int hycapi_enable; extern int hycapi_capi_create(hysdn_card *); /* create a new capi device */ extern int hycapi_capi_release(hysdn_card *); /* delete the device */ extern int hycapi_capi_stop(hysdn_card *card); /* suspend */ -extern int hycapi_load_firmware(struct capi_ctr *, capiloaddata *); -extern void hycapi_reset_ctr(struct capi_ctr *); -extern void hycapi_remove_ctr(struct capi_ctr *); -extern void hycapi_register_appl(struct capi_ctr *, __u16 appl, - capi_register_params *); -extern void hycapi_release_appl(struct capi_ctr *, __u16 appl); -extern u16 hycapi_send_message(struct capi_ctr *, struct sk_buff *skb); -extern char *hycapi_procinfo(struct capi_ctr *); -extern int hycapi_read_proc(char *page, char **start, off_t off, - int count, int *eof, struct capi_ctr *card); extern void hycapi_rx_capipkt(hysdn_card * card, uchar * buf, word len); extern void hycapi_tx_capiack(hysdn_card * card); extern struct sk_buff *hycapi_tx_capiget(hysdn_card *card); diff --git a/drivers/isdn/hysdn/hysdn_init.c b/drivers/isdn/hysdn/hysdn_init.c index 5cac2bf..12c8137 100644 --- a/drivers/isdn/hysdn/hysdn_init.c +++ b/drivers/isdn/hysdn/hysdn_init.c @@ -34,7 +34,7 @@ MODULE_AUTHOR("Werner Cornelius"); MODULE_LICENSE("GPL"); static char *hysdn_init_revision = "$Revision: 1.6.6.6 $"; -int cardmax; /* number of found cards */ +static int cardmax; /* number of found cards */ hysdn_card *card_root = NULL; /* pointer to first card */ /**********************************************/ diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index 8ef2b7c..4d57011 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -22,6 +22,8 @@ /* the proc subdir for the interface is defined in the procconf module */ extern struct proc_dir_entry *hysdn_proc_entry; +static void put_log_buffer(hysdn_card * card, char *cp); + /*************************************************/ /* structure keeping ascii log for device output */ /*************************************************/ @@ -93,7 +95,7 @@ hysdn_addlog(hysdn_card * card, char *fmt,...) /* opened for read got the contents. */ /* Flushes buffers not longer in use. */ /********************************************/ -void +static void put_log_buffer(hysdn_card * card, char *cp) { struct log_data *ib; -- cgit v1.1 From 334a13ec3d01a1a4b4f2249735b793105cb4a519 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 28 Jun 2005 20:44:58 -0700 Subject: [PATCH] really remove xattr_acl.h Looks like it sneaked back with the NFS ACL merge.. Signed-off-by: Christoph Hellwig Cc: Trond Myklebust Cc: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/nfs/nfs3acl.c | 14 ++++++------- fs/nfsd/vfs.c | 13 ++++++------ include/linux/xattr_acl.h | 50 ----------------------------------------------- 3 files changed, 13 insertions(+), 64 deletions(-) delete mode 100644 include/linux/xattr_acl.h diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index ee3536f..1b7a3ef 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #define NFSDBG_FACILITY NFSDBG_PROC @@ -53,9 +53,9 @@ ssize_t nfs3_getxattr(struct dentry *dentry, const char *name, struct posix_acl *acl; int type, error = 0; - if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) type = ACL_TYPE_ACCESS; - else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) + else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) type = ACL_TYPE_DEFAULT; else return -EOPNOTSUPP; @@ -82,9 +82,9 @@ int nfs3_setxattr(struct dentry *dentry, const char *name, struct posix_acl *acl; int type, error; - if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) type = ACL_TYPE_ACCESS; - else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) + else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) type = ACL_TYPE_DEFAULT; else return -EOPNOTSUPP; @@ -103,9 +103,9 @@ int nfs3_removexattr(struct dentry *dentry, const char *name) struct inode *inode = dentry->d_inode; int type; - if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) + if (strcmp(name, POSIX_ACL_XATTR_ACCESS) == 0) type = ACL_TYPE_ACCESS; - else if (strcmp(name, XATTR_NAME_ACL_DEFAULT) == 0) + else if (strcmp(name, POSIX_ACL_XATTR_DEFAULT) == 0) type = ACL_TYPE_DEFAULT; else return -EOPNOTSUPP; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index de340ff..be24ead 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -46,10 +46,9 @@ #include #include #include -#include #include -#ifdef CONFIG_NFSD_V4 #include +#ifdef CONFIG_NFSD_V4 #include #include #include @@ -1872,10 +1871,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, int type) return ERR_PTR(-EOPNOTSUPP); switch(type) { case ACL_TYPE_ACCESS: - name = XATTR_NAME_ACL_ACCESS; + name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: - name = XATTR_NAME_ACL_DEFAULT; + name = POSIX_ACL_XATTR_DEFAULT; break; default: return ERR_PTR(-EOPNOTSUPP); @@ -1919,17 +1918,17 @@ nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl) return -EOPNOTSUPP; switch(type) { case ACL_TYPE_ACCESS: - name = XATTR_NAME_ACL_ACCESS; + name = POSIX_ACL_XATTR_ACCESS; break; case ACL_TYPE_DEFAULT: - name = XATTR_NAME_ACL_DEFAULT; + name = POSIX_ACL_XATTR_DEFAULT; break; default: return -EOPNOTSUPP; } if (acl && acl->a_count) { - size = xattr_acl_size(acl->a_count); + size = posix_acl_xattr_size(acl->a_count); value = kmalloc(size, GFP_KERNEL); if (!value) return -ENOMEM; diff --git a/include/linux/xattr_acl.h b/include/linux/xattr_acl.h deleted file mode 100644 index 7a1f9b9..0000000 --- a/include/linux/xattr_acl.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - File: linux/xattr_acl.h - - (extended attribute representation of access control lists) - - (C) 2000 Andreas Gruenbacher, -*/ - -#ifndef _LINUX_XATTR_ACL_H -#define _LINUX_XATTR_ACL_H - -#include - -#define XATTR_NAME_ACL_ACCESS "system.posix_acl_access" -#define XATTR_NAME_ACL_DEFAULT "system.posix_acl_default" - -#define XATTR_ACL_VERSION 0x0002 - -typedef struct { - __u16 e_tag; - __u16 e_perm; - __u32 e_id; -} xattr_acl_entry; - -typedef struct { - __u32 a_version; - xattr_acl_entry a_entries[0]; -} xattr_acl_header; - -static inline size_t xattr_acl_size(int count) -{ - return sizeof(xattr_acl_header) + count * sizeof(xattr_acl_entry); -} - -static inline int xattr_acl_count(size_t size) -{ - if (size < sizeof(xattr_acl_header)) - return -1; - size -= sizeof(xattr_acl_header); - if (size % sizeof(xattr_acl_entry)) - return -1; - return size / sizeof(xattr_acl_entry); -} - -struct posix_acl * posix_acl_from_xattr(const void *value, size_t size); -int posix_acl_to_xattr(const struct posix_acl *acl, void *buffer, size_t size); - - - -#endif /* _LINUX_XATTR_ACL_H */ -- cgit v1.1 From c016e2257acd00a7ffd87fa1eec896138563d1aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=E9bastien=20Dugu?= Date: Tue, 28 Jun 2005 20:44:59 -0700 Subject: [PATCH] aio-retry-fix: fix aio retry work queueing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the case of buffered AIO, in the aio retry path (aio_run_iocb), when the retry method returns EIOCBRETRY the kicked iocb is added to the context run list but is never queued onto the work queue. The request therefore is never completed. This patch fixes that by adding the appropriate call to aio_queue_work in aio_run_aiocb so that subsequent retries will be handled by the aio worker thread. Signed-off-by: Sébastien Dugué Acked-by: Benjamin LaHaise Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/aio.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/aio.c b/fs/aio.c index 7afa222..06d7d43 100644 --- a/fs/aio.c +++ b/fs/aio.c @@ -58,6 +58,7 @@ static DEFINE_SPINLOCK(fput_lock); static LIST_HEAD(fput_head); static void aio_kick_handler(void *); +static void aio_queue_work(struct kioctx *); /* aio_setup * Creates the slab caches used by the aio routines, panic on @@ -747,6 +748,14 @@ out: * has already been kicked */ if (kiocbIsKicked(iocb)) { __queue_kicked_iocb(iocb); + + /* + * __queue_kicked_iocb will always return 1 here, because + * iocb->ki_run_list is empty at this point so it should + * be safe to unconditionally queue the context into the + * work queue. + */ + aio_queue_work(ctx); } } return ret; -- cgit v1.1 From 12822bc272e857544476cef9175462711899008b Mon Sep 17 00:00:00 2001 From: GOTO Masanori Date: Tue, 28 Jun 2005 20:45:03 -0700 Subject: [PATCH] headers: enable ppc64 ___arch__swab16 and ___arch__swab32 This patch cleans up asm-ppc64/byteorder.h to enable ___arch__swab16 and ___arch__swab32 which are marked TODO currently. It removes ___arch__swab64 because ppc64 does not have short instruction combinations for swab64, the recent gcc generates enough smart code that is equivalent to hand assembled code under my tests. Signed-off-by: GOTO Masanori Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-ppc64/byteorder.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/include/asm-ppc64/byteorder.h b/include/asm-ppc64/byteorder.h index 8032753..8b57da6 100644 --- a/include/asm-ppc64/byteorder.h +++ b/include/asm-ppc64/byteorder.h @@ -40,7 +40,6 @@ static __inline__ void st_le32(volatile __u32 *addr, const __u32 val) __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -#if 0 static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 value) { __u16 result; @@ -63,17 +62,8 @@ static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 value) return result; } -static __inline__ __attribute_const__ __u64 ___arch__swab64(__u64 value) -{ - __u64 result; -#error implement me -} - #define __arch__swab16(x) ___arch__swab16(x) #define __arch__swab32(x) ___arch__swab32(x) -#define __arch__swab64(x) ___arch__swab64(x) - -#endif /* The same, but returns converted value from the location pointer by addr. */ #define __arch__swab16p(addr) ld_le16(addr) -- cgit v1.1 From 3607d1dfc80dcfbd3a6f236c70aa0d8eb7292278 Mon Sep 17 00:00:00 2001 From: GOTO Masanori Date: Tue, 28 Jun 2005 20:45:04 -0700 Subject: [PATCH] headers: include linux/compiler.h for __user This patch lets i2c-dev.h include linux/compiler.h so that __user is defined. Signed-off-by: GOTO Masanori Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/i2c-dev.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/i2c-dev.h b/include/linux/i2c-dev.h index d228230..5416956 100644 --- a/include/linux/i2c-dev.h +++ b/include/linux/i2c-dev.h @@ -25,6 +25,7 @@ #define _LINUX_I2C_DEV_H #include +#include /* Some IOCTL commands are defined in */ /* Note: 10-bit addresses are NOT supported! */ -- cgit v1.1 From 4cceb4d13abaedbd52e54053367c793ed4aedb6b Mon Sep 17 00:00:00 2001 From: GOTO Masanori Date: Tue, 28 Jun 2005 20:45:05 -0700 Subject: [PATCH] headers: include linux/types.h for usb_ch9.h This patch for usb_ch9.h includes linux/types.h instead of asm/types.h so that __le16 and so on is explicitly defined. It also cleans up non standard // comment. Signed-off-by: GOTO Masanori Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/usb_ch9.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/usb_ch9.h b/include/linux/usb_ch9.h index 39e7ff4..ee21e6b 100644 --- a/include/linux/usb_ch9.h +++ b/include/linux/usb_ch9.h @@ -19,7 +19,7 @@ #ifndef __LINUX_USB_CH9_H #define __LINUX_USB_CH9_H -#include /* __u8 etc */ +#include /* __u8 etc */ /*-------------------------------------------------------------------------*/ @@ -294,8 +294,8 @@ struct usb_endpoint_descriptor { __le16 wMaxPacketSize; __u8 bInterval; - // NOTE: these two are _only_ in audio endpoints. - // use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. + /* NOTE: these two are _only_ in audio endpoints. */ + /* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */ __u8 bRefresh; __u8 bSynchAddress; } __attribute__ ((packed)); -- cgit v1.1 From a8f5034540195307362d071a8b387226b410469f Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:06 -0700 Subject: [PATCH] coverity: i386: build.c: negative return to unsigned fix Variable "c" was declared as an unsigned int, but used in: 125 for (i=0 ; (c=read(fd, buf, sizeof(buf)))>0 ; i+=c ) 126 if (write(1, buf, c) != c) 127 die("Write call failed"); (akpm: read() can return -1. If it does, we fill the disk up with garbage). Signed-off-by: Zaur Kambarov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/boot/tools/build.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/i386/boot/tools/build.c b/arch/i386/boot/tools/build.c index 4a17956..6835f6d 100644 --- a/arch/i386/boot/tools/build.c +++ b/arch/i386/boot/tools/build.c @@ -70,7 +70,8 @@ void usage(void) int main(int argc, char ** argv) { - unsigned int i, c, sz, setup_sectors; + unsigned int i, sz, setup_sectors; + int c; u32 sys_size; byte major_root, minor_root; struct stat sb; -- cgit v1.1 From a77e3362a224212d9d3b9e6fdec44df2eef6cf92 Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:06 -0700 Subject: [PATCH] coverity: i386: scsi_lib buffer overrun fix The check in 627 BUG_ON(index > SG_MEMPOOL_NR); with SG_MEMPOOL_NR defined in 32 #define SG_MEMPOOL_NR (sizeof(scsi_sg_pools)/sizeof(struct scsi_host_sg_pool)) was not sufficient. sgp, set in 629 sgp = scsi_sg_pools + index; is dereferenced in 630 mempool_free(sgl, sgp->pool); Signed-off-by: Zaur Kambarov Cc: Cc: James Bottomley Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/scsi_lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 621dee8..10506f9 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -632,7 +632,7 @@ static void scsi_free_sgtable(struct scatterlist *sgl, int index) { struct scsi_host_sg_pool *sgp; - BUG_ON(index > SG_MEMPOOL_NR); + BUG_ON(index >= SG_MEMPOOL_NR); sgp = scsi_sg_pools + index; mempool_free(sgl, sgp->pool); -- cgit v1.1 From 9c101fd439dab60d6eba76afb35fd2696f42c63d Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:08 -0700 Subject: [PATCH] coverity: ipmi_msghandler() channels array overrun fix We fix the check in 1084, which was 1084 if (addr->channel > IPMI_NUM_CHANNELS) { 1085 spin_lock_irqsave(&intf->counter_lock, flags); 1086 intf->sent_invalid_commands++; 1087 spin_unlock_irqrestore(&intf->counter_lock, flags); 1088 rv = -EINVAL; 1089 goto out_err; 1090 } addr->channel is used in 1092 if (intf->channels[addr->channel].medium Definitions involved: 221 struct ipmi_channel channels[IPMI_MAX_CHANNELS]; 134 #define IPMI_MAX_CHANNELS 8 In /linux-2.6.12-rc6/include/linux/ipmi.h 148 #define IPMI_NUM_CHANNELS 0x10 Signed-off-by: Zaur Kambarov Cc: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_msghandler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 1813d0d..e16c13f 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1088,8 +1088,8 @@ static inline int i_ipmi_request(ipmi_user_t user, long seqid; int broadcast = 0; - if (addr->channel > IPMI_NUM_CHANNELS) { - spin_lock_irqsave(&intf->counter_lock, flags); + if (addr->channel >= IPMI_MAX_CHANNELS) { + spin_lock_irqsave(&intf->counter_lock, flags); intf->sent_invalid_commands++; spin_unlock_irqrestore(&intf->counter_lock, flags); rv = -EINVAL; -- cgit v1.1 From ec471dc484b8ca5352903ee28796b8b248313547 Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:10 -0700 Subject: [PATCH] coverity: fs/udf/namei.c null check "dir" was dereferenced before null check Signed-off-by: Zaur Kambarov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/udf/namei.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 3f6dc71..4673157 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -159,7 +159,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, char *nameptr; uint8_t lfi; uint16_t liu; - loff_t size = (udf_ext0_offset(dir) + dir->i_size) >> 2; + loff_t size; kernel_lb_addr bloc, eloc; uint32_t extoffset, elen, offset; struct buffer_head *bh = NULL; @@ -167,6 +167,8 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, if (!dir) return NULL; + size = (udf_ext0_offset(dir) + dir->i_size) >> 2; + f_pos = (udf_ext0_offset(dir) >> 2); fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; -- cgit v1.1 From c7f1721ef284c6e8257c7471a02148db76105036 Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:11 -0700 Subject: [PATCH] coverity: fs/ext3/super.c: match_int return check The return value of "match_int" is checked 27 out of 28 times In lib/parser.c 142 /** 143 * match_int: - scan a decimal representation of an integer from a substring_t 144 * @s: substring_t to be scanned 145 * @result: resulting integer on success 146 * 147 * Description: Attempts to parse the &substring_t @s as a decimal integer. On 148 * success, sets @result to the integer represented by the string and returns 0. 149 * Returns either -ENOMEM or -EINVAL on failure. 150 */ 151 int match_int(substring_t *s, int *result) 152 { 153 return match_number(s, result, 0); 154 } Signed-off-by: Zaur Kambarov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ext3/super.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/ext3/super.c b/fs/ext3/super.c index b4b3e8a..a6d1779 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -944,7 +944,8 @@ clear_qf_name: "for remount\n"); return 0; } - match_int(&args[0], &option); + if (match_int(&args[0], &option) != 0) + return 0; *n_blocks_count = option; break; case Opt_nobh: -- cgit v1.1 From 69f63c5c34d0b34ee2cbf10c5ff7fcff0404879e Mon Sep 17 00:00:00 2001 From: "KAMBAROV, ZAUR" Date: Tue, 28 Jun 2005 20:45:12 -0700 Subject: [PATCH] coverity: tty_ldisc_ref return null check We add a check of the return value of tty_ldisc_ref(), which is checked 7 out of 8 times, e.g.: 149 ld = tty_ldisc_ref(tty); 150 if (ld != NULL) { 151 if (ld->set_termios) 152 (ld->set_termios)(tty, &old_termios); 153 tty_ldisc_deref(ld); 154 } This defect was found automatically by Coverity Prevent, a static analysis tool. (akpm: presumably `ld' is never NULL. Oh well) Signed-off-by: Zaur Kambarov Cc: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tty_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c index 5859799..f19cf9d 100644 --- a/drivers/char/tty_ioctl.c +++ b/drivers/char/tty_ioctl.c @@ -476,11 +476,11 @@ int n_tty_ioctl(struct tty_struct * tty, struct file * file, ld = tty_ldisc_ref(tty); switch (arg) { case TCIFLUSH: - if (ld->flush_buffer) + if (ld && ld->flush_buffer) ld->flush_buffer(tty); break; case TCIOFLUSH: - if (ld->flush_buffer) + if (ld && ld->flush_buffer) ld->flush_buffer(tty); /* fall through */ case TCOFLUSH: -- cgit v1.1 From 450991bc1026135ee30482a4a806d069915ab2f6 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 28 Jun 2005 20:45:13 -0700 Subject: [PATCH] blk: __make_request efficiency In the case where the request is not able to be merged by the elevator, don't retake the lock and retry the merge mechanism after allocating a new request. Instead assume that the chance of a merge remains slim, and now that we've done most of the work allocating a request we may as well just go with it. Also be rid of the GFP_ATOMIC allocation: we've got working mempools for the block layer now, so let's save atomic memory for things like networking. Lastly, in get_request_wait, do an initial get_request call before going into the waitqueue. This is reported to help efficiency. Signed-off-by: Nick Piggin Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/ll_rw_blk.c | 62 ++++++++++++++++------------------------------- 1 file changed, 21 insertions(+), 41 deletions(-) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 6c98cf0..67431f2 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1971,10 +1971,11 @@ out: static struct request *get_request_wait(request_queue_t *q, int rw, struct bio *bio) { - DEFINE_WAIT(wait); struct request *rq; - do { + rq = get_request(q, rw, bio, GFP_NOIO); + while (!rq) { + DEFINE_WAIT(wait); struct request_list *rl = &q->rq; prepare_to_wait_exclusive(&rl->wait[rw], &wait, @@ -1999,7 +2000,7 @@ static struct request *get_request_wait(request_queue_t *q, int rw, put_io_context(ioc); } finish_wait(&rl->wait[rw], &wait); - } while (!rq); + } return rq; } @@ -2521,7 +2522,7 @@ EXPORT_SYMBOL(blk_attempt_remerge); static int __make_request(request_queue_t *q, struct bio *bio) { - struct request *req, *freereq = NULL; + struct request *req; int el_ret, rw, nr_sectors, cur_nr_sectors, barrier, err, sync; unsigned short prio; sector_t sector; @@ -2549,14 +2550,9 @@ static int __make_request(request_queue_t *q, struct bio *bio) goto end_io; } -again: spin_lock_irq(q->queue_lock); - if (elv_queue_empty(q)) { - blk_plug_device(q); - goto get_rq; - } - if (barrier) + if (unlikely(barrier) || elv_queue_empty(q)) goto get_rq; el_ret = elv_merge(q, &req, bio); @@ -2601,40 +2597,23 @@ again: elv_merged_request(q, req); goto out; - /* - * elevator says don't/can't merge. get new request - */ - case ELEVATOR_NO_MERGE: - break; - + /* ELV_NO_MERGE: elevator says don't/can't merge. */ default: - printk("elevator returned crap (%d)\n", el_ret); - BUG(); + ; } +get_rq: /* - * Grab a free request from the freelist - if that is empty, check - * if we are doing read ahead and abort instead of blocking for - * a free slot. + * Grab a free request. This is might sleep but can not fail. + */ + spin_unlock_irq(q->queue_lock); + req = get_request_wait(q, rw, bio); + /* + * After dropping the lock and possibly sleeping here, our request + * may now be mergeable after it had proven unmergeable (above). + * We don't worry about that case for efficiency. It won't happen + * often, and the elevators are able to handle it. */ -get_rq: - if (freereq) { - req = freereq; - freereq = NULL; - } else { - spin_unlock_irq(q->queue_lock); - if ((freereq = get_request(q, rw, bio, GFP_ATOMIC)) == NULL) { - /* - * READA bit set - */ - err = -EWOULDBLOCK; - if (bio_rw_ahead(bio)) - goto end_io; - - freereq = get_request_wait(q, rw, bio); - } - goto again; - } req->flags |= REQ_CMD; @@ -2663,10 +2642,11 @@ get_rq: req->rq_disk = bio->bi_bdev->bd_disk; req->start_time = jiffies; + spin_lock_irq(q->queue_lock); + if (elv_queue_empty(q)) + blk_plug_device(q); add_request(q, req); out: - if (freereq) - __blk_put_request(q, freereq); if (sync) __generic_unplug_device(q); -- cgit v1.1 From d6344532a26a318c128102507f6328aaafe02d4d Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 28 Jun 2005 20:45:14 -0700 Subject: [PATCH] blk: reduce locking Change around locking a bit for a result of 1-2 less spin lock unlock pairs in request submission paths. Signed-off-by: Nick Piggin Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/ll_rw_blk.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 67431f2..5caebe2 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1867,19 +1867,20 @@ static void freed_request(request_queue_t *q, int rw) #define blkdev_free_rq(list) list_entry((list)->next, struct request, queuelist) /* - * Get a free request, queue_lock must not be held + * Get a free request, queue_lock must be held. + * Returns NULL on failure, with queue_lock held. + * Returns !NULL on success, with queue_lock *not held*. */ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, int gfp_mask) { struct request *rq = NULL; struct request_list *rl = &q->rq; - struct io_context *ioc = get_io_context(gfp_mask); + struct io_context *ioc = get_io_context(GFP_ATOMIC); if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) goto out; - spin_lock_irq(q->queue_lock); if (rl->count[rw]+1 >= q->nr_requests) { /* * The queue will fill after this allocation, so set it as @@ -1907,7 +1908,6 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, * The queue is full and the allocating process is not a * "batcher", and not exempted by the IO scheduler */ - spin_unlock_irq(q->queue_lock); goto out; } @@ -1950,7 +1950,6 @@ rq_starved: if (unlikely(rl->count[rw] == 0)) rl->starved[rw] = 1; - spin_unlock_irq(q->queue_lock); goto out; } @@ -1967,6 +1966,8 @@ out: /* * No available requests for this queue, unplug the device and wait for some * requests to become available. + * + * Called with q->queue_lock held, and returns with it unlocked. */ static struct request *get_request_wait(request_queue_t *q, int rw, struct bio *bio) @@ -1986,7 +1987,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw, if (!rq) { struct io_context *ioc; - generic_unplug_device(q); + __generic_unplug_device(q); + spin_unlock_irq(q->queue_lock); io_schedule(); /* @@ -1998,6 +2000,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw, ioc = get_io_context(GFP_NOIO); ioc_set_batching(q, ioc); put_io_context(ioc); + + spin_lock_irq(q->queue_lock); } finish_wait(&rl->wait[rw], &wait); } @@ -2011,14 +2015,18 @@ struct request *blk_get_request(request_queue_t *q, int rw, int gfp_mask) BUG_ON(rw != READ && rw != WRITE); - if (gfp_mask & __GFP_WAIT) + spin_lock_irq(q->queue_lock); + if (gfp_mask & __GFP_WAIT) { rq = get_request_wait(q, rw, NULL); - else + } else { rq = get_request(q, rw, NULL, gfp_mask); + if (!rq) + spin_unlock_irq(q->queue_lock); + } + /* q->queue_lock is unlocked at this point */ return rq; } - EXPORT_SYMBOL(blk_get_request); /** @@ -2605,9 +2613,10 @@ static int __make_request(request_queue_t *q, struct bio *bio) get_rq: /* * Grab a free request. This is might sleep but can not fail. + * Returns with the queue unlocked. */ - spin_unlock_irq(q->queue_lock); req = get_request_wait(q, rw, bio); + /* * After dropping the lock and possibly sleeping here, our request * may now be mergeable after it had proven unmergeable (above). -- cgit v1.1 From fb3cc4320e1fd87143683b540e459a2e20fdc9bb Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Tue, 28 Jun 2005 20:45:15 -0700 Subject: [PATCH] blk: light iocontext ops get_io_context needlessly turned off interrupts and checked for racing io context creations. Both of which aren't needed, because the io context can only be created while in process context of the current process. Also, split the function in 2. A light version, current_io_context does not elevate the reference count specifically, but can be used when in process context, because the process holds a reference itself. Signed-off-by: Nick Piggin Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/ll_rw_blk.c | 56 +++++++++++++++++++++-------------------------- include/linux/blkdev.h | 1 + 2 files changed, 26 insertions(+), 31 deletions(-) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 5caebe2..1197462 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1876,7 +1876,7 @@ static struct request *get_request(request_queue_t *q, int rw, struct bio *bio, { struct request *rq = NULL; struct request_list *rl = &q->rq; - struct io_context *ioc = get_io_context(GFP_ATOMIC); + struct io_context *ioc = current_io_context(GFP_ATOMIC); if (unlikely(test_bit(QUEUE_FLAG_DRAIN, &q->queue_flags))) goto out; @@ -1959,7 +1959,6 @@ rq_starved: rq_init(q, rq); rq->rl = rl; out: - put_io_context(ioc); return rq; } @@ -1997,9 +1996,8 @@ static struct request *get_request_wait(request_queue_t *q, int rw, * up to a big batch of them for a small period time. * See ioc_batching, ioc_set_batching */ - ioc = get_io_context(GFP_NOIO); + ioc = current_io_context(GFP_NOIO); ioc_set_batching(q, ioc); - put_io_context(ioc); spin_lock_irq(q->queue_lock); } @@ -3282,24 +3280,20 @@ void exit_io_context(void) /* * If the current task has no IO context then create one and initialise it. - * If it does have a context, take a ref on it. + * Otherwise, return its existing IO context. * - * This is always called in the context of the task which submitted the I/O. - * But weird things happen, so we disable local interrupts to ensure exclusive - * access to *current. + * This returned IO context doesn't have a specifically elevated refcount, + * but since the current task itself holds a reference, the context can be + * used in general code, so long as it stays within `current` context. */ -struct io_context *get_io_context(int gfp_flags) +struct io_context *current_io_context(int gfp_flags) { struct task_struct *tsk = current; - unsigned long flags; struct io_context *ret; - local_irq_save(flags); ret = tsk->io_context; - if (ret) - goto out; - - local_irq_restore(flags); + if (likely(ret)) + return ret; ret = kmem_cache_alloc(iocontext_cachep, gfp_flags); if (ret) { @@ -3310,25 +3304,25 @@ struct io_context *get_io_context(int gfp_flags) ret->nr_batch_requests = 0; /* because this is 0 */ ret->aic = NULL; ret->cic = NULL; + tsk->io_context = ret; + } - local_irq_save(flags); - - /* - * very unlikely, someone raced with us in setting up the task - * io context. free new context and just grab a reference. - */ - if (!tsk->io_context) - tsk->io_context = ret; - else { - kmem_cache_free(iocontext_cachep, ret); - ret = tsk->io_context; - } + return ret; +} +EXPORT_SYMBOL(current_io_context); -out: +/* + * If the current task has no IO context then create one and initialise it. + * If it does have a context, take a ref on it. + * + * This is always called in the context of the task which submitted the I/O. + */ +struct io_context *get_io_context(int gfp_flags) +{ + struct io_context *ret; + ret = current_io_context(gfp_flags); + if (likely(ret)) atomic_inc(&ret->refcount); - local_irq_restore(flags); - } - return ret; } EXPORT_SYMBOL(get_io_context); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 21a8674..0881b5c 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -96,6 +96,7 @@ struct io_context { void put_io_context(struct io_context *ioc); void exit_io_context(void); +struct io_context *current_io_context(int gfp_flags); struct io_context *get_io_context(int gfp_flags); void copy_io_context(struct io_context **pdst, struct io_context **psrc); void swap_io_context(struct io_context **ioc1, struct io_context **ioc2); -- cgit v1.1 From 21fe3471c3aaa5c489c5d3a4d705291eb7511248 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Tue, 28 Jun 2005 20:45:16 -0700 Subject: [PATCH] ext3: reduce allocate-with-reservation lock latencies Currently in ext3 block reservation code, the global filesystem reservation tree lock (rsv_block) is hold during the process of searching for a space to make a new reservation window, including while scaning the block bitmap to verify if the avalible window has a free block. Holding the lock during bitmap scan is unnecessary and could possibly cause scalability issue and latency issues. This patch tries to address this by dropping the lock before scan the bitmap. Before that we need to reserve the open window in case someone else is targetting at the same window. Question was should we reserve the whole free reservable space or just the window size we need. Reserve the whole free reservable space will possibly force other threads which intended to do block allocation nearby move to another block group(cause bad layout). In this patch, we just reserve the desired size before drop the lock and scan the block bitmap. This patch fixed a ext3 reservation latency issue seen on a cvs check out test. Patch is tested with many fsx, tiobench, dbench and untar a kernel test. Signed-Off-By: Mingming Cao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/ext3/balloc.c | 135 ++++++++++++++++++++++++++----------------------------- fs/ext3/file.c | 4 ++ 2 files changed, 67 insertions(+), 72 deletions(-) diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index ccd632f..e463dca 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c @@ -749,24 +749,24 @@ fail_access: * to find a free region that is of my size and has not * been reserved. * - * on succeed, it returns the reservation window to be appended to. - * failed, return NULL. */ -static struct ext3_reserve_window_node *find_next_reservable_window( +static int find_next_reservable_window( struct ext3_reserve_window_node *search_head, - unsigned long size, int *start_block, + struct ext3_reserve_window_node *my_rsv, + struct super_block * sb, int start_block, int last_block) { struct rb_node *next; struct ext3_reserve_window_node *rsv, *prev; int cur; + int size = my_rsv->rsv_goal_size; /* TODO: make the start of the reservation window byte-aligned */ /* cur = *start_block & ~7;*/ - cur = *start_block; + cur = start_block; rsv = search_head; if (!rsv) - return NULL; + return -1; while (1) { if (cur <= rsv->rsv_end) @@ -782,11 +782,11 @@ static struct ext3_reserve_window_node *find_next_reservable_window( * space with expected-size (or more)... */ if (cur > last_block) - return NULL; /* fail */ + return -1; /* fail */ prev = rsv; next = rb_next(&rsv->rsv_node); - rsv = list_entry(next, struct ext3_reserve_window_node, rsv_node); + rsv = list_entry(next,struct ext3_reserve_window_node,rsv_node); /* * Reached the last reservation, we can just append to the @@ -813,8 +813,25 @@ static struct ext3_reserve_window_node *find_next_reservable_window( * return the reservation window that we could append to. * succeed. */ - *start_block = cur; - return prev; + + if ((prev != my_rsv) && (!rsv_is_empty(&my_rsv->rsv_window))) + rsv_window_remove(sb, my_rsv); + + /* + * Let's book the whole avaliable window for now. We will check the + * disk bitmap later and then, if there are free blocks then we adjust + * the window size if it's larger than requested. + * Otherwise, we will remove this node from the tree next time + * call find_next_reservable_window. + */ + my_rsv->rsv_start = cur; + my_rsv->rsv_end = cur + size - 1; + my_rsv->rsv_alloc_hit = 0; + + if (prev != my_rsv) + ext3_rsv_window_add(sb, my_rsv); + + return 0; } /** @@ -852,6 +869,7 @@ static struct ext3_reserve_window_node *find_next_reservable_window( * @sb: the super block * @group: the group we are trying to allocate in * @bitmap_bh: the block group block bitmap + * */ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, int goal, struct super_block *sb, @@ -860,10 +878,10 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, struct ext3_reserve_window_node *search_head; int group_first_block, group_end_block, start_block; int first_free_block; - int reservable_space_start; - struct ext3_reserve_window_node *prev_rsv; struct rb_root *fs_rsv_root = &EXT3_SB(sb)->s_rsv_window_root; unsigned long size; + int ret; + spinlock_t *rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; group_first_block = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + group * EXT3_BLOCKS_PER_GROUP(sb); @@ -875,6 +893,7 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, start_block = goal + group_first_block; size = my_rsv->rsv_goal_size; + if (!rsv_is_empty(&my_rsv->rsv_window)) { /* * if the old reservation is cross group boundary @@ -908,6 +927,8 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, my_rsv->rsv_goal_size= size; } } + + spin_lock(rsv_lock); /* * shift the search start to the window near the goal block */ @@ -921,11 +942,16 @@ static int alloc_new_reservation(struct ext3_reserve_window_node *my_rsv, * need to check the bitmap after we found a reservable window. */ retry: - prev_rsv = find_next_reservable_window(search_head, size, - &start_block, group_end_block); - if (prev_rsv == NULL) - goto failed; - reservable_space_start = start_block; + ret = find_next_reservable_window(search_head, my_rsv, sb, + start_block, group_end_block); + + if (ret == -1) { + if (!rsv_is_empty(&my_rsv->rsv_window)) + rsv_window_remove(sb, my_rsv); + spin_unlock(rsv_lock); + return -1; + } + /* * On success, find_next_reservable_window() returns the * reservation window where there is a reservable space after it. @@ -937,8 +963,9 @@ retry: * block. Search start from the start block of the reservable space * we just found. */ + spin_unlock(rsv_lock); first_free_block = bitmap_search_next_usable_block( - reservable_space_start - group_first_block, + my_rsv->rsv_start - group_first_block, bitmap_bh, group_end_block - group_first_block + 1); if (first_free_block < 0) { @@ -946,54 +973,29 @@ retry: * no free block left on the bitmap, no point * to reserve the space. return failed. */ - goto failed; + spin_lock(rsv_lock); + if (!rsv_is_empty(&my_rsv->rsv_window)) + rsv_window_remove(sb, my_rsv); + spin_unlock(rsv_lock); + return -1; /* failed */ } + start_block = first_free_block + group_first_block; /* * check if the first free block is within the - * free space we just found + * free space we just reserved */ - if ((start_block >= reservable_space_start) && - (start_block < reservable_space_start + size)) - goto found_rsv_window; + if (start_block >= my_rsv->rsv_start && start_block < my_rsv->rsv_end) + return 0; /* success */ /* * if the first free bit we found is out of the reservable space - * this means there is no free block on the reservable space - * we should continue search for next reservable space, + * continue search for next reservable space, * start from where the free block is, * we also shift the list head to where we stopped last time */ - search_head = prev_rsv; + search_head = my_rsv; + spin_lock(rsv_lock); goto retry; - -found_rsv_window: - /* - * great! the reservable space contains some free blocks. - * if the search returns that we should add the new - * window just next to where the old window, we don't - * need to remove the old window first then add it to the - * same place, just update the new start and new end. - */ - if (my_rsv != prev_rsv) { - if (!rsv_is_empty(&my_rsv->rsv_window)) - rsv_window_remove(sb, my_rsv); - } - my_rsv->rsv_start = reservable_space_start; - my_rsv->rsv_end = my_rsv->rsv_start + size - 1; - my_rsv->rsv_alloc_hit = 0; - if (my_rsv != prev_rsv) { - ext3_rsv_window_add(sb, my_rsv); - } - return 0; /* succeed */ -failed: - /* - * failed to find a new reservation window in the current - * group, remove the current(stale) reservation window - * if there is any - */ - if (!rsv_is_empty(&my_rsv->rsv_window)) - rsv_window_remove(sb, my_rsv); - return -1; /* failed */ } /* @@ -1023,7 +1025,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, int goal, struct ext3_reserve_window_node * my_rsv, int *errp) { - spinlock_t *rsv_lock; unsigned long group_first_block; int ret = 0; int fatal; @@ -1052,7 +1053,6 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, NULL); goto out; } - rsv_lock = &EXT3_SB(sb)->s_rsv_window_lock; /* * goal is a group relative block number (if there is a goal) * 0 < goal < EXT3_BLOCKS_PER_GROUP(sb) @@ -1078,30 +1078,21 @@ ext3_try_to_allocate_with_rsv(struct super_block *sb, handle_t *handle, * then we could go to allocate from the reservation window directly. */ while (1) { - struct ext3_reserve_window rsv_copy; - - rsv_copy._rsv_start = my_rsv->rsv_start; - rsv_copy._rsv_end = my_rsv->rsv_end; - - if (rsv_is_empty(&rsv_copy) || (ret < 0) || - !goal_in_my_reservation(&rsv_copy, goal, group, sb)) { - spin_lock(rsv_lock); + if (rsv_is_empty(&my_rsv->rsv_window) || (ret < 0) || + !goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) { ret = alloc_new_reservation(my_rsv, goal, sb, group, bitmap_bh); - rsv_copy._rsv_start = my_rsv->rsv_start; - rsv_copy._rsv_end = my_rsv->rsv_end; - spin_unlock(rsv_lock); if (ret < 0) break; /* failed */ - if (!goal_in_my_reservation(&rsv_copy, goal, group, sb)) + if (!goal_in_my_reservation(&my_rsv->rsv_window, goal, group, sb)) goal = -1; } - if ((rsv_copy._rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) - || (rsv_copy._rsv_end < group_first_block)) + if ((my_rsv->rsv_start >= group_first_block + EXT3_BLOCKS_PER_GROUP(sb)) + || (my_rsv->rsv_end < group_first_block)) BUG(); ret = ext3_try_to_allocate(sb, handle, group, bitmap_bh, goal, - &rsv_copy); + &my_rsv->rsv_window); if (ret >= 0) { my_rsv->rsv_alloc_hit++; break; /* succeed */ diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 5ad8cf02..98e7834 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c @@ -36,7 +36,11 @@ static int ext3_release_file (struct inode * inode, struct file * filp) /* if we are the last writer on the inode, drop the block reservation */ if ((filp->f_mode & FMODE_WRITE) && (atomic_read(&inode->i_writecount) == 1)) + { + down(&EXT3_I(inode)->truncate_sem); ext3_discard_reservation(inode); + up(&EXT3_I(inode)->truncate_sem); + } if (is_dx(inode) && filp->private_data) ext3_htree_free_dir_info(filp->private_data); -- cgit v1.1 From 200803dfe4ff772740d63db725ab2f1b185ccf92 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 28 Jun 2005 20:45:18 -0700 Subject: [PATCH] irqpoll Anyone reporting a stuck IRQ should try these options. Its effectiveness varies we've found in the Fedora case. Quite a few systems with misdescribed IRQ routing just work when you use irqpoll. It also fixes up the VIA systems although thats now fixed with the VIA quirk (which we could just make default as its what Redmond OS does but Linus didn't like it historically). A small number of systems have jammed IRQ sources or misdescribes that cause an IRQ that we have no handler registered anywhere for. In those cases it doesn't help. Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/kernel-parameters.txt | 15 +++++ arch/ppc64/kernel/irq.c | 2 +- include/linux/irq.h | 5 +- kernel/irq/handle.c | 2 +- kernel/irq/spurious.c | 113 +++++++++++++++++++++++++++++++++++- 5 files changed, 131 insertions(+), 6 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 0f71251..67e99f1 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -437,6 +437,10 @@ running once the system is up. Format: {"of[f]" | "sk[ipmbr]"} See comment in arch/i386/boot/edd.S + edd [EDD] + Format: {"of[f]" | "sk[ipmbr]"} + See comment in arch/i386/boot/edd.S + eicon= [HW,ISDN] Format: ,, @@ -622,6 +626,17 @@ running once the system is up. ips= [HW,SCSI] Adaptec / IBM ServeRAID controller See header of drivers/scsi/ips.c. + irqfixup [HW] + When an interrupt is not handled search all handlers + for it. Intended to get systems with badly broken + firmware running. + + irqpoll [HW] + When an interrupt is not handled search all handlers + for it. Also check all handlers each timer + interrupt. Intended to get systems with badly broken + firmware running. + isapnp= [ISAPNP] Format: , , , diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c..ffe3006 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -245,7 +245,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) spin_lock(&desc->lock); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; diff --git a/include/linux/irq.h b/include/linux/irq.h index 1227779..069d3b8 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -85,9 +85,10 @@ extern int no_irq_affinity; extern int noirqdebug_setup(char *str); extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, - struct irqaction *action); + struct irqaction *action); extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); -extern void note_interrupt(unsigned int irq, irq_desc_t *desc, int action_ret); +extern void note_interrupt(unsigned int irq, irq_desc_t *desc, + int action_ret, struct pt_regs *regs); extern int can_request_irq(unsigned int irq, unsigned long irqflags); extern void init_irq_proc(void); diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 436c7d9..c29f83c 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c @@ -172,7 +172,7 @@ fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs) spin_lock(&desc->lock); if (!noirqdebug) - note_interrupt(irq, desc, action_ret); + note_interrupt(irq, desc, action_ret, regs); if (likely(!(desc->status & IRQ_PENDING))) break; desc->status &= ~IRQ_PENDING; diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c index ba039e8..7df9abd 100644 --- a/kernel/irq/spurious.c +++ b/kernel/irq/spurious.c @@ -11,6 +11,83 @@ #include #include +static int irqfixup; + +/* + * Recovery handler for misrouted interrupts. + */ + +static int misrouted_irq(int irq, struct pt_regs *regs) +{ + int i; + irq_desc_t *desc; + int ok = 0; + int work = 0; /* Did we do work for a real IRQ */ + + for(i = 1; i < NR_IRQS; i++) { + struct irqaction *action; + + if (i == irq) /* Already tried */ + continue; + desc = &irq_desc[i]; + spin_lock(&desc->lock); + action = desc->action; + /* Already running on another processor */ + if (desc->status & IRQ_INPROGRESS) { + /* + * Already running: If it is shared get the other + * CPU to go looking for our mystery interrupt too + */ + if (desc->action && (desc->action->flags & SA_SHIRQ)) + desc->status |= IRQ_PENDING; + spin_unlock(&desc->lock); + continue; + } + /* Honour the normal IRQ locking */ + desc->status |= IRQ_INPROGRESS; + spin_unlock(&desc->lock); + while (action) { + /* Only shared IRQ handlers are safe to call */ + if (action->flags & SA_SHIRQ) { + if (action->handler(i, action->dev_id, regs) == + IRQ_HANDLED) + ok = 1; + } + action = action->next; + } + local_irq_disable(); + /* Now clean up the flags */ + spin_lock(&desc->lock); + action = desc->action; + + /* + * While we were looking for a fixup someone queued a real + * IRQ clashing with our walk + */ + + while ((desc->status & IRQ_PENDING) && action) { + /* + * Perform real IRQ processing for the IRQ we deferred + */ + work = 1; + spin_unlock(&desc->lock); + handle_IRQ_event(i, regs, action); + spin_lock(&desc->lock); + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; + /* + * If we did actual work for the real IRQ line we must let the + * IRQ controller clean up too + */ + if(work) + desc->handler->end(i); + spin_unlock(&desc->lock); + } + /* So the caller can adjust the irq error counts */ + return ok; +} + /* * If 99,900 of the previous 100,000 interrupts have not been handled * then assume that the IRQ is stuck in some manner. Drop a diagnostic @@ -31,7 +108,8 @@ __report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) printk(KERN_ERR "irq event %d: bogus return value %x\n", irq, action_ret); } else { - printk(KERN_ERR "irq %d: nobody cared!\n", irq); + printk(KERN_ERR "irq %d: nobody cared (try booting with " + "the \"irqpoll\" option)\n", irq); } dump_stack(); printk(KERN_ERR "handlers:\n"); @@ -55,7 +133,8 @@ static void report_bad_irq(unsigned int irq, irq_desc_t *desc, irqreturn_t actio } } -void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) +void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret, + struct pt_regs *regs) { if (action_ret != IRQ_HANDLED) { desc->irqs_unhandled++; @@ -63,6 +142,15 @@ void note_interrupt(unsigned int irq, irq_desc_t *desc, irqreturn_t action_ret) report_bad_irq(irq, desc, action_ret); } + if (unlikely(irqfixup)) { + /* Don't punish working computers */ + if ((irqfixup == 2 && irq == 0) || action_ret == IRQ_NONE) { + int ok = misrouted_irq(irq, regs); + if (action_ret == IRQ_NONE) + desc->irqs_unhandled -= ok; + } + } + desc->irq_count++; if (desc->irq_count < 100000) return; @@ -94,3 +182,24 @@ int __init noirqdebug_setup(char *str) __setup("noirqdebug", noirqdebug_setup); +static int __init irqfixup_setup(char *str) +{ + irqfixup = 1; + printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n"); + printk(KERN_WARNING "This may impact system performance.\n"); + return 1; +} + +__setup("irqfixup", irqfixup_setup); + +static int __init irqpoll_setup(char *str) +{ + irqfixup = 2; + printk(KERN_WARNING "Misrouted IRQ fixup and polling support " + "enabled\n"); + printk(KERN_WARNING "This may significantly impact system " + "performance\n"); + return 1; +} + +__setup("irqpoll", irqpoll_setup); -- cgit v1.1 From 96b6aba08762f09e5dfa616854cb80ce054a7bf8 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Jun 2005 20:45:20 -0700 Subject: [PATCH] V4L maintainer patch This patch updates maintainer info for BTTV and V4L. Signed-off-by: Mauro Carvalho Chehab Acked-by: Gerd Knorr Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 4db63de..19a9a1c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -512,11 +512,11 @@ W: http://linuxppc64.org S: Supported BTTV VIDEO4LINUX DRIVER -P: Gerd Knorr -M: kraxel@bytesex.org +P: Mauro Carvalho Chehab +M: mchehab@brturbo.com.br L: video4linux-list@redhat.com -W: http://bytesex.org/bttv/ -S: Orphan +W: http://linuxtv.org +S: Maintained BUSLOGIC SCSI DRIVER P: Leonard N. Zubkoff @@ -2625,10 +2625,11 @@ W: http://rio500.sourceforge.net S: Maintained VIDEO FOR LINUX -P: Gerd Knorr -M: kraxel@bytesex.org +P: Mauro Carvalho Chehab +M: mchehab@brturbo.com.br L: video4linux-list@redhat.com -S: Orphan +W: http://linuxtv.org +S: Maintained W1 DALLAS'S 1-WIRE BUS P: Evgeniy Polyakov -- cgit v1.1 From 586b0cab2516640fec4dffc3049c4d8bca188f89 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Jun 2005 20:45:21 -0700 Subject: [PATCH] v4l: tuner improvements *tuner-core.c: - some tuner_info msgs will be generated only if insmod opt tuner_debug enabled. - Implemented tuner-core support for VIDIO_S_TUNER to allow changing mono/stereo mode - Remove unneeded config options. - I2C_CLIENT_MULTI option removed. - support for Philips FMD12ME hybrid tuner - allow to initialize with another tuner - Move PHILIPS_FMD initialization code to set_type function, * tda8290: - Fix dumb error in tda8290 tunning. - Radio tuner uses high-precision step instead of 62.5 KHz. *tea5767.c: - tuner_info msgs will be generated only if insmod tuner option tuner_debug enabled. - some cleanups for better reading. - Radio tuner uses high-precision step instead of 62.5 KHz. - Changing radio mode stereo/mono for tea5767 working. *tuner-simple.c: - TNF9533-D/IF UHF fixup. - Radio tuners now uses high-precision step instead of 62.5 KHz. *mt20xx.c: - Radio tuner uses high-precision step instead of 62.5 KHz. *tda9887.c: - tab and blank spaces corrections. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Gerd Knorr Signed-off-by: Nickolay V Shmyrev Signed-off-by: Hartmut Hackmann Signed-off-by: Michael Krufky Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/Makefile | 3 +- drivers/media/video/mt20xx.c | 6 +- drivers/media/video/tda8290.c | 20 ++- drivers/media/video/tda9887.c | 7 +- drivers/media/video/tea5767.c | 334 +++++++++++++++++++++++++++++++++++++ drivers/media/video/tuner-core.c | 163 +++++++++--------- drivers/media/video/tuner-simple.c | 34 ++-- include/media/tuner.h | 20 ++- 8 files changed, 471 insertions(+), 116 deletions(-) create mode 100644 drivers/media/video/tea5767.c diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 2dc906f..810e7aa 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -7,8 +7,7 @@ bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \ zoran-objs := zr36120.o zr36120_i2c.o zr36120_mem.o zr36067-objs := zoran_procfs.o zoran_device.o \ zoran_driver.o zoran_card.o -tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o - +tuner-objs := tuner-core.o tuner-simple.o mt20xx.o tda8290.o tea5767.o obj-$(CONFIG_VIDEO_DEV) += videodev.o v4l2-common.o v4l1-compat.o obj-$(CONFIG_VIDEO_BT848) += bttv.o msp3400.o tvaudio.o \ diff --git a/drivers/media/video/mt20xx.c b/drivers/media/video/mt20xx.c index 95ad17b..9c005cb 100644 --- a/drivers/media/video/mt20xx.c +++ b/drivers/media/video/mt20xx.c @@ -1,5 +1,5 @@ /* - * $Id: mt20xx.c,v 1.4 2005/03/04 09:24:56 kraxel Exp $ + * $Id: mt20xx.c,v 1.5 2005/06/16 08:29:49 nsh Exp $ * * i2c tv tuner chip device driver * controls microtune tuners, mt2032 + mt2050 at the moment. @@ -295,8 +295,8 @@ static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq) int if2 = t->radio_if2; // per Manual for FM tuning: first if center freq. 1085 MHz - mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */, - 1085*1000*1000,if2,if2,if2); + mt2032_set_if_freq(c, freq * 1000 / 16, + 1085*1000*1000,if2,if2,if2); } // Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001 diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index b27cc34..f59d460 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -1,5 +1,5 @@ /* - * $Id: tda8290.c,v 1.7 2005/03/07 12:01:51 kraxel Exp $ + * $Id: tda8290.c,v 1.11 2005/06/18 06:09:06 nsh Exp $ * * i2c tv tuner chip device driver * controls the philips tda8290+75 tuner chip combo. @@ -69,7 +69,7 @@ static __u8 get_freq_entry( struct freq_entry* table, __u16 freq) static unsigned char i2c_enable_bridge[2] = { 0x21, 0xC0 }; static unsigned char i2c_disable_bridge[2] = { 0x21, 0x80 }; static unsigned char i2c_init_tda8275[14] = { 0x00, 0x00, 0x00, 0x00, - 0x7C, 0x04, 0xA3, 0x3F, + 0xfC, 0x04, 0xA3, 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 }; static unsigned char i2c_set_VS[2] = { 0x30, 0x6F }; @@ -138,16 +138,24 @@ static int tda8290_tune(struct i2c_client *c) static void set_frequency(struct tuner *t, u16 ifc) { - u32 N = (((t->freq<<3)+ifc)&0x3fffc); + u32 freq; + u32 N; - N = N >> get_freq_entry(div_table, t->freq); + if (t->mode == V4L2_TUNER_RADIO) + freq = t->freq / 1000; + else + freq = t->freq; + + N = (((freq<<3)+ifc)&0x3fffc); + + N = N >> get_freq_entry(div_table, freq); t->i2c_set_freq[0] = 0; t->i2c_set_freq[1] = (unsigned char)(N>>8); t->i2c_set_freq[2] = (unsigned char) N; t->i2c_set_freq[3] = 0x40; t->i2c_set_freq[4] = 0x52; - t->i2c_set_freq[5] = get_freq_entry(band_table, t->freq); - t->i2c_set_freq[6] = get_freq_entry(agc_table, t->freq); + t->i2c_set_freq[5] = get_freq_entry(band_table, freq); + t->i2c_set_freq[6] = get_freq_entry(agc_table, freq); t->i2c_set_freq[7] = 0x8f; } diff --git a/drivers/media/video/tda9887.c b/drivers/media/video/tda9887.c index 3977363..ee35562 100644 --- a/drivers/media/video/tda9887.c +++ b/drivers/media/video/tda9887.c @@ -368,7 +368,7 @@ static int tda9887_set_tvnorm(struct tda9887 *t, char *buf) if (t->radio_mode == V4L2_TUNER_MODE_MONO) norm = &radio_mono; else - norm = &radio_stereo; + norm = &radio_stereo; } else { for (i = 0; i < ARRAY_SIZE(tvnorms); i++) { if (tvnorms[i].std & t->std) { @@ -566,7 +566,6 @@ static int tda9887_configure(struct tda9887 *t) if (UNSET != t->pinnacle_id) { tda9887_set_pinnacle(t,buf); } - tda9887_set_config(t,buf); tda9887_set_insmod(t,buf); @@ -615,8 +614,8 @@ static int tda9887_attach(struct i2c_adapter *adap, int addr, int kind) t->pinnacle_id = UNSET; t->radio_mode = V4L2_TUNER_MODE_STEREO; - i2c_set_clientdata(&t->client, t); - i2c_attach_client(&t->client); + i2c_set_clientdata(&t->client, t); + i2c_attach_client(&t->client); return 0; } diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c new file mode 100644 index 0000000..a29f08f --- /dev/null +++ b/drivers/media/video/tea5767.c @@ -0,0 +1,334 @@ +/* + * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview + * I2C address is allways 0xC0. + * + * $Id: tea5767.c,v 1.11 2005/06/21 15:40:33 mchehab Exp $ + * + * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) + * This code is placed under the terms of the GNU General Public License + * + * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa + * from their contributions on DScaler. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* Declared at tuner-core.c */ +extern unsigned int tuner_debug; + +#define PREFIX "TEA5767 " + +/*****************************************************************************/ + +/****************************** + * Write mode register values * + ******************************/ + +/* First register */ +#define TEA5767_MUTE 0x80 /* Mutes output */ +#define TEA5767_SEARCH 0x40 /* Activates station search */ +/* Bits 0-5 for divider MSB */ + +/* Second register */ +/* Bits 0-7 for divider LSB */ + +/* Third register */ + +/* Station search from botton to up */ +#define TEA5767_SEARCH_UP 0x80 + +/* Searches with ADC output = 10 */ +#define TEA5767_SRCH_HIGH_LVL 0x60 + +/* Searches with ADC output = 10 */ +#define TEA5767_SRCH_MID_LVL 0x40 + +/* Searches with ADC output = 5 */ +#define TEA5767_SRCH_LOW_LVL 0x20 + +/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */ +#define TEA5767_HIGH_LO_INJECT 0x10 + +/* Disable stereo */ +#define TEA5767_MONO 0x08 + +/* Disable right channel and turns to mono */ +#define TEA5767_MUTE_RIGHT 0x04 + +/* Disable left channel and turns to mono */ +#define TEA5767_MUTE_LEFT 0x02 + +#define TEA5767_PORT1_HIGH 0x01 + +/* Forth register */ +#define TEA5767_PORT2_HIGH 0x80 +/* Chips stops working. Only I2C bus remains on */ +#define TEA5767_STDBY 0x40 + +/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */ +#define TEA5767_JAPAN_BAND 0x20 + +/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */ +#define TEA5767_XTAL_32768 0x10 + +/* Cuts weak signals */ +#define TEA5767_SOFT_MUTE 0x08 + +/* Activates high cut control */ +#define TEA5767_HIGH_CUT_CTRL 0x04 + +/* Activates stereo noise control */ +#define TEA5767_ST_NOISE_CTL 0x02 + +/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */ +#define TEA5767_SRCH_IND 0x01 + +/* Fiveth register */ + +/* By activating, it will use Xtal at 13 MHz as reference for divider */ +#define TEA5767_PLLREF_ENABLE 0x80 + +/* By activating, deemphasis=50, or else, deemphasis of 50us */ +#define TEA5767_DEEMPH_75 0X40 + +/***************************** + * Read mode register values * + *****************************/ + +/* First register */ +#define TEA5767_READY_FLAG_MASK 0x80 +#define TEA5767_BAND_LIMIT_MASK 0X40 +/* Bits 0-5 for divider MSB after search or preset */ + +/* Second register */ +/* Bits 0-7 for divider LSB after search or preset */ + +/* Third register */ +#define TEA5767_STEREO_MASK 0x80 +#define TEA5767_IF_CNTR_MASK 0x7f + +/* Four register */ +#define TEA5767_ADC_LEVEL_MASK 0xf0 + +/* should be 0 */ +#define TEA5767_CHIP_ID_MASK 0x0f + +/* Fiveth register */ +/* Reserved for future extensions */ +#define TEA5767_RESERVED_MASK 0xff + +/*****************************************************************************/ + +static void set_tv_freq(struct i2c_client *c, unsigned int freq) +{ + struct tuner *t = i2c_get_clientdata(c); + + tuner_warn("This tuner doesn't support TV freq.\n"); +} + +static void tea5767_status_dump(unsigned char *buffer) +{ + unsigned int div, frq; + + if (TEA5767_READY_FLAG_MASK & buffer[0]) + printk(PREFIX "Ready Flag ON\n"); + else + printk(PREFIX "Ready Flag OFF\n"); + + if (TEA5767_BAND_LIMIT_MASK & buffer[0]) + printk(PREFIX "Tuner at band limit\n"); + else + printk(PREFIX "Tuner not at band limit\n"); + + div=((buffer[0]&0x3f)<<8) | buffer[1]; + + switch (TEA5767_HIGH_LO_32768) { + case TEA5767_HIGH_LO_13MHz: + frq = 1000*(div*50-700-225)/4; /* Freq in KHz */ + break; + case TEA5767_LOW_LO_13MHz: + frq = 1000*(div*50+700+225)/4; /* Freq in KHz */ + break; + case TEA5767_LOW_LO_32768: + frq = 1000*(div*32768/1000+700+225)/4; /* Freq in KHz */ + break; + case TEA5767_HIGH_LO_32768: + default: + frq = 1000*(div*32768/1000-700-225)/4; /* Freq in KHz */ + break; + } + buffer[0] = (div>>8) & 0x3f; + buffer[1] = div & 0xff; + + printk(PREFIX "Frequency %d.%03d KHz (divider = 0x%04x)\n", + frq/1000,frq%1000,div); + + if (TEA5767_STEREO_MASK & buffer[2]) + printk(PREFIX "Stereo\n"); + else + printk(PREFIX "Mono\n"); + + printk(PREFIX "IF Counter = %d\n",buffer[2] & TEA5767_IF_CNTR_MASK); + + printk(PREFIX "ADC Level = %d\n",(buffer[3] & TEA5767_ADC_LEVEL_MASK)>>4); + + printk(PREFIX "Chip ID = %d\n",(buffer[3] & TEA5767_CHIP_ID_MASK)); + + printk(PREFIX "Reserved = 0x%02x\n",(buffer[4] & TEA5767_RESERVED_MASK)); +} + +/* Freq should be specifyed at 62.5 Hz */ +static void set_radio_freq(struct i2c_client *c, unsigned int frq) +{ + struct tuner *t = i2c_get_clientdata(c); + unsigned char buffer[5]; + unsigned div; + int rc; + + if ( tuner_debug ) + printk(PREFIX "radio freq counter %d\n",frq); + + /* Rounds freq to next decimal value - for 62.5 KHz step */ + /* frq = 20*(frq/16)+radio_frq[frq%16]; */ + + buffer[2] = TEA5767_PORT1_HIGH; + buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL | TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND; + buffer[4]=0; + + if (t->audmode == V4L2_TUNER_MODE_MONO) { + tuner_dbg("TEA5767 set to mono\n"); + buffer[2] |= TEA5767_MONO; + } else + tuner_dbg("TEA5767 set to stereo\n"); + + switch (t->type) { + case TEA5767_HIGH_LO_13MHz: + tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); + buffer[2] |= TEA5767_HIGH_LO_INJECT; + buffer[4] |= TEA5767_PLLREF_ENABLE; + div = (frq*4/16+700+225+25)/50; + break; + case TEA5767_LOW_LO_13MHz: + tuner_dbg("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); + + buffer[4] |= TEA5767_PLLREF_ENABLE; + div = (frq*4/16-700-225+25)/50; + break; + case TEA5767_LOW_LO_32768: + tuner_dbg("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); + buffer[3] |= TEA5767_XTAL_32768; + /* const 700=4000*175 Khz - to adjust freq to right value */ + div = (1000*(frq*4/16-700-225)+16384)>>15; + break; + case TEA5767_HIGH_LO_32768: + default: + tuner_dbg("TEA5767 radio HIGH LO inject xtal @ 32,768 MHz\n"); + + buffer[2] |= TEA5767_HIGH_LO_INJECT; + buffer[3] |= TEA5767_XTAL_32768; + div = (1000*(frq*4/16+700+225)+16384)>>15; + break; + } + buffer[0] = (div>>8) & 0x3f; + buffer[1] = div & 0xff; + + if ( tuner_debug ) + tea5767_status_dump(buffer); + + if (5 != (rc = i2c_master_send(c,buffer,5))) + tuner_warn("i2c i/o error: rc == %d (should be 5)\n",rc); +} + +static int tea5767_signal(struct i2c_client *c) +{ + unsigned char buffer[5]; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + memset(buffer,0,sizeof(buffer)); + if (5 != (rc = i2c_master_recv(c,buffer,5))) + tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); + + return ((buffer[3] & TEA5767_ADC_LEVEL_MASK) <<(13-4)); +} + +static int tea5767_stereo(struct i2c_client *c) +{ + unsigned char buffer[5]; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + memset(buffer,0,sizeof(buffer)); + if (5 != (rc = i2c_master_recv(c,buffer,5))) + tuner_warn ( "i2c i/o error: rc == %d (should be 5)\n",rc); + + rc = buffer[2] & TEA5767_STEREO_MASK; + + if ( tuner_debug ) + tuner_dbg("TEA5767 radio ST GET = %02x\n", rc); + + return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0); +} + +int tea_detection(struct i2c_client *c) +{ + unsigned char buffer[5]= { 0xff, 0xff, 0xff, 0xff, 0xff }; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + if (5 != (rc = i2c_master_recv(c,buffer,5))) { + tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc ); + return EINVAL; + } + + /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */ + if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && + buffer[0] == buffer[3] && buffer[0] == buffer[4]) { + tuner_warn ( "All bytes are equal. It is not a TEA5767\n" ); + return EINVAL; + } + + /* Status bytes: + * Byte 4: bit 3:1 : CI (Chip Identification) == 0 + * bit 0 : internally set to 0 + * Byte 5: bit 7:0 : == 0 + */ + + if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { + tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" ); + return EINVAL; + } + tuner_warn ( "TEA5767 detected.\n" ); + return 0; +} + +int tea5767_tuner_init(struct i2c_client *c) +{ + struct tuner *t = i2c_get_clientdata(c); + + if (tea_detection(c)==EINVAL) return EINVAL; + + tuner_info("type set to %d (%s)\n", + t->type, TEA5767_TUNER_NAME); + strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name)); + + t->tv_freq = set_tv_freq; + t->radio_freq = set_radio_freq; + t->has_signal = tea5767_signal; + t->is_stereo = tea5767_stereo; + + return (0); +} diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index eaabfc8..6f6bf4a 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-core.c,v 1.15 2005/06/12 01:36:14 mchehab Exp $ + * $Id: tuner-core.c,v 1.29 2005/06/21 15:40:33 mchehab Exp $ * * i2c tv tuner chip device driver * core core, i.e. kernel interfaces, registering and so on @@ -26,7 +26,6 @@ /* * comment line bellow to return to old behavor, where only one I2C device is supported */ -#define CONFIG_TUNER_MULTI_I2C /**/ #define UNSET (-1U) @@ -58,9 +57,7 @@ MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); MODULE_LICENSE("GPL"); static int this_adap; -#ifdef CONFIG_TUNER_MULTI_I2C static unsigned short first_tuner, tv_tuner, radio_tuner; -#endif static struct i2c_driver driver; static struct i2c_client client_template; @@ -81,26 +78,9 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) return; } if (freq < tv_range[0]*16 || freq > tv_range[1]*16) { - - if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { - /* V4L2_TUNER_CAP_LOW frequency */ - - tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for TV. Tuners yet doesn't support converting it to valid freq.\n"); - - t->tv_freq(c,freq>>10); - - return; - } else { - /* FIXME: better do that chip-specific, but - right now we don't have that in the config - struct and this way is still better than no - check at all */ tuner_info("TV freq (%d.%02d) out of range (%d-%d)\n", freq/16,freq%16*100/16,tv_range[0],tv_range[1]); - return; - } } - tuner_dbg("62.5 Khz freq step selected for TV.\n"); t->tv_freq(c,freq); } @@ -116,31 +96,18 @@ static void set_radio_freq(struct i2c_client *c, unsigned int freq) tuner_info("no radio tuning for this one, sorry.\n"); return; } - if (freq < radio_range[0]*16 || freq > radio_range[1]*16) { - if (freq >= tv_range[0]*16364 && freq <= tv_range[1]*16384) { - /* V4L2_TUNER_CAP_LOW frequency */ - if (t->type == TUNER_TEA5767) { - tuner_info("radio freq step 62.5Hz (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); - t->radio_freq(c,freq>>10); - return; - } - - tuner_dbg("V4L2_TUNER_CAP_LOW freq selected for Radio. Tuners yet doesn't support converting it to valid freq.\n"); - - tuner_info("radio freq (%d.%06d)\n",(freq>>14),freq%(1<<14)*10000); - - t->radio_freq(c,freq>>10); - return; - - } else { - tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", - freq/16,freq%16*100/16, - radio_range[0],radio_range[1]); - return; - } + if (freq >= radio_range[0]*16000 && freq <= radio_range[1]*16000) { + if (tuner_debug) + tuner_info("radio freq step 62.5Hz (%d.%06d)\n", + freq/16000,freq%16000*1000/16); + t->radio_freq(c,freq); + } else { + tuner_info("radio freq (%d.%02d) out of range (%d-%d)\n", + freq/16,freq%16*100/16, + radio_range[0],radio_range[1]); } - tuner_dbg("62.5 Khz freq step selected for Radio.\n"); - t->radio_freq(c,freq); + + return; } static void set_freq(struct i2c_client *c, unsigned long freq) @@ -166,8 +133,8 @@ static void set_freq(struct i2c_client *c, unsigned long freq) static void set_type(struct i2c_client *c, unsigned int type) { struct tuner *t = i2c_get_clientdata(c); + unsigned char buffer[4]; - tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); /* sanity check */ if (type == UNSET || type == TUNER_ABSENT) return; @@ -179,8 +146,8 @@ static void set_type(struct i2c_client *c, unsigned int type) t->type = type; return; } - if (t->initialized) - /* run only once */ + if ((t->initialized) && (t->type == type)) + /* run only once except type change Hac 04/05*/ return; t->initialized = 1; @@ -193,25 +160,42 @@ static void set_type(struct i2c_client *c, unsigned int type) case TUNER_PHILIPS_TDA8290: tda8290_init(c); break; + case TUNER_TEA5767: + if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT; + break; + case TUNER_PHILIPS_FMD1216ME_MK3: + buffer[0] = 0x0b; + buffer[1] = 0xdc; + buffer[2] = 0x9c; + buffer[3] = 0x60; + i2c_master_send(c,buffer,4); + mdelay(1); + buffer[2] = 0x86; + buffer[3] = 0x54; + i2c_master_send(c,buffer,4); + default_tuner_init(c); + break; default: + /* TEA5767 autodetection code */ + if (tea5767_tuner_init(c)!=EINVAL) { + t->type = TUNER_TEA5767; + if (first_tuner == 0x60) + first_tuner++; + break; + } + default_tuner_init(c); break; } + tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); } -#ifdef CONFIG_TUNER_MULTI_I2C #define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ - return 0; } else \ + return 0; } else if (tuner_debug) \ tuner_info ("Cmd %s accepted to "tun"\n",cmd); #define CHECK_MODE(cmd) if (t->mode == V4L2_TUNER_RADIO) { \ CHECK_ADDR(radio_tuner,cmd,"radio") } else \ { CHECK_ADDR(tv_tuner,cmd,"TV"); } -#else -#define CHECK_ADDR(tp,cmd,tun) tuner_info ("Cmd %s accepted to "tun"\n",cmd); -#define CHECK_MODE(cmd) tuner_info ("Cmd %s accepted\n",cmd); -#endif - -#ifdef CONFIG_TUNER_MULTI_I2C static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) { @@ -242,9 +226,6 @@ static void set_addr(struct i2c_client *c, struct tuner_addr *tun_addr) } set_type(c,tun_addr->type); } -#else -#define set_addr(c,tun_addr) set_type(c,(tun_addr)->type) -#endif static char pal[] = "-"; module_param_string(pal, pal, sizeof(pal), 0644); @@ -284,17 +265,12 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) { struct tuner *t; -#ifndef CONFIG_TUNER_MULTI_I2C - if (this_adap > 0) - return -1; -#else /* by default, first I2C card is both tv and radio tuner */ if (this_adap == 0) { first_tuner = addr; tv_tuner = addr; radio_tuner = addr; } -#endif this_adap++; client_template.adapter = adap; @@ -308,6 +284,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) i2c_set_clientdata(&t->i2c, t); t->type = UNSET; t->radio_if2 = 10700*1000; /* 10.7MHz - FM radio */ + t->audmode = V4L2_TUNER_MODE_STEREO; i2c_attach_client(&t->i2c); tuner_info("chip found @ 0x%x (%s)\n", @@ -325,11 +302,9 @@ static int tuner_probe(struct i2c_adapter *adap) } this_adap = 0; -#ifdef CONFIG_TUNER_MULTI_I2C first_tuner = 0; tv_tuner = 0; radio_tuner = 0; -#endif if (adap->class & I2C_CLASS_TV_ANALOG) return i2c_probe(adap, &addr_data, tuner_attach); @@ -392,8 +367,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) t->radio_if2 = 41300 * 1000; break; } - break; - + break; /* --- v4l ioctls --- */ /* take care: bttv does userspace copying, we'll get a kernel pointer here... */ @@ -440,11 +414,18 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) vt->signal = t->has_signal(client); if (t->is_stereo) { if (t->is_stereo(client)) - vt-> flags |= VIDEO_TUNER_STEREO_ON; + vt->flags |= VIDEO_TUNER_STEREO_ON; else - vt-> flags &= 0xffff ^ VIDEO_TUNER_STEREO_ON; + vt->flags &= ~VIDEO_TUNER_STEREO_ON; } vt->flags |= V4L2_TUNER_CAP_LOW; /* Allow freqs at 62.5 Hz */ + + vt->rangelow = radio_range[0] * 16000; + vt->rangehigh = radio_range[1] * 16000; + + } else { + vt->rangelow = tv_range[0] * 16; + vt->rangehigh = tv_range[1] * 16; } return 0; @@ -510,20 +491,46 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) tuner -> signal = t->has_signal(client); if (t->is_stereo) { if (t->is_stereo(client)) { - tuner -> capability |= V4L2_TUNER_CAP_STEREO; - tuner -> rxsubchans |= V4L2_TUNER_SUB_STEREO; + tuner -> rxsubchans = V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_MONO; } else { - tuner -> rxsubchans &= 0xffff ^ V4L2_TUNER_SUB_STEREO; + tuner -> rxsubchans = V4L2_TUNER_SUB_MONO; } } + tuner->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; + tuner->audmode = t->audmode; + + tuner->rangelow = radio_range[0] * 16000; + tuner->rangehigh = radio_range[1] * 16000; + } else { + tuner->rangelow = tv_range[0] * 16; + tuner->rangehigh = tv_range[1] * 16; } - /* Wow to deal with V4L2_TUNER_CAP_LOW ? For now, it accepts from low at 62.5KHz step to high at 62.5 Hz */ - tuner->rangelow = tv_range[0] * 16; -// tuner->rangehigh = tv_range[1] * 16; -// tuner->rangelow = tv_range[0] * 16384; - tuner->rangehigh = tv_range[1] * 16384; break; } + case VIDIOC_S_TUNER: /* Allow changing radio range and audio mode */ + { + struct v4l2_tuner *tuner = arg; + + CHECK_ADDR(radio_tuner,"VIDIOC_S_TUNER","radio"); + SWITCH_V4L2; + + /* To switch the audio mode, applications initialize the + index and audmode fields and the reserved array and + call the VIDIOC_S_TUNER ioctl. */ + /* rxsubchannels: V4L2_TUNER_MODE_MONO, V4L2_TUNER_MODE_STEREO, + V4L2_TUNER_MODE_LANG1, V4L2_TUNER_MODE_LANG2, + V4L2_TUNER_MODE_SAP */ + + if (tuner->audmode == V4L2_TUNER_MODE_MONO) + t->audmode = V4L2_TUNER_MODE_MONO; + else + t->audmode = V4L2_TUNER_MODE_STEREO; + + set_radio_freq(client, t->freq); + break; + } + case TDA9887_SET_CONFIG: /* Nothing to do on tuner-core */ + break; default: tuner_dbg ("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); /* nothing */ diff --git a/drivers/media/video/tuner-simple.c b/drivers/media/video/tuner-simple.c index 539f305..c39ed62 100644 --- a/drivers/media/video/tuner-simple.c +++ b/drivers/media/video/tuner-simple.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-simple.c,v 1.21 2005/06/10 19:53:26 nsh Exp $ + * $Id: tuner-simple.c,v 1.31 2005/06/21 16:02:25 mkrufky Exp $ * * i2c tv tuner chip device driver * controls all those simple 4-control-bytes style tuners. @@ -207,28 +207,27 @@ static struct tunertype tuners[] = { { "LG PAL (TAPE series)", LGINNOTEK, PAL, 16*170.00, 16*450.00, 0x01,0x02,0x08,0xce,623}, - { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, - 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, - { "Philips FQ1236A MK4", Philips, NTSC, - 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, + { "Philips PAL/SECAM multi (FQ1216AME MK4)", Philips, PAL, + 16*160.00,16*442.00,0x01,0x02,0x04,0xce,623 }, + { "Philips FQ1236A MK4", Philips, NTSC, + 16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 }, /* Should work for TVF8531MF, TVF8831MF, TVF8731MF */ { "Ymec TVision TVF-8531MF", Philips, NTSC, 16*160.00,16*454.00,0xa0,0x90,0x30,0x8e,732}, { "Ymec TVision TVF-5533MF", Philips, NTSC, 16*160.00,16*454.00,0x01,0x02,0x04,0x8e,732}, - { "Thomson DDT 7611 (ATSC/NTSC)", THOMSON, ATSC, 16*157.25,16*454.00,0x39,0x3a,0x3c,0x8e,732}, - { "Tena TNF9533-D/IF", LGINNOTEK, PAL, - 16*160.25, 16*464.25, 0x01,0x02,0x08,0x8e,623}, + /* Should work for TNF9533-D/IF, TNF9533-B/DF */ + { "Tena TNF9533-D/IF", Philips, PAL, + 16*160.25,16*464.25,0x01,0x02,0x04,0x8e,623}, - /* - * This entry is for TEA5767 FM radio only chip used on several boards - * w/TV tuner - */ + /* This entry is for TEA5767 FM radio only chip used on several boards w/TV tuner */ { TEA5767_TUNER_NAME, Philips, RADIO, - -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, + -1, -1, 0, 0, 0, TEA5767_LOW_LO_32768,0}, + { "Philips FMD1216ME MK3 Hybrid Tuner", Philips, PAL, + 16*160.00,16*442.00,0x51,0x52,0x54,0x86,623 }, }; unsigned const int tuner_count = ARRAY_SIZE(tuners); @@ -455,24 +454,24 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq) int rc; tun=&tuners[t->type]; - div = freq + (int)(16*10.7); + div = (freq / 1000) + (int)(16*10.7); buffer[2] = tun->config; switch (t->type) { case TUNER_TENA_9533_DI: case TUNER_YMEC_TVF_5533MF: - /*These values are empirically determinated */ - div = (freq*122)/16 - 20; + div = (freq * 122) / 16000 - 20; buffer[2] = 0x88; /* could be also 0x80 */ buffer[3] = 0x19; /* could be also 0x10, 0x18, 0x99 */ break; case TUNER_PHILIPS_FM1216ME_MK3: case TUNER_PHILIPS_FM1236_MK3: + case TUNER_PHILIPS_FMD1216ME_MK3: buffer[3] = 0x19; break; case TUNER_PHILIPS_FM1256_IH3: - div = (20 * freq)/16 + 333 * 2; + div = (20 * freq) / 16000 + 333 * 2; buffer[2] = 0x80; buffer[3] = 0x19; break; @@ -505,6 +504,7 @@ int default_tuner_init(struct i2c_client *c) t->radio_freq = default_set_radio_freq; t->has_signal = tuner_signal; t->is_stereo = tuner_stereo; + return 0; } diff --git a/include/media/tuner.h b/include/media/tuner.h index 2dd8310..4794c56 100644 --- a/include/media/tuner.h +++ b/include/media/tuner.h @@ -1,5 +1,6 @@ -/* +/* $Id: tuner.h,v 1.33 2005/06/21 14:58:08 mkrufky Exp $ + * tuner.h - definition for different tuners Copyright (C) 1997 Markus Schroeder (schroedm@uni-duesseldorf.de) @@ -23,6 +24,8 @@ #ifndef _TUNER_H #define _TUNER_H +#include + #include "id.h" #define ADDR_UNSET (255) @@ -88,7 +91,7 @@ #define TUNER_LG_NTSC_TAPE 47 #define TUNER_TNF_8831BGFF 48 -#define TUNER_MICROTUNE_4042FI5 49 /* FusionHDTV 3 Gold - 4042 FI5 (3X 8147) */ +#define TUNER_MICROTUNE_4042FI5 49 /* DViCO FusionHDTV 3 Gold-Q - 4042 FI5 (3X 8147) */ #define TUNER_TCL_2002N 50 #define TUNER_PHILIPS_FM1256_IH3 51 @@ -98,18 +101,18 @@ #define TUNER_LG_PAL_TAPE 55 /* Hauppauge PVR-150 PAL */ #define TUNER_PHILIPS_FQ1216AME_MK4 56 /* Hauppauge PVR-150 PAL */ -#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ +#define TUNER_PHILIPS_FQ1236A_MK4 57 /* Hauppauge PVR-500MCE NTSC */ #define TUNER_YMEC_TVF_8531MF 58 #define TUNER_YMEC_TVF_5533MF 59 /* Pixelview Pro Ultra NTSC */ -#define TUNER_THOMSON_DTT7611 60 +#define TUNER_THOMSON_DTT7611 60 /* DViCO FusionHDTV 3 Gold-T */ #define TUNER_TENA_9533_DI 61 + #define TUNER_TEA5767 62 /* Only FM Radio Tuner */ +#define TUNER_PHILIPS_FMD1216ME_MK3 63 #define TEA5767_TUNER_NAME "Philips TEA5767HN FM Radio" -#define TUNER_THOMSON_DTT7611 60 - #define NOTUNER 0 #define PAL 1 /* PAL_BG */ #define PAL_I 2 @@ -194,11 +197,15 @@ struct tuner { unsigned char i2c_easy_mode[2]; unsigned char i2c_set_freq[8]; + /* used to keep track of audmode */ + unsigned int audmode; + /* function ptrs */ void (*tv_freq)(struct i2c_client *c, unsigned int freq); void (*radio_freq)(struct i2c_client *c, unsigned int freq); int (*has_signal)(struct i2c_client *c); int (*is_stereo)(struct i2c_client *c); + int (*set_tuner)(struct i2c_client *c, struct v4l2_tuner *v); }; extern unsigned int tuner_debug; @@ -206,6 +213,7 @@ extern unsigned const int tuner_count; extern int microtune_init(struct i2c_client *c); extern int tda8290_init(struct i2c_client *c); +extern int tea5767_tuner_init(struct i2c_client *c); extern int default_tuner_init(struct i2c_client *c); #define tuner_warn(fmt, arg...) \ -- cgit v1.1 From 060d3027f26aab9adeac8ff6d1184bca67c7d174 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Jun 2005 20:45:25 -0700 Subject: [PATCH] v4l: bttv new insmod parameters * bttv-driver.c, bttvp.h: - New bttv module params: - uv_ratio : allow a ratio of saturation between u and v. If you have a ratio of 40 and a saturation of 100, usat will be 80 and vstat 120. Useful to correct a bad color balance. - full_luma_range : provide a better contrast in using the full range 0-253 of values instead of 16-253. - coring : to have a better black level. - radio range is now defined on tuner-core.c. Cleaning up. * bttvp.h: - Fix gcc 4.0 compilation Signed-off-by: Jorik Jonker Signed-off-by: Sylvain Meyer Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Nickolay V Shmyrev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/media/video/bttv-driver.c | 73 ++++++++++++++++++++++++++++++++++----- drivers/media/video/bttvp.h | 5 ++- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/drivers/media/video/bttv-driver.c b/drivers/media/video/bttv-driver.c index 290289a..7d62b39 100644 --- a/drivers/media/video/bttv-driver.c +++ b/drivers/media/video/bttv-driver.c @@ -1,5 +1,5 @@ /* - $Id: bttv-driver.c,v 1.38 2005/06/10 17:20:24 mchehab Exp $ + $Id: bttv-driver.c,v 1.40 2005/06/16 21:38:45 nsh Exp $ bttv - Bt848 frame grabber driver @@ -76,6 +76,9 @@ static unsigned int whitecrush_upper = 0xCF; static unsigned int whitecrush_lower = 0x7F; static unsigned int vcr_hack = 0; static unsigned int irq_iswitch = 0; +static unsigned int uv_ratio = 50; +static unsigned int full_luma_range = 0; +static unsigned int coring = 0; /* API features (turn on/off stuff for testing) */ static unsigned int v4l2 = 1; @@ -106,6 +109,9 @@ module_param(adc_crush, int, 0444); module_param(whitecrush_upper, int, 0444); module_param(whitecrush_lower, int, 0444); module_param(vcr_hack, int, 0444); +module_param(uv_ratio, int, 0444); +module_param(full_luma_range, int, 0444); +module_param(coring, int, 0444); module_param_array(radio, int, NULL, 0444); @@ -124,6 +130,9 @@ MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127"); MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)"); MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler"); +MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50"); +MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)"); +MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)"); MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards"); MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr"); @@ -484,7 +493,10 @@ static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats); #define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5) #define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6) #define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7) -#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10) +#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11) static const struct v4l2_queryctrl no_ctl = { .name = "42", @@ -618,8 +630,32 @@ static const struct v4l2_queryctrl bttv_ctls[] = { .step = 1, .default_value = 0x7F, .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_PRIVATE_UV_RATIO, + .name = "uv ratio", + .minimum = 0, + .maximum = 100, + .step = 1, + .default_value = 50, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE, + .name = "full luma range", + .minimum = 0, + .maximum = 1, + .type = V4L2_CTRL_TYPE_BOOLEAN, + },{ + .id = V4L2_CID_PRIVATE_CORING, + .name = "coring", + .minimum = 0, + .maximum = 3, + .step = 1, + .default_value = 0, + .type = V4L2_CTRL_TYPE_INTEGER, } + + }; static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls); @@ -833,8 +869,8 @@ static void bt848_sat(struct bttv *btv, int color) btv->saturation = color; /* 0-511 for the color */ - val_u = color >> 7; - val_v = ((color>>7)*180L)/254; + val_u = ((color * btv->opt_uv_ratio) / 50) >> 7; + val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254; hibits = (val_u >> 7) & 2; hibits |= (val_v >> 8) & 1; btwrite(val_u & 0xff, BT848_SAT_U_LO); @@ -1151,6 +1187,15 @@ static int get_control(struct bttv *btv, struct v4l2_control *c) case V4L2_CID_PRIVATE_WHITECRUSH_LOWER: c->value = btv->opt_whitecrush_lower; break; + case V4L2_CID_PRIVATE_UV_RATIO: + c->value = btv->opt_uv_ratio; + break; + case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: + c->value = btv->opt_full_luma_range; + break; + case V4L2_CID_PRIVATE_CORING: + c->value = btv->opt_coring; + break; default: return -EINVAL; } @@ -1247,6 +1292,18 @@ static int set_control(struct bttv *btv, struct v4l2_control *c) btv->opt_whitecrush_lower = c->value; btwrite(c->value, BT848_WC_DOWN); break; + case V4L2_CID_PRIVATE_UV_RATIO: + btv->opt_uv_ratio = c->value; + bt848_sat(btv, btv->saturation); + break; + case V4L2_CID_PRIVATE_FULL_LUMA_RANGE: + btv->opt_full_luma_range = c->value; + btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM); + break; + case V4L2_CID_PRIVATE_CORING: + btv->opt_coring = c->value; + btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM); + break; default: return -EINVAL; } @@ -3117,11 +3174,6 @@ static int radio_do_ioctl(struct inode *inode, struct file *file, return -EINVAL; memset(v,0,sizeof(*v)); strcpy(v->name, "Radio"); - /* japan: 76.0 MHz - 89.9 MHz - western europe: 87.5 MHz - 108.0 MHz - russia: 65.0 MHz - 108.0 MHz */ - v->rangelow=(int)(65*16); - v->rangehigh=(int)(108*16); bttv_call_i2c_clients(btv,cmd,v); return 0; } @@ -3876,6 +3928,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, btv->opt_vcr_hack = vcr_hack; btv->opt_whitecrush_upper = whitecrush_upper; btv->opt_whitecrush_lower = whitecrush_lower; + btv->opt_uv_ratio = uv_ratio; + btv->opt_full_luma_range = full_luma_range; + btv->opt_coring = coring; /* fill struct bttv with some useful defaults */ btv->init.btv = btv; diff --git a/drivers/media/video/bttvp.h b/drivers/media/video/bttvp.h index 7b6f1e8..f3293e4 100644 --- a/drivers/media/video/bttvp.h +++ b/drivers/media/video/bttvp.h @@ -1,5 +1,5 @@ /* - $Id: bttvp.h,v 1.17 2005/02/16 12:14:10 kraxel Exp $ + $Id: bttvp.h,v 1.19 2005/06/16 21:38:45 nsh Exp $ bttv - Bt848 frame grabber driver @@ -326,6 +326,9 @@ struct bttv { int opt_vcr_hack; int opt_whitecrush_upper; int opt_whitecrush_lower; + int opt_uv_ratio; + int opt_full_luma_range; + int opt_coring; /* radio data/state */ int has_radio; -- cgit v1.1 From 115d6f3fd25991f2a7de1ff4d758086209b1ed12 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Jun 2005 20:45:27 -0700 Subject: [PATCH] V4L: API new webcam formats included Add Philips Webcam format. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Luc Saillard . Signed-off-by: Nickolay V Shmyrev Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/videodev2.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 4e0edce..acbfc52 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -221,6 +221,8 @@ struct v4l2_pix_format /* Vendor-specific formats */ #define V4L2_PIX_FMT_WNVA v4l2_fourcc('W','N','V','A') /* Winnov hw compress */ #define V4L2_PIX_FMT_SN9C10X v4l2_fourcc('S','9','1','0') /* SN9C10x compression */ +#define V4L2_PIX_FMT_PWC1 v4l2_fourcc('P','W','C','1') /* pwc older webcam */ +#define V4L2_PIX_FMT_PWC2 v4l2_fourcc('P','W','C','2') /* pwc newer webcam */ /* * F O R M A T E N U M E R A T I O N -- cgit v1.1 From 6623e6205e36c310367009f3b01f5cbe7cc0005d Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 28 Jun 2005 20:45:28 -0700 Subject: [PATCH] V4L: documentation changes - mostly new cards included New cards included. V4L1 api renamed. Message included informing it is obsoleted by V4L2 API. V4L2 api included. Mark all 7135 cards as 7133. Signed-off-by: Luc Saillard . Signed-off-by: Nickolay V Shmyrev Signed-off-by: Hermann Pitton Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/video4linux/API.html | 415 ++--------------------------- Documentation/video4linux/CARDLIST.cx88 | 8 +- Documentation/video4linux/CARDLIST.saa7134 | 6 + Documentation/video4linux/CARDLIST.tuner | 3 + Documentation/video4linux/README.saa7134 | 9 + 5 files changed, 38 insertions(+), 403 deletions(-) diff --git a/Documentation/video4linux/API.html b/Documentation/video4linux/API.html index 4b3d8f6..441407b 100644 --- a/Documentation/video4linux/API.html +++ b/Documentation/video4linux/API.html @@ -1,399 +1,16 @@ - -Video4Linux Kernel API Reference v0.1:19990430 - - - - - -

Devices

-Video4Linux provides the following sets of device files. These live on the -character device formerly known as "/dev/bttv". /dev/bttv should be a -symlink to /dev/video0 for most people. -

- - - - - - -
Device NameMinor RangeFunction
/dev/video0-63Video Capture Interface
/dev/radio64-127AM/FM Radio Devices
/dev/vtx192-223Teletext Interface Chips
/dev/vbi224-239Raw VBI Data (Intercast/teletext)
-

-Video4Linux programs open and scan the devices to find what they are looking -for. Capability queries define what each interface supports. The -described API is only defined for video capture cards. The relevant subset -applies to radio cards. Teletext interfaces talk the existing VTX API. -

-

Capability Query Ioctl

-The VIDIOCGCAP ioctl call is used to obtain the capability -information for a video device. The struct video_capability object -passed to the ioctl is completed and returned. It contains the following -information -

- - - - - - - - - -
name[32]Canonical name for this interface
typeType of interface
channelsNumber of radio/tv channels if appropriate
audiosNumber of audio devices if appropriate
maxwidthMaximum capture width in pixels
maxheightMaximum capture height in pixels
minwidthMinimum capture width in pixels
minheightMinimum capture height in pixels
-

-The type field lists the capability flags for the device. These are -as follows -

- - - - - - - - - - - - -
NameDescription
VID_TYPE_CAPTURECan capture to memory
VID_TYPE_TUNERHas a tuner of some form
VID_TYPE_TELETEXTHas teletext capability
VID_TYPE_OVERLAYCan overlay its image onto the frame buffer
VID_TYPE_CHROMAKEYOverlay is Chromakeyed
VID_TYPE_CLIPPINGOverlay clipping is supported
VID_TYPE_FRAMERAMOverlay overwrites frame buffer memory
VID_TYPE_SCALESThe hardware supports image scaling
VID_TYPE_MONOCHROMEImage capture is grey scale only
VID_TYPE_SUBCAPTURECapture can be of only part of the image
-

-The minimum and maximum sizes listed for a capture device do not imply all -that all height/width ratios or sizes within the range are possible. A -request to set a size will be honoured by the largest available capture -size whose capture is no large than the requested rectangle in either -direction. For example the quickcam has 3 fixed settings. -

-

Frame Buffer

-Capture cards that drop data directly onto the frame buffer must be told the -base address of the frame buffer, its size and organisation. This is a -privileged ioctl and one that eventually X itself should set. -

-The VIDIOCSFBUF ioctl sets the frame buffer parameters for a capture -card. If the card does not do direct writes to the frame buffer then this -ioctl will be unsupported. The VIDIOCGFBUF ioctl returns the -currently used parameters. The structure used in both cases is a -struct video_buffer. -

- - - - - - -
void *baseBase physical address of the buffer
int heightHeight of the frame buffer
int widthWidth of the frame buffer
int depthDepth of the frame buffer
int bytesperlineNumber of bytes of memory between the start of two adjacent lines
-

-Note that these values reflect the physical layout of the frame buffer. -The visible area may be smaller. In fact under XFree86 this is commonly the -case. XFree86 DGA can provide the parameters required to set up this ioctl. -Setting the base address to NULL indicates there is no physical frame buffer -access. -

-

Capture Windows

-The capture area is described by a struct video_window. This defines -a capture area and the clipping information if relevant. The -VIDIOCGWIN ioctl recovers the current settings and the -VIDIOCSWIN sets new values. A successful call to VIDIOCSWIN -indicates that a suitable set of parameters have been chosen. They do not -indicate that exactly what was requested was granted. The program should -call VIDIOCGWIN to check if the nearest match was suitable. The -struct video_window contains the following fields. -

- - - - - - - - - -
xThe X co-ordinate specified in X windows format.
yThe Y co-ordinate specified in X windows format.
widthThe width of the image capture.
heightThe height of the image capture.
chromakeyA host order RGB32 value for the chroma key.
flagsAdditional capture flags.
clipsA list of clipping rectangles. (Set only)
clipcountThe number of clipping rectangles. (Set only)
-

-Clipping rectangles are passed as an array. Each clip consists of the following -fields available to the user. -

- - - - - -
xX co-ordinate of rectangle to skip
yY co-ordinate of rectangle to skip
widthWidth of rectangle to skip
heightHeight of rectangle to skip
-

-Merely setting the window does not enable capturing. Overlay capturing -(i.e. PCI-PCI transfer to the frame buffer of the video card) -is activated by passing the VIDIOCCAPTURE ioctl a value of 1, and -disabled by passing it a value of 0. -

-Some capture devices can capture a subfield of the image they actually see. -This is indicated when VIDEO_TYPE_SUBCAPTURE is defined. -The video_capture describes the time and special subfields to capture. -The video_capture structure contains the following fields. -

- - - - - - - -
xX co-ordinate of source rectangle to grab
yY co-ordinate of source rectangle to grab
widthWidth of source rectangle to grab
heightHeight of source rectangle to grab
decimationDecimation to apply
flagsFlag settings for grabbing
-The available flags are -

- - - - -
NameDescription
VIDEO_CAPTURE_ODDCapture only odd frames
VIDEO_CAPTURE_EVENCapture only even frames
-

-

Video Sources

-Each video4linux video or audio device captures from one or more -source channels. Each channel can be queries with the -VDIOCGCHAN ioctl call. Before invoking this function the caller -must set the channel field to the channel that is being queried. On return -the struct video_channel is filled in with information about the -nature of the channel itself. -

-The VIDIOCSCHAN ioctl takes an integer argument and switches the -capture to this input. It is not defined whether parameters such as colour -settings or tuning are maintained across a channel switch. The caller should -maintain settings as desired for each channel. (This is reasonable as -different video inputs may have different properties). -

-The struct video_channel consists of the following -

- - - - - - - -
channelThe channel number
nameThe input name - preferably reflecting the label -on the card input itself
tunersNumber of tuners for this input
flagsProperties the tuner has
typeInput type (if known)
normThe norm for this channel
-

-The flags defined are -

- - - - -
VIDEO_VC_TUNERChannel has tuners.
VIDEO_VC_AUDIOChannel has audio.
VIDEO_VC_NORMChannel has norm setting.
-

-The types defined are -

- - - -
VIDEO_TYPE_TVThe input is a TV input.
VIDEO_TYPE_CAMERAThe input is a camera.
-

-

Image Properties

-The image properties of the picture can be queried with the VIDIOCGPICT -ioctl which fills in a struct video_picture. The VIDIOCSPICT -ioctl allows values to be changed. All values except for the palette type -are scaled between 0-65535. -

-The struct video_picture consists of the following fields -

- - - - - - - - -
brightnessPicture brightness
huePicture hue (colour only)
colourPicture colour (colour only)
contrastPicture contrast
whitenessThe whiteness (greyscale only)
depthThe capture depth (may need to match the frame buffer depth)
paletteReports the palette that should be used for this image
-

-The following palettes are defined -

- - - - - - - - - - - - - - - -
VIDEO_PALETTE_GREYLinear intensity grey scale (255 is brightest).
VIDEO_PALETTE_HI240The BT848 8bit colour cube.
VIDEO_PALETTE_RGB565RGB565 packed into 16 bit words.
VIDEO_PALETTE_RGB555RGV555 packed into 16 bit words, top bit undefined.
VIDEO_PALETTE_RGB24RGB888 packed into 24bit words.
VIDEO_PALETTE_RGB32RGB888 packed into the low 3 bytes of 32bit words. The top 8bits are undefined.
VIDEO_PALETTE_YUV422Video style YUV422 - 8bits packed 4bits Y 2bits U 2bits V
VIDEO_PALETTE_YUYVDescribe me
VIDEO_PALETTE_UYVYDescribe me
VIDEO_PALETTE_YUV420YUV420 capture
VIDEO_PALETTE_YUV411YUV411 capture
VIDEO_PALETTE_RAWRAW capture (BT848)
VIDEO_PALETTE_YUV422PYUV 4:2:2 Planar
VIDEO_PALETTE_YUV411PYUV 4:1:1 Planar
-

-

Tuning

-Each video input channel can have one or more tuners associated with it. Many -devices will not have tuners. TV cards and radio cards will have one or more -tuners attached. -

-Tuners are described by a struct video_tuner which can be obtained by -the VIDIOCGTUNER ioctl. Fill in the tuner number in the structure -then pass the structure to the ioctl to have the data filled in. The -tuner can be switched using VIDIOCSTUNER which takes an integer argument -giving the tuner to use. A struct tuner has the following fields -

- - - - - - - - -
tunerNumber of the tuner
nameCanonical name for this tuner (eg FM/AM/TV)
rangelowLowest tunable frequency
rangehighHighest tunable frequency
flagsFlags describing the tuner
modeThe video signal mode if relevant
signalSignal strength if known - between 0-65535
-

-The following flags exist -

- - - - - - - - - -
VIDEO_TUNER_PALPAL tuning is supported
VIDEO_TUNER_NTSCNTSC tuning is supported
VIDEO_TUNER_SECAMSECAM tuning is supported
VIDEO_TUNER_LOWFrequency is in a lower range
VIDEO_TUNER_NORMThe norm for this tuner is settable
VIDEO_TUNER_STEREO_ONThe tuner is seeing stereo audio
VIDEO_TUNER_RDS_ONThe tuner is seeing a RDS datastream
VIDEO_TUNER_MBS_ONThe tuner is seeing a MBS datastream
-

-The following modes are defined -

- - - - - -
VIDEO_MODE_PALThe tuner is in PAL mode
VIDEO_MODE_NTSCThe tuner is in NTSC mode
VIDEO_MODE_SECAMThe tuner is in SECAM mode
VIDEO_MODE_AUTOThe tuner auto switches, or mode does not apply
-

-Tuning frequencies are an unsigned 32bit value in 1/16th MHz or if the -VIDEO_TUNER_LOW flag is set they are in 1/16th KHz. The current -frequency is obtained as an unsigned long via the VIDIOCGFREQ ioctl and -set by the VIDIOCSFREQ ioctl. -

-

Audio

-TV and Radio devices have one or more audio inputs that may be selected. -The audio properties are queried by passing a struct video_audio to VIDIOCGAUDIO ioctl. The -VIDIOCSAUDIO ioctl sets audio properties. -

-The structure contains the following fields -

- - - - - - - - - - -
audioThe channel number
volumeThe volume level
bassThe bass level
trebleThe treble level
flagsFlags describing the audio channel
nameCanonical name for the audio input
modeThe mode the audio input is in
balanceThe left/right balance
stepActual step used by the hardware
-

-The following flags are defined -

- - - - - - - -
VIDEO_AUDIO_MUTEThe audio is muted
VIDEO_AUDIO_MUTABLEAudio muting is supported
VIDEO_AUDIO_VOLUMEThe volume is controllable
VIDEO_AUDIO_BASSThe bass is controllable
VIDEO_AUDIO_TREBLEThe treble is controllable
VIDEO_AUDIO_BALANCEThe balance is controllable
-

-The following decoding modes are defined -

- - - - - -
VIDEO_SOUND_MONOMono signal
VIDEO_SOUND_STEREOStereo signal (NICAM for TV)
VIDEO_SOUND_LANG1European TV alternate language 1
VIDEO_SOUND_LANG2European TV alternate language 2
-

-

Reading Images

-Each call to the read syscall returns the next available image -from the device. It is up to the caller to set format and size (using -the VIDIOCSPICT and VIDIOCSWIN ioctls) and then to pass a suitable -size buffer and length to the function. Not all devices will support -read operations. -

-A second way to handle image capture is via the mmap interface if supported. -To use the mmap interface a user first sets the desired image size and depth -properties. Next the VIDIOCGMBUF ioctl is issued. This reports the size -of buffer to mmap and the offset within the buffer for each frame. The -number of frames supported is device dependent and may only be one. -

-The video_mbuf structure contains the following fields -

- - - - -
sizeThe number of bytes to map
framesThe number of frames
offsetsThe offset of each frame
-

-Once the mmap has been made the VIDIOCMCAPTURE ioctl starts the -capture to a frame using the format and image size specified in the -video_mmap (which should match or be below the initial query size). -When the VIDIOCMCAPTURE ioctl returns the frame is not -captured yet, the driver just instructed the hardware to start the -capture. The application has to use the VIDIOCSYNC ioctl to wait -until the capture of a frame is finished. VIDIOCSYNC takes the frame -number you want to wait for as argument. -

-It is allowed to call VIDIOCMCAPTURE multiple times (with different -frame numbers in video_mmap->frame of course) and thus have multiple -outstanding capture requests. A simple way do to double-buffering -using this feature looks like this: -

-/* setup everything */
-VIDIOCMCAPTURE(0)
-while (whatever) {
-   VIDIOCMCAPTURE(1)
-   VIDIOCSYNC(0)
-   /* process frame 0 while the hardware captures frame 1 */
-   VIDIOCMCAPTURE(0)
-   VIDIOCSYNC(1)
-   /* process frame 1 while the hardware captures frame 0 */
-}
-
-Note that you are not limited to only two frames. The API -allows up to 32 frames, the VIDIOCGMBUF ioctl returns the number of -frames the driver granted. Thus it is possible to build deeper queues -to avoid loosing frames on load peaks. -

-While capturing to memory the driver will make a "best effort" attempt -to capture to screen as well if requested. This normally means all -frames that "miss" memory mapped capture will go to the display. -

-A final ioctl exists to allow a device to obtain related devices if a -driver has multiple components (for example video0 may not be associated -with vbi0 which would cause an intercast display program to make a bad -mistake). The VIDIOCGUNIT ioctl reports the unit numbers of the associated -devices if any exist. The video_unit structure has the following fields. -

- - - - - - -
videoVideo capture device
vbiVBI capture device
radioRadio device
audioAudio mixer
teletextTeletext device
-

-

RDS Datastreams

-For radio devices that support it, it is possible to receive Radio Data -System (RDS) data by means of a read() on the device. The data is packed in -groups of three, as follows: - - - - - - -
First OctetLeast Significant Byte of RDS Block
Second OctetMost Significant Byte of RDS Block -
Third OctetBit 7:Error bit. Indicates that -an uncorrectable error occurred during reception of this block.
 Bit 6:Corrected bit. Indicates that -an error was corrected for this data block.
 Bits 5-3:Received Offset. Indicates the -offset received by the sync system.
 Bits 2-0:Offset Name. Indicates the -offset applied to this data.
- - +V4L API +

Video For Linux APIs

+ + + +
+ +V4L original API + +Obsoleted by V4L2 API +
+ +V4L2 API + +Should be used for new projects +
diff --git a/Documentation/video4linux/CARDLIST.cx88 b/Documentation/video4linux/CARDLIST.cx88 index 216f705..4377aa1 100644 --- a/Documentation/video4linux/CARDLIST.cx88 +++ b/Documentation/video4linux/CARDLIST.cx88 @@ -13,17 +13,17 @@ card=11 - Prolink PlayTV PVR card=12 - ASUS PVR-416 card=13 - MSI TV-@nywhere card=14 - KWorld/VStream XPert DVB-T -card=15 - DVICO FusionHDTV DVB-T1 +card=15 - DViCO FusionHDTV DVB-T1 card=16 - KWorld LTV883RF -card=17 - DViCO - FusionHDTV 3 Gold +card=17 - DViCO FusionHDTV 3 Gold-Q card=18 - Hauppauge Nova-T DVB-T card=19 - Conexant DVB-T reference design card=20 - Provideo PV259 -card=21 - DVICO FusionHDTV DVB-T Plus +card=21 - DViCO FusionHDTV DVB-T Plus card=22 - digitalnow DNTV Live! DVB-T card=23 - pcHDTV HD3000 HDTV card=24 - Hauppauge WinTV 28xxx (Roslyn) models card=25 - Digital-Logic MICROSPACE Entertainment Center (MEC) card=26 - IODATA GV/BCTV7E card=27 - PixelView PlayTV Ultra Pro (Stereo) -card=28 - DViCO - FusionHDTV 3 Gold-T +card=28 - DViCO FusionHDTV 3 Gold-T diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134 index d5ed95d..735e8ba 100644 --- a/Documentation/video4linux/CARDLIST.saa7134 +++ b/Documentation/video4linux/CARDLIST.saa7134 @@ -54,3 +54,9 @@ 55 -> LifeView FlyDVB-T DUO [5168:0306] 56 -> Avermedia AVerTV 307 [1461:a70a] 57 -> Avermedia AVerTV GO 007 FM [1461:f31f] + 58 -> ADS Tech Instant TV (saa7135) [1421:0350,1421:0370] + 59 -> Kworld/Tevion V-Stream Xpert TV PVR7134 + 60 -> Typhoon DVB-T Duo Digital/Analog Cardbus + 61 -> Philips TOUGH DVB-T reference design + 62 -> Compro VideoMate TV Gold+II + 63 -> Kworld Xpert TV PVR7134 diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner index aeb8df8..e78020f 100644 --- a/Documentation/video4linux/CARDLIST.tuner +++ b/Documentation/video4linux/CARDLIST.tuner @@ -59,3 +59,6 @@ tuner=57 - Philips FQ1236A MK4 tuner=58 - Ymec TVision TVF-8531MF tuner=59 - Ymec TVision TVF-5533MF tuner=60 - Thomson DDT 7611 (ATSC/NTSC) +tuner=61 - Tena TNF9533-D/IF +tuner=62 - Philips TEA5767HN FM Radio +tuner=63 - Philips FMD1216ME MK3 Hybrid Tuner diff --git a/Documentation/video4linux/README.saa7134 b/Documentation/video4linux/README.saa7134 index 1a446c6..1f788e4 100644 --- a/Documentation/video4linux/README.saa7134 +++ b/Documentation/video4linux/README.saa7134 @@ -57,6 +57,15 @@ Cards can use either of these two crystals (xtal): - 24.576MHz -> .audio_clock=0x200000 (xtal * .audio_clock = 51539600) +Some details about 30/34/35: + + - saa7130 - low-price chip, doesn't have mute, that is why all those + cards should have .mute field defined in their tuner structure. + + - saa7134 - usual chip + + - saa7133/35 - saa7135 is probably a marketing decision, since all those + chips identifies itself as 33 on pci. Credits ======= -- cgit v1.1 From 84da7c0844f8ab7668559c61e4f0af416fc58cf6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 28 Jun 2005 20:45:30 -0700 Subject: [PATCH] Doc/Submitting: corrections, additions Corrections to Documentation/Submitting{Drivers,Patches} - update LANANA info. - fix some typos - update 2.2 kernel maintainer info. - update 'dontdiff' info. - update URLs for patch scripts - add Trivial Patch Monkey URL - add more references for submitting patches Signed-off-by: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/SubmittingDrivers | 14 +++++++------ Documentation/SubmittingPatches | 44 +++++++++++++++++++++++++++-------------- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/Documentation/SubmittingDrivers b/Documentation/SubmittingDrivers index de3b252..c3cca92 100644 --- a/Documentation/SubmittingDrivers +++ b/Documentation/SubmittingDrivers @@ -13,13 +13,14 @@ Allocating Device Numbers ------------------------- Major and minor numbers for block and character devices are allocated -by the Linux assigned name and number authority (currently better -known as H Peter Anvin). The site is http://www.lanana.org/. This +by the Linux assigned name and number authority (currently this is +Torben Mathiasen). The site is http://www.lanana.org/. This also deals with allocating numbers for devices that are not going to be submitted to the mainstream kernel. +See Documentation/devices.txt for more information on this. -If you don't use assigned numbers then when you device is submitted it will -get given an assigned number even if that is different from values you may +If you don't use assigned numbers then when your device is submitted it will +be given an assigned number even if that is different from values you may have shipped to customers before. Who To Submit Drivers To @@ -32,7 +33,8 @@ Linux 2.2: If the code area has a general maintainer then please submit it to the maintainer listed in MAINTAINERS in the kernel file. If the maintainer does not respond or you cannot find the appropriate - maintainer then please contact Alan Cox + maintainer then please contact the 2.2 kernel maintainer: + Marc-Christian Petersen . Linux 2.4: The same rules apply as 2.2. The final contact point for Linux 2.4 @@ -48,7 +50,7 @@ What Criteria Determine Acceptance Licensing: The code must be released to us under the GNU General Public License. We don't insist on any kind - of exclusively GPL licensing, and if you wish the driver + of exclusive GPL licensing, and if you wish the driver to be useful to other communities such as BSD you may well wish to release under multiple licenses. diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 4d1f41b..6761a7b 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -35,7 +35,7 @@ not in any lower subdirectory. To create a patch for a single file, it is often sufficient to do: - SRCTREE= linux-2.4 + SRCTREE= linux-2.6 MYFILE= drivers/net/mydriver.c cd $SRCTREE @@ -48,17 +48,18 @@ To create a patch for multiple files, you should unpack a "vanilla", or unmodified kernel source tree, and generate a diff against your own source tree. For example: - MYSRC= /devel/linux-2.4 + MYSRC= /devel/linux-2.6 - tar xvfz linux-2.4.0-test11.tar.gz - mv linux linux-vanilla - wget http://www.moses.uklinux.net/patches/dontdiff - diff -uprN -X dontdiff linux-vanilla $MYSRC > /tmp/patch - rm -f dontdiff + tar xvfz linux-2.6.12.tar.gz + mv linux-2.6.12 linux-2.6.12-vanilla + diff -uprN -X linux-2.6.12-vanilla/Documentation/dontdiff \ + linux-2.6.12-vanilla $MYSRC > /tmp/patch "dontdiff" is a list of files which are generated by the kernel during the build process, and should be ignored in any diff(1)-generated -patch. dontdiff is maintained by Tigran Aivazian +patch. The "dontdiff" file is included in the kernel tree in +2.6.12 and later. For earlier kernel versions, you can get it +from . Make sure your patch does not include any extra files which do not belong in a patch submission. Make sure to review your patch -after- @@ -66,18 +67,20 @@ generated it with diff(1), to ensure accuracy. If your changes produce a lot of deltas, you may want to look into splitting them into individual patches which modify things in -logical stages, this will facilitate easier reviewing by other +logical stages. This will facilitate easier reviewing by other kernel developers, very important if you want your patch accepted. -There are a number of scripts which can aid in this; +There are a number of scripts which can aid in this: Quilt: http://savannah.nongnu.org/projects/quilt Randy Dunlap's patch scripts: -http://developer.osdl.org/rddunlap/scripts/patching-scripts.tgz +http://www.xenotime.net/linux/scripts/patching-scripts-002.tar.gz Andrew Morton's patch scripts: -http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.16 +http://www.zip.com.au/~akpm/linux/patches/patch-scripts-0.20 + + 2) Describe your changes. @@ -163,6 +166,8 @@ patches. Trivial patches must qualify for one of the following rules: since people copy, as long as it's trivial) Any fix by the author/maintainer of the file. (ie. patch monkey in re-transmission mode) +URL: + @@ -291,6 +296,17 @@ now, but you can do this to mark internal company procedures or just point out some special detail about the sign-off. + +12) More references for submitting patches + +Andrew Morton, "The perfect patch" (tpp). + + +Jeff Garzik, "Linux kernel patch submission format." + + + + ----------------------------------- SECTION 2 - HINTS, TIPS, AND TRICKS ----------------------------------- @@ -359,7 +375,5 @@ and 'extern __inline__'. 4) Don't over-design. Don't try to anticipate nebulous future cases which may or may not -be useful: "Make it as simple as you can, and no simpler" - - +be useful: "Make it as simple as you can, and no simpler." -- cgit v1.1 From 2668fb91cbfbd5e6799017a3579f20309aac758b Mon Sep 17 00:00:00 2001 From: William Lee Irwin III Date: Tue, 28 Jun 2005 20:45:31 -0700 Subject: [PATCH] sparc32: Kconfig fixups Something reverted most of the arch/sparc/Kconfig changes, leaving arch/sparc/ unconfigurable. This patch re-removes the parts made redundant by drivers/Kconfig in addition to a mysterious, spurious second instance of source "mm/Kconfig". cvs strikes again? Signed-off-by: William Irwin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/sparc/Kconfig | 56 ------------------------------------------------------ 1 file changed, 56 deletions(-) diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index 262e13d..7a117ef 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -270,66 +270,10 @@ endmenu source "drivers/Kconfig" -config PRINTER - tristate "Parallel printer support" - depends on PARPORT - ---help--- - If you intend to attach a printer to the parallel port of your Linux - box (as opposed to using a serial printer; if the connector at the - printer has 9 or 25 holes ["female"], then it's serial), say Y. - Also read the Printing-HOWTO, available from - . - - It is possible to share one parallel port among several devices - (e.g. printer and ZIP drive) and it is safe to compile the - corresponding drivers into the kernel. If you want to compile this - driver as a module however, choose M here and read - . The module will be called lp. - - If you have several parallel ports, you can specify which ports to - use with the "lp" kernel command line option. (Try "man bootparam" - or see the documentation of your boot loader (silo) about how to pass - options to the kernel at boot time.) The syntax of the "lp" command - line option can be found in . - - If you have more than 8 printers, you need to increase the LP_NO - macro in lp.c and the PARPORT_MAX macro in parport.h. - -source "mm/Kconfig" - -endmenu - -source "drivers/base/Kconfig" - -source "drivers/video/Kconfig" - -source "drivers/mtd/Kconfig" - -source "drivers/serial/Kconfig" - if !SUN4 source "drivers/sbus/char/Kconfig" endif -source "drivers/block/Kconfig" - -# Don't frighten a common SBus user -if PCI - -source "drivers/ide/Kconfig" - -endif - -source "drivers/isdn/Kconfig" - -source "drivers/scsi/Kconfig" - -source "drivers/fc4/Kconfig" - -source "drivers/md/Kconfig" - -source "net/Kconfig" - # This one must be before the filesystem configs. -DaveM menu "Unix98 PTY support" -- cgit v1.1 From 2fa938b8a3964c21b23d9d095091e7abc88249c5 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Tue, 28 Jun 2005 20:08:29 -0400 Subject: [PATCH] sis 760 support. This patch adds the SiS 760 ID to the amd64-agp driver, so that agpgart can be used on Athlon64 boards based on this chip. Signed-off-by: Daniel Drake Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- drivers/char/agp/amd64-agp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 1407945..59f589d 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -686,6 +686,15 @@ static struct pci_device_id agp_amd64_pci_table[] = { .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, }, + /* SIS 760 */ + { + .class = (PCI_CLASS_BRIDGE_HOST << 8), + .class_mask = ~0, + .vendor = PCI_VENDOR_ID_SI, + .device = PCI_DEVICE_ID_SI_760, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + }, { } }; -- cgit v1.1 From b9a05d1d51e27681e8a1162d8f11c1820915e921 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 29 Jun 2005 01:17:55 -0400 Subject: [PATCH] ieee80211.h build fix This crept in with the resync-to-mainline. Nothing uses 802.11-crypt in mainline, so we can safely comment it out for now. Signed-off-by: Jeff Garzik Signed-off-by: Linus Torvalds --- include/net/ieee80211.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index 151c4f2..db09580 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -426,7 +426,9 @@ struct ieee80211_stats { struct ieee80211_device; +#if 0 /* for later */ #include "ieee80211_crypt.h" +#endif #define SEC_KEY_1 (1<<0) #define SEC_KEY_2 (1<<1) -- cgit v1.1 From 4c91aedb75d1b87deccf16d58f67fb46402d7d44 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 28 Jun 2005 22:57:29 -0700 Subject: Linux v2.6.13-rc1 Ok, a lot of things were pending after the 2.6.12 release, let's try to start calming things down again. --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1fdace7..77aab7b 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 -SUBLEVEL = 12 -EXTRAVERSION = +SUBLEVEL = 13 +EXTRAVERSION =-rc1 NAME=Woozy Numbat # *DOCUMENTATION* -- cgit v1.1 From c5f4644e6c8ba21666128603e4e92544d3cd740d Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 09:42:38 +0100 Subject: [PATCH] Serial: Adjust serial locking This patch changes the way serial ports are locked when getting modem status. This change is necessary because we will need to atomically read the modem status and take action depending on the CTS status. Signed-off-by: Russell King --- Documentation/serial/driver | 4 ++-- drivers/serial/8250.c | 3 --- drivers/serial/au1x00_uart.c | 3 --- drivers/serial/ip22zilog.c | 13 +++++++------ drivers/serial/mpsc.c | 3 --- drivers/serial/pmac_zilog.c | 4 ++-- drivers/serial/pxa.c | 3 --- drivers/serial/serial_core.c | 11 ++++++++++- drivers/serial/serial_txx9.c | 3 --- drivers/serial/sunsab.c | 7 +------ drivers/serial/sunsu.c | 3 --- drivers/serial/sunzilog.c | 13 +++++++------ 12 files changed, 29 insertions(+), 41 deletions(-) diff --git a/Documentation/serial/driver b/Documentation/serial/driver index e9c0178..ac7eabb 100644 --- a/Documentation/serial/driver +++ b/Documentation/serial/driver @@ -107,8 +107,8 @@ hardware. indicate that the signal is permanently active. If RI is not available, the signal should not be indicated as active. - Locking: none. - Interrupts: caller dependent. + Locking: port->lock taken. + Interrupts: locally disabled. This call must not sleep stop_tx(port,tty_stop) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 34e75bc..b53b53b 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -1376,13 +1376,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) static unsigned int serial8250_get_mctrl(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/au1x00_uart.c b/drivers/serial/au1x00_uart.c index 5400dc2..6104aee 100644 --- a/drivers/serial/au1x00_uart.c +++ b/drivers/serial/au1x00_uart.c @@ -556,13 +556,10 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) static unsigned int serial8250_get_mctrl(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/ip22zilog.c b/drivers/serial/ip22zilog.c index 3ea46c0..ea5bf4d 100644 --- a/drivers/serial/ip22zilog.c +++ b/drivers/serial/ip22zilog.c @@ -518,27 +518,28 @@ static irqreturn_t ip22zilog_interrupt(int irq, void *dev_id, struct pt_regs *re static __inline__ unsigned char ip22zilog_read_channel_status(struct uart_port *port) { struct zilog_channel *channel; - unsigned long flags; unsigned char status; - spin_lock_irqsave(&port->lock, flags); - channel = ZILOG_CHANNEL_FROM_PORT(port); status = readb(&channel->control); ZSDELAY(); - spin_unlock_irqrestore(&port->lock, flags); - return status; } /* The port lock is not held. */ static unsigned int ip22zilog_tx_empty(struct uart_port *port) { + unsigned long flags; unsigned char status; unsigned int ret; + spin_lock_irqsave(&port->lock, flags); + status = ip22zilog_read_channel_status(port); + + spin_unlock_irqrestore(&port->lock, flags); + if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; else @@ -547,7 +548,7 @@ static unsigned int ip22zilog_tx_empty(struct uart_port *port) return ret; } -/* The port lock is not held. */ +/* The port lock is held and interrupts are disabled. */ static unsigned int ip22zilog_get_mctrl(struct uart_port *port) { unsigned char status; diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index a2a6433..e43276c 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -1058,12 +1058,9 @@ mpsc_get_mctrl(struct uart_port *port) { struct mpsc_port_info *pi = (struct mpsc_port_info *)port; u32 mflags, status; - ulong iflags; - spin_lock_irqsave(&pi->port.lock, iflags); status = (pi->mirror_regs) ? pi->MPSC_CHR_10_m : readl(pi->mpsc_base + MPSC_CHR_10); - spin_unlock_irqrestore(&pi->port.lock, iflags); mflags = 0; if (status & 0x1) diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 85abd8a..1c9f716 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -604,7 +604,7 @@ static void pmz_set_mctrl(struct uart_port *port, unsigned int mctrl) /* * Get Modem Control bits (only the input ones, the core will * or that with a cached value of the control ones) - * The port lock is not held. + * The port lock is held and interrupts are disabled. */ static unsigned int pmz_get_mctrl(struct uart_port *port) { @@ -615,7 +615,7 @@ static unsigned int pmz_get_mctrl(struct uart_port *port) if (ZS_IS_ASLEEP(uap) || uap->node == NULL) return 0; - status = pmz_peek_status(to_pmz(port)); + status = read_zsreg(uap, R0); ret = 0; if (status & DCD) diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 08b08d6..461c81c 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c @@ -274,14 +274,11 @@ static unsigned int serial_pxa_tx_empty(struct uart_port *port) static unsigned int serial_pxa_get_mctrl(struct uart_port *port) { struct uart_pxa_port *up = (struct uart_pxa_port *)port; - unsigned long flags; unsigned char status; unsigned int ret; return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 36b1ae0..f5ce58d 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -828,7 +828,10 @@ static int uart_tiocmget(struct tty_struct *tty, struct file *file) if ((!file || !tty_hung_up_p(file)) && !(tty->flags & (1 << TTY_IO_ERROR))) { result = port->mctrl; + + spin_lock_irq(&port->lock); result |= port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); } up(&state->sem); @@ -1369,6 +1372,7 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) DECLARE_WAITQUEUE(wait, current); struct uart_info *info = state->info; struct uart_port *port = state->port; + unsigned int mctrl; info->blocked_open++; state->count--; @@ -1416,7 +1420,10 @@ uart_block_til_ready(struct file *filp, struct uart_state *state) * and wait for the carrier to indicate that the * modem is ready for us. */ - if (port->ops->get_mctrl(port) & TIOCM_CAR) + spin_lock_irq(&port->lock); + mctrl = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); + if (mctrl & TIOCM_CAR) break; up(&state->sem); @@ -1618,7 +1625,9 @@ static int uart_line_info(char *buf, struct uart_driver *drv, int i) if(capable(CAP_SYS_ADMIN)) { + spin_lock_irq(&port->lock); status = port->ops->get_mctrl(port); + spin_unlock_irq(&port->lock); ret += sprintf(buf + ret, " tx:%d rx:%d", port->icount.tx, port->icount.rx); diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 3f1051a..d085030 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -442,13 +442,10 @@ static unsigned int serial_txx9_tx_empty(struct uart_port *port) static unsigned int serial_txx9_get_mctrl(struct uart_port *port) { struct uart_txx9_port *up = (struct uart_txx9_port *)port; - unsigned long flags; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); - spin_unlock_irqrestore(&up->port.lock, flags); return ret; } diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 10e2990..8d19888 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c @@ -426,18 +426,15 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) sunsab_tx_idle(up); } -/* port->lock is not held. */ +/* port->lock is held by caller and interrupts are disabled. */ static unsigned int sunsab_get_mctrl(struct uart_port *port) { struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; - unsigned long flags; unsigned char val; unsigned int result; result = 0; - spin_lock_irqsave(&up->port.lock, flags); - val = readb(&up->regs->r.pvr); result |= (val & up->pvr_dsr_bit) ? 0 : TIOCM_DSR; @@ -447,8 +444,6 @@ static unsigned int sunsab_get_mctrl(struct uart_port *port) val = readb(&up->regs->r.star); result |= (val & SAB82532_STAR_CTS) ? TIOCM_CTS : 0; - spin_unlock_irqrestore(&up->port.lock, flags); - return result; } diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index ddc97c9..d57a355 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -572,13 +572,10 @@ static unsigned int sunsu_tx_empty(struct uart_port *port) static unsigned int sunsu_get_mctrl(struct uart_port *port) { struct uart_sunsu_port *up = (struct uart_sunsu_port *) port; - unsigned long flags; unsigned char status; unsigned int ret; - spin_lock_irqsave(&up->port.lock, flags); status = serial_in(up, UART_MSR); - spin_unlock_irqrestore(&up->port.lock, flags); ret = 0; if (status & UART_MSR_DCD) diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 8e65206..bff42a7 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -610,27 +610,28 @@ static irqreturn_t sunzilog_interrupt(int irq, void *dev_id, struct pt_regs *reg static __inline__ unsigned char sunzilog_read_channel_status(struct uart_port *port) { struct zilog_channel __iomem *channel; - unsigned long flags; unsigned char status; - spin_lock_irqsave(&port->lock, flags); - channel = ZILOG_CHANNEL_FROM_PORT(port); status = sbus_readb(&channel->control); ZSDELAY(); - spin_unlock_irqrestore(&port->lock, flags); - return status; } /* The port lock is not held. */ static unsigned int sunzilog_tx_empty(struct uart_port *port) { + unsigned long flags; unsigned char status; unsigned int ret; + spin_lock_irqsave(&port->lock, flags); + status = sunzilog_read_channel_status(port); + + spin_unlock_irqrestore(&port->lock, flags); + if (status & Tx_BUF_EMP) ret = TIOCSER_TEMT; else @@ -639,7 +640,7 @@ static unsigned int sunzilog_tx_empty(struct uart_port *port) return ret; } -/* The port lock is not held. */ +/* The port lock is held and interrupts are disabled. */ static unsigned int sunzilog_get_mctrl(struct uart_port *port) { unsigned char status; -- cgit v1.1 From f705b1aed7002495a504086705ff9725ed9412dc Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 29 Jun 2005 11:09:15 +0100 Subject: [PATCH] ARM: 2764/1: S3C24XX - Common PM functions for Simtec boards Patch from Ben Dooks All current S3C24XX implementations from Simtec share the same requirements for suspend/resume information. This patch moves the save code out of the mach-bast.c file, and into it's own so it can be shared by all the current Simtec S3C24XX implementations. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/Kconfig | 5 +++ arch/arm/mach-s3c2410/Makefile | 1 + arch/arm/mach-s3c2410/mach-bast.c | 39 +++-------------------- arch/arm/mach-s3c2410/pm-simtec.c | 65 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 75 insertions(+), 35 deletions(-) create mode 100644 arch/arm/mach-s3c2410/pm-simtec.c diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index 534df0c..d4d03d0 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -154,6 +154,11 @@ config S3C2410_PM_CHECK_CHUNKSIZE the CRC data block will take more memory, but wil identify any faults with better precision. +config PM_SIMTEC + bool + depends on PM && (ARCH_BAST || MACH_VR1000) + default y + config S3C2410_LOWLEVEL_UART_PORT int "S3C2410 UART to use for low-level messages" default 0 diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 7c379aa..f99b689 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -18,6 +18,7 @@ obj-$(CONFIG_S3C2410_DMA) += dma.o # Power Management support obj-$(CONFIG_PM) += pm.o sleep.o +obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o # S3C2440 support diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index f3e9700..549bcb1 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -27,6 +27,7 @@ * 10-Mar-2005 LCVR Changed S3C2410_VA to S3C24XX_VA * 14-Mar-2006 BJD Updated for __iomem changes * 22-Jun-2006 BJD Added DM9000 platform information + * 28-Jun-2006 BJD Moved pm functionality out to common code */ #include @@ -67,7 +68,6 @@ #include "devs.h" #include "cpu.h" #include "usb-simtec.h" -#include "pm.h" #define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" @@ -405,44 +405,13 @@ void __init bast_map_io(void) usb_simtec_init(); } -void __init bast_init_irq(void) -{ - s3c24xx_init_irq(); -} - -#ifdef CONFIG_PM - -/* bast_init_machine - * - * enable the power management functions for the EB2410ITX -*/ - -static __init void bast_init_machine(void) -{ - unsigned long gstatus4; - - printk(KERN_INFO "BAST Power Manangement" COPYRIGHT "\n"); - - gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; - gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; - gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); - - __raw_writel(gstatus4, S3C2410_GSTATUS4); - - s3c2410_pm_init(); -} - -#else -#define bast_init_machine NULL -#endif - MACHINE_START(BAST, "Simtec-BAST") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(bast_map_io) - INITIRQ(bast_init_irq) - .init_machine = bast_init_machine, + + .map_io = bast_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/mach-s3c2410/pm-simtec.c new file mode 100644 index 0000000..2cb7988 --- /dev/null +++ b/arch/arm/mach-s3c2410/pm-simtec.c @@ -0,0 +1,65 @@ +/* linux/arch/arm/mach-s3c2410/pm-simtec.c + * + * Copyright (c) 2004 Simtec Electronics + * Ben Dooks + * + * http://armlinux.simtec.co.uk/ + * + * Power Management helpers for Simtec S3C24XX implementations + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "pm.h" + +#define COPYRIGHT ", (c) 2005 Simtec Electronics" + +/* pm_simtec_init + * + * enable the power management functions +*/ + +static __init int pm_simtec_init(void) +{ + unsigned long gstatus4; + + /* check which machine we are running on */ + + if (!machine_is_bast() && !machine_is_vr1000()) + return 0; + + printk(KERN_INFO "Simtec Board Power Manangement" COPYRIGHT "\n"); + + gstatus4 = (__raw_readl(S3C2410_BANKCON7) & 0x3) << 30; + gstatus4 |= (__raw_readl(S3C2410_BANKCON6) & 0x3) << 28; + gstatus4 |= (__raw_readl(S3C2410_BANKSIZE) & S3C2410_BANKSIZE_MASK); + + __raw_writel(gstatus4, S3C2410_GSTATUS4); + + return s3c2410_pm_init(); +} + +arch_initcall(pm_simtec_init); -- cgit v1.1 From 6904b2465cf30265a67711025815784aa345bfad Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Wed, 29 Jun 2005 11:09:15 +0100 Subject: [PATCH] ARM: 2765/1: S3C24XX - small cleanups in arch/arm/mach-s3c2410 Patch from Ben Dooks Re-tab the devs.c file, and change the initialiser for the mach-vr1000.c to use `.xxx = yyy` form. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-s3c2410/devs.c | 4 ++-- arch/arm/mach-s3c2410/mach-vr1000.c | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/mach-s3c2410/devs.c index 64792f6..4664bd1 100644 --- a/arch/arm/mach-s3c2410/devs.c +++ b/arch/arm/mach-s3c2410/devs.c @@ -96,8 +96,8 @@ struct platform_device s3c_device_lcd = { .num_resources = ARRAY_SIZE(s3c_lcd_resource), .resource = s3c_lcd_resource, .dev = { - .dma_mask = &s3c_device_lcd_dmamask, - .coherent_dma_mask = 0xffffffffUL + .dma_mask = &s3c_device_lcd_dmamask, + .coherent_dma_mask = 0xffffffffUL } }; diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 76be074..1db2855 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -371,16 +371,12 @@ void __init vr1000_map_io(void) usb_simtec_init(); } -void __init vr1000_init_irq(void) -{ - s3c24xx_init_irq(); -} MACHINE_START(VR1000, "Thorcom-VR1000") MAINTAINER("Ben Dooks ") BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(vr1000_map_io) - INITIRQ(vr1000_init_irq) + .map_io = vr1000_map_io, + .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, MACHINE_END -- cgit v1.1 From b720f73296916e87c744193c57bc8687d35888fe Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 15:15:54 +0100 Subject: [PATCH] ARM: Convert ARM timer implementations to use readl/writel Convert ARMs timer implementations to use readl/writel instead of accessing the registers via a struct. People have recently asked if accessing timers via a structure is the "right way" and its not the Linux way. So fix this code to conform to "The Linux Way"(tm). Signed-off-by: Russell King Acked-by: Catalin Marinas --- arch/arm/mach-integrator/core.c | 42 +++++++++---------------- arch/arm/mach-versatile/core.c | 61 ++++++++++++++---------------------- include/asm-arm/hardware/arm_timer.h | 21 +++++++++++++ 3 files changed, 59 insertions(+), 65 deletions(-) create mode 100644 include/asm-arm/hardware/arm_timer.h diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 9222e57..797c7fd 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -156,16 +157,6 @@ EXPORT_SYMBOL(cm_control); #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - static unsigned long timer_reload; /* @@ -174,7 +165,6 @@ static unsigned long timer_reload; */ unsigned long integrator_gettimeoffset(void) { - volatile TimerStruct_t *timer1 = (TimerStruct_t *)TIMER1_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -183,11 +173,11 @@ unsigned long integrator_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + IRQ_RAW_STATUS); - ticks2 = timer1->TimerValue & 0xffff; + ticks2 = readl(TIMER1_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -213,20 +203,19 @@ unsigned long integrator_gettimeoffset(void) static irqreturn_t integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - write_seqlock(&xtime_lock); /* * clear the interrupt */ - timer1->TimerClear = 1; + writel(1, TIMER1_VA_BASE + TIMER_INTCLR); /* * the clock tick routines are only processed on the * primary CPU */ if (hard_smp_processor_id() == 0) { + nmi_tick(); timer_tick(regs); #ifdef CONFIG_SMP smp_send_timer(); @@ -256,32 +245,29 @@ static struct irqaction integrator_timer_irq = { */ void __init integrator_time_init(unsigned long reload, unsigned int ctrl) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - unsigned int timer_ctrl = 0x80 | 0x40; /* periodic */ + unsigned int timer_ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC; timer_reload = reload; timer_ctrl |= ctrl; if (timer_reload > 0x100000) { timer_reload >>= 8; - timer_ctrl |= 0x08; /* /256 */ + timer_ctrl |= TIMER_CTRL_DIV256; } else if (timer_reload > 0x010000) { timer_reload >>= 4; - timer_ctrl |= 0x04; /* /16 */ + timer_ctrl |= TIMER_CTRL_DIV16; } /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); - timer1->TimerLoad = timer_reload; - timer1->TimerValue = timer_reload; - timer1->TimerControl = timer_ctrl; + writel(timer_reload, TIMER1_VA_BASE + TIMER_LOAD); + writel(timer_reload, TIMER1_VA_BASE + TIMER_VALUE); + writel(timer_ctrl, TIMER1_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index 9d1f225..f01c0f8 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -788,38 +789,25 @@ void __init versatile_init(void) */ #define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_10) #if TIMER_INTERVAL >= 0x100000 -#define TIMER_RELOAD (TIMER_INTERVAL >> 8) /* Divide by 256 */ -#define TIMER_CTRL 0x88 /* Enable, Clock / 256 */ +#define TIMER_RELOAD (TIMER_INTERVAL >> 8) +#define TIMER_DIVISOR (TIMER_CTRL_DIV256) #define TICKS2USECS(x) (256 * (x) / TICKS_PER_uSEC) #elif TIMER_INTERVAL >= 0x10000 #define TIMER_RELOAD (TIMER_INTERVAL >> 4) /* Divide by 16 */ -#define TIMER_CTRL 0x84 /* Enable, Clock / 16 */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV16) #define TICKS2USECS(x) (16 * (x) / TICKS_PER_uSEC) #else #define TIMER_RELOAD (TIMER_INTERVAL) -#define TIMER_CTRL 0x80 /* Enable */ +#define TIMER_DIVISOR (TIMER_CTRL_DIV1) #define TICKS2USECS(x) ((x) / TICKS_PER_uSEC) #endif -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable */ - -/* - * What does it look like? - */ -typedef struct TimerStruct { - unsigned long TimerLoad; - unsigned long TimerValue; - unsigned long TimerControl; - unsigned long TimerClear; -} TimerStruct_t; - /* * Returns number of ms since last clock interrupt. Note that interrupts * will have been disabled by do_gettimeoffset() */ static unsigned long versatile_gettimeoffset(void) { - volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE; unsigned long ticks1, ticks2, status; /* @@ -828,11 +816,11 @@ static unsigned long versatile_gettimeoffset(void) * an interrupt. We get around this by ensuring that the * counter has not reloaded between our two reads. */ - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; do { ticks1 = ticks2; status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS); - ticks2 = timer0->TimerValue & 0xffff; + ticks2 = readl(TIMER0_VA_BASE + TIMER_VALUE) & 0xffff; } while (ticks2 > ticks1); /* @@ -859,12 +847,10 @@ static unsigned long versatile_gettimeoffset(void) */ static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - write_seqlock(&xtime_lock); // ...clear the interrupt - timer0->TimerClear = 1; + writel(1, TIMER0_VA_BASE + TIMER_INTCLR); timer_tick(regs); @@ -884,31 +870,32 @@ static struct irqaction versatile_timer_irq = { */ static void __init versatile_timer_init(void) { - volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE; - volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE; - volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE; - volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE; + u32 val; /* * set clock frequency: * VERSATILE_REFCLK is 32KHz * VERSATILE_TIMCLK is 1MHz */ - *(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= - ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | - (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel)); + val = readl(IO_ADDRESS(VERSATILE_SCTL_BASE)); + writel((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | + (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel) | val, + IO_ADDRESS(VERSATILE_SCTL_BASE)); /* * Initialise to a known state (all timers off) */ - timer0->TimerControl = 0; - timer1->TimerControl = 0; - timer2->TimerControl = 0; - timer3->TimerControl = 0; - - timer0->TimerLoad = TIMER_RELOAD; - timer0->TimerValue = TIMER_RELOAD; - timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE; /* periodic + IE */ + writel(0, TIMER0_VA_BASE + TIMER_CTRL); + writel(0, TIMER1_VA_BASE + TIMER_CTRL); + writel(0, TIMER2_VA_BASE + TIMER_CTRL); + writel(0, TIMER3_VA_BASE + TIMER_CTRL); + + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_LOAD); + writel(TIMER_RELOAD, TIMER0_VA_BASE + TIMER_VALUE); + writel(TIMER_DIVISOR | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC | + TIMER_CTRL_IE, TIMER0_VA_BASE + TIMER_CTRL); /* * Make irqs happen for the system timer diff --git a/include/asm-arm/hardware/arm_timer.h b/include/asm-arm/hardware/arm_timer.h new file mode 100644 index 0000000..04be3bd --- /dev/null +++ b/include/asm-arm/hardware/arm_timer.h @@ -0,0 +1,21 @@ +#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H +#define __ASM_ARM_HARDWARE_ARM_TIMER_H + +#define TIMER_LOAD 0x00 +#define TIMER_VALUE 0x04 +#define TIMER_CTRL 0x08 +#define TIMER_CTRL_ONESHOT (1 << 0) +#define TIMER_CTRL_32BIT (1 << 1) +#define TIMER_CTRL_DIV1 (0 << 2) +#define TIMER_CTRL_DIV16 (1 << 2) +#define TIMER_CTRL_DIV256 (2 << 2) +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ +#define TIMER_CTRL_PERIODIC (1 << 6) +#define TIMER_CTRL_ENABLE (1 << 7) + +#define TIMER_INTCLR 0x0c +#define TIMER_RIS 0x10 +#define TIMER_MIS 0x14 +#define TIMER_BGLOAD 0x18 + +#endif -- cgit v1.1 From 9ec3c75cdeb57fa3c12a813c63706ece7fb63648 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Wed, 29 Jun 2005 15:17:49 +0100 Subject: [PATCH] ARM: 2768/1: PXA: Add a required header file for LL_DEBUG Patch from Richard Purdie With DEBUG enabled, head.S includes arch/debug-macro.S. On the PXA, this contains references to the macro io_p2v() so hardware.h needs to be included. Signed-off-by: Richard Purdie Signed-off-by: Russell King --- include/asm-arm/arch-pxa/debug-macro.S | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/asm-arm/arch-pxa/debug-macro.S b/include/asm-arm/arch-pxa/debug-macro.S index f288e74..b6ec688 100644 --- a/include/asm-arm/arch-pxa/debug-macro.S +++ b/include/asm-arm/arch-pxa/debug-macro.S @@ -11,6 +11,8 @@ * */ +#include "hardware.h" + .macro addruart,rx mrc p15, 0, \rx, c1, c0 tst \rx, #1 @ MMU enabled? -- cgit v1.1 From aaaa3f9e51245be3215ff67bb3c7aaf5abb82f00 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 29 Jun 2005 15:34:39 +0100 Subject: [PATCH] ARM: 2769/1: cpu_init() stack setup fix Patch from Catalin Marinas The compiler allocates r14 for the stk variable in the __asm__ directive. This is a shadowed register and gets changed when the mode is changed, causing random values in the SP register. The patch adds a clobber for the r14 register. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8cf733d..35b7273 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -359,7 +359,8 @@ void cpu_init(void) "I" (offsetof(struct stack, abt[0])), "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), - "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)); + "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE) + : "r14"); } static struct machine_desc * __init setup_machine(unsigned int nr) -- cgit v1.1 From 541cecac534ea0df95fbc76b0a3091e91b101895 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 29 Jun 2005 08:43:49 -0700 Subject: Remove duplicate mention of "edd" in Documentation/kernel-parameters.txt --- Documentation/kernel-parameters.txt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 67e99f1..4ec75c0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -437,10 +437,6 @@ running once the system is up. Format: {"of[f]" | "sk[ipmbr]"} See comment in arch/i386/boot/edd.S - edd [EDD] - Format: {"of[f]" | "sk[ipmbr]"} - See comment in arch/i386/boot/edd.S - eicon= [HW,ISDN] Format: ,, -- cgit v1.1 From fd782a4a99d2d3e818b9465c427b10f7f027d7da Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Wed, 29 Jun 2005 15:15:40 +0100 Subject: [PATCH] Fix get_request nastiness get_request is now expected to be holding on to queue_lock, with interrupts disabled, when it returns NULL; but one path forgot that, causing all kinds of nastiness under swap load - badness backtraces, strange failures, BUGs. Signed-off-by: Hugh Dickins Signed-off-by: Linus Torvalds --- drivers/block/ll_rw_blk.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 1197462..692a5fc 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1917,10 +1917,9 @@ get_rq: * limit of requests, otherwise we could have thousands of requests * allocated with any setting of ->nr_requests */ - if (rl->count[rw] >= (3 * q->nr_requests / 2)) { - spin_unlock_irq(q->queue_lock); + if (rl->count[rw] >= (3 * q->nr_requests / 2)) goto out; - } + rl->count[rw]++; rl->starved[rw] = 0; if (rl->count[rw] >= queue_congestion_on_threshold(q)) -- cgit v1.1 From 164cad9bacc2cf190493d2ee4918dc2869ba6f53 Mon Sep 17 00:00:00 2001 From: Prakash Punnoor Date: Wed, 29 Jun 2005 14:13:54 +0200 Subject: [PATCH] Don't fill up log with atxp1 vcore messages change message I am using the atxp1 module to change vcore on my NForce2 via userspace daemon (see punnoor.de). Currently the atxp1 module will write to the log on every vcore change, thus filling up my log - which I don't want. I am no kernel coder, but I guess, this one-liner will change this behaviour in a wanted way, ie output will be made for debug purposes only. Signed-off-by: Prakash Punnoor Signed-off-by: Linus Torvalds --- drivers/i2c/chips/atxp1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/i2c/chips/atxp1.c b/drivers/i2c/chips/atxp1.c index 5c6597a..0bcf82b 100644 --- a/drivers/i2c/chips/atxp1.c +++ b/drivers/i2c/chips/atxp1.c @@ -144,7 +144,7 @@ static ssize_t atxp1_storevcore(struct device *dev, struct device_attribute *att if (vid == cvid) return count; - dev_info(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid); + dev_dbg(dev, "Setting VCore to %d mV (0x%02x)\n", vcore, vid); /* Write every 25 mV step to increase stability */ if (cvid > vid) { -- cgit v1.1 From c7e788766610bdc764d7150e69ace2e0c4196cf0 Mon Sep 17 00:00:00 2001 From: Nicolas Pitre Date: Wed, 29 Jun 2005 18:10:54 +0100 Subject: [PATCH] ARM: 2723/2: remove __udivdi3 and __umoddi3 from the kernel Patch from Nicolas Pitre Those are big, slow and generally not recommended for kernel code. They are even not present on i386. So it should be concluded that one could as well get away with do_div() alone. Signed-off-by: Nicolas Pitre Signed-off-by: Russell King --- arch/arm/kernel/armksyms.c | 6 -- arch/arm/lib/Makefile | 2 +- arch/arm/lib/longlong.h | 183 ------------------------------------- arch/arm/lib/udivdi3.c | 222 --------------------------------------------- drivers/net/arm/etherh.c | 16 ++-- 5 files changed, 8 insertions(+), 421 deletions(-) delete mode 100644 arch/arm/lib/longlong.h delete mode 100644 arch/arm/lib/udivdi3.c diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 4c38bd8..b713c44 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -30,9 +30,6 @@ extern void __lshrdi3(void); extern void __modsi3(void); extern void __muldi3(void); extern void __ucmpdi2(void); -extern void __udivdi3(void); -extern void __umoddi3(void); -extern void __udivmoddi4(void); extern void __udivsi3(void); extern void __umodsi3(void); extern void __do_div64(void); @@ -134,9 +131,6 @@ EXPORT_SYMBOL(__lshrdi3); EXPORT_SYMBOL(__modsi3); EXPORT_SYMBOL(__muldi3); EXPORT_SYMBOL(__ucmpdi2); -EXPORT_SYMBOL(__udivdi3); -EXPORT_SYMBOL(__umoddi3); -EXPORT_SYMBOL(__udivmoddi4); EXPORT_SYMBOL(__udivsi3); EXPORT_SYMBOL(__umodsi3); EXPORT_SYMBOL(__do_div64); diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index c0e6583..8725d63 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -11,7 +11,7 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ strnlen_user.o strchr.o strrchr.o testchangebit.o \ testclearbit.o testsetbit.o uaccess.o getuser.o \ putuser.o ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ - ucmpdi2.o udivdi3.o lib1funcs.o div64.o \ + ucmpdi2.o lib1funcs.o div64.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o ifeq ($(CONFIG_CPU_32v3),y) diff --git a/arch/arm/lib/longlong.h b/arch/arm/lib/longlong.h deleted file mode 100644 index 90ae647..0000000 --- a/arch/arm/lib/longlong.h +++ /dev/null @@ -1,183 +0,0 @@ -/* longlong.h -- based on code from gcc-2.95.3 - - definitions for mixed size 32/64 bit arithmetic. - Copyright (C) 1991, 92, 94, 95, 96, 1997, 1998 Free Software Foundation, Inc. - - This definition file 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, or (at your option) any later version. - - This definition file 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* Borrowed from GCC 2.95.3, I Molton 29/07/01 */ - -#ifndef SI_TYPE_SIZE -#define SI_TYPE_SIZE 32 -#endif - -#define __BITS4 (SI_TYPE_SIZE / 4) -#define __ll_B (1L << (SI_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((u32) (t) % __ll_B) -#define __ll_highpart(t) ((u32) (t) / __ll_B) - -/* Define auxiliary asm macros. - - 1) umul_ppmm(high_prod, low_prod, multipler, multiplicand) - multiplies two u32 integers MULTIPLER and MULTIPLICAND, - and generates a two-part u32 product in HIGH_PROD and - LOW_PROD. - - 2) __umulsidi3(a,b) multiplies two u32 integers A and B, - and returns a u64 product. This is just a variant of umul_ppmm. - - 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator) divides a two-word unsigned integer, composed by the - integers HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and - places the quotient in QUOTIENT and the remainder in REMAINDER. - HIGH_NUMERATOR must be less than DENOMINATOR for correct operation. - If, in addition, the most significant bit of DENOMINATOR must be 1, - then the pre-processor symbol UDIV_NEEDS_NORMALIZATION is defined to 1. - - 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator). Like udiv_qrnnd but the numbers are signed. The - quotient is rounded towards 0. - - 5) count_leading_zeros(count, x) counts the number of zero-bits from - the msb to the first non-zero bit. This is the number of steps X - needs to be shifted left to set the msb. Undefined for X == 0. - - 6) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, - high_addend_2, low_addend_2) adds two two-word unsigned integers, - composed by HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and - LOW_ADDEND_2 respectively. The result is placed in HIGH_SUM and - LOW_SUM. Overflow (i.e. carry out) is not stored anywhere, and is - lost. - - 7) sub_ddmmss(high_difference, low_difference, high_minuend, - low_minuend, high_subtrahend, low_subtrahend) subtracts two - two-word unsigned integers, composed by HIGH_MINUEND_1 and - LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and LOW_SUBTRAHEND_2 - respectively. The result is placed in HIGH_DIFFERENCE and - LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, - and is lost. - - If any of these macros are left undefined for a particular CPU, - C macros are used. */ - -#if defined (__arm__) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("adds %1, %4, %5 \n\ - adc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "%r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "%r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subs %1, %4, %5 \n\ - sbc %0, %2, %3" \ - : "=r" ((u32) (sh)), \ - "=&r" ((u32) (sl)) \ - : "r" ((u32) (ah)), \ - "rI" ((u32) (bh)), \ - "r" ((u32) (al)), \ - "rI" ((u32) (bl))) -#define umul_ppmm(xh, xl, a, b) \ -{register u32 __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm \n\ - mov %2, %5, lsr #16 \n\ - mov %0, %6, lsr #16 \n\ - bic %3, %5, %2, lsl #16 \n\ - bic %4, %6, %0, lsl #16 \n\ - mul %1, %3, %4 \n\ - mul %4, %2, %4 \n\ - mul %3, %0, %3 \n\ - mul %0, %2, %0 \n\ - adds %3, %4, %3 \n\ - addcs %0, %0, #65536 \n\ - adds %1, %1, %3, lsl #16 \n\ - adc %0, %0, %3, lsr #16" \ - : "=&r" ((u32) (xh)), \ - "=r" ((u32) (xl)), \ - "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ - : "r" ((u32) (a)), \ - "r" ((u32) (b)));} -#define UMUL_TIME 20 -#define UDIV_TIME 100 -#endif /* __arm__ */ - -#define __umulsidi3(u, v) \ - ({DIunion __w; \ - umul_ppmm (__w.s.high, __w.s.low, u, v); \ - __w.ll; }) - -#define __udiv_qrnnd_c(q, r, n1, n0, d) \ - do { \ - u32 __d1, __d0, __q1, __q0; \ - u32 __r1, __r0, __m; \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __r1 = (n1) % __d1; \ - __q1 = (n1) / __d1; \ - __m = (u32) __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __r0 = __r1 % __d1; \ - __q0 = __r1 / __d1; \ - __m = (u32) __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = (u32) __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c - -#define count_leading_zeros(count, x) \ - do { \ - u32 __xr = (x); \ - u32 __a; \ - \ - if (SI_TYPE_SIZE <= 32) \ - { \ - __a = __xr < ((u32)1<<2*__BITS4) \ - ? (__xr < ((u32)1<<__BITS4) ? 0 : __BITS4) \ - : (__xr < ((u32)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ - } \ - else \ - { \ - for (__a = SI_TYPE_SIZE - 8; __a > 0; __a -= 8) \ - if (((__xr >> __a) & 0xff) != 0) \ - break; \ - } \ - \ - (count) = SI_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ - } while (0) diff --git a/arch/arm/lib/udivdi3.c b/arch/arm/lib/udivdi3.c deleted file mode 100644 index e343be4..0000000 --- a/arch/arm/lib/udivdi3.c +++ /dev/null @@ -1,222 +0,0 @@ -/* More subroutines needed by GCC output code on some machines. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc. - -This file is part of GNU CC. - -GNU CC 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, or (at your option) -any later version. - -GNU CC 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 General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU CC; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. - */ -/* support functions required by the kernel. based on code from gcc-2.95.3 */ -/* I Molton 29/07/01 */ - -#include "gcclib.h" -#include "longlong.h" - -static const u8 __clz_tab[] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 5, 5, 5, 5, 5, 5, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, -}; - -u64 __udivmoddi4(u64 n, u64 d, u64 * rp) -{ - DIunion ww; - DIunion nn, dd; - DIunion rr; - u32 d0, d1, n0, n1, n2; - u32 q0, q1; - u32 b, bm; - - nn.ll = n; - dd.ll = d; - - d0 = dd.s.low; - d1 = dd.s.high; - n0 = nn.s.low; - n1 = nn.s.high; - - if (d1 == 0) { - if (d0 > n1) { - /* 0q = nn / 0D */ - - count_leading_zeros(bm, d0); - - if (bm != 0) { - /* Normalize, i.e. make the most significant bit of the - denominator set. */ - - d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); - n0 = n0 << bm; - } - - udiv_qrnnd(q0, n0, n1, n0, d0); - q1 = 0; - - /* Remainder in n0 >> bm. */ - } else { - /* qq = NN / 0d */ - - if (d0 == 0) - d0 = 1 / d0; /* Divide intentionally by zero. */ - - count_leading_zeros(bm, d0); - - if (bm == 0) { - /* From (n1 >= d0) /\ (the most significant bit of d0 is set), - conclude (the most significant bit of n1 is set) /\ (the - leading quotient digit q1 = 1). - - This special case is necessary, not an optimization. - (Shifts counts of SI_TYPE_SIZE are undefined.) */ - - n1 -= d0; - q1 = 1; - } else { - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q1, n1, n2, n1, d0); - } - - /* n1 != d0... */ - - udiv_qrnnd(q0, n0, n1, n0, d0); - - /* Remainder in n0 >> bm. */ - } - - if (rp != 0) { - rr.s.low = n0 >> bm; - rr.s.high = 0; - *rp = rr.ll; - } - } else { - if (d1 > n1) { - /* 00 = nn / DD */ - - q0 = 0; - q1 = 0; - - /* Remainder in n1n0. */ - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - /* 0q = NN / dd */ - - count_leading_zeros(bm, d1); - if (bm == 0) { - /* From (n1 >= d1) /\ (the most significant bit of d1 is set), - conclude (the most significant bit of n1 is set) /\ (the - quotient digit q0 = 0 or 1). - - This special case is necessary, not an optimization. */ - - /* The condition on the next line takes advantage of that - n1 >= d1 (true due to program flow). */ - if (n1 > d1 || n0 >= d0) { - q0 = 1; - sub_ddmmss(n1, n0, n1, n0, d1, d0); - } else - q0 = 0; - - q1 = 0; - - if (rp != 0) { - rr.s.low = n0; - rr.s.high = n1; - *rp = rr.ll; - } - } else { - u32 m1, m0; - /* Normalize. */ - - b = SI_TYPE_SIZE - bm; - - d1 = (d1 << bm) | (d0 >> b); - d0 = d0 << bm; - n2 = n1 >> b; - n1 = (n1 << bm) | (n0 >> b); - n0 = n0 << bm; - - udiv_qrnnd(q0, n1, n2, n1, d1); - umul_ppmm(m1, m0, q0, d0); - - if (m1 > n1 || (m1 == n1 && m0 > n0)) { - q0--; - sub_ddmmss(m1, m0, m1, m0, d1, d0); - } - - q1 = 0; - - /* Remainder in (n1n0 - m1m0) >> bm. */ - if (rp != 0) { - sub_ddmmss(n1, n0, n1, n0, m1, m0); - rr.s.low = (n1 << b) | (n0 >> bm); - rr.s.high = n1 >> bm; - *rp = rr.ll; - } - } - } - } - - ww.s.low = q0; - ww.s.high = q1; - return ww.ll; -} - -u64 __udivdi3(u64 n, u64 d) -{ - return __udivmoddi4(n, d, (u64 *) 0); -} - -u64 __umoddi3(u64 u, u64 v) -{ - u64 w; - - (void)__udivmoddi4(u, v, &w); - - return w; -} diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c index 2e28c20..942a281 100644 --- a/drivers/net/arm/etherh.c +++ b/drivers/net/arm/etherh.c @@ -68,7 +68,6 @@ struct etherh_priv { void __iomem *dma_base; unsigned int id; void __iomem *ctrl_port; - void __iomem *base; unsigned char ctrl; u32 supported; }; @@ -178,7 +177,7 @@ etherh_setif(struct net_device *dev) switch (etherh_priv(dev)->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: - addr = etherh_priv(dev)->base + EN0_RCNTHI; + addr = (void *)dev->base_addr + EN0_RCNTHI; switch (dev->if_port) { case IF_PORT_10BASE2: @@ -219,7 +218,7 @@ etherh_getifstat(struct net_device *dev) switch (etherh_priv(dev)->id) { case PROD_I3_ETHERLAN600: case PROD_I3_ETHERLAN600A: - addr = etherh_priv(dev)->base + EN0_RCNTHI; + addr = (void *)dev->base_addr + EN0_RCNTHI; switch (dev->if_port) { case IF_PORT_10BASE2: stat = 1; @@ -282,7 +281,7 @@ static void etherh_reset(struct net_device *dev) { struct ei_device *ei_local = netdev_priv(dev); - void __iomem *addr = etherh_priv(dev)->base; + void __iomem *addr = (void *)dev->base_addr; writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr); @@ -328,7 +327,7 @@ etherh_block_output (struct net_device *dev, int count, const unsigned char *buf ei_local->dmaing = 1; - addr = etherh_priv(dev)->base; + addr = (void *)dev->base_addr; dma_base = etherh_priv(dev)->dma_base; count = (count + 1) & ~1; @@ -388,7 +387,7 @@ etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ei_local->dmaing = 1; - addr = etherh_priv(dev)->base; + addr = (void *)dev->base_addr; dma_base = etherh_priv(dev)->dma_base; buf = skb->data; @@ -428,7 +427,7 @@ etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_p ei_local->dmaing = 1; - addr = etherh_priv(dev)->base; + addr = (void *)dev->base_addr; dma_base = etherh_priv(dev)->dma_base; writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD); @@ -697,8 +696,7 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id) eh->ctrl_port = eh->ioc_fast; } - eh->base = eh->memc + data->ns8390_offset; - dev->base_addr = (unsigned long)eh->base; + dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset; eh->dma_base = eh->memc + data->dataport_offset; eh->ctrl_port += data->ctrlport_offset; -- cgit v1.1 From 20f720ccce8864583365d844d48d3fe8d0d171ad Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 18:26:19 +0100 Subject: [PATCH] ARM: Remove nmi_tick from integrator platforms The nmi watchdog code hasn't been merged for this platform yet. Signed-off-by: Russell King --- arch/arm/mach-integrator/core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 797c7fd..dacbf50 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -215,7 +215,6 @@ integrator_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * primary CPU */ if (hard_smp_processor_id() == 0) { - nmi_tick(); timer_tick(regs); #ifdef CONFIG_SMP smp_send_timer(); -- cgit v1.1 From 0dd7a1aed7c34a39917c4faf75b4230c169e809b Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 18:40:53 +0100 Subject: [PATCH] Serial: Check status of CTS when using flow control Fix bugme #4712: read the CTS status and set hw_stopped if CTS is not active when opening the port and/or enabling CRTSCTS Thanks to Stefan Wolff for spotting this problem. Signed-off-by: Russell King --- drivers/serial/serial_core.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index f5ce58d..139863a 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -182,6 +182,13 @@ static int uart_startup(struct uart_state *state, int init_hw) uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR); } + if (info->flags & UIF_CTS_FLOW) { + spin_lock_irq(&port->lock); + if (!(port->ops->get_mctrl(port) & TIOCM_CTS)) + info->tty->hw_stopped = 1; + spin_unlock_irq(&port->lock); + } + info->flags |= UIF_INITIALIZED; clear_bit(TTY_IO_ERROR, &info->tty->flags); @@ -1134,6 +1141,16 @@ static void uart_set_termios(struct tty_struct *tty, struct termios *old_termios spin_unlock_irqrestore(&state->port->lock, flags); } + /* Handle turning on CRTSCTS */ + if (!(old_termios->c_cflag & CRTSCTS) && (cflag & CRTSCTS)) { + spin_lock_irqsave(&state->port->lock, flags); + if (!(state->port->ops->get_mctrl(state->port) & TIOCM_CTS)) { + tty->hw_stopped = 1; + state->port->ops->stop_tx(state->port, 0); + } + spin_unlock_irqrestore(&state->port->lock, flags); + } + #if 0 /* * No need to wake up processes in open wait, since they -- cgit v1.1 From e763b90c41563a0f8258d379fe71a9a1f1fa5445 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 18:41:51 +0100 Subject: [PATCH] Serial: Disable OX950 transmitter for flow control Disable the transmitter whenever we want to prevent characters being transmitted by flow control. However, if we run out of characters to send and want to only disable the TX interrupt, allow that scenario. Signed-off-by: Russell King --- drivers/serial/8250.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index b53b53b..429994d 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -993,21 +993,24 @@ static void autoconfig_irq(struct uart_8250_port *up) up->port.irq = (irq > 0) ? irq : 0; } +static inline void __stop_tx(struct uart_8250_port *p) +{ + if (p->ier & UART_IER_THRI) { + p->ier &= ~UART_IER_THRI; + serial_out(p, UART_IER, p->ier); + } +} + static void serial8250_stop_tx(struct uart_port *port, unsigned int tty_stop) { struct uart_8250_port *up = (struct uart_8250_port *)port; - if (up->ier & UART_IER_THRI) { - up->ier &= ~UART_IER_THRI; - serial_out(up, UART_IER, up->ier); - } + __stop_tx(up); /* - * We only do this from uart_stop - if we run out of - * characters to send, we don't want to prevent the - * FIFO from emptying. + * We really want to stop the transmitter from sending. */ - if (up->port.type == PORT_16C950 && tty_stop) { + if (up->port.type == PORT_16C950) { up->acr |= UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -1031,10 +1034,11 @@ static void serial8250_start_tx(struct uart_port *port, unsigned int tty_start) transmit_chars(up); } } + /* - * We only do this from uart_start + * Re-enable the transmitter if we disabled it. */ - if (tty_start && up->port.type == PORT_16C950) { + if (up->port.type == PORT_16C950 && up->acr & UART_ACR_TXDIS) { up->acr &= ~UART_ACR_TXDIS; serial_icr_write(up, UART_ACR, up->acr); } @@ -1155,7 +1159,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { - serial8250_stop_tx(&up->port, 0); + __stop_tx(up); return; } @@ -1174,7 +1178,7 @@ static _INLINE_ void transmit_chars(struct uart_8250_port *up) DEBUG_INTR("THRE..."); if (uart_circ_empty(xmit)) - serial8250_stop_tx(&up->port, 0); + __stop_tx(up); } static _INLINE_ void check_modem_status(struct uart_8250_port *up) -- cgit v1.1 From 026d02a236f429eb61a1277166bd425f8514c431 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 18:45:19 +0100 Subject: [PATCH] Serial: Split 8250 port table (part 2) Remove legacy ISA serial ports for Accent, Boca, Fourport, Hub6 and MCA from the architecture specific serial.h include. The only ports which remain in asm-*/serial.h are the platform specific entries. These should really be converted by platform maintainers to use a platform device, such as can be found in arch/arm/mach-footbridge/isa.c Signed-off-by: Russell King --- arch/parisc/configs/712_defconfig | 2 +- arch/parisc/configs/a500_defconfig | 2 +- arch/parisc/configs/b180_defconfig | 2 +- arch/parisc/configs/c3000_defconfig | 2 +- arch/parisc/defconfig | 2 +- drivers/serial/8250.c | 2 +- drivers/serial/Kconfig | 2 +- include/asm-alpha/serial.h | 47 +---------------- include/asm-arm26/serial.h | 22 +------- include/asm-i386/serial.h | 102 +----------------------------------- include/asm-m68k/serial.h | 47 +---------------- include/asm-mips/serial.h | 84 ----------------------------- include/asm-parisc/serial.h | 16 +----- include/asm-ppc/pc_serial.h | 86 +----------------------------- include/asm-sh/bigsur/serial.h | 5 +- include/asm-sh/ec3104/serial.h | 4 +- include/asm-sh/serial.h | 6 +-- include/asm-sh64/serial.h | 4 +- include/asm-x86_64/serial.h | 102 +----------------------------------- 19 files changed, 20 insertions(+), 519 deletions(-) diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig index 872085d..6efaa92 100644 --- a/arch/parisc/configs/712_defconfig +++ b/arch/parisc/configs/712_defconfig @@ -506,7 +506,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index d28ebfa..30fc03e 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig @@ -662,7 +662,7 @@ CONFIG_HW_CONSOLE=y CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CS=m -CONFIG_SERIAL_8250_NR_UARTS=8 +CONFIG_SERIAL_8250_NR_UARTS=17 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig index 1700d7a..46c9511 100644 --- a/arch/parisc/configs/b180_defconfig +++ b/arch/parisc/configs/b180_defconfig @@ -514,7 +514,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig index b279801..67aca6c 100644 --- a/arch/parisc/configs/c3000_defconfig +++ b/arch/parisc/configs/c3000_defconfig @@ -661,7 +661,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig index ebd6301..fdae21c5 100644 --- a/arch/parisc/defconfig +++ b/arch/parisc/defconfig @@ -517,7 +517,7 @@ CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250_CONSOLE=y -CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_NR_UARTS=13 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_MANY_PORTS=y CONFIG_SERIAL_8250_SHARE_IRQ=y diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 429994d..9224fc3 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -105,7 +105,7 @@ static struct old_serial_port old_serial_port[] = { SERIAL_PORT_DFNS /* defined in asm/serial.h */ }; -#define UART_NR (ARRAY_SIZE(old_serial_port) + CONFIG_SERIAL_8250_NR_UARTS) +#define UART_NR CONFIG_SERIAL_8250_NR_UARTS #ifdef CONFIG_SERIAL_8250_RSA diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index e879bce..e0d0a47 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -86,7 +86,7 @@ config SERIAL_8250_ACPI namespace, say Y here. If unsure, say N. config SERIAL_8250_NR_UARTS - int "Maximum number of non-legacy 8250/16550 serial ports" + int "Maximum number of 8250/16550 serial ports" depends on SERIAL_8250 default "4" help diff --git a/include/asm-alpha/serial.h b/include/asm-alpha/serial.h index 7b2d9ee..7e4b298 100644 --- a/include/asm-alpha/serial.h +++ b/include/asm-alpha/serial.h @@ -22,54 +22,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#endif - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS diff --git a/include/asm-arm26/serial.h b/include/asm-arm26/serial.h index 21e1df3..5fc747d 100644 --- a/include/asm-arm26/serial.h +++ b/include/asm-arm26/serial.h @@ -30,34 +30,16 @@ #if defined(CONFIG_ARCH_A5K) /* UART CLK PORT IRQ FLAGS */ -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ { 0, BASE_BAUD, 0x3F8, 10, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 10, STD_COM_FLAGS }, /* ttyS1 */ #else -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS1 */ #endif -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS2 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS3 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS - #endif diff --git a/include/asm-i386/serial.h b/include/asm-i386/serial.h index 21ddecc..e1ecfcc 100644 --- a/include/asm-i386/serial.h +++ b/include/asm-i386/serial.h @@ -22,109 +22,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -#define MCA_COM_FLAGS (STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA) - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - -#ifdef CONFIG_MCA -#define MCA_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS }, -#else -#define MCA_SERIAL_PORT_DFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MCA_SERIAL_PORT_DFNS - diff --git a/include/asm-m68k/serial.h b/include/asm-m68k/serial.h index 9f5bcdc..3fe29f8 100644 --- a/include/asm-m68k/serial.h +++ b/include/asm-m68k/serial.h @@ -26,54 +26,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#endif - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 8a70ff5..4eed8e2a 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h @@ -29,32 +29,6 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#define RS_TABLE_SIZE 64 -#else -#define RS_TABLE_SIZE -#endif - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - #ifdef CONFIG_MACH_JAZZ #include @@ -240,66 +214,10 @@ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else /* CONFIG_SERIAL_MANY_PORTS */ -#define EXTRA_SERIAL_PORT_DEFNS -#endif /* CONFIG_SERIAL_MANY_PORTS */ - #else /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ #define STD_SERIAL_PORT_DEFNS -#define EXTRA_SERIAL_PORT_DEFNS #endif /* CONFIG_HAVE_STD_PC_SERIAL_PORTS */ -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - #ifdef CONFIG_MOMENCO_JAGUAR_ATX /* Ordinary NS16552 duart with a 20MHz crystal. */ #define JAGUAR_ATX_UART_CLK 20000000 @@ -427,8 +345,6 @@ COBALT_SERIAL_PORT_DEFNS \ DDB5477_SERIAL_PORT_DEFNS \ EV96100_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ IP32_SERIAL_PORT_DEFNS \ ITE_SERIAL_PORT_DEFNS \ IVR_SERIAL_PORT_DEFNS \ diff --git a/include/asm-parisc/serial.h b/include/asm-parisc/serial.h index 239c5dc..82fd820 100644 --- a/include/asm-parisc/serial.h +++ b/include/asm-parisc/serial.h @@ -19,18 +19,4 @@ * A500 w/ PCI serial cards: 5 + 4 * card ~= 17 */ -#define STD_SERIAL_PORT_DEFNS \ - { 0, }, /* ttyS0 */ \ - { 0, }, /* ttyS1 */ \ - { 0, }, /* ttyS2 */ \ - { 0, }, /* ttyS3 */ \ - { 0, }, /* ttyS4 */ \ - { 0, }, /* ttyS5 */ \ - { 0, }, /* ttyS6 */ \ - { 0, }, /* ttyS7 */ \ - { 0, }, /* ttyS8 */ - - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS - +#define SERIAL_PORT_DFNS diff --git a/include/asm-ppc/pc_serial.h b/include/asm-ppc/pc_serial.h index fa9cbb6..8f994f9 100644 --- a/include/asm-ppc/pc_serial.h +++ b/include/asm-ppc/pc_serial.h @@ -35,93 +35,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS diff --git a/include/asm-sh/bigsur/serial.h b/include/asm-sh/bigsur/serial.h index 540f122..7233af4 100644 --- a/include/asm-sh/bigsur/serial.h +++ b/include/asm-sh/bigsur/serial.h @@ -14,13 +14,10 @@ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ - -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) diff --git a/include/asm-sh/ec3104/serial.h b/include/asm-sh/ec3104/serial.h index f8eb163..cfe4d78 100644 --- a/include/asm-sh/ec3104/serial.h +++ b/include/asm-sh/ec3104/serial.h @@ -10,13 +10,11 @@ * it's got the keyboard controller behind it so we can't really use it * (without moving the keyboard driver to userspace, which doesn't sound * like a very good idea) */ -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x11C00, EC3104_IRQBASE+7, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x12000, EC3104_IRQBASE+8, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x12400, EC3104_IRQBASE+9, STD_COM_FLAGS }, /* ttyS2 */ -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) diff --git a/include/asm-sh/serial.h b/include/asm-sh/serial.h index 5474dbd..f51e232 100644 --- a/include/asm-sh/serial.h +++ b/include/asm-sh/serial.h @@ -29,20 +29,18 @@ #ifdef CONFIG_HD64465 #include -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, HD64465_IRQ_UART, STD_COM_FLAGS } /* ttyS0 */ #else -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS } /* ttyS1 */ #endif -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - #endif #endif /* _ASM_SERIAL_H */ diff --git a/include/asm-sh64/serial.h b/include/asm-sh64/serial.h index 8e39b4e..29c9be1 100644 --- a/include/asm-sh64/serial.h +++ b/include/asm-sh64/serial.h @@ -20,13 +20,11 @@ #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST) -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS } /* ttyS1 */ -#define SERIAL_PORT_DFNS STD_SERIAL_PORT_DEFNS - /* XXX: This should be moved ino irq.h */ #define irq_cannonicalize(x) (x) diff --git a/include/asm-x86_64/serial.h b/include/asm-x86_64/serial.h index dbab232..dc752ea 100644 --- a/include/asm-x86_64/serial.h +++ b/include/asm-x86_64/serial.h @@ -22,109 +22,9 @@ #define STD_COM4_FLAGS ASYNC_BOOT_AUTOCONF #endif -#ifdef CONFIG_SERIAL_MANY_PORTS -#define FOURPORT_FLAGS ASYNC_FOURPORT -#define ACCENT_FLAGS 0 -#define BOCA_FLAGS 0 -#define HUB6_FLAGS 0 -#endif - -#define MCA_COM_FLAGS (STD_COM_FLAGS|ASYNC_BOOT_ONLYMCA) - -/* - * The following define the access methods for the HUB6 card. All - * access is through two ports for all 24 possible chips. The card is - * selected through the high 2 bits, the port on that card with the - * "middle" 3 bits, and the register on that port with the bottom - * 3 bits. - * - * While the access port and interrupt is configurable, the default - * port locations are 0x302 for the port control register, and 0x303 - * for the data read/write register. Normally, the interrupt is at irq3 - * but can be anything from 3 to 7 inclusive. Note that using 3 will - * require disabling com2. - */ - -#define C_P(card,port) (((card)<<6|(port)<<3) + 1) - -#define STD_SERIAL_PORT_DEFNS \ +#define SERIAL_PORT_DFNS \ /* UART CLK PORT IRQ FLAGS */ \ { 0, BASE_BAUD, 0x3F8, 4, STD_COM_FLAGS }, /* ttyS0 */ \ { 0, BASE_BAUD, 0x2F8, 3, STD_COM_FLAGS }, /* ttyS1 */ \ { 0, BASE_BAUD, 0x3E8, 4, STD_COM_FLAGS }, /* ttyS2 */ \ { 0, BASE_BAUD, 0x2E8, 3, STD_COM4_FLAGS }, /* ttyS3 */ - - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define EXTRA_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, 0x1A0, 9, FOURPORT_FLAGS }, /* ttyS4 */ \ - { 0, BASE_BAUD, 0x1A8, 9, FOURPORT_FLAGS }, /* ttyS5 */ \ - { 0, BASE_BAUD, 0x1B0, 9, FOURPORT_FLAGS }, /* ttyS6 */ \ - { 0, BASE_BAUD, 0x1B8, 9, FOURPORT_FLAGS }, /* ttyS7 */ \ - { 0, BASE_BAUD, 0x2A0, 5, FOURPORT_FLAGS }, /* ttyS8 */ \ - { 0, BASE_BAUD, 0x2A8, 5, FOURPORT_FLAGS }, /* ttyS9 */ \ - { 0, BASE_BAUD, 0x2B0, 5, FOURPORT_FLAGS }, /* ttyS10 */ \ - { 0, BASE_BAUD, 0x2B8, 5, FOURPORT_FLAGS }, /* ttyS11 */ \ - { 0, BASE_BAUD, 0x330, 4, ACCENT_FLAGS }, /* ttyS12 */ \ - { 0, BASE_BAUD, 0x338, 4, ACCENT_FLAGS }, /* ttyS13 */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS14 (spare) */ \ - { 0, BASE_BAUD, 0x000, 0, 0 }, /* ttyS15 (spare) */ \ - { 0, BASE_BAUD, 0x100, 12, BOCA_FLAGS }, /* ttyS16 */ \ - { 0, BASE_BAUD, 0x108, 12, BOCA_FLAGS }, /* ttyS17 */ \ - { 0, BASE_BAUD, 0x110, 12, BOCA_FLAGS }, /* ttyS18 */ \ - { 0, BASE_BAUD, 0x118, 12, BOCA_FLAGS }, /* ttyS19 */ \ - { 0, BASE_BAUD, 0x120, 12, BOCA_FLAGS }, /* ttyS20 */ \ - { 0, BASE_BAUD, 0x128, 12, BOCA_FLAGS }, /* ttyS21 */ \ - { 0, BASE_BAUD, 0x130, 12, BOCA_FLAGS }, /* ttyS22 */ \ - { 0, BASE_BAUD, 0x138, 12, BOCA_FLAGS }, /* ttyS23 */ \ - { 0, BASE_BAUD, 0x140, 12, BOCA_FLAGS }, /* ttyS24 */ \ - { 0, BASE_BAUD, 0x148, 12, BOCA_FLAGS }, /* ttyS25 */ \ - { 0, BASE_BAUD, 0x150, 12, BOCA_FLAGS }, /* ttyS26 */ \ - { 0, BASE_BAUD, 0x158, 12, BOCA_FLAGS }, /* ttyS27 */ \ - { 0, BASE_BAUD, 0x160, 12, BOCA_FLAGS }, /* ttyS28 */ \ - { 0, BASE_BAUD, 0x168, 12, BOCA_FLAGS }, /* ttyS29 */ \ - { 0, BASE_BAUD, 0x170, 12, BOCA_FLAGS }, /* ttyS30 */ \ - { 0, BASE_BAUD, 0x178, 12, BOCA_FLAGS }, /* ttyS31 */ -#else -#define EXTRA_SERIAL_PORT_DEFNS -#endif - -/* You can have up to four HUB6's in the system, but I've only - * included two cards here for a total of twelve ports. - */ -#if (defined(CONFIG_HUB6) && defined(CONFIG_SERIAL_MANY_PORTS)) -#define HUB6_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,0) }, /* ttyS32 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,1) }, /* ttyS33 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,2) }, /* ttyS34 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,3) }, /* ttyS35 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,4) }, /* ttyS36 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(0,5) }, /* ttyS37 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,0) }, /* ttyS38 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,1) }, /* ttyS39 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,2) }, /* ttyS40 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,3) }, /* ttyS41 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,4) }, /* ttyS42 */ \ - { 0, BASE_BAUD, 0x302, 3, HUB6_FLAGS, C_P(1,5) }, /* ttyS43 */ -#else -#define HUB6_SERIAL_PORT_DFNS -#endif - -#ifdef CONFIG_MCA -#define MCA_SERIAL_PORT_DFNS \ - { 0, BASE_BAUD, 0x3220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x3228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x4228, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5220, 3, MCA_COM_FLAGS }, \ - { 0, BASE_BAUD, 0x5228, 3, MCA_COM_FLAGS }, -#else -#define MCA_SERIAL_PORT_DFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - EXTRA_SERIAL_PORT_DEFNS \ - HUB6_SERIAL_PORT_DFNS \ - MCA_SERIAL_PORT_DFNS - -- cgit v1.1 From b3402cf50efead37dd9553b90fbf1486e09fb78e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 29 Jun 2005 19:59:48 +0100 Subject: [PATCH] ARM: 2771/1: Dynamic Tick support for OMAP, take 4 Patch from Tony Lindgren This patch adds support for Dynamic Tick Timer for OMAP. This patch is an updated version of ARM patch 2642/1 to make it work with the already integrated generic ARM dyntick support. Signed-off-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/mach-omap/pm.c | 16 ++++++++++------ arch/arm/mach-omap/time.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-omap/pm.c b/arch/arm/mach-omap/pm.c index 00fac15..6b03ccd 100644 --- a/arch/arm/mach-omap/pm.c +++ b/arch/arm/mach-omap/pm.c @@ -41,7 +41,9 @@ #include #include +#include #include + #include #include #include @@ -80,13 +82,13 @@ void omap_pm_idle(void) return; } mask32 = omap_readl(ARM_SYSST); - local_fiq_enable(); - local_irq_enable(); -#if defined(CONFIG_OMAP_32K_TIMER) && defined(CONFIG_NO_IDLE_HZ) - /* Override timer to use VST for the next cycle */ - omap_32k_timer_next_vst_interrupt(); -#endif + /* + * Since an interrupt may set up a timer, we don't want to + * reprogram the hardware timer with interrupts enabled. + * Re-enable interrupts only after returning from idle. + */ + timer_dyn_reprogram(); if ((mask32 & DSP_IDLE) == 0) { __asm__ volatile ("mcr p15, 0, r0, c7, c0, 4"); @@ -102,6 +104,8 @@ void omap_pm_idle(void) func_ptr(); } + local_fiq_enable(); + local_irq_enable(); } /* diff --git a/arch/arm/mach-omap/time.c b/arch/arm/mach-omap/time.c index 589e8b2..dd34e9f 100644 --- a/arch/arm/mach-omap/time.c +++ b/arch/arm/mach-omap/time.c @@ -4,7 +4,7 @@ * OMAP Timers * * Copyright (C) 2004 Nokia Corporation - * Partial timer rewrite and additional VST timer support by + * Partial timer rewrite and additional dynamic tick timer support by * Tony Lindgen and * Tuukka Tikkanen * @@ -261,7 +261,6 @@ unsigned long long sched_clock(void) * so with HZ = 100, TVR = 327.68. */ #define OMAP_32K_TIMER_TICK_PERIOD ((32768 / HZ) - 1) -#define MAX_SKIP_JIFFIES 25 #define TIMER_32K_SYNCHRONIZED 0xfffbc410 #define JIFFIES_TO_HW_TICKS(nr_jiffies, clock_rate) \ @@ -347,6 +346,42 @@ static irqreturn_t omap_32k_timer_interrupt(int irq, void *dev_id, return IRQ_HANDLED; } +#ifdef CONFIG_NO_IDLE_HZ +/* + * Programs the next timer interrupt needed. Called when dynamic tick is + * enabled, and to reprogram the ticks to skip from pm_idle. Note that + * we can keep the timer continuous, and don't need to set it to run in + * one-shot mode. This is because the timer will get reprogrammed again + * after next interrupt. + */ +void omap_32k_timer_reprogram(unsigned long next_tick) +{ + omap_32k_timer_start(JIFFIES_TO_HW_TICKS(next_tick, 32768) + 1); +} + +static struct irqaction omap_32k_timer_irq; +extern struct timer_update_handler timer_update; + +static int omap_32k_timer_enable_dyn_tick(void) +{ + /* No need to reprogram timer, just use the next interrupt */ + return 0; +} + +static int omap_32k_timer_disable_dyn_tick(void) +{ + omap_32k_timer_start(OMAP_32K_TIMER_TICK_PERIOD); + return 0; +} + +static struct dyn_tick_timer omap_dyn_tick_timer = { + .enable = omap_32k_timer_enable_dyn_tick, + .disable = omap_32k_timer_disable_dyn_tick, + .reprogram = omap_32k_timer_reprogram, + .handler = omap_32k_timer_interrupt, +}; +#endif /* CONFIG_NO_IDLE_HZ */ + static struct irqaction omap_32k_timer_irq = { .name = "32KHz timer", .flags = SA_INTERRUPT | SA_TIMER, @@ -355,6 +390,11 @@ static struct irqaction omap_32k_timer_irq = { static __init void omap_init_32k_timer(void) { + +#ifdef CONFIG_NO_IDLE_HZ + omap_timer.dyn_tick = &omap_dyn_tick_timer; +#endif + setup_irq(INT_OS_TIMER, &omap_32k_timer_irq); omap_timer.offset = omap_32k_timer_gettimeoffset; omap_32k_last_tick = omap_32k_sync_timer_read(); -- cgit v1.1 From 438a76167959061e371025f727fabec2ad9e70a7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 23:01:02 +0100 Subject: [PATCH] ARM: Fix VFP to use do_div() VFP used __divdi3 64-bit division needlessly. Convert it to use our 64-bit by 32-bit division instead. Signed-off-by: Russell King --- arch/arm/vfp/vfp.h | 15 +++++++++++++-- arch/arm/vfp/vfpdouble.c | 2 ++ arch/arm/vfp/vfpsingle.c | 14 ++++++++++++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/arch/arm/vfp/vfp.h b/arch/arm/vfp/vfp.h index 55a02bc..4b97950 100644 --- a/arch/arm/vfp/vfp.h +++ b/arch/arm/vfp/vfp.h @@ -117,7 +117,13 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) if (nh >= m) return ~0ULL; mh = m >> 32; - z = (mh << 32 <= nh) ? 0xffffffff00000000ULL : (nh / mh) << 32; + if (mh << 32 <= nh) { + z = 0xffffffff00000000ULL; + } else { + z = nh; + do_div(z, mh); + z <<= 32; + } mul64to128(&termh, &terml, m, z); sub128(&remh, &reml, nh, nl, termh, terml); ml = m << 32; @@ -126,7 +132,12 @@ static inline u64 vfp_estimate_div128to64(u64 nh, u64 nl, u64 m) add128(&remh, &reml, remh, reml, mh, ml); } remh = (remh << 32) | (reml >> 32); - z |= (mh << 32 <= remh) ? 0xffffffff : remh / mh; + if (mh << 32 <= remh) { + z |= 0xffffffff; + } else { + do_div(remh, mh); + z |= remh; + } return z; } diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index fa3053e..b801cd6 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c @@ -32,6 +32,8 @@ */ #include #include + +#include #include #include diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 6849fe3..14dd696 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c @@ -32,6 +32,8 @@ */ #include #include + +#include #include #include @@ -303,7 +305,11 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) if (z <= a) return (s32)a >> 1; } - return (u32)(((u64)a << 31) / z) + (z >> 1); + { + u64 v = (u64)a << 31; + do_div(v, z); + return v + (z >> 1); + } } static u32 vfp_single_fsqrt(int sd, int unused, s32 m, u32 fpscr) @@ -1107,7 +1113,11 @@ static u32 vfp_single_fdiv(int sd, int sn, s32 m, u32 fpscr) vsn.significand >>= 1; vsd.exponent++; } - vsd.significand = ((u64)vsn.significand << 32) / vsm.significand; + { + u64 significand = (u64)vsn.significand << 32; + do_div(significand, vsm.significand); + vsd.significand = significand; + } if ((vsd.significand & 0x3f) == 0) vsd.significand |= ((u64)vsm.significand * vsd.significand != (u64)vsn.significand << 32); -- cgit v1.1 From da41119af78864d27ccbf505949df788d5e8aaf5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 29 Jun 2005 23:02:02 +0100 Subject: [PATCH] ARM: Don't force SIGFPE We were forcing SIGFPE on to a user program for no good reason. Use send_sig_info() instead. Signed-off-by: Russell King --- arch/arm/vfp/vfpmodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 3aeedd2..22f3da4 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c @@ -89,7 +89,7 @@ void vfp_raise_sigfpe(unsigned int sicode, struct pt_regs *regs) current->thread.error_code = 0; current->thread.trap_no = 6; - force_sig_info(SIGFPE, &info, current); + send_sig_info(SIGFPE, &info, current); } static void vfp_panic(char *reason) -- cgit v1.1 From 06697eea4ce18870fbce82dffbb375e216145f47 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 29 Jun 2005 15:45:41 -0700 Subject: [IA64] Update tiger_defconfig Signed-off-by: Tony Luck --- arch/ia64/configs/tiger_defconfig | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/arch/ia64/configs/tiger_defconfig b/arch/ia64/configs/tiger_defconfig index 47f4534..73454ee 100644 --- a/arch/ia64/configs/tiger_defconfig +++ b/arch/ia64/configs/tiger_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-20050621 -# Tue Jun 21 14:03:24 2005 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:28:12 2005 # # @@ -80,18 +80,29 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y CONFIG_HOLES_IN_ZONE=y CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=4 CONFIG_HOTPLUG_CPU=y # CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y @@ -257,6 +268,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set CONFIG_BLK_DEV_PIIX=y +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -395,6 +407,7 @@ CONFIG_UNIX=y CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -407,6 +420,8 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_TUNNEL is not set CONFIG_IP_TCPDIAG=y # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set # CONFIG_NETFILTER is not set @@ -598,9 +613,7 @@ CONFIG_GAMEPORT=m # CONFIG_GAMEPORT_NS558 is not set # CONFIG_GAMEPORT_L4 is not set # CONFIG_GAMEPORT_EMU10K1 is not set -# CONFIG_GAMEPORT_VORTEX is not set # CONFIG_GAMEPORT_FM801 is not set -# CONFIG_GAMEPORT_CS461X is not set # # Character devices @@ -629,7 +642,6 @@ CONFIG_SERIAL_8250_NR_UARTS=6 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -743,6 +755,7 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_EHCI_HCD=m # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=m # CONFIG_USB_OHCI_BIG_ENDIAN is not set CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -779,9 +792,11 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_HIDDEV is not set # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -838,7 +853,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_TEST is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -857,12 +872,17 @@ CONFIG_USB_HIDINPUT=y # CONFIG_INFINIBAND is not set # +# SN Devices +# + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y CONFIG_EXT2_FS_POSIX_ACL=y CONFIG_EXT2_FS_SECURITY=y +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y CONFIG_EXT3_FS_POSIX_ACL=y @@ -922,7 +942,6 @@ CONFIG_NTFS_FS=m CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -953,15 +972,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=m CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y CONFIG_NFS_DIRECTIO=y CONFIG_NFSD=m CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set CONFIG_NFSD_V4=y CONFIG_NFSD_TCP=y CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_RPCSEC_GSS_KRB5=m @@ -1069,6 +1091,7 @@ CONFIG_LOG_BUF_SHIFT=20 # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set # CONFIG_DEBUG_FS is not set +# CONFIG_KPROBES is not set CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set # CONFIG_IA64_PRINT_HAZARDS is not set @@ -1090,7 +1113,7 @@ CONFIG_CRYPTO=y # CONFIG_CRYPTO_HMAC is not set # CONFIG_CRYPTO_NULL is not set # CONFIG_CRYPTO_MD4 is not set -CONFIG_CRYPTO_MD5=m +CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA1 is not set # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set -- cgit v1.1 From 0647d8cfd40f7974335884d73deef83feeffc2a0 Mon Sep 17 00:00:00 2001 From: Tony Luck Date: Wed, 29 Jun 2005 16:01:40 -0700 Subject: [IA64] Update zx1_defconfig Signed-off-by: Tony Luck --- arch/ia64/configs/zx1_defconfig | 166 +++++++++++++++++++++++++++++----------- 1 file changed, 122 insertions(+), 44 deletions(-) diff --git a/arch/ia64/configs/zx1_defconfig b/arch/ia64/configs/zx1_defconfig index 21d6f9b..b7755e4 100644 --- a/arch/ia64/configs/zx1_defconfig +++ b/arch/ia64/configs/zx1_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.10 -# Wed Dec 29 09:05:48 2004 +# Linux kernel version: 2.6.13-rc1-20050629 +# Wed Jun 29 15:31:11 2005 # # @@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y CONFIG_BROKEN=y CONFIG_BROKEN_ON_SMP=y CONFIG_LOCK_KERNEL=y +CONFIG_INIT_ENV_ARG_LIMIT=32 # # General setup @@ -24,23 +25,26 @@ CONFIG_BSD_PROCESS_ACCT=y # CONFIG_BSD_PROCESS_ACCT_V3 is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set -CONFIG_LOG_BUF_SHIFT=17 CONFIG_HOTPLUG=y CONFIG_KOBJECT_UEVENT=y # CONFIG_IKCONFIG is not set +# CONFIG_CPUSETS is not set # CONFIG_EMBEDDED is not set CONFIG_KALLSYMS=y # CONFIG_KALLSYMS_ALL is not set # CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y -# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SHMEM=y CONFIG_CC_ALIGN_FUNCTIONS=0 CONFIG_CC_ALIGN_LABELS=0 CONFIG_CC_ALIGN_LOOPS=0 CONFIG_CC_ALIGN_JUMPS=0 # CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 # # Loadable module support @@ -59,12 +63,15 @@ CONFIG_IA64=y CONFIG_64BIT=y CONFIG_MMU=y CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_TIME_INTERPOLATION=y CONFIG_EFI=y CONFIG_GENERIC_IOMAP=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y # CONFIG_IA64_GENERIC is not set # CONFIG_IA64_DIG is not set CONFIG_IA64_HP_ZX1=y +# CONFIG_IA64_HP_ZX1_SWIOTLB is not set # CONFIG_IA64_SGI_SN2 is not set # CONFIG_IA64_HP_SIM is not set # CONFIG_ITANIUM is not set @@ -73,22 +80,36 @@ CONFIG_MCKINLEY=y # CONFIG_IA64_PAGE_SIZE_8KB is not set CONFIG_IA64_PAGE_SIZE_16KB=y # CONFIG_IA64_PAGE_SIZE_64KB is not set +# CONFIG_HZ_100 is not set +CONFIG_HZ_250=y +# CONFIG_HZ_1000 is not set +CONFIG_HZ=250 CONFIG_IA64_L1_CACHE_SHIFT=7 # CONFIG_NUMA is not set CONFIG_VIRTUAL_MEM_MAP=y +CONFIG_HOLES_IN_ZONE=y # CONFIG_IA64_CYCLONE is not set CONFIG_IOSAPIC=y +# CONFIG_IA64_SGI_SN_XP is not set CONFIG_FORCE_MAX_ZONEORDER=18 CONFIG_SMP=y CONFIG_NR_CPUS=16 # CONFIG_HOTPLUG_CPU is not set +# CONFIG_SCHED_SMT is not set # CONFIG_PREEMPT is not set +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y CONFIG_HAVE_DEC_LOCK=y CONFIG_IA32_SUPPORT=y CONFIG_COMPAT=y CONFIG_IA64_MCA_RECOVERY=y CONFIG_PERFMON=y CONFIG_IA64_PALINFO=y +CONFIG_ACPI_DEALLOCATE_IRQ=y # # Firmware Drivers @@ -120,6 +141,7 @@ CONFIG_ACPI_BUS=y CONFIG_ACPI_POWER=y CONFIG_ACPI_PCI=y CONFIG_ACPI_SYSTEM=y +# CONFIG_ACPI_CONTAINER is not set # # Bus options (PCI, PCMCIA) @@ -129,6 +151,7 @@ CONFIG_PCI_DOMAINS=y # CONFIG_PCI_MSI is not set CONFIG_PCI_LEGACY_PROC=y CONFIG_PCI_NAMES=y +# CONFIG_PCI_DEBUG is not set # # PCI Hotplug Support @@ -138,7 +161,6 @@ CONFIG_HOTPLUG_PCI=y CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_HOTPLUG_PCI_ACPI_IBM is not set # CONFIG_HOTPLUG_PCI_CPCI is not set -# CONFIG_HOTPLUG_PCI_PCIE is not set # CONFIG_HOTPLUG_PCI_SHPC is not set # @@ -147,10 +169,6 @@ CONFIG_HOTPLUG_PCI_ACPI=y # CONFIG_PCCARD is not set # -# PC-card bridges -# - -# # Device Drivers # @@ -184,6 +202,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set # CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_CRYPTOLOOP is not set # CONFIG_BLK_DEV_NBD is not set @@ -203,6 +222,7 @@ CONFIG_IOSCHED_NOOP=y CONFIG_IOSCHED_AS=y CONFIG_IOSCHED_DEADLINE=y CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set # # ATA/ATAPI/MFM/RLL support @@ -246,6 +266,7 @@ CONFIG_BLK_DEV_CMD64X=y # CONFIG_BLK_DEV_HPT366 is not set # CONFIG_BLK_DEV_SC1200 is not set # CONFIG_BLK_DEV_PIIX is not set +# CONFIG_BLK_DEV_IT821X is not set # CONFIG_BLK_DEV_NS87415 is not set # CONFIG_BLK_DEV_PDC202XX_OLD is not set # CONFIG_BLK_DEV_PDC202XX_NEW is not set @@ -275,6 +296,7 @@ CONFIG_CHR_DEV_OSST=y CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set # # Some SCSI devices (e.g. CD jukebox) support multiple LUNs @@ -288,6 +310,7 @@ CONFIG_SCSI_LOGGING=y # CONFIG_SCSI_SPI_ATTRS=y # CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set # # SCSI low-level drivers @@ -303,13 +326,10 @@ CONFIG_SCSI_SPI_ATTRS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_SCSI_SATA is not set -# CONFIG_SCSI_BUSLOGIC is not set # CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_EATA is not set # CONFIG_SCSI_EATA_PIO is not set # CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set # CONFIG_SCSI_IPS is not set # CONFIG_SCSI_INITIO is not set # CONFIG_SCSI_INIA100 is not set @@ -319,8 +339,6 @@ CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 # CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_QLOGIC_ISP is not set # CONFIG_SCSI_QLOGIC_FC is not set CONFIG_SCSI_QLOGIC_1280=y @@ -331,7 +349,7 @@ CONFIG_SCSI_QLA2XXX=y # CONFIG_SCSI_QLA2300 is not set # CONFIG_SCSI_QLA2322 is not set # CONFIG_SCSI_QLA6312 is not set -# CONFIG_SCSI_QLA6322 is not set +# CONFIG_SCSI_LPFC is not set # CONFIG_SCSI_DC395x is not set # CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_DEBUG is not set @@ -344,9 +362,9 @@ CONFIG_SCSI_QLA2XXX=y # # Fusion MPT device support # -CONFIG_FUSION=y -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_CTL is not set +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set # # IEEE 1394 (FireWire) support @@ -368,12 +386,12 @@ CONFIG_NET=y # CONFIG_PACKET=y # CONFIG_PACKET_MMAP is not set -# CONFIG_NETLINK_DEV is not set CONFIG_UNIX=y # CONFIG_NET_KEY is not set CONFIG_INET=y CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y # CONFIG_IP_PNP is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set @@ -386,6 +404,8 @@ CONFIG_IP_MULTICAST=y # CONFIG_INET_TUNNEL is not set # CONFIG_IP_TCPDIAG is not set # CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y # # IP: Virtual Server Configuration @@ -405,8 +425,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_ARPTABLES=y # CONFIG_IP_NF_ARPFILTER is not set # CONFIG_IP_NF_ARP_MANGLE is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set # # SCTP Configuration (EXPERIMENTAL) @@ -483,7 +501,6 @@ CONFIG_NET_PCI=y # CONFIG_DGRS is not set # CONFIG_EEPRO100 is not set CONFIG_E100=y -# CONFIG_E100_NAPI is not set # CONFIG_FEALNX is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set @@ -505,9 +522,11 @@ CONFIG_E1000=y # CONFIG_HAMACHI is not set # CONFIG_YELLOWFIN is not set # CONFIG_R8169 is not set +# CONFIG_SKGE is not set # CONFIG_SK98LIN is not set # CONFIG_VIA_VELOCITY is not set CONFIG_TIGON3=y +# CONFIG_BNX2 is not set # # Ethernet (10000 Mbit) @@ -565,18 +584,6 @@ CONFIG_INPUT_EVDEV=y # CONFIG_INPUT_EVBUG is not set # -# Input I/O drivers -# -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y -CONFIG_SERIO=y -# CONFIG_SERIO_I8042 is not set -# CONFIG_SERIO_SERPORT is not set -# CONFIG_SERIO_CT82C710 is not set -# CONFIG_SERIO_PCIPS2 is not set -# CONFIG_SERIO_RAW is not set - -# # Input Device Drivers # # CONFIG_INPUT_KEYBOARD is not set @@ -586,6 +593,16 @@ CONFIG_SERIO=y # CONFIG_INPUT_MISC is not set # +# Hardware I/O ports +# +CONFIG_SERIO=y +# CONFIG_SERIO_I8042 is not set +# CONFIG_SERIO_SERPORT is not set +# CONFIG_SERIO_PCIPS2 is not set +# CONFIG_SERIO_RAW is not set +# CONFIG_GAMEPORT is not set + +# # Character devices # CONFIG_VT=y @@ -603,7 +620,6 @@ CONFIG_SERIAL_8250_NR_UARTS=8 CONFIG_SERIAL_8250_EXTENDED=y CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_8250_DETECT_IRQ is not set -# CONFIG_SERIAL_8250_MULTIPORT is not set # CONFIG_SERIAL_8250_RSA is not set # @@ -611,6 +627,7 @@ CONFIG_SERIAL_8250_SHARE_IRQ=y # CONFIG_SERIAL_CORE=y CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set CONFIG_UNIX98_PTYS=y CONFIG_LEGACY_PTYS=y CONFIG_LEGACY_PTY_COUNT=256 @@ -644,6 +661,12 @@ CONFIG_DRM_RADEON=y # CONFIG_DRM_SIS is not set # CONFIG_RAW_DRIVER is not set # CONFIG_HPET is not set +# CONFIG_HANGCHECK_TIMER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set # # I2C support @@ -668,6 +691,7 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_I2C_AMD8111 is not set # CONFIG_I2C_I801 is not set # CONFIG_I2C_I810 is not set +# CONFIG_I2C_PIIX4 is not set # CONFIG_I2C_ISA is not set # CONFIG_I2C_NFORCE2 is not set # CONFIG_I2C_PARPORT_LIGHT is not set @@ -691,10 +715,14 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_ADM1025 is not set # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ASB100 is not set +# CONFIG_SENSORS_ATXP1 is not set # CONFIG_SENSORS_DS1621 is not set # CONFIG_SENSORS_FSCHER is not set +# CONFIG_SENSORS_FSCPOS is not set # CONFIG_SENSORS_GL518SM is not set +# CONFIG_SENSORS_GL520SM is not set # CONFIG_SENSORS_IT87 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM75 is not set @@ -705,21 +733,29 @@ CONFIG_I2C_ALGOPCF=y # CONFIG_SENSORS_LM85 is not set # CONFIG_SENSORS_LM87 is not set # CONFIG_SENSORS_LM90 is not set +# CONFIG_SENSORS_LM92 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_PC87360 is not set +# CONFIG_SENSORS_SMSC47B397 is not set +# CONFIG_SENSORS_SIS5595 is not set # CONFIG_SENSORS_SMSC47M1 is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_W83781D is not set # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83627HF is not set +# CONFIG_SENSORS_W83627EHF is not set # # Other I2C Chip support # +# CONFIG_SENSORS_DS1337 is not set +# CONFIG_SENSORS_DS1374 is not set # CONFIG_SENSORS_EEPROM is not set # CONFIG_SENSORS_PCF8574 is not set +# CONFIG_SENSORS_PCA9539 is not set # CONFIG_SENSORS_PCF8591 is not set # CONFIG_SENSORS_RTC8564 is not set +# CONFIG_SENSORS_MAX6875 is not set # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -746,6 +782,7 @@ CONFIG_VIDEO_DEV=y # # Video Adapters # +# CONFIG_TUNER_MULTI_I2C is not set # CONFIG_VIDEO_BT848 is not set # CONFIG_VIDEO_CPIA is not set # CONFIG_VIDEO_SAA5246A is not set @@ -778,6 +815,11 @@ CONFIG_VIDEO_DEV=y # Graphics support # CONFIG_FB=y +CONFIG_FB_CFB_FILLRECT=y +CONFIG_FB_CFB_COPYAREA=y +CONFIG_FB_CFB_IMAGEBLIT=y +CONFIG_FB_SOFT_CURSOR=y +# CONFIG_FB_MACMODES is not set CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_CIRRUS is not set @@ -785,6 +827,7 @@ CONFIG_FB_MODE_HELPERS=y # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_ASILIANT is not set # CONFIG_FB_IMSTT is not set +# CONFIG_FB_NVIDIA is not set # CONFIG_FB_RIVA is not set # CONFIG_FB_MATROX is not set # CONFIG_FB_RADEON_OLD is not set @@ -801,6 +844,7 @@ CONFIG_FB_RADEON_DEBUG=y # CONFIG_FB_VOODOO1 is not set # CONFIG_FB_TRIDENT is not set # CONFIG_FB_PM3 is not set +# CONFIG_FB_S1D13XXX is not set # CONFIG_FB_VIRTUAL is not set # @@ -820,6 +864,7 @@ CONFIG_LOGO=y # CONFIG_LOGO_LINUX_MONO is not set # CONFIG_LOGO_LINUX_VGA16 is not set CONFIG_LOGO_LINUX_CLUT224=y +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set # # Sound @@ -869,6 +914,8 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_CS46XX is not set # CONFIG_SND_CS4281 is not set # CONFIG_SND_EMU10K1 is not set +# CONFIG_SND_EMU10K1X is not set +# CONFIG_SND_CA0106 is not set # CONFIG_SND_KORG1212 is not set # CONFIG_SND_MIXART is not set # CONFIG_SND_NM256 is not set @@ -876,6 +923,7 @@ CONFIG_SND_AC97_CODEC=y # CONFIG_SND_RME96 is not set # CONFIG_SND_RME9652 is not set # CONFIG_SND_HDSP is not set +# CONFIG_SND_HDSPM is not set # CONFIG_SND_TRIDENT is not set # CONFIG_SND_YMFPCI is not set # CONFIG_SND_ALS4000 is not set @@ -893,13 +941,14 @@ CONFIG_SND_FM801_TEA575X=y # CONFIG_SND_INTEL8X0M is not set # CONFIG_SND_SONICVIBES is not set # CONFIG_SND_VIA82XX is not set +# CONFIG_SND_VIA82XX_MODEM is not set # CONFIG_SND_VX222 is not set +# CONFIG_SND_HDA_INTEL is not set # # USB devices # # CONFIG_SND_USB_AUDIO is not set -# CONFIG_SND_USB_USX2Y is not set # # Open Sound System @@ -909,6 +958,8 @@ CONFIG_SND_FM801_TEA575X=y # # USB support # +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -920,8 +971,6 @@ CONFIG_USB_BANDWIDTH=y # CONFIG_USB_DYNAMIC_MINORS is not set # CONFIG_USB_SUSPEND is not set # CONFIG_USB_OTG is not set -CONFIG_USB_ARCH_HAS_HCD=y -CONFIG_USB_ARCH_HAS_OHCI=y # # USB Host Controller Drivers @@ -929,7 +978,10 @@ CONFIG_USB_ARCH_HAS_OHCI=y CONFIG_USB_EHCI_HCD=y # CONFIG_USB_EHCI_SPLIT_ISO is not set # CONFIG_USB_EHCI_ROOT_HUB_TT is not set +# CONFIG_USB_ISP116X_HCD is not set CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_BIG_ENDIAN is not set +CONFIG_USB_OHCI_LITTLE_ENDIAN=y CONFIG_USB_UHCI_HCD=y # CONFIG_USB_SL811_HCD is not set @@ -947,12 +999,11 @@ CONFIG_USB_UHCI_HCD=y # CONFIG_USB_STORAGE=y # CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_RW_DETECT is not set # CONFIG_USB_STORAGE_DATAFAB is not set # CONFIG_USB_STORAGE_FREECOM is not set # CONFIG_USB_STORAGE_ISD200 is not set # CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set +# CONFIG_USB_STORAGE_USBAT is not set # CONFIG_USB_STORAGE_SDDR09 is not set # CONFIG_USB_STORAGE_SDDR55 is not set # CONFIG_USB_STORAGE_JUMPSHOT is not set @@ -966,9 +1017,11 @@ CONFIG_USB_HIDINPUT=y CONFIG_USB_HIDDEV=y # CONFIG_USB_AIPTEK is not set # CONFIG_USB_WACOM is not set +# CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set # CONFIG_USB_MTOUCH is not set +# CONFIG_USB_ITMTOUCH is not set # CONFIG_USB_EGALAX is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -978,7 +1031,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set # # USB Multimedia devices @@ -992,6 +1044,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_SE401 is not set # CONFIG_USB_SN9C102 is not set # CONFIG_USB_STV680 is not set +# CONFIG_USB_PWC is not set # # USB Network Adapters @@ -1001,6 +1054,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_PEGASUS is not set # CONFIG_USB_RTL8150 is not set # CONFIG_USB_USBNET is not set +CONFIG_USB_MON=y # # USB port drivers @@ -1016,7 +1070,6 @@ CONFIG_USB_HIDDEV=y # # CONFIG_USB_EMI62 is not set # CONFIG_USB_EMI26 is not set -# CONFIG_USB_TIGL is not set # CONFIG_USB_AUERSWALD is not set # CONFIG_USB_RIO500 is not set # CONFIG_USB_LEGOTOWER is not set @@ -1025,9 +1078,11 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set +# CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_SISUSBVGA is not set # -# USB ATM/DSL drivers +# USB DSL modem support # # @@ -1041,12 +1096,22 @@ CONFIG_USB_HIDDEV=y # CONFIG_MMC is not set # +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# SN Devices +# + +# # File systems # CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y # CONFIG_EXT2_FS_POSIX_ACL is not set # CONFIG_EXT2_FS_SECURITY is not set +# CONFIG_EXT2_FS_XIP is not set CONFIG_EXT3_FS=y CONFIG_EXT3_FS_XATTR=y # CONFIG_EXT3_FS_POSIX_ACL is not set @@ -1056,6 +1121,10 @@ CONFIG_JBD=y CONFIG_FS_MBCACHE=y # CONFIG_REISERFS_FS is not set # CONFIG_JFS_FS is not set + +# +# XFS support +# # CONFIG_XFS_FS is not set # CONFIG_MINIX_FS is not set # CONFIG_ROMFS_FS is not set @@ -1089,7 +1158,6 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set # CONFIG_DEVPTS_FS_XATTR is not set CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y @@ -1120,15 +1188,18 @@ CONFIG_RAMFS=y # CONFIG_NFS_FS=y CONFIG_NFS_V3=y +# CONFIG_NFS_V3_ACL is not set CONFIG_NFS_V4=y # CONFIG_NFS_DIRECTIO is not set CONFIG_NFSD=y CONFIG_NFSD_V3=y +# CONFIG_NFSD_V3_ACL is not set # CONFIG_NFSD_V4 is not set # CONFIG_NFSD_TCP is not set CONFIG_LOCKD=y CONFIG_LOCKD_V4=y CONFIG_EXPORTFS=y +CONFIG_NFS_COMMON=y CONFIG_SUNRPC=y CONFIG_SUNRPC_GSS=y CONFIG_RPCSEC_GSS_KRB5=y @@ -1209,6 +1280,8 @@ CONFIG_NLS_UTF8=y # CONFIG_CRC_CCITT is not set CONFIG_CRC32=y # CONFIG_LIBCRC32C is not set +CONFIG_GENERIC_HARDIRQS=y +CONFIG_GENERIC_IRQ_PROBE=y # # Profiling support @@ -1218,14 +1291,18 @@ CONFIG_CRC32=y # # Kernel hacking # +# CONFIG_PRINTK_TIME is not set CONFIG_DEBUG_KERNEL=y CONFIG_MAGIC_SYSRQ=y +CONFIG_LOG_BUF_SHIFT=17 # CONFIG_SCHEDSTATS is not set # CONFIG_DEBUG_SLAB is not set # CONFIG_DEBUG_SPINLOCK is not set # CONFIG_DEBUG_SPINLOCK_SLEEP is not set # CONFIG_DEBUG_KOBJECT is not set # CONFIG_DEBUG_INFO is not set +# CONFIG_DEBUG_FS is not set +CONFIG_KPROBES=y CONFIG_IA64_GRANULE_16MB=y # CONFIG_IA64_GRANULE_64MB is not set CONFIG_IA64_PRINT_HAZARDS=y @@ -1252,6 +1329,7 @@ CONFIG_CRYPTO_MD5=y # CONFIG_CRYPTO_SHA256 is not set # CONFIG_CRYPTO_SHA512 is not set # CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set CONFIG_CRYPTO_DES=y # CONFIG_CRYPTO_BLOWFISH is not set # CONFIG_CRYPTO_TWOFISH is not set -- cgit v1.1 From 869eb76e7b60ebd8f87a358b72e97fa0aef1d1f5 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 29 Jun 2005 18:52:28 -0400 Subject: [PATCH] reiserfs: Check if attrs are enabled for attr ioctls ReiserFS currently will allow the user to set/get attrs for files regardless if they are enabled. The patch checks to see if they are enabled, and returns -NOTTY if they are not. ext[23] doesn't need this check because attrs are always enabled. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/ioctl.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 94dc424..76caedf 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -36,10 +36,16 @@ int reiserfs_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, /* following two cases are taken from fs/ext2/ioctl.c by Remy Card (card@masi.ibp.fr) */ case REISERFS_IOC_GETFLAGS: + if (!reiserfs_attrs (inode->i_sb)) + return -ENOTTY; + flags = REISERFS_I(inode) -> i_attrs; i_attrs_to_sd_attrs( inode, ( __u16 * ) &flags ); return put_user(flags, (int __user *) arg); case REISERFS_IOC_SETFLAGS: { + if (!reiserfs_attrs (inode->i_sb)) + return -ENOTTY; + if (IS_RDONLY(inode)) return -EROFS; -- cgit v1.1 From 2949ccf9379678df66ecf2ca70ed4656159eacdd Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 29 Jun 2005 18:53:06 -0400 Subject: [PATCH] reiserfs: enable attrs by default if saf The following patch enables attrs by default if the reiserfs_attrs_cleared bit is set in the superblock. This allows chattr-type attrs to be used without any further action by the user. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- fs/reiserfs/super.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 660aefc..d50a5cd 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1066,6 +1066,8 @@ static void handle_attrs( struct super_block *s ) reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block" ); REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); } + } else if (le32_to_cpu( rs -> s_flags ) & reiserfs_attrs_cleared) { + REISERFS_SB(s)->s_mount_opt |= REISERFS_ATTRS; } } -- cgit v1.1 From bea248fb30c3122ece8c34798527fac431c1d7b0 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:09 +1000 Subject: [PATCH] ppc64: Remove lpqueue pointer from the paca on iSeries The iSeries code keeps a pointer to the ItLpQueue in its paca struct. But all these pointers end up pointing to the one place, ie. xItLpQueue. So remove the pointer from the paca struct and just refer to xItLpQueue directly where needed. The only complication is that the spread_lpevents logic was implemented by having a NULL lpqueue pointer in the paca on CPUs that weren't supposed to process events. Instead we just compare the spread_lpevents value to the processor id to get the same behaviour. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 16 +++++++++------- arch/ppc64/kernel/iSeries_setup.c | 6 ++---- arch/ppc64/kernel/idle.c | 4 ++-- arch/ppc64/kernel/irq.c | 6 ++---- arch/ppc64/kernel/mf.c | 5 ++--- arch/ppc64/kernel/pacaData.c | 1 - arch/ppc64/kernel/time.c | 7 ++----- include/asm-ppc64/paca.h | 2 -- 8 files changed, 19 insertions(+), 28 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index cdea00d..e90dca8 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -69,15 +69,17 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) return nextLpEvent; } +unsigned long spread_lpevents = 1; + int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) { - int retval = 0; - struct HvLpEvent * nextLpEvent; - if ( lpQueue ) { - nextLpEvent = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - retval = nextLpEvent->xFlags.xValid | lpQueue->xPlicOverflowIntPending; - } - return retval; + struct HvLpEvent *next_event; + + if (smp_processor_id() >= spread_lpevents) + return 0; + + next_event = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + return next_event->xFlags.xValid | lpQueue->xPlicOverflowIntPending; } void ItLpQueue_clearValid( struct HvLpEvent * event ) diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 86966ce..2049b6d 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -855,17 +855,15 @@ late_initcall(iSeries_src_init); static int set_spread_lpevents(char *str) { - unsigned long i; unsigned long val = simple_strtoul(str, NULL, 0); + extern unsigned long spread_lpevents; /* * The parameter is the number of processors to share in processing * lp events. */ if (( val > 0) && (val <= NR_CPUS)) { - for (i = 1; i < val; ++i) - paca[i].lpqueue_ptr = paca[0].lpqueue_ptr; - + spread_lpevents = val; printk("lpevent processing spread over %ld processors\n", val); } else { printk("invalid spread_lpevents %ld\n", val); diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index bdf13b4..63977a7 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) + if (ItLpQueue_isLpIntPending(&xItLpQueue)) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending(lpaca->lpqueue_ptr)) + if (ItLpQueue_isLpIntPending(&xItLpQueue)) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 3defc8c..b1e6acb 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -269,7 +269,6 @@ out: void do_IRQ(struct pt_regs *regs) { struct paca_struct *lpaca; - struct ItLpQueue *lpq; irq_enter(); @@ -295,9 +294,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); + if (ItLpQueue_isLpIntPending(&xItLpQueue)) + lpevent_count += ItLpQueue_process(&xItLpQueue, regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d98bebf..d6a297a 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -802,9 +802,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { extern unsigned long lpevent_count; - struct ItLpQueue *lpq = get_paca()->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, NULL); + if (ItLpQueue_isLpIntPending(&xItLpQueue)) + lpevent_count += ItLpQueue_process(&xItLpQueue, NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index a3e0975c..ebfb517 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -45,7 +45,6 @@ extern unsigned long __toc_start; #ifdef CONFIG_PPC_ISERIES #define EXTRA_INITS(number, lpq) \ .lppaca_ptr = &paca[number].lppaca, \ - .lpqueue_ptr = (lpq), /* &xItLpQueue, */ \ .reg_save_ptr = &paca[number].reg_save, \ .reg_save = { \ .xDesc = 0xd397d9e2, /* "LpRS" */ \ diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index 2a532db..cdc43af 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -367,11 +367,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - { - struct ItLpQueue *lpq = lpaca->lpqueue_ptr; - if (lpq && ItLpQueue_isLpIntPending(lpq)) - lpevent_count += ItLpQueue_process(lpq, regs); - } + if (ItLpQueue_isLpIntPending(&xItLpQueue)) + lpevent_count += ItLpQueue_process(&xItLpQueue, regs); #endif /* collect purr register values often, for accurate calculations */ diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h index ae76cae..0146f516 100644 --- a/include/asm-ppc64/paca.h +++ b/include/asm-ppc64/paca.h @@ -20,7 +20,6 @@ #include #include #include -#include #include register struct paca_struct *local_paca asm("r13"); @@ -62,7 +61,6 @@ struct paca_struct { u16 paca_index; /* Logical processor number */ u32 default_decr; /* Default decrementer value */ - struct ItLpQueue *lpqueue_ptr; /* LpQueue handled by this CPU */ u64 kernel_toc; /* Kernel TOC address */ u64 stab_real; /* Absolute address of segment table */ u64 stab_addr; /* Virtual address of segment table */ -- cgit v1.1 From fc07695386067a4abbd5ac8c7974059eae0b0a79 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:21 +1000 Subject: [PATCH] ppc64: Spread lpevents by default on iSeries With the previous patch in place, spreading lpevents by default becomes a one liner. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index e90dca8..d377934 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -69,7 +69,7 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) return nextLpEvent; } -unsigned long spread_lpevents = 1; +unsigned long spread_lpevents = NR_CPUS; int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) { -- cgit v1.1 From 0c885c175c06bdfe13e88d974d56a5e93ad2f544 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:33 +1000 Subject: [PATCH] ppc64: Move set_spread_lpevents() into ItLpQueue.c The only code outside ItLpQueue.c that refers to spread_lpevents is in set_apread_lpevents(), so move it inside ItLpQueue.c and make spread_lpevents static. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 22 +++++++++++++++++++++- arch/ppc64/kernel/iSeries_setup.c | 20 -------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index d377934..61be23e 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -69,7 +69,7 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) return nextLpEvent; } -unsigned long spread_lpevents = NR_CPUS; +static unsigned long spread_lpevents = NR_CPUS; int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) { @@ -166,3 +166,23 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) return numIntsProcessed; } + +static int set_spread_lpevents(char *str) +{ + unsigned long val = simple_strtoul(str, NULL, 0); + + /* + * The parameter is the number of processors to share in processing + * lp events. + */ + if (( val > 0) && (val <= NR_CPUS)) { + spread_lpevents = val; + printk("lpevent processing spread over %ld processors\n", val); + } else { + printk("invalid spread_lpevents %ld\n", val); + } + + return 1; +} +__setup("spread_lpevents=", set_spread_lpevents); + diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 2049b6d..78f2835 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -853,26 +853,6 @@ static int __init iSeries_src_init(void) late_initcall(iSeries_src_init); -static int set_spread_lpevents(char *str) -{ - unsigned long val = simple_strtoul(str, NULL, 0); - extern unsigned long spread_lpevents; - - /* - * The parameter is the number of processors to share in processing - * lp events. - */ - if (( val > 0) && (val <= NR_CPUS)) { - spread_lpevents = val; - printk("lpevent processing spread over %ld processors\n", val); - } else { - printk("invalid spread_lpevents %ld\n", val); - } - - return 1; -} -__setup("spread_lpevents=", set_spread_lpevents); - #ifndef CONFIG_PCI void __init iSeries_init_IRQ(void) { } #endif -- cgit v1.1 From ee48444b85f498d99592835f61125385d8e9c975 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:48 +1000 Subject: [PATCH] ppc64: Reorganise the paca initialisation macros This patch updates the macros that initialise the paca to remove the lpq parameter. It also rearranges them a bit with the hope of making them a bit clearer. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/pacaData.c | 211 +++++++++++++------------------------------ 1 file changed, 65 insertions(+), 146 deletions(-) diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c index ebfb517..6316188 100644 --- a/arch/ppc64/kernel/pacaData.c +++ b/arch/ppc64/kernel/pacaData.c @@ -42,20 +42,7 @@ extern unsigned long __toc_start; * processors. The processor VPD array needs one entry per physical * processor (not thread). */ -#ifdef CONFIG_PPC_ISERIES -#define EXTRA_INITS(number, lpq) \ - .lppaca_ptr = &paca[number].lppaca, \ - .reg_save_ptr = &paca[number].reg_save, \ - .reg_save = { \ - .xDesc = 0xd397d9e2, /* "LpRS" */ \ - .xSize = sizeof(struct ItLpRegSave) \ - }, -#else -#define EXTRA_INITS(number, lpq) -#endif - -#define PACAINITDATA(number,start,lpq,asrr,asrv) \ -{ \ +#define PACA_INIT_COMMON(number, start, asrr, asrv) \ .lock_token = 0x8000, \ .paca_index = (number), /* Paca Index */ \ .default_decr = 0x00ff0000, /* Initial Decr */ \ @@ -73,147 +60,79 @@ extern unsigned long __toc_start; .end_of_quantum = 0xfffffffffffffffful, \ .slb_count = 64, \ }, \ - EXTRA_INITS((number), (lpq)) \ -} -struct paca_struct paca[] = { #ifdef CONFIG_PPC_ISERIES - PACAINITDATA( 0, 1, &xItLpQueue, 0, STAB0_VIRT_ADDR), +#define PACA_INIT_ISERIES(number) \ + .lppaca_ptr = &paca[number].lppaca, \ + .reg_save_ptr = &paca[number].reg_save, \ + .reg_save = { \ + .xDesc = 0xd397d9e2, /* "LpRS" */ \ + .xSize = sizeof(struct ItLpRegSave) \ + } + +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ + PACA_INIT_ISERIES(number) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, 0, STAB0_VIRT_ADDR) \ + PACA_INIT_ISERIES(number) \ +} + #else - PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR), +#define PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 0, 0, 0) \ +} + +#define BOOTCPU_PACA_INIT(number) \ +{ \ + PACA_INIT_COMMON(number, 1, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR) \ +} #endif + +struct paca_struct paca[] = { + BOOTCPU_PACA_INIT(0), #if NR_CPUS > 1 - PACAINITDATA( 1, 0, NULL, 0, 0), - PACAINITDATA( 2, 0, NULL, 0, 0), - PACAINITDATA( 3, 0, NULL, 0, 0), + PACA_INIT( 1), PACA_INIT( 2), PACA_INIT( 3), #if NR_CPUS > 4 - PACAINITDATA( 4, 0, NULL, 0, 0), - PACAINITDATA( 5, 0, NULL, 0, 0), - PACAINITDATA( 6, 0, NULL, 0, 0), - PACAINITDATA( 7, 0, NULL, 0, 0), + PACA_INIT( 4), PACA_INIT( 5), PACA_INIT( 6), PACA_INIT( 7), #if NR_CPUS > 8 - PACAINITDATA( 8, 0, NULL, 0, 0), - PACAINITDATA( 9, 0, NULL, 0, 0), - PACAINITDATA(10, 0, NULL, 0, 0), - PACAINITDATA(11, 0, NULL, 0, 0), - PACAINITDATA(12, 0, NULL, 0, 0), - PACAINITDATA(13, 0, NULL, 0, 0), - PACAINITDATA(14, 0, NULL, 0, 0), - PACAINITDATA(15, 0, NULL, 0, 0), - PACAINITDATA(16, 0, NULL, 0, 0), - PACAINITDATA(17, 0, NULL, 0, 0), - PACAINITDATA(18, 0, NULL, 0, 0), - PACAINITDATA(19, 0, NULL, 0, 0), - PACAINITDATA(20, 0, NULL, 0, 0), - PACAINITDATA(21, 0, NULL, 0, 0), - PACAINITDATA(22, 0, NULL, 0, 0), - PACAINITDATA(23, 0, NULL, 0, 0), - PACAINITDATA(24, 0, NULL, 0, 0), - PACAINITDATA(25, 0, NULL, 0, 0), - PACAINITDATA(26, 0, NULL, 0, 0), - PACAINITDATA(27, 0, NULL, 0, 0), - PACAINITDATA(28, 0, NULL, 0, 0), - PACAINITDATA(29, 0, NULL, 0, 0), - PACAINITDATA(30, 0, NULL, 0, 0), - PACAINITDATA(31, 0, NULL, 0, 0), + PACA_INIT( 8), PACA_INIT( 9), PACA_INIT( 10), PACA_INIT( 11), + PACA_INIT( 12), PACA_INIT( 13), PACA_INIT( 14), PACA_INIT( 15), + PACA_INIT( 16), PACA_INIT( 17), PACA_INIT( 18), PACA_INIT( 19), + PACA_INIT( 20), PACA_INIT( 21), PACA_INIT( 22), PACA_INIT( 23), + PACA_INIT( 24), PACA_INIT( 25), PACA_INIT( 26), PACA_INIT( 27), + PACA_INIT( 28), PACA_INIT( 29), PACA_INIT( 30), PACA_INIT( 31), #if NR_CPUS > 32 - PACAINITDATA(32, 0, NULL, 0, 0), - PACAINITDATA(33, 0, NULL, 0, 0), - PACAINITDATA(34, 0, NULL, 0, 0), - PACAINITDATA(35, 0, NULL, 0, 0), - PACAINITDATA(36, 0, NULL, 0, 0), - PACAINITDATA(37, 0, NULL, 0, 0), - PACAINITDATA(38, 0, NULL, 0, 0), - PACAINITDATA(39, 0, NULL, 0, 0), - PACAINITDATA(40, 0, NULL, 0, 0), - PACAINITDATA(41, 0, NULL, 0, 0), - PACAINITDATA(42, 0, NULL, 0, 0), - PACAINITDATA(43, 0, NULL, 0, 0), - PACAINITDATA(44, 0, NULL, 0, 0), - PACAINITDATA(45, 0, NULL, 0, 0), - PACAINITDATA(46, 0, NULL, 0, 0), - PACAINITDATA(47, 0, NULL, 0, 0), - PACAINITDATA(48, 0, NULL, 0, 0), - PACAINITDATA(49, 0, NULL, 0, 0), - PACAINITDATA(50, 0, NULL, 0, 0), - PACAINITDATA(51, 0, NULL, 0, 0), - PACAINITDATA(52, 0, NULL, 0, 0), - PACAINITDATA(53, 0, NULL, 0, 0), - PACAINITDATA(54, 0, NULL, 0, 0), - PACAINITDATA(55, 0, NULL, 0, 0), - PACAINITDATA(56, 0, NULL, 0, 0), - PACAINITDATA(57, 0, NULL, 0, 0), - PACAINITDATA(58, 0, NULL, 0, 0), - PACAINITDATA(59, 0, NULL, 0, 0), - PACAINITDATA(60, 0, NULL, 0, 0), - PACAINITDATA(61, 0, NULL, 0, 0), - PACAINITDATA(62, 0, NULL, 0, 0), - PACAINITDATA(63, 0, NULL, 0, 0), + PACA_INIT( 32), PACA_INIT( 33), PACA_INIT( 34), PACA_INIT( 35), + PACA_INIT( 36), PACA_INIT( 37), PACA_INIT( 38), PACA_INIT( 39), + PACA_INIT( 40), PACA_INIT( 41), PACA_INIT( 42), PACA_INIT( 43), + PACA_INIT( 44), PACA_INIT( 45), PACA_INIT( 46), PACA_INIT( 47), + PACA_INIT( 48), PACA_INIT( 49), PACA_INIT( 50), PACA_INIT( 51), + PACA_INIT( 52), PACA_INIT( 53), PACA_INIT( 54), PACA_INIT( 55), + PACA_INIT( 56), PACA_INIT( 57), PACA_INIT( 58), PACA_INIT( 59), + PACA_INIT( 60), PACA_INIT( 61), PACA_INIT( 62), PACA_INIT( 63), #if NR_CPUS > 64 - PACAINITDATA(64, 0, NULL, 0, 0), - PACAINITDATA(65, 0, NULL, 0, 0), - PACAINITDATA(66, 0, NULL, 0, 0), - PACAINITDATA(67, 0, NULL, 0, 0), - PACAINITDATA(68, 0, NULL, 0, 0), - PACAINITDATA(69, 0, NULL, 0, 0), - PACAINITDATA(70, 0, NULL, 0, 0), - PACAINITDATA(71, 0, NULL, 0, 0), - PACAINITDATA(72, 0, NULL, 0, 0), - PACAINITDATA(73, 0, NULL, 0, 0), - PACAINITDATA(74, 0, NULL, 0, 0), - PACAINITDATA(75, 0, NULL, 0, 0), - PACAINITDATA(76, 0, NULL, 0, 0), - PACAINITDATA(77, 0, NULL, 0, 0), - PACAINITDATA(78, 0, NULL, 0, 0), - PACAINITDATA(79, 0, NULL, 0, 0), - PACAINITDATA(80, 0, NULL, 0, 0), - PACAINITDATA(81, 0, NULL, 0, 0), - PACAINITDATA(82, 0, NULL, 0, 0), - PACAINITDATA(83, 0, NULL, 0, 0), - PACAINITDATA(84, 0, NULL, 0, 0), - PACAINITDATA(85, 0, NULL, 0, 0), - PACAINITDATA(86, 0, NULL, 0, 0), - PACAINITDATA(87, 0, NULL, 0, 0), - PACAINITDATA(88, 0, NULL, 0, 0), - PACAINITDATA(89, 0, NULL, 0, 0), - PACAINITDATA(90, 0, NULL, 0, 0), - PACAINITDATA(91, 0, NULL, 0, 0), - PACAINITDATA(92, 0, NULL, 0, 0), - PACAINITDATA(93, 0, NULL, 0, 0), - PACAINITDATA(94, 0, NULL, 0, 0), - PACAINITDATA(95, 0, NULL, 0, 0), - PACAINITDATA(96, 0, NULL, 0, 0), - PACAINITDATA(97, 0, NULL, 0, 0), - PACAINITDATA(98, 0, NULL, 0, 0), - PACAINITDATA(99, 0, NULL, 0, 0), - PACAINITDATA(100, 0, NULL, 0, 0), - PACAINITDATA(101, 0, NULL, 0, 0), - PACAINITDATA(102, 0, NULL, 0, 0), - PACAINITDATA(103, 0, NULL, 0, 0), - PACAINITDATA(104, 0, NULL, 0, 0), - PACAINITDATA(105, 0, NULL, 0, 0), - PACAINITDATA(106, 0, NULL, 0, 0), - PACAINITDATA(107, 0, NULL, 0, 0), - PACAINITDATA(108, 0, NULL, 0, 0), - PACAINITDATA(109, 0, NULL, 0, 0), - PACAINITDATA(110, 0, NULL, 0, 0), - PACAINITDATA(111, 0, NULL, 0, 0), - PACAINITDATA(112, 0, NULL, 0, 0), - PACAINITDATA(113, 0, NULL, 0, 0), - PACAINITDATA(114, 0, NULL, 0, 0), - PACAINITDATA(115, 0, NULL, 0, 0), - PACAINITDATA(116, 0, NULL, 0, 0), - PACAINITDATA(117, 0, NULL, 0, 0), - PACAINITDATA(118, 0, NULL, 0, 0), - PACAINITDATA(119, 0, NULL, 0, 0), - PACAINITDATA(120, 0, NULL, 0, 0), - PACAINITDATA(121, 0, NULL, 0, 0), - PACAINITDATA(122, 0, NULL, 0, 0), - PACAINITDATA(123, 0, NULL, 0, 0), - PACAINITDATA(124, 0, NULL, 0, 0), - PACAINITDATA(125, 0, NULL, 0, 0), - PACAINITDATA(126, 0, NULL, 0, 0), - PACAINITDATA(127, 0, NULL, 0, 0), + PACA_INIT( 64), PACA_INIT( 65), PACA_INIT( 66), PACA_INIT( 67), + PACA_INIT( 68), PACA_INIT( 69), PACA_INIT( 70), PACA_INIT( 71), + PACA_INIT( 72), PACA_INIT( 73), PACA_INIT( 74), PACA_INIT( 75), + PACA_INIT( 76), PACA_INIT( 77), PACA_INIT( 78), PACA_INIT( 79), + PACA_INIT( 80), PACA_INIT( 81), PACA_INIT( 82), PACA_INIT( 83), + PACA_INIT( 84), PACA_INIT( 85), PACA_INIT( 86), PACA_INIT( 87), + PACA_INIT( 88), PACA_INIT( 89), PACA_INIT( 90), PACA_INIT( 91), + PACA_INIT( 92), PACA_INIT( 93), PACA_INIT( 94), PACA_INIT( 95), + PACA_INIT( 96), PACA_INIT( 97), PACA_INIT( 98), PACA_INIT( 99), + PACA_INIT(100), PACA_INIT(101), PACA_INIT(102), PACA_INIT(103), + PACA_INIT(104), PACA_INIT(105), PACA_INIT(106), PACA_INIT(107), + PACA_INIT(108), PACA_INIT(109), PACA_INIT(110), PACA_INIT(111), + PACA_INIT(112), PACA_INIT(113), PACA_INIT(114), PACA_INIT(115), + PACA_INIT(116), PACA_INIT(117), PACA_INIT(118), PACA_INIT(119), + PACA_INIT(120), PACA_INIT(121), PACA_INIT(122), PACA_INIT(123), + PACA_INIT(124), PACA_INIT(125), PACA_INIT(126), PACA_INIT(127), #endif #endif #endif -- cgit v1.1 From 1b19bc721416ae5bc813521d9e010a89f4816120 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:07:57 +1000 Subject: [PATCH] ppc64: Don't pass the pointers to xItLpQueue around Because there's only one ItLpQueue and we know where it is, ie. xItLpQueue, there's no point passing pointers to it it around all over the place. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 46 +++++++++++++++++------------------ arch/ppc64/kernel/idle.c | 4 +-- arch/ppc64/kernel/irq.c | 4 +-- arch/ppc64/kernel/mf.c | 4 +-- arch/ppc64/kernel/time.c | 4 +-- include/asm-ppc64/iSeries/ItLpQueue.h | 6 ++--- 6 files changed, 34 insertions(+), 34 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 61be23e..35f6dea 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -17,10 +17,10 @@ #include #include -static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) +static __inline__ int set_inUse(void) { int t; - u32 * inUseP = &(lpQueue->xInUseWord); + u32 * inUseP = &xItLpQueue.xInUseWord; __asm__ __volatile__("\n\ 1: lwarx %0,0,%2 \n\ @@ -31,37 +31,37 @@ static __inline__ int set_inUse( struct ItLpQueue * lpQueue ) stwcx. %0,0,%2 \n\ bne- 1b \n\ 2: eieio" - : "=&r" (t), "=m" (lpQueue->xInUseWord) - : "r" (inUseP), "m" (lpQueue->xInUseWord) + : "=&r" (t), "=m" (xItLpQueue.xInUseWord) + : "r" (inUseP), "m" (xItLpQueue.xInUseWord) : "cc"); return t; } -static __inline__ void clear_inUse( struct ItLpQueue * lpQueue ) +static __inline__ void clear_inUse(void) { - lpQueue->xInUseWord = 0; + xItLpQueue.xInUseWord = 0; } /* Array of LpEvent handler functions */ extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; unsigned long ItLpQueueInProcess = 0; -struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) +struct HvLpEvent * ItLpQueue_getNextLpEvent(void) { struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; if ( nextLpEvent->xFlags.xValid ) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + + xItLpQueue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + LpEventAlign ) / LpEventAlign ) * LpEventAlign; /* Wrap to beginning if no room at end */ - if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) - lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; + if (xItLpQueue.xSlicCurEventPtr > xItLpQueue.xSlicLastValidEventPtr) + xItLpQueue.xSlicCurEventPtr = xItLpQueue.xSlicEventStackPtr; } else nextLpEvent = NULL; @@ -71,15 +71,15 @@ struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) static unsigned long spread_lpevents = NR_CPUS; -int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) +int ItLpQueue_isLpIntPending(void) { struct HvLpEvent *next_event; if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; - return next_event->xFlags.xValid | lpQueue->xPlicOverflowIntPending; + next_event = (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; + return next_event->xFlags.xValid | xItLpQueue.xPlicOverflowIntPending; } void ItLpQueue_clearValid( struct HvLpEvent * event ) @@ -104,13 +104,13 @@ void ItLpQueue_clearValid( struct HvLpEvent * event ) event->xFlags.xValid = 0; } -unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) +unsigned ItLpQueue_process(struct pt_regs *regs) { unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; /* If we have recursed, just return */ - if ( !set_inUse( lpQueue ) ) + if ( !set_inUse() ) return 0; if (ItLpQueueInProcess == 0) @@ -119,13 +119,13 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) BUG(); for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); + nextLpEvent = ItLpQueue_getNextLpEvent(); if ( nextLpEvent ) { /* Count events to return to caller - * and count processed events in lpQueue + * and count processed events in xItLpQueue */ ++numIntsProcessed; - lpQueue->xLpIntCount++; + xItLpQueue.xLpIntCount++; /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -140,7 +140,7 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) * here! */ if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - lpQueue->xLpIntCountByType[nextLpEvent->xType]++; + xItLpQueue.xLpIntCountByType[nextLpEvent->xType]++; if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && lpEventHandler[nextLpEvent->xType] ) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); @@ -148,19 +148,19 @@ unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); ItLpQueue_clearValid( nextLpEvent ); - } else if ( lpQueue->xPlicOverflowIntPending ) + } else if ( xItLpQueue.xPlicOverflowIntPending ) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( lpQueue->xIndex); + HvCallEvent_getOverflowLpEvents( xItLpQueue.xIndex); else break; } ItLpQueueInProcess = 0; mb(); - clear_inUse( lpQueue ); + clear_inUse(); get_paca()->lpevent_count += numIntsProcessed; diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index 63977a7..a7ebd02 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending(&xItLpQueue)) + if (ItLpQueue_isLpIntPending()) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending(&xItLpQueue)) + if (ItLpQueue_isLpIntPending()) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index b1e6acb..46a7151 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -294,8 +294,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - if (ItLpQueue_isLpIntPending(&xItLpQueue)) - lpevent_count += ItLpQueue_process(&xItLpQueue, regs); + if (ItLpQueue_isLpIntPending()) + lpevent_count += ItLpQueue_process(regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index d6a297a..ef92069 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -802,8 +802,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { extern unsigned long lpevent_count; - if (ItLpQueue_isLpIntPending(&xItLpQueue)) - lpevent_count += ItLpQueue_process(&xItLpQueue, NULL); + if (ItLpQueue_isLpIntPending()) + lpevent_count += ItLpQueue_process(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index cdc43af..c133f9c 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -367,8 +367,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - if (ItLpQueue_isLpIntPending(&xItLpQueue)) - lpevent_count += ItLpQueue_process(&xItLpQueue, regs); + if (ItLpQueue_isLpIntPending()) + lpevent_count += ItLpQueue_process(regs); #endif /* collect purr register values often, for accurate calculations */ diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index 393299e..832497e 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -76,9 +76,9 @@ struct ItLpQueue { extern struct ItLpQueue xItLpQueue; -extern struct HvLpEvent *ItLpQueue_getNextLpEvent(struct ItLpQueue *); -extern int ItLpQueue_isLpIntPending(struct ItLpQueue *); -extern unsigned ItLpQueue_process(struct ItLpQueue *, struct pt_regs *); +extern struct HvLpEvent *ItLpQueue_getNextLpEvent(void); +extern int ItLpQueue_isLpIntPending(void); +extern unsigned ItLpQueue_process(struct pt_regs *); extern void ItLpQueue_clearValid(struct HvLpEvent *); #endif /* _ITLPQUEUE_H */ -- cgit v1.1 From 512d31d6a824a961f39b418f11480f678320e4f3 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:08:27 +1000 Subject: [PATCH] ppc64: Move initialisation of xItLpQueue into ItLpQueue.c The xItLpQueue is initalised manually in iSeries_setup_arch(). Move this code into ItLpQueue.c for a cleaner separation. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 22 ++++++++++++++++++++++ arch/ppc64/kernel/iSeries_setup.c | 21 +-------------------- include/asm-ppc64/iSeries/ItLpQueue.h | 1 + 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 35f6dea..091aaed 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -186,3 +187,24 @@ static int set_spread_lpevents(char *str) } __setup("spread_lpevents=", set_spread_lpevents); +void setup_hvlpevent_queue(void) +{ + void *eventStack; + + /* + * Allocate a page for the Event Stack. The Hypervisor needs the + * absolute real address, so we subtract out the KERNELBASE and add + * in the absolute real address of the kernel load area. + */ + eventStack = alloc_bootmem_pages(LpEventStackSize); + memset(eventStack, 0, LpEventStackSize); + + /* Invoke the hypervisor to initialize the event stack */ + HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + + xItLpQueue.xSlicEventStackPtr = (char *)eventStack; + xItLpQueue.xSlicCurEventPtr = (char *)eventStack; + xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + + (LpEventStackSize - LpEventMaxSize); + xItLpQueue.xIndex = 0; +} diff --git a/arch/ppc64/kernel/iSeries_setup.c b/arch/ppc64/kernel/iSeries_setup.c index 78f2835..b3f770f 100644 --- a/arch/ppc64/kernel/iSeries_setup.c +++ b/arch/ppc64/kernel/iSeries_setup.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -676,7 +675,6 @@ static void __init iSeries_bolt_kernel(unsigned long saddr, unsigned long eaddr) */ static void __init iSeries_setup_arch(void) { - void *eventStack; unsigned procIx = get_paca()->lppaca.dyn_hv_phys_proc_index; /* Add an eye catcher and the systemcfg layout version number */ @@ -685,24 +683,7 @@ static void __init iSeries_setup_arch(void) systemcfg->version.minor = SYSTEMCFG_MINOR; /* Setup the Lp Event Queue */ - - /* Allocate a page for the Event Stack - * The hypervisor wants the absolute real address, so - * we subtract out the KERNELBASE and add in the - * absolute real address of the kernel load area - */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); - - /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); - - /* Initialize fields in our Lp Event Queue */ - xItLpQueue.xSlicEventStackPtr = (char *)eventStack; - xItLpQueue.xSlicCurEventPtr = (char *)eventStack; - xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - xItLpQueue.xIndex = 0; + setup_hvlpevent_queue(); /* Compute processor frequency */ procFreqHz = ((1UL << 34) * 1000000) / diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index 832497e..de90fee 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -80,5 +80,6 @@ extern struct HvLpEvent *ItLpQueue_getNextLpEvent(void); extern int ItLpQueue_isLpIntPending(void); extern unsigned ItLpQueue_process(struct pt_regs *); extern void ItLpQueue_clearValid(struct HvLpEvent *); +extern void setup_hvlpevent_queue(void); #endif /* _ITLPQUEUE_H */ -- cgit v1.1 From 7b01328d455b50ff040d3a06b342ca370b1d8b0a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:08:44 +1000 Subject: [PATCH] ppc64: Move xItLpQueue proc code into ItLpQueue.c Move the code that displays xItLpQueue values in /proc into ItLpQueue.c. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 59 ++++++++++++++++++++++++++++++++++++++++ arch/ppc64/kernel/iSeries_proc.c | 48 -------------------------------- 2 files changed, 59 insertions(+), 48 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 091aaed..11cd31d 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -12,12 +12,26 @@ #include #include #include +#include +#include #include #include #include #include #include +static char *event_types[9] = { + "Hypervisor\t\t", + "Machine Facilities\t", + "Session Manager\t", + "SPD I/O\t\t", + "Virtual Bus\t\t", + "PCI I/O\t\t", + "RIO I/O\t\t", + "Virtual Lan\t\t", + "Virtual I/O\t\t" +}; + static __inline__ int set_inUse(void) { int t; @@ -208,3 +222,48 @@ void setup_hvlpevent_queue(void) (LpEventStackSize - LpEventMaxSize); xItLpQueue.xIndex = 0; } + +static int proc_lpevents_show(struct seq_file *m, void *v) +{ + unsigned int i; + + seq_printf(m, "LpEventQueue 0\n"); + seq_printf(m, " events processed:\t%lu\n", + (unsigned long)xItLpQueue.xLpIntCount); + + for (i = 0; i < 9; ++i) + seq_printf(m, " %s %10lu\n", event_types[i], + (unsigned long)xItLpQueue.xLpIntCountByType[i]); + + seq_printf(m, "\n events processed by processor:\n"); + + for_each_online_cpu(i) + seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); + + return 0; +} + +static int proc_lpevents_open(struct inode *inode, struct file *file) +{ + return single_open(file, proc_lpevents_show, NULL); +} + +static struct file_operations proc_lpevents_operations = { + .open = proc_lpevents_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init proc_lpevents_init(void) +{ + struct proc_dir_entry *e; + + e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); + if (e) + e->proc_fops = &proc_lpevents_operations; + + return 0; +} +__initcall(proc_lpevents_init); + diff --git a/arch/ppc64/kernel/iSeries_proc.c b/arch/ppc64/kernel/iSeries_proc.c index 356bd99..0fe3116 100644 --- a/arch/ppc64/kernel/iSeries_proc.c +++ b/arch/ppc64/kernel/iSeries_proc.c @@ -40,50 +40,6 @@ static int __init iseries_proc_create(void) } core_initcall(iseries_proc_create); -static char *event_types[9] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" -}; - -static int proc_lpevents_show(struct seq_file *m, void *v) -{ - unsigned int i; - - seq_printf(m, "LpEventQueue 0\n"); - seq_printf(m, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount); - - for (i = 0; i < 9; ++i) - seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i]); - - seq_printf(m, "\n events processed by processor:\n"); - - for_each_online_cpu(i) - seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); - - return 0; -} - -static int proc_lpevents_open(struct inode *inode, struct file *file) -{ - return single_open(file, proc_lpevents_show, NULL); -} - -static struct file_operations proc_lpevents_operations = { - .open = proc_lpevents_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static unsigned long startTitan = 0; static unsigned long startTb = 0; @@ -148,10 +104,6 @@ static int __init iseries_proc_init(void) { struct proc_dir_entry *e; - e = create_proc_entry("iSeries/lpevents", S_IFREG|S_IRUGO, NULL); - if (e) - e->proc_fops = &proc_lpevents_operations; - e = create_proc_entry("iSeries/titanTod", S_IFREG|S_IRUGO, NULL); if (e) e->proc_fops = &proc_titantod_operations; -- cgit v1.1 From 0f6014b37e25e50724867c0a4127615427ec2a75 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:08:56 +1000 Subject: [PATCH] ppc64: Make two ItLpQueue related functions static External parties don't need to use ItLpQueue_getNextLpEvent() or ItLpQueue_clearValid(), they're internal to ItLpQueue.c Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 4 ++-- include/asm-ppc64/iSeries/ItLpQueue.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 11cd31d..ac0b05a 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -62,7 +62,7 @@ static __inline__ void clear_inUse(void) extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; unsigned long ItLpQueueInProcess = 0; -struct HvLpEvent * ItLpQueue_getNextLpEvent(void) +static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) { struct HvLpEvent * nextLpEvent = (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; @@ -97,7 +97,7 @@ int ItLpQueue_isLpIntPending(void) return next_event->xFlags.xValid | xItLpQueue.xPlicOverflowIntPending; } -void ItLpQueue_clearValid( struct HvLpEvent * event ) +static void ItLpQueue_clearValid( struct HvLpEvent * event ) { /* Clear the valid bit of the event * Also clear bits within this event that might diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index de90fee..be1cb7f 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -76,10 +76,8 @@ struct ItLpQueue { extern struct ItLpQueue xItLpQueue; -extern struct HvLpEvent *ItLpQueue_getNextLpEvent(void); extern int ItLpQueue_isLpIntPending(void); extern unsigned ItLpQueue_process(struct pt_regs *); -extern void ItLpQueue_clearValid(struct HvLpEvent *); extern void setup_hvlpevent_queue(void); #endif /* _ITLPQUEUE_H */ -- cgit v1.1 From ab354b637924beb33dcc23eedc9482f2c692188f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:12:21 +1000 Subject: [PATCH] ppc64: Move definition of xItLpQueue The xItLpQueue is declared in LparData.c, move it into ItLpQueue.c. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 8 ++++++++ arch/ppc64/kernel/LparData.c | 7 ------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index ac0b05a..7ddbfb9 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -20,6 +20,14 @@ #include #include +/* + * The LpQueue is used to pass event data from the hypervisor to + * the partition. This is where I/O interrupt events are communicated. + * + * It is written to by the hypervisor so cannot end up in the BSS. + */ +struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); + static char *event_types[9] = { "Hypervisor\t\t", "Machine Facilities\t", diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index badc5a4..f42ee35 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -28,13 +28,6 @@ #include #include -/* The LpQueue is used to pass event data from the hypervisor to - * the partition. This is where I/O interrupt events are communicated. - */ - -/* May be filled in by the hypervisor so cannot end up in the BSS */ -struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); - /* The HvReleaseData is the root of the information shared between * the hypervisor and Linux. -- cgit v1.1 From a61874648d14450f4d397489527998e3dd1119de Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:15:32 +1000 Subject: [PATCH] ppc64: Rename xItLpQueue to hvlpevent_queue The xItLpQueue is a queue of HvLpEvents that we're given by the Hypervisor. Rename xItLpQueue to hvlpevent_queue and make the type struct hvlpevent_queue. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 44 +++++++++++++++++------------------ arch/ppc64/kernel/LparData.c | 4 ++-- include/asm-ppc64/iSeries/ItLpQueue.h | 4 ++-- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 7ddbfb9..e55fe1a 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -26,7 +26,7 @@ * * It is written to by the hypervisor so cannot end up in the BSS. */ -struct ItLpQueue xItLpQueue __attribute__((__section__(".data"))); +struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); static char *event_types[9] = { "Hypervisor\t\t", @@ -43,7 +43,7 @@ static char *event_types[9] = { static __inline__ int set_inUse(void) { int t; - u32 * inUseP = &xItLpQueue.xInUseWord; + u32 * inUseP = &hvlpevent_queue.xInUseWord; __asm__ __volatile__("\n\ 1: lwarx %0,0,%2 \n\ @@ -54,8 +54,8 @@ static __inline__ int set_inUse(void) stwcx. %0,0,%2 \n\ bne- 1b \n\ 2: eieio" - : "=&r" (t), "=m" (xItLpQueue.xInUseWord) - : "r" (inUseP), "m" (xItLpQueue.xInUseWord) + : "=&r" (t), "=m" (hvlpevent_queue.xInUseWord) + : "r" (inUseP), "m" (hvlpevent_queue.xInUseWord) : "cc"); return t; @@ -63,7 +63,7 @@ static __inline__ int set_inUse(void) static __inline__ void clear_inUse(void) { - xItLpQueue.xInUseWord = 0; + hvlpevent_queue.xInUseWord = 0; } /* Array of LpEvent handler functions */ @@ -73,18 +73,18 @@ unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) { struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; + (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; if ( nextLpEvent->xFlags.xValid ) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - xItLpQueue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + + hvlpevent_queue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + LpEventAlign ) / LpEventAlign ) * LpEventAlign; /* Wrap to beginning if no room at end */ - if (xItLpQueue.xSlicCurEventPtr > xItLpQueue.xSlicLastValidEventPtr) - xItLpQueue.xSlicCurEventPtr = xItLpQueue.xSlicEventStackPtr; + if (hvlpevent_queue.xSlicCurEventPtr > hvlpevent_queue.xSlicLastValidEventPtr) + hvlpevent_queue.xSlicCurEventPtr = hvlpevent_queue.xSlicEventStackPtr; } else nextLpEvent = NULL; @@ -101,8 +101,8 @@ int ItLpQueue_isLpIntPending(void) if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)xItLpQueue.xSlicCurEventPtr; - return next_event->xFlags.xValid | xItLpQueue.xPlicOverflowIntPending; + next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } static void ItLpQueue_clearValid( struct HvLpEvent * event ) @@ -145,10 +145,10 @@ unsigned ItLpQueue_process(struct pt_regs *regs) nextLpEvent = ItLpQueue_getNextLpEvent(); if ( nextLpEvent ) { /* Count events to return to caller - * and count processed events in xItLpQueue + * and count processed events in hvlpevent_queue */ ++numIntsProcessed; - xItLpQueue.xLpIntCount++; + hvlpevent_queue.xLpIntCount++; /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -163,7 +163,7 @@ unsigned ItLpQueue_process(struct pt_regs *regs) * here! */ if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - xItLpQueue.xLpIntCountByType[nextLpEvent->xType]++; + hvlpevent_queue.xLpIntCountByType[nextLpEvent->xType]++; if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && lpEventHandler[nextLpEvent->xType] ) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); @@ -171,12 +171,12 @@ unsigned ItLpQueue_process(struct pt_regs *regs) printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); ItLpQueue_clearValid( nextLpEvent ); - } else if ( xItLpQueue.xPlicOverflowIntPending ) + } else if ( hvlpevent_queue.xPlicOverflowIntPending ) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( xItLpQueue.xIndex); + HvCallEvent_getOverflowLpEvents( hvlpevent_queue.xIndex); else break; } @@ -224,11 +224,11 @@ void setup_hvlpevent_queue(void) /* Invoke the hypervisor to initialize the event stack */ HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); - xItLpQueue.xSlicEventStackPtr = (char *)eventStack; - xItLpQueue.xSlicCurEventPtr = (char *)eventStack; - xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + + hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; + hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; + hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + (LpEventStackSize - LpEventMaxSize); - xItLpQueue.xIndex = 0; + hvlpevent_queue.xIndex = 0; } static int proc_lpevents_show(struct seq_file *m, void *v) @@ -237,11 +237,11 @@ static int proc_lpevents_show(struct seq_file *m, void *v) seq_printf(m, "LpEventQueue 0\n"); seq_printf(m, " events processed:\t%lu\n", - (unsigned long)xItLpQueue.xLpIntCount); + (unsigned long)hvlpevent_queue.xLpIntCount); for (i = 0; i < 9; ++i) seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)xItLpQueue.xLpIntCountByType[i]); + (unsigned long)hvlpevent_queue.xLpIntCountByType[i]); seq_printf(m, "\n events processed by processor:\n"); diff --git a/arch/ppc64/kernel/LparData.c b/arch/ppc64/kernel/LparData.c index f42ee35..6ffcf67 100644 --- a/arch/ppc64/kernel/LparData.c +++ b/arch/ppc64/kernel/LparData.c @@ -193,7 +193,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ sizeof(struct IoHriProcessorVpd),/* 16 length of Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - sizeof(struct ItLpQueue),/* 23 length of Lp Queue */ + sizeof(struct hvlpevent_queue), /* 23 length of Lp Queue */ 0,0 /* 24 - 25 */ }, .xSlicVpdAdrs = { /* VPD addresses */ @@ -211,7 +211,7 @@ struct ItVpdAreas itVpdAreas = { 0,0,0, /* 13 - 15 */ &xIoHriProcessorVpd, /* 16 Proc Vpd */ 0,0,0,0,0,0, /* 17 - 22 */ - &xItLpQueue, /* 23 Lp Queue */ + &hvlpevent_queue, /* 23 Lp Queue */ 0,0 } }; diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index be1cb7f..bebfb36 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -41,7 +41,7 @@ struct HvLpEvent; #define LpEventMaxSize 256 #define LpEventAlign 64 -struct ItLpQueue { +struct hvlpevent_queue { /* * The xSlicCurEventPtr is the pointer to the next event stack entry * that will become valid. The OS must peek at this entry to determine @@ -74,7 +74,7 @@ struct ItLpQueue { u64 xLpIntCountByType[9]; // 0x38-0x7F Event counts by type }; -extern struct ItLpQueue xItLpQueue; +extern struct hvlpevent_queue hvlpevent_queue; extern int ItLpQueue_isLpIntPending(void); extern unsigned ItLpQueue_process(struct pt_regs *); -- cgit v1.1 From 937b31b114b5540f456ce1566aae67e02db41f2c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:15:42 +1000 Subject: [PATCH] ppc64: Rename ItLpQueue_* functions to hvlpevent_queue_* Now that we've renamed the xItLpQueue structure, rename the functions that operate on it also. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 12 ++++++------ arch/ppc64/kernel/idle.c | 4 ++-- arch/ppc64/kernel/irq.c | 4 ++-- arch/ppc64/kernel/mf.c | 4 ++-- arch/ppc64/kernel/time.c | 4 ++-- include/asm-ppc64/iSeries/ItLpQueue.h | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index e55fe1a..a81e49b 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -70,7 +70,7 @@ static __inline__ void clear_inUse(void) extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; unsigned long ItLpQueueInProcess = 0; -static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) +static struct HvLpEvent * get_next_hvlpevent(void) { struct HvLpEvent * nextLpEvent = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; @@ -94,7 +94,7 @@ static struct HvLpEvent * ItLpQueue_getNextLpEvent(void) static unsigned long spread_lpevents = NR_CPUS; -int ItLpQueue_isLpIntPending(void) +int hvlpevent_is_pending(void) { struct HvLpEvent *next_event; @@ -105,7 +105,7 @@ int ItLpQueue_isLpIntPending(void) return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } -static void ItLpQueue_clearValid( struct HvLpEvent * event ) +static void hvlpevent_clear_valid( struct HvLpEvent * event ) { /* Clear the valid bit of the event * Also clear bits within this event that might @@ -127,7 +127,7 @@ static void ItLpQueue_clearValid( struct HvLpEvent * event ) event->xFlags.xValid = 0; } -unsigned ItLpQueue_process(struct pt_regs *regs) +unsigned process_hvlpevents(struct pt_regs *regs) { unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; @@ -142,7 +142,7 @@ unsigned ItLpQueue_process(struct pt_regs *regs) BUG(); for (;;) { - nextLpEvent = ItLpQueue_getNextLpEvent(); + nextLpEvent = get_next_hvlpevent(); if ( nextLpEvent ) { /* Count events to return to caller * and count processed events in hvlpevent_queue @@ -170,7 +170,7 @@ unsigned ItLpQueue_process(struct pt_regs *regs) else printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - ItLpQueue_clearValid( nextLpEvent ); + hvlpevent_clear_valid( nextLpEvent ); } else if ( hvlpevent_queue.xPlicOverflowIntPending ) /* * No more valid events. If overflow events are diff --git a/arch/ppc64/kernel/idle.c b/arch/ppc64/kernel/idle.c index a7ebd02..08952c7 100644 --- a/arch/ppc64/kernel/idle.c +++ b/arch/ppc64/kernel/idle.c @@ -88,7 +88,7 @@ static int iSeries_idle(void) while (1) { if (lpaca->lppaca.shared_proc) { - if (ItLpQueue_isLpIntPending()) + if (hvlpevent_is_pending()) process_iSeries_events(); if (!need_resched()) yield_shared_processor(); @@ -100,7 +100,7 @@ static int iSeries_idle(void) while (!need_resched()) { HMT_medium(); - if (ItLpQueue_isLpIntPending()) + if (hvlpevent_is_pending()) process_iSeries_events(); HMT_low(); } diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index 46a7151..bd4b035 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -294,8 +294,8 @@ void do_IRQ(struct pt_regs *regs) iSeries_smp_message_recv(regs); } #endif /* CONFIG_SMP */ - if (ItLpQueue_isLpIntPending()) - lpevent_count += ItLpQueue_process(regs); + if (hvlpevent_is_pending()) + lpevent_count += process_hvlpevents(regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index ef92069..609bf1b 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -802,8 +802,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { extern unsigned long lpevent_count; - if (ItLpQueue_isLpIntPending()) - lpevent_count += ItLpQueue_process(NULL); + if (hvlpevent_is_pending()) + lpevent_count += process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index c133f9c..f9c1840 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -367,8 +367,8 @@ int timer_interrupt(struct pt_regs * regs) set_dec(next_dec); #ifdef CONFIG_PPC_ISERIES - if (ItLpQueue_isLpIntPending()) - lpevent_count += ItLpQueue_process(regs); + if (hvlpevent_is_pending()) + lpevent_count += process_hvlpevents(regs); #endif /* collect purr register values often, for accurate calculations */ diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index bebfb36..f0f24a3 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -76,8 +76,8 @@ struct hvlpevent_queue { extern struct hvlpevent_queue hvlpevent_queue; -extern int ItLpQueue_isLpIntPending(void); -extern unsigned ItLpQueue_process(struct pt_regs *); +extern int hvlpevent_is_pending(void); +extern unsigned process_hvlpevents(struct pt_regs *); extern void setup_hvlpevent_queue(void); #endif /* _ITLPQUEUE_H */ -- cgit v1.1 From 74889802a1585af4e1652f0cb853ac22a65816a4 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:15:53 +1000 Subject: [PATCH] ppc64: Don't count number of events processed for caller Currently we count the number of lpevents processed in 3 seperate places. One of these counters is never read, so just remove it. This means hvlpevent_queue_process() no longer needs to return the number of events processed. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 9 ++------- arch/ppc64/kernel/irq.c | 3 +-- arch/ppc64/kernel/mf.c | 3 +-- arch/ppc64/kernel/time.c | 3 +-- include/asm-ppc64/iSeries/ItLpQueue.h | 2 +- 5 files changed, 6 insertions(+), 14 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a81e49b..a849f67 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -127,14 +127,14 @@ static void hvlpevent_clear_valid( struct HvLpEvent * event ) event->xFlags.xValid = 0; } -unsigned process_hvlpevents(struct pt_regs *regs) +void process_hvlpevents(struct pt_regs *regs) { unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; /* If we have recursed, just return */ if ( !set_inUse() ) - return 0; + return; if (ItLpQueueInProcess == 0) ItLpQueueInProcess = 1; @@ -144,9 +144,6 @@ unsigned process_hvlpevents(struct pt_regs *regs) for (;;) { nextLpEvent = get_next_hvlpevent(); if ( nextLpEvent ) { - /* Count events to return to caller - * and count processed events in hvlpevent_queue - */ ++numIntsProcessed; hvlpevent_queue.xLpIntCount++; /* Call appropriate handler here, passing @@ -186,8 +183,6 @@ unsigned process_hvlpevents(struct pt_regs *regs) clear_inUse(); get_paca()->lpevent_count += numIntsProcessed; - - return numIntsProcessed; } static int set_spread_lpevents(char *str) diff --git a/arch/ppc64/kernel/irq.c b/arch/ppc64/kernel/irq.c index bd4b035..e79420b 100644 --- a/arch/ppc64/kernel/irq.c +++ b/arch/ppc64/kernel/irq.c @@ -66,7 +66,6 @@ EXPORT_SYMBOL(irq_desc); int distribute_irqs = 1; int __irq_offset_value; int ppc_spurious_interrupts; -unsigned long lpevent_count; u64 ppc64_interrupt_controller; int show_interrupts(struct seq_file *p, void *v) @@ -295,7 +294,7 @@ void do_IRQ(struct pt_regs *regs) } #endif /* CONFIG_SMP */ if (hvlpevent_is_pending()) - lpevent_count += process_hvlpevents(regs); + process_hvlpevents(regs); irq_exit(); diff --git a/arch/ppc64/kernel/mf.c b/arch/ppc64/kernel/mf.c index 609bf1b..ef4a338 100644 --- a/arch/ppc64/kernel/mf.c +++ b/arch/ppc64/kernel/mf.c @@ -801,9 +801,8 @@ int mf_get_boot_rtc(struct rtc_time *tm) return rc; /* We need to poll here as we are not yet taking interrupts */ while (rtc_data.busy) { - extern unsigned long lpevent_count; if (hvlpevent_is_pending()) - lpevent_count += process_hvlpevents(NULL); + process_hvlpevents(NULL); } return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm); } diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c index f9c1840..909462e 100644 --- a/arch/ppc64/kernel/time.c +++ b/arch/ppc64/kernel/time.c @@ -99,7 +99,6 @@ unsigned long tb_to_ns_shift; struct gettimeofday_struct do_gtod; extern unsigned long wall_jiffies; -extern unsigned long lpevent_count; extern int smp_tb_synchronized; extern struct timezone sys_tz; @@ -368,7 +367,7 @@ int timer_interrupt(struct pt_regs * regs) #ifdef CONFIG_PPC_ISERIES if (hvlpevent_is_pending()) - lpevent_count += process_hvlpevents(regs); + process_hvlpevents(regs); #endif /* collect purr register values often, for accurate calculations */ diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index f0f24a3..6ba74c0 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -77,7 +77,7 @@ struct hvlpevent_queue { extern struct hvlpevent_queue hvlpevent_queue; extern int hvlpevent_is_pending(void); -extern unsigned process_hvlpevents(struct pt_regs *); +extern void process_hvlpevents(struct pt_regs *); extern void setup_hvlpevent_queue(void); #endif /* _ITLPQUEUE_H */ -- cgit v1.1 From ed094150bdeb6eca691f1b7a05bd34d4d1a95488 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:09 +1000 Subject: [PATCH] ppc64: Simplify counting of lpevents, remove lpevent_count from paca Currently there's a per-cpu count of lpevents processed, a per-queue (ie. global) total count, and a count by event type. Replace all that with a count by event for each cpu. We only need to add it up int the proc code. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 44 +++++++++++++++++++++++------------ include/asm-ppc64/iSeries/ItLpQueue.h | 2 -- include/asm-ppc64/paca.h | 1 - 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a849f67..4a6ab9d 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -28,7 +28,9 @@ */ struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); -static char *event_types[9] = { +DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); + +static char *event_types[HvLpEvent_Type_NumTypes] = { "Hypervisor\t\t", "Machine Facilities\t", "Session Manager\t", @@ -129,7 +131,6 @@ static void hvlpevent_clear_valid( struct HvLpEvent * event ) void process_hvlpevents(struct pt_regs *regs) { - unsigned numIntsProcessed = 0; struct HvLpEvent * nextLpEvent; /* If we have recursed, just return */ @@ -144,8 +145,6 @@ void process_hvlpevents(struct pt_regs *regs) for (;;) { nextLpEvent = get_next_hvlpevent(); if ( nextLpEvent ) { - ++numIntsProcessed; - hvlpevent_queue.xLpIntCount++; /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -160,7 +159,7 @@ void process_hvlpevents(struct pt_regs *regs) * here! */ if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) - hvlpevent_queue.xLpIntCountByType[nextLpEvent->xType]++; + __get_cpu_var(hvlpevent_counts)[nextLpEvent->xType]++; if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && lpEventHandler[nextLpEvent->xType] ) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); @@ -181,8 +180,6 @@ void process_hvlpevents(struct pt_regs *regs) ItLpQueueInProcess = 0; mb(); clear_inUse(); - - get_paca()->lpevent_count += numIntsProcessed; } static int set_spread_lpevents(char *str) @@ -228,20 +225,37 @@ void setup_hvlpevent_queue(void) static int proc_lpevents_show(struct seq_file *m, void *v) { - unsigned int i; + int cpu, i; + unsigned long sum; + static unsigned long cpu_totals[NR_CPUS]; + + /* FIXME: do we care that there's no locking here? */ + sum = 0; + for_each_online_cpu(cpu) { + cpu_totals[cpu] = 0; + for (i = 0; i < HvLpEvent_Type_NumTypes; i++) { + cpu_totals[cpu] += per_cpu(hvlpevent_counts, cpu)[i]; + } + sum += cpu_totals[cpu]; + } seq_printf(m, "LpEventQueue 0\n"); - seq_printf(m, " events processed:\t%lu\n", - (unsigned long)hvlpevent_queue.xLpIntCount); + seq_printf(m, " events processed:\t%lu\n", sum); - for (i = 0; i < 9; ++i) - seq_printf(m, " %s %10lu\n", event_types[i], - (unsigned long)hvlpevent_queue.xLpIntCountByType[i]); + for (i = 0; i < HvLpEvent_Type_NumTypes; ++i) { + sum = 0; + for_each_online_cpu(cpu) { + sum += per_cpu(hvlpevent_counts, cpu)[i]; + } + + seq_printf(m, " %s %10lu\n", event_types[i], sum); + } seq_printf(m, "\n events processed by processor:\n"); - for_each_online_cpu(i) - seq_printf(m, " CPU%02d %10u\n", i, paca[i].lpevent_count); + for_each_online_cpu(cpu) { + seq_printf(m, " CPU%02d %10lu\n", cpu, cpu_totals[cpu]); + } return 0; } diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index 6ba74c0..51db088 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -70,8 +70,6 @@ struct hvlpevent_queue { u8 xIndex; // 0x28 unique sequential index. u8 xSlicRsvd[3]; // 0x29-2b u32 xInUseWord; // 0x2C - u64 xLpIntCount; // 0x30 Total Lp Int msgs processed - u64 xLpIntCountByType[9]; // 0x38-0x7F Event counts by type }; extern struct hvlpevent_queue hvlpevent_queue; diff --git a/include/asm-ppc64/paca.h b/include/asm-ppc64/paca.h index 0146f516..2f0f36f 100644 --- a/include/asm-ppc64/paca.h +++ b/include/asm-ppc64/paca.h @@ -89,7 +89,6 @@ struct paca_struct { u64 next_jiffy_update_tb; /* TB value for next jiffy update */ u64 saved_r1; /* r1 save for RTAS calls */ u64 saved_msr; /* MSR saved here by enter_rtas */ - u32 lpevent_count; /* lpevents processed */ u8 proc_enabled; /* irq soft-enable flag */ /* not yet used */ -- cgit v1.1 From 9b0470200a2441766599ad84f92ab9daca8ed86d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:18 +1000 Subject: [PATCH] ppc64: Cleanup proc printing of event types The code that prints event counts by type uses a hand-coded number of tabs to get the alignment right. Instead use a printf alignment which will allow allow us to use the event_type strings elsewhere in the future. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 4a6ab9d..83fb36a 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -31,15 +31,15 @@ struct hvlpevent_queue hvlpevent_queue __attribute__((__section__(".data"))); DEFINE_PER_CPU(unsigned long[HvLpEvent_Type_NumTypes], hvlpevent_counts); static char *event_types[HvLpEvent_Type_NumTypes] = { - "Hypervisor\t\t", - "Machine Facilities\t", - "Session Manager\t", - "SPD I/O\t\t", - "Virtual Bus\t\t", - "PCI I/O\t\t", - "RIO I/O\t\t", - "Virtual Lan\t\t", - "Virtual I/O\t\t" + "Hypervisor", + "Machine Facilities", + "Session Manager", + "SPD I/O", + "Virtual Bus", + "PCI I/O", + "RIO I/O", + "Virtual Lan", + "Virtual I/O" }; static __inline__ int set_inUse(void) @@ -248,7 +248,7 @@ static int proc_lpevents_show(struct seq_file *m, void *v) sum += per_cpu(hvlpevent_counts, cpu)[i]; } - seq_printf(m, " %s %10lu\n", event_types[i], sum); + seq_printf(m, " %-20s %10lu\n", event_types[i], sum); } seq_printf(m, "\n events processed by processor:\n"); -- cgit v1.1 From 38fcdcfe38fc3f8972c906db64cd7d540b7760e8 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:28 +1000 Subject: [PATCH] ppc64: Cleanup whitespace in arch/ppc64/kernel/ItLpQueue.c Just cleanup white space. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 58 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 83fb36a..61a9dbd 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -1,7 +1,7 @@ /* * ItLpQueue.c * Copyright (C) 2001 Mike Corrigan IBM Corporation - * + * * 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 @@ -74,21 +74,21 @@ unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * get_next_hvlpevent(void) { - struct HvLpEvent * nextLpEvent = + struct HvLpEvent * nextLpEvent = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - if ( nextLpEvent->xFlags.xValid ) { + if (nextLpEvent->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ hvlpevent_queue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign ) / - LpEventAlign ) * + LpEventAlign) / + LpEventAlign) * LpEventAlign; /* Wrap to beginning if no room at end */ if (hvlpevent_queue.xSlicCurEventPtr > hvlpevent_queue.xSlicLastValidEventPtr) hvlpevent_queue.xSlicCurEventPtr = hvlpevent_queue.xSlicEventStackPtr; } - else + else nextLpEvent = NULL; return nextLpEvent; @@ -107,23 +107,23 @@ int hvlpevent_is_pending(void) return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; } -static void hvlpevent_clear_valid( struct HvLpEvent * event ) +static void hvlpevent_clear_valid(struct HvLpEvent * event) { /* Clear the valid bit of the event * Also clear bits within this event that might * look like valid bits (on 64-byte boundaries) - */ - unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / - LpEventAlign ) - 1; - switch ( extra ) { - case 3: + */ + unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / + LpEventAlign) - 1; + switch (extra) { + case 3: ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; - case 2: + case 2: ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; - case 1: + case 1: ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; + case 0: + ; } mb(); event->xFlags.xValid = 0; @@ -136,7 +136,7 @@ void process_hvlpevents(struct pt_regs *regs) /* If we have recursed, just return */ if ( !set_inUse() ) return; - + if (ItLpQueueInProcess == 0) ItLpQueueInProcess = 1; else @@ -144,35 +144,35 @@ void process_hvlpevents(struct pt_regs *regs) for (;;) { nextLpEvent = get_next_hvlpevent(); - if ( nextLpEvent ) { - /* Call appropriate handler here, passing + if (nextLpEvent) { + /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it * needs it in a bottom half. (perhaps for * an ACK) - * - * Handlers are responsible for ACK processing + * + * Handlers are responsible for ACK processing * * The Hypervisor guarantees that LpEvents will * only be delivered with types that we have * registered for, so no type check is necessary * here! - */ - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) + */ + if (nextLpEvent->xType < HvLpEvent_Type_NumTypes) __get_cpu_var(hvlpevent_counts)[nextLpEvent->xType]++; - if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType] ) + if (nextLpEvent->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[nextLpEvent->xType]) lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); else printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); - - hvlpevent_clear_valid( nextLpEvent ); - } else if ( hvlpevent_queue.xPlicOverflowIntPending ) + + hvlpevent_clear_valid(nextLpEvent); + } else if (hvlpevent_queue.xPlicOverflowIntPending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents( hvlpevent_queue.xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); else break; } -- cgit v1.1 From ffe1b7e14e6b606bd84cab564aa2f481dbd4e418 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:16:48 +1000 Subject: [PATCH] ppc64: Formatting cleanups in arch/ppc64/kernel/ItLpQueue.c Just formatting cleanups: * rename some "nextLpEvent" variables to just "event" * make code fit in 80 columns * use brackets around if/else * use a temporary to make hvlpevent_clear_valid clearer Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 72 ++++++++++++++++++++++++------------------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index 61a9dbd..a4f32cb 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -74,24 +74,27 @@ unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * get_next_hvlpevent(void) { - struct HvLpEvent * nextLpEvent = - (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - if (nextLpEvent->xFlags.xValid) { + struct HvLpEvent * event; + event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + + if (event->xFlags.xValid) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - hvlpevent_queue.xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + - LpEventAlign) / - LpEventAlign) * - LpEventAlign; + hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + + LpEventAlign) / LpEventAlign) * LpEventAlign; + /* Wrap to beginning if no room at end */ - if (hvlpevent_queue.xSlicCurEventPtr > hvlpevent_queue.xSlicLastValidEventPtr) - hvlpevent_queue.xSlicCurEventPtr = hvlpevent_queue.xSlicEventStackPtr; + if (hvlpevent_queue.xSlicCurEventPtr > + hvlpevent_queue.xSlicLastValidEventPtr) { + hvlpevent_queue.xSlicCurEventPtr = + hvlpevent_queue.xSlicEventStackPtr; + } + } else { + event = NULL; } - else - nextLpEvent = NULL; - return nextLpEvent; + return event; } static unsigned long spread_lpevents = NR_CPUS; @@ -104,34 +107,41 @@ int hvlpevent_is_pending(void) return 0; next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; - return next_event->xFlags.xValid | hvlpevent_queue.xPlicOverflowIntPending; + + return next_event->xFlags.xValid | + hvlpevent_queue.xPlicOverflowIntPending; } static void hvlpevent_clear_valid(struct HvLpEvent * event) { - /* Clear the valid bit of the event - * Also clear bits within this event that might - * look like valid bits (on 64-byte boundaries) + /* Tell the Hypervisor that we're done with this event. + * Also clear bits within this event that might look like valid bits. + * ie. on 64-byte boundaries. */ + struct HvLpEvent *tmp; unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / LpEventAlign) - 1; + switch (extra) { case 3: - ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; + tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp->xFlags.xValid = 0; case 2: - ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; + tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp->xFlags.xValid = 0; case 1: - ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; - case 0: - ; + tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp->xFlags.xValid = 0; } + mb(); + event->xFlags.xValid = 0; } void process_hvlpevents(struct pt_regs *regs) { - struct HvLpEvent * nextLpEvent; + struct HvLpEvent * event; /* If we have recursed, just return */ if ( !set_inUse() ) @@ -143,8 +153,8 @@ void process_hvlpevents(struct pt_regs *regs) BUG(); for (;;) { - nextLpEvent = get_next_hvlpevent(); - if (nextLpEvent) { + event = get_next_hvlpevent(); + if (event) { /* Call appropriate handler here, passing * a pointer to the LpEvent. The handler * must make a copy of the LpEvent if it @@ -158,15 +168,15 @@ void process_hvlpevents(struct pt_regs *regs) * registered for, so no type check is necessary * here! */ - if (nextLpEvent->xType < HvLpEvent_Type_NumTypes) - __get_cpu_var(hvlpevent_counts)[nextLpEvent->xType]++; - if (nextLpEvent->xType < HvLpEvent_Type_NumTypes && - lpEventHandler[nextLpEvent->xType]) - lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); + if (event->xType < HvLpEvent_Type_NumTypes) + __get_cpu_var(hvlpevent_counts)[event->xType]++; + if (event->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[event->xType]) + lpEventHandler[event->xType](event, regs); else - printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); + printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); - hvlpevent_clear_valid(nextLpEvent); + hvlpevent_clear_valid(event); } else if (hvlpevent_queue.xPlicOverflowIntPending) /* * No more valid events. If overflow events are -- cgit v1.1 From 719d1cd86780c156f954fc34f34481adac197aec Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 30 Jun 2005 15:17:02 +1000 Subject: [PATCH] ppc64: Replace custom locking code with a spinlock The hvlpevent_queue (formally ItLpQueue) has a member called xInUseWord which is used for serialising access to the queue. Because it's a word (ie. 32 bit) there's a custom 32-bit version of test_and_set_bit() or thereabouts in ItLpQueue.c. The xInUseWord is not shared with they hypervisor, so we can replace it with a spinlock and remove the custom code. There is also another locking mechanism (ItLpQueueInProcess). This is redundant because it's only manipulated while the lock's held. Remove it. Signed-off-by: Michael Ellerman Acked-by: Stephen Rothwell Signed-off-by: Paul Mackerras --- arch/ppc64/kernel/ItLpQueue.c | 38 ++--------------------------------- include/asm-ppc64/iSeries/ItLpQueue.h | 2 +- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/arch/ppc64/kernel/ItLpQueue.c b/arch/ppc64/kernel/ItLpQueue.c index a4f32cb..4231861 100644 --- a/arch/ppc64/kernel/ItLpQueue.c +++ b/arch/ppc64/kernel/ItLpQueue.c @@ -42,35 +42,8 @@ static char *event_types[HvLpEvent_Type_NumTypes] = { "Virtual I/O" }; -static __inline__ int set_inUse(void) -{ - int t; - u32 * inUseP = &hvlpevent_queue.xInUseWord; - - __asm__ __volatile__("\n\ -1: lwarx %0,0,%2 \n\ - cmpwi 0,%0,0 \n\ - li %0,0 \n\ - bne- 2f \n\ - addi %0,%0,1 \n\ - stwcx. %0,0,%2 \n\ - bne- 1b \n\ -2: eieio" - : "=&r" (t), "=m" (hvlpevent_queue.xInUseWord) - : "r" (inUseP), "m" (hvlpevent_queue.xInUseWord) - : "cc"); - - return t; -} - -static __inline__ void clear_inUse(void) -{ - hvlpevent_queue.xInUseWord = 0; -} - /* Array of LpEvent handler functions */ extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; -unsigned long ItLpQueueInProcess = 0; static struct HvLpEvent * get_next_hvlpevent(void) { @@ -144,14 +117,9 @@ void process_hvlpevents(struct pt_regs *regs) struct HvLpEvent * event; /* If we have recursed, just return */ - if ( !set_inUse() ) + if (!spin_trylock(&hvlpevent_queue.lock)) return; - if (ItLpQueueInProcess == 0) - ItLpQueueInProcess = 1; - else - BUG(); - for (;;) { event = get_next_hvlpevent(); if (event) { @@ -187,9 +155,7 @@ void process_hvlpevents(struct pt_regs *regs) break; } - ItLpQueueInProcess = 0; - mb(); - clear_inUse(); + spin_unlock(&hvlpevent_queue.lock); } static int set_spread_lpevents(char *str) diff --git a/include/asm-ppc64/iSeries/ItLpQueue.h b/include/asm-ppc64/iSeries/ItLpQueue.h index 51db088..69b26ad 100644 --- a/include/asm-ppc64/iSeries/ItLpQueue.h +++ b/include/asm-ppc64/iSeries/ItLpQueue.h @@ -69,7 +69,7 @@ struct hvlpevent_queue { char *xSlicEventStackPtr; // 0x20 u8 xIndex; // 0x28 unique sequential index. u8 xSlicRsvd[3]; // 0x29-2b - u32 xInUseWord; // 0x2C + spinlock_t lock; }; extern struct hvlpevent_queue hvlpevent_queue; -- cgit v1.1 From 0edb586049e57c56e625536476931117a57671e9 Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 22 Jun 2005 16:59:51 +0200 Subject: [PATCH] driver core: add bus_find_device & driver_find_device functions Add bus_find_device() and driver_find_device() which allow searching for a device in the bus's resp. the driver's klist and obtain a reference on it. Signed-off-by: Cornelia Huck Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 34 ++++++++++++++++++++++++++++++++++ drivers/base/driver.c | 35 +++++++++++++++++++++++++++++++++++ include/linux/device.h | 5 +++++ 3 files changed, 74 insertions(+) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index c3fac7f..2c64b79 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -177,6 +177,39 @@ int bus_for_each_dev(struct bus_type * bus, struct device * start, return error; } +/** + * bus_find_device - device iterator for locating a particular device. + * @bus: bus type + * @start: Device to begin with + * @data: Data to pass to match function + * @match: Callback function to check device + * + * This is similar to the bus_for_each_dev() function above, but it + * returns a reference to a device that is 'found' for later use, as + * determined by the @match callback. + * + * The callback should return 0 if the device doesn't match and non-zero + * if it does. If the callback returns non-zero, this function will + * return to the caller and not iterate over any more devices. + */ +struct device * bus_find_device(struct bus_type *bus, + struct device *start, void *data, + int (*match)(struct device *, void *)) +{ + struct klist_iter i; + struct device *dev; + + if (!bus) + return NULL; + + klist_iter_init_node(&bus->klist_devices, &i, + (start ? &start->knode_bus : NULL)); + while ((dev = next_device(&i))) + if (match(dev, data) && get_device(dev)) + break; + klist_iter_exit(&i); + return dev; +} static struct device_driver * next_driver(struct klist_iter * i) @@ -557,6 +590,7 @@ int __init buses_init(void) EXPORT_SYMBOL_GPL(bus_for_each_dev); +EXPORT_SYMBOL_GPL(bus_find_device); EXPORT_SYMBOL_GPL(bus_for_each_drv); EXPORT_SYMBOL_GPL(bus_add_device); diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 1b64588..291c595 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -56,6 +56,41 @@ EXPORT_SYMBOL_GPL(driver_for_each_device); /** + * driver_find_device - device iterator for locating a particular device. + * @driver: The device's driver + * @start: Device to begin with + * @data: Data to pass to match function + * @match: Callback function to check device + * + * This is similar to the driver_for_each_device() function above, but + * it returns a reference to a device that is 'found' for later use, as + * determined by the @match callback. + * + * The callback should return 0 if the device doesn't match and non-zero + * if it does. If the callback returns non-zero, this function will + * return to the caller and not iterate over any more devices. + */ +struct device * driver_find_device(struct device_driver *drv, + struct device * start, void * data, + int (*match)(struct device *, void *)) +{ + struct klist_iter i; + struct device *dev; + + if (!drv) + return NULL; + + klist_iter_init_node(&drv->klist_devices, &i, + (start ? &start->knode_driver : NULL)); + while ((dev = next_device(&i))) + if (match(dev, data) && get_device(dev)) + break; + klist_iter_exit(&i); + return dev; +} +EXPORT_SYMBOL_GPL(driver_find_device); + +/** * driver_create_file - create sysfs file for driver. * @drv: driver. * @attr: driver attribute descriptor. diff --git a/include/linux/device.h b/include/linux/device.h index 7b781a7..07222c5 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -80,6 +80,8 @@ extern struct bus_type * find_bus(char * name); int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, int (*fn)(struct device *, void *)); +struct device * bus_find_device(struct bus_type *bus, struct device *start, + void *data, int (*match)(struct device *, void *)); int bus_for_each_drv(struct bus_type * bus, struct device_driver * start, void * data, int (*fn)(struct device_driver *, void *)); @@ -142,6 +144,9 @@ extern void driver_remove_file(struct device_driver *, struct driver_attribute * extern int driver_for_each_device(struct device_driver * drv, struct device * start, void * data, int (*fn)(struct device *, void *)); +struct device * driver_find_device(struct device_driver *drv, + struct device *start, void *data, + int (*match)(struct device *, void *)); /* -- cgit v1.1 From 151ef38f7c0ec1b0420f04438b0316e3a30bf2e4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 22 Jun 2005 16:09:05 -0700 Subject: [PATCH] driver core: Add the ability to unbind drivers to devices from userspace This adds a single file, "unbind", to the sysfs directory of every device that is currently bound to a driver. To unbind the driver from the device, write anything to this file and they will be disconnected from each other. Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 2c64b79..fa41ee9 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -133,6 +133,34 @@ static struct kobj_type ktype_bus = { decl_subsys(bus, &ktype_bus, NULL); +/* Manually detach a device from it's associated driver. */ +static int driver_helper(struct device *dev, void *data) +{ + const char *name = data; + + if (strcmp(name, dev->bus_id) == 0) + return 1; + return 0; +} + +static ssize_t driver_unbind(struct device_driver *drv, + const char *buf, size_t count) +{ + struct bus_type *bus = get_bus(drv->bus); + struct device *dev; + int err = -ENODEV; + + dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); + if ((dev) && + (dev->driver == drv)) { + device_release_driver(dev); + err = count; + } + return err; +} +static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); + + static struct device * next_device(struct klist_iter * i) { struct klist_node * n = klist_next(i); @@ -396,6 +424,7 @@ int bus_add_driver(struct device_driver * drv) module_add_driver(drv->owner, drv); driver_add_attrs(bus, drv); + driver_create_file(drv, &driver_attr_unbind); } return error; } @@ -413,6 +442,7 @@ int bus_add_driver(struct device_driver * drv) void bus_remove_driver(struct device_driver * drv) { if (drv->bus) { + driver_remove_file(drv, &driver_attr_unbind); driver_remove_attrs(drv->bus, drv); klist_remove(&drv->knode_bus); pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name); -- cgit v1.1 From afdce75f1eaebcf358b7594ba7969aade105c3b0 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 22 Jun 2005 16:09:05 -0700 Subject: [PATCH] driver core: Add the ability to bind drivers to devices from userspace This adds a single file, "bind", to the sysfs directory of every driver registered with the driver core. To bind a device to a driver, write the bus id of the device you wish to bind to that specific driver to the "bind" file (remember to not add a trailing \n). If that bus id matches a device on that bus, and it does not currently have a driver bound to it, the probe sequence will be initiated with that driver and device. Note, this requires that the driver itself be willing and able to accept that device (usually through a device id type table). This patch does not make it possible to override the driver's id table. Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 1 + drivers/base/bus.c | 26 ++++++++++++++++++++++++++ drivers/base/dd.c | 2 +- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 645f6269..783752b 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -5,6 +5,7 @@ extern int bus_add_driver(struct device_driver *); extern void bus_remove_driver(struct device_driver *); extern void driver_detach(struct device_driver * drv); +extern int driver_probe_device(struct device_driver *, struct device *); static inline struct class_device *to_class_dev(struct kobject *obj) { diff --git a/drivers/base/bus.c b/drivers/base/bus.c index fa41ee9..7e17488 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -160,6 +160,30 @@ static ssize_t driver_unbind(struct device_driver *drv, } static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); +/* + * Manually attach a device to a driver. + * Note: the driver must want to bind to the device, + * it is not possible to override the driver's id table. + */ +static ssize_t driver_bind(struct device_driver *drv, + const char *buf, size_t count) +{ + struct bus_type *bus = get_bus(drv->bus); + struct device *dev; + int err = -ENODEV; + + dev = bus_find_device(bus, NULL, (void *)buf, driver_helper); + if ((dev) && + (dev->driver == NULL)) { + down(&dev->sem); + err = driver_probe_device(drv, dev); + up(&dev->sem); + put_device(dev); + } + return err; +} +static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); + static struct device * next_device(struct klist_iter * i) { @@ -425,6 +449,7 @@ int bus_add_driver(struct device_driver * drv) driver_add_attrs(bus, drv); driver_create_file(drv, &driver_attr_unbind); + driver_create_file(drv, &driver_attr_bind); } return error; } @@ -442,6 +467,7 @@ int bus_add_driver(struct device_driver * drv) void bus_remove_driver(struct device_driver * drv) { if (drv->bus) { + driver_remove_file(drv, &driver_attr_bind); driver_remove_file(drv, &driver_attr_unbind); driver_remove_attrs(drv->bus, drv); klist_remove(&drv->knode_bus); diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 6db3a78..16323f9 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -65,7 +65,7 @@ void device_bind_driver(struct device * dev) * * This function must be called with @dev->sem held. */ -static int driver_probe_device(struct device_driver * drv, struct device * dev) +int driver_probe_device(struct device_driver * drv, struct device * dev) { int ret = 0; -- cgit v1.1 From 23d3d602cb96addd3c1158424fb01a49ea5e81b1 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 22 Jun 2005 16:09:05 -0700 Subject: [PATCH] driver core: change bus_rescan_devices to return void No one was looking at the return value of bus_rescan_devices, and it really wasn't anything that anyone in the kernel would ever care about. So change it which enabled some counting code to be removed also. Signed-off-by: Greg Kroah-Hartman --- drivers/base/bus.c | 27 +++++++++------------------ include/linux/device.h | 2 +- 2 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 7e17488..96fe2f9 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -483,31 +483,22 @@ void bus_remove_driver(struct device_driver * drv) /* Helper for bus_rescan_devices's iter */ static int bus_rescan_devices_helper(struct device *dev, void *data) { - int *count = data; - - if (!dev->driver && (device_attach(dev) > 0)) - (*count)++; - + if (!dev->driver) + device_attach(dev); return 0; } - /** - * bus_rescan_devices - rescan devices on the bus for possible drivers - * @bus: the bus to scan. + * bus_rescan_devices - rescan devices on the bus for possible drivers + * @bus: the bus to scan. * - * This function will look for devices on the bus with no driver - * attached and rescan it against existing drivers to see if it - * matches any. Calls device_attach(). Returns the number of devices - * that were sucessfully bound to a driver. + * This function will look for devices on the bus with no driver + * attached and rescan it against existing drivers to see if it matches + * any by calling device_attach() for the unbound devices. */ -int bus_rescan_devices(struct bus_type * bus) +void bus_rescan_devices(struct bus_type * bus) { - int count = 0; - - bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper); - - return count; + bus_for_each_dev(bus, NULL, NULL, bus_rescan_devices_helper); } diff --git a/include/linux/device.h b/include/linux/device.h index 07222c5..f378c84 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -69,7 +69,7 @@ struct bus_type { extern int bus_register(struct bus_type * bus); extern void bus_unregister(struct bus_type * bus); -extern int bus_rescan_devices(struct bus_type * bus); +extern void bus_rescan_devices(struct bus_type * bus); extern struct bus_type * get_bus(struct bus_type * bus); extern void put_bus(struct bus_type * bus); -- cgit v1.1 From d62c0f9fd2d3943a3eca85b490d86e1605000ccb Mon Sep 17 00:00:00 2001 From: Patrick Mochel Date: Fri, 24 Jun 2005 08:39:33 -0700 Subject: [PATCH] Driver core: Use klist_del() instead of klist_remove(). Use klist_del() instead of klist_remove() when unregistering devices. This will prevent a deadlock when executing a recursive unregister using device_for_each_child(). Signed-off-by Patrick Mochel Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 86d7975..efe03a0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -333,7 +333,7 @@ void device_del(struct device * dev) struct device * parent = dev->parent; if (parent) - klist_remove(&dev->knode_parent); + klist_del(&dev->knode_parent); /* Notify the platform of the removal, in case they * need to do anything... -- cgit v1.1 From cfb0810eab39d1162f45b73fc96f45ab1cbcbe8b Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Jun 2005 11:06:49 +0100 Subject: [PATCH] ARM: Don't try to send a signal to pid0 If we receive an unrecognised abort during boot, don't try to send a signal to pid0, but instead report the current state. This leads to less confusing debug reports. Signed-off-by: Russell King --- arch/arm/kernel/traps.c | 12 ++------ arch/arm/mm/fault.c | 75 ++++++++++++++++++++++++++---------------------- include/asm-arm/system.h | 4 ++- 3 files changed, 45 insertions(+), 46 deletions(-) diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2fb0a4c..df2cb06 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -230,16 +230,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) do_exit(SIGSEGV); } -void die_if_kernel(const char *str, struct pt_regs *regs, int err) -{ - if (user_mode(regs)) - return; - - die(str, regs, err); -} - -static void notify_die(const char *str, struct pt_regs *regs, siginfo_t *info, - unsigned long err, unsigned long trap) +void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap) { if (user_mode(regs)) { current->thread.error_code = err; diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index e25b4fd..65bfe84 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -372,49 +372,50 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs) static struct fsr_info { int (*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs); int sig; + int code; const char *name; } fsr_info[] = { /* * The following are the standard ARMv3 and ARMv4 aborts. ARMv5 * defines these to be "precise" aborts. */ - { do_bad, SIGSEGV, "vector exception" }, - { do_bad, SIGILL, "alignment exception" }, - { do_bad, SIGKILL, "terminal exception" }, - { do_bad, SIGILL, "alignment exception" }, - { do_bad, SIGBUS, "external abort on linefetch" }, - { do_translation_fault, SIGSEGV, "section translation fault" }, - { do_bad, SIGBUS, "external abort on linefetch" }, - { do_page_fault, SIGSEGV, "page translation fault" }, - { do_bad, SIGBUS, "external abort on non-linefetch" }, - { do_bad, SIGSEGV, "section domain fault" }, - { do_bad, SIGBUS, "external abort on non-linefetch" }, - { do_bad, SIGSEGV, "page domain fault" }, - { do_bad, SIGBUS, "external abort on translation" }, - { do_sect_fault, SIGSEGV, "section permission fault" }, - { do_bad, SIGBUS, "external abort on translation" }, - { do_page_fault, SIGSEGV, "page permission fault" }, + { do_bad, SIGSEGV, 0, "vector exception" }, + { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, + { do_bad, SIGKILL, 0, "terminal exception" }, + { do_bad, SIGILL, BUS_ADRALN, "alignment exception" }, + { do_bad, SIGBUS, 0, "external abort on linefetch" }, + { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" }, + { do_bad, SIGBUS, 0, "external abort on linefetch" }, + { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" }, + { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" }, + { do_bad, SIGBUS, 0, "external abort on non-linefetch" }, + { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" }, + { do_bad, SIGBUS, 0, "external abort on translation" }, + { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" }, + { do_bad, SIGBUS, 0, "external abort on translation" }, + { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" }, /* * The following are "imprecise" aborts, which are signalled by bit * 10 of the FSR, and may not be recoverable. These are only * supported if the CPU abort handler supports bit 10. */ - { do_bad, SIGBUS, "unknown 16" }, - { do_bad, SIGBUS, "unknown 17" }, - { do_bad, SIGBUS, "unknown 18" }, - { do_bad, SIGBUS, "unknown 19" }, - { do_bad, SIGBUS, "lock abort" }, /* xscale */ - { do_bad, SIGBUS, "unknown 21" }, - { do_bad, SIGBUS, "imprecise external abort" }, /* xscale */ - { do_bad, SIGBUS, "unknown 23" }, - { do_bad, SIGBUS, "dcache parity error" }, /* xscale */ - { do_bad, SIGBUS, "unknown 25" }, - { do_bad, SIGBUS, "unknown 26" }, - { do_bad, SIGBUS, "unknown 27" }, - { do_bad, SIGBUS, "unknown 28" }, - { do_bad, SIGBUS, "unknown 29" }, - { do_bad, SIGBUS, "unknown 30" }, - { do_bad, SIGBUS, "unknown 31" } + { do_bad, SIGBUS, 0, "unknown 16" }, + { do_bad, SIGBUS, 0, "unknown 17" }, + { do_bad, SIGBUS, 0, "unknown 18" }, + { do_bad, SIGBUS, 0, "unknown 19" }, + { do_bad, SIGBUS, 0, "lock abort" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 21" }, + { do_bad, SIGBUS, BUS_OBJERR, "imprecise external abort" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 23" }, + { do_bad, SIGBUS, 0, "dcache parity error" }, /* xscale */ + { do_bad, SIGBUS, 0, "unknown 25" }, + { do_bad, SIGBUS, 0, "unknown 26" }, + { do_bad, SIGBUS, 0, "unknown 27" }, + { do_bad, SIGBUS, 0, "unknown 28" }, + { do_bad, SIGBUS, 0, "unknown 29" }, + { do_bad, SIGBUS, 0, "unknown 30" }, + { do_bad, SIGBUS, 0, "unknown 31" } }; void __init @@ -435,15 +436,19 @@ asmlinkage void do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs) { const struct fsr_info *inf = fsr_info + (fsr & 15) + ((fsr & (1 << 10)) >> 6); + struct siginfo info; if (!inf->fn(addr, fsr, regs)) return; printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n", inf->name, fsr, addr); - force_sig(inf->sig, current); - show_pte(current->mm, addr); - die_if_kernel("Oops", regs, 0); + + info.si_signo = inf->sig; + info.si_errno = 0; + info.si_code = inf->code; + info.si_addr = (void __user *)addr; + notify_die("", regs, &info, fsr, 0); } asmlinkage void diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h index cdf49f4..2f44b20 100644 --- a/include/asm-arm/system.h +++ b/include/asm-arm/system.h @@ -85,7 +85,9 @@ struct pt_regs; void die(const char *msg, struct pt_regs *regs, int err) __attribute__((noreturn)); -void die_if_kernel(const char *str, struct pt_regs *regs, int err); +struct siginfo; +void notify_die(const char *str, struct pt_regs *regs, struct siginfo *info, + unsigned long err, unsigned long trap); void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int, struct pt_regs *), -- cgit v1.1 From 41359dca9442b0c664336e3fcf3aaf70b6507b1d Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Jun 2005 16:30:07 +0100 Subject: [PATCH] ARM: Acornfb: Don't claim IRQ fbcon for cursor The generic fbcon code tries to register and use the vsync IRQ for ARM platforms with acornfb, but forgets to disable its own cursor timer. The result is a flickering flashing cursor. Remove the code from the fbcon core to register this platform private interrupt. Signed-off-by: Russell King --- drivers/video/console/fbcon.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index b209adb..9dd0fbc 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c @@ -142,7 +142,6 @@ static int fbcon_set_origin(struct vc_data *); #define CURSOR_DRAW_DELAY (1) /* # VBL ints between cursor state changes */ -#define ARM_CURSOR_BLINK_RATE (10) #define ATARI_CURSOR_BLINK_RATE (42) #define MAC_CURSOR_BLINK_RATE (32) #define DEFAULT_CURSOR_BLINK_RATE (20) @@ -288,7 +287,7 @@ static void fb_flashcursor(void *private) release_console_sem(); } -#if (defined(__arm__) && defined(IRQ_VSYNCPULSE)) || defined(CONFIG_ATARI) || defined(CONFIG_MAC) +#if defined(CONFIG_ATARI) || defined(CONFIG_MAC) static int cursor_blink_rate; static irqreturn_t fb_vbl_handler(int irq, void *dev_id, struct pt_regs *fp) { @@ -878,11 +877,6 @@ static const char *fbcon_startup(void) } #endif /* CONFIG_MAC */ -#if defined(__arm__) && defined(IRQ_VSYNCPULSE) - cursor_blink_rate = ARM_CURSOR_BLINK_RATE; - irqres = request_irq(IRQ_VSYNCPULSE, fb_vbl_handler, SA_SHIRQ, - "framebuffer vbl", info); -#endif /* Initialize the work queue. If the driver provides its * own work queue this means it will use something besides * default timer to flash the cursor. */ -- cgit v1.1 From 3704511b2ee8b01475ca7c171d62c682342fa38e Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 30 Jun 2005 02:58:47 -0700 Subject: [PATCH] pcmcia: fix modalias attribute in sysfs Fix up PCMCIA modalias file in sysfs Signed-off-by: Dominik Brodowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/pcmcia/ds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index cabddd4..d5afd55 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -847,7 +847,7 @@ pcmcia_device_stringattr(prod_id2, prod_id[1]); pcmcia_device_stringattr(prod_id3, prod_id[2]); pcmcia_device_stringattr(prod_id4, prod_id[3]); -static ssize_t modalias_show(struct device *dev, char *buf) +static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, char *buf) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); int i; -- cgit v1.1 From eb05bfe4fbf031f95e392204efaa4da71c75b2e2 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Thu, 30 Jun 2005 02:58:47 -0700 Subject: [PATCH] pcmcia: update Documentation As the information is now exported via sysfs, there's no need for an userspace tool any longer. Signed-off-by: Dominik Brodowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/Changes | 2 +- Documentation/pcmcia/devicetable.txt | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Documentation/Changes b/Documentation/Changes index afebdbc..dfec756 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -57,7 +57,7 @@ o e2fsprogs 1.29 # tune2fs o jfsutils 1.1.3 # fsck.jfs -V o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs o xfsprogs 2.6.0 # xfs_db -V -o pcmciautils 001 +o pcmciautils 004 o pcmcia-cs 3.1.21 # cardmgr -V o quota-tools 3.09 # quota -V o PPP 2.4.0 # pppd --version diff --git a/Documentation/pcmcia/devicetable.txt b/Documentation/pcmcia/devicetable.txt index 045511a..3351c035 100644 --- a/Documentation/pcmcia/devicetable.txt +++ b/Documentation/pcmcia/devicetable.txt @@ -19,9 +19,8 @@ PCMCIA_DEVICE_PROD_ID1("some_string", 0x(hash_of_some_string)), If the hash is incorrect, the kernel will inform you about this in "dmesg" upon module initialization, and tell you of the correct hash. -You can determine the hash of the product ID strings by running -"pcmcia-modalias %n.%m" [%n being replaced with the socket number and %m being -replaced with the device function] from pcmciautils. It generates a string +You can determine the hash of the product ID strings by catting the file +"modalias" in the sysfs directory of the PCMCIA device. It generates a string in the following form: pcmcia:m0149cC1ABf06pfn00fn00pa725B842DpbF1EFEE84pc0877B627pd00000000 -- cgit v1.1 From 5ee24d9594ffb070261b70461f71c42913c663bb Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Thu, 30 Jun 2005 02:58:48 -0700 Subject: [PATCH] s390: fix finish_arch_switch Commit 4866cde064afbb6c2a488c265e696879de616daa requires finish_arch_switch to have only one parameter instead of two. Also fix another compile error (double declaration of account_system_vtime) if CONFIG_VIRT_CPU_ACCOUNTING is not defined. Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-s390/system.h | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h index b4a9f05..864cae7 100644 --- a/include/asm-s390/system.h +++ b/include/asm-s390/system.h @@ -107,11 +107,9 @@ static inline void restore_access_regs(unsigned int *acrs) #ifdef CONFIG_VIRT_CPU_ACCOUNTING extern void account_user_vtime(struct task_struct *); extern void account_system_vtime(struct task_struct *); -#else -#define account_system_vtime(prev) do { } while (0) #endif -#define finish_arch_switch(rq, prev) do { \ +#define finish_arch_switch(prev) do { \ set_fs(current->thread.mm_segment); \ account_system_vtime(prev); \ } while (0) -- cgit v1.1 From ee93b43a05506667d771c4fb0c384301edd7d036 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Thu, 30 Jun 2005 02:58:49 -0700 Subject: [PATCH] ppc32: use correct register names in arch/ppc/kernel/relocate_kernel.S CONFIG_KEXEC=y doesnt work: arch/ppc/kernel/relocate_kernel.S:37: Error: unsupported relocation against SRR1 arch/ppc/kernel/relocate_kernel.S:39: Error: unsupported relocation against SRR0 Signed-off-by: Olaf Hering Cc: "Eric W. Biederman" Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/relocate_kernel.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/ppc/kernel/relocate_kernel.S b/arch/ppc/kernel/relocate_kernel.S index 7ff69c4..9b2ad48 100644 --- a/arch/ppc/kernel/relocate_kernel.S +++ b/arch/ppc/kernel/relocate_kernel.S @@ -34,9 +34,9 @@ relocate_new_kernel: mr r8, r0 ori r8, r8, MSR_RI|MSR_ME - mtspr SRR1, r8 + mtspr SPRN_SRR1, r8 addi r8, r4, 1f - relocate_new_kernel - mtspr SRR0, r8 + mtspr SPRN_SRR0, r8 sync rfi -- cgit v1.1 From 9a936eb928c1a253c2e5d66b947688bdc55094a6 Mon Sep 17 00:00:00 2001 From: Kylene Jo Hall Date: Thu, 30 Jun 2005 02:58:50 -0700 Subject: [PATCH] tpm: fix bug introduced by the /proc/misc In fixing the /proc/misc problem that was reported last week where the tpm module name was being obfuscated in /proc/misc I introduced a bug in the module unloading code. This patch fixes the problem. Signed-off-by: Kylene Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/tpm/tpm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 854475c..049d128 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -464,7 +464,7 @@ void __devexit tpm_remove(struct pci_dev *pci_dev) pci_set_drvdata(pci_dev, NULL); misc_deregister(&chip->vendor->miscdev); - kfree(&chip->vendor->miscdev.name); + kfree(chip->vendor->miscdev.name); sysfs_remove_group(&pci_dev->dev.kobj, chip->vendor->attr_group); -- cgit v1.1 From 6931dfc9f3f81d148b7ed0ab3fd796f8b986a995 Mon Sep 17 00:00:00 2001 From: Eric Paris Date: Thu, 30 Jun 2005 02:58:51 -0700 Subject: [PATCH] selinux_sb_copy_data() should not require a whole page Currently selinux_sb_copy_data requires an entire page be allocated to *orig when the function is called. This "requirement" is based on the fact that we call copy_page(in_save, nosec_save) and in_save = orig when the data is not FS_BINARY_MOUNTDATA. This means that if a caller were to call do_kern_mount with only about 10 bytes of options, they would get passed here and then we would corrupt PAGE_SIZE - 10 bytes of memory (with all zeros.) Currently it appears all in kernel FS's use one page of data so this has not been a problem. An out of kernel FS did just what is described above and it would almost always panic shortly after they tried to mount. From looking else where in the kernel it is obvious that this string of data must always be null terminated. (See example in do_mount where it always zeros the last byte.) Thus I suggest we use strcpy in place of copy_page. In this way we make sure the amount we copy is always less than or equal to the amount we received and since do_mount is zeroing the last byte this should be safe for all. Signed-off-by: Eric Paris Cc: Stephen Smalley Acked-by: James Morris Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- security/selinux/hooks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 17a1189..6be2738 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -68,6 +68,7 @@ #include #include #include +#include #include "avc.h" #include "objsec.h" @@ -1943,7 +1944,7 @@ static int selinux_sb_copy_data(struct file_system_type *type, void *orig, void } } while (*in_end++); - copy_page(in_save, nosec_save); + strcpy(in_save, nosec_save); free_page((unsigned long)nosec_save); out: return rc; -- cgit v1.1 From bcbda35ca7470bf0123a7ae685899776f67814b2 Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Thu, 30 Jun 2005 02:58:55 -0700 Subject: [PATCH] ppc32: Fix pointer check for MPC8540 ADS device Editor snafu in which the call to ppc_sys_get_pdata got inside the if check instead of before it. Oops. Signed-off-by: Kumar Gala Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/platforms/85xx/mpc8540_ads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c index ddd2e9a..f761fdf 100644 --- a/arch/ppc/platforms/85xx/mpc8540_ads.c +++ b/arch/ppc/platforms/85xx/mpc8540_ads.c @@ -111,8 +111,8 @@ mpc8540ads_setup_arch(void) memcpy(pdata->mac_addr, binfo->bi_enet1addr, 6); } + pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); if (pdata) { - pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_FEC); pdata->board_flags = 0; pdata->interruptPHY = MPC85xx_IRQ_EXT5; pdata->phyid = 3; -- cgit v1.1 From 306e440daf5f40b195afd83d05dee89fa63189e7 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 30 Jun 2005 02:58:55 -0700 Subject: [PATCH] x86: i8253/i8259A lock cleanup Introduce proper declarations for i8253_lock and i8259A_lock. Signed-off-by: Ingo Molnar Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/apic.c | 2 +- arch/i386/kernel/apm.c | 5 ++--- arch/i386/kernel/io_apic.c | 2 +- arch/i386/kernel/time.c | 5 ++++- arch/i386/kernel/timers/timer_cyclone.c | 4 ++-- arch/i386/kernel/timers/timer_pit.c | 4 +--- arch/i386/kernel/timers/timer_tsc.c | 3 +-- arch/i386/mach-voyager/voyager_basic.c | 2 +- arch/x86_64/kernel/io_apic.c | 1 - drivers/ide/legacy/hd.c | 4 +++- drivers/input/gameport/gameport.c | 3 ++- drivers/input/joystick/analog.c | 4 +++- include/asm-i386/i8253.h | 6 ++++++ include/asm-i386/mach-default/do_timer.h | 1 + include/asm-x86_64/io_apic.h | 2 ++ 15 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 include/asm-i386/i8253.h diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index 93df90b..bd1dbf3 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -879,7 +880,6 @@ fake_ioapic_page: */ static unsigned int __devinit get_8254_timer_count(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index d48ce92..064211d 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c @@ -228,10 +228,10 @@ #include #include #include +#include #include "io_ports.h" -extern spinlock_t i8253_lock; extern unsigned long get_cmos_time(void); extern void machine_real_restart(unsigned char *, int); @@ -1168,8 +1168,7 @@ static void get_time_diff(void) static void reinit_timer(void) { #ifdef INIT_TIMER_AFTER_SUSPEND - unsigned long flags; - extern spinlock_t i8253_lock; + unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); /* set the clock to 100 Hz */ diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index 35eb8e2..6578f40 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -1566,7 +1567,6 @@ void print_all_local_APICs (void) void /*__init*/ print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c index e68d9fd..2854c35 100644 --- a/arch/i386/kernel/time.c +++ b/arch/i386/kernel/time.c @@ -68,7 +68,8 @@ #include "io_ports.h" -extern spinlock_t i8259A_lock; +#include + int pit_latch_buggy; /* extern */ #include "do_timer.h" @@ -85,6 +86,8 @@ extern unsigned long wall_jiffies; DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); +#include + DEFINE_SPINLOCK(i8253_lock); EXPORT_SYMBOL(i8253_lock); diff --git a/arch/i386/kernel/timers/timer_cyclone.c b/arch/i386/kernel/timers/timer_cyclone.c index f6f1206..13892a6 100644 --- a/arch/i386/kernel/timers/timer_cyclone.c +++ b/arch/i386/kernel/timers/timer_cyclone.c @@ -17,9 +17,9 @@ #include #include #include -#include "io_ports.h" +#include -extern spinlock_t i8253_lock; +#include "io_ports.h" /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; diff --git a/arch/i386/kernel/timers/timer_pit.c b/arch/i386/kernel/timers/timer_pit.c index 967d545..06de036a 100644 --- a/arch/i386/kernel/timers/timer_pit.c +++ b/arch/i386/kernel/timers/timer_pit.c @@ -15,9 +15,8 @@ #include #include #include +#include -extern spinlock_t i8259A_lock; -extern spinlock_t i8253_lock; #include "do_timer.h" #include "io_ports.h" @@ -166,7 +165,6 @@ struct init_timer_opts __initdata timer_pit_init = { void setup_pit_timer(void) { - extern spinlock_t i8253_lock; unsigned long flags; spin_lock_irqsave(&i8253_lock, flags); diff --git a/arch/i386/kernel/timers/timer_tsc.c b/arch/i386/kernel/timers/timer_tsc.c index f46e625..8f4e4d5 100644 --- a/arch/i386/kernel/timers/timer_tsc.c +++ b/arch/i386/kernel/timers/timer_tsc.c @@ -24,6 +24,7 @@ #include "mach_timer.h" #include +#include #ifdef CONFIG_HPET_TIMER static unsigned long hpet_usec_quotient; @@ -35,8 +36,6 @@ static inline void cpufreq_delayed_get(void); int tsc_disable __devinitdata = 0; -extern spinlock_t i8253_lock; - static int use_tsc; /* Number of usecs that the last interrupt was delayed */ static int delay_at_last_interrupt; diff --git a/arch/i386/mach-voyager/voyager_basic.c b/arch/i386/mach-voyager/voyager_basic.c index 602aea2..3e439ce 100644 --- a/arch/i386/mach-voyager/voyager_basic.c +++ b/arch/i386/mach-voyager/voyager_basic.c @@ -30,6 +30,7 @@ #include #include #include +#include /* * Power off function, if any @@ -182,7 +183,6 @@ voyager_timer_interrupt(struct pt_regs *regs) * and swiftly introduce it to something sharp and * pointy. */ __u16 val; - extern spinlock_t i8253_lock; spin_lock(&i8253_lock); diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 157190d..d206d7e 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1064,7 +1064,6 @@ void print_all_local_APICs (void) void __apicdebuginit print_PIC(void) { - extern spinlock_t i8259A_lock; unsigned int v; unsigned long flags; diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index e884cd4..242029c 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c @@ -156,11 +156,13 @@ else \ #if (HD_DELAY > 0) + +#include + unsigned long last_req; unsigned long read_timer(void) { - extern spinlock_t i8253_lock; unsigned long t, flags; int i; diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 3e72c9b..ab09cf40 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -60,12 +60,13 @@ static void gameport_disconnect_port(struct gameport *gameport); #if defined(__i386__) +#include + #define DELTA(x,y) ((y)-(x)+((y)<(x)?1193182/HZ:0)) #define GET_TIME(x) do { x = get_time_pit(); } while (0) static unsigned int get_time_pit(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 504b7d5..c3a5739 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -140,12 +140,14 @@ struct analog_port { */ #ifdef __i386__ + +#include + #define GET_TIME(x) do { if (cpu_has_tsc) rdtscl(x); else x = get_time_pit(); } while (0) #define DELTA(x,y) (cpu_has_tsc ? ((y) - (x)) : ((x) - (y) + ((x) < (y) ? CLOCK_TICK_RATE / HZ : 0))) #define TIME_NAME (cpu_has_tsc?"TSC":"PIT") static unsigned int get_time_pit(void) { - extern spinlock_t i8253_lock; unsigned long flags; unsigned int count; diff --git a/include/asm-i386/i8253.h b/include/asm-i386/i8253.h new file mode 100644 index 0000000..015d8df --- /dev/null +++ b/include/asm-i386/i8253.h @@ -0,0 +1,6 @@ +#ifndef __ASM_I8253_H__ +#define __ASM_I8253_H__ + +extern spinlock_t i8253_lock; + +#endif /* __ASM_I8253_H__ */ diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h index 03dd13a..5621141 100644 --- a/include/asm-i386/mach-default/do_timer.h +++ b/include/asm-i386/mach-default/do_timer.h @@ -1,6 +1,7 @@ /* defines for inline arch setup functions */ #include +#include /** * do_timer_interrupt_hook - hook into timer tick diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h index 3257374..a8babd2 100644 --- a/include/asm-x86_64/io_apic.h +++ b/include/asm-x86_64/io_apic.h @@ -217,4 +217,6 @@ extern int assign_irq_vector(int irq); void enable_NMI_through_LVT0 (void * dummy); +extern spinlock_t i8259A_lock; + #endif -- cgit v1.1 From 0ee23b50f1541aacc3b975edae170a1b995b84f5 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 30 Jun 2005 02:58:56 -0700 Subject: [PATCH] xtensa: use valid_signal() xtensa should use valid_signal() instead of testing _NSIG directly like everyone else. Signed-off-by: Jesper Juhl Cc: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/kernel/ptrace.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index 9ef07a4..2659efd 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -239,7 +240,7 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_CONT: /* restart after signal. */ { ret = -EIO; - if ((unsigned long) data > _NSIG) + if (!valid_signal(data)) break; if (request == PTRACE_SYSCALL) set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); @@ -269,7 +270,7 @@ int sys_ptrace(long request, long pid, long addr, long data) case PTRACE_SINGLESTEP: ret = -EIO; - if ((unsigned long) data > _NSIG) + if (!valid_signal(data)) break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); child->ptrace |= PT_SINGLESTEP; -- cgit v1.1 From 5b0de927d9c9a72e42a4b581a897710f9ae5a6d1 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 30 Jun 2005 02:58:57 -0700 Subject: [PATCH] xtensa: cleanups for errno and ipc. I noticed this because I was doing some more ipc cleanups and I did the original errno and ipc cleanups for other architectures, so it stuck out. Signed-off-by: Stephen Rothwell Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-xtensa/errno.h | 128 +-------------------------------------------- include/asm-xtensa/ipc.h | 20 +------ 2 files changed, 2 insertions(+), 146 deletions(-) diff --git a/include/asm-xtensa/errno.h b/include/asm-xtensa/errno.h index ced5194..a0f3b96 100644 --- a/include/asm-xtensa/errno.h +++ b/include/asm-xtensa/errno.h @@ -11,132 +11,6 @@ #ifndef _XTENSA_ERRNO_H #define _XTENSA_ERRNO_H -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ +#include #endif /* _XTENSA_ERRNO_H */ diff --git a/include/asm-xtensa/ipc.h b/include/asm-xtensa/ipc.h index d37bdb4d4c..a9eed4e 100644 --- a/include/asm-xtensa/ipc.h +++ b/include/asm-xtensa/ipc.h @@ -11,24 +11,6 @@ #ifndef _XTENSA_IPC_H #define _XTENSA_IPC_H -struct ipc_kludge { - struct msgbuf __user *msgp; - long msgtyp; -}; - -#define SEMOP 1 -#define SEMGET 2 -#define SEMCTL 3 -#define SEMTIMEDOP 4 -#define MSGSND 11 -#define MSGRCV 12 -#define MSGGET 13 -#define MSGCTL 14 -#define SHMAT 21 -#define SHMDT 22 -#define SHMGET 23 -#define SHMCTL 24 - -#define IPCCALL(version,op) ((version)<<16 | (op)) +#include #endif /* _XTENSA_IPC_H */ -- cgit v1.1 From 82300bf479d7cdf87214b81ca5dc003bbc4f7e8f Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 30 Jun 2005 02:58:58 -0700 Subject: [PATCH] xtensa: Added mm/Kconfig to get a flat memory layout Added 'mm/Kconfig' to the xtensa Kconfig file to get a flat memory layout. Fixed a typo in one of the help texts (thanks Geert for pointing it out) Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/Kconfig | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 3e89767..c9b5d29 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -132,7 +132,7 @@ config XTENSA_CPU_CLOCK config GENERIC_CALIBRATE_DELAY bool "Auto calibration of the BogoMIPS value" ---help--- - The BogoMIPS value can easily derived from the CPU frequency. + The BogoMIPS value can easily be derived from the CPU frequency. config CMDLINE_BOOL bool "Default bootloader kernel arguments" @@ -158,6 +158,8 @@ config XTENSA_ISS_NETWORK depends on XTENSA_PLATFORM_ISS default y +source "mm/Kconfig" + endmenu menu "Bus options" -- cgit v1.1 From e7d163f7666560c90b163907b9d96ec6207e0f6f Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 30 Jun 2005 02:58:59 -0700 Subject: [PATCH] xtensa: Removed local copy of zlib and fixed O= support Removed an unnecessary local copy of zlib (sorry for the add'l traffic). Fixed 'O=' support (thanks to Jan Dittmer for pointing it out). Some minor clean-ups in the make files. Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/Makefile | 48 +- arch/xtensa/boot/Makefile | 10 +- arch/xtensa/boot/boot-elf/Makefile | 4 +- arch/xtensa/boot/boot-redboot/Makefile | 10 +- arch/xtensa/boot/include/zlib.h | 433 ------- arch/xtensa/boot/lib/Makefile | 13 +- arch/xtensa/boot/lib/memcpy.S | 36 - arch/xtensa/boot/lib/zlib.c | 2150 -------------------------------- arch/xtensa/boot/lib/zmem.c | 20 +- 9 files changed, 53 insertions(+), 2671 deletions(-) delete mode 100644 arch/xtensa/boot/include/zlib.h delete mode 100644 arch/xtensa/boot/lib/memcpy.S delete mode 100644 arch/xtensa/boot/lib/zlib.c diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 4fa2745..27847e4 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -21,23 +21,17 @@ export CPU # Platform configuration -platform-y := common platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss PLATFORM = $(platform-y) export PLATFORM -#LDFLAGS_vmlinux := -T$(word 1,$(LINKSCRIPT)) -AFLAGS_vmlinux.lds.o := -Uxtensa -CPPFLAGS += -Iarch/xtensa -Iinclude/asm -mlongcalls -g -AFLAGS += -Iarch/xtensa -Iinclude/asm -CPP = $(CC) -E $(CFLAGS) +CPPFLAGS += $(if $(KBUILD_SRC),-I$(srctree)/include/asm-xtensa/) +CPPFLAGS += -Iinclude/asm +CFLAGS += -pipe -mlongcalls -cflags-y += -Iarch/xtensa -pipe -mlongcalls - - -KBUILD_DEFCONFIG := common_defconfig +KBUILD_DEFCONFIG := iss_defconfig # ramdisk/initrd support # You need a compressed ramdisk image, named ramdisk.gz in @@ -62,30 +56,36 @@ endif LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) head-y := arch/xtensa/kernel/head.o -core-y += arch/xtensa/kernel/ \ - arch/xtensa/mm/ arch/xtensa/platform-$(PLATFORM)/ +core-y += arch/xtensa/kernel/ arch/xtensa/mm/ +ifneq ($(PLATFORM),) +core-y += arch/xtensa/platform-$(PLATFORM)/ +endif libs-y += arch/xtensa/lib/ $(LIBGCC) -boot := arch/xtensa/boot +boot := arch/xtensa/boot + +archinc := include/asm-xtensa arch/xtensa/kernel/asm-offsets.s: \ - arch/xtensa/kernel/asm-offsets.c \ - include/asm-xtensa/.platform + arch/xtensa/kernel/asm-offsets.c $(archinc)/.platform include/asm-xtensa/offsets.h: arch/xtensa/kernel/asm-offsets.s $(call filechk,gen-asm-offsets) -prepare: include/asm-xtensa/.platform include/asm-xtensa/offsets.h +prepare: $(archinc)/.platform $(archinc)/offsets.h # Update machine cpu and platform symlinks if something which affects # them changed. -include/asm-xtensa/.platform: $(wildcard include/config/arch/*.h) - @echo ' Setting up cpu ($(CPU)) and platform ($(PLATFORM)) symlinks' - $(Q)rm -f include/asm-xtensa/platform - $(Q)rm -f include/asm-xtensa/xtensa/config - $(Q)(cd include/asm-xtensa/; ln -sf platform-$(PLATFORM) platform) - $(Q)(cd include/asm-xtensa/xtensa; ln -sf config-$(CPU) config) +$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER + @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' + $(Q)mkdir -p $(archinc) + $(Q)mkdir -p $(archinc)/xtensa + $(Q)ln -fsn $(srctree)/$(archinc)/xtensa/config-$(CPU) $(archinc)/xtensa/config + @echo ' SYMLINK $(archinc)/platform -> $(archinc)/platform-$(PLATFORM)' + $(Q)ln -fsn $(srctree)/$(archinc)/platform-$(PLATFORM) $(archinc)/platform + @touch $@ + all: zImage @@ -94,7 +94,9 @@ bzImage : zImage zImage zImage.initrd: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ -CLEAN_FILES += arch/xtensa/vmlinux.lds include/asm-xtensa/offset.h +CLEAN_FILES += arch/xtensa/vmlinux.lds $(archinc)/offset.h \ + $(archinc)/platform $(archinc)/xtensa/config \ + $(archinc)/.platform define archhelp @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' diff --git a/arch/xtensa/boot/Makefile b/arch/xtensa/boot/Makefile index 260f456..820b31d 100644 --- a/arch/xtensa/boot/Makefile +++ b/arch/xtensa/boot/Makefile @@ -11,21 +11,19 @@ CFLAGS += -fno-builtin -Iarch/$(ARCH)/boot/include HOSTFLAGS += -Iarch/$(ARCH)/boot/include -BIG_ENDIAN := $(shell echo -e "\#ifdef __XTENSA_EL__\nint little;\n\#else\nint big;\n\#endif" | $(CC) -E -|grep -c big) - +BIG_ENDIAN := $(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#") export CFLAGS export AFLAGS export BIG_ENDIAN +subdir-y := lib + # Subdirs for the boot loader(s) bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf -subdir-y := lib/ - -subdir-y += boot-elf/ boot-redboot/ zImage zImage.initrd Image Image.initrd: $(bootdir-y) @@ -33,5 +31,3 @@ $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ $(addprefix $(obj)/,$(host-progs)) $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) - - diff --git a/arch/xtensa/boot/boot-elf/Makefile b/arch/xtensa/boot/boot-elf/Makefile index f6ef6a3..734db7f 100644 --- a/arch/xtensa/boot/boot-elf/Makefile +++ b/arch/xtensa/boot/boot-elf/Makefile @@ -27,7 +27,7 @@ Image: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp @@ -41,7 +41,7 @@ Image.initrd: vmlinux $(OBJS) --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T arch/$(ARCH)/boot/boot-elf/boot.ld \ + -T $(srctree)/arch/$(ARCH)/boot/boot-elf/boot.ld \ -o arch/$(ARCH)/boot/$@.elf $@.tmp rm -f $@.tmp vmlinux.tmp diff --git a/arch/xtensa/boot/boot-redboot/Makefile b/arch/xtensa/boot/boot-redboot/Makefile index ca8a68b..f53262c 100644 --- a/arch/xtensa/boot/boot-redboot/Makefile +++ b/arch/xtensa/boot/boot-redboot/Makefile @@ -12,24 +12,24 @@ else OBJCOPY_ARGS := -O elf32-xtensa-le endif -LD_ARGS = -T $(obj)/boot.ld +LD_ARGS = -T $(srctree)/$(obj)/boot.ld boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) -LIBS := arch/$(ARCH)/boot/lib/lib.a arch/$(ARCH)/lib/lib.a +LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a LIBGCC := $(shell $(CC) $(CFLAGS) -print-libgcc-file-name) zImage: vmlinux $(OBJS) $(LIBS) $(OBJCOPY) --strip-all -R .comment -R .xt.insn -O binary \ - $(TOPDIR)/vmlinux vmlinux.tmp + vmlinux vmlinux.tmp gzip -vf9 vmlinux.tmp $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ --add-section image=vmlinux.tmp.gz \ --set-section-flags image=contents,alloc,load,load,data \ $(OBJS) $@.tmp $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) - $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/images/$@.redboot -# rm -f $@.tmp $@.elf vmlinux.tmp.gz + $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot + rm -f $@.tmp $@.elf vmlinux.tmp.gz diff --git a/arch/xtensa/boot/include/zlib.h b/arch/xtensa/boot/include/zlib.h deleted file mode 100644 index ea29b62..0000000 --- a/arch/xtensa/boot/include/zlib.h +++ /dev/null @@ -1,433 +0,0 @@ -/* - * BK Id: SCCS/s.zlib.h 1.8 05/18/01 15:17:23 cort - */ -/* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 960122== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. - - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ - -#ifndef _ZLIB_H -#define _ZLIB_H - -/* #include "zconf.h" */ /* included directly here */ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ - -/* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. - */ - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. - */ - -#ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC -# endif -#endif - -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -#ifndef FAR -# define FAR -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* end of original zconf.h */ - -#define ZLIB_VERSION "0.95P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ - -} z_stream; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ - -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Used to set the data_type field */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - */ - - /* basic functions */ - -extern int inflateInit OF((z_stream *strm)); -/* - Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). -*/ - - -extern int inflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ - - -extern int inflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* advanced functions */ - -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); -/* - This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1< $@ + +$(addprefix $(obj)/,$(zlib)): $(obj)/%: $(srctree)/lib/zlib_inflate/% + $(call cmd,copy_zlib) + +clean-files := $(zlib) diff --git a/arch/xtensa/boot/lib/memcpy.S b/arch/xtensa/boot/lib/memcpy.S deleted file mode 100644 index a029f5d..0000000 --- a/arch/xtensa/boot/lib/memcpy.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * arch/xtensa/lib/memcpy.S - * - * ANSI C standard library function memcpy - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of - * this archive for more details. - * - * Copyright (C) 2002 Tensilica Inc. - */ - -#define _ASMLANGUAGE -#include - -.text -.align 4 -.global bcopy -.type bcopy,@function -bcopy: - movi a14, xthal_bcopy // a14 safe to use regardless of whether caller - // used call4 or call8 (can't have used call12) - jx a14 // let the Core HAL do the work - -.text -.align 4 -.global memcpy -.type memcpy,@function -memcpy: -.global memmove -.type memmove,@function -memmove: - movi a14, xthal_memcpy // a14 safe to use regardless of whether caller - // used call4 or call8 (can't have used call12) - jx a14 // let the Core HAL do the work - diff --git a/arch/xtensa/boot/lib/zlib.c b/arch/xtensa/boot/lib/zlib.c deleted file mode 100644 index e3859f6..0000000 --- a/arch/xtensa/boot/lib/zlib.c +++ /dev/null @@ -1,2150 +0,0 @@ -/* - * BK Id: SCCS/s.zlib.c 1.8 05/18/01 15:17:24 cort - */ -/* - * This file is derived from various .h and .c files from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp - * - */ - -/*+++++*/ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ - -#define _Z_UTIL_H - -#include "zlib.h" - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#define FAR - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ - -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - /* common constants */ - -#define DEFLATED 8 - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - - /* functions */ - -#include -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include -# ifndef verbose -# define verbose 0 -# endif -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); - -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} - -/* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/*+++++*/ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, - check_func c, /* check function */ - uInt w)); /* window size */ - -local int inflate_blocks OF(( - inflate_blocks_statef *, - z_stream *, - int)); /* initial return code */ - -local void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_addhistory OF(( - inflate_blocks_statef *, - z_stream *)); - -local int inflate_packet_flush OF(( - inflate_blocks_statef *)); - -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; -#endif - -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2(z, w) -z_stream *z; -int w; -{ - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit(z) -z_stream *z; -{ - return inflateInit2(z, DEF_WBITS); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_stream *z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) - { - z->state->mode = BAD; - z->msg = "unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = "invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = "incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = "incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_stream *z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE - -/*+++++*/ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* - * The IBM 150 firmware munges the data right after _etext[]. This - * protects it. -- Cort - */ -local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); - - -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -local void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -local inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_stream *z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -local int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = "invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.trees.nblens = t; - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = BADB; - z->msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -local int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -local int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} - - -/*+++++*/ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_stream *zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } - q->word.Nalloc = z + 1; -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -local int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_lock = 0; -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer (not used) */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= fixed_left, - "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree(q, p, n) -voidpf q; -voidpf p; -uInt n; -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ -} - - -local int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - fixed_built = 1; - } - fixed_lock--; - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -local int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_stream *z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q; - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); - p = q; - } - return Z_OK; -} - -/*+++++*/ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl, *td; -z_stream *z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -local int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_stream *z; -{ - ZFREE(z, c, sizeof(struct inflate_codes_state)); - Tracev((stderr, "inflate: codes free\n")); -} - -/*+++++*/ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt n; - Bytef *p, *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - - -/*+++++*/ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -local int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl, *td; -inflate_blocks_statef *s; -z_stream *z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = "invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - - -/*+++++*/ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ - -char *zlib_version = ZLIB_VERSION; - -char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -""}; - - -/*+++++*/ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff --git a/arch/xtensa/boot/lib/zmem.c b/arch/xtensa/boot/lib/zmem.c index 7848f12..d9862aa 100644 --- a/arch/xtensa/boot/lib/zmem.c +++ b/arch/xtensa/boot/lib/zmem.c @@ -1,4 +1,4 @@ -#include "zlib.h" +#include /* bits taken from ppc */ @@ -9,11 +9,10 @@ void exit (void) for (;;); } -void *zalloc(void *x, unsigned items, unsigned size) +void *zalloc(unsigned size) { void *p = avail_ram; - size *= items; size = (size + 7) & -8; avail_ram += size; if (avail_ram > end_avail) { @@ -24,11 +23,6 @@ void *zalloc(void *x, unsigned items, unsigned size) return p; } -void zfree(void *x, void *addr, unsigned nb) -{ -} - - #define HEAD_CRC 2 #define EXTRA_FIELD 4 #define ORIG_NAME 8 @@ -43,7 +37,6 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) int r, i, flags; /* skip header */ - i = 10; flags = src[3]; if (src[2] != DEFLATED || (flags & RESERVED) != 0) { @@ -65,9 +58,8 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) exit(); } - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); + s.workspace = zalloc(zlib_inflate_workspacesize()); + r = zlib_inflateInit2(&s, -MAX_WBITS); if (r != Z_OK) { //puts("inflateInit2 returned "); puthex(r); puts("\n"); exit(); @@ -76,12 +68,12 @@ void gunzip (void *dst, int dstlen, unsigned char *src, int *lenp) s.avail_in = *lenp - i; s.next_out = dst; s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); + r = zlib_inflate(&s, Z_FINISH); if (r != Z_OK && r != Z_STREAM_END) { //puts("inflate returned "); puthex(r); puts("\n"); exit(); } *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); + zlib_inflateEnd(&s); } -- cgit v1.1 From 9ec55a9bd365dfc78945bb8e6bf5d0fdf1d75ad0 Mon Sep 17 00:00:00 2001 From: Chris Zankel Date: Thu, 30 Jun 2005 02:59:00 -0700 Subject: [PATCH] xtensa: Fix asm macro Removed dead code in arch/xtensa/kernel/pci.c and use the pci_name() macro. Fixed an error in the delay asm macro: '1' is an invalid immediate value. Signed-off-by: Chris Zankel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/xtensa/kernel/pci.c | 95 +++------------------------------------------- include/asm-xtensa/delay.h | 2 +- 2 files changed, 6 insertions(+), 91 deletions(-) diff --git a/arch/xtensa/kernel/pci.c b/arch/xtensa/kernel/pci.c index d29a816..09887c9 100644 --- a/arch/xtensa/kernel/pci.c +++ b/arch/xtensa/kernel/pci.c @@ -57,50 +57,6 @@ struct pci_controller** pci_ctrl_tail = &pci_ctrl_head; static int pci_bus_count; -static void pcibios_fixup_resources(struct pci_dev* dev); - -#if 0 // FIXME -struct pci_fixup pcibios_fixups[] = { - { DECLARE_PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, - { 0 } -}; -#endif - -void -pcibios_update_resource(struct pci_dev *dev, struct resource *root, - struct resource *res, int resource) -{ - u32 new, check, mask; - int reg; - struct pci_controller* pci_ctrl = dev->sysdata; - - new = res->start; - if (pci_ctrl && res->flags & IORESOURCE_IO) { - new -= pci_ctrl->io_space.base; - } - new |= (res->flags & PCI_REGION_FLAG_MASK); - if (resource < 6) { - reg = PCI_BASE_ADDRESS_0 + 4*resource; - } else if (resource == PCI_ROM_RESOURCE) { - res->flags |= PCI_ROM_ADDRESS_ENABLE; - reg = dev->rom_base_reg; - } else { - /* Somebody might have asked allocation of a non-standard resource */ - return; - } - - pci_write_config_dword(dev, reg, new); - pci_read_config_dword(dev, reg, &check); - mask = (new & PCI_BASE_ADDRESS_SPACE_IO) ? - PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK; - - if ((new ^ check) & mask) { - printk(KERN_ERR "PCI: Error while updating region " - "%s/%d (%08x != %08x)\n", dev->slot_name, resource, - new, check); - } -} - /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -125,7 +81,7 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size, if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", dev->slot_name, + " (%ld bytes)\n", pci_name(dev), dev->resource - res, size); } @@ -149,7 +105,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) r = &dev->resource[idx]; if (!r->start && r->end) { printk (KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); + "of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -161,7 +117,7 @@ pcibios_enable_resources(struct pci_dev *dev, int mask) cmd |= PCI_COMMAND_MEMORY; if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } return 0; @@ -293,7 +249,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) r = &dev->resource[idx]; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because " - "of resource collisions\n", dev->slot_name); + "of resource collisions\n", pci_name(dev)); return -EINVAL; } if (r->flags & IORESOURCE_IO) @@ -303,7 +259,7 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) } if (cmd != old_cmd) { printk("PCI: Enabling device %s (%04x -> %04x)\n", - dev->slot_name, old_cmd, cmd); + pci_name(dev), old_cmd, cmd); pci_write_config_word(dev, PCI_COMMAND, cmd); } @@ -325,47 +281,6 @@ pci_controller_num(struct pci_dev *dev) #endif /* CONFIG_PROC_FS */ - -static void -pcibios_fixup_resources(struct pci_dev *dev) -{ - struct pci_controller* pci_ctrl = (struct pci_controller *)dev->sysdata; - int i; - unsigned long offset; - - if (!pci_ctrl) { - printk(KERN_ERR "No pci_ctrl for PCI dev %s!\n",dev->slot_name); - return; - } - for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { - struct resource *res = dev->resource + i; - if (!res->start || !res->flags) - continue; - if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", - dev->slot_name, i, res->start, res->end); - res->end -= res->start; - res->start = 0; - continue; - } - offset = 0; - if (res->flags & IORESOURCE_IO) - offset = (unsigned long) pci_ctrl->io_space.base; - else if (res->flags & IORESOURCE_MEM) - offset = (unsigned long) pci_ctrl->mem_space.base; - - if (offset != 0) { - res->start += offset; - res->end += offset; -#ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", - i, res->flags, dev->slot_name, - res->start - offset, res->start); -#endif - } - } -} - /* * Platform support for /proc/bus/pci/X/Y mmap()s, * modelled on the sparc64 implementation by Dave Miller. diff --git a/include/asm-xtensa/delay.h b/include/asm-xtensa/delay.h index 6359c55..0a123d5 100644 --- a/include/asm-xtensa/delay.h +++ b/include/asm-xtensa/delay.h @@ -21,7 +21,7 @@ extern unsigned long loops_per_jiffy; extern __inline__ void __delay(unsigned long loops) { /* 2 cycles per loop. */ - __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 1, 1b" + __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" : "=r" (loops) : "0" (loops)); } -- cgit v1.1 From 532a39a3754a3b8ce507414863023f8db21f9a7c Mon Sep 17 00:00:00 2001 From: Pekka J Enberg Date: Thu, 30 Jun 2005 02:59:01 -0700 Subject: [PATCH] fat: fix slab cache leak This patch plugs a slab cache leak in fat module initialization. Signed-off-by: Pekka Enberg Acked-by: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fat/inode.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 8ccee84..3e31c4a 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1331,12 +1331,21 @@ void __exit fat_cache_destroy(void); static int __init init_fat_fs(void) { - int ret; + int err; - ret = fat_cache_init(); - if (ret < 0) - return ret; - return fat_init_inodecache(); + err = fat_cache_init(); + if (err) + return err; + + err = fat_init_inodecache(); + if (err) + goto failed; + + return 0; + +failed: + fat_cache_destroy(); + return err; } static void __exit exit_fat_fs(void) -- cgit v1.1 From 1c71e22e4e4b4e7261f147635518d5634136c226 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 30 Jun 2005 02:59:02 -0700 Subject: [PATCH] udf_find_entry() cleanup udf_find_entry can never be called with a NULL argument, so we shouldn't check for it. Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/udf/namei.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/fs/udf/namei.c b/fs/udf/namei.c index 4673157..ac191ed 100644 --- a/fs/udf/namei.c +++ b/fs/udf/namei.c @@ -164,11 +164,7 @@ udf_find_entry(struct inode *dir, struct dentry *dentry, uint32_t extoffset, elen, offset; struct buffer_head *bh = NULL; - if (!dir) - return NULL; - size = (udf_ext0_offset(dir) + dir->i_size) >> 2; - f_pos = (udf_ext0_offset(dir) >> 2); fibh->soffset = fibh->eoffset = (f_pos & ((dir->i_sb->s_blocksize - 1) >> 2)) << 2; -- cgit v1.1 From f220ab2a5162c35cca6993ea473937cfc962fce4 Mon Sep 17 00:00:00 2001 From: Jay Lan Date: Thu, 30 Jun 2005 02:59:03 -0700 Subject: [PATCH] Improper initrd failure message at boot time On system boot up, there was an failure reported to boot.msg: <5>Trying to move old root to /initrd ... failed According to initrd(4) man page, step #7 of BOOT-UP OPERATION is described as below: 7. If the normal root file has directory /initrd, device /dev/ram0 is moved from / to /initrd. Otherwise if directory /initrd does not exist device /dev/ram0 is unmounted. We got service calls from customers concerning about this failure message at boot time. Many systems do not have /initrd and thus the message can be changed in the case of non-existing /initrd so that it does not sound like a failure of the system. Signed-off-by: Jay Lan Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- init/do_mounts_initrd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index 4def882..a05cabd 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -86,7 +86,10 @@ static void __init handle_initrd(void) printk("okay\n"); else { int fd = sys_open("/dev/root.old", O_RDWR, 0); - printk("failed\n"); + if (error == -ENOENT) + printk("/initrd does not exist. Ignored.\n"); + else + printk("failed\n"); printk(KERN_NOTICE "Unmounting old root\n"); sys_umount("/old", MNT_DETACH); printk(KERN_NOTICE "Trying to free ramdisk memory ... "); -- cgit v1.1 From ba03bda81e160b2724451074cdcb597d14f7d7e0 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 30 Jun 2005 02:59:04 -0700 Subject: [PATCH] freevxfs: fix buffer_head leak - fix a buffer_head leak in vxfs_getfsh() - s/SLAB_KERNEL/GFP_KERNEL/ - check sb_bread() return value - drop pointless buffer-mapped() test. Signed-off-by: Pekka Enberg Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/freevxfs/vxfs_fshead.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/fs/freevxfs/vxfs_fshead.c b/fs/freevxfs/vxfs_fshead.c index 05b19f7..6dee109 100644 --- a/fs/freevxfs/vxfs_fshead.c +++ b/fs/freevxfs/vxfs_fshead.c @@ -78,17 +78,18 @@ vxfs_getfsh(struct inode *ip, int which) struct buffer_head *bp; bp = vxfs_bread(ip, which); - if (buffer_mapped(bp)) { + if (bp) { struct vxfs_fsh *fhp; - if (!(fhp = kmalloc(sizeof(*fhp), SLAB_KERNEL))) - return NULL; + if (!(fhp = kmalloc(sizeof(*fhp), GFP_KERNEL))) + goto out; memcpy(fhp, bp->b_data, sizeof(*fhp)); - brelse(bp); + put_bh(bp); return (fhp); } - +out: + brelse(bp); return NULL; } -- cgit v1.1 From 1d2cc3b87b1694df72ab75cee8e12f8b369577ce Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 30 Jun 2005 02:59:05 -0700 Subject: [PATCH] freevxfs: remove 2.4 compatability This patch removes 2.4 compatability header from freevxfs. Signed-off-by: Pekka Enberg Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/freevxfs/vxfs.h | 1 - fs/freevxfs/vxfs_kcompat.h | 49 ---------------------------------------------- fs/freevxfs/vxfs_subr.c | 1 - 3 files changed, 51 deletions(-) delete mode 100644 fs/freevxfs/vxfs_kcompat.h diff --git a/fs/freevxfs/vxfs.h b/fs/freevxfs/vxfs.h index 8da0252..583bd78 100644 --- a/fs/freevxfs/vxfs.h +++ b/fs/freevxfs/vxfs.h @@ -37,7 +37,6 @@ * superblocks of the Veritas Filesystem. */ #include -#include "vxfs_kcompat.h" /* diff --git a/fs/freevxfs/vxfs_kcompat.h b/fs/freevxfs/vxfs_kcompat.h deleted file mode 100644 index 342a4cc..0000000 --- a/fs/freevxfs/vxfs_kcompat.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _VXFS_KCOMPAT_H -#define _VXFS_KCOMPAT_H - -#include - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) - -#include - -typedef long sector_t; - -/* From include/linux/fs.h (Linux 2.5.2-pre3) */ -static inline struct buffer_head * sb_bread(struct super_block *sb, int block) -{ - return bread(sb->s_dev, block, sb->s_blocksize); -} - -/* Dito. */ -static inline void map_bh(struct buffer_head *bh, struct super_block *sb, int block) -{ - bh->b_state |= 1 << BH_Mapped; - bh->b_dev = sb->s_dev; - bh->b_blocknr = block; -} - -/* From fs/block_dev.c (Linux 2.5.2-pre2) */ -static inline int sb_set_blocksize(struct super_block *sb, int size) -{ - int bits; - if (set_blocksize(sb->s_dev, size) < 0) - return 0; - sb->s_blocksize = size; - for (bits = 9, size >>= 9; size >>= 1; bits++) - ; - sb->s_blocksize_bits = bits; - return sb->s_blocksize; -} - -/* Dito. */ -static inline int sb_min_blocksize(struct super_block *sb, int size) -{ - int minsize = get_hardsect_size(sb->s_dev); - if (size < minsize) - size = minsize; - return sb_set_blocksize(sb, size); -} - -#endif /* Kernel 2.4 */ -#endif /* _VXFS_KCOMPAT_H */ diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c index 5e30561..50aae77 100644 --- a/fs/freevxfs/vxfs_subr.c +++ b/fs/freevxfs/vxfs_subr.c @@ -36,7 +36,6 @@ #include #include -#include "vxfs_kcompat.h" #include "vxfs_extern.h" -- cgit v1.1 From 8cb681b9c7fff5cb35b5c05ba4f1b7e285e258fb Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Thu, 30 Jun 2005 02:59:05 -0700 Subject: [PATCH] freevxfs: minor cleanups This patch addresses the following minor issues: - Typo in printk - Redundant casts - Use C99 struct initializers instead of memset - Parenthesis around return value - Use inline instead of __inline__ Signed-off-by: Pekka Enberg Cc: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/freevxfs/vxfs_bmap.c | 2 +- fs/freevxfs/vxfs_lookup.c | 8 ++++---- fs/freevxfs/vxfs_olt.c | 10 +++++----- fs/freevxfs/vxfs_super.c | 7 +++---- 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/fs/freevxfs/vxfs_bmap.c b/fs/freevxfs/vxfs_bmap.c index bc4b57d..d3f6b28 100644 --- a/fs/freevxfs/vxfs_bmap.c +++ b/fs/freevxfs/vxfs_bmap.c @@ -101,7 +101,7 @@ vxfs_bmap_ext4(struct inode *ip, long bn) return 0; fail_size: - printk("vxfs: indirect extent to big!\n"); + printk("vxfs: indirect extent too big!\n"); fail_buf: return 0; } diff --git a/fs/freevxfs/vxfs_lookup.c b/fs/freevxfs/vxfs_lookup.c index 506ae25..554eb45 100644 --- a/fs/freevxfs/vxfs_lookup.c +++ b/fs/freevxfs/vxfs_lookup.c @@ -61,13 +61,13 @@ struct file_operations vxfs_dir_operations = { }; -static __inline__ u_long +static inline u_long dir_pages(struct inode *inode) { return (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; } -static __inline__ u_long +static inline u_long dir_blocks(struct inode *ip) { u_long bsize = ip->i_sb->s_blocksize; @@ -79,7 +79,7 @@ dir_blocks(struct inode *ip) * * len <= VXFS_NAMELEN and de != NULL are guaranteed by caller. */ -static __inline__ int +static inline int vxfs_match(int len, const char * const name, struct vxfs_direct *de) { if (len != de->d_namelen) @@ -89,7 +89,7 @@ vxfs_match(int len, const char * const name, struct vxfs_direct *de) return !memcmp(name, de->d_name, len); } -static __inline__ struct vxfs_direct * +static inline struct vxfs_direct * vxfs_next_entry(struct vxfs_direct *de) { return ((struct vxfs_direct *)((char*)de + de->d_reclen)); diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c index 7a204e3..1334762 100644 --- a/fs/freevxfs/vxfs_olt.c +++ b/fs/freevxfs/vxfs_olt.c @@ -38,7 +38,7 @@ #include "vxfs_olt.h" -static __inline__ void +static inline void vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) { if (infp->vsi_fshino) @@ -46,7 +46,7 @@ vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) infp->vsi_fshino = fshp->olt_fsino[0]; } -static __inline__ void +static inline void vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) { if (infp->vsi_iext) @@ -54,7 +54,7 @@ vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) infp->vsi_iext = ilistp->olt_iext[0]; } -static __inline__ u_long +static inline u_long vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize) { if (sbp->s_blocksize % bsize) @@ -104,8 +104,8 @@ vxfs_read_olt(struct super_block *sbp, u_long bsize) goto fail; } - oaddr = (char *)bp->b_data + op->olt_size; - eaddr = (char *)bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize); + oaddr = bp->b_data + op->olt_size; + eaddr = bp->b_data + (infp->vsi_oltsize * sbp->s_blocksize); while (oaddr < eaddr) { struct vxfs_oltcommon *ocp = diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index 0ae2c7b..27f66d3 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c @@ -155,12 +155,11 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) sbp->s_flags |= MS_RDONLY; - infp = kmalloc(sizeof(*infp), GFP_KERNEL); + infp = kcalloc(1, sizeof(*infp), GFP_KERNEL); if (!infp) { printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n"); return -ENOMEM; } - memset(infp, 0, sizeof(*infp)); bsize = sb_min_blocksize(sbp, BLOCK_SIZE); if (!bsize) { @@ -196,7 +195,7 @@ static int vxfs_fill_super(struct super_block *sbp, void *dp, int silent) #endif sbp->s_magic = rsbp->vs_magic; - sbp->s_fs_info = (void *)infp; + sbp->s_fs_info = infp; infp->vsi_raw = rsbp; infp->vsi_bp = bp; @@ -263,7 +262,7 @@ vxfs_init(void) sizeof(struct vxfs_inode_info), 0, SLAB_RECLAIM_ACCOUNT, NULL, NULL); if (vxfs_inode_cachep) - return (register_filesystem(&vxfs_fs_type)); + return register_filesystem(&vxfs_fs_type); return -ENOMEM; } -- cgit v1.1 From c60e81ee1cac32dae1f9bf623dcb6b3b2bde8eab Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 30 Jun 2005 02:59:06 -0700 Subject: [PATCH] reiserfs: handle_attrs() fix Fix a use-uninitialised bug. Cc: Jeff Mahoney Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/reiserfs/super.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index d50a5cd..4b80ab9 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -1053,10 +1053,9 @@ static void handle_barrier_mode(struct super_block *s, unsigned long bits) { static void handle_attrs( struct super_block *s ) { - struct reiserfs_super_block * rs; + struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK (s); if( reiserfs_attrs( s ) ) { - rs = SB_DISK_SUPER_BLOCK (s); if( old_format_only(s) ) { reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format" ); REISERFS_SB(s) -> s_mount_opt &= ~ ( 1 << REISERFS_ATTRS ); -- cgit v1.1 From c19cb1df809dcf343dd1eb6fe60d53639dafcb8c Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 30 Jun 2005 17:04:13 +0100 Subject: [PATCH] ARM: 2777/1: Fix broken comment arch/arm/mm/proc-arm1020.S Patch from Catalin Marinas This patch fixes a broken comment in the proc-arm1020.S file which prevents the file compilation Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/proc-arm1020.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index 1f32523..e69f194 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -445,7 +445,7 @@ __arm1020_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + * .0.1 1001 ..11 0101 FIXME: why no V bit? */ .type arm1020_cr1_clear, #object .type arm1020_cr1_set, #object -- cgit v1.1 From c28a814f25d48f193565003223df0ae617796892 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 30 Jun 2005 17:04:14 +0100 Subject: [PATCH] ARM: 2778/1: Add -mno-thumb-interwork to CFLAGS_ABI Patch from Catalin Marinas The new EABI gcc adds -mthumb-interwork by default, even if -mabi=apcs-gnu is passed. This causes a warning for every compiled C file when -march=armv4 is used. The patch adds -mno-thumb-interwork if the option is supported. This is also useful since we don't need any ARM/Thumb interworking in the kernel Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 8330495..eb933dc 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -56,7 +56,7 @@ tune-$(CONFIG_CPU_XSCALE) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) tune-$(CONFIG_CPU_V6) :=-mtune=strongarm # Need -Uarm for gcc < 3.x -CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) +CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) -msoft-float -Uarm AFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -msoft-float -- cgit v1.1 From abaf48a05a8f097654e746af2a5afb2ab95861a1 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 30 Jun 2005 17:04:14 +0100 Subject: [PATCH] ARM: 2779/1: Fix the V bit setting for the ARM1020x CPUs Patch from Catalin Marinas This patch fixes the V bit setting for the ARM1020x processors. At reset, this bit is automatically set to the value of the HIVECSINIT input signal which just happened to be 1 but it is not mandatory. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/proc-arm1020.S | 4 ++-- arch/arm/mm/proc-arm1020e.S | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S index e69f194..5c0ae52 100644 --- a/arch/arm/mm/proc-arm1020.S +++ b/arch/arm/mm/proc-arm1020.S @@ -445,14 +445,14 @@ __arm1020_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 FIXME: why no V bit? + * .011 1001 ..11 0101 */ .type arm1020_cr1_clear, #object .type arm1020_cr1_set, #object arm1020_cr1_clear: .word 0x593f arm1020_cr1_set: - .word 0x1935 + .word 0x3935 __INITDATA diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S index 142a2c2..d69389c 100644 --- a/arch/arm/mm/proc-arm1020e.S +++ b/arch/arm/mm/proc-arm1020e.S @@ -427,14 +427,14 @@ __arm1020e_setup: /* * R * .RVI ZFRS BLDP WCAM - * .0.1 1001 ..11 0101 /* FIXME: why no V bit? */ + * .011 1001 ..11 0101 */ .type arm1020e_cr1_clear, #object .type arm1020e_cr1_set, #object arm1020e_cr1_clear: .word 0x5f3f arm1020e_cr1_set: - .word 0x1935 + .word 0x3935 __INITDATA -- cgit v1.1 From 44454bcdb90532b372c74e3546043d8a3a468939 Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 30 Jun 2005 22:41:22 +0100 Subject: [PATCH] Serial: Fix small CONFIG_SERIAL_8250_NR_UARTS If CONFIG_SERIAL_8250_NR_UARTS is smaller than the array size in asm/serial.h, we trampled on memory which wasn't ours. Take our big boots away by limiting the number of ports initialised to the smaller of ...NR_UARTS and the array size. Signed-off-by: Russell King --- drivers/serial/8250.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 9224fc3..7e8fc7c 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -2061,7 +2061,8 @@ static void __init serial8250_isa_init_ports(void) up->port.ops = &serial8250_pops; } - for (i = 0, up = serial8250_ports; i < ARRAY_SIZE(old_serial_port); + for (i = 0, up = serial8250_ports; + i < ARRAY_SIZE(old_serial_port) && i < UART_NR; i++, up++) { up->port.iobase = old_serial_port[i].port; up->port.irq = irq_canonicalize(old_serial_port[i].irq); -- cgit v1.1 From 747aead34de65c25765da79825ce2c08d8257b10 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Thu, 30 Jun 2005 23:01:09 +0100 Subject: [PATCH] ARM: 2780/1: AFS partition length calculation fix Patch from Catalin Marinas This patch calculates the AFS partition length by expanding the image length information to the nearest erase block boundary. This eliminates the problems with JFFS2 erasing the footer. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- drivers/mtd/afs.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 801e6c7..7363e10 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c @@ -219,7 +219,7 @@ static int parse_afs_partitions(struct mtd_info *mtd, */ for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { struct image_info_struct iis; - u_int iis_ptr, img_ptr, size; + u_int iis_ptr, img_ptr; /* Read the footer. */ ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); @@ -236,21 +236,9 @@ static int parse_afs_partitions(struct mtd_info *mtd, continue; strcpy(str, iis.name); - size = mtd->erasesize + off - img_ptr; - - /* - * In order to support JFFS2 partitions on this layout, - * we must lie to MTD about the real size of JFFS2 - * partitions; this ensures that the AFS flash footer - * won't be erased by JFFS2. Please ensure that your - * JFFS2 partitions are given image numbers between - * 1000 and 2000 inclusive. - */ - if (iis.imageNumber >= 1000 && iis.imageNumber < 2000) - size -= mtd->erasesize; parts[idx].name = str; - parts[idx].size = size; + parts[idx].size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1); parts[idx].offset = img_ptr; parts[idx].mask_flags = 0; -- cgit v1.1 From eaf05be039cf5adfba5b1846452ce89646110fdb Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 30 Jun 2005 20:02:18 +0400 Subject: [PATCH] alpha smp fix As usual, the reason of this breakage is quite silly: in do_entIF, we are checking for PS == 0 to see whether it was a kernel BUG() or userspace trap. It works, unless BUG() happens in interrupt - PS is not 0 in kernel mode due to non-zero IPL, and the things get messed up horribly then. In this particular case it was BUG_ON(!irqs_disabled()) triggered in run_posix_cpu_timers(), so we ended up shooting "current" with the bursts of one SIGTRAP and three SIGILLs on every timer tick. ;-) --- arch/alpha/kernel/traps.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c index fd7bd17..6f509a6 100644 --- a/arch/alpha/kernel/traps.c +++ b/arch/alpha/kernel/traps.c @@ -240,7 +240,7 @@ do_entIF(unsigned long type, struct pt_regs *regs) siginfo_t info; int signo, code; - if (regs->ps == 0) { + if ((regs->ps & ~IPL_MAX) == 0) { if (type == 1) { const unsigned int *data = (const unsigned int *) regs->pc; -- cgit v1.1 From ef6689eff4b58273fed9e54293a3da983b321e9a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 30 Jun 2005 22:13:14 -0700 Subject: [PATCH] fatfs sectioning fix Fixup for the recent slab leak fix Cc: Pekka Enberg Cc: OGAWA Hirofumi Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/fat/cache.c | 2 +- fs/fat/inode.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/fat/cache.c b/fs/fat/cache.c index 7c52e46..77c24fc 100644 --- a/fs/fat/cache.c +++ b/fs/fat/cache.c @@ -56,7 +56,7 @@ int __init fat_cache_init(void) return 0; } -void __exit fat_cache_destroy(void) +void fat_cache_destroy(void) { if (kmem_cache_destroy(fat_cache_cachep)) printk(KERN_INFO "fat_cache: not all structures were freed\n"); diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 3e31c4a..96ae85b 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c @@ -1327,7 +1327,7 @@ out_fail: EXPORT_SYMBOL(fat_fill_super); int __init fat_cache_init(void); -void __exit fat_cache_destroy(void); +void fat_cache_destroy(void); static int __init init_fat_fs(void) { -- cgit v1.1 From 26705ca46bdf81113cc6729eb12b9eee2263bbfc Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Fri, 1 Jul 2005 11:27:05 +0100 Subject: [PATCH] ARM: 2781/2: PXA27x Standby mode take 2 Patch from Todd Poynor Add support for PXA27x Standby mode, a low-power mode that retains CPU and some peripheral state (the existing "sleep" mode is a power-power mode that retains less state). Activated via: echo -n standby > /sys/power/state From: David Burrage and Todd Poynor Signed-off-by: Todd Poynor Signed-off-by: Russell King --- arch/arm/mach-pxa/Makefile | 4 ++++ arch/arm/mach-pxa/pxa27x.c | 9 ++++++++- arch/arm/mach-pxa/standby.S | 32 ++++++++++++++++++++++++++++++++ include/asm-arm/arch-pxa/pxa-regs.h | 1 + 4 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-pxa/standby.S diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index c4e6d25..efc2f65 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -24,3 +24,7 @@ obj-$(CONFIG_LEDS) += $(led-y) # Misc features obj-$(CONFIG_PM) += pm.o sleep.o + +ifeq ($(CONFIG_PXA27x),y) +obj-$(CONFIG_PM) += standby.o +endif diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 893964f..9a791b0 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -126,6 +126,7 @@ int pxa_cpu_pm_prepare(suspend_state_t state) { switch (state) { case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: return 0; default: return -EINVAL; @@ -138,7 +139,10 @@ void pxa_cpu_pm_enter(suspend_state_t state) extern void pxa_cpu_suspend(unsigned int); extern void pxa_cpu_resume(void); - CKEN = CKEN22_MEMC | CKEN9_OSTIMER; + if (state == PM_SUSPEND_STANDBY) + CKEN = CKEN22_MEMC | CKEN9_OSTIMER | CKEN16_LCD |CKEN0_PWM0; + else + CKEN = CKEN22_MEMC | CKEN9_OSTIMER; /* ensure voltage-change sequencer not initiated, which hangs */ PCFR &= ~PCFR_FVC; @@ -147,6 +151,9 @@ void pxa_cpu_pm_enter(suspend_state_t state) PEDR = 0xDF12FE1B; switch (state) { + case PM_SUSPEND_STANDBY: + pxa_cpu_standby(); + break; case PM_SUSPEND_MEM: /* set resume return address */ PSPR = virt_to_phys(pxa_cpu_resume); diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S new file mode 100644 index 0000000..8a3f27b --- /dev/null +++ b/arch/arm/mach-pxa/standby.S @@ -0,0 +1,32 @@ +/* + * PXA27x standby mode + * + * Author: David Burrage + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#include +#include +#include +#include + +#include + + .text + +ENTRY(pxa_cpu_standby) + ldr r0, =PSSR + mov r1, #(PSSR_PH | PSSR_STS) + mov r2, #2 + mov r3, #UNCACHED_PHYS_0 @ Read mem context in. + ldr ip, [r3] + b 1f + + .align 5 +1: mcr p14, 0, r2, c7, c0, 0 @ put the system into Standby + str r1, [r0] @ make sure PSSR_PH/STS are clear + mov pc, lr diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index b5e54a9e..803dc92 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1505,6 +1505,7 @@ #define PSSR_OTGPH (1 << 6) /* OTG Peripheral control Hold */ #define PSSR_RDH (1 << 5) /* Read Disable Hold */ #define PSSR_PH (1 << 4) /* Peripheral Control Hold */ +#define PSSR_STS (1 << 3) /* Standby Mode Status */ #define PSSR_VFS (1 << 2) /* VDD Fault Status */ #define PSSR_BFS (1 << 1) /* Battery Fault Status */ #define PSSR_SSS (1 << 0) /* Software Sleep Status */ -- cgit v1.1 From 3e18a45abc5b20db2e34f02b87226ac2713bbb13 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Fri, 1 Jul 2005 11:27:06 +0100 Subject: [PATCH] ARM: 2782/1: PXA27x MDREFR K0DB4 define Patch from Todd Poynor Add definition of K0DB4 SDCLK<0,3> divide-by-4 control/status bit in the MDREFR register for Intel XScale PXA27x. Signed-off-by: Todd Poynor Signed-off-by: Russell King --- include/asm-arm/arch-pxa/pxa-regs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h index 803dc92..51f0fe0 100644 --- a/include/asm-arm/arch-pxa/pxa-regs.h +++ b/include/asm-arm/arch-pxa/pxa-regs.h @@ -1966,6 +1966,7 @@ #define MECR_NOS (1 << 0) /* Number Of Sockets: 0 -> 1 sock, 1 -> 2 sock */ #define MECR_CIT (1 << 1) /* Card Is There: 0 -> no card, 1 -> card inserted */ +#define MDREFR_K0DB4 (1 << 29) /* SDCLK0 Divide by 4 Control/Status */ #define MDREFR_K2FREE (1 << 25) /* SDRAM Free-Running Control */ #define MDREFR_K1FREE (1 << 24) /* SDRAM Free-Running Control */ #define MDREFR_K0FREE (1 << 23) /* SDRAM Free-Running Control */ -- cgit v1.1 From e695f60454f665604fe1b6e473f25b098203965a Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Fri, 1 Jul 2005 11:27:06 +0100 Subject: [PATCH] ARM: 2783/1: Remove omnimeter_defconfig as there is no kernel support Patch from Ben Dooks The omnimeter_defconfig does not define any machines and seems to have no other support in the current kernel. This patch removes the config file, as this is the only thing currently mentioning the ominmeter. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/configs/omnimeter_defconfig | 803 ----------------------------------- 1 file changed, 803 deletions(-) delete mode 100644 arch/arm/configs/omnimeter_defconfig diff --git a/arch/arm/configs/omnimeter_defconfig b/arch/arm/configs/omnimeter_defconfig deleted file mode 100644 index 78fdb4a..0000000 --- a/arch/arm/configs/omnimeter_defconfig +++ /dev/null @@ -1,803 +0,0 @@ -# -# Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-rc1-bk2 -# Sun Mar 27 21:31:45 2005 -# -CONFIG_ARM=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y -CONFIG_GENERIC_CALIBRATE_DELAY=y -CONFIG_GENERIC_IOMAP=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y -CONFIG_CLEAN_COMPILE=y -CONFIG_BROKEN_ON_SMP=y - -# -# General setup -# -CONFIG_LOCALVERSION="" -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -# CONFIG_POSIX_MQUEUE is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_AUDIT is not set -CONFIG_HOTPLUG=y -CONFIG_KOBJECT_UEVENT=y -# CONFIG_IKCONFIG is not set -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -# CONFIG_KALLSYMS_EXTRA_PASS is not set -CONFIG_BASE_FULL=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_CC_OPTIMIZE_FOR_SIZE=y -CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 -# CONFIG_TINY_SHMEM is not set -CONFIG_BASE_SMALL=0 - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODULE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y -# CONFIG_MODVERSIONS is not set -# CONFIG_MODULE_SRCVERSION_ALL is not set -CONFIG_KMOD=y - -# -# System Type -# -# CONFIG_ARCH_CLPS7500 is not set -# CONFIG_ARCH_CLPS711X is not set -# CONFIG_ARCH_CO285 is not set -# CONFIG_ARCH_EBSA110 is not set -# CONFIG_ARCH_CAMELOT is not set -# CONFIG_ARCH_FOOTBRIDGE is not set -# CONFIG_ARCH_INTEGRATOR is not set -# CONFIG_ARCH_IOP3XX is not set -# CONFIG_ARCH_IXP4XX is not set -# CONFIG_ARCH_IXP2000 is not set -# CONFIG_ARCH_L7200 is not set -# CONFIG_ARCH_PXA is not set -# CONFIG_ARCH_RPC is not set -CONFIG_ARCH_SA1100=y -# CONFIG_ARCH_S3C2410 is not set -# CONFIG_ARCH_SHARK is not set -# CONFIG_ARCH_LH7A40X is not set -# CONFIG_ARCH_OMAP is not set -# CONFIG_ARCH_VERSATILE is not set -# CONFIG_ARCH_IMX is not set -# CONFIG_ARCH_H720X is not set - -# -# SA11x0 Implementations -# -# CONFIG_SA1100_ASSABET is not set -# CONFIG_SA1100_CERF is not set -# CONFIG_SA1100_COLLIE is not set -# CONFIG_SA1100_H3100 is not set -# CONFIG_SA1100_H3600 is not set -# CONFIG_SA1100_H3800 is not set -# CONFIG_SA1100_BADGE4 is not set -# CONFIG_SA1100_JORNADA720 is not set -# CONFIG_SA1100_HACKKIT is not set -# CONFIG_SA1100_LART is not set -# CONFIG_SA1100_PLEB is not set -# CONFIG_SA1100_SHANNON is not set -# CONFIG_SA1100_SIMPAD is not set -# CONFIG_SA1100_SSP is not set - -# -# Processor Type -# -CONFIG_CPU_32=y -CONFIG_CPU_SA1100=y -CONFIG_CPU_32v4=y -CONFIG_CPU_ABRT_EV4=y -CONFIG_CPU_CACHE_V4WB=y -CONFIG_CPU_CACHE_VIVT=y -CONFIG_CPU_TLB_V4WB=y -CONFIG_CPU_MINICACHE=y - -# -# Processor Features -# - -# -# Bus support -# -CONFIG_ISA=y - -# -# PCCARD (PCMCIA/CardBus) support -# -CONFIG_PCCARD=y -# CONFIG_PCMCIA_DEBUG is not set -CONFIG_PCMCIA=y - -# -# PC-card bridges -# -CONFIG_I82365=y -# CONFIG_TCIC is not set -CONFIG_PCMCIA_SA1100=y -CONFIG_PCCARD_NONSTATIC=y - -# -# Kernel Features -# -# CONFIG_PREEMPT is not set -CONFIG_DISCONTIGMEM=y -# CONFIG_LEDS is not set -CONFIG_ALIGNMENT_TRAP=y - -# -# Boot options -# -CONFIG_ZBOOT_ROM_TEXT=0x0 -CONFIG_ZBOOT_ROM_BSS=0x0 -CONFIG_CMDLINE="keepinitrd mem=16M root=/dev/ram ramdisk=8192 initrd=0xd0000000,4M" -# CONFIG_XIP_KERNEL is not set - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set - -# -# Floating point emulation -# - -# -# At least one emulation must be selected -# -# CONFIG_FPE_NWFPE is not set -# CONFIG_FPE_FASTFPE is not set - -# -# Userspace binary formats -# -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_AOUT=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_ARTHUR is not set - -# -# Power management options -# -# CONFIG_PM is not set - -# -# Device Drivers -# - -# -# Generic Driver Options -# -CONFIG_STANDALONE=y -CONFIG_PREVENT_FIRMWARE_BUILD=y -# CONFIG_FW_LOADER is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play support -# -# CONFIG_PNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_BLK_DEV_COW_COMMON is not set -CONFIG_BLK_DEV_LOOP=m -# CONFIG_BLK_DEV_CRYPTOLOOP is not set -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_RAM is not set -CONFIG_BLK_DEV_RAM_COUNT=16 -CONFIG_INITRAMFS_SOURCE="" -# CONFIG_CDROM_PKTCDVD is not set - -# -# IO Schedulers -# -CONFIG_IOSCHED_NOOP=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y -CONFIG_IOSCHED_CFQ=y -# CONFIG_ATA_OVER_ETH is not set - -# -# ATA/ATAPI/MFM/RLL support -# -CONFIG_IDE=y -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_IDE_SATA is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_BLK_DEV_IDECS is not set -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -CONFIG_IDE_GENERIC=y -# CONFIG_IDE_ARM is not set -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_IDEDMA is not set -# CONFIG_IDEDMA_AUTO is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI device support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Fusion MPT device support -# - -# -# IEEE 1394 (FireWire) support -# - -# -# I2O device support -# - -# -# Networking support -# -CONFIG_NET=y - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_INET_TUNNEL is not set -CONFIG_IP_TCPDIAG=y -# CONFIG_IP_TCPDIAG_IPV6 is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set - -# -# IP: Netfilter Configuration -# -# CONFIG_IP_NF_CONNTRACK is not set -# CONFIG_IP_NF_CONNTRACK_MARK is not set -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_BRIDGE is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_DECNET is not set -# CONFIG_LLC2 is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set -# CONFIG_NET_CLS_ROUTE is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -# CONFIG_NETPOLL is not set -# CONFIG_NET_POLL_CONTROLLER is not set -# CONFIG_HAMRADIO is not set -# CONFIG_IRDA is not set -# CONFIG_BT is not set -CONFIG_NETDEVICES=y -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_MII is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_SMC91X is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# - -# -# Token Ring devices -# -# CONFIG_TR is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y - -# -# Obsolete Wireless cards support (pre-802.11) -# -# CONFIG_STRIP is not set -# CONFIG_ARLAN is not set -# CONFIG_WAVELAN is not set -CONFIG_PCMCIA_WAVELAN=y -# CONFIG_PCMCIA_NETWAVE is not set - -# -# Wireless 802.11 Frequency Hopping cards support -# -# CONFIG_PCMCIA_RAYCS is not set - -# -# Wireless 802.11b ISA/PCI cards support -# -# CONFIG_HERMES is not set -# CONFIG_ATMEL is not set - -# -# Wireless 802.11b Pcmcia/Cardbus cards support -# -CONFIG_AIRO_CS=y -CONFIG_PCMCIA_WL3501=y -CONFIG_NET_WIRELESS=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=y -# CONFIG_PCMCIA_3C574 is not set -# CONFIG_PCMCIA_FMVJ18X is not set -CONFIG_PCMCIA_PCNET=y -# CONFIG_PCMCIA_NMCLAN is not set -# CONFIG_PCMCIA_SMC91C92 is not set -# CONFIG_PCMCIA_XIRC2PS is not set -# CONFIG_PCMCIA_AXNET is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set -# CONFIG_SHAPER is not set -# CONFIG_NETCONSOLE is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input device support -# -CONFIG_INPUT=y - -# -# Userland interfaces -# -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_PSAUX=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_TSDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_EVBUG is not set - -# -# Input Device Drivers -# -CONFIG_INPUT_KEYBOARD=y -CONFIG_KEYBOARD_ATKBD=y -# CONFIG_KEYBOARD_SUNKBD is not set -# CONFIG_KEYBOARD_LKKBD is not set -# CONFIG_KEYBOARD_XTKBD is not set -# CONFIG_KEYBOARD_NEWTON is not set -CONFIG_INPUT_MOUSE=y -CONFIG_MOUSE_PS2=y -# CONFIG_MOUSE_SERIAL is not set -# CONFIG_MOUSE_INPORT is not set -# CONFIG_MOUSE_LOGIBM is not set -# CONFIG_MOUSE_PC110PAD is not set -# CONFIG_MOUSE_VSXXXAA is not set -# CONFIG_INPUT_JOYSTICK is not set -# CONFIG_INPUT_TOUCHSCREEN is not set -# CONFIG_INPUT_MISC is not set - -# -# Hardware I/O ports -# -CONFIG_SERIO=y -CONFIG_SERIO_SERPORT=y -CONFIG_SERIO_LIBPS2=y -# CONFIG_SERIO_RAW is not set -# CONFIG_GAMEPORT is not set -CONFIG_SOUND_GAMEPORT=y - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_HW_CONSOLE=y -# CONFIG_SERIAL_NONSTANDARD is not set - -# -# Serial drivers -# -# CONFIG_SERIAL_8250 is not set - -# -# Non-8250 serial port support -# -CONFIG_SERIAL_SA1100=y -CONFIG_SERIAL_SA1100_CONSOLE=y -CONFIG_SERIAL_CORE=y -CONFIG_SERIAL_CORE_CONSOLE=y -CONFIG_UNIX98_PTYS=y -CONFIG_LEGACY_PTYS=y -CONFIG_LEGACY_PTY_COUNT=256 - -# -# IPMI -# -# CONFIG_IPMI_HANDLER is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_SYNCLINK_CS is not set -# CONFIG_RAW_DRIVER is not set - -# -# TPM devices -# -# CONFIG_TCG_TPM is not set - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Misc devices -# - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Digital Video Broadcasting Devices -# -# CONFIG_DVB is not set - -# -# Graphics support -# -CONFIG_FB=y -CONFIG_FB_CFB_FILLRECT=y -CONFIG_FB_CFB_COPYAREA=y -CONFIG_FB_CFB_IMAGEBLIT=y -CONFIG_FB_SOFT_CURSOR=y -# CONFIG_FB_MODE_HELPERS is not set -# CONFIG_FB_TILEBLITTING is not set -CONFIG_FB_SA1100=y -# CONFIG_FB_VIRTUAL is not set - -# -# Console display driver support -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_MDA_CONSOLE is not set -CONFIG_DUMMY_CONSOLE=y -CONFIG_FRAMEBUFFER_CONSOLE=y -CONFIG_FONTS=y -CONFIG_FONT_8x8=y -# CONFIG_FONT_8x16 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set -# CONFIG_FONT_MINI_4x6 is not set -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set - -# -# Logo configuration -# -# CONFIG_LOGO is not set -# CONFIG_BACKLIGHT_LCD_SUPPORT is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB_ARCH_HAS_HCD=y -# CONFIG_USB_ARCH_HAS_OHCI is not set -# CONFIG_USB is not set - -# -# USB Gadget Support -# -# CONFIG_USB_GADGET is not set - -# -# MMC/SD Card support -# -# CONFIG_MMC is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set - -# -# XFS support -# -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -CONFIG_DNOTIFY=y -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_VFAT_FS is not set -CONFIG_FAT_DEFAULT_CODEPAGE=437 -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_SYSFS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVPTS_FS_XATTR is not set -# CONFIG_TMPFS is not set -# CONFIG_HUGETLB_PAGE is not set -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -CONFIG_NFS_FS=y -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_V4 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_NFSD is not set -CONFIG_LOCKD=y -CONFIG_SUNRPC=y -# CONFIG_RPCSEC_GSS_KRB5 is not set -# CONFIG_RPCSEC_GSS_SPKM3 is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Native Language Support -# -CONFIG_NLS=y -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ASCII is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -# CONFIG_PRINTK_TIME is not set -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=14 -CONFIG_DEBUG_BUGVERBOSE=y -CONFIG_FRAME_POINTER=y -# CONFIG_DEBUG_USER is not set - -# -# Security options -# -# CONFIG_KEYS is not set -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Hardware crypto devices -# - -# -# Library routines -# -# CONFIG_CRC_CCITT is not set -CONFIG_CRC32=y -# CONFIG_LIBCRC32C is not set -- cgit v1.1 From c77b042700ae1fc4d661d7d62787899e755160d5 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 1 Jul 2005 11:56:55 +0100 Subject: [PATCH] ARM: Make the magic values in head.S more obvious Make the magic address values in head.S more obvious as to where they came from. Wrap all debug code in CONFIG_DEBUG_LL. Signed-off-by: Russell King --- arch/arm/kernel/head.S | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index bd4823c..1155cf0 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S @@ -344,9 +344,9 @@ __create_page_tables: str r6, [r0] #endif +#ifdef CONFIG_DEBUG_LL bic r7, r7, #0x0c @ turn off cacheable @ and bufferable bits -#ifdef CONFIG_DEBUG_LL /* * Map in IO space for serial debugging. * This allows debug messages to be output @@ -372,28 +372,24 @@ __create_page_tables: teq r1, #MACH_TYPE_NETWINDER teqne r1, #MACH_TYPE_CATS bne 1f - add r0, r4, #0x3fc0 @ ff000000 - mov r3, #0x7c000000 - orr r3, r3, r7 - str r3, [r0], #4 - add r3, r3, #1 << 20 - str r3, [r0], #4 + add r0, r4, #0xff000000 >> 18 + orr r3, r7, #0x7c000000 + str r3, [r0] 1: #endif -#endif #ifdef CONFIG_ARCH_RPC /* * Map in screen at 0x02000000 & SCREEN2_BASE * Similar reasons here - for debug. This is * only for Acorn RiscPC architectures. */ - add r0, r4, #0x80 @ 02000000 - mov r3, #0x02000000 - orr r3, r3, r7 + add r0, r4, #0x02000000 >> 18 + orr r3, r7, #0x02000000 str r3, [r0] - add r0, r4, #0x3600 @ d8000000 + add r0, r4, #0xd8000000 >> 18 str r3, [r0] #endif +#endif mov pc, lr .ltorg -- cgit v1.1 From 7b09cdac5af1e13ab4b30421ae5c4b7953c26841 Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 1 Jul 2005 12:02:59 +0100 Subject: [PATCH] MMC: Fix divdi3 reference in mmci.c Use do_div() instead. Signed-off-by: Russell King --- drivers/mmc/mmci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/mmc/mmci.c b/drivers/mmc/mmci.c index 3a5f6ac..7a42966 100644 --- a/drivers/mmc/mmci.c +++ b/drivers/mmc/mmci.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -70,6 +71,7 @@ static void mmci_stop_data(struct mmci_host *host) static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) { unsigned int datactrl, timeout, irqmask; + unsigned long long clks; void __iomem *base; DBG(host, "blksz %04x blks %04x flags %08x\n", @@ -81,9 +83,10 @@ static void mmci_start_data(struct mmci_host *host, struct mmc_data *data) mmci_init_sg(host, data); - timeout = data->timeout_clks + - ((unsigned long long)data->timeout_ns * host->cclk) / - 1000000000ULL; + clks = (unsigned long long)data->timeout_ns * host->cclk; + do_div(clks, 1000000000UL); + + timeout = data->timeout_clks + (unsigned int)clks; base = host->base; writel(timeout, base + MMCIDATATIMER); -- cgit v1.1 From db5795547694cf68388aaf8f59723e850f7466f6 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Fri, 1 Jul 2005 12:11:51 +0100 Subject: [PATCH] ARM: replace schedule_timeout() with msleep() Use msleep() instead of schedule_timeout() to guarantee the task delays as expected. Neither signals nor wait-queue events are important at this point in the code, I believe. Signed-off-by: Nishanth Aravamudan Signed-off-by: Domen Puncer Signed-off-by: Russell King --- arch/arm/mach-sa1100/cpu-sa1110.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-sa1100/cpu-sa1110.c b/arch/arm/mach-sa1100/cpu-sa1110.c index 8d2a89a..04c94ab 100644 --- a/arch/arm/mach-sa1100/cpu-sa1110.c +++ b/arch/arm/mach-sa1100/cpu-sa1110.c @@ -271,8 +271,7 @@ static int sa1110_target(struct cpufreq_policy *policy, */ sdram_set_refresh(2); if (!irqs_disabled()) { - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(20 * HZ / 1000); + msleep(20); } else { mdelay(20); } -- cgit v1.1 From 6e6293dd3d4372c114674266158053d049366a0d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 1 Jul 2005 12:13:55 +0100 Subject: [PATCH] MMC: wbsd delayed insertion Wait 0.5 seconds before scanning for cards after an insertion interrupt. The electrical connection needs this time to stabilise for some cards. Signed-off-by: Pierre Ossman Signed-off-by: Russell King --- drivers/mmc/wbsd.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- drivers/mmc/wbsd.h | 2 ++ 2 files changed, 43 insertions(+), 10 deletions(-) diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index b7fbd30..0bd9b53 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -1051,6 +1051,20 @@ static struct mmc_host_ops wbsd_ops = { \*****************************************************************************/ /* + * Helper function for card detection + */ +static void wbsd_detect_card(unsigned long data) +{ + struct wbsd_host *host = (struct wbsd_host*)data; + + BUG_ON(host == NULL); + + DBG("Executing card detection\n"); + + mmc_detect_change(host->mmc); +} + +/* * Tasklets */ @@ -1075,7 +1089,6 @@ static void wbsd_tasklet_card(unsigned long param) { struct wbsd_host* host = (struct wbsd_host*)param; u8 csr; - int change = 0; spin_lock(&host->lock); @@ -1094,14 +1107,20 @@ static void wbsd_tasklet_card(unsigned long param) { DBG("Card inserted\n"); host->flags |= WBSD_FCARD_PRESENT; - change = 1; + + /* + * Delay card detection to allow electrical connections + * to stabilise. + */ + mod_timer(&host->timer, jiffies + HZ/2); } + + spin_unlock(&host->lock); } else if (host->flags & WBSD_FCARD_PRESENT) { DBG("Card removed\n"); host->flags &= ~WBSD_FCARD_PRESENT; - change = 1; if (host->mrq) { @@ -1112,15 +1131,14 @@ static void wbsd_tasklet_card(unsigned long param) host->mrq->cmd->error = MMC_ERR_FAILED; tasklet_schedule(&host->finish_tasklet); } - } - - /* - * Unlock first since we might get a call back. - */ - spin_unlock(&host->lock); + + /* + * Unlock first since we might get a call back. + */ + spin_unlock(&host->lock); - if (change) mmc_detect_change(host->mmc); + } } static void wbsd_tasklet_fifo(unsigned long param) @@ -1325,6 +1343,13 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) spin_lock_init(&host->lock); /* + * Set up detection timer + */ + init_timer(&host->timer); + host->timer.data = (unsigned long)host; + host->timer.function = wbsd_detect_card; + + /* * Maximum number of segments. Worst case is one sector per segment * so this will be 64kB/512. */ @@ -1351,11 +1376,17 @@ static int __devinit wbsd_alloc_mmc(struct device* dev) static void __devexit wbsd_free_mmc(struct device* dev) { struct mmc_host* mmc; + struct wbsd_host* host; mmc = dev_get_drvdata(dev); if (!mmc) return; + host = mmc_priv(mmc); + BUG_ON(host == NULL); + + del_timer_sync(&host->timer); + mmc_free_host(mmc); dev_set_drvdata(dev, NULL); diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index 864f3082..9f5383e 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h @@ -187,4 +187,6 @@ struct wbsd_host struct tasklet_struct timeout_tasklet; struct tasklet_struct finish_tasklet; struct tasklet_struct block_tasklet; + + struct timer_list timer; /* Card detection timer */ }; -- cgit v1.1 From 3eee0d03e33b0294eb3165c96f213a8c8ee461a8 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 1 Jul 2005 13:07:37 +0100 Subject: [PATCH] MMC: wbsd cleanups This patch contains the following possible cleanups: - make some needlessly global code static - remove the unneeded global function DBG_REG Signed-off-by: Adrian Bunk Signed-off-by: Russell King --- drivers/mmc/wbsd.c | 29 +++++++---------------------- drivers/mmc/wbsd.h | 7 ------- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 0bd9b53..0c41d4b 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c @@ -54,28 +54,6 @@ #define DBGF(x...) do { } while (0) #endif -#ifdef CONFIG_MMC_DEBUG -void DBG_REG(int reg, u8 value) -{ - int i; - - printk(KERN_DEBUG "wbsd: Register %d: 0x%02X %3d '%c' ", - reg, (int)value, (int)value, (value < 0x20)?'.':value); - - for (i = 7;i >= 0;i--) - { - if (value & (1 << i)) - printk("x"); - else - printk("."); - } - - printk("\n"); -} -#else -#define DBG_REG(r, v) do {} while (0) -#endif - /* * Device resources */ @@ -92,6 +70,13 @@ MODULE_DEVICE_TABLE(pnp, pnp_dev_table); #endif /* CONFIG_PNP */ +static const int config_ports[] = { 0x2E, 0x4E }; +static const int unlock_codes[] = { 0x83, 0x87 }; + +static const int valid_ids[] = { + 0x7112, + }; + #ifdef CONFIG_PNP static unsigned int nopnp = 0; #else diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index 9f5383e..661a9f6 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h @@ -8,13 +8,6 @@ * published by the Free Software Foundation. */ -const int config_ports[] = { 0x2E, 0x4E }; -const int unlock_codes[] = { 0x83, 0x87 }; - -const int valid_ids[] = { - 0x7112, - }; - #define LOCK_CODE 0xAA #define WBSD_CONF_SWRST 0x02 -- cgit v1.1 From 4a89a04f1ee21a7c1f4413f1ad7dcfac50ff9b63 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Fri, 1 Jul 2005 16:46:26 +0400 Subject: [PATCH] alpha smp fix (part #2) This fixes the bug that caused BUG_ON(!irqs_disabled()) to trigger in run_posix_cpu_timers() on alpha/smp. We didn't disable interrupts properly before calling smp_percpu_timer_interrupt(). We *do* disable interrupts everywhere except this unfortunate smp_percpu_timer_interrupt(). Fixed thus. Signed-off-by: Linus Torvalds --- arch/alpha/kernel/irq_alpha.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c index e6ded33..9d34ce2 100644 --- a/arch/alpha/kernel/irq_alpha.c +++ b/arch/alpha/kernel/irq_alpha.c @@ -55,6 +55,8 @@ do_entInt(unsigned long type, unsigned long vector, #ifdef CONFIG_SMP { long cpu; + + local_irq_disable(); smp_percpu_timer_interrupt(regs); cpu = smp_processor_id(); if (cpu != boot_cpuid) { -- cgit v1.1 From 26f674ae0e37190bf61c988e52911e4372fdb5f5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Jun 2005 15:41:48 -0700 Subject: [PATCH] PCI: Fix up PCI routing in parent bridge When the cardbus bridge is behind another bridge change the routing in the parent bridge for new cards. This fixes Cardbus on various AMD64 laptops. Signed-off-by: Andi Kleen Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 6a0a82f..9392ff3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -398,6 +398,16 @@ static void pci_enable_crs(struct pci_dev *dev) pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); } +static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) +{ + struct pci_bus *parent = child->parent; + while (parent->parent && parent->subordinate < max) { + parent->subordinate = max; + pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max); + parent = parent->parent; + } +} + unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); /* @@ -499,7 +509,13 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max if (!is_cardbus) { child->bridge_ctl = PCI_BRIDGE_CTL_NO_ISA; - + /* + * Adjust subordinate busnr in parent buses. + * We do this before scanning for children because + * some devices may not be detected if the bios + * was lazy. + */ + pci_fixup_parent_subordinate_busnr(child, max); /* Now we can scan all subordinate buses... */ max = pci_scan_child_bus(child); } else { @@ -513,6 +529,7 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max max+i+1)) break; max += i; + pci_fixup_parent_subordinate_busnr(child, max); } /* * Set the subordinate bus number to its real value. -- cgit v1.1 From a03fa955576af50df80bec9127b46ef57e0877c0 Mon Sep 17 00:00:00 2001 From: "rajesh.shah@intel.com" Date: Thu, 2 Jun 2005 15:41:48 -0700 Subject: [PATCH] PCI: Increase the number of PCI bus resources This patch increases the number of resource pointers in the pci_bus structure. This is needed to store >4 resource ranges for host bridges and transparent PCI bridges. With this change, all PCI buses will have more resource pointers, but most PCI buses will only use the first 3 or 4, the remaining being NULL. The PCI core already deals with this correctly. Signed-off-by: Rajesh Shah Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/pci.h b/include/linux/pci.h index 66798b4..a46cabf 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -586,7 +586,7 @@ struct pci_dev { #define PCI_NUM_RESOURCES 11 #ifndef PCI_BUS_NUM_RESOURCES -#define PCI_BUS_NUM_RESOURCES 4 +#define PCI_BUS_NUM_RESOURCES 8 #endif #define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */ -- cgit v1.1 From 90b54929b626c80056262d9d99b3f48522e404d0 Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Tue, 7 Jun 2005 04:07:02 +0400 Subject: [PATCH] PCI: handle subtractive decode pci-pci bridge better With the number of PCI bus resources increased to 8, we can handle the subtractive decode PCI-PCI bridge like a normal bridge, taking into account standard PCI-PCI bridge windows (resources 0-2). This helps to avoid problems with peer-to-peer DMA behind such bridges, poor performance for MMIO ranges outside bridge windows and prefetchable vs. non-prefetchable memory issues. To reflect the fact that such bridges do forward all addresses to the secondary bus (transparency), remaining bus resources 3-7 are linked to resources 0-4 of the primary bus. These resources will be used as fallback by resource management code if allocation from standard bridge windows fails for some reason. Signed-off-by: Ivan Kokshaysky Acked-by: Dominik Brodowski Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9392ff3..df3bdae 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -239,9 +239,8 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) if (dev->transparent) { printk(KERN_INFO "PCI: Transparent bridge - %s\n", pci_name(dev)); - for(i = 0; i < PCI_BUS_NUM_RESOURCES; i++) - child->resource[i] = child->parent->resource[i]; - return; + for(i = 3; i < PCI_BUS_NUM_RESOURCES; i++) + child->resource[i] = child->parent->resource[i - 3]; } for(i=0; i<3; i++) -- cgit v1.1 From 299de0343c7d18448a69c635378342e9214b14af Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Wed, 15 Jun 2005 18:59:27 +0400 Subject: [PATCH] PCI: pci_assign_unassigned_resources() on x86 - Add sanity check for io[port,mem]_resource in setup-bus.c. These resources look like "free" as they have no parents, but obviously we must not touch them. - In i386.c:pci_allocate_bus_resources(), if a bridge resource cannot be allocated for some reason, then clear its flags. This prevents any child allocations in this range, so the setup-bus code will work with a clean resource sub-tree. - i386.c:pcibios_enable_resources() doesn't enable bridges, as it checks only resources 0-5, which looks like a clear bug to me. I suspect it might break hotplug as well in some cases. From: Ivan Kokshaysky Signed-off-by: Greg Kroah-Hartman --- arch/i386/pci/common.c | 1 + arch/i386/pci/i386.c | 11 ++++++++--- drivers/pci/setup-bus.c | 2 ++ 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c index 8732526..70bcd53 100644 --- a/arch/i386/pci/common.c +++ b/arch/i386/pci/common.c @@ -165,6 +165,7 @@ static int __init pcibios_init(void) if ((pci_probe & PCI_BIOS_SORT) && !(pci_probe & PCI_NO_SORT)) pcibios_sort(); #endif + pci_assign_unassigned_resources(); return 0; } diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index c205ea7..93a364c 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -106,11 +106,16 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) if ((dev = bus->self)) { for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) { r = &dev->resource[idx]; - if (!r->start) + if (!r->flags) continue; pr = pci_find_parent_resource(dev, r); - if (!pr || request_resource(pr, r) < 0) + if (!r->start || !pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev)); + /* Something is wrong with the region. + Invalidate the resource to prevent child + resource allocations in this range. */ + r->flags = 0; + } } } pcibios_allocate_bus_resources(&bus->children); @@ -227,7 +232,7 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; - for(idx=0; idx<6; idx++) { + for(idx = 0; idx < PCI_NUM_RESOURCES; idx++) { /* Only set up the requested stuff */ if (!(mask & (1<resource[i]; + if (r == &ioport_resource || r == &iomem_resource) + continue; if (r && (r->flags & type_mask) == type && !r->parent) return r; } -- cgit v1.1 From 75865858971add95809c5c9cd35dc4cfba08e33b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 30 Jun 2005 02:18:12 -0700 Subject: [PATCH] PCI: clean up dynamic pci id logic The dynamic pci id logic has been bothering me for a while, and now that I started to look into how to move some of this to the driver core, I thought it was time to clean it all up. It ends up making the code smaller, and easier to follow, and fixes a few bugs at the same time (dynamic ids were not being matched everywhere, and so could be missed on some call paths for new devices, semaphore not needed to be grabbed when adding a new id and calling the driver core, etc.) I also renamed the function pci_match_device() to pci_match_id() as that's what it really does. Signed-off-by: Greg Kroah-Hartman --- arch/i386/kernel/cpu/cpufreq/gx-suspmod.c | 2 +- drivers/char/hw_random.c | 2 +- drivers/char/watchdog/i8xx_tco.c | 2 +- drivers/ide/setup-pci.c | 2 +- drivers/parport/parport_pc.c | 2 +- drivers/pci/pci-driver.c | 196 +++++++++++------------------- include/linux/pci-dynids.h | 18 --- include/linux/pci.h | 3 +- sound/pci/bt87x.c | 2 +- 9 files changed, 79 insertions(+), 150 deletions(-) delete mode 100644 include/linux/pci-dynids.h diff --git a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c index 1a49adb..e86ea48 100644 --- a/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c +++ b/arch/i386/kernel/cpu/cpufreq/gx-suspmod.c @@ -190,7 +190,7 @@ static __init struct pci_dev *gx_detect_chipset(void) /* detect which companion chip is used */ while ((gx_pci = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, gx_pci)) != NULL) { - if ((pci_match_device (gx_chipset_tbl, gx_pci)) != NULL) { + if ((pci_match_id(gx_chipset_tbl, gx_pci)) != NULL) { return gx_pci; } } diff --git a/drivers/char/hw_random.c b/drivers/char/hw_random.c index 7e6ac14..3480535 100644 --- a/drivers/char/hw_random.c +++ b/drivers/char/hw_random.c @@ -579,7 +579,7 @@ static int __init rng_init (void) /* Probe for Intel, AMD RNGs */ for_each_pci_dev(pdev) { - ent = pci_match_device (rng_pci_tbl, pdev); + ent = pci_match_id(rng_pci_tbl, pdev); if (ent) { rng_ops = &rng_vendor_ops[ent->driver_data]; goto match; diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index b14d642..5d07ee5 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c @@ -401,7 +401,7 @@ static unsigned char __init i8xx_tco_getdevice (void) */ while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { - if (pci_match_device(i8xx_tco_pci_tbl, dev)) { + if (pci_match_id(i8xx_tco_pci_tbl, dev)) { i8xx_tco_pci = dev; break; } diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index e501675..77da827 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c @@ -847,7 +847,7 @@ static int __init ide_scan_pcidev(struct pci_dev *dev) d = list_entry(l, struct pci_driver, node); if(d->id_table) { - const struct pci_device_id *id = pci_match_device(d->id_table, dev); + const struct pci_device_id *id = pci_match_id(d->id_table, dev); if(id != NULL) { if(d->probe(dev, id) >= 0) diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 80edfa3..4598c6a 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -3008,7 +3008,7 @@ static int __init parport_pc_init_superio (int autoirq, int autodma) int ret = 0; while ((pdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { - id = pci_match_device (parport_pc_pci_tbl, pdev); + id = pci_match_id(parport_pc_pci_tbl, pdev); if (id == NULL || id->driver_data >= last_sio) continue; diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index e65bf2b..aac6de9 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -7,7 +7,6 @@ #include #include #include -#include #include "pci.h" /* @@ -19,35 +18,11 @@ */ #ifdef CONFIG_HOTPLUG -/** - * pci_device_probe_dynamic() - * - * Walk the dynamic ID list looking for a match. - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. - */ -static int -pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) -{ - int error = -ENODEV; - struct list_head *pos; - struct dynid *dynid; - spin_lock(&drv->dynids.lock); - list_for_each(pos, &drv->dynids.list) { - dynid = list_entry(pos, struct dynid, node); - if (pci_match_one_device(&dynid->id, pci_dev)) { - spin_unlock(&drv->dynids.lock); - error = drv->probe(pci_dev, &dynid->id); - if (error >= 0) { - pci_dev->driver = drv; - return 0; - } - return error; - } - } - spin_unlock(&drv->dynids.lock); - return error; -} +struct pci_dynid { + struct list_head node; + struct pci_device_id id; +}; /** * store_new_id @@ -58,8 +33,7 @@ pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) static inline ssize_t store_new_id(struct device_driver *driver, const char *buf, size_t count) { - struct dynid *dynid; - struct bus_type * bus; + struct pci_dynid *dynid; struct pci_driver *pdrv = to_pci_driver(driver); __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, subdevice=PCI_ANY_ID, class=0, class_mask=0; @@ -91,37 +65,22 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) list_add_tail(&pdrv->dynids.list, &dynid->node); spin_unlock(&pdrv->dynids.lock); - bus = get_bus(pdrv->driver.bus); - if (bus) { - if (get_driver(&pdrv->driver)) { - down_write(&bus->subsys.rwsem); - driver_attach(&pdrv->driver); - up_write(&bus->subsys.rwsem); - put_driver(&pdrv->driver); - } - put_bus(bus); + if (get_driver(&pdrv->driver)) { + driver_attach(&pdrv->driver); + put_driver(&pdrv->driver); } return count; } - static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); -static inline void -pci_init_dynids(struct pci_dynids *dynids) -{ - spin_lock_init(&dynids->lock); - INIT_LIST_HEAD(&dynids->list); -} static void pci_free_dynids(struct pci_driver *drv) { - struct list_head *pos, *n; - struct dynid *dynid; + struct pci_dynid *dynid, *n; spin_lock(&drv->dynids.lock); - list_for_each_safe(pos, n, &drv->dynids.list) { - dynid = list_entry(pos, struct dynid, node); + list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { list_del(&dynid->node); kfree(dynid); } @@ -138,83 +97,70 @@ pci_create_newid_file(struct pci_driver *drv) return error; } -static int -pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv) -{ - struct list_head *pos; - struct dynid *dynid; - - spin_lock(&pci_drv->dynids.lock); - list_for_each(pos, &pci_drv->dynids.list) { - dynid = list_entry(pos, struct dynid, node); - if (pci_match_one_device(&dynid->id, pci_dev)) { - spin_unlock(&pci_drv->dynids.lock); - return 1; - } - } - spin_unlock(&pci_drv->dynids.lock); - return 0; -} - #else /* !CONFIG_HOTPLUG */ -static inline int pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev) -{ - return -ENODEV; -} -static inline void pci_init_dynids(struct pci_dynids *dynids) {} static inline void pci_free_dynids(struct pci_driver *drv) {} static inline int pci_create_newid_file(struct pci_driver *drv) { return 0; } -static inline int pci_bus_match_dynids(const struct pci_dev *pci_dev, struct pci_driver *pci_drv) -{ - return 0; -} #endif /** - * pci_match_device - Tell if a PCI device structure has a matching - * PCI device id structure + * pci_match_id - See if a pci device matches a given pci_id table * @ids: array of PCI device id structures to search in - * @dev: the PCI device structure to match against - * + * @dev: the PCI device structure to match against. + * * Used by a driver to check whether a PCI device present in the - * system is in its list of supported devices.Returns the matching + * system is in its list of supported devices. Returns the matching * pci_device_id structure or %NULL if there is no match. + * + * Depreciated, don't use this as it will not catch any dynamic ids + * that a driver might want to check for. */ -const struct pci_device_id * -pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) +const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, + struct pci_dev *dev) { - while (ids->vendor || ids->subvendor || ids->class_mask) { - if (pci_match_one_device(ids, dev)) - return ids; - ids++; + if (ids) { + while (ids->vendor || ids->subvendor || ids->class_mask) { + if (pci_match_one_device(ids, dev)) + return ids; + ids++; + } } return NULL; } /** - * pci_device_probe_static() - * - * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error. + * pci_match_device - Tell if a PCI device structure has a matching + * PCI device id structure + * @ids: array of PCI device id structures to search in + * @dev: the PCI device structure to match against + * @drv: the PCI driver to match against + * + * Used by a driver to check whether a PCI device present in the + * system is in its list of supported devices. Returns the matching + * pci_device_id structure or %NULL if there is no match. */ -static int -pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev) -{ - int error = -ENODEV; +const struct pci_device_id *pci_match_device(struct pci_driver *drv, + struct pci_dev *dev) +{ const struct pci_device_id *id; + struct pci_dynid *dynid; - if (!drv->id_table) - return error; - id = pci_match_device(drv->id_table, pci_dev); + id = pci_match_id(drv->id_table, dev); if (id) - error = drv->probe(pci_dev, id); - if (error >= 0) { - pci_dev->driver = drv; - error = 0; + return id; + + /* static ids didn't match, lets look at the dynamic ones */ + spin_lock(&drv->dynids.lock); + list_for_each_entry(dynid, &drv->dynids.list, node) { + if (pci_match_one_device(&dynid->id, dev)) { + spin_unlock(&drv->dynids.lock); + return &dynid->id; + } } - return error; + spin_unlock(&drv->dynids.lock); + return NULL; } /** @@ -225,13 +171,20 @@ pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev) */ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev) -{ +{ + const struct pci_device_id *id; int error = 0; if (!pci_dev->driver && drv->probe) { - error = pci_device_probe_static(drv, pci_dev); - if (error == -ENODEV) - error = pci_device_probe_dynamic(drv, pci_dev); + error = -ENODEV; + + id = pci_match_device(drv, pci_dev); + if (id) + error = drv->probe(pci_dev, id); + if (error >= 0) { + pci_dev->driver = drv; + error = 0; + } } return error; } @@ -371,12 +324,6 @@ static struct kobj_type pci_driver_kobj_type = { .sysfs_ops = &pci_driver_sysfs_ops, }; -static int -pci_populate_driver_dir(struct pci_driver *drv) -{ - return pci_create_newid_file(drv); -} - /** * pci_register_driver - register a new pci driver * @drv: the driver structure to register @@ -401,13 +348,15 @@ int pci_register_driver(struct pci_driver *drv) drv->driver.shutdown = pci_device_shutdown; drv->driver.owner = drv->owner; drv->driver.kobj.ktype = &pci_driver_kobj_type; - pci_init_dynids(&drv->dynids); + + spin_lock_init(&drv->dynids.lock); + INIT_LIST_HEAD(&drv->dynids.list); /* register with core */ error = driver_register(&drv->driver); if (!error) - pci_populate_driver_dir(drv); + error = pci_create_newid_file(drv); return error; } @@ -463,21 +412,17 @@ pci_dev_driver(const struct pci_dev *dev) * system is in its list of supported devices.Returns the matching * pci_device_id structure or %NULL if there is no match. */ -static int pci_bus_match(struct device * dev, struct device_driver * drv) +static int pci_bus_match(struct device *dev, struct device_driver *drv) { - const struct pci_dev * pci_dev = to_pci_dev(dev); - struct pci_driver * pci_drv = to_pci_driver(drv); - const struct pci_device_id * ids = pci_drv->id_table; + struct pci_dev *pci_dev = to_pci_dev(dev); + struct pci_driver *pci_drv = to_pci_driver(drv); const struct pci_device_id *found_id; - if (!ids) - return 0; - - found_id = pci_match_device(ids, pci_dev); + found_id = pci_match_device(pci_drv, pci_dev); if (found_id) return 1; - return pci_bus_match_dynids(pci_dev, pci_drv); + return 0; } /** @@ -536,6 +481,7 @@ static int __init pci_driver_init(void) postcore_initcall(pci_driver_init); +EXPORT_SYMBOL(pci_match_id); EXPORT_SYMBOL(pci_match_device); EXPORT_SYMBOL(pci_register_driver); EXPORT_SYMBOL(pci_unregister_driver); diff --git a/include/linux/pci-dynids.h b/include/linux/pci-dynids.h deleted file mode 100644 index 183b6b0..0000000 --- a/include/linux/pci-dynids.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * PCI defines and function prototypes - * Copyright 2003 Dell Inc. - * by Matt Domsch - */ - -#ifndef LINUX_PCI_DYNIDS_H -#define LINUX_PCI_DYNIDS_H - -#include -#include - -struct dynid { - struct list_head node; - struct pci_device_id id; -}; - -#endif diff --git a/include/linux/pci.h b/include/linux/pci.h index a46cabf..7ac1496 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -860,7 +860,8 @@ int pci_register_driver(struct pci_driver *); void pci_unregister_driver(struct pci_driver *); void pci_remove_behind_bridge(struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *); -const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); +const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev); +const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); /* kmem_cache style wrapper around pci_alloc_consistent() */ diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index defdc5a..909fef8 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -804,7 +804,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) int i; const struct pci_device_id *supported; - supported = pci_match_device(snd_bt87x_ids, pci); + supported = pci_match_device(driver, pci); if (supported) return supported->driver_data; -- cgit v1.1 From a00db371624e2e3718e5ab7d73bf364681098106 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Wed, 29 Jun 2005 17:04:06 +0200 Subject: [PATCH] PCI: Add PCI quirk for SMBus on the Asus P4B-LX One more Asus motherboard requiring the SMBus quirk (P4B-LX). Original patch from Salah Coronya. Signed-off-by: Salah Coronya Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 968033f..1521fd5 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -767,6 +767,7 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev) if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_ASUSTEK)) { if (dev->device == PCI_DEVICE_ID_INTEL_82845_HB) switch(dev->subsystem_device) { + case 0x8025: /* P4B-LX */ case 0x8070: /* P4B */ case 0x8088: /* P4B533 */ case 0x1626: /* L3C notebook */ -- cgit v1.1 From 5823d100ae260d022b4dd5ec9cc0b85f0bf0d646 Mon Sep 17 00:00:00 2001 From: long Date: Wed, 22 Jun 2005 09:09:54 -0700 Subject: [PATCH] PCI: acpi tg3 ethernet not coming back properly after S3 suspendon DellM70 This patch, is based on kernel 2.6.12, provides a fix for PCIe port bus driver suspend/resume. Signed-off-by: T. Long Nguyen Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pcie/portdrv.h | 5 +++ drivers/pci/pcie/portdrv_core.c | 8 +++++ drivers/pci/pcie/portdrv_pci.c | 79 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 91 insertions(+), 1 deletion(-) diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 537b372..a63bd8f 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -27,6 +27,11 @@ #define get_descriptor_id(type, service) (((type - 4) << 4) | service) +struct pcie_port_device_ext { + int interrupt_mode; /* [0:INTx | 1:MSI | 2:MSI-X] */ + unsigned int saved_msi_config_space[5]; +}; + extern struct bus_type pcie_port_bus_type; extern int pcie_port_device_probe(struct pci_dev *dev); extern int pcie_port_device_register(struct pci_dev *dev); diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index f5c5f10..4db6998 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -275,10 +275,17 @@ int pcie_port_device_probe(struct pci_dev *dev) int pcie_port_device_register(struct pci_dev *dev) { + struct pcie_port_device_ext *p_ext; int status, type, capabilities, irq_mode, i; int vectors[PCIE_PORT_DEVICE_MAXSERVICES]; u16 reg16; + /* Allocate port device extension */ + if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL))) + return -ENOMEM; + + pci_set_drvdata(dev, p_ext); + /* Get port type */ pci_read_config_word(dev, pci_find_capability(dev, PCI_CAP_ID_EXP) + @@ -288,6 +295,7 @@ int pcie_port_device_register(struct pci_dev *dev) /* Now get port services */ capabilities = get_port_device_capability(dev); irq_mode = assign_interrupt_mode(dev, vectors, capabilities); + p_ext->interrupt_mode = irq_mode; /* Allocate child services if any */ for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) { diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index e9095ee..30bac7e 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -29,6 +29,78 @@ MODULE_LICENSE("GPL"); /* global data */ static const char device_name[] = "pcieport-driver"; +static void pci_save_msi_state(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + int i = 0, pos; + u16 control; + + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0) + return; + + pci_read_config_dword(dev, pos, &p_ext->saved_msi_config_space[i++]); + control = p_ext->saved_msi_config_space[0] >> 16; + pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, + &p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_64BIT) { + pci_read_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, + &p_ext->saved_msi_config_space[i++]); + pci_read_config_dword(dev, pos + PCI_MSI_DATA_64, + &p_ext->saved_msi_config_space[i++]); + } else + pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, + &p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_MASKBIT) + pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, + &p_ext->saved_msi_config_space[i++]); +} + +static void pci_restore_msi_state(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + int i = 0, pos; + u16 control; + + if ((pos = pci_find_capability(dev, PCI_CAP_ID_MSI)) <= 0) + return; + + control = p_ext->saved_msi_config_space[i++] >> 16; + pci_write_config_word(dev, pos + PCI_MSI_FLAGS, control); + pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_LO, + p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_64BIT) { + pci_write_config_dword(dev, pos + PCI_MSI_ADDRESS_HI, + p_ext->saved_msi_config_space[i++]); + pci_write_config_dword(dev, pos + PCI_MSI_DATA_64, + p_ext->saved_msi_config_space[i++]); + } else + pci_write_config_dword(dev, pos + PCI_MSI_DATA_32, + p_ext->saved_msi_config_space[i++]); + if (control & PCI_MSI_FLAGS_MASKBIT) + pci_write_config_dword(dev, pos + PCI_MSI_MASK_BIT, + p_ext->saved_msi_config_space[i++]); +} + +static void pcie_portdrv_save_config(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + + pci_save_state(dev); + if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) + pci_save_msi_state(dev); +} + +static void pcie_portdrv_restore_config(struct pci_dev *dev) +{ + struct pcie_port_device_ext *p_ext = pci_get_drvdata(dev); + + pci_restore_state(dev); + if (p_ext->interrupt_mode == PCIE_PORT_MSI_MODE) + pci_restore_msi_state(dev); + pci_enable_device(dev); + pci_set_master(dev); +} + /* * pcie_portdrv_probe - Probe PCI-Express port devices * @dev: PCI-Express port device being probed @@ -64,16 +136,21 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev, static void pcie_portdrv_remove (struct pci_dev *dev) { pcie_port_device_remove(dev); + kfree(pci_get_drvdata(dev)); } #ifdef CONFIG_PM static int pcie_portdrv_suspend (struct pci_dev *dev, pm_message_t state) { - return pcie_port_device_suspend(dev, state); + int ret = pcie_port_device_suspend(dev, state); + + pcie_portdrv_save_config(dev); + return ret; } static int pcie_portdrv_resume (struct pci_dev *dev) { + pcie_portdrv_restore_config(dev); return pcie_port_device_resume(dev); } #endif -- cgit v1.1 From c6e21e1683c2508a2b23588e1fc2e7bf6fc2549e Mon Sep 17 00:00:00 2001 From: Hannes Reinecke Date: Tue, 28 Jun 2005 14:57:10 +0200 Subject: [PATCH] PCI: Remove newline from pci MODALIAS variable the pci core sends out a hotplug event variable MODALIAS with a trailing newline. This is inconsistent with all other event variables and breaks some hotplug tools. This patch removes the said newline. Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index 3903f8c..b844bc9 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c @@ -54,7 +54,7 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, envp[i++] = scratch; length += scnprintf (scratch, buffer_size - length, - "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", + "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device, (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), -- cgit v1.1 From 5848f23d811acc1cb6c19a12e1341e0640a85d0e Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Fri, 1 Jul 2005 14:07:28 -0400 Subject: [PATCH] pci: cleanup argument comments for pci_{save,restore}_state The buffer arguments have been removed from pci_{save,restore}_state. The comment blocks for those functions should reflect that. Signed-off-by: John W. Linville Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f04b9ff..d382bdb 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -334,10 +334,6 @@ EXPORT_SYMBOL(pci_choose_state); /** * pci_save_state - save the PCI configuration space of a device before suspending * @dev: - PCI device that we're dealing with - * @buffer: - buffer to hold config space context - * - * @buffer must be large enough to hold the entire PCI 2.2 config space - * (>= 64 bytes). */ int pci_save_state(struct pci_dev *dev) @@ -352,8 +348,6 @@ pci_save_state(struct pci_dev *dev) /** * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with - * @buffer: - saved PCI config space - * */ int pci_restore_state(struct pci_dev *dev) -- cgit v1.1 From 43a6b76050aa137c51d00eec91d67ac43ac3846e Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Mon, 20 Jun 2005 14:29:25 -0700 Subject: [PATCH] gregkh-pci-pci-assign-unassigned-resources fix It seems that X86 architectures in general need the setup-bus.o not just those with HOTPLUG. This avoids the following error on X86_NUMAQ and x86_64: arch/i386/pci/built-in.o(.init.text+0x15a6): In function `pcibios_init': : undefined reference to `pci_assign_unassigned_resources' Signed-off-by: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/pci/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index 7dea494..3657f61 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_HOTPLUG_PCI) += hotplug/ # # Some architectures use the generic PCI setup functions # +obj-$(CONFIG_X86) += setup-bus.o obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o obj-$(CONFIG_PARISC) += setup-bus.o -- cgit v1.1 From 44f8e1a20cf3afe10a3744bd9317808a39a242bb Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Sat, 2 Jul 2005 10:35:33 -0700 Subject: If ACPI doesn't find an irq listed, don't accept 0 as a valid PCI irq. That zero just means that nothing else found any irq information either. --- drivers/acpi/pci_irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 8dbf802..d1f42b9 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c @@ -433,7 +433,7 @@ acpi_pci_irq_enable ( printk(KERN_WARNING PREFIX "PCI Interrupt %s[%c]: no GSI", pci_name(dev), ('A' + pin)); /* Interrupt Line values above 0xF are forbidden */ - if (dev->irq >= 0 && (dev->irq <= 0xF)) { + if (dev->irq > 0 && (dev->irq <= 0xF)) { printk(" - using IRQ %d\n", dev->irq); acpi_register_gsi(dev->irq, ACPI_LEVEL_SENSITIVE, ACPI_ACTIVE_LOW); return_VALUE(0); -- cgit v1.1 From c2f12589bfc4119f2c331ecea8cca4945ed48497 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:06:13 +0200 Subject: [PATCH] ide: hotplug mark __devinit alim15x3.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. see the thread about the pci hotplug crash on a stratus box. http://marc.theaimsgroup.com/?l=linux-kernel&m=111930108613386&w=2 Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/alim15x3.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index 67efb38..6cf4939 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c @@ -583,7 +583,7 @@ static int ali15x3_dma_setup(ide_drive_t *drive) * appropriate also sets up the 1533 southbridge. */ -static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_ali15x3 (struct pci_dev *dev, const char *name) { unsigned long flags; u8 tmpbyte; @@ -677,7 +677,7 @@ static unsigned int __init init_chipset_ali15x3 (struct pci_dev *dev, const char * FIXME: frobs bits that are not defined on newer ALi devicea */ -static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) +static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ata66 = 0; @@ -748,7 +748,7 @@ static unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif) * Initialize the IDE structure side of the ALi 15x3 driver. */ -static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif) +static void __devinit init_hwif_common_ali15x3 (ide_hwif_t *hwif) { hwif->autodma = 0; hwif->tuneproc = &ali15x3_tune_drive; @@ -794,7 +794,7 @@ static void __init init_hwif_common_ali15x3 (ide_hwif_t *hwif) * Sparc systems */ -static void __init init_hwif_ali15x3 (ide_hwif_t *hwif) +static void __devinit init_hwif_ali15x3 (ide_hwif_t *hwif) { u8 ideic, inmir; s8 irq_routing_table[] = { -1, 9, 3, 10, 4, 5, 7, 6, @@ -847,7 +847,7 @@ static void __init init_hwif_ali15x3 (ide_hwif_t *hwif) * the actual work. */ -static void __init init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) +static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase) { if (m5229_revision < 0x20) return; -- cgit v1.1 From e895f926cd8b6d50a42cc985d470bdc9a70caeed Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:15:41 +0200 Subject: [PATCH] ide: hotplug mark __devinit amd74xx.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/amd74xx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 4e0f13d..65eab9b 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -309,7 +309,7 @@ static int amd74xx_ide_dma_check(ide_drive_t *drive) * and initialize its drive independent registers. */ -static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_amd74xx(struct pci_dev *dev, const char *name) { unsigned char t; unsigned int u; @@ -413,7 +413,7 @@ static unsigned int __init init_chipset_amd74xx(struct pci_dev *dev, const char return dev->irq; } -static void __init init_hwif_amd74xx(ide_hwif_t *hwif) +static void __devinit init_hwif_amd74xx(ide_hwif_t *hwif) { int i; -- cgit v1.1 From 88de8e996f16b958721368ed9b4fd4e29cdb923e Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:23:08 +0200 Subject: [PATCH] ide: hotplug mark __devinit cs5530.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5530.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index 0381961..09269e5 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -217,7 +217,7 @@ static int cs5530_config_dma (ide_drive_t *drive) * Initialize the cs5530 bridge for reliable IDE DMA operation. */ -static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const char *name) { struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; @@ -308,7 +308,7 @@ static unsigned int __init init_chipset_cs5530 (struct pci_dev *dev, const char * performs channel-specific pre-initialization before drive probing. */ -static void __init init_hwif_cs5530 (ide_hwif_t *hwif) +static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) { unsigned long basereg; u32 d0_timings; -- cgit v1.1 From ddbc9fb47252f9b6966bfe9b0aa27bfeaa585cca Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:25:46 +0200 Subject: [PATCH] ide: hotplug mark __devinit cy82c693.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cy82c693.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c index 80d67e9..5a33513 100644 --- a/drivers/ide/pci/cy82c693.c +++ b/drivers/ide/pci/cy82c693.c @@ -391,7 +391,7 @@ static void cy82c693_tune_drive (ide_drive_t *drive, u8 pio) /* * this function is called during init and is used to setup the cy82c693 chip */ -static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_cy82c693(struct pci_dev *dev, const char *name) { if (PCI_FUNC(dev->devfn) != 1) return 0; @@ -443,7 +443,7 @@ static unsigned int __init init_chipset_cy82c693(struct pci_dev *dev, const char /* * the init function - called for each ide channel once */ -static void __init init_hwif_cy82c693(ide_hwif_t *hwif) +static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif) { hwif->autodma = 0; @@ -467,9 +467,9 @@ static void __init init_hwif_cy82c693(ide_hwif_t *hwif) hwif->drives[1].autodma = hwif->autodma; } -static __initdata ide_hwif_t *primary; +static __devinitdata ide_hwif_t *primary; -void __init init_iops_cy82c693(ide_hwif_t *hwif) +void __devinit init_iops_cy82c693(ide_hwif_t *hwif) { if (PCI_FUNC(hwif->pci_dev->devfn) == 1) primary = hwif; -- cgit v1.1 From a380a8849f90ba81a5ff0c325fd5d8125c70b3bb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:28:44 +0200 Subject: [PATCH] ide: hotplug mark __devinit it8172.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/it8172.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/it8172.c b/drivers/ide/pci/it8172.c index 631927c..9346292 100644 --- a/drivers/ide/pci/it8172.c +++ b/drivers/ide/pci/it8172.c @@ -216,7 +216,7 @@ fast_ata_pio: return 0; } -static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_it8172 (struct pci_dev *dev, const char *name) { unsigned char progif; @@ -230,7 +230,7 @@ static unsigned int __init init_chipset_it8172 (struct pci_dev *dev, const char } -static void __init init_hwif_it8172 (ide_hwif_t *hwif) +static void __devinit init_hwif_it8172 (ide_hwif_t *hwif) { struct pci_dev* dev = hwif->pci_dev; unsigned long cmdBase, ctrlBase; -- cgit v1.1 From c20530ed26e5b9e3b188b4088d0a5ab1d773a529 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:31:04 +0200 Subject: [PATCH] ide: hotplug mark __devinit ns87415.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/ns87415.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 205a32f..fcd5142 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -195,7 +195,7 @@ static int ns87415_ide_dma_check (ide_drive_t *drive) return __ide_dma_check(drive); } -static void __init init_hwif_ns87415 (ide_hwif_t *hwif) +static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned int ctrl, using_inta; -- cgit v1.1 From 9307145700e869dd410d565477f98377e93e9160 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:33:16 +0200 Subject: [PATCH] ide: hotplug mark __devinit opti621.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/opti621.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c index cf4fd91..7a7c2ef 100644 --- a/drivers/ide/pci/opti621.c +++ b/drivers/ide/pci/opti621.c @@ -326,7 +326,7 @@ static void opti621_tune_drive (ide_drive_t *drive, u8 pio) /* * init_hwif_opti621() is called once for each hwif found at boot. */ -static void __init init_hwif_opti621 (ide_hwif_t *hwif) +static void __devinit init_hwif_opti621 (ide_hwif_t *hwif) { hwif->autodma = 0; hwif->drives[0].drive_data = PIO_DONT_KNOW; -- cgit v1.1 From 6a6e1b1cf41b0bf35fffbf18787e8d8f865b66d6 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:35:07 +0200 Subject: [PATCH] ide: hotplug mark __devinit sc1200.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sc1200.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c index 3bc3bf1..10592ce 100644 --- a/drivers/ide/pci/sc1200.c +++ b/drivers/ide/pci/sc1200.c @@ -459,7 +459,7 @@ printk("%s: SC1200: resume\n", hwif->name); * This gets invoked by the IDE driver once for each channel, * and performs channel-specific pre-initialization before drive probing. */ -static void __init init_hwif_sc1200 (ide_hwif_t *hwif) +static void __devinit init_hwif_sc1200 (ide_hwif_t *hwif) { if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; -- cgit v1.1 From 34a6224691e638dd36b393aa439d021a19578fcc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:36:56 +0200 Subject: [PATCH] ide: hotplug mark __devinit sl82c105.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/sl82c105.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c index 1d970a0..ea0806c 100644 --- a/drivers/ide/pci/sl82c105.c +++ b/drivers/ide/pci/sl82c105.c @@ -386,7 +386,7 @@ static unsigned int sl82c105_bridge_revision(struct pci_dev *dev) * channel 0 here at least, but channel 1 has to be enabled by * firmware or arch code. We still set both to 16 bits mode. */ -static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char *msg) +static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const char *msg) { u32 val; @@ -399,7 +399,7 @@ static unsigned int __init init_chipset_sl82c105(struct pci_dev *dev, const char return dev->irq; } -static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) +static void __devinit init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) { unsigned int rev; u8 dma_state; @@ -431,7 +431,7 @@ static void __init init_dma_sl82c105(ide_hwif_t *hwif, unsigned long dma_base) * Initialise the chip */ -static void __init init_hwif_sl82c105(ide_hwif_t *hwif) +static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; u32 val; -- cgit v1.1 From 97319630b21c2022a55d51a6cfbf53cbb84a2f42 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:38:51 +0200 Subject: [PATCH] ide: hotplug mark __devinit slc90e66.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/slc90e66.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c index 7fbf363..5112c72 100644 --- a/drivers/ide/pci/slc90e66.c +++ b/drivers/ide/pci/slc90e66.c @@ -196,7 +196,7 @@ fast_ata_pio: } #endif /* CONFIG_BLK_DEV_IDEDMA */ -static void __init init_hwif_slc90e66 (ide_hwif_t *hwif) +static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) { u8 reg47 = 0; u8 mask = hwif->channel ? 0x01 : 0x02; /* bit0:Primary */ -- cgit v1.1 From d6904ab66f74cb99793e3919fc589dd0163a7740 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:40:31 +0200 Subject: [PATCH] ide: hotplug mark __devinit triflex.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/triflex.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index a1df2bf..f96b568 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -130,7 +130,7 @@ static int triflex_config_drive_xfer_rate(ide_drive_t *drive) return hwif->ide_dma_off_quietly(drive); } -static void __init init_hwif_triflex(ide_hwif_t *hwif) +static void __devinit init_hwif_triflex(ide_hwif_t *hwif) { hwif->tuneproc = &triflex_tune_drive; hwif->speedproc = &triflex_tune_chipset; -- cgit v1.1 From f3718d3e135117f80de0ff219be91544baa75599 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Jul 2005 16:42:18 +0200 Subject: [PATCH] ide: hotplug mark __devinit via82cxxx.c From: Herbert Xu mark the __init section __devinit. Splitted up from the Debian kernel patch. Signed-off-by: maximilian attems Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/via82cxxx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c index 069dbff..a4d099c 100644 --- a/drivers/ide/pci/via82cxxx.c +++ b/drivers/ide/pci/via82cxxx.c @@ -415,7 +415,7 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive) * and initialize its drive independent registers. */ -static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_via82cxxx(struct pci_dev *dev, const char *name) { struct pci_dev *isa = NULL; u8 t, v; @@ -576,7 +576,7 @@ static unsigned int __init init_chipset_via82cxxx(struct pci_dev *dev, const cha return 0; } -static void __init init_hwif_via82cxxx(ide_hwif_t *hwif) +static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif) { int i; -- cgit v1.1 From 13bbbf28fb914da6707aad44a073651f5c9d13a5 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sun, 3 Jul 2005 17:09:13 +0200 Subject: [PATCH] ide: fix line break in ide messages From: Denis Vlasenko * printk("\n") is misplaced, resulting in stray empty line in kernel log * cleanups nerby: some back-to-back printks are combined, etc Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-lib.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index 6806d40..b09a653 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c @@ -487,8 +487,7 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) u8 err = 0; local_irq_set(flags); - printk("%s: %s: status=0x%02x", drive->name, msg, stat); - printk(" { "); + printk("%s: %s: status=0x%02x { ", drive->name, msg, stat); if (stat & BUSY_STAT) printk("Busy "); else { @@ -500,15 +499,13 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) if (stat & INDEX_STAT) printk("Index "); if (stat & ERR_STAT) printk("Error "); } - printk("}"); - printk("\n"); + printk("}\n"); if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { err = hwif->INB(IDE_ERROR_REG); - printk("%s: %s: error=0x%02x", drive->name, msg, err); - printk(" { "); + printk("%s: %s: error=0x%02x { ", drive->name, msg, err); if (err & ABRT_ERR) printk("DriveStatusError "); if (err & ICRC_ERR) - printk("Bad%s ", (err & ABRT_ERR) ? "CRC" : "Sector"); + printk((err & ABRT_ERR) ? "BadCRC " : "BadSector "); if (err & ECC_ERR) printk("UncorrectableError "); if (err & ID_ERR) printk("SectorIdNotFound "); if (err & TRK0_ERR) printk("TrackZeroNotFound "); @@ -546,8 +543,8 @@ static u8 ide_dump_ata_status(ide_drive_t *drive, const char *msg, u8 stat) printk(", sector=%llu", (unsigned long long)HWGROUP(drive)->rq->sector); } + printk("\n"); } - printk("\n"); ide_dump_opcode(drive); local_irq_restore(flags); return err; -- cgit v1.1 From 21e2c01dc3e38d466eda5871645878d2c3a33261 Mon Sep 17 00:00:00 2001 From: Rob Punkunus Date: Sun, 3 Jul 2005 17:37:18 +0200 Subject: [PATCH] amd74xx: support MCP55 device IDs From: Rob Punkunus Rob Punkunus recently submitted a patch to enable support for MCP51/MCP55 in the amd74xx driver. This patch was whitespace-corrupted and didn't apply to 2.6.12 since MCP51 support was merged in the 2.6.12-rc series. Gentoo would like to support this hardware for our upcoming release media, so I fixed the patch, and here it is :) Signed-off-by: Daniel Drake Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/amd74xx.c | 3 +++ include/linux/pci_ids.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c index 65eab9b..844a6c9 100644 --- a/drivers/ide/pci/amd74xx.c +++ b/drivers/ide/pci/amd74xx.c @@ -73,6 +73,7 @@ static struct amd_ide_chip { { PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, 0x50, AMD_UDMA_133 }, { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, 0x50, AMD_UDMA_133 }, + { PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, 0x50, AMD_UDMA_133 }, { 0 } }; @@ -489,6 +490,7 @@ static ide_pci_device_t amd74xx_chipsets[] __devinitdata = { /* 13 */ DECLARE_NV_DEV("NFORCE-CK804"), /* 14 */ DECLARE_NV_DEV("NFORCE-MCP04"), /* 15 */ DECLARE_NV_DEV("NFORCE-MCP51"), + /* 16 */ DECLARE_NV_DEV("NFORCE-MCP55"), }; static int __devinit amd74xx_probe(struct pci_dev *dev, const struct pci_device_id *id) @@ -524,6 +526,7 @@ static struct pci_device_id amd74xx_pci_tbl[] = { { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14 }, { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 15 }, + { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 16 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, amd74xx_pci_tbl); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index c3ee1ae..27348c2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1238,6 +1238,7 @@ #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B -- cgit v1.1 From 10e047b40aafefef1fdc8ea4ea7837b9557a9400 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Sun, 3 Jul 2005 17:44:10 +0200 Subject: [PATCH] drivers/ide/Makefile: kill dead CONFIG_BLK_DEV_IDE_TCQ entry This patch kills the dead CONFIG_BLK_DEV_IDE_TCQ entry. Signed-off-by: Adrian Bunk Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 5be8ad6d..cca9c07 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -20,7 +20,6 @@ ide-core-$(CONFIG_BLK_DEV_CMD640) += pci/cmd640.o # Core IDE code - must come before legacy ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o -ide-core-$(CONFIG_BLK_DEV_IDE_TCQ) += ide-tcq.o ide-core-$(CONFIG_PROC_FS) += ide-proc.o ide-core-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o -- cgit v1.1 From e9dea0c65d2de6981356c055781fb99d7191b14e Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Jul 2005 17:38:58 +0100 Subject: [PATCH] ARM: Remove machine description macros Remove the pointless machine description macros, favouring C99 initialisers instead. Signed-off-by: Russell King --- arch/arm/mach-aaec2000/aaed2000.c | 10 +++--- arch/arm/mach-clps711x/autcpu12.c | 12 ++++--- arch/arm/mach-clps711x/cdb89712.c | 12 ++++--- arch/arm/mach-clps711x/ceiva.c | 12 ++++--- arch/arm/mach-clps711x/clep7312.c | 14 ++++---- arch/arm/mach-clps711x/edb7211-arch.c | 14 ++++---- arch/arm/mach-clps711x/fortunet.c | 14 ++++---- arch/arm/mach-clps711x/p720t.c | 14 ++++---- arch/arm/mach-clps7500/core.c | 14 ++++---- arch/arm/mach-ebsa110/core.c | 18 +++++----- arch/arm/mach-epxa10db/arch.c | 10 +++--- arch/arm/mach-footbridge/cats-hw.c | 16 +++++---- arch/arm/mach-footbridge/co285.c | 12 ++++--- arch/arm/mach-footbridge/ebsa285.c | 15 ++++---- arch/arm/mach-footbridge/netwinder-hw.c | 21 ++++++----- arch/arm/mach-footbridge/personal.c | 12 ++++--- arch/arm/mach-h720x/h7201-eval.c | 14 ++++---- arch/arm/mach-h720x/h7202-eval.c | 16 +++++---- arch/arm/mach-imx/mx1ads.c | 14 ++++---- arch/arm/mach-integrator/integrator_ap.c | 14 ++++---- arch/arm/mach-integrator/integrator_cp.c | 14 ++++---- arch/arm/mach-iop3xx/iop321-setup.c | 28 ++++++++------- arch/arm/mach-iop3xx/iop331-setup.c | 30 ++++++++-------- arch/arm/mach-ixp2000/enp2611.c | 14 ++++---- arch/arm/mach-ixp2000/ixdp2400.c | 14 ++++---- arch/arm/mach-ixp2000/ixdp2800.c | 14 ++++---- arch/arm/mach-ixp2000/ixdp2x01.c | 28 ++++++++------- arch/arm/mach-ixp4xx/coyote-setup.c | 30 ++++++++-------- arch/arm/mach-ixp4xx/gtwx5715-setup.c | 17 ++++----- arch/arm/mach-ixp4xx/ixdp425-setup.c | 60 +++++++++++++++++--------------- arch/arm/mach-l7200/core.c | 10 +++--- arch/arm/mach-lh7a40x/arch-kev7a400.c | 12 ++++--- arch/arm/mach-lh7a40x/arch-lpd7a40x.c | 28 ++++++++------- arch/arm/mach-omap/board-generic.c | 14 ++++---- arch/arm/mach-omap/board-h2.c | 14 ++++---- arch/arm/mach-omap/board-h3.c | 14 ++++---- arch/arm/mach-omap/board-innovator.c | 14 ++++---- arch/arm/mach-omap/board-netstar.c | 16 +++++---- arch/arm/mach-omap/board-osk.c | 14 ++++---- arch/arm/mach-omap/board-perseus2.c | 14 ++++---- arch/arm/mach-omap/board-voiceblue.c | 16 +++++---- arch/arm/mach-omap/usb.c | 1 - arch/arm/mach-pxa/corgi.c | 42 ++++++++++++---------- arch/arm/mach-pxa/idp.c | 12 ++++--- arch/arm/mach-pxa/lubbock.c | 12 ++++--- arch/arm/mach-pxa/mainstone.c | 12 ++++--- arch/arm/mach-pxa/poodle.c | 14 ++++---- arch/arm/mach-rpc/riscpc.c | 16 +++++---- arch/arm/mach-s3c2410/mach-bast.c | 9 ++--- arch/arm/mach-s3c2410/mach-h1940.c | 12 ++++--- arch/arm/mach-s3c2410/mach-n30.c | 9 ++--- arch/arm/mach-s3c2410/mach-nexcoder.c | 8 +++-- arch/arm/mach-s3c2410/mach-otom.c | 8 +++-- arch/arm/mach-s3c2410/mach-rx3715.c | 14 ++++---- arch/arm/mach-s3c2410/mach-smdk2410.c | 12 ++++--- arch/arm/mach-s3c2410/mach-smdk2440.c | 8 +++-- arch/arm/mach-s3c2410/mach-vr1000.c | 8 +++-- arch/arm/mach-sa1100/assabet.c | 12 ++++--- arch/arm/mach-sa1100/badge4.c | 10 +++--- arch/arm/mach-sa1100/cerf.c | 10 +++--- arch/arm/mach-sa1100/collie.c | 8 +++-- arch/arm/mach-sa1100/h3600.c | 30 +++++++++------- arch/arm/mach-sa1100/hackkit.c | 10 +++--- arch/arm/mach-sa1100/jornada720.c | 10 +++--- arch/arm/mach-sa1100/lart.c | 10 +++--- arch/arm/mach-sa1100/pleb.c | 8 +++-- arch/arm/mach-sa1100/shannon.c | 10 +++--- arch/arm/mach-sa1100/simpad.c | 12 ++++--- arch/arm/mach-shark/core.c | 12 ++++--- arch/arm/mach-versatile/versatile_ab.c | 14 ++++---- arch/arm/mach-versatile/versatile_pb.c | 14 ++++---- include/asm-arm/mach/arch.h | 32 ----------------- 72 files changed, 607 insertions(+), 485 deletions(-) diff --git a/arch/arm/mach-aaec2000/aaed2000.c b/arch/arm/mach-aaec2000/aaed2000.c index 5417ca3..c9d8998 100644 --- a/arch/arm/mach-aaec2000/aaed2000.c +++ b/arch/arm/mach-aaec2000/aaed2000.c @@ -40,9 +40,11 @@ static void __init aaed2000_map_io(void) } MACHINE_START(AAED2000, "Agilent AAED-2000 Development Platform") - MAINTAINER("Nicolas Bellido Y Ortega") - BOOT_MEM(0xf0000000, PIO_BASE, VIO_BASE) - MAPIO(aaed2000_map_io) - INITIRQ(aaed2000_init_irq) + /* Maintainer: Nicolas Bellido Y Ortega */ + .phys_ram = 0xf0000000, + .phys_io = PIO_BASE, + .io_pg_offst = ((VIO_BASE) >> 18) & 0xfffc, + .map_io = aaed2000_map_io, + .init_irq = aaed2000_init_irq, .timer = &aaec2000_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/autcpu12.c b/arch/arm/mach-clps711x/autcpu12.c index c106704..dc73feb 100644 --- a/arch/arm/mach-clps711x/autcpu12.c +++ b/arch/arm/mach-clps711x/autcpu12.c @@ -59,11 +59,13 @@ void __init autcpu12_map_io(void) } MACHINE_START(AUTCPU12, "autronix autcpu12") - MAINTAINER("Thomas Gleixner") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0020000) - MAPIO(autcpu12_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Thomas Gleixner */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0020000, + .map_io = autcpu12_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/cdb89712.c b/arch/arm/mach-clps711x/cdb89712.c index 7664f9c..a46c82c 100644 --- a/arch/arm/mach-clps711x/cdb89712.c +++ b/arch/arm/mach-clps711x/cdb89712.c @@ -49,10 +49,12 @@ static void __init cdb89712_map_io(void) } MACHINE_START(CDB89712, "Cirrus-CDB89712") - MAINTAINER("Ray Lehtiniemi") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - MAPIO(cdb89712_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Ray Lehtiniemi */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = cdb89712_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/ceiva.c b/arch/arm/mach-clps711x/ceiva.c index e4093be..780d918 100644 --- a/arch/arm/mach-clps711x/ceiva.c +++ b/arch/arm/mach-clps711x/ceiva.c @@ -53,10 +53,12 @@ static void __init ceiva_map_io(void) MACHINE_START(CEIVA, "CEIVA/Polaroid Photo MAX Digital Picture Frame") - MAINTAINER("Rob Scott") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - MAPIO(ceiva_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Rob Scott */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = ceiva_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/clep7312.c b/arch/arm/mach-clps711x/clep7312.c index 9ca21cb..c83f3fd 100644 --- a/arch/arm/mach-clps711x/clep7312.c +++ b/arch/arm/mach-clps711x/clep7312.c @@ -37,12 +37,14 @@ fixup_clep7312(struct machine_desc *desc, struct tag *tags, MACHINE_START(CLEP7212, "Cirrus Logic 7212/7312") - MAINTAINER("Nobody") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_clep7312) - MAPIO(clps711x_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Nobody */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_clep7312, + .map_io = clps711x_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/edb7211-arch.c b/arch/arm/mach-clps711x/edb7211-arch.c index c6c4632..255c98b 100644 --- a/arch/arm/mach-clps711x/edb7211-arch.c +++ b/arch/arm/mach-clps711x/edb7211-arch.c @@ -51,11 +51,13 @@ fixup_edb7211(struct machine_desc *desc, struct tag *tags, } MACHINE_START(EDB7211, "CL-EDB7211 (EP7211 eval board)") - MAINTAINER("Jon McClintock") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0020100) /* 0xc0000000 - 0xc001ffff can be video RAM */ - FIXUP(fixup_edb7211) - MAPIO(edb7211_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: Jon McClintock */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0020100, /* 0xc0000000 - 0xc001ffff can be video RAM */ + .fixup = fixup_edb7211, + .map_io = edb7211_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/fortunet.c b/arch/arm/mach-clps711x/fortunet.c index c1c5b8e..f83a597 100644 --- a/arch/arm/mach-clps711x/fortunet.c +++ b/arch/arm/mach-clps711x/fortunet.c @@ -75,11 +75,13 @@ fortunet_fixup(struct machine_desc *desc, struct tag *tags, } MACHINE_START(FORTUNET, "ARM-FortuNet") - MAINTAINER("FortuNet Inc.") - BOOT_MEM(0xc0000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0x00000000) - FIXUP(fortunet_fixup) - MAPIO(clps711x_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: FortuNet Inc. */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x00000000, + .fixup = fortunet_fixup, + .map_io = clps711x_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps711x/p720t.c b/arch/arm/mach-clps711x/p720t.c index 29269df..5bdb90e 100644 --- a/arch/arm/mach-clps711x/p720t.c +++ b/arch/arm/mach-clps711x/p720t.c @@ -79,12 +79,14 @@ static void __init p720t_map_io(void) } MACHINE_START(P720T, "ARM-Prospector720T") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0xc0000000, 0x80000000, 0xff000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_p720t) - MAPIO(p720t_map_io) - INITIRQ(clps711x_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xff000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_p720t, + .map_io = p720t_map_io, + .init_irq = clps711x_init_irq, .timer = &clps711x_timer, MACHINE_END diff --git a/arch/arm/mach-clps7500/core.c b/arch/arm/mach-clps7500/core.c index 90e85f43..112f1d68 100644 --- a/arch/arm/mach-clps7500/core.c +++ b/arch/arm/mach-clps7500/core.c @@ -366,11 +366,13 @@ static void __init clps7500_init(void) } MACHINE_START(CLPS7500, "CL-PS7500") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) - MAPIO(clps7500_map_io) - INITIRQ(clps7500_init_irq) - .init_machine = clps7500_init, - .timer = &clps7500_timer, + /* Maintainer: Philip Blundell */ + .phys_ram = 0x10000000, + .phys_io = 0x03000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .map_io = clps7500_map_io, + .init_irq = clps7500_init_irq, + .init_machine = clps7500_init, + .timer = &clps7500_timer, MACHINE_END diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c index 86ffdbb..23c4da1 100644 --- a/arch/arm/mach-ebsa110/core.c +++ b/arch/arm/mach-ebsa110/core.c @@ -233,13 +233,15 @@ static int __init ebsa110_init(void) arch_initcall(ebsa110_init); MACHINE_START(EBSA110, "EBSA110") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000) - BOOT_PARAMS(0x00000400) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - SOFT_REBOOT - MAPIO(ebsa110_map_io) - INITIRQ(ebsa110_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x00000000, + .phys_io = 0xe0000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x00000400, + .reserve_lp0 = 1, + .reserve_lp2 = 1, + .soft_reboot = 1, + .map_io = ebsa110_map_io, + .init_irq = ebsa110_init_irq, .timer = &ebsa110_timer, MACHINE_END diff --git a/arch/arm/mach-epxa10db/arch.c b/arch/arm/mach-epxa10db/arch.c index 1b40340..7daa021 100644 --- a/arch/arm/mach-epxa10db/arch.c +++ b/arch/arm/mach-epxa10db/arch.c @@ -63,10 +63,12 @@ extern void epxa10db_init_irq(void); extern struct sys_timer epxa10db_timer; MACHINE_START(CAMELOT, "Altera Epxa10db") - MAINTAINER("Altera Corporation") - BOOT_MEM(0x00000000, 0x7fffc000, 0xffffc000) - MAPIO(epxa10db_map_io) - INITIRQ(epxa10db_init_irq) + /* Maintainer: Altera Corporation */ + .phys_ram = 0x00000000, + .phys_io = 0x7fffc000, + .io_pg_offst = ((0xffffc000) >> 18) & 0xfffc, + .map_io = epxa10db_map_io, + .init_irq = epxa10db_init_irq, .timer = &epxa10db_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c index d1ced86..49b898a 100644 --- a/arch/arm/mach-footbridge/cats-hw.c +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -84,12 +84,14 @@ fixup_cats(struct machine_desc *desc, struct tag *tags, } MACHINE_START(CATS, "Chalice-CATS") - MAINTAINER("Philip Blundell") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - SOFT_REBOOT - FIXUP(fixup_cats) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Philip Blundell */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .soft_reboot = 1, + .fixup = fixup_cats, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &isa_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/co285.c b/arch/arm/mach-footbridge/co285.c index e154191..548a790 100644 --- a/arch/arm/mach-footbridge/co285.c +++ b/arch/arm/mach-footbridge/co285.c @@ -28,11 +28,13 @@ fixup_coebsa285(struct machine_desc *desc, struct tag *tags, } MACHINE_START(CO285, "co-EBSA285") - MAINTAINER("Mark van Doesburg") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) - FIXUP(fixup_coebsa285) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Mark van Doesburg */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0x7cf00000) >> 18) & 0xfffc, + .fixup = fixup_coebsa285, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/ebsa285.c b/arch/arm/mach-footbridge/ebsa285.c index d0931f5a..1c37605 100644 --- a/arch/arm/mach-footbridge/ebsa285.c +++ b/arch/arm/mach-footbridge/ebsa285.c @@ -13,12 +13,15 @@ #include "common.h" MACHINE_START(EBSA285, "EBSA285") - MAINTAINER("Russell King") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .video_start = 0x000a0000, + .video_end = 0x000bffff, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c index 1e1dfd7..775f85f 100644 --- a/arch/arm/mach-footbridge/netwinder-hw.c +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -647,14 +647,17 @@ fixup_netwinder(struct machine_desc *desc, struct tag *tags, } MACHINE_START(NETWINDER, "Rebel-NetWinder") - MAINTAINER("Russell King/Rebel.com") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - VIDEO(0x000a0000, 0x000bffff) - DISABLE_PARPORT(0) - DISABLE_PARPORT(2) - FIXUP(fixup_netwinder) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Russell King/Rebel.com */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .video_start = 0x000a0000, + .video_end = 0x000bffff, + .reserve_lp0 = 1, + .reserve_lp2 = 1, + .fixup = fixup_netwinder, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &isa_timer, MACHINE_END diff --git a/arch/arm/mach-footbridge/personal.c b/arch/arm/mach-footbridge/personal.c index 415086d..0146b8b 100644 --- a/arch/arm/mach-footbridge/personal.c +++ b/arch/arm/mach-footbridge/personal.c @@ -13,11 +13,13 @@ #include "common.h" MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") - MAINTAINER("Jamey Hicks / George France") - BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) - BOOT_PARAMS(0x00000100) - MAPIO(footbridge_map_io) - INITIRQ(footbridge_init_irq) + /* Maintainer: Jamey Hicks / George France */ + .phys_ram = 0x00000000, + .phys_io = DC21285_ARMCSR_BASE, + .io_pg_offst = ((0xfe000000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = footbridge_map_io, + .init_irq = footbridge_init_irq, .timer = &footbridge_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/h7201-eval.c b/arch/arm/mach-h720x/h7201-eval.c index 9b24b9b..fa59e9e 100644 --- a/arch/arm/mach-h720x/h7201-eval.c +++ b/arch/arm/mach-h720x/h7201-eval.c @@ -30,10 +30,12 @@ #include "common.h" MACHINE_START(H7201, "Hynix GMS30C7201") - MAINTAINER("Robert Schwebel, Pengutronix") - BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0xc0001000) - MAPIO(h720x_map_io) - INITIRQ(h720x_init_irq) - .timer = &h7201_timer, + /* Maintainer: Robert Schwebel, Pengutronix */ + .phys_ram = 0x40000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0xc0001000, + .map_io = h720x_map_io, + .init_irq = h720x_init_irq, + .timer = &h7201_timer, MACHINE_END diff --git a/arch/arm/mach-h720x/h7202-eval.c b/arch/arm/mach-h720x/h7202-eval.c index 3456a00..db9078a 100644 --- a/arch/arm/mach-h720x/h7202-eval.c +++ b/arch/arm/mach-h720x/h7202-eval.c @@ -71,11 +71,13 @@ static void __init init_eval_h7202(void) } MACHINE_START(H7202, "Hynix HMS30C7202") - MAINTAINER("Robert Schwebel, Pengutronix") - BOOT_MEM(0x40000000, 0x80000000, 0xf0000000) - BOOT_PARAMS(0x40000100) - MAPIO(h720x_map_io) - INITIRQ(h7202_init_irq) - .timer = &h7202_timer, - INIT_MACHINE(init_eval_h7202) + /* Maintainer: Robert Schwebel, Pengutronix */ + .phys_ram = 0x40000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf0000000) >> 18) & 0xfffc, + .boot_params = 0x40000100, + .map_io = h720x_map_io, + .init_irq = h7202_init_irq, + .timer = &h7202_timer, + .init_machine = init_eval_h7202, MACHINE_END diff --git a/arch/arm/mach-imx/mx1ads.c b/arch/arm/mach-imx/mx1ads.c index 625dd01..5d25434 100644 --- a/arch/arm/mach-imx/mx1ads.c +++ b/arch/arm/mach-imx/mx1ads.c @@ -78,11 +78,13 @@ mx1ads_map_io(void) } MACHINE_START(MX1ADS, "Motorola MX1ADS") - MAINTAINER("Sascha Hauer, Pengutronix") - BOOT_MEM(0x08000000, 0x00200000, 0xe0200000) - BOOT_PARAMS(0x08000100) - MAPIO(mx1ads_map_io) - INITIRQ(imx_init_irq) + /* Maintainer: Sascha Hauer, Pengutronix */ + .phys_ram = 0x08000000, + .phys_io = 0x00200000, + .io_pg_offst = ((0xe0200000) >> 18) & 0xfffc, + .boot_params = 0x08000100, + .map_io = mx1ads_map_io, + .init_irq = imx_init_irq, .timer = &imx_timer, - INIT_MACHINE(mx1ads_init) + .init_machine = mx1ads_init, MACHINE_END diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 91ba9fd..36e2b6e 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -292,11 +292,13 @@ static struct sys_timer ap_timer = { }; MACHINE_START(INTEGRATOR, "ARM-Integrator") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(ap_map_io) - INITIRQ(ap_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ap_map_io, + .init_irq = ap_init_irq, .timer = &ap_timer, - INIT_MACHINE(ap_init) + .init_machine = ap_init, MACHINE_END diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index e0a01ee..569f328 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -532,11 +532,13 @@ static struct sys_timer cp_timer = { }; MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x16000000, 0xf1600000) - BOOT_PARAMS(0x00000100) - MAPIO(intcp_map_io) - INITIRQ(intcp_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x16000000, + .io_pg_offst = ((0xf1600000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = intcp_map_io, + .init_irq = intcp_init_irq, .timer = &cp_timer, - INIT_MACHINE(intcp_init) + .init_machine = intcp_init, MACHINE_END diff --git a/arch/arm/mach-iop3xx/iop321-setup.c b/arch/arm/mach-iop3xx/iop321-setup.c index bf23e0f..0f921ba 100644 --- a/arch/arm/mach-iop3xx/iop321-setup.c +++ b/arch/arm/mach-iop3xx/iop321-setup.c @@ -146,23 +146,27 @@ extern void iop321_init_time(void); #if defined(CONFIG_ARCH_IQ80321) MACHINE_START(IQ80321, "Intel IQ80321") - MAINTAINER("Intel Corporation") - BOOT_MEM(PHYS_OFFSET, IQ80321_UART, IQ80321_UART) - MAPIO(iq80321_map_io) - INITIRQ(iop321_init_irq) + /* Maintainer: Intel Corporation */ + .phys_ram = PHYS_OFFSET, + .phys_io = IQ80321_UART, + .io_pg_offst = ((IQ80321_UART) >> 18) & 0xfffc, + .map_io = iq80321_map_io, + .init_irq = iop321_init_irq, .timer = &iop321_timer, - BOOT_PARAMS(0xa0000100) - INIT_MACHINE(iop32x_init) + .boot_params = 0xa0000100, + .init_machine = iop32x_init, MACHINE_END #elif defined(CONFIG_ARCH_IQ31244) MACHINE_START(IQ31244, "Intel IQ31244") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, IQ31244_UART, IQ31244_UART) - MAPIO(iq31244_map_io) - INITIRQ(iop321_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IQ31244_UART, + .io_pg_offst = ((IQ31244_UART) >> 18) & 0xfffc, + .map_io = iq31244_map_io, + .init_irq = iop321_init_irq, .timer = &iop321_timer, - BOOT_PARAMS(0xa0000100) - INIT_MACHINE(iop32x_init) + .boot_params = 0xa0000100, + .init_machine = iop32x_init, MACHINE_END #else #error No machine descriptor defined for this IOP3XX implementation diff --git a/arch/arm/mach-iop3xx/iop331-setup.c b/arch/arm/mach-iop3xx/iop331-setup.c index 622e7914..fc74b72 100644 --- a/arch/arm/mach-iop3xx/iop331-setup.c +++ b/arch/arm/mach-iop3xx/iop331-setup.c @@ -148,26 +148,28 @@ extern void iq80332_map_io(void); #if defined(CONFIG_ARCH_IQ80331) MACHINE_START(IQ80331, "Intel IQ80331") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical - //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) - MAPIO(iq80331_map_io) - INITIRQ(iop331_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80331_map_io, + .init_irq = iop331_init_irq, .timer = &iop331_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(iop33x_init) + .boot_params = 0x0100, + .init_machine = iop33x_init, MACHINE_END #elif defined(CONFIG_MACH_IQ80332) MACHINE_START(IQ80332, "Intel IQ80332") - MAINTAINER("Intel Corp.") - BOOT_MEM(PHYS_OFFSET, 0xfefff000, 0xfffff000) // virtual, physical - //BOOT_MEM(PHYS_OFFSET, IOP331_UART0_VIRT, IOP331_UART0_PHYS) - MAPIO(iq80332_map_io) - INITIRQ(iop331_init_irq) + /* Maintainer: Intel Corp. */ + .phys_ram = PHYS_OFFSET, + .phys_io = 0xfefff000, + .io_pg_offst = ((0xfffff000) >> 18) & 0xfffc, // virtual, physical + .map_io = iq80332_map_io, + .init_irq = iop331_init_irq, .timer = &iop331_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(iop33x_init) + .boot_params = 0x0100, + .init_machine = iop33x_init, MACHINE_END #else diff --git a/arch/arm/mach-ixp2000/enp2611.c b/arch/arm/mach-ixp2000/enp2611.c index f3a291b..b7ebf38 100644 --- a/arch/arm/mach-ixp2000/enp2611.c +++ b/arch/arm/mach-ixp2000/enp2611.c @@ -223,13 +223,15 @@ static void __init enp2611_init_machine(void) MACHINE_START(ENP2611, "Radisys ENP-2611 PCI network processor board") - MAINTAINER("Lennert Buytenhek ") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixp2000_map_io) - INITIRQ(ixp2000_init_irq) + /* Maintainer: Lennert Buytenhek */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixp2000_map_io, + .init_irq = ixp2000_init_irq, .timer = &enp2611_timer, - INIT_MACHINE(enp2611_init_machine) + .init_machine = enp2611_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2400.c b/arch/arm/mach-ixp2000/ixdp2400.c index df3ff26..fd280a9 100644 --- a/arch/arm/mach-ixp2000/ixdp2400.c +++ b/arch/arm/mach-ixp2000/ixdp2400.c @@ -168,12 +168,14 @@ void ixdp2400_init_irq(void) } MACHINE_START(IXDP2400, "Intel IXDP2400 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x00_map_io) - INITIRQ(ixdp2400_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2400_init_irq, .timer = &ixdp2400_timer, - INIT_MACHINE(ixdp2x00_init_machine) + .init_machine = ixdp2x00_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2800.c b/arch/arm/mach-ixp2000/ixdp2800.c index 468a4bb..f9073aa 100644 --- a/arch/arm/mach-ixp2000/ixdp2800.c +++ b/arch/arm/mach-ixp2000/ixdp2800.c @@ -284,12 +284,14 @@ void ixdp2800_init_irq(void) } MACHINE_START(IXDP2800, "Intel IXDP2800 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x00_map_io) - INITIRQ(ixdp2800_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x00_map_io, + .init_irq = ixdp2800_init_irq, .timer = &ixdp2800_timer, - INIT_MACHINE(ixdp2x00_init_machine) + .init_machine = ixdp2x00_init_machine, MACHINE_END diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c index e94dace..c735887 100644 --- a/arch/arm/mach-ixp2000/ixdp2x01.c +++ b/arch/arm/mach-ixp2000/ixdp2x01.c @@ -375,25 +375,29 @@ static void __init ixdp2x01_init_machine(void) #ifdef CONFIG_ARCH_IXDP2401 MACHINE_START(IXDP2401, "Intel IXDP2401 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x01_map_io) - INITIRQ(ixdp2x01_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, .timer = &ixdp2x01_timer, - INIT_MACHINE(ixdp2x01_init_machine) + .init_machine = ixdp2x01_init_machine, MACHINE_END #endif #ifdef CONFIG_ARCH_IXDP2801 MACHINE_START(IXDP2801, "Intel IXDP2801 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x00000000, IXP2000_UART_PHYS_BASE, IXP2000_UART_VIRT_BASE) - BOOT_PARAMS(0x00000100) - MAPIO(ixdp2x01_map_io) - INITIRQ(ixdp2x01_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x00000000, + .phys_io = IXP2000_UART_PHYS_BASE, + .io_pg_offst = ((IXP2000_UART_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ixdp2x01_map_io, + .init_irq = ixdp2x01_init_irq, .timer = &ixdp2x01_timer, - INIT_MACHINE(ixdp2x01_init_machine) + .init_machine = ixdp2x01_init_machine, MACHINE_END #endif diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 8a05a12..c6335f5 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -100,14 +100,15 @@ static void __init coyote_init(void) #ifdef CONFIG_ARCH_ADI_COYOTE MACHINE_START(ADI_COYOTE, "ADI Engineering Coyote") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(coyote_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = coyote_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(coyote_init) + .boot_params = 0x0100, + .init_machine = coyote_init, MACHINE_END #endif @@ -117,14 +118,15 @@ MACHINE_END */ #ifdef CONFIG_MACH_IXDPG425 MACHINE_START(IXDPG425, "Intel IXDPG425") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(coyote_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = coyote_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(coyote_init) + .boot_params = 0x0100, + .init_machine = coyote_init, MACHINE_END #endif diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index e77c86e..8ba1cd9 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c @@ -140,14 +140,15 @@ static void __init gtwx5715_init(void) MACHINE_START(GTWX5715, "Gemtek GTWX5715 (Linksys WRV54G)") - MAINTAINER("George Joseph") - BOOT_MEM(PHYS_OFFSET, IXP4XX_UART2_BASE_PHYS, - IXP4XX_UART2_BASE_VIRT) - MAPIO(gtwx5715_map_io) - INITIRQ(ixp4xx_init_irq) - .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(gtwx5715_init) + /* Maintainer: George Joseph */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_UART2_BASE_PHYS, + .io_pg_offst = ((IXP4XX_UART2_BASE_VIRT) >> 18) & 0xfffc, + .map_io = gtwx5715_map_io, + .init_irq = ixp4xx_init_irq, + .timer = &ixp4xx_timer, + .boot_params = 0x0100, + .init_machine = gtwx5715_init, MACHINE_END diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 77346c1..f2e9c0e 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -128,36 +128,39 @@ static void __init ixdp425_init(void) } MACHINE_START(IXDP425, "Intel IXDP425 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END MACHINE_START(IXDP465, "Intel IXDP465 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END /* @@ -168,14 +171,15 @@ MACHINE_END */ #ifdef CONFIG_ARCH_AVILA MACHINE_START(AVILA, "Gateworks Avila Network Platform") - MAINTAINER("Deepak Saxena ") - BOOT_MEM(PHYS_OFFSET, IXP4XX_PERIPHERAL_BASE_PHYS, - IXP4XX_PERIPHERAL_BASE_VIRT) - MAPIO(ixdp425_map_io) - INITIRQ(ixp4xx_init_irq) + /* Maintainer: Deepak Saxena */ + .phys_ram = PHYS_OFFSET, + .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS, + .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc, + .map_io = ixdp425_map_io, + .init_irq = ixp4xx_init_irq, .timer = &ixp4xx_timer, - BOOT_PARAMS(0x0100) - INIT_MACHINE(ixdp425_init) + .boot_params = 0x0100, + .init_machine = ixdp425_init, MACHINE_END #endif diff --git a/arch/arm/mach-l7200/core.c b/arch/arm/mach-l7200/core.c index 606ca95..2a7fee2 100644 --- a/arch/arm/mach-l7200/core.c +++ b/arch/arm/mach-l7200/core.c @@ -81,9 +81,11 @@ static void __init l7200_map_io(void) } MACHINE_START(L7200, "LinkUp Systems L7200") - MAINTAINER("Steve Hill / Scott McConnell") - BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000) - MAPIO(l7200_map_io) - INITIRQ(l7200_init_irq) + /* Maintainer: Steve Hill / Scott McConnell */ + .phys_ram = 0xf0000000, + .phys_io = 0x80040000, + .io_pg_offst = ((0xd0000000) >> 18) & 0xfffc, + .map_io = l7200_map_io, + .init_irq = l7200_init_irq, MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-kev7a400.c b/arch/arm/mach-lh7a40x/arch-kev7a400.c index be5d17f..cb3dcd3 100644 --- a/arch/arm/mach-lh7a40x/arch-kev7a400.c +++ b/arch/arm/mach-lh7a40x/arch-kev7a400.c @@ -102,10 +102,12 @@ void __init lh7a40x_init_board_irq (void) } MACHINE_START (KEV7A400, "Sharp KEV7a400") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (kev7a400_map_io) - INITIRQ (lh7a400_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = kev7a400_map_io, + .init_irq = lh7a400_init_irq, .timer = &lh7a40x_timer, MACHINE_END diff --git a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c index c823447..6eb61a1 100644 --- a/arch/arm/mach-lh7a40x/arch-lpd7a40x.c +++ b/arch/arm/mach-lh7a40x/arch-lpd7a40x.c @@ -260,13 +260,15 @@ lpd7a400_map_io(void) #ifdef CONFIG_MACH_LPD7A400 MACHINE_START (LPD7A400, "Logic Product Development LPD7A400-10") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (lpd7a400_map_io) - INITIRQ (lh7a400_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lpd7a400_map_io, + .init_irq = lh7a400_init_irq, .timer = &lh7a40x_timer, - INIT_MACHINE (lpd7a40x_init) + .init_machine = lpd7a40x_init, MACHINE_END #endif @@ -274,13 +276,15 @@ MACHINE_END #ifdef CONFIG_MACH_LPD7A404 MACHINE_START (LPD7A404, "Logic Product Development LPD7A404-10") - MAINTAINER ("Marc Singer") - BOOT_MEM (0xc0000000, 0x80000000, io_p2v (0x80000000)) - BOOT_PARAMS (0xc0000100) - MAPIO (lpd7a400_map_io) - INITIRQ (lh7a404_init_irq) + /* Maintainer: Marc Singer */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((io_p2v (0x80000000))>>18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lpd7a400_map_io, + .init_irq = lh7a404_init_irq, .timer = &lh7a40x_timer, - INIT_MACHINE (lpd7a40x_init) + .init_machine = lpd7a40x_init, MACHINE_END #endif diff --git a/arch/arm/mach-omap/board-generic.c b/arch/arm/mach-omap/board-generic.c index 2102a2c..384bc7c 100644 --- a/arch/arm/mach-omap/board-generic.c +++ b/arch/arm/mach-omap/board-generic.c @@ -88,11 +88,13 @@ static void __init omap_generic_map_io(void) } MACHINE_START(OMAP_GENERIC, "Generic OMAP1510/1610/1710") - MAINTAINER("Tony Lindgren ") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(omap_generic_map_io) - INITIRQ(omap_generic_init_irq) - INIT_MACHINE(omap_generic_init) + /* Maintainer: Tony Lindgren */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_generic_map_io, + .init_irq = omap_generic_init_irq, + .init_machine = omap_generic_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-h2.c b/arch/arm/mach-omap/board-h2.c index 1f06783..f37c76a 100644 --- a/arch/arm/mach-omap/board-h2.c +++ b/arch/arm/mach-omap/board-h2.c @@ -177,11 +177,13 @@ static void __init h2_map_io(void) } MACHINE_START(OMAP_H2, "TI-H2") - MAINTAINER("Imre Deak ") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(h2_map_io) - INITIRQ(h2_init_irq) - INIT_MACHINE(h2_init) + /* Maintainer: Imre Deak */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = h2_map_io, + .init_irq = h2_init_irq, + .init_machine = h2_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-h3.c b/arch/arm/mach-omap/board-h3.c index 486a5a0..705e485 100644 --- a/arch/arm/mach-omap/board-h3.c +++ b/arch/arm/mach-omap/board-h3.c @@ -195,11 +195,13 @@ static void __init h3_map_io(void) } MACHINE_START(OMAP_H3, "TI OMAP1710 H3 board") - MAINTAINER("Texas Instruments, Inc.") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(h3_map_io) - INITIRQ(h3_init_irq) - INIT_MACHINE(h3_init) + /* Maintainer: Texas Instruments, Inc. */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = h3_map_io, + .init_irq = h3_init_irq, + .init_machine = h3_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-innovator.c b/arch/arm/mach-omap/board-innovator.c index 57cf4da..523363f 100644 --- a/arch/arm/mach-omap/board-innovator.c +++ b/arch/arm/mach-omap/board-innovator.c @@ -270,11 +270,13 @@ static void __init innovator_map_io(void) } MACHINE_START(OMAP_INNOVATOR, "TI-Innovator") - MAINTAINER("MontaVista Software, Inc.") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(innovator_map_io) - INITIRQ(innovator_init_irq) - INIT_MACHINE(innovator_init) + /* Maintainer: MontaVista Software, Inc. */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = innovator_map_io, + .init_irq = innovator_init_irq, + .init_machine = innovator_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-netstar.c b/arch/arm/mach-omap/board-netstar.c index 54acbd2..8c65373 100644 --- a/arch/arm/mach-omap/board-netstar.c +++ b/arch/arm/mach-omap/board-netstar.c @@ -141,11 +141,13 @@ static int __init netstar_late_init(void) postcore_initcall(netstar_late_init); MACHINE_START(NETSTAR, "NetStar OMAP5910") - MAINTAINER("Ladislav Michl ") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(netstar_map_io) - INITIRQ(netstar_init_irq) - INIT_MACHINE(netstar_init) - .timer = &omap_timer, + /* Maintainer: Ladislav Michl */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = netstar_map_io, + .init_irq = netstar_init_irq, + .init_machine = netstar_init, + .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-osk.c b/arch/arm/mach-omap/board-osk.c index a951fc8..cb43343 100644 --- a/arch/arm/mach-omap/board-osk.c +++ b/arch/arm/mach-omap/board-osk.c @@ -159,11 +159,13 @@ static void __init osk_map_io(void) } MACHINE_START(OMAP_OSK, "TI-OSK") - MAINTAINER("Dirk Behme ") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(osk_map_io) - INITIRQ(osk_init_irq) - INIT_MACHINE(osk_init) + /* Maintainer: Dirk Behme */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = osk_map_io, + .init_irq = osk_init_irq, + .init_machine = osk_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-perseus2.c b/arch/arm/mach-omap/board-perseus2.c index 64515ae..d534204 100644 --- a/arch/arm/mach-omap/board-perseus2.c +++ b/arch/arm/mach-omap/board-perseus2.c @@ -179,11 +179,13 @@ static void __init omap_perseus2_map_io(void) } MACHINE_START(OMAP_PERSEUS2, "OMAP730 Perseus2") - MAINTAINER("Kevin Hilman ") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(omap_perseus2_map_io) - INITIRQ(omap_perseus2_init_irq) - INIT_MACHINE(omap_perseus2_init) + /* Maintainer: Kevin Hilman */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = omap_perseus2_map_io, + .init_irq = omap_perseus2_init_irq, + .init_machine = omap_perseus2_init, .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/board-voiceblue.c b/arch/arm/mach-omap/board-voiceblue.c index f1a5bff..6b0c500 100644 --- a/arch/arm/mach-omap/board-voiceblue.c +++ b/arch/arm/mach-omap/board-voiceblue.c @@ -246,11 +246,13 @@ EXPORT_SYMBOL(voiceblue_wdt_disable); EXPORT_SYMBOL(voiceblue_wdt_ping); MACHINE_START(VOICEBLUE, "VoiceBlue OMAP5910") - MAINTAINER("Ladislav Michl ") - BOOT_MEM(0x10000000, 0xfff00000, 0xfef00000) - BOOT_PARAMS(0x10000100) - MAPIO(voiceblue_map_io) - INITIRQ(voiceblue_init_irq) - INIT_MACHINE(voiceblue_init) - .timer = &omap_timer, + /* Maintainer: Ladislav Michl */ + .phys_ram = 0x10000000, + .phys_io = 0xfff00000, + .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .map_io = voiceblue_map_io, + .init_irq = voiceblue_init_irq, + .init_machine = voiceblue_init, + .timer = &omap_timer, MACHINE_END diff --git a/arch/arm/mach-omap/usb.c b/arch/arm/mach-omap/usb.c index 7f37857..fd483ff 100644 --- a/arch/arm/mach-omap/usb.c +++ b/arch/arm/mach-omap/usb.c @@ -41,7 +41,6 @@ /* These routines should handle the standard chip-specific modes * for usb0/1/2 ports, covering basic mux and transceiver setup. - * Call omap_usb_init() once, from INIT_MACHINE(). * * Some board-*.c files will need to set up additional mux options, * like for suspend handling, vbus sensing, GPIOs, and the D+ pullup. diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index f691cf7..276431b 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -287,34 +287,40 @@ static void __init corgi_map_io(void) #ifdef CONFIG_MACH_CORGI MACHINE_START(CORGI, "SHARP Corgi") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif #ifdef CONFIG_MACH_SHEPHERD MACHINE_START(SHEPHERD, "SHARP Shepherd") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif #ifdef CONFIG_MACH_HUSKY MACHINE_START(HUSKY, "SHARP Husky") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_corgi) - MAPIO(corgi_map_io) - INITIRQ(corgi_init_irq) - .init_machine = corgi_init, - .timer = &pxa_timer, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .fixup = fixup_corgi, + .map_io = corgi_map_io, + .init_irq = corgi_init_irq, + .init_machine = corgi_init, + .timer = &pxa_timer, MACHINE_END #endif diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index c5a66bf..f82f5aa 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -181,10 +181,12 @@ static void __init idp_map_io(void) MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") - MAINTAINER("Vibren Technologies") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(idp_map_io) - INITIRQ(idp_init_irq) + /* Maintainer: Vibren Technologies */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .map_io = idp_map_io, + .init_irq = idp_init_irq, .timer = &pxa_timer, - INIT_MACHINE(idp_init) + .init_machine = idp_init, MACHINE_END diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index f2c9e0d..e30b7c6 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -268,10 +268,12 @@ static void __init lubbock_map_io(void) } MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(lubbock_map_io) - INITIRQ(lubbock_init_irq) + /* Maintainer: MontaVista Software Inc. */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .map_io = lubbock_map_io, + .init_irq = lubbock_init_irq, .timer = &pxa_timer, - INIT_MACHINE(lubbock_init) + .init_machine = lubbock_init, MACHINE_END diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 9896afc..5d2f76b 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -345,10 +345,12 @@ static void __init mainstone_map_io(void) } MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") - MAINTAINER("MontaVista Software Inc.") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - MAPIO(mainstone_map_io) - INITIRQ(mainstone_init_irq) + /* Maintainer: MontaVista Software Inc. */ + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .map_io = mainstone_map_io, + .init_irq = mainstone_init_irq, .timer = &pxa_timer, - INIT_MACHINE(mainstone_init) + .init_machine = mainstone_init, MACHINE_END diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index b6c746e..ebae969 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -180,10 +180,12 @@ static void __init poodle_map_io(void) } MACHINE_START(POODLE, "SHARP Poodle") - BOOT_MEM(0xa0000000, 0x40000000, io_p2v(0x40000000)) - FIXUP(fixup_poodle) - MAPIO(poodle_map_io) - INITIRQ(pxa_init_irq) - .timer = &pxa_timer, - .init_machine = poodle_init, + .phys_ram = 0xa0000000, + .phys_io = 0x40000000, + .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .fixup = fixup_poodle, + .map_io = poodle_map_io, + .init_irq = pxa_init_irq, + .timer = &pxa_timer, + .init_machine = poodle_init, MACHINE_END diff --git a/arch/arm/mach-rpc/riscpc.c b/arch/arm/mach-rpc/riscpc.c index 4371068..a102686 100644 --- a/arch/arm/mach-rpc/riscpc.c +++ b/arch/arm/mach-rpc/riscpc.c @@ -163,12 +163,14 @@ arch_initcall(rpc_init); extern struct sys_timer ioc_timer; MACHINE_START(RISCPC, "Acorn-RiscPC") - MAINTAINER("Russell King") - BOOT_MEM(0x10000000, 0x03000000, 0xe0000000) - BOOT_PARAMS(0x10000100) - DISABLE_PARPORT(0) - DISABLE_PARPORT(1) - MAPIO(rpc_map_io) - INITIRQ(rpc_init_irq) + /* Maintainer: Russell King */ + .phys_ram = 0x10000000, + .phys_io = 0x03000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x10000100, + .reserve_lp0 = 1, + .reserve_lp1 = 1, + .map_io = rpc_map_io, + .init_irq = rpc_init_irq, .timer = &ioc_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c index 549bcb1..ccb6bce 100644 --- a/arch/arm/mach-s3c2410/mach-bast.c +++ b/arch/arm/mach-s3c2410/mach-bast.c @@ -407,10 +407,11 @@ void __init bast_map_io(void) MACHINE_START(BAST, "Simtec-BAST") - MAINTAINER("Ben Dooks ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - + /* Maintainer: Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = bast_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index 2924afc..ea4fb1a 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -117,10 +117,12 @@ void __init h1940_init_irq(void) } MACHINE_START(H1940, "IPAQ-H1940") - MAINTAINER("Ben Dooks ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(h1940_map_io) - INITIRQ(h1940_init_irq) + /* Maintainer: Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = h1940_map_io, + .init_irq = h1940_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c index bd15998..79044d9 100644 --- a/arch/arm/mach-s3c2410/mach-n30.c +++ b/arch/arm/mach-s3c2410/mach-n30.c @@ -137,10 +137,11 @@ void __init n30_init(void) } MACHINE_START(N30, "Acer-N30") - MAINTAINER("Christer Weinigel , Ben Dooks ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - + /* Maintainer: Christer Weinigel , Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .timer = &s3c24xx_timer, .init_machine = n30_init, .init_irq = n30_init_irq, diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2410/mach-nexcoder.c index 70487bf..d24c242 100644 --- a/arch/arm/mach-s3c2410/mach-nexcoder.c +++ b/arch/arm/mach-s3c2410/mach-nexcoder.c @@ -147,9 +147,11 @@ void __init nexcoder_map_io(void) MACHINE_START(NEXCODER_2440, "NexVision - Nexcoder 2440") - MAINTAINER("Guillaume GOURAT ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Guillaume GOURAT */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = nexcoder_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c index 67d8ce8..d901ed4 100644 --- a/arch/arm/mach-s3c2410/mach-otom.c +++ b/arch/arm/mach-s3c2410/mach-otom.c @@ -115,9 +115,11 @@ void __init otom11_map_io(void) MACHINE_START(OTOM, "Nex Vision - Otom 1.1") - MAINTAINER("Guillaume GOURAT ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Guillaume GOURAT */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = otom11_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2410/mach-rx3715.c index f8d3a97..a73d61c 100644 --- a/arch/arm/mach-s3c2410/mach-rx3715.c +++ b/arch/arm/mach-s3c2410/mach-rx3715.c @@ -131,11 +131,13 @@ static void __init rx3715_init_machine(void) #endif MACHINE_START(RX3715, "IPAQ-RX3715") - MAINTAINER("Ben Dooks ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(rx3715_map_io) - INITIRQ(rx3715_init_irq) - INIT_MACHINE(rx3715_init_machine) + /* Maintainer: Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = rx3715_map_io, + .init_irq = rx3715_init_irq, + .init_machine = rx3715_init_machine, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c index c1a4a14..67e903a 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2410.c +++ b/arch/arm/mach-s3c2410/mach-smdk2410.c @@ -112,11 +112,13 @@ void __init smdk2410_init_irq(void) MACHINE_START(SMDK2410, "SMDK2410") /* @TODO: request a new identifier and switch * to SMDK2410 */ - MAINTAINER("Jonas Dietsche") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) - MAPIO(smdk2410_map_io) - INITIRQ(smdk2410_init_irq) + /* Maintainer: Jonas Dietsche */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, + .map_io = smdk2410_map_io, + .init_irq = smdk2410_init_irq, .timer = &s3c24xx_timer, MACHINE_END diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2410/mach-smdk2440.c index 7857176..3575221 100644 --- a/arch/arm/mach-s3c2410/mach-smdk2440.c +++ b/arch/arm/mach-s3c2410/mach-smdk2440.c @@ -124,9 +124,11 @@ void __init smdk2440_machine_init(void) } MACHINE_START(S3C2440, "SMDK2440") - MAINTAINER("Ben Dooks ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .init_irq = s3c24xx_init_irq, .map_io = smdk2440_map_io, diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c index 1db2855..924e846 100644 --- a/arch/arm/mach-s3c2410/mach-vr1000.c +++ b/arch/arm/mach-s3c2410/mach-vr1000.c @@ -373,9 +373,11 @@ void __init vr1000_map_io(void) MACHINE_START(VR1000, "Thorcom-VR1000") - MAINTAINER("Ben Dooks ") - BOOT_MEM(S3C2410_SDRAM_PA, S3C2410_PA_UART, (u32)S3C24XX_VA_UART) - BOOT_PARAMS(S3C2410_SDRAM_PA + 0x100) + /* Maintainer: Ben Dooks */ + .phys_ram = S3C2410_SDRAM_PA, + .phys_io = S3C2410_PA_UART, + .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc, + .boot_params = S3C2410_SDRAM_PA + 0x100, .map_io = vr1000_map_io, .init_irq = s3c24xx_init_irq, .timer = &s3c24xx_timer, diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c index bedf88f..4d4d303 100644 --- a/arch/arm/mach-sa1100/assabet.c +++ b/arch/arm/mach-sa1100/assabet.c @@ -431,11 +431,13 @@ static void __init assabet_map_io(void) MACHINE_START(ASSABET, "Intel-Assabet") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - FIXUP(fixup_assabet) - MAPIO(assabet_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .fixup = fixup_assabet, + .map_io = assabet_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = assabet_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/badge4.c b/arch/arm/mach-sa1100/badge4.c index 6a60b49..b6169cb 100644 --- a/arch/arm/mach-sa1100/badge4.c +++ b/arch/arm/mach-sa1100/badge4.c @@ -285,9 +285,11 @@ static void __init badge4_map_io(void) } MACHINE_START(BADGE4, "Hewlett-Packard Laboratories BadgePAD 4") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(badge4_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = badge4_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c index f8edde5..0aa918e 100644 --- a/arch/arm/mach-sa1100/cerf.c +++ b/arch/arm/mach-sa1100/cerf.c @@ -123,10 +123,12 @@ static void __init cerf_init(void) } MACHINE_START(CERF, "Intrinsyc CerfBoard/CerfCube") - MAINTAINER("support@intrinsyc.com") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(cerf_map_io) - INITIRQ(cerf_init_irq) + /* Maintainer: support@intrinsyc.com */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = cerf_map_io, + .init_irq = cerf_init_irq, .timer = &sa1100_timer, .init_machine = cerf_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c index 9928789..8cb6911 100644 --- a/arch/arm/mach-sa1100/collie.c +++ b/arch/arm/mach-sa1100/collie.c @@ -184,9 +184,11 @@ static void __init collie_map_io(void) } MACHINE_START(COLLIE, "Sharp-Collie") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(collie_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = collie_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = collie_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c index 65dbe99..e7aa2681 100644 --- a/arch/arm/mach-sa1100/h3600.c +++ b/arch/arm/mach-sa1100/h3600.c @@ -380,10 +380,12 @@ static void __init h3100_map_io(void) } MACHINE_START(H3100, "Compaq iPAQ H3100") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3100_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3100_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END @@ -496,10 +498,12 @@ static void __init h3600_map_io(void) } MACHINE_START(H3600, "Compaq iPAQ H3600") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3600_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3600_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END @@ -881,10 +885,12 @@ static void __init h3800_map_io(void) } MACHINE_START(H3800, "Compaq iPAQ H3800") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(h3800_map_io) - INITIRQ(h3800_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = h3800_map_io, + .init_irq = h3800_init_irq, .timer = &sa1100_timer, .init_machine = h3xxx_mach_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/hackkit.c b/arch/arm/mach-sa1100/hackkit.c index 5708417..502d65c 100644 --- a/arch/arm/mach-sa1100/hackkit.c +++ b/arch/arm/mach-sa1100/hackkit.c @@ -191,10 +191,12 @@ static void __init hackkit_init(void) */ MACHINE_START(HACKKIT, "HackKit Cpu Board") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(hackkit_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = hackkit_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = hackkit_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c index 6be7829..eee3cbc 100644 --- a/arch/arm/mach-sa1100/jornada720.c +++ b/arch/arm/mach-sa1100/jornada720.c @@ -97,9 +97,11 @@ static void __init jornada720_map_io(void) } MACHINE_START(JORNADA720, "HP Jornada 720") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(jornada720_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = jornada720_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c index 51c08cc..870b488 100644 --- a/arch/arm/mach-sa1100/lart.c +++ b/arch/arm/mach-sa1100/lart.c @@ -41,9 +41,11 @@ static void __init lart_map_io(void) } MACHINE_START(LART, "LART") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(lart_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = lart_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c index 5606bd7..e17b58f 100644 --- a/arch/arm/mach-sa1100/pleb.c +++ b/arch/arm/mach-sa1100/pleb.c @@ -146,9 +146,11 @@ static void __init pleb_map_io(void) } MACHINE_START(PLEB, "PLEB") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - MAPIO(pleb_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .map_io = pleb_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = pleb_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c index edddd55..43a0035 100644 --- a/arch/arm/mach-sa1100/shannon.c +++ b/arch/arm/mach-sa1100/shannon.c @@ -76,10 +76,12 @@ static void __init shannon_map_io(void) } MACHINE_START(SHANNON, "Shannon (AKA: Tuxscreen)") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(shannon_map_io) - INITIRQ(sa1100_init_irq) + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = shannon_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, .init_machine = shannon_init, MACHINE_END diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c index 8d113d6..7797858 100644 --- a/arch/arm/mach-sa1100/simpad.c +++ b/arch/arm/mach-sa1100/simpad.c @@ -215,10 +215,12 @@ arch_initcall(simpad_init); MACHINE_START(SIMPAD, "Simpad") - MAINTAINER("Holger Freyther") - BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000) - BOOT_PARAMS(0xc0000100) - MAPIO(simpad_map_io) - INITIRQ(sa1100_init_irq) + /* Maintainer: Holger Freyther */ + .phys_ram = 0xc0000000, + .phys_io = 0x80000000, + .io_pg_offst = ((0xf8000000) >> 18) & 0xfffc, + .boot_params = 0xc0000100, + .map_io = simpad_map_io, + .init_irq = sa1100_init_irq, .timer = &sa1100_timer, MACHINE_END diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index aa0e2f6..7264458 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -105,10 +105,12 @@ static struct sys_timer shark_timer = { }; MACHINE_START(SHARK, "Shark") - MAINTAINER("Alexander Schulz") - BOOT_MEM(0x08000000, 0x40000000, 0xe0000000) - BOOT_PARAMS(0x08003000) - MAPIO(shark_map_io) - INITIRQ(shark_init_irq) + /* Maintainer: Alexander Schulz */ + .phys_ram = 0x08000000, + .phys_io = 0x40000000, + .io_pg_offst = ((0xe0000000) >> 18) & 0xfffc, + .boot_params = 0x08003000, + .map_io = shark_map_io, + .init_irq = shark_init_irq, .timer = &shark_timer, MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_ab.c b/arch/arm/mach-versatile/versatile_ab.c index d332084..8b0b3be 100644 --- a/arch/arm/mach-versatile/versatile_ab.c +++ b/arch/arm/mach-versatile/versatile_ab.c @@ -35,11 +35,13 @@ #include "core.h" MACHINE_START(VERSATILE_AB, "ARM-Versatile AB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x101f1000, + .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = versatile_map_io, + .init_irq = versatile_init_irq, .timer = &versatile_timer, - INIT_MACHINE(versatile_init) + .init_machine = versatile_init, MACHINE_END diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c index 2702099..7c3078c 100644 --- a/arch/arm/mach-versatile/versatile_pb.c +++ b/arch/arm/mach-versatile/versatile_pb.c @@ -99,11 +99,13 @@ static int __init versatile_pb_init(void) arch_initcall(versatile_pb_init); MACHINE_START(VERSATILE_PB, "ARM-Versatile PB") - MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd") - BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000) - BOOT_PARAMS(0x00000100) - MAPIO(versatile_map_io) - INITIRQ(versatile_init_irq) + /* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */ + .phys_ram = 0x00000000, + .phys_io = 0x101f1000, + .io_pg_offst = ((0xf11f1000) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = versatile_map_io, + .init_irq = versatile_init_irq, .timer = &versatile_timer, - INIT_MACHINE(versatile_init) + .init_machine = versatile_init, MACHINE_END diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index 3a32e92..a2fbb65 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -54,38 +54,6 @@ const struct machine_desc __mach_desc_##_type \ .nr = MACH_TYPE_##_type, \ .name = _name, -#define MAINTAINER(n) - -#define BOOT_MEM(_pram,_pio,_vio) \ - .phys_ram = _pram, \ - .phys_io = _pio, \ - .io_pg_offst = ((_vio)>>18)&0xfffc, - -#define BOOT_PARAMS(_params) \ - .param_offset = _params, - -#define VIDEO(_start,_end) \ - .video_start = _start, \ - .video_end = _end, - -#define DISABLE_PARPORT(_n) \ - .reserve_lp##_n = 1, - -#define SOFT_REBOOT \ - .soft_reboot = 1, - -#define FIXUP(_func) \ - .fixup = _func, - -#define MAPIO(_func) \ - .map_io = _func, - -#define INITIRQ(_func) \ - .init_irq = _func, - -#define INIT_MACHINE(_func) \ - .init_machine = _func, - #define MACHINE_END \ }; -- cgit v1.1 From 75f631dc45c7327df26b82b9aea69376a306409c Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Sun, 3 Jul 2005 17:44:40 +0100 Subject: [PATCH] ARM: 2785/1: S3C24XX - serial calls request_irq() with IRQs disabled Patch from Ben Dooks The request_irq() function is called by s3c24xx uart driver with the local IRQs disabled. The request_irq() function can allocate memory via kmalloc(), and this may sleep causing a warning about sleeping in an invalid context. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- drivers/serial/s3c2410.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 5c46784..7365d4b 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c @@ -522,14 +522,11 @@ static void s3c24xx_serial_shutdown(struct uart_port *port) static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); - unsigned long flags; int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); - local_irq_save(flags); - rx_enabled(port) = 1; ret = request_irq(RX_IRQ(port), @@ -563,12 +560,10 @@ static int s3c24xx_serial_startup(struct uart_port *port) /* the port reset code should have done the correct * register setup for the port controls */ - local_irq_restore(flags); return ret; err: s3c24xx_serial_shutdown(port); - local_irq_restore(flags); return ret; } -- cgit v1.1 From 0d670b413f042eccdffc45bafb9840244752707f Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Sun, 3 Jul 2005 17:53:25 +0100 Subject: [PATCH] ARM: 2784/1: Fix the block cache flush operation range Patch from Catalin Marinas The range for the ARMv6 block cache operations is inclusive but the kernel doesn't re-calculate the end address, causing a page fault when used (this only happens with support for cache aliasing, otherwise the blk_flush_kern_dcache_page() is not called). This patch subtracts L1_CACHE_BYTES from the end address. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/blockops.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/arm/mm/blockops.c b/arch/arm/mm/blockops.c index 806c6ee..4f5ee2d 100644 --- a/arch/arm/mm/blockops.c +++ b/arch/arm/mm/blockops.c @@ -25,13 +25,14 @@ blk_flush_kern_dcache_page(void *kaddr) { asm( "add r1, r0, %0 \n\ + sub r1, r1, %1 \n\ 1: .word 0xec401f0e @ mcrr p15, 0, r0, r1, c14, 0 @ blocking \n\ mov r0, #0 \n\ mcr p15, 0, r0, c7, c5, 0 \n\ mcr p15, 0, r0, c7, c10, 4 \n\ mov pc, lr" : - : "I" (PAGE_SIZE)); + : "I" (PAGE_SIZE), "I" (L1_CACHE_BYTES)); } /* -- cgit v1.1 From 976ecd12b8144d066a23fe97c6fbfc1ac8470af7 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 3 Jul 2005 21:05:45 +0100 Subject: [PATCH] Serial: Fix console port spinlock initialisation Initialise the spinlock for port being used by the console early, but don't re-initialise it again later. Signed-off-by: Russell King --- drivers/serial/serial_core.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 139863a..54699c3 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1808,6 +1808,12 @@ uart_set_options(struct uart_port *port, struct console *co, struct termios termios; int i; + /* + * Ensure that the serial console lock is initialised + * early. + */ + spin_lock_init(&port->lock); + memset(&termios, 0, sizeof(struct termios)); termios.c_cflag = CREAD | HUPCL | CLOCAL; @@ -2196,10 +2202,16 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port) state->port = port; - spin_lock_init(&port->lock); port->cons = drv->cons; port->info = state->info; + /* + * If this port is a console, then the spinlock is already + * initialised. + */ + if (!uart_console(port)) + spin_lock_init(&port->lock); + uart_configure_port(drv, state, port); /* -- cgit v1.1 From f9bd6ea446946b97208f9e1528eb5f9ef8f931cb Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Jul 2005 10:43:36 +0100 Subject: [PATCH] ARM: Change 'param_offset' to 'boot_params' Signed-off-by: Russell King --- arch/arm/kernel/setup.c | 4 ++-- include/asm-arm/mach/arch.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 35b7273..c9b6977 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -737,8 +737,8 @@ void __init setup_arch(char **cmdline_p) if (mdesc->soft_reboot) reboot_setup("s"); - if (mdesc->param_offset) - tags = phys_to_virt(mdesc->param_offset); + if (mdesc->boot_params) + tags = phys_to_virt(mdesc->boot_params); /* * If we have the old style parameters, convert them to diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h index a2fbb65..56c6bf4 100644 --- a/include/asm-arm/mach/arch.h +++ b/include/asm-arm/mach/arch.h @@ -26,7 +26,7 @@ struct machine_desc { * page tabe entry */ const char *name; /* architecture name */ - unsigned int param_offset; /* parameter page */ + unsigned long boot_params; /* tagged list */ unsigned int video_start; /* start of video RAM */ unsigned int video_end; /* end of video RAM */ -- cgit v1.1 From 68070bdeeca7b7af6a42c0b3e5b1247e83c22ff9 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Jul 2005 10:44:34 +0100 Subject: [PATCH] ARM: Fix non-standard PXA io_pg_offst initialisers These didn't match my sed expression correctly, fix them up manually. Signed-off-by: Russell King --- arch/arm/mach-pxa/corgi.c | 6 +++--- arch/arm/mach-pxa/idp.c | 2 +- arch/arm/mach-pxa/lubbock.c | 2 +- arch/arm/mach-pxa/mainstone.c | 2 +- arch/arm/mach-pxa/poodle.c | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 276431b..86b862f 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -289,7 +289,7 @@ static void __init corgi_map_io(void) MACHINE_START(CORGI, "SHARP Corgi") .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_corgi, .map_io = corgi_map_io, .init_irq = corgi_init_irq, @@ -302,7 +302,7 @@ MACHINE_END MACHINE_START(SHEPHERD, "SHARP Shepherd") .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_corgi, .map_io = corgi_map_io, .init_irq = corgi_init_irq, @@ -315,7 +315,7 @@ MACHINE_END MACHINE_START(HUSKY, "SHARP Husky") .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_corgi, .map_io = corgi_map_io, .init_irq = corgi_init_irq, diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c index f82f5aa..386e107 100644 --- a/arch/arm/mach-pxa/idp.c +++ b/arch/arm/mach-pxa/idp.c @@ -184,7 +184,7 @@ MACHINE_START(PXA_IDP, "Vibren PXA255 IDP") /* Maintainer: Vibren Technologies */ .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = idp_map_io, .init_irq = idp_init_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c index e30b7c6..6309853 100644 --- a/arch/arm/mach-pxa/lubbock.c +++ b/arch/arm/mach-pxa/lubbock.c @@ -271,7 +271,7 @@ MACHINE_START(LUBBOCK, "Intel DBPXA250 Development Platform (aka Lubbock)") /* Maintainer: MontaVista Software Inc. */ .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = lubbock_map_io, .init_irq = lubbock_init_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 5d2f76b..827b7b5 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -348,7 +348,7 @@ MACHINE_START(MAINSTONE, "Intel HCDDBBVA0 Development Platform (aka Mainstone)") /* Maintainer: MontaVista Software Inc. */ .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .map_io = mainstone_map_io, .init_irq = mainstone_init_irq, .timer = &pxa_timer, diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index ebae969..0e4f6fa 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -182,7 +182,7 @@ static void __init poodle_map_io(void) MACHINE_START(POODLE, "SHARP Poodle") .phys_ram = 0xa0000000, .phys_io = 0x40000000, - .io_pg_offst = ((io_p2v(0x40000000) >> 18) & 0xfffc,) + .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .fixup = fixup_poodle, .map_io = poodle_map_io, .init_irq = pxa_init_irq, -- cgit v1.1 From 17af691cd19765b782d891fc50c1568d0f1276b3 Mon Sep 17 00:00:00 2001 From: Russell King Date: Mon, 4 Jul 2005 13:02:46 +0100 Subject: [PATCH] ARM: Fix new-ABI layout of struct stat64 Add __attribute__((packed)) to ensure that the stat64 structure is correctly laid out no matter which ABI the kernel is compiled for. Signed-off-by: Russell King --- include/asm-arm/stat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/asm-arm/stat.h b/include/asm-arm/stat.h index ca8e7a8..ec4e2c2 100644 --- a/include/asm-arm/stat.h +++ b/include/asm-arm/stat.h @@ -89,6 +89,6 @@ struct stat64 { unsigned long st_ctime_nsec; unsigned long long st_ino; -}; +} __attribute__((packed)); #endif -- cgit v1.1 From e7270dec080002d8aa18256c756af6c32331ef48 Mon Sep 17 00:00:00 2001 From: Raphael Assenat Date: Mon, 4 Jul 2005 13:23:45 -0700 Subject: [SPARC64/COMPAT]: Add some compat ioctl for ppdev The following patch adds some ioctls to include/linux/compat_ioctl.h to allow using ppdev from the 32 bit user space on sparc64. This patch also adds the PPDEV option in the sparc64 menu, near Parallel printer support in the 'General machine setup' submenu. All those ioctls seem to be compatible, since (correct me if I'm wrong) they dont use the 'long' type. See include/linux/ppdev.h. The application I used to test the new ioctls only used the following: PPEXCL PPCLAIM PPNEGOT PPGETMODES PPRCONTROL PPWCONTROL PPDATADIR PPWDATA PPRDATA But I beleive that the other ioctls will work fine. Signed-off-by: David S. Miller --- arch/sparc64/Kconfig | 18 ++++++++++++++++++ include/linux/compat_ioctl.h | 19 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index e2b050e..d78bc13 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -444,6 +444,24 @@ config PRINTER If you have more than 8 printers, you need to increase the LP_NO macro in lp.c and the PARPORT_MAX macro in parport.h. +config PPDEV + tristate "Support for user-space parallel port device drivers" + depends on PARPORT + ---help--- + Saying Y to this adds support for /dev/parport device nodes. This + is needed for programs that want portable access to the parallel + port, for instance deviceid (which displays Plug-and-Play device + IDs). + + This is the parallel port equivalent of SCSI generic support (sg). + It is safe to say N to this -- it is not needed for normal printing + or parallel port CD-ROM/disk support. + + To compile this driver as a module, choose M here: the + module will be called ppdev. + + If unsure, say N. + config ENVCTRL tristate "SUNW, envctrl support" depends on PCI diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index 70a4ebb..ecb0d39 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -346,10 +346,27 @@ COMPATIBLE_IOCTL(PPPOEIOCDFWD) /* LP */ COMPATIBLE_IOCTL(LPGETSTATUS) /* ppdev */ +COMPATIBLE_IOCTL(PPSETMODE) +COMPATIBLE_IOCTL(PPRSTATUS) +COMPATIBLE_IOCTL(PPRCONTROL) +COMPATIBLE_IOCTL(PPWCONTROL) +COMPATIBLE_IOCTL(PPFCONTROL) +COMPATIBLE_IOCTL(PPRDATA) +COMPATIBLE_IOCTL(PPWDATA) COMPATIBLE_IOCTL(PPCLAIM) COMPATIBLE_IOCTL(PPRELEASE) -COMPATIBLE_IOCTL(PPEXCL) COMPATIBLE_IOCTL(PPYIELD) +COMPATIBLE_IOCTL(PPEXCL) +COMPATIBLE_IOCTL(PPDATADIR) +COMPATIBLE_IOCTL(PPNEGOT) +COMPATIBLE_IOCTL(PPWCTLONIRQ) +COMPATIBLE_IOCTL(PPCLRIRQ) +COMPATIBLE_IOCTL(PPSETPHASE) +COMPATIBLE_IOCTL(PPGETMODES) +COMPATIBLE_IOCTL(PPGETMODE) +COMPATIBLE_IOCTL(PPGETPHASE) +COMPATIBLE_IOCTL(PPGETFLAGS) +COMPATIBLE_IOCTL(PPSETFLAGS) /* CDROM stuff */ COMPATIBLE_IOCTL(CDROMPAUSE) COMPATIBLE_IOCTL(CDROMRESUME) -- cgit v1.1 From 06326e40b7c66477d4a460bfc23c951f7b39f191 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Mon, 4 Jul 2005 13:24:14 -0700 Subject: [SPARC]: bpp: remove sleep_on usage Use schedule_timeout() instead of sleep_on + timer. Totally untested due to lack of hardware, but the changes are rather trivial. Signed-off-by: David S. Miller --- drivers/sbus/char/bpp.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index 8f0f469..87302fb 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -79,10 +79,6 @@ struct inst { unsigned char run_length; unsigned char repeat_byte; - - /* These members manage timeouts for programmed delays */ - wait_queue_head_t wait_queue; - struct timer_list timer_list; }; static struct inst instances[BPP_NO]; @@ -297,16 +293,10 @@ static unsigned short get_pins(unsigned minor) #endif /* __sparc__ */ -static void bpp_wake_up(unsigned long val) -{ wake_up(&instances[val].wait_queue); } - static void snooze(unsigned long snooze_time, unsigned minor) { - init_timer(&instances[minor].timer_list); - instances[minor].timer_list.expires = jiffies + snooze_time + 1; - instances[minor].timer_list.data = minor; - add_timer(&instances[minor].timer_list); - sleep_on (&instances[minor].wait_queue); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(snooze_time + 1); } static int wait_for(unsigned short set, unsigned short clr, @@ -880,11 +870,8 @@ static void probeLptPort(unsigned idx) instances[idx].enhanced = 0; instances[idx].direction = 0; instances[idx].mode = COMPATIBILITY; - instances[idx].wait_queue = 0; instances[idx].run_length = 0; instances[idx].run_flag = 0; - init_timer(&instances[idx].timer_list); - instances[idx].timer_list.function = bpp_wake_up; if (!request_region(lpAddr,3, dev_name)) return; /* @@ -977,11 +964,8 @@ static void probeLptPort(unsigned idx) instances[idx].enhanced = 0; instances[idx].direction = 0; instances[idx].mode = COMPATIBILITY; - init_waitqueue_head(&instances[idx].wait_queue); instances[idx].run_length = 0; instances[idx].run_flag = 0; - init_timer(&instances[idx].timer_list); - instances[idx].timer_list.function = bpp_wake_up; if (!rp) return; -- cgit v1.1 From 088dd1f81b3577c17c4c4381696bf2105ea0e43a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 13:24:38 -0700 Subject: [SPARC64]: Add support for IRQ pre-handlers. This allows a PCI controller to shim into IRQ delivery so that DMA queues can be drained, if necessary. If some bus specific code needs to run before an IRQ handler is invoked, the bus driver simply needs to setup the function pointer in bucket->irq_info->pre_handler and the two args bucket->irq_info->pre_handler_arg[12]. The Schizo PCI driver is converted over to use a pre-handler for the DMA write-sync processing it needs when a device is behind a PCI->PCI bus deeper than the top-level APB bridges. While we're here, clean up all of the action allocation and handling. Now, we allocate the irqaction as part of the bucket->irq_info area. There is an array of 4 irqaction (for PCI irq sharing) and a bitmask saying which entries are active. The bucket->irq_info is allocated at build_irq() time, not at request_irq() time. This simplifies request_irq() and free_irq() tremendously. The SMP dynamic IRQ retargetting code got removed in this change too. It was disabled for a few months now, and we can resurrect it in the future if we want. Signed-off-by: David S. Miller --- arch/sparc64/kernel/entry.S | 21 +- arch/sparc64/kernel/irq.c | 581 ++++++++++++++-------------------------- arch/sparc64/kernel/pci_sabre.c | 46 ++-- arch/sparc64/kernel/time.c | 2 +- include/asm-sparc64/irq.h | 49 ++-- include/asm-sparc64/signal.h | 15 -- 6 files changed, 247 insertions(+), 467 deletions(-) diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index eee516a..d3973d8 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -553,13 +553,11 @@ do_ivec: sllx %g3, 5, %g3 or %g2, %lo(ivector_table), %g2 add %g2, %g3, %g3 - ldx [%g3 + 0x08], %g2 /* irq_info */ ldub [%g3 + 0x04], %g4 /* pil */ - brz,pn %g2, do_ivec_spurious - mov 1, %g2 - + mov 1, %g2 sllx %g2, %g4, %g2 sllx %g4, 2, %g4 + lduw [%g6 + %g4], %g5 /* g5 = irq_work(cpu, pil) */ stw %g5, [%g3 + 0x00] /* bucket->irq_chain = g5 */ stw %g3, [%g6 + %g4] /* irq_work(cpu, pil) = bucket */ @@ -567,9 +565,9 @@ do_ivec: retry do_ivec_xcall: mov 0x50, %g1 - ldxa [%g1 + %g0] ASI_INTR_R, %g1 srl %g3, 0, %g3 + mov 0x60, %g7 ldxa [%g7 + %g0] ASI_INTR_R, %g7 stxa %g0, [%g0] ASI_INTR_RECEIVE @@ -581,19 +579,6 @@ do_ivec_xcall: 1: jmpl %g3, %g0 nop -do_ivec_spurious: - stw %g3, [%g6 + 0x00] /* irq_work(cpu, 0) = bucket */ - rdpr %pstate, %g5 - - wrpr %g5, PSTATE_IG | PSTATE_AG, %pstate - sethi %hi(109f), %g7 - ba,pt %xcc, etrap -109: or %g7, %lo(109b), %g7 - call catch_disabled_ivec - add %sp, PTREGS_OFF, %o0 - ba,pt %xcc, rtrap - clr %l6 - .globl save_alternate_globals save_alternate_globals: /* %o0 = save_area */ rdpr %pstate, %o5 diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 4247125..74a2e08 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -71,31 +71,7 @@ struct irq_work_struct { struct irq_work_struct __irq_work[NR_CPUS]; #define irq_work(__cpu, __pil) &(__irq_work[(__cpu)].irq_worklists[(__pil)]) -#ifdef CONFIG_PCI -/* This is a table of physical addresses used to deal with IBF_DMA_SYNC. - * It is used for PCI only to synchronize DMA transfers with IRQ delivery - * for devices behind busses other than APB on Sabre systems. - * - * Currently these physical addresses are just config space accesses - * to the command register for that device. - */ -unsigned long pci_dma_wsync; -unsigned long dma_sync_reg_table[256]; -unsigned char dma_sync_reg_table_entry = 0; -#endif - -/* This is based upon code in the 32-bit Sparc kernel written mostly by - * David Redman (djhr@tadpole.co.uk). - */ -#define MAX_STATIC_ALLOC 4 -static struct irqaction static_irqaction[MAX_STATIC_ALLOC]; -static int static_irq_count; - -/* This is exported so that fast IRQ handlers can get at it... -DaveM */ -struct irqaction *irq_action[NR_IRQS+1] = { - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL , NULL, NULL -}; +static struct irqaction *irq_action[NR_IRQS+1]; /* This only synchronizes entities which modify IRQ handler * state and some selected user-level spots that want to @@ -241,17 +217,22 @@ void disable_irq(unsigned int irq) * the CPU %tick register and not by some normal vectored interrupt * source. To handle this special case, we use this dummy INO bucket. */ +static struct irq_desc pil0_dummy_desc; static struct ino_bucket pil0_dummy_bucket = { - 0, /* irq_chain */ - 0, /* pil */ - 0, /* pending */ - 0, /* flags */ - 0, /* __unused */ - NULL, /* irq_info */ - 0UL, /* iclr */ - 0UL, /* imap */ + .irq_info = &pil0_dummy_desc, }; +static void build_irq_error(const char *msg, unsigned int ino, int pil, int inofixup, + unsigned long iclr, unsigned long imap, + struct ino_bucket *bucket) +{ + prom_printf("IRQ: INO %04x (%d:%016lx:%016lx) --> " + "(%d:%d:%016lx:%016lx), halting...\n", + ino, bucket->pil, bucket->iclr, bucket->imap, + pil, inofixup, iclr, imap); + prom_halt(); +} + unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long imap) { struct ino_bucket *bucket; @@ -280,28 +261,35 @@ unsigned int build_irq(int pil, int inofixup, unsigned long iclr, unsigned long prom_halt(); } - /* Ok, looks good, set it up. Don't touch the irq_chain or - * the pending flag. - */ bucket = &ivector_table[ino]; - if ((bucket->flags & IBF_ACTIVE) || - (bucket->irq_info != NULL)) { - /* This is a gross fatal error if it happens here. */ - prom_printf("IRQ: Trying to reinit INO bucket, fatal error.\n"); - prom_printf("IRQ: Request INO %04x (%d:%d:%016lx:%016lx)\n", - ino, pil, inofixup, iclr, imap); - prom_printf("IRQ: Existing (%d:%016lx:%016lx)\n", - bucket->pil, bucket->iclr, bucket->imap); - prom_printf("IRQ: Cannot continue, halting...\n"); + if (bucket->flags & IBF_ACTIVE) + build_irq_error("IRQ: Trying to build active INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + if (bucket->irq_info) { + if (bucket->imap != imap || bucket->iclr != iclr) + build_irq_error("IRQ: Trying to reinit INO bucket.\n", + ino, pil, inofixup, iclr, imap, bucket); + + goto out; + } + + bucket->irq_info = kmalloc(sizeof(struct irq_desc), GFP_ATOMIC); + if (!bucket->irq_info) { + prom_printf("IRQ: Error, kmalloc(irq_desc) failed.\n"); prom_halt(); } + memset(bucket->irq_info, 0, sizeof(struct irq_desc)); + + /* Ok, looks good, set it up. Don't touch the irq_chain or + * the pending flag. + */ bucket->imap = imap; bucket->iclr = iclr; bucket->pil = pil; bucket->flags = 0; - bucket->irq_info = NULL; - +out: return __irq(bucket); } @@ -319,26 +307,65 @@ static void atomic_bucket_insert(struct ino_bucket *bucket) __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); } +static int check_irq_sharing(int pil, unsigned long irqflags) +{ + struct irqaction *action, *tmp; + + action = *(irq_action + pil); + if (action) { + if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) { + for (tmp = action; tmp->next; tmp = tmp->next) + ; + } else { + return -EBUSY; + } + } + return 0; +} + +static void append_irq_action(int pil, struct irqaction *action) +{ + struct irqaction **pp = irq_action + pil; + + while (*pp) + pp = &((*pp)->next); + *pp = action; +} + +static struct irqaction *get_action_slot(struct ino_bucket *bucket) +{ + struct irq_desc *desc = bucket->irq_info; + int max_irq, i; + + max_irq = 1; + if (bucket->flags & IBF_PCI) + max_irq = MAX_IRQ_DESC_ACTION; + for (i = 0; i < max_irq; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); + + if (desc->action_active_mask & mask) + continue; + + desc->action_active_mask |= mask; + return p; + } + return NULL; +} + int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char *name, void *dev_id) { - struct irqaction *action, *tmp = NULL; + struct irqaction *action; struct ino_bucket *bucket = __bucket(irq); unsigned long flags; int pending = 0; - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; - - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "request_irq: Old style IRQ registry attempt " - "from %p, irq %08x.\n", caller, irq); + if (unlikely(!handler)) return -EINVAL; - } - if (!handler) - return -EINVAL; + + if (unlikely(!bucket->irq_info)) + return -ENODEV; if ((bucket != &pil0_dummy_bucket) && (irqflags & SA_SAMPLE_RANDOM)) { /* @@ -356,93 +383,20 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ spin_lock_irqsave(&irq_action_lock, flags); - action = *(bucket->pil + irq_action); - if (action) { - if ((action->flags & SA_SHIRQ) && (irqflags & SA_SHIRQ)) - for (tmp = action; tmp->next; tmp = tmp->next) - ; - else { - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - } - action = NULL; /* Or else! */ + if (check_irq_sharing(bucket->pil, irqflags)) { + spin_unlock_irqrestore(&irq_action_lock, flags); + return -EBUSY; } - /* If this is flagged as statically allocated then we use our - * private struct which is never freed. - */ - if (irqflags & SA_STATIC_ALLOC) { - if (static_irq_count < MAX_STATIC_ALLOC) - action = &static_irqaction[static_irq_count++]; - else - printk("Request for IRQ%d (%s) SA_STATIC_ALLOC failed " - "using kmalloc\n", irq, name); - } - if (action == NULL) - action = (struct irqaction *)kmalloc(sizeof(struct irqaction), - GFP_ATOMIC); - + action = get_action_slot(bucket); if (!action) { spin_unlock_irqrestore(&irq_action_lock, flags); return -ENOMEM; } - if (bucket == &pil0_dummy_bucket) { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } else { - if ((bucket->flags & IBF_ACTIVE) != 0) { - void *orig = bucket->irq_info; - void **vector = NULL; - - if ((bucket->flags & IBF_PCI) == 0) { - printk("IRQ: Trying to share non-PCI bucket.\n"); - goto free_and_ebusy; - } - if ((bucket->flags & IBF_MULTI) == 0) { - vector = kmalloc(sizeof(void *) * 4, GFP_ATOMIC); - if (vector == NULL) - goto free_and_enomem; - - /* We might have slept. */ - if ((bucket->flags & IBF_MULTI) != 0) { - int ent; - - kfree(vector); - vector = (void **)bucket->irq_info; - for(ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } else { - vector[0] = orig; - vector[1] = action; - vector[2] = NULL; - vector[3] = NULL; - bucket->irq_info = vector; - bucket->flags |= IBF_MULTI; - } - } else { - int ent; - - vector = (void **)orig; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == NULL) { - vector[ent] = action; - break; - } - } - if (ent == 4) - goto free_and_ebusy; - } - } else { - bucket->irq_info = action; - bucket->flags |= IBF_ACTIVE; - } + bucket->flags |= IBF_ACTIVE; + pending = 0; + if (bucket != &pil0_dummy_bucket) { pending = bucket->pending; if (pending) bucket->pending = 0; @@ -456,10 +410,7 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ put_ino_in_irqaction(action, irq); put_smpaff_in_irqaction(action, CPU_MASK_NONE); - if (tmp) - tmp->next = action; - else - *(bucket->pil + irq_action) = action; + append_irq_action(bucket->pil, action); enable_irq(irq); @@ -468,147 +419,103 @@ int request_irq(unsigned int irq, irqreturn_t (*handler)(int, void *, struct pt_ atomic_bucket_insert(bucket); set_softint(1 << bucket->pil); } + spin_unlock_irqrestore(&irq_action_lock, flags); - if ((bucket != &pil0_dummy_bucket) && (!(irqflags & SA_STATIC_ALLOC))) + + if (bucket != &pil0_dummy_bucket) register_irq_proc(__irq_ino(irq)); #ifdef CONFIG_SMP distribute_irqs(); #endif return 0; - -free_and_ebusy: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -EBUSY; - -free_and_enomem: - kfree(action); - spin_unlock_irqrestore(&irq_action_lock, flags); - return -ENOMEM; } EXPORT_SYMBOL(request_irq); -void free_irq(unsigned int irq, void *dev_id) +static struct irqaction *unlink_irq_action(unsigned int irq, void *dev_id) { - struct irqaction *action; - struct irqaction *tmp = NULL; - unsigned long flags; - struct ino_bucket *bucket = __bucket(irq), *bp; - - if ((bucket != &pil0_dummy_bucket) && - (bucket < &ivector_table[0] || - bucket >= &ivector_table[NUM_IVECS])) { - unsigned int *caller; + struct ino_bucket *bucket = __bucket(irq); + struct irqaction *action, **pp; - __asm__ __volatile__("mov %%i7, %0" : "=r" (caller)); - printk(KERN_CRIT "free_irq: Old style IRQ removal attempt " - "from %p, irq %08x.\n", caller, irq); - return; - } - - spin_lock_irqsave(&irq_action_lock, flags); + pp = irq_action + bucket->pil; + action = *pp; + if (unlikely(!action)) + return NULL; - action = *(bucket->pil + irq_action); - if (!action->handler) { + if (unlikely(!action->handler)) { printk("Freeing free IRQ %d\n", bucket->pil); - return; - } - if (dev_id) { - for ( ; action; action = action->next) { - if (action->dev_id == dev_id) - break; - tmp = action; - } - if (!action) { - printk("Trying to free free shared IRQ %d\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; - } - } else if (action->flags & SA_SHIRQ) { - printk("Trying to free shared IRQ %d with NULL device ID\n", bucket->pil); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + return NULL; } - if (action->flags & SA_STATIC_ALLOC) { - printk("Attempt to free statically allocated IRQ %d (%s)\n", - bucket->pil, action->name); - spin_unlock_irqrestore(&irq_action_lock, flags); - return; + while (action && action->dev_id != dev_id) { + pp = &action->next; + action = *pp; } - if (action && tmp) - tmp->next = action->next; - else - *(bucket->pil + irq_action) = action->next; + if (likely(action)) + *pp = action->next; + + return action; +} + +void free_irq(unsigned int irq, void *dev_id) +{ + struct irqaction *action; + struct ino_bucket *bucket; + unsigned long flags; + + spin_lock_irqsave(&irq_action_lock, flags); + + action = unlink_irq_action(irq, dev_id); spin_unlock_irqrestore(&irq_action_lock, flags); + if (unlikely(!action)) + return; + synchronize_irq(irq); spin_lock_irqsave(&irq_action_lock, flags); + bucket = __bucket(irq); if (bucket != &pil0_dummy_bucket) { + struct irq_desc *desc = bucket->irq_info; unsigned long imap = bucket->imap; - void **vector, *orig; - int ent; - - orig = bucket->irq_info; - vector = (void **)orig; - - if ((bucket->flags & IBF_MULTI) != 0) { - int other = 0; - void *orphan = NULL; - for (ent = 0; ent < 4; ent++) { - if (vector[ent] == action) - vector[ent] = NULL; - else if (vector[ent] != NULL) { - orphan = vector[ent]; - other++; - } - } + int ent, i; - /* Only free when no other shared irq - * uses this bucket. - */ - if (other) { - if (other == 1) { - /* Convert back to non-shared bucket. */ - bucket->irq_info = orphan; - bucket->flags &= ~(IBF_MULTI); - kfree(vector); - } - goto out; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + + if (p == action) { + desc->action_active_mask &= ~(1 << i); + break; } - } else { - bucket->irq_info = NULL; } - /* This unique interrupt source is now inactive. */ - bucket->flags &= ~IBF_ACTIVE; + if (!desc->action_active_mask) { + /* This unique interrupt source is now inactive. */ + bucket->flags &= ~IBF_ACTIVE; - /* See if any other buckets share this bucket's IMAP - * and are still active. - */ - for (ent = 0; ent < NUM_IVECS; ent++) { - bp = &ivector_table[ent]; - if (bp != bucket && - bp->imap == imap && - (bp->flags & IBF_ACTIVE) != 0) - break; - } + /* See if any other buckets share this bucket's IMAP + * and are still active. + */ + for (ent = 0; ent < NUM_IVECS; ent++) { + struct ino_bucket *bp = &ivector_table[ent]; + if (bp != bucket && + bp->imap == imap && + (bp->flags & IBF_ACTIVE) != 0) + break; + } - /* Only disable when no other sub-irq levels of - * the same IMAP are active. - */ - if (ent == NUM_IVECS) - disable_irq(irq); + /* Only disable when no other sub-irq levels of + * the same IMAP are active. + */ + if (ent == NUM_IVECS) + disable_irq(irq); + } } -out: - kfree(action); spin_unlock_irqrestore(&irq_action_lock, flags); } @@ -647,99 +554,55 @@ void synchronize_irq(unsigned int irq) } #endif /* CONFIG_SMP */ -void catch_disabled_ivec(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - struct ino_bucket *bucket = __bucket(*irq_work(cpu, 0)); - - /* We can actually see this on Ultra/PCI PCI cards, which are bridges - * to other devices. Here a single IMAP enabled potentially multiple - * unique interrupt sources (which each do have a unique ICLR register. - * - * So what we do is just register that the IVEC arrived, when registered - * for real the request_irq() code will check the bit and signal - * a local CPU interrupt for it. - */ -#if 0 - printk("IVEC: Spurious interrupt vector (%x) received at (%016lx)\n", - bucket - &ivector_table[0], regs->tpc); -#endif - *irq_work(cpu, 0) = 0; - bucket->pending = 1; -} - -/* Tune this... */ -#define FORWARD_VOLUME 12 - -#ifdef CONFIG_SMP - -static inline void redirect_intr(int cpu, struct ino_bucket *bp) +static void process_bucket(int irq, struct ino_bucket *bp, struct pt_regs *regs) { - /* Ok, here is what is going on: - * 1) Retargeting IRQs on Starfire is very - * expensive so just forget about it on them. - * 2) Moving around very high priority interrupts - * is a losing game. - * 3) If the current cpu is idle, interrupts are - * useful work, so keep them here. But do not - * pass to our neighbour if he is not very idle. - * 4) If sysadmin explicitly asks for directed intrs, - * Just Do It. - */ - struct irqaction *ap = bp->irq_info; - cpumask_t cpu_mask; - unsigned int buddy, ticks; + struct irq_desc *desc = bp->irq_info; + unsigned char flags = bp->flags; + u32 action_mask, i; + int random; - cpu_mask = get_smpaff_in_irqaction(ap); - cpus_and(cpu_mask, cpu_mask, cpu_online_map); - if (cpus_empty(cpu_mask)) - cpu_mask = cpu_online_map; + bp->flags |= IBF_INPROGRESS; - if (this_is_starfire != 0 || - bp->pil >= 10 || current->pid == 0) + if (unlikely(!(flags & IBF_ACTIVE))) { + bp->pending = 1; goto out; - - /* 'cpu' is the MID (ie. UPAID), calculate the MID - * of our buddy. - */ - buddy = cpu + 1; - if (buddy >= NR_CPUS) - buddy = 0; - - ticks = 0; - while (!cpu_isset(buddy, cpu_mask)) { - if (++buddy >= NR_CPUS) - buddy = 0; - if (++ticks > NR_CPUS) { - put_smpaff_in_irqaction(ap, CPU_MASK_NONE); - goto out; - } } - if (buddy == cpu) - goto out; + if (desc->pre_handler) + desc->pre_handler(bp, + desc->pre_handler_arg1, + desc->pre_handler_arg2); - /* Voo-doo programming. */ - if (cpu_data(buddy).idle_volume < FORWARD_VOLUME) - goto out; + action_mask = desc->action_active_mask; + random = 0; + for (i = 0; i < MAX_IRQ_DESC_ACTION; i++) { + struct irqaction *p = &desc->action[i]; + u32 mask = (1 << i); - /* This just so happens to be correct on Cheetah - * at the moment. - */ - buddy <<= 26; + if (!(action_mask & mask)) + continue; + + action_mask &= ~mask; - /* Push it to our buddy. */ - upa_writel(buddy | IMAP_VALID, bp->imap); + if (p->handler(__irq(bp), p->dev_id, regs) == IRQ_HANDLED) + random |= p->flags; + if (!action_mask) + break; + } + if (bp->pil != 0) { + upa_writel(ICLR_IDLE, bp->iclr); + /* Test and add entropy */ + if (random & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + } out: - return; + bp->flags &= ~IBF_INPROGRESS; } -#endif - void handler_irq(int irq, struct pt_regs *regs) { - struct ino_bucket *bp, *nbp; + struct ino_bucket *bp; int cpu = smp_processor_id(); #ifndef CONFIG_SMP @@ -757,8 +620,6 @@ void handler_irq(int irq, struct pt_regs *regs) clear_softint(clr_mask); } #else - int should_forward = 0; - clear_softint(1 << irq); #endif @@ -773,63 +634,12 @@ void handler_irq(int irq, struct pt_regs *regs) #else bp = __bucket(xchg32(irq_work(cpu, irq), 0)); #endif - for ( ; bp != NULL; bp = nbp) { - unsigned char flags = bp->flags; - unsigned char random = 0; + while (bp) { + struct ino_bucket *nbp = __bucket(bp->irq_chain); - nbp = __bucket(bp->irq_chain); bp->irq_chain = 0; - - bp->flags |= IBF_INPROGRESS; - - if ((flags & IBF_ACTIVE) != 0) { -#ifdef CONFIG_PCI - if ((flags & IBF_DMA_SYNC) != 0) { - upa_readl(dma_sync_reg_table[bp->synctab_ent]); - upa_readq(pci_dma_wsync); - } -#endif - if ((flags & IBF_MULTI) == 0) { - struct irqaction *ap = bp->irq_info; - int ret; - - ret = ap->handler(__irq(bp), ap->dev_id, regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } else { - void **vector = (void **)bp->irq_info; - int ent; - for (ent = 0; ent < 4; ent++) { - struct irqaction *ap = vector[ent]; - if (ap != NULL) { - int ret; - - ret = ap->handler(__irq(bp), - ap->dev_id, - regs); - if (ret == IRQ_HANDLED) - random |= ap->flags; - } - } - } - /* Only the dummy bucket lacks IMAP/ICLR. */ - if (bp->pil != 0) { -#ifdef CONFIG_SMP - if (should_forward) { - redirect_intr(cpu, bp); - should_forward = 0; - } -#endif - upa_writel(ICLR_IDLE, bp->iclr); - - /* Test and add entropy */ - if (random & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - } - } else - bp->pending = 1; - - bp->flags &= ~IBF_INPROGRESS; + process_bucket(irq, bp, regs); + bp = nbp; } irq_exit(); } @@ -959,7 +769,10 @@ static void distribute_irqs(void) */ for (level = 1; level < NR_IRQS; level++) { struct irqaction *p = irq_action[level]; - if (level == 12) continue; + + if (level == 12) + continue; + while(p) { cpu = retarget_one_irq(p, cpu); p = p->next; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index 53d333b..52bf343 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -595,6 +595,23 @@ static int __init sabre_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +/* When a device lives behind a bridge deeper in the PCI bus topology + * than APB, a special sequence must run to make sure all pending DMA + * transfers at the time of IRQ delivery are visible in the coherency + * domain by the cpu. This sequence is to perform a read on the far + * side of the non-APB bridge, then perform a read of Sabre's DMA + * write-sync register. + */ +static void sabre_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + struct pci_dev *pdev = _arg1; + unsigned long sync_reg = (unsigned long) _arg2; + u16 _unused; + + pci_read_config_word(pdev, PCI_VENDOR_ID, &_unused); + sabre_read(sync_reg); +} + static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -639,24 +656,14 @@ static unsigned int __init sabre_irq_build(struct pci_pbm_info *pbm, if (pdev) { struct pcidev_cookie *pcp = pdev->sysdata; - /* When a device lives behind a bridge deeper in the - * PCI bus topology than APB, a special sequence must - * run to make sure all pending DMA transfers at the - * time of IRQ delivery are visible in the coherency - * domain by the cpu. This sequence is to perform - * a read on the far side of the non-APB bridge, then - * perform a read of Sabre's DMA write-sync register. - * - * Currently, the PCI_CONFIG register for the device - * is used for this read from the far side of the bridge. - */ if (pdev->bus->number != pcp->pbm->pci_first_busno) { - bucket->flags |= IBF_DMA_SYNC; - bucket->synctab_ent = dma_sync_reg_table_entry++; - dma_sync_reg_table[bucket->synctab_ent] = - (unsigned long) sabre_pci_config_mkaddr( - pcp->pbm, - pdev->bus->number, pdev->devfn, PCI_COMMAND); + struct pci_controller_info *p = pcp->pbm->parent; + struct irq_desc *d = bucket->irq_info; + + d->pre_handler = sabre_wsync_handler; + d->pre_handler_arg1 = pdev; + d->pre_handler_arg2 = (void *) + p->pbm_A.controller_regs + SABRE_WRSYNC; } } return __irq(bucket); @@ -1626,10 +1633,9 @@ void __init sabre_init(int pnode, char *model_name) */ p->pbm_A.controller_regs = pr_regs[0].phys_addr; p->pbm_B.controller_regs = pr_regs[0].phys_addr; - pci_dma_wsync = p->pbm_A.controller_regs + SABRE_WRSYNC; - printk("PCI: Found SABRE, main regs at %016lx, wsync at %016lx\n", - p->pbm_A.controller_regs, pci_dma_wsync); + printk("PCI: Found SABRE, main regs at %016lx\n", + p->pbm_A.controller_regs); /* Clear interrupts */ diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 71b4e38..b40db38 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -973,7 +973,7 @@ static void sparc64_start_timers(irqreturn_t (*cfunc)(int, void *, struct pt_reg int err; /* Register IRQ handler. */ - err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, SA_STATIC_ALLOC, + err = request_irq(build_irq(0, 0, 0UL, 0UL), cfunc, 0, "timer", NULL); if (err) { diff --git a/include/asm-sparc64/irq.h b/include/asm-sparc64/irq.h index 018e2e4..8b70edc 100644 --- a/include/asm-sparc64/irq.h +++ b/include/asm-sparc64/irq.h @@ -16,6 +16,18 @@ #include #include +struct ino_bucket; + +#define MAX_IRQ_DESC_ACTION 4 + +struct irq_desc { + void (*pre_handler)(struct ino_bucket *, void *, void *); + void *pre_handler_arg1; + void *pre_handler_arg2; + u32 action_active_mask; + struct irqaction action[MAX_IRQ_DESC_ACTION]; +}; + /* You should not mess with this directly. That's the job of irq.c. * * If you make changes here, please update hand coded assembler of @@ -42,24 +54,11 @@ struct ino_bucket { /* Miscellaneous flags. */ /*0x06*/unsigned char flags; - /* This is used to deal with IBF_DMA_SYNC on - * Sabre systems. - */ -/*0x07*/unsigned char synctab_ent; - - /* Reference to handler for this IRQ. If this is - * non-NULL this means it is active and should be - * serviced. Else the pending member is set to one - * and later registry of the interrupt checks for - * this condition. - * - * Normally this is just an irq_action structure. - * But, on PCI, if multiple interrupt sources behind - * a bridge have multiple interrupt sources that share - * the same INO bucket, this points to an array of - * pointers to four IRQ action structures. - */ -/*0x08*/void *irq_info; + /* Currently unused. */ +/*0x07*/unsigned char __pad; + + /* Reference to IRQ descriptor for this bucket. */ +/*0x08*/struct irq_desc *irq_info; /* Sun5 Interrupt Clear Register. */ /*0x10*/unsigned long iclr; @@ -69,12 +68,6 @@ struct ino_bucket { }; -#ifdef CONFIG_PCI -extern unsigned long pci_dma_wsync; -extern unsigned long dma_sync_reg_table[256]; -extern unsigned char dma_sync_reg_table_entry; -#endif - /* IMAP/ICLR register defines */ #define IMAP_VALID 0x80000000 /* IRQ Enabled */ #define IMAP_TID_UPA 0x7c000000 /* UPA TargetID */ @@ -90,11 +83,9 @@ extern unsigned char dma_sync_reg_table_entry; #define ICLR_PENDING 0x00000003 /* Pending state */ /* Only 8-bits are available, be careful. -DaveM */ -#define IBF_DMA_SYNC 0x01 /* DMA synchronization behind PCI bridge needed. */ -#define IBF_PCI 0x02 /* Indicates PSYCHO/SABRE/SCHIZO PCI interrupt. */ -#define IBF_ACTIVE 0x04 /* This interrupt is active and has a handler. */ -#define IBF_MULTI 0x08 /* On PCI, indicates shared bucket. */ -#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ +#define IBF_PCI 0x02 /* PSYCHO/SABRE/SCHIZO PCI interrupt. */ +#define IBF_ACTIVE 0x04 /* Interrupt is active and has a handler.*/ +#define IBF_INPROGRESS 0x10 /* IRQ is being serviced. */ #define NUM_IVECS (IMAP_INR + 1) extern struct ino_bucket ivector_table[NUM_IVECS]; diff --git a/include/asm-sparc64/signal.h b/include/asm-sparc64/signal.h index becdf1b..e3059bb 100644 --- a/include/asm-sparc64/signal.h +++ b/include/asm-sparc64/signal.h @@ -162,21 +162,6 @@ struct sigstack { #define MINSIGSTKSZ 4096 #define SIGSTKSZ 16384 -#ifdef __KERNEL__ -/* - * DJHR - * SA_STATIC_ALLOC is used for the SPARC system to indicate that this - * interrupt handler's irq structure should be statically allocated - * by the request_irq routine. - * The alternative is that arch/sparc/kernel/irq.c has carnal knowledge - * of interrupt usage and that sucks. Also without a flag like this - * it may be possible for the free_irq routine to attempt to free - * statically allocated data.. which is NOT GOOD. - * - */ -#define SA_STATIC_ALLOC 0x80 -#endif - #include struct __new_sigaction { -- cgit v1.1 From bb6743f4f0aed5c1f09fa77cd8d3973c31792f4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 13:26:04 -0700 Subject: [SPARC64]: Do proper DMA IRQ syncing on Tomatillo This was the main impetus behind adding the PCI IRQ shim. In order to properly order DMA writes wrt. interrupts, you have to write to a PCI controller register, then poll for that bit clearing. There is one bit for each interrupt source, and setting this register bit tells Tomatillo to drain all pending DMA from that device. Furthermore, Tomatillo's with revision less than 4 require us to do a block store due to some memory transaction ordering issues it has on JBUS. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_schizo.c | 51 ++++++++++++++++++++++++++++++++++++++++ include/asm-sparc64/pbm.h | 3 +++ 2 files changed, 54 insertions(+) diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 5753175..68b1a63 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "pci_impl.h" #include "iommu_common.h" @@ -326,6 +327,44 @@ static int __init schizo_ino_to_pil(struct pci_dev *pdev, unsigned int ino) return ret; } +static void tomatillo_wsync_handler(struct ino_bucket *bucket, void *_arg1, void *_arg2) +{ + unsigned long sync_reg = (unsigned long) _arg2; + u64 mask = 1 << (__irq_ino(__irq(bucket)) & IMAP_INO); + u64 val; + int limit; + + schizo_write(sync_reg, mask); + + limit = 100000; + val = 0; + while (--limit) { + val = schizo_read(sync_reg); + if (!(val & mask)) + break; + } + if (limit <= 0) { + printk("tomatillo_wsync_handler: DMA won't sync [%lx:%lx]\n", + val, mask); + } + + if (_arg1) { + static unsigned char cacheline[64] + __attribute__ ((aligned (64))); + + __asm__ __volatile__("rd %%fprs, %0\n\t" + "or %0, %4, %1\n\t" + "wr %1, 0x0, %%fprs\n\t" + "stda %%f0, [%5] %6\n\t" + "wr %0, 0x0, %%fprs\n\t" + "membar #Sync" + : "=&r" (mask), "=&r" (val) + : "0" (mask), "1" (val), + "i" (FPRS_FEF), "r" (&cacheline[0]), + "i" (ASI_BLK_COMMIT_P)); + } +} + static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, struct pci_dev *pdev, unsigned int ino) @@ -369,6 +408,15 @@ static unsigned int schizo_irq_build(struct pci_pbm_info *pbm, bucket = __bucket(build_irq(pil, ign_fixup, iclr, imap)); bucket->flags |= IBF_PCI; + if (pdev && pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) { + struct irq_desc *p = bucket->irq_info; + + p->pre_handler = tomatillo_wsync_handler; + p->pre_handler_arg1 = ((pbm->chip_version <= 4) ? + (void *) 1 : (void *) 0); + p->pre_handler_arg2 = (void *) pbm->sync_reg; + } + return __irq(bucket); } @@ -2015,6 +2063,9 @@ static void __init schizo_pbm_init(struct pci_controller_info *p, pbm->pbm_regs = pr_regs[0].phys_addr; pbm->controller_regs = pr_regs[1].phys_addr - 0x10000UL; + if (chip_type == PBM_CHIP_TYPE_TOMATILLO) + pbm->sync_reg = pr_regs[3].phys_addr + 0x1a18UL; + sprintf(pbm->name, (chip_type == PBM_CHIP_TYPE_TOMATILLO ? "TOMATILLO%d PBM%c" : diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index 4c15610a..38bbbcc 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -145,6 +145,9 @@ struct pci_pbm_info { /* Physical address base of PBM registers. */ unsigned long pbm_regs; + /* Physical address of DMA sync register, if any. */ + unsigned long sync_reg; + /* Opaque 32-bit system bus Port ID. */ u32 portid; -- cgit v1.1 From 9fba62a59cf1407cd5495f6c61d22d169ca1553f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 14:53:33 -0700 Subject: [SPARC64]: Small Schizo PCI controller programming tweaks. Use macro instead of magic value for Tomatillo discard- timeout interrupt enable register bit. Leave OBP programming PTO value unless Tomatillo and version >= 0x2. If no-bus-parking property is present, explicitly clear PCICTRL_PARK bit. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_schizo.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index 68b1a63..f4f68e1 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -933,6 +933,7 @@ static irqreturn_t schizo_ce_intr(int irq, void *dev_id, struct pt_regs *regs) #define SCHIZO_PCI_CTRL (0x2000UL) #define SCHIZO_PCICTRL_BUS_UNUS (1UL << 63UL) /* Safari */ +#define SCHIZO_PCICTRL_DTO_INT (1UL << 61UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ARB_PRIO (0x1ff << 52UL) /* Tomatillo */ #define SCHIZO_PCICTRL_ESLCK (1UL << 51UL) /* Safari */ #define SCHIZO_PCICTRL_ERRSLOT (7UL << 48UL) /* Safari */ @@ -1939,33 +1940,25 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, SCHIZO_IRQ_RETRY_INF); - /* Enable arbiter for all PCI slots. Also, disable PCI interval - * timer so that DTO (Discard TimeOuts) are not reported because - * some Schizo revisions report them erroneously. - */ tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); - if (pbm->chip_type == PBM_CHIP_TYPE_SCHIZO_PLUS && - pbm->chip_version == 0x5 && - pbm->chip_revision == 0x1) - tmp |= 0x0f; - else - tmp |= 0xff; - tmp &= ~SCHIZO_PCICTRL_PTO; + /* Enable arbiter for all PCI slots. */ + tmp |= 0xff; + if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version >= 0x2) tmp |= 0x3UL << SCHIZO_PCICTRL_PTO_SHIFT; - else - tmp |= 0x1UL << SCHIZO_PCICTRL_PTO_SHIFT; if (!prom_getbool(pbm->prom_node, "no-bus-parking")) tmp |= SCHIZO_PCICTRL_PARK; + else + tmp &= ~SCHIZO_PCICTRL_PARK; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO && pbm->chip_version <= 0x1) - tmp |= (1UL << 61); + tmp |= SCHIZO_PCICTRL_DTO_INT; else - tmp &= ~(1UL << 61); + tmp &= ~SCHIZO_PCICTRL_DTO_INT; if (pbm->chip_type == PBM_CHIP_TYPE_TOMATILLO) tmp |= (SCHIZO_PCICTRL_MRM_PREF | -- cgit v1.1 From 864ae180074931f3a28c84ea85aa8cfeca18bc4f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 4 Jul 2005 15:58:19 -0700 Subject: [SPARC64]: Fix IRQ retry interval timer value on sparc64 PCI controllers. Use '5' instead of 'infinity'. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_psycho.c | 3 +-- arch/sparc64/kernel/pci_schizo.c | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index 534320e..91ab466 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1303,8 +1303,7 @@ static void psycho_controller_hwinit(struct pci_controller_info *p) { u64 tmp; - /* PROM sets the IRQ retry value too low, increase it. */ - psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 0xff); + psycho_write(p->pbm_A.controller_regs + PSYCHO_IRQ_RETRY, 5); /* Enable arbiter for all PCI slots. */ tmp = psycho_read(p->pbm_A.controller_regs + PSYCHO_PCIA_CTRL); diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c index f4f68e1..6a182bb 100644 --- a/arch/sparc64/kernel/pci_schizo.c +++ b/arch/sparc64/kernel/pci_schizo.c @@ -1936,9 +1936,7 @@ static void __init schizo_pbm_hw_init(struct pci_pbm_info *pbm) { u64 tmp; - /* Set IRQ retry to infinity. */ - schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, - SCHIZO_IRQ_RETRY_INF); + schizo_write(pbm->pbm_regs + SCHIZO_PCI_IRQ_RETRY, 5); tmp = schizo_read(pbm->pbm_regs + SCHIZO_PCI_CTRL); -- cgit v1.1 From 55820ee2f8c767a2833b21bd365e5753f50bd8ce Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 5 Jul 2005 14:08:10 -0700 Subject: [NET]: Fix signedness issues in net/core/filter.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the code to load packet data into a register: k = fentry->k; if (k < 0) { ... } else { u32 _tmp, *p; p = skb_header_pointer(skb, k, 4, &_tmp); if (p != NULL) { A = ntohl(*p); continue; } } skb_header_pointer checks if the requested data is within the linear area: int hlen = skb_headlen(skb); if (offset + len <= hlen) return skb->data + offset; When offset is within [INT_MAX-len+1..INT_MAX] the addition will result in a negative number which is <= hlen. I couldn't trigger a crash on my AMD64 with 2GB of memory, but a coworker tried on his x86 machine and it crashed immediately. This patch fixes the check in skb_header_pointer to handle large positive offsets similar to skb_copy_bits. Invalid data can still be accessed using negative offsets (also similar to skb_copy_bits), anyone using negative offsets needs to verify them himself. Thanks to Thomas Vögtle for verifying the problem by crashing his machine and providing me with an Oops. Signed-off-by: Patrick McHardy Acked-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 416a2e4..fbcb186 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1211,7 +1211,7 @@ static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, { int hlen = skb_headlen(skb); - if (offset + len <= hlen) + if (hlen - offset >= len) return skb->data + offset; if (skb_copy_bits(skb, offset, buffer, len) < 0) -- cgit v1.1 From 6935d46c2da64aa032a557374c95336e265cd7ef Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 5 Jul 2005 14:08:57 -0700 Subject: [NET]: Remove redundant code in net/core/filter.c skb_header_pointer handles linear and non-linear data, no need to handle linear data again. Signed-off-by: Patrick McHardy Acked-by: Herbert Xu Signed-off-by: David S. Miller --- net/core/filter.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index f3b8820..e1267b4 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -168,10 +168,6 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) case BPF_LD|BPF_W|BPF_ABS: k = fentry->k; load_w: - if (k >= 0 && (unsigned int)(k+sizeof(u32)) <= len) { - A = ntohl(*(u32*)&data[k]); - continue; - } if (k < 0) { u8 *ptr; @@ -194,10 +190,6 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) case BPF_LD|BPF_H|BPF_ABS: k = fentry->k; load_h: - if (k >= 0 && (unsigned int)(k + sizeof(u16)) <= len) { - A = ntohs(*(u16*)&data[k]); - continue; - } if (k < 0) { u8 *ptr; @@ -220,10 +212,6 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) case BPF_LD|BPF_B|BPF_ABS: k = fentry->k; load_b: - if (k >= 0 && (unsigned int)k < len) { - A = data[k]; - continue; - } if (k < 0) { u8 *ptr; -- cgit v1.1 From 0b05b2a49e430220876f8faa7e4778dc7497033c Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 5 Jul 2005 14:10:21 -0700 Subject: [NET]: Consolidate common code in net/core/filter.c Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/core/filter.c | 90 ++++++++++++++++++++----------------------------------- 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index e1267b4..3923428 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -36,7 +36,7 @@ #include /* No hurry in this branch */ -static u8 *load_pointer(struct sk_buff *skb, int k) +static void *__load_pointer(struct sk_buff *skb, int k) { u8 *ptr = NULL; @@ -50,6 +50,18 @@ static u8 *load_pointer(struct sk_buff *skb, int k) return NULL; } +static inline void *load_pointer(struct sk_buff *skb, int k, + unsigned int size, void *buffer) +{ + if (k >= 0) + return skb_header_pointer(skb, k, size, buffer); + else { + if (k >= SKF_AD_OFF) + return NULL; + return __load_pointer(skb, k); + } +} + /** * sk_run_filter - run a filter on a socket * @skb: buffer to run the filter on @@ -64,15 +76,16 @@ static u8 *load_pointer(struct sk_buff *skb, int k) int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) { - unsigned char *data = skb->data; /* len is UNSIGNED. Byte wide insns relies only on implicit type casts to prevent reading arbitrary memory locations. */ unsigned int len = skb->len-skb->data_len; struct sock_filter *fentry; /* We walk down these */ + void *ptr; u32 A = 0; /* Accumulator */ u32 X = 0; /* Index Register */ u32 mem[BPF_MEMWORDS]; /* Scratch Memory Store */ + u32 tmp; int k; int pc; @@ -168,67 +181,28 @@ int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) case BPF_LD|BPF_W|BPF_ABS: k = fentry->k; load_w: - if (k < 0) { - u8 *ptr; - - if (k >= SKF_AD_OFF) - break; - ptr = load_pointer(skb, k); - if (ptr) { - A = ntohl(*(u32*)ptr); - continue; - } - } else { - u32 _tmp, *p; - p = skb_header_pointer(skb, k, 4, &_tmp); - if (p != NULL) { - A = ntohl(*p); - continue; - } + ptr = load_pointer(skb, k, 4, &tmp); + if (ptr != NULL) { + A = ntohl(*(u32 *)ptr); + continue; } return 0; case BPF_LD|BPF_H|BPF_ABS: k = fentry->k; load_h: - if (k < 0) { - u8 *ptr; - - if (k >= SKF_AD_OFF) - break; - ptr = load_pointer(skb, k); - if (ptr) { - A = ntohs(*(u16*)ptr); - continue; - } - } else { - u16 _tmp, *p; - p = skb_header_pointer(skb, k, 2, &_tmp); - if (p != NULL) { - A = ntohs(*p); - continue; - } + ptr = load_pointer(skb, k, 2, &tmp); + if (ptr != NULL) { + A = ntohs(*(u16 *)ptr); + continue; } return 0; case BPF_LD|BPF_B|BPF_ABS: k = fentry->k; load_b: - if (k < 0) { - u8 *ptr; - - if (k >= SKF_AD_OFF) - break; - ptr = load_pointer(skb, k); - if (ptr) { - A = *ptr; - continue; - } - } else { - u8 _tmp, *p; - p = skb_header_pointer(skb, k, 1, &_tmp); - if (p != NULL) { - A = *p; - continue; - } + ptr = load_pointer(skb, k, 1, &tmp); + if (ptr != NULL) { + A = *(u8 *)ptr; + continue; } return 0; case BPF_LD|BPF_W|BPF_LEN: @@ -247,10 +221,12 @@ load_b: k = X + fentry->k; goto load_b; case BPF_LDX|BPF_B|BPF_MSH: - if (fentry->k >= len) - return 0; - X = (data[fentry->k] & 0xf) << 2; - continue; + ptr = load_pointer(skb, fentry->k, 1, &tmp); + if (ptr != NULL) { + X = (*(u8 *)ptr & 0xf) << 2; + continue; + } + return 0; case BPF_LD|BPF_IMM: A = fentry->k; continue; -- cgit v1.1 From 3154e540e374bbfd62693d95bc8ed51da95efe75 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 5 Jul 2005 14:10:40 -0700 Subject: [NET]: net/core/filter.c: make len cover the entire packet As suggested by Herbert Xu: Since we don't require anything to be in the linear packet range anymore make len cover the entire packet. Signed-off-by: Patrick McHardy Signed-off-by: David S. Miller --- net/core/filter.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/core/filter.c b/net/core/filter.c index 3923428..cd91a24 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -76,10 +76,6 @@ static inline void *load_pointer(struct sk_buff *skb, int k, int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int flen) { - /* len is UNSIGNED. Byte wide insns relies only on implicit - type casts to prevent reading arbitrary memory locations. - */ - unsigned int len = skb->len-skb->data_len; struct sock_filter *fentry; /* We walk down these */ void *ptr; u32 A = 0; /* Accumulator */ @@ -206,10 +202,10 @@ load_b: } return 0; case BPF_LD|BPF_W|BPF_LEN: - A = len; + A = skb->len; continue; case BPF_LDX|BPF_W|BPF_LEN: - X = len; + X = skb->len; continue; case BPF_LD|BPF_W|BPF_IND: k = X + fentry->k; -- cgit v1.1 From e176fe8954a5239c24afe79b1001ba3c29511963 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 14:12:44 -0700 Subject: [NET]: Remove unused security member in sk_buff Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/skbuff.h | 4 +--- include/linux/tc_ematch/tc_em_meta.h | 2 +- net/core/skbuff.c | 2 -- net/ipv4/ip_output.c | 1 - net/ipv6/ip6_output.c | 1 - net/sched/em_meta.c | 6 ------ 6 files changed, 2 insertions(+), 14 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index fbcb186..1e6290f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -183,7 +183,6 @@ struct skb_shared_info { * @priority: Packet queueing priority * @users: User count - see {datagram,tcp}.c * @protocol: Packet protocol from driver - * @security: Security level of packet * @truesize: Buffer size * @head: Head of buffer * @data: Data head pointer @@ -255,8 +254,7 @@ struct sk_buff { pkt_type, ip_summed; __u32 priority; - unsigned short protocol, - security; + unsigned short protocol; void (*destructor)(struct sk_buff *skb); #ifdef CONFIG_NETFILTER diff --git a/include/linux/tc_ematch/tc_em_meta.h b/include/linux/tc_ematch/tc_em_meta.h index a6b2cc5..bcb762d 100644 --- a/include/linux/tc_ematch/tc_em_meta.h +++ b/include/linux/tc_ematch/tc_em_meta.h @@ -45,7 +45,7 @@ enum TCF_META_ID_REALDEV, TCF_META_ID_PRIORITY, TCF_META_ID_PROTOCOL, - TCF_META_ID_SECURITY, + TCF_META_ID_SECURITY, /* obsolete */ TCF_META_ID_PKTTYPE, TCF_META_ID_PKTLEN, TCF_META_ID_DATALEN, diff --git a/net/core/skbuff.c b/net/core/skbuff.c index bb73b21..733deee 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -357,7 +357,6 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask) C(ip_summed); C(priority); C(protocol); - C(security); n->destructor = NULL; #ifdef CONFIG_NETFILTER C(nfmark); @@ -422,7 +421,6 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) new->pkt_type = old->pkt_type; new->stamp = old->stamp; new->destructor = NULL; - new->security = old->security; #ifdef CONFIG_NETFILTER new->nfmark = old->nfmark; new->nfcache = old->nfcache; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 6ce5c32..1bfa49e 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -389,7 +389,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; - to->security = from->security; dst_release(to->dst); to->dst = dst_clone(from->dst); to->dev = from->dev; diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 06e7cdae..1f2c2f9 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -465,7 +465,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) to->pkt_type = from->pkt_type; to->priority = from->priority; to->protocol = from->protocol; - to->security = from->security; dst_release(to->dst); to->dst = dst_clone(from->dst); to->dev = from->dev; diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 48bb23c..53d98f8 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c @@ -205,11 +205,6 @@ META_COLLECTOR(int_protocol) dst->value = skb->protocol; } -META_COLLECTOR(int_security) -{ - dst->value = skb->security; -} - META_COLLECTOR(int_pkttype) { dst->value = skb->pkt_type; @@ -524,7 +519,6 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = { [META_ID(REALDEV)] = META_FUNC(int_realdev), [META_ID(PRIORITY)] = META_FUNC(int_priority), [META_ID(PROTOCOL)] = META_FUNC(int_protocol), - [META_ID(SECURITY)] = META_FUNC(int_security), [META_ID(PKTTYPE)] = META_FUNC(int_pkttype), [META_ID(PKTLEN)] = META_FUNC(int_pktlen), [META_ID(DATALEN)] = META_FUNC(int_datalen), -- cgit v1.1 From 1cbb3380ef683f742876f48e3739b3df4ea9e168 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 14:13:41 -0700 Subject: [NET]: Reduce size of sk_buff by 4 bytes Reduce local_df to a bit field and ip_summed to a 2 bits field thus saving 13 bits. Move bit fields, packet type, and protocol into the spare area between the priority and the destructor. Saves 4 bytes on both, 32bit and 64bit architectures. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/linux/skbuff.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 1e6290f..14b9504 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -248,17 +248,18 @@ struct sk_buff { data_len, mac_len, csum; - unsigned char local_df, - cloned:1, - nohdr:1, - pkt_type, - ip_summed; __u32 priority; - unsigned short protocol; + __u8 local_df:1, + cloned:1, + ip_summed:2, + nohdr:1; + /* 3 bits spare */ + __u8 pkt_type; + __u16 protocol; void (*destructor)(struct sk_buff *skb); #ifdef CONFIG_NETFILTER - unsigned long nfmark; + unsigned long nfmark; __u32 nfcache; __u32 nfctinfo; struct nf_conntrack *nfct; -- cgit v1.1 From e41a33e6ec20a0a6ac762629149e36cab5d4213f Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 14:14:30 -0700 Subject: [PKT_SCHED]: Move sch_generic.c prototypes to correct header file Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/net/pkt_sched.h | 10 ---------- include/net/sch_generic.h | 12 ++++++++++++ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index fcb05a3..2f494a2 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -207,8 +207,6 @@ psched_tod_diff(int delta_sec, int bound) #endif /* !CONFIG_NET_SCH_CLK_GETTIMEOFDAY */ -extern struct Qdisc noop_qdisc; -extern struct Qdisc_ops noop_qdisc_ops; extern struct Qdisc_ops pfifo_qdisc_ops; extern struct Qdisc_ops bfifo_qdisc_ops; @@ -216,14 +214,6 @@ extern int register_qdisc(struct Qdisc_ops *qops); extern int unregister_qdisc(struct Qdisc_ops *qops); extern struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle); extern struct Qdisc *qdisc_lookup_class(struct net_device *dev, u32 handle); -extern void dev_init_scheduler(struct net_device *dev); -extern void dev_shutdown(struct net_device *dev); -extern void dev_activate(struct net_device *dev); -extern void dev_deactivate(struct net_device *dev); -extern void qdisc_reset(struct Qdisc *qdisc); -extern void qdisc_destroy(struct Qdisc *qdisc); -extern struct Qdisc * qdisc_create_dflt(struct net_device *dev, - struct Qdisc_ops *ops); extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct rtattr *tab); extern void qdisc_put_rtab(struct qdisc_rate_table *tab); diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index 7b97405..c76d34e 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -164,6 +164,18 @@ extern void qdisc_unlock_tree(struct net_device *dev); #define tcf_tree_lock(tp) qdisc_lock_tree((tp)->q->dev) #define tcf_tree_unlock(tp) qdisc_unlock_tree((tp)->q->dev) +extern struct Qdisc noop_qdisc; +extern struct Qdisc_ops noop_qdisc_ops; + +extern void dev_init_scheduler(struct net_device *dev); +extern void dev_shutdown(struct net_device *dev); +extern void dev_activate(struct net_device *dev); +extern void dev_deactivate(struct net_device *dev); +extern void qdisc_reset(struct Qdisc *qdisc); +extern void qdisc_destroy(struct Qdisc *qdisc); +extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, + struct Qdisc_ops *ops); + static inline void tcf_destroy(struct tcf_proto *tp) { -- cgit v1.1 From 3d54b82fdf0ca79608f61448fb8ab92676487645 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 14:15:09 -0700 Subject: [PKT_SCHED]: Cleanup qdisc creation and alignment macros Adds qdisc_alloc() to share code between qdisc_create() and qdisc_create_dflt(). Hides the qdisc alignment behind macros and makes use of them. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- include/net/pkt_sched.h | 7 +++---- include/net/sch_generic.h | 1 + net/sched/sch_api.c | 41 +++++++++-------------------------------- net/sched/sch_generic.c | 35 ++++++++++++++++++++++++----------- 4 files changed, 37 insertions(+), 47 deletions(-) diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h index 2f494a2..6492e73 100644 --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -13,13 +13,12 @@ struct qdisc_walker extern rwlock_t qdisc_tree_lock; -#define QDISC_ALIGN 32 -#define QDISC_ALIGN_CONST (QDISC_ALIGN - 1) +#define QDISC_ALIGNTO 32 +#define QDISC_ALIGN(len) (((len) + QDISC_ALIGNTO-1) & ~(QDISC_ALIGNTO-1)) static inline void *qdisc_priv(struct Qdisc *q) { - return (char *)q + ((sizeof(struct Qdisc) + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); + return (char *) q + QDISC_ALIGN(sizeof(struct Qdisc)); } /* diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index c76d34e..7b6ec99 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -173,6 +173,7 @@ extern void dev_activate(struct net_device *dev); extern void dev_deactivate(struct net_device *dev); extern void qdisc_reset(struct Qdisc *qdisc); extern void qdisc_destroy(struct Qdisc *qdisc); +extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops); diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 05e6e0a..1ef482b 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -399,10 +399,8 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) { int err; struct rtattr *kind = tca[TCA_KIND-1]; - void *p = NULL; struct Qdisc *sch; struct Qdisc_ops *ops; - int size; ops = qdisc_lookup_ops(kind); #ifdef CONFIG_KMOD @@ -437,43 +435,23 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) if (ops == NULL) goto err_out; - /* ensure that the Qdisc and the private data are 32-byte aligned */ - size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); - size += ops->priv_size + QDISC_ALIGN_CONST; - - p = kmalloc(size, GFP_KERNEL); - err = -ENOBUFS; - if (!p) + sch = qdisc_alloc(dev, ops); + if (IS_ERR(sch)) { + err = PTR_ERR(sch); goto err_out2; - memset(p, 0, size); - sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); - sch->padded = (char *)sch - (char *)p; - - INIT_LIST_HEAD(&sch->list); - skb_queue_head_init(&sch->q); + } - if (handle == TC_H_INGRESS) + if (handle == TC_H_INGRESS) { sch->flags |= TCQ_F_INGRESS; - - sch->ops = ops; - sch->enqueue = ops->enqueue; - sch->dequeue = ops->dequeue; - sch->dev = dev; - dev_hold(dev); - atomic_set(&sch->refcnt, 1); - sch->stats_lock = &dev->queue_lock; - if (handle == 0) { + handle = TC_H_MAKE(TC_H_INGRESS, 0); + } else if (handle == 0) { handle = qdisc_alloc_handle(dev); err = -ENOMEM; if (handle == 0) goto err_out3; } - if (handle == TC_H_INGRESS) - sch->handle =TC_H_MAKE(TC_H_INGRESS, 0); - else - sch->handle = handle; + sch->handle = handle; if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { qdisc_lock_tree(dev); @@ -489,12 +467,11 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) } err_out3: dev_put(dev); + kfree((char *) sch - sch->padded); err_out2: module_put(ops->owner); err_out: *errp = err; - if (p) - kfree(p); return NULL; } diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 7683b34..73e218e 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -395,24 +395,23 @@ static struct Qdisc_ops pfifo_fast_ops = { .owner = THIS_MODULE, }; -struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) +struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops) { void *p; struct Qdisc *sch; - int size; + unsigned int size; + int err = -ENOBUFS; /* ensure that the Qdisc and the private data are 32-byte aligned */ - size = ((sizeof(*sch) + QDISC_ALIGN_CONST) & ~QDISC_ALIGN_CONST); - size += ops->priv_size + QDISC_ALIGN_CONST; + size = QDISC_ALIGN(sizeof(*sch)); + size += ops->priv_size + (QDISC_ALIGNTO - 1); p = kmalloc(size, GFP_KERNEL); if (!p) - return NULL; + goto errout; memset(p, 0, size); - - sch = (struct Qdisc *)(((unsigned long)p + QDISC_ALIGN_CONST) - & ~QDISC_ALIGN_CONST); - sch->padded = (char *)sch - (char *)p; + sch = (struct Qdisc *) QDISC_ALIGN((unsigned long) p); + sch->padded = (char *) sch - (char *) p; INIT_LIST_HEAD(&sch->list); skb_queue_head_init(&sch->q); @@ -423,11 +422,24 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) dev_hold(dev); sch->stats_lock = &dev->queue_lock; atomic_set(&sch->refcnt, 1); + + return sch; +errout: + return ERR_PTR(-err); +} + +struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) +{ + struct Qdisc *sch; + + sch = qdisc_alloc(dev, ops); + if (IS_ERR(sch)) + goto errout; + if (!ops->init || ops->init(sch, NULL) == 0) return sch; - dev_put(dev); - kfree(p); +errout: return NULL; } @@ -591,6 +603,7 @@ EXPORT_SYMBOL(__netdev_watchdog_up); EXPORT_SYMBOL(noop_qdisc); EXPORT_SYMBOL(noop_qdisc_ops); EXPORT_SYMBOL(qdisc_create_dflt); +EXPORT_SYMBOL(qdisc_alloc); EXPORT_SYMBOL(qdisc_destroy); EXPORT_SYMBOL(qdisc_reset); EXPORT_SYMBOL(qdisc_restart); -- cgit v1.1 From 023e09a767a89bf1b8646307410852d93fd72f00 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 14:15:53 -0700 Subject: [PKT_SCHED]: Report rate estimator configuration errors during qdisc allocation Current behaviour is to not report an error if a rate estimator is created together with a qdisc and the configuration of the rate estimator is bogus. This leads to unexpected behaviour because the user is not notified. New behaviour is to report the error and let the whole qdisc creation operation fail so the user is able to fix his mistake. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/sched/sch_api.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 1ef482b..b9a069a 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c @@ -454,15 +454,27 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp) sch->handle = handle; if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS-1])) == 0) { +#ifdef CONFIG_NET_ESTIMATOR + if (tca[TCA_RATE-1]) { + err = gen_new_estimator(&sch->bstats, &sch->rate_est, + sch->stats_lock, + tca[TCA_RATE-1]); + if (err) { + /* + * Any broken qdiscs that would require + * a ops->reset() here? The qdisc was never + * in action so it shouldn't be necessary. + */ + if (ops->destroy) + ops->destroy(sch); + goto err_out3; + } + } +#endif qdisc_lock_tree(dev); list_add_tail(&sch->list, &dev->qdisc_list); qdisc_unlock_tree(dev); -#ifdef CONFIG_NET_ESTIMATOR - if (tca[TCA_RATE-1]) - gen_new_estimator(&sch->bstats, &sch->rate_est, - sch->stats_lock, tca[TCA_RATE-1]); -#endif return sch; } err_out3: -- cgit v1.1 From a31488ca4b8476a8dd301b21388631df52d05c5a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 14:24:35 -0700 Subject: [SKGE]: Fix build on big-endian Missing PCI_REV_DESC define. Signed-off-by: David S. Miller --- drivers/net/skge.h | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 14d0cc0..fced3d2 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h @@ -7,6 +7,7 @@ /* PCI config registers */ #define PCI_DEV_REG1 0x40 #define PCI_DEV_REG2 0x44 +#define PCI_REV_DESC 0x4 #define PCI_STATUS_ERROR_BITS (PCI_STATUS_DETECTED_PARITY | \ PCI_STATUS_SIG_SYSTEM_ERROR | \ -- cgit v1.1 From 30e224d76f34e041c30df66a4dcbeeb53556ea3f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 5 Jul 2005 14:40:10 -0700 Subject: [IPV4]: Fix crash in ip_rcv while booting related to netconsole Makes IPv4 ip_rcv registration happen last in af_inet. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv4/af_inet.c | 11 +++++++++++ net/ipv4/ip_output.c | 15 --------------- 2 files changed, 11 insertions(+), 15 deletions(-) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 658e797..ef74683 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1009,6 +1009,15 @@ static int __init init_ipv4_mibs(void) static int ipv4_proc_init(void); extern void ipfrag_init(void); +/* + * IP protocol layer initialiser + */ + +static struct packet_type ip_packet_type = { + .type = __constant_htons(ETH_P_IP), + .func = ip_rcv, +}; + static int __init inet_init(void) { struct sk_buff *dummy_skb; @@ -1102,6 +1111,8 @@ static int __init inet_init(void) ipfrag_init(); + dev_add_pack(&ip_packet_type); + rc = 0; out: return rc; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 1bfa49e..9de83e6 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1328,23 +1328,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar ip_rt_put(rt); } -/* - * IP protocol layer initialiser - */ - -static struct packet_type ip_packet_type = { - .type = __constant_htons(ETH_P_IP), - .func = ip_rcv, -}; - -/* - * IP registers the packet type and then calls the subprotocol initialisers - */ - void __init ip_init(void) { - dev_add_pack(&ip_packet_type); - ip_rt_init(); inet_initpeers(); -- cgit v1.1 From e2ed4052aa662e7cfb22a1793b9d8158603be6d7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 5 Jul 2005 14:41:20 -0700 Subject: [IPV6]: Makes IPv6 rcv registration happen last during initialisation. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- net/ipv6/af_inet6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 2b193e3..28d9bca 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -774,7 +774,6 @@ static int __init inet6_init(void) if (if6_proc_init()) goto proc_if6_fail; #endif - ipv6_packet_init(); ip6_route_init(); ip6_flowlabel_init(); err = addrconf_init(); @@ -791,6 +790,8 @@ static int __init inet6_init(void) /* Init v6 transport protocols. */ udpv6_init(); tcpv6_init(); + + ipv6_packet_init(); err = 0; out: return err; @@ -798,7 +799,6 @@ out: addrconf_fail: ip6_flowlabel_cleanup(); ip6_route_cleanup(); - ipv6_packet_cleanup(); #ifdef CONFIG_PROC_FS if6_proc_exit(); proc_if6_fail: -- cgit v1.1 From d244c892c8e23d6baba88af88f78f7201a224d39 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Tue, 5 Jul 2005 14:42:33 -0700 Subject: [TG3]: support for ethtool -C Add support for ethtool -C with verification of user parameters. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- drivers/net/tg3.h | 10 +++++++++ 2 files changed, 73 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7e371b1..7f84dc8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -5117,7 +5117,7 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr, } static void __tg3_set_rx_mode(struct net_device *); -static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) +static void __tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) { tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs); tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs); @@ -5460,7 +5460,7 @@ static int tg3_reset_hw(struct tg3 *tp) udelay(10); } - tg3_set_coalesce(tp, &tp->coal); + __tg3_set_coalesce(tp, &tp->coal); /* set status block DMA address */ tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, @@ -7821,6 +7821,60 @@ static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) return 0; } +static int tg3_set_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) +{ + struct tg3 *tp = netdev_priv(dev); + u32 max_rxcoal_tick_int = 0, max_txcoal_tick_int = 0; + u32 max_stat_coal_ticks = 0, min_stat_coal_ticks = 0; + + if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { + max_rxcoal_tick_int = MAX_RXCOAL_TICK_INT; + max_txcoal_tick_int = MAX_TXCOAL_TICK_INT; + max_stat_coal_ticks = MAX_STAT_COAL_TICKS; + min_stat_coal_ticks = MIN_STAT_COAL_TICKS; + } + + if ((ec->rx_coalesce_usecs > MAX_RXCOL_TICKS) || + (ec->tx_coalesce_usecs > MAX_TXCOL_TICKS) || + (ec->rx_max_coalesced_frames > MAX_RXMAX_FRAMES) || + (ec->tx_max_coalesced_frames > MAX_TXMAX_FRAMES) || + (ec->rx_coalesce_usecs_irq > max_rxcoal_tick_int) || + (ec->tx_coalesce_usecs_irq > max_txcoal_tick_int) || + (ec->rx_max_coalesced_frames_irq > MAX_RXCOAL_MAXF_INT) || + (ec->tx_max_coalesced_frames_irq > MAX_TXCOAL_MAXF_INT) || + (ec->stats_block_coalesce_usecs > max_stat_coal_ticks) || + (ec->stats_block_coalesce_usecs < min_stat_coal_ticks)) + return -EINVAL; + + /* No rx interrupts will be generated if both are zero */ + if ((ec->rx_coalesce_usecs == 0) && + (ec->rx_max_coalesced_frames == 0)) + return -EINVAL; + + /* No tx interrupts will be generated if both are zero */ + if ((ec->tx_coalesce_usecs == 0) && + (ec->tx_max_coalesced_frames == 0)) + return -EINVAL; + + /* Only copy relevant parameters, ignore all others. */ + tp->coal.rx_coalesce_usecs = ec->rx_coalesce_usecs; + tp->coal.tx_coalesce_usecs = ec->tx_coalesce_usecs; + tp->coal.rx_max_coalesced_frames = ec->rx_max_coalesced_frames; + tp->coal.tx_max_coalesced_frames = ec->tx_max_coalesced_frames; + tp->coal.rx_coalesce_usecs_irq = ec->rx_coalesce_usecs_irq; + tp->coal.tx_coalesce_usecs_irq = ec->tx_coalesce_usecs_irq; + tp->coal.rx_max_coalesced_frames_irq = ec->rx_max_coalesced_frames_irq; + tp->coal.tx_max_coalesced_frames_irq = ec->tx_max_coalesced_frames_irq; + tp->coal.stats_block_coalesce_usecs = ec->stats_block_coalesce_usecs; + + if (netif_running(dev)) { + tg3_full_lock(tp, 0); + __tg3_set_coalesce(tp, &tp->coal); + tg3_full_unlock(tp); + } + return 0; +} + static struct ethtool_ops tg3_ethtool_ops = { .get_settings = tg3_get_settings, .set_settings = tg3_set_settings, @@ -7856,6 +7910,7 @@ static struct ethtool_ops tg3_ethtool_ops = { .get_stats_count = tg3_get_stats_count, .get_ethtool_stats = tg3_get_ethtool_stats, .get_coalesce = tg3_get_coalesce, + .set_coalesce = tg3_set_coalesce, }; static void __devinit tg3_get_eeprom_size(struct tg3 *tp) @@ -9800,6 +9855,12 @@ static void __devinit tg3_init_coal(struct tg3 *tp) ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS; ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS; } + + if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) { + ec->rx_coalesce_usecs_irq = 0; + ec->tx_coalesce_usecs_irq = 0; + ec->stats_block_coalesce_usecs = 0; + } } static int __devinit tg3_init_one(struct pci_dev *pdev, diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 99c5f96..70ad450 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -879,31 +879,41 @@ #define LOW_RXCOL_TICKS_CLRTCKS 0x00000014 #define DEFAULT_RXCOL_TICKS 0x00000048 #define HIGH_RXCOL_TICKS 0x00000096 +#define MAX_RXCOL_TICKS 0x000003ff #define HOSTCC_TXCOL_TICKS 0x00003c0c #define LOW_TXCOL_TICKS 0x00000096 #define LOW_TXCOL_TICKS_CLRTCKS 0x00000048 #define DEFAULT_TXCOL_TICKS 0x0000012c #define HIGH_TXCOL_TICKS 0x00000145 +#define MAX_TXCOL_TICKS 0x000003ff #define HOSTCC_RXMAX_FRAMES 0x00003c10 #define LOW_RXMAX_FRAMES 0x00000005 #define DEFAULT_RXMAX_FRAMES 0x00000008 #define HIGH_RXMAX_FRAMES 0x00000012 +#define MAX_RXMAX_FRAMES 0x000000ff #define HOSTCC_TXMAX_FRAMES 0x00003c14 #define LOW_TXMAX_FRAMES 0x00000035 #define DEFAULT_TXMAX_FRAMES 0x0000004b #define HIGH_TXMAX_FRAMES 0x00000052 +#define MAX_TXMAX_FRAMES 0x000000ff #define HOSTCC_RXCOAL_TICK_INT 0x00003c18 #define DEFAULT_RXCOAL_TICK_INT 0x00000019 #define DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014 +#define MAX_RXCOAL_TICK_INT 0x000003ff #define HOSTCC_TXCOAL_TICK_INT 0x00003c1c #define DEFAULT_TXCOAL_TICK_INT 0x00000019 #define DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014 +#define MAX_TXCOAL_TICK_INT 0x000003ff #define HOSTCC_RXCOAL_MAXF_INT 0x00003c20 #define DEFAULT_RXCOAL_MAXF_INT 0x00000005 +#define MAX_RXCOAL_MAXF_INT 0x000000ff #define HOSTCC_TXCOAL_MAXF_INT 0x00003c24 #define DEFAULT_TXCOAL_MAXF_INT 0x00000005 +#define MAX_TXCOAL_MAXF_INT 0x000000ff #define HOSTCC_STAT_COAL_TICKS 0x00003c28 #define DEFAULT_STAT_COAL_TICKS 0x000f4240 +#define MAX_STAT_COAL_TICKS 0xd693d400 +#define MIN_STAT_COAL_TICKS 0x00000064 /* 0x3c2c --> 0x3c30 unused */ #define HOSTCC_STATS_BLK_HOST_ADDR 0x00003c30 /* 64-bit */ #define HOSTCC_STATUS_BLK_HOST_ADDR 0x00003c38 /* 64-bit */ -- cgit v1.1 From 93e266f600f4048fe7a2e8803abb9f8baff84aa7 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 14:43:19 -0700 Subject: [TG3]: Update driver version and reldate. Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 7f84dc8..5464068 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -66,8 +66,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.32" -#define DRV_MODULE_RELDATE "June 24, 2005" +#define DRV_MODULE_VERSION "3.33" +#define DRV_MODULE_RELDATE "July 5, 2005" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 -- cgit v1.1 From f0e36f8cee8101604378085171c980d9cc71d779 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Tue, 5 Jul 2005 14:44:55 -0700 Subject: [IPV4]: Handle large allocations in fib_trie Inflating a node a couple of times makes it exceed the 128k kmalloc limit. Use __get_free_pages for allocations > PAGE_SIZE, as in fib_hash. Signed-off-by: Patrick McHardy Acked-by: Robert Olsson Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index b56e88e..9038b91 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -358,11 +358,32 @@ static inline void free_leaf_info(struct leaf_info *li) kfree(li); } +static struct tnode *tnode_alloc(unsigned int size) +{ + if (size <= PAGE_SIZE) { + return kmalloc(size, GFP_KERNEL); + } else { + return (struct tnode *) + __get_free_pages(GFP_KERNEL, get_order(size)); + } +} + +static void __tnode_free(struct tnode *tn) +{ + unsigned int size = sizeof(struct tnode) + + (1<bits) * sizeof(struct node *); + + if (size <= PAGE_SIZE) + kfree(tn); + else + free_pages((unsigned long)tn, get_order(size)); +} + static struct tnode* tnode_new(t_key key, int pos, int bits) { int nchildren = 1< 0 ) printk("FT %p \n", tn); } -- cgit v1.1 From 22c047ccbc68fa8f3fa57f0e8f906479a062c426 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Jul 2005 14:55:24 -0700 Subject: [NET]: Hashed spinlocks in net/ipv4/route.c - Locking abstraction - Spinlocks moved out of rt hash table : Less memory (50%) used by rt hash table. it's a win even on UP. - Sizing of spinlocks table depends on NR_CPUS Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 66 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 19 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 12a1cf3..daf82f8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -54,6 +54,7 @@ * Marc Boucher : routing by fwmark * Robert Olsson : Added rt_cache statistics * Arnaldo C. Melo : Convert proc stuff to seq_file + * Eric Dumazet : hashed spinlocks * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -201,8 +202,37 @@ __u8 ip_tos2prio[16] = { struct rt_hash_bucket { struct rtable *chain; - spinlock_t lock; -} __attribute__((__aligned__(8))); +}; +#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK) +/* + * Instead of using one spinlock for each rt_hash_bucket, we use a table of spinlocks + * The size of this table is a power of two and depends on the number of CPUS. + */ +#if NR_CPUS >= 32 +#define RT_HASH_LOCK_SZ 4096 +#elif NR_CPUS >= 16 +#define RT_HASH_LOCK_SZ 2048 +#elif NR_CPUS >= 8 +#define RT_HASH_LOCK_SZ 1024 +#elif NR_CPUS >= 4 +#define RT_HASH_LOCK_SZ 512 +#else +#define RT_HASH_LOCK_SZ 256 +#endif + +static spinlock_t *rt_hash_locks; +# define rt_hash_lock_addr(slot) &rt_hash_locks[(slot) & (RT_HASH_LOCK_SZ - 1)] +# define rt_hash_lock_init() { \ + int i; \ + rt_hash_locks = kmalloc(sizeof(spinlock_t) * RT_HASH_LOCK_SZ, GFP_KERNEL); \ + if (!rt_hash_locks) panic("IP: failed to allocate rt_hash_locks\n"); \ + for (i = 0; i < RT_HASH_LOCK_SZ; i++) \ + spin_lock_init(&rt_hash_locks[i]); \ + } +#else +# define rt_hash_lock_addr(slot) NULL +# define rt_hash_lock_init() +#endif static struct rt_hash_bucket *rt_hash_table; static unsigned rt_hash_mask; @@ -587,7 +617,7 @@ static void rt_check_expire(unsigned long dummy) i = (i + 1) & rt_hash_mask; rthp = &rt_hash_table[i].chain; - spin_lock(&rt_hash_table[i].lock); + spin_lock(rt_hash_lock_addr(i)); while ((rth = *rthp) != NULL) { if (rth->u.dst.expires) { /* Entry is expired even if it is in use */ @@ -620,7 +650,7 @@ static void rt_check_expire(unsigned long dummy) rt_free(rth); #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ } - spin_unlock(&rt_hash_table[i].lock); + spin_unlock(rt_hash_lock_addr(i)); /* Fallback loop breaker. */ if (time_after(jiffies, now)) @@ -643,11 +673,11 @@ static void rt_run_flush(unsigned long dummy) get_random_bytes(&rt_hash_rnd, 4); for (i = rt_hash_mask; i >= 0; i--) { - spin_lock_bh(&rt_hash_table[i].lock); + spin_lock_bh(rt_hash_lock_addr(i)); rth = rt_hash_table[i].chain; if (rth) rt_hash_table[i].chain = NULL; - spin_unlock_bh(&rt_hash_table[i].lock); + spin_unlock_bh(rt_hash_lock_addr(i)); for (; rth; rth = next) { next = rth->u.rt_next; @@ -780,7 +810,7 @@ static int rt_garbage_collect(void) k = (k + 1) & rt_hash_mask; rthp = &rt_hash_table[k].chain; - spin_lock_bh(&rt_hash_table[k].lock); + spin_lock_bh(rt_hash_lock_addr(k)); while ((rth = *rthp) != NULL) { if (!rt_may_expire(rth, tmo, expire)) { tmo >>= 1; @@ -812,7 +842,7 @@ static int rt_garbage_collect(void) goal--; #endif /* CONFIG_IP_ROUTE_MULTIPATH_CACHED */ } - spin_unlock_bh(&rt_hash_table[k].lock); + spin_unlock_bh(rt_hash_lock_addr(k)); if (goal <= 0) break; } @@ -882,7 +912,7 @@ restart: rthp = &rt_hash_table[hash].chain; - spin_lock_bh(&rt_hash_table[hash].lock); + spin_lock_bh(rt_hash_lock_addr(hash)); while ((rth = *rthp) != NULL) { #ifdef CONFIG_IP_ROUTE_MULTIPATH_CACHED if (!(rth->u.dst.flags & DST_BALANCED) && @@ -908,7 +938,7 @@ restart: rth->u.dst.__use++; dst_hold(&rth->u.dst); rth->u.dst.lastuse = now; - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); rt_drop(rt); *rp = rth; @@ -949,7 +979,7 @@ restart: if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { int err = arp_bind_neighbour(&rt->u.dst); if (err) { - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); if (err != -ENOBUFS) { rt_drop(rt); @@ -990,7 +1020,7 @@ restart: } #endif rt_hash_table[hash].chain = rt; - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); *rp = rt; return 0; } @@ -1058,7 +1088,7 @@ static void rt_del(unsigned hash, struct rtable *rt) { struct rtable **rthp; - spin_lock_bh(&rt_hash_table[hash].lock); + spin_lock_bh(rt_hash_lock_addr(hash)); ip_rt_put(rt); for (rthp = &rt_hash_table[hash].chain; *rthp; rthp = &(*rthp)->u.rt_next) @@ -1067,7 +1097,7 @@ static void rt_del(unsigned hash, struct rtable *rt) rt_free(rt); break; } - spin_unlock_bh(&rt_hash_table[hash].lock); + spin_unlock_bh(rt_hash_lock_addr(hash)); } void ip_rt_redirect(u32 old_gw, u32 daddr, u32 new_gw, @@ -3073,7 +3103,7 @@ __setup("rhash_entries=", set_rhash_entries); int __init ip_rt_init(void) { - int i, order, goal, rc = 0; + int order, goal, rc = 0; rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^ (jiffies ^ (jiffies >> 7))); @@ -3122,10 +3152,8 @@ int __init ip_rt_init(void) /* NOTHING */; rt_hash_mask--; - for (i = 0; i <= rt_hash_mask; i++) { - spin_lock_init(&rt_hash_table[i].lock); - rt_hash_table[i].chain = NULL; - } + memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket)); + rt_hash_lock_init(); ipv4_dst_ops.gc_thresh = (rt_hash_mask + 1); ip_rt_max_size = (rt_hash_mask + 1) * 16; -- cgit v1.1 From 424c4b70cc4ff3930ee36a2ef7b204e4d704fd26 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Jul 2005 14:58:19 -0700 Subject: [IPV4]: Use the fancy alloc_large_system_hash() function for route hash table - rt hash table allocated using alloc_large_system_hash() function. Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 43 ++++++++++++++++--------------------------- 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index daf82f8..9fcbb1b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -3103,12 +3104,14 @@ __setup("rhash_entries=", set_rhash_entries); int __init ip_rt_init(void) { - int order, goal, rc = 0; + int rc = 0; rt_hash_rnd = (int) ((num_physpages ^ (num_physpages>>8)) ^ (jiffies ^ (jiffies >> 7))); #ifdef CONFIG_NET_CLS_ROUTE + { + int order; for (order = 0; (PAGE_SIZE << order) < 256 * sizeof(struct ip_rt_acct) * NR_CPUS; order++) /* NOTHING */; @@ -3116,6 +3119,7 @@ int __init ip_rt_init(void) if (!ip_rt_acct) panic("IP: failed to allocate ip_rt_acct\n"); memset(ip_rt_acct, 0, PAGE_SIZE << order); + } #endif ipv4_dst_ops.kmem_cachep = kmem_cache_create("ip_dst_cache", @@ -3126,32 +3130,17 @@ int __init ip_rt_init(void) if (!ipv4_dst_ops.kmem_cachep) panic("IP: failed to allocate ip_dst_cache\n"); - goal = num_physpages >> (26 - PAGE_SHIFT); - if (rhash_entries) - goal = (rhash_entries * sizeof(struct rt_hash_bucket)) >> PAGE_SHIFT; - for (order = 0; (1UL << order) < goal; order++) - /* NOTHING */; - - do { - rt_hash_mask = (1UL << order) * PAGE_SIZE / - sizeof(struct rt_hash_bucket); - while (rt_hash_mask & (rt_hash_mask - 1)) - rt_hash_mask--; - rt_hash_table = (struct rt_hash_bucket *) - __get_free_pages(GFP_ATOMIC, order); - } while (rt_hash_table == NULL && --order > 0); - - if (!rt_hash_table) - panic("Failed to allocate IP route cache hash table\n"); - - printk(KERN_INFO "IP: routing cache hash table of %u buckets, %ldKbytes\n", - rt_hash_mask, - (long) (rt_hash_mask * sizeof(struct rt_hash_bucket)) / 1024); - - for (rt_hash_log = 0; (1 << rt_hash_log) != rt_hash_mask; rt_hash_log++) - /* NOTHING */; - - rt_hash_mask--; + rt_hash_table = (struct rt_hash_bucket *) + alloc_large_system_hash("IP route cache", + sizeof(struct rt_hash_bucket), + rhash_entries, + (num_physpages >= 128 * 1024) ? + (27 - PAGE_SHIFT) : + (29 - PAGE_SHIFT), + HASH_HIGHMEM, + &rt_hash_log, + &rt_hash_mask, + 0); memset(rt_hash_table, 0, (rt_hash_mask + 1) * sizeof(struct rt_hash_bucket)); rt_hash_lock_init(); -- cgit v1.1 From bb1d23b02657f494dff295f6cdd1f29df30fa61e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 5 Jul 2005 15:00:32 -0700 Subject: [IPV4]: Bug fix in rt_check_expire() - rt_check_expire() fixes (an overflow occured if size of the hash was >= 65536) reminder of the bugfix: The rt_check_expire() has a serious problem on machines with large route caches, and a standard HZ value of 1000. With default values, ie ip_rt_gc_interval = 60*HZ = 60000 ; the loop count : for (t = ip_rt_gc_interval << rt_hash_log; t >= 0; overflows (t is a 31 bit value) as soon rt_hash_log is >= 16 (65536 slots in route cache hash table). In this case, rt_check_expire() does nothing at all Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- net/ipv4/route.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 9fcbb1b..726ea5e 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -54,7 +54,7 @@ * Marc Boucher : routing by fwmark * Robert Olsson : Added rt_cache statistics * Arnaldo C. Melo : Convert proc stuff to seq_file - * Eric Dumazet : hashed spinlocks + * Eric Dumazet : hashed spinlocks and rt_check_expire() fixes. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -606,18 +606,25 @@ static struct rtable **rt_remove_balanced_route(struct rtable **chain_head, /* This runs via a timer and thus is always in BH context. */ static void rt_check_expire(unsigned long dummy) { - static int rover; - int i = rover, t; + static unsigned int rover; + unsigned int i = rover, goal; struct rtable *rth, **rthp; unsigned long now = jiffies; - - for (t = ip_rt_gc_interval << rt_hash_log; t >= 0; - t -= ip_rt_gc_timeout) { + u64 mult; + + mult = ((u64)ip_rt_gc_interval) << rt_hash_log; + if (ip_rt_gc_timeout > 1) + do_div(mult, ip_rt_gc_timeout); + goal = (unsigned int)mult; + if (goal > rt_hash_mask) goal = rt_hash_mask + 1; + for (; goal > 0; goal--) { unsigned long tmo = ip_rt_gc_timeout; i = (i + 1) & rt_hash_mask; rthp = &rt_hash_table[i].chain; + if (*rthp == 0) + continue; spin_lock(rt_hash_lock_addr(i)); while ((rth = *rthp) != NULL) { if (rth->u.dst.expires) { @@ -658,7 +665,7 @@ static void rt_check_expire(unsigned long dummy) break; } rover = i; - mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval); + mod_timer(&rt_periodic_timer, jiffies + ip_rt_gc_interval); } /* This can run from both BH and non-BH contexts, the latter -- cgit v1.1 From db1322b8012e1a8ad711c04813817328cff46718 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 15:01:25 -0700 Subject: [DECNET]: Fix memset overflow on 64bit archs while dumping decnet routing rules Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/decnet/dn_fib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 9934b25..99bc061 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -551,7 +551,8 @@ int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb) if (t < s_t) continue; if (t > s_t) - memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int)); + memset(&cb->args[1], 0, + sizeof(cb->args) - sizeof(cb->args[0])); tb = dn_fib_get_table(t, 0); if (tb == NULL) continue; -- cgit v1.1 From 2f36895aa774cf4d1c3d68921e0209e796b66600 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Tue, 5 Jul 2005 15:02:40 -0700 Subject: [IPV4]: More broken memory allocation fixes for fib_trie Below a patch to preallocate memory when doing resize of trie (inflate halve) If preallocations fails it just skips the resize of this tnode for this time. The oops we got when killing bgpd (with full routing) is now gone. Patrick memory patch is also used. Signed-off-by: Robert Olsson Signed-off-by: David S. Miller --- net/ipv4/fib_trie.c | 177 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 145 insertions(+), 32 deletions(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 9038b91..4be234c 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -43,7 +43,7 @@ * 2 of the License, or (at your option) any later version. */ -#define VERSION "0.324" +#define VERSION "0.325" #include #include @@ -136,6 +136,7 @@ struct trie_use_stats { unsigned int semantic_match_passed; unsigned int semantic_match_miss; unsigned int null_node_hit; + unsigned int resize_node_skipped; }; #endif @@ -164,8 +165,8 @@ static void put_child(struct trie *t, struct tnode *tn, int i, struct node *n); static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int wasfull); static int tnode_child_length(struct tnode *tn); static struct node *resize(struct trie *t, struct tnode *tn); -static struct tnode *inflate(struct trie *t, struct tnode *tn); -static struct tnode *halve(struct trie *t, struct tnode *tn); +static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err); +static struct tnode *halve(struct trie *t, struct tnode *tn, int *err); static void tnode_free(struct tnode *tn); static void trie_dump_seq(struct seq_file *seq, struct trie *t); extern struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio); @@ -481,6 +482,7 @@ static void tnode_put_child_reorg(struct tnode *tn, int i, struct node *n, int w static struct node *resize(struct trie *t, struct tnode *tn) { int i; + int err = 0; if (!tn) return NULL; @@ -577,12 +579,20 @@ static struct node *resize(struct trie *t, struct tnode *tn) */ check_tnode(tn); - + + err = 0; while ((tn->full_children > 0 && 50 * (tn->full_children + tnode_child_length(tn) - tn->empty_children) >= inflate_threshold * tnode_child_length(tn))) { - tn = inflate(t, tn); + tn = inflate(t, tn, &err); + + if(err) { +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.resize_node_skipped++; +#endif + break; + } } check_tnode(tn); @@ -591,11 +601,22 @@ static struct node *resize(struct trie *t, struct tnode *tn) * Halve as long as the number of empty children in this * node is above threshold. */ + + err = 0; while (tn->bits > 1 && 100 * (tnode_child_length(tn) - tn->empty_children) < - halve_threshold * tnode_child_length(tn)) + halve_threshold * tnode_child_length(tn)) { + + tn = halve(t, tn, &err); + + if(err) { +#ifdef CONFIG_IP_FIB_TRIE_STATS + t->stats.resize_node_skipped++; +#endif + break; + } + } - tn = halve(t, tn); /* Only one child remains */ @@ -620,7 +641,7 @@ static struct node *resize(struct trie *t, struct tnode *tn) return (struct node *) tn; } -static struct tnode *inflate(struct trie *t, struct tnode *tn) +static struct tnode *inflate(struct trie *t, struct tnode *tn, int *err) { struct tnode *inode; struct tnode *oldtnode = tn; @@ -632,8 +653,63 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) tn = tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits + 1); - if (!tn) - trie_bug("tnode_new failed"); + if (!tn) { + *err = -ENOMEM; + return oldtnode; + } + + /* + * Preallocate and store tnodes before the actual work so we + * don't get into an inconsistent state if memory allocation + * fails. In case of failure we return the oldnode and inflate + * of tnode is ignored. + */ + + for(i = 0; i < olen; i++) { + struct tnode *inode = (struct tnode *) tnode_get_child(oldtnode, i); + + if (inode && + IS_TNODE(inode) && + inode->pos == oldtnode->pos + oldtnode->bits && + inode->bits > 1) { + struct tnode *left, *right; + + t_key m = TKEY_GET_MASK(inode->pos, 1); + + left = tnode_new(inode->key&(~m), inode->pos + 1, + inode->bits - 1); + + if(!left) { + *err = -ENOMEM; + break; + } + + right = tnode_new(inode->key|m, inode->pos + 1, + inode->bits - 1); + + if(!right) { + *err = -ENOMEM; + break; + } + + put_child(t, tn, 2*i, (struct node *) left); + put_child(t, tn, 2*i+1, (struct node *) right); + } + } + + if(*err) { + int size = tnode_child_length(tn); + int j; + + for(j = 0; j < size; j++) + if( tn->child[j]) + tnode_free((struct tnode *)tn->child[j]); + + tnode_free(tn); + + *err = -ENOMEM; + return oldtnode; + } for(i = 0; i < olen; i++) { struct node *node = tnode_get_child(oldtnode, i); @@ -646,7 +722,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) if(IS_LEAF(node) || ((struct tnode *) node)->pos > tn->pos + tn->bits - 1) { - if(tkey_extract_bits(node->key, tn->pos + tn->bits - 1, + if(tkey_extract_bits(node->key, oldtnode->pos + oldtnode->bits, 1) == 0) put_child(t, tn, 2*i, node); else @@ -686,27 +762,22 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) * the position (inode->pos) */ - t_key m = TKEY_GET_MASK(inode->pos, 1); - /* Use the old key, but set the new significant * bit to zero. */ - left = tnode_new(inode->key&(~m), inode->pos + 1, - inode->bits - 1); - if(!left) - trie_bug("tnode_new failed"); - - - /* Use the old key, but set the new significant - * bit to one. - */ - right = tnode_new(inode->key|m, inode->pos + 1, - inode->bits - 1); + left = (struct tnode *) tnode_get_child(tn, 2*i); + put_child(t, tn, 2*i, NULL); + + if(!left) + BUG(); + + right = (struct tnode *) tnode_get_child(tn, 2*i+1); + put_child(t, tn, 2*i+1, NULL); + + if(!right) + BUG(); - if(!right) - trie_bug("tnode_new failed"); - size = tnode_child_length(left); for(j = 0; j < size; j++) { put_child(t, left, j, inode->child[j]); @@ -722,7 +793,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn) return tn; } -static struct tnode *halve(struct trie *t, struct tnode *tn) +static struct tnode *halve(struct trie *t, struct tnode *tn, int *err) { struct tnode *oldtnode = tn; struct node *left, *right; @@ -733,8 +804,48 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) tn=tnode_new(oldtnode->key, oldtnode->pos, oldtnode->bits - 1); - if(!tn) - trie_bug("tnode_new failed"); + if (!tn) { + *err = -ENOMEM; + return oldtnode; + } + + /* + * Preallocate and store tnodes before the actual work so we + * don't get into an inconsistent state if memory allocation + * fails. In case of failure we return the oldnode and halve + * of tnode is ignored. + */ + + for(i = 0; i < olen; i += 2) { + left = tnode_get_child(oldtnode, i); + right = tnode_get_child(oldtnode, i+1); + + /* Two nonempty children */ + if( left && right) { + struct tnode *newBinNode = + tnode_new(left->key, tn->pos + tn->bits, 1); + + if(!newBinNode) { + *err = -ENOMEM; + break; + } + put_child(t, tn, i/2, (struct node *)newBinNode); + } + } + + if(*err) { + int size = tnode_child_length(tn); + int j; + + for(j = 0; j < size; j++) + if( tn->child[j]) + tnode_free((struct tnode *)tn->child[j]); + + tnode_free(tn); + + *err = -ENOMEM; + return oldtnode; + } for(i = 0; i < olen; i += 2) { left = tnode_get_child(oldtnode, i); @@ -751,10 +862,11 @@ static struct tnode *halve(struct trie *t, struct tnode *tn) /* Two nonempty children */ else { struct tnode *newBinNode = - tnode_new(left->key, tn->pos + tn->bits, 1); + (struct tnode *) tnode_get_child(tn, i/2); + put_child(t, tn, i/2, NULL); if(!newBinNode) - trie_bug("tnode_new failed"); + BUG(); put_child(t, newBinNode, 0, left); put_child(t, newBinNode, 1, right); @@ -2322,6 +2434,7 @@ static void collect_and_show(struct trie *t, struct seq_file *seq) seq_printf(seq,"semantic match passed = %d\n", t->stats.semantic_match_passed); seq_printf(seq,"semantic match miss = %d\n", t->stats.semantic_match_miss); seq_printf(seq,"null node hit= %d\n", t->stats.null_node_hit); + seq_printf(seq,"skipped node resize = %d\n", t->stats.resize_node_skipped); #ifdef CLEAR_STATS memset(&(t->stats), 0, sizeof(t->stats)); #endif -- cgit v1.1 From bc971dee6ece1fd0d431948924becd9c50e7b778 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 5 Jul 2005 15:03:46 -0700 Subject: [SHAPER]: Switch to spinlocks. Dave, you were right and the sleeping locks in shaper were broken. Markus Kanet noticed this and also tested the patch below that switches locking to spinlocks. Signed-off-by: Christoph Hellwig Signed-off-by: David S. Miller --- drivers/net/shaper.c | 42 ++++++++++++++++-------------------------- include/linux/if_shaper.h | 2 +- 2 files changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c index 20edeb3..3ad0b67 100644 --- a/drivers/net/shaper.c +++ b/drivers/net/shaper.c @@ -135,10 +135,8 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct shaper *shaper = dev->priv; struct sk_buff *ptr; - - if (down_trylock(&shaper->sem)) - return -1; - + + spin_lock(&shaper->lock); ptr=shaper->sendq.prev; /* @@ -232,7 +230,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev) shaper->stats.collisions++; } shaper_kick(shaper); - up(&shaper->sem); + spin_unlock(&shaper->lock); return 0; } @@ -271,11 +269,9 @@ static void shaper_timer(unsigned long data) { struct shaper *shaper = (struct shaper *)data; - if (!down_trylock(&shaper->sem)) { - shaper_kick(shaper); - up(&shaper->sem); - } else - mod_timer(&shaper->timer, jiffies); + spin_lock(&shaper->lock); + shaper_kick(shaper); + spin_unlock(&shaper->lock); } /* @@ -332,21 +328,6 @@ static void shaper_kick(struct shaper *shaper) /* - * Flush the shaper queues on a closedown - */ - -static void shaper_flush(struct shaper *shaper) -{ - struct sk_buff *skb; - - down(&shaper->sem); - while((skb=skb_dequeue(&shaper->sendq))!=NULL) - dev_kfree_skb(skb); - shaper_kick(shaper); - up(&shaper->sem); -} - -/* * Bring the interface up. We just disallow this until a * bind. */ @@ -375,7 +356,15 @@ static int shaper_open(struct net_device *dev) static int shaper_close(struct net_device *dev) { struct shaper *shaper=dev->priv; - shaper_flush(shaper); + struct sk_buff *skb; + + while ((skb = skb_dequeue(&shaper->sendq)) != NULL) + dev_kfree_skb(skb); + + spin_lock_bh(&shaper->lock); + shaper_kick(shaper); + spin_unlock_bh(&shaper->lock); + del_timer_sync(&shaper->timer); return 0; } @@ -576,6 +565,7 @@ static void shaper_init_priv(struct net_device *dev) init_timer(&sh->timer); sh->timer.function=shaper_timer; sh->timer.data=(unsigned long)sh; + spin_lock_init(&sh->lock); } /* diff --git a/include/linux/if_shaper.h b/include/linux/if_shaper.h index 004e6f0..68c896a 100644 --- a/include/linux/if_shaper.h +++ b/include/linux/if_shaper.h @@ -23,7 +23,7 @@ struct shaper __u32 shapeclock; unsigned long recovery; /* Time we can next clock a packet out on an empty queue */ - struct semaphore sem; + spinlock_t lock; struct net_device_stats stats; struct net_device *dev; int (*hard_start_xmit) (struct sk_buff *skb, -- cgit v1.1 From 52609c0b56d7c8dfb6e16ec0a715adf8fcbdae36 Mon Sep 17 00:00:00 2001 From: David Chau Date: Tue, 5 Jul 2005 15:11:06 -0700 Subject: [NET]: improve readability of dev_set_promiscuity() in net/core/dev.c A trivial patch to improve the readability of dev_set_promiscuity() in net/core/dev.c. New code does exactly the same thing as original code. Signed-off-by: David Chau Signed-off-by: Domen Puncer Signed-off-by: David S. Miller --- net/core/dev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index 7016e0c..7f5f62c 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2089,10 +2089,11 @@ void dev_set_promiscuity(struct net_device *dev, int inc) { unsigned short old_flags = dev->flags; - dev->flags |= IFF_PROMISC; if ((dev->promiscuity += inc) == 0) dev->flags &= ~IFF_PROMISC; - if (dev->flags ^ old_flags) { + else + dev->flags |= IFF_PROMISC; + if (dev->flags != old_flags) { dev_mc_upload(dev); printk(KERN_INFO "device %s %s promiscuous mode\n", dev->name, (dev->flags & IFF_PROMISC) ? "entered" : -- cgit v1.1 From b8259d9ad1d0f8d0c5ea0e37bb15080b0bd395b5 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Tue, 5 Jul 2005 15:12:04 -0700 Subject: [NET]: Remove __ARGS from include/net/slhc_vj.h I suspect "#define __ARGS(x) ()" was deprecated before I was born. Signed-off-by: Alexey Dobriyan Signed-off-by: Domen Puncer Signed-off-by: David S. Miller --- include/net/slhc_vj.h | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/include/net/slhc_vj.h b/include/net/slhc_vj.h index 0b2c278..8716d59 100644 --- a/include/net/slhc_vj.h +++ b/include/net/slhc_vj.h @@ -170,19 +170,14 @@ struct slcompress { }; #define NULLSLCOMPR (struct slcompress *)0 -#define __ARGS(x) x - /* In slhc.c: */ -struct slcompress *slhc_init __ARGS((int rslots, int tslots)); -void slhc_free __ARGS((struct slcompress *comp)); - -int slhc_compress __ARGS((struct slcompress *comp, unsigned char *icp, - int isize, unsigned char *ocp, unsigned char **cpp, - int compress_cid)); -int slhc_uncompress __ARGS((struct slcompress *comp, unsigned char *icp, - int isize)); -int slhc_remember __ARGS((struct slcompress *comp, unsigned char *icp, - int isize)); -int slhc_toss __ARGS((struct slcompress *comp)); +struct slcompress *slhc_init(int rslots, int tslots); +void slhc_free(struct slcompress *comp); + +int slhc_compress(struct slcompress *comp, unsigned char *icp, int isize, + unsigned char *ocp, unsigned char **cpp, int compress_cid); +int slhc_uncompress(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_remember(struct slcompress *comp, unsigned char *icp, int isize); +int slhc_toss(struct slcompress *comp); #endif /* _SLHC_H */ -- cgit v1.1 From c65f7f00c587828e3d50737805a78f74804972de Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:17:25 -0700 Subject: [TCP]: Simplify SKB data portion allocation with NETIF_F_SG. The ideal and most optimal layout for an SKB when doing scatter-gather is to put all the headers at skb->data, and all the user data in the page array. This makes SKB splitting and combining extremely simple, especially before a packet goes onto the wire the first time. So, when sk_stream_alloc_pskb() is given a zero size, make sure there is no skb_tailroom(). This is achieved by applying SKB_DATA_ALIGN() to the header length used here. Next, make select_size() in TCP output segmentation use a length of zero when NETIF_F_SG is true on the outgoing interface. Signed-off-by: David S. Miller --- include/net/sock.h | 7 +++++-- net/ipv4/tcp.c | 13 ++----------- 2 files changed, 7 insertions(+), 13 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index e593af5..7b76f89 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1134,13 +1134,16 @@ static inline void sk_stream_moderate_sndbuf(struct sock *sk) static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, int size, int mem, int gfp) { - struct sk_buff *skb = alloc_skb(size + sk->sk_prot->max_header, gfp); + struct sk_buff *skb; + int hdr_len; + hdr_len = SKB_DATA_ALIGN(sk->sk_prot->max_header); + skb = alloc_skb(size + hdr_len, gfp); if (skb) { skb->truesize += mem; if (sk->sk_forward_alloc >= (int)skb->truesize || sk_stream_mem_schedule(sk, skb->truesize, 0)) { - skb_reserve(skb, sk->sk_prot->max_header); + skb_reserve(skb, hdr_len); return skb; } __kfree_skb(skb); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 882436d..be35415 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -756,13 +756,9 @@ static inline int select_size(struct sock *sk, struct tcp_sock *tp) { int tmp = tp->mss_cache_std; - if (sk->sk_route_caps & NETIF_F_SG) { - int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); + if (sk->sk_route_caps & NETIF_F_SG) + tmp = 0; - if (tmp >= pgbreak && - tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) - tmp = pgbreak; - } return tmp; } @@ -872,11 +868,6 @@ new_segment: tcp_mark_push(tp, skb); goto new_segment; } else if (page) { - /* If page is cached, align - * offset to L1 cache boundary - */ - off = (off + L1_CACHE_BYTES - 1) & - ~(L1_CACHE_BYTES - 1); if (off == PAGE_SIZE) { put_page(page); TCP_PAGE(sk) = page = NULL; -- cgit v1.1 From fc6415bcb0f58f03adb910e56d7e1df6368794e0 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:17:45 -0700 Subject: [TCP]: Fix quick-ack decrementing with TSO. On each packet output, we call tcp_dec_quickack_mode() if the ACK flag is set. It drops tp->ack.quick until it hits zero, at which time we deflate the ATO value. When doing TSO, we are emitting multiple packets with ACK set, so we should decrement tp->ack.quick that many segments. Note that, unlike this case, tcp_enter_cwr() should not take the tcp_skb_pcount(skb) into consideration. That function, one time, readjusts tp->snd_cwnd and moves into TCP_CA_CWR state. Signed-off-by: David S. Miller --- include/net/tcp.h | 13 +++++++++---- net/ipv4/tcp_output.c | 6 +++--- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index ec9e20c..afe41c5 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -721,11 +721,16 @@ static inline int tcp_ack_scheduled(struct tcp_sock *tp) return tp->ack.pending&TCP_ACK_SCHED; } -static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp) +static __inline__ void tcp_dec_quickack_mode(struct tcp_sock *tp, unsigned int pkts) { - if (tp->ack.quick && --tp->ack.quick == 0) { - /* Leaving quickack mode we deflate ATO. */ - tp->ack.ato = TCP_ATO_MIN; + if (tp->ack.quick) { + if (pkts >= tp->ack.quick) { + tp->ack.quick = 0; + + /* Leaving quickack mode we deflate ATO. */ + tp->ack.ato = TCP_ATO_MIN; + } else + tp->ack.quick -= pkts; } } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0e17c24..389deeb 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -140,11 +140,11 @@ static inline void tcp_event_data_sent(struct tcp_sock *tp, tp->ack.pingpong = 1; } -static __inline__ void tcp_event_ack_sent(struct sock *sk) +static __inline__ void tcp_event_ack_sent(struct sock *sk, unsigned int pkts) { struct tcp_sock *tp = tcp_sk(sk); - tcp_dec_quickack_mode(tp); + tcp_dec_quickack_mode(tp, pkts); tcp_clear_xmit_timer(sk, TCP_TIME_DACK); } @@ -355,7 +355,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) tp->af_specific->send_check(sk, th, skb->len, skb); if (tcb->flags & TCPCB_FLAG_ACK) - tcp_event_ack_sent(sk); + tcp_event_ack_sent(sk, tcp_skb_pcount(skb)); if (skb->len != tcp_header_size) tcp_event_data_sent(tp, skb, sk); -- cgit v1.1 From f6302d1d78f77c2d4c8bd32b0afc2df7fdf5f281 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:18:03 -0700 Subject: [TCP]: Move send test logic out of net/tcp.h This just moves the code into tcp_output.c, no code logic changes are made by this patch. Using this as a baseline, we can begin to untangle the mess of comparisons for the Nagle test et al. We will also be able to reduce all of the redundant computation that occurs when outputting data packets. Signed-off-by: David S. Miller --- include/net/tcp.h | 113 +------------------------------------ net/ipv4/tcp_output.c | 150 +++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 132 insertions(+), 131 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index afe41c5..f2b1045 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -849,6 +849,9 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, /* tcp_output.c */ extern int tcp_write_xmit(struct sock *, int nonagle); +extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, + unsigned cur_mss, int nonagle); +extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_xmit_retransmit_queue(struct sock *); extern void tcp_simple_retransmit(struct sock *); @@ -1284,12 +1287,6 @@ static __inline__ __u32 tcp_max_burst(const struct tcp_sock *tp) return 3; } -static __inline__ int tcp_minshall_check(const struct tcp_sock *tp) -{ - return after(tp->snd_sml,tp->snd_una) && - !after(tp->snd_sml, tp->snd_nxt); -} - static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, const struct sk_buff *skb) { @@ -1297,122 +1294,18 @@ static __inline__ void tcp_minshall_update(struct tcp_sock *tp, int mss, tp->snd_sml = TCP_SKB_CB(skb)->end_seq; } -/* Return 0, if packet can be sent now without violation Nagle's rules: - 1. It is full sized. - 2. Or it contains FIN. - 3. Or TCP_NODELAY was set. - 4. Or TCP_CORK is not set, and all sent packets are ACKed. - With Minshall's modification: all sent small packets are ACKed. - */ - -static __inline__ int -tcp_nagle_check(const struct tcp_sock *tp, const struct sk_buff *skb, - unsigned mss_now, int nonagle) -{ - return (skb->len < mss_now && - !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && - ((nonagle&TCP_NAGLE_CORK) || - (!nonagle && - tp->packets_out && - tcp_minshall_check(tp)))); -} - -extern void tcp_set_skb_tso_segs(struct sock *, struct sk_buff *); - -/* This checks if the data bearing packet SKB (usually sk->sk_send_head) - * should be put on the wire right now. - */ -static __inline__ int tcp_snd_test(struct sock *sk, - struct sk_buff *skb, - unsigned cur_mss, int nonagle) -{ - struct tcp_sock *tp = tcp_sk(sk); - int pkts = tcp_skb_pcount(skb); - - if (!pkts) { - tcp_set_skb_tso_segs(sk, skb); - pkts = tcp_skb_pcount(skb); - } - - /* RFC 1122 - section 4.2.3.4 - * - * We must queue if - * - * a) The right edge of this frame exceeds the window - * b) There are packets in flight and we have a small segment - * [SWS avoidance and Nagle algorithm] - * (part of SWS is done on packetization) - * Minshall version sounds: there are no _small_ - * segments in flight. (tcp_nagle_check) - * c) We have too many packets 'in flight' - * - * Don't use the nagle rule for urgent data (or - * for the final FIN -DaveM). - * - * Also, Nagle rule does not apply to frames, which - * sit in the middle of queue (they have no chances - * to get new data) and if room at tail of skb is - * not enough to save something seriously (<32 for now). - */ - - /* Don't be strict about the congestion window for the - * final FIN frame. -DaveM - */ - return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode - || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && - (((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) || - (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && - !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); -} - static __inline__ void tcp_check_probe_timer(struct sock *sk, struct tcp_sock *tp) { if (!tp->packets_out && !tp->pending) tcp_reset_xmit_timer(sk, TCP_TIME_PROBE0, tp->rto); } -static __inline__ int tcp_skb_is_last(const struct sock *sk, - const struct sk_buff *skb) -{ - return skb->next == (struct sk_buff *)&sk->sk_write_queue; -} - -/* Push out any pending frames which were held back due to - * TCP_CORK or attempt at coalescing tiny packets. - * The socket must be locked by the caller. - */ -static __inline__ void __tcp_push_pending_frames(struct sock *sk, - struct tcp_sock *tp, - unsigned cur_mss, - int nonagle) -{ - struct sk_buff *skb = sk->sk_send_head; - - if (skb) { - if (!tcp_skb_is_last(sk, skb)) - nonagle = TCP_NAGLE_PUSH; - if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || - tcp_write_xmit(sk, nonagle)) - tcp_check_probe_timer(sk, tp); - } - tcp_cwnd_validate(sk, tp); -} - static __inline__ void tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp) { __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 1), tp->nonagle); } -static __inline__ int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) -{ - struct sk_buff *skb = sk->sk_send_head; - - return (skb && - tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), - tcp_skb_is_last(sk, skb) ? TCP_NAGLE_PUSH : tp->nonagle)); -} - static __inline__ void tcp_init_wl(struct tcp_sock *tp, u32 ack, u32 seq) { tp->snd_wl1 = seq; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 389deeb..2cbe879 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -413,6 +413,135 @@ static inline void tcp_tso_set_push(struct sk_buff *skb) TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; } +static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_sock *tp = tcp_sk(sk); + + if (skb->len <= tp->mss_cache_std || + !(sk->sk_route_caps & NETIF_F_TSO)) { + /* Avoid the costly divide in the normal + * non-TSO case. + */ + skb_shinfo(skb)->tso_segs = 1; + skb_shinfo(skb)->tso_size = 0; + } else { + unsigned int factor; + + factor = skb->len + (tp->mss_cache_std - 1); + factor /= tp->mss_cache_std; + skb_shinfo(skb)->tso_segs = factor; + skb_shinfo(skb)->tso_size = tp->mss_cache_std; + } +} + +static inline int tcp_minshall_check(const struct tcp_sock *tp) +{ + return after(tp->snd_sml,tp->snd_una) && + !after(tp->snd_sml, tp->snd_nxt); +} + +/* Return 0, if packet can be sent now without violation Nagle's rules: + * 1. It is full sized. + * 2. Or it contains FIN. + * 3. Or TCP_NODELAY was set. + * 4. Or TCP_CORK is not set, and all sent packets are ACKed. + * With Minshall's modification: all sent small packets are ACKed. + */ + +static inline int tcp_nagle_check(const struct tcp_sock *tp, + const struct sk_buff *skb, + unsigned mss_now, int nonagle) +{ + return (skb->len < mss_now && + !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && + ((nonagle&TCP_NAGLE_CORK) || + (!nonagle && + tp->packets_out && + tcp_minshall_check(tp)))); +} + +/* This checks if the data bearing packet SKB (usually sk->sk_send_head) + * should be put on the wire right now. + */ +static int tcp_snd_test(struct sock *sk, struct sk_buff *skb, + unsigned cur_mss, int nonagle) +{ + struct tcp_sock *tp = tcp_sk(sk); + int pkts = tcp_skb_pcount(skb); + + if (!pkts) { + tcp_set_skb_tso_segs(sk, skb); + pkts = tcp_skb_pcount(skb); + } + + /* RFC 1122 - section 4.2.3.4 + * + * We must queue if + * + * a) The right edge of this frame exceeds the window + * b) There are packets in flight and we have a small segment + * [SWS avoidance and Nagle algorithm] + * (part of SWS is done on packetization) + * Minshall version sounds: there are no _small_ + * segments in flight. (tcp_nagle_check) + * c) We have too many packets 'in flight' + * + * Don't use the nagle rule for urgent data (or + * for the final FIN -DaveM). + * + * Also, Nagle rule does not apply to frames, which + * sit in the middle of queue (they have no chances + * to get new data) and if room at tail of skb is + * not enough to save something seriously (<32 for now). + */ + + /* Don't be strict about the congestion window for the + * final FIN frame. -DaveM + */ + return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode + || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && + (((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) || + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && + !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); +} + +static inline int tcp_skb_is_last(const struct sock *sk, + const struct sk_buff *skb) +{ + return skb->next == (struct sk_buff *)&sk->sk_write_queue; +} + +/* Push out any pending frames which were held back due to + * TCP_CORK or attempt at coalescing tiny packets. + * The socket must be locked by the caller. + */ +void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, + unsigned cur_mss, int nonagle) +{ + struct sk_buff *skb = sk->sk_send_head; + + if (skb) { + if (!tcp_skb_is_last(sk, skb)) + nonagle = TCP_NAGLE_PUSH; + if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || + tcp_write_xmit(sk, nonagle)) + tcp_check_probe_timer(sk, tp); + } + tcp_cwnd_validate(sk, tp); +} + +int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) +{ + struct sk_buff *skb = sk->sk_send_head; + + return (skb && + tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), + (tcp_skb_is_last(sk, skb) ? + TCP_NAGLE_PUSH : + tp->nonagle))); +} + + /* Send _single_ skb sitting at the send head. This function requires * true push pending frames to setup probe timer etc. */ @@ -434,27 +563,6 @@ void tcp_push_one(struct sock *sk, unsigned cur_mss) } } -void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (skb->len <= tp->mss_cache_std || - !(sk->sk_route_caps & NETIF_F_TSO)) { - /* Avoid the costly divide in the normal - * non-TSO case. - */ - skb_shinfo(skb)->tso_segs = 1; - skb_shinfo(skb)->tso_size = 0; - } else { - unsigned int factor; - - factor = skb->len + (tp->mss_cache_std - 1); - factor /= tp->mss_cache_std; - skb_shinfo(skb)->tso_segs = factor; - skb_shinfo(skb)->tso_size = tp->mss_cache_std; - } -} - /* Function to create two new TCP segments. Shrinks the given segment * to the specified size and appends a new segment with the rest of the * packet to the list. This won't be called frequently, I hope. -- cgit v1.1 From 84d3e7b9573291a1ea845bdd51b74bb484597661 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:18:18 -0700 Subject: [TCP]: Move __tcp_data_snd_check into tcp_output.c It reimplements portions of tcp_snd_check(), so it we move it to tcp_output.c we can consolidate it's logic much easier in a later change. Signed-off-by: David S. Miller --- include/net/tcp.h | 1 + net/ipv4/tcp_input.c | 10 ---------- net/ipv4/tcp_output.c | 10 ++++++++++ 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index f2b1045..4888f9d 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -849,6 +849,7 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, /* tcp_output.c */ extern int tcp_write_xmit(struct sock *, int nonagle); +extern void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb); extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, unsigned cur_mss, int nonagle); extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 7bbbbc3..5774243 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3346,16 +3346,6 @@ static inline void tcp_check_space(struct sock *sk) } } -static void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || - tcp_packets_in_flight(tp) >= tp->snd_cwnd || - tcp_write_xmit(sk, tp->nonagle)) - tcp_check_probe_timer(sk, tp); -} - static __inline__ void tcp_data_snd_check(struct sock *sk) { struct sk_buff *skb = sk->sk_send_head; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2cbe879..362b811 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -530,6 +530,16 @@ void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, tcp_cwnd_validate(sk, tp); } +void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_sock *tp = tcp_sk(sk); + + if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || + tcp_packets_in_flight(tp) >= tp->snd_cwnd || + tcp_write_xmit(sk, tp->nonagle)) + tcp_check_probe_timer(sk, tp); +} + int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) { struct sk_buff *skb = sk->sk_send_head; -- cgit v1.1 From f44b527177d57ed382bfd93e1b55232465f6d058 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:18:34 -0700 Subject: [TCP]: Add missing skb_header_release() call to tcp_fragment(). When we add any new packet to the TCP socket write queue, we must call skb_header_release() on it in order for the TSO sharing checks in the drivers to work. Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 362b811..5e63ed0 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -655,6 +655,7 @@ static int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len) } /* Link BUFF into the send queue. */ + skb_header_release(buff); __skb_append(skb, buff); return 0; -- cgit v1.1 From a762a9800752f05fa8768bb0ac35d0e7f1bcfe7f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:18:51 -0700 Subject: [TCP]: Kill extra cwnd validate in __tcp_push_pending_frames(). The tcp_cwnd_validate() function should only be invoked if we actually send some frames, yet __tcp_push_pending_frames() will always invoke it. tcp_write_xmit() does the call for us, so the call here can simply be removed. Also, tcp_write_xmit() can be marked static. Signed-off-by: David S. Miller --- include/net/tcp.h | 26 ++--------------- net/ipv4/tcp_output.c | 79 ++++++++++++++++++++++++++++++++------------------- 2 files changed, 52 insertions(+), 53 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 4888f9d..f32e7ae 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -848,7 +848,6 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, /* tcp_output.c */ -extern int tcp_write_xmit(struct sock *, int nonagle); extern void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb); extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, unsigned cur_mss, int nonagle); @@ -868,6 +867,9 @@ extern void tcp_push_one(struct sock *, unsigned mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); +/* tcp_input.c */ +extern void tcp_cwnd_application_limited(struct sock *sk); + /* tcp_timer.c */ extern void tcp_init_xmit_timers(struct sock *); extern void tcp_clear_xmit_timers(struct sock *); @@ -1234,28 +1236,6 @@ static inline void tcp_sync_left_out(struct tcp_sock *tp) tp->left_out = tp->sacked_out + tp->lost_out; } -extern void tcp_cwnd_application_limited(struct sock *sk); - -/* Congestion window validation. (RFC2861) */ - -static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) -{ - __u32 packets_out = tp->packets_out; - - if (packets_out >= tp->snd_cwnd) { - /* Network is feed fully. */ - tp->snd_cwnd_used = 0; - tp->snd_cwnd_stamp = tcp_time_stamp; - } else { - /* Network starves. */ - if (tp->packets_out > tp->snd_cwnd_used) - tp->snd_cwnd_used = tp->packets_out; - - if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) - tcp_cwnd_application_limited(sk); - } -} - /* Set slow start threshould and cwnd not falling to slow start */ static inline void __tcp_enter_cwr(struct tcp_sock *tp) { diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5e63ed0..a6375ca 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -511,35 +511,6 @@ static inline int tcp_skb_is_last(const struct sock *sk, return skb->next == (struct sk_buff *)&sk->sk_write_queue; } -/* Push out any pending frames which were held back due to - * TCP_CORK or attempt at coalescing tiny packets. - * The socket must be locked by the caller. - */ -void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, - unsigned cur_mss, int nonagle) -{ - struct sk_buff *skb = sk->sk_send_head; - - if (skb) { - if (!tcp_skb_is_last(sk, skb)) - nonagle = TCP_NAGLE_PUSH; - if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || - tcp_write_xmit(sk, nonagle)) - tcp_check_probe_timer(sk, tp); - } - tcp_cwnd_validate(sk, tp); -} - -void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || - tcp_packets_in_flight(tp) >= tp->snd_cwnd || - tcp_write_xmit(sk, tp->nonagle)) - tcp_check_probe_timer(sk, tp); -} - int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) { struct sk_buff *skb = sk->sk_send_head; @@ -841,6 +812,26 @@ unsigned int tcp_current_mss(struct sock *sk, int large) return mss_now; } +/* Congestion window validation. (RFC2861) */ + +static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) +{ + __u32 packets_out = tp->packets_out; + + if (packets_out >= tp->snd_cwnd) { + /* Network is feed fully. */ + tp->snd_cwnd_used = 0; + tp->snd_cwnd_stamp = tcp_time_stamp; + } else { + /* Network starves. */ + if (tp->packets_out > tp->snd_cwnd_used) + tp->snd_cwnd_used = tp->packets_out; + + if ((s32)(tcp_time_stamp - tp->snd_cwnd_stamp) >= tp->rto) + tcp_cwnd_application_limited(sk); + } +} + /* This routine writes packets to the network. It advances the * send_head. This happens as incoming acks open up the remote * window for us. @@ -848,7 +839,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large) * Returns 1, if no segments are in flight and we have queued segments, but * cannot send anything now because of SWS or another problem. */ -int tcp_write_xmit(struct sock *sk, int nonagle) +static int tcp_write_xmit(struct sock *sk, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); unsigned int mss_now; @@ -901,6 +892,34 @@ int tcp_write_xmit(struct sock *sk, int nonagle) return 0; } +/* Push out any pending frames which were held back due to + * TCP_CORK or attempt at coalescing tiny packets. + * The socket must be locked by the caller. + */ +void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, + unsigned cur_mss, int nonagle) +{ + struct sk_buff *skb = sk->sk_send_head; + + if (skb) { + if (!tcp_skb_is_last(sk, skb)) + nonagle = TCP_NAGLE_PUSH; + if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || + tcp_write_xmit(sk, nonagle)) + tcp_check_probe_timer(sk, tp); + } +} + +void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) +{ + struct tcp_sock *tp = tcp_sk(sk); + + if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || + tcp_packets_in_flight(tp) >= tp->snd_cwnd || + tcp_write_xmit(sk, tp->nonagle)) + tcp_check_probe_timer(sk, tp); +} + /* This function returns the amount that we can raise the * usable window based on the following constraints * -- cgit v1.1 From 92df7b518dcb113de8bc2494e3cd275ad887f12b Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:19:06 -0700 Subject: [TCP]: tcp_write_xmit() tabbing cleanup Put the main basic block of work at the top-level of tabbing, and mark the TCP_CLOSE test with unlikely(). Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 68 +++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a6375ca..2a8409c 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -842,54 +842,54 @@ static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) static int tcp_write_xmit(struct sock *sk, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb; unsigned int mss_now; + int sent_pkts; /* If we are closed, the bytes will have to remain here. * In time closedown will finish, we empty the write queue and all * will be happy. */ - if (sk->sk_state != TCP_CLOSE) { - struct sk_buff *skb; - int sent_pkts = 0; + if (unlikely(sk->sk_state == TCP_CLOSE)) + return 0; - /* Account for SACKS, we may need to fragment due to this. - * It is just like the real MSS changing on us midstream. - * We also handle things correctly when the user adds some - * IP options mid-stream. Silly to do, but cover it. - */ - mss_now = tcp_current_mss(sk, 1); - - while ((skb = sk->sk_send_head) && - tcp_snd_test(sk, skb, mss_now, - tcp_skb_is_last(sk, skb) ? nonagle : - TCP_NAGLE_PUSH)) { - if (skb->len > mss_now) { - if (tcp_fragment(sk, skb, mss_now)) - break; - } - TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); - if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) + /* Account for SACKS, we may need to fragment due to this. + * It is just like the real MSS changing on us midstream. + * We also handle things correctly when the user adds some + * IP options mid-stream. Silly to do, but cover it. + */ + mss_now = tcp_current_mss(sk, 1); + sent_pkts = 0; + while ((skb = sk->sk_send_head) && + tcp_snd_test(sk, skb, mss_now, + tcp_skb_is_last(sk, skb) ? nonagle : + TCP_NAGLE_PUSH)) { + if (skb->len > mss_now) { + if (tcp_fragment(sk, skb, mss_now)) break; + } - /* Advance the send_head. This one is sent out. - * This call will increment packets_out. - */ - update_send_head(sk, tp, skb); + TCP_SKB_CB(skb)->when = tcp_time_stamp; + tcp_tso_set_push(skb); + if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) + break; - tcp_minshall_update(tp, mss_now, skb); - sent_pkts = 1; - } + /* Advance the send_head. This one is sent out. + * This call will increment packets_out. + */ + update_send_head(sk, tp, skb); - if (sent_pkts) { - tcp_cwnd_validate(sk, tp); - return 0; - } + tcp_minshall_update(tp, mss_now, skb); + sent_pkts = 1; + } - return !tp->packets_out && sk->sk_send_head; + if (sent_pkts) { + tcp_cwnd_validate(sk, tp); + return 0; } - return 0; + + return !tp->packets_out && sk->sk_send_head; } /* Push out any pending frames which were held back due to -- cgit v1.1 From a2e2a59c93cc8ba39caa9011c2573f429e40ccd9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:19:23 -0700 Subject: [TCP]: Fix redundant calculations of tcp_current_mss() tcp_write_xmit() uses tcp_current_mss(), but some of it's callers, namely __tcp_push_pending_frames(), already has this value available already. While we're here, fix the "cur_mss" argument to be "unsigned int" instead of plain "unsigned". Signed-off-by: David S. Miller --- include/net/tcp.h | 2 +- net/ipv4/tcp_output.c | 16 ++++------------ 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index f32e7ae..9416236 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -850,7 +850,7 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, extern void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb); extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, - unsigned cur_mss, int nonagle); + unsigned int cur_mss, int nonagle); extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp); extern int tcp_retransmit_skb(struct sock *, struct sk_buff *); extern void tcp_xmit_retransmit_queue(struct sock *); diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 2a8409c..e292e11 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -839,11 +839,10 @@ static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) * Returns 1, if no segments are in flight and we have queued segments, but * cannot send anything now because of SWS or another problem. */ -static int tcp_write_xmit(struct sock *sk, int nonagle) +static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; - unsigned int mss_now; int sent_pkts; /* If we are closed, the bytes will have to remain here. @@ -853,13 +852,6 @@ static int tcp_write_xmit(struct sock *sk, int nonagle) if (unlikely(sk->sk_state == TCP_CLOSE)) return 0; - - /* Account for SACKS, we may need to fragment due to this. - * It is just like the real MSS changing on us midstream. - * We also handle things correctly when the user adds some - * IP options mid-stream. Silly to do, but cover it. - */ - mss_now = tcp_current_mss(sk, 1); sent_pkts = 0; while ((skb = sk->sk_send_head) && tcp_snd_test(sk, skb, mss_now, @@ -897,7 +889,7 @@ static int tcp_write_xmit(struct sock *sk, int nonagle) * The socket must be locked by the caller. */ void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, - unsigned cur_mss, int nonagle) + unsigned int cur_mss, int nonagle) { struct sk_buff *skb = sk->sk_send_head; @@ -905,7 +897,7 @@ void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, if (!tcp_skb_is_last(sk, skb)) nonagle = TCP_NAGLE_PUSH; if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || - tcp_write_xmit(sk, nonagle)) + tcp_write_xmit(sk, cur_mss, nonagle)) tcp_check_probe_timer(sk, tp); } } @@ -916,7 +908,7 @@ void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || tcp_packets_in_flight(tp) >= tp->snd_cwnd || - tcp_write_xmit(sk, tp->nonagle)) + tcp_write_xmit(sk, tcp_current_mss(sk, 1), tp->nonagle)) tcp_check_probe_timer(sk, tp); } -- cgit v1.1 From 55c97f3e990c1ff63957c64f6cb10711a09fd70e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:19:38 -0700 Subject: [TCP]: Fix __tcp_push_pending_frames() 'nonagle' handling. 'nonagle' should be passed to the tcp_snd_test() function as 'TCP_NAGLE_PUSH' if we are checking an SKB not at the tail of the write_queue. This is because Nagle does not apply to such frames since we cannot possibly tack more data onto them. However, while doing this __tcp_push_pending_frames() makes all of the packets in the write_queue use this modified 'nonagle' value. Fix the bug and simplify this function by just calling tcp_write_xmit() directly if sk_send_head is non-NULL. As a result, we can now make tcp_data_snd_check() just call tcp_push_pending_frames() instead of the specialized __tcp_data_snd_check(). Signed-off-by: David S. Miller --- include/net/tcp.h | 1 - net/ipv4/tcp_input.c | 17 +++++++---------- net/ipv4/tcp_output.c | 15 +-------------- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/include/net/tcp.h b/include/net/tcp.h index 9416236..b192380 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -848,7 +848,6 @@ extern __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, /* tcp_output.c */ -extern void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb); extern void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, unsigned int cur_mss, int nonagle); extern int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp); diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5774243..b27be2f 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3346,12 +3346,9 @@ static inline void tcp_check_space(struct sock *sk) } } -static __inline__ void tcp_data_snd_check(struct sock *sk) +static __inline__ void tcp_data_snd_check(struct sock *sk, struct tcp_sock *tp) { - struct sk_buff *skb = sk->sk_send_head; - - if (skb != NULL) - __tcp_data_snd_check(sk, skb); + tcp_push_pending_frames(sk, tp); tcp_check_space(sk); } @@ -3645,7 +3642,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, */ tcp_ack(sk, skb, 0); __kfree_skb(skb); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); return 0; } else { /* Header too small */ TCP_INC_STATS_BH(TCP_MIB_INERRS); @@ -3711,7 +3708,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, if (TCP_SKB_CB(skb)->ack_seq != tp->snd_una) { /* Well, only one small jumplet in fast path... */ tcp_ack(sk, skb, FLAG_DATA); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); if (!tcp_ack_scheduled(tp)) goto no_ack; } @@ -3789,7 +3786,7 @@ step5: /* step 7: process the segment text */ tcp_data_queue(sk, skb); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); tcp_ack_snd_check(sk); return 0; @@ -4099,7 +4096,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* Do step6 onward by hand. */ tcp_urg(sk, skb, th); __kfree_skb(skb); - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); return 0; } @@ -4290,7 +4287,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, /* tcp_data could move socket to TIME-WAIT */ if (sk->sk_state != TCP_CLOSE) { - tcp_data_snd_check(sk); + tcp_data_snd_check(sk, tp); tcp_ack_snd_check(sk); } diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index e292e11..ce1d7cf 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -894,24 +894,11 @@ void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb = sk->sk_send_head; if (skb) { - if (!tcp_skb_is_last(sk, skb)) - nonagle = TCP_NAGLE_PUSH; - if (!tcp_snd_test(sk, skb, cur_mss, nonagle) || - tcp_write_xmit(sk, cur_mss, nonagle)) + if (tcp_write_xmit(sk, cur_mss, nonagle)) tcp_check_probe_timer(sk, tp); } } -void __tcp_data_snd_check(struct sock *sk, struct sk_buff *skb) -{ - struct tcp_sock *tp = tcp_sk(sk); - - if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd) || - tcp_packets_in_flight(tp) >= tp->snd_cwnd || - tcp_write_xmit(sk, tcp_current_mss(sk, 1), tp->nonagle)) - tcp_check_probe_timer(sk, tp); -} - /* This function returns the amount that we can raise the * usable window based on the following constraints * -- cgit v1.1 From 7f4dd0a9438c73cbb1c240ece31390cf2c57294e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:19:54 -0700 Subject: [TCP]: Break out tcp_snd_test() into it's constituent parts. tcp_snd_test() does several different things, use inline functions to express this more clearly. 1) It initializes the TSO count of SKB, if necessary. 2) It performs the Nagle test. 3) It makes sure the congestion window is adhered to. 4) It makes sure SKB fits into the send window. This cleanup also sets things up so that things like the available packets in the congestion window does not need to be calculated multiple times by packet sending loops such as tcp_write_xmit(). Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 120 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 38 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index ce1d7cf..8327e5e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -434,6 +434,33 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) } } +/* Does SKB fit into the send window? */ +static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss) +{ + u32 end_seq = TCP_SKB_CB(skb)->end_seq; + + return !after(end_seq, tp->snd_una + tp->snd_wnd); +} + +/* Can at least one segment of SKB be sent right now, according to the + * congestion window rules? If so, return how many segments are allowed. + */ +static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb) +{ + u32 in_flight, cwnd; + + /* Don't be strict about the congestion window for the final FIN. */ + if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) + return 1; + + in_flight = tcp_packets_in_flight(tp); + cwnd = tp->snd_cwnd; + if (in_flight < cwnd) + return (cwnd - in_flight); + + return 0; +} + static inline int tcp_minshall_check(const struct tcp_sock *tp) { return after(tp->snd_sml,tp->snd_una) && @@ -442,7 +469,7 @@ static inline int tcp_minshall_check(const struct tcp_sock *tp) /* Return 0, if packet can be sent now without violation Nagle's rules: * 1. It is full sized. - * 2. Or it contains FIN. + * 2. Or it contains FIN. (already checked by caller) * 3. Or TCP_NODELAY was set. * 4. Or TCP_CORK is not set, and all sent packets are ACKed. * With Minshall's modification: all sent small packets are ACKed. @@ -453,56 +480,73 @@ static inline int tcp_nagle_check(const struct tcp_sock *tp, unsigned mss_now, int nonagle) { return (skb->len < mss_now && - !(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) && ((nonagle&TCP_NAGLE_CORK) || (!nonagle && tp->packets_out && tcp_minshall_check(tp)))); } -/* This checks if the data bearing packet SKB (usually sk->sk_send_head) - * should be put on the wire right now. +/* Return non-zero if the Nagle test allows this packet to be + * sent now. */ -static int tcp_snd_test(struct sock *sk, struct sk_buff *skb, - unsigned cur_mss, int nonagle) +static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb, + unsigned int cur_mss, int nonagle) { - struct tcp_sock *tp = tcp_sk(sk); - int pkts = tcp_skb_pcount(skb); + /* Nagle rule does not apply to frames, which sit in the middle of the + * write_queue (they have no chances to get new data). + * + * This is implemented in the callers, where they modify the 'nonagle' + * argument based upon the location of SKB in the send queue. + */ + if (nonagle & TCP_NAGLE_PUSH) + return 1; + + /* Don't use the nagle rule for urgent data (or for the final FIN). */ + if (tp->urg_mode || + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) + return 1; + + if (!tcp_nagle_check(tp, skb, cur_mss, nonagle)) + return 1; - if (!pkts) { + return 0; +} + +/* This must be invoked the first time we consider transmitting + * SKB onto the wire. + */ +static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb) +{ + int tso_segs = tcp_skb_pcount(skb); + + if (!tso_segs) { tcp_set_skb_tso_segs(sk, skb); - pkts = tcp_skb_pcount(skb); + tso_segs = tcp_skb_pcount(skb); } + return tso_segs; +} - /* RFC 1122 - section 4.2.3.4 - * - * We must queue if - * - * a) The right edge of this frame exceeds the window - * b) There are packets in flight and we have a small segment - * [SWS avoidance and Nagle algorithm] - * (part of SWS is done on packetization) - * Minshall version sounds: there are no _small_ - * segments in flight. (tcp_nagle_check) - * c) We have too many packets 'in flight' - * - * Don't use the nagle rule for urgent data (or - * for the final FIN -DaveM). - * - * Also, Nagle rule does not apply to frames, which - * sit in the middle of queue (they have no chances - * to get new data) and if room at tail of skb is - * not enough to save something seriously (<32 for now). - */ +/* This checks if the data bearing packet SKB (usually sk->sk_send_head) + * should be put on the wire right now. If so, it returns the number of + * packets allowed by the congestion window. + */ +static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb, + unsigned int cur_mss, int nonagle) +{ + struct tcp_sock *tp = tcp_sk(sk); + unsigned int cwnd_quota; - /* Don't be strict about the congestion window for the - * final FIN frame. -DaveM - */ - return (((nonagle&TCP_NAGLE_PUSH) || tp->urg_mode - || !tcp_nagle_check(tp, skb, cur_mss, nonagle)) && - (((tcp_packets_in_flight(tp) + (pkts-1)) < tp->snd_cwnd) || - (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) && - !after(TCP_SKB_CB(skb)->end_seq, tp->snd_una + tp->snd_wnd)); + tcp_init_tso_segs(sk, skb); + + if (!tcp_nagle_test(tp, skb, cur_mss, nonagle)) + return 0; + + cwnd_quota = tcp_cwnd_test(tp, skb); + if (cwnd_quota && + !tcp_snd_wnd_test(tp, skb, cur_mss)) + cwnd_quota = 0; + + return cwnd_quota; } static inline int tcp_skb_is_last(const struct sock *sk, -- cgit v1.1 From aa93466bdfd901b926e033801f0b82b3eaa67be2 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:20:09 -0700 Subject: [TCP]: Eliminate redundant computations in tcp_write_xmit(). tcp_snd_test() is run for every packet output by a single call to tcp_write_xmit(), but this is not necessary. For one, the congestion window space needs to only be calculated one time, then used throughout the duration of the loop. This cleanup also makes experimenting with different TSO packetization schemes much easier. Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 40 +++++++++++++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 8327e5e..0a4cd24 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -887,6 +887,7 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; + unsigned int tso_segs, cwnd_quota; int sent_pkts; /* If we are closed, the bytes will have to remain here. @@ -896,19 +897,31 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) if (unlikely(sk->sk_state == TCP_CLOSE)) return 0; + skb = sk->sk_send_head; + if (unlikely(!skb)) + return 0; + + tso_segs = tcp_init_tso_segs(sk, skb); + cwnd_quota = tcp_cwnd_test(tp, skb); sent_pkts = 0; - while ((skb = sk->sk_send_head) && - tcp_snd_test(sk, skb, mss_now, - tcp_skb_is_last(sk, skb) ? nonagle : - TCP_NAGLE_PUSH)) { - if (skb->len > mss_now) { - if (tcp_fragment(sk, skb, mss_now)) + + while (cwnd_quota >= tso_segs) { + if (unlikely(!tcp_nagle_test(tp, skb, mss_now, + (tcp_skb_is_last(sk, skb) ? + nonagle : TCP_NAGLE_PUSH)))) + break; + + if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) + break; + + if (unlikely(skb->len > mss_now)) { + if (unlikely(tcp_fragment(sk, skb, mss_now))) break; } TCP_SKB_CB(skb)->when = tcp_time_stamp; tcp_tso_set_push(skb); - if (tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))) + if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))) break; /* Advance the send_head. This one is sent out. @@ -917,10 +930,19 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) update_send_head(sk, tp, skb); tcp_minshall_update(tp, mss_now, skb); - sent_pkts = 1; + sent_pkts++; + + /* Do not optimize this to use tso_segs. If we chopped up + * the packet above, tso_segs will no longer be valid. + */ + cwnd_quota -= tcp_skb_pcount(skb); + skb = sk->sk_send_head; + if (!skb) + break; + tso_segs = tcp_init_tso_segs(sk, skb); } - if (sent_pkts) { + if (likely(sent_pkts)) { tcp_cwnd_validate(sk, tp); return 0; } -- cgit v1.1 From b4e26f5ea0dbdd1e813c5571fb467022d8eb948a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:20:27 -0700 Subject: [TCP]: Fix send-side cpu utiliziation regression. Only put user data purely to pages when doing TSO. The extra page allocations cause two problems: 1) Add the overhead of the page allocations themselves. 2) Make us do small user copies when we get to the end of the TCP socket cache page. It is still beneficial to purely use pages for TSO, so we will do it for that case. Signed-off-by: David S. Miller --- net/ipv4/tcp.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index be35415..2ba73bf 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -756,8 +756,17 @@ static inline int select_size(struct sock *sk, struct tcp_sock *tp) { int tmp = tp->mss_cache_std; - if (sk->sk_route_caps & NETIF_F_SG) - tmp = 0; + if (sk->sk_route_caps & NETIF_F_SG) { + if (sk->sk_route_caps & NETIF_F_TSO) + tmp = 0; + else { + int pgbreak = SKB_MAX_HEAD(MAX_TCP_HEADER); + + if (tmp >= pgbreak && + tmp <= pgbreak + (MAX_SKB_FRAGS - 1) * PAGE_SIZE) + tmp = pgbreak; + } + } return tmp; } -- cgit v1.1 From a56476962e92a6c389a1a561274d4a27607b7b5f Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:20:41 -0700 Subject: [TCP]: Kill bogus comment above tcp_tso_acked(). Everything stated there is out of data. tcp_trim_skb() does adjust the available socket send buffer space and skb->truesize now. Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b27be2f..1dba7fd 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -1957,15 +1957,6 @@ static inline void tcp_ack_packets_out(struct sock *sk, struct tcp_sock *tp) } } -/* There is one downside to this scheme. Although we keep the - * ACK clock ticking, adjusting packet counters and advancing - * congestion window, we do not liberate socket send buffer - * space. - * - * Mucking with skb->truesize and sk->sk_wmem_alloc et al. - * then making a write space wakeup callback is a possible - * future enhancement. WARNING: it is not trivial to make. - */ static int tcp_tso_acked(struct sock *sk, struct sk_buff *skb, __u32 now, __s32 *seq_rtt) { -- cgit v1.1 From cb83199a29dc0408423d6df432f28cc67fcadaf4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:20:55 -0700 Subject: [TCP]: Do not call tcp_tso_acked() if no work to do. In tcp_clean_rtx_queue(), if the TSO packet is not even partially acked, do not waste time calling tcp_tso_acked(). Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 1dba7fd..b948e4e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -2038,7 +2038,8 @@ static int tcp_clean_rtx_queue(struct sock *sk, __s32 *seq_rtt_p, s32 *seq_usrtt * the other end. */ if (after(scb->end_seq, tp->snd_una)) { - if (tcp_skb_pcount(skb) > 1) + if (tcp_skb_pcount(skb) > 1 && + after(tp->snd_una, scb->seq)) acked |= tcp_tso_acked(sk, skb, now, &seq_rtt); break; -- cgit v1.1 From 0d9901df62fe4820aee86b49f1a074cdb5c6928e Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:21:10 -0700 Subject: [TCP]: Break out send buffer expansion test. This makes it easier to understand, and allows easier tweaking of the heuristic later on. Signed-off-by: David S. Miller --- net/ipv4/tcp_input.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index b948e4e..2ef2f35 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -3300,6 +3300,28 @@ void tcp_cwnd_application_limited(struct sock *sk) tp->snd_cwnd_stamp = tcp_time_stamp; } +static inline int tcp_should_expand_sndbuf(struct sock *sk, struct tcp_sock *tp) +{ + /* If the user specified a specific send buffer setting, do + * not modify it. + */ + if (sk->sk_userlocks & SOCK_SNDBUF_LOCK) + return 0; + + /* If we are under global TCP memory pressure, do not expand. */ + if (tcp_memory_pressure) + return 0; + + /* If we are under soft global TCP memory pressure, do not expand. */ + if (atomic_read(&tcp_memory_allocated) >= sysctl_tcp_mem[0]) + return 0; + + /* If we filled the congestion window, do not expand. */ + if (tp->packets_out >= tp->snd_cwnd) + return 0; + + return 1; +} /* When incoming ACK allowed to free some skb from write_queue, * we remember this event in flag SOCK_QUEUE_SHRUNK and wake up socket @@ -3311,10 +3333,7 @@ static void tcp_new_space(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - if (tp->packets_out < tp->snd_cwnd && - !(sk->sk_userlocks & SOCK_SNDBUF_LOCK) && - !tcp_memory_pressure && - atomic_read(&tcp_memory_allocated) < sysctl_tcp_mem[0]) { + if (tcp_should_expand_sndbuf(sk, tp)) { int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache_std) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, -- cgit v1.1 From c1b4a7e69576d65efc31a8cea0714173c2841244 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:24:38 -0700 Subject: [TCP]: Move to new TSO segmenting scheme. Make TSO segment transmit size decisions at send time not earlier. The basic scheme is that we try to build as large a TSO frame as possible when pulling in the user data, but the size of the TSO frame output to the card is determined at transmit time. This is guided by tp->xmit_size_goal. It is always set to a multiple of MSS and tells sendmsg/sendpage how large an SKB to try and build. Later, tcp_write_xmit() and tcp_push_one() chop up the packet if necessary and conditions warrant. These routines can also decide to "defer" in order to wait for more ACKs to arrive and thus allow larger TSO frames to be emitted. A general observation is that TSO elongates the pipe, thus requiring a larger congestion window and larger buffering especially at the sender side. Therefore, it is important that applications 1) get a large enough socket send buffer (this is accomplished by our dynamic send buffer expansion code) 2) do large enough writes. Signed-off-by: David S. Miller --- include/linux/tcp.h | 2 +- include/net/tcp.h | 4 +- net/ipv4/tcp.c | 26 ++- net/ipv4/tcp_input.c | 10 +- net/ipv4/tcp_ipv4.c | 2 +- net/ipv4/tcp_output.c | 578 +++++++++++++++++++++++++++++++------------------- net/ipv6/tcp_ipv6.c | 2 +- 7 files changed, 384 insertions(+), 240 deletions(-) diff --git a/include/linux/tcp.h b/include/linux/tcp.h index dfd93d0..e4fd82e 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -286,7 +286,7 @@ struct tcp_sock { __u32 max_window; /* Maximal window ever seen from peer */ __u32 pmtu_cookie; /* Last pmtu seen by socket */ __u32 mss_cache; /* Cached effective mss, not including SACKS */ - __u16 mss_cache_std; /* Like mss_cache, but without TSO */ + __u16 xmit_size_goal; /* Goal for segmenting output packets */ __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ __u8 ca_state; /* State of fast-retransmit machine */ __u8 retransmits; /* Number of unrecovered RTO timeouts. */ diff --git a/include/net/tcp.h b/include/net/tcp.h index b192380..a166918 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -862,7 +862,7 @@ extern int tcp_write_wakeup(struct sock *); extern void tcp_send_fin(struct sock *sk); extern void tcp_send_active_reset(struct sock *sk, int priority); extern int tcp_send_synack(struct sock *); -extern void tcp_push_one(struct sock *, unsigned mss_now); +extern void tcp_push_one(struct sock *, unsigned int mss_now); extern void tcp_send_ack(struct sock *sk); extern void tcp_send_delayed_ack(struct sock *sk); @@ -968,7 +968,7 @@ static inline void tcp_reset_xmit_timer(struct sock *sk, int what, unsigned long static inline void tcp_initialize_rcv_mss(struct sock *sk) { struct tcp_sock *tp = tcp_sk(sk); - unsigned int hint = min(tp->advmss, tp->mss_cache_std); + unsigned int hint = min_t(unsigned int, tp->advmss, tp->mss_cache); hint = min(hint, tp->rcv_wnd/2); hint = min(hint, TCP_MIN_RCVMSS); diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 2ba73bf..29894c7 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -615,7 +615,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse size_t psize, int flags) { struct tcp_sock *tp = tcp_sk(sk); - int mss_now; + int mss_now, size_goal; int err; ssize_t copied; long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); @@ -628,6 +628,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; copied = 0; err = -EPIPE; @@ -641,7 +642,7 @@ static ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffse int offset = poffset % PAGE_SIZE; int size = min_t(size_t, psize, PAGE_SIZE - offset); - if (!sk->sk_send_head || (copy = mss_now - skb->len) <= 0) { + if (!sk->sk_send_head || (copy = size_goal - skb->len) <= 0) { new_segment: if (!sk_stream_memory_free(sk)) goto wait_for_sndbuf; @@ -652,7 +653,7 @@ new_segment: goto wait_for_memory; skb_entail(sk, tp, skb); - copy = mss_now; + copy = size_goal; } if (copy > size) @@ -693,7 +694,7 @@ new_segment: if (!(psize -= copy)) goto out; - if (skb->len != mss_now || (flags & MSG_OOB)) + if (skb->len < mss_now || (flags & MSG_OOB)) continue; if (forced_push(tp)) { @@ -713,6 +714,7 @@ wait_for_memory: goto do_error; mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; } out: @@ -754,7 +756,7 @@ ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, static inline int select_size(struct sock *sk, struct tcp_sock *tp) { - int tmp = tp->mss_cache_std; + int tmp = tp->mss_cache; if (sk->sk_route_caps & NETIF_F_SG) { if (sk->sk_route_caps & NETIF_F_TSO) @@ -778,7 +780,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; int iovlen, flags; - int mss_now; + int mss_now, size_goal; int err, copied; long timeo; @@ -797,6 +799,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; /* Ok commence sending. */ iovlen = msg->msg_iovlen; @@ -819,7 +822,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, skb = sk->sk_write_queue.prev; if (!sk->sk_send_head || - (copy = mss_now - skb->len) <= 0) { + (copy = size_goal - skb->len) <= 0) { new_segment: /* Allocate new segment. If the interface is SG, @@ -842,7 +845,7 @@ new_segment: skb->ip_summed = CHECKSUM_HW; skb_entail(sk, tp, skb); - copy = mss_now; + copy = size_goal; } /* Try to append data to the end of skb. */ @@ -937,7 +940,7 @@ new_segment: if ((seglen -= copy) == 0 && iovlen == 0) goto out; - if (skb->len != mss_now || (flags & MSG_OOB)) + if (skb->len < mss_now || (flags & MSG_OOB)) continue; if (forced_push(tp)) { @@ -957,6 +960,7 @@ wait_for_memory: goto do_error; mss_now = tcp_current_mss(sk, !(flags&MSG_OOB)); + size_goal = tp->xmit_size_goal; } } @@ -2128,7 +2132,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info) info->tcpi_rto = jiffies_to_usecs(tp->rto); info->tcpi_ato = jiffies_to_usecs(tp->ack.ato); - info->tcpi_snd_mss = tp->mss_cache_std; + info->tcpi_snd_mss = tp->mss_cache; info->tcpi_rcv_mss = tp->ack.rcv_mss; info->tcpi_unacked = tp->packets_out; @@ -2178,7 +2182,7 @@ int tcp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, switch (optname) { case TCP_MAXSEG: - val = tp->mss_cache_std; + val = tp->mss_cache; if (!val && ((1 << sk->sk_state) & (TCPF_CLOSE | TCPF_LISTEN))) val = tp->rx_opt.user_mss; break; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 2ef2f35..8de2f10 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -740,10 +740,10 @@ __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst) __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0); if (!cwnd) { - if (tp->mss_cache_std > 1460) + if (tp->mss_cache > 1460) cwnd = 2; else - cwnd = (tp->mss_cache_std > 1095) ? 3 : 4; + cwnd = (tp->mss_cache > 1095) ? 3 : 4; } return min_t(__u32, cwnd, tp->snd_cwnd_clamp); } @@ -914,7 +914,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ if (sk->sk_route_caps & NETIF_F_TSO) { sk->sk_route_caps &= ~NETIF_F_TSO; sock_set_flag(sk, SOCK_NO_LARGESEND); - tp->mss_cache = tp->mss_cache_std; + tp->mss_cache = tp->mss_cache; } if (!tp->sacked_out) @@ -1077,7 +1077,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_ (IsFack(tp) || !before(lost_retrans, TCP_SKB_CB(skb)->ack_seq + tp->reordering * - tp->mss_cache_std))) { + tp->mss_cache))) { TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; tp->retrans_out -= tcp_skb_pcount(skb); @@ -3334,7 +3334,7 @@ static void tcp_new_space(struct sock *sk) struct tcp_sock *tp = tcp_sk(sk); if (tcp_should_expand_sndbuf(sk, tp)) { - int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache_std) + + int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) + MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), demanded = max_t(unsigned int, tp->snd_cwnd, tp->reordering + 1); diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index ebf1123..62f62bb 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2045,7 +2045,7 @@ static int tcp_v4_init_sock(struct sock *sk) */ tp->snd_ssthresh = 0x7fffffff; /* Infinity */ tp->snd_cwnd_clamp = ~0; - tp->mss_cache_std = tp->mss_cache = 536; + tp->mss_cache = 536; tp->reordering = sysctl_tcp_reordering; tp->ca_ops = &tcp_init_congestion_ops; diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 0a4cd24..fd3ce38 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -49,7 +49,7 @@ int sysctl_tcp_retrans_collapse = 1; * will allow a single TSO frame to consume. Building TSO frames * which are too large can cause TCP streams to be bursty. */ -int sysctl_tcp_tso_win_divisor = 8; +int sysctl_tcp_tso_win_divisor = 3; static inline void update_send_head(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb) @@ -403,21 +403,11 @@ static void tcp_queue_skb(struct sock *sk, struct sk_buff *skb) sk->sk_send_head = skb; } -static inline void tcp_tso_set_push(struct sk_buff *skb) -{ - /* Force push to be on for any TSO frames to workaround - * problems with busted implementations like Mac OS-X that - * hold off socket receive wakeups until push is seen. - */ - if (tcp_skb_pcount(skb) > 1) - TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; -} - static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) { struct tcp_sock *tp = tcp_sk(sk); - if (skb->len <= tp->mss_cache_std || + if (skb->len <= tp->mss_cache || !(sk->sk_route_caps & NETIF_F_TSO)) { /* Avoid the costly divide in the normal * non-TSO case. @@ -427,164 +417,10 @@ static void tcp_set_skb_tso_segs(struct sock *sk, struct sk_buff *skb) } else { unsigned int factor; - factor = skb->len + (tp->mss_cache_std - 1); - factor /= tp->mss_cache_std; + factor = skb->len + (tp->mss_cache - 1); + factor /= tp->mss_cache; skb_shinfo(skb)->tso_segs = factor; - skb_shinfo(skb)->tso_size = tp->mss_cache_std; - } -} - -/* Does SKB fit into the send window? */ -static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss) -{ - u32 end_seq = TCP_SKB_CB(skb)->end_seq; - - return !after(end_seq, tp->snd_una + tp->snd_wnd); -} - -/* Can at least one segment of SKB be sent right now, according to the - * congestion window rules? If so, return how many segments are allowed. - */ -static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb) -{ - u32 in_flight, cwnd; - - /* Don't be strict about the congestion window for the final FIN. */ - if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) - return 1; - - in_flight = tcp_packets_in_flight(tp); - cwnd = tp->snd_cwnd; - if (in_flight < cwnd) - return (cwnd - in_flight); - - return 0; -} - -static inline int tcp_minshall_check(const struct tcp_sock *tp) -{ - return after(tp->snd_sml,tp->snd_una) && - !after(tp->snd_sml, tp->snd_nxt); -} - -/* Return 0, if packet can be sent now without violation Nagle's rules: - * 1. It is full sized. - * 2. Or it contains FIN. (already checked by caller) - * 3. Or TCP_NODELAY was set. - * 4. Or TCP_CORK is not set, and all sent packets are ACKed. - * With Minshall's modification: all sent small packets are ACKed. - */ - -static inline int tcp_nagle_check(const struct tcp_sock *tp, - const struct sk_buff *skb, - unsigned mss_now, int nonagle) -{ - return (skb->len < mss_now && - ((nonagle&TCP_NAGLE_CORK) || - (!nonagle && - tp->packets_out && - tcp_minshall_check(tp)))); -} - -/* Return non-zero if the Nagle test allows this packet to be - * sent now. - */ -static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb, - unsigned int cur_mss, int nonagle) -{ - /* Nagle rule does not apply to frames, which sit in the middle of the - * write_queue (they have no chances to get new data). - * - * This is implemented in the callers, where they modify the 'nonagle' - * argument based upon the location of SKB in the send queue. - */ - if (nonagle & TCP_NAGLE_PUSH) - return 1; - - /* Don't use the nagle rule for urgent data (or for the final FIN). */ - if (tp->urg_mode || - (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) - return 1; - - if (!tcp_nagle_check(tp, skb, cur_mss, nonagle)) - return 1; - - return 0; -} - -/* This must be invoked the first time we consider transmitting - * SKB onto the wire. - */ -static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb) -{ - int tso_segs = tcp_skb_pcount(skb); - - if (!tso_segs) { - tcp_set_skb_tso_segs(sk, skb); - tso_segs = tcp_skb_pcount(skb); - } - return tso_segs; -} - -/* This checks if the data bearing packet SKB (usually sk->sk_send_head) - * should be put on the wire right now. If so, it returns the number of - * packets allowed by the congestion window. - */ -static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb, - unsigned int cur_mss, int nonagle) -{ - struct tcp_sock *tp = tcp_sk(sk); - unsigned int cwnd_quota; - - tcp_init_tso_segs(sk, skb); - - if (!tcp_nagle_test(tp, skb, cur_mss, nonagle)) - return 0; - - cwnd_quota = tcp_cwnd_test(tp, skb); - if (cwnd_quota && - !tcp_snd_wnd_test(tp, skb, cur_mss)) - cwnd_quota = 0; - - return cwnd_quota; -} - -static inline int tcp_skb_is_last(const struct sock *sk, - const struct sk_buff *skb) -{ - return skb->next == (struct sk_buff *)&sk->sk_write_queue; -} - -int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) -{ - struct sk_buff *skb = sk->sk_send_head; - - return (skb && - tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), - (tcp_skb_is_last(sk, skb) ? - TCP_NAGLE_PUSH : - tp->nonagle))); -} - - -/* Send _single_ skb sitting at the send head. This function requires - * true push pending frames to setup probe timer etc. - */ -void tcp_push_one(struct sock *sk, unsigned cur_mss) -{ - struct tcp_sock *tp = tcp_sk(sk); - struct sk_buff *skb = sk->sk_send_head; - - if (tcp_snd_test(sk, skb, cur_mss, TCP_NAGLE_PUSH)) { - /* Send it out now. */ - TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); - if (!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation))) { - sk->sk_send_head = NULL; - tp->snd_nxt = TCP_SKB_CB(skb)->end_seq; - tcp_packets_out_inc(sk, tp, skb); - return; - } + skb_shinfo(skb)->tso_size = tp->mss_cache; } } @@ -791,7 +627,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) /* And store cached results */ tp->pmtu_cookie = pmtu; - tp->mss_cache = tp->mss_cache_std = mss_now; + tp->mss_cache = mss_now; return mss_now; } @@ -803,56 +639,47 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu) * cannot be large. However, taking into account rare use of URG, this * is not a big flaw. */ - -unsigned int tcp_current_mss(struct sock *sk, int large) +unsigned int tcp_current_mss(struct sock *sk, int large_allowed) { struct tcp_sock *tp = tcp_sk(sk); struct dst_entry *dst = __sk_dst_get(sk); - unsigned int do_large, mss_now; + u32 mss_now; + u16 xmit_size_goal; + int doing_tso = 0; + + mss_now = tp->mss_cache; + + if (large_allowed && + (sk->sk_route_caps & NETIF_F_TSO) && + !tp->urg_mode) + doing_tso = 1; - mss_now = tp->mss_cache_std; if (dst) { u32 mtu = dst_mtu(dst); if (mtu != tp->pmtu_cookie) mss_now = tcp_sync_mss(sk, mtu); } - do_large = (large && - (sk->sk_route_caps & NETIF_F_TSO) && - !tp->urg_mode); + if (tp->rx_opt.eff_sacks) + mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + + (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); - if (do_large) { - unsigned int large_mss, factor, limit; + xmit_size_goal = mss_now; - large_mss = 65535 - tp->af_specific->net_header_len - + if (doing_tso) { + xmit_size_goal = 65535 - + tp->af_specific->net_header_len - tp->ext_header_len - tp->tcp_header_len; - if (tp->max_window && large_mss > (tp->max_window>>1)) - large_mss = max((tp->max_window>>1), - 68U - tp->tcp_header_len); - - factor = large_mss / mss_now; + if (tp->max_window && + (xmit_size_goal > (tp->max_window >> 1))) + xmit_size_goal = max((tp->max_window >> 1), + 68U - tp->tcp_header_len); - /* Always keep large mss multiple of real mss, but - * do not exceed 1/tso_win_divisor of the congestion window - * so we can keep the ACK clock ticking and minimize - * bursting. - */ - limit = tp->snd_cwnd; - if (sysctl_tcp_tso_win_divisor) - limit /= sysctl_tcp_tso_win_divisor; - limit = max(1U, limit); - if (factor > limit) - factor = limit; - - tp->mss_cache = mss_now * factor; - - mss_now = tp->mss_cache; + xmit_size_goal -= (xmit_size_goal % mss_now); } + tp->xmit_size_goal = xmit_size_goal; - if (tp->rx_opt.eff_sacks) - mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + - (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); return mss_now; } @@ -876,6 +703,251 @@ static inline void tcp_cwnd_validate(struct sock *sk, struct tcp_sock *tp) } } +static unsigned int tcp_window_allows(struct tcp_sock *tp, struct sk_buff *skb, unsigned int mss_now, unsigned int cwnd) +{ + u32 window, cwnd_len; + + window = (tp->snd_una + tp->snd_wnd - TCP_SKB_CB(skb)->seq); + cwnd_len = mss_now * cwnd; + return min(window, cwnd_len); +} + +/* Can at least one segment of SKB be sent right now, according to the + * congestion window rules? If so, return how many segments are allowed. + */ +static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, struct sk_buff *skb) +{ + u32 in_flight, cwnd; + + /* Don't be strict about the congestion window for the final FIN. */ + if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) + return 1; + + in_flight = tcp_packets_in_flight(tp); + cwnd = tp->snd_cwnd; + if (in_flight < cwnd) + return (cwnd - in_flight); + + return 0; +} + +/* This must be invoked the first time we consider transmitting + * SKB onto the wire. + */ +static inline int tcp_init_tso_segs(struct sock *sk, struct sk_buff *skb) +{ + int tso_segs = tcp_skb_pcount(skb); + + if (!tso_segs) { + tcp_set_skb_tso_segs(sk, skb); + tso_segs = tcp_skb_pcount(skb); + } + return tso_segs; +} + +static inline int tcp_minshall_check(const struct tcp_sock *tp) +{ + return after(tp->snd_sml,tp->snd_una) && + !after(tp->snd_sml, tp->snd_nxt); +} + +/* Return 0, if packet can be sent now without violation Nagle's rules: + * 1. It is full sized. + * 2. Or it contains FIN. (already checked by caller) + * 3. Or TCP_NODELAY was set. + * 4. Or TCP_CORK is not set, and all sent packets are ACKed. + * With Minshall's modification: all sent small packets are ACKed. + */ + +static inline int tcp_nagle_check(const struct tcp_sock *tp, + const struct sk_buff *skb, + unsigned mss_now, int nonagle) +{ + return (skb->len < mss_now && + ((nonagle&TCP_NAGLE_CORK) || + (!nonagle && + tp->packets_out && + tcp_minshall_check(tp)))); +} + +/* Return non-zero if the Nagle test allows this packet to be + * sent now. + */ +static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb, + unsigned int cur_mss, int nonagle) +{ + /* Nagle rule does not apply to frames, which sit in the middle of the + * write_queue (they have no chances to get new data). + * + * This is implemented in the callers, where they modify the 'nonagle' + * argument based upon the location of SKB in the send queue. + */ + if (nonagle & TCP_NAGLE_PUSH) + return 1; + + /* Don't use the nagle rule for urgent data (or for the final FIN). */ + if (tp->urg_mode || + (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) + return 1; + + if (!tcp_nagle_check(tp, skb, cur_mss, nonagle)) + return 1; + + return 0; +} + +/* Does at least the first segment of SKB fit into the send window? */ +static inline int tcp_snd_wnd_test(struct tcp_sock *tp, struct sk_buff *skb, unsigned int cur_mss) +{ + u32 end_seq = TCP_SKB_CB(skb)->end_seq; + + if (skb->len > cur_mss) + end_seq = TCP_SKB_CB(skb)->seq + cur_mss; + + return !after(end_seq, tp->snd_una + tp->snd_wnd); +} + +/* This checks if the data bearing packet SKB (usually sk->sk_send_head) + * should be put on the wire right now. If so, it returns the number of + * packets allowed by the congestion window. + */ +static unsigned int tcp_snd_test(struct sock *sk, struct sk_buff *skb, + unsigned int cur_mss, int nonagle) +{ + struct tcp_sock *tp = tcp_sk(sk); + unsigned int cwnd_quota; + + tcp_init_tso_segs(sk, skb); + + if (!tcp_nagle_test(tp, skb, cur_mss, nonagle)) + return 0; + + cwnd_quota = tcp_cwnd_test(tp, skb); + if (cwnd_quota && + !tcp_snd_wnd_test(tp, skb, cur_mss)) + cwnd_quota = 0; + + return cwnd_quota; +} + +static inline int tcp_skb_is_last(const struct sock *sk, + const struct sk_buff *skb) +{ + return skb->next == (struct sk_buff *)&sk->sk_write_queue; +} + +int tcp_may_send_now(struct sock *sk, struct tcp_sock *tp) +{ + struct sk_buff *skb = sk->sk_send_head; + + return (skb && + tcp_snd_test(sk, skb, tcp_current_mss(sk, 1), + (tcp_skb_is_last(sk, skb) ? + TCP_NAGLE_PUSH : + tp->nonagle))); +} + +/* Trim TSO SKB to LEN bytes, put the remaining data into a new packet + * which is put after SKB on the list. It is very much like + * tcp_fragment() except that it may make several kinds of assumptions + * in order to speed up the splitting operation. In particular, we + * know that all the data is in scatter-gather pages, and that the + * packet has never been sent out before (and thus is not cloned). + */ +static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len) +{ + struct sk_buff *buff; + int nlen = skb->len - len; + u16 flags; + + /* All of a TSO frame must be composed of paged data. */ + BUG_ON(skb->len != skb->data_len); + + buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC); + if (unlikely(buff == NULL)) + return -ENOMEM; + + buff->truesize = nlen; + skb->truesize -= nlen; + + /* Correct the sequence numbers. */ + TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; + TCP_SKB_CB(buff)->end_seq = TCP_SKB_CB(skb)->end_seq; + TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(buff)->seq; + + /* PSH and FIN should only be set in the second packet. */ + flags = TCP_SKB_CB(skb)->flags; + TCP_SKB_CB(skb)->flags = flags & ~(TCPCB_FLAG_FIN|TCPCB_FLAG_PSH); + TCP_SKB_CB(buff)->flags = flags; + + /* This packet was never sent out yet, so no SACK bits. */ + TCP_SKB_CB(buff)->sacked = 0; + + buff->ip_summed = skb->ip_summed = CHECKSUM_HW; + skb_split(skb, buff, len); + + /* Fix up tso_factor for both original and new SKB. */ + tcp_set_skb_tso_segs(sk, skb); + tcp_set_skb_tso_segs(sk, buff); + + /* Link BUFF into the send queue. */ + skb_header_release(buff); + __skb_append(skb, buff); + + return 0; +} + +/* Try to defer sending, if possible, in order to minimize the amount + * of TSO splitting we do. View it as a kind of TSO Nagle test. + * + * This algorithm is from John Heffner. + */ +static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_buff *skb) +{ + u32 send_win, cong_win, limit, in_flight; + + if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) + return 0; + + in_flight = tcp_packets_in_flight(tp); + + BUG_ON(tcp_skb_pcount(skb) <= 1 || + (tp->snd_cwnd <= in_flight)); + + send_win = (tp->snd_una + tp->snd_wnd) - TCP_SKB_CB(skb)->seq; + + /* From in_flight test above, we know that cwnd > in_flight. */ + cong_win = (tp->snd_cwnd - in_flight) * tp->mss_cache; + + limit = min(send_win, cong_win); + + /* If sk_send_head can be sent fully now, just do it. */ + if (skb->len <= limit) + return 0; + + if (sysctl_tcp_tso_win_divisor) { + u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); + + /* If at least some fraction of a window is available, + * just use it. + */ + chunk /= sysctl_tcp_tso_win_divisor; + if (limit >= chunk) + return 0; + } else { + /* Different approach, try not to defer past a single + * ACK. Receiver should ACK every other full sized + * frame, so if we have space for more than 3 frames + * then send now. + */ + if (limit > tcp_max_burst(tp) * tp->mss_cache) + return 0; + } + + /* Ok, it looks like it is advisable to defer. */ + return 1; +} + /* This routine writes packets to the network. It advances the * send_head. This happens as incoming acks open up the remote * window for us. @@ -887,8 +959,8 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) { struct tcp_sock *tp = tcp_sk(sk); struct sk_buff *skb; - unsigned int tso_segs, cwnd_quota; - int sent_pkts; + unsigned int tso_segs, sent_pkts; + int cwnd_quota; /* If we are closed, the bytes will have to remain here. * In time closedown will finish, we empty the write queue and all @@ -903,24 +975,44 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) tso_segs = tcp_init_tso_segs(sk, skb); cwnd_quota = tcp_cwnd_test(tp, skb); + if (unlikely(!cwnd_quota)) + goto out; + sent_pkts = 0; + while (likely(tcp_snd_wnd_test(tp, skb, mss_now))) { + BUG_ON(!tso_segs); - while (cwnd_quota >= tso_segs) { - if (unlikely(!tcp_nagle_test(tp, skb, mss_now, - (tcp_skb_is_last(sk, skb) ? - nonagle : TCP_NAGLE_PUSH)))) - break; + if (tso_segs == 1) { + if (unlikely(!tcp_nagle_test(tp, skb, mss_now, + (tcp_skb_is_last(sk, skb) ? + nonagle : TCP_NAGLE_PUSH)))) + break; + } else { + if (tcp_tso_should_defer(sk, tp, skb)) + break; + } - if (unlikely(!tcp_snd_wnd_test(tp, skb, mss_now))) - break; + if (tso_segs > 1) { + u32 limit = tcp_window_allows(tp, skb, + mss_now, cwnd_quota); + + if (skb->len < limit) { + unsigned int trim = skb->len % mss_now; - if (unlikely(skb->len > mss_now)) { + if (trim) + limit = skb->len - trim; + } + if (skb->len > limit) { + if (tso_fragment(sk, skb, limit)) + break; + } + } else if (unlikely(skb->len > mss_now)) { if (unlikely(tcp_fragment(sk, skb, mss_now))) break; } TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); + if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))) break; @@ -936,6 +1028,11 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) * the packet above, tso_segs will no longer be valid. */ cwnd_quota -= tcp_skb_pcount(skb); + + BUG_ON(cwnd_quota < 0); + if (!cwnd_quota) + break; + skb = sk->sk_send_head; if (!skb) break; @@ -946,7 +1043,7 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle) tcp_cwnd_validate(sk, tp); return 0; } - +out: return !tp->packets_out && sk->sk_send_head; } @@ -965,6 +1062,53 @@ void __tcp_push_pending_frames(struct sock *sk, struct tcp_sock *tp, } } +/* Send _single_ skb sitting at the send head. This function requires + * true push pending frames to setup probe timer etc. + */ +void tcp_push_one(struct sock *sk, unsigned int mss_now) +{ + struct tcp_sock *tp = tcp_sk(sk); + struct sk_buff *skb = sk->sk_send_head; + unsigned int tso_segs, cwnd_quota; + + BUG_ON(!skb || skb->len < mss_now); + + tso_segs = tcp_init_tso_segs(sk, skb); + cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH); + + if (likely(cwnd_quota)) { + BUG_ON(!tso_segs); + + if (tso_segs > 1) { + u32 limit = tcp_window_allows(tp, skb, + mss_now, cwnd_quota); + + if (skb->len < limit) { + unsigned int trim = skb->len % mss_now; + + if (trim) + limit = skb->len - trim; + } + if (skb->len > limit) { + if (unlikely(tso_fragment(sk, skb, limit))) + return; + } + } else if (unlikely(skb->len > mss_now)) { + if (unlikely(tcp_fragment(sk, skb, mss_now))) + return; + } + + /* Send it out now. */ + TCP_SKB_CB(skb)->when = tcp_time_stamp; + + if (likely(!tcp_transmit_skb(sk, skb_clone(skb, sk->sk_allocation)))) { + update_send_head(sk, tp, skb); + tcp_cwnd_validate(sk, tp); + return; + } + } +} + /* This function returns the amount that we can raise the * usable window based on the following constraints * @@ -1222,7 +1366,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) if (sk->sk_route_caps & NETIF_F_TSO) { sk->sk_route_caps &= ~NETIF_F_TSO; sock_set_flag(sk, SOCK_NO_LARGESEND); - tp->mss_cache = tp->mss_cache_std; } if (tcp_trim_head(sk, skb, tp->snd_una - TCP_SKB_CB(skb)->seq)) @@ -1284,7 +1427,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) * is still in somebody's hands, else make a clone. */ TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); err = tcp_transmit_skb(sk, (skb_cloned(skb) ? pskb_copy(skb, GFP_ATOMIC): @@ -1853,14 +1995,12 @@ int tcp_write_wakeup(struct sock *sk) if (sk->sk_route_caps & NETIF_F_TSO) { sock_set_flag(sk, SOCK_NO_LARGESEND); sk->sk_route_caps &= ~NETIF_F_TSO; - tp->mss_cache = tp->mss_cache_std; } } else if (!tcp_skb_pcount(skb)) tcp_set_skb_tso_segs(sk, skb); TCP_SKB_CB(skb)->flags |= TCPCB_FLAG_PSH; TCP_SKB_CB(skb)->when = tcp_time_stamp; - tcp_tso_set_push(skb); err = tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)); if (!err) { update_send_head(sk, tp, skb); diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 9dac7fd..f6e288d 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -2018,7 +2018,7 @@ static int tcp_v6_init_sock(struct sock *sk) */ tp->snd_ssthresh = 0x7fffffff; tp->snd_cwnd_clamp = ~0; - tp->mss_cache_std = tp->mss_cache = 536; + tp->mss_cache = 536; tp->reordering = sysctl_tcp_reordering; -- cgit v1.1 From 63d886c96b2a580b1bf764de238ba3c63515b5ee Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Tue, 5 Jul 2005 15:29:16 -0700 Subject: [PKT_SCHED]: Blackhole queueing discipline Useful in combination with classful qdiscs to drop or temporary disable certain flows, e.g. one could block specific ds flows with dsmark. Unlike the noop qdisc it can be controlled by the user and statistic accounting is done. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- net/sched/Makefile | 2 +- net/sched/sch_blackhole.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 net/sched/sch_blackhole.c diff --git a/net/sched/Makefile b/net/sched/Makefile index 8f58cec..e48d0d4 100644 --- a/net/sched/Makefile +++ b/net/sched/Makefile @@ -4,7 +4,7 @@ obj-y := sch_generic.o -obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o +obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o sch_blackhole.o obj-$(CONFIG_NET_CLS) += cls_api.o obj-$(CONFIG_NET_CLS_ACT) += act_api.o obj-$(CONFIG_NET_ACT_POLICE) += police.o diff --git a/net/sched/sch_blackhole.c b/net/sched/sch_blackhole.c new file mode 100644 index 0000000..81f0b83 --- /dev/null +++ b/net/sched/sch_blackhole.c @@ -0,0 +1,54 @@ +/* + * net/sched/sch_blackhole.c Black hole queue + * + * 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: Thomas Graf + * + * Note: Quantum tunneling is not supported. + */ + +#include +#include +#include +#include +#include +#include +#include + +static int blackhole_enqueue(struct sk_buff *skb, struct Qdisc *sch) +{ + qdisc_drop(skb, sch); + return NET_XMIT_SUCCESS; +} + +static struct sk_buff *blackhole_dequeue(struct Qdisc *sch) +{ + return NULL; +} + +static struct Qdisc_ops blackhole_qdisc_ops = { + .id = "blackhole", + .priv_size = 0, + .enqueue = blackhole_enqueue, + .dequeue = blackhole_dequeue, + .owner = THIS_MODULE, +}; + +static int __init blackhole_module_init(void) +{ + return register_qdisc(&blackhole_qdisc_ops); +} + +static void __exit blackhole_module_exit(void) +{ + unregister_qdisc(&blackhole_qdisc_ops); +} + +module_init(blackhole_module_init) +module_exit(blackhole_module_exit) + +MODULE_LICENSE("GPL"); -- cgit v1.1 From 908a75c17a9e5a888347c2c1d3572203d1b1c7db Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 15:43:58 -0700 Subject: [TCP]: Never TSO defer under periods of congestion. Congestion window recover after loss depends upon the fact that if we have a full MSS sized frame at the head of the send queue, we will send it. TSO deferral can defeat the ACK clocking necessary to exit cleanly from recovery. Signed-off-by: David S. Miller --- net/ipv4/tcp_output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index fd3ce38..e041d05 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -909,6 +909,9 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ if (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN) return 0; + if (tp->ca_state != TCP_CA_Open) + return 0; + in_flight = tcp_packets_in_flight(tp); BUG_ON(tcp_skb_pcount(skb) <= 1 || -- cgit v1.1 From b2f571026594884e7a2a3f8bc6ad5c92e0703330 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Tue, 5 Jul 2005 16:38:26 -0700 Subject: [IPV4]: Add LC-Trie implementation notes Signed-off-by: Robert Olsson Signed-off-by: David S. Miller --- Documentation/networking/fib_trie.txt | 145 ++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 Documentation/networking/fib_trie.txt diff --git a/Documentation/networking/fib_trie.txt b/Documentation/networking/fib_trie.txt new file mode 100644 index 0000000..f50d0c6 --- /dev/null +++ b/Documentation/networking/fib_trie.txt @@ -0,0 +1,145 @@ + LC-trie implementation notes. + +Node types +---------- +leaf + An end node with data. This has a copy of the relevant key, along + with 'hlist' with routing table entries sorted by prefix length. + See struct leaf and struct leaf_info. + +trie node or tnode + An internal node, holding an array of child (leaf or tnode) pointers, + indexed through a subset of the key. See Level Compression. + +A few concepts explained +------------------------ +Bits (tnode) + The number of bits in the key segment used for indexing into the + child array - the "child index". See Level Compression. + +Pos (tnode) + The position (in the key) of the key segment used for indexing into + the child array. See Path Compression. + +Path Compression / skipped bits + Any given tnode is linked to from the child array of its parent, using + a segment of the key specified by the parent's "pos" and "bits" + In certain cases, this tnode's own "pos" will not be immediately + adjacent to the parent (pos+bits), but there will be some bits + in the key skipped over because they represent a single path with no + deviations. These "skipped bits" constitute Path Compression. + Note that the search algorithm will simply skip over these bits when + searching, making it necessary to save the keys in the leaves to + verify that they actually do match the key we are searching for. + +Level Compression / child arrays + the trie is kept level balanced moving, under certain conditions, the + children of a full child (see "full_children") up one level, so that + instead of a pure binary tree, each internal node ("tnode") may + contain an arbitrarily large array of links to several children. + Conversely, a tnode with a mostly empty child array (see empty_children) + may be "halved", having some of its children moved downwards one level, + in order to avoid ever-increasing child arrays. + +empty_children + the number of positions in the child array of a given tnode that are + NULL. + +full_children + the number of children of a given tnode that aren't path compressed. + (in other words, they aren't NULL or leaves and their "pos" is equal + to this tnode's "pos"+"bits"). + + (The word "full" here is used more in the sense of "complete" than + as the opposite of "empty", which might be a tad confusing.) + +Comments +--------- + +We have tried to keep the structure of the code as close to fib_hash as +possible to allow verification and help up reviewing. + +fib_find_node() + A good start for understanding this code. This function implements a + straightforward trie lookup. + +fib_insert_node() + Inserts a new leaf node in the trie. This is bit more complicated than + fib_find_node(). Inserting a new node means we might have to run the + level compression algorithm on part of the trie. + +trie_leaf_remove() + Looks up a key, deletes it and runs the level compression algorithm. + +trie_rebalance() + The key function for the dynamic trie after any change in the trie + it is run to optimize and reorganize. Tt will walk the trie upwards + towards the root from a given tnode, doing a resize() at each step + to implement level compression. + +resize() + Analyzes a tnode and optimizes the child array size by either inflating + or shrinking it repeatedly until it fullfills the criteria for optimal + level compression. This part follows the original paper pretty closely + and there may be some room for experimentation here. + +inflate() + Doubles the size of the child array within a tnode. Used by resize(). + +halve() + Halves the size of the child array within a tnode - the inverse of + inflate(). Used by resize(); + +fn_trie_insert(), fn_trie_delete(), fn_trie_select_default() + The route manipulation functions. Should conform pretty closely to the + corresponding functions in fib_hash. + +fn_trie_flush() + This walks the full trie (using nextleaf()) and searches for empty + leaves which have to be removed. + +fn_trie_dump() + Dumps the routing table ordered by prefix length. This is somewhat + slower than the corresponding fib_hash function, as we have to walk the + entire trie for each prefix length. In comparison, fib_hash is organized + as one "zone"/hash per prefix length. + +Locking +------- + +fib_lock is used for an RW-lock in the same way that this is done in fib_hash. +However, the functions are somewhat separated for other possible locking +scenarios. It might conceivably be possible to run trie_rebalance via RCU +to avoid read_lock in the fn_trie_lookup() function. + +Main lookup mechanism +--------------------- +fn_trie_lookup() is the main lookup function. + +The lookup is in its simplest form just like fib_find_node(). We descend the +trie, key segment by key segment, until we find a leaf. check_leaf() does +the fib_semantic_match in the leaf's sorted prefix hlist. + +If we find a match, we are done. + +If we don't find a match, we enter prefix matching mode. The prefix length, +starting out at the same as the key length, is reduced one step at a time, +and we backtrack upwards through the trie trying to find a longest matching +prefix. The goal is always to reach a leaf and get a positive result from the +fib_semantic_match mechanism. + +Inside each tnode, the search for longest matching prefix consists of searching +through the child array, chopping off (zeroing) the least significant "1" of +the child index until we find a match or the child index consists of nothing but +zeros. + +At this point we backtrack (t->stats.backtrack++) up the trie, continuing to +chop off part of the key in order to find the longest matching prefix. + +At this point we will repeatedly descend subtries to look for a match, and there +are some optimizations available that can provide us with "shortcuts" to avoid +descending into dead ends. Look for "HL_OPTIMIZE" sections in the code. + +To alleviate any doubts about the correctness of the route selection process, +a new netlink operation has been added. Look for NETLINK_FIB_LOOKUP, which +gives userland access to fib_lookup(). -- cgit v1.1 From e6b6239f8e8e5bd9ba0192a854652abf14e28ce4 Mon Sep 17 00:00:00 2001 From: Andrei Konovalov Date: Tue, 5 Jul 2005 18:54:43 -0700 Subject: [PATCH] ppc32: add Freescale MPC885ADS board support This patch adds the Freescale MPC86xADS board support. The supported devices are SMC UART and 10Mbit ethernet on SCC1. The manual for the board says that it "is compatible with the MPC8xxFADS for software point of view". That's why this patch extends FADS instead of introducing a new platform. FEC is not supported as the "combined FCC/FEC ethernet driver" driver by Pantelis Antoniou should replace the current FEC driver. Signed-off-by: Gennadiy Kurtsman Signed-off-by: Andrei Konovalov Acked-by: Tom Rini Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/8xx_io/enet.c | 52 ++- arch/ppc/Kconfig | 22 +- arch/ppc/configs/mpc86x_ads_defconfig | 633 ++++++++++++++++++++++++++++++++ arch/ppc/configs/mpc885ads_defconfig | 622 +++++++++++++++++++++++++++++++ arch/ppc/platforms/fads.h | 109 +++++- arch/ppc/platforms/mpc885ads.h | 92 +++++ drivers/serial/cpm_uart/cpm_uart_cpm1.c | 32 +- include/asm-ppc/mpc8xx.h | 4 + 8 files changed, 1550 insertions(+), 16 deletions(-) create mode 100644 arch/ppc/configs/mpc86x_ads_defconfig create mode 100644 arch/ppc/configs/mpc885ads_defconfig create mode 100644 arch/ppc/platforms/mpc885ads.h diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index 4ea7158..ece6a9f 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -714,16 +714,24 @@ static int __init scc_enet_init(void) immap->im_ioport.iop_pcdat &= ~PC_ENET_LBK; /* Disable Loopback */ #endif /* PC_ENET_LBK */ - /* Configure port C pins to enable CLSN and RENA. +#ifdef PE_ENET_TCLK + /* Configure port E for TCLK and RCLK. */ - immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); - immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); - + cp->cp_pepar |= (PE_ENET_TCLK | PE_ENET_RCLK); + cp->cp_pedir &= ~(PE_ENET_TCLK | PE_ENET_RCLK); + cp->cp_peso &= ~(PE_ENET_TCLK | PE_ENET_RCLK); +#else /* Configure port A for TCLK and RCLK. */ immap->im_ioport.iop_papar |= (PA_ENET_TCLK | PA_ENET_RCLK); immap->im_ioport.iop_padir &= ~(PA_ENET_TCLK | PA_ENET_RCLK); +#endif + + /* Configure port C pins to enable CLSN and RENA. + */ + immap->im_ioport.iop_pcpar &= ~(PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcdir &= ~(PC_ENET_CLSN | PC_ENET_RENA); + immap->im_ioport.iop_pcso |= (PC_ENET_CLSN | PC_ENET_RENA); /* Configure Serial Interface clock routing. * First, clear all SCC bits to zero, then set the ones we want. @@ -896,14 +904,18 @@ static int __init scc_enet_init(void) /* It is now OK to enable the Ethernet transmitter. * Unfortunately, there are board implementation differences here. */ -#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA)) +#if (!defined (PB_ENET_TENA) && defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) immap->im_ioport.iop_pcpar |= PC_ENET_TENA; immap->im_ioport.iop_pcdir &= ~PC_ENET_TENA; -#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA)) +#elif ( defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && !defined (PE_ENET_TENA)) cp->cp_pbpar |= PB_ENET_TENA; cp->cp_pbdir |= PB_ENET_TENA; +#elif ( !defined (PB_ENET_TENA) && !defined (PC_ENET_TENA) && defined (PE_ENET_TENA)) + cp->cp_pepar |= PE_ENET_TENA; + cp->cp_pedir &= ~PE_ENET_TENA; + cp->cp_peso |= PE_ENET_TENA; #else -#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA +#error Configuration Error: define exactly ONE of PB_ENET_TENA, PC_ENET_TENA, PE_ENET_TENA #endif #if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) @@ -936,6 +948,29 @@ static int __init scc_enet_init(void) *((volatile uint *)BCSR1) &= ~BCSR1_ETHEN; #endif +#ifdef CONFIG_MPC885ADS + + /* Deassert PHY reset and enable the PHY. + */ + { + volatile uint __iomem *bcsr = ioremap(BCSR_ADDR, BCSR_SIZE); + uint tmp; + + tmp = in_be32(bcsr + 1 /* BCSR1 */); + tmp |= BCSR1_ETHEN; + out_be32(bcsr + 1, tmp); + tmp = in_be32(bcsr + 4 /* BCSR4 */); + tmp |= BCSR4_ETH10_RST; + out_be32(bcsr + 4, tmp); + iounmap(bcsr); + } + + /* On MPC885ADS SCC ethernet PHY defaults to the full duplex mode + * upon reset. SCC is set to half duplex by default. So this + * inconsistency should be better fixed by the software. + */ +#endif + dev->base_addr = (unsigned long)ep; #if 0 dev->name = "CPM_ENET"; @@ -969,3 +1004,4 @@ static int __init scc_enet_init(void) } module_init(scc_enet_init); + diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index a7835cd..23b0d2f 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -284,6 +284,9 @@ endmenu menu "Platform options" +config FADS + bool + choice prompt "8xx Machine Type" depends on 8xx @@ -399,8 +402,25 @@ config BSEIP 26MB DRAM, 4MB flash, Ethernet, a 16K-gate FPGA, USB, an LCD/video controller, and two RS232 ports. -config FADS +config MPC8XXFADS bool "FADS" + select FADS + +config MPC86XADS + bool "MPC86XADS" + help + MPC86x Application Development System by Freescale Semiconductor. + The MPC86xADS is meant to serve as a platform for s/w and h/w + development around the MPC86X processor families. + select FADS + +config MPC885ADS + bool "MPC885ADS" + help + Freescale Semiconductor MPC885 Application Development System (ADS). + Also known as DUET. + The MPC885ADS is meant to serve as a platform for s/w and h/w + development around the MPC885 processor family. config TQM823L bool "TQM823L" diff --git a/arch/ppc/configs/mpc86x_ads_defconfig b/arch/ppc/configs/mpc86x_ads_defconfig new file mode 100644 index 0000000..f63c6f5 --- /dev/null +++ b/arch/ppc/configs/mpc86x_ads_defconfig @@ -0,0 +1,633 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc4 +# Tue Jun 14 13:36:35 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_HOTPLUG is not set +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +# CONFIG_BASE_FULL is not set +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +# CONFIG_SHMEM is not set +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +CONFIG_TINY_SHMEM=y +CONFIG_BASE_SMALL=1 + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODULE_UNLOAD is not set +CONFIG_OBSOLETE_MODPARM=y +# CONFIG_MODVERSIONS is not set +# CONFIG_MODULE_SRCVERSION_ALL is not set +# CONFIG_KMOD is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +CONFIG_8xx=y +# CONFIG_E500 is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y + +# +# Platform options +# +CONFIG_FADS=y +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_MPC8XXFADS is not set +CONFIG_MPC86XADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_QSPAN is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +# CONFIG_STANDALONE is not set +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_AS=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +CONFIG_IPV6=m +# CONFIG_IPV6_PRIVACY is not set +# CONFIG_INET6_AH is not set +# CONFIG_INET6_ESP is not set +# CONFIG_INET6_IPCOMP is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_IPV6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MII is not set +# CONFIG_OAKNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set +CONFIG_SOUND_GAMEPORT=y + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +# CONFIG_SERIAL_CPM_SCC1 is not set +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +# CONFIG_SERIAL_CPM_SCC4 is not set +CONFIG_SERIAL_CPM_SMC1=y +# CONFIG_SERIAL_CPM_SMC2 is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +# CONFIG_EXT2_FS is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_XATTR is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +CONFIG_NFS_V3=y +CONFIG_NFS_V4=y +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_RPCSEC_GSS_KRB5=y +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +CONFIG_SCC1_ENET=y +# CONFIG_SCC2_ENET is not set +# CONFIG_SCC3_ENET is not set +# CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set + +# +# Generic MPC8xx Options +# +# CONFIG_8xx_COPYBACK is not set +# CONFIG_8xx_CPU6 is not set +CONFIG_NO_UCODE_PATCH=y +# CONFIG_USB_SOF_UCODE_PATCH is not set +# CONFIG_I2C_SPI_UCODE_PATCH is not set +# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +CONFIG_CRYPTO=y +# CONFIG_CRYPTO_HMAC is not set +# CONFIG_CRYPTO_NULL is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# CONFIG_CRYPTO_SHA1 is not set +# CONFIG_CRYPTO_SHA256 is not set +# CONFIG_CRYPTO_SHA512 is not set +# CONFIG_CRYPTO_WP512 is not set +# CONFIG_CRYPTO_TGR192 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_TWOFISH is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_AES is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_ARC4 is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_ANUBIS is not set +# CONFIG_CRYPTO_DEFLATE is not set +# CONFIG_CRYPTO_MICHAEL_MIC is not set +# CONFIG_CRYPTO_CRC32C is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/configs/mpc885ads_defconfig b/arch/ppc/configs/mpc885ads_defconfig new file mode 100644 index 0000000..016f94d --- /dev/null +++ b/arch/ppc/configs/mpc885ads_defconfig @@ -0,0 +1,622 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.12-rc6 +# Thu Jun 9 21:17:29 2005 +# +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_HAVE_DEC_LOCK=y +CONFIG_PPC=y +CONFIG_PPC32=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +# CONFIG_CLEAN_COMPILE is not set +CONFIG_BROKEN=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +# CONFIG_SWAP is not set +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +CONFIG_HOTPLUG=y +CONFIG_KOBJECT_UEVENT=y +# CONFIG_IKCONFIG is not set +CONFIG_EMBEDDED=y +# CONFIG_KALLSYMS is not set +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +# CONFIG_EPOLL is not set +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_SHMEM=y +CONFIG_CC_ALIGN_FUNCTIONS=0 +CONFIG_CC_ALIGN_LABELS=0 +CONFIG_CC_ALIGN_LOOPS=0 +CONFIG_CC_ALIGN_JUMPS=0 +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Processor +# +# CONFIG_6xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +CONFIG_8xx=y +# CONFIG_E500 is not set +# CONFIG_MATH_EMULATION is not set +# CONFIG_CPU_FREQ is not set +CONFIG_EMBEDDEDBOOT=y +# CONFIG_PM is not set +CONFIG_NOT_COHERENT_CACHE=y + +# +# Platform options +# +# CONFIG_RPXLITE is not set +# CONFIG_RPXCLASSIC is not set +# CONFIG_BSEIP is not set +# CONFIG_FADS is not set +CONFIG_MPC885ADS=y +# CONFIG_TQM823L is not set +# CONFIG_TQM850L is not set +# CONFIG_TQM855L is not set +# CONFIG_TQM860L is not set +# CONFIG_FPS850L is not set +# CONFIG_SPD823TS is not set +# CONFIG_IVMS8 is not set +# CONFIG_IVML24 is not set +# CONFIG_SM850 is not set +# CONFIG_HERMES_PRO is not set +# CONFIG_IP860 is not set +# CONFIG_LWMON is not set +# CONFIG_PCU_E is not set +# CONFIG_CCM is not set +# CONFIG_LANTEC is not set +# CONFIG_MBX is not set +# CONFIG_WINCEPT is not set +# CONFIG_SMP is not set +# CONFIG_PREEMPT is not set +# CONFIG_HIGHMEM is not set +CONFIG_BINFMT_ELF=y +# CONFIG_BINFMT_MISC is not set +# CONFIG_CMDLINE_BOOL is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +# CONFIG_PCI is not set +# CONFIG_PCI_DOMAINS is not set +# CONFIG_PCI_QSPAN is not set + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_CONSISTENT_START=0xff100000 +CONFIG_CONSISTENT_SIZE=0x00200000 +CONFIG_BOOT_LOAD=0x00400000 + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +# CONFIG_BLK_DEV_LOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_LBD is not set +# CONFIG_CDROM_PKTCDVD is not set + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +# CONFIG_IOSCHED_AS is not set +# CONFIG_IOSCHED_DEADLINE is not set +# CONFIG_IOSCHED_CFQ is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_SCSI is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# + +# +# Macintosh device drivers +# + +# +# Networking support +# +CONFIG_NET=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_ARPD is not set +# CONFIG_SYN_COOKIES is not set +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_IP_TCPDIAG=y +# CONFIG_IP_TCPDIAG_IPV6 is not set +# CONFIG_IPV6 is not set +# CONFIG_NETFILTER is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set +# CONFIG_NET_CLS_ROUTE is not set + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_OAKNET is not set + +# +# Ethernet (1000 Mbit) +# + +# +# Ethernet (10000 Mbit) +# + +# +# Token Ring devices +# + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +# CONFIG_PPP_BSDCOMP is not set +# CONFIG_PPPOE is not set +# CONFIG_SLIP is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +# CONFIG_SERIAL_8250 is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +CONFIG_SERIAL_CPM=y +CONFIG_SERIAL_CPM_CONSOLE=y +# CONFIG_SERIAL_CPM_SCC1 is not set +# CONFIG_SERIAL_CPM_SCC2 is not set +# CONFIG_SERIAL_CPM_SCC3 is not set +# CONFIG_SERIAL_CPM_SCC4 is not set +CONFIG_SERIAL_CPM_SMC1=y +CONFIG_SERIAL_CPM_SMC2=y +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM is not set +# CONFIG_GEN_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB_ARCH_HAS_HCD is not set +# CONFIG_USB_ARCH_HAS_OHCI is not set + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +CONFIG_EXT2_FS_XATTR=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set + +# +# XFS support +# +# CONFIG_XFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_QUOTA is not set +# CONFIG_DNOTIFY is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +# CONFIG_PROC_KCORE is not set +CONFIG_SYSFS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVPTS_FS_XATTR is not set +# CONFIG_TMPFS is not set +# CONFIG_HUGETLBFS is not set +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# MPC8xx CPM Options +# +CONFIG_SCC_ENET=y +# CONFIG_SCC1_ENET is not set +# CONFIG_SCC2_ENET is not set +CONFIG_SCC3_ENET=y +# CONFIG_FEC_ENET is not set +# CONFIG_ENET_BIG_BUFFERS is not set + +# +# Generic MPC8xx Options +# +CONFIG_8xx_COPYBACK=y +CONFIG_8xx_CPU6=y +CONFIG_NO_UCODE_PATCH=y +# CONFIG_USB_SOF_UCODE_PATCH is not set +# CONFIG_I2C_SPI_UCODE_PATCH is not set +# CONFIG_I2C_SPI_SMC1_UCODE_PATCH is not set + +# +# Library routines +# +CONFIG_CRC_CCITT=y +# CONFIG_CRC32 is not set +# CONFIG_LIBCRC32C is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y + +# +# Profiling support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/arch/ppc/platforms/fads.h b/arch/ppc/platforms/fads.h index 632b817..b60c564 100644 --- a/arch/ppc/platforms/fads.h +++ b/arch/ppc/platforms/fads.h @@ -3,7 +3,18 @@ * the Motorola 860T FADS board. Copied from the MBX stuff. * * Copyright (c) 1998 Dan Malek (dmalek@jlc.net) + * + * Added MPC86XADS support. + * The MPC86xADS manual says the board "is compatible with the MPC8xxFADS + * for SW point of view". This is 99% correct. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. */ + #ifdef __KERNEL__ #ifndef __ASM_FADS_H__ #define __ASM_FADS_H__ @@ -12,18 +23,45 @@ #include +#if defined(CONFIG_MPC86XADS) + +/* U-Boot maps BCSR to 0xff080000 */ +#define BCSR_ADDR ((uint)0xff080000) + +/* MPC86XADS has one more CPLD and an additional BCSR. + */ +#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) +#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) + +#define BCSR5_T1_RST 0x10 +#define BCSR5_ATM155_RST 0x08 +#define BCSR5_ATM25_RST 0x04 +#define BCSR5_MII1_EN 0x02 +#define BCSR5_MII1_RST 0x01 + +/* There is no PHY link change interrupt */ +#define PHY_INTERRUPT (-1) + +#else /* FADS */ + /* Memory map is configured by the PROM startup. * I tried to follow the FADS manual, although the startup PROM * dictates this and we simply have to move some of the physical * addresses for Linux. */ #define BCSR_ADDR ((uint)0xff010000) + +/* PHY link change interrupt */ +#define PHY_INTERRUPT SIU_IRQ2 + +#endif /* CONFIG_MPC86XADS */ + #define BCSR_SIZE ((uint)(64 * 1024)) -#define BCSR0 ((uint)0xff010000) -#define BCSR1 ((uint)0xff010004) -#define BCSR2 ((uint)0xff010008) -#define BCSR3 ((uint)0xff01000c) -#define BCSR4 ((uint)0xff010010) +#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) +#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) +#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) +#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) +#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) #define IMAP_ADDR ((uint)0xff000000) #define IMAP_SIZE ((uint)(64 * 1024)) @@ -34,8 +72,17 @@ /* Bits of interest in the BCSRs. */ #define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_IRDAEN ((uint)0x10000000) #define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_PCCEN ((uint)0x00800000) +#define BCSR1_PCCVCC0 ((uint)0x00400000) +#define BCSR1_PCCVPP0 ((uint)0x00200000) +#define BCSR1_PCCVPP1 ((uint)0x00100000) +#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) #define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR1_PCCVCC1 ((uint)0x00010000) +#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) + #define BCSR4_ETHLOOP ((uint)0x80000000) /* EEST Loopback */ #define BCSR4_EEFDX ((uint)0x40000000) /* EEST FDX enable */ #define BCSR4_FETH_EN ((uint)0x08000000) /* PHY enable */ @@ -44,14 +91,64 @@ #define BCSR4_FETHFDE ((uint)0x02000000) /* PHY FDX advertise */ #define BCSR4_FETHRST ((uint)0x00200000) /* PHY Reset */ +/* IO_BASE definition for pcmcia. + */ +#define _IO_BASE 0x80000000 +#define _IO_BASE_SIZE 0x1000 + +#ifdef CONFIG_IDE +#define MAX_HWIFS 1 +#endif + /* Interrupt level assignments. */ #define FEC_INTERRUPT SIU_LEVEL1 /* FEC interrupt */ -#define PHY_INTERRUPT SIU_IRQ2 /* PHY link change interrupt */ /* We don't use the 8259. */ #define NR_8259_INTS 0 +/* CPM Ethernet through SCC1 or SCC2 */ + +#ifdef CONFIG_SCC1_ENET /* Probably 860 variant */ +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + * TCLK - CLK1, RCLK - CLK2. + */ +#define PA_ENET_RXD ((ushort)0x0001) +#define PA_ENET_TXD ((ushort)0x0002) +#define PA_ENET_TCLK ((ushort)0x0100) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00001000) +#define PC_ENET_CLSN ((ushort)0x0010) +#define PC_ENET_RENA ((ushort)0x0020) + +/* Control bits in the SICR to route TCLK (CLK1) and RCLK (CLK2) to + * SCC1. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x000000ff) +#define SICR_ENET_CLKRT ((uint)0x0000002c) +#endif /* CONFIG_SCC1_ENET */ + +#ifdef CONFIG_SCC2_ENET /* Probably 823/850 variant */ +/* Bits in parallel I/O port registers that have to be set/cleared + * to configure the pins for SCC1 use. + * TCLK - CLK1, RCLK - CLK2. + */ +#define PA_ENET_RXD ((ushort)0x0004) +#define PA_ENET_TXD ((ushort)0x0008) +#define PA_ENET_TCLK ((ushort)0x0400) +#define PA_ENET_RCLK ((ushort)0x0200) +#define PB_ENET_TENA ((uint)0x00002000) +#define PC_ENET_CLSN ((ushort)0x0040) +#define PC_ENET_RENA ((ushort)0x0080) + +/* Control bits in the SICR to route TCLK and RCLK to + * SCC2. Also, make sure GR1 (bit 24) and SC1 (bit 25) are zero. + */ +#define SICR_ENET_MASK ((uint)0x0000ff00) +#define SICR_ENET_CLKRT ((uint)0x00002e00) +#endif /* CONFIG_SCC2_ENET */ + #endif /* __ASM_FADS_H__ */ #endif /* __KERNEL__ */ diff --git a/arch/ppc/platforms/mpc885ads.h b/arch/ppc/platforms/mpc885ads.h new file mode 100644 index 0000000..eb38663 --- /dev/null +++ b/arch/ppc/platforms/mpc885ads.h @@ -0,0 +1,92 @@ +/* + * A collection of structures, addresses, and values associated with + * the Freescale MPC885ADS board. + * Copied from the FADS stuff. + * + * Author: MontaVista Software, Inc. + * source@mvista.com + * + * 2005 (c) MontaVista Software, Inc. This file is licensed under the + * terms of the GNU General Public License version 2. This program is licensed + * "as is" without any warranty of any kind, whether express or implied. + */ + +#ifdef __KERNEL__ +#ifndef __ASM_MPC885ADS_H__ +#define __ASM_MPC885ADS_H__ + +#include + +#include + +/* U-Boot maps BCSR to 0xff080000 */ +#define BCSR_ADDR ((uint)0xff080000) +#define BCSR_SIZE ((uint)32) +#define BCSR0 ((uint)(BCSR_ADDR + 0x00)) +#define BCSR1 ((uint)(BCSR_ADDR + 0x04)) +#define BCSR2 ((uint)(BCSR_ADDR + 0x08)) +#define BCSR3 ((uint)(BCSR_ADDR + 0x0c)) +#define BCSR4 ((uint)(BCSR_ADDR + 0x10)) + +#define CFG_PHYDEV_ADDR ((uint)0xff0a0000) +#define BCSR5 ((uint)(CFG_PHYDEV_ADDR + 0x300)) + +#define IMAP_ADDR ((uint)0xff000000) +#define IMAP_SIZE ((uint)(64 * 1024)) + +#define PCMCIA_MEM_ADDR ((uint)0xff020000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) + +/* Bits of interest in the BCSRs. + */ +#define BCSR1_ETHEN ((uint)0x20000000) +#define BCSR1_IRDAEN ((uint)0x10000000) +#define BCSR1_RS232EN_1 ((uint)0x01000000) +#define BCSR1_PCCEN ((uint)0x00800000) +#define BCSR1_PCCVCC0 ((uint)0x00400000) +#define BCSR1_PCCVPP0 ((uint)0x00200000) +#define BCSR1_PCCVPP1 ((uint)0x00100000) +#define BCSR1_PCCVPP_MASK (BCSR1_PCCVPP0 | BCSR1_PCCVPP1) +#define BCSR1_RS232EN_2 ((uint)0x00040000) +#define BCSR1_PCCVCC1 ((uint)0x00010000) +#define BCSR1_PCCVCC_MASK (BCSR1_PCCVCC0 | BCSR1_PCCVCC1) + +#define BCSR4_ETH10_RST ((uint)0x80000000) /* 10Base-T PHY reset*/ +#define BCSR4_USB_LO_SPD ((uint)0x04000000) +#define BCSR4_USB_VCC ((uint)0x02000000) +#define BCSR4_USB_FULL_SPD ((uint)0x00040000) +#define BCSR4_USB_EN ((uint)0x00020000) + +#define BCSR5_MII2_EN 0x40 +#define BCSR5_MII2_RST 0x20 +#define BCSR5_T1_RST 0x10 +#define BCSR5_ATM155_RST 0x08 +#define BCSR5_ATM25_RST 0x04 +#define BCSR5_MII1_EN 0x02 +#define BCSR5_MII1_RST 0x01 + +/* Interrupt level assignments */ +#define PHY_INTERRUPT SIU_IRQ7 /* PHY link change interrupt */ +#define SIU_INT_FEC1 SIU_LEVEL1 /* FEC1 interrupt */ +#define SIU_INT_FEC2 SIU_LEVEL3 /* FEC2 interrupt */ +#define FEC_INTERRUPT SIU_INT_FEC1 /* FEC interrupt */ + +/* We don't use the 8259 */ +#define NR_8259_INTS 0 + +/* CPM Ethernet through SCC3 */ +#define PA_ENET_RXD ((ushort)0x0040) +#define PA_ENET_TXD ((ushort)0x0080) +#define PE_ENET_TCLK ((uint)0x00004000) +#define PE_ENET_RCLK ((uint)0x00008000) +#define PE_ENET_TENA ((uint)0x00000010) +#define PC_ENET_CLSN ((ushort)0x0400) +#define PC_ENET_RENA ((ushort)0x0800) + +/* Control bits in the SICR to route TCLK (CLK5) and RCLK (CLK6) to + * SCC3. Also, make sure GR3 (bit 8) and SC3 (bit 9) are zero */ +#define SICR_ENET_MASK ((uint)0x00ff0000) +#define SICR_ENET_CLKRT ((uint)0x002c0000) + +#endif /* __ASM_MPC885ADS_H__ */ +#endif /* __KERNEL__ */ diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm1.c b/drivers/serial/cpm_uart/cpm_uart_cpm1.c index de26cf7..7911912 100644 --- a/drivers/serial/cpm_uart/cpm_uart_cpm1.c +++ b/drivers/serial/cpm_uart/cpm_uart_cpm1.c @@ -94,12 +94,42 @@ void smc1_lineif(struct uart_cpm_port *pinfo) ((immap_t *)IMAP_ADDR)->im_ioport.iop_paodr &= ~iobits; } +#ifdef CONFIG_MPC885ADS + /* Enable SMC1 transceivers */ + { + volatile uint __iomem *bcsr1 = ioremap(BCSR1, 4); + uint tmp; + + tmp = in_be32(bcsr1); + tmp &= ~BCSR1_RS232EN_1; + out_be32(bcsr1, tmp); + iounmap(bcsr1); + } +#endif + pinfo->brg = 1; } void smc2_lineif(struct uart_cpm_port *pinfo) { - /* XXX SMC2: insert port configuration here */ +#ifdef CONFIG_MPC885ADS + volatile cpm8xx_t *cp = cpmp; + volatile uint __iomem *bcsr1; + uint tmp; + + cp->cp_pepar |= 0x00000c00; + cp->cp_pedir &= ~0x00000c00; + cp->cp_peso &= ~0x00000400; + cp->cp_peso |= 0x00000800; + + /* Enable SMC2 transceivers */ + bcsr1 = ioremap(BCSR1, 4); + tmp = in_be32(bcsr1); + tmp &= ~BCSR1_RS232EN_2; + out_be32(bcsr1, tmp); + iounmap(bcsr1); +#endif + pinfo->brg = 2; } diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h index 714d69c..7c31f2d 100644 --- a/include/asm-ppc/mpc8xx.h +++ b/include/asm-ppc/mpc8xx.h @@ -68,6 +68,10 @@ #include #endif +#if defined(CONFIG_MPC885ADS) +#include +#endif + /* Currently, all 8xx boards that support a processor to PCI/ISA bridge * use the same memory map. */ -- cgit v1.1 From f326d22b8cc5bfebfa5b3f6a4066dc737def2234 Mon Sep 17 00:00:00 2001 From: john stultz Date: Tue, 5 Jul 2005 18:54:44 -0700 Subject: [PATCH] ppc32: stop misusing NTP's time_offset value As part of my timeofday rework, I've been looking at the NTP code and I noticed that the PPC architecture is apparently misusing the NTP's time_offset (it is a terrible name!) value as some form of timezone offset. This could cause problems when time_offset changed by the NTP code. This patch changes the PPC code so it uses a more clear local variable: timezone_offset. Signed-off-by: John Stultz Acked-by: Tom Rini Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/kernel/time.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index 7358665..bf4ddca 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -89,6 +89,9 @@ unsigned long tb_to_ns_scale; extern unsigned long wall_jiffies; +/* used for timezone offset */ +static long timezone_offset; + DEFINE_SPINLOCK(rtc_lock); EXPORT_SYMBOL(rtc_lock); @@ -170,7 +173,7 @@ void timer_interrupt(struct pt_regs * regs) xtime.tv_sec - last_rtc_update >= 659 && abs((xtime.tv_nsec / 1000) - (1000000-1000000/HZ)) < 500000/HZ && jiffies - wall_jiffies == 1) { - if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0) + if (ppc_md.set_rtc_time(xtime.tv_sec+1 + timezone_offset) == 0) last_rtc_update = xtime.tv_sec+1; else /* Try again one minute later */ @@ -286,7 +289,7 @@ void __init time_init(void) unsigned old_stamp, stamp, elapsed; if (ppc_md.time_init != NULL) - time_offset = ppc_md.time_init(); + timezone_offset = ppc_md.time_init(); if (__USE_RTC()) { /* 601 processor: dec counts down by 128 every 128ns */ @@ -331,10 +334,10 @@ void __init time_init(void) set_dec(tb_ticks_per_jiffy); /* If platform provided a timezone (pmac), we correct the time */ - if (time_offset) { - sys_tz.tz_minuteswest = -time_offset / 60; + if (timezone_offset) { + sys_tz.tz_minuteswest = -timezone_offset / 60; sys_tz.tz_dsttime = 0; - xtime.tv_sec -= time_offset; + xtime.tv_sec -= timezone_offset; } set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); -- cgit v1.1 From 4b1294f928d9396e45f62b1c306ac8bf9fae036b Mon Sep 17 00:00:00 2001 From: Eugene Surovegin Date: Tue, 5 Jul 2005 18:54:45 -0700 Subject: [PATCH] ppc32: explicitly disable 440GP IRQ compatibility mode in 440GX setup Add explicit disabling of 440GP IRQ compatibility mode when configuring 440GX interrupt controller. This helps when board firmware for some reason uses this compatibility mode and leaves it enabled. It breaks 440GX interrupt code because it assumes native 440GX IRQ mode. People seems to be continuously bitten by this. Signed-off-by: Eugene Surovegin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/syslib/ppc4xx_pic.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/ppc/syslib/ppc4xx_pic.c b/arch/ppc/syslib/ppc4xx_pic.c index 05686fa..4008621 100644 --- a/arch/ppc/syslib/ppc4xx_pic.c +++ b/arch/ppc/syslib/ppc4xx_pic.c @@ -110,6 +110,10 @@ static int ppc4xx_pic_get_irq(struct pt_regs *regs) static void __init ppc4xx_pic_impl_init(void) { +#if defined(CONFIG_440GX) + /* Disable 440GP compatibility mode if it was enabled in firmware */ + SDR_WRITE(DCRN_SDR_MFR, SDR_READ(DCRN_SDR_MFR) & ~DCRN_SDR_MFR_PCM); +#endif /* Configure Base UIC */ mtdcr(DCRN_UIC_CR(UICB), 0); mtdcr(DCRN_UIC_TR(UICB), 0); -- cgit v1.1 From 6772926bef3c9f0ec761b39e5702535471fff70b Mon Sep 17 00:00:00 2001 From: Rusty Lynch Date: Tue, 5 Jul 2005 18:54:50 -0700 Subject: [PATCH] kprobes: fix namespace problem and sparc64 build The following renames arch_init, a kprobes function for performing any architecture specific initialization, to arch_init_kprobes in order to cleanup the namespace. Also, this patch adds arch_init_kprobes to sparc64 to fix the sparc64 kprobes build from the last return probe patch. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/i386/kernel/kprobes.c | 2 +- arch/ia64/kernel/kprobes.c | 2 +- arch/ppc64/kernel/kprobes.c | 2 +- arch/sparc64/kernel/kprobes.c | 5 +++++ arch/x86_64/kernel/kprobes.c | 2 +- include/linux/kprobes.h | 2 +- kernel/kprobes.c | 2 +- 7 files changed, 11 insertions(+), 6 deletions(-) diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index fc8b175..a6d8c45 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c @@ -537,7 +537,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 3aa3167..884f5cd 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c @@ -713,7 +713,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { trampoline_p.addr = (kprobe_opcode_t *)((struct fnptr *)kretprobe_trampoline)->ip; diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c index 1d2ff6d..a3d5195 100644 --- a/arch/ppc64/kernel/kprobes.c +++ b/arch/ppc64/kernel/kprobes.c @@ -444,7 +444,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index bdac631..bbf11f8 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c @@ -433,3 +433,8 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) return 0; } +/* architecture specific initialization */ +int arch_init_kprobes(void) +{ + return 0; +} diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index acd2a77..5c6dc70 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c @@ -682,7 +682,7 @@ static struct kprobe trampoline_p = { .pre_handler = trampoline_probe_handler }; -int __init arch_init(void) +int __init arch_init_kprobes(void) { return register_kprobe(&trampoline_p); } diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index b7a194c..e050fc2 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -155,7 +155,7 @@ extern void arch_copy_kprobe(struct kprobe *p); extern void arch_arm_kprobe(struct kprobe *p); extern void arch_disarm_kprobe(struct kprobe *p); extern void arch_remove_kprobe(struct kprobe *p); -extern int arch_init(void); +extern int arch_init_kprobes(void); extern void show_registers(struct pt_regs *regs); extern kprobe_opcode_t *get_insn_slot(void); extern void free_insn_slot(kprobe_opcode_t *slot); diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 90c0e82..b023712 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c @@ -574,7 +574,7 @@ static int __init init_kprobes(void) INIT_HLIST_HEAD(&kretprobe_inst_table[i]); } - err = arch_init(); + err = arch_init_kprobes(); if (!err) err = register_die_notifier(&kprobe_exceptions_nb); -- cgit v1.1 From fef43da4e4341697a682f5aae1d5d428e840bc61 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 5 Jul 2005 19:45:24 -0700 Subject: [SPARC64]: Fix UltraSPARC-III fallout from membar changes. The membar changes made the size of __cheetah_flush_tlb_pending grow by one instruction, but the boot-time code patching was not updated to match. Signed-off-by: David S. Miller --- arch/sparc64/mm/ultra.S | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 7a2431d..3637708 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -72,6 +72,7 @@ __flush_tlb_pending: flush %g6 retl wrpr %g7, 0x0, %pstate + nop .align 32 .globl __flush_tlb_kernel_range @@ -249,7 +250,7 @@ __cheetah_flush_tlb_mm: /* 15 insns */ retl wrpr %g7, 0x0, %pstate -__cheetah_flush_tlb_pending: /* 22 insns */ +__cheetah_flush_tlb_pending: /* 23 insns */ /* %o0 = context, %o1 = nr, %o2 = vaddrs[] */ rdpr %pstate, %g7 sllx %o1, 3, %o1 @@ -317,7 +318,7 @@ cheetah_patch_cachetlbops: sethi %hi(__cheetah_flush_tlb_pending), %o1 or %o1, %lo(__cheetah_flush_tlb_pending), %o1 call cheetah_patch_one - mov 22, %o2 + mov 23, %o2 #ifdef DCACHE_ALIASING_POSSIBLE sethi %hi(__flush_dcache_page), %o0 -- cgit v1.1 From a18bcb7450840f07a772a45229de4811d930f461 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 5 Jul 2005 20:46:33 -0700 Subject: Linux v2.6.13-rc3 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 77aab7b..278d509 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 6 SUBLEVEL = 13 -EXTRAVERSION =-rc1 +EXTRAVERSION =-rc2 NAME=Woozy Numbat # *DOCUMENTATION* -- cgit v1.1 From 3d3c2ae1101c1f2dff7e2f9d514769779dbd2737 Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 6 Jul 2005 09:09:38 -0700 Subject: [PATCH] PCI: fix !CONFIG_HOTPLUG pci build problem Here's a patch to fix the build issue when CONFIG_HOTPLUG is not enabled in 2.6.13-rc2. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- drivers/pci/pci-driver.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index aac6de9..e4115a0 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -17,13 +17,13 @@ * Dynamic device IDs are disabled for !CONFIG_HOTPLUG */ -#ifdef CONFIG_HOTPLUG - struct pci_dynid { struct list_head node; struct pci_device_id id; }; +#ifdef CONFIG_HOTPLUG + /** * store_new_id * -- cgit v1.1 From b4634484815e1879512a23e4f59eef648135c30a Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 6 Jul 2005 08:51:03 -0700 Subject: [PATCH] Fix bt87x.c build problem Missing forward declaration Signed-off-by: Greg Kroah-Hartman Signed-off-by: Linus Torvalds --- sound/pci/bt87x.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 909fef8..15202f1 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -798,6 +798,8 @@ static struct { {0x270f, 0xfc00}, /* Chaintech Digitop DST-1000 DVB-S */ }; +static struct pci_driver driver; + /* return the rate of the card, or a negative value if it's blacklisted */ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) { -- cgit v1.1 From 83b78bd2d31f12d7d9317d9802a1996a7bd8a6f2 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Wed, 6 Jul 2005 10:47:07 -0700 Subject: [PATCH] Fix broken kmalloc_node in rc1/rc2 This patch used to be in Andrew's tree before the NUMA slab allocator went in. Either this patch or the NUMA slab allocator is needed in order for kmalloc_node to work correctly. pcibus_to_node may be used to generate the node information passed to kmalloc_node. pcibus_to_node returns -1 if it was not able to determine on which node a pcibus is located. For that case kmalloc_node must work like kmalloc. Signed-off-by: Christoph Lameter Signed-off-by: Linus Torvalds --- mm/slab.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/slab.c b/mm/slab.c index 122d031..e57abd4 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -2372,6 +2372,9 @@ void *kmem_cache_alloc_node(kmem_cache_t *cachep, int flags, int nodeid) struct slab *slabp; kmem_bufctl_t next; + if (nodeid == -1) + return kmem_cache_alloc(cachep, flags); + for (loop = 0;;loop++) { struct list_head *q; -- cgit v1.1 From 159f597a8bd0f1d7650d5e580c93a2666c9c26d1 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 6 Jul 2005 15:29:09 -0400 Subject: [PATCH] Fix bt87x.c build problem for real Just the declaration fix wasn't enough to fix things in bt78x.c Signed-off-by: Dave Jones Signed-off-by: Linus Torvalds --- sound/pci/bt87x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 15202f1..c5557ea 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -806,7 +806,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) int i; const struct pci_device_id *supported; - supported = pci_match_device(driver, pci); + supported = pci_match_device(&driver, pci); if (supported) return supported->driver_data; -- cgit v1.1 From 5e6557722e69840506eb8bc5a1edcdb4e447a917 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 6 Jul 2005 15:44:41 -0400 Subject: [PATCH] openfirmware: generate device table for userspace This converts the usage of struct of_match to struct of_device_id, similar to pci_device_id. This allows a device table to be generated, which can be parsed by depmod(8) to generate a map file for module loading. In order for hotplug to work with macio devices, patches to module-init-tools and hotplug must be applied. Those patches are available at: ftp://ftp.suse.com/pub/people/jeffm/linux/macio-hotplug/ Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- arch/ppc/syslib/of_device.c | 15 ++++++++------- arch/ppc64/kernel/of_device.c | 15 ++++++++------- drivers/i2c/busses/i2c-keywest.c | 7 +++---- drivers/ide/ppc/pmac.c | 12 ++---------- drivers/macintosh/macio_asic.c | 4 ++-- drivers/macintosh/mediabay.c | 7 ++----- drivers/macintosh/therm_pm72.c | 9 ++++----- drivers/macintosh/therm_windtunnel.c | 6 +++--- drivers/net/bmac.c | 7 ++----- drivers/net/mace.c | 6 ++---- drivers/net/wireless/airport.c | 8 ++++---- drivers/scsi/mac53c94.c | 7 +++---- drivers/scsi/mesh.c | 8 +++----- drivers/serial/pmac_zilog.c | 9 +++------ drivers/video/platinumfb.c | 6 ++---- include/asm-ppc/macio.h | 5 +++-- include/asm-ppc/of_device.h | 20 ++++---------------- include/linux/mod_devicetable.h | 11 +++++++++++ scripts/mod/file2alias.c | 22 ++++++++++++++++++++++ 19 files changed, 91 insertions(+), 93 deletions(-) diff --git a/arch/ppc/syslib/of_device.c b/arch/ppc/syslib/of_device.c index 49c0e34..1eb4f72 100644 --- a/arch/ppc/syslib/of_device.c +++ b/arch/ppc/syslib/of_device.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -15,20 +16,20 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * of_match_device(const struct of_match *matches, +const struct of_device_id * of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name || matches->type || matches->compatible) { + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; - if (matches->name && matches->name != OF_ANY_MATCH) + if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); - if (matches->type && matches->type != OF_ANY_MATCH) + if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); - if (matches->compatible && matches->compatible != OF_ANY_MATCH) + if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) @@ -42,7 +43,7 @@ static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_match * matches = of_drv->match_table; + const struct of_device_id * matches = of_drv->match_table; if (!matches) return 0; @@ -75,7 +76,7 @@ static int of_device_probe(struct device *dev) int error = -ENODEV; struct of_platform_driver *drv; struct of_device *of_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); of_dev = to_of_device(dev); diff --git a/arch/ppc64/kernel/of_device.c b/arch/ppc64/kernel/of_device.c index 66bd5ab7..b80e819 100644 --- a/arch/ppc64/kernel/of_device.c +++ b/arch/ppc64/kernel/of_device.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -15,20 +16,20 @@ * Used by a driver to check whether an of_device present in the * system is in its list of supported devices. */ -const struct of_match * of_match_device(const struct of_match *matches, +const struct of_device_id *of_match_device(const struct of_device_id *matches, const struct of_device *dev) { if (!dev->node) return NULL; - while (matches->name || matches->type || matches->compatible) { + while (matches->name[0] || matches->type[0] || matches->compatible[0]) { int match = 1; - if (matches->name && matches->name != OF_ANY_MATCH) + if (matches->name[0]) match &= dev->node->name && !strcmp(matches->name, dev->node->name); - if (matches->type && matches->type != OF_ANY_MATCH) + if (matches->type[0]) match &= dev->node->type && !strcmp(matches->type, dev->node->type); - if (matches->compatible && matches->compatible != OF_ANY_MATCH) + if (matches->compatible[0]) match &= device_is_compatible(dev->node, matches->compatible); if (match) @@ -42,7 +43,7 @@ static int of_platform_bus_match(struct device *dev, struct device_driver *drv) { struct of_device * of_dev = to_of_device(dev); struct of_platform_driver * of_drv = to_of_platform_driver(drv); - const struct of_match * matches = of_drv->match_table; + const struct of_device_id * matches = of_drv->match_table; if (!matches) return 0; @@ -75,7 +76,7 @@ static int of_device_probe(struct device *dev) int error = -ENODEV; struct of_platform_driver *drv; struct of_device *of_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_of_platform_driver(dev->driver); of_dev = to_of_device(dev); diff --git a/drivers/i2c/busses/i2c-keywest.c b/drivers/i2c/busses/i2c-keywest.c index 363e545..94ae808 100644 --- a/drivers/i2c/busses/i2c-keywest.c +++ b/drivers/i2c/busses/i2c-keywest.c @@ -698,7 +698,7 @@ dispose_iface(struct device *dev) } static int -create_iface_macio(struct macio_dev* dev, const struct of_match *match) +create_iface_macio(struct macio_dev* dev, const struct of_device_id *match) { return create_iface(dev->ofdev.node, &dev->ofdev.dev); } @@ -710,7 +710,7 @@ dispose_iface_macio(struct macio_dev* dev) } static int -create_iface_of_platform(struct of_device* dev, const struct of_match *match) +create_iface_of_platform(struct of_device* dev, const struct of_device_id *match) { return create_iface(dev->node, &dev->dev); } @@ -721,10 +721,9 @@ dispose_iface_of_platform(struct of_device* dev) return dispose_iface(&dev->dev); } -static struct of_match i2c_keywest_match[] = +static struct of_device_id i2c_keywest_match[] = { { - .name = OF_ANY_MATCH, .type = "i2c", .compatible = "keywest" }, diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 818380b..be0fcc8 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -1419,7 +1419,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) * Attach to a macio probed interface */ static int __devinit -pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_match *match) +pmac_ide_macio_attach(struct macio_dev *mdev, const struct of_device_id *match) { void __iomem *base; unsigned long regbase; @@ -1637,27 +1637,19 @@ pmac_ide_pci_resume(struct pci_dev *pdev) return rc; } -static struct of_match pmac_ide_macio_match[] = +static struct of_device_id pmac_ide_macio_match[] = { { .name = "IDE", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { .name = "ATA", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { - .name = OF_ANY_MATCH, .type = "ide", - .compatible = OF_ANY_MATCH }, { - .name = OF_ANY_MATCH, .type = "ata", - .compatible = OF_ANY_MATCH }, {}, }; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index d0bda7e..37b18ee 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -33,7 +33,7 @@ static int macio_bus_match(struct device *dev, struct device_driver *drv) { struct macio_dev * macio_dev = to_macio_device(dev); struct macio_driver * macio_drv = to_macio_driver(drv); - const struct of_match * matches = macio_drv->match_table; + const struct of_device_id * matches = macio_drv->match_table; if (!matches) return 0; @@ -66,7 +66,7 @@ static int macio_device_probe(struct device *dev) int error = -ENODEV; struct macio_driver *drv; struct macio_dev *macio_dev; - const struct of_match *match; + const struct of_device_id *match; drv = to_macio_driver(dev->driver); macio_dev = to_macio_device(dev); diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index 4be709e..7c16c25 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c @@ -642,7 +642,7 @@ static int __pmac media_bay_task(void *x) } } -static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_match *match) +static int __devinit media_bay_attach(struct macio_dev *mdev, const struct of_device_id *match) { struct media_bay_info* bay; u32 __iomem *regbase; @@ -797,23 +797,20 @@ static struct mb_ops keylargo_mb_ops __pmacdata = { * Therefore we do it all by polling the media bay once each tick. */ -static struct of_match media_bay_match[] = +static struct of_device_id media_bay_match[] = { { .name = "media-bay", - .type = OF_ANY_MATCH, .compatible = "keylargo-media-bay", .data = &keylargo_mb_ops, }, { .name = "media-bay", - .type = OF_ANY_MATCH, .compatible = "heathrow-media-bay", .data = &heathrow_mb_ops, }, { .name = "media-bay", - .type = OF_ANY_MATCH, .compatible = "ohare-media-bay", .data = &ohare_mb_ops, }, diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index feb4e24..703e3197 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -120,6 +120,7 @@ #include #include #include +#include #include "therm_pm72.h" @@ -1986,7 +1987,7 @@ static void fcu_lookup_fans(struct device_node *fcu_node) } } -static int fcu_of_probe(struct of_device* dev, const struct of_match *match) +static int fcu_of_probe(struct of_device* dev, const struct of_device_id *match) { int rc; @@ -2009,12 +2010,10 @@ static int fcu_of_remove(struct of_device* dev) return 0; } -static struct of_match fcu_of_match[] = +static struct of_device_id fcu_match[] = { { - .name = OF_ANY_MATCH, .type = "fcu", - .compatible = OF_ANY_MATCH }, {}, }; @@ -2022,7 +2021,7 @@ static struct of_match fcu_of_match[] = static struct of_platform_driver fcu_of_platform_driver = { .name = "temperature", - .match_table = fcu_of_match, + .match_table = fcu_match, .probe = fcu_of_probe, .remove = fcu_of_remove }; diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c index 61400f0..cbb72eb 100644 --- a/drivers/macintosh/therm_windtunnel.c +++ b/drivers/macintosh/therm_windtunnel.c @@ -43,6 +43,7 @@ #include #include #include +#include #define LOG_TEMP 0 /* continously log temperature */ @@ -450,7 +451,7 @@ do_probe( struct i2c_adapter *adapter, int addr, int kind ) /************************************************************************/ static int -therm_of_probe( struct of_device *dev, const struct of_match *match ) +therm_of_probe( struct of_device *dev, const struct of_device_id *match ) { return i2c_add_driver( &g4fan_driver ); } @@ -461,9 +462,8 @@ therm_of_remove( struct of_device *dev ) return i2c_del_driver( &g4fan_driver ); } -static struct of_match therm_of_match[] = {{ +static struct of_device_id therm_of_match[] = {{ .name = "fan", - .type = OF_ANY_MATCH, .compatible = "adm1030" }, {} }; diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c index 00e5257..8dc657f 100644 --- a/drivers/net/bmac.c +++ b/drivers/net/bmac.c @@ -1261,7 +1261,7 @@ static void bmac_reset_and_enable(struct net_device *dev) spin_unlock_irqrestore(&bp->lock, flags); } -static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_match *match) +static int __devinit bmac_probe(struct macio_dev *mdev, const struct of_device_id *match) { int j, rev, ret; struct bmac_data *bp; @@ -1645,16 +1645,13 @@ static int __devexit bmac_remove(struct macio_dev *mdev) return 0; } -static struct of_match bmac_match[] = +static struct of_device_id bmac_match[] = { { .name = "bmac", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH, .data = (void *)0, }, { - .name = OF_ANY_MATCH, .type = "network", .compatible = "bmac+", .data = (void *)1, diff --git a/drivers/net/mace.c b/drivers/net/mace.c index 6ed2d7d..81d0a26 100644 --- a/drivers/net/mace.c +++ b/drivers/net/mace.c @@ -109,7 +109,7 @@ bitrev(int b) } -static int __devinit mace_probe(struct macio_dev *mdev, const struct of_match *match) +static int __devinit mace_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *mace = macio_get_of_node(mdev); struct net_device *dev; @@ -1009,12 +1009,10 @@ static irqreturn_t mace_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs) return IRQ_HANDLED; } -static struct of_match mace_match[] = +static struct of_device_id mace_match[] = { { .name = "mace", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c index b4f4bd7..9d49670 100644 --- a/drivers/net/wireless/airport.c +++ b/drivers/net/wireless/airport.c @@ -184,7 +184,7 @@ static int airport_hard_reset(struct orinoco_private *priv) } static int -airport_attach(struct macio_dev *mdev, const struct of_match *match) +airport_attach(struct macio_dev *mdev, const struct of_device_id *match) { struct orinoco_private *priv; struct net_device *dev; @@ -266,16 +266,16 @@ MODULE_AUTHOR("Benjamin Herrenschmidt "); MODULE_DESCRIPTION("Driver for the Apple Airport wireless card."); MODULE_LICENSE("Dual MPL/GPL"); -static struct of_match airport_match[] = +static struct of_device_id airport_match[] = { { .name = "radio", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, airport_match); + static struct macio_driver airport_driver = { .name = DRIVER_NAME, diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index edd47d1..932dcf0 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -424,7 +424,7 @@ static struct scsi_host_template mac53c94_template = { .use_clustering = DISABLE_CLUSTERING, }; -static int mac53c94_probe(struct macio_dev *mdev, const struct of_match *match) +static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *node = macio_get_of_node(mdev); struct pci_dev *pdev = macio_get_pci_dev(mdev); @@ -544,15 +544,14 @@ static int mac53c94_remove(struct macio_dev *mdev) } -static struct of_match mac53c94_match[] = +static struct of_device_id mac53c94_match[] = { { .name = "53c94", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, mac53c94_match); static struct macio_driver mac53c94_driver = { diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index b05737a..ff19332 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1847,7 +1847,7 @@ static struct scsi_host_template mesh_template = { .use_clustering = DISABLE_CLUSTERING, }; -static int mesh_probe(struct macio_dev *mdev, const struct of_match *match) +static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) { struct device_node *mesh = macio_get_of_node(mdev); struct pci_dev* pdev = macio_get_pci_dev(mdev); @@ -2012,20 +2012,18 @@ static int mesh_remove(struct macio_dev *mdev) } -static struct of_match mesh_match[] = +static struct of_device_id mesh_match[] = { { .name = "mesh", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { - .name = OF_ANY_MATCH, .type = "scsi", .compatible = "chrp,mesh0" }, {}, }; +MODULE_DEVICE_TABLE (of, mesh_match); static struct macio_driver mesh_driver = { diff --git a/drivers/serial/pmac_zilog.c b/drivers/serial/pmac_zilog.c index 1c9f716..7db2f37 100644 --- a/drivers/serial/pmac_zilog.c +++ b/drivers/serial/pmac_zilog.c @@ -1545,7 +1545,7 @@ static void pmz_dispose_port(struct uart_pmac_port *uap) /* * Called upon match with an escc node in the devive-tree. */ -static int pmz_attach(struct macio_dev *mdev, const struct of_match *match) +static int pmz_attach(struct macio_dev *mdev, const struct of_device_id *match) { int i; @@ -1850,20 +1850,17 @@ err_out: return rc; } -static struct of_match pmz_match[] = +static struct of_device_id pmz_match[] = { { .name = "ch-a", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, { .name = "ch-b", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH }, {}, }; +MODULE_DEVICE_TABLE (of, pmz_match); static struct macio_driver pmz_driver = { diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 3dd1de1..b00887e 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -523,7 +523,7 @@ int __init platinumfb_setup(char *options) #define invalidate_cache(addr) #endif -static int __devinit platinumfb_probe(struct of_device* odev, const struct of_match *match) +static int __devinit platinumfb_probe(struct of_device* odev, const struct of_device_id *match) { struct device_node *dp = odev->node; struct fb_info *info; @@ -647,12 +647,10 @@ static int __devexit platinumfb_remove(struct of_device* odev) return 0; } -static struct of_match platinumfb_match[] = +static struct of_device_id platinumfb_match[] = { { .name = "platinum", - .type = OF_ANY_MATCH, - .compatible = OF_ANY_MATCH, }, {}, }; diff --git a/include/asm-ppc/macio.h b/include/asm-ppc/macio.h index 2cafc99..a481b77 100644 --- a/include/asm-ppc/macio.h +++ b/include/asm-ppc/macio.h @@ -1,6 +1,7 @@ #ifndef __MACIO_ASIC_H__ #define __MACIO_ASIC_H__ +#include #include extern struct bus_type macio_bus_type; @@ -120,10 +121,10 @@ static inline struct pci_dev *macio_get_pci_dev(struct macio_dev *mdev) struct macio_driver { char *name; - struct of_match *match_table; + struct of_device_id *match_table; struct module *owner; - int (*probe)(struct macio_dev* dev, const struct of_match *match); + int (*probe)(struct macio_dev* dev, const struct of_device_id *match); int (*remove)(struct macio_dev* dev); int (*suspend)(struct macio_dev* dev, pm_message_t state); diff --git a/include/asm-ppc/of_device.h b/include/asm-ppc/of_device.h index 7229735..4b264cf 100644 --- a/include/asm-ppc/of_device.h +++ b/include/asm-ppc/of_device.h @@ -24,20 +24,8 @@ struct of_device }; #define to_of_device(d) container_of(d, struct of_device, dev) -/* - * Struct used for matching a device - */ -struct of_match -{ - char *name; - char *type; - char *compatible; - void *data; -}; -#define OF_ANY_MATCH ((char *)-1L) - -extern const struct of_match *of_match_device( - const struct of_match *matches, const struct of_device *dev); +extern const struct of_device_id *of_match_device( + const struct of_device_id *matches, const struct of_device *dev); extern struct of_device *of_dev_get(struct of_device *dev); extern void of_dev_put(struct of_device *dev); @@ -49,10 +37,10 @@ extern void of_dev_put(struct of_device *dev); struct of_platform_driver { char *name; - struct of_match *match_table; + struct of_device_id *match_table; struct module *owner; - int (*probe)(struct of_device* dev, const struct of_match *match); + int (*probe)(struct of_device* dev, const struct of_device_id *match); int (*remove)(struct of_device* dev); int (*suspend)(struct of_device* dev, pm_message_t state); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 9b6d051..dce53ac 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -174,6 +174,17 @@ struct serio_device_id { __u8 proto; }; +/* + * Struct used for matching a device + */ +struct of_device_id +{ + char name[32]; + char type[32]; + char compatible[128]; + void *data; +}; + /* PCMCIA */ diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 908bff6..5180405 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -25,6 +25,8 @@ typedef Elf64_Addr kernel_ulong_t; #include #endif +#include + typedef uint32_t __u32; typedef uint16_t __u16; typedef unsigned char __u8; @@ -323,6 +325,22 @@ static int do_pcmcia_entry(const char *filename, +static int do_of_entry (const char *filename, struct of_device_id *of, char *alias) +{ + char *tmp; + sprintf (alias, "of:N%sT%sC%s", + of->name[0] ? of->name : "*", + of->type[0] ? of->type : "*", + of->compatible[0] ? of->compatible : "*"); + + /* Replace all whitespace with underscores */ + for (tmp = alias; tmp && *tmp; tmp++) + if (isspace (*tmp)) + *tmp = '_'; + + return 1; +} + /* Ignore any prefix, eg. v850 prepends _ */ static inline int sym_is(const char *symbol, const char *name) { @@ -401,6 +419,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, else if (sym_is(symname, "__mod_pcmcia_device_table")) do_table(symval, sym->st_size, sizeof(struct pcmcia_device_id), do_pcmcia_entry, mod); + else if (sym_is(symname, "__mod_of_device_table")) + do_table(symval, sym->st_size, sizeof(struct of_device_id), + do_of_entry, mod); + } /* Now add out buffered information to the generated C source */ -- cgit v1.1 From b5bf5b6786ccfc9e0c8801291f463d92c8e0b423 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 6 Jul 2005 15:26:27 -0400 Subject: [PATCH] openfirmware: add sysfs nodes for open firmware devices This adds sysfs nodes that the hotplug userspace can use to load the appropriate modules. In order for hotplug to work with macio devices, patches to module-init-tools and hotplug must be applied. Those patches are available at: ftp://ftp.suse.com/pub/people/jeffm/linux/macio-hotplug/ Changes: The previous versions were built on 2.6.12. 2.6.13-rcX introduced a device_attribute parameter to the show functions. Since that parameter was treated as the output buffer, memory corruption would result, causing Oopsen very quickly. Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- drivers/macintosh/Makefile | 2 +- drivers/macintosh/macio_asic.c | 3 +++ drivers/macintosh/macio_sysfs.c | 50 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 drivers/macintosh/macio_sysfs.c diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile index f5ae171..236291b 100644 --- a/drivers/macintosh/Makefile +++ b/drivers/macintosh/Makefile @@ -4,7 +4,7 @@ # Each configuration option enables a list of files. -obj-$(CONFIG_PPC_PMAC) += macio_asic.o +obj-$(CONFIG_PPC_PMAC) += macio_asic.o macio_sysfs.o obj-$(CONFIG_PMAC_MEDIABAY) += mediabay.o obj-$(CONFIG_MAC_EMUMOUSEBTN) += mac_hid.o diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 37b18ee..7fa369c 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -126,11 +126,14 @@ static int macio_device_resume(struct device * dev) return 0; } +extern struct device_attribute macio_dev_attrs[]; + struct bus_type macio_bus_type = { .name = "macio", .match = macio_bus_match, .suspend = macio_device_suspend, .resume = macio_device_resume, + .dev_attrs = macio_dev_attrs, }; static int __init macio_bus_driver_init(void) diff --git a/drivers/macintosh/macio_sysfs.c b/drivers/macintosh/macio_sysfs.c new file mode 100644 index 0000000..97d22bb --- /dev/null +++ b/drivers/macintosh/macio_sysfs.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include + + +#define macio_config_of_attr(field, format_string) \ +static ssize_t \ +field##_show (struct device *dev, struct device_attribute *attr, \ + char *buf) \ +{ \ + struct macio_dev *mdev = to_macio_device (dev); \ + return sprintf (buf, format_string, mdev->ofdev.node->field); \ +} + +static ssize_t +compatible_show (struct device *dev, struct device_attribute *attr, char *buf) +{ + struct of_device *of; + char *compat; + int cplen; + int length = 0; + + of = &to_macio_device (dev)->ofdev; + compat = (char *) get_property(of->node, "compatible", &cplen); + if (!compat) { + *buf = '\0'; + return 0; + } + while (cplen > 0) { + int l; + length += sprintf (buf, "%s\n", compat); + buf += length; + l = strlen (compat) + 1; + compat += l; + cplen -= l; + } + + return length; +} + +macio_config_of_attr (name, "%s\n"); +macio_config_of_attr (type, "%s\n"); + +struct device_attribute macio_dev_attrs[] = { + __ATTR_RO(name), + __ATTR_RO(type), + __ATTR_RO(compatible), + __ATTR_NULL +}; -- cgit v1.1 From 184f6eb8c46afc2a4aa6cb7c51ebc423c36d9c9d Mon Sep 17 00:00:00 2001 From: Jeff Mahoney Date: Wed, 6 Jul 2005 15:45:09 -0400 Subject: [PATCH] openfirmware: implement hotplug for macio devices This adds the hotplug routine for generating hotplug events when devices are seen on the macio bus. It uses the attributed created by the sysfs nodes to generate the hotplug environment vars for userspace. Since the characters allowed inside the 'compatible' field are NUL terminated, they are exported as individual OF_COMPATIBLE_# variables, with OF_COMPATIBLE_N maintaining a count of how many there are. In order for hotplug to work with macio devices, patches to module-init-tools and hotplug must be applied. Those patches are available at: ftp://ftp.suse.com/pub/people/jeffm/linux/macio-hotplug/ Signed-off-by: Jeff Mahoney Signed-off-by: Linus Torvalds --- drivers/macintosh/macio_asic.c | 71 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index 7fa369c..1ee0033 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -126,11 +126,82 @@ static int macio_device_resume(struct device * dev) return 0; } +static int macio_hotplug (struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size) +{ + struct macio_dev * macio_dev; + struct of_device * of; + char *scratch, *compat; + int i = 0; + int length = 0; + int cplen, seen = 0; + + if (!dev) + return -ENODEV; + + macio_dev = to_macio_device(dev); + if (!macio_dev) + return -ENODEV; + + of = &macio_dev->ofdev; + scratch = buffer; + + /* stuff we want to pass to /sbin/hotplug */ + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, "OF_NAME=%s", + of->node->name); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, "OF_TYPE=%s", + of->node->type); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + /* Since the compatible field can contain pretty much anything + * it's not really legal to split it out with commas. We split it + * up using a number of environment variables instead. */ + + compat = (char *) get_property(of->node, "compatible", &cplen); + while (compat && cplen > 0) { + int l; + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, + "OF_COMPATIBLE_%d=%s", seen, compat); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + length++; + scratch += length; + l = strlen (compat) + 1; + compat += l; + cplen -= l; + seen++; + } + + envp[i++] = scratch; + length += scnprintf (scratch, buffer_size - length, + "OF_COMPATIBLE_N=%d", seen); + if ((buffer_size - length <= 0) || (i >= num_envp)) + return -ENOMEM; + ++length; + scratch += length; + + envp[i] = NULL; + + return 0; +} + extern struct device_attribute macio_dev_attrs[]; struct bus_type macio_bus_type = { .name = "macio", .match = macio_bus_match, + .hotplug = macio_hotplug, .suspend = macio_device_suspend, .resume = macio_device_resume, .dev_attrs = macio_dev_attrs, -- cgit v1.1 From 07bbeaf12310263d808b1958f8413b95f98786ea Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 6 Jul 2005 13:05:50 -0700 Subject: ieee1394: fix broken signed char assumption. "ack_code" is assigned (and tested against) negative numbers, but was declared as "char". Which only works if "char" is signed - which it necessarily isn't. So make that signedness assumption specific. --- drivers/ieee1394/ieee1394_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h index 73bd8ef..0b31429 100644 --- a/drivers/ieee1394/ieee1394_core.h +++ b/drivers/ieee1394/ieee1394_core.h @@ -38,8 +38,8 @@ struct hpsb_packet { /* These are core internal. */ signed char tlabel; - char ack_code; - char tcode; + signed char ack_code; + unsigned char tcode; unsigned expect_response:1; unsigned no_waiter:1; -- cgit v1.1 From 8279dd748f9704b811e528b31304e2fab026abc5 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 6 Jul 2005 13:51:00 -0700 Subject: [CRYPTO] Don't check for NULL before kfree() Checking a pointer for NULL before calling kfree() on it is redundant. This patch removes such checks from crypto/ Signed-off-by: Jesper Juhl Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/cipher.c | 3 +-- crypto/hmac.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/crypto/cipher.c b/crypto/cipher.c index f434ce7..6926449 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -336,6 +336,5 @@ out: void crypto_exit_cipher_ops(struct crypto_tfm *tfm) { - if (tfm->crt_cipher.cit_iv) - kfree(tfm->crt_cipher.cit_iv); + kfree(tfm->crt_cipher.cit_iv); } diff --git a/crypto/hmac.c b/crypto/hmac.c index 847df92..da0456b 100644 --- a/crypto/hmac.c +++ b/crypto/hmac.c @@ -49,8 +49,7 @@ int crypto_alloc_hmac_block(struct crypto_tfm *tfm) void crypto_free_hmac_block(struct crypto_tfm *tfm) { - if (tfm->crt_digest.dit_hmac_block) - kfree(tfm->crt_digest.dit_hmac_block); + kfree(tfm->crt_digest.dit_hmac_block); } void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen) -- cgit v1.1 From c774e93e2152d0be2612739418689e6e6400f4eb Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:51:31 -0700 Subject: [CRYPTO] Add plumbing for multi-block operations The VIA Padlock device is able to perform much better when multiple blocks are fed to it at once. As this device offers an exceptional throughput rate it is worthwhile to optimise the infrastructure specifically for it. We shift the existing page-sized fast path down to the CBC/ECB functions. We can then replace the CBC/ECB functions with functions provided by the underlying algorithm that performs the multi-block operations. As a side-effect this improves the performance of large cipher operations for all existing algorithm implementations. I've measured the gain to be around 5% for 3DES and 15% for AES. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/cipher.c | 246 ++++++++++++++++++++++++++++++++------------------- crypto/scatterwalk.c | 4 +- crypto/scatterwalk.h | 6 +- 3 files changed, 161 insertions(+), 95 deletions(-) diff --git a/crypto/cipher.c b/crypto/cipher.c index 6926449..c424334 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -4,6 +4,7 @@ * Cipher operations. * * Copyright (c) 2002 James Morris + * Copyright (c) 2005 Herbert Xu * * 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 @@ -22,9 +23,13 @@ #include "internal.h" #include "scatterwalk.h" -typedef void (cryptfn_t)(void *, u8 *, const u8 *); -typedef void (procfn_t)(struct crypto_tfm *, u8 *, - u8*, cryptfn_t, void *); +struct cipher_desc { + struct crypto_tfm *tfm; + void (*crfn)(void *ctx, u8 *dst, const u8 *src); + unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes); + void *info; +}; static inline void xor_64(u8 *a, const u8 *b) { @@ -39,63 +44,57 @@ static inline void xor_128(u8 *a, const u8 *b) ((u32 *)a)[2] ^= ((u32 *)b)[2]; ((u32 *)a)[3] ^= ((u32 *)b)[3]; } - -static inline void *prepare_src(struct scatter_walk *walk, int bsize, - void *tmp, int in_place) + +static unsigned int crypt_slow(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, unsigned int bsize) { - void *src = walk->data; - int n = bsize; + u8 src[bsize]; + u8 dst[bsize]; + unsigned int n; - if (unlikely(scatterwalk_across_pages(walk, bsize))) { - src = tmp; - n = scatterwalk_copychunks(src, walk, bsize, 0); - } - scatterwalk_advance(walk, n); - return src; -} + n = scatterwalk_copychunks(src, in, bsize, 0); + scatterwalk_advance(in, n); -static inline void *prepare_dst(struct scatter_walk *walk, int bsize, - void *tmp, int in_place) -{ - void *dst = walk->data; + desc->prfn(desc, dst, src, bsize); - if (unlikely(scatterwalk_across_pages(walk, bsize)) || in_place) - dst = tmp; - return dst; -} + n = scatterwalk_copychunks(dst, out, bsize, 1); + scatterwalk_advance(out, n); -static inline void complete_src(struct scatter_walk *walk, int bsize, - void *src, int in_place) -{ + return bsize; } -static inline void complete_dst(struct scatter_walk *walk, int bsize, - void *dst, int in_place) +static inline unsigned int crypt_fast(const struct cipher_desc *desc, + struct scatter_walk *in, + struct scatter_walk *out, + unsigned int nbytes) { - int n = bsize; + u8 *src, *dst; + + src = in->data; + dst = scatterwalk_samebuf(in, out) ? src : out->data; + + nbytes = desc->prfn(desc, dst, src, nbytes); + + scatterwalk_advance(in, nbytes); + scatterwalk_advance(out, nbytes); - if (unlikely(scatterwalk_across_pages(walk, bsize))) - n = scatterwalk_copychunks(dst, walk, bsize, 1); - else if (in_place) - memcpy(walk->data, dst, bsize); - scatterwalk_advance(walk, n); + return nbytes; } /* * Generic encrypt/decrypt wrapper for ciphers, handles operations across * multiple page boundaries by using temporary blocks. In user context, - * the kernel is given a chance to schedule us once per block. + * the kernel is given a chance to schedule us once per page. */ -static int crypt(struct crypto_tfm *tfm, +static int crypt(const struct cipher_desc *desc, struct scatterlist *dst, struct scatterlist *src, - unsigned int nbytes, cryptfn_t crfn, - procfn_t prfn, void *info) + unsigned int nbytes) { struct scatter_walk walk_in, walk_out; + struct crypto_tfm *tfm = desc->tfm; const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - u8 tmp_src[bsize]; - u8 tmp_dst[bsize]; if (!nbytes) return 0; @@ -109,29 +108,20 @@ static int crypt(struct crypto_tfm *tfm, scatterwalk_start(&walk_out, dst); for(;;) { - u8 *src_p, *dst_p; - int in_place; + unsigned int n; scatterwalk_map(&walk_in, 0); scatterwalk_map(&walk_out, 1); - in_place = scatterwalk_samebuf(&walk_in, &walk_out); + n = scatterwalk_clamp(&walk_in, nbytes); + n = scatterwalk_clamp(&walk_out, n); - do { - src_p = prepare_src(&walk_in, bsize, tmp_src, - in_place); - dst_p = prepare_dst(&walk_out, bsize, tmp_dst, - in_place); + if (likely(n >= bsize)) + n = crypt_fast(desc, &walk_in, &walk_out, n); + else + n = crypt_slow(desc, &walk_in, &walk_out, bsize); - prfn(tfm, dst_p, src_p, crfn, info); - - complete_src(&walk_in, bsize, src_p, in_place); - complete_dst(&walk_out, bsize, dst_p, in_place); - - nbytes -= bsize; - } while (nbytes && - !scatterwalk_across_pages(&walk_in, bsize) && - !scatterwalk_across_pages(&walk_out, bsize)); + nbytes -= n; scatterwalk_done(&walk_in, 0, nbytes); scatterwalk_done(&walk_out, 1, nbytes); @@ -143,30 +133,78 @@ static int crypt(struct crypto_tfm *tfm, } } -static void cbc_process_encrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src, - cryptfn_t fn, void *info) +static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) { - u8 *iv = info; + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + do { + xor(iv, src); + fn(crypto_tfm_ctx(tfm), dst, iv); + memcpy(iv, dst, bsize); - tfm->crt_u.cipher.cit_xor_block(iv, src); - fn(crypto_tfm_ctx(tfm), dst, iv); - memcpy(iv, dst, crypto_tfm_alg_blocksize(tfm)); + src += bsize; + dst += bsize; + } while ((done += bsize) < nbytes); + + return done; } -static void cbc_process_decrypt(struct crypto_tfm *tfm, u8 *dst, u8 *src, - cryptfn_t fn, void *info) +static unsigned int cbc_process_decrypt(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes) { - u8 *iv = info; + struct crypto_tfm *tfm = desc->tfm; + void (*xor)(u8 *, const u8 *) = tfm->crt_u.cipher.cit_xor_block; + int bsize = crypto_tfm_alg_blocksize(tfm); + + u8 stack[src == dst ? bsize : 0]; + u8 *buf = stack; + u8 **dst_p = src == dst ? &buf : &dst; + + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; + u8 *iv = desc->info; + unsigned int done = 0; + + do { + u8 *tmp_dst = *dst_p; - fn(crypto_tfm_ctx(tfm), dst, src); - tfm->crt_u.cipher.cit_xor_block(dst, iv); - memcpy(iv, src, crypto_tfm_alg_blocksize(tfm)); + fn(crypto_tfm_ctx(tfm), tmp_dst, src); + xor(tmp_dst, iv); + memcpy(iv, src, bsize); + if (tmp_dst != dst) + memcpy(dst, tmp_dst, bsize); + + src += bsize; + dst += bsize; + } while ((done += bsize) < nbytes); + + return done; } -static void ecb_process(struct crypto_tfm *tfm, u8 *dst, u8 *src, - cryptfn_t fn, void *info) +static unsigned int ecb_process(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes) { - fn(crypto_tfm_ctx(tfm), dst, src); + struct crypto_tfm *tfm = desc->tfm; + int bsize = crypto_tfm_alg_blocksize(tfm); + void (*fn)(void *, u8 *, const u8 *) = desc->crfn; + unsigned int done = 0; + + do { + fn(crypto_tfm_ctx(tfm), dst, src); + + src += bsize; + dst += bsize; + } while ((done += bsize) < nbytes); + + return done; } static int setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int keylen) @@ -185,9 +223,13 @@ static int ecb_encrypt(struct crypto_tfm *tfm, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_encrypt, - ecb_process, NULL); + struct cipher_desc desc; + + desc.tfm = tfm; + desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; + desc.prfn = ecb_process; + + return crypt(&desc, dst, src, nbytes); } static int ecb_decrypt(struct crypto_tfm *tfm, @@ -195,9 +237,13 @@ static int ecb_decrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_decrypt, - ecb_process, NULL); + struct cipher_desc desc; + + desc.tfm = tfm; + desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; + desc.prfn = ecb_process; + + return crypt(&desc, dst, src, nbytes); } static int cbc_encrypt(struct crypto_tfm *tfm, @@ -205,9 +251,14 @@ static int cbc_encrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_encrypt, - cbc_process_encrypt, tfm->crt_cipher.cit_iv); + struct cipher_desc desc; + + desc.tfm = tfm; + desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; + desc.prfn = cbc_process_encrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); } static int cbc_encrypt_iv(struct crypto_tfm *tfm, @@ -215,9 +266,14 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes, u8 *iv) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_encrypt, - cbc_process_encrypt, iv); + struct cipher_desc desc; + + desc.tfm = tfm; + desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; + desc.prfn = cbc_process_encrypt; + desc.info = iv; + + return crypt(&desc, dst, src, nbytes); } static int cbc_decrypt(struct crypto_tfm *tfm, @@ -225,9 +281,14 @@ static int cbc_decrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_decrypt, - cbc_process_decrypt, tfm->crt_cipher.cit_iv); + struct cipher_desc desc; + + desc.tfm = tfm; + desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; + desc.prfn = cbc_process_decrypt; + desc.info = tfm->crt_cipher.cit_iv; + + return crypt(&desc, dst, src, nbytes); } static int cbc_decrypt_iv(struct crypto_tfm *tfm, @@ -235,9 +296,14 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes, u8 *iv) { - return crypt(tfm, dst, src, nbytes, - tfm->__crt_alg->cra_cipher.cia_decrypt, - cbc_process_decrypt, iv); + struct cipher_desc desc; + + desc.tfm = tfm; + desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; + desc.prfn = cbc_process_decrypt; + desc.info = iv; + + return crypt(&desc, dst, src, nbytes); } static int nocrypt(struct crypto_tfm *tfm, diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c index 50c9461..47ac90e 100644 --- a/crypto/scatterwalk.c +++ b/crypto/scatterwalk.c @@ -100,7 +100,7 @@ void scatterwalk_done(struct scatter_walk *walk, int out, int more) int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out) { - do { + while (nbytes > walk->len_this_page) { memcpy_dir(buf, walk->data, walk->len_this_page, out); buf += walk->len_this_page; nbytes -= walk->len_this_page; @@ -108,7 +108,7 @@ int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, scatterwalk_unmap(walk, out); scatterwalk_pagedone(walk, out, 1); scatterwalk_map(walk, out); - } while (nbytes > walk->len_this_page); + } memcpy_dir(buf, walk->data, nbytes, out); return nbytes; diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h index 02aa56c..5495bb9 100644 --- a/crypto/scatterwalk.h +++ b/crypto/scatterwalk.h @@ -40,10 +40,10 @@ static inline int scatterwalk_samebuf(struct scatter_walk *walk_in, walk_in->offset == walk_out->offset; } -static inline int scatterwalk_across_pages(struct scatter_walk *walk, - unsigned int nbytes) +static inline unsigned int scatterwalk_clamp(struct scatter_walk *walk, + unsigned int nbytes) { - return nbytes > walk->len_this_page; + return nbytes > walk->len_this_page ? walk->len_this_page : nbytes; } static inline void scatterwalk_advance(struct scatter_walk *walk, -- cgit v1.1 From 40725181b74be6b0e3bdc8c05bd1e0b9873ec5cc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:51:52 -0700 Subject: [CRYPTO] Add support for low-level multi-block operations This patch adds hooks for cipher algorithms to implement multi-block ECB/CBC operations directly. This is expected to provide significant performance boots to the VIA Padlock. It could also be used for improving software implementations such as AES where operating on multiple blocks at a time may enable certain optimisations. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/cipher.c | 38 ++++++++++++++++++-------------------- crypto/internal.h | 5 ----- include/linux/crypto.h | 28 +++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/crypto/cipher.c b/crypto/cipher.c index c424334..54c4a56 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -23,14 +23,6 @@ #include "internal.h" #include "scatterwalk.h" -struct cipher_desc { - struct crypto_tfm *tfm; - void (*crfn)(void *ctx, u8 *dst, const u8 *src); - unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst, - const u8 *src, unsigned int nbytes); - void *info; -}; - static inline void xor_64(u8 *a, const u8 *b) { ((u32 *)a)[0] ^= ((u32 *)b)[0]; @@ -224,10 +216,11 @@ static int ecb_encrypt(struct crypto_tfm *tfm, struct scatterlist *src, unsigned int nbytes) { struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; desc.tfm = tfm; - desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; - desc.prfn = ecb_process; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_ecb ?: ecb_process; return crypt(&desc, dst, src, nbytes); } @@ -238,10 +231,11 @@ static int ecb_decrypt(struct crypto_tfm *tfm, unsigned int nbytes) { struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; desc.tfm = tfm; - desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; - desc.prfn = ecb_process; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_ecb ?: ecb_process; return crypt(&desc, dst, src, nbytes); } @@ -252,10 +246,11 @@ static int cbc_encrypt(struct crypto_tfm *tfm, unsigned int nbytes) { struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; desc.tfm = tfm; - desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; - desc.prfn = cbc_process_encrypt; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; desc.info = tfm->crt_cipher.cit_iv; return crypt(&desc, dst, src, nbytes); @@ -267,10 +262,11 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm, unsigned int nbytes, u8 *iv) { struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; desc.tfm = tfm; - desc.crfn = tfm->__crt_alg->cra_cipher.cia_encrypt; - desc.prfn = cbc_process_encrypt; + desc.crfn = cipher->cia_encrypt; + desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; desc.info = iv; return crypt(&desc, dst, src, nbytes); @@ -282,10 +278,11 @@ static int cbc_decrypt(struct crypto_tfm *tfm, unsigned int nbytes) { struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; desc.tfm = tfm; - desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; - desc.prfn = cbc_process_decrypt; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; desc.info = tfm->crt_cipher.cit_iv; return crypt(&desc, dst, src, nbytes); @@ -297,10 +294,11 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm, unsigned int nbytes, u8 *iv) { struct cipher_desc desc; + struct cipher_alg *cipher = &tfm->__crt_alg->cra_cipher; desc.tfm = tfm; - desc.crfn = tfm->__crt_alg->cra_cipher.cia_decrypt; - desc.prfn = cbc_process_decrypt; + desc.crfn = cipher->cia_decrypt; + desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; desc.info = iv; return crypt(&desc, dst, src, nbytes); diff --git a/crypto/internal.h b/crypto/internal.h index 964b9a6..5ed383f 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -42,11 +42,6 @@ static inline void crypto_yield(struct crypto_tfm *tfm) cond_resched(); } -static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) -{ - return (void *)&tfm[1]; -} - struct crypto_alg *crypto_alg_lookup(const char *name); /* A far more intelligent version of this is planned. For now, just diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 387da6a..26ce01c 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -61,6 +61,15 @@ #define CRYPTO_DIR_DECRYPT 0 struct scatterlist; +struct crypto_tfm; + +struct cipher_desc { + struct crypto_tfm *tfm; + void (*crfn)(void *ctx, u8 *dst, const u8 *src); + unsigned int (*prfn)(const struct cipher_desc *desc, u8 *dst, + const u8 *src, unsigned int nbytes); + void *info; +}; /* * Algorithms: modular crypto algorithm implementations, managed @@ -73,6 +82,19 @@ struct cipher_alg { unsigned int keylen, u32 *flags); void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); + + unsigned int (*cia_encrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_ecb)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_encrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); + unsigned int (*cia_decrypt_cbc)(const struct cipher_desc *desc, + u8 *dst, const u8 *src, + unsigned int nbytes); }; struct digest_alg { @@ -136,7 +158,6 @@ static inline int crypto_alg_available(const char *name, u32 flags) * and core processing logic. Managed via crypto_alloc_tfm() and * crypto_free_tfm(), as well as the various helpers below. */ -struct crypto_tfm; struct cipher_tfm { void *cit_iv; @@ -266,6 +287,11 @@ static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) return tfm->__crt_alg->cra_digest.dia_digestsize; } +static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) +{ + return (void *)&tfm[1]; +} + /* * API wrappers. */ -- cgit v1.1 From 95477377995aefa2ec1654a9a3777bd57ea99146 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:52:09 -0700 Subject: [CRYPTO] Add alignmask for low-level cipher implementations The VIA Padlock device requires the input and output buffers to be aligned on 16-byte boundaries. This patch adds the alignmask attribute for low-level cipher implementations to indicate their alignment requirements. The mid-level crypt() function will copy the input/output buffers if they are not aligned correctly before they are passed to the low-level implementation. Strictly speaking, some of the software implementations require the buffers to be aligned on 4-byte boundaries as they do 32-bit loads. However, it is not clear whether it is better to copy the buffers or pay the penalty for unaligned loads/stores. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/api.c | 6 ++++++ crypto/cipher.c | 43 ++++++++++++++++++++++++++++++++++++------- crypto/scatterwalk.h | 6 ++++++ include/linux/crypto.h | 1 + 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/crypto/api.c b/crypto/api.c index 394169a..f55856b 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -168,6 +168,12 @@ int crypto_register_alg(struct crypto_alg *alg) { int ret = 0; struct crypto_alg *q; + + if (alg->cra_alignmask & (alg->cra_alignmask + 1)) + return -EINVAL; + + if (alg->cra_alignmask > PAGE_SIZE) + return -EINVAL; down_write(&crypto_alg_sem); diff --git a/crypto/cipher.c b/crypto/cipher.c index 54c4a56..85eb12f 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -41,8 +41,10 @@ static unsigned int crypt_slow(const struct cipher_desc *desc, struct scatter_walk *in, struct scatter_walk *out, unsigned int bsize) { - u8 src[bsize]; - u8 dst[bsize]; + unsigned int alignmask = desc->tfm->__crt_alg->cra_alignmask; + u8 buffer[bsize * 2 + alignmask]; + u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + u8 *dst = src + bsize; unsigned int n; n = scatterwalk_copychunks(src, in, bsize, 0); @@ -59,15 +61,24 @@ static unsigned int crypt_slow(const struct cipher_desc *desc, static inline unsigned int crypt_fast(const struct cipher_desc *desc, struct scatter_walk *in, struct scatter_walk *out, - unsigned int nbytes) + unsigned int nbytes, u8 *tmp) { u8 *src, *dst; src = in->data; dst = scatterwalk_samebuf(in, out) ? src : out->data; + if (tmp) { + memcpy(tmp, in->data, nbytes); + src = tmp; + dst = tmp; + } + nbytes = desc->prfn(desc, dst, src, nbytes); + if (tmp) + memcpy(out->data, tmp, nbytes); + scatterwalk_advance(in, nbytes); scatterwalk_advance(out, nbytes); @@ -87,6 +98,8 @@ static int crypt(const struct cipher_desc *desc, struct scatter_walk walk_in, walk_out; struct crypto_tfm *tfm = desc->tfm; const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); + unsigned int alignmask = tfm->__crt_alg->cra_alignmask; + unsigned long buffer = 0; if (!nbytes) return 0; @@ -100,16 +113,27 @@ static int crypt(const struct cipher_desc *desc, scatterwalk_start(&walk_out, dst); for(;;) { - unsigned int n; + unsigned int n = nbytes; + u8 *tmp = NULL; + + if (!scatterwalk_aligned(&walk_in, alignmask) || + !scatterwalk_aligned(&walk_out, alignmask)) { + if (!buffer) { + buffer = __get_free_page(GFP_ATOMIC); + if (!buffer) + n = 0; + } + tmp = (u8 *)buffer; + } scatterwalk_map(&walk_in, 0); scatterwalk_map(&walk_out, 1); - n = scatterwalk_clamp(&walk_in, nbytes); + n = scatterwalk_clamp(&walk_in, n); n = scatterwalk_clamp(&walk_out, n); if (likely(n >= bsize)) - n = crypt_fast(desc, &walk_in, &walk_out, n); + n = crypt_fast(desc, &walk_in, &walk_out, n, tmp); else n = crypt_slow(desc, &walk_in, &walk_out, bsize); @@ -119,10 +143,15 @@ static int crypt(const struct cipher_desc *desc, scatterwalk_done(&walk_out, 1, nbytes); if (!nbytes) - return 0; + break; crypto_yield(tfm); } + + if (buffer) + free_page(buffer); + + return 0; } static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h index 5495bb9..e79925c 100644 --- a/crypto/scatterwalk.h +++ b/crypto/scatterwalk.h @@ -55,6 +55,12 @@ static inline void scatterwalk_advance(struct scatter_walk *walk, walk->len_this_segment -= nbytes; } +static inline unsigned int scatterwalk_aligned(struct scatter_walk *walk, + unsigned int alignmask) +{ + return !(walk->offset & alignmask); +} + void scatterwalk_start(struct scatter_walk *walk, struct scatterlist *sg); int scatterwalk_copychunks(void *buf, struct scatter_walk *walk, size_t nbytes, int out); void scatterwalk_map(struct scatter_walk *walk, int out); diff --git a/include/linux/crypto.h b/include/linux/crypto.h index 26ce01c..ac9d49b 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -124,6 +124,7 @@ struct crypto_alg { u32 cra_flags; unsigned int cra_blocksize; unsigned int cra_ctxsize; + unsigned int cra_alignmask; const char cra_name[CRYPTO_MAX_ALG_NAME]; union { -- cgit v1.1 From 6789b2dc455b90efc9c88886c9366adc9abb7347 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:52:27 -0700 Subject: [PADLOCK] Move fast path work into aes_set_key and upper layer Most of the work done aes_padlock can be done in aes_set_key. This means that we only have to do it once when the key changes rather than every time we perform an encryption or decryption. This patch also sets cra_alignmask to let the upper layer ensure that the buffers fed to us are aligned correctly. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/crypto/padlock-aes.c | 102 +++++++++++++++++-------------------------- drivers/crypto/padlock.h | 22 +++++----- 2 files changed, 52 insertions(+), 72 deletions(-) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index ed708b4..5f28909 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include "padlock.h" @@ -59,8 +60,12 @@ #define AES_EXTENDED_KEY_SIZE_B (AES_EXTENDED_KEY_SIZE * sizeof(uint32_t)) struct aes_ctx { - uint32_t e_data[AES_EXTENDED_KEY_SIZE+4]; - uint32_t d_data[AES_EXTENDED_KEY_SIZE+4]; + uint32_t e_data[AES_EXTENDED_KEY_SIZE]; + uint32_t d_data[AES_EXTENDED_KEY_SIZE]; + struct { + struct cword encrypt; + struct cword decrypt; + } cword; uint32_t *E; uint32_t *D; int key_length; @@ -280,10 +285,15 @@ aes_hw_extkey_available(uint8_t key_len) return 0; } +static inline struct aes_ctx *aes_ctx(void *ctx) +{ + return (struct aes_ctx *)ALIGN((unsigned long)ctx, PADLOCK_ALIGNMENT); +} + static int aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t *flags) { - struct aes_ctx *ctx = ctx_arg; + struct aes_ctx *ctx = aes_ctx(ctx_arg); uint32_t i, t, u, v, w; uint32_t P[AES_EXTENDED_KEY_SIZE]; uint32_t rounds; @@ -295,25 +305,36 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t ctx->key_length = key_len; + /* + * If the hardware is capable of generating the extended key + * itself we must supply the plain key for both encryption + * and decryption. + */ ctx->E = ctx->e_data; - ctx->D = ctx->d_data; - - /* Ensure 16-Bytes alignmentation of keys for VIA PadLock. */ - if ((int)(ctx->e_data) & 0x0F) - ctx->E += 4 - (((int)(ctx->e_data) & 0x0F) / sizeof (ctx->e_data[0])); - - if ((int)(ctx->d_data) & 0x0F) - ctx->D += 4 - (((int)(ctx->d_data) & 0x0F) / sizeof (ctx->d_data[0])); + ctx->D = ctx->e_data; E_KEY[0] = uint32_t_in (in_key); E_KEY[1] = uint32_t_in (in_key + 4); E_KEY[2] = uint32_t_in (in_key + 8); E_KEY[3] = uint32_t_in (in_key + 12); + /* Prepare control words. */ + memset(&ctx->cword, 0, sizeof(ctx->cword)); + + ctx->cword.decrypt.encdec = 1; + ctx->cword.encrypt.rounds = 10 + (key_len - 16) / 4; + ctx->cword.decrypt.rounds = ctx->cword.encrypt.rounds; + ctx->cword.encrypt.ksize = (key_len - 16) / 8; + ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize; + /* Don't generate extended keys if the hardware can do it. */ if (aes_hw_extkey_available(key_len)) return 0; + ctx->D = ctx->d_data; + ctx->cword.encrypt.keygen = 1; + ctx->cword.decrypt.keygen = 1; + switch (key_len) { case 16: t = E_KEY[3]; @@ -370,9 +391,8 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t /* ====== Encryption/decryption routines ====== */ /* This is the real call to PadLock. */ -static inline void -padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key, - void *control_word, uint32_t count) +static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, + void *control_word, u32 count) { asm volatile ("pushfl; popfl"); /* enforce key reload. */ asm volatile (".byte 0xf3,0x0f,0xa7,0xc8" /* rep xcryptecb */ @@ -381,66 +401,26 @@ padlock_xcrypt_ecb(uint8_t *input, uint8_t *output, uint8_t *key, } static void -aes_padlock(void *ctx_arg, uint8_t *out_arg, const uint8_t *in_arg, int encdec) -{ - /* Don't blindly modify this structure - the items must - fit on 16-Bytes boundaries! */ - struct padlock_xcrypt_data { - uint8_t buf[AES_BLOCK_SIZE]; - union cword cword; - }; - - struct aes_ctx *ctx = ctx_arg; - char bigbuf[sizeof(struct padlock_xcrypt_data) + 16]; - struct padlock_xcrypt_data *data; - void *key; - - /* Place 'data' at the first 16-Bytes aligned address in 'bigbuf'. */ - if (((long)bigbuf) & 0x0F) - data = (void*)(bigbuf + 16 - ((long)bigbuf & 0x0F)); - else - data = (void*)bigbuf; - - /* Prepare Control word. */ - memset (data, 0, sizeof(struct padlock_xcrypt_data)); - data->cword.b.encdec = !encdec; /* in the rest of cryptoapi ENC=1/DEC=0 */ - data->cword.b.rounds = 10 + (ctx->key_length - 16) / 4; - data->cword.b.ksize = (ctx->key_length - 16) / 8; - - /* Is the hardware capable to generate the extended key? */ - if (!aes_hw_extkey_available(ctx->key_length)) - data->cword.b.keygen = 1; - - /* ctx->E starts with a plain key - if the hardware is capable - to generate the extended key itself we must supply - the plain key for both Encryption and Decryption. */ - if (encdec == CRYPTO_DIR_ENCRYPT || data->cword.b.keygen == 0) - key = ctx->E; - else - key = ctx->D; - - memcpy(data->buf, in_arg, AES_BLOCK_SIZE); - padlock_xcrypt_ecb(data->buf, data->buf, key, &data->cword, 1); - memcpy(out_arg, data->buf, AES_BLOCK_SIZE); -} - -static void aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { - aes_padlock(ctx_arg, out, in, CRYPTO_DIR_ENCRYPT); + struct aes_ctx *ctx = aes_ctx(ctx_arg); + padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, 1); } static void aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { - aes_padlock(ctx_arg, out, in, CRYPTO_DIR_DECRYPT); + struct aes_ctx *ctx = aes_ctx(ctx_arg); + padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); } static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct aes_ctx), + .cra_ctxsize = sizeof(struct aes_ctx) + + PADLOCK_ALIGNMENT, + .cra_alignmask = PADLOCK_ALIGNMENT - 1, .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), .cra_u = { diff --git a/drivers/crypto/padlock.h b/drivers/crypto/padlock.h index 7a50060..3cf2b7a 100644 --- a/drivers/crypto/padlock.h +++ b/drivers/crypto/padlock.h @@ -13,18 +13,18 @@ #ifndef _CRYPTO_PADLOCK_H #define _CRYPTO_PADLOCK_H +#define PADLOCK_ALIGNMENT 16 + /* Control word. */ -union cword { - uint32_t cword[4]; - struct { - int rounds:4; - int algo:3; - int keygen:1; - int interm:1; - int encdec:1; - int ksize:2; - } b; -}; +struct cword { + int __attribute__ ((__packed__)) + rounds:4, + algo:3, + keygen:1, + interm:1, + encdec:1, + ksize:2; +} __attribute__ ((__aligned__(PADLOCK_ALIGNMENT))); #define PFX "padlock: " -- cgit v1.1 From 28e8c3ad9464de54a632f00ab3df88fa5f4652d1 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:52:43 -0700 Subject: [PADLOCK] Implement multi-block operations By operating on multiple blocks at once, we expect to extract more performance out of the VIA Padlock. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/crypto/padlock-aes.c | 55 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 5f28909..d2745ff 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -390,7 +390,7 @@ aes_set_key(void *ctx_arg, const uint8_t *in_key, unsigned int key_len, uint32_t /* ====== Encryption/decryption routines ====== */ -/* This is the real call to PadLock. */ +/* These are the real call to PadLock. */ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, void *control_word, u32 count) { @@ -400,6 +400,17 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, : "d"(control_word), "b"(key), "c"(count)); } +static inline void padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, + u8 *iv, void *control_word, u32 count) +{ + /* Enforce key reload. */ + asm volatile ("pushfl; popfl"); + /* rep xcryptcbc */ + asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" + : "+S" (input), "+D" (output), "+a" (iv) + : "d" (control_word), "b" (key), "c" (count)); +} + static void aes_encrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) { @@ -414,6 +425,42 @@ aes_decrypt(void *ctx_arg, uint8_t *out, const uint8_t *in) padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, 1); } +static unsigned int aes_encrypt_ecb(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_ecb(in, out, ctx->E, &ctx->cword.encrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + +static unsigned int aes_decrypt_ecb(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_ecb(in, out, ctx->D, &ctx->cword.decrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + +static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_cbc(in, out, ctx->E, desc->info, &ctx->cword.encrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + +static unsigned int aes_decrypt_cbc(const struct cipher_desc *desc, u8 *out, + const u8 *in, unsigned int nbytes) +{ + struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); + padlock_xcrypt_cbc(in, out, ctx->D, desc->info, &ctx->cword.decrypt, + nbytes / AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); +} + static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_flags = CRYPTO_ALG_TYPE_CIPHER, @@ -429,7 +476,11 @@ static struct crypto_alg aes_alg = { .cia_max_keysize = AES_MAX_KEY_SIZE, .cia_setkey = aes_set_key, .cia_encrypt = aes_encrypt, - .cia_decrypt = aes_decrypt + .cia_decrypt = aes_decrypt, + .cia_encrypt_ecb = aes_encrypt_ecb, + .cia_decrypt_ecb = aes_decrypt_ecb, + .cia_encrypt_cbc = aes_encrypt_cbc, + .cia_decrypt_cbc = aes_decrypt_cbc, } } }; -- cgit v1.1 From 176c3652c544b6f8d4bb1984c58c10080f45dbf0 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 6 Jul 2005 13:53:09 -0700 Subject: [CRYPTO] Make crypto_alg_lookup static This patch makes a needlessly global function static. Signed-off-by: Adrian Bunk Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/api.c | 10 +++++++++- crypto/internal.h | 10 ---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/crypto/api.c b/crypto/api.c index f55856b..0b583d2 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include "internal.h" @@ -33,7 +34,7 @@ static inline void crypto_alg_put(struct crypto_alg *alg) module_put(alg->cra_module); } -struct crypto_alg *crypto_alg_lookup(const char *name) +static struct crypto_alg *crypto_alg_lookup(const char *name) { struct crypto_alg *q, *alg = NULL; @@ -54,6 +55,13 @@ struct crypto_alg *crypto_alg_lookup(const char *name) return alg; } +/* A far more intelligent version of this is planned. For now, just + * try an exact match on the name of the algorithm. */ +static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) +{ + return try_then_request_module(crypto_alg_lookup(name), name); +} + static int crypto_init_flags(struct crypto_tfm *tfm, u32 flags) { tfm->crt_flags = 0; diff --git a/crypto/internal.h b/crypto/internal.h index 5ed383f..83b1b6d 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -16,7 +16,6 @@ #include #include #include -#include #include extern enum km_type crypto_km_types[]; @@ -42,15 +41,6 @@ static inline void crypto_yield(struct crypto_tfm *tfm) cond_resched(); } -struct crypto_alg *crypto_alg_lookup(const char *name); - -/* A far more intelligent version of this is planned. For now, just - * try an exact match on the name of the algorithm. */ -static inline struct crypto_alg *crypto_alg_mod_lookup(const char *name) -{ - return try_then_request_module(crypto_alg_lookup(name), name); -} - #ifdef CONFIG_CRYPTO_HMAC int crypto_alloc_hmac_block(struct crypto_tfm *tfm); void crypto_free_hmac_block(struct crypto_tfm *tfm); -- cgit v1.1 From fbdae9f3e7fb57c07cb0d973f113eb25da2e8ff2 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:53:29 -0700 Subject: [CRYPTO] Ensure cit_iv is aligned correctly This patch ensures that cit_iv is aligned according to cra_alignmask by allocating it as part of the tfm structure. As a side effect the crypto layer will also guarantee that the tfm ctx area has enough space to be aligned by cra_alignmask. This allows us to remove the extra space reservation from the Padlock driver. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/api.c | 32 +++++++++++++++++++++++++++++--- crypto/cipher.c | 15 +++++++++------ crypto/internal.h | 28 ++++++++++++++++++++++++++++ drivers/crypto/padlock-aes.c | 3 +-- include/linux/crypto.h | 5 +++++ 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/crypto/api.c b/crypto/api.c index 0b583d2..2d8d828 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -125,20 +125,46 @@ static void crypto_exit_ops(struct crypto_tfm *tfm) } } +static unsigned int crypto_ctxsize(struct crypto_alg *alg, int flags) +{ + unsigned int len; + + switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { + default: + BUG(); + + case CRYPTO_ALG_TYPE_CIPHER: + len = crypto_cipher_ctxsize(alg, flags); + break; + + case CRYPTO_ALG_TYPE_DIGEST: + len = crypto_digest_ctxsize(alg, flags); + break; + + case CRYPTO_ALG_TYPE_COMPRESS: + len = crypto_compress_ctxsize(alg, flags); + break; + } + + return len + alg->cra_alignmask; +} + struct crypto_tfm *crypto_alloc_tfm(const char *name, u32 flags) { struct crypto_tfm *tfm = NULL; struct crypto_alg *alg; + unsigned int tfm_size; alg = crypto_alg_mod_lookup(name); if (alg == NULL) goto out; - - tfm = kmalloc(sizeof(*tfm) + alg->cra_ctxsize, GFP_KERNEL); + + tfm_size = sizeof(*tfm) + crypto_ctxsize(alg, flags); + tfm = kmalloc(tfm_size, GFP_KERNEL); if (tfm == NULL) goto out_put; - memset(tfm, 0, sizeof(*tfm) + alg->cra_ctxsize); + memset(tfm, 0, tfm_size); tfm->__crt_alg = alg; diff --git a/crypto/cipher.c b/crypto/cipher.c index 85eb12f..d3295ce 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -41,7 +41,7 @@ static unsigned int crypt_slow(const struct cipher_desc *desc, struct scatter_walk *in, struct scatter_walk *out, unsigned int bsize) { - unsigned int alignmask = desc->tfm->__crt_alg->cra_alignmask; + unsigned int alignmask = crypto_tfm_alg_alignmask(desc->tfm); u8 buffer[bsize * 2 + alignmask]; u8 *src = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); u8 *dst = src + bsize; @@ -98,7 +98,7 @@ static int crypt(const struct cipher_desc *desc, struct scatter_walk walk_in, walk_out; struct crypto_tfm *tfm = desc->tfm; const unsigned int bsize = crypto_tfm_alg_blocksize(tfm); - unsigned int alignmask = tfm->__crt_alg->cra_alignmask; + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); unsigned long buffer = 0; if (!nbytes) @@ -399,6 +399,8 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) } if (ops->cit_mode == CRYPTO_TFM_MODE_CBC) { + unsigned int align; + unsigned long addr; switch (crypto_tfm_alg_blocksize(tfm)) { case 8: @@ -418,9 +420,11 @@ int crypto_init_cipher_ops(struct crypto_tfm *tfm) } ops->cit_ivsize = crypto_tfm_alg_blocksize(tfm); - ops->cit_iv = kmalloc(ops->cit_ivsize, GFP_KERNEL); - if (ops->cit_iv == NULL) - ret = -ENOMEM; + align = crypto_tfm_alg_alignmask(tfm) + 1; + addr = (unsigned long)crypto_tfm_ctx(tfm); + addr = ALIGN(addr, align); + addr += ALIGN(tfm->__crt_alg->cra_ctxsize, align); + ops->cit_iv = (void *)addr; } out: @@ -429,5 +433,4 @@ out: void crypto_exit_cipher_ops(struct crypto_tfm *tfm) { - kfree(tfm->crt_cipher.cit_iv); } diff --git a/crypto/internal.h b/crypto/internal.h index 83b1b6d..6861287 100644 --- a/crypto/internal.h +++ b/crypto/internal.h @@ -16,6 +16,7 @@ #include #include #include +#include #include extern enum km_type crypto_km_types[]; @@ -61,6 +62,33 @@ static inline void crypto_init_proc(void) { } #endif +static inline unsigned int crypto_digest_ctxsize(struct crypto_alg *alg, + int flags) +{ + return alg->cra_ctxsize; +} + +static inline unsigned int crypto_cipher_ctxsize(struct crypto_alg *alg, + int flags) +{ + unsigned int len = alg->cra_ctxsize; + + switch (flags & CRYPTO_TFM_MODE_MASK) { + case CRYPTO_TFM_MODE_CBC: + len = ALIGN(len, alg->cra_alignmask + 1); + len += alg->cra_blocksize; + break; + } + + return len; +} + +static inline unsigned int crypto_compress_ctxsize(struct crypto_alg *alg, + int flags) +{ + return alg->cra_ctxsize; +} + int crypto_init_digest_flags(struct crypto_tfm *tfm, u32 flags); int crypto_init_cipher_flags(struct crypto_tfm *tfm, u32 flags); int crypto_init_compress_flags(struct crypto_tfm *tfm, u32 flags); diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index d2745ff..c5b58fa 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -465,8 +465,7 @@ static struct crypto_alg aes_alg = { .cra_name = "aes", .cra_flags = CRYPTO_ALG_TYPE_CIPHER, .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct aes_ctx) + - PADLOCK_ALIGNMENT, + .cra_ctxsize = sizeof(struct aes_ctx), .cra_alignmask = PADLOCK_ALIGNMENT - 1, .cra_module = THIS_MODULE, .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), diff --git a/include/linux/crypto.h b/include/linux/crypto.h index ac9d49b..5e2bcc6 100644 --- a/include/linux/crypto.h +++ b/include/linux/crypto.h @@ -288,6 +288,11 @@ static inline unsigned int crypto_tfm_alg_digestsize(struct crypto_tfm *tfm) return tfm->__crt_alg->cra_digest.dia_digestsize; } +static inline unsigned int crypto_tfm_alg_alignmask(struct crypto_tfm *tfm) +{ + return tfm->__crt_alg->cra_alignmask; +} + static inline void *crypto_tfm_ctx(struct crypto_tfm *tfm) { return (void *)&tfm[1]; -- cgit v1.1 From 915e8561d559abba1b81934e31e54a3f850fa7bf Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:53:47 -0700 Subject: [CRYPTO] Handle unaligned iv from encrypt_iv/decrypt_iv Even though cit_iv is now always aligned, the user can still supply an unaligned iv through crypto_cipher_encrypt_iv/crypto_cipher_decrypt_iv. This patch will check the alignment of the user-supplied iv and copy it if necessary. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/cipher.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/crypto/cipher.c b/crypto/cipher.c index d3295ce..1c92c6b 100644 --- a/crypto/cipher.c +++ b/crypto/cipher.c @@ -154,6 +154,31 @@ static int crypt(const struct cipher_desc *desc, return 0; } +static int crypt_iv_unaligned(struct cipher_desc *desc, + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) +{ + struct crypto_tfm *tfm = desc->tfm; + unsigned int alignmask = crypto_tfm_alg_alignmask(tfm); + u8 *iv = desc->info; + + if (unlikely(((unsigned long)iv & alignmask))) { + unsigned int ivsize = tfm->crt_cipher.cit_ivsize; + u8 buffer[ivsize + alignmask]; + u8 *tmp = (u8 *)ALIGN((unsigned long)buffer, alignmask + 1); + int err; + + desc->info = memcpy(tmp, iv, ivsize); + err = crypt(desc, dst, src, nbytes); + memcpy(iv, tmp, ivsize); + + return err; + } + + return crypt(desc, dst, src, nbytes); +} + static unsigned int cbc_process_encrypt(const struct cipher_desc *desc, u8 *dst, const u8 *src, unsigned int nbytes) @@ -298,7 +323,7 @@ static int cbc_encrypt_iv(struct crypto_tfm *tfm, desc.prfn = cipher->cia_encrypt_cbc ?: cbc_process_encrypt; desc.info = iv; - return crypt(&desc, dst, src, nbytes); + return crypt_iv_unaligned(&desc, dst, src, nbytes); } static int cbc_decrypt(struct crypto_tfm *tfm, @@ -330,7 +355,7 @@ static int cbc_decrypt_iv(struct crypto_tfm *tfm, desc.prfn = cipher->cia_decrypt_cbc ?: cbc_process_decrypt; desc.info = iv; - return crypt(&desc, dst, src, nbytes); + return crypt_iv_unaligned(&desc, dst, src, nbytes); } static int nocrypt(struct crypto_tfm *tfm, -- cgit v1.1 From 476df259cd577e20379b02a7f7ffd086ea925a83 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:54:09 -0700 Subject: [CRYPTO] Update IV correctly for Padlock CBC encryption When the Padlock does CBC encryption, the memory pointed to by EAX is not updated at all. Instead, it updates the value of EAX by pointing it to the last block in the output. Therefore to maintain the correct semantics we need to copy the IV. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/crypto/padlock-aes.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index c5b58fa..71407c5 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c @@ -400,8 +400,8 @@ static inline void padlock_xcrypt_ecb(const u8 *input, u8 *output, void *key, : "d"(control_word), "b"(key), "c"(count)); } -static inline void padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, - u8 *iv, void *control_word, u32 count) +static inline u8 *padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, + u8 *iv, void *control_word, u32 count) { /* Enforce key reload. */ asm volatile ("pushfl; popfl"); @@ -409,6 +409,7 @@ static inline void padlock_xcrypt_cbc(const u8 *input, u8 *output, void *key, asm volatile (".byte 0xf3,0x0f,0xa7,0xd0" : "+S" (input), "+D" (output), "+a" (iv) : "d" (control_word), "b" (key), "c" (count)); + return iv; } static void @@ -447,8 +448,12 @@ static unsigned int aes_encrypt_cbc(const struct cipher_desc *desc, u8 *out, const u8 *in, unsigned int nbytes) { struct aes_ctx *ctx = aes_ctx(crypto_tfm_ctx(desc->tfm)); - padlock_xcrypt_cbc(in, out, ctx->E, desc->info, &ctx->cword.encrypt, - nbytes / AES_BLOCK_SIZE); + u8 *iv; + + iv = padlock_xcrypt_cbc(in, out, ctx->E, desc->info, + &ctx->cword.encrypt, nbytes / AES_BLOCK_SIZE); + memcpy(desc->info, iv, AES_BLOCK_SIZE); + return nbytes & ~(AES_BLOCK_SIZE - 1); } -- cgit v1.1 From a61cc44812ff94793987bf43b70a3d9bc64a6820 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 6 Jul 2005 13:54:31 -0700 Subject: [CRYPTO] Add null short circuit to crypto_free_tfm As far as I'm aware there's a general concensus that functions that are responsible for freeing resources should be able to cope with being passed a NULL pointer. This makes sense as it removes the need for all callers to check for NULL, thus elliminating the bugs that happen when some forget (safer to just check centrally in the freeing function) and it also makes for smaller code all over due to the lack of all those NULL checks. This patch makes it safe to pass the crypto_free_tfm() function a NULL pointer. Once this patch is applied we can start removing the NULL checks from the callers. Signed-off-by: Jesper Juhl Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/api.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/crypto/api.c b/crypto/api.c index 2d8d828..b472881 100644 --- a/crypto/api.c +++ b/crypto/api.c @@ -13,6 +13,8 @@ * any later version. * */ + +#include #include #include #include @@ -189,8 +191,14 @@ out: void crypto_free_tfm(struct crypto_tfm *tfm) { - struct crypto_alg *alg = tfm->__crt_alg; - int size = sizeof(*tfm) + alg->cra_ctxsize; + struct crypto_alg *alg; + int size; + + if (unlikely(!tfm)) + return; + + alg = tfm->__crt_alg; + size = sizeof(*tfm) + alg->cra_ctxsize; crypto_exit_ops(tfm); crypto_alg_put(alg); -- cgit v1.1 From a2a892a236d03a6e985471a7e57d1c863de144c8 Mon Sep 17 00:00:00 2001 From: Andreas Steinmetz Date: Wed, 6 Jul 2005 13:55:00 -0700 Subject: [CRYPTO] Add x86_64 asm AES Implementation: =============== The encrypt/decrypt code is based on an x86 implementation I did a while ago which I never published. This unpublished implementation does include an assembler based key schedule and precomputed tables. For simplicity and best acceptance, however, I took Gladman's in-kernel code for table generation and key schedule for the kernel port of my assembler code and modified this code to produce the key schedule as required by my assembler implementation. File locations and Kconfig are kept similar to the i586 AES assembler implementation. It may seem a little bit strange to use 32 bit I/O and registers in the assembler implementation but this gives the best code size. My implementation takes one instruction more per round compared to Gladman's x86 assembler but it doesn't require any stack for local variables or saved registers and it is less serialized than Gladman's code. Note that all comparisons to Gladman's code were done after my code was implemented. I did only use FIPS PUB 197 for the implementation so my implementation is independent work. If anybody has a better assembler solution for x86_64 I'll be pleased to have my code replaced with the better solution. Testing: ======== The implementation passes the in-kernel crypto testing module and I'm running it without any problems on my laptop where it is mainly used for dm-crypt. Microbenchmark: =============== The microbenchmark was done in userspace with similar compile flags as used during kernel compile. Encrypt/decrypt is about 35% faster than the generic C implementation. As the generic C as well as my assembler implementation are both table I don't really expect that there is much room for further improvements though I'll be glad to be corrected here. The key schedule is about 5% slower than the generic C implementation. This is due to the fact that some more work has to be done in the key schedule routine to fit the schedule to the assembler implementation. Code Size: ========== Encrypt and decrypt are together about 2.1 Kbytes smaller than the generic C implementation which is important with regard to L1 cache usage. The key schedule routine is about 100 bytes larger than the generic C implementation. Data Size: ========== There's no difference in data size requirements between the assembler implementation and the generic C implementation. License: ======== Gladmans's code is dual BSD/GPL whereas my assembler code is GPLv2 only (I'm not going to change the license for my code). So I had to change the module license for the x86_64 aes module from 'Dual BSD/GPL' to 'GPL' to reflect the most restrictive license within the module. Signed-off-by: Andreas Steinmetz Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- arch/x86_64/Makefile | 4 +- arch/x86_64/crypto/Makefile | 9 + arch/x86_64/crypto/aes-x86_64-asm.S | 186 +++++++++++++++++++++ arch/x86_64/crypto/aes.c | 324 ++++++++++++++++++++++++++++++++++++ crypto/Kconfig | 22 ++- 5 files changed, 543 insertions(+), 2 deletions(-) create mode 100644 arch/x86_64/crypto/Makefile create mode 100644 arch/x86_64/crypto/aes-x86_64-asm.S create mode 100644 arch/x86_64/crypto/aes.c diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile index 8a73794..4289156 100644 --- a/arch/x86_64/Makefile +++ b/arch/x86_64/Makefile @@ -65,7 +65,9 @@ CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,) head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o libs-y += arch/x86_64/lib/ -core-y += arch/x86_64/kernel/ arch/x86_64/mm/ +core-y += arch/x86_64/kernel/ \ + arch/x86_64/mm/ \ + arch/x86_64/crypto/ core-$(CONFIG_IA32_EMULATION) += arch/x86_64/ia32/ drivers-$(CONFIG_PCI) += arch/x86_64/pci/ drivers-$(CONFIG_OPROFILE) += arch/x86_64/oprofile/ diff --git a/arch/x86_64/crypto/Makefile b/arch/x86_64/crypto/Makefile new file mode 100644 index 0000000..426d20f --- /dev/null +++ b/arch/x86_64/crypto/Makefile @@ -0,0 +1,9 @@ +# +# x86_64/crypto/Makefile +# +# Arch-specific CryptoAPI modules. +# + +obj-$(CONFIG_CRYPTO_AES_X86_64) += aes-x86_64.o + +aes-x86_64-y := aes-x86_64-asm.o aes.o diff --git a/arch/x86_64/crypto/aes-x86_64-asm.S b/arch/x86_64/crypto/aes-x86_64-asm.S new file mode 100644 index 0000000..483cbb2 --- /dev/null +++ b/arch/x86_64/crypto/aes-x86_64-asm.S @@ -0,0 +1,186 @@ +/* AES (Rijndael) implementation (FIPS PUB 197) for x86_64 + * + * Copyright (C) 2005 Andreas Steinmetz, + * + * License: + * This code can be distributed under the terms of the GNU General Public + * License (GPL) Version 2 provided that the above header down to and + * including this sentence is retained in full. + */ + +.extern aes_ft_tab +.extern aes_it_tab +.extern aes_fl_tab +.extern aes_il_tab + +.text + +#define R1 %rax +#define R1E %eax +#define R1X %ax +#define R1H %ah +#define R1L %al +#define R2 %rbx +#define R2E %ebx +#define R2X %bx +#define R2H %bh +#define R2L %bl +#define R3 %rcx +#define R3E %ecx +#define R3X %cx +#define R3H %ch +#define R3L %cl +#define R4 %rdx +#define R4E %edx +#define R4X %dx +#define R4H %dh +#define R4L %dl +#define R5 %rsi +#define R5E %esi +#define R6 %rdi +#define R6E %edi +#define R7 %rbp +#define R7E %ebp +#define R8 %r8 +#define R9 %r9 +#define R10 %r10 +#define R11 %r11 + +#define prologue(FUNC,BASE,B128,B192,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11) \ + .global FUNC; \ + .type FUNC,@function; \ + .align 8; \ +FUNC: movq r1,r2; \ + movq r3,r4; \ + leaq BASE+52(r8),r9; \ + movq r10,r11; \ + movl (r7),r5 ## E; \ + movl 4(r7),r1 ## E; \ + movl 8(r7),r6 ## E; \ + movl 12(r7),r7 ## E; \ + movl (r8),r10 ## E; \ + xorl -48(r9),r5 ## E; \ + xorl -44(r9),r1 ## E; \ + xorl -40(r9),r6 ## E; \ + xorl -36(r9),r7 ## E; \ + cmpl $24,r10 ## E; \ + jb B128; \ + leaq 32(r9),r9; \ + je B192; \ + leaq 32(r9),r9; + +#define epilogue(r1,r2,r3,r4,r5,r6,r7,r8,r9) \ + movq r1,r2; \ + movq r3,r4; \ + movl r5 ## E,(r9); \ + movl r6 ## E,4(r9); \ + movl r7 ## E,8(r9); \ + movl r8 ## E,12(r9); \ + ret; + +#define round(TAB,OFFSET,r1,r2,r3,r4,r5,r6,r7,r8,ra,rb,rc,rd) \ + movzbl r2 ## H,r5 ## E; \ + movzbl r2 ## L,r6 ## E; \ + movl TAB+1024(,r5,4),r5 ## E;\ + movw r4 ## X,r2 ## X; \ + movl TAB(,r6,4),r6 ## E; \ + roll $16,r2 ## E; \ + shrl $16,r4 ## E; \ + movzbl r4 ## H,r7 ## E; \ + movzbl r4 ## L,r4 ## E; \ + xorl OFFSET(r8),ra ## E; \ + xorl OFFSET+4(r8),rb ## E; \ + xorl TAB+3072(,r7,4),r5 ## E;\ + xorl TAB+2048(,r4,4),r6 ## E;\ + movzbl r1 ## L,r7 ## E; \ + movzbl r1 ## H,r4 ## E; \ + movl TAB+1024(,r4,4),r4 ## E;\ + movw r3 ## X,r1 ## X; \ + roll $16,r1 ## E; \ + shrl $16,r3 ## E; \ + xorl TAB(,r7,4),r5 ## E; \ + movzbl r3 ## H,r7 ## E; \ + movzbl r3 ## L,r3 ## E; \ + xorl TAB+3072(,r7,4),r4 ## E;\ + xorl TAB+2048(,r3,4),r5 ## E;\ + movzbl r1 ## H,r7 ## E; \ + movzbl r1 ## L,r3 ## E; \ + shrl $16,r1 ## E; \ + xorl TAB+3072(,r7,4),r6 ## E;\ + movl TAB+2048(,r3,4),r3 ## E;\ + movzbl r1 ## H,r7 ## E; \ + movzbl r1 ## L,r1 ## E; \ + xorl TAB+1024(,r7,4),r6 ## E;\ + xorl TAB(,r1,4),r3 ## E; \ + movzbl r2 ## H,r1 ## E; \ + movzbl r2 ## L,r7 ## E; \ + shrl $16,r2 ## E; \ + xorl TAB+3072(,r1,4),r3 ## E;\ + xorl TAB+2048(,r7,4),r4 ## E;\ + movzbl r2 ## H,r1 ## E; \ + movzbl r2 ## L,r2 ## E; \ + xorl OFFSET+8(r8),rc ## E; \ + xorl OFFSET+12(r8),rd ## E; \ + xorl TAB+1024(,r1,4),r3 ## E;\ + xorl TAB(,r2,4),r4 ## E; + +#define move_regs(r1,r2,r3,r4) \ + movl r3 ## E,r1 ## E; \ + movl r4 ## E,r2 ## E; + +#define entry(FUNC,BASE,B128,B192) \ + prologue(FUNC,BASE,B128,B192,R2,R8,R7,R9,R1,R3,R4,R6,R10,R5,R11) + +#define return epilogue(R8,R2,R9,R7,R5,R6,R3,R4,R11) + +#define encrypt_round(TAB,OFFSET) \ + round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) \ + move_regs(R1,R2,R5,R6) + +#define encrypt_final(TAB,OFFSET) \ + round(TAB,OFFSET,R1,R2,R3,R4,R5,R6,R7,R10,R5,R6,R3,R4) + +#define decrypt_round(TAB,OFFSET) \ + round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) \ + move_regs(R1,R2,R5,R6) + +#define decrypt_final(TAB,OFFSET) \ + round(TAB,OFFSET,R2,R1,R4,R3,R6,R5,R7,R10,R5,R6,R3,R4) + +/* void aes_encrypt(void *ctx, u8 *out, const u8 *in) */ + + entry(aes_encrypt,0,enc128,enc192) + encrypt_round(aes_ft_tab,-96) + encrypt_round(aes_ft_tab,-80) +enc192: encrypt_round(aes_ft_tab,-64) + encrypt_round(aes_ft_tab,-48) +enc128: encrypt_round(aes_ft_tab,-32) + encrypt_round(aes_ft_tab,-16) + encrypt_round(aes_ft_tab, 0) + encrypt_round(aes_ft_tab, 16) + encrypt_round(aes_ft_tab, 32) + encrypt_round(aes_ft_tab, 48) + encrypt_round(aes_ft_tab, 64) + encrypt_round(aes_ft_tab, 80) + encrypt_round(aes_ft_tab, 96) + encrypt_final(aes_fl_tab,112) + return + +/* void aes_decrypt(void *ctx, u8 *out, const u8 *in) */ + + entry(aes_decrypt,240,dec128,dec192) + decrypt_round(aes_it_tab,-96) + decrypt_round(aes_it_tab,-80) +dec192: decrypt_round(aes_it_tab,-64) + decrypt_round(aes_it_tab,-48) +dec128: decrypt_round(aes_it_tab,-32) + decrypt_round(aes_it_tab,-16) + decrypt_round(aes_it_tab, 0) + decrypt_round(aes_it_tab, 16) + decrypt_round(aes_it_tab, 32) + decrypt_round(aes_it_tab, 48) + decrypt_round(aes_it_tab, 64) + decrypt_round(aes_it_tab, 80) + decrypt_round(aes_it_tab, 96) + decrypt_final(aes_il_tab,112) + return diff --git a/arch/x86_64/crypto/aes.c b/arch/x86_64/crypto/aes.c new file mode 100644 index 0000000..2b5c401 --- /dev/null +++ b/arch/x86_64/crypto/aes.c @@ -0,0 +1,324 @@ +/* + * Cryptographic API. + * + * AES Cipher Algorithm. + * + * Based on Brian Gladman's code. + * + * Linux developers: + * Alexander Kjeldaas + * Herbert Valerio Riedel + * Kyle McMartin + * Adam J. Richter (conversion to 2.5 API). + * Andreas Steinmetz (adapted to x86_64 assembler) + * + * 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. + * + * --------------------------------------------------------------------------- + * Copyright (c) 2002, Dr Brian Gladman , Worcester, UK. + * All rights reserved. + * + * LICENSE TERMS + * + * The free distribution and use of this software in both source and binary + * form is allowed (with or without changes) provided that: + * + * 1. distributions of this source code include the above copyright + * notice, this list of conditions and the following disclaimer; + * + * 2. distributions in binary form include the above copyright + * notice, this list of conditions and the following disclaimer + * in the documentation and/or other associated materials; + * + * 3. the copyright holder's name is not used to endorse products + * built using this software without specific written permission. + * + * ALTERNATIVELY, provided that this notice is retained in full, this product + * may be distributed under the terms of the GNU General Public License (GPL), + * in which case the provisions of the GPL apply INSTEAD OF those given above. + * + * DISCLAIMER + * + * This software is provided 'as is' with no explicit or implied warranties + * in respect of its properties, including, but not limited to, correctness + * and/or fitness for purpose. + * --------------------------------------------------------------------------- + */ + +/* Some changes from the Gladman version: + s/RIJNDAEL(e_key)/E_KEY/g + s/RIJNDAEL(d_key)/D_KEY/g +*/ + +#include +#include +#include +#include +#include +#include +#include + +#define AES_MIN_KEY_SIZE 16 +#define AES_MAX_KEY_SIZE 32 + +#define AES_BLOCK_SIZE 16 + +/* + * #define byte(x, nr) ((unsigned char)((x) >> (nr*8))) + */ +static inline u8 byte(const u32 x, const unsigned n) +{ + return x >> (n << 3); +} + +#define u32_in(x) le32_to_cpu(*(const __le32 *)(x)) + +struct aes_ctx +{ + u32 key_length; + u32 E[60]; + u32 D[60]; +}; + +#define E_KEY ctx->E +#define D_KEY ctx->D + +static u8 pow_tab[256] __initdata; +static u8 log_tab[256] __initdata; +static u8 sbx_tab[256] __initdata; +static u8 isb_tab[256] __initdata; +static u32 rco_tab[10]; +u32 aes_ft_tab[4][256]; +u32 aes_it_tab[4][256]; + +u32 aes_fl_tab[4][256]; +u32 aes_il_tab[4][256]; + +static inline u8 f_mult(u8 a, u8 b) +{ + u8 aa = log_tab[a], cc = aa + log_tab[b]; + + return pow_tab[cc + (cc < aa ? 1 : 0)]; +} + +#define ff_mult(a, b) (a && b ? f_mult(a, b) : 0) + +#define ls_box(x) \ + (aes_fl_tab[0][byte(x, 0)] ^ \ + aes_fl_tab[1][byte(x, 1)] ^ \ + aes_fl_tab[2][byte(x, 2)] ^ \ + aes_fl_tab[3][byte(x, 3)]) + +static void __init gen_tabs(void) +{ + u32 i, t; + u8 p, q; + + /* log and power tables for GF(2**8) finite field with + 0x011b as modular polynomial - the simplest primitive + root is 0x03, used here to generate the tables */ + + for (i = 0, p = 1; i < 256; ++i) { + pow_tab[i] = (u8)p; + log_tab[p] = (u8)i; + + p ^= (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + log_tab[1] = 0; + + for (i = 0, p = 1; i < 10; ++i) { + rco_tab[i] = p; + + p = (p << 1) ^ (p & 0x80 ? 0x01b : 0); + } + + for (i = 0; i < 256; ++i) { + p = (i ? pow_tab[255 - log_tab[i]] : 0); + q = ((p >> 7) | (p << 1)) ^ ((p >> 6) | (p << 2)); + p ^= 0x63 ^ q ^ ((q >> 6) | (q << 2)); + sbx_tab[i] = p; + isb_tab[p] = (u8)i; + } + + for (i = 0; i < 256; ++i) { + p = sbx_tab[i]; + + t = p; + aes_fl_tab[0][i] = t; + aes_fl_tab[1][i] = rol32(t, 8); + aes_fl_tab[2][i] = rol32(t, 16); + aes_fl_tab[3][i] = rol32(t, 24); + + t = ((u32)ff_mult(2, p)) | + ((u32)p << 8) | + ((u32)p << 16) | ((u32)ff_mult(3, p) << 24); + + aes_ft_tab[0][i] = t; + aes_ft_tab[1][i] = rol32(t, 8); + aes_ft_tab[2][i] = rol32(t, 16); + aes_ft_tab[3][i] = rol32(t, 24); + + p = isb_tab[i]; + + t = p; + aes_il_tab[0][i] = t; + aes_il_tab[1][i] = rol32(t, 8); + aes_il_tab[2][i] = rol32(t, 16); + aes_il_tab[3][i] = rol32(t, 24); + + t = ((u32)ff_mult(14, p)) | + ((u32)ff_mult(9, p) << 8) | + ((u32)ff_mult(13, p) << 16) | + ((u32)ff_mult(11, p) << 24); + + aes_it_tab[0][i] = t; + aes_it_tab[1][i] = rol32(t, 8); + aes_it_tab[2][i] = rol32(t, 16); + aes_it_tab[3][i] = rol32(t, 24); + } +} + +#define star_x(x) (((x) & 0x7f7f7f7f) << 1) ^ ((((x) & 0x80808080) >> 7) * 0x1b) + +#define imix_col(y, x) \ + u = star_x(x); \ + v = star_x(u); \ + w = star_x(v); \ + t = w ^ (x); \ + (y) = u ^ v ^ w; \ + (y) ^= ror32(u ^ t, 8) ^ \ + ror32(v ^ t, 16) ^ \ + ror32(t, 24) + +/* initialise the key schedule from the user supplied key */ + +#define loop4(i) \ +{ \ + t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[4 * i]; E_KEY[4 * i + 4] = t; \ + t ^= E_KEY[4 * i + 1]; E_KEY[4 * i + 5] = t; \ + t ^= E_KEY[4 * i + 2]; E_KEY[4 * i + 6] = t; \ + t ^= E_KEY[4 * i + 3]; E_KEY[4 * i + 7] = t; \ +} + +#define loop6(i) \ +{ \ + t = ror32(t, 8); t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[6 * i]; E_KEY[6 * i + 6] = t; \ + t ^= E_KEY[6 * i + 1]; E_KEY[6 * i + 7] = t; \ + t ^= E_KEY[6 * i + 2]; E_KEY[6 * i + 8] = t; \ + t ^= E_KEY[6 * i + 3]; E_KEY[6 * i + 9] = t; \ + t ^= E_KEY[6 * i + 4]; E_KEY[6 * i + 10] = t; \ + t ^= E_KEY[6 * i + 5]; E_KEY[6 * i + 11] = t; \ +} + +#define loop8(i) \ +{ \ + t = ror32(t, 8); ; t = ls_box(t) ^ rco_tab[i]; \ + t ^= E_KEY[8 * i]; E_KEY[8 * i + 8] = t; \ + t ^= E_KEY[8 * i + 1]; E_KEY[8 * i + 9] = t; \ + t ^= E_KEY[8 * i + 2]; E_KEY[8 * i + 10] = t; \ + t ^= E_KEY[8 * i + 3]; E_KEY[8 * i + 11] = t; \ + t = E_KEY[8 * i + 4] ^ ls_box(t); \ + E_KEY[8 * i + 12] = t; \ + t ^= E_KEY[8 * i + 5]; E_KEY[8 * i + 13] = t; \ + t ^= E_KEY[8 * i + 6]; E_KEY[8 * i + 14] = t; \ + t ^= E_KEY[8 * i + 7]; E_KEY[8 * i + 15] = t; \ +} + +static int aes_set_key(void *ctx_arg, const u8 *in_key, unsigned int key_len, + u32 *flags) +{ + struct aes_ctx *ctx = ctx_arg; + u32 i, j, t, u, v, w; + + if (key_len != 16 && key_len != 24 && key_len != 32) { + *flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + ctx->key_length = key_len; + + D_KEY[key_len + 24] = E_KEY[0] = u32_in(in_key); + D_KEY[key_len + 25] = E_KEY[1] = u32_in(in_key + 4); + D_KEY[key_len + 26] = E_KEY[2] = u32_in(in_key + 8); + D_KEY[key_len + 27] = E_KEY[3] = u32_in(in_key + 12); + + switch (key_len) { + case 16: + t = E_KEY[3]; + for (i = 0; i < 10; ++i) + loop4(i); + break; + + case 24: + E_KEY[4] = u32_in(in_key + 16); + t = E_KEY[5] = u32_in(in_key + 20); + for (i = 0; i < 8; ++i) + loop6 (i); + break; + + case 32: + E_KEY[4] = u32_in(in_key + 16); + E_KEY[5] = u32_in(in_key + 20); + E_KEY[6] = u32_in(in_key + 24); + t = E_KEY[7] = u32_in(in_key + 28); + for (i = 0; i < 7; ++i) + loop8(i); + break; + } + + D_KEY[0] = E_KEY[key_len + 24]; + D_KEY[1] = E_KEY[key_len + 25]; + D_KEY[2] = E_KEY[key_len + 26]; + D_KEY[3] = E_KEY[key_len + 27]; + + for (i = 4; i < key_len + 24; ++i) { + j = key_len + 24 - (i & ~3) + (i & 3); + imix_col(D_KEY[j], E_KEY[i]); + } + + return 0; +} + +extern void aes_encrypt(void *ctx_arg, u8 *out, const u8 *in); +extern void aes_decrypt(void *ctx_arg, u8 *out, const u8 *in); + +static struct crypto_alg aes_alg = { + .cra_name = "aes", + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct aes_ctx), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(aes_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_MIN_KEY_SIZE, + .cia_max_keysize = AES_MAX_KEY_SIZE, + .cia_setkey = aes_set_key, + .cia_encrypt = aes_encrypt, + .cia_decrypt = aes_decrypt + } + } +}; + +static int __init aes_init(void) +{ + gen_tabs(); + return crypto_register_alg(&aes_alg); +} + +static void __exit aes_fini(void) +{ + crypto_unregister_alg(&aes_alg); +} + +module_init(aes_init); +module_exit(aes_fini); + +MODULE_DESCRIPTION("Rijndael (AES) Cipher Algorithm"); +MODULE_LICENSE("GPL"); diff --git a/crypto/Kconfig b/crypto/Kconfig index 90d6089..256c0b1 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -146,7 +146,7 @@ config CRYPTO_SERPENT config CRYPTO_AES tristate "AES cipher algorithms" - depends on CRYPTO && !((X86 || UML_X86) && !64BIT) + depends on CRYPTO && !(X86 || UML_X86) help AES cipher algorithms (FIPS-197). AES uses the Rijndael algorithm. @@ -184,6 +184,26 @@ config CRYPTO_AES_586 See for more information. +config CRYPTO_AES_X86_64 + tristate "AES cipher algorithms (x86_64)" + depends on CRYPTO && ((X86 || UML_X86) && 64BIT) + help + AES cipher algorithms (FIPS-197). AES uses the Rijndael + algorithm. + + Rijndael appears to be consistently a very good performer in + both hardware and software across a wide range of computing + environments regardless of its use in feedback or non-feedback + modes. Its key setup time is excellent, and its key agility is + good. Rijndael's very low memory requirements make it very well + suited for restricted-space environments, in which it also + demonstrates excellent performance. Rijndael's operations are + among the easiest to defend against power and timing attacks. + + The AES specifies three key sizes: 128, 192 and 256 bits + + See for more information. + config CRYPTO_CAST5 tristate "CAST5 (CAST-128) cipher algorithm" depends on CRYPTO -- cgit v1.1 From a9df3597fec5472d0840fbfdc2a3fac5268f7d08 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Wed, 6 Jul 2005 13:55:21 -0700 Subject: [CRYPTO] Remove unused iv field from context structure The iv field in des_ctx/des3_ede_ctx/serpent_ctx has never been used. This was noticed by Dag Arne Osvik. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/des.c | 2 -- crypto/serpent.c | 1 - 2 files changed, 3 deletions(-) diff --git a/crypto/des.c b/crypto/des.c index 1c7e6de..fc5d1b6 100644 --- a/crypto/des.c +++ b/crypto/des.c @@ -38,12 +38,10 @@ #define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o)) struct des_ctx { - u8 iv[DES_BLOCK_SIZE]; u32 expkey[DES_EXPKEY_WORDS]; }; struct des3_ede_ctx { - u8 iv[DES_BLOCK_SIZE]; u32 expkey[DES3_EDE_EXPKEY_WORDS]; }; diff --git a/crypto/serpent.c b/crypto/serpent.c index 7d152e8..3cf2c50 100644 --- a/crypto/serpent.c +++ b/crypto/serpent.c @@ -210,7 +210,6 @@ x4 ^= x2; struct serpent_ctx { - u8 iv[SERPENT_BLOCK_SIZE]; u32 expkey[SERPENT_EXPKEY_WORDS]; }; -- cgit v1.1 From e1d5dea1dfbfe484358c40db7f233ed6b5605646 Mon Sep 17 00:00:00 2001 From: Dag Arne Osvik Date: Wed, 6 Jul 2005 13:55:44 -0700 Subject: [CRYPTO] Add faster DES code from Dag Arne Osvik I've made a new implementation of DES to replace the old one in the kernel. It provides faster encryption on all tested processors apart from the original Pentium, and key setup is many times faster. Speed relative to old kernel implementation Processor des_setkey des_encrypt des3_ede_setkey des3_ede_encrypt Pentium 120Mhz 6.8 0.82 7.2 0.86 Pentium III 1.266Ghz 5.6 1.19 5.8 1.34 Pentium M 1.3Ghz 5.7 1.15 6.0 1.31 Pentium 4 2.266Ghz 5.8 1.24 6.0 1.40 Pentium 4E 3Ghz 5.4 1.27 5.5 1.48 StrongARM 1110 206Mhz 4.3 1.03 4.4 1.14 Athlon XP 2Ghz 7.8 1.44 8.1 1.61 Athlon 64 2Ghz 7.8 1.34 8.3 1.49 Signed-off-by: Dag Arne Osvik Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- crypto/des.c | 2003 +++++++++++++++++++++++++--------------------------------- 1 file changed, 854 insertions(+), 1149 deletions(-) diff --git a/crypto/des.c b/crypto/des.c index fc5d1b6..a3c863d 100644 --- a/crypto/des.c +++ b/crypto/des.c @@ -1,18 +1,9 @@ -/* +/* * Cryptographic API. * * DES & Triple DES EDE Cipher Algorithms. * - * Originally released as descore by Dana L. How . - * Modified by Raimar Falke for the Linux-Kernel. - * Derived from Cryptoapi and Nettle implementations, adapted for in-place - * scatterlist interface. Changed LGPL to GPL per section 3 of the LGPL. - * - * Copyright (c) 1992 Dana L. How. - * Copyright (c) Raimar Falke - * Copyright (c) Gisle Sælensminde - * Copyright (C) 2001 Niels Möller. - * Copyright (c) 2002 James Morris + * Copyright (c) 2005 Dag Arne Osvik * * 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 @@ -20,11 +11,11 @@ * (at your option) any later version. * */ + +#include #include #include -#include #include -#include #include #define DES_KEY_SIZE 8 @@ -35,7 +26,8 @@ #define DES3_EDE_EXPKEY_WORDS (3 * DES_EXPKEY_WORDS) #define DES3_EDE_BLOCK_SIZE DES_BLOCK_SIZE -#define ROR(d,c,o) ((d) = (d) >> (c) | (d) << (o)) +#define ROL(x, r) ((x) = rol32((x), (r))) +#define ROR(x, r) ((x) = ror32((x), (r))) struct des_ctx { u32 expkey[DES_EXPKEY_WORDS]; @@ -45,1145 +37,815 @@ struct des3_ede_ctx { u32 expkey[DES3_EDE_EXPKEY_WORDS]; }; -static const u32 des_keymap[] = { - 0x02080008, 0x02082000, 0x00002008, 0x00000000, - 0x02002000, 0x00080008, 0x02080000, 0x02082008, - 0x00000008, 0x02000000, 0x00082000, 0x00002008, - 0x00082008, 0x02002008, 0x02000008, 0x02080000, - 0x00002000, 0x00082008, 0x00080008, 0x02002000, - 0x02082008, 0x02000008, 0x00000000, 0x00082000, - 0x02000000, 0x00080000, 0x02002008, 0x02080008, - 0x00080000, 0x00002000, 0x02082000, 0x00000008, - 0x00080000, 0x00002000, 0x02000008, 0x02082008, - 0x00002008, 0x02000000, 0x00000000, 0x00082000, - 0x02080008, 0x02002008, 0x02002000, 0x00080008, - 0x02082000, 0x00000008, 0x00080008, 0x02002000, - 0x02082008, 0x00080000, 0x02080000, 0x02000008, - 0x00082000, 0x00002008, 0x02002008, 0x02080000, - 0x00000008, 0x02082000, 0x00082008, 0x00000000, - 0x02000000, 0x02080008, 0x00002000, 0x00082008, - - 0x08000004, 0x00020004, 0x00000000, 0x08020200, - 0x00020004, 0x00000200, 0x08000204, 0x00020000, - 0x00000204, 0x08020204, 0x00020200, 0x08000000, - 0x08000200, 0x08000004, 0x08020000, 0x00020204, - 0x00020000, 0x08000204, 0x08020004, 0x00000000, - 0x00000200, 0x00000004, 0x08020200, 0x08020004, - 0x08020204, 0x08020000, 0x08000000, 0x00000204, - 0x00000004, 0x00020200, 0x00020204, 0x08000200, - 0x00000204, 0x08000000, 0x08000200, 0x00020204, - 0x08020200, 0x00020004, 0x00000000, 0x08000200, - 0x08000000, 0x00000200, 0x08020004, 0x00020000, - 0x00020004, 0x08020204, 0x00020200, 0x00000004, - 0x08020204, 0x00020200, 0x00020000, 0x08000204, - 0x08000004, 0x08020000, 0x00020204, 0x00000000, - 0x00000200, 0x08000004, 0x08000204, 0x08020200, - 0x08020000, 0x00000204, 0x00000004, 0x08020004, - - 0x80040100, 0x01000100, 0x80000000, 0x81040100, - 0x00000000, 0x01040000, 0x81000100, 0x80040000, - 0x01040100, 0x81000000, 0x01000000, 0x80000100, - 0x81000000, 0x80040100, 0x00040000, 0x01000000, - 0x81040000, 0x00040100, 0x00000100, 0x80000000, - 0x00040100, 0x81000100, 0x01040000, 0x00000100, - 0x80000100, 0x00000000, 0x80040000, 0x01040100, - 0x01000100, 0x81040000, 0x81040100, 0x00040000, - 0x81040000, 0x80000100, 0x00040000, 0x81000000, - 0x00040100, 0x01000100, 0x80000000, 0x01040000, - 0x81000100, 0x00000000, 0x00000100, 0x80040000, - 0x00000000, 0x81040000, 0x01040100, 0x00000100, - 0x01000000, 0x81040100, 0x80040100, 0x00040000, - 0x81040100, 0x80000000, 0x01000100, 0x80040100, - 0x80040000, 0x00040100, 0x01040000, 0x81000100, - 0x80000100, 0x01000000, 0x81000000, 0x01040100, - - 0x04010801, 0x00000000, 0x00010800, 0x04010000, - 0x04000001, 0x00000801, 0x04000800, 0x00010800, - 0x00000800, 0x04010001, 0x00000001, 0x04000800, - 0x00010001, 0x04010800, 0x04010000, 0x00000001, - 0x00010000, 0x04000801, 0x04010001, 0x00000800, - 0x00010801, 0x04000000, 0x00000000, 0x00010001, - 0x04000801, 0x00010801, 0x04010800, 0x04000001, - 0x04000000, 0x00010000, 0x00000801, 0x04010801, - 0x00010001, 0x04010800, 0x04000800, 0x00010801, - 0x04010801, 0x00010001, 0x04000001, 0x00000000, - 0x04000000, 0x00000801, 0x00010000, 0x04010001, - 0x00000800, 0x04000000, 0x00010801, 0x04000801, - 0x04010800, 0x00000800, 0x00000000, 0x04000001, - 0x00000001, 0x04010801, 0x00010800, 0x04010000, - 0x04010001, 0x00010000, 0x00000801, 0x04000800, - 0x04000801, 0x00000001, 0x04010000, 0x00010800, - - 0x00000400, 0x00000020, 0x00100020, 0x40100000, - 0x40100420, 0x40000400, 0x00000420, 0x00000000, - 0x00100000, 0x40100020, 0x40000020, 0x00100400, - 0x40000000, 0x00100420, 0x00100400, 0x40000020, - 0x40100020, 0x00000400, 0x40000400, 0x40100420, - 0x00000000, 0x00100020, 0x40100000, 0x00000420, - 0x40100400, 0x40000420, 0x00100420, 0x40000000, - 0x40000420, 0x40100400, 0x00000020, 0x00100000, - 0x40000420, 0x00100400, 0x40100400, 0x40000020, - 0x00000400, 0x00000020, 0x00100000, 0x40100400, - 0x40100020, 0x40000420, 0x00000420, 0x00000000, - 0x00000020, 0x40100000, 0x40000000, 0x00100020, - 0x00000000, 0x40100020, 0x00100020, 0x00000420, - 0x40000020, 0x00000400, 0x40100420, 0x00100000, - 0x00100420, 0x40000000, 0x40000400, 0x40100420, - 0x40100000, 0x00100420, 0x00100400, 0x40000400, - - 0x00800000, 0x00001000, 0x00000040, 0x00801042, - 0x00801002, 0x00800040, 0x00001042, 0x00801000, - 0x00001000, 0x00000002, 0x00800002, 0x00001040, - 0x00800042, 0x00801002, 0x00801040, 0x00000000, - 0x00001040, 0x00800000, 0x00001002, 0x00000042, - 0x00800040, 0x00001042, 0x00000000, 0x00800002, - 0x00000002, 0x00800042, 0x00801042, 0x00001002, - 0x00801000, 0x00000040, 0x00000042, 0x00801040, - 0x00801040, 0x00800042, 0x00001002, 0x00801000, - 0x00001000, 0x00000002, 0x00800002, 0x00800040, - 0x00800000, 0x00001040, 0x00801042, 0x00000000, - 0x00001042, 0x00800000, 0x00000040, 0x00001002, - 0x00800042, 0x00000040, 0x00000000, 0x00801042, - 0x00801002, 0x00801040, 0x00000042, 0x00001000, - 0x00001040, 0x00801002, 0x00800040, 0x00000042, - 0x00000002, 0x00001042, 0x00801000, 0x00800002, - - 0x10400000, 0x00404010, 0x00000010, 0x10400010, - 0x10004000, 0x00400000, 0x10400010, 0x00004010, - 0x00400010, 0x00004000, 0x00404000, 0x10000000, - 0x10404010, 0x10000010, 0x10000000, 0x10404000, - 0x00000000, 0x10004000, 0x00404010, 0x00000010, - 0x10000010, 0x10404010, 0x00004000, 0x10400000, - 0x10404000, 0x00400010, 0x10004010, 0x00404000, - 0x00004010, 0x00000000, 0x00400000, 0x10004010, - 0x00404010, 0x00000010, 0x10000000, 0x00004000, - 0x10000010, 0x10004000, 0x00404000, 0x10400010, - 0x00000000, 0x00404010, 0x00004010, 0x10404000, - 0x10004000, 0x00400000, 0x10404010, 0x10000000, - 0x10004010, 0x10400000, 0x00400000, 0x10404010, - 0x00004000, 0x00400010, 0x10400010, 0x00004010, - 0x00400010, 0x00000000, 0x10404000, 0x10000010, - 0x10400000, 0x10004010, 0x00000010, 0x00404000, - - 0x00208080, 0x00008000, 0x20200000, 0x20208080, - 0x00200000, 0x20008080, 0x20008000, 0x20200000, - 0x20008080, 0x00208080, 0x00208000, 0x20000080, - 0x20200080, 0x00200000, 0x00000000, 0x20008000, - 0x00008000, 0x20000000, 0x00200080, 0x00008080, - 0x20208080, 0x00208000, 0x20000080, 0x00200080, - 0x20000000, 0x00000080, 0x00008080, 0x20208000, - 0x00000080, 0x20200080, 0x20208000, 0x00000000, - 0x00000000, 0x20208080, 0x00200080, 0x20008000, - 0x00208080, 0x00008000, 0x20000080, 0x00200080, - 0x20208000, 0x00000080, 0x00008080, 0x20200000, - 0x20008080, 0x20000000, 0x20200000, 0x00208000, - 0x20208080, 0x00008080, 0x00208000, 0x20200080, - 0x00200000, 0x20000080, 0x20008000, 0x00000000, - 0x00008000, 0x00200000, 0x20200080, 0x00208080, - 0x20000000, 0x20208000, 0x00000080, 0x20008080, +/* Lookup tables for key expansion */ + +static const u8 pc1[256] = { + 0x00, 0x00, 0x40, 0x04, 0x10, 0x10, 0x50, 0x14, + 0x04, 0x40, 0x44, 0x44, 0x14, 0x50, 0x54, 0x54, + 0x02, 0x02, 0x42, 0x06, 0x12, 0x12, 0x52, 0x16, + 0x06, 0x42, 0x46, 0x46, 0x16, 0x52, 0x56, 0x56, + 0x80, 0x08, 0xc0, 0x0c, 0x90, 0x18, 0xd0, 0x1c, + 0x84, 0x48, 0xc4, 0x4c, 0x94, 0x58, 0xd4, 0x5c, + 0x82, 0x0a, 0xc2, 0x0e, 0x92, 0x1a, 0xd2, 0x1e, + 0x86, 0x4a, 0xc6, 0x4e, 0x96, 0x5a, 0xd6, 0x5e, + 0x20, 0x20, 0x60, 0x24, 0x30, 0x30, 0x70, 0x34, + 0x24, 0x60, 0x64, 0x64, 0x34, 0x70, 0x74, 0x74, + 0x22, 0x22, 0x62, 0x26, 0x32, 0x32, 0x72, 0x36, + 0x26, 0x62, 0x66, 0x66, 0x36, 0x72, 0x76, 0x76, + 0xa0, 0x28, 0xe0, 0x2c, 0xb0, 0x38, 0xf0, 0x3c, + 0xa4, 0x68, 0xe4, 0x6c, 0xb4, 0x78, 0xf4, 0x7c, + 0xa2, 0x2a, 0xe2, 0x2e, 0xb2, 0x3a, 0xf2, 0x3e, + 0xa6, 0x6a, 0xe6, 0x6e, 0xb6, 0x7a, 0xf6, 0x7e, + 0x08, 0x80, 0x48, 0x84, 0x18, 0x90, 0x58, 0x94, + 0x0c, 0xc0, 0x4c, 0xc4, 0x1c, 0xd0, 0x5c, 0xd4, + 0x0a, 0x82, 0x4a, 0x86, 0x1a, 0x92, 0x5a, 0x96, + 0x0e, 0xc2, 0x4e, 0xc6, 0x1e, 0xd2, 0x5e, 0xd6, + 0x88, 0x88, 0xc8, 0x8c, 0x98, 0x98, 0xd8, 0x9c, + 0x8c, 0xc8, 0xcc, 0xcc, 0x9c, 0xd8, 0xdc, 0xdc, + 0x8a, 0x8a, 0xca, 0x8e, 0x9a, 0x9a, 0xda, 0x9e, + 0x8e, 0xca, 0xce, 0xce, 0x9e, 0xda, 0xde, 0xde, + 0x28, 0xa0, 0x68, 0xa4, 0x38, 0xb0, 0x78, 0xb4, + 0x2c, 0xe0, 0x6c, 0xe4, 0x3c, 0xf0, 0x7c, 0xf4, + 0x2a, 0xa2, 0x6a, 0xa6, 0x3a, 0xb2, 0x7a, 0xb6, + 0x2e, 0xe2, 0x6e, 0xe6, 0x3e, 0xf2, 0x7e, 0xf6, + 0xa8, 0xa8, 0xe8, 0xac, 0xb8, 0xb8, 0xf8, 0xbc, + 0xac, 0xe8, 0xec, 0xec, 0xbc, 0xf8, 0xfc, 0xfc, + 0xaa, 0xaa, 0xea, 0xae, 0xba, 0xba, 0xfa, 0xbe, + 0xae, 0xea, 0xee, 0xee, 0xbe, 0xfa, 0xfe, 0xfe }; -static const u8 rotors[] = { - 34, 13, 5, 46, 47, 18, 32, 41, 11, 53, 33, 20, - 14, 36, 30, 24, 49, 2, 15, 37, 42, 50, 0, 21, - 38, 48, 6, 26, 39, 4, 52, 25, 12, 27, 31, 40, - 1, 17, 28, 29, 23, 51, 35, 7, 3, 22, 9, 43, - - 41, 20, 12, 53, 54, 25, 39, 48, 18, 31, 40, 27, - 21, 43, 37, 0, 1, 9, 22, 44, 49, 2, 7, 28, - 45, 55, 13, 33, 46, 11, 6, 32, 19, 34, 38, 47, - 8, 24, 35, 36, 30, 3, 42, 14, 10, 29, 16, 50, - - 55, 34, 26, 38, 11, 39, 53, 5, 32, 45, 54, 41, - 35, 2, 51, 14, 15, 23, 36, 3, 8, 16, 21, 42, - 6, 12, 27, 47, 31, 25, 20, 46, 33, 48, 52, 4, - 22, 7, 49, 50, 44, 17, 1, 28, 24, 43, 30, 9, - - 12, 48, 40, 52, 25, 53, 38, 19, 46, 6, 11, 55, - 49, 16, 10, 28, 29, 37, 50, 17, 22, 30, 35, 1, - 20, 26, 41, 4, 45, 39, 34, 31, 47, 5, 13, 18, - 36, 21, 8, 9, 3, 0, 15, 42, 7, 2, 44, 23, - - 26, 5, 54, 13, 39, 38, 52, 33, 31, 20, 25, 12, - 8, 30, 24, 42, 43, 51, 9, 0, 36, 44, 49, 15, - 34, 40, 55, 18, 6, 53, 48, 45, 4, 19, 27, 32, - 50, 35, 22, 23, 17, 14, 29, 1, 21, 16, 3, 37, - - 40, 19, 11, 27, 53, 52, 13, 47, 45, 34, 39, 26, - 22, 44, 7, 1, 2, 10, 23, 14, 50, 3, 8, 29, - 48, 54, 12, 32, 20, 38, 5, 6, 18, 33, 41, 46, - 9, 49, 36, 37, 0, 28, 43, 15, 35, 30, 17, 51, - - 54, 33, 25, 41, 38, 13, 27, 4, 6, 48, 53, 40, - 36, 3, 21, 15, 16, 24, 37, 28, 9, 17, 22, 43, - 5, 11, 26, 46, 34, 52, 19, 20, 32, 47, 55, 31, - 23, 8, 50, 51, 14, 42, 2, 29, 49, 44, 0, 10, - - 11, 47, 39, 55, 52, 27, 41, 18, 20, 5, 38, 54, - 50, 17, 35, 29, 30, 7, 51, 42, 23, 0, 36, 2, - 19, 25, 40, 31, 48, 13, 33, 34, 46, 4, 12, 45, - 37, 22, 9, 10, 28, 1, 16, 43, 8, 3, 14, 24, - - 18, 54, 46, 5, 6, 34, 48, 25, 27, 12, 45, 4, - 2, 24, 42, 36, 37, 14, 3, 49, 30, 7, 43, 9, - 26, 32, 47, 38, 55, 20, 40, 41, 53, 11, 19, 52, - 44, 29, 16, 17, 35, 8, 23, 50, 15, 10, 21, 0, - - 32, 11, 31, 19, 20, 48, 5, 39, 41, 26, 6, 18, - 16, 7, 1, 50, 51, 28, 17, 8, 44, 21, 2, 23, - 40, 46, 4, 52, 12, 34, 54, 55, 38, 25, 33, 13, - 3, 43, 30, 0, 49, 22, 37, 9, 29, 24, 35, 14, - - 46, 25, 45, 33, 34, 5, 19, 53, 55, 40, 20, 32, - 30, 21, 15, 9, 10, 42, 0, 22, 3, 35, 16, 37, - 54, 31, 18, 13, 26, 48, 11, 12, 52, 39, 47, 27, - 17, 2, 44, 14, 8, 36, 51, 23, 43, 7, 49, 28, - - 31, 39, 6, 47, 48, 19, 33, 38, 12, 54, 34, 46, - 44, 35, 29, 23, 24, 1, 14, 36, 17, 49, 30, 51, - 11, 45, 32, 27, 40, 5, 25, 26, 13, 53, 4, 41, - 0, 16, 3, 28, 22, 50, 10, 37, 2, 21, 8, 42, - - 45, 53, 20, 4, 5, 33, 47, 52, 26, 11, 48, 31, - 3, 49, 43, 37, 7, 15, 28, 50, 0, 8, 44, 10, - 25, 6, 46, 41, 54, 19, 39, 40, 27, 38, 18, 55, - 14, 30, 17, 42, 36, 9, 24, 51, 16, 35, 22, 1, - - 6, 38, 34, 18, 19, 47, 4, 13, 40, 25, 5, 45, - 17, 8, 2, 51, 21, 29, 42, 9, 14, 22, 3, 24, - 39, 20, 31, 55, 11, 33, 53, 54, 41, 52, 32, 12, - 28, 44, 0, 1, 50, 23, 7, 10, 30, 49, 36, 15, - - 20, 52, 48, 32, 33, 4, 18, 27, 54, 39, 19, 6, - 0, 22, 16, 10, 35, 43, 1, 23, 28, 36, 17, 7, - 53, 34, 45, 12, 25, 47, 38, 11, 55, 13, 46, 26, - 42, 3, 14, 15, 9, 37, 21, 24, 44, 8, 50, 29, - - 27, 6, 55, 39, 40, 11, 25, 34, 4, 46, 26, 13, - 7, 29, 23, 17, 42, 50, 8, 30, 35, 43, 24, 14, - 31, 41, 52, 19, 32, 54, 45, 18, 5, 20, 53, 33, - 49, 10, 21, 22, 16, 44, 28, 0, 51, 15, 2, 36, +static const u8 rs[256] = { + 0x00, 0x00, 0x80, 0x80, 0x02, 0x02, 0x82, 0x82, + 0x04, 0x04, 0x84, 0x84, 0x06, 0x06, 0x86, 0x86, + 0x08, 0x08, 0x88, 0x88, 0x0a, 0x0a, 0x8a, 0x8a, + 0x0c, 0x0c, 0x8c, 0x8c, 0x0e, 0x0e, 0x8e, 0x8e, + 0x10, 0x10, 0x90, 0x90, 0x12, 0x12, 0x92, 0x92, + 0x14, 0x14, 0x94, 0x94, 0x16, 0x16, 0x96, 0x96, + 0x18, 0x18, 0x98, 0x98, 0x1a, 0x1a, 0x9a, 0x9a, + 0x1c, 0x1c, 0x9c, 0x9c, 0x1e, 0x1e, 0x9e, 0x9e, + 0x20, 0x20, 0xa0, 0xa0, 0x22, 0x22, 0xa2, 0xa2, + 0x24, 0x24, 0xa4, 0xa4, 0x26, 0x26, 0xa6, 0xa6, + 0x28, 0x28, 0xa8, 0xa8, 0x2a, 0x2a, 0xaa, 0xaa, + 0x2c, 0x2c, 0xac, 0xac, 0x2e, 0x2e, 0xae, 0xae, + 0x30, 0x30, 0xb0, 0xb0, 0x32, 0x32, 0xb2, 0xb2, + 0x34, 0x34, 0xb4, 0xb4, 0x36, 0x36, 0xb6, 0xb6, + 0x38, 0x38, 0xb8, 0xb8, 0x3a, 0x3a, 0xba, 0xba, + 0x3c, 0x3c, 0xbc, 0xbc, 0x3e, 0x3e, 0xbe, 0xbe, + 0x40, 0x40, 0xc0, 0xc0, 0x42, 0x42, 0xc2, 0xc2, + 0x44, 0x44, 0xc4, 0xc4, 0x46, 0x46, 0xc6, 0xc6, + 0x48, 0x48, 0xc8, 0xc8, 0x4a, 0x4a, 0xca, 0xca, + 0x4c, 0x4c, 0xcc, 0xcc, 0x4e, 0x4e, 0xce, 0xce, + 0x50, 0x50, 0xd0, 0xd0, 0x52, 0x52, 0xd2, 0xd2, + 0x54, 0x54, 0xd4, 0xd4, 0x56, 0x56, 0xd6, 0xd6, + 0x58, 0x58, 0xd8, 0xd8, 0x5a, 0x5a, 0xda, 0xda, + 0x5c, 0x5c, 0xdc, 0xdc, 0x5e, 0x5e, 0xde, 0xde, + 0x60, 0x60, 0xe0, 0xe0, 0x62, 0x62, 0xe2, 0xe2, + 0x64, 0x64, 0xe4, 0xe4, 0x66, 0x66, 0xe6, 0xe6, + 0x68, 0x68, 0xe8, 0xe8, 0x6a, 0x6a, 0xea, 0xea, + 0x6c, 0x6c, 0xec, 0xec, 0x6e, 0x6e, 0xee, 0xee, + 0x70, 0x70, 0xf0, 0xf0, 0x72, 0x72, 0xf2, 0xf2, + 0x74, 0x74, 0xf4, 0xf4, 0x76, 0x76, 0xf6, 0xf6, + 0x78, 0x78, 0xf8, 0xf8, 0x7a, 0x7a, 0xfa, 0xfa, + 0x7c, 0x7c, 0xfc, 0xfc, 0x7e, 0x7e, 0xfe, 0xfe }; -static const u8 parity[] = { - 8,1,0,8,0,8,8,0,0,8,8,0,8,0,2,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,3, - 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, - 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, - 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, - 0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8, - 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, - 8,0,0,8,0,8,8,0,0,8,8,0,8,0,0,8,0,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0, - 4,8,8,0,8,0,0,8,8,0,0,8,0,8,8,0,8,5,0,8,0,8,8,0,0,8,8,0,8,0,6,8, +static const u32 pc2[1024] = { + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00040000, 0x00000000, 0x04000000, 0x00100000, + 0x00400000, 0x00000008, 0x00000800, 0x40000000, + 0x00440000, 0x00000008, 0x04000800, 0x40100000, + 0x00000400, 0x00000020, 0x08000000, 0x00000100, + 0x00040400, 0x00000020, 0x0c000000, 0x00100100, + 0x00400400, 0x00000028, 0x08000800, 0x40000100, + 0x00440400, 0x00000028, 0x0c000800, 0x40100100, + 0x80000000, 0x00000010, 0x00000000, 0x00800000, + 0x80040000, 0x00000010, 0x04000000, 0x00900000, + 0x80400000, 0x00000018, 0x00000800, 0x40800000, + 0x80440000, 0x00000018, 0x04000800, 0x40900000, + 0x80000400, 0x00000030, 0x08000000, 0x00800100, + 0x80040400, 0x00000030, 0x0c000000, 0x00900100, + 0x80400400, 0x00000038, 0x08000800, 0x40800100, + 0x80440400, 0x00000038, 0x0c000800, 0x40900100, + 0x10000000, 0x00000000, 0x00200000, 0x00001000, + 0x10040000, 0x00000000, 0x04200000, 0x00101000, + 0x10400000, 0x00000008, 0x00200800, 0x40001000, + 0x10440000, 0x00000008, 0x04200800, 0x40101000, + 0x10000400, 0x00000020, 0x08200000, 0x00001100, + 0x10040400, 0x00000020, 0x0c200000, 0x00101100, + 0x10400400, 0x00000028, 0x08200800, 0x40001100, + 0x10440400, 0x00000028, 0x0c200800, 0x40101100, + 0x90000000, 0x00000010, 0x00200000, 0x00801000, + 0x90040000, 0x00000010, 0x04200000, 0x00901000, + 0x90400000, 0x00000018, 0x00200800, 0x40801000, + 0x90440000, 0x00000018, 0x04200800, 0x40901000, + 0x90000400, 0x00000030, 0x08200000, 0x00801100, + 0x90040400, 0x00000030, 0x0c200000, 0x00901100, + 0x90400400, 0x00000038, 0x08200800, 0x40801100, + 0x90440400, 0x00000038, 0x0c200800, 0x40901100, + 0x00000200, 0x00080000, 0x00000000, 0x00000004, + 0x00040200, 0x00080000, 0x04000000, 0x00100004, + 0x00400200, 0x00080008, 0x00000800, 0x40000004, + 0x00440200, 0x00080008, 0x04000800, 0x40100004, + 0x00000600, 0x00080020, 0x08000000, 0x00000104, + 0x00040600, 0x00080020, 0x0c000000, 0x00100104, + 0x00400600, 0x00080028, 0x08000800, 0x40000104, + 0x00440600, 0x00080028, 0x0c000800, 0x40100104, + 0x80000200, 0x00080010, 0x00000000, 0x00800004, + 0x80040200, 0x00080010, 0x04000000, 0x00900004, + 0x80400200, 0x00080018, 0x00000800, 0x40800004, + 0x80440200, 0x00080018, 0x04000800, 0x40900004, + 0x80000600, 0x00080030, 0x08000000, 0x00800104, + 0x80040600, 0x00080030, 0x0c000000, 0x00900104, + 0x80400600, 0x00080038, 0x08000800, 0x40800104, + 0x80440600, 0x00080038, 0x0c000800, 0x40900104, + 0x10000200, 0x00080000, 0x00200000, 0x00001004, + 0x10040200, 0x00080000, 0x04200000, 0x00101004, + 0x10400200, 0x00080008, 0x00200800, 0x40001004, + 0x10440200, 0x00080008, 0x04200800, 0x40101004, + 0x10000600, 0x00080020, 0x08200000, 0x00001104, + 0x10040600, 0x00080020, 0x0c200000, 0x00101104, + 0x10400600, 0x00080028, 0x08200800, 0x40001104, + 0x10440600, 0x00080028, 0x0c200800, 0x40101104, + 0x90000200, 0x00080010, 0x00200000, 0x00801004, + 0x90040200, 0x00080010, 0x04200000, 0x00901004, + 0x90400200, 0x00080018, 0x00200800, 0x40801004, + 0x90440200, 0x00080018, 0x04200800, 0x40901004, + 0x90000600, 0x00080030, 0x08200000, 0x00801104, + 0x90040600, 0x00080030, 0x0c200000, 0x00901104, + 0x90400600, 0x00080038, 0x08200800, 0x40801104, + 0x90440600, 0x00080038, 0x0c200800, 0x40901104, + 0x00000002, 0x00002000, 0x20000000, 0x00000001, + 0x00040002, 0x00002000, 0x24000000, 0x00100001, + 0x00400002, 0x00002008, 0x20000800, 0x40000001, + 0x00440002, 0x00002008, 0x24000800, 0x40100001, + 0x00000402, 0x00002020, 0x28000000, 0x00000101, + 0x00040402, 0x00002020, 0x2c000000, 0x00100101, + 0x00400402, 0x00002028, 0x28000800, 0x40000101, + 0x00440402, 0x00002028, 0x2c000800, 0x40100101, + 0x80000002, 0x00002010, 0x20000000, 0x00800001, + 0x80040002, 0x00002010, 0x24000000, 0x00900001, + 0x80400002, 0x00002018, 0x20000800, 0x40800001, + 0x80440002, 0x00002018, 0x24000800, 0x40900001, + 0x80000402, 0x00002030, 0x28000000, 0x00800101, + 0x80040402, 0x00002030, 0x2c000000, 0x00900101, + 0x80400402, 0x00002038, 0x28000800, 0x40800101, + 0x80440402, 0x00002038, 0x2c000800, 0x40900101, + 0x10000002, 0x00002000, 0x20200000, 0x00001001, + 0x10040002, 0x00002000, 0x24200000, 0x00101001, + 0x10400002, 0x00002008, 0x20200800, 0x40001001, + 0x10440002, 0x00002008, 0x24200800, 0x40101001, + 0x10000402, 0x00002020, 0x28200000, 0x00001101, + 0x10040402, 0x00002020, 0x2c200000, 0x00101101, + 0x10400402, 0x00002028, 0x28200800, 0x40001101, + 0x10440402, 0x00002028, 0x2c200800, 0x40101101, + 0x90000002, 0x00002010, 0x20200000, 0x00801001, + 0x90040002, 0x00002010, 0x24200000, 0x00901001, + 0x90400002, 0x00002018, 0x20200800, 0x40801001, + 0x90440002, 0x00002018, 0x24200800, 0x40901001, + 0x90000402, 0x00002030, 0x28200000, 0x00801101, + 0x90040402, 0x00002030, 0x2c200000, 0x00901101, + 0x90400402, 0x00002038, 0x28200800, 0x40801101, + 0x90440402, 0x00002038, 0x2c200800, 0x40901101, + 0x00000202, 0x00082000, 0x20000000, 0x00000005, + 0x00040202, 0x00082000, 0x24000000, 0x00100005, + 0x00400202, 0x00082008, 0x20000800, 0x40000005, + 0x00440202, 0x00082008, 0x24000800, 0x40100005, + 0x00000602, 0x00082020, 0x28000000, 0x00000105, + 0x00040602, 0x00082020, 0x2c000000, 0x00100105, + 0x00400602, 0x00082028, 0x28000800, 0x40000105, + 0x00440602, 0x00082028, 0x2c000800, 0x40100105, + 0x80000202, 0x00082010, 0x20000000, 0x00800005, + 0x80040202, 0x00082010, 0x24000000, 0x00900005, + 0x80400202, 0x00082018, 0x20000800, 0x40800005, + 0x80440202, 0x00082018, 0x24000800, 0x40900005, + 0x80000602, 0x00082030, 0x28000000, 0x00800105, + 0x80040602, 0x00082030, 0x2c000000, 0x00900105, + 0x80400602, 0x00082038, 0x28000800, 0x40800105, + 0x80440602, 0x00082038, 0x2c000800, 0x40900105, + 0x10000202, 0x00082000, 0x20200000, 0x00001005, + 0x10040202, 0x00082000, 0x24200000, 0x00101005, + 0x10400202, 0x00082008, 0x20200800, 0x40001005, + 0x10440202, 0x00082008, 0x24200800, 0x40101005, + 0x10000602, 0x00082020, 0x28200000, 0x00001105, + 0x10040602, 0x00082020, 0x2c200000, 0x00101105, + 0x10400602, 0x00082028, 0x28200800, 0x40001105, + 0x10440602, 0x00082028, 0x2c200800, 0x40101105, + 0x90000202, 0x00082010, 0x20200000, 0x00801005, + 0x90040202, 0x00082010, 0x24200000, 0x00901005, + 0x90400202, 0x00082018, 0x20200800, 0x40801005, + 0x90440202, 0x00082018, 0x24200800, 0x40901005, + 0x90000602, 0x00082030, 0x28200000, 0x00801105, + 0x90040602, 0x00082030, 0x2c200000, 0x00901105, + 0x90400602, 0x00082038, 0x28200800, 0x40801105, + 0x90440602, 0x00082038, 0x2c200800, 0x40901105, + + 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000008, 0x00080000, 0x10000000, + 0x02000000, 0x00000000, 0x00000080, 0x00001000, + 0x02000000, 0x00000008, 0x00080080, 0x10001000, + 0x00004000, 0x00000000, 0x00000040, 0x00040000, + 0x00004000, 0x00000008, 0x00080040, 0x10040000, + 0x02004000, 0x00000000, 0x000000c0, 0x00041000, + 0x02004000, 0x00000008, 0x000800c0, 0x10041000, + 0x00020000, 0x00008000, 0x08000000, 0x00200000, + 0x00020000, 0x00008008, 0x08080000, 0x10200000, + 0x02020000, 0x00008000, 0x08000080, 0x00201000, + 0x02020000, 0x00008008, 0x08080080, 0x10201000, + 0x00024000, 0x00008000, 0x08000040, 0x00240000, + 0x00024000, 0x00008008, 0x08080040, 0x10240000, + 0x02024000, 0x00008000, 0x080000c0, 0x00241000, + 0x02024000, 0x00008008, 0x080800c0, 0x10241000, + 0x00000000, 0x01000000, 0x00002000, 0x00000020, + 0x00000000, 0x01000008, 0x00082000, 0x10000020, + 0x02000000, 0x01000000, 0x00002080, 0x00001020, + 0x02000000, 0x01000008, 0x00082080, 0x10001020, + 0x00004000, 0x01000000, 0x00002040, 0x00040020, + 0x00004000, 0x01000008, 0x00082040, 0x10040020, + 0x02004000, 0x01000000, 0x000020c0, 0x00041020, + 0x02004000, 0x01000008, 0x000820c0, 0x10041020, + 0x00020000, 0x01008000, 0x08002000, 0x00200020, + 0x00020000, 0x01008008, 0x08082000, 0x10200020, + 0x02020000, 0x01008000, 0x08002080, 0x00201020, + 0x02020000, 0x01008008, 0x08082080, 0x10201020, + 0x00024000, 0x01008000, 0x08002040, 0x00240020, + 0x00024000, 0x01008008, 0x08082040, 0x10240020, + 0x02024000, 0x01008000, 0x080020c0, 0x00241020, + 0x02024000, 0x01008008, 0x080820c0, 0x10241020, + 0x00000400, 0x04000000, 0x00100000, 0x00000004, + 0x00000400, 0x04000008, 0x00180000, 0x10000004, + 0x02000400, 0x04000000, 0x00100080, 0x00001004, + 0x02000400, 0x04000008, 0x00180080, 0x10001004, + 0x00004400, 0x04000000, 0x00100040, 0x00040004, + 0x00004400, 0x04000008, 0x00180040, 0x10040004, + 0x02004400, 0x04000000, 0x001000c0, 0x00041004, + 0x02004400, 0x04000008, 0x001800c0, 0x10041004, + 0x00020400, 0x04008000, 0x08100000, 0x00200004, + 0x00020400, 0x04008008, 0x08180000, 0x10200004, + 0x02020400, 0x04008000, 0x08100080, 0x00201004, + 0x02020400, 0x04008008, 0x08180080, 0x10201004, + 0x00024400, 0x04008000, 0x08100040, 0x00240004, + 0x00024400, 0x04008008, 0x08180040, 0x10240004, + 0x02024400, 0x04008000, 0x081000c0, 0x00241004, + 0x02024400, 0x04008008, 0x081800c0, 0x10241004, + 0x00000400, 0x05000000, 0x00102000, 0x00000024, + 0x00000400, 0x05000008, 0x00182000, 0x10000024, + 0x02000400, 0x05000000, 0x00102080, 0x00001024, + 0x02000400, 0x05000008, 0x00182080, 0x10001024, + 0x00004400, 0x05000000, 0x00102040, 0x00040024, + 0x00004400, 0x05000008, 0x00182040, 0x10040024, + 0x02004400, 0x05000000, 0x001020c0, 0x00041024, + 0x02004400, 0x05000008, 0x001820c0, 0x10041024, + 0x00020400, 0x05008000, 0x08102000, 0x00200024, + 0x00020400, 0x05008008, 0x08182000, 0x10200024, + 0x02020400, 0x05008000, 0x08102080, 0x00201024, + 0x02020400, 0x05008008, 0x08182080, 0x10201024, + 0x00024400, 0x05008000, 0x08102040, 0x00240024, + 0x00024400, 0x05008008, 0x08182040, 0x10240024, + 0x02024400, 0x05008000, 0x081020c0, 0x00241024, + 0x02024400, 0x05008008, 0x081820c0, 0x10241024, + 0x00000800, 0x00010000, 0x20000000, 0x00000010, + 0x00000800, 0x00010008, 0x20080000, 0x10000010, + 0x02000800, 0x00010000, 0x20000080, 0x00001010, + 0x02000800, 0x00010008, 0x20080080, 0x10001010, + 0x00004800, 0x00010000, 0x20000040, 0x00040010, + 0x00004800, 0x00010008, 0x20080040, 0x10040010, + 0x02004800, 0x00010000, 0x200000c0, 0x00041010, + 0x02004800, 0x00010008, 0x200800c0, 0x10041010, + 0x00020800, 0x00018000, 0x28000000, 0x00200010, + 0x00020800, 0x00018008, 0x28080000, 0x10200010, + 0x02020800, 0x00018000, 0x28000080, 0x00201010, + 0x02020800, 0x00018008, 0x28080080, 0x10201010, + 0x00024800, 0x00018000, 0x28000040, 0x00240010, + 0x00024800, 0x00018008, 0x28080040, 0x10240010, + 0x02024800, 0x00018000, 0x280000c0, 0x00241010, + 0x02024800, 0x00018008, 0x280800c0, 0x10241010, + 0x00000800, 0x01010000, 0x20002000, 0x00000030, + 0x00000800, 0x01010008, 0x20082000, 0x10000030, + 0x02000800, 0x01010000, 0x20002080, 0x00001030, + 0x02000800, 0x01010008, 0x20082080, 0x10001030, + 0x00004800, 0x01010000, 0x20002040, 0x00040030, + 0x00004800, 0x01010008, 0x20082040, 0x10040030, + 0x02004800, 0x01010000, 0x200020c0, 0x00041030, + 0x02004800, 0x01010008, 0x200820c0, 0x10041030, + 0x00020800, 0x01018000, 0x28002000, 0x00200030, + 0x00020800, 0x01018008, 0x28082000, 0x10200030, + 0x02020800, 0x01018000, 0x28002080, 0x00201030, + 0x02020800, 0x01018008, 0x28082080, 0x10201030, + 0x00024800, 0x01018000, 0x28002040, 0x00240030, + 0x00024800, 0x01018008, 0x28082040, 0x10240030, + 0x02024800, 0x01018000, 0x280020c0, 0x00241030, + 0x02024800, 0x01018008, 0x280820c0, 0x10241030, + 0x00000c00, 0x04010000, 0x20100000, 0x00000014, + 0x00000c00, 0x04010008, 0x20180000, 0x10000014, + 0x02000c00, 0x04010000, 0x20100080, 0x00001014, + 0x02000c00, 0x04010008, 0x20180080, 0x10001014, + 0x00004c00, 0x04010000, 0x20100040, 0x00040014, + 0x00004c00, 0x04010008, 0x20180040, 0x10040014, + 0x02004c00, 0x04010000, 0x201000c0, 0x00041014, + 0x02004c00, 0x04010008, 0x201800c0, 0x10041014, + 0x00020c00, 0x04018000, 0x28100000, 0x00200014, + 0x00020c00, 0x04018008, 0x28180000, 0x10200014, + 0x02020c00, 0x04018000, 0x28100080, 0x00201014, + 0x02020c00, 0x04018008, 0x28180080, 0x10201014, + 0x00024c00, 0x04018000, 0x28100040, 0x00240014, + 0x00024c00, 0x04018008, 0x28180040, 0x10240014, + 0x02024c00, 0x04018000, 0x281000c0, 0x00241014, + 0x02024c00, 0x04018008, 0x281800c0, 0x10241014, + 0x00000c00, 0x05010000, 0x20102000, 0x00000034, + 0x00000c00, 0x05010008, 0x20182000, 0x10000034, + 0x02000c00, 0x05010000, 0x20102080, 0x00001034, + 0x02000c00, 0x05010008, 0x20182080, 0x10001034, + 0x00004c00, 0x05010000, 0x20102040, 0x00040034, + 0x00004c00, 0x05010008, 0x20182040, 0x10040034, + 0x02004c00, 0x05010000, 0x201020c0, 0x00041034, + 0x02004c00, 0x05010008, 0x201820c0, 0x10041034, + 0x00020c00, 0x05018000, 0x28102000, 0x00200034, + 0x00020c00, 0x05018008, 0x28182000, 0x10200034, + 0x02020c00, 0x05018000, 0x28102080, 0x00201034, + 0x02020c00, 0x05018008, 0x28182080, 0x10201034, + 0x00024c00, 0x05018000, 0x28102040, 0x00240034, + 0x00024c00, 0x05018008, 0x28182040, 0x10240034, + 0x02024c00, 0x05018000, 0x281020c0, 0x00241034, + 0x02024c00, 0x05018008, 0x281820c0, 0x10241034 }; +/* S-box lookup tables */ + +static const u32 S1[64] = { + 0x01010400, 0x00000000, 0x00010000, 0x01010404, + 0x01010004, 0x00010404, 0x00000004, 0x00010000, + 0x00000400, 0x01010400, 0x01010404, 0x00000400, + 0x01000404, 0x01010004, 0x01000000, 0x00000004, + 0x00000404, 0x01000400, 0x01000400, 0x00010400, + 0x00010400, 0x01010000, 0x01010000, 0x01000404, + 0x00010004, 0x01000004, 0x01000004, 0x00010004, + 0x00000000, 0x00000404, 0x00010404, 0x01000000, + 0x00010000, 0x01010404, 0x00000004, 0x01010000, + 0x01010400, 0x01000000, 0x01000000, 0x00000400, + 0x01010004, 0x00010000, 0x00010400, 0x01000004, + 0x00000400, 0x00000004, 0x01000404, 0x00010404, + 0x01010404, 0x00010004, 0x01010000, 0x01000404, + 0x01000004, 0x00000404, 0x00010404, 0x01010400, + 0x00000404, 0x01000400, 0x01000400, 0x00000000, + 0x00010004, 0x00010400, 0x00000000, 0x01010004 +}; -static void des_small_fips_encrypt(u32 *expkey, u8 *dst, const u8 *src) -{ - u32 x, y, z; - - x = src[7]; - x <<= 8; - x |= src[6]; - x <<= 8; - x |= src[5]; - x <<= 8; - x |= src[4]; - y = src[3]; - y <<= 8; - y |= src[2]; - y <<= 8; - y |= src[1]; - y <<= 8; - y |= src[0]; - z = ((x >> 004) ^ y) & 0x0F0F0F0FL; - x ^= z << 004; - y ^= z; - z = ((y >> 020) ^ x) & 0x0000FFFFL; - y ^= z << 020; - x ^= z; - z = ((x >> 002) ^ y) & 0x33333333L; - x ^= z << 002; - y ^= z; - z = ((y >> 010) ^ x) & 0x00FF00FFL; - y ^= z << 010; - x ^= z; - x = x >> 1 | x << 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y >> 1 | y << 31; - z = expkey[0]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[1]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[2]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[3]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[4]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[5]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[6]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[7]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[8]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[9]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[10]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[11]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[12]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[13]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[14]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[15]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[16]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[17]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[18]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[19]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[20]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[21]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[22]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[23]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[24]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[25]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[26]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[27]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[28]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[29]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[30]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[31]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - x = x << 1 | x >> 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y << 1 | y >> 31; - z = ((x >> 010) ^ y) & 0x00FF00FFL; - x ^= z << 010; - y ^= z; - z = ((y >> 002) ^ x) & 0x33333333L; - y ^= z << 002; - x ^= z; - z = ((x >> 020) ^ y) & 0x0000FFFFL; - x ^= z << 020; - y ^= z; - z = ((y >> 004) ^ x) & 0x0F0F0F0FL; - y ^= z << 004; - x ^= z; - dst[0] = x; - x >>= 8; - dst[1] = x; - x >>= 8; - dst[2] = x; - x >>= 8; - dst[3] = x; - dst[4] = y; - y >>= 8; - dst[5] = y; - y >>= 8; - dst[6] = y; - y >>= 8; - dst[7] = y; -} +static const u32 S2[64] = { + 0x80108020, 0x80008000, 0x00008000, 0x00108020, + 0x00100000, 0x00000020, 0x80100020, 0x80008020, + 0x80000020, 0x80108020, 0x80108000, 0x80000000, + 0x80008000, 0x00100000, 0x00000020, 0x80100020, + 0x00108000, 0x00100020, 0x80008020, 0x00000000, + 0x80000000, 0x00008000, 0x00108020, 0x80100000, + 0x00100020, 0x80000020, 0x00000000, 0x00108000, + 0x00008020, 0x80108000, 0x80100000, 0x00008020, + 0x00000000, 0x00108020, 0x80100020, 0x00100000, + 0x80008020, 0x80100000, 0x80108000, 0x00008000, + 0x80100000, 0x80008000, 0x00000020, 0x80108020, + 0x00108020, 0x00000020, 0x00008000, 0x80000000, + 0x00008020, 0x80108000, 0x00100000, 0x80000020, + 0x00100020, 0x80008020, 0x80000020, 0x00100020, + 0x00108000, 0x00000000, 0x80008000, 0x00008020, + 0x80000000, 0x80100020, 0x80108020, 0x00108000 +}; -static void des_small_fips_decrypt(u32 *expkey, u8 *dst, const u8 *src) -{ - u32 x, y, z; - - x = src[7]; - x <<= 8; - x |= src[6]; - x <<= 8; - x |= src[5]; - x <<= 8; - x |= src[4]; - y = src[3]; - y <<= 8; - y |= src[2]; - y <<= 8; - y |= src[1]; - y <<= 8; - y |= src[0]; - z = ((x >> 004) ^ y) & 0x0F0F0F0FL; - x ^= z << 004; - y ^= z; - z = ((y >> 020) ^ x) & 0x0000FFFFL; - y ^= z << 020; - x ^= z; - z = ((x >> 002) ^ y) & 0x33333333L; - x ^= z << 002; - y ^= z; - z = ((y >> 010) ^ x) & 0x00FF00FFL; - y ^= z << 010; - x ^= z; - x = x >> 1 | x << 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y >> 1 | y << 31; - z = expkey[31]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[30]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[29]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[28]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[27]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[26]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[25]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[24]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[23]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[22]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[21]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[20]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[19]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[18]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[17]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[16]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[15]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[14]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[13]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[12]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[11]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[10]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[9]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[8]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[7]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[6]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[5]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[4]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[3]; - z ^= y; - z = z << 4 | z >> 28; - x ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[2]; - z ^= y; - x ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - x ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - z = expkey[1]; - z ^= x; - z = z << 4 | z >> 28; - y ^= * (u32 *) ((u8 *) (des_keymap + 448) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 384) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 320) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 256) + (0xFC & z)); - z = expkey[0]; - z ^= x; - y ^= * (u32 *) ((u8 *) (des_keymap + 192) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 128) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) (des_keymap + 64) + (0xFC & z)); - z >>= 8; - y ^= * (u32 *) ((u8 *) des_keymap + (0xFC & z)); - x = x << 1 | x >> 31; - z = (x ^ y) & 0x55555555L; - y ^= z; - x ^= z; - y = y << 1 | y >> 31; - z = ((x >> 010) ^ y) & 0x00FF00FFL; - x ^= z << 010; - y ^= z; - z = ((y >> 002) ^ x) & 0x33333333L; - y ^= z << 002; - x ^= z; - z = ((x >> 020) ^ y) & 0x0000FFFFL; - x ^= z << 020; - y ^= z; - z = ((y >> 004) ^ x) & 0x0F0F0F0FL; - y ^= z << 004; - x ^= z; - dst[0] = x; - x >>= 8; - dst[1] = x; - x >>= 8; - dst[2] = x; - x >>= 8; - dst[3] = x; - dst[4] = y; - y >>= 8; - dst[5] = y; - y >>= 8; - dst[6] = y; - y >>= 8; - dst[7] = y; -} +static const u32 S3[64] = { + 0x00000208, 0x08020200, 0x00000000, 0x08020008, + 0x08000200, 0x00000000, 0x00020208, 0x08000200, + 0x00020008, 0x08000008, 0x08000008, 0x00020000, + 0x08020208, 0x00020008, 0x08020000, 0x00000208, + 0x08000000, 0x00000008, 0x08020200, 0x00000200, + 0x00020200, 0x08020000, 0x08020008, 0x00020208, + 0x08000208, 0x00020200, 0x00020000, 0x08000208, + 0x00000008, 0x08020208, 0x00000200, 0x08000000, + 0x08020200, 0x08000000, 0x00020008, 0x00000208, + 0x00020000, 0x08020200, 0x08000200, 0x00000000, + 0x00000200, 0x00020008, 0x08020208, 0x08000200, + 0x08000008, 0x00000200, 0x00000000, 0x08020008, + 0x08000208, 0x00020000, 0x08000000, 0x08020208, + 0x00000008, 0x00020208, 0x00020200, 0x08000008, + 0x08020000, 0x08000208, 0x00000208, 0x08020000, + 0x00020208, 0x00000008, 0x08020008, 0x00020200 +}; + +static const u32 S4[64] = { + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802080, 0x00800081, 0x00800001, 0x00002001, + 0x00000000, 0x00802000, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00800080, 0x00800001, + 0x00000001, 0x00002000, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002001, 0x00002080, + 0x00800081, 0x00000001, 0x00002080, 0x00800080, + 0x00002000, 0x00802080, 0x00802081, 0x00000081, + 0x00800080, 0x00800001, 0x00802000, 0x00802081, + 0x00000081, 0x00000000, 0x00000000, 0x00802000, + 0x00002080, 0x00800080, 0x00800081, 0x00000001, + 0x00802001, 0x00002081, 0x00002081, 0x00000080, + 0x00802081, 0x00000081, 0x00000001, 0x00002000, + 0x00800001, 0x00002001, 0x00802080, 0x00800081, + 0x00002001, 0x00002080, 0x00800000, 0x00802001, + 0x00000080, 0x00800000, 0x00002000, 0x00802080 +}; + +static const u32 S5[64] = { + 0x00000100, 0x02080100, 0x02080000, 0x42000100, + 0x00080000, 0x00000100, 0x40000000, 0x02080000, + 0x40080100, 0x00080000, 0x02000100, 0x40080100, + 0x42000100, 0x42080000, 0x00080100, 0x40000000, + 0x02000000, 0x40080000, 0x40080000, 0x00000000, + 0x40000100, 0x42080100, 0x42080100, 0x02000100, + 0x42080000, 0x40000100, 0x00000000, 0x42000000, + 0x02080100, 0x02000000, 0x42000000, 0x00080100, + 0x00080000, 0x42000100, 0x00000100, 0x02000000, + 0x40000000, 0x02080000, 0x42000100, 0x40080100, + 0x02000100, 0x40000000, 0x42080000, 0x02080100, + 0x40080100, 0x00000100, 0x02000000, 0x42080000, + 0x42080100, 0x00080100, 0x42000000, 0x42080100, + 0x02080000, 0x00000000, 0x40080000, 0x42000000, + 0x00080100, 0x02000100, 0x40000100, 0x00080000, + 0x00000000, 0x40080000, 0x02080100, 0x40000100 +}; + +static const u32 S6[64] = { + 0x20000010, 0x20400000, 0x00004000, 0x20404010, + 0x20400000, 0x00000010, 0x20404010, 0x00400000, + 0x20004000, 0x00404010, 0x00400000, 0x20000010, + 0x00400010, 0x20004000, 0x20000000, 0x00004010, + 0x00000000, 0x00400010, 0x20004010, 0x00004000, + 0x00404000, 0x20004010, 0x00000010, 0x20400010, + 0x20400010, 0x00000000, 0x00404010, 0x20404000, + 0x00004010, 0x00404000, 0x20404000, 0x20000000, + 0x20004000, 0x00000010, 0x20400010, 0x00404000, + 0x20404010, 0x00400000, 0x00004010, 0x20000010, + 0x00400000, 0x20004000, 0x20000000, 0x00004010, + 0x20000010, 0x20404010, 0x00404000, 0x20400000, + 0x00404010, 0x20404000, 0x00000000, 0x20400010, + 0x00000010, 0x00004000, 0x20400000, 0x00404010, + 0x00004000, 0x00400010, 0x20004010, 0x00000000, + 0x20404000, 0x20000000, 0x00400010, 0x20004010 +}; + +static const u32 S7[64] = { + 0x00200000, 0x04200002, 0x04000802, 0x00000000, + 0x00000800, 0x04000802, 0x00200802, 0x04200800, + 0x04200802, 0x00200000, 0x00000000, 0x04000002, + 0x00000002, 0x04000000, 0x04200002, 0x00000802, + 0x04000800, 0x00200802, 0x00200002, 0x04000800, + 0x04000002, 0x04200000, 0x04200800, 0x00200002, + 0x04200000, 0x00000800, 0x00000802, 0x04200802, + 0x00200800, 0x00000002, 0x04000000, 0x00200800, + 0x04000000, 0x00200800, 0x00200000, 0x04000802, + 0x04000802, 0x04200002, 0x04200002, 0x00000002, + 0x00200002, 0x04000000, 0x04000800, 0x00200000, + 0x04200800, 0x00000802, 0x00200802, 0x04200800, + 0x00000802, 0x04000002, 0x04200802, 0x04200000, + 0x00200800, 0x00000000, 0x00000002, 0x04200802, + 0x00000000, 0x00200802, 0x04200000, 0x00000800, + 0x04000002, 0x04000800, 0x00000800, 0x00200002 +}; + +static const u32 S8[64] = { + 0x10001040, 0x00001000, 0x00040000, 0x10041040, + 0x10000000, 0x10001040, 0x00000040, 0x10000000, + 0x00040040, 0x10040000, 0x10041040, 0x00041000, + 0x10041000, 0x00041040, 0x00001000, 0x00000040, + 0x10040000, 0x10000040, 0x10001000, 0x00001040, + 0x00041000, 0x00040040, 0x10040040, 0x10041000, + 0x00001040, 0x00000000, 0x00000000, 0x10040040, + 0x10000040, 0x10001000, 0x00041040, 0x00040000, + 0x00041040, 0x00040000, 0x10041000, 0x00001000, + 0x00000040, 0x10040040, 0x00001000, 0x00041040, + 0x10001000, 0x00000040, 0x10000040, 0x10040000, + 0x10040040, 0x10000000, 0x00040000, 0x10001040, + 0x00000000, 0x10041040, 0x00040040, 0x10000040, + 0x10040000, 0x10001000, 0x10001040, 0x00000000, + 0x10041040, 0x00041000, 0x00041000, 0x00001040, + 0x00001040, 0x00040040, 0x10000000, 0x10041000 +}; + +/* Encryption components: IP, FP, and round function */ + +#define IP(L, R, T) \ + ROL(R, 4); \ + T = L; \ + L ^= R; \ + L &= 0xf0f0f0f0; \ + R ^= L; \ + L ^= T; \ + ROL(R, 12); \ + T = L; \ + L ^= R; \ + L &= 0xffff0000; \ + R ^= L; \ + L ^= T; \ + ROR(R, 14); \ + T = L; \ + L ^= R; \ + L &= 0xcccccccc; \ + R ^= L; \ + L ^= T; \ + ROL(R, 6); \ + T = L; \ + L ^= R; \ + L &= 0xff00ff00; \ + R ^= L; \ + L ^= T; \ + ROR(R, 7); \ + T = L; \ + L ^= R; \ + L &= 0xaaaaaaaa; \ + R ^= L; \ + L ^= T; \ + ROL(L, 1); + +#define FP(L, R, T) \ + ROR(L, 1); \ + T = L; \ + L ^= R; \ + L &= 0xaaaaaaaa; \ + R ^= L; \ + L ^= T; \ + ROL(R, 7); \ + T = L; \ + L ^= R; \ + L &= 0xff00ff00; \ + R ^= L; \ + L ^= T; \ + ROR(R, 6); \ + T = L; \ + L ^= R; \ + L &= 0xcccccccc; \ + R ^= L; \ + L ^= T; \ + ROL(R, 14); \ + T = L; \ + L ^= R; \ + L &= 0xffff0000; \ + R ^= L; \ + L ^= T; \ + ROR(R, 12); \ + T = L; \ + L ^= R; \ + L &= 0xf0f0f0f0; \ + R ^= L; \ + L ^= T; \ + ROR(R, 4); + +#define ROUND(L, R, A, B, K, d) \ + B = K[0]; A = K[1]; K += d; \ + B ^= R; A ^= R; \ + B &= 0x3f3f3f3f; ROR(A, 4); \ + L ^= S8[0xff & B]; A &= 0x3f3f3f3f; \ + L ^= S6[0xff & (B >> 8)]; B >>= 16; \ + L ^= S7[0xff & A]; \ + L ^= S5[0xff & (A >> 8)]; A >>= 16; \ + L ^= S4[0xff & B]; \ + L ^= S2[0xff & (B >> 8)]; \ + L ^= S3[0xff & A]; \ + L ^= S1[0xff & (A >> 8)]; + +/* + * PC2 lookup tables are organized as 2 consecutive sets of 4 interleaved + * tables of 128 elements. One set is for C_i and the other for D_i, while + * the 4 interleaved tables correspond to four 7-bit subsets of C_i or D_i. + * + * After PC1 each of the variables a,b,c,d contains a 7 bit subset of C_i + * or D_i in bits 7-1 (bit 0 being the least significant). + */ + +#define T1(x) pt[2 * (x) + 0] +#define T2(x) pt[2 * (x) + 1] +#define T3(x) pt[2 * (x) + 2] +#define T4(x) pt[2 * (x) + 3] + +#define PC2(a, b, c, d) (T4(d) | T3(c) | T2(b) | T1(a)) /* + * Encryption key expansion + * * RFC2451: Weak key checks SHOULD be performed. + * + * FIPS 74: + * + * Keys having duals are keys which produce all zeros, all ones, or + * alternating zero-one patterns in the C and D registers after Permuted + * Choice 1 has operated on the key. + * */ -static int setkey(u32 *expkey, const u8 *key, unsigned int keylen, u32 *flags) +static unsigned long ekey(u32 *pe, const u8 *k) { - const u8 *k; - u8 *b0, *b1; - u32 n, w; - u8 bits0[56], bits1[56]; - - n = parity[key[0]]; n <<= 4; - n |= parity[key[1]]; n <<= 4; - n |= parity[key[2]]; n <<= 4; - n |= parity[key[3]]; n <<= 4; - n |= parity[key[4]]; n <<= 4; - n |= parity[key[5]]; n <<= 4; - n |= parity[key[6]]; n <<= 4; - n |= parity[key[7]]; - w = 0x88888888L; - - if ((*flags & CRYPTO_TFM_REQ_WEAK_KEY) - && !((n - (w >> 3)) & w)) { /* 1 in 10^10 keys passes this test */ - if (n < 0x41415151) { - if (n < 0x31312121) { - if (n < 0x14141515) { - /* 01 01 01 01 01 01 01 01 */ - if (n == 0x11111111) goto weak; - /* 01 1F 01 1F 01 0E 01 0E */ - if (n == 0x13131212) goto weak; - } else { - /* 01 E0 01 E0 01 F1 01 F1 */ - if (n == 0x14141515) goto weak; - /* 01 FE 01 FE 01 FE 01 FE */ - if (n == 0x16161616) goto weak; - } - } else { - if (n < 0x34342525) { - /* 1F 01 1F 01 0E 01 0E 01 */ - if (n == 0x31312121) goto weak; - /* 1F 1F 1F 1F 0E 0E 0E 0E (?) */ - if (n == 0x33332222) goto weak; - } else { - /* 1F E0 1F E0 0E F1 0E F1 */ - if (n == 0x34342525) goto weak; - /* 1F FE 1F FE 0E FE 0E FE */ - if (n == 0x36362626) goto weak; - } - } - } else { - if (n < 0x61616161) { - if (n < 0x44445555) { - /* E0 01 E0 01 F1 01 F1 01 */ - if (n == 0x41415151) goto weak; - /* E0 1F E0 1F F1 0E F1 0E */ - if (n == 0x43435252) goto weak; - } else { - /* E0 E0 E0 E0 F1 F1 F1 F1 (?) */ - if (n == 0x44445555) goto weak; - /* E0 FE E0 FE F1 FE F1 FE */ - if (n == 0x46465656) goto weak; - } - } else { - if (n < 0x64646565) { - /* FE 01 FE 01 FE 01 FE 01 */ - if (n == 0x61616161) goto weak; - /* FE 1F FE 1F FE 0E FE 0E */ - if (n == 0x63636262) goto weak; - } else { - /* FE E0 FE E0 FE F1 FE F1 */ - if (n == 0x64646565) goto weak; - /* FE FE FE FE FE FE FE FE */ - if (n == 0x66666666) goto weak; - } - } - } - - goto not_weak; -weak: - *flags |= CRYPTO_TFM_RES_WEAK_KEY; - return -EINVAL; + /* K&R: long is at least 32 bits */ + unsigned long a, b, c, d, w; + const u32 *pt = pc2; + + d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d]; + c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c]; + b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b]; + a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a]; + + pe[15 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; + pe[14 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[13 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[12 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[11 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[10 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 9 * 2 + 0] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 8 * 2 + 0] = PC2(d, a, b, c); c = rs[c]; + pe[ 7 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 6 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 5 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 4 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 3 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 2 * 2 + 0] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 1 * 2 + 0] = PC2(c, d, a, b); b = rs[b]; + pe[ 0 * 2 + 0] = PC2(b, c, d, a); + + /* Check if first half is weak */ + w = (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]); + + /* Skip to next table set */ + pt += 512; + + d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1]; + c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1]; + b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1]; + a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1]; + + /* Check if second half is weak */ + w |= (a ^ c) | (b ^ d) | (rs[a] ^ c) | (b ^ rs[d]); + + pe[15 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; + pe[14 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[13 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[12 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[11 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[10 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 9 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 8 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; + pe[ 7 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 6 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 5 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 4 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 3 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 2 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[ 1 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; + pe[ 0 * 2 + 1] = PC2(b, c, d, a); + + /* Fixup: 2413 5768 -> 1357 2468 */ + for (d = 0; d < 16; ++d) { + a = pe[2 * d]; + b = pe[2 * d + 1]; + c = a ^ b; + c &= 0xffff0000; + a ^= c; + b ^= c; + ROL(b, 18); + pe[2 * d] = a; + pe[2 * d + 1] = b; } -not_weak: - - /* explode the bits */ - n = 56; - b0 = bits0; - b1 = bits1; - - do { - w = (256 | *key++) << 2; - do { - --n; - b1[n] = 8 & w; - w >>= 1; - b0[n] = 4 & w; - } while ( w >= 16 ); - } while ( n ); - - /* put the bits in the correct places */ - n = 16; - k = rotors; - - do { - w = (b1[k[ 0 ]] | b0[k[ 1 ]]) << 4; - w |= (b1[k[ 2 ]] | b0[k[ 3 ]]) << 2; - w |= b1[k[ 4 ]] | b0[k[ 5 ]]; - w <<= 8; - w |= (b1[k[ 6 ]] | b0[k[ 7 ]]) << 4; - w |= (b1[k[ 8 ]] | b0[k[ 9 ]]) << 2; - w |= b1[k[10 ]] | b0[k[11 ]]; - w <<= 8; - w |= (b1[k[12 ]] | b0[k[13 ]]) << 4; - w |= (b1[k[14 ]] | b0[k[15 ]]) << 2; - w |= b1[k[16 ]] | b0[k[17 ]]; - w <<= 8; - w |= (b1[k[18 ]] | b0[k[19 ]]) << 4; - w |= (b1[k[20 ]] | b0[k[21 ]]) << 2; - w |= b1[k[22 ]] | b0[k[23 ]]; - expkey[0] = w; - - w = (b1[k[ 0+24]] | b0[k[ 1+24]]) << 4; - w |= (b1[k[ 2+24]] | b0[k[ 3+24]]) << 2; - w |= b1[k[ 4+24]] | b0[k[ 5+24]]; - w <<= 8; - w |= (b1[k[ 6+24]] | b0[k[ 7+24]]) << 4; - w |= (b1[k[ 8+24]] | b0[k[ 9+24]]) << 2; - w |= b1[k[10+24]] | b0[k[11+24]]; - w <<= 8; - w |= (b1[k[12+24]] | b0[k[13+24]]) << 4; - w |= (b1[k[14+24]] | b0[k[15+24]]) << 2; - w |= b1[k[16+24]] | b0[k[17+24]]; - w <<= 8; - w |= (b1[k[18+24]] | b0[k[19+24]]) << 4; - w |= (b1[k[20+24]] | b0[k[21+24]]) << 2; - w |= b1[k[22+24]] | b0[k[23+24]]; - - ROR(w, 4, 28); /* could be eliminated */ - expkey[1] = w; - - k += 48; - expkey += 2; - } while (--n); + /* Zero if weak key */ + return w; +} - return 0; +/* + * Decryption key expansion + * + * No weak key checking is performed, as this is only used by triple DES + * + */ +static void dkey(u32 *pe, const u8 *k) +{ + /* K&R: long is at least 32 bits */ + unsigned long a, b, c, d; + const u32 *pt = pc2; + + d = k[4]; d &= 0x0e; d <<= 4; d |= k[0] & 0x1e; d = pc1[d]; + c = k[5]; c &= 0x0e; c <<= 4; c |= k[1] & 0x1e; c = pc1[c]; + b = k[6]; b &= 0x0e; b <<= 4; b |= k[2] & 0x1e; b = pc1[b]; + a = k[7]; a &= 0x0e; a <<= 4; a |= k[3] & 0x1e; a = pc1[a]; + + pe[ 0 * 2] = PC2(a, b, c, d); d = rs[d]; + pe[ 1 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 2 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 3 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 4 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 5 * 2] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 6 * 2] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 7 * 2] = PC2(d, a, b, c); c = rs[c]; + pe[ 8 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 9 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[10 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[11 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[12 * 2] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[13 * 2] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[14 * 2] = PC2(c, d, a, b); b = rs[b]; + pe[15 * 2] = PC2(b, c, d, a); + + /* Skip to next table set */ + pt += 512; + + d = k[0]; d &= 0xe0; d >>= 4; d |= k[4] & 0xf0; d = pc1[d + 1]; + c = k[1]; c &= 0xe0; c >>= 4; c |= k[5] & 0xf0; c = pc1[c + 1]; + b = k[2]; b &= 0xe0; b >>= 4; b |= k[6] & 0xf0; b = pc1[b + 1]; + a = k[3]; a &= 0xe0; a >>= 4; a |= k[7] & 0xf0; a = pc1[a + 1]; + + pe[ 0 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; + pe[ 1 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 2 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 3 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 4 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 5 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; b = rs[b]; + pe[ 6 * 2 + 1] = PC2(b, c, d, a); a = rs[a]; d = rs[d]; + pe[ 7 * 2 + 1] = PC2(d, a, b, c); c = rs[c]; + pe[ 8 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[ 9 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[10 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[11 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[12 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; a = rs[a]; + pe[13 * 2 + 1] = PC2(a, b, c, d); d = rs[d]; c = rs[c]; + pe[14 * 2 + 1] = PC2(c, d, a, b); b = rs[b]; + pe[15 * 2 + 1] = PC2(b, c, d, a); + + /* Fixup: 2413 5768 -> 1357 2468 */ + for (d = 0; d < 16; ++d) { + a = pe[2 * d]; + b = pe[2 * d + 1]; + c = a ^ b; + c &= 0xffff0000; + a ^= c; + b ^= c; + ROL(b, 18); + pe[2 * d] = a; + pe[2 * d + 1] = b; + } } static int des_setkey(void *ctx, const u8 *key, unsigned int keylen, u32 *flags) { - return setkey(((struct des_ctx *)ctx)->expkey, key, keylen, flags); + struct des_ctx *dctx = ctx; + u32 tmp[DES_EXPKEY_WORDS]; + int ret; + + /* Expand to tmp */ + ret = ekey(tmp, key); + + if (unlikely(ret == 0) && (*flags & CRYPTO_TFM_REQ_WEAK_KEY)) { + *flags |= CRYPTO_TFM_RES_WEAK_KEY; + return -EINVAL; + } + + /* Copy to output */ + memcpy(dctx->expkey, tmp, sizeof(dctx->expkey)); + + return 0; } static void des_encrypt(void *ctx, u8 *dst, const u8 *src) { - des_small_fips_encrypt(((struct des_ctx *)ctx)->expkey, dst, src); + const u32 *K = ((struct des_ctx *)ctx)->expkey; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, 2); + ROUND(R, L, A, B, K, 2); + } + FP(R, L, A); + + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } static void des_decrypt(void *ctx, u8 *dst, const u8 *src) { - des_small_fips_decrypt(((struct des_ctx *)ctx)->expkey, dst, src); + const u32 *K = ((struct des_ctx *)ctx)->expkey + DES_EXPKEY_WORDS - 2; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, -2); + ROUND(R, L, A, B, K, -2); + } + FP(R, L, A); + + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } -/* +/* * RFC2451: * * For DES-EDE3, there is no known need to reject weak or @@ -1197,44 +859,86 @@ static void des_decrypt(void *ctx, u8 *dst, const u8 *src) * */ static int des3_ede_setkey(void *ctx, const u8 *key, - unsigned int keylen, u32 *flags) + unsigned int keylen, u32 *flags) { - unsigned int i, off; + const u32 *K = (const u32 *)key; struct des3_ede_ctx *dctx = ctx; + u32 *expkey = dctx->expkey; - if (!(memcmp(key, &key[DES_KEY_SIZE], DES_KEY_SIZE) && - memcmp(&key[DES_KEY_SIZE], &key[DES_KEY_SIZE * 2], - DES_KEY_SIZE))) { - + if (unlikely(!((K[0] ^ K[2]) | (K[1] ^ K[3])) || + !((K[2] ^ K[4]) | (K[3] ^ K[5])))) + { *flags |= CRYPTO_TFM_RES_BAD_KEY_SCHED; return -EINVAL; } - - for (i = 0, off = 0; i < 3; i++, off += DES_EXPKEY_WORDS, - key += DES_KEY_SIZE) { - int ret = setkey(&dctx->expkey[off], key, DES_KEY_SIZE, flags); - if (ret < 0) - return ret; - } + + ekey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE; + dkey(expkey, key); expkey += DES_EXPKEY_WORDS; key += DES_KEY_SIZE; + ekey(expkey, key); + return 0; } static void des3_ede_encrypt(void *ctx, u8 *dst, const u8 *src) { struct des3_ede_ctx *dctx = ctx; - - des_small_fips_encrypt(dctx->expkey, dst, src); - des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst); - des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, dst); + const u32 *K = dctx->expkey; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, 2); + ROUND(R, L, A, B, K, 2); + } + for (i = 0; i < 8; i++) { + ROUND(R, L, A, B, K, 2); + ROUND(L, R, A, B, K, 2); + } + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, 2); + ROUND(R, L, A, B, K, 2); + } + FP(R, L, A); + + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } static void des3_ede_decrypt(void *ctx, u8 *dst, const u8 *src) { struct des3_ede_ctx *dctx = ctx; + const u32 *K = dctx->expkey + DES3_EDE_EXPKEY_WORDS - 2; + const __le32 *s = (const __le32 *)src; + __le32 *d = (__le32 *)dst; + u32 L, R, A, B; + int i; + + L = le32_to_cpu(s[0]); + R = le32_to_cpu(s[1]); + + IP(L, R, A); + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, -2); + ROUND(R, L, A, B, K, -2); + } + for (i = 0; i < 8; i++) { + ROUND(R, L, A, B, K, -2); + ROUND(L, R, A, B, K, -2); + } + for (i = 0; i < 8; i++) { + ROUND(L, R, A, B, K, -2); + ROUND(R, L, A, B, K, -2); + } + FP(R, L, A); - des_small_fips_decrypt(&dctx->expkey[DES_EXPKEY_WORDS * 2], dst, src); - des_small_fips_encrypt(&dctx->expkey[DES_EXPKEY_WORDS], dst, dst); - des_small_fips_decrypt(dctx->expkey, dst, dst); + d[0] = cpu_to_le32(R); + d[1] = cpu_to_le32(L); } static struct crypto_alg des_alg = { @@ -1247,7 +951,7 @@ static struct crypto_alg des_alg = { .cra_u = { .cipher = { .cia_min_keysize = DES_KEY_SIZE, .cia_max_keysize = DES_KEY_SIZE, - .cia_setkey = des_setkey, + .cia_setkey = des_setkey, .cia_encrypt = des_encrypt, .cia_decrypt = des_decrypt } } }; @@ -1262,9 +966,9 @@ static struct crypto_alg des3_ede_alg = { .cra_u = { .cipher = { .cia_min_keysize = DES3_EDE_KEY_SIZE, .cia_max_keysize = DES3_EDE_KEY_SIZE, - .cia_setkey = des3_ede_setkey, - .cia_encrypt = des3_ede_encrypt, - .cia_decrypt = des3_ede_decrypt } } + .cia_setkey = des3_ede_setkey, + .cia_encrypt = des3_ede_encrypt, + .cia_decrypt = des3_ede_decrypt } } }; MODULE_ALIAS("des3_ede"); @@ -1272,7 +976,7 @@ MODULE_ALIAS("des3_ede"); static int __init init(void) { int ret = 0; - + ret = crypto_register_alg(&des_alg); if (ret < 0) goto out; @@ -1280,7 +984,7 @@ static int __init init(void) ret = crypto_register_alg(&des3_ede_alg); if (ret < 0) crypto_unregister_alg(&des_alg); -out: +out: return ret; } @@ -1295,3 +999,4 @@ module_exit(fini); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("DES & Triple DES EDE Cipher Algorithms"); +MODULE_AUTHOR("Dag Arne Osvik "); -- cgit v1.1 From d1d890edace65721e9a7582545c943f67f500709 Mon Sep 17 00:00:00 2001 From: Catalin Marinas Date: Wed, 6 Jul 2005 23:06:03 +0100 Subject: [PATCH] ARM: 2789/1: Enable access to both CP10 and CP11 on ARMv6 Patch from Catalin Marinas The VFP instructions trigger undefined exceptions because the access to CP11 is disabled (only CP10 is currently enabled by the kernel). The patch fixes this problem. Signed-off-by: Catalin Marinas Signed-off-by: Russell King --- arch/arm/mm/proc-v6.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S index e3d8510..352db98 100644 --- a/arch/arm/mm/proc-v6.S +++ b/arch/arm/mm/proc-v6.S @@ -200,7 +200,7 @@ __v6_setup: mcr p15, 0, r4, c2, c0, 1 @ load TTB1 #ifdef CONFIG_VFP mrc p15, 0, r0, c1, c0, 2 - orr r0, r0, #(3 << 20) + orr r0, r0, #(0xf << 20) mcr p15, 0, r0, c1, c0, 2 @ Enable full access to VFP #endif mrc p15, 0, r0, c1, c0, 0 @ read control register -- cgit v1.1 From bcaafbe4a14e3c9b5275b3986c7599f7c6c278e4 Mon Sep 17 00:00:00 2001 From: Stefan Sorensen Date: Wed, 6 Jul 2005 23:06:04 +0100 Subject: [PATCH] ARM: 2790/1: Properly terminate plat_serial8250_port arrays on ixdp425 and coyote Patch from Stefan Sorensen On the ixdp425 and coyote platforms, the plat_serial8250_port arrays are missing the terminating entry required by serial8250_probe. Signed-off-by: Stefan Sorensen Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/coyote-setup.c | 27 +++++++++++++++------------ arch/arm/mach-ixp4xx/ixdp425-setup.c | 3 ++- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index c6335f5..4ff4393 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c @@ -56,21 +56,24 @@ static struct resource coyote_uart_resource = { .flags = IORESOURCE_MEM, }; -static struct plat_serial8250_port coyote_uart_data = { - .mapbase = IXP4XX_UART2_BASE_PHYS, - .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, - .irq = IRQ_IXP4XX_UART2, - .flags = UPF_BOOT_AUTOCONF, - .iotype = UPIO_MEM, - .regshift = 2, - .uartclk = IXP4XX_UART_XTAL, +static struct plat_serial8250_port coyote_uart_data[] = { + { + .mapbase = IXP4XX_UART2_BASE_PHYS, + .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET, + .irq = IRQ_IXP4XX_UART2, + .flags = UPF_BOOT_AUTOCONF, + .iotype = UPIO_MEM, + .regshift = 2, + .uartclk = IXP4XX_UART_XTAL, + }, + { }, }; static struct platform_device coyote_uart = { .name = "serial8250", .id = 0, .dev = { - .platform_data = &coyote_uart_data, + .platform_data = coyote_uart_data, }, .num_resources = 1, .resource = &coyote_uart_resource, @@ -87,10 +90,10 @@ static void __init coyote_init(void) *IXP4XX_EXP_CS1 = *IXP4XX_EXP_CS0; if (machine_is_ixdpg425()) { - coyote_uart_data.membase = + coyote_uart_data[0].membase = (char*)(IXP4XX_UART1_BASE_VIRT + REG_OFFSET); - coyote_uart_data.mapbase = IXP4XX_UART1_BASE_PHYS; - coyote_uart_data.irq = IRQ_IXP4XX_UART1; + coyote_uart_data[0].mapbase = IXP4XX_UART1_BASE_PHYS; + coyote_uart_data[0].irq = IRQ_IXP4XX_UART1; } diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index f2e9c0e..c2ba759 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c @@ -95,7 +95,8 @@ static struct plat_serial8250_port ixdp425_uart_data[] = { .iotype = UPIO_MEM, .regshift = 2, .uartclk = IXP4XX_UART_XTAL, - } + }, + { }, }; static struct platform_device ixdp425_uart = { -- cgit v1.1 From 7bc7fc50ce272d9a68f8e11707cfc2cc94f4e8f5 Mon Sep 17 00:00:00 2001 From: Todd Poynor Date: Wed, 6 Jul 2005 23:06:05 +0100 Subject: [PATCH] ARM: 2791/1: Add CRCs for aliased ARM symbols Patch from Todd Poynor Fix module versioning for 3 ARM symbols that do not have CRCs added, avoid "disagrees about version of symbol struct_module" errors at module load time. From David Singleton. Signed-off-by: Todd Poynor Signed-off-by: Russell King --- arch/arm/kernel/armksyms.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index b713c44..835d450 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -41,7 +41,10 @@ extern void fp_enter(void); * This has a special calling convention; it doesn't * modify any of the usual registers, except for LR. */ +#define EXPORT_CRC_ALIAS(sym) __CRC_SYMBOL(sym, "") + #define EXPORT_SYMBOL_ALIAS(sym,orig) \ + EXPORT_CRC_ALIAS(sym) \ const struct kernel_symbol __ksymtab_##sym \ __attribute__((section("__ksymtab"))) = \ { (unsigned long)&orig, #sym }; -- cgit v1.1 From 450008b5a62bb09445ae05c4d01d510386c9435d Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Wed, 6 Jul 2005 23:06:05 +0100 Subject: [PATCH] ARM: 2792/1: IXP4xx iomap API implementation Patch from Deepak Saxena This patch implements the iomap API for Intel IXP4xx NPU systems. We need to implement our own version of the API functions b/c of the PCI hostbridge does not provide the capability to map PCI I/O space into the CPU's physical memory space. In addition, if a system has more than 64M of PCI memory mapped BARs, PCI memory must also be accessed indirectly. This patch changes the assignment of PCI I/O resources to fall into to 0x0000:0xffff range so that we can trap I/O areas in our ioread/iowrite macros. Signed-off-by: Deepak Saxena Signed-off-by: Russell King --- arch/arm/mach-ixp4xx/common-pci.c | 4 +- include/asm-arm/arch-ixp4xx/io.h | 176 +++++++++++++++++++++++++++++++++++++- 2 files changed, 177 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index aa92e37..2b54436 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c @@ -453,8 +453,8 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys) local_write_config(PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); res[0].name = "PCI I/O Space"; - res[0].start = 0x00001000; - res[0].end = 0xffff0000; + res[0].start = 0x00000000; + res[0].end = 0x0000ffff; res[0].flags = IORESOURCE_IO; res[1].name = "PCI Memory Space"; diff --git a/include/asm-arm/arch-ixp4xx/io.h b/include/asm-arm/arch-ixp4xx/io.h index c27b9d3..7495026 100644 --- a/include/asm-arm/arch-ixp4xx/io.h +++ b/include/asm-arm/arch-ixp4xx/io.h @@ -3,7 +3,7 @@ * * Author: Deepak Saxena * - * Copyright (C) 2002-2004 MontaVista Software, Inc. + * Copyright (C) 2002-2005 MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -383,6 +383,180 @@ __ixp4xx_insl(u32 io_addr, u32 *vaddr, u32 count) *vaddr++ = inl(io_addr); } +#define __is_io_address(p) (((unsigned long)p >= 0x0) && \ + ((unsigned long)p <= 0x0000ffff)) +static inline unsigned int +__ixp4xx_ioread8(void __iomem *port) +{ + if (__is_io_address(port)) + return (unsigned int)__ixp4xx_inb((unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + return (unsigned int)__raw_readb((u32)port); +#else + return (unsigned int)__ixp4xx_readb((u32)port); +#endif +} + +static inline void +__ixp4xx_ioread8_rep(u32 port, u8 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_insb(port, vaddr, count); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsb((void __iomem *)port, vaddr, count); +#else + __ixp4xx_readsb(port, vaddr, count); +#endif +} + +static inline unsigned int +__ixp4xx_ioread16(void __iomem *port) +{ + if (__is_io_address(port)) + return (unsigned int)__ixp4xx_inw((unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + return le16_to_cpu(__raw_readw((u32)port)); +#else + return (unsigned int)__ixp4xx_readw((u32)port); +#endif +} + +static inline void +__ixp4xx_ioread16_rep(u32 port, u16 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_insw(port, vaddr, count); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsw((void __iomem *)port, vaddr, count); +#else + __ixp4xx_readsw(port, vaddr, count); +#endif +} + +static inline unsigned int +__ixp4xx_ioread32(void __iomem *port) +{ + if (__is_io_address(port)) + return (unsigned int)__ixp4xx_inl((unsigned int)port); + else { +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + return le32_to_cpu(__raw_readl((u32)port)); +#else + return (unsigned int)__ixp4xx_readl((u32)port); +#endif + } +} + +static inline void +__ixp4xx_ioread32_rep(u32 port, u32 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_insl(port, vaddr, count); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsl((void __iomem *)port, vaddr, count); +#else + __ixp4xx_readsl(port, vaddr, count); +#endif +} + +static inline void +__ixp4xx_iowrite8(u8 value, void __iomem *port) +{ + if (__is_io_address(port)) + __ixp4xx_outb(value, (unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writeb(value, (u32)port); +#else + __ixp4xx_writeb(value, (u32)port); +#endif +} + +static inline void +__ixp4xx_iowrite8_rep(u32 port, u8 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_outsb(port, vaddr, count); +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writesb((void __iomem *)port, vaddr, count); +#else + __ixp4xx_writesb(port, vaddr, count); +#endif +} + +static inline void +__ixp4xx_iowrite16(u16 value, void __iomem *port) +{ + if (__is_io_address(port)) + __ixp4xx_outw(value, (unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writew(cpu_to_le16(value), (u32)port); +#else + __ixp4xx_writew(value, (u32)port); +#endif +} + +static inline void +__ixp4xx_iowrite16_rep(u32 port, u16 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_outsw(port, vaddr, count); +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsw((void __iomem *)port, vaddr, count); +#else + __ixp4xx_writesw(port, vaddr, count); +#endif +} + +static inline void +__ixp4xx_iowrite32(u32 value, void __iomem *port) +{ + if (__is_io_address(port)) + __ixp4xx_outl(value, (unsigned int)port); + else +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_writel(cpu_to_le32(value), (u32)port); +#else + __ixp4xx_writel(value, (u32)port); +#endif +} + +static inline void +__ixp4xx_iowrite32_rep(u32 port, u32 *vaddr, u32 count) +{ + if (__is_io_address(port)) + __ixp4xx_outsl(port, vaddr, count); +#ifndef CONFIG_IXP4XX_INDIRECT_PCI + __raw_readsl((void __iomem *)port, vaddr, count); +#else + __ixp4xx_outsl(port, vaddr, count); +#endif +} + +#define ioread8(p) __ixp4xx_ioread8(p) +#define ioread16(p) __ixp4xx_ioread16(p) +#define ioread32(p) __ixp4xx_ioread32(p) + +#define ioread8_rep(p, v, c) __ixp4xx_ioread8_rep(p, v, c) +#define ioread16_rep(p, v, c) __ixp4xx_ioread16_rep(p, v, c) +#define ioread32_rep(p, v, c) __ixp4xx_ioread32_rep(p, v, c) + +#define iowrite8(v,p) __ixp4xx_iowrite8(v,p) +#define iowrite16(v,p) __ixp4xx_iowrite16(v,p) +#define iowrite32(v,p) __ixp4xx_iowrite32(v,p) + +#define iowrite8_rep(p, v, c) __ixp4xx_iowrite8_rep(p, v, c) +#define iowrite16_rep(p, v, c) __ixp4xx_iowrite16_rep(p, v, c) +#define iowrite32_rep(p, v, c) __ixp4xx_iowrite32_rep(p, v, c) + +#define ioport_map(port, nr) ((void __iomem*)port) +#define ioport_unmap(addr) #endif // __ASM_ARM_ARCH_IO_H -- cgit v1.1 From 90cdba648c5edf0ccabdadfc6e61f40c04e8bb00 Mon Sep 17 00:00:00 2001 From: "Eddie C. Dost" Date: Wed, 6 Jul 2005 15:37:58 -0700 Subject: [SPARC]: Fix "Eddie C. Dost" e-mail address Signed-off-by: David S. Miller --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 19a9a1c..302b319 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2161,7 +2161,7 @@ UltraSPARC (sparc64): P: David S. Miller M: davem@davemloft.net P: Eddie C. Dost -M: ecd@skynet.be +M: ecd@brainaid.de P: Jakub Jelinek M: jj@sunsite.ms.mff.cuni.cz P: Anton Blanchard -- cgit v1.1 From 12cf649f417c68b6bdd2a3b4ed97113159c6029e Mon Sep 17 00:00:00 2001 From: "Eddie C. Dost" Date: Wed, 6 Jul 2005 15:40:21 -0700 Subject: [SPARC64]: Fix set_intr_affinity() Do not cat bucket->irq_info to struct irqaction * directly, but go through struct irq_desc *. Signed-off-by: David S. Miller --- arch/sparc64/kernel/irq.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index 74a2e08..daa2fb9 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c @@ -917,7 +917,8 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { struct ino_bucket *bp = ivector_table + (long)data; - struct irqaction *ap = bp->irq_info; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; cpumask_t mask; int len; @@ -935,11 +936,13 @@ static int irq_affinity_read_proc (char *page, char **start, off_t off, static inline void set_intr_affinity(int irq, cpumask_t hw_aff) { struct ino_bucket *bp = ivector_table + irq; + struct irq_desc *desc = bp->irq_info; + struct irqaction *ap = desc->action; /* Users specify affinity in terms of hw cpu ids. * As soon as we do this, handler_irq() might see and take action. */ - put_smpaff_in_irqaction((struct irqaction *)bp->irq_info, hw_aff); + put_smpaff_in_irqaction(ap, hw_aff); /* Migration is simply done by the next cpu to service this * interrupt. -- cgit v1.1 From 9d7495330be2fd88ab939fa5080d3ca9f64368c2 Mon Sep 17 00:00:00 2001 From: "Eddie C. Dost" Date: Wed, 6 Jul 2005 15:41:17 -0700 Subject: [DVB]: Do not include from drivers. Signed-off-by: David S. Miller --- drivers/media/dvb/frontends/tda80xx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c index 032d348..88e1250 100644 --- a/drivers/media/dvb/frontends/tda80xx.c +++ b/drivers/media/dvb/frontends/tda80xx.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include -- cgit v1.1 From e3e01d6005ab4b0877f1fb3efef7f5b745e743be Mon Sep 17 00:00:00 2001 From: "Eddie C. Dost" Date: Wed, 6 Jul 2005 15:41:54 -0700 Subject: [SPARC64]: Fix enable_dma() in asm-sparc64/parport.h Call ebus_dma_enable() before calling ebus_dma_request(), otherwise ebus_dma_request() returns -EINVAL and enable_dma() calls BUG()... Signed-off-by: David S. Miller --- include/asm-sparc64/parport.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/asm-sparc64/parport.h b/include/asm-sparc64/parport.h index b7e6355..56b5197d 100644 --- a/include/asm-sparc64/parport.h +++ b/include/asm-sparc64/parport.h @@ -27,12 +27,12 @@ static struct sparc_ebus_info { static __inline__ void enable_dma(unsigned int dmanr) { + ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); + if (ebus_dma_request(&sparc_ebus_dmas[dmanr].info, sparc_ebus_dmas[dmanr].addr, sparc_ebus_dmas[dmanr].count)) BUG(); - - ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1); } static __inline__ void disable_dma(unsigned int dmanr) -- cgit v1.1 From 960b8466548c9bc6f718b5f470c1a58000fab09d Mon Sep 17 00:00:00 2001 From: Ivan Kokshaysky Date: Thu, 7 Jul 2005 03:07:56 +0400 Subject: [PATCH] yet another fix for setup-bus.c/x86 merge There is a slight disagreement between setup-bus.c code and traditional x86 PCI setup wrt which recourses are invalid vs resources that are free for further allocations. In particular, in the setup-bus.c, if we failed to allocate some resource, we nullify "start" and "flags" fields, but *not* the "end" one. But x86 pcibios_enable_resources() does the following check: if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev)); return -EINVAL; which means that the device owning the offending resource cannot be enabled. In particular, this breaks cardbus behind the normal decode p2p bridge - the cardbus code from setup-bus.c requests rather large IO and MEM windows, and if it fails, the socket is completely unavailable. Which is wrong, as the yenta code is capable to allocate smaller windows. Signed-off-by: Ivan Kokshaysky Signed-off-by: Linus Torvalds --- drivers/pci/setup-bus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index c1bdfb4..9fe48f7 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -74,6 +74,7 @@ pbus_assign_resources_sorted(struct pci_bus *bus) idx = res - &list->dev->resource[0]; if (pci_assign_resource(list->dev, idx)) { res->start = 0; + res->end = 0; res->flags = 0; } tmp = list; -- cgit v1.1