From ad6ac752bf92c4ae2d22050449d3366063ff6951 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 23 Nov 2007 15:19:53 -0500 Subject: [PATCH] Linux 2.2.13pre11 o Fix /dev/random scribble (Ted Tso) o Multicast on token ring (Mike Phillips) o Fix tty locking bug (Ted Tso) o Alpha updates (fix udelay etc) (Jay Estabrook) o Make NULL C++ friendly in kernel (Ben La Haise) o pcwd watchdog bug fix (Marc Boucher) o Fix dummycom bug on Alpha (Jay Estabrook) --- Makefile | 2 +- arch/alpha/config.in | 6 +- arch/alpha/kernel/Makefile | 2 +- arch/alpha/kernel/alpha_ksyms.c | 2 + arch/alpha/kernel/bios32.c | 10 +-- arch/alpha/kernel/head.S | 18 +++++ arch/alpha/kernel/process.c | 121 +++++++++++++++++------------- arch/alpha/kernel/proto.h | 1 + arch/alpha/kernel/setup.c | 5 +- arch/alpha/kernel/sys_dp264.c | 85 ++++++++++++++++++++- arch/alpha/kernel/sys_takara.c | 51 ++++++++++--- arch/alpha/math-emu/fp-emul.c | 12 +-- arch/alpha/math-emu/sfp-machine.h | 20 ++--- drivers/char/pcwd.c | 6 +- drivers/char/random.c | 2 +- drivers/char/tty_io.c | 5 +- drivers/net/Space.c | 4 + drivers/net/dmfe.c | 14 +--- drivers/net/ibmtr.c | 48 +++++++++++- drivers/net/ibmtr.h | 2 +- drivers/net/net_init.c | 2 +- drivers/video/dummycon.c | 2 +- include/asm-alpha/delay.h | 16 +++- include/asm-alpha/hwrpb.h | 1 + include/asm-alpha/irq.h | 11 ++- include/linux/fs.h | 5 +- include/linux/posix_types.h | 10 +-- include/linux/sched.h | 4 - include/linux/stddef.h | 4 + include/linux/string.h | 5 +- include/linux/tty.h | 1 + include/net/ip.h | 16 ++++ net/802/tr.c | 21 ++++-- net/ipv4/arp.c | 9 ++- 34 files changed, 371 insertions(+), 152 deletions(-) diff --git a/Makefile b/Makefile index a6f656c34ac1..883f368207c9 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 2 SUBLEVEL = 13 -EXTRAVERSION = pre10 +EXTRAVERSION = pre11 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff --git a/arch/alpha/config.in b/arch/alpha/config.in index 4a0da0cbcb30..e9e2f15b06a4 100644 --- a/arch/alpha/config.in +++ b/arch/alpha/config.in @@ -33,6 +33,7 @@ choice 'Alpha system type' \ EB64+ CONFIG_ALPHA_EB64P \ EB66 CONFIG_ALPHA_EB66 \ EB66+ CONFIG_ALPHA_EB66P \ + Eiger CONFIG_ALPHA_EIGER \ Jensen CONFIG_ALPHA_JENSEN \ LX164 CONFIG_ALPHA_LX164 \ Miata CONFIG_ALPHA_MIATA \ @@ -117,7 +118,7 @@ then define_bool CONFIG_ALPHA_EV5 y define_bool CONFIG_ALPHA_PYXIS y fi -if [ "$CONFIG_ALPHA_DP264" = "y" ] +if [ "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_EIGER" = "y" ] then define_bool CONFIG_PCI y define_bool CONFIG_ALPHA_EV6 y @@ -147,7 +148,8 @@ if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \ -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \ -o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \ -o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \ - -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" ] + -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \ + -o "$CONFIG_ALPHA_EIGER" = "y" ] then bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 9b1553cfe580..f65d3e68d5a0 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -64,7 +64,7 @@ endif ifneq ($(CONFIG_ALPHA_CABRIOLET)$(CONFIG_ALPHA_EB164)$(CONFIG_ALPHA_EB66P)$(CONFIG_ALPHA_LX164)$(CONFIG_ALPHA_PC164),) O_OBJS += sys_cabriolet.o endif -ifdef CONFIG_ALPHA_DP264 +ifneq ($(CONFIG_ALPHA_DP264)$(CONFIG_ALPHA_EIGER),) O_OBJS += sys_dp264.o endif ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),) diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index bfc2248db7eb..b79ff1f7ec3f 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c @@ -30,6 +30,7 @@ #include #include #include +#include #define __KERNEL_SYSCALLS__ #include @@ -98,6 +99,7 @@ EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(__memsetw); EXPORT_SYMBOL(__constant_c_memset); +EXPORT_SYMBOL(___delay); EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); diff --git a/arch/alpha/kernel/bios32.c b/arch/alpha/kernel/bios32.c index 1c7823397b7f..2a0394781f36 100644 --- a/arch/alpha/kernel/bios32.c +++ b/arch/alpha/kernel/bios32.c @@ -639,11 +639,11 @@ layout_dev(struct pci_dev *dev) /* Bypass hi reg in the loop. */ dev->base_address[++idx] = 0; - printk("bios32 WARNING: " - "handling 64-bit device in " - "slot %d, function %d: \n", - PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); + DBG_DEVS(("bios32 WARNING: " + "handling 64-bit device in " + "slot %d, function %d: \n", + PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn))); } DBG_DEVS(("layout_dev: dev 0x%x MEM @ 0x%lx (0x%x)\n", diff --git a/arch/alpha/kernel/head.S b/arch/alpha/kernel/head.S index 3b004b7f615e..f330847443b7 100644 --- a/arch/alpha/kernel/head.S +++ b/arch/alpha/kernel/head.S @@ -95,3 +95,21 @@ halt: .prologue 0 call_pal PAL_halt .end halt + + # + # Having the delay loop out of line guarantees that we wont + # run into weird alignment conditions (on new processors) + # that vary the speed of the loop. + # + .align 5 + .globl ___delay + .ent ___delay +___delay: + .set noat + .frame $30,0,$28,0 + .prologue 0 +1: subq $0,1,$0 + bge $0,1b + ret $31,($28),0 + .set at + .end ___delay diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 19109d12e1a1..0140f2ce64e2 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c @@ -117,58 +117,46 @@ sys_idle(void) } } -void -generic_kill_arch (int mode, char *restart_cmd) +struct halt_info { + int mode; + char * restart_cmd; +}; + +static void +halt_processor(void * generic_ptr) { - /* The following currently only has any effect on SRM. We should - fix MILO to understand it. Should be pretty easy. Also we can - support RESTART2 via the ipc_buffer machinations pictured below, - which SRM ignores. */ + struct percpu_struct * cpup; + struct halt_info * how = (struct halt_info *)generic_ptr; + unsigned long *flags, dummy = 0; + int cpuid = smp_processor_id(); + + /* No point in taking interrupts anymore. */ + cli(); if (alpha_using_srm) { - struct percpu_struct *cpup; - unsigned long flags; - cpup = (struct percpu_struct *) - ((unsigned long)hwrpb + hwrpb->processor_offset); + ((unsigned long)hwrpb + hwrpb->processor_offset + + hwrpb->processor_size * cpuid); + flags = &cpup->flags; + } else + flags = &dummy; - flags = cpup->flags; + /* Clear reason to "default"; clear "bootstrap in progress". */ + *flags &= ~0x00ff0001UL; - /* Clear reason to "default"; clear "bootstrap in progress". */ - flags &= ~0x00ff0001UL; - - if (mode == LINUX_REBOOT_CMD_RESTART) { - if (!restart_cmd) { - flags |= 0x00020000UL; /* "cold bootstrap" */ - cpup->ipc_buffer[0] = 0; - } else { - flags |= 0x00030000UL; /* "warm bootstrap" */ - strncpy((char *)cpup->ipc_buffer, restart_cmd, - sizeof(cpup->ipc_buffer)); - } - } else { - flags |= 0x00040000UL; /* "remain halted" */ - } - - cpup->flags = flags; - mb(); - - reset_for_srm(); - set_hae(srm_hae); - -#ifdef CONFIG_DUMMY_CONSOLE - /* This has the effect of reseting the VGA video origin. */ - take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); -#endif +#ifdef __SMP__ + /* Secondaries halt here. */ + if (cpuid != smp_boot_cpuid) { + *flags |= 0x00040000UL; + clear_bit(cpuid, &cpu_present_mask); + halt(); } - +#endif /* __SMP__ */ #ifdef CONFIG_RTC /* Reset rtc to defaults. */ { unsigned char control; - cli(); - /* Reset periodic interrupt frequency. */ CMOS_WRITE(0x26, RTC_FREQ_SELECT); @@ -177,22 +165,53 @@ generic_kill_arch (int mode, char *restart_cmd) control |= RTC_PIE; CMOS_WRITE(control, RTC_CONTROL); CMOS_READ(RTC_INTR_FLAGS); - - sti(); } -#endif +#endif /* CONFIG_RTC */ + if (alpha_using_srm) { + if (how->mode == LINUX_REBOOT_CMD_RESTART) { + if (!how->restart_cmd) { + *flags |= 0x00020000UL; /* "cold bootstrap" */ + cpup->ipc_buffer[0] = 0; + } else { + *flags |= 0x00030000UL; /* "warm bootstrap" */ + strncpy((char *)cpup->ipc_buffer, + how->restart_cmd, + sizeof(cpup->ipc_buffer)); + } + } else + *flags |= 0x00040000UL; /* "remain halted" */ - if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) { - /* Unfortunately, since MILO doesn't currently understand - the hwrpb bits above, we can't reliably halt the - processor and keep it halted. So just loop. */ - return; + reset_for_srm(); + set_hae(srm_hae); + +#ifdef CONFIG_DUMMY_CONSOLE + /* This has the effect of reseting the VGA video origin. */ + take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1); +#endif +#ifdef __SMP__ + /* Wait for the secondaries to halt. */ + clear_bit(smp_boot_cpuid, &cpu_present_mask); + while (cpu_present_mask) + /* Make sure we sample memory and not a register. */ + barrier(); +#endif /* __SMP__ */ } + /* PRIMARY */ + halt(); +} - if (alpha_using_srm) - srm_paging_stop(); +void +generic_kill_arch(int mode, char * restart_cmd) +{ + struct halt_info copy_of_args; - halt(); + copy_of_args.mode = mode; + copy_of_args.restart_cmd = restart_cmd; +#ifdef __SMP__ + /* A secondary can't wait here for the primary to finish, can it now? */ + smp_call_function(halt_processor, (void *)©_of_args, 1, 0); +#endif /* __SMP__ */ + halt_processor(©_of_args); } void diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h index 12f181b98c3d..743fc1d64eb4 100644 --- a/arch/alpha/kernel/proto.h +++ b/arch/alpha/kernel/proto.h @@ -153,6 +153,7 @@ extern int smp_info(char *buffer); extern void handle_ipi(struct pt_regs *); extern void smp_percpu_timer_interrupt(struct pt_regs *); extern int smp_boot_cpuid; +extern unsigned long cpu_present_mask; /* bios32.c */ extern void reset_for_srm(void); diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c index b52d386baf3f..5894310729b5 100644 --- a/arch/alpha/kernel/setup.c +++ b/arch/alpha/kernel/setup.c @@ -112,6 +112,7 @@ WEAK(eb164_mv); WEAK(eb64p_mv); WEAK(eb66_mv); WEAK(eb66p_mv); +WEAK(eiger_mv); WEAK(jensen_mv); WEAK(lx164_mv); WEAK(miata_mv); @@ -358,7 +359,7 @@ static char systype_names[][16] = { "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1", "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake", "Cortex", "29", "Miata", "XXM", "Takara", "Yukon", - "Tsunami", "Wildfire", "CUSCO" + "Tsunami", "Wildfire", "CUSCO", "Eiger" }; static char unofficial_names[][8] = {"100", "Ruffian"}; @@ -429,6 +430,7 @@ get_sysvec(long type, long variation, long cpu) NULL, /* Tsunami -- see variation. */ NULL, /* Wildfire */ NULL, /* CUSCO */ + &eiger_mv, /* Eiger */ }; static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata = @@ -558,6 +560,7 @@ get_sysvec_byname(const char *name) &eb64p_mv, &eb66_mv, &eb66p_mv, + &eiger_mv, &jensen_mv, &lx164_mv, &miata_mv, diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c index 1c4ecf3ade5f..1467a26017ab 100644 --- a/arch/alpha/kernel/sys_dp264.c +++ b/arch/alpha/kernel/sys_dp264.c @@ -92,6 +92,24 @@ clipper_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) outb(mask, 0x21); /* ISA PIC1 */ } +static void +eiger_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) +{ + if (irq >= 16) { + volatile unsigned long *csr; + + csr = &TSUNAMI_cchip->dim0.csr; + + *csr = ~mask; + mb(); + *csr; + } + else if (irq >= 8) + outb(mask >> 8, 0xA1); /* ISA PIC2 */ + else + outb(mask, 0x21); /* ISA PIC1 */ +} + static void dp264_device_interrupt(unsigned long vector, struct pt_regs * regs) { @@ -169,6 +187,21 @@ clipper_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) handle_irq(irq, ack, regs); } +static void +eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) +{ + int irq, ack; + + ack = irq = (vector - 0x800) >> 4; + + /* This is just like TAKARA rather than like the other TSUNAMIs. */ + /* ??? Is this really correct??? */ + if (irq > 15) + ack = irq = ((vector - 0x800) >> 6) + 12; + + handle_irq(irq, ack, regs); +} + static void __init dp264_init_irq(void) { @@ -203,6 +236,25 @@ clipper_init_irq(void) enable_irq(2); } +static void __init +eiger_init_irq(void) +{ + outb(0, DMA1_RESET_REG); + outb(0, DMA2_RESET_REG); + outb(DMA_MODE_CASCADE, DMA2_MODE_REG); + outb(0, DMA2_MASK_REG); + + if (alpha_using_srm) + alpha_mv.device_interrupt = eiger_srm_device_interrupt; + + eiger_update_irq_hw(16, alpha_irq_mask, 0); + +#if 0 + enable_irq(55); /* Enable ISA interrupt controller. */ +#endif + enable_irq(2); +} + /* * PCI Fixup configuration. @@ -402,7 +454,6 @@ webbrick_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(webbrick_map_irq, common_swizzle); - SMC669_Init(0); } static void __init @@ -412,6 +463,13 @@ clipper_pci_fixup(void) common_pci_fixup(clipper_map_irq, common_swizzle); } +static void __init +eiger_pci_fixup(void) +{ + layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); + common_pci_fixup(monet_map_irq, monet_swizzle); +} + /* * The System Vectors @@ -505,6 +563,29 @@ struct alpha_machine_vector clipper_mv __initmv = { pci_fixup: clipper_pci_fixup, kill_arch: generic_kill_arch, }; - /* No alpha_mv alias for webbrick/monet/clipper, since we compile them in unconditionally with DP264; setup_arch knows how to cope. */ + +struct alpha_machine_vector eiger_mv __initmv = { + vector_name: "Eiger", + DO_EV6_MMU, + DO_DEFAULT_RTC, + DO_TSUNAMI_IO, + DO_TSUNAMI_BUS, + machine_check: tsunami_machine_check, + max_dma_address: ALPHA_MAX_DMA_ADDRESS, + + nr_irqs: 64, + irq_probe_mask: _PROBE_MASK(64), + update_irq_hw: eiger_update_irq_hw, + ack_irq: generic_ack_irq, + device_interrupt: dp264_device_interrupt, + + init_arch: tsunami_init_arch, + init_irq: eiger_init_irq, + init_pit: generic_init_pit, + pci_fixup: eiger_pci_fixup, + kill_arch: generic_kill_arch, +}; +ALIAS_MV(eiger) + diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c index c554a9fa1a07..677ccf8e9ebc 100644 --- a/arch/alpha/kernel/sys_takara.c +++ b/arch/alpha/kernel/sys_takara.c @@ -42,7 +42,7 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) outb(mask >> 8, 0xA1); /* ISA PIC2 */ } else if (irq <= 31) { regaddr = 0x510 + ((irq - 16) & 0x0c); - outl((mask >> ((irq - 16) & 0x0c)) & 0xf0000Ul, regaddr); + outl((mask >> ((irq - 16) & 0x0c)) & 0x000f0000UL, regaddr); } } @@ -101,8 +101,7 @@ takara_init_irq(void) if (alpha_using_srm) alpha_mv.device_interrupt = takara_srm_device_interrupt; - - if (!alpha_using_srm) { + else { unsigned int ctlreg = inl(0x500); /* Return to non-accelerated mode. */ @@ -129,7 +128,7 @@ takara_init_irq(void) static int __init takara_map_irq(struct pci_dev *dev, int slot, int pin) { - static char irq_tab[15][5] __initlocaldata = { + static char arc_irq_tab[15][5] __initlocaldata = { { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */ @@ -146,8 +145,32 @@ takara_map_irq(struct pci_dev *dev, int slot, int pin) { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 19 == device 2 */ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 20 == device 1 */ }; + static char srm_irq_tab[15][5] __initlocaldata = { + { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */ + { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */ + { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */ + { -1, -1, -1, -1, -1}, /* slot 9 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 10 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 11 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 12 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 13 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 14 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 15 == nothing */ + { -1, -1, -1, -1, -1}, /* slot 16 == nothing */ + {16+12,16+12,16+13,16+14,16+15}, /* slot 17= device 4 */ + {16+ 8, 16+8, 16+9,16+10,16+11}, /* slot 18= device 3 */ + {16+ 4, 16+4, 16+5, 16+6, 16+7}, /* slot 19= device 2 */ + {16+ 0, 16+0, 16+1, 16+2, 16+3}, /* slot 20= device 1 */ + }; const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5; - return COMMON_TABLE_LOOKUP; + + if (slot >= min_idsel && slot <= max_idsel && pin < irqs_per_slot) { + if (alpha_using_srm) + return srm_irq_tab[slot - min_idsel][pin]; + else + return arc_irq_tab[slot - min_idsel][pin]; + } else + return -1; } static int __init @@ -159,14 +182,18 @@ takara_swizzle(struct pci_dev *dev, int *pinp) unsigned int busslot = PCI_SLOT(dev->bus->self->devfn); /* Check first for built-in bridges. */ - if (busslot > 16 && ((1<<(36-busslot)) & ctlreg)) { + if (busslot > 16 && ((1U << (36 - busslot)) & ctlreg)) { if (pin == 1) pin += (20 - busslot); else { - /* Must be a card-based bridge. */ - printk(KERN_WARNING "takara_swizzle: cannot handle " - "card-bridge behind builtin bridge yet.\n"); + /* Can only handle INTA pins currently. */ + printk(KERN_WARNING "takara_swizzle: cannot only " + "handle cards with INTA IRQ pin now.\n"); } + } else { + /* Must be a card-based bridge. */ + printk(KERN_WARNING "takara_swizzle: cannot handle " + "card-bridge behind builtin bridge yet.\n"); } *pinp = pin; @@ -178,7 +205,7 @@ takara_pci_fixup(void) { layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(takara_map_irq, takara_swizzle); - /* enable_ide(0x26e); */ + enable_ide(0x26e); } @@ -195,8 +222,8 @@ struct alpha_machine_vector takara_mv __initmv = { machine_check: cia_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, - nr_irqs: 20, - irq_probe_mask: _PROBE_MASK(20), + nr_irqs: 32, + irq_probe_mask: _PROBE_MASK(32), update_irq_hw: takara_update_irq_hw, ack_irq: generic_ack_irq, device_interrupt: takara_device_interrupt, diff --git a/arch/alpha/math-emu/fp-emul.c b/arch/alpha/math-emu/fp-emul.c index 9ab3b710b2bc..16651b09643b 100644 --- a/arch/alpha/math-emu/fp-emul.c +++ b/arch/alpha/math-emu/fp-emul.c @@ -85,15 +85,15 @@ void cleanup_module(void) /* For 128-bit division. */ -__complex__ unsigned long +void udiv128(unsigned long divisor_f0, unsigned long divisor_f1, - unsigned long dividend_f0, unsigned long dividend_f1) + unsigned long dividend_f0, unsigned long dividend_f1, + unsigned long *quot, unsigned long *remd) { _FP_FRAC_DECL_2(quo); _FP_FRAC_DECL_2(rem); _FP_FRAC_DECL_2(tmp); unsigned long i, num_bits, bit; - __complex__ unsigned long ret; _FP_FRAC_SET_2(rem, _FP_ZEROFRAC_2); _FP_FRAC_SET_2(quo, _FP_ZEROFRAC_2); @@ -139,9 +139,9 @@ udiv128(unsigned long divisor_f0, unsigned long divisor_f1, } out: - __real__ ret = quo_f1; - __imag__ ret = rem_f1; - return ret; + *quot = quo_f1; + *remd = rem_f1; + return; } /* diff --git a/arch/alpha/math-emu/sfp-machine.h b/arch/alpha/math-emu/sfp-machine.h index 9557f5aa6dda..710eade038d9 100644 --- a/arch/alpha/math-emu/sfp-machine.h +++ b/arch/alpha/math-emu/sfp-machine.h @@ -552,15 +552,17 @@ do { \ : "r" ((UDItype)(u)), \ "r" ((UDItype)(v))) -extern __complex__ unsigned long udiv128(unsigned long, unsigned long, - unsigned long, unsigned long); - -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - __complex__ unsigned long x_; \ - x_ = udiv128((n0), (n1), 0, (d)); \ - (q) = __real__ x_; \ - (r) = __imag__ x_; \ +extern void udiv128(unsigned long, unsigned long, + unsigned long, unsigned long, + unsigned long *, + unsigned long *); + +#define udiv_qrnnd(q, r, n1, n0, d) \ + do { \ + unsigned long xr, xi; \ + udiv128((n0), (n1), 0, (d), &xr, &xi); \ + (q) = xr; \ + (r) = xi; \ } while (0) #define UDIV_NEEDS_NORMALIZATION 1 diff --git a/drivers/char/pcwd.c b/drivers/char/pcwd.c index 8c31de05faee..63f67bd86922 100644 --- a/drivers/char/pcwd.c +++ b/drivers/char/pcwd.c @@ -34,6 +34,8 @@ * 971222 Changed open/close for temperature handling * Michael Meskes . * 980112 Used minor numbers from include/linux/miscdevice.h + * 990403 Clear reset status after reading control status register in + * pcwd_showprevstate(). [Marc Boucher ] */ #include @@ -177,8 +179,10 @@ void pcwd_showprevstate(void) if (revision == PCWD_REVISION_A) initial_status = card_status = inb(current_readport); - else + else { initial_status = card_status = inb(current_readport + 1); + outb_p(0x00, current_readport + 1); /* clear reset status */ + } if (revision == PCWD_REVISION_A) { if (card_status & WD_WDRST) diff --git a/drivers/char/random.c b/drivers/char/random.c index f78974d6922e..c6f0cd02bc97 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c @@ -1698,7 +1698,7 @@ __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr, if (!rekey_time || (tv.tv_sec - rekey_time) > REKEY_INTERVAL) { rekey_time = tv.tv_sec; /* First three words are overwritten below. */ - get_random_bytes(&secret+3, sizeof(secret)-12); + get_random_bytes(&secret[3], sizeof(secret)-12); count = (tv.tv_sec/REKEY_INTERVAL) << HASH_BITS; } diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 97185fc062f4..3796b29f2d28 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -652,7 +652,7 @@ static inline ssize_t do_tty_write( struct inode *inode = file->f_dentry->d_inode; up(&inode->i_sem); - if (down_interruptible(&inode->i_atomic_write)) { + if (down_interruptible(&tty->atomic_write)) { down(&inode->i_sem); return -ERESTARTSYS; } @@ -682,7 +682,7 @@ static inline ssize_t do_tty_write( file->f_dentry->d_inode->i_mtime = CURRENT_TIME; ret = written; } - up(&inode->i_atomic_write); + up(&tty->atomic_write); down(&inode->i_sem); return ret; } @@ -1939,6 +1939,7 @@ static void initialize_tty_struct(struct tty_struct *tty) tty->tq_hangup.routine = do_tty_hangup; tty->tq_hangup.data = tty; sema_init(&tty->atomic_read, 1); + sema_init(&tty->atomic_write, 1); } /* diff --git a/drivers/net/Space.c b/drivers/net/Space.c index ee57d82fdd11..8c3ef645d62f 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c @@ -119,6 +119,7 @@ extern int via_rhine_probe(struct device *dev); extern int tc515_probe(struct device *dev); extern int lance_probe(struct device *dev); extern int rcpci_probe(struct device *); +extern int dmfe_reg_board(struct device *); /* Gigabit Ethernet adapters */ extern int yellowfin_probe(struct device *dev); @@ -229,6 +230,9 @@ struct devprobe pci_probes[] __initdata = { #ifdef CONFIG_VIA_RHINE {via_rhine_probe, 0}, #endif +#ifdef CONFI_NET_DM9102 + {dmfe_reg_board, 0}, +#endif {NULL, 0}, }; diff --git a/drivers/net/dmfe.c b/drivers/net/dmfe.c index a037b2931aea..7893c16ad789 100644 --- a/drivers/net/dmfe.c +++ b/drivers/net/dmfe.c @@ -47,16 +47,8 @@ */ #include -#ifdef MODULE -#ifdef MODVERSIONS -#include -#endif #include #include -#else -#define MOD_INC_USE_COUNT -#define MOD_DEC_USE_COUNT -#endif #include #include @@ -69,10 +61,6 @@ #include #include -#if LINUX_VERSION_CODE < 0x20155 -#include -#endif - #include #include #include @@ -291,7 +279,7 @@ unsigned long CrcTable[256] = }; /* function declaration ------------------------------------- */ -static int dmfe_reg_board(struct device *); +int dmfe_reg_board(struct device *); static int dmfe_open(struct device *); static int dmfe_start_xmit(struct sk_buff *, struct device *); static int dmfe_stop(struct device *); diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c index cc690c7fae66..d67399a08f73 100644 --- a/drivers/net/ibmtr.c +++ b/drivers/net/ibmtr.c @@ -79,6 +79,10 @@ * * Changes by Tim Hockin (thockin@isunix.it.ilstu.edu) : * + added spinlocks for SMP sanity (10 March 1999) + * + * Changes by Jochen Friedrich to enable RFC1469 Option 2 multicasting + * i.e. using functional address C0 00 00 04 00 00 to transmit and + * receive multicast packets. */ /* change the define of IBMTR_DEBUG_MESSAGES to a nonzero value @@ -213,6 +217,7 @@ static int tok_open(struct device *dev); static int tok_close(struct device *dev); static int tok_send_packet(struct sk_buff *skb, struct device *dev); static struct net_device_stats * tok_get_stats(struct device *dev); +static void tok_set_multicast_list(struct device *dev); void ibmtr_readlog(struct device *dev); void ibmtr_reset_timer(struct timer_list *tmr, struct device *dev); int ibmtr_change_mtu(struct device *dev, int mtu); @@ -778,7 +783,7 @@ __initfunc(static int trdev_init(struct device *dev)) dev->stop = tok_close; dev->hard_start_xmit = tok_send_packet; dev->get_stats = tok_get_stats; - dev->set_multicast_list = NULL; + dev->set_multicast_list = tok_set_multicast_list; dev->change_mtu = ibmtr_change_mtu; #ifndef MODULE @@ -790,6 +795,43 @@ __initfunc(static int trdev_init(struct device *dev)) } +static void tok_set_multicast_list(struct device *dev) +{ + struct tok_info *ti=(struct tok_info *)dev->priv; + struct dev_mc_list *mclist; + unsigned char address[4]; + + int i; + + address[0] = address[1] = address[2] = address[3] = 0; + + mclist = dev->mc_list; + for (i=0; i< dev->mc_count; i++) + { + address[0] |= mclist->dmi_addr[2]; + address[1] |= mclist->dmi_addr[3]; + address[2] |= mclist->dmi_addr[4]; + address[3] |= mclist->dmi_addr[5]; + mclist = mclist->next; + } + SET_PAGE(ti->srb); + for (i=0; isrb+i); + + writeb(DIR_SET_FUNC_ADDR, + ti->srb + offsetof(struct srb_set_funct_addr, command)); + + DPRINTK("Setting functional address: "); + + for (i=0; i<4; i++) + { + writeb(address[i], + ti->srb + offsetof(struct srb_set_funct_addr, funct_address)+i); + printk("%02X ", address[i]); + } + writeb(CMD_IN_SRB, ti->mmio + ACA_OFFSET + ACA_SET + ISRA_ODD); + printk("\n"); +} static int tok_open(struct device *dev) { @@ -1621,12 +1663,10 @@ static void tr_rx(struct device *dev) ti->tr_stats.rx_packets++; skb->protocol = tr_type_trans(skb,dev); - - if (IPv4_p){ + if (IPv4_p){ skb->csum = chksum; skb->ip_summed = 1; } - netif_rx(skb); } diff --git a/drivers/net/ibmtr.h b/drivers/net/ibmtr.h index 4708366c7022..9f84d79c6482 100644 --- a/drivers/net/ibmtr.h +++ b/drivers/net/ibmtr.h @@ -444,6 +444,6 @@ struct srb_set_funct_addr { unsigned char reserved1; unsigned char ret_code; unsigned char reserved2[3]; - __u32 funct_address; + unsigned char funct_address[4]; }; diff --git a/drivers/net/net_init.c b/drivers/net/net_init.c index 9d3d4e48dbb6..a356120235ce 100644 --- a/drivers/net/net_init.c +++ b/drivers/net/net_init.c @@ -587,7 +587,7 @@ trfound: /* From the double loop above. */ memset(dev->broadcast,0xFF, TR_ALEN); /* New-style flags. */ - dev->flags = IFF_BROADCAST; + dev->flags = IFF_BROADCAST | IFF_MULTICAST ; if (new_device) register_netdevice(dev); diff --git a/drivers/video/dummycon.c b/drivers/video/dummycon.c index ea8743495ac3..9b54b6a76448 100644 --- a/drivers/video/dummycon.c +++ b/drivers/video/dummycon.c @@ -25,7 +25,7 @@ #define DUMMY_ROWS 25 #endif -__initfunc(static const char *dummycon_startup(void)) +static const char *dummycon_startup(void) { return "dummy device"; } diff --git a/include/asm-alpha/delay.h b/include/asm-alpha/delay.h index a55752abb0e9..1b63e672b74d 100644 --- a/include/asm-alpha/delay.h +++ b/include/asm-alpha/delay.h @@ -9,12 +9,22 @@ * Delay routines, using a pre-computed "loops_per_second" value. */ +/* We must make the innermost loop external, ie called via "jsr/bsr", so + that timings will be consistent accross ALL invocations, which is not + the case for a completely inline implementation. */ + +extern void ___delay(void); + extern __inline__ void __delay(unsigned long loops) { - __asm__ __volatile__(".align 3\n" - "1:\tsubq %0,1,%0\n\t" - "bge %0,1b": "=r" (loops) : "0" (loops)); + register unsigned long r0 __asm__("$0") = loops; +#ifdef MODULE + __asm__ __volatile__("lda $28,___delay; jsr $28,($28),0" + : "=r"(r0) : "r"(r0) : "$28"); +#else + __asm__ __volatile__("bsr $28,___delay" : "=r"(r0) : "r"(r0) : "$28"); +#endif } /* diff --git a/include/asm-alpha/hwrpb.h b/include/asm-alpha/hwrpb.h index 69823af357c4..d67700d10440 100644 --- a/include/asm-alpha/hwrpb.h +++ b/include/asm-alpha/hwrpb.h @@ -55,6 +55,7 @@ #define ST_DEC_TSUNAMI 34 /* Tsunami systype */ #define ST_DEC_WILDFIRE 35 /* Wildfire systype */ #define ST_DEC_CUSCO 36 /* CUSCO systype */ +#define ST_DEC_EIGER 37 /* Eiger systype */ /* UNOFFICIAL!!! */ #define ST_UNOFFICIAL_BIAS 100 diff --git a/include/asm-alpha/irq.h b/include/asm-alpha/irq.h index ad1c917a36b6..b47f09eb379a 100644 --- a/include/asm-alpha/irq.h +++ b/include/asm-alpha/irq.h @@ -27,7 +27,8 @@ #elif defined(CONFIG_ALPHA_EB66) || \ defined(CONFIG_ALPHA_EB64P) || \ - defined(CONFIG_ALPHA_MIKASA) + defined(CONFIG_ALPHA_MIKASA) || \ + defined(CONFIG_ALPHA_TAKARA) # define NR_IRQS 32 #elif defined(CONFIG_ALPHA_ALCOR) || \ @@ -42,13 +43,11 @@ defined(CONFIG_ALPHA_SX164) # define NR_IRQS 40 -#elif defined(CONFIG_ALPHA_DP264) || \ - defined(CONFIG_ALPHA_RAWHIDE) +#elif defined(CONFIG_ALPHA_DP264) || \ + defined(CONFIG_ALPHA_RAWHIDE) || \ + defined(CONFIG_ALPHA_EIGER) # define NR_IRQS 64 -#elif defined(CONFIG_ALPHA_TAKARA) -# define NR_IRQS 20 - #else /* everyone else */ # define NR_IRQS 16 #endif diff --git a/include/linux/fs.h b/include/linux/fs.h index 4e05d30e4a11..93a39537ac5c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -22,6 +22,7 @@ #include #include #include +#include /* just in case the #define NULL previously in here was needed */ struct poll_table_struct; @@ -65,10 +66,6 @@ extern int max_super_blocks, nr_super_blocks; #define READA 2 /* read-ahead - don't block if no resources */ #define WRITEA 3 /* write-ahead - don't block if no resources */ -#ifndef NULL -#define NULL ((void *) 0) -#endif - #define NIL_FILP ((struct file *)0) #define SEL_IN 1 #define SEL_OUT 2 diff --git a/include/linux/posix_types.h b/include/linux/posix_types.h index 338160e48b48..3ee2ed9de1db 100644 --- a/include/linux/posix_types.h +++ b/include/linux/posix_types.h @@ -1,15 +1,7 @@ #ifndef _LINUX_POSIX_TYPES_H #define _LINUX_POSIX_TYPES_H -/* - * This file is generally used by user-level software, so you need to - * be a little careful about namespace pollution etc. Also, we cannot - * assume GCC is being used. - */ - -#ifndef NULL -# define NULL ((void *) 0) -#endif +#include /* * This allows for 1024 file descriptors: if NR_OPEN is ever grown diff --git a/include/linux/sched.h b/include/linux/sched.h index 5ef85c63c6ae..da3d5ca0e614 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -97,10 +97,6 @@ struct sched_param { int sched_priority; }; -#ifndef NULL -#define NULL ((void *) 0) -#endif - #ifdef __KERNEL__ #include diff --git a/include/linux/stddef.h b/include/linux/stddef.h index 39da8088d942..dfa23221524e 100644 --- a/include/linux/stddef.h +++ b/include/linux/stddef.h @@ -2,7 +2,11 @@ #define _LINUX_STDDEF_H #undef NULL +#if defined(__cplusplus) +#define NULL 0 +#else #define NULL ((void *)0) +#endif #undef offsetof #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) diff --git a/include/linux/string.h b/include/linux/string.h index 1b3fa4e51cf0..9ea63cd05c23 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -2,10 +2,7 @@ #define _LINUX_STRING_H_ #include /* for size_t */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif +#include /* for NULL */ #ifdef __cplusplus extern "C" { diff --git a/include/linux/tty.h b/include/linux/tty.h index ddeb2d9bb7f8..d215a2703023 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -303,6 +303,7 @@ struct tty_struct { unsigned long canon_head; unsigned int canon_column; struct semaphore atomic_read; + struct semaphore atomic_write; }; /* tty magic number */ diff --git a/include/net/ip.h b/include/net/ip.h index 5e80fb4380fc..1a6cb610e2c5 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -203,6 +203,22 @@ extern __inline__ void ip_eth_mc_map(u32 addr, char *buf) buf[3]=addr&0x7F; } +/* + * Map a multicast IP onto multicast MAC for type Token Ring. + * This conforms to RFC1469 Option 2 Multicasting i.e. + * using a functional address to transmit / receive + * multicast packets. + */ + +extern __inline__ void ip_tr_mc_map(u32 addr, char *buf) +{ + buf[0]=0xC0; + buf[1]=0x00; + buf[2]=0x00; + buf[3]=0x04; + buf[4]=0x00; + buf[5]=0x00; +} extern int ip_call_ra_chain(struct sk_buff *skb); diff --git a/net/802/tr.c b/net/802/tr.c index 9047eaa49108..56e28b8894d0 100644 --- a/net/802/tr.c +++ b/net/802/tr.c @@ -189,22 +189,27 @@ unsigned short tr_type_trans(struct sk_buff *skb, struct device *dev) skb_pull(skb,sizeof(struct trh_hdr)-TR_MAXRIFLEN+riflen); - tr_add_rif_info(trh, dev); - - if(*trh->daddr & 1) + if(*trh->daddr & 0x80) { if(!memcmp(trh->daddr,dev->broadcast,TR_ALEN)) skb->pkt_type=PACKET_BROADCAST; else skb->pkt_type=PACKET_MULTICAST; } - + else if ( (trh->daddr[0] & 0x01) && (trh->daddr[1] & 0x00) && (trh->daddr[2] & 0x5E)) + { + skb->pkt_type=PACKET_MULTICAST; + } else if(dev->flags & IFF_PROMISC) { if(memcmp(trh->daddr, dev->dev_addr, TR_ALEN)) skb->pkt_type=PACKET_OTHERHOST; } + if ((skb->pkt_type != PACKET_BROADCAST) && + (skb->pkt_type != PACKET_MULTICAST)) + tr_add_rif_info(trh,dev) ; + /* * Strip the SNAP header from ARP packets since we don't * pass them through to the 802.2/SNAP layers. @@ -231,14 +236,18 @@ static void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct devic unsigned int hash; rif_cache entry; unsigned char *olddata; + unsigned char mcast_func_addr[] = {0xC0,0x00,0x00,0x04,0x00,0x00} ; + unsigned long flags; spin_lock_irqsave(&rif_lock, flags); /* * Broadcasts are single route as stated in RFC 1042 - */ - if(!memcmp(&(trh->daddr[0]),&(dev->broadcast[0]),TR_ALEN)) + */ + + if ( (!memcmp(&(trh->daddr[0]),&(dev->broadcast[0]),TR_ALEN)) || + (!memcmp(&(trh->daddr[0]),&(mcast_func_addr[0]), TR_ALEN)) ) { trh->rcf=htons((((sizeof(trh->rcf)) << 8) & TR_RCF_LEN_MASK) | TR_RCF_FRAME2K | TR_RCF_LIMITED_BROADCAST); diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 27d2f80214b6..1e5cf1b1142e 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -194,9 +194,14 @@ int arp_mc_map(u32 addr, u8 *haddr, struct device *dev, int dir) { switch (dev->type) { case ARPHRD_ETHER: - case ARPHRD_IEEE802: case ARPHRD_FDDI: - ip_eth_mc_map(addr, haddr); + ip_eth_mc_map(addr, haddr) ; + return 0 ; + case ARPHRD_IEEE802: + if ( (dev->name[0] == 't') && (dev->name[1] == 'r')) /* Token Ring */ + ip_tr_mc_map(addr,haddr) ; + else + ip_eth_mc_map(addr, haddr); return 0; default: if (dir) { -- 2.39.5