diff options
| author | Paul Mackerras <paulus@samba.org> | 2002-12-25 15:20:55 +1100 |
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2002-12-25 15:20:55 +1100 |
| commit | 888b567c962f0e0cccbd10d24e37c1f8ece507cb (patch) | |
| tree | 4e22422b91006202b193e7f79e52deea345201ef /include | |
| parent | 75528e466f18a2f2cd431f6c3fe27119317bb629 (diff) | |
| parent | 5e32ae7ed6f1dd53fbdd9c3540f4b1dcbcc0c5ef (diff) | |
Merge samba.org:/home/paulus/kernel/linux-2.5
into samba.org:/home/paulus/kernel/for-linus-ppc
Diffstat (limited to 'include')
34 files changed, 1109 insertions, 17 deletions
diff --git a/include/asm-i386/mach-default/do_timer.h b/include/asm-i386/mach-default/do_timer.h new file mode 100644 index 000000000000..e41ce3fe29da --- /dev/null +++ b/include/asm-i386/mach-default/do_timer.h @@ -0,0 +1,82 @@ +/* defines for inline arch setup functions */ + +#include <asm/apic.h> + +/** + * do_timer_interrupt_hook - hook into timer tick + * @regs: standard registers from interrupt + * + * Description: + * This hook is called immediately after the timer interrupt is ack'd. + * It's primary purpose is to allow architectures that don't possess + * individual per CPU clocks (like the CPU APICs supply) to broadcast the + * timer interrupt as a means of triggering reschedules etc. + **/ + +static inline void do_timer_interrupt_hook(struct pt_regs *regs) +{ + do_timer(regs); +/* + * In the SMP case we use the local APIC timer interrupt to do the + * profiling, except when we simulate SMP mode on a uniprocessor + * system, in that case we have to call the local interrupt handler. + */ +#ifndef CONFIG_X86_LOCAL_APIC + x86_do_profile(regs); +#else + if (!using_apic_timer) + smp_local_timer_interrupt(regs); +#endif +} + + +/* you can safely undefine this if you don't have the Neptune chipset */ + +#define BUGGY_NEPTUN_TIMER + +/** + * do_timer_overflow - process a detected timer overflow condition + * @count: hardware timer interrupt count on overflow + * + * Description: + * This call is invoked when the jiffies count has not incremented but + * the hardware timer interrupt has. It means that a timer tick interrupt + * came along while the previous one was pending, thus a tick was missed + **/ +static inline int do_timer_overflow(int count) +{ + int i; + + spin_lock(&i8259A_lock); + /* + * This is tricky when I/O APICs are used; + * see do_timer_interrupt(). + */ + i = inb(0x20); + spin_unlock(&i8259A_lock); + + /* assumption about timer being IRQ0 */ + if (i & 0x01) { + /* + * We cannot detect lost timer interrupts ... + * well, that's why we call them lost, don't we? :) + * [hmm, on the Pentium and Alpha we can ... sort of] + */ + count -= LATCH; + } else { +#ifdef BUGGY_NEPTUN_TIMER + /* + * for the Neptun bug we know that the 'latch' + * command doesnt latch the high and low value + * of the counter atomically. Thus we have to + * substract 256 from the counter + * ... funny, isnt it? :) + */ + + count -= 256; +#else + printk("do_slow_gettimeoffset(): hardware timer problem?\n"); +#endif + } + return count; +} diff --git a/include/asm-i386/mach-default/entry_arch.h b/include/asm-i386/mach-default/entry_arch.h new file mode 100644 index 000000000000..bc861469bdba --- /dev/null +++ b/include/asm-i386/mach-default/entry_arch.h @@ -0,0 +1,34 @@ +/* + * This file is designed to contain the BUILD_INTERRUPT specifications for + * all of the extra named interrupt vectors used by the architecture. + * Usually this is the Inter Process Interrupts (IPIs) + */ + +/* + * The following vectors are part of the Linux architecture, there + * is no hardware IRQ pin equivalent for them, they are triggered + * through the ICC by us (IPIs) + */ +#ifdef CONFIG_X86_SMP +BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) +BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) +BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) +#endif + +/* + * every pentium local APIC has two 'local interrupts', with a + * soft-definable vector attached to both interrupts, one of + * which is a timer interrupt, the other one is error counter + * overflow. Linux uses the local APIC timer interrupt to get + * a much simpler SMP time architecture: + */ +#ifdef CONFIG_X86_LOCAL_APIC +BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) +BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) +BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) + +#ifdef CONFIG_X86_MCE_P4THERMAL +BUILD_INTERRUPT(thermal_interrupt,THERMAL_APIC_VECTOR) +#endif + +#endif diff --git a/include/asm-i386/mach-default/irq_vectors.h b/include/asm-i386/mach-default/irq_vectors.h new file mode 100644 index 000000000000..6963e978ffae --- /dev/null +++ b/include/asm-i386/mach-default/irq_vectors.h @@ -0,0 +1,85 @@ +/* + * This file should contain #defines for all of the interrupt vector + * numbers used by this architecture. + * + * In addition, there are some standard defines: + * + * FIRST_EXTERNAL_VECTOR: + * The first free place for external interrupts + * + * SYSCALL_VECTOR: + * The IRQ vector a syscall makes the user to kernel transition + * under. + * + * TIMER_IRQ: + * The IRQ number the timer interrupt comes in at. + * + * NR_IRQS: + * The total number of interrupt vectors (including all the + * architecture specific interrupts) needed. + * + */ +#ifndef _ASM_IRQ_VECTORS_H +#define _ASM_IRQ_VECTORS_H + +/* + * IDT vectors usable for external interrupt sources start + * at 0x20: + */ +#define FIRST_EXTERNAL_VECTOR 0x20 + +#define SYSCALL_VECTOR 0x80 + +/* + * Vectors 0x20-0x2f are used for ISA interrupts. + */ + +/* + * Special IRQ vectors used by the SMP architecture, 0xf0-0xff + * + * some of the following vectors are 'rare', they are merged + * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. + * TLB, reschedule and local APIC vectors are performance-critical. + * + * Vectors 0xf0-0xfa are free (reserved for future Linux use). + */ +#define SPURIOUS_APIC_VECTOR 0xff +#define ERROR_APIC_VECTOR 0xfe +#define INVALIDATE_TLB_VECTOR 0xfd +#define RESCHEDULE_VECTOR 0xfc +#define CALL_FUNCTION_VECTOR 0xfb + +#define THERMAL_APIC_VECTOR 0xf0 +/* + * Local APIC timer IRQ vector is on a different priority level, + * to work around the 'lost local interrupt if more than 2 IRQ + * sources per level' errata. + */ +#define LOCAL_TIMER_VECTOR 0xef + +/* + * First APIC vector available to drivers: (vectors 0x30-0xee) + * we start at 0x31 to spread out vectors evenly between priority + * levels. (0x80 is the syscall vector) + */ +#define FIRST_DEVICE_VECTOR 0x31 +#define FIRST_SYSTEM_VECTOR 0xef + +#define TIMER_IRQ 0 + +/* + * 16 8259A IRQ's, 208 potential APIC interrupt sources. + * Right now the APIC is mostly only used for SMP. + * 256 vectors is an architectural limit. (we can have + * more than 256 devices theoretically, but they will + * have to use shared interrupts) + * Since vectors 0x00-0x1f are used/reserved for the CPU, + * the usable vector space is 0x20-0xff (224 vectors) + */ +#ifdef CONFIG_X86_IO_APIC +#define NR_IRQS 224 +#else +#define NR_IRQS 16 +#endif + +#endif /* _ASM_IRQ_VECTORS_H */ diff --git a/include/asm-i386/mach-default/mach_apic.h b/include/asm-i386/mach-default/mach_apic.h new file mode 100644 index 000000000000..a24df01ffe2e --- /dev/null +++ b/include/asm-i386/mach-default/mach_apic.h @@ -0,0 +1,83 @@ +#ifndef __ASM_MACH_APIC_H +#define __ASM_MACH_APIC_H + +#define APIC_DFR_VALUE (APIC_DFR_FLAT) + +#ifdef CONFIG_SMP + #define TARGET_CPUS (cpu_online_map) +#else + #define TARGET_CPUS 0x01 +#endif + +#define no_balance_irq (0) + +#define APIC_BROADCAST_ID 0x0F +#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid)) + +static inline int apic_id_registered(void) +{ + return (test_bit(GET_APIC_ID(apic_read(APIC_ID)), + &phys_cpu_present_map)); +} + +/* + * Set up the logical destination ID. + * + * Intel recommends to set DFR, LDR and TPR before enabling + * an APIC. See e.g. "AP-388 82489DX User's Manual" (Intel + * document number 292116). So here it goes... + */ +static inline void init_apic_ldr(void) +{ + unsigned long val; + + apic_write_around(APIC_DFR, APIC_DFR_VALUE); + val = apic_read(APIC_LDR) & ~APIC_LDR_MASK; + val |= SET_APIC_LOGICAL_ID(1UL << smp_processor_id()); + apic_write_around(APIC_LDR, val); +} + +static inline ulong ioapic_phys_id_map(ulong phys_map) +{ + return phys_map; +} + +static inline void clustered_apic_check(void) +{ + printk("Enabling APIC mode: %s. Using %d I/O APICs\n", + "Flat", nr_ioapics); +} + +static inline int multi_timer_check(int apic, int irq) +{ + return 0; +} + +static inline int cpu_present_to_apicid(int mps_cpu) +{ + return mps_cpu; +} + +static inline unsigned long apicid_to_cpu_present(int phys_apicid) +{ + return (1ul << phys_apicid); +} + +static inline int mpc_apic_id(struct mpc_config_processor *m, int quad) +{ + printk("Processor #%d %ld:%ld APIC version %d\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver); + return (m->mpc_apicid); +} + +#define wakeup_secondary_cpu(apicid, start_eip) \ + wakeup_secondary_via_INIT(apicid, start_eip) + +static inline void setup_portio_remap(void) +{ +} + +#endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-default/mach_ipi.h b/include/asm-i386/mach-default/mach_ipi.h new file mode 100644 index 000000000000..481692a7b885 --- /dev/null +++ b/include/asm-i386/mach-default/mach_ipi.h @@ -0,0 +1,30 @@ +#ifndef __ASM_MACH_IPI_H +#define __ASM_MACH_IPI_H + +static inline void send_IPI_mask_bitmask(int mask, int vector); +static inline void __send_IPI_shortcut(unsigned int shortcut, int vector); + +static inline void send_IPI_mask(int mask, int vector) +{ + send_IPI_mask_bitmask(mask, vector); +} + +static inline void send_IPI_allbutself(int vector) +{ + /* + * if there are no other CPUs in the system then we get an APIC send + * error if we try to broadcast, thus avoid sending IPIs in this case. + */ + if (!(num_online_cpus() > 1)) + return; + + __send_IPI_shortcut(APIC_DEST_ALLBUT, vector); + return; +} + +static inline void send_IPI_all(int vector) +{ + __send_IPI_shortcut(APIC_DEST_ALLINC, vector); +} + +#endif /* __ASM_MACH_IPI_H */ diff --git a/include/asm-i386/mach-default/mach_mpparse.h b/include/asm-i386/mach-default/mach_mpparse.h new file mode 100644 index 000000000000..20a41976843d --- /dev/null +++ b/include/asm-i386/mach-default/mach_mpparse.h @@ -0,0 +1,20 @@ +#ifndef __ASM_MACH_MPPARSE_H +#define __ASM_MACH_MPPARSE_H + +static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, + struct mpc_config_translation *translation) +{ + Dprintk("Bus #%d is %s\n", m->mpc_busid, name); +} + +static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, + struct mpc_config_translation *translation) +{ +} + +static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ +} + +#endif /* __ASM_MACH_MPPARSE_H */ diff --git a/include/asm-i386/mach-default/setup_arch_post.h b/include/asm-i386/mach-default/setup_arch_post.h new file mode 100644 index 000000000000..43b3b2d1fa11 --- /dev/null +++ b/include/asm-i386/mach-default/setup_arch_post.h @@ -0,0 +1,40 @@ +/** + * machine_specific_memory_setup - Hook for machine specific memory setup. + * + * Description: + * This is included late in kernel/setup.c so that it can make + * use of all of the static functions. + **/ + +static inline char * __init machine_specific_memory_setup(void) +{ + char *who; + + + who = "BIOS-e820"; + + /* + * Try to copy the BIOS-supplied E820-map. + * + * Otherwise fake a memory map; one section from 0k->640k, + * the next section from 1mb->appropriate_mem_k + */ + sanitize_e820_map(E820_MAP, &E820_MAP_NR); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } + return who; +} diff --git a/include/asm-i386/mach-default/setup_arch_pre.h b/include/asm-i386/mach-default/setup_arch_pre.h new file mode 100644 index 000000000000..fb42099e7bd4 --- /dev/null +++ b/include/asm-i386/mach-default/setup_arch_pre.h @@ -0,0 +1,5 @@ +/* Hook to call BIOS initialisation function */ + +/* no action for generic */ + +#define ARCH_SETUP diff --git a/include/asm-i386/mach-default/smpboot_hooks.h b/include/asm-i386/mach-default/smpboot_hooks.h new file mode 100644 index 000000000000..868a41933c68 --- /dev/null +++ b/include/asm-i386/mach-default/smpboot_hooks.h @@ -0,0 +1,33 @@ +/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws + * which needs to alter them. */ + +static inline void smpboot_clear_io_apic_irqs(void) +{ + io_apic_irqs = 0; +} + +static inline void smpboot_setup_warm_reset_vector(void) +{ + /* + * Install writable page 0 entry to set BIOS data area. + */ + local_flush_tlb(); + + /* + * Paranoid: Set warm reset code and vector here back + * to default values. + */ + CMOS_WRITE(0, 0xf); + + *((volatile long *) phys_to_virt(0x467)) = 0; +} + +static inline void smpboot_setup_io_apic(void) +{ + /* + * Here we can be sure that there is an IO-APIC in the system. Let's + * go and set it up: + */ + if (!skip_ioapic_setup && nr_ioapics) + setup_IO_APIC(); +} diff --git a/include/asm-i386/mach-numaq/mach_apic.h b/include/asm-i386/mach-numaq/mach_apic.h new file mode 100644 index 000000000000..be8eacb32aa0 --- /dev/null +++ b/include/asm-i386/mach-numaq/mach_apic.h @@ -0,0 +1,86 @@ +#ifndef __ASM_MACH_APIC_H +#define __ASM_MACH_APIC_H + +#define APIC_DFR_VALUE (APIC_DFR_FLAT) + +#define TARGET_CPUS (0xf) + +#define no_balance_irq (1) + +#define APIC_BROADCAST_ID 0x0F +#define check_apicid_used(bitmap, apicid) (bitmap & (1 << apicid)) + +static inline int apic_id_registered(void) +{ + return (1); +} + +static inline void init_apic_ldr(void) +{ + /* Already done in NUMA-Q firmware */ +} + +static inline void clustered_apic_check(void) +{ + printk("Enabling APIC mode: %s. Using %d I/O APICs\n", + "NUMA-Q", nr_ioapics); +} + +static inline int multi_timer_check(int apic, int irq) +{ + return (apic != 0 && irq == 0); +} + +static inline ulong ioapic_phys_id_map(ulong phys_map) +{ + /* We don't have a good way to do this yet - hack */ + return 0xf; +} + +static inline int cpu_present_to_apicid(int mps_cpu) +{ + return ( ((mps_cpu/4)*16) + (1<<(mps_cpu%4)) ); +} + +static inline int generate_logical_apicid(int quad, int phys_apicid) +{ + return ( (quad << 4) + (phys_apicid ? phys_apicid << 1 : 1) ); +} + +static inline int apicid_to_quad(int logical_apicid) +{ + return (logical_apicid >> 4); +} + +static inline unsigned long apicid_to_cpu_present(int logical_apicid) +{ + return ( (logical_apicid&0xf) << (4*apicid_to_quad(logical_apicid)) ); +} + +static inline int mpc_apic_id(struct mpc_config_processor *m, int quad) +{ + int logical_apicid = generate_logical_apicid(quad, m->mpc_apicid); + + printk("Processor #%d %ld:%ld APIC version %d (quad %d, apic %d)\n", + m->mpc_apicid, + (m->mpc_cpufeature & CPU_FAMILY_MASK) >> 8, + (m->mpc_cpufeature & CPU_MODEL_MASK) >> 4, + m->mpc_apicver, quad, logical_apicid); + return logical_apicid; +} + +#define wakeup_secondary_cpu(apicid, start_eip) \ + wakeup_secondary_via_NMI(apicid) + +static inline void setup_portio_remap(void) +{ + if (numnodes <= 1) + return; + + printk("Remapping cross-quad port I/O for %d quads\n", numnodes); + xquad_portio = ioremap (XQUAD_PORTIO_BASE, numnodes*XQUAD_PORTIO_QUAD); + printk("xquad_portio vaddr 0x%08lx, len %08lx\n", + (u_long) xquad_portio, (u_long) numnodes*XQUAD_PORTIO_QUAD); +} + +#endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-numaq/mach_ipi.h b/include/asm-i386/mach-numaq/mach_ipi.h new file mode 100644 index 000000000000..e0866134e624 --- /dev/null +++ b/include/asm-i386/mach-numaq/mach_ipi.h @@ -0,0 +1,24 @@ +#ifndef __ASM_MACH_IPI_H +#define __ASM_MACH_IPI_H + +static inline void send_IPI_mask_sequence(int mask, int vector); + +static inline void send_IPI_mask(int mask, int vector) +{ + send_IPI_mask_sequence(mask, vector); +} + +static inline void send_IPI_allbutself(int vector) +{ + unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); + + if (mask) + send_IPI_mask(mask, vector); +} + +static inline void send_IPI_all(int vector) +{ + send_IPI_mask(cpu_online_map, vector); +} + +#endif /* __ASM_MACH_IPI_H */ diff --git a/include/asm-i386/mach-numaq/mach_mpparse.h b/include/asm-i386/mach-numaq/mach_mpparse.h new file mode 100644 index 000000000000..ddda81a724a8 --- /dev/null +++ b/include/asm-i386/mach-numaq/mach_mpparse.h @@ -0,0 +1,37 @@ +#ifndef __ASM_MACH_MPPARSE_H +#define __ASM_MACH_MPPARSE_H + +static void __init smp_read_mpc_oem(struct mp_config_oemtable *oemtable, + unsigned short oemsize); + +static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, + struct mpc_config_translation *translation) +{ + int quad = translation->trans_quad; + int local = translation->trans_local; + + mp_bus_id_to_node[m->mpc_busid] = quad; + mp_bus_id_to_local[m->mpc_busid] = local; + printk("Bus #%d is %s (node %d)\n", m->mpc_busid, name, quad); +} + +static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, + struct mpc_config_translation *translation) +{ + int quad = translation->trans_quad; + int local = translation->trans_local; + + quad_local_to_mp_bus_id[quad][local] = m->mpc_busid; +} + +static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ + if (strncmp(oem, "IBM NUMA", 8)) + printk("Warning! May not be a NUMA-Q system!\n"); + if (mpc->mpc_oemptr) + smp_read_mpc_oem((struct mp_config_oemtable *) mpc->mpc_oemptr, + mpc->mpc_oemsize); +} + +#endif /* __ASM_MACH_MPPARSE_H */ diff --git a/include/asm-i386/mach-summit/mach_apic.h b/include/asm-i386/mach-summit/mach_apic.h new file mode 100644 index 000000000000..2de1e9fea7cd --- /dev/null +++ b/include/asm-i386/mach-summit/mach_apic.h @@ -0,0 +1,64 @@ +#ifndef __ASM_MACH_APIC_H +#define __ASM_MACH_APIC_H + +extern int x86_summit; + +#define XAPIC_DEST_CPUS_MASK 0x0Fu +#define XAPIC_DEST_CLUSTER_MASK 0xF0u + +#define xapic_phys_to_log_apicid(phys_apic) ( (1ul << ((phys_apic) & 0x3)) |\ + ((phys_apic) & XAPIC_DEST_CLUSTER_MASK) ) + +static inline unsigned long calculate_ldr(unsigned long old) +{ + unsigned long id; + + if (x86_summit) + id = xapic_phys_to_log_apicid(hard_smp_processor_id()); + else + id = 1UL << smp_processor_id(); + return ((old & ~APIC_LDR_MASK) | SET_APIC_LOGICAL_ID(id)); +} + +#define APIC_DFR_VALUE (x86_summit ? APIC_DFR_CLUSTER : APIC_DFR_FLAT) +#define TARGET_CPUS (x86_summit ? XAPIC_DEST_CPUS_MASK : cpu_online_map) + +#define APIC_BROADCAST_ID (x86_summit ? 0xFF : 0x0F) +#define check_apicid_used(bitmap, apicid) (0) + +static inline void clustered_apic_check(void) +{ + printk("Enabling APIC mode: %s. Using %d I/O APICs\n", + (x86_summit ? "Summit" : "Flat"), nr_ioapics); +} + +static inline int cpu_present_to_apicid(int mps_cpu) +{ + if (x86_summit) + return (int) raw_phys_apicid[mps_cpu]; + else + return mps_cpu; +} + +static inline ulong ioapic_phys_id_map(ulong phys_map) +{ + /* For clustered we don't have a good way to do this yet - hack */ + return (x86_summit ? 0x0F : phys_map); +} + +static inline unsigned long apicid_to_phys_cpu_present(int apicid) +{ + if (x86_summit) + return (1ul << (((apicid >> 4) << 2) | (apicid & 0x3))); + else + return (1ul << apicid); +} + +#define wakeup_secondary_cpu(apicid, start_eip) \ + wakeup_secondary_via_INIT(apicid, start_eip) + +static inline void setup_portio_remap(void) +{ +} + +#endif /* __ASM_MACH_APIC_H */ diff --git a/include/asm-i386/mach-summit/mach_ipi.h b/include/asm-i386/mach-summit/mach_ipi.h new file mode 100644 index 000000000000..e0866134e624 --- /dev/null +++ b/include/asm-i386/mach-summit/mach_ipi.h @@ -0,0 +1,24 @@ +#ifndef __ASM_MACH_IPI_H +#define __ASM_MACH_IPI_H + +static inline void send_IPI_mask_sequence(int mask, int vector); + +static inline void send_IPI_mask(int mask, int vector) +{ + send_IPI_mask_sequence(mask, vector); +} + +static inline void send_IPI_allbutself(int vector) +{ + unsigned long mask = cpu_online_map & ~(1 << smp_processor_id()); + + if (mask) + send_IPI_mask(mask, vector); +} + +static inline void send_IPI_all(int vector) +{ + send_IPI_mask(cpu_online_map, vector); +} + +#endif /* __ASM_MACH_IPI_H */ diff --git a/include/asm-i386/mach-summit/mach_mpparse.h b/include/asm-i386/mach-summit/mach_mpparse.h new file mode 100644 index 000000000000..7bb66819082f --- /dev/null +++ b/include/asm-i386/mach-summit/mach_mpparse.h @@ -0,0 +1,22 @@ +#ifndef __ASM_MACH_MPPARSE_H +#define __ASM_MACH_MPPARSE_H + +static inline void mpc_oem_bus_info(struct mpc_config_bus *m, char *name, + struct mpc_config_translation *translation) +{ + Dprintk("Bus #%d is %s\n", m->mpc_busid, name); +} + +static inline void mpc_oem_pci_bus(struct mpc_config_bus *m, + struct mpc_config_translation *translation) +{ +} + +static inline void mps_oem_check(struct mp_config_table *mpc, char *oem, + char *productid) +{ + if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(str, "VIGIL SMP", 9)) + x86_summit = 1; +} + +#endif /* __ASM_MACH_MPPARSE_H */ diff --git a/include/asm-i386/mach-visws/do_timer.h b/include/asm-i386/mach-visws/do_timer.h new file mode 100644 index 000000000000..d19c7063e17d --- /dev/null +++ b/include/asm-i386/mach-visws/do_timer.h @@ -0,0 +1,49 @@ +/* defines for inline arch setup functions */ + +#include <asm/fixmap.h> +#include <asm/cobalt.h> + +static inline void do_timer_interrupt_hook(struct pt_regs *regs) +{ + /* Clear the interrupt */ + co_cpu_write(CO_CPU_STAT,co_cpu_read(CO_CPU_STAT) & ~CO_STAT_TIMEINTR); + + do_timer(regs); +/* + * In the SMP case we use the local APIC timer interrupt to do the + * profiling, except when we simulate SMP mode on a uniprocessor + * system, in that case we have to call the local interrupt handler. + */ +#ifndef CONFIG_X86_LOCAL_APIC + x86_do_profile(regs); +#else + if (!using_apic_timer) + smp_local_timer_interrupt(regs); +#endif +} + +static inline int do_timer_overflow(int count) +{ + int i; + + spin_lock(&i8259A_lock); + /* + * This is tricky when I/O APICs are used; + * see do_timer_interrupt(). + */ + i = inb(0x20); + spin_unlock(&i8259A_lock); + + /* assumption about timer being IRQ0 */ + if (i & 0x01) { + /* + * We cannot detect lost timer interrupts ... + * well, that's why we call them lost, don't we? :) + * [hmm, on the Pentium and Alpha we can ... sort of] + */ + count -= LATCH; + } else { + printk("do_slow_gettimeoffset(): hardware timer problem?\n"); + } + return count; +} diff --git a/include/asm-i386/mach-visws/entry_arch.h b/include/asm-i386/mach-visws/entry_arch.h new file mode 100644 index 000000000000..b183fa6d83d9 --- /dev/null +++ b/include/asm-i386/mach-visws/entry_arch.h @@ -0,0 +1,23 @@ +/* + * The following vectors are part of the Linux architecture, there + * is no hardware IRQ pin equivalent for them, they are triggered + * through the ICC by us (IPIs) + */ +#ifdef CONFIG_X86_SMP +BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR) +BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR) +BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR) +#endif + +/* + * every pentium local APIC has two 'local interrupts', with a + * soft-definable vector attached to both interrupts, one of + * which is a timer interrupt, the other one is error counter + * overflow. Linux uses the local APIC timer interrupt to get + * a much simpler SMP time architecture: + */ +#ifdef CONFIG_X86_LOCAL_APIC +BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR) +BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR) +BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) +#endif diff --git a/include/asm-i386/mach-visws/irq_vectors.h b/include/asm-i386/mach-visws/irq_vectors.h new file mode 100644 index 000000000000..5c53f00e21a8 --- /dev/null +++ b/include/asm-i386/mach-visws/irq_vectors.h @@ -0,0 +1,64 @@ +#ifndef _ASM_IRQ_VECTORS_H +#define _ASM_IRQ_VECTORS_H + +/* + * IDT vectors usable for external interrupt sources start + * at 0x20: + */ +#define FIRST_EXTERNAL_VECTOR 0x20 + +#define SYSCALL_VECTOR 0x80 + +/* + * Vectors 0x20-0x2f are used for ISA interrupts. + */ + +/* + * Special IRQ vectors used by the SMP architecture, 0xf0-0xff + * + * some of the following vectors are 'rare', they are merged + * into a single vector (CALL_FUNCTION_VECTOR) to save vector space. + * TLB, reschedule and local APIC vectors are performance-critical. + * + * Vectors 0xf0-0xfa are free (reserved for future Linux use). + */ +#define SPURIOUS_APIC_VECTOR 0xff +#define ERROR_APIC_VECTOR 0xfe +#define INVALIDATE_TLB_VECTOR 0xfd +#define RESCHEDULE_VECTOR 0xfc +#define CALL_FUNCTION_VECTOR 0xfb + +#define THERMAL_APIC_VECTOR 0xf0 +/* + * Local APIC timer IRQ vector is on a different priority level, + * to work around the 'lost local interrupt if more than 2 IRQ + * sources per level' errata. + */ +#define LOCAL_TIMER_VECTOR 0xef + +/* + * First APIC vector available to drivers: (vectors 0x30-0xee) + * we start at 0x31 to spread out vectors evenly between priority + * levels. (0x80 is the syscall vector) + */ +#define FIRST_DEVICE_VECTOR 0x31 +#define FIRST_SYSTEM_VECTOR 0xef + +#define TIMER_IRQ 0 + +/* + * 16 8259A IRQ's, 208 potential APIC interrupt sources. + * Right now the APIC is mostly only used for SMP. + * 256 vectors is an architectural limit. (we can have + * more than 256 devices theoretically, but they will + * have to use shared interrupts) + * Since vectors 0x00-0x1f are used/reserved for the CPU, + * the usable vector space is 0x20-0xff (224 vectors) + */ +#ifdef CONFIG_X86_IO_APIC +#define NR_IRQS 224 +#else +#define NR_IRQS 16 +#endif + +#endif /* _ASM_IRQ_VECTORS_H */ diff --git a/include/asm-i386/mach-visws/setup_arch_post.h b/include/asm-i386/mach-visws/setup_arch_post.h new file mode 100644 index 000000000000..e8611ae44c45 --- /dev/null +++ b/include/asm-i386/mach-visws/setup_arch_post.h @@ -0,0 +1,37 @@ +/* Hook for machine specific memory setup. + * + * This is included late in kernel/setup.c so that it can make use of all of + * the static functions. */ + +static inline char * __init machine_specific_memory_setup(void) +{ + char *who; + + + who = "BIOS-e820"; + + /* + * Try to copy the BIOS-supplied E820-map. + * + * Otherwise fake a memory map; one section from 0k->640k, + * the next section from 1mb->appropriate_mem_k + */ + sanitize_e820_map(E820_MAP, &E820_MAP_NR); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } + return who; +} diff --git a/include/asm-i386/mach-visws/setup_arch_pre.h b/include/asm-i386/mach-visws/setup_arch_pre.h new file mode 100644 index 000000000000..b92d6d9a4d3c --- /dev/null +++ b/include/asm-i386/mach-visws/setup_arch_pre.h @@ -0,0 +1,5 @@ +/* Hook to call BIOS initialisation function */ + +/* no action for visws */ + +#define ARCH_SETUP diff --git a/include/asm-i386/mach-visws/smpboot_hooks.h b/include/asm-i386/mach-visws/smpboot_hooks.h new file mode 100644 index 000000000000..b8abdb9bea99 --- /dev/null +++ b/include/asm-i386/mach-visws/smpboot_hooks.h @@ -0,0 +1,13 @@ +/* for visws do nothing for any of these */ + +static inline void smpboot_clear_io_apic_irqs(void) +{ +} + +static inline void smpboot_setup_warm_reset_vector(void) +{ +} + +static inline void smpboot_setup_io_apic(void) +{ +} diff --git a/include/asm-i386/mach-voyager/do_timer.h b/include/asm-i386/mach-voyager/do_timer.h new file mode 100644 index 000000000000..75c642f9af74 --- /dev/null +++ b/include/asm-i386/mach-voyager/do_timer.h @@ -0,0 +1,22 @@ +/* defines for inline arch setup functions */ +#include <asm/voyager.h> + +static inline void do_timer_interrupt_hook(struct pt_regs *regs) +{ + do_timer(regs); + + voyager_timer_interrupt(regs); +} + +static inline int do_timer_overflow(int count) +{ + /* can't read the ISR, just assume 1 tick + overflow */ + if(count > LATCH || count < 0) { + printk(KERN_ERR "VOYAGER PROBLEM: count is %d, latch is %d\n", count, LATCH); + count = LATCH; + } + count -= LATCH; + + return count; +} diff --git a/include/asm-i386/mach-voyager/entry_arch.h b/include/asm-i386/mach-voyager/entry_arch.h new file mode 100644 index 000000000000..4a1e1e8c10b6 --- /dev/null +++ b/include/asm-i386/mach-voyager/entry_arch.h @@ -0,0 +1,26 @@ +/* -*- mode: c; c-basic-offset: 8 -*- */ + +/* Copyright (C) 2002 + * + * Author: James.Bottomley@HansenPartnership.com + * + * linux/arch/i386/voyager/entry_arch.h + * + * This file builds the VIC and QIC CPI gates + */ + +/* initialise the voyager interrupt gates + * + * This uses the macros in irq.h to set up assembly jump gates. The + * calls are then redirected to the same routine with smp_ prefixed */ +BUILD_INTERRUPT(vic_sys_interrupt, VIC_SYS_INT) +BUILD_INTERRUPT(vic_cmn_interrupt, VIC_CMN_INT) +BUILD_INTERRUPT(vic_cpi_interrupt, VIC_CPI_LEVEL0); + +/* do all the QIC interrupts */ +BUILD_INTERRUPT(qic_timer_interrupt, QIC_TIMER_CPI); +BUILD_INTERRUPT(qic_invalidate_interrupt, QIC_INVALIDATE_CPI); +BUILD_INTERRUPT(qic_reschedule_interrupt, QIC_RESCHEDULE_CPI); +BUILD_INTERRUPT(qic_enable_irq_interrupt, QIC_ENABLE_IRQ_CPI); +BUILD_INTERRUPT(qic_call_function_interrupt, QIC_CALL_FUNCTION_CPI); + diff --git a/include/asm-i386/mach-voyager/irq_vectors.h b/include/asm-i386/mach-voyager/irq_vectors.h new file mode 100644 index 000000000000..4d4060a20434 --- /dev/null +++ b/include/asm-i386/mach-voyager/irq_vectors.h @@ -0,0 +1,71 @@ +/* -*- mode: c; c-basic-offset: 8 -*- */ + +/* Copyright (C) 2002 + * + * Author: James.Bottomley@HansenPartnership.com + * + * linux/arch/i386/voyager/irq_vectors.h + * + * This file provides definitions for the VIC and QIC CPIs + */ + +#ifndef _ASM_IRQ_VECTORS_H +#define _ASM_IRQ_VECTORS_H + +/* + * IDT vectors usable for external interrupt sources start + * at 0x20: + */ +#define FIRST_EXTERNAL_VECTOR 0x20 + +#define SYSCALL_VECTOR 0x80 + +/* + * Vectors 0x20-0x2f are used for ISA interrupts. + */ + +/* These define the CPIs we use in linux */ +#define VIC_CPI_LEVEL0 0 +#define VIC_CPI_LEVEL1 1 +/* now the fake CPIs */ +#define VIC_TIMER_CPI 2 +#define VIC_INVALIDATE_CPI 3 +#define VIC_RESCHEDULE_CPI 4 +#define VIC_ENABLE_IRQ_CPI 5 +#define VIC_CALL_FUNCTION_CPI 6 + +/* Now the QIC CPIs: Since we don't need the two initial levels, + * these are 2 less than the VIC CPIs */ +#define QIC_CPI_OFFSET 1 +#define QIC_TIMER_CPI (VIC_TIMER_CPI - QIC_CPI_OFFSET) +#define QIC_INVALIDATE_CPI (VIC_INVALIDATE_CPI - QIC_CPI_OFFSET) +#define QIC_RESCHEDULE_CPI (VIC_RESCHEDULE_CPI - QIC_CPI_OFFSET) +#define QIC_ENABLE_IRQ_CPI (VIC_ENABLE_IRQ_CPI - QIC_CPI_OFFSET) +#define QIC_CALL_FUNCTION_CPI (VIC_CALL_FUNCTION_CPI - QIC_CPI_OFFSET) + +#define VIC_START_FAKE_CPI VIC_TIMER_CPI +#define VIC_END_FAKE_CPI VIC_CALL_FUNCTION_CPI + +/* this is the SYS_INT CPI. */ +#define VIC_SYS_INT 8 +#define VIC_CMN_INT 15 + +/* This is the boot CPI for alternate processors. It gets overwritten + * by the above once the system has activated all available processors */ +#define VIC_CPU_BOOT_CPI VIC_CPI_LEVEL0 +#define VIC_CPU_BOOT_ERRATA_CPI (VIC_CPI_LEVEL0 + 8) + +#define NR_IRQS 224 + +#ifndef __ASSEMBLY__ +extern asmlinkage void vic_cpi_interrupt(void); +extern asmlinkage void vic_sys_interrupt(void); +extern asmlinkage void vic_cmn_interrupt(void); +extern asmlinkage void qic_timer_interrupt(void); +extern asmlinkage void qic_invalidate_interrupt(void); +extern asmlinkage void qic_reschedule_interrupt(void); +extern asmlinkage void qic_enable_irq_interrupt(void); +extern asmlinkage void qic_call_function_interrupt(void); +#endif /* !__ASSEMBLY__ */ + +#endif /* _ASM_IRQ_VECTORS_H */ diff --git a/include/asm-i386/mach-voyager/setup_arch_post.h b/include/asm-i386/mach-voyager/setup_arch_post.h new file mode 100644 index 000000000000..4c7cef49b8b2 --- /dev/null +++ b/include/asm-i386/mach-voyager/setup_arch_post.h @@ -0,0 +1,73 @@ +/* Hook for machine specific memory setup. + * + * This is included late in kernel/setup.c so that it can make use of all of + * the static functions. */ + +static inline char * __init machine_specific_memory_setup(void) +{ + char *who; + + who = "NOT VOYAGER"; + + if(voyager_level == 5) { + __u32 addr, length; + int i; + + who = "Voyager-SUS"; + + e820.nr_map = 0; + for(i=0; voyager_memory_detect(i, &addr, &length); i++) { + add_memory_region(addr, length, E820_RAM); + } + return who; + } else if(voyager_level == 4) { + __u32 tom; + __u16 catbase = inb(VOYAGER_SSPB_RELOCATION_PORT)<<8; + /* select the DINO config space */ + outb(VOYAGER_DINO, VOYAGER_CAT_CONFIG_PORT); + /* Read DINO top of memory register */ + tom = ((inb(catbase + 0x4) & 0xf0) << 16) + + ((inb(catbase + 0x5) & 0x7f) << 24); + + if(inb(catbase) != VOYAGER_DINO) { + printk(KERN_ERR "Voyager: Failed to get DINO for L4, setting tom to EXT_MEM_K\n"); + tom = (EXT_MEM_K)<<10; + } + who = "Voyager-TOM"; + add_memory_region(0, 0x9f000, E820_RAM); + /* map from 1M to top of memory */ + add_memory_region(1*1024*1024, tom - 1*1024*1024, E820_RAM); + /* FIXME: Should check the ASICs to see if I need to + * take out the 8M window. Just do it at the moment + * */ + add_memory_region(8*1024*1024, 8*1024*1024, E820_RESERVED); + return who; + } + + who = "BIOS-e820"; + + /* + * Try to copy the BIOS-supplied E820-map. + * + * Otherwise fake a memory map; one section from 0k->640k, + * the next section from 1mb->appropriate_mem_k + */ + sanitize_e820_map(E820_MAP, &E820_MAP_NR); + if (copy_e820_map(E820_MAP, E820_MAP_NR) < 0) { + unsigned long mem_size; + + /* compare results from other methods and take the greater */ + if (ALT_MEM_K < EXT_MEM_K) { + mem_size = EXT_MEM_K; + who = "BIOS-88"; + } else { + mem_size = ALT_MEM_K; + who = "BIOS-e801"; + } + + e820.nr_map = 0; + add_memory_region(0, LOWMEMSIZE(), E820_RAM); + add_memory_region(HIGH_MEMORY, mem_size << 10, E820_RAM); + } + return who; +} diff --git a/include/asm-i386/mach-voyager/setup_arch_pre.h b/include/asm-i386/mach-voyager/setup_arch_pre.h new file mode 100644 index 000000000000..48f7e6ff49a5 --- /dev/null +++ b/include/asm-i386/mach-voyager/setup_arch_pre.h @@ -0,0 +1,10 @@ +#include <asm/voyager.h> +#define VOYAGER_BIOS_INFO ((struct voyager_bios_info *)(PARAM+0x40)) + +/* Hook to call BIOS initialisation function */ + +/* for voyager, pass the voyager BIOS/SUS info area to the detection + * routines */ + +#define ARCH_SETUP voyager_detect(VOYAGER_BIOS_INFO); + diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index ac467d123706..bf944abdf821 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -78,6 +78,7 @@ struct cpuinfo_x86 { */ extern struct cpuinfo_x86 boot_cpu_data; +extern struct cpuinfo_x86 new_cpu_data; extern struct tss_struct init_tss[NR_CPUS]; #ifdef CONFIG_SMP diff --git a/include/asm-i386/thread_info.h b/include/asm-i386/thread_info.h index b0560dc4647e..1bf8d4830649 100644 --- a/include/asm-i386/thread_info.h +++ b/include/asm-i386/thread_info.h @@ -109,6 +109,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ #define TIF_SIGPENDING 2 /* signal pending */ #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ +#define TIF_SINGLESTEP 4 /* restore singlestep on return to user mode */ #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ @@ -116,6 +117,7 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) +#define _TIF_SINGLESTEP (1<<TIF_SINGLESTEP) #define _TIF_USEDFPU (1<<TIF_USEDFPU) #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) diff --git a/include/linux/if_bonding.h b/include/linux/if_bonding.h index a263da6bd01c..b673b0830ddd 100644 --- a/include/linux/if_bonding.h +++ b/include/linux/if_bonding.h @@ -37,9 +37,10 @@ #define BOND_CHECK_MII_STATUS (SIOCGMIIPHY) -#define BOND_MODE_ROUNDROBIN 0 -#define BOND_MODE_ACTIVEBACKUP 1 -#define BOND_MODE_XOR 2 +#define BOND_MODE_ROUNDROBIN 0 +#define BOND_MODE_ACTIVEBACKUP 1 +#define BOND_MODE_XOR 2 +#define BOND_MODE_BROADCAST 3 /* each slave's link has 4 states */ #define BOND_LINK_UP 0 /* link is up and running */ @@ -74,6 +75,7 @@ typedef struct slave { struct slave *prev; struct net_device *dev; short delay; + unsigned long jiffies; char link; /* one of BOND_LINK_XXXX */ char state; /* one of BOND_STATE_XXXX */ unsigned short original_flags; @@ -93,6 +95,8 @@ typedef struct bonding { slave_t *next; slave_t *prev; slave_t *current_slave; + slave_t *primary_slave; + slave_t *current_arp_slave; __s32 slave_cnt; rwlock_t lock; rwlock_t ptrlock; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 0b905659ac4b..b115623159e9 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -544,7 +544,8 @@ enum { NET_SCTP_PATH_MAX_RETRANS = 8, NET_SCTP_MAX_INIT_RETRANSMITS = 9, NET_SCTP_HB_INTERVAL = 10, - NET_SCTP_MAX_BURST = 11, + NET_SCTP_PRESERVE_ENABLE = 11, + NET_SCTP_MAX_BURST = 12, }; /* CTL_PROC names: */ diff --git a/include/net/dst.h b/include/net/dst.h index 1fbb39584b97..2fccbbfe5eb6 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -10,6 +10,7 @@ #include <linux/config.h> #include <linux/rtnetlink.h> +#include <linux/rcupdate.h> #include <net/neighbour.h> #include <asm/processor.h> @@ -71,6 +72,7 @@ struct dst_entry #endif struct dst_ops *ops; + struct rcu_head rcu_head; char info[0]; }; diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 73c948813e72..f12e54cd4919 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -123,8 +123,8 @@ extern sctp_protocol_t sctp_proto; extern struct sock *sctp_get_ctl_sock(void); extern int sctp_copy_local_addr_list(sctp_protocol_t *, sctp_bind_addr_t *, sctp_scope_t, int priority, int flags); -extern sctp_pf_t *sctp_get_pf_specific(int family); -extern void sctp_set_pf_specific(int family, sctp_pf_t *); +extern struct sctp_pf *sctp_get_pf_specific(sa_family_t family); +extern int sctp_register_pf(struct sctp_pf *, sa_family_t); /* * sctp_socket.c diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index e811bf37e4ca..68af144ef56c 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -140,6 +140,8 @@ sctp_state_fn_t sctp_sf_do_5_2_2_dupinit; sctp_state_fn_t sctp_sf_do_5_2_4_dupcook; sctp_state_fn_t sctp_sf_unk_chunk; sctp_state_fn_t sctp_sf_do_8_5_1_E_sa; +sctp_state_fn_t sctp_sf_cookie_echoed_err; +sctp_state_fn_t sctp_sf_do_5_2_6_stale; /* Prototypes for primitive event state functions. */ sctp_state_fn_t sctp_sf_do_prm_asoc; @@ -175,7 +177,6 @@ sctp_state_fn_t sctp_sf_autoclose_timer_expire; */ /* Prototypes for chunk state functions. Not in use. */ -sctp_state_fn_t sctp_sf_do_5_2_6_stale; sctp_state_fn_t sctp_sf_do_9_2_reshutack; sctp_state_fn_t sctp_sf_do_9_2_reshut; sctp_state_fn_t sctp_sf_do_9_2_shutack; @@ -211,7 +212,7 @@ void sctp_populate_tie_tags(__u8 *cookie, __u32 curTag, __u32 hisTag); /* Prototypes for chunk-building functions. */ sctp_chunk_t *sctp_make_init(const sctp_association_t *, const sctp_bind_addr_t *, - int priority); + int priority, int vparam_len); sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *, const sctp_chunk_t *, const int priority, @@ -322,9 +323,15 @@ sctp_pack_cookie(const sctp_endpoint_t *, const sctp_association_t *, const __u8 *, int addrs_len); sctp_association_t *sctp_unpack_cookie(const sctp_endpoint_t *, const sctp_association_t *, - sctp_chunk_t *, int priority, int *err); + sctp_chunk_t *, int priority, int *err, + sctp_chunk_t **err_chk_p); int sctp_addip_addr_config(sctp_association_t *, sctp_param_t, struct sockaddr_storage*, int); +void sctp_send_stale_cookie_err(const sctp_endpoint_t *ep, + const sctp_association_t *asoc, + const sctp_chunk_t *chunk, + sctp_cmd_seq_t *commands, + sctp_chunk_t *err_chunk); /* 3rd level prototypes */ __u32 sctp_generate_tag(const sctp_endpoint_t *); diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index d7b5674bdbdc..db3a3041bfe8 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -42,6 +42,7 @@ * Sridhar Samudrala <sri@us.ibm.com> * Daisy Chang <daisyc@us.ibm.com> * Dajiang Zhang <dajiang.zhang@nokia.com> + * Ardelle Fan <ardelle.fan@intel.com> * * Any bugs reported given to us we will try to fix... any fixes shared will * be incorporated into the next SCTP release. @@ -182,6 +183,9 @@ struct SCTP_protocol { /* Valid.Cookie.Life - 60 seconds */ int valid_cookie_life; + + /* Whether Cookie Preservative is enabled(1) or not(0) */ + int cookie_preserve_enable; /* Association.Max.Retrans - 10 attempts * Path.Max.Retrans - 5 attempts (per destination address) @@ -234,7 +238,7 @@ struct SCTP_protocol { * Pointers to address related SCTP functions. * (i.e. things that depend on the address family.) */ -typedef struct sctp_func { +struct sctp_af { int (*queue_xmit) (struct sk_buff *skb); int (*setsockopt) (struct sock *sk, int level, @@ -259,27 +263,34 @@ typedef struct sctp_func { void (*from_skb) (union sctp_addr *, struct sk_buff *skb, int saddr); + void (*from_sk) (union sctp_addr *, + struct sock *sk); + void (*to_sk) (union sctp_addr *, + struct sock *sk); int (*addr_valid) (union sctp_addr *); sctp_scope_t (*scope) (union sctp_addr *); void (*inaddr_any) (union sctp_addr *, unsigned short); int (*is_any) (const union sctp_addr *); + int (*available) (const union sctp_addr *); __u16 net_header_len; int sockaddr_len; sa_family_t sa_family; struct list_head list; -} sctp_func_t; +}; -sctp_func_t *sctp_get_af_specific(sa_family_t); +struct sctp_af *sctp_get_af_specific(sa_family_t); +int sctp_register_af(struct sctp_af *); /* Protocol family functions. */ typedef struct sctp_pf { void (*event_msgname)(sctp_ulpevent_t *, char *, int *); - void (*skb_msgname)(struct sk_buff *, char *, int *); - int (*af_supported)(sa_family_t); + void (*skb_msgname) (struct sk_buff *, char *, int *); + int (*af_supported) (sa_family_t); int (*cmp_addr) (const union sctp_addr *, const union sctp_addr *, struct sctp_opt *); - struct sctp_func *af; + int (*bind_verify) (struct sctp_opt *, union sctp_addr *); + struct sctp_af *af; } sctp_pf_t; /* SCTP Socket type: UDP or TCP style. */ @@ -623,7 +634,7 @@ struct SCTP_transport { union sctp_addr ipaddr; /* These are the functions we call to handle LLP stuff. */ - sctp_func_t *af_specific; + struct sctp_af *af_specific; /* Which association do we belong to? */ sctp_association_t *asoc; @@ -1271,7 +1282,6 @@ struct SCTP_association { /* The cookie life I award for any cookie. */ struct timeval cookie_life; - __u32 cookie_preserve; /* Overall : The overall association error count. * Error Count : [Clear this any time I get something.] @@ -1350,6 +1360,9 @@ struct SCTP_association { */ __u32 rwnd; + /* This is the last advertised value of rwnd over a SACK chunk. */ + __u32 a_rwnd; + /* Number of bytes by which the rwnd has slopped. The rwnd is allowed * to slop over a maximum of the association's frag_point. */ |
