diff options
358 files changed, 13166 insertions, 9169 deletions
diff --git a/Documentation/Changes b/Documentation/Changes index 4521da0de42e..0b2f66e6f91e 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -335,9 +335,9 @@ o <ftp://ftp.isdn4linux.de/pub/isdn4linux/utils/testing/isdn4k-utils.v3.1beta7. Netfilter --------- -o <http://netfilter.filewatcher.org/iptables-1.1.1.tar.bz2> -o <http://www.samba.org/netfilter/iptables-1.1.1.tar.bz2> -o <http://netfilter.kernelnotes.org/iptables-1.1.1.tar.bz2> +o <http://netfilter.filewatcher.org/iptables-1.2.tar.bz2> +o <http://netfilter.samba.org/iptables-1.2.tar.bz2> +o <http://netfilter.kernelnotes.org/iptables-1.2.tar.bz2> Ip-route2 --------- diff --git a/Documentation/Configure.help b/Documentation/Configure.help index 9381fcf0de6a..bfe48e9ba811 100644 --- a/Documentation/Configure.help +++ b/Documentation/Configure.help @@ -2069,6 +2069,72 @@ CONFIG_INET_ECN If in doubt, say N. +IP6 tables support (required for filtering/masq/NAT) +CONFIG_IP6_NF_IPTABLES + ip6tables is a general, extensible packet identification framework. + Currently only the packet filtering and packet mangling subsystem + for IPv6 use this, but connection tracking is going to follow. + Say 'Y' or 'M' here if you want to use either of those. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + +IPv6 limit match support +CONFIG_IP6_NF_MATCH_LIMIT + limit matching allows you to control the rate at which a rule can be + matched: mainly useful in combination with the LOG target ("LOG + target support", below) and to avoid some Denial of Service attacks. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + +MAC address match support +CONFIG_IP6_NF_MATCH_MAC + mac matching allows you to match packets based on the source + ethernet address of the packet. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + +netfilter mark match support +CONFIG_IP6_NF_MATCH_MARK + Netfilter mark matching allows you to match packets based on the + `nfmark' value in the packet. This can be set by the MARK target + (see below). + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + +Packet filtering +CONFIG_IP6_NF_FILTER + Packet filtering defines a table `filter', which has a series of + rules for simple packet filtering at local input, forwarding and + local output. See the man page for iptables(8). + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + +Packet mangling +CONFIG_IP6_NF_MANGLE + This option adds a `mangle' table to iptables: see the man page for + iptables(8). This table is used for various packet alterations + which can effect how the packet is routed. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + +MARK target support +CONFIG_IP6_NF_TARGET_MARK + This option adds a `MARK' target, which allows you to create rules + in the `mangle' table which alter the netfilter mark (nfmark) field + associated with the packet packet prior to routing. This can change + the routing method (see `IP: use netfilter MARK value as routing + key') and can also be used by other subsystems to change their + behavior. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. + SYN flood protection CONFIG_SYN_COOKIES Normal TCP/IP networking is open to an attack known as "SYN @@ -13266,7 +13332,7 @@ CONFIG_ACPI This support requires an ACPI compliant platform (hardware/firmware). If both ACPI and Advanced Power Management (APM) support are - configured, ACPI is used. + configured, whichever is loaded first shall be used. This code DOES NOT currently provide a complete OSPM implementation -- it has not yet reached APM's level of functionality. When fully @@ -17004,6 +17070,20 @@ CONFIG_DISPLAY7SEG another UltraSPARC-IIi-cEngine boardset with a 7-segment display, you should say N to this option. +CP1XXX Hardware Watchdog support +CONFIG_WATCHDOG_CP1XXX + This is the driver for the hardware watchdog timers present on + Sun Microsystems CompactPCI models CP1400 and CP1500. + + This driver is also available as a module ( = code which can be + inserted in and removed from the running kernel whenever you want). + The module will be called cpwatchdog.o. If you want to compile it + as a module, say M here and read Documentation/modules.txt. + + If you do not have a CompactPCI model CP1400 or CP1500, or + another UltraSPARC-IIi-cEngine boardset with hardware watchdog, + you should say N to this option. + IA-64 system type CONFIG_IA64_GENERIC This selects the system type of your hardware. A "generic" kernel diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt index f3ae78497971..c47cd632d964 100644 --- a/Documentation/cachetlb.txt +++ b/Documentation/cachetlb.txt @@ -167,7 +167,7 @@ Here are the routines, one by one: This interface flushes an entire user address space from the caches. That is, after running, there will be no cache - lines assosciated with 'mm'. + lines associated with 'mm'. This interface is used to handle whole address space page table operations such as what happens during @@ -209,7 +209,7 @@ require a whole different set of interfaces to handle properly. The biggest problem is that of virtual aliasing in the data cache of a processor. -Is your port subsceptible to virtual aliasing in it's D-cache? +Is your port susceptible to virtual aliasing in it's D-cache? Well, if your D-cache is virtually indexed, is larger in size than PAGE_SIZE, and does not prevent multiple cache lines for the same physical address from existing at once, you have this problem. @@ -221,6 +221,9 @@ size). This setting will force the SYSv IPC layer to only allow user processes to mmap shared memory at address which are a multiple of this value. +NOTE: This does not fix shared mmaps, check out the sparc64 port for +one way to solve this (in particular SPARC_FLAG_MMAPSHARED). + Next, you have two methods to solve the D-cache aliasing issue for all other cases. Please keep in mind that fact that, for a given page mapped into some user address space, there is always at least one more @@ -240,7 +243,7 @@ existing ports should move over to the new mechanism as well. The physical page 'page' is about to be place into the user address space of a process. If it is possible for stores done recently by the kernel into this physical - page, to not be visible to an arbitray mapping in userspace, + page, to not be visible to an arbitrary mapping in userspace, you must flush this page from the D-cache. If the D-cache is writeback in nature, the dirty data (if @@ -266,7 +269,7 @@ Here is the new interface: For example, a port may temporarily map 'from' and 'to' to kernel virtual addresses during the copy. The virtual address - for these two pages is choosen in such a way that the kernel + for these two pages is chosen in such a way that the kernel load/store instructions happen to virtual addresses which are of the same "color" as the user mapping of the page. Sparc64 for example, uses this technique. @@ -306,7 +309,7 @@ Here is the new interface: simply be defined as a nop on that architecture. There is a bit set aside in page->flags (PG_arch_1) as - "architecture private". The kernel guarentees that, + "architecture private". The kernel guarantees that, for pagecache pages, it will clear this bit when such a page first enters the pagecache. @@ -323,7 +326,14 @@ Here is the new interface: update_mmu_cache(), a check is made of this flag bit, and if set the flush is done and the flag bit is cleared. -XXX Not documented: flush_icache_page(), need to talk to Paul - Mackerras, David Mosberger-Tang, et al. - to see what the expected semantics of this - interface are. -DaveM + void flush_icache_range(unsigned long start, unsigned long end) + When the kernel stores into addresses that it will execute + out of (eg when loading modules), this function is called. + + If the icache does not snoop stores then this routine will need + to flush it. + + void flush_icache_page(struct vm_area_struct *vma, struct page *page) + All the functionality of flush_icache_page can be implemented in + flush_dcache_page and update_mmu_cache. In 2.5 the hope is to + remove this interface completely. @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 1 -EXTRAVERSION =-pre9 +EXTRAVERSION =-pre10 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index c5aece040da0..b17f499b4ab5 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -253,7 +253,8 @@ static int __init find_isa_irq_pin(int irq, int type) * Find a specific PCI IRQ entry. * Not an __init, possibly needed by modules */ -static int __init pin_2_irq(int idx, int apic, int pin); +static int pin_2_irq(int idx, int apic, int pin); + int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin) { int apic, i, best_guess = -1; @@ -475,7 +476,7 @@ static inline int irq_trigger(int idx) return MPBIOS_trigger(idx); } -static int __init pin_2_irq(int idx, int apic, int pin) +static int pin_2_irq(int idx, int apic, int pin) { int irq, i; int bus = mp_irqs[idx].mpc_srcbus; diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 2423a8b06ef1..7df9c875ce7f 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c @@ -26,8 +26,6 @@ #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int sys_wait4(pid_t pid, unsigned long *stat_addr, - int options, unsigned long *ru); asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index e1ff3c09248e..77b0eb279387 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -633,6 +633,9 @@ int __init scc_enet_init(void) /* Allocate some private information. */ cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL); + if (cep == NULL) + return -ENOMEM; + __clear_user(cep,sizeof(*cep)); spin_lock_init(&cep->lock); diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index da3991ae33ff..c8c31bd4241f 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -1082,6 +1082,9 @@ int __init fec_enet_init(void) */ cep = (struct fcc_enet_private *) kmalloc(sizeof(*cep), GFP_KERNEL); + if (cep == NULL) + return -ENOMEM; + __clear_user(cep,sizeof(*cep)); spin_lock_init(&cep->lock); cep->fip = fip; diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index b77cf32da5e4..01eb2758b672 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -652,7 +652,9 @@ int __init scc_enet_init(void) /* Allocate some private information. */ cep = (struct scc_enet_private *)kmalloc(sizeof(*cep), GFP_KERNEL); - /*memset(cep, 0, sizeof(*cep));*/ + if (cep == NULL) + return -ENOMEM; + __clear_user(cep,sizeof(*cep)); spin_lock_init(&cep->lock); diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c index 659576e8ce5b..6e5e9e686f2c 100644 --- a/arch/ppc/8xx_io/fec.c +++ b/arch/ppc/8xx_io/fec.c @@ -1459,6 +1459,9 @@ int __init fec_enet_init(void) /* Allocate some private information. */ fep = (struct fec_enet_private *)kmalloc(sizeof(*fep), GFP_KERNEL); + if (fep == NULL) + return -ENOMEM; + __clear_user(fep,sizeof(*fep)); /* Create an Ethernet device instance. diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index d4172ed4a9b2..488766003a16 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -145,9 +145,6 @@ endif clean_config: rm -f .config arch/ppc/defconfig -gemini_config: clean_config - cp -f arch/ppc/configs/gemini_defconfig arch/ppc/defconfig - pmac_config: clean_config cp -f arch/ppc/configs/pmac_defconfig arch/ppc/defconfig diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 26961e8ea5ac..32c2926a141f 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -25,22 +25,12 @@ ZSZ = 0 IOFF = 0 ISZ = 0 -ifeq ($(CONFIG_ALL_PPC),y) -CONFIG_PREP=y -endif - ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.prep.smp$(MSIZE) else TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE) endif -ifeq ($(CONFIG_SMP),y) -TFTPSIMAGE=/tftpboot/sImage.smp -else -TFTPSIMAGE=/tftpboot/sImage -endif - ifeq ($(CONFIG_PPC64BRIDGE),y) MSIZE=.64 else @@ -81,8 +71,8 @@ zvmlinux.initrd: zvmlinux zvmlinux.initrd.tmp $@ rm zvmlinux.initrd.tmp -zImage: zvmlinux mkprep sImage -ifdef CONFIG_PREP +zImage: zvmlinux mkprep +ifdef CONFIG_ALL_PPC ./mkprep -pbp zvmlinux zImage endif ifdef CONFIG_APUS @@ -90,13 +80,8 @@ ifdef CONFIG_APUS gzip $(GZIP_FLAGS) vmapus endif -sImage: ../../../vmlinux -ifdef CONFIG_GEMINI - $(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage -endif - zImage.initrd: zvmlinux.initrd mkprep -ifdef CONFIG_PREP +ifdef CONFIG_ALL_PPC ./mkprep -pbp zvmlinux.initrd zImage.initrd endif @@ -128,18 +113,15 @@ mkprep : mkprep.c $(HOSTCC) -o mkprep mkprep.c znetboot : zImage -ifdef CONFIG_PREP +ifdef CONFIG_ALL_PPC cp zImage $(TFTPIMAGE) endif -ifdef CONFIG_GEMINI - cp sImage $(TFTPSIMAGE) -endif znetboot.initrd : zImage.initrd cp zImage.initrd $(TFTPIMAGE) clean: - rm -f vmlinux* zvmlinux* mkprep zImage* sImage* + rm -f vmlinux* zvmlinux* mkprep zImage* fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/boot/vreset.c b/arch/ppc/boot/vreset.c index c01361dc6721..dfabd72e73f9 100644 --- a/arch/ppc/boot/vreset.c +++ b/arch/ppc/boot/vreset.c @@ -19,12 +19,16 @@ */ #include "iso_font.h" -#include <linux/delay.h> extern char *vidmem; extern int lines, cols; -/* estimate for delay */ -unsigned long loops_per_sec = 50000000;; + +static void mdelay(int ms) +{ + for (; ms > 0; --ms) + udelay(1000); +} + /* * VGA Register */ diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile index f7ea3a3fa6b2..9dbb7909dc51 100644 --- a/arch/ppc/chrpboot/Makefile +++ b/arch/ppc/chrpboot/Makefile @@ -23,11 +23,6 @@ LD_ARGS = -Ttext 0x00400000 OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o LIBS = $(TOPDIR)/lib/lib.a -ifeq ($(CONFIG_ALL_PPC),y) -# yes, we want to build chrp stuff -CONFIG_CHRP = y -endif - ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE) else @@ -37,10 +32,10 @@ endif all: $(TOPDIR)/zImage # -# Only build anything here if we're configured for CHRP +# Only build anything here if we're configured for ALL_PPC # -- cort # -ifeq ($(CONFIG_CHRP),y) +ifeq ($(CONFIG_ALL_PPC),y) znetboot: zImage cp zImage $(TFTPIMAGE) @@ -96,6 +91,7 @@ vmlinux.coff.initrd: clean: rm -f piggyback note addnote $(OBJS) zImage + rm -f zImage.rs6k zImage.initrd zImage.initrd.rs6k fastdep: $(TOPDIR)/scripts/mkdep *.[Sch] > .depend diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile index 494026e42d80..2835e1f8966e 100644 --- a/arch/ppc/coffboot/Makefile +++ b/arch/ppc/coffboot/Makefile @@ -20,18 +20,13 @@ else MSIZE= endif -ifeq ($(CONFIG_ALL_PPC),y) -# yes, we want to build pmac stuff -CONFIG_PMAC = y -endif - ifeq ($(CONFIG_SMP),y) TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE) else TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE) endif -ifeq ($(CONFIG_PMAC),y) +ifeq ($(CONFIG_ALL_PPC),y) chrpmain.o: chrpmain.c $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c index b76ba5976d9b..49e769f2240e 100644 --- a/arch/ppc/coffboot/coffmain.c +++ b/arch/ppc/coffboot/coffmain.c @@ -22,11 +22,18 @@ void gunzip(void *, int, unsigned char *, int *); #define get_32be(x) (*(unsigned *)(x)) #define RAM_START 0xc0000000 -#define PROG_START RAM_START #define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ +#define PROG_START RAM_START +#define PROG_SIZE 0x00400000 + +#define SCRATCH_SIZE (128 << 10) + char *avail_ram; -char *end_avail; +char *begin_avail, *end_avail; +char *avail_high; +unsigned int heap_use; +unsigned int heap_max; extern char _start[], _end[]; extern char image_data[]; @@ -34,6 +41,7 @@ extern int image_len; extern char initrd_data[]; extern int initrd_len; +char heap[SCRATCH_SIZE]; boot(int a1, int a2, void *prom) { @@ -58,16 +66,18 @@ boot(int a1, int a2, void *prom) im = image_data; len = image_len; /* claim 3MB starting at 0 */ - claim(0, 3 << 20, 0); + claim(0, PROG_SIZE, 0); dst = (void *) RAM_START; if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim 512kB for scratch space */ - avail_ram = claim(0, 512 << 10, 0x10) + RAM_START; - end_avail = avail_ram + (512 << 10); - printf("avail_ram = %x\n", avail_ram); + /* claim some memory for scratch space */ + begin_avail = avail_high = avail_ram = heap; + end_avail = heap + sizeof(heap); + printf("heap at 0x%x\n", avail_ram); printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, 3 << 20, im, &len); + gunzip(dst, PROG_SIZE, im, &len); printf("done %u bytes\n", len); + printf("%u bytes of heap consumed, max in use %u\n", + avail_high - begin_avail, heap_max); } else { memmove(dst, im, len); } @@ -78,9 +88,6 @@ boot(int a1, int a2, void *prom) sa = (unsigned long)PROG_START; printf("start address = 0x%x\n", sa); -#if 0 - pause(); -#endif (*(void (*)())sa)(a1, a2, prom); printf("returned?\n"); @@ -114,13 +121,33 @@ void make_bi_recs(unsigned long addr) rec = (struct bi_record *)((unsigned long)rec + rec->size); } +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + void *zalloc(void *x, unsigned items, unsigned size) { - void *p = avail_ram; + void *p; + struct memchunk **mpp, *mp; size *= items; size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; if (avail_ram > end_avail) { printf("oops... out of memory\n"); pause(); @@ -130,6 +157,17 @@ void *zalloc(void *x, unsigned items, unsigned size) void zfree(void *x, void *addr, unsigned nb) { + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; } #define HEAD_CRC 2 diff --git a/arch/ppc/coffboot/main.c b/arch/ppc/coffboot/main.c deleted file mode 100644 index e6049b4a22bc..000000000000 --- a/arch/ppc/coffboot/main.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * 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 "nonstdio.h" -#include "rs6000.h" -#include "zlib.h" -#include <asm/bootinfo.h> -#include <asm/processor.h> -#define __KERNEL__ -#include <asm/page.h> - -extern void *finddevice(const char *); -extern int getprop(void *, const char *, void *, int); -void gunzip(void *, int, unsigned char *, int *); - -#define get_16be(x) (*(unsigned short *)(x)) -#define get_32be(x) (*(unsigned *)(x)) - -#define RAM_START 0xc0000000 -#define PROG_START RAM_START -#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ - -#define RAM_FREE (RAM_START + 0x540000) /* after image of coffboot */ - -char *avail_ram; -char *end_avail; - -coffboot(int a1, int a2, void *prom) -{ - void *options; - unsigned loadbase; - struct external_filehdr *eh; - struct external_scnhdr *sp; - struct external_scnhdr *isect, *rsect; - int ns, oh, i; - unsigned sa, len; - void *dst; - unsigned char *im; - unsigned initrd_start, initrd_size; - - printf("coffboot starting\n"); - options = finddevice("/options"); - if (options == (void *) -1) - exit(); - if (getprop(options, "load-base", &loadbase, sizeof(loadbase)) - != sizeof(loadbase)) { - printf("error getting load-base\n"); - exit(); - } - setup_bats(RAM_START); - - loadbase += RAM_START; - eh = (struct external_filehdr *) loadbase; - ns = get_16be(eh->f_nscns); - oh = get_16be(eh->f_opthdr); - - sp = (struct external_scnhdr *) (loadbase + sizeof(struct external_filehdr) + oh); - isect = rsect = NULL; - for (i = 0; i < ns; ++i, ++sp) { - if (strcmp(sp->s_name, "image") == 0) - isect = sp; - else if (strcmp(sp->s_name, "initrd") == 0) - rsect = sp; - } - if (isect == NULL) { - printf("image section not found\n"); - exit(); - } - - if (rsect != NULL && (initrd_size = get_32be(rsect->s_size)) != 0) { - initrd_start = (RAM_END - initrd_size) & ~0xFFF; - a1 = initrd_start; - a2 = initrd_size; - printf("initial ramdisk at %x (%u bytes)\n", - initrd_start, initrd_size); - memcpy((char *) initrd_start, - (char *) (loadbase + get_32be(rsect->s_scnptr)), - initrd_size); - end_avail = (char *) initrd_start; - } else { - end_avail = (char *) RAM_END; - } - - im = (unsigned char *)(loadbase + get_32be(isect->s_scnptr)); - len = get_32be(isect->s_size); - dst = (void *) PROG_START; - - if (im[0] == 0x1f && im[1] == 0x8b) { - void *cp = (void *) RAM_FREE; - avail_ram = (void *) (RAM_FREE + ((len + 7) & -8)); - memcpy(cp, im, len); - printf("gunzipping... "); - gunzip(dst, 0x400000, cp, &len); - printf("done\n"); - - } else { - memmove(dst, im, len); - } - - flush_cache(dst, len); - - sa = (unsigned long)dst; - printf("start address = 0x%x\n", sa); - -#if 0 - pause(); -#endif - { - struct bi_record *rec; - - rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(1<<20)-1,(1<<20)); - - rec->tag = BI_FIRST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_BOOTLOADER_ID; - sprintf( (char *)rec->data, "coffboot"); - rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_MACHTYPE; - rec->data[0] = _MACH_Pmac; - rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_LAST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - } - - (*(void (*)())sa)(a1, a2, prom); - - printf("returned?\n"); - - pause(); -} - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p = avail_ram; - - size *= items; - size = (size + 7) & -8; - avail_ram += size; - if (avail_ram > end_avail) { - printf("oops... out of memory\n"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - printf("bad gzipped data\n"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - printf("gunzip: ran out of data in header\n"); - exit(); - } - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf("inflateInit2 returned %d\n", r); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - printf("inflate returned %d\n", r); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); -} diff --git a/arch/ppc/config.in b/arch/ppc/config.in index 34606f99a33b..3b4c2c1412c8 100644 --- a/arch/ppc/config.in +++ b/arch/ppc/config.in @@ -24,21 +24,24 @@ mainmenu_option next_comment comment 'Platform support' define_bool CONFIG_PPC y choice 'Processor Type' \ - "6xx/7xx/7400 CONFIG_6xx \ + "6xx/7xx/74xx/8260 CONFIG_6xx \ 4xx CONFIG_4xx \ POWER3 CONFIG_POWER3 \ POWER4 CONFIG_POWER4 \ - 8260 CONFIG_8260 \ 8xx CONFIG_8xx" 6xx +if [ "$CONFIG_6xx" = "y" ]; then + bool 'MPC8260 CPM Support' CONFIG_8260 +fi + if [ "$CONFIG_POWER3" = "y" -o "$CONFIG_POWER4" = "y" ]; then define_bool CONFIG_PPC64BRIDGE y define_bool CONFIG_ALL_PPC y fi - + if [ "$CONFIG_8260" = "y" ]; then - define_bool CONFIG_6xx y define_bool CONFIG_SERIAL_CONSOLE y + bool 'Support for EST8260' CONFIG_EST8260 fi if [ "$CONFIG_4xx" = "y" ]; then @@ -59,25 +62,32 @@ if [ "$CONFIG_8xx" = "y" ]; then TQM860 CONFIG_TQM860 \ MBX CONFIG_MBX \ WinCept CONFIG_WINCEPT" RPX-Lite + + if [ "$CONFIG_TQM8xxL" = "y" ]; then + bool 'FPS850 Mainboard' CONFIG_FPS850 + fi fi -if [ "$CONFIG_6xx" = "y" ]; then + +if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then choice 'Machine Type' \ "PowerMac/PReP/MTX/CHRP CONFIG_ALL_PPC \ - Gemini CONFIG_GEMINI \ - EST8260 CONFIG_EST8260 \ APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP fi +if [ "$CONFIG_PPC64BRIDGE" != "y" ]; then + bool 'Workarounds for PPC601 bugs' CONFIG_PPC601_SYNC_FIX +fi + if [ "$CONFIG_8xx" = "y" -o "$CONFIG_8260" = "y" ]; then define_bool CONFIG_ALL_PPC n fi -if [ "$CONFIG_TQM8xxL" = "y" ]; then - bool 'FPS850 Mainboard' CONFIG_FPS850 +bool 'Symmetric multi-processing support' CONFIG_SMP +if [ "$CONFIG_SMP" = "y" ]; then + bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS fi -bool 'Symmetric multi-processing support' CONFIG_SMP -if [ "$CONFIG_6xx" = "y" ];then +if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then bool 'AltiVec Support' CONFIG_ALTIVEC fi @@ -106,14 +116,14 @@ define_bool CONFIG_MCA n if [ "$CONFIG_APUS" = "y" -o "$CONFIG_4xx" = "y" -o \ "$CONFIG_8260" = "y" ]; then - define_bool CONFIG_PCI n + define_bool CONFIG_PCI n else - if [ "$CONFIG_8xx" = "y" ]; then - bool 'QSpan PCI' CONFIG_PCI_QSPAN - define_bool CONFIG_PCI $CONFIG_PCI_QSPAN - else - define_bool CONFIG_PCI y - fi + if [ "$CONFIG_8xx" = "y" ]; then + bool 'QSpan PCI' CONFIG_PCI_QSPAN + define_bool CONFIG_PCI $CONFIG_PCI_QSPAN + else + define_bool CONFIG_PCI y + fi fi bool 'Networking support' CONFIG_NET @@ -123,40 +133,34 @@ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT # only elf supported, a.out is not -- Cort if [ "$CONFIG_PROC_FS" = "y" ]; then - define_bool CONFIG_KCORE_ELF y + define_bool CONFIG_KCORE_ELF y fi define_bool CONFIG_BINFMT_ELF y define_bool CONFIG_KERNEL_ELF y tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC source drivers/pci/Config.in -source drivers/zorro/Config.in bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG if [ "$CONFIG_HOTPLUG" = "y" ]; then - source drivers/pcmcia/Config.in + source drivers/pcmcia/Config.in else - define_bool CONFIG_PCMCIA n + define_bool CONFIG_PCMCIA n fi source drivers/parport/Config.in if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then - bool 'Support for VGA Console' CONFIG_VGA_CONSOLE - bool 'Support for frame buffer devices' CONFIG_FB - if [ "$CONFIG_FB" = "y" ]; then - bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC - fi - tristate 'Support for /dev/rtc' CONFIG_PPC_RTC - bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE - bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT - bool 'Support for Motorola Hot Swap' CONFIG_MOTOROLA_HOTSWAP fi -if [ "$CONFIG_PREP" = "y" -o "$CONFIG_ALL_PPC" = "y" ]; then - bool 'PReP bootloader kernel arguments' CONFIG_CMDLINE_BOOL +if [ "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE + bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS + bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT + bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL + bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" fi @@ -181,6 +185,7 @@ if [ "$CONFIG_APUS" = "y" ]; then fi bool 'Use power LED as a heartbeat' CONFIG_HEARTBEAT bool '/proc/hardware support' CONFIG_PROC_HARDWARE + source drivers/zorro/Config.in fi endmenu @@ -254,7 +259,13 @@ endmenu mainmenu_option next_comment comment 'Console drivers' -source drivers/video/Config.in +if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then + bool 'Support for VGA Console' CONFIG_VGA_CONSOLE +fi + source drivers/video/Config.in +if [ "$CONFIG_FB" = "y" -a "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC +fi endmenu source drivers/input/Config.in @@ -267,29 +278,26 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then bool 'Support for CUDA based PowerMacs' CONFIG_ADB_CUDA bool 'Support for PMU based PowerMacs' CONFIG_ADB_PMU if [ "$CONFIG_ADB_PMU" = "y" ]; then - bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK - # made a separate option since backlight may end up beeing used - # on non-powerbook machines (but only on PMU based ones AFAIK) - bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT + bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK + # made a separate option since backlight may end up beeing used + # on non-powerbook machines (but only on PMU based ones AFAIK) + bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT fi bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL if [ "$CONFIG_MAC_SERIAL" = "y" ]; then - bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE + bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE fi bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB if [ "$CONFIG_ADB" = "y" ]; then - bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO - fi -fi -if [ "$CONFIG_ADB" = "y" ]; then - dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT - if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then - define_bool CONFIG_MAC_HID y - bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES - bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN - else - bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD + bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO + dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT + if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then + bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES + bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN + else + bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD + fi fi fi endmenu diff --git a/arch/ppc/configs/apus_defconfig b/arch/ppc/configs/apus_defconfig index ed930fff2524..69e25a9b3849 100644 --- a/arch/ppc/configs/apus_defconfig +++ b/arch/ppc/configs/apus_defconfig @@ -11,9 +11,7 @@ CONFIG_EXPERIMENTAL=y # # Loadable module support # -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y +# CONFIG_MODULES is not set # # Platform support @@ -23,14 +21,14 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set -CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set -# CONFIG_APUS is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +CONFIG_APUS=y +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set # CONFIG_ALTIVEC is not set +CONFIG_MACH_SPECIFIC=y # # General setup @@ -38,8 +36,10 @@ CONFIG_ALL_PPC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set -CONFIG_PCI=y +# CONFIG_MCA is not set +# CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y CONFIG_SYSVIPC=y @@ -47,23 +47,35 @@ CONFIG_SYSVIPC=y CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_PCI_NAMES is not set -# CONFIG_HOTPLUG is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# # CONFIG_PCMCIA is not set # # Parallel port support # # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set +CONFIG_PPC_RTC=y +CONFIG_FB_CONSOLE=y +CONFIG_AMIGA=y +CONFIG_ZORRO=y +CONFIG_AMIGAMOUSE=y +CONFIG_ABSTRACT_CONSOLE=y CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y -# CONFIG_PPC_RTC is not set -CONFIG_PROC_DEVICETREE=y -# CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_AMIGA_BUILTIN_SERIAL=y +# CONFIG_M68K_PRINTER is not set +CONFIG_GVPIOEXT=y +# CONFIG_GVPIOEXT_LP is not set +CONFIG_GVPIOEXT_PLIP=y +CONFIG_MULTIFACE_III_TTY=y +# CONFIG_SERIAL_CONSOLE is not set +CONFIG_HEARTBEAT=y +CONFIG_PROC_HARDWARE=y +CONFIG_ZORRO_NAMES=y # # Memory Technology Devices (MTD) @@ -80,12 +92,14 @@ CONFIG_PROC_DEVICETREE=y # Block devices # # CONFIG_BLK_DEV_FD is not set +CONFIG_AMIGA_FLOPPY=y +CONFIG_AMIGA_Z2RAM=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 @@ -106,21 +120,17 @@ CONFIG_BLK_DEV_INITRD=y # # Networking options # -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK=y -# CONFIG_RTNETLINK is not set -# CONFIG_NETLINK_DEV is not set +# CONFIG_PACKET is not set +# CONFIG_NETLINK is not set # CONFIG_NETFILTER is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y -CONFIG_IP_MULTICAST=y +# CONFIG_IP_MULTICAST is not set # 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_INET_ECN is not set # CONFIG_SYN_COOKIES is not set # CONFIG_IPV6 is not set @@ -131,7 +141,7 @@ CONFIG_IP_MULTICAST=y # # # CONFIG_IPX is not set -CONFIG_ATALK=m +# CONFIG_ATALK is not set # CONFIG_DECNET is not set # CONFIG_BRIDGE is not set # CONFIG_X25 is not set @@ -151,9 +161,48 @@ CONFIG_ATALK=m # # ATA/IDE/MFM/RLL support # -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set +CONFIG_IDE=y + +# +# IDE, ATA and ATAPI Block devices +# +CONFIG_BLK_DEV_IDE=y + +# +# Please see Documentation/ide.txt for help/info on IDE drives +# +# CONFIG_BLK_DEV_HD_IDE is not set # CONFIG_BLK_DEV_HD is not set +CONFIG_BLK_DEV_IDEDISK=y +# CONFIG_IDEDISK_MULTI_MODE is not set +# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set +# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set +# CONFIG_BLK_DEV_IDEDISK_IBM is not set +# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set +# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set +# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set +# CONFIG_BLK_DEV_IDEDISK_WD is not set +# CONFIG_BLK_DEV_COMMERIAL is not set +# CONFIG_BLK_DEV_TIVO is not set +# CONFIG_BLK_DEV_IDECS is not set +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# IDE chipset support/bugfixes +# +# CONFIG_BLK_DEV_CMD640 is not set +# CONFIG_BLK_DEV_CMD640_ENHANCED is not set +# CONFIG_BLK_DEV_ISAPNP is not set +CONFIG_BLK_DEV_GAYLE=y +CONFIG_BLK_DEV_IDEDOUBLER=y +CONFIG_BLK_DEV_BUDDHA=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_DMA_NONPCI is not set +# CONFIG_BLK_DEV_IDE_MODES is not set # # SCSI support @@ -165,7 +214,8 @@ CONFIG_SCSI=y # CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -176,29 +226,23 @@ CONFIG_SR_EXTRA_DEVS=2 # # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y +# CONFIG_SCSI_CONSTANTS is not set # CONFIG_SCSI_LOGGING is not set # # SCSI low-level drivers # -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set # CONFIG_SCSI_7000FASST is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AIC7XXX=y -# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set -CONFIG_AIC7XXX_CMDS_PER_DEVICE=8 -CONFIG_AIC7XXX_PROC_STATS=y -CONFIG_AIC7XXX_RESET_DELAY=15 +# CONFIG_SCSI_AIC7XXX is not set # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set # CONFIG_SCSI_MEGARAID is not set # CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set # CONFIG_SCSI_DMX3191D is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA is not set @@ -211,30 +255,18 @@ CONFIG_AIC7XXX_RESET_DELAY=15 # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set # CONFIG_SCSI_PSI240I is not set # CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_SIM710 is not set # CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_DEBUG is not set -CONFIG_SCSI_MESH=y -CONFIG_SCSI_MESH_SYNC_RATE=5 -CONFIG_SCSI_MAC53C94=y - -# -# IEEE 1394 (FireWire) support -# -# CONFIG_IEEE1394 is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set # # Network device support @@ -245,34 +277,30 @@ CONFIG_NETDEVICES=y # ARCnet devices # # CONFIG_ARCNET is not set - -# -# Appletalk devices -# -# CONFIG_APPLETALK is not set # CONFIG_DUMMY is not set # CONFIG_BONDING is not set # CONFIG_EQUALIZER is not set # CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set # CONFIG_NET_SB1000 is not set # # Ethernet (10 or 100Mbit) # CONFIG_NET_ETHERNET=y -CONFIG_MACE=y -CONFIG_BMAC=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set +CONFIG_ARIADNE=y +# CONFIG_NE2K_ZORRO is not set +CONFIG_A2065=y +CONFIG_HYDRA=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC 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 @@ -287,13 +315,16 @@ CONFIG_BMAC=y # CONFIG_FDDI is not set # CONFIG_HIPPI is not set CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set +CONFIG_PPP_MULTILINK=y +CONFIG_PPP_ASYNC=y +CONFIG_PPP_SYNC_TTY=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y # CONFIG_PPPOE is not set -# CONFIG_SLIP is not set +CONFIG_SLIP=y +CONFIG_SLIP_COMPRESSED=y +CONFIG_SLIP_SMART=y +# CONFIG_SLIP_MODE_SLIP6 is not set # # Wireless LAN (non-hamradio) @@ -336,44 +367,47 @@ CONFIG_PPP=y # # Console drivers # +# CONFIG_VGA_CONSOLE is not set # # Frame-buffer support # CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y -# CONFIG_FB_RIVA is not set -# CONFIG_FB_CLGEN is not set -# CONFIG_FB_PM2 is not set +CONFIG_FB_CLGEN=y +CONFIG_FB_PM2=y +CONFIG_FB_PM2_CVPPC=y # CONFIG_FB_CYBER2000 is not set -CONFIG_FB_OF=y -CONFIG_FB_CONTROL=y -CONFIG_FB_PLATINUM=y -CONFIG_FB_VALKYRIE=y -CONFIG_FB_CT65550=y -CONFIG_FB_IMSTT=y +CONFIG_FB_AMIGA=y +CONFIG_FB_AMIGA_OCS=y +CONFIG_FB_AMIGA_ECS=y +CONFIG_FB_AMIGA_AGA=y +CONFIG_FB_CYBER=y +CONFIG_FB_VIRGE=y +CONFIG_FB_RETINAZ3=y +# CONFIG_FB_FM2 is not set +# CONFIG_FB_OF is not set +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set # CONFIG_FB_S3TRIO is not set # CONFIG_FB_VGA16 is not set -# CONFIG_FB_MATROX is not set -CONFIG_FB_ATY=y -# CONFIG_FB_ATY128 is not set -# CONFIG_FB_3DFX is not set -# CONFIG_FB_SIS is not set # CONFIG_FB_VIRTUAL is not set # CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_MFB=y CONFIG_FBCON_CFB8=y CONFIG_FBCON_CFB16=y CONFIG_FBCON_CFB24=y CONFIG_FBCON_CFB32=y -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -CONFIG_FBCON_FONTS=y -# CONFIG_FONT_8x8 is not set +CONFIG_FBCON_AFB=y +CONFIG_FBCON_ILBM=y +CONFIG_FBCON_FONTWIDTH8_ONLY=y +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y -CONFIG_FONT_SUN8x16=y -CONFIG_FONT_SUN12x22=y -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set +CONFIG_FONT_PEARL_8x8=y # # Input core support @@ -383,23 +417,17 @@ CONFIG_FONT_SUN12x22=y # # Macintosh device drivers # -# CONFIG_ADB_CUDA is not set -# CONFIG_ADB_PMU is not set -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set -# CONFIG_ADB is not set # # Character devices # CONFIG_VT=y CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=m +CONFIG_SERIAL=y +# CONFIG_SERIAL_CONSOLE is not set # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 +# CONFIG_UNIX98_PTYS is not set # # I2C support @@ -427,7 +455,7 @@ CONFIG_UNIX98_PTY_COUNT=256 # # CONFIG_WATCHDOG is not set # CONFIG_INTEL_RNG is not set -CONFIG_NVRAM=y +# CONFIG_NVRAM is not set # CONFIG_RTC is not set # CONFIG_DTLK is not set # CONFIG_R3964 is not set @@ -449,24 +477,24 @@ CONFIG_NVRAM=y # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y +# CONFIG_AUTOFS_FS is not set # CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set +CONFIG_AFFS_FS=y CONFIG_HFS_FS=y # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=m +CONFIG_VFAT_FS=y # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set # CONFIG_RAMFS is not set CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set -# CONFIG_MINIX_FS is not set +CONFIG_MINIX_FS=y # CONFIG_NTFS_FS is not set # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set @@ -474,7 +502,7 @@ CONFIG_PROC_FS=y # CONFIG_DEVFS_FS is not set # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set # CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set @@ -493,7 +521,7 @@ CONFIG_EXT2_FS=y CONFIG_NFS_FS=y # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set -CONFIG_NFSD=y +# CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y @@ -505,8 +533,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -514,14 +540,15 @@ CONFIG_LOCKD=y # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y +CONFIG_AMIGA_PARTITION=y +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # # Native Language Support # CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y +# 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 @@ -541,7 +568,7 @@ CONFIG_NLS_CODEPAGE_437=y # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=y # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -558,23 +585,7 @@ CONFIG_NLS_CODEPAGE_437=y # # Sound # -CONFIG_SOUND=y -# CONFIG_DMASOUND_AWACS is not set -# CONFIG_SOUND_CMPCI is not set -# CONFIG_SOUND_EMU10K1 is not set -# CONFIG_SOUND_FUSION is not set -# CONFIG_SOUND_CS4281 is not set -# CONFIG_SOUND_ES1370 is not set -# CONFIG_SOUND_ES1371 is not set -# CONFIG_SOUND_ESSSOLO1 is not set -# CONFIG_SOUND_MAESTRO is not set -# CONFIG_SOUND_SONICVIBES is not set -# CONFIG_SOUND_TRIDENT is not set -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -# CONFIG_SOUND_VIA82CXXX is not set -# CONFIG_SOUND_OSS is not set -# CONFIG_SOUND_TVMIXER is not set +# CONFIG_SOUND is not set # # USB support diff --git a/arch/ppc/configs/bseip_defconfig b/arch/ppc/configs/bseip_defconfig index f0ff611f471e..82b7174bdc1c 100644 --- a/arch/ppc/configs/bseip_defconfig +++ b/arch/ppc/configs/bseip_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -32,6 +31,7 @@ CONFIG_BSEIP=y # CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -377,8 +377,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig index 5574ecbdb70b..210887de706c 100644 --- a/arch/ppc/configs/common_defconfig +++ b/arch/ppc/configs/common_defconfig @@ -23,12 +23,11 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set +# CONFIG_8260 is not set CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set # CONFIG_APUS is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -36,9 +35,11 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set +CONFIG_MOL=y # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -49,21 +50,24 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# # CONFIG_PCMCIA is not set # # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_VGA_CONSOLE=y -CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y CONFIG_BOOTX_TEXT=y -# CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_PREP_RESIDUAL=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2" # # Memory Technology Devices (MTD) @@ -79,7 +83,7 @@ CONFIG_BOOTX_TEXT=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_FD=m # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set @@ -111,7 +115,8 @@ CONFIG_PACKET=y CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -123,6 +128,34 @@ CONFIG_IP_MULTICAST=y # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -239,6 +272,7 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -344,7 +378,6 @@ CONFIG_NET_ETHERNET=y CONFIG_MACE=y CONFIG_BMAC=y CONFIG_GMAC=y -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -357,27 +390,28 @@ CONFIG_GMAC=y CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_TULIP is not set +CONFIG_TULIP=y +CONFIG_DE4X5=m # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set # CONFIG_LNE390 is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set -# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -439,6 +473,7 @@ CONFIG_PPP_DEFLATE=y # # Console drivers # +CONFIG_VGA_CONSOLE=y # # Frame-buffer support @@ -460,7 +495,8 @@ CONFIG_FB_IMSTT=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_G450 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y CONFIG_FB_ATY128=y @@ -481,6 +517,7 @@ CONFIG_FONT_SUN12x22=y # CONFIG_FONT_6x11 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC is not set # # Input core support @@ -498,15 +535,13 @@ CONFIG_INPUT_EVDEV=y # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -CONFIG_PMAC_PBOOK=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_MAC_FLOPPY is not set +CONFIG_MAC_SERIAL=m CONFIG_ADB=y CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y -CONFIG_MAC_HID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y @@ -575,17 +610,17 @@ CONFIG_NVRAM=y # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set +CONFIG_HFS_FS=m # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set @@ -631,8 +666,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -652,6 +685,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # @@ -678,7 +712,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -695,9 +729,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y +CONFIG_SOUND=m +CONFIG_DMASOUND_AWACS=m +CONFIG_DMASOUND=m # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set @@ -711,43 +745,14 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set # # USB support # CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set # # Miscellaneous USB options @@ -763,33 +768,69 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_OHCI=y # -# USB Devices +# USB Device Class drivers # +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_SERIAL is not set + +# +# USB Multimedia devices +# # CONFIG_USB_IBMCAM is not set # CONFIG_USB_OV511 is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set +# CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# # CONFIG_USB_PLUSB is not set # CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_NET1080 is not set # -# USB Human Interface Devices (HID) +# USB port drivers # -CONFIG_USB_HID=y -# CONFIG_USB_WACOM is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB misc drivers +# +# CONFIG_USB_RIO500 is not set # # Kernel hacking diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig index afb972c0352f..a4a44f0abdb2 100644 --- a/arch/ppc/configs/est8260_defconfig +++ b/arch/ppc/configs/est8260_defconfig @@ -17,21 +17,17 @@ CONFIG_EXPERIMENTAL=y # Platform support # CONFIG_PPC=y -# CONFIG_6xx is not set +CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -CONFIG_8260=y # CONFIG_8xx is not set -CONFIG_6xx=y +CONFIG_8260=y CONFIG_SERIAL_CONSOLE=y -# CONFIG_ALL_PPC is not set -# CONFIG_GEMINI is not set CONFIG_EST8260=y -# CONFIG_APUS is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set -# CONFIG_ALTIVEC is not set CONFIG_MACH_SPECIFIC=y # @@ -40,7 +36,9 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -57,12 +55,7 @@ CONFIG_KERNEL_ELF=y # Parallel port support # # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_FB is not set # CONFIG_PPC_RTC is not set -# CONFIG_PROC_DEVICETREE is not set -# CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set # # Memory Technology Devices (MTD) @@ -184,7 +177,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -192,7 +184,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -250,6 +241,7 @@ CONFIG_NET_ETHERNET=y # # Console drivers # +# CONFIG_VGA_CONSOLE is not set # # Frame-buffer support @@ -379,8 +371,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -397,6 +387,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/ibmchrp_defconfig index 44147f58c59a..652b94209823 100644 --- a/arch/ppc/configs/gemini_defconfig +++ b/arch/ppc/configs/ibmchrp_defconfig @@ -1,5 +1,5 @@ # -# Automatically generated make config: don't edit +# Automatically generated by make menuconfig: don't edit # # CONFIG_UID16 is not set @@ -25,21 +25,22 @@ CONFIG_6xx=y # CONFIG_POWER4 is not set # CONFIG_8260 is not set # CONFIG_8xx is not set -# CONFIG_ALL_PPC is not set -CONFIG_GEMINI=y -# CONFIG_EST8260 is not set +CONFIG_ALL_PPC=y +# CONFIG_GEMINI is not set # CONFIG_APUS is not set +# CONFIG_PPC601_SYNC_FIX is not set # CONFIG_SMP is not set -CONFIG_ALTIVEC=y -CONFIG_MACH_SPECIFIC=y +# CONFIG_ALTIVEC is not set # # General setup # -# CONFIG_HIGHMEM is not set +CONFIG_HIGHMEM=y # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -48,8 +49,8 @@ CONFIG_SYSVIPC=y CONFIG_KCORE_ELF=y CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_PCI_NAMES is not set +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y # CONFIG_HOTPLUG is not set # CONFIG_PCMCIA is not set @@ -57,12 +58,12 @@ CONFIG_KERNEL_ELF=y # Parallel port support # # CONFIG_PARPORT is not set -# CONFIG_VGA_CONSOLE is not set -# CONFIG_FB is not set -# CONFIG_PPC_RTC is not set -# CONFIG_PROC_DEVICETREE is not set +CONFIG_PPC_RTC=y +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y # CONFIG_BOOTX_TEXT is not set -# CONFIG_MOTOROLA_HOTSWAP is not set +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set # # Memory Technology Devices (MTD) @@ -78,16 +79,17 @@ CONFIG_KERNEL_ELF=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_FD=y # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set # CONFIG_BLK_CPQ_CISS_DA is not set # CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y # # Multi-device support (RAID and LVM) @@ -109,7 +111,8 @@ CONFIG_PACKET=y CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -121,13 +124,37 @@ CONFIG_IP_MULTICAST=y # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set - -# -# -# # CONFIG_IPX is not set # CONFIG_ATALK is not set # CONFIG_DECNET is not set @@ -157,21 +184,14 @@ CONFIG_SYN_COOKIES=y # SCSI support # CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 -# CONFIG_CHR_DEV_SG is not set - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# +CONFIG_CHR_DEV_SG=y # CONFIG_SCSI_DEBUG_QUEUES is not set # CONFIG_SCSI_MULTI_LUN is not set CONFIG_SCSI_CONSTANTS=y @@ -205,13 +225,14 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set -CONFIG_SCSI_NCR53C8XX=y -# CONFIG_SCSI_SYM53C8XX is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 CONFIG_SCSI_NCR53C8XX_SYNC=20 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set # CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set # CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set @@ -258,7 +279,7 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -CONFIG_NCR885E=y +# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -268,7 +289,31 @@ CONFIG_NCR885E=y # CONFIG_DEPCA is not set # CONFIG_HP100 is not set # CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +CONFIG_DE4X5=y +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -291,7 +336,12 @@ CONFIG_NCR885E=y # # Token Ring devices # -# CONFIG_TR is not set +CONFIG_TR=y +# CONFIG_IBMTR is not set +CONFIG_IBMOL=y +# CONFIG_IBMLS is not set +# CONFIG_TMS380TR is not set +# CONFIG_SMCTR is not set # CONFIG_NET_FC is not set # CONFIG_RCPCI is not set # CONFIG_SHAPER is not set @@ -324,25 +374,77 @@ CONFIG_NCR885E=y # # Console drivers # +CONFIG_VGA_CONSOLE=y # # Frame-buffer support # -# CONFIG_FB is not set +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G450 is not set +# CONFIG_FB_MATROX_MULTIHEAD is not set +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +CONFIG_FB_3DFX=y +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC is not set # # Input core support # -# CONFIG_INPUT is not set +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y # # Macintosh device drivers # +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set # # Character devices # -# CONFIG_VT is not set +CONFIG_VT=y +CONFIG_VT_CONSOLE=y CONFIG_SERIAL=y CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set @@ -358,17 +460,19 @@ CONFIG_UNIX98_PTY_COUNT=256 # # Mice # -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set # # Joysticks # # CONFIG_JOYSTICK is not set - -# -# Input core support is needed for joysticks -# # CONFIG_QIC02_TAPE is not set # @@ -376,8 +480,8 @@ CONFIG_UNIX98_PTY_COUNT=256 # # CONFIG_WATCHDOG is not set # CONFIG_INTEL_RNG is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set +CONFIG_NVRAM=y +CONFIG_RTC=y # CONFIG_DTLK is not set # CONFIG_R3964 is not set # CONFIG_APPLICOM is not set @@ -405,10 +509,10 @@ CONFIG_UNIX98_PTY_COUNT=256 # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set @@ -420,7 +524,7 @@ CONFIG_ISO9660_FS=y # CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set +CONFIG_DEVFS_FS=y # CONFIG_DEVFS_MOUNT is not set # CONFIG_DEVFS_DEBUG is not set CONFIG_DEVPTS_FS=y @@ -439,13 +543,13 @@ CONFIG_EXT2_FS=y # Network File Systems # # CONFIG_CODA_FS is not set -CONFIG_NFS_FS=y +# CONFIG_NFS_FS is not set # CONFIG_NFS_V3 is not set # CONFIG_ROOT_NFS is not set # CONFIG_NFSD is not set # CONFIG_NFSD_V3 is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y +# CONFIG_SUNRPC is not set +# CONFIG_LOCKD is not set # CONFIG_SMB_FS is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set @@ -454,17 +558,65 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set # # Partition Types # -# CONFIG_PARTITION_ADVANCED is not set +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=y CONFIG_MSDOS_PARTITION=y -# CONFIG_NLS is not set +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 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_8 is not set +# CONFIG_NLS_ISO8859_9 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_UTF8 is not set # # Sound @@ -479,6 +631,6 @@ CONFIG_MSDOS_PARTITION=y # # Kernel hacking # -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y # CONFIG_KGDB is not set -# CONFIG_XMON is not set +CONFIG_XMON=y diff --git a/arch/ppc/configs/mbx_defconfig b/arch/ppc/configs/mbx_defconfig index 6230f5877d07..81829327a3ad 100644 --- a/arch/ppc/configs/mbx_defconfig +++ b/arch/ppc/configs/mbx_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -32,6 +31,7 @@ CONFIG_SERIAL_CONSOLE=y # CONFIG_TQM860 is not set CONFIG_MBX=y # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -176,7 +178,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -184,7 +185,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -370,8 +370,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -388,6 +386,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig index f33966d35db9..d8f39c36e220 100644 --- a/arch/ppc/configs/oak_defconfig +++ b/arch/ppc/configs/oak_defconfig @@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y # Loadable module support # CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y CONFIG_KMOD=y # @@ -23,10 +23,10 @@ CONFIG_PPC=y CONFIG_4xx=y # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set CONFIG_OAK=y # CONFIG_WALNUT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # CONFIG_MATH_EMULATION is not set @@ -37,7 +37,9 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -171,7 +173,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set CONFIG_OAKNET=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -179,7 +180,6 @@ CONFIG_OAKNET=y # 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 @@ -366,8 +366,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -376,6 +374,7 @@ CONFIG_LOCKD=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/power3_defconfig b/arch/ppc/configs/power3_defconfig new file mode 100644 index 000000000000..0deb9b5e8862 --- /dev/null +++ b/arch/ppc/configs/power3_defconfig @@ -0,0 +1,662 @@ +# +# Automatically generated by make menuconfig: don't edit +# +# CONFIG_UID16 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +CONFIG_POWER3=y +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +CONFIG_PPC64BRIDGE=y +CONFIG_ALL_PPC=y +CONFIG_SMP=y + +# +# General setup +# +CONFIG_HIGHMEM=y +# CONFIG_MOL is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +CONFIG_PARPORT=m +CONFIG_PARPORT_PC=m +CONFIG_PARPORT_PC_FIFO=y +# CONFIG_PARPORT_PC_SUPERIO is not set +# CONFIG_PARPORT_AMIGA is not set +# CONFIG_PARPORT_MFC3 is not set +# CONFIG_PARPORT_ATARI is not set +# CONFIG_PARPORT_SUNBPP is not set +# CONFIG_PARPORT_OTHER is not set +# CONFIG_PARPORT_1284 is not set +# CONFIG_PPC_RTC is not set +CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y +# CONFIG_BOOTX_TEXT is not set +# CONFIG_PREP_RESIDUAL is not set +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_NBD is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=4096 +CONFIG_BLK_DEV_INITRD=y + +# +# Multi-device support (RAID and LVM) +# +CONFIG_MD=y +CONFIG_BLK_DEV_MD=y +CONFIG_MD_LINEAR=y +CONFIG_MD_RAID0=y +CONFIG_MD_RAID1=y +CONFIG_MD_RAID5=y +# CONFIG_MD_BOOT is not set +# CONFIG_AUTODETECT_RAID is not set +CONFIG_BLK_DEV_LVM=y +CONFIG_LVM_PROC_FS=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +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_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# CONFIG_IPV6 is not set +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_DECNET is not set +# CONFIG_BRIDGE is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +# CONFIG_NET_SCHED is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +CONFIG_SCSI=y +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +CONFIG_BLK_DEV_SR_VENDOR=y +CONFIG_SR_EXTRA_DEVS=2 +CONFIG_CHR_DEV_SG=y +# CONFIG_SCSI_DEBUG_QUEUES is not set +# CONFIG_SCSI_MULTI_LUN is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y + +# +# SCSI low-level drivers +# +# CONFIG_BLK_DEV_3W_XXXX_RAID is not set +# CONFIG_SCSI_7000FASST is not set +# CONFIG_SCSI_ACARD is not set +# CONFIG_SCSI_AHA152X is not set +# CONFIG_SCSI_AHA1542 is not set +# CONFIG_SCSI_AHA1740 is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_ADVANSYS is not set +# CONFIG_SCSI_IN2000 is not set +# CONFIG_SCSI_AM53C974 is not set +# CONFIG_SCSI_MEGARAID is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_CPQFCTS is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_DTC3280 is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_EATA_DMA 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_GENERIC_NCR5380 is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_PPA is not set +# CONFIG_SCSI_IMM is not set +# CONFIG_SCSI_NCR53C406A is not set +# CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set +CONFIG_SCSI_SYM53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set +# CONFIG_SCSI_PAS16 is not set +# CONFIG_SCSI_PCI2000 is not set +# CONFIG_SCSI_PCI2220I is not set +# CONFIG_SCSI_PSI240I is not set +# CONFIG_SCSI_QLOGIC_FAS is not set +# CONFIG_SCSI_QLOGIC_ISP is not set +# CONFIG_SCSI_QLOGIC_FC is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_SIM710 is not set +# CONFIG_SCSI_SYM53C416 is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_T128 is not set +# CONFIG_SCSI_U14_34F is not set +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_OAKNET is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC 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=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set +# CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Token Ring devices +# +CONFIG_TR=y +# CONFIG_IBMTR is not set +CONFIG_IBMOL=y +# CONFIG_IBMLS is not set +# CONFIG_TMS380TR is not set +# CONFIG_SMCTR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +# CONFIG_SHAPER is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +CONFIG_FB=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_RIVA is not set +# CONFIG_FB_CLGEN is not set +# CONFIG_FB_PM2 is not set +# CONFIG_FB_CYBER2000 is not set +CONFIG_FB_OF=y +# CONFIG_FB_CONTROL is not set +# CONFIG_FB_PLATINUM is not set +# CONFIG_FB_VALKYRIE is not set +# CONFIG_FB_CT65550 is not set +# CONFIG_FB_IMSTT is not set +# CONFIG_FB_S3TRIO is not set +# CONFIG_FB_VGA16 is not set +CONFIG_FB_MATROX=y +CONFIG_FB_MATROX_MILLENIUM=y +CONFIG_FB_MATROX_MYSTIQUE=y +CONFIG_FB_MATROX_G100=y +CONFIG_FB_MATROX_I2C=y +# CONFIG_FB_MATROX_MAVEN is not set +# CONFIG_FB_MATROX_G450 is not set +CONFIG_FB_MATROX_MULTIHEAD=y +# CONFIG_FB_ATY is not set +# CONFIG_FB_ATY128 is not set +# CONFIG_FB_3DFX is not set +# CONFIG_FB_SIS is not set +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB16=y +CONFIG_FBCON_CFB24=y +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +CONFIG_FBCON_FONTS=y +# CONFIG_FONT_8x8 is not set +CONFIG_FONT_8x16=y +CONFIG_FONT_SUN8x16=y +CONFIG_FONT_SUN12x22=y +# CONFIG_FONT_6x11 is not set +# CONFIG_FONT_PEARL_8x8 is not set +# CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC is not set + +# +# Input core support +# +CONFIG_INPUT=y +CONFIG_INPUT_KEYBDEV=y +CONFIG_INPUT_MOUSEDEV=y +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 +# CONFIG_INPUT_JOYDEV is not set +CONFIG_INPUT_EVDEV=y + +# +# Macintosh device drivers +# +# CONFIG_ADB_CUDA is not set +# CONFIG_ADB_PMU is not set +# CONFIG_MAC_FLOPPY is not set +# CONFIG_MAC_SERIAL is not set +# CONFIG_ADB is not set + +# +# Character devices +# +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=2048 +CONFIG_PRINTER=m +# CONFIG_LP_CONSOLE is not set +# CONFIG_PPDEV is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_ALGOBIT=y +# CONFIG_I2C_PHILIPSPAR is not set +# CONFIG_I2C_ELV is not set +# CONFIG_I2C_VELLEMAN is not set +CONFIG_I2C_ALGOPCF=y +# CONFIG_I2C_ELEKTOR is not set +CONFIG_I2C_CHARDEV=y + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +CONFIG_NVRAM=y +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +# CONFIG_UMSDOS_FS is not set +CONFIG_VFAT_FS=y +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_RAMFS is not set +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +CONFIG_EXT2_FS=y +# CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_ROOT_NFS is not set +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_DEFAULT="iso8859-1" +CONFIG_NLS_CODEPAGE_437=y +# 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_874 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +CONFIG_NLS_ISO8859_1=y +# 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_8 is not set +# CONFIG_NLS_ISO8859_9 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_UTF8 is not set + +# +# Sound +# +CONFIG_SOUND=y +# CONFIG_DMASOUND_AWACS is not set +# CONFIG_SOUND_CMPCI is not set +# CONFIG_SOUND_EMU10K1 is not set +# CONFIG_SOUND_FUSION is not set +# CONFIG_SOUND_CS4281 is not set +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_ESSSOLO1 is not set +# CONFIG_SOUND_MAESTRO is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_TRIDENT is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +# CONFIG_SOUND_VIA82CXXX is not set +CONFIG_SOUND_OSS=y +CONFIG_SOUND_TRACEINIT=y +# CONFIG_SOUND_DMAP is not set +# CONFIG_SOUND_AD1816 is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_ACI_MIXER is not set +CONFIG_SOUND_CS4232=m +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_ICH is not set +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_TRIX is not set +CONFIG_SOUND_MSS=m +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_NM256 is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_PAS is not set +# CONFIG_PAS_JOYSTICK is not set +# CONFIG_SOUND_PSS is not set +# CONFIG_SOUND_SB is not set +# CONFIG_SOUND_AWE32_SYNTH is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_YM3812 is not set +# CONFIG_SOUND_OPL3SA1 is not set +# CONFIG_SOUND_OPL3SA2 is not set +# CONFIG_SOUND_YMPCI is not set +# CONFIG_SOUND_YMFPCI is not set +# CONFIG_SOUND_UART6850 is not set +# CONFIG_SOUND_AEDSP16 is not set +CONFIG_SOUND_TVMIXER=y + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +CONFIG_MAGIC_SYSRQ=y +# CONFIG_KGDB is not set +CONFIG_XMON=y diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig index 78ee82230527..258d3e79ffe0 100644 --- a/arch/ppc/configs/rpxcllf_defconfig +++ b/arch/ppc/configs/rpxcllf_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y # CONFIG_RPXLITE is not set @@ -32,6 +31,7 @@ CONFIG_RPXCLASSIC=y # CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -377,8 +377,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/rpxlite_defconfig b/arch/ppc/configs/rpxlite_defconfig index 741d9265ff0c..df00f5acee75 100644 --- a/arch/ppc/configs/rpxlite_defconfig +++ b/arch/ppc/configs/rpxlite_defconfig @@ -21,7 +21,6 @@ CONFIG_PPC=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set CONFIG_8xx=y CONFIG_SERIAL_CONSOLE=y CONFIG_RPXLITE=y @@ -32,6 +31,7 @@ CONFIG_RPXLITE=y # CONFIG_TQM860 is not set # CONFIG_MBX is not set # CONFIG_WINCEPT is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_ALL_PPC is not set # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y @@ -43,7 +43,9 @@ CONFIG_MATH_EMULATION=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI_QSPAN is not set # CONFIG_PCI is not set CONFIG_NET=y @@ -182,7 +184,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -190,7 +191,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -377,8 +377,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -395,6 +393,7 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig index c3e95c6acf61..eef439fc24e1 100644 --- a/arch/ppc/configs/walnut_defconfig +++ b/arch/ppc/configs/walnut_defconfig @@ -12,7 +12,7 @@ CONFIG_EXPERIMENTAL=y # Loadable module support # CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set +CONFIG_MODVERSIONS=y CONFIG_KMOD=y # @@ -23,10 +23,10 @@ CONFIG_PPC=y CONFIG_4xx=y # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set # CONFIG_OAK is not set CONFIG_WALNUT=y +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_MACH_SPECIFIC=y # CONFIG_MATH_EMULATION is not set @@ -37,7 +37,9 @@ CONFIG_MACH_SPECIFIC=y # CONFIG_HIGHMEM is not set # CONFIG_MOL is not set # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set # CONFIG_PCI is not set CONFIG_NET=y CONFIG_SYSCTL=y @@ -171,7 +173,6 @@ CONFIG_NET_ETHERNET=y # CONFIG_MACE is not set # CONFIG_BMAC is not set # CONFIG_GMAC is not set -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -179,7 +180,6 @@ CONFIG_NET_ETHERNET=y # 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 @@ -369,8 +369,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -379,6 +377,7 @@ CONFIG_LOCKD=y # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set # CONFIG_NLS is not set # diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig index 5574ecbdb70b..210887de706c 100644 --- a/arch/ppc/defconfig +++ b/arch/ppc/defconfig @@ -23,12 +23,11 @@ CONFIG_6xx=y # CONFIG_4xx is not set # CONFIG_POWER3 is not set # CONFIG_POWER4 is not set -# CONFIG_8260 is not set # CONFIG_8xx is not set +# CONFIG_8260 is not set CONFIG_ALL_PPC=y -# CONFIG_GEMINI is not set -# CONFIG_EST8260 is not set # CONFIG_APUS is not set +CONFIG_PPC601_SYNC_FIX=y # CONFIG_SMP is not set CONFIG_ALTIVEC=y @@ -36,9 +35,11 @@ CONFIG_ALTIVEC=y # General setup # # CONFIG_HIGHMEM is not set -# CONFIG_MOL is not set +CONFIG_MOL=y # CONFIG_ISA is not set +# CONFIG_EISA is not set # CONFIG_SBUS is not set +# CONFIG_MCA is not set CONFIG_PCI=y CONFIG_NET=y CONFIG_SYSCTL=y @@ -49,21 +50,24 @@ CONFIG_BINFMT_ELF=y CONFIG_KERNEL_ELF=y CONFIG_BINFMT_MISC=m CONFIG_PCI_NAMES=y -# CONFIG_HOTPLUG is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# # CONFIG_PCMCIA is not set # # Parallel port support # # CONFIG_PARPORT is not set -CONFIG_VGA_CONSOLE=y -CONFIG_FB=y -CONFIG_FB_COMPAT_XPMAC=y CONFIG_PPC_RTC=y CONFIG_PROC_DEVICETREE=y +CONFIG_PPC_RTAS=y CONFIG_BOOTX_TEXT=y -# CONFIG_MOTOROLA_HOTSWAP is not set -# CONFIG_CMDLINE_BOOL is not set +CONFIG_PREP_RESIDUAL=y +CONFIG_CMDLINE_BOOL=y +CONFIG_CMDLINE="console=ttyS0,9600 console=tty0 root=/dev/sda2" # # Memory Technology Devices (MTD) @@ -79,7 +83,7 @@ CONFIG_BOOTX_TEXT=y # # Block devices # -# CONFIG_BLK_DEV_FD is not set +CONFIG_BLK_DEV_FD=m # CONFIG_BLK_DEV_XD is not set # CONFIG_PARIDE is not set # CONFIG_BLK_CPQ_DA is not set @@ -111,7 +115,8 @@ CONFIG_PACKET=y CONFIG_NETLINK=y # CONFIG_RTNETLINK is not set # CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y @@ -123,6 +128,34 @@ CONFIG_IP_MULTICAST=y # CONFIG_IP_MROUTE is not set # CONFIG_INET_ECN is not set CONFIG_SYN_COOKIES=y + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM is not set # CONFIG_IPV6 is not set # CONFIG_KHTTPD is not set # CONFIG_ATM is not set @@ -239,6 +272,7 @@ CONFIG_SCSI=y CONFIG_BLK_DEV_SD=y CONFIG_SD_EXTRA_DEVS=40 CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set CONFIG_BLK_DEV_SR=y CONFIG_BLK_DEV_SR_VENDOR=y CONFIG_SR_EXTRA_DEVS=2 @@ -344,7 +378,6 @@ CONFIG_NET_ETHERNET=y CONFIG_MACE=y CONFIG_BMAC=y CONFIG_GMAC=y -# CONFIG_NCR885E is not set # CONFIG_OAKNET is not set # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set @@ -357,27 +390,28 @@ CONFIG_GMAC=y CONFIG_NET_PCI=y CONFIG_PCNET32=y # CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_TULIP is not set +CONFIG_TULIP=y +CONFIG_DE4X5=m # CONFIG_DGRS is not set # CONFIG_DM9102 is not set # CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set # CONFIG_LNE390 is not set # CONFIG_NATSEMI is not set # CONFIG_NE2K_PCI is not set # CONFIG_NE3210 is not set # CONFIG_ES3210 is not set -# CONFIG_RTL8129 is not set # CONFIG_8139TOO is not set +# CONFIG_RTL8129 is not set # CONFIG_SIS900 is not set # CONFIG_EPIC100 is not set # CONFIG_SUNDANCE is not set # CONFIG_TLAN is not set # CONFIG_VIA_RHINE is not set # CONFIG_WINBOND_840 is not set +# CONFIG_HAPPYMEAL is not set # CONFIG_NET_POCKET is not set # @@ -439,6 +473,7 @@ CONFIG_PPP_DEFLATE=y # # Console drivers # +CONFIG_VGA_CONSOLE=y # # Frame-buffer support @@ -460,7 +495,8 @@ CONFIG_FB_IMSTT=y CONFIG_FB_MATROX=y CONFIG_FB_MATROX_MILLENIUM=y CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G100=y +# CONFIG_FB_MATROX_G100 is not set +# CONFIG_FB_MATROX_G450 is not set # CONFIG_FB_MATROX_MULTIHEAD is not set CONFIG_FB_ATY=y CONFIG_FB_ATY128=y @@ -481,6 +517,7 @@ CONFIG_FONT_SUN12x22=y # CONFIG_FONT_6x11 is not set # CONFIG_FONT_PEARL_8x8 is not set # CONFIG_FONT_ACORN_8x8 is not set +# CONFIG_FB_COMPAT_XPMAC is not set # # Input core support @@ -498,15 +535,13 @@ CONFIG_INPUT_EVDEV=y # CONFIG_ADB_CUDA=y CONFIG_ADB_PMU=y -CONFIG_PMAC_PBOOK=y -CONFIG_PMAC_BACKLIGHT=y -CONFIG_MAC_FLOPPY=y -CONFIG_MAC_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +# CONFIG_PMAC_PBOOK is not set +# CONFIG_PMAC_BACKLIGHT is not set +# CONFIG_MAC_FLOPPY is not set +CONFIG_MAC_SERIAL=m CONFIG_ADB=y CONFIG_ADB_MACIO=y CONFIG_INPUT_ADBHID=y -CONFIG_MAC_HID=y CONFIG_MAC_ADBKEYCODES=y CONFIG_MAC_EMUMOUSEBTN=y @@ -575,17 +610,17 @@ CONFIG_NVRAM=y # File systems # # CONFIG_QUOTA is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set # CONFIG_ADFS_FS is not set # CONFIG_ADFS_FS_RW is not set # CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set +CONFIG_HFS_FS=m # CONFIG_BFS_FS is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y +CONFIG_FAT_FS=m +CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y +CONFIG_VFAT_FS=m # CONFIG_EFS_FS is not set # CONFIG_JFFS_FS is not set # CONFIG_CRAMFS is not set @@ -631,8 +666,6 @@ CONFIG_LOCKD=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -652,6 +685,7 @@ CONFIG_MSDOS_PARTITION=y # CONFIG_SGI_PARTITION is not set # CONFIG_ULTRIX_PARTITION is not set # CONFIG_SUN_PARTITION is not set +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # @@ -678,7 +712,7 @@ CONFIG_NLS_DEFAULT="iso8859-1" # CONFIG_NLS_CODEPAGE_936 is not set # CONFIG_NLS_CODEPAGE_949 is not set # CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_ISO8859_1 is not set +CONFIG_NLS_ISO8859_1=m # CONFIG_NLS_ISO8859_2 is not set # CONFIG_NLS_ISO8859_3 is not set # CONFIG_NLS_ISO8859_4 is not set @@ -695,9 +729,9 @@ CONFIG_NLS_DEFAULT="iso8859-1" # # Sound # -CONFIG_SOUND=y -CONFIG_DMASOUND_AWACS=y -CONFIG_DMASOUND=y +CONFIG_SOUND=m +CONFIG_DMASOUND_AWACS=m +CONFIG_DMASOUND=m # CONFIG_SOUND_CMPCI is not set # CONFIG_SOUND_EMU10K1 is not set # CONFIG_SOUND_FUSION is not set @@ -711,43 +745,14 @@ CONFIG_DMASOUND=y # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set # CONFIG_SOUND_VIA82CXXX is not set -CONFIG_SOUND_OSS=y -# CONFIG_SOUND_TRACEINIT is not set -# CONFIG_SOUND_DMAP is not set -# CONFIG_SOUND_AD1816 is not set -# CONFIG_SOUND_SGALAXY is not set -# CONFIG_SOUND_ADLIB is not set -# CONFIG_SOUND_ACI_MIXER is not set -CONFIG_SOUND_CS4232=m -# CONFIG_SOUND_SSCAPE is not set -# CONFIG_SOUND_GUS is not set -# CONFIG_SOUND_ICH is not set -# CONFIG_SOUND_VMIDI is not set -# CONFIG_SOUND_TRIX is not set -# CONFIG_SOUND_MSS is not set -# CONFIG_SOUND_MPU401 is not set -# CONFIG_SOUND_NM256 is not set -# CONFIG_SOUND_MAD16 is not set -# CONFIG_SOUND_PAS is not set -# CONFIG_PAS_JOYSTICK is not set -# CONFIG_SOUND_PSS is not set -# CONFIG_SOUND_SB is not set -# CONFIG_SOUND_AWE32_SYNTH is not set -# CONFIG_SOUND_WAVEFRONT is not set -# CONFIG_SOUND_MAUI is not set -# CONFIG_SOUND_YM3812 is not set -# CONFIG_SOUND_OPL3SA1 is not set -# CONFIG_SOUND_OPL3SA2 is not set -# CONFIG_SOUND_YMPCI is not set -# CONFIG_SOUND_UART6850 is not set -# CONFIG_SOUND_AEDSP16 is not set +# CONFIG_SOUND_OSS is not set # CONFIG_SOUND_TVMIXER is not set # # USB support # CONFIG_USB=y -CONFIG_USB_DEBUG=y +# CONFIG_USB_DEBUG is not set # # Miscellaneous USB options @@ -763,33 +768,69 @@ CONFIG_USB_DEVICEFS=y CONFIG_USB_OHCI=y # -# USB Devices +# USB Device Class drivers # +# CONFIG_USB_AUDIO is not set +# CONFIG_USB_BLUETOOTH is not set +# CONFIG_USB_STORAGE is not set +CONFIG_USB_ACM=m # CONFIG_USB_PRINTER is not set + +# +# USB Human Interface Devices (HID) +# +CONFIG_USB_HID=y +# CONFIG_USB_WACOM is not set + +# +# USB Imaging devices +# +# CONFIG_USB_DC2XX is not set +# CONFIG_USB_MDC800 is not set # CONFIG_USB_SCANNER is not set # CONFIG_USB_MICROTEK is not set -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_SERIAL is not set + +# +# USB Multimedia devices +# # CONFIG_USB_IBMCAM is not set # CONFIG_USB_OV511 is not set -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_USS720 is not set +# CONFIG_USB_DSBR is not set # CONFIG_USB_DABUSB is not set + +# +# USB Network adaptors +# # CONFIG_USB_PLUSB is not set # CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_DSBR is not set -# CONFIG_USB_BLUETOOTH is not set # CONFIG_USB_NET1080 is not set # -# USB Human Interface Devices (HID) +# USB port drivers # -CONFIG_USB_HID=y -# CONFIG_USB_WACOM is not set +# CONFIG_USB_USS720 is not set + +# +# USB Serial Converter support +# +CONFIG_USB_SERIAL=m +# CONFIG_USB_SERIAL_DEBUG is not set +# CONFIG_USB_SERIAL_GENERIC is not set +# CONFIG_USB_SERIAL_BELKIN is not set +# CONFIG_USB_SERIAL_WHITEHEAT is not set +# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set +# CONFIG_USB_SERIAL_EMPEG is not set +# CONFIG_USB_SERIAL_FTDI_SIO is not set +CONFIG_USB_SERIAL_VISOR=m +# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set +# CONFIG_USB_SERIAL_KEYSPAN is not set +# CONFIG_USB_SERIAL_MCT_U232 is not set +# CONFIG_USB_SERIAL_OMNINET is not set + +# +# USB misc drivers +# +# CONFIG_USB_RIO500 is not set # # Kernel hacking diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 4a9852612549..545fce0cddd0 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_PPC) := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o bitops.o ptrace.o \ ppc_htab.o semaphore.o syscalls.o \ align.o setup.o +obj-$(CONFIG_MODULES) += ppc_ksyms.o obj-$(CONFIG_POWER4) += xics.o obj-$(CONFIG_PCI) += pci.o pci-dma.o obj-$(CONFIG_KGDB) += ppc-stub.o @@ -62,11 +63,8 @@ obj-$(CONFIG_ALL_PPC) += pmac_pic.o pmac_setup.o pmac_time.o prom.o \ feature.o pmac_pci.o chrp_setup.o \ chrp_time.o chrp_pci.o open_pic.o \ indirect_pci.o i8259.o prep_pci.o \ - prep_time.o prep_nvram.o ppc_ksyms.o \ - prep_setup.o + prep_time.o prep_nvram.o prep_setup.o obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o -obj-$(CONFIG_GEMINI) += gemini_prom.o gemini_pci.o gemini_setup.o \ - open_pic.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c index 5979c9312913..70a683d20087 100644 --- a/arch/ppc/kernel/apus_setup.c +++ b/arch/ppc/kernel/apus_setup.c @@ -647,25 +647,6 @@ apus_ide_default_io_base(int index) return 0; } -int -apus_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return 0; -} - -void -apus_ide_request_region(ide_ioreg_t from, - unsigned int extent, - const char *name) -{ -} - -void -apus_ide_release_region(ide_ioreg_t from, - unsigned int extent) -{ -} - void apus_ide_fix_driveid(struct hd_driveid *id) { @@ -1131,9 +1112,6 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.outsw = apus_ide_outsw; ppc_ide_md.default_irq = apus_ide_default_irq; ppc_ide_md.default_io_base = apus_ide_default_io_base; - ppc_ide_md.ide_check_region = apus_ide_check_region; - ppc_ide_md.ide_request_region = apus_ide_request_region; - ppc_ide_md.ide_release_region = apus_ide_release_region; ppc_ide_md.fix_driveid = apus_ide_fix_driveid; ppc_ide_md.ide_init_hwif = apus_ide_init_hwif_ports; diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c index 43b678861ca2..914ed02ff1a3 100644 --- a/arch/ppc/kernel/chrp_pci.c +++ b/arch/ppc/kernel/chrp_pci.c @@ -8,8 +8,8 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/openpic.h> #include <linux/ide.h> +#include <linux/bootmem.h> #include <asm/io.h> #include <asm/pgtable.h> @@ -19,16 +19,19 @@ #include <asm/gg2.h> #include <asm/machdep.h> #include <asm/init.h> +#include <asm/pci-bridge.h> +#include "open_pic.h" #include "pci.h" + #ifdef CONFIG_POWER4 -static unsigned long pci_address_offset(int, unsigned int); +extern unsigned long pci_address_offset(int, unsigned int); #endif /* CONFIG_POWER4 */ /* LongTrail */ -#define pci_config_addr(bus, dev, offset) \ -(GG2_PCI_CONFIG_BASE | ((bus)<<16) | ((dev)<<8) | (offset)) +#define pci_config_addr(dev, offset) \ +(GG2_PCI_CONFIG_BASE | ((dev->bus->number)<<16) | ((dev->devfn)<<8) | (offset)) volatile struct Hydra *Hydra = NULL; @@ -37,205 +40,127 @@ volatile struct Hydra *Hydra = NULL; * limit the bus number to 3 bits */ -int __chrp gg2_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - if (bus > 7) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_8((unsigned char *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define GG2_PCI_OP(rw, size, type, op) \ +int __chrp gg2_##rw##_config_##size(struct pci_dev *dev, int off, type val) \ +{ \ + if (dev->bus->number > 7) { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, pci_config_addr(dev, off), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -int __chrp gg2_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - if (bus > 7) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp gg2_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if (bus > 7) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - *val = in_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_8((unsigned char *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp gg2_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le16((unsigned short *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} +GG2_PCI_OP(read, byte, u8 *, in_8) +GG2_PCI_OP(read, word, u16 *, in_le16) +GG2_PCI_OP(read, dword, u32 *, in_le32) +GG2_PCI_OP(write, byte, u8, out_8) +GG2_PCI_OP(write, word, u16, out_le16) +GG2_PCI_OP(write, dword, u32, out_le32) -int __chrp gg2_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops gg2_pci_ops = { - if (bus > 7) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32((unsigned int *)pci_config_addr(bus, dev_fn, offset), val); - return PCIBIOS_SUCCESSFUL; -} + gg2_read_config_byte, + gg2_read_config_word, + gg2_read_config_dword, + gg2_write_config_byte, + gg2_write_config_word, + gg2_write_config_dword +}; -#define python_config_address(bus) (unsigned *)((0xfef00000+0xf8000)-(bus*0x100000)) -#define python_config_data(bus) ((0xfef00000+0xf8010)-(bus*0x100000)) -#define PYTHON_CFA(b, d, o) (0x80 | ((b<<6) << 8) | ((d) << 16) \ +/* + * Access functions for PCI config space on IBM "python" host bridges. + */ +#define PYTHON_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ | (((o) & ~3) << 24)) -unsigned int python_busnr = 0; - -int __chrp python_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - if (bus > python_busnr) { - *val = 0xff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_8((unsigned char *)python_config_data(bus) + (offset&3)); - return PCIBIOS_SUCCESSFUL; -} -int __chrp python_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - if (bus > python_busnr) { - *val = 0xffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_le16((unsigned short *)(python_config_data(bus) + (offset&3))); - return PCIBIOS_SUCCESSFUL; +#define PYTHON_PCI_OP(rw, size, type, op, mask) \ +int __chrp \ +python_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + \ + out_be32(hose->cfg_addr, \ + PYTHON_CFA(dev->bus->number, dev->devfn, offset)); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } +PYTHON_PCI_OP(read, byte, u8 *, in_8, 3) +PYTHON_PCI_OP(read, word, u16 *, in_le16, 2) +PYTHON_PCI_OP(read, dword, u32 *, in_le32, 0) +PYTHON_PCI_OP(write, byte, u8, out_8, 3) +PYTHON_PCI_OP(write, word, u16, out_le16, 2) +PYTHON_PCI_OP(write, dword, u32, out_le32, 0) -int __chrp python_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if (bus > python_busnr) { - *val = 0xffffffff; - return PCIBIOS_DEVICE_NOT_FOUND; - } - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - *val = in_le32((unsigned *)python_config_data(bus)); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static struct pci_ops python_pci_ops = { - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_8((volatile unsigned char *)python_config_data(bus) + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_le16((volatile unsigned short *)python_config_data(bus) + (offset&3), - val); - return PCIBIOS_SUCCESSFUL; -} - -int __chrp python_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - if (bus > python_busnr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32( python_config_address( bus ), PYTHON_CFA(bus,dev_fn,offset)); - out_le32((unsigned *)python_config_data(bus) + (offset&3), val); - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp rtas_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas( "read-pci-config", 2, 2, &ret, addr, 1) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - -int __chrp rtas_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; - - if (call_rtas("read-pci-config", 2, 2, &ret, addr, 2) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; -} - - -int __chrp rtas_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - unsigned long ret; + python_read_config_byte, + python_read_config_word, + python_read_config_dword, + python_write_config_byte, + python_write_config_word, + python_write_config_dword +}; - if (call_rtas("read-pci-config", 2, 2, &ret, addr, 4) != 0) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = ret; - return PCIBIOS_SUCCESSFUL; +#ifdef CONFIG_POWER4 +/* + * Access functions for PCI config space using RTAS calls. + */ +#define RTAS_PCI_READ_OP(size, type, nbytes) \ +int __chrp \ +rtas_read_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \ + | ((dev->bus->number & 0xff) << 16); \ + unsigned long ret = ~0UL; \ + int rval; \ + \ + rval = call_rtas("read-pci-config", 2, 2, &ret, addr, nbytes); \ + *val = ret; \ + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \ } -int __chrp rtas_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 1, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; +#define RTAS_PCI_WRITE_OP(size, type, nbytes) \ +int __chrp \ +rtas_write_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + unsigned long addr = (offset & 0xff) | ((dev->devfn & 0xff) << 8) \ + | ((dev->bus->number & 0xff) << 16); \ + int rval; \ + \ + rval = call_rtas("write-pci-config", 3, 1, NULL, \ + addr, nbytes, (ulong)val); \ + return rval? PCIBIOS_DEVICE_NOT_FOUND: PCIBIOS_SUCCESSFUL; \ } -int __chrp rtas_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 2, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} +RTAS_PCI_READ_OP(byte, u8 *, 1) +RTAS_PCI_READ_OP(word, u16 *, 2) +RTAS_PCI_READ_OP(dword, u32 *, 4) +RTAS_PCI_WRITE_OP(byte, u8, 1) +RTAS_PCI_WRITE_OP(word, u16, 2) +RTAS_PCI_WRITE_OP(dword, u32, 4) -int __chrp rtas_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops rtas_pci_ops = { - unsigned long addr = (offset&0xff) | ((dev_fn&0xff)<<8) | ((bus & 0xff)<<16); - if ( call_rtas( "write-pci-config", 3, 1, NULL, addr, 4, (ulong)val ) != 0 ) - return PCIBIOS_DEVICE_NOT_FOUND; - return PCIBIOS_SUCCESSFUL; -} + rtas_read_config_byte, + rtas_read_config_word, + rtas_read_config_dword, + rtas_write_config_byte, + rtas_write_config_word, + rtas_write_config_dword +}; +#endif /* CONFIG_POWER4 */ /* * Temporary fixes for PCI devices. These should be replaced by OF query @@ -278,7 +203,7 @@ hydra_init(void) HYDRA_FC_MPIC_ENABLE | HYDRA_FC_SLOW_SCC_PCLK | HYDRA_FC_MPIC_IS_MASTER)); - OpenPIC = (volatile struct OpenPIC *)&Hydra->OpenPIC; + OpenPIC_Addr = &Hydra->OpenPIC; OpenPIC_InitSenses = hydra_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(hydra_openpic_initsenses); return 1; @@ -316,54 +241,25 @@ void __init chrp_pcibios_fixup(void) { struct pci_dev *dev; - int *brp; struct device_node *np; - extern struct pci_ops generic_pci_ops; - -#ifndef CONFIG_POWER4 - np = find_devices("device-tree"); - if (np != 0) { - for (np = np->child; np != NULL; np = np->sibling) { - if (np->type == NULL || strcmp(np->type, "pci") != 0) - continue; - if ((brp = (int *) get_property(np, "bus-range", NULL)) == 0) - continue; - if (brp[0] != 0) /* bus 0 is already done */ - pci_scan_bus(brp[0], &generic_pci_ops, NULL); - } - } -#else - /* XXX kludge for now because we can't properly handle - physical addresses > 4GB. -- paulus */ - pci_scan_bus(0x1e, &generic_pci_ops, NULL); -#endif /* CONFIG_POWER4 */ /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { - np = find_pci_device_OFnode(dev->bus->number, dev->devfn); + np = pci_device_to_OF_node(dev); if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0)) dev->irq = np->intrs[0].line; - /* these need to be absolute addrs for OF and Matrox FB -- Cort */ - if ( dev->vendor == PCI_VENDOR_ID_MATROX ) - { - if ( dev->resource[0].start < isa_mem_base ) - dev->resource[0].start += isa_mem_base; - if ( dev->resource[1].start < isa_mem_base ) - dev->resource[1].start += isa_mem_base; - } + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + /* the F50 identifies the amd as a trident */ if ( (dev->vendor == PCI_VENDOR_ID_TRIDENT) && (dev->class>>8 == PCI_CLASS_NETWORK_ETHERNET) ) { dev->vendor = PCI_VENDOR_ID_AMD; - pcibios_write_config_word(dev->bus->number, - dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD); + pci_write_config_word(dev, PCI_VENDOR_ID, + PCI_VENDOR_ID_AMD); } #ifdef CONFIG_POWER4 power4_fixup_dev(dev); -#else - if (dev->bus->number > 0 && python_busnr > 0) - dev->resource[0].start += dev->bus->number*0x01000000; #endif } } @@ -402,86 +298,213 @@ static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus) bus->resource[1] = &gg2_resources.pci_mem; } -decl_config_access_method(grackle); -decl_config_access_method(indirect); -decl_config_access_method(rtas); +static void process_bridge_ranges(struct pci_controller *hose, + struct device_node *dev, int index) +{ + unsigned int *ranges; + int rlen = 0; + int memno = 0; + struct resource *res; + + hose->io_base_phys = 0; + ranges = (unsigned int *) get_property(dev, "ranges", &rlen); + while ((rlen -= 6 * sizeof(unsigned int)) >= 0) { + res = NULL; + switch (ranges[0] >> 24) { + case 1: /* I/O space */ + if (ranges[2] != 0) + break; + hose->io_base_phys = ranges[3]; + hose->io_base_virt = ioremap(ranges[3], ranges[5]); + if (index == 0) { + isa_io_base = (unsigned long) hose->io_base_virt; + printk("isa_io_base=%lx\n", isa_io_base); + } + res = &hose->io_resource; + res->flags = IORESOURCE_IO; + break; + case 2: /* memory space */ + if (index == 0 && ranges[1] == 0 && ranges[2] == 0){ + isa_mem_base = ranges[3]; + printk("isa_mem_base=%lx\n", isa_mem_base); + } + if (memno == 0) { + hose->pci_mem_offset = ranges[3] - ranges[2]; + printk("pci_mem_offset=%lx for this bridge\n", + hose->pci_mem_offset); + } + res = &hose->mem_resources[memno]; + res->flags = IORESOURCE_MEM; + ++memno; + break; + } + if (res != NULL) { + res->name = dev->full_name; + res->start = ranges[3]; + res->end = res->start + ranges[5] - 1; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; + } + ranges += 6; + } +} + +/* this is largely modeled and stolen after the pmac_pci code -- tgall + */ + +static void __init +ibm_add_bridges(struct device_node *dev) +{ + int *bus_range; + int len, index = 0; + struct pci_controller *hose; + volatile unsigned char *cfg; + unsigned int *dma; +#ifdef CONFIG_POWER3 + unsigned long *opprop = (unsigned long *) + get_property(find_path_device("/"), "platform-open-pic", NULL); +#endif + + for(; dev != NULL; dev = dev->next, ++index) { + if (dev->n_addrs < 1) { + printk(KERN_WARNING "Can't use %s: no address\n", + dev->full_name); + continue; + } + bus_range = (int *) get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + dev->full_name); + continue; + } + if (bus_range[1] == bus_range[0]) + printk(KERN_INFO "PCI bus %d", bus_range[0]); + else + printk(KERN_INFO "PCI buses %d..%d", + bus_range[0], bus_range[1]); + printk(" controlled by %s at %x\n", dev->type, + dev->addrs[0].address); + + hose = pcibios_alloc_controller(); + if (!hose) { + printk("Can't allocate PCI controller structure for %s\n", + dev->full_name); + continue; + } + hose->arch_data = dev; + hose->first_busno = bus_range[0]; + hose->last_busno = bus_range[1]; + hose->ops = &python_pci_ops; + + cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); + hose->cfg_addr = (volatile unsigned int *) cfg; + hose->cfg_data = cfg + 0x10; + + process_bridge_ranges(hose, dev, index); + +#ifdef CONFIG_POWER3 + openpic_setup_ISU(index, opprop[index+1]); +#endif /* CONFIG_POWER3 */ + + /* check the first bridge for a property that we can + use to set pci_dram_offset */ + dma = (unsigned int *) + get_property(dev, "ibm,dma-ranges", &len); + if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { + pci_dram_offset = dma[2] - dma[3]; + printk("pci_dram_offset = %lx\n", pci_dram_offset); + } + } +} + +#ifdef CONFIG_POWER4 +void __init +power4_add_bridge(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + + hose->ops = &rtas_pci_ops; + pci_dram_offset = 0; +} +#endif /* CONFIG_POWER4 */ void __init -chrp_setup_pci_ptrs(void) +chrp_find_bridges(void) { struct device_node *py; + char *model, *name; + struct pci_controller* hose; ppc_md.pcibios_fixup = chrp_pcibios_fixup; + #ifdef CONFIG_POWER4 - set_config_access_method(rtas); - pci_dram_offset = 0; + power4_add_bridge(); #else /* CONFIG_POWER4 */ - if ( !strncmp("MOT", - get_property(find_path_device("/"), "model", NULL),3) ) - { - pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - isa_io_base = 0xfe000000; - set_config_access_method(grackle); - } - else - { - if ((py = find_compatible_devices("pci", "IBM,python")) != 0 - || (py = find_compatible_devices("pci", "IBM,python3.0")) != 0) - { - char *name = get_property(find_path_device("/"), "name", NULL); - - /* find out how many pythons */ - while ( (py = py->next) ) python_busnr++; - set_config_access_method(python); - - /* - * We base these values on the machine type but should - * try to read them from the python controller itself. - * -- Cort - */ - if ( !strncmp("IBM,7025-F50", name, 12) ) - { - pci_dram_offset = 0x80000000; - isa_mem_base = 0xa0000000; - isa_io_base = 0x88000000; - } else if ( !strncmp("IBM,7043-260", name, 12) - || !strncmp("IBM,7044-270", name, 12)) - { - pci_dram_offset = 0x0; - isa_mem_base = 0xc0000000; - isa_io_base = 0xf8000000; - } - } - else - { - if ( !strncmp("IBM,7043-150", get_property(find_path_device("/"), "name", NULL),12) || - !strncmp("IBM,7046-155", get_property(find_path_device("/"), "name", NULL),12) || - !strncmp("IBM,7046-B50", get_property(find_path_device("/"), "name", NULL),12) ) - { - pci_dram_offset = 0; - isa_mem_base = 0x80000000; - isa_io_base = 0xfe000000; - pci_config_address = (unsigned int *)0xfec00000; - pci_config_data = (unsigned char *)0xfee00000; - set_config_access_method(indirect); - } - else - { - /* LongTrail */ - pci_dram_offset = 0; - isa_mem_base = 0xf7000000; - isa_io_base = 0xf8000000; - set_config_access_method(gg2); - ppc_md.pcibios_fixup = gg2_pcibios_fixup; - ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; - } - } + model = get_property(find_path_device("/"), "model", NULL); + if (!strncmp("MOT", model, 3)) { + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + /* Check that please. This must be the root of the OF + * PCI tree (the root host bridge + */ + hose->arch_data = find_devices("pci"); + setup_grackle(hose, 0x20000); + return; } + + if ((py = find_compatible_devices("pci", "IBM,python"))) + { + /* XXX xmon_init_scc needs this set and the BAT + set up in MMU_init */ + ibm_add_bridges(find_devices("pci")); + return; + } + + + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->first_busno = 0; + hose->last_busno = 0xff; + /* Check that please. This must be the root of the OF + * PCI tree (the root host bridge + */ + hose->arch_data = find_devices("pci"); + name = get_property(find_path_device("/"), "name", NULL); + if (!strncmp("IBM,7043-150", name, 12) || + !strncmp("IBM,7046-155", name, 12) || + !strncmp("IBM,7046-B50", name, 12) ) { + setup_grackle(hose, 0x01000000); + isa_mem_base = 0x80000000; + return; + } + + /* LongTrail */ + hose->ops = &gg2_pci_ops; + pci_dram_offset = 0; + isa_mem_base = 0xf7000000; + hose->io_base_phys = (unsigned long) 0xf8000000; + hose->io_base_virt = ioremap(hose->io_base_phys, 0x10000); + isa_io_base = (unsigned long) hose->io_base_virt; + ppc_md.pcibios_fixup = gg2_pcibios_fixup; + ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus; #endif /* CONFIG_POWER4 */ } #ifdef CONFIG_PPC64BRIDGE +#ifdef CONFIG_POWER4 /* * Hack alert!!! * 64-bit machines like POWER3 and POWER4 have > 32 bit @@ -490,9 +513,7 @@ chrp_setup_pci_ptrs(void) * page table gives us into parts of the physical address * space above 4GB so we can access the I/O devices. */ - -#ifdef CONFIG_POWER4 -static unsigned long pci_address_offset(int busnr, unsigned int flags) +unsigned long pci_address_offset(int busnr, unsigned int flags) { unsigned long offset = 0; @@ -508,34 +529,5 @@ static unsigned long pci_address_offset(int busnr, unsigned int flags) } return offset; } - -unsigned long phys_to_bus(unsigned long pa) -{ - if (pa >= 0xf8000000) - pa -= 0x38000000; - else if (pa >= 0x80000000 && pa < 0xc0000000) - pa += 0x40000000; - return pa; -} - -unsigned long bus_to_phys(unsigned int ba, int busnr) -{ - return ba + pci_address_offset(busnr, IORESOURCE_MEM); -} - -#else /* CONFIG_POWER4 */ -/* - * For now assume I/O addresses are < 4GB and PCI bridges don't - * remap addresses on POWER3 machines. - */ -unsigned long phys_to_bus(unsigned long pa) -{ - return pa; -} - -unsigned long bus_to_phys(unsigned int ba, int busnr) -{ - return ba; -} #endif /* CONFIG_POWER4 */ #endif /* CONFIG_PPC64BRIDGE */ diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c index ccc6621deeaa..5682f3fad879 100644 --- a/arch/ppc/kernel/chrp_setup.c +++ b/arch/ppc/kernel/chrp_setup.c @@ -30,7 +30,6 @@ #include <linux/ioport.h> #include <linux/console.h> #include <linux/pci.h> -#include <linux/openpic.h> #include <linux/version.h> #include <linux/adb.h> #include <linux/module.h> @@ -50,21 +49,19 @@ #include <asm/hydra.h> #include <asm/keyboard.h> #include <asm/init.h> - #include <asm/time.h> + #include "local_irq.h" #include "i8259.h" #include "open_pic.h" #include "xics.h" -extern volatile unsigned char *chrp_int_ack_special; - unsigned long chrp_get_rtc_time(void); int chrp_set_rtc_time(unsigned long nowtime); void chrp_calibrate_decr(void); long chrp_time_init(void); -void chrp_setup_pci_ptrs(void); +void chrp_find_bridges(void); void chrp_event_scan(void); void rtas_display_progress(char *, unsigned short); void rtas_indicator_progress(char *, unsigned short); @@ -92,7 +89,7 @@ kdev_t boot_dev; extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; extern int bootx_text_mapped; static int max_width; @@ -244,7 +241,7 @@ chrp_setup_arch(void) struct device_node *device; /* init to some ~sane value until calibrate_delay() runs */ - loops_per_sec = 50000000; + loops_per_jiffy = 50000000/HZ; #ifdef CONFIG_BLK_DEV_INITRD /* this is fine for chrp */ @@ -257,6 +254,9 @@ chrp_setup_arch(void) ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */ printk("Boot arguments: %s\n", cmd_line); + /* Lookup PCI host bridges */ + chrp_find_bridges(); + #ifndef CONFIG_PPC64BRIDGE /* PCI bridge config space access area - * appears to be not in devtree on longtrail. */ @@ -266,11 +266,12 @@ chrp_setup_arch(void) * -- Geert */ hydra_init(); /* Mac I/O */ + #endif /* CONFIG_PPC64BRIDGE */ #ifndef CONFIG_POWER4 /* Some IBM machines don't have the hydra -- Cort */ - if ( !OpenPIC ) + if ( !OpenPIC_Addr ) { unsigned long *opprop; @@ -279,7 +280,7 @@ chrp_setup_arch(void) if (opprop != 0) { printk("OpenPIC addrs: %lx %lx %lx\n", opprop[0], opprop[1], opprop[2]); - OpenPIC = ioremap(opprop[0], sizeof(struct OpenPIC)); + OpenPIC_Addr = ioremap(opprop[0], 0x40000); } } #endif @@ -292,23 +293,17 @@ chrp_setup_arch(void) conswitchp = &dummy_con; #endif -#ifndef CONFIG_PPC64BRIDGE - pmac_find_bridges(); -#endif /* CONFIG_PPC64BRIDGE */ - /* Get the event scan rate for the rtas so we know how * often it expects a heartbeat. -- Cort */ - if ( rtas_data ) - { + if ( rtas_data ) { struct property *p; device = find_devices("rtas"); for ( p = device->properties; p && strncmp(p->name, "rtas-event-scan-rate", 20); p = p->next ) /* nothing */ ; - if ( p && *(unsigned long *)p->value ) - { + if ( p && *(unsigned long *)p->value ) { ppc_md.heartbeat = chrp_event_scan; ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1; ppc_md.heartbeat_count = 1; @@ -365,79 +360,44 @@ chrp_irq_cannonicalize(u_int irq) } } -int __chrp chrp_get_irq( struct pt_regs *regs ) -{ - int irq; - - irq = openpic_irq( smp_processor_id() ); - if (irq == IRQ_8259_CASCADE) - { - /* - * This magic address generates a PCI IACK cycle. - */ - if ( chrp_int_ack_special ) - irq = *chrp_int_ack_special; - else - irq = i8259_irq( smp_processor_id() ); - openpic_eoi( smp_processor_id() ); - } - if (irq == OPENPIC_VEC_SPURIOUS) - /* - * Spurious interrupts should never be - * acknowledged - */ - irq = -1; - /* - * I would like to openpic_eoi here but there seem to be timing problems - * between the openpic ack and the openpic eoi. - * -- Cort - */ - return irq; -} - -void __chrp chrp_post_irq(struct pt_regs* regs, int irq) -{ - /* - * If it's an i8259 irq then we've already done the - * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi - * - * We do it this way since our irq_desc[irq].handler can change - * with RTL and no longer be open_pic -- Cort - */ - if ( irq >= open_pic_irq_offset) - openpic_eoi( smp_processor_id() ); -} - void __init chrp_init_IRQ(void) { struct device_node *np; int i; unsigned long *addrp; + unsigned char* chrp_int_ack_special = 0; + unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + int nmi_irq = -1; +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) + struct device_node *kbd; +#endif if (!(np = find_devices("pci")) || !(addrp = (unsigned long *) get_property(np, "8259-interrupt-acknowledge", NULL))) printk("Cannot find pci to get ack address\n"); else - chrp_int_ack_special = (volatile unsigned char *) - ioremap(*addrp, 1); - open_pic_irq_offset = 16; - for ( i = 16 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); - enable_irq(IRQ_8259_CASCADE); - for ( i = 0 ; i < 16 ; i++ ) + chrp_int_ack_special = (unsigned char *)ioremap(*addrp, 1); + /* hydra still sets OpenPIC_InitSenses to a static set of values */ + if (OpenPIC_InitSenses == NULL) { + prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; + } + openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; i8259_init(); -#ifdef CONFIG_XMON - request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI), - xmon_irq, 0, "NMI", 0); -#endif /* CONFIG_XMON */ -#ifdef CONFIG_SMP - request_irq(openpic_to_irq(OPENPIC_VEC_IPI), - openpic_ipi_action, 0, "IPI0", 0); -#endif /* CONFIG_SMP */ +#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) + if (kbd->parent && kbd->parent->type + && strcmp(kbd->parent->type, "adb") == 0) + break; + if (kbd) + request_irq( HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0); +#endif } void __init @@ -556,12 +516,6 @@ chrp_ide_release_region(ide_ioreg_t from, } void __chrp -chrp_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); -} - -void __chrp chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq) { ide_ioreg_t reg = data_port; @@ -586,7 +540,6 @@ void __init chrp_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - chrp_setup_pci_ptrs(); #ifdef CONFIG_BLK_DEV_INITRD /* take care of initrd if we have one */ if ( r6 ) @@ -596,10 +549,10 @@ void __init } #endif /* CONFIG_BLK_DEV_INITRD */ - /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */ ISA_DMA_THRESHOLD = ~0L; DMA_MODE_READ = 0x44; DMA_MODE_WRITE = 0x48; + isa_io_base = CHRP_ISA_IO_BASE; /* default value */ ppc_md.setup_arch = chrp_setup_arch; ppc_md.setup_residual = NULL; @@ -607,8 +560,8 @@ void __init ppc_md.irq_cannonicalize = chrp_irq_cannonicalize; #ifndef CONFIG_POWER4 ppc_md.init_IRQ = chrp_init_IRQ; - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; #else ppc_md.init_IRQ = xics_init_IRQ; ppc_md.get_irq = xics_get_irq; @@ -669,11 +622,12 @@ void __init ppc_ide_md.ide_check_region = chrp_ide_check_region; ppc_ide_md.ide_request_region = chrp_ide_request_region; ppc_ide_md.ide_release_region = chrp_ide_release_region; - ppc_ide_md.fix_driveid = chrp_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports; ppc_ide_md.io_base = _IO_BASE; #endif + /* * Print the banner, then scroll down so boot progress * can be printed. -- Cort diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 89922aaab10b..93bb8ca00b16 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S @@ -234,7 +234,6 @@ _GLOBAL(_switch) li r0,0x0ff0 stw r0,TRAP(r1) stw r1,KSP(r3) /* Set old stack pointer */ - sync tophys(r0,r4) CLR_TOP32(r0) mtspr SPRG3,r0 /* Update current THREAD phys addr */ @@ -251,7 +250,7 @@ _GLOBAL(_switch) #endif mtspr M_TWB,r9 /* Update MMU base address */ tlbia - SYNC + sync #endif /* CONFIG_8xx */ lwz r1,KSP(r4) /* Load new stack pointer */ /* save the old current 'last' for return value */ @@ -342,23 +341,23 @@ lost_irq_ret: do_bottom_half_ret: 2: lwz r3,_MSR(r1) /* Returning to user mode? */ andi. r3,r3,MSR_PR - beq+ restore /* if so, check need_resched and signals */ - .globl ret_to_user_hook -ret_to_user_hook: - nop + beq+ do_signal_ret /* if so, check need_resched and signals */ lwz r3,NEED_RESCHED(r2) cmpi 0,r3,0 /* check need_resched flag */ beq+ 7f bl schedule 7: lwz r5,SIGPENDING(r2) /* Check for pending unblocked signals */ cmpwi 0,r5,0 - beq+ restore + beq+ do_signal_ret li r3,0 addi r4,r1,STACK_FRAME_OVERHEAD MOL_HOOK_MMU(8,r8) bl do_signal .globl do_signal_ret do_signal_ret: + .globl ret_to_user_hook +ret_to_user_hook: + nop restore: lwz r3,_XER(r1) mtspr XER,r3 @@ -372,7 +371,7 @@ restore: */ mfmsr r0 /* Get current interrupt state */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ /* if returning to user mode, set new sprg2 and save kernel SP */ @@ -468,7 +467,7 @@ enter_rtas: andc r0,r9,r0 li r10,MSR_IR|MSR_DR|MSR_FE0|MSR_FE1|MSR_FP andc r9,r0,r10 - sync /* disable interrupts so SRR0/1 */ + SYNC /* disable interrupts so SRR0/1 */ mtmsr r0 /* don't get trashed */ mtlr r6 CLR_TOP32(r7) diff --git a/arch/ppc/kernel/error_log.c b/arch/ppc/kernel/error_log.c new file mode 100644 index 000000000000..5ee750dda444 --- /dev/null +++ b/arch/ppc/kernel/error_log.c @@ -0,0 +1,183 @@ +/* + * arch/ppc/kernel/error_log.c + * + * Copyright (c) 2000 Tilmann Bitterberg + * (tilmann@bitterberg.de) + * + * Error processing of errors found by rtas even-scan routine + * which is done with every heartbeat. (chrp_setup.c) + */ + +#include <linux/sched.h> + +#include <asm/prom.h> + +#include "error_log.h" + +/* ****************************************************************** */ +/* + * EVENT-SCAN + * The whole stuff below here doesn't take any action when it found + * an error, it just prints as much information as possible and + * then its up to the user to decide what to do. + * + * Returns 0 if no errors were found + * Returns 1 if there may be more errors + */ +int ppc_rtas_errorlog_scan(void) +{ +const char *_errlog_severity[] = { +#ifdef VERBOSE_ERRORS + "No Error\n\t\ +Should require no further information", + "Event\n\t\ +This is not really an error, it is an event. I use events\n\t\ +to communicate with RTAS back and forth.", + "Warning\n\t\ +Indicates a non-state-losing error, either fully recovered\n\t\ +by RTAS or not needing recovery. Ignore it.", + "Error sync\n\t\ +May only be fatal to a certain program or thread. Recovery\n\t\ +and continuation is possible, if I only had a handler for\n\t\ +this. Less serious", + "Error\n\t\ +Less serious, but still causing a loss of data and state.\n\t\ +I can't tell you exactly what to do, You have to decide\n\t\ +with help from the target and initiator field, what kind\n\t\ +of further actions may take place.", + "Fatal\n\t\ +Represent a permanent hardware failure and I believe this\n\t\ +affects my overall performance and behaviour. I would not\n\t\ +attempt to continue normal operation." +#else + "No Error", + "Event", + "Warning", + "Error sync", + "Error", + "Fatal" +#endif /* VERBOSE_ERRORS */ +}; + +#if 0 /* unused?? */ +const char *_errlog_disposition[] = { +#ifdef VERBOSE_ERRORS + "Fully recovered\n\t\ +There was an error, but it is fully recovered by RTAS.", + "Limited recovery\n\t\ +RTAS was able to recover the state of the machine, but some\n\t\ +feature of the machine has been disabled or lost (for example\n\t\ +error checking) or performance may suffer.", + "Not recovered\n\t\ +Whether RTAS did not try to recover anything or recovery failed:\n\t\ +HOUSTON, WE HAVE A PROBLEM!" +#else + "Fully recovered", + "Limited recovery", + "Not recovered" +#endif /* VERBOSE_ERRORS */ +}; +#endif + +const char *_errlog_extended[] = { +#ifdef VERBOSE_ERRORS + "Not present\n\t\ +Sad, the RTAS call didn't return an extended error log.", + "Present\n\t\ +The extended log is present and hopefully it contains a lot of\n\t\ +useful information, which leads to the solution of the problem." +#else + "Not present", + "Present" +#endif /* VERBOSE_ERRORS */ +}; + +const char *_errlog_initiator[] = { + "Unknown or not applicable", + "CPU", + "PCI", + "ISA", + "Memory", + "Power management" +}; + +const char *_errlog_target[] = { + "Unknown or not applicable", + "CPU", + "PCI", + "ISA", + "Memory", + "Power management" +}; + rtas_error_log error_log; + char logdata[1024]; + int error; +#if 0 /* unused?? */ + int retries = 0; /* if HW error, try 10 times */ +#endif + + error = call_rtas ("event-scan", 4, 1, (unsigned long *)&error_log, + INTERNAL_ERROR | EPOW_WARNING, + 0, __pa(logdata), 1024); + + if (error == 1) /* no errors found */ + return 0; + + if (error == -1) { + printk(KERN_ERR "Unable to get errors. Do you a favor and throw this box away\n"); + return 0; + } + if (error_log.version != 1) + printk(KERN_WARNING "Unknown version (%d), please implement me\n", + error_log.version); + + switch (error_log.disposition) { + case DISP_FULLY_RECOVERED: + /* there was an error, but everything is fine now */ + return 0; + case DISP_NOT_RECOVERED: + printk("We have a really serious Problem!\n"); + case DISP_LIMITED_RECOVERY: + printk("Error classification\n"); + printk("Severity : %s\n", + ppc_rtas_errorlog_check_severity (error_log)); + printk("Initiator : %s\n", + ppc_rtas_errorlog_check_initiator (error_log)); + printk("Target : %s\n", + ppc_rtas_errorlog_check_target (error_log)); + printk("Type : %s\n", + ppc_rtas_errorlog_check_type (error_log)); + printk("Ext. log : %s\n", + ppc_rtas_errorlog_check_extended (error_log)); + if (error_log.extended) + ppc_rtas_errorlog_disect_extended (logdata); + return 1; + default: + /* nothing */ + break; + } + return 0; +} +/* ****************************************************************** */ +const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log) +{ + const char *_errlog_type[] = { + "unknown type", + "too many tries failed", + "TCE error", + "RTAS device failed", + "target timed out", + "parity error on data", /* 5 */ + "parity error on address", + "parity error on external cache", + "access to invalid address", + "uncorrectable ECC error", + "corrected ECC error" /* 10 */ + }; + if (error_log.type == TYPE_EPOW) + return "EPOW"; + if (error_log.type >= TYPE_PMGM_POWER_SW_ON) + return "PowerMGM Event (not handled right now)"; + return _errlog_type[error_log.type]; +} + diff --git a/arch/ppc/kernel/error_log.h b/arch/ppc/kernel/error_log.h new file mode 100644 index 000000000000..579fc3e0d052 --- /dev/null +++ b/arch/ppc/kernel/error_log.h @@ -0,0 +1,95 @@ +#ifndef __ERROR_LOG_H__ +#define __ERROR_LOG_H__ + +#define VERBOSE_ERRORS 1 /* Maybe I enlarge the kernel too much */ +#undef VERBOSE_ERRORS + +/* Event classes */ +/* XXX: Endianess correct? NOW*/ +#define INTERNAL_ERROR 0x80000000 /* set bit 0 */ +#define EPOW_WARNING 0x40000000 /* set bit 1 */ +#define POWERMGM_EVENTS 0x20000000 /* set bit 2 */ + +/* event-scan returns */ +#define SEVERITY_FATAL 0x5 +#define SEVERITY_ERROR 0x4 +#define SEVERITY_ERROR_SYNC 0x3 +#define SEVERITY_WARNING 0x2 +#define SEVERITY_EVENT 0x1 +#define SEVERITY_NO_ERROR 0x0 +#define DISP_FULLY_RECOVERED 0x0 +#define DISP_LIMITED_RECOVERY 0x1 +#define DISP_NOT_RECOVERED 0x2 +#define PART_PRESENT 0x0 +#define PART_NOT_PRESENT 0x1 +#define INITIATOR_UNKNOWN 0x0 +#define INITIATOR_CPU 0x1 +#define INITIATOR_PCI 0x2 +#define INITIATOR_ISA 0x3 +#define INITIATOR_MEMORY 0x4 +#define INITIATOR_POWERMGM 0x5 +#define TARGET_UNKNOWN 0x0 +#define TARGET_CPU 0x1 +#define TARGET_PCI 0x2 +#define TARGET_ISA 0x3 +#define TARGET_MEMORY 0x4 +#define TARGET_POWERMGM 0x5 +#define TYPE_RETRY 0x01 +#define TYPE_TCE_ERR 0x02 +#define TYPE_INTERN_DEV_FAIL 0x03 +#define TYPE_TIMEOUT 0x04 +#define TYPE_DATA_PARITY 0x05 +#define TYPE_ADDR_PARITY 0x06 +#define TYPE_CACHE_PARITY 0x07 +#define TYPE_ADDR_INVALID 0x08 +#define TYPE_ECC_UNCORR 0x09 +#define TYPE_ECC_CORR 0x0a +#define TYPE_EPOW 0x40 +/* I don't add PowerMGM events right now, this is a different topic */ +#define TYPE_PMGM_POWER_SW_ON 0x60 +#define TYPE_PMGM_POWER_SW_OFF 0x61 +#define TYPE_PMGM_LID_OPEN 0x62 +#define TYPE_PMGM_LID_CLOSE 0x63 +#define TYPE_PMGM_SLEEP_BTN 0x64 +#define TYPE_PMGM_WAKE_BTN 0x65 +#define TYPE_PMGM_BATTERY_WARN 0x66 +#define TYPE_PMGM_BATTERY_CRIT 0x67 +#define TYPE_PMGM_SWITCH_TO_BAT 0x68 +#define TYPE_PMGM_SWITCH_TO_AC 0x69 +#define TYPE_PMGM_KBD_OR_MOUSE 0x6a +#define TYPE_PMGM_ENCLOS_OPEN 0x6b +#define TYPE_PMGM_ENCLOS_CLOSED 0x6c +#define TYPE_PMGM_RING_INDICATE 0x6d +#define TYPE_PMGM_LAN_ATTENTION 0x6e +#define TYPE_PMGM_TIME_ALARM 0x6f +#define TYPE_PMGM_CONFIG_CHANGE 0x70 +#define TYPE_PMGM_SERVICE_PROC 0x71 + +typedef struct _rtas_error_log { + unsigned long version:8; /* Architectural version */ + unsigned long severity:3; /* Severity level of error */ + unsigned long disposition:2; /* Degree of recovery */ + unsigned long extended:1; /* extended log present? */ + unsigned long /* reserved */ :2; /* Reserved for future use */ + unsigned long initiator:4; /* Initiator of event */ + unsigned long target:4; /* Target of failed operation */ + unsigned long type:8; /* General event or error*/ + unsigned long extended_log_length:32; /* length in bytes */ +} rtas_error_log; + +/* ****************************************************************** */ +#define ppc_rtas_errorlog_check_severity(x) \ + (_errlog_severity[x.severity]) +#define ppc_rtas_errorlog_check_target(x) \ + (_errlog_target[x.target]) +#define ppc_rtas_errorlog_check_initiator(x) \ + (_errlog_initiator[x.initiator]) +#define ppc_rtas_errorlog_check_extended(x) \ + (_errlog_extended[x.extended]) +#define ppc_rtas_errorlog_disect_extended(x) \ + do { /* implement me */ } while(0) +extern const char * ppc_rtas_errorlog_check_type (rtas_error_log error_log); +extern int ppc_rtas_errorlog_scan(void); + + +#endif /* __ERROR_LOG_H__ */ diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c index 57599917ae85..f22f4b1639e3 100644 --- a/arch/ppc/kernel/feature.c +++ b/arch/ppc/kernel/feature.c @@ -238,12 +238,15 @@ feature_add_controller(struct device_node *controller_device, fbit* bits); static struct feature_controller* feature_lookup_controller(struct device_node *device); +#ifdef CONFIG_PMAC_PBOOK static void heathrow_prepare_for_sleep(struct feature_controller* ctrler); static void heathrow_wakeup(struct feature_controller* ctrler); -static void keylargo_init(void); -static void uninorth_init(void); static void core99_prepare_for_sleep(struct feature_controller* ctrler); static void core99_wake_up(struct feature_controller* ctrler); +#endif /* CONFIG_PMAC_PBOOK */ + +static void keylargo_init(void); +static void uninorth_init(void); /* static variables */ static struct feature_controller controllers[MAX_FEATURE_CONTROLLERS]; @@ -255,6 +258,10 @@ static volatile u32* keylargo_base = NULL; static int uninorth_rev; static int keylargo_rev; +/* + * WARNING ! This function is called early in setup_arch, neither the IO base + * nor the udelay calibration have been done yet + */ void feature_init(void) { @@ -527,14 +534,31 @@ feature_set_usb_power(struct device_node* device, int power) void feature_set_firewire_power(struct device_node* device, int power) { + if (!uninorth_base) + return; + if (power) + UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + else + UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_FW); + udelay(20); +} + +#ifdef CONFIG_SMP +void +feature_core99_kick_cpu1(void) +{ + out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_UP); + udelay(1); + out_8((volatile u8 *)KL_FCR(KL_GPIO_KICK_CPU1), KL_GPIO_KICK_CPU1_DOWN); } +#endif /* CONFIG_SMP */ /* Initialize the Core99 UniNorth host bridge and memory controller */ static void uninorth_init(void) { - struct device_node* gmac; + struct device_node* gmac, *fw; unsigned long actrl; /* Set the arbitrer QAck delay according to what Apple does @@ -564,6 +588,11 @@ uninorth_init(void) } if (gmac) feature_set_gmac_power(gmac, 0); + + /* Kludge (enable FW before PCI probe) */ + fw = find_devices("firewire"); + if (fw && device_is_compatible(fw, "pci106b,18")) + feature_set_firewire_power(fw, 1); } /* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure @@ -576,6 +605,43 @@ keylargo_init(void) } #ifdef CONFIG_PMAC_PBOOK + +static u32 save_fcr[5]; +static u32 save_mbcr; + +static void +heathrow_prepare_for_sleep(struct feature_controller* ctrler) +{ + save_mbcr = in_le32(FREG(ctrler, 0x34)); + save_fcr[0] = in_le32(FREG(ctrler, 0x38)); + save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); + + out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); +} + +static void +heathrow_wakeup(struct feature_controller* ctrler) +{ + out_le32(FREG(ctrler, 0x38), save_fcr[0]); + out_le32(FREG(ctrler, 0x3c), save_fcr[1]); + out_le32(FREG(ctrler, 0x34), save_mbcr); + mdelay(1); + out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); + mdelay(1); +} + +static void +core99_prepare_for_sleep(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + +static void +core99_wake_up(struct feature_controller* ctrler) +{ + /* Not yet implemented */ +} + void feature_prepare_for_sleep(void) { @@ -599,7 +665,6 @@ feature_prepare_for_sleep(void) } } - void feature_wake_up(void) { @@ -622,39 +687,4 @@ feature_wake_up(void) } } -static u32 save_fcr[5]; -static u32 save_mbcr; - -static void -heathrow_prepare_for_sleep(struct feature_controller* ctrler) -{ - save_mbcr = in_le32(FREG(ctrler, 0x34)); - save_fcr[0] = in_le32(FREG(ctrler, 0x38)); - save_fcr[1] = in_le32(FREG(ctrler, 0x3c)); - - out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE); -} - -static void -heathrow_wakeup(struct feature_controller* ctrler) -{ - out_le32(FREG(ctrler, 0x38), save_fcr[0]); - out_le32(FREG(ctrler, 0x3c), save_fcr[1]); - out_le32(FREG(ctrler, 0x34), save_mbcr); - mdelay(1); - out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE); - mdelay(1); -} - -static void -core99_prepare_for_sleep(struct feature_controller* ctrler) -{ - /* Not yet implemented */ -} - -static void -core99_wake_up(struct feature_controller* ctrler) -{ - /* Not yet implemented */ -} #endif /* CONFIG_PMAC_PBOOK */ diff --git a/arch/ppc/kernel/galaxy_pci.c b/arch/ppc/kernel/galaxy_pci.c index aeddd9a0e6b5..36e7e14fb920 100644 --- a/arch/ppc/kernel/galaxy_pci.c +++ b/arch/ppc/kernel/galaxy_pci.c @@ -36,67 +36,84 @@ /* Function Prototypes */ -decl_config_access_method(galaxy); - - void __init galaxy_pcibios_fixup(void) { } -void __init -galaxy_setup_pci_ptrs(void) +static int +galaxy_pcibios_read_config_byte(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u8 *val) { - set_config_access_method(galaxy); - ppc_md.pcibios_fixup = galaxy_pcibios_fixup; + return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) +static int +galaxy_pcibios_read_config_word(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u16 *val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) +static int +galaxy_pcibios_read_config_dword(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u32 *val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static int +galaxy_pcibios_write_config_byte(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u8 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static int +galaxy_pcibios_write_config_word(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u16 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) +static int +galaxy_pcibios_write_config_dword(struct pci_controller* hose, + u8 bus, u8 dev, u8 offset, u32 val) { return (PCIBIOS_SUCCESSFUL); } -int -galaxy_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_controller_ops galaxy_pci_ops = { + galaxy_pcibios_read_config_byte, + galaxy_pcibios_read_config_word, + galaxy_pcibios_read_config_dword, + galaxy_pcibios_write_config_byte, + galaxy_pcibios_write_config_word, + galaxy_pcibios_write_config_dword +}; - return (PCIBIOS_SUCCESSFUL); +void __init +galaxy_find_bridges(void) +{ + struct pci_controller* hose; + + set_config_access_method(galaxy); + + ppc_md.pcibios_fixup = galaxy_pcibios_fixup; + hose = pcibios_alloc_controller(); + if (!hose) + return; + hose->ops = &galaxy_pci_ops; + /* Todo ... + hose->cfg_data = ioremap(PCICFGDATA, ...); + hose->cfg_addr = ioremap(PCICFGADDR, ...); + */ } diff --git a/arch/ppc/kernel/gemini_pci.c b/arch/ppc/kernel/gemini_pci.c deleted file mode 100644 index 1ac83d1c88fe..000000000000 --- a/arch/ppc/kernel/gemini_pci.c +++ /dev/null @@ -1,103 +0,0 @@ -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/pci.h> -#include <linux/malloc.h> - -#include <asm/machdep.h> -#include <asm/gemini.h> -#include <asm/byteorder.h> -#include <asm/io.h> -#include <asm/uaccess.h> - -#include "pci.h" - -#define pci_config_addr(bus,dev,offset) \ - (0x80000000 | (bus<<16) | (dev<<8) | offset) - - -int -gemini_pcibios_read_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char *val) -{ - unsigned long reg; - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); - *val = ((reg >> ((offset & 0x3) << 3)) & 0xff); - return PCIBIOS_SUCCESSFUL; -} - -int -gemini_pcibios_read_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short *val) -{ - unsigned long reg; - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); - *val = ((reg >> ((offset & 0x3) << 3)) & 0xffff); - return PCIBIOS_SUCCESSFUL; -} - -int -gemini_pcibios_read_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int *val) -{ - *val = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); - return PCIBIOS_SUCCESSFUL; -} - -int -gemini_pcibios_write_config_byte(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned char val) -{ - unsigned long reg; - int shifts = offset & 0x3; - - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); - reg = (reg & ~(0xff << (shifts << 3))) | (val << (shifts << 3)); - grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), reg ); - return PCIBIOS_SUCCESSFUL; -} - -int -gemini_pcibios_write_config_word(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned short val) -{ - unsigned long reg; - int shifts = offset & 0x3; - - reg = grackle_read( pci_config_addr( bus, dev, (offset & ~(0x3)))); - reg = (reg & ~(0xffff << (shifts << 3))) | (val << (shifts << 3)); - grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), reg ); - return PCIBIOS_SUCCESSFUL; -} - -int -gemini_pcibios_write_config_dword(unsigned char bus, unsigned char dev, - unsigned char offset, unsigned int val) -{ - grackle_write( pci_config_addr( bus, dev, (offset & ~(0x3))), val ); - return PCIBIOS_SUCCESSFUL; -} - -void __init gemini_pcibios_fixup(void) -{ - int i; - struct pci_dev *dev; - - pci_for_each_dev(dev) { - for(i = 0; i < 6; i++) { - if (dev->resource[i].flags & IORESOURCE_IO) { - dev->resource[i].start |= (0xfe << 24); - dev->resource[i].end |= (0xfe << 24); - } - } - } -} - -decl_config_access_method(gemini); - -/* The "bootloader" for Synergy boards does none of this for us, so we need to - lay it all out ourselves... --Dan */ -void __init gemini_setup_pci_ptrs(void) -{ - set_config_access_method(gemini); - ppc_md.pcibios_fixup = gemini_pcibios_fixup; -} diff --git a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/kernel/gemini_prom.S deleted file mode 100644 index 0904bb0eb3f8..000000000000 --- a/arch/ppc/kernel/gemini_prom.S +++ /dev/null @@ -1,96 +0,0 @@ -/* - * arch/ppc/kernel/gemini_prom.S - * - * Not really prom support code (yet), but sort of anti-prom code. The current - * bootloader does a number of things it shouldn't and doesn't do things that it - * should. The stuff in here is mainly a hodge-podge collection of setup code - * to get the board up and running. - * ---Dan - */ - -#include "ppc_asm.tmpl" -#include "ppc_defs.h" -#include <linux/config.h> -#include <asm/processor.h> -#include <asm/page.h> -#include <asm/gemini.h> - -#define HID0_ABE (1<<3) - -/* - * On 750's the MMU is on when Linux is booted, so we need to clear out the - * bootloader's BAT settings, make sure we're in supervisor state (gotcha!), - * and turn off the MMU. - * - */ - -_GLOBAL(prom_init) -_GLOBAL(gemini_prom_init) -#ifdef CONFIG_SMP - /* Since the MMU's on, get stuff in rom space that we'll need */ - lis r4,GEMINI_CPUSTAT@h - ori r4,r4,GEMINI_CPUSTAT@l - lbz r5,0(r4) - andi. r5,r5,3 - mr r24,r5 /* cpu # used later on */ -#endif - mfmsr r4 - li r3,MSR_PR /* ensure supervisor! */ - ori r3,r3,MSR_IR|MSR_DR - andc r4,r4,r3 - mtmsr r4 -#if 0 - /* zero out the bats now that the MMU is off */ -prom_no_mmu: - li r3,0 - mtspr IBAT0U,r3 - mtspr IBAT0L,r3 - mtspr IBAT1U,r3 - mtspr IBAT1L,r3 - mtspr IBAT2U,r3 - mtspr IBAT2L,r3 - mtspr IBAT3U,r3 - mtspr IBAT3L,r3 - - mtspr DBAT0U,r3 - mtspr DBAT0L,r3 - mtspr DBAT1U,r3 - mtspr DBAT1L,r3 - mtspr DBAT2U,r3 - mtspr DBAT2L,r3 - mtspr DBAT3U,r3 - mtspr DBAT3L,r3 -#endif - - /* the bootloader (as far as I'm currently aware) doesn't mess with page - tables, but since we're already here, might as well zap these, too */ - li r4,0 - mtspr SDR1,r4 - - li r4,16 - mtctr r4 - li r3,0 - li r4,0 -3: mtsrin r3,r4 - addi r3,r3,1 - bdnz 3b - -#ifdef CONFIG_SMP - /* The 750 book (and Mot/IBM support) says that this will "assist" snooping - when in SMP. Not sure yet whether this should stay or leave... */ - mfspr r4,HID0 - ori r4,r4,HID0_ABE - mtspr HID0,r4 - sync -#endif /* CONFIG_SMP */ - blr - -/* apparently, SMon doesn't pay attention to HID0[SRST]. Disable the MMU and - branch to 0xfff00100 */ -_GLOBAL(_gemini_reboot) - lis r5,GEMINI_BOOT_INIT@h - ori r5,r5,GEMINI_BOOT_INIT@l - li r6,MSR_IP - mtspr SRR0,r5 - mtspr SRR1,r6 - rfi diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c deleted file mode 100644 index a01ff9eca080..000000000000 --- a/arch/ppc/kernel/gemini_setup.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * linux/arch/ppc/kernel/setup.c - * - * Copyright (C) 1995 Linus Torvalds - * Adapted from 'alpha' version by Gary Thomas - * Modified by Cort Dougan (cort@cs.nmt.edu) - * Synergy Microsystems board support by Dan Cox (dan@synergymicro.com) - * - */ - -#include <linux/config.h> -#include <linux/stddef.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/reboot.h> -#include <linux/pci.h> -#include <linux/time.h> -#include <linux/kdev_t.h> -#include <linux/types.h> -#include <linux/major.h> -#include <linux/blk.h> -#include <linux/console.h> -#include <linux/openpic.h> - -#include <asm/system.h> -#include <asm/pgtable.h> -#include <asm/page.h> -#include <asm/dma.h> -#include <asm/io.h> -#include <asm/m48t35.h> -#include <asm/gemini.h> - -#include <asm/time.h> -#include "local_irq.h" -#include "open_pic.h" - -void gemini_setup_pci_ptrs(void); -static int gemini_get_clock_speed(void); -extern void gemini_pcibios_fixup(void); - -static char *gemini_board_families[] = { - "VGM", "VSS", "KGM", "VGR", "VCM", "VCS", "KCM", "VCR" -}; -static int gemini_board_count = sizeof(gemini_board_families) / - sizeof(gemini_board_families[0]); - -static unsigned int cpu_7xx[16] = { - 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 -}; -static unsigned int cpu_6xx[16] = { - 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0 -}; - -int chrp_get_irq(struct pt_regs *); -void chrp_post_irq(struct pt_regs* regs, int); - -static inline unsigned long _get_HID1(void) -{ - unsigned long val; - - __asm__ __volatile__("mfspr %0,1009" : "=r" (val)); - return val; -} - -int -gemini_get_cpuinfo(char *buffer) -{ - int len; - unsigned char reg, rev; - char *family; - unsigned int type; - - reg = readb(GEMINI_FEAT); - family = gemini_board_families[((reg>>4) & 0xf)]; - if (((reg>>4) & 0xf) > gemini_board_count) - printk(KERN_ERR "cpuinfo(): unable to determine board family\n"); - - reg = readb(GEMINI_BREV); - type = (reg>>4) & 0xf; - rev = reg & 0xf; - - reg = readb(GEMINI_BECO); - - len = sprintf( buffer, "machine\t\t: Gemini %s%d, rev %c, eco %d\n", - family, type, (rev + 'A'), (reg & 0xf)); - - len = sprintf(buffer, "board\t\t: Gemini %s", family); - if (type > 9) - len += sprintf(buffer+len, "%c", (type - 10) + 'A'); - else - len += sprintf(buffer+len, "%d", type); - - len += sprintf(buffer+len, ", rev %c, eco %d\n", - (rev + 'A'), (reg & 0xf)); - - len += sprintf(buffer+len, "clock\t\t: %dMhz\n", - gemini_get_clock_speed()); - - return len; -} - -static u_char gemini_openpic_initsenses[] = { - 1, - 1, - 1, - 1, - 0, - 0, - 1, /* remainder are level-triggered */ -}; - -#define GEMINI_MPIC_ADDR (0xfcfc0000) -#define GEMINI_MPIC_PCI_CFG (0x80005800) - -void __init gemini_openpic_init(void) -{ - - OpenPIC = (volatile struct OpenPIC *) - grackle_read(0x80005800 + 0x10); -#if 0 - grackle_write(GEMINI_MPIC_PCI_CFG + PCI_BASE_ADDRESS_0, - GEMINI_MPIC_ADDR); - grackle_write(GEMINI_MPIC_PCI_CFG + PCI_COMMAND, PCI_COMMAND_MEMORY); - - OpenPIC = (volatile struct OpenPIC *) GEMINI_MPIC_ADDR; -#endif - OpenPIC_InitSenses = gemini_openpic_initsenses; - OpenPIC_NumInitSenses = sizeof( gemini_openpic_initsenses ); - - ioremap( GEMINI_MPIC_ADDR, sizeof( struct OpenPIC )); -} - - -extern unsigned long loops_per_sec; -extern int root_mountflags; -extern char cmd_line[]; - -void -gemini_heartbeat(void) -{ - static unsigned long led = GEMINI_LEDBASE+(4*8); - static char direction = 8; - *(char *)led = 0; - if ( (led + direction) > (GEMINI_LEDBASE+(7*8)) || - (led + direction) < (GEMINI_LEDBASE+(4*8)) ) - direction *= -1; - led += direction; - *(char *)led = 0xff; - ppc_md.heartbeat_count = ppc_md.heartbeat_reset; -} - -void __init gemini_setup_arch(void) -{ - extern char cmd_line[]; - - - loops_per_sec = 50000000; - -#ifdef CONFIG_BLK_DEV_INITRD - /* bootable off CDROM */ - if (initrd_start) - ROOT_DEV = MKDEV(SCSI_CDROM_MAJOR, 0); - else -#endif - ROOT_DEV = to_kdev_t(0x0801); - - /* nothing but serial consoles... */ - sprintf(cmd_line, "%s console=ttyS0", cmd_line); - - printk("Boot arguments: %s\n", cmd_line); - - ppc_md.heartbeat = gemini_heartbeat; - ppc_md.heartbeat_reset = HZ/8; - ppc_md.heartbeat_count = 1; - - /* take special pains to map the MPIC, since it isn't mapped yet */ - gemini_openpic_init(); - /* start the L2 */ - gemini_init_l2(); -} - - -int -gemini_get_clock_speed(void) -{ - unsigned long hid1, pvr = _get_PVR(); - int clock; - - hid1 = (_get_HID1() >> 28) & 0xf; - if (PVR_VER(pvr) == 8 || - PVR_VER(pvr) == 12) - hid1 = cpu_7xx[hid1]; - else - hid1 = cpu_6xx[hid1]; - - switch((readb(GEMINI_BSTAT) & 0xc) >> 2) { - - case 0: - default: - clock = (hid1*100)/3; - break; - - case 1: - clock = (hid1*125)/3; - break; - - case 2: - clock = (hid1*50); - break; - } - - return clock; -} - -#define L2CR_PIPE_LATEWR (0x01800000) /* late-write SRAM */ -#define L2CR_L2CTL (0x00100000) /* RAM control */ -#define L2CR_INST_DISABLE (0x00400000) /* disable for insn's */ -#define L2CR_L2I (0x00200000) /* global invalidate */ -#define L2CR_L2E (0x80000000) /* enable */ -#define L2CR_L2WT (0x00080000) /* write-through */ - -void __init gemini_init_l2(void) -{ - unsigned char reg, brev, fam, creg; - unsigned long cache; - unsigned long pvr = _get_PVR(); - - reg = readb(GEMINI_L2CFG); - brev = readb(GEMINI_BREV); - fam = readb(GEMINI_FEAT); - - switch(PVR_VER(pvr)) { - - case 8: - if (reg & 0xc0) - cache = (((reg >> 6) & 0x3) << 28); - else - cache = 0x3 << 28; - -#ifdef CONFIG_SMP - /* Pre-3.0 processor revs had snooping errata. Leave - their L2's disabled with SMP. -- Dan */ - if (PVR_CFG(pvr) < 3) { - printk("Pre-3.0 750; L2 left disabled!\n"); - return; - } -#endif /* CONFIG_SMP */ - - /* Special case: VGM5-B's came before L2 ratios were set on - the board. Processor speed shouldn't be too high, so - set L2 ratio to 1:1.5. */ - if ((brev == 0x51) && ((fam & 0xa0) >> 4) == 0) - reg |= 1; - - /* determine best cache ratio based upon what the board - tells us (which sometimes _may_ not be true) and - the processor speed. */ - else { - if (gemini_get_clock_speed() > 250) - reg = 2; - } - break; - case 12: - { - static unsigned long l2_size_val = 0; - - if (!l2_size_val) - l2_size_val = _get_L2CR(); - cache = l2_size_val; - break; - } - case 4: - case 9: - creg = readb(GEMINI_CPUSTAT); - if (((creg & 0xc) >> 2) != 1) - printk("Dual-604 boards don't support the use of L2\n"); - else - writeb(1, GEMINI_L2CFG); - return; - default: - printk("Unknown processor; L2 left disabled\n"); - return; - } - - cache |= ((1<<reg) << 25); - cache |= (L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE); - _set_L2CR(0); - _set_L2CR(cache | L2CR_L2I | L2CR_L2E); - -} - -void -gemini_restart(char *cmd) -{ - __cli(); - /* make a clean restart, not via the MPIC */ - _gemini_reboot(); - for(;;); -} - -void -gemini_power_off(void) -{ - for(;;); -} - -void -gemini_halt(void) -{ - gemini_restart(NULL); -} - -void __init gemini_init_IRQ(void) -{ - int i; - - /* gemini has no 8259 */ - open_pic_irq_offset = 0; - for( i=0; i < NR_IRQS; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); -#ifdef CONFIG_SMP - request_irq(OPENPIC_VEC_IPI, openpic_ipi_action, - 0, "IPI0", 0); - request_irq(OPENPIC_VEC_IPI+1, openpic_ipi_action, - 0, "IPI1 (invalidate TLB)", 0); - request_irq(OPENPIC_VEC_IPI+2, openpic_ipi_action, - 0, "IPI2 (stop CPU)", 0); - request_irq(OPENPIC_VEC_IPI+3, openpic_ipi_action, - 0, "IPI3 (reschedule)", 0); -#endif /* CONFIG_SMP */ -} - -#define gemini_rtc_read(x) (readb(GEMINI_RTC+(x))) -#define gemini_rtc_write(val,x) (writeb((val),(GEMINI_RTC+(x)))) - -/* ensure that the RTC is up and running */ -long __init gemini_time_init(void) -{ - unsigned char reg; - - reg = gemini_rtc_read(M48T35_RTC_CONTROL); - - if ( reg & M48T35_RTC_STOPPED ) { - printk(KERN_INFO "M48T35 real-time-clock was stopped. Now starting...\n"); - gemini_rtc_write((reg & ~(M48T35_RTC_STOPPED)), M48T35_RTC_CONTROL); - gemini_rtc_write((reg | M48T35_RTC_SET), M48T35_RTC_CONTROL); - } - return 0; -} - -#undef DEBUG_RTC - -unsigned long -gemini_get_rtc_time(void) -{ - unsigned int year, mon, day, hour, min, sec; - unsigned char reg; - - reg = gemini_rtc_read(M48T35_RTC_CONTROL); - gemini_rtc_write((reg|M48T35_RTC_READ), M48T35_RTC_CONTROL); -#ifdef DEBUG_RTC - printk("get rtc: reg = %x\n", reg); -#endif - - do { - sec = gemini_rtc_read(M48T35_RTC_SECONDS); - min = gemini_rtc_read(M48T35_RTC_MINUTES); - hour = gemini_rtc_read(M48T35_RTC_HOURS); - day = gemini_rtc_read(M48T35_RTC_DOM); - mon = gemini_rtc_read(M48T35_RTC_MONTH); - year = gemini_rtc_read(M48T35_RTC_YEAR); - } while( sec != gemini_rtc_read(M48T35_RTC_SECONDS)); -#ifdef DEBUG_RTC - printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", - sec, min, hour, day, mon, year); -#endif - - gemini_rtc_write(reg, M48T35_RTC_CONTROL); - - BCD_TO_BIN(sec); - BCD_TO_BIN(min); - BCD_TO_BIN(hour); - BCD_TO_BIN(day); - BCD_TO_BIN(mon); - BCD_TO_BIN(year); - - if ((year += 1900) < 1970) - year += 100; -#ifdef DEBUG_RTC - printk("get rtc: sec=%x, min=%x, hour=%x, day=%x, mon=%x, year=%x\n", - sec, min, hour, day, mon, year); -#endif - - return mktime( year, mon, day, hour, min, sec ); -} - - -int -gemini_set_rtc_time( unsigned long now ) -{ - unsigned char reg; - struct rtc_time tm; - - to_tm( now, &tm ); - - reg = gemini_rtc_read(M48T35_RTC_CONTROL); -#if DEBUG_RTC - printk("set rtc: reg = %x\n", reg); -#endif - - gemini_rtc_write((reg|M48T35_RTC_SET), M48T35_RTC_CONTROL); -#if DEBUG_RTC - printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n", - tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year); -#endif - - tm.tm_year -= 1900; - BIN_TO_BCD(tm.tm_sec); - BIN_TO_BCD(tm.tm_min); - BIN_TO_BCD(tm.tm_hour); - BIN_TO_BCD(tm.tm_mon); - BIN_TO_BCD(tm.tm_mday); - BIN_TO_BCD(tm.tm_year); -#ifdef DEBUG_RTC - printk("set rtc: tm vals - sec=%x, min=%x, hour=%x, mon=%x, mday=%x, year=%x\n", - tm.tm_sec, tm.tm_min, tm.tm_hour, tm.tm_mon, tm.tm_mday, tm.tm_year); -#endif - - gemini_rtc_write(tm.tm_sec, M48T35_RTC_SECONDS); - gemini_rtc_write(tm.tm_min, M48T35_RTC_MINUTES); - gemini_rtc_write(tm.tm_hour, M48T35_RTC_HOURS); - gemini_rtc_write(tm.tm_mday, M48T35_RTC_DOM); - gemini_rtc_write(tm.tm_mon, M48T35_RTC_MONTH); - gemini_rtc_write(tm.tm_year, M48T35_RTC_YEAR); - - /* done writing */ - gemini_rtc_write(reg, M48T35_RTC_CONTROL); - - if ((time_state == TIME_ERROR) || (time_state == TIME_BAD)) - time_state = TIME_OK; - - return 0; -} - -/* use the RTC to determine the decrementer count */ -void __init gemini_calibrate_decr(void) -{ - int freq, divisor; - unsigned char reg; - - /* determine processor bus speed */ - reg = readb(GEMINI_BSTAT); - - switch(((reg & 0x0c)>>2)&0x3) { - case 0: - default: - freq = 66; - break; - case 1: - freq = 83; - break; - case 2: - freq = 100; - break; - } - - freq *= 1000000; - divisor = 4; - decrementer_count = freq / HZ / divisor; - count_period_num = divisor; - count_period_den = freq / 1000000; -} - -int gemini_get_irq( struct pt_regs *regs ) -{ - int irq; - - irq = openpic_irq( smp_processor_id() ); - if (irq == OPENPIC_VEC_SPURIOUS) - /* - * Spurious interrupts should never be - * acknowledged - */ - irq = -1; - /* - * I would like to openpic_eoi here but there seem to be timing problems - * between the openpic ack and the openpic eoi. - * -- Cort - */ - return irq; -} - -void gemini_post_irq(struct pt_regs* regs, int irq) -{ - /* - * If it's an i8259 irq then we've already done the - * openpic irq. So we just check to make sure the controller - * is an openpic and if it is then eoi - * - * We do it this way since our irq_desc[irq].handler can change - * with RTL and no longer be open_pic -- Cort - */ - if ( irq >= open_pic_irq_offset) - openpic_eoi( smp_processor_id() ); -} - - -void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, - unsigned long r6, unsigned long r7) -{ - int i; - int chrp_get_irq( struct pt_regs * ); - - for(i = 0; i < GEMINI_LEDS; i++) - gemini_led_off(i); - - gemini_setup_pci_ptrs(); - - ISA_DMA_THRESHOLD = 0; - DMA_MODE_READ = 0; - DMA_MODE_WRITE = 0; - -#ifdef CONFIG_BLK_DEV_INITRD - if ( r4 ) - { - initrd_start = r4 + KERNELBASE; - initrd_end = r5 + KERNELBASE; - } -#endif - - ppc_md.setup_arch = gemini_setup_arch; - ppc_md.setup_residual = NULL; - ppc_md.get_cpuinfo = gemini_get_cpuinfo; - ppc_md.irq_cannonicalize = NULL; - ppc_md.init_IRQ = gemini_init_IRQ; - ppc_md.get_irq = gemini_get_irq; - ppc_md.post_irq = gemini_post_irq; - ppc_md.init = NULL; - - ppc_md.restart = gemini_restart; - ppc_md.power_off = gemini_power_off; - ppc_md.halt = gemini_halt; - - ppc_md.time_init = gemini_time_init; - ppc_md.set_rtc_time = gemini_set_rtc_time; - ppc_md.get_rtc_time = gemini_get_rtc_time; - ppc_md.calibrate_decr = gemini_calibrate_decr; - - /* no keyboard/mouse/video stuff yet.. */ - ppc_md.kbd_setkeycode = NULL; - ppc_md.kbd_getkeycode = NULL; - ppc_md.kbd_translate = NULL; - ppc_md.kbd_unexpected_up = NULL; - ppc_md.kbd_leds = NULL; - ppc_md.kbd_init_hw = NULL; -#ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = NULL; -#endif - ppc_md.pcibios_fixup_bus = gemini_pcibios_fixup; -} diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S index 06b7c6f1d00d..8ea3cdc7a7dc 100644 --- a/arch/ppc/kernel/hashtable.S +++ b/arch/ppc/kernel/hashtable.S @@ -56,7 +56,6 @@ hash_page: #ifdef CONFIG_PPC64BRIDGE mfmsr r0 clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - sync MTMSRD(r0) isync #endif @@ -112,23 +111,31 @@ hash_page: #endif tophys(r2,r5) rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r6,0(r2) /* get linux-style pte */ ori r4,r4,1 /* set _PAGE_PRESENT bit in access */ + rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ + ori r5,r5,0x100 /* set _PAGE_ACCESSED */ +retry: + lwz r6,0(r2) /* get linux-style pte */ andc. r0,r4,r6 /* check access & ~permission */ #ifdef CONFIG_SMP bne- hash_page_out /* return if access not permitted */ #else bnelr- #endif + andc. r0,r5,r6 /* any bits not yet set? */ + beq 2f - ori r6,r6,0x100 /* set _PAGE_ACCESSED in pte */ - rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ - rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ - or r6,r6,r5 - stw r6,0(r2) /* update PTE (accessed/dirty bits) */ + /* Update the linux PTE atomically */ + lwarx r0,0,r2 /* refetch the pte and check */ + cmpw 0,r0,r6 /* that it hasn't been changed */ + bne- retry /* retry if it has */ + or r6,r6,r5 /* set accessed/dirty bits */ + stwcx. r6,0,r2 /* attempt to update PTE */ + bne- retry /* retry if someone got there first */ /* Convert linux-style PTE to low word of PPC-style PTE */ - rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ +2: rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ rlwimi r6,r6,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ ori r4,r4,0xe04 /* clear out reserved bits */ andc r6,r6,r4 /* PP=2 or 0, when _PAGE_HWWRITE */ @@ -166,12 +173,16 @@ hash_page_patch_A: rlwimi r4,r5,32-5,25-Hash_bits,24 /* (VSID & hash_mask) << 7 */ rlwinm r0,r3,32-5,25-Hash_bits,24 /* (PI & hash_mask) << 7 */ xor r4,r4,r0 /* make primary hash */ + li r2,8 /* PTEs/group */ +#ifndef CONFIG_SMP + /* We don't do this for SMP - another cpu could have put in + the appropriate PTE since we took the exception. -- paulus. */ /* See whether it was a PTE not found exception or a protection violation. */ andis. r0,r20,0x4000 - li r2,8 /* PTEs/group */ bne 10f /* no PTE: go look for an empty slot */ +#endif /* CONFIG_SMP */ tlbie r3 /* invalidate TLB entry */ /* Search the primary PTEG for a PTE whose 1st dword matches r5 */ @@ -263,7 +274,6 @@ found_empty: std r5,0(r3) found_slot: std r6,8(r3) - sync #else /* CONFIG_SMP */ /* @@ -311,12 +321,16 @@ hash_page_patch_A: rlwimi r4,r5,32-1,26-Hash_bits,25 /* (VSID & hash_mask) << 6 */ rlwinm r0,r3,32-6,26-Hash_bits,25 /* (PI & hash_mask) << 6 */ xor r4,r4,r0 /* make primary hash */ + li r2,8 /* PTEs/group */ +#ifndef CONFIG_SMP + /* We don't do this for SMP - another cpu could have put in + the appropriate PTE since we took the exception. -- paulus. */ /* See whether it was a PTE not found exception or a protection violation. */ andis. r0,r20,0x4000 - li r2,8 /* PTEs/group */ bne 10f /* no PTE: go look for an empty slot */ +#endif /* CONFIG_SMP */ tlbie r3 /* invalidate TLB entry */ /* Search the primary PTEG for a PTE whose 1st word matches r5 */ @@ -394,7 +408,6 @@ found_empty: stw r5,0(r3) found_slot: stw r6,4(r3) - sync #else /* CONFIG_SMP */ /* @@ -428,6 +441,8 @@ found_slot: #endif /* CONFIG_SMP */ #endif /* CONFIG_PPC64BRIDGE */ + sync /* make sure pte updates get to memory */ + /* * Update the hash table miss count. We only want misses here * that _are_ valid addresses and have a pte otherwise we don't @@ -517,7 +532,7 @@ _GLOBAL(flush_hash_segments) a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -616,7 +631,7 @@ _GLOBAL(flush_hash_page) a hash table miss while we have the hash table locked, or we'll get a deadlock. -paulus */ mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -628,10 +643,14 @@ _GLOBAL(flush_hash_page) oris r8,r8,9 10: lwarx r7,0,r9 cmpi 0,r7,0 - bne- 10b + bne- 11f stwcx. r8,0,r9 - bne- 10b - eieio + beq+ 12f +11: lwz r7,0(r9) + cmpi 0,r7,0 + beq 10b + b 11b +12: eieio #endif #ifndef CONFIG_PPC64BRIDGE rlwinm r3,r3,11,1,20 /* put context into vsid */ diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 71b5a96c5cfc..f296d1606832 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -149,6 +149,8 @@ __start: mr r28,r6 mr r27,r7 li r24,0 /* cpu # */ + /* N.B. prom_init clears the BSS even if it doesn't do + * anything else -- paulus. */ bl prom_init #ifdef CONFIG_APUS @@ -159,7 +161,6 @@ __start: bl fix_mem_constants #endif /* CONFIG_APUS */ -#ifndef CONFIG_GEMINI /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by prom_init() */ @@ -167,7 +168,6 @@ __start: __after_mmu_off: bl clear_bats bl flush_tlbs -#endif #ifndef CONFIG_POWER4 /* POWER4 doesn't have BATs */ @@ -290,6 +290,7 @@ label: \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ bl transfer_to_handler; \ +i##n: \ .long hdlr; \ .long ret_from_except @@ -301,17 +302,13 @@ label: \ addi r3,r1,STACK_FRAME_OVERHEAD; \ li r20,MSR_KERNEL; \ bl transfer_to_handler; \ +i##n: \ .long hdlr; \ .long ret_from_except /* System reset */ -#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */ -#ifdef CONFIG_GEMINI - . = 0x100 - b __secondary_start_gemini -#else /* CONFIG_GEMINI */ +#ifdef CONFIG_SMP /* MVME/MTX start the secondary here */ STD_EXCEPTION(0x100, Reset, __secondary_start_psurge) -#endif /* CONFIG_GEMINI */ #else STD_EXCEPTION(0x100, Reset, UnknownException) #endif @@ -344,6 +341,7 @@ DataAccess: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x300: .long do_page_fault .long ret_from_except @@ -384,6 +382,7 @@ InstructionAccess: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x400: .long do_page_fault .long ret_from_except @@ -429,6 +428,7 @@ Alignment: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x600: .long AlignmentException .long ret_from_except @@ -441,6 +441,7 @@ ProgramCheck: li r20,MSR_KERNEL rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */ bl transfer_to_handler +i0x700: .long ProgramCheckException .long ret_from_except @@ -452,6 +453,7 @@ FPUnavailable: bne load_up_fpu /* if from user, just load it up */ li r20,MSR_KERNEL bl transfer_to_handler /* if from kernel, take a trap */ +i0x800: .long KernelFP .long ret_from_except @@ -575,7 +577,7 @@ InstructionAddressInvalid: mfmsr r0 /* Restore "normal" registers */ xoris r0,r0,MSR_TGPR>>16 mtcrf 0x80,r3 /* Restore CR0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 b InstructionAccess @@ -646,7 +648,7 @@ DataAddressInvalid: mfmsr r0 /* Restore "normal" registers */ xoris r0,r0,MSR_TGPR>>16 mtcrf 0x80,r3 /* Restore CR0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 b DataAccess @@ -843,7 +845,7 @@ load_up_fpu: #endif /* CONFIG_PPC64BRIDGE */ SYNC MTMSRD(r5) /* enable use of fpu now */ - SYNC + isync /* * For SMP, we don't do lazy FPU switching because it just gets too * horrendously complex, especially when a task switches from one CPU @@ -929,7 +931,7 @@ load_up_altivec: oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ - SYNC + isync /* * For SMP, we don't do lazy AltiVec switching because it just gets too * horrendously complex, especially when a task switches from one CPU @@ -1023,7 +1025,7 @@ giveup_altivec: oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ - SYNC + isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ @@ -1064,7 +1066,7 @@ giveup_fpu: ori r5,r5,MSR_FP SYNC mtmsr r5 /* enable use of fpu now */ - SYNC + isync cmpi 0,r3,0 beqlr- /* if no previous owner, done */ addi r3,r3,THREAD /* want THREAD of task */ @@ -1163,6 +1165,7 @@ fix_mem_constants: icbi r0,r14 /* flush the icache line */ cmpw r12,r13 bne 1b + isync /* * Map the memory where the exception handlers will @@ -1208,9 +1211,9 @@ apus_interrupt_entry: mfmsr 20 xori r20,r20,MSR_DR - sync + SYNC mtmsr r20 - sync + isync lis r4,APUS_IPL_EMU@h @@ -1243,9 +1246,9 @@ apus_interrupt_entry: mfmsr r20 xori r20,r20,MSR_DR - sync + SYNC mtmsr r20 - sync + isync stw r3,(_CCR+4)(r21); @@ -1263,28 +1266,24 @@ apus_interrupt_entry: #endif /* CONFIG_APUS */ #ifdef CONFIG_SMP -#ifdef CONFIG_GEMINI - .globl __secondary_start_gemini -__secondary_start_gemini: - mfspr r4,HID0 - ori r4,r4,HID0_ICFI - li r3,0 - ori r3,r3,HID0_ICE - andc r4,r4,r3 - mtspr HID0,r4 - sync - bl prom_init - b __secondary_start -#endif /* CONFIG_GEMINI */ - .globl __secondary_start_psurge __secondary_start_psurge: li r24,1 /* cpu # */ + b __secondary_start_psurge99 + .globl __secondary_start_psurge2 +__secondary_start_psurge2: + li r24,2 /* cpu # */ + b __secondary_start_psurge99 + .globl __secondary_start_psurge3 +__secondary_start_psurge3: + li r24,3 /* cpu # */ + b __secondary_start_psurge99 +__secondary_start_psurge99: /* we come in here with IR=0 and DR=1, and DBAT 0 set to map the 0xf0000000 - 0xffffffff region */ mfmsr r0 rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ - sync + SYNC mtmsr r0 isync @@ -1293,7 +1292,7 @@ __secondary_start: #ifdef CONFIG_PPC64BRIDGE mfmsr r0 clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - sync + SYNC MTMSRD(r0) isync #else @@ -1445,21 +1444,6 @@ start_here: li r3,0 mtspr SPRG2,r3 /* 0 => r1 has kernel sp */ - /* Clear out the BSS */ - lis r11,_end@ha - addi r11,r11,_end@l - lis r8,__bss_start@ha - addi r8,r8,__bss_start@l - subf r11,r8,r11 - addi r11,r11,3 - rlwinm. r11,r11,30,2,31 - beq 2f - addi r8,r8,-4 - mtctr r11 - li r0,0 -3: stwu r0,4(r8) - bdnz 3b -2: /* stack */ addi r1,r2,TASK_UNION_SIZE li r0,0 @@ -1504,7 +1488,7 @@ start_here: RFI /* Load up the kernel context */ 2: - SYNC /* Force all PTE updates to finish */ + sync /* Force all PTE updates to finish */ tlbia /* Clear all TLB entries */ sync /* wait for tlbia/tlbie to finish */ #ifdef CONFIG_SMP @@ -1552,7 +1536,6 @@ _GLOBAL(set_context) * -- Cort */ clear_bats: -#if !defined(CONFIG_GEMINI) li r20,0 mfspr r9,PVR rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */ @@ -1576,10 +1559,8 @@ clear_bats: mtspr IBAT2L,r20 mtspr IBAT3U,r20 mtspr IBAT3L,r20 -#endif /* !defined(CONFIG_GEMINI) */ blr -#ifndef CONFIG_GEMINI flush_tlbs: lis r20, 0x40 1: addic. r20, r20, -0x1000 @@ -1598,7 +1579,6 @@ mmu_off: mtspr SRR1,r3 sync RFI -#endif #ifndef CONFIG_POWER4 /* @@ -1745,3 +1725,12 @@ swapper_pg_dir: .globl cmd_line cmd_line: .space 512 + + .globl intercept_table +intercept_table: + .long 0, i0x100, i0x200, i0x300, i0x400, 0, i0x600, i0x700 + .long i0x800, 0, 0, 0, 0, i0xd00, 0, 0 + .long 0, 0, 0, i0x1300, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 + .long 0, 0, 0, 0, 0, 0, 0, 0 diff --git a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c index bdb6ec84430d..7690d909130e 100644 --- a/arch/ppc/kernel/i8259.c +++ b/arch/ppc/kernel/i8259.c @@ -10,12 +10,15 @@ unsigned char cached_8259[2] = { 0xff, 0xff }; #define cached_A1 (cached_8259[0]) #define cached_21 (cached_8259[1]) +spinlock_t i8259_lock = SPIN_LOCK_UNLOCKED; + int i8259_pic_irq_offset; int i8259_irq(int cpu) { int irq; + spin_lock/*_irqsave*/(&i8259_lock/*, flags*/); /* * Perform an interrupt acknowledge cycle on controller 1 */ @@ -40,14 +43,20 @@ int i8259_irq(int cpu) * interrupt */ outb(0x0b, 0x20); - if(~inb(0x20)&0x80) + if(~inb(0x20)&0x80) { + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); return -1; + } } + spin_unlock/*_irqrestore*/(&i8259_lock/*, flags*/); return irq; } static void i8259_mask_and_ack_irq(unsigned int irq_nr) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; @@ -63,6 +72,7 @@ static void i8259_mask_and_ack_irq(unsigned int irq_nr) outb(cached_21,0x21); outb(0x20,0x20); /* Non-specific EOI */ } + spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_set_irq_mask(int irq_nr) @@ -73,6 +83,9 @@ static void i8259_set_irq_mask(int irq_nr) static void i8259_mask_irq(unsigned int irq_nr) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) @@ -80,11 +93,14 @@ static void i8259_mask_irq(unsigned int irq_nr) else cached_A1 |= 1 << (irq_nr-8); i8259_set_irq_mask(irq_nr); + spin_unlock_irqrestore(&i8259_lock, flags); } static void i8259_unmask_irq(unsigned int irq_nr) { + unsigned long flags; + spin_lock_irqsave(&i8259_lock, flags); if ( irq_nr >= i8259_pic_irq_offset ) irq_nr -= i8259_pic_irq_offset; if ( irq_nr < 8 ) @@ -92,6 +108,13 @@ static void i8259_unmask_irq(unsigned int irq_nr) else cached_A1 &= ~(1 << (irq_nr-8)); i8259_set_irq_mask(irq_nr); + spin_unlock_irqrestore(&i8259_lock, flags); +} + +static void i8259_end_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + i8259_unmask_irq(irq); } struct hw_interrupt_type i8259_pic = { @@ -101,11 +124,15 @@ struct hw_interrupt_type i8259_pic = { i8259_unmask_irq, i8259_mask_irq, i8259_mask_and_ack_irq, - 0 + i8259_end_irq, + NULL }; void __init i8259_init(void) { + unsigned long flags; + + spin_lock_irqsave(&i8259_lock, flags); /* init master interrupt controller */ outb(0x11, 0x20); /* Start init sequence */ outb(0x00, 0x21); /* Vector base */ @@ -120,7 +147,7 @@ void __init i8259_init(void) outb(0xFF, 0xA1); /* Mask all */ outb(cached_A1, 0xA1); outb(cached_21, 0x21); + spin_unlock_irqrestore(&i8259_lock, flags); request_irq( i8259_pic_irq_offset + 2, no_action, SA_INTERRUPT, "82c59 secondary cascade", NULL ); - enable_irq(i8259_pic_irq_offset + 2); /* Enable cascade interrupt */ } diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c index a363a0e34720..6ca61697957b 100644 --- a/arch/ppc/kernel/idle.c +++ b/arch/ppc/kernel/idle.c @@ -47,24 +47,35 @@ atomic_t zeropage_calls; /* # zero'd pages request that've been made */ int idled(void) { + int do_power_save = 0; + + /* only sleep on the 603-family/750 processors */ + switch (_get_PVR() >> 16) { + case 3: /* 603 */ + case 6: /* 603e */ + case 7: /* 603ev */ + case 8: /* 750 */ + case 12: /* 7400 */ + do_power_save = 1; + } + /* endless loop with no priority at all */ current->nice = 20; current->counter = -100; init_idle(); for (;;) { - __sti(); - - check_pgt_cache(); - - /*if ( !current->need_resched && zero_paged_on ) zero_paged();*/ - if ( !current->need_resched && htab_reclaim_on ) htab_reclaim(); - if ( !current->need_resched ) power_save(); + /*if ( !current->need_resched && zero_paged_on ) + zero_paged();*/ + if (!current->need_resched && htab_reclaim_on) + htab_reclaim(); + if (do_power_save && !current->need_resched) + power_save(); -#ifdef CONFIG_SMP - if (current->need_resched) -#endif + if (current->need_resched) { schedule(); + check_pgt_cache(); + } } return 0; } @@ -278,31 +289,31 @@ void zero_paged(void) void power_save(void) { - unsigned long msr, hid0; - - /* only sleep on the 603-family/750 processors */ - switch (_get_PVR() >> 16) { - case 3: /* 603 */ - case 6: /* 603e */ - case 7: /* 603ev */ - case 8: /* 750 */ - case 12: /* 7400 */ - save_flags(msr); - __cli(); - if (!current->need_resched) { - asm("mfspr %0,1008" : "=r" (hid0) :); - hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE); - hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM; - asm("mtspr 1008,%0" : : "r" (hid0)); + unsigned long hid0; + /* + * Disable interrupts to prevent a lost wakeup + * when going to sleep. This is necessary even with + * RTLinux since we are not guaranteed an interrupt + * didn't come in and is waiting for a __sti() before + * emulating one. This way, we really do hard disable. + * + * We assume that we're sti-ed when we come in here. We + * are in the idle loop so if we're cli-ed then it's a bug + * anyway. + * -- Cort + */ + _nmask_and_or_msr(MSR_EE, 0); + if (!current->need_resched) + { + asm("mfspr %0,1008" : "=r" (hid0) :); + hid0 &= ~(HID0_NAP | HID0_SLEEP | HID0_DOZE); + hid0 |= (powersave_nap? HID0_NAP: HID0_DOZE) | HID0_DPM; + asm("mtspr 1008,%0" : : "r" (hid0)); - /* set the POW bit in the MSR, and enable interrupts - * so we wake up sometime! */ - __sti(); /* this keeps rtl from getting confused -- Cort */ - _nmask_and_or_msr(0, MSR_POW | MSR_EE); - } - restore_flags(msr); - default: - return; + /* set the POW bit in the MSR, and enable interrupts + * so we wake up sometime! */ + _nmask_and_or_msr(0, MSR_POW | MSR_EE); } + _nmask_and_or_msr(0, MSR_EE); } diff --git a/arch/ppc/kernel/indirect_pci.c b/arch/ppc/kernel/indirect_pci.c index 552c552dc8d4..3ba335d1f5b7 100644 --- a/arch/ppc/kernel/indirect_pci.c +++ b/arch/ppc/kernel/indirect_pci.c @@ -9,113 +9,59 @@ * 2 of the License, or (at your option) any later version. */ +#include <linux/kernel.h> #include <linux/pci.h> -#include <asm/io.h> -#include <asm/system.h> - -unsigned int * pci_config_address; -unsigned char * pci_config_data; - -int indirect_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned long flags; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); +#include <linux/delay.h> +#include <linux/string.h> +#include <linux/init.h> +#include <linux/bootmem.h> - *val= in_8(pci_config_data + (offset&3)); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; +#include <asm/init.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/pci-bridge.h> +#include <asm/machdep.h> + +#include "pci.h" + +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define INDIRECT_PCI_OP(rw, size, type, op, mask) \ +static int \ +indirect_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + \ + out_be32(hose->cfg_addr, \ + ((offset & 0xfc) << 24) | (dev->devfn << 16) \ + | (dev->bus->number << 8) | 0x80); \ + cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -int indirect_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned long flags; - - if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); +INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3) +INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2) +INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0) +INDIRECT_PCI_OP(write, byte, u8, out_8, 3) +INDIRECT_PCI_OP(write, word, u16, out_le16, 2) +INDIRECT_PCI_OP(write, dword, u32, out_le32, 0) - *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static struct pci_ops indirect_pci_ops = { - unsigned long flags; - - if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - *val= in_le32((unsigned *)pci_config_data); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) + indirect_read_config_byte, + indirect_read_config_word, + indirect_read_config_dword, + indirect_write_config_byte, + indirect_write_config_word, + indirect_write_config_dword +}; + +void __init +setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) { - unsigned long flags; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_8(pci_config_data + (offset&3), val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} - -int indirect_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned long flags; - - if (offset&1) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_le16((unsigned short *)(pci_config_data + (offset&3)), val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; + hose->ops = &indirect_pci_ops; + hose->cfg_addr = (unsigned int *) ioremap(cfg_addr, 4); + hose->cfg_data = (unsigned char *) ioremap(cfg_data, 4); } -int indirect_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned long flags; - - if (offset&3) return PCIBIOS_BAD_REGISTER_NUMBER; - - save_flags(flags); cli(); - - out_be32(pci_config_address, - ((offset&0xfc)<<24) | (dev_fn<<16) | (bus<<8) | 0x80); - - out_le32((unsigned *)pci_config_data, val); - - restore_flags(flags); - return PCIBIOS_SUCCESSFUL; -} diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index a0caa4a4c9ec..02ff4d964ad0 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -41,11 +41,11 @@ #include <linux/config.h> #include <linux/init.h> #include <linux/malloc.h> -#include <linux/openpic.h> #include <linux/pci.h> #include <linux/delay.h> #include <linux/irq.h> #include <linux/proc_fs.h> +#include <linux/random.h> #include <asm/uaccess.h> #include <asm/bitops.h> @@ -64,19 +64,22 @@ #include "local_irq.h" -extern volatile unsigned long ipi_count; +atomic_t ipi_recv; +atomic_t ipi_sent; void enable_irq(unsigned int irq_nr); void disable_irq(unsigned int irq_nr); -volatile unsigned char *chrp_int_ack_special; +static void register_irq_proc (unsigned int irq); #define MAXCOUNT 10000000 -irq_desc_t irq_desc[NR_IRQS]; +irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = + { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; + int ppc_spurious_interrupts = 0; struct irqaction *ppc_irq_action[NR_IRQS]; -unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; -unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; +unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; atomic_t ppc_n_lost_interrupts; /* nasty hack for shared irq's since we need to do kmalloc calls but @@ -115,52 +118,136 @@ void irq_kfree(void *ptr) kfree(ptr); } +int +setup_irq(unsigned int irq, struct irqaction * new) +{ + int shared = 0; + unsigned long flags; + struct irqaction *old, **p; + irq_desc_t *desc = irq_desc + irq; + + /* + * Some drivers like serial.c use request_irq() heavily, + * so we have to be careful not to interfere with a + * running system. + */ + if (new->flags & SA_SAMPLE_RANDOM) { + /* + * This function might sleep, we want to call it first, + * outside of the atomic block. + * Yes, this might clear the entropy pool if the wrong + * driver is attempted to be loaded, without actually + * installing a new handler, but is this really a problem, + * only the sysadmin is able to do this. + */ + rand_initialize_irq(irq); + } + + /* + * The following block of code has to be executed atomically + */ + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + if ((old = *p) != NULL) { + /* Can't share interrupts unless both agree to */ + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&desc->lock,flags); + return -EBUSY; + } + + /* add new interrupt at end of irq queue */ + do { + p = &old->next; + old = *p; + } while (old); + shared = 1; + } + + *p = new; + + if (!shared) { + desc->depth = 0; + desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING); + unmask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + + register_irq_proc(irq); + return 0; +} + +/* This could be promoted to a real free_irq() ... */ +static int +do_free_irq(int irq, void* dev_id) +{ + irq_desc_t *desc; + struct irqaction **p; + unsigned long flags; + + desc = irq_desc + irq; + spin_lock_irqsave(&desc->lock,flags); + p = &desc->action; + for (;;) { + struct irqaction * action = *p; + if (action) { + struct irqaction **pp = p; + p = &action->next; + if (action->dev_id != dev_id) + continue; + + /* Found it - now remove it from the list of entries */ + *pp = action->next; + if (!desc->action) { + desc->status |= IRQ_DISABLED; + mask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock,flags); + +#ifdef CONFIG_SMP + /* Wait to make sure it's not being used on another CPU */ + while (desc->status & IRQ_INPROGRESS) + barrier(); +#endif + irq_kfree(action); + return 0; + } + printk("Trying to free free IRQ%d\n",irq); + spin_unlock_irqrestore(&desc->lock,flags); + break; + } + return -ENOENT; +} + #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) /* Name change so we can catch standard drivers that potentially mess up * the internal interrupt controller on 8xx and 8260. Just bear with me, * I don't like this either and I am searching a better solution. For * now, this is what I need. -- Dan */ -int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +#define request_irq request_8xxirq #elif defined(CONFIG_APUS) -int request_sysirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), -#else -int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), +#define request_irq request_sysirq +#define free_irq sys_free_irq #endif + +int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long irqflags, const char * devname, void *dev_id) { - struct irqaction *old, **p, *action; - unsigned long flags; + struct irqaction *action; + int retval; if (irq >= NR_IRQS) return -EINVAL; if (!handler) - { - /* Free */ - p = &irq_desc[irq].action; - while ((action = *p) != NULL && action->dev_id != dev_id) - p = &action->next; - if (action == NULL) - return -ENOENT; - - /* Found it - now free it */ - save_flags(flags); - cli(); - *p = action->next; - if (irq_desc[irq].action == NULL) - disable_irq(irq); - restore_flags(flags); - irq_kfree(action); - return 0; - } + /* We could implement really free_irq() instead of that... */ + return do_free_irq(irq, dev_id); action = (struct irqaction *) irq_kmalloc(sizeof(struct irqaction), GFP_KERNEL); - if (!action) + if (!action) { + printk(KERN_ERR "irq_kmalloc() failed for irq %d !\n", irq); return -ENOMEM; - - save_flags(flags); - cli(); + } action->handler = handler; action->flags = irqflags; @@ -168,57 +255,109 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) action->name = devname; action->dev_id = dev_id; action->next = NULL; - enable_irq(irq); - p = &irq_desc[irq].action; - - if ((old = *p) != NULL) { - /* Can't share interrupts unless both agree to */ - if (!(old->flags & action->flags & SA_SHIRQ)) - return -EBUSY; - /* add new interrupt at end of irq queue */ - do { - p = &old->next; - old = *p; - } while (old); - } - *p = action; - - restore_flags(flags); + retval = setup_irq(irq, action); + if (retval) + kfree(action); + return 0; } -#ifdef CONFIG_APUS -void sys_free_irq(unsigned int irq, void *dev_id) -{ - sys_request_irq(irq, NULL, 0, NULL, dev_id); -} -#else void free_irq(unsigned int irq, void *dev_id) { -#if (defined(CONFIG_8xx) || defined(CONFIG_8260)) - request_8xxirq(irq, NULL, 0, NULL, dev_id); -#else request_irq(irq, NULL, 0, NULL, dev_id); -#endif } -#endif -/* XXX should implement irq disable depth like on intel */ -void disable_irq_nosync(unsigned int irq_nr) +/* + * Generic enable/disable code: this just calls + * down into the PIC-specific version for the actual + * hardware disable after having gotten the irq + * controller lock. + */ + +/** + * disable_irq_nosync - disable an irq without waiting + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. Unlike disable_irq(), this function does not ensure existing + * instances of the IRQ handler have completed before returning. + * + * This function may be called from IRQ context. + */ + + void disable_irq_nosync(unsigned int irq) { - mask_irq(irq_nr); + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + if (!desc->depth++) { + if (!(desc->status & IRQ_PER_CPU)) + desc->status |= IRQ_DISABLED; + mask_irq(irq); + } + spin_unlock_irqrestore(&desc->lock, flags); } -void disable_irq(unsigned int irq_nr) +/** + * disable_irq - disable an irq and wait for completion + * @irq: Interrupt to disable + * + * Disable the selected interrupt line. Disables of an interrupt + * stack. That is for two disables you need two enables. This + * function waits for any pending IRQ handlers for this interrupt + * to complete before returning. If you use this function while + * holding a resource the IRQ handler may need you will deadlock. + * + * This function may be called - with care - from IRQ context. + */ + +void disable_irq(unsigned int irq) { - mask_irq(irq_nr); - synchronize_irq(); + disable_irq_nosync(irq); + + if (!local_irq_count(smp_processor_id())) { + do { + barrier(); + } while (irq_desc[irq].status & IRQ_INPROGRESS); + } } -void enable_irq(unsigned int irq_nr) +/** + * enable_irq - enable interrupt handling on an irq + * @irq: Interrupt to enable + * + * Re-enables the processing of interrupts on this IRQ line + * providing no disable_irq calls are now in effect. + * + * This function may be called from IRQ context. + */ + +void enable_irq(unsigned int irq) { - unmask_irq(irq_nr); + irq_desc_t *desc = irq_desc + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock, flags); + switch (desc->depth) { + case 1: { + unsigned int status = desc->status & ~IRQ_DISABLED; + desc->status = status; + if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { + desc->status = status | IRQ_REPLAY; + hw_resend_irq(desc->handler,irq); + } + unmask_irq(irq); + /* fall-through */ + } + default: + desc->depth--; + break; + case 0: + printk("enable_irq(%u) unbalanced\n", irq); + } + spin_unlock_irqrestore(&desc->lock, flags); } int get_irq_list(char *buf) @@ -257,15 +396,41 @@ int get_irq_list(char *buf) } len += sprintf(buf+len, "\n"); } +#ifdef CONFIG_TAU + len += sprintf(buf+len, "TAU: "); + for (j = 0; j < smp_num_cpus; j++) + len += sprintf(buf+len, "%10u ", + tau_interrupts(j)); + len += sprintf(buf+len, "\n"); +#endif #ifdef CONFIG_SMP /* should this be per processor send/receive? */ - len += sprintf(buf+len, "IPI: %10lu\n", ipi_count); + len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", + atomic_read(&ipi_recv), atomic_read(&ipi_sent)); #endif len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); return len; #endif /* CONFIG_APUS */ } +static inline void +handle_irq_event(int irq, struct pt_regs *regs, struct irqaction *action) +{ + int status = 0; + + if (!(action->flags & SA_INTERRUPT)) + __sti(); + + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + __cli(); +} + /* * Eventually, this should take an array of interrupts and an array size * so it can dispatch multiple interrupts. @@ -275,33 +440,87 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq) int status; struct irqaction *action; int cpu = smp_processor_id(); + irq_desc_t *desc = irq_desc + irq; - mask_and_ack_irq(irq); - status = 0; - action = irq_desc[irq].action; kstat.irqs[cpu][irq]++; - if (action && action->handler) { - if (!(action->flags & SA_INTERRUPT)) - __sti(); - do { - status |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while ( action ); - __cli(); - if (irq_desc[irq].handler) { - if (irq_desc[irq].handler->end) - irq_desc[irq].handler->end(irq); - else if (irq_desc[irq].handler->enable) - irq_desc[irq].handler->enable(irq); + spin_lock(&desc->lock); + ack_irq(irq); + /* + REPLAY is when Linux resends an IRQ that was dropped earlier + WAITING is used by probe to mark irqs that are being tested + */ + status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); + if (!(status & IRQ_PER_CPU)) + status |= IRQ_PENDING; /* we _want_ to handle it */ + + /* + * If the IRQ is disabled for whatever reason, we cannot + * use the action we have. + */ + action = NULL; + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { + action = desc->action; + if (!action || !action->handler) { + ppc_spurious_interrupts++; + printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); + /* We can't call disable_irq here, it would deadlock */ + if (!desc->depth) + desc->depth = 1; + desc->status |= IRQ_DISABLED; + /* This is not a real spurrious interrupt, we + * have to eoi it, so we jump to out + */ + mask_irq(irq); + goto out; } - } else { - ppc_spurious_interrupts++; - printk(KERN_DEBUG "Unhandled interrupt %x, disabled\n", irq); - disable_irq(irq); + status &= ~IRQ_PENDING; /* we commit to handling */ + if (!(status & IRQ_PER_CPU)) + status |= IRQ_INPROGRESS; /* we are handling it */ + } + desc->status = status; + + /* + * If there is no IRQ handler or it was disabled, exit early. + Since we set PENDING, if another processor is handling + a different instance of this same irq, the other processor + will take care of it. + */ + if (!action) + goto out; + + + /* + * Edge triggered interrupts need to remember + * pending events. + * This applies to any hw interrupts that allow a second + * instance of the same irq to arrive while we are in do_IRQ + * or in the handler. But the code here only handles the _second_ + * instance of the irq, not the third or fourth. So it is mostly + * useful for irq hardware that does not mask cleanly in an + * SMP environment. + */ + for (;;) { + spin_unlock(&desc->lock); + handle_irq_event(irq, regs, action); + spin_lock(&desc->lock); + + if (!(desc->status & IRQ_PENDING)) + break; + desc->status &= ~IRQ_PENDING; + } + desc->status &= ~IRQ_INPROGRESS; +out: + /* + * The ->end() handler has to deal with interrupts which got + * disabled while the handler was running. + */ + if (irq_desc[irq].handler) { if (irq_desc[irq].handler->end) irq_desc[irq].handler->end(irq); + else if (irq_desc[irq].handler->enable) + irq_desc[irq].handler->enable(irq); } + spin_unlock(&desc->lock); } int do_IRQ(struct pt_regs *regs, int isfake) @@ -320,6 +539,7 @@ int do_IRQ(struct pt_regs *regs, int isfake) { printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", irq, regs->nip); + /* That's not SMP safe ... but who cares ? */ ppc_spurious_interrupts++; } goto out; @@ -362,7 +582,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SMP unsigned char global_irq_holder = NO_PROC_ID; -unsigned volatile int global_irq_lock; +unsigned volatile long global_irq_lock; /* pendantic :long for set_bit--RR*/ atomic_t global_irq_count; atomic_t global_bh_count; @@ -634,7 +854,11 @@ static struct proc_dir_entry * root_irq_dir; static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; +#ifdef CONFIG_IRQ_ALL_CPUS unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff}; +#else /* CONFIG_IRQ_ALL_CPUS */ +unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000}; +#endif /* CONFIG_IRQ_ALL_CPUS */ #define HEX_DIGITS 8 @@ -694,6 +918,7 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, err = parse_hex_value(buffer, count, &new_value); +/* Why is this disabled ? --BenH */ #if 0/*CONFIG_SMP*/ /* * Do not allow disabling IRQs completely - it's a too easy diff --git a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h index 5c616bbbdbbc..319e3377c08c 100644 --- a/arch/ppc/kernel/local_irq.h +++ b/arch/ppc/kernel/local_irq.h @@ -15,8 +15,5 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq); extern int ppc_spurious_interrupts; extern int ppc_second_irq; extern struct irqaction *ppc_irq_action[NR_IRQS]; -extern unsigned int ppc_cached_irq_mask[NR_MASK_WORDS]; -extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; -extern atomic_t ppc_n_lost_interrupts; #endif /* _PPC_KERNEL_LOCAL_IRQ_H */ diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c index 6e006a8677f5..a55f5235dc56 100644 --- a/arch/ppc/kernel/m8260_setup.c +++ b/arch/ppc/kernel/m8260_setup.c @@ -62,7 +62,7 @@ extern void mackbd_leds(unsigned char leds); extern void mackbd_init_hw(void); #endif -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; unsigned char __res[sizeof(bd_t)]; unsigned long empty_zero_page[1024]; @@ -286,10 +286,7 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.outsw = m8xx_ide_outsw; ppc_ide_md.default_irq = m8xx_ide_default_irq; ppc_ide_md.default_io_base = m8xx_ide_default_io_base; - ppc_ide_md.check_region = m8xx_ide_check_region; - ppc_ide_md.request_region = m8xx_ide_request_region; - ppc_ide_md.release_region = m8xx_ide_release_region; - ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; @@ -297,13 +294,39 @@ m8260_init(unsigned long r3, unsigned long r4, unsigned long r5, #endif } -void +/* + * Copied from prom.c so I don't have include all of that crap. + * -- Dan + * + * prom_init() is called very early on, before the kernel text + * and data have been mapped to KERNELBASE. At this point the code + * is running at whatever address it has been loaded at, so + * references to extern and static variables must be relocated + * explicitly. The procedure reloc_offset() returns the address + * we're currently running at minus the address we were linked at. + * (Note that strings count as static variables.) + */ +extern unsigned long reloc_offset(void); +#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) + +__init +unsigned long prom_init(uint r3, uint r4, uint r5, uint r6) { - /* Nothing to do now, but we are called immediatedly upon - * kernel start up with MMU disabled, so if there is - * anything we need to do...... - */ + unsigned long offset = reloc_offset(); + unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS -- use memset, some arches don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); + + /* Default */ + phys = offset + KERNELBASE; + + /* We are done. + */ + return phys; } /* Mainly for ksyms. diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c index 7dc408a13116..f9813fa75137 100644 --- a/arch/ppc/kernel/m8xx_setup.c +++ b/arch/ppc/kernel/m8xx_setup.c @@ -63,8 +63,6 @@ extern void mackbd_leds(unsigned char leds); extern void mackbd_init_hw(void); #endif -extern unsigned long loops_per_sec; - unsigned char __res[sizeof(bd_t)]; unsigned long empty_zero_page[1024]; @@ -344,25 +342,6 @@ m8xx_ide_default_io_base(int index) } int -m8xx_ide_check_region(ide_ioreg_t from, unsigned int extent) -{ - return 0; -} - -void -m8xx_ide_request_region(ide_ioreg_t from, - unsigned int extent, - const char *name) -{ -} - -void -m8xx_ide_release_region(ide_ioreg_t from, - unsigned int extent) -{ -} - -int m8xx_ide_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *), unsigned long flags, @@ -376,12 +355,6 @@ m8xx_ide_request_irq(unsigned int irq, #endif } -void -m8xx_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); -} - /* We can use an external IDE controller or wire the IDE interface to * the internal PCMCIA controller. */ @@ -515,10 +488,7 @@ m8xx_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.outsw = m8xx_ide_outsw; ppc_ide_md.default_irq = m8xx_ide_default_irq; ppc_ide_md.default_io_base = m8xx_ide_default_io_base; - ppc_ide_md.check_region = m8xx_ide_check_region; - ppc_ide_md.request_region = m8xx_ide_request_region; - ppc_ide_md.release_region = m8xx_ide_release_region; - ppc_ide_md.fix_driveid = m8xx_ide_fix_driveid; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.ide_init_hwif = m8xx_ide_init_hwif_ports; ppc_ide_md.ide_request_irq = m8xx_ide_request_irq; diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 94e1cd277ddf..3f54003c7182 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -37,6 +37,14 @@ .text + .align 5 +_GLOBAL(__delay) + cmpwi 0,r3,0 + mtctr r3 + beqlr +1: bdnz 1b + blr + /* * Returns (address we're running at) - (address we were linked at) * for use before the text and data are mapped to KERNELBASE. @@ -82,16 +90,16 @@ _GLOBAL(__no_use_restore_flags) lwz r7,ppc_n_lost_interrupts@l(r7) cmpi 0,r7,0 /* lost interrupts to process first? */ bne- do_lost_interrupts -1: sync +1: SYNC mtmsr r3 - isync + SYNC blr _GLOBAL(__no_use_cli) mfmsr r0 /* Get current interrupt state */ rlwinm r3,r0,16+1,32-1,31 /* Extract old value of 'EE' */ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ blr /* Done */ @@ -102,7 +110,7 @@ _GLOBAL(__no_use_sti) ori r3,r3,MSR_EE /* Turn on 'EE' bit */ cmpi 0,r4,0 /* lost interrupts to process first? */ bne- do_lost_interrupts - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r3 /* Update machine state */ blr @@ -121,7 +129,7 @@ _GLOBAL(do_lost_interrupts) cmpi 0,r4,0 bne- 1b lwz r3,8(r1) - sync + SYNC mtmsr r3 lwz r0,20(r1) mtlr r0 @@ -137,8 +145,9 @@ _GLOBAL(do_lost_interrupts) mfmsr r0 /* Get current msr */ andc r0,r0,r3 /* And off the bits set in r3 (first parm) */ or r0,r0,r4 /* Or on the bits in r4 (second parm) */ - sync /* Some chip revs have problems here... */ + SYNC /* Some chip revs have problems here... */ mtmsr r0 /* Update machine state */ + isync blr /* Done */ @@ -148,7 +157,7 @@ _GLOBAL(do_lost_interrupts) _GLOBAL(_tlbia) #if defined(CONFIG_SMP) mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -161,7 +170,6 @@ _GLOBAL(_tlbia) bne- 10b stwcx. r8,0,r9 bne- 10b - eieio #endif /* CONFIG_SMP */ sync tlbia @@ -182,7 +190,7 @@ _GLOBAL(_tlbia) _GLOBAL(_tlbie) #if defined(CONFIG_SMP) mfmsr r10 - sync + SYNC rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ mtmsr r0 SYNC @@ -228,7 +236,7 @@ _GLOBAL(flush_instruction_cache) ori r3,r3,HID0_ICFI mtspr HID0,r3 #endif /* CONFIG_8xx */ - SYNC + isync blr /* @@ -259,7 +267,6 @@ _GLOBAL(flush_icache_range) 2: icbi 0,r6 addi r6,r6,CACHE_LINE_SIZE bdnz 2b - sync isync blr @@ -717,6 +724,8 @@ _GLOBAL(_get_SP) mr r3,r1 /* Close enough */ blr +#if 0 +/* isn't it just easier to use the mtspr/mfspr inline macros?? --Troy */ _GLOBAL(_get_THRM1) mfspr r3,THRM1 blr @@ -740,6 +749,7 @@ _GLOBAL(_set_THRM2) _GLOBAL(_set_THRM3) mtspr THRM3,r3 blr +#endif _GLOBAL(_get_PVR) mfspr r3,PVR @@ -755,6 +765,12 @@ _GLOBAL(_get_HID0) mfspr r3,HID0 blr +_GLOBAL(_set_HID0) + sync + mtspr HID0, r3 + SYNC /* Handle erratas in some cases */ + blr + _GLOBAL(_get_ICTC) mfspr r3,ICTC blr @@ -763,7 +779,6 @@ _GLOBAL(_set_ICTC) mtspr ICTC,r3 blr - /* L2CR functions Copyright © 1997-1998 by PowerLogix R & D, Inc. @@ -785,6 +800,17 @@ _GLOBAL(_set_ICTC) /* Thur, Dec. 12, 1998. - First public release, contributed by PowerLogix. + *********** + Sat, Aug. 7, 1999. + - Terry: Made sure code disabled interrupts before running. (Previously + it was assumed interrupts were already disabled). + - Terry: Updated for tentative G4 support. 4MB of memory is now flushed + instead of 2MB. (Prob. only 3 is necessary). + - Terry: Updated for workaround to HID0[DPM] processor bug + during global invalidates. + *********** + Thu, July 13, 2000. + - Terry: Added isync to correct for an errata. Author: Terry Greeniaus (tgree@phys.ualberta.ca) Please e-mail updates to this file to me, thanks! @@ -823,82 +849,94 @@ _GLOBAL(_set_ICTC) causes cache pushes from the L1 cache to go to the L2 cache instead of to main memory. */ - +/* + * Summary: this procedure ignores the L2I bit in the value passed in, + * flushes the cache if it was already enabled, always invalidates the + * cache, then enables the cache if the L2E bit is set in the value + * passed in. + * -- paulus. + */ _GLOBAL(_set_L2CR) - /* Make sure this is a 750 chip */ + /* Make sure this is a 750 or 7400 chip */ mfspr r4,PVR rlwinm r4,r4,16,16,31 - cmplwi r4,0x0008 - beq thisIs750 - cmplwi r4,0x000c - beq thisIs750 - li r3,-1 - blr - -thisIs750: - /* Get the current enable bit of the L2CR into r4 */ - mfspr r4,L2CR - mfmsr r7 - - /* See if we want to perform a global inval this time. */ - rlwinm r6,r3,0,10,10 /* r6 contains the new invalidate bit */ - rlwinm. r5,r3,0,0,0 /* r5 contains the new enable bit */ - rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ - rlwimi r3,r4,0,0,0 /* Keep the enable bit the same as it was. */ - bne dontDisableCache /* Only disable the cache if L2CRApply - has the enable bit off */ - -disableCache: - /* Disable the cache. First, we turn off interrupts. - An interrupt while we are flushing the cache could bring - in data which may not get properly flushed. */ - rlwinm r4,r7,0,17,15 /* Turn off EE bit */ + cmpwi r4,0x0008 + cmpwi cr1,r4,0x000c + cror 2,2,4*cr1+2 + bne 99f + + /* Turn off interrupts and data relocation. */ + mfmsr r7 /* Save MSR in r7 */ + rlwinm r4,r7,0,17,15 + rlwinm r4,r4,0,28,26 /* Turn off DR bit */ sync mtmsr r4 - sync + isync + + /* Get the current enable bit of the L2CR into r4 */ + mfspr r4,L2CR -/* - Now, read the first 2MB of memory to put new data in the cache. - (Actually we only need the size of the L2 cache plus the size - of the L1 cache, but 2MB will cover everything just to be safe). -*/ - lis r4,0x0001 + /* Tweak some bits */ + rlwinm r5,r3,0,0,0 /* r5 contains the new enable bit */ + rlwinm r3,r3,0,11,9 /* Turn off the invalidate bit */ + rlwinm r3,r3,0,1,31 /* Turn off the enable bit */ + + /* Check to see if we need to flush */ + rlwinm. r4,r4,0,0,0 + beq 2f + + /* Flush the cache. First, read the first 4MB of memory (physical) to + * put new data in the cache. (Actually we only need + * the size of the L2 cache plus the size of the L1 cache, but 4MB will + * cover everything just to be safe). + */ + + /**** Might be a good idea to set L2DO here - to prevent instructions + from getting into the cache. But since we invalidate + the next time we enable the cache it doesn't really matter. + ****/ + + lis r4,0x0002 mtctr r4 - lis r4,KERNELBASE@h -1: lwzx r0,r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ + li r4,0 +1: + lwzx r0,r0,r4 + addi r4,r4,32 /* Go to start of next cache line */ bdnz 1b - /* Now, flush the first 2MB of memory */ - lis r4,0x0001 + /* Now, flush the first 4MB of memory */ + lis r4,0x0002 mtctr r4 - lis r4,KERNELBASE@h + li r4,0 sync -2: dcbf r0,r4 - addi r4,r4,0x0020 /* Go to start of next cache line */ - bdnz 2b - - /* Turn off the L2CR enable bit. */ - rlwinm r3,r3,0,1,31 - -dontDisableCache: - /* Set up the L2CR configuration bits */ +1: + dcbf r0,r4 + addi r4,r4,32 /* Go to start of next cache line */ + bdnz 1b + +2: + /* Set up the L2CR configuration bits (and switch L2 off) */ sync mtspr L2CR,r3 sync - /* Reenable interrupts if necessary. */ - mtmsr r7 + /* Before we perform the global invalidation, we must disable dynamic + * power management via HID0[DPM] to work around a processor bug where + * DPM can possibly interfere with the state machine in the processor + * that invalidates the L2 cache tags. + */ + mfspr r8,HID0 /* Save HID0 in r8 */ + rlwinm r4,r8,0,12,10 /* Turn off HID0[DPM] */ sync - - cmplwi r6,0 - beq noInval - + mtspr HID0,r4 /* Disable DPM */ + sync + /* Perform a global invalidation */ oris r3,r3,0x0020 sync mtspr L2CR,r3 sync + isync /* For errata */ /* Wait for the invalidation to complete */ 3: mfspr r3,L2CR @@ -910,27 +948,38 @@ dontDisableCache: mtspr L2CR,r3 sync -noInval: + /* Restore HID0[DPM] to whatever it was before */ + sync + mtspr 1008,r8 + sync + /* See if we need to enable the cache */ cmplwi r5,0 - beqlr + beq 4f /* Enable the cache */ oris r3,r3,0x8000 mtspr L2CR,r3 sync + + /* Restore MSR (restores EE and DR bits to original state) */ +4: SYNC + mtmsr r7 + isync + blr + +99: li r3,-1 blr _GLOBAL(_get_L2CR) /* Make sure this is a 750 chip */ mfspr r3,PVR - rlwinm r3,r3,16,16,31 - cmplwi r3,0x0008 - beq 1f - cmplwi r3,0x000c + srwi r3,r3,16 + cmpwi r3,0x0008 + cmpwi cr1,r3,0x000c li r3,0 + cror 2,2,4*cr1+2 bnelr -1: /* Return the L2CR contents */ mfspr r3,L2CR blr @@ -986,15 +1035,6 @@ _GLOBAL(cvt_df) blr #endif -_GLOBAL(__clear_msr_me) - mfmsr r0 /* Get current interrupt state */ - lis r3,0 - ori r3,r3,MSR_ME - andc r0,r0,r3 /* Clears bit in (r4) */ - sync /* Some chip revs have problems here */ - mtmsr r0 /* Update machine state */ - blr - /* * Create a kernel thread * kernel_thread(fn, arg, flags) @@ -1244,16 +1284,20 @@ _GLOBAL(sys_call_table) .long sys_getrlimit /* 190 */ .long sys_ni_syscall /* 191 */ /* Unused */ .long sys_ni_syscall /* 192 - reserved - mmap2 */ - .long sys_ni_syscall /* 193 - reserved - truncate64 */ - .long sys_ni_syscall /* 194 - reserved - ftruncate64 */ - .long sys_ni_syscall /* 195 - reserved - stat64 */ - .long sys_ni_syscall /* 196 - reserved - lstat64 */ - .long sys_ni_syscall /* 197 - reserved - fstat64 */ + .long sys_truncate64 /* 193 */ + .long sys_ftruncate64 /* 194 */ + .long sys_stat64 /* 195 */ + .long sys_lstat64 /* 196 */ + .long sys_fstat64 /* 197 */ .long sys_pciconfig_read /* 198 */ .long sys_pciconfig_write /* 199 */ .long sys_pciconfig_iobase /* 200 */ .long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */ .long sys_getdents64 /* 202 */ + .long sys_pivot_root /* 203 */ + .long sys_fcntl64 /* 204 */ + .long sys_madvise /* 205 */ + .long sys_mincore /* 206 */ .rept NR_syscalls-(.-sys_call_table)/4 .long sys_ni_syscall .endr diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c index 5ca365b1c7bc..0cbd4f55323c 100644 --- a/arch/ppc/kernel/open_pic.c +++ b/arch/ppc/kernel/open_pic.c @@ -1,5 +1,5 @@ /* - * arch/ppc/kernel/openpic.c -- OpenPIC Interrupt Handling + * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling * * Copyright (C) 1997 Geert Uytterhoeven * @@ -13,35 +13,38 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/init.h> -#include <linux/openpic.h> +#include <linux/irq.h> #include <asm/ptrace.h> #include <asm/signal.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/prom.h> + #include "local_irq.h" +#include "open_pic.h" +#include "open_pic_defs.h" -volatile struct OpenPIC *OpenPIC = NULL; +void* OpenPIC_Addr; +static volatile struct OpenPIC *OpenPIC = NULL; u_int OpenPIC_NumInitSenses __initdata = 0; u_char *OpenPIC_InitSenses __initdata = NULL; -int open_pic_irq_offset; extern int use_of_interrupt_tree; -void chrp_mask_irq(unsigned int); -void chrp_unmask_irq(unsigned int); void find_ISUs(void); static u_int NumProcessors; static u_int NumSources; -OpenPIC_Source *ISU; -/* - * We should use this if we have > 1 ISU. - * We can just point each entry to the - * appropriate source regs but it wastes a lot of space - * so until we have >1 ISU I'll leave it unimplemented. - * -- Cort -OpenPIC_Source ISU[128]; -*/ +#ifdef CONFIG_POWER3 +static int NumISUs; +#endif +static int open_pic_irq_offset; +static volatile unsigned char* chrp_int_ack_special; + +OpenPIC_SourcePtr ISU[OPENPIC_MAX_ISU]; + +static void openpic_end_irq(unsigned int irq_nr); +static void openpic_ack_irq(unsigned int irq_nr); +static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask); struct hw_interrupt_type open_pic = { " OpenPIC ", @@ -49,45 +52,69 @@ struct hw_interrupt_type open_pic = { NULL, openpic_enable_irq, openpic_disable_irq, - 0, + openpic_ack_irq, + openpic_end_irq, + openpic_set_affinity +}; + +#ifdef CONFIG_SMP +static void openpic_end_ipi(unsigned int irq_nr); +static void openpic_ack_ipi(unsigned int irq_nr); +static void openpic_enable_ipi(unsigned int irq_nr); +static void openpic_disable_ipi(unsigned int irq_nr); + +struct hw_interrupt_type open_pic_ipi = { + " OpenPIC ", + NULL, + NULL, + openpic_enable_ipi, + openpic_disable_ipi, + openpic_ack_ipi, + openpic_end_ipi, 0 }; +#endif /* CONFIG_SMP */ /* - * Accesses to the current processor's registers + * Accesses to the current processor's openpic registers */ -#ifndef __powerpc__ -#define THIS_CPU Private -#define CHECK_THIS_CPU do {} while (0) -#else +#ifdef CONFIG_SMP #define THIS_CPU Processor[cpu] +#define DECL_THIS_CPU int cpu = smp_hw_index[smp_processor_id()] #define CHECK_THIS_CPU check_arg_cpu(cpu) -#endif +#else +#define THIS_CPU Processor[0] +#define DECL_THIS_CPU +#define CHECK_THIS_CPU +#endif /* CONFIG_SMP */ #if 1 #define check_arg_ipi(ipi) \ if (ipi < 0 || ipi >= OPENPIC_NUM_IPI) \ - printk("openpic.c:%d: illegal ipi %d\n", __LINE__, ipi); + printk("open_pic.c:%d: illegal ipi %d\n", __LINE__, ipi); #define check_arg_timer(timer) \ if (timer < 0 || timer >= OPENPIC_NUM_TIMERS) \ - printk("openpic.c:%d: illegal timer %d\n", __LINE__, timer); + printk("open_pic.c:%d: illegal timer %d\n", __LINE__, timer); #define check_arg_vec(vec) \ if (vec < 0 || vec >= OPENPIC_NUM_VECTORS) \ - printk("openpic.c:%d: illegal vector %d\n", __LINE__, vec); + printk("open_pic.c:%d: illegal vector %d\n", __LINE__, vec); #define check_arg_pri(pri) \ if (pri < 0 || pri >= OPENPIC_NUM_PRI) \ - printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri); + printk("open_pic.c:%d: illegal priority %d\n", __LINE__, pri); /* - * I changed this to return to keep us from from trying to use irq #'s - * that we're using for IPI's. - * -- Cort - */ + * Print out a backtrace if it's out of range, since if it's larger than NR_IRQ's + * data has probably been corrupted and we're going to panic or deadlock later + * anyway --Troy + */ +extern unsigned long* _get_SP(void); #define check_arg_irq(irq) \ - /*if (irq < 0 || irq >= (NumSources+open_pic_irq_offset)) \ - printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/ + if (irq < open_pic_irq_offset || irq >= (NumSources+open_pic_irq_offset)){ \ + printk("open_pic.c:%d: illegal irq %d\n", __LINE__, irq); \ + print_backtrace(_get_SP()); } #define check_arg_cpu(cpu) \ - if (cpu < 0 || cpu >= NumProcessors) \ - printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu); + if (cpu < 0 || cpu >= NumProcessors){ \ + printk("open_pic.c:%d: illegal cpu %d\n", __LINE__, cpu); \ + print_backtrace(_get_SP()); } #else #define check_arg_ipi(ipi) do {} while (0) #define check_arg_timer(timer) do {} while (0) @@ -97,23 +124,10 @@ struct hw_interrupt_type open_pic = { #define check_arg_cpu(cpu) do {} while (0) #endif -#ifdef CONFIG_SMP -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) -{ - smp_message_recv(cpl-OPENPIC_VEC_IPI, regs); -} -#endif /* CONFIG_SMP */ - -#ifdef __i386__ -static inline u_int in_le32(volatile u_int *addr) -{ - return *addr; -} - -static inline void out_le32(volatile u_int *addr, u_int val) -{ - *addr = val; -} +#ifdef CONFIG_POWER3 + #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] +#else + #define GET_ISU(source) ISU[0][(source)] #endif u_int openpic_read(volatile u_int *addr) @@ -156,22 +170,66 @@ static void openpic_safe_writefield(volatile u_int *addr, u_int mask, u_int field) { openpic_setfield(addr, OPENPIC_MASK); - /* wait until it's not in use */ - /* BenH: Is this code really enough ? I would rather check the result - * and eventually retry ... - */ while (openpic_read(addr) & OPENPIC_ACTIVITY); openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); } -void __init openpic_init(int main_pic) +#ifdef CONFIG_SMP +/* yes this is right ... bug, feature, you decide! -- tgall */ +u_int openpic_read_IPI(volatile u_int* addr) +{ + u_int val = 0; +#ifdef CONFIG_POWER3 + val = in_be32(addr); +#else + val = in_le32(addr); +#endif + return val; +} + +/* because of the power3 be / le above, this is needed */ +inline void openpic_writefield_IPI(volatile u_int* addr, u_int mask, u_int field) +{ + u_int val = openpic_read_IPI(addr); + openpic_write(addr, (val & ~mask) | (field & mask)); +} + +static inline void openpic_clearfield_IPI(volatile u_int *addr, u_int mask) +{ + openpic_writefield_IPI(addr, mask, 0); +} + +static inline void openpic_setfield_IPI(volatile u_int *addr, u_int mask) +{ + openpic_writefield_IPI(addr, mask, mask); +} + +static void openpic_safe_writefield_IPI(volatile u_int *addr, u_int mask, u_int field) +{ + openpic_setfield_IPI(addr, OPENPIC_MASK); + + /* wait until it's not in use */ + /* BenH: Is this code really enough ? I would rather check the result + * and eventually retry ... + */ + while(openpic_read_IPI(addr) & OPENPIC_ACTIVITY); + + openpic_writefield_IPI(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK); +} +#endif /* CONFIG_SMP */ + +void __init openpic_init(int main_pic, int offset, unsigned char* chrp_ack, + int programmer_switch_irq) { u_int t, i; u_int timerfreq; const char *version; - if (!OpenPIC) - panic("No OpenPIC found"); + if (!OpenPIC_Addr) { + printk("No OpenPIC found !\n"); + return; + } + OpenPIC = (volatile struct OpenPIC *)OpenPIC_Addr; if ( ppc_md.progress ) ppc_md.progress("openpic enter",0x122); @@ -194,179 +252,180 @@ void __init openpic_init(int main_pic) OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT) + 1; NumSources = ((t & OPENPIC_FEATURE_LAST_SOURCE_MASK) >> OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1; - if ( _machine != _MACH_Pmac ) - { - printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version, - NumProcessors, NumSources, OpenPIC); - timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); - printk("OpenPIC timer frequency is "); - if (timerfreq) - printk("%d MHz\n", timerfreq>>20); - else - printk("not set\n"); + printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", + version, NumProcessors, NumSources, OpenPIC); + timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency); + if (timerfreq) + printk("OpenPIC timer frequency is %d.%06d MHz\n", + timerfreq / 1000000, timerfreq % 1000000); + + if (!main_pic) + return; + + open_pic_irq_offset = offset; + chrp_int_ack_special = (volatile unsigned char*)chrp_ack; + + /* Initialize timer interrupts */ + if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); + for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { + /* Disabled, Priority 0 */ + openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i+offset); + /* No processor */ + openpic_maptimer(i, 0); } - - if ( main_pic ) - { - /* Initialize timer interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic timer",0x3ba); - for (i = 0; i < OPENPIC_NUM_TIMERS; i++) { - /* Disabled, Priority 0 */ - openpic_inittimer(i, 0, OPENPIC_VEC_TIMER+i); - /* No processor */ - openpic_maptimer(i, 0); - } - - /* Initialize IPI interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); - for (i = 0; i < OPENPIC_NUM_IPI; i++) { - /* Disabled, Priority 8 */ - openpic_initipi(i, 8, OPENPIC_VEC_IPI+i); - } - find_ISUs(); - if ( _machine != _MACH_Pmac ) - { - /* Initialize external interrupts */ - if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc); - /* SIOint (8259 cascade) is special */ - openpic_initirq(0, 8, open_pic_irq_offset, 1, 1); - openpic_mapirq(0, 1<<0); - for (i = 1; i < NumSources; i++) { - /* Enabled, Priority 8 */ - openpic_initirq(i, 8, open_pic_irq_offset+i, 0, - i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1); - /* Processor 0 */ - openpic_mapirq(i, 1<<0); - } - } - else - { - /* Prevent any interrupt from occuring during initialisation. - * Hum... I believe this is not necessary, Apple does that in - * Darwin's PowerExpress code. - */ - openpic_set_priority(0, 0xf); - - /* First disable all interrupts and map them to CPU 0 */ - for (i = 0; i < NumSources; i++) { - openpic_disable_irq(i); - openpic_mapirq(i, 1<<0); - } - - /* If we use the device tree, then lookup all interrupts and - * initialize them according to sense infos found in the tree - */ - if (use_of_interrupt_tree) { - struct device_node* np = find_all_nodes(); - while(np) { - int j, pri; - pri = strcmp(np->name, "programmer-switch") ? 2 : 7; - for (j=0;j<np->n_intrs;j++) { - openpic_initirq(np->intrs[j].line, - pri, - np->intrs[j].line, - 0, - np->intrs[j].sense); - if (np->intrs[j].sense) - irq_desc[np->intrs[j].line].status = IRQ_LEVEL; - } - np = np->next; - } - } - } - - /* Initialize the spurious interrupt */ - if ( ppc_md.progress ) ppc_md.progress("openpic spurious",0x3bd); - openpic_set_spurious(OPENPIC_VEC_SPURIOUS); - if ( !(_machine & (_MACH_gemini|_MACH_Pmac)) ) - { - if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT, - "82c59 cascade", NULL)) - printk("Unable to get OpenPIC IRQ 0 for cascade\n"); - } - openpic_set_priority(0, 0); - openpic_disable_8259_pass_through(); + +#ifdef CONFIG_SMP + /* Initialize IPI interrupts */ + if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb); + for (i = 0; i < OPENPIC_NUM_IPI; i++) { + /* Disabled, Priority 10..13 */ + openpic_initipi(i, 10+i, OPENPIC_VEC_IPI+i+offset); + /* IPIs are per-CPU */ + irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; + irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; + } +#endif + + find_ISUs(); + + /* Initialize external interrupts */ + if (ppc_md.progress) ppc_md.progress("openpic ext",0x3bc); + + openpic_set_priority(0xf); + + /* SIOint (8259 cascade) is special */ + if (offset) { + openpic_initirq(0, 8, offset, 1, 1); + openpic_mapirq(0, 1<<0); + } + + /* Init all external sources */ + for (i = 1; i < NumSources; i++) { + int pri, sense; + + /* the bootloader may have left it enabled (bad !) */ + openpic_disable_irq(i+offset); + + pri = (i == programmer_switch_irq)? 9: 8; + sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1; + if (sense) + irq_desc[i+offset].status = IRQ_LEVEL; + + /* Enabled, Priority 8 or 9 */ + openpic_initirq(i, pri, i+offset, !sense, sense); + /* Processor 0 */ + openpic_mapirq(i, 1<<0); } - if ( ppc_md.progress ) ppc_md.progress("openpic exit",0x222); + + /* Init descriptors */ + for (i = offset; i < NumSources + offset; i++) + irq_desc[i].handler = &open_pic; + + /* Initialize the spurious interrupt */ + if (ppc_md.progress) ppc_md.progress("openpic spurious",0x3bd); + openpic_set_spurious(OPENPIC_VEC_SPURIOUS+offset); + + /* Initialize the cascade */ + if (offset) { + if (request_irq(offset, no_action, SA_INTERRUPT, + "82c59 cascade", NULL)) + printk("Unable to get OpenPIC IRQ 0 for cascade\n"); + } + openpic_set_priority(0); + openpic_disable_8259_pass_through(); + + if (ppc_md.progress) ppc_md.progress("openpic exit",0x222); +} + +#ifdef CONFIG_POWER3 +void openpic_setup_ISU(int isu_num, unsigned long addr) +{ + if (isu_num >= OPENPIC_MAX_ISU) + return; + ISU[isu_num] = (OpenPIC_SourcePtr) ioremap(addr, 0x400); + if (isu_num >= NumISUs) + NumISUs = isu_num + 1; } +#endif void find_ISUs(void) { -#ifdef CONFIG_PPC64BRIDGE - /* hardcode this for now since the IBM 260 is the only thing with - * a distributed openpic right now. -- Cort +#ifdef CONFIG_POWER3 + /* Use /interrupt-controller/reg and + * /interrupt-controller/interrupt-ranges from OF device tree + * the ISU array is setup in chrp_pci.c in ibm_add_bridges + * as a result + * -- tgall + */ + + /* basically each ISU is a bus, and this assumes that + * open_pic_isu_count interrupts per bus are possible + * ISU == Interrupt Source */ - ISU = (OpenPIC_Source *)0xfeff7c00; - NumSources = 0x10; + NumSources = NumISUs * 0x10; + #else /* for non-distributed OpenPIC implementations it's in the IDU -- Cort */ - ISU = (OpenPIC_Source *)OpenPIC->Source; + ISU[0] = (OpenPIC_Source *)OpenPIC->Source; #endif } -void openpic_reset(void) +static inline void openpic_reset(void) { openpic_setfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_RESET); } -void openpic_enable_8259_pass_through(void) +static inline void openpic_enable_8259_pass_through(void) { openpic_clearfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } -void openpic_disable_8259_pass_through(void) +static void openpic_disable_8259_pass_through(void) { openpic_setfield(&OpenPIC->Global.Global_Configuration0, OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE); } -#ifndef __i386__ /* * Find out the current interrupt */ -u_int openpic_irq(u_int cpu) +static u_int openpic_irq(void) { u_int vec; + DECL_THIS_CPU; - check_arg_cpu(cpu); + CHECK_THIS_CPU; vec = openpic_readfield(&OpenPIC->THIS_CPU.Interrupt_Acknowledge, OPENPIC_VECTOR_MASK); return vec; } -#endif -#ifndef __powerpc__ -void openpic_eoi(void) -#else -void openpic_eoi(u_int cpu) -#endif +static void openpic_eoi(void) { - check_arg_cpu(cpu); + DECL_THIS_CPU; + + CHECK_THIS_CPU; openpic_write(&OpenPIC->THIS_CPU.EOI, 0); /* Handle PCI write posting */ (void)openpic_read(&OpenPIC->THIS_CPU.EOI); } -#ifndef __powerpc__ -u_int openpic_get_priority(void) -#else -u_int openpic_get_priority(u_int cpu) -#endif +static inline u_int openpic_get_priority(void) { + DECL_THIS_CPU; + CHECK_THIS_CPU; return openpic_readfield(&OpenPIC->THIS_CPU.Current_Task_Priority, OPENPIC_CURRENT_TASK_PRIORITY_MASK); } -#ifndef __powerpc__ -void openpic_set_priority(u_int pri) -#else -void openpic_set_priority(u_int cpu, u_int pri) -#endif +static void openpic_set_priority(u_int pri) { + DECL_THIS_CPU; + CHECK_THIS_CPU; check_arg_pri(pri); openpic_writefield(&OpenPIC->THIS_CPU.Current_Task_Priority, @@ -376,24 +435,43 @@ void openpic_set_priority(u_int cpu, u_int pri) /* * Get/set the spurious vector */ -u_int openpic_get_spurious(void) +static inline u_int openpic_get_spurious(void) { return openpic_readfield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK); } -void openpic_set_spurious(u_int vec) +static void openpic_set_spurious(u_int vec) { check_arg_vec(vec); openpic_writefield(&OpenPIC->Global.Spurious_Vector, OPENPIC_VECTOR_MASK, vec); } +#ifdef CONFIG_SMP +/* + * Convert a cpu mask from logical to physical cpu numbers. + */ +static inline u32 physmask(u32 cpumask) +{ + int i; + u32 mask = 0; + + for (i = 0; i < smp_num_cpus; ++i, cpumask >>= 1) + mask |= (cpumask & 1) << smp_hw_index[i]; + return mask; +} +#else +#define physmask(cpumask) (cpumask) +#endif + void openpic_init_processor(u_int cpumask) { - openpic_write(&OpenPIC->Global.Processor_Initialization, cpumask); + openpic_write(&OpenPIC->Global.Processor_Initialization, + physmask(cpumask)); } +#ifdef CONFIG_SMP /* * Initialize an interprocessor interrupt (and disable it) * @@ -401,35 +479,55 @@ void openpic_init_processor(u_int cpumask) * pri: interrupt source priority * vec: the vector it will produce */ -void openpic_initipi(u_int ipi, u_int pri, u_int vec) +static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec) { - check_arg_timer(ipi); + check_arg_ipi(ipi); check_arg_pri(pri); check_arg_vec(vec); - openpic_safe_writefield(&OpenPIC->Global.IPI_Vector_Priority(ipi), + openpic_safe_writefield_IPI(&OpenPIC->Global.IPI_Vector_Priority(ipi), OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK, (pri << OPENPIC_PRIORITY_SHIFT) | vec); } /* * Send an IPI to one or more CPUs + * + * Externally called, however, it takes an IPI number (0...OPENPIC_NUM_IPI) + * and not a system-wide interrupt number */ -#ifndef __powerpc__ void openpic_cause_IPI(u_int ipi, u_int cpumask) -#else -void openpic_cause_IPI(u_int cpu, u_int ipi, u_int cpumask) -#endif { + DECL_THIS_CPU; + CHECK_THIS_CPU; check_arg_ipi(ipi); - openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), cpumask); + openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), + physmask(cpumask)); } -void openpic_enable_IPI(u_int ipi) +void openpic_request_IPIs(void) { - check_arg_ipi(ipi); - openpic_clearfield(&OpenPIC->Global.IPI_Vector_Priority(ipi), - OPENPIC_MASK); + int i; + + /* + * Make sure this matches what is defined in smp.c for + * smp_message_{pass|recv}() or what shows up in + * /proc/interrupts will be wrong!!! --Troy */ + + if (OpenPIC == NULL) + return; + + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset, + openpic_ipi_action, 0, "IPI0 (call function)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+1, + openpic_ipi_action, 0, "IPI1 (reschedule)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+2, + openpic_ipi_action, 0, "IPI2 (invalidate tlb)", 0); + request_irq(OPENPIC_VEC_IPI+open_pic_irq_offset+3, + openpic_ipi_action, 0, "IPI3 (xmon break)", 0); + + for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) + openpic_enable_ipi(OPENPIC_VEC_IPI+open_pic_irq_offset+i); } /* @@ -437,21 +535,31 @@ void openpic_enable_IPI(u_int ipi) * * Get IPI's working and start taking interrupts. * -- Cort - */ -void do_openpic_setup_cpu(void) + */ +static spinlock_t openpic_setup_lock __initdata = SPIN_LOCK_UNLOCKED; + +void __init do_openpic_setup_cpu(void) { int i; - - for ( i = 0; i < OPENPIC_NUM_IPI ; i++ ) - openpic_enable_IPI(i); -#if 0 - /* let the openpic know we want intrs */ - for ( i = 0; i < NumSources ; i++ ) - openpic_mapirq(i, openpic_read(ISU[i].Destination) - | (1<<smp_processor_id()) ); -#endif - openpic_set_priority(smp_processor_id(), 0); + u32 msk = 1 << smp_hw_index[smp_processor_id()]; + + spin_lock(&openpic_setup_lock); + +#ifdef CONFIG_IRQ_ALL_CPUS + /* let the openpic know we want intrs. default affinity + * is 0xffffffff until changed via /proc + * That's how it's done on x86. If we want it differently, then + * we should make sure we also change the default values of irq_affinity + * in irq.c. + */ + for (i = 0; i < NumSources ; i++) + openpic_mapirq(i, openpic_read(&GET_ISU(i).Destination) | msk); +#endif /* CONFIG_IRQ_ALL_CPUS */ + openpic_set_priority(0); + + spin_unlock(&openpic_setup_lock); } +#endif /* CONFIG_SMP */ /* * Initialize a timer interrupt (and disable it) @@ -460,7 +568,7 @@ void do_openpic_setup_cpu(void) * pri: interrupt source priority * vec: the vector it will produce */ -void openpic_inittimer(u_int timer, u_int pri, u_int vec) +static void __init openpic_inittimer(u_int timer, u_int pri, u_int vec) { check_arg_timer(timer); check_arg_pri(pri); @@ -473,37 +581,99 @@ void openpic_inittimer(u_int timer, u_int pri, u_int vec) /* * Map a timer interrupt to one or more CPUs */ -void openpic_maptimer(u_int timer, u_int cpumask) +static void __init openpic_maptimer(u_int timer, u_int cpumask) { check_arg_timer(timer); - openpic_write(&OpenPIC->Global.Timer[timer].Destination, cpumask); + openpic_write(&OpenPIC->Global.Timer[timer].Destination, + physmask(cpumask)); } + +/* + * + * All functions below take an offset'ed irq argument + * + */ + + /* - * Enable/disable an interrupt source + * Enable/disable an external interrupt source + * + * Externally called, irq is an offseted system-wide interrupt number */ -void openpic_enable_irq(u_int irq) +static void openpic_enable_irq(u_int irq) { check_arg_irq(irq); - openpic_clearfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK); + + /* + * Never want to disable a timer or ipi irq + * (only want to disable irqs within an ISU). + */ + if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) && + (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) || + ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) && + (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS))) + { + /* silently ignore the enable of the timer or ipi irq. */ + return; + } + + + openpic_clearfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, + } while(openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK)); } -void openpic_disable_irq(u_int irq) +static void openpic_disable_irq(u_int irq) { + u32 vp; + check_arg_irq(irq); - openpic_setfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK); + /* + * Never want to disable a timer or ipi irq + * (only want to disable irqs within an ISU). + */ + if (((irq >= OPENPIC_VEC_IPI+open_pic_irq_offset) && + (irq < OPENPIC_VEC_IPI+open_pic_irq_offset+OPENPIC_NUM_IPI)) || + ((irq >= OPENPIC_VEC_TIMER+open_pic_irq_offset) && + (irq < OPENPIC_VEC_TIMER+open_pic_irq_offset+OPENPIC_NUM_TIMERS))) + { + panic("openpic_disable_irq - disabling non-ISU irq"); + } + + + openpic_setfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, OPENPIC_MASK); /* make sure mask gets to controller before we return to user */ do { mb(); /* sync is probably useless here */ - } while(!openpic_readfield(&ISU[irq - open_pic_irq_offset].Vector_Priority, - OPENPIC_MASK)); + vp = openpic_readfield(&GET_ISU(irq - open_pic_irq_offset).Vector_Priority, + OPENPIC_MASK | OPENPIC_ACTIVITY); + } while((vp & OPENPIC_ACTIVITY) && !(vp & OPENPIC_MASK)); } +#ifdef CONFIG_SMP +/* + * Enable/disable an IPI interrupt source + * + * Externally called, irq is an offseted system-wide interrupt number + */ +void openpic_enable_ipi(u_int irq) +{ + irq -= (OPENPIC_VEC_IPI+open_pic_irq_offset); + check_arg_ipi(irq); + openpic_clearfield_IPI(&OpenPIC->Global.IPI_Vector_Priority(irq), OPENPIC_MASK); + +} +void openpic_disable_ipi(u_int irq) +{ + /* NEVER disable an IPI... that's just plain wrong! */ +} + +#endif + /* * Initialize an interrupt source (and disable it!) * @@ -513,12 +683,9 @@ void openpic_disable_irq(u_int irq) * pol: polarity (1 for positive, 0 for negative) * sense: 1 for level, 0 for edge */ -void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) +static void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) { - check_arg_irq(irq); - check_arg_pri(pri); - check_arg_vec(vec); - openpic_safe_writefield(&ISU[irq].Vector_Priority, + openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK | OPENPIC_SENSE_MASK | OPENPIC_POLARITY_MASK, (pri << OPENPIC_PRIORITY_SHIFT) | vec | @@ -530,10 +697,9 @@ void openpic_initirq(u_int irq, u_int pri, u_int vec, int pol, int sense) /* * Map an interrupt source to one or more CPUs */ -void openpic_mapirq(u_int irq, u_int cpumask) +static void openpic_mapirq(u_int irq, u_int physmask) { - check_arg_irq(irq); - openpic_write(&ISU[irq].Destination, cpumask); + openpic_write(&GET_ISU(irq).Destination, physmask); } /* @@ -541,10 +707,92 @@ void openpic_mapirq(u_int irq, u_int cpumask) * * sense: 1 for level, 0 for edge */ -void openpic_set_sense(u_int irq, int sense) +static inline void openpic_set_sense(u_int irq, int sense) { - check_arg_irq(irq); - openpic_safe_writefield(&ISU[irq].Vector_Priority, + openpic_safe_writefield(&GET_ISU(irq).Vector_Priority, OPENPIC_SENSE_LEVEL, (sense ? OPENPIC_SENSE_LEVEL : 0)); } + +/* No spinlocks, should not be necessary with the OpenPIC + * (1 register = 1 interrupt and we have the desc lock). + */ +static void openpic_ack_irq(unsigned int irq_nr) +{ +#if 1 /* masking should be unnecessary, but I still get spurrious */ + openpic_disable_irq(irq_nr); +#endif + if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) + openpic_eoi(); +} + +static void openpic_end_irq(unsigned int irq_nr) +{ + if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) + openpic_eoi(); + +#if 1 /* masking should be unnecessary, but I still get spurrious */ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + openpic_enable_irq(irq_nr); +#endif +} + +static void openpic_set_affinity(unsigned int irq_nr, unsigned long cpumask) +{ + openpic_mapirq(irq_nr - open_pic_irq_offset, physmask(cpumask)); +} + +#ifdef CONFIG_SMP +static void openpic_ack_ipi(unsigned int irq_nr) +{ +} + +static void openpic_end_ipi(unsigned int irq_nr) +{ + /* IPIs are marked IRQ_PER_CPU. This has the side effect of + * preventing the IRQ_PENDING/IRQ_INPROGRESS logic from + * applying to them. We EOI them late to avoid re-entering. + * however, I'm wondering if we could simply let them have the + * SA_INTERRUPT flag and let them execute with all interrupts OFF. + * This would have the side effect of either running cross-CPU + * functions with interrupts off, or we can re-enable them explicitely + * with a __sti() in smp_call_function_interrupt(), since + * smp_call_function() is protected by a spinlock. + * Or maybe we shouldn't set the IRQ_PER_CPU flag on cross-CPU + * function calls IPI at all but that would make a special case. + */ + openpic_eoi(); +} + +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs) +{ + smp_message_recv(cpl-OPENPIC_VEC_IPI-open_pic_irq_offset, regs); +} + +#endif /* CONFIG_SMP */ + +/* This one may be merged with PReP and CHRP */ +int +openpic_get_irq(struct pt_regs *regs) +{ + extern int i8259_irq(int cpu); + + int irq = openpic_irq(); + + /* Management of the cascade should be moved out of here */ + if (open_pic_irq_offset && irq == open_pic_irq_offset) + { + /* + * This magic address generates a PCI IACK cycle. + */ + if ( chrp_int_ack_special ) + irq = *chrp_int_ack_special; + else + irq = i8259_irq( smp_processor_id() ); + openpic_eoi(); + } + if (irq == OPENPIC_VEC_SPURIOUS + open_pic_irq_offset) + irq = -1; + return irq; +} + diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h index 3e51ffba374f..ac99cd1e04f9 100644 --- a/arch/ppc/kernel/open_pic.h +++ b/arch/ppc/kernel/open_pic.h @@ -1,11 +1,43 @@ +/* + * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling + * + * Copyright (C) 1997 Geert Uytterhoeven + * + * 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. + * + */ + #ifndef _PPC_KERNEL_OPEN_PIC_H #define _PPC_KERNEL_OPEN_PIC_H +#define OPENPIC_SIZE 0x40000 + +/* OpenPIC IRQ controller structure */ extern struct hw_interrupt_type open_pic; -void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); -void openpic_enable_IPI(u_int ipi); -void do_openpic_setup_cpu(void); +/* OpenPIC IPI controller structure */ +#ifdef CONFIG_SMP +extern struct hw_interrupt_type open_pic_ipi; +#endif /* CONFIG_SMP */ + +extern u_int OpenPIC_NumInitSenses; +extern u_char *OpenPIC_InitSenses; +extern void* OpenPIC_Addr; + +/* Exported functions */ +extern void openpic_init(int, int, unsigned char *, int); +extern void openpic_request_IPIs(void); +extern void do_openpic_setup_cpu(void); +extern int openpic_get_irq(struct pt_regs *regs); +extern void openpic_init_processor(u_int cpumask); +extern void openpic_setup_ISU(int isu_num, unsigned long addr); +extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern int open_pic_irq_offset; +extern inline int openpic_to_irq(int irq) +{ + return irq += NUM_8259_INTERRUPTS; +} +/*extern int open_pic_irq_offset;*/ #endif /* _PPC_KERNEL_OPEN_PIC_H */ diff --git a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h new file mode 100644 index 000000000000..fed4dd1cc8d7 --- /dev/null +++ b/arch/ppc/kernel/open_pic_defs.h @@ -0,0 +1,328 @@ +/* + * linux/openpic.h -- OpenPIC definitions + * + * Copyright (C) 1997 Geert Uytterhoeven + * + * This file is based on the following documentation: + * + * The Open Programmable Interrupt Controller (PIC) + * Register Interface Specification Revision 1.2 + * + * Issue Date: October 1995 + * + * Issued jointly by Advanced Micro Devices and Cyrix Corporation + * + * AMD is a registered trademark of Advanced Micro Devices, Inc. + * Copyright (C) 1995, Advanced Micro Devices, Inc. and Cyrix, Inc. + * All Rights Reserved. + * + * To receive a copy of this documentation, send an email to openpic@amd.com. + * + * 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. + */ + +#ifndef _LINUX_OPENPIC_H +#define _LINUX_OPENPIC_H + +#ifdef __KERNEL__ + +#include <linux/config.h> + + /* + * OpenPIC supports up to 2048 interrupt sources and up to 32 processors + */ + +#define OPENPIC_MAX_SOURCES 2048 +#define OPENPIC_MAX_PROCESSORS 32 +#define OPENPIC_MAX_ISU 16 + +#define OPENPIC_NUM_TIMERS 4 +#define OPENPIC_NUM_IPI 4 +#define OPENPIC_NUM_PRI 16 +#define OPENPIC_NUM_VECTORS 256 + + + /* + * Non-offset'ed vector numbers + */ + +#define OPENPIC_VEC_TIMER 64 /* and up */ +#define OPENPIC_VEC_IPI 72 /* and up */ +#define OPENPIC_VEC_SPURIOUS 127 + + + /* + * OpenPIC Registers are 32 bits and aligned on 128 bit boundaries + */ + +typedef struct _OpenPIC_Reg { + u_int Reg; /* Little endian! */ + char Pad[0xc]; +} OpenPIC_Reg; + + + /* + * Per Processor Registers + */ + +typedef struct _OpenPIC_Processor { + /* + * Private Shadow Registers (for SLiC backwards compatibility) + */ + u_int IPI0_Dispatch_Shadow; /* Write Only */ + char Pad1[0x4]; + u_int IPI0_Vector_Priority_Shadow; /* Read/Write */ + char Pad2[0x34]; + /* + * Interprocessor Interrupt Command Ports + */ + OpenPIC_Reg _IPI_Dispatch[OPENPIC_NUM_IPI]; /* Write Only */ + /* + * Current Task Priority Register + */ + OpenPIC_Reg _Current_Task_Priority; /* Read/Write */ + char Pad3[0x10]; + /* + * Interrupt Acknowledge Register + */ + OpenPIC_Reg _Interrupt_Acknowledge; /* Read Only */ + /* + * End of Interrupt (EOI) Register + */ + OpenPIC_Reg _EOI; /* Read/Write */ + char Pad5[0xf40]; +} OpenPIC_Processor; + + + /* + * Timer Registers + */ + +typedef struct _OpenPIC_Timer { + OpenPIC_Reg _Current_Count; /* Read Only */ + OpenPIC_Reg _Base_Count; /* Read/Write */ + OpenPIC_Reg _Vector_Priority; /* Read/Write */ + OpenPIC_Reg _Destination; /* Read/Write */ +} OpenPIC_Timer; + + + /* + * Global Registers + */ + +typedef struct _OpenPIC_Global { + /* + * Feature Reporting Registers + */ + OpenPIC_Reg _Feature_Reporting0; /* Read Only */ + OpenPIC_Reg _Feature_Reporting1; /* Future Expansion */ + /* + * Global Configuration Registers + */ + OpenPIC_Reg _Global_Configuration0; /* Read/Write */ + OpenPIC_Reg _Global_Configuration1; /* Future Expansion */ + /* + * Vendor Specific Registers + */ + OpenPIC_Reg _Vendor_Specific[4]; + /* + * Vendor Identification Register + */ + OpenPIC_Reg _Vendor_Identification; /* Read Only */ + /* + * Processor Initialization Register + */ + OpenPIC_Reg _Processor_Initialization; /* Read/Write */ + /* + * IPI Vector/Priority Registers + */ + OpenPIC_Reg _IPI_Vector_Priority[OPENPIC_NUM_IPI]; /* Read/Write */ + /* + * Spurious Vector Register + */ + OpenPIC_Reg _Spurious_Vector; /* Read/Write */ + /* + * Global Timer Registers + */ + OpenPIC_Reg _Timer_Frequency; /* Read/Write */ + OpenPIC_Timer Timer[OPENPIC_NUM_TIMERS]; + char Pad1[0xee00]; +} OpenPIC_Global; + + + /* + * Interrupt Source Registers + */ + +typedef struct _OpenPIC_Source { + OpenPIC_Reg _Vector_Priority; /* Read/Write */ + OpenPIC_Reg _Destination; /* Read/Write */ +} OpenPIC_Source, *OpenPIC_SourcePtr; + + + /* + * OpenPIC Register Map + */ + +struct OpenPIC { + char Pad1[0x1000]; + /* + * Global Registers + */ + OpenPIC_Global Global; + /* + * Interrupt Source Configuration Registers + */ + OpenPIC_Source Source[OPENPIC_MAX_SOURCES]; + /* + * Per Processor Registers + */ + OpenPIC_Processor Processor[OPENPIC_MAX_PROCESSORS]; +}; + +extern volatile struct OpenPIC *OpenPIC; + + + /* + * Current Task Priority Register + */ + +#define OPENPIC_CURRENT_TASK_PRIORITY_MASK 0x0000000f + + /* + * Who Am I Register + */ + +#define OPENPIC_WHO_AM_I_ID_MASK 0x0000001f + + /* + * Feature Reporting Register 0 + */ + +#define OPENPIC_FEATURE_LAST_SOURCE_MASK 0x07ff0000 +#define OPENPIC_FEATURE_LAST_SOURCE_SHIFT 16 +#define OPENPIC_FEATURE_LAST_PROCESSOR_MASK 0x00001f00 +#define OPENPIC_FEATURE_LAST_PROCESSOR_SHIFT 8 +#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff + + /* + * Global Configuration Register 0 + */ + +#define OPENPIC_CONFIG_RESET 0x80000000 +#define OPENPIC_CONFIG_8259_PASSTHROUGH_DISABLE 0x20000000 +#define OPENPIC_CONFIG_BASE_MASK 0x000fffff + + /* + * Vendor Identification Register + */ + +#define OPENPIC_VENDOR_ID_STEPPING_MASK 0x00ff0000 +#define OPENPIC_VENDOR_ID_STEPPING_SHIFT 16 +#define OPENPIC_VENDOR_ID_DEVICE_ID_MASK 0x0000ff00 +#define OPENPIC_VENDOR_ID_DEVICE_ID_SHIFT 8 +#define OPENPIC_VENDOR_ID_VENDOR_ID_MASK 0x000000ff + + /* + * Vector/Priority Registers + */ + +#define OPENPIC_MASK 0x80000000 +#define OPENPIC_ACTIVITY 0x40000000 /* Read Only */ +#define OPENPIC_PRIORITY_MASK 0x000f0000 +#define OPENPIC_PRIORITY_SHIFT 16 +#define OPENPIC_VECTOR_MASK 0x000000ff + + + /* + * Interrupt Source Registers + */ + +#define OPENPIC_POLARITY_POSITIVE 0x00800000 +#define OPENPIC_POLARITY_NEGATIVE 0x00000000 +#define OPENPIC_POLARITY_MASK 0x00800000 +#define OPENPIC_SENSE_LEVEL 0x00400000 +#define OPENPIC_SENSE_EDGE 0x00000000 +#define OPENPIC_SENSE_MASK 0x00400000 + + + /* + * Timer Registers + */ + +#define OPENPIC_COUNT_MASK 0x7fffffff +#define OPENPIC_TIMER_TOGGLE 0x80000000 +#define OPENPIC_TIMER_COUNT_INHIBIT 0x80000000 + + + /* + * Aliases to make life simpler + */ + +/* Per Processor Registers */ +#define IPI_Dispatch(i) _IPI_Dispatch[i].Reg +#define Current_Task_Priority _Current_Task_Priority.Reg +#define Interrupt_Acknowledge _Interrupt_Acknowledge.Reg +#define EOI _EOI.Reg + +/* Global Registers */ +#define Feature_Reporting0 _Feature_Reporting0.Reg +#define Feature_Reporting1 _Feature_Reporting1.Reg +#define Global_Configuration0 _Global_Configuration0.Reg +#define Global_Configuration1 _Global_Configuration1.Reg +#define Vendor_Specific(i) _Vendor_Specific[i].Reg +#define Vendor_Identification _Vendor_Identification.Reg +#define Processor_Initialization _Processor_Initialization.Reg +#define IPI_Vector_Priority(i) _IPI_Vector_Priority[i].Reg +#define Spurious_Vector _Spurious_Vector.Reg +#define Timer_Frequency _Timer_Frequency.Reg + +/* Timer Registers */ +#define Current_Count _Current_Count.Reg +#define Base_Count _Base_Count.Reg +#define Vector_Priority _Vector_Priority.Reg +#define Destination _Destination.Reg + +/* Interrupt Source Registers */ +#define Vector_Priority _Vector_Priority.Reg +#define Destination _Destination.Reg + + /* + * Local (static) OpenPIC Operations + */ + + +/* Global Operations */ +static void openpic_reset(void); +static void openpic_enable_8259_pass_through(void); +static void openpic_disable_8259_pass_through(void); +static u_int openpic_irq(void); +static void openpic_eoi(void); +static u_int openpic_get_priority(void); +static void openpic_set_priority(u_int pri); +static u_int openpic_get_spurious(void); +static void openpic_set_spurious(u_int vector); + +#ifdef CONFIG_SMP +/* Interprocessor Interrupts */ +static void openpic_initipi(u_int ipi, u_int pri, u_int vector); +static void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs); +#endif + +/* Timer Interrupts */ +static void openpic_inittimer(u_int timer, u_int pri, u_int vector); +static void openpic_maptimer(u_int timer, u_int cpumask); + +/* Interrupt Sources */ +static void openpic_enable_irq(u_int irq); +static void openpic_disable_irq(u_int irq); +static void openpic_initirq(u_int irq, u_int pri, u_int vector, int polarity, + int is_level); +static void openpic_mapirq(u_int irq, u_int cpumask); +static void openpic_set_sense(u_int irq, int sense); + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_OPENPIC_H */ diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c index 6d6f775f22d8..30a5e70058ee 100644 --- a/arch/ppc/kernel/pci.c +++ b/arch/ppc/kernel/pci.c @@ -8,10 +8,10 @@ #include <linux/delay.h> #include <linux/string.h> #include <linux/init.h> -#include <linux/openpic.h> #include <linux/capability.h> #include <linux/sched.h> #include <linux/errno.h> +#include <linux/bootmem.h> #include <asm/processor.h> #include <asm/io.h> @@ -25,7 +25,7 @@ #include "pci.h" -#undef DEBUG +#define DEBUG #ifdef DEBUG #define DBG(x...) printk(x) @@ -37,54 +37,44 @@ unsigned long isa_io_base = 0; unsigned long isa_mem_base = 0; unsigned long pci_dram_offset = 0; -struct pci_fixup pcibios_fixups[] = { - { 0 } -}; +static u8* pci_to_OF_bus_map; -int generic_pcibios_read_byte(struct pci_dev *dev, int where, u8 *val) -{ - return ppc_md.pcibios_read_config_byte(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_read_word(struct pci_dev *dev, int where, u16 *val) -{ - return ppc_md.pcibios_read_config_word(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_read_dword(struct pci_dev *dev, int where, u32 *val) -{ - return ppc_md.pcibios_read_config_dword(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_byte(struct pci_dev *dev, int where, u8 val) -{ - return ppc_md.pcibios_write_config_byte(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_word(struct pci_dev *dev, int where, u16 val) -{ - return ppc_md.pcibios_write_config_word(dev->bus->number,dev->devfn,where,val); -} -int generic_pcibios_write_dword(struct pci_dev *dev, int where, u32 val) -{ - return ppc_md.pcibios_write_config_dword(dev->bus->number,dev->devfn,where,val); -} +static void pcibios_fixup_resources(struct pci_dev* dev); +#ifdef CONFIG_ALL_PPC +static void pcibios_fixup_cardbus(struct pci_dev* dev); +#endif -struct pci_ops generic_pci_ops = -{ - generic_pcibios_read_byte, - generic_pcibios_read_word, - generic_pcibios_read_dword, - generic_pcibios_write_byte, - generic_pcibios_write_word, - generic_pcibios_write_dword -}; +/* By default, we don't re-assign bus numbers. We do this only on + * some pmacs + */ +int pci_assign_all_busses; + +struct pci_controller* hose_head; +struct pci_controller** hose_tail = &hose_head; +static int pci_bus_count; +struct pci_fixup pcibios_fixups[] = { + { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_resources }, +#ifdef CONFIG_ALL_PPC + /* We should add per-machine fixup support in xxx_setup.c or xxx_pci.c */ + { PCI_FIXUP_FINAL, PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_1211, pcibios_fixup_cardbus }, +#endif /* CONFIG_ALL_PPC */ + { 0 } +}; -void pcibios_update_resource(struct pci_dev *dev, struct resource *root, +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, struct resource *res, int resource) { u32 new, check; int reg; - - new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + struct pci_controller* hose = dev->sysdata; + + new = res->start; + if (hose && res->flags & IORESOURCE_MEM) + new -= hose->pci_mem_offset; + new |= (res->flags & PCI_REGION_FLAG_MASK); if (resource < 6) { reg = PCI_BASE_ADDRESS_0 + 4*resource; } else if (resource == PCI_ROM_RESOURCE) { @@ -104,6 +94,62 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root, } } +static void +pcibios_fixup_resources(struct pci_dev* dev) +{ + struct pci_controller* hose = + (struct pci_controller *)dev->sysdata; + int i; + if (!hose) { + printk("No hose for PCI dev %x.%x !\n", dev->bus->number, dev->devfn >> 3); + return; + } + for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { + struct resource *res = dev->resource + i; + if (!res->start) + continue; + if (res->flags & IORESOURCE_MEM) { + res->start += hose->pci_mem_offset; + res->end += hose->pci_mem_offset; +#ifdef DEBUG + printk("Fixup mem res, dev: %x.%x, res_start: %lx->%lx\n", + dev->bus->number, dev->devfn>>3, res->start-hose->pci_mem_offset, + res->start); +#endif + } + + if ((res->flags & IORESOURCE_IO) + && (unsigned long) hose->io_base_virt != isa_io_base) { + unsigned long offs = (unsigned long) hose->io_base_virt - isa_io_base; + res->start += offs; + res->end += offs; + printk("Fixup IO res, dev: %x.%x, res_start: %lx->%lx\n", + dev->bus->number, dev->devfn>>3, + res->start - offs, res->start); + } + } +} + +#ifdef CONFIG_ALL_PPC +static void +pcibios_fixup_cardbus(struct pci_dev* dev) +{ + /* + * Fix the interrupt routing on the TI1211 chip on the 1999 + * G3 powerbook, which doesn't get initialized properly by OF. + */ + if (dev->vendor == PCI_VENDOR_ID_TI + && dev->device == PCI_DEVICE_ID_TI_1211) { + u32 val; + /* 0x8c == TI122X_IRQMUX, 2 says to route the INTA + signal out the MFUNC0 pin */ + if (pci_read_config_dword(dev, 0x8c, &val) == 0 + && val == 0) + pci_write_config_dword(dev, 0x8c, 2); + } +} +#endif /* CONFIG_ALL_PPC */ + /* * We need to avoid collisions with `mirrored' VGA ports * and other strange ISA hardware, so we always want the @@ -172,7 +218,8 @@ pcibios_align_resource(void *data, struct resource *res, unsigned long size) * as well. */ -static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) +static void __init +pcibios_allocate_bus_resources(struct list_head *bus_list) { struct list_head *ln; struct pci_bus *bus; @@ -197,7 +244,8 @@ static void __init pcibios_allocate_bus_resources(struct list_head *bus_list) } } -static void __init pcibios_allocate_resources(int pass) +static void __init +pcibios_allocate_resources(int pass) { struct pci_dev *dev; int idx, disabled; @@ -250,7 +298,8 @@ static void __init pcibios_allocate_resources(int pass) } } -static void __init pcibios_assign_resources(void) +static void __init +pcibios_assign_resources(void) { struct pci_dev *dev; int idx; @@ -278,7 +327,9 @@ static void __init pcibios_assign_resources(void) * the BIOS forgot to do so or because we have decided the old * address was unusable for some reason. */ - if (!r->start && r->end) + if (!r->start && r->end && + (!ppc_md.pcibios_enable_device_hook || + !ppc_md.pcibios_enable_device_hook(dev, 1))) pci_assign_resource(dev, idx); } @@ -293,7 +344,8 @@ static void __init pcibios_assign_resources(void) } -int pcibios_enable_resources(struct pci_dev *dev) +int +pcibios_enable_resources(struct pci_dev *dev) { u16 cmd, old_cmd; int idx; @@ -321,18 +373,267 @@ int pcibios_enable_resources(struct pci_dev *dev) return 0; } +struct pci_controller * __init +pcibios_alloc_controller(void) +{ + struct pci_controller *hose; + + hose = (struct pci_controller *)alloc_bootmem(sizeof(*hose)); + memset(hose, 0, sizeof(struct pci_controller)); + + *hose_tail = hose; + hose_tail = &hose->next; + + return hose; +} +static void +make_one_node_map(struct device_node* node, u8 pci_bus) +{ + int *bus_range; + int len; + + if (pci_bus >= pci_bus_count) + return; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + node->full_name); + return; + } + pci_to_OF_bus_map[pci_bus] = bus_range[0]; + + for (node=node->child; node != 0;node = node->sibling) { + struct pci_dev* dev; + unsigned int *class_code, *reg; + + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + reg = (unsigned int *)get_property(node, "reg", 0); + if (!reg) + continue; + dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff)); + if (!dev || !dev->subordinate) + continue; + make_one_node_map(node, dev->subordinate->number); + } +} + +void +pcibios_make_OF_bus_map(void) +{ + int i; + struct pci_controller* hose; + u8* of_prop_map; + + pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL); + if (!pci_to_OF_bus_map) { + printk(KERN_ERR "Can't allocate OF bus map !\n"); + return; + } + + /* We fill the bus map with invalid values, that helps + * debugging. + */ + for (i=0; i<pci_bus_count; i++) + pci_to_OF_bus_map[i] = 0xff; + + /* For each hose, we begin searching bridges */ + for(hose=hose_head; hose; hose=hose->next) { + struct device_node* node; + node = (struct device_node *)hose->arch_data; + if (!node) + continue; + make_one_node_map(node, hose->first_busno); + } + of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", 0); + if (of_prop_map) + memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count); +#ifdef DEBUG + printk("PCI->OF bus map:\n"); + for (i=0; i<pci_bus_count; i++) { + if (pci_to_OF_bus_map[i] == 0xff) + continue; + printk("%d -> %d\n", i, pci_to_OF_bus_map[i]); + } +#endif +} -void __init pcibios_init(void) +static struct device_node* +scan_OF_childs_for_device(struct device_node* node, u8 bus, u8 dev_fn) { + struct device_node* sub_node; + + for (; node != 0;node = node->sibling) { + unsigned int *class_code, *reg; + + reg = (unsigned int *) get_property(node, "reg", 0); + if (reg && ((reg[0] >> 8) & 0xff) == dev_fn + && ((reg[0] >> 16) & 0xff) == bus) + return node; + + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + sub_node = scan_OF_childs_for_device(node->child, bus, dev_fn); + if (sub_node) + return sub_node; + } + return NULL; +} + +/* + * Scans the OF tree for a device node matching a PCI device + */ +struct device_node* +pci_device_to_OF_node(struct pci_dev *dev) +{ + struct pci_controller *hose; + struct device_node *node; + int bus; + + if (!have_of) + return NULL; + + /* Lookup the hose */ + bus = dev->bus->number; + hose = pci_bus_to_hose(bus); + if (!hose) + return NULL; + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + return NULL; + + /* Fixup bus number according to what OF think it is. */ + if (pci_to_OF_bus_map) + bus = pci_to_OF_bus_map[bus]; + if (bus == 0xff) + return NULL; + + /* Now, lookup childs of the hose */ + return scan_OF_childs_for_device(node->child, bus, dev->devfn); +} + +/* This routine is meant to be used early during boot, when the + * PCI bus numbers have not yet been assigned, and you need to + * issue PCI config cycles to an OF device. + * It could also be used to "fix" RTAS config cycles if you want + * to set pci_assign_all_busses to 1 and still use RTAS for PCI + * config cycles. + */ +struct pci_controller* +pci_find_hose_for_OF_device(struct device_node* node) +{ + if (!have_of) + return NULL; + while(node) { + struct pci_controller* hose; + for (hose=hose_head;hose;hose=hose->next) + if (hose->arch_data == node) + return hose; + node=node->parent; + } + return NULL; +} + +/* + * Returns the PCI device matching a given OF node + */ +int +pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn) +{ + unsigned int *reg; + int i; + + if (!have_of) + return -ENODEV; + reg = (unsigned int *) get_property(node, "reg", 0); + if (!reg) + return -ENODEV; + *bus = (reg[0] >> 16) & 0xff; + for (i=0; pci_to_OF_bus_map && i<pci_bus_count; i++) + if (pci_to_OF_bus_map[i] == *bus) { + *bus = i; + break; + } + *devfn = ((reg[0] >> 8) & 0xff); + return 0; +} + +void __init +pcibios_init(void) +{ + struct pci_controller *hose; + struct pci_bus *bus; + int next_busno; + printk("PCI: Probing PCI hardware\n"); - pci_scan_bus(0, &generic_pci_ops, NULL); + + /* Scan all of the recorded PCI controllers. */ + for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { + if (pci_assign_all_busses) + hose->first_busno = next_busno; + hose->last_busno = 0xff; + bus = pci_scan_bus(hose->first_busno, hose->ops, hose); + hose->bus = bus; + hose->last_busno = bus->subordinate; + if (pci_assign_all_busses || next_busno <= hose->last_busno) + next_busno = hose->last_busno+1; + } + pci_bus_count = next_busno; + + /* OpenFirmware based machines need a map of OF bus + * numbers vs. kernel bus numbers since we may have to + * remap them. + */ + if (pci_assign_all_busses && have_of) + pcibios_make_OF_bus_map(); + + /* Call machine dependant fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); + + /* Allocate and assign resources */ pcibios_allocate_bus_resources(&pci_root_buses); pcibios_allocate_resources(0); pcibios_allocate_resources(1); pcibios_assign_resources(); + +#ifdef CONFIG_BLK_DEV_IDE + /* OF fails to initialize IDE controllers on macs + * (and maybe other machines) + * + * This late fixup is done here since I want it to happen after + * resource assignement, and there's no "late-init" arch hook + * + * Ideally, this should be moved to the IDE layer, but we need + * to check specifically with Andre Hedrick how to do it cleanly + * since the common IDE code seem to care about the fact that the + * BIOS may have disabled a controller. + * + * -- BenH + */ + if (_machine == _MACH_Pmac) { + struct pci_dev *dev; + pci_for_each_dev(dev) + { + if ((dev->class >> 16) == PCI_BASE_CLASS_STORAGE) + pci_enable_device(dev); + } + } +#endif /* CONFIG_BLK_DEV_IDE */ +} + +int __init +pcibios_assign_all_busses(void) +{ + return pci_assign_all_busses; } void __init @@ -344,9 +645,16 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ra ranges->mem_end -= bus->resource[1]->start; } +unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, + unsigned long start, unsigned long size) +{ + return start; +} void __init pcibios_fixup_bus(struct pci_bus *bus) { + pci_read_bridge_bases(bus); + if ( ppc_md.pcibios_fixup_bus ) ppc_md.pcibios_fixup_bus(bus); } @@ -370,6 +678,10 @@ int pcibios_enable_device(struct pci_dev *dev) int idx; struct resource *r; + if (ppc_md.pcibios_enable_device_hook) + if (ppc_md.pcibios_enable_device_hook(dev, 0)) + return -EINVAL; + pci_read_config_word(dev, PCI_COMMAND, &cmd); old_cmd = cmd; for (idx=0; idx<6; idx++) { @@ -391,37 +703,99 @@ int pcibios_enable_device(struct pci_dev *dev) return 0; } -void * -pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) +struct pci_controller* +pci_bus_to_hose(int bus) { - if (!ppc_md.pci_dev_io_base) { - /* Please, someone fix this for non-pmac machines, we - * need either the virtual or physical PCI IO base - */ - return 0; - } - return ppc_md.pci_dev_io_base(bus, devfn, physical); + struct pci_controller* hose = hose_head; + + for (; hose; hose = hose->next) + if (bus >= hose->first_busno && bus <= hose->last_busno) + return hose; + return NULL; } -void * -pci_dev_mem_base(unsigned char bus, unsigned char devfn) +void* +pci_bus_io_base(unsigned int bus) { - /* Default memory base is 0 (1:1 mapping) */ - if (!ppc_md.pci_dev_mem_base) { - /* Please, someone fix this for non-pmac machines.*/ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) + return NULL; + return hose->io_base_virt; +} + +unsigned long +pci_bus_io_base_phys(unsigned int bus) +{ + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) return 0; - } - return ppc_md.pci_dev_mem_base(bus, devfn); + return hose->io_base_phys; } -/* Returns the root-bridge number (Uni-N number) of a device */ -int -pci_dev_root_bridge(unsigned char bus, unsigned char devfn) +unsigned long +pci_bus_mem_base_phys(unsigned int bus) { - /* Defaults to 0 */ - if (!ppc_md.pci_dev_root_bridge) + struct pci_controller *hose; + + hose = pci_bus_to_hose(bus); + if (!hose) return 0; - return ppc_md.pci_dev_root_bridge(bus, devfn); + return hose->pci_mem_offset; +} + +#ifdef CONFIG_POWER4 +extern unsigned long pci_address_offset(int, unsigned int); +#endif /* CONFIG_POWER4 */ + +unsigned long +pci_resource_to_bus(struct pci_dev *pdev, struct resource *res) +{ + /* Hack alert again ! See comments in chrp_pci.c + */ +#ifdef CONFIG_POWER4 + unsigned long offset = pci_address_offset(pdev->bus->number, res->flags); + return res->start - offset; +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = + (struct pci_controller *)pdev->sysdata; + if (hose && res->flags & IORESOURCE_MEM) + return res->start - hose->pci_mem_offset; + /* We may want to do something with IOs here... */ + return res->start; +#endif +} + +/* Obsolete functions. Should be removed once the symbios driver + * is fixed + */ +unsigned long +pci_phys_to_bus(unsigned long pa, int busnr) +{ +#ifdef CONFIG_POWER4 + return pa - pci_address_offset(busnr, IORESOURCE_MEM); +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = pci_bus_to_hose(busnr); + if (!hose) + return pa; + return pa - hose->pci_mem_offset; +#endif +} + +unsigned long +pci_bus_to_phys(unsigned int ba, int busnr) +{ +#ifdef CONFIG_POWER4 + return ba + pci_address_offset(dev->bus->number, IORESOURCE_MEM); +#else /* CONFIG_POWER4 */ + struct pci_controller* hose = pci_bus_to_hose(busnr); + if (!hose) + return ba; + return ba + hose->pci_mem_offset; +#endif } /* Provide information on locations of various I/O regions in physical @@ -430,23 +804,93 @@ pci_dev_root_bridge(unsigned char bus, unsigned char devfn) * Note that the returned IO or memory base is a physical address */ -asmlinkage long +long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) { + struct pci_controller* hose = pci_bus_to_hose(bus); long result = -EOPNOTSUPP; + + if (!hose) + return -ENODEV; switch (which) { case IOBASE_BRIDGE_NUMBER: - return (long)pci_dev_root_bridge(bus, devfn); + return (long)hose->first_busno; case IOBASE_MEMORY: - return (long)pci_dev_mem_base(bus, devfn); + return (long)hose->pci_mem_offset; case IOBASE_IO: - result = (long)pci_dev_io_base(bus, devfn, 1); - if (result == 0) - result = -EOPNOTSUPP; - break; + return (long)hose->io_base_phys; + case IOBASE_ISA_IO: + return (long)isa_io_base; + case IOBASE_ISA_MEM: + return (long)isa_mem_base; } return result; } +/* + * Null PCI config access functions, for the case when we can't + * find a hose. + */ +#define NULL_PCI_OP(rw, size, type) \ +static int \ +null_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + return PCIBIOS_DEVICE_NOT_FOUND; \ +} + +NULL_PCI_OP(read, byte, u8 *) +NULL_PCI_OP(read, word, u16 *) +NULL_PCI_OP(read, dword, u32 *) +NULL_PCI_OP(write, byte, u8) +NULL_PCI_OP(write, word, u16) +NULL_PCI_OP(write, dword, u32) + +static struct pci_ops null_pci_ops = +{ + null_read_config_byte, + null_read_config_word, + null_read_config_dword, + null_write_config_byte, + null_write_config_word, + null_write_config_dword +}; + +/* + * These functions are used early on before PCI scanning is done + * and all of the pci_dev and pci_bus structures have been created. + */ +static struct pci_dev * +fake_pci_dev(struct pci_controller *hose, int busnr, int devfn) +{ + static struct pci_dev dev; + static struct pci_bus bus; + + if (hose == 0) { + hose = pci_bus_to_hose(busnr); + if (hose == 0) + printk(KERN_ERR "Can't find hose for PCI bus %d!\n", busnr); + } + dev.bus = &bus; + dev.sysdata = hose; + dev.devfn = devfn; + bus.number = busnr; + bus.ops = hose? hose->ops: &null_pci_ops; + return &dev; +} + +#define EARLY_PCI_OP(rw, size, type) \ +int early_##rw##_config_##size(struct pci_controller *hose, int bus, \ + int devfn, int offset, type value) \ +{ \ + return pci_##rw##_config_##size(fake_pci_dev(hose, bus, devfn), \ + offset, value); \ +} + +EARLY_PCI_OP(read, byte, u8 *) +EARLY_PCI_OP(read, word, u16 *) +EARLY_PCI_OP(read, dword, u32 *) +EARLY_PCI_OP(write, byte, u8) +EARLY_PCI_OP(write, word, u16) +EARLY_PCI_OP(write, dword, u32) diff --git a/arch/ppc/kernel/pci.h b/arch/ppc/kernel/pci.h index d79eb0f4acc2..07a64d9f3399 100644 --- a/arch/ppc/kernel/pci.h +++ b/arch/ppc/kernel/pci.h @@ -2,47 +2,23 @@ #ifndef __PPC_KERNEL_PCI_H__ #define __PPC_KERNEL_PCI_H__ +/* Configure those in your xxx_init() or xxx_setup_arch() function */ extern unsigned long isa_io_base; extern unsigned long isa_mem_base; extern unsigned long pci_dram_offset; -extern unsigned int *pci_config_address; -extern unsigned char *pci_config_data; +/* Set this to 1 if you want the kernel to re-assign all PCI + * bus numbers + */ +extern int pci_assign_all_busses; -void fix_intr(struct device_node *node, struct pci_dev *dev); -#if 0 -#define decl_config_access_method(name) \ -struct pci_ops name##_pci_ops = { \ - name##_pcibios_read_config_byte, \ - name##_pcibios_read_config_word, \ - name##_pcibios_read_config_dword, \ - name##_pcibios_write_config_byte, \ - name##_pcibios_write_config_word, \ - name##_pcibios_write_config_dword \ -} -#endif +extern struct pci_controller* pcibios_alloc_controller(void); +extern struct pci_controller* pci_find_hose_for_OF_device( + struct device_node* node); -#define decl_config_access_method(name) \ -extern int name##_pcibios_read_config_byte(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned char *val); \ -extern int name##_pcibios_read_config_word(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned short *val); \ -extern int name##_pcibios_read_config_dword(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned int *val); \ -extern int name##_pcibios_write_config_byte(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned char val); \ -extern int name##_pcibios_write_config_word(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned short val); \ -extern int name##_pcibios_write_config_dword(unsigned char bus, \ - unsigned char dev_fn, unsigned char offset, unsigned int val) - -#define set_config_access_method(name) \ - ppc_md.pcibios_read_config_byte = name##_pcibios_read_config_byte; \ - ppc_md.pcibios_read_config_word = name##_pcibios_read_config_word; \ - ppc_md.pcibios_read_config_dword = name##_pcibios_read_config_dword; \ - ppc_md.pcibios_write_config_byte = name##_pcibios_write_config_byte; \ - ppc_md.pcibios_write_config_word = name##_pcibios_write_config_word; \ - ppc_md.pcibios_write_config_dword = name##_pcibios_write_config_dword +extern void setup_indirect_pci(struct pci_controller* hose, + u32 cfg_addr, u32 cfg_data); +extern void setup_grackle(struct pci_controller *hose, unsigned io_space_size); #endif /* __PPC_KERNEL_PCI_H__ */ diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c index 8f7b3d7c231c..9e1fffb49f75 100644 --- a/arch/ppc/kernel/pmac_pci.c +++ b/arch/ppc/kernel/pmac_pci.c @@ -27,23 +27,14 @@ #include "pci.h" -struct bridge_data **bridges, *bridge_list; -static int max_bus; - -struct uninorth_data { - struct device_node* node; - volatile unsigned int* cfg_addr; - volatile unsigned int* cfg_data; - void* iobase; - unsigned long iobase_phys; -}; - -static struct uninorth_data uninorth_bridges[3]; -static int uninorth_count; -static int uninorth_default = -1; +#undef DEBUG static void add_bridges(struct device_node *dev); +/* XXX Could be per-controller, but I don't think we risk anything by + * assuming we won't have both UniNorth and Bandit */ +static int has_uninorth; + /* * Magic constants for enabling cache coherency in the bandit/PSX bridge. */ @@ -56,477 +47,201 @@ static void add_bridges(struct device_node *dev); #define BANDIT_MAGIC 0x50 #define BANDIT_COHERENT 0x40 -/* Obsolete, should be replaced by pmac_pci_dev_io_base() (below) */ -__pmac -void *pci_io_base(unsigned int bus) -{ - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return 0; - return bp->io_base; -} - -__pmac -int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, - unsigned char *devfn_ptr) +static int __init +fixup_one_level_bus_range(struct device_node *node, int higher) { - unsigned int *reg; - int len; + for (; node != 0;node = node->sibling) { + int * bus_range; + unsigned int *class_code; + int len; - reg = (unsigned int *) get_property(dev, "reg", &len); - if (reg == 0 || len < 5 * sizeof(unsigned int)) { - /* doesn't look like a PCI device */ - *bus_ptr = 0xff; - *devfn_ptr = 0xff; - return -1; + /* For PCI<->PCI bridges or CardBus bridges, we go down */ + class_code = (unsigned int *) get_property(node, "class-code", 0); + if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + continue; + bus_range = (int *) get_property(node, "bus-range", &len); + if (bus_range != NULL && len > 2 * sizeof(int)) { + if (bus_range[1] > higher) + higher = bus_range[1]; + } + higher = fixup_one_level_bus_range(node->child, higher); } - *bus_ptr = reg[0] >> 16; - *devfn_ptr = reg[0] >> 8; - return 0; + return higher; } -/* This routines figures out on which root bridge a given PCI device - * is attached. +/* This routine fixes the "bus-range" property of all bridges in the + * system since they tend to have their "last" member wrong on macs + * + * Note that the bus numbers manipulated here are OF bus numbers, they + * are not Linux bus numbers. */ -__pmac -int -pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn) +static void __init +fixup_bus_range(struct device_node *bridge) { - struct device_node *node, *bridge_node; - int bridge = uninorth_default; - - if (uninorth_count == 0) - return 0; - if (bus == 0 && PCI_SLOT(dev_fn) < 11) - return 0; + int * bus_range; + int len; - /* We look for the OF device corresponding to this bus/devfn pair. If we - * don't find it, we default to the external PCI */ - bridge_node = NULL; - node = find_pci_device_OFnode(bus, dev_fn & 0xf8); - if (node) { - /* note: we don't stop on the first occurence since we need to go - * up to the root bridge */ - do { - if (node->type && !strcmp(node->type, "pci") - && device_is_compatible(node, "uni-north")) - bridge_node = node; - node=node->parent; - } while (node); - } - if (bridge_node) { - int i; - for (i=0;i<uninorth_count;i++) - if (uninorth_bridges[i].node == bridge_node) { - bridge = i; - break; - } - } - - if (bridge == -1) { - printk(KERN_WARNING "pmac_pci: no default bridge !\n"); - return 0; - } - - return bridge; -} - -__pmac -void * -pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical) -{ - int bridge = -1; - if (uninorth_count != 0) - bridge = pmac_pci_dev_root_bridge(bus, devfn); - if (bridge == -1) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return 0; - return physical ? (void *) bp->io_base_phys : bp->io_base; + /* Lookup the "bus-range" property for the hose */ + bus_range = (int *) get_property(bridge, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s\n", + bridge->full_name); + return; } - return physical ? (void *) uninorth_bridges[bridge].iobase_phys - : uninorth_bridges[bridge].iobase; -} - -__pmac -void * -pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn) -{ - return 0; + bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]); } -/* This function only works for bus 0, uni-N uses a different mecanism for - * other busses (see below) +/* + * Apple MacRISC (UniNorth, Bandit) PCI controllers. + * + * The "Bandit" version is present in all early PCI PowerMacs, + * and up to the first ones using Grackle. Some machines may + * have 2 bandit controllers (2 PCI busses). + * + * The "UniNorth" version is present in all Core99 machines + * (iBook, G4, new IMacs, and all the recent Apple machines). + * It contains 3 controllers in one ASIC. */ -#define UNI_N_CFA0(devfn, off) \ + +#define MACRISC_CFA0(devfn, off) \ ((1 << (unsigned long)PCI_SLOT(dev_fn)) \ | (((unsigned long)PCI_FUNC(dev_fn)) << 8) \ | (((unsigned long)(off)) & 0xFCUL)) -/* This one is for type 1 config accesses */ -#define UNI_N_CFA1(bus, devfn, off) \ +#define MACRISC_CFA1(bus, devfn, off) \ ((((unsigned long)(bus)) << 16) \ |(((unsigned long)(devfn)) << 8) \ |(((unsigned long)(off)) & 0xFCUL) \ |1UL) -__pmac static -unsigned int -uni_north_access_data(unsigned char bus, unsigned char dev_fn, - unsigned char offset) +static unsigned int __pmac +macrisc_cfg_access(struct pci_controller* hose, u8 bus, u8 dev_fn, u8 offset) { - int bridge; unsigned int caddr; - - bridge = pmac_pci_dev_root_bridge(bus, dev_fn); - if (bus == 0) - caddr = UNI_N_CFA0(dev_fn, offset); - else - caddr = UNI_N_CFA1(bus, dev_fn, offset); - - if (bridge == -1) { - printk(KERN_WARNING "pmac_pci: no default bridge !\n"); - return 0; - } - - /* Uninorth will return garbage if we don't read back the value ! */ - out_le32(uninorth_bridges[bridge].cfg_addr, caddr); - (void)in_le32(uninorth_bridges[bridge].cfg_addr); - /* Yes, offset is & 7, not & 3 ! */ - return (unsigned int)(uninorth_bridges[bridge].cfg_data) + (offset & 0x07); -} - -__pmac -int uni_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - unsigned int addr; - - *val = 0xff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_8((volatile unsigned char*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - unsigned int addr; - - *val = 0xffff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_le16((volatile unsigned short*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - unsigned int addr; - *val = 0xffff; - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - *val = in_le32((volatile unsigned int*)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_8((volatile unsigned char *)addr, val); - (void)in_8((volatile unsigned char *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le16((volatile unsigned short *)addr, val); - (void)in_le16((volatile unsigned short *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int uni_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - unsigned int addr; - - addr = uni_north_access_data(bus, dev_fn, offset); - if (!addr) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32((volatile unsigned int *)addr, val); - (void)in_le32((volatile unsigned int *)addr); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - struct bridge_data *bp; - - *val = 0xff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* Bus number once again taken into consideration. - * Change applied from 2.1.24. This makes devices located - * behind PCI-PCI bridges visible. - * -Ranjit Deshpande, 01/20/99 - */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - *val = in_8(bp->cfg_data + (offset & 3)); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - struct bridge_data *bp; - - *val = 0xffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3))); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - struct bridge_data *bp; - - *val = 0xffffffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + offset); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + offset + 1); - } - udelay(2); - *val = in_le32((volatile unsigned int *)bp->cfg_data); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if (bus == bp->bus_number) { +#ifdef DEBUG +// printk("macrisc_config_access(hose: 0x%08lx, bus: 0x%x, devfb: 0x%x, offset: 0x%x)\n", +// hose, bus, dev_fn, offset); +#endif + if (bus == hose->first_busno) { if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_8(bp->cfg_data + (offset & 3), val); - return PCIBIOS_SUCCESSFUL; -} - -__pmac -int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - struct bridge_data *bp; + return 0; + caddr = MACRISC_CFA0(dev_fn, offset); + } else + caddr = MACRISC_CFA1(bus, dev_fn, offset); + + /* Uninorth will return garbage if we don't read back the value ! */ + do { + out_le32(hose->cfg_addr, caddr); + } while(in_le32(hose->cfg_addr) != caddr); + + offset &= has_uninorth ? 0x07 : 0x03; + return (unsigned int)(hose->cfg_data) + (unsigned int)offset; +} + +#define cfg_read(val, addr, type, op, op2) \ + *val = op((type)(addr)) +#define cfg_write(val, addr, type, op, op2) \ + op((type *)(addr), (val)); (void) op2((type *)(addr)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define MACRISC_PCI_OP(rw, size, type, op, op2) \ +static int __pmac \ +macrisc_##rw##_config_##size(struct pci_dev *dev, int off, type val) \ +{ \ + struct pci_controller *hose = dev->sysdata; \ + unsigned int addr; \ + \ + addr = macrisc_cfg_access(hose, dev->bus->number, dev->devfn, off); \ + if (!addr) { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, addr, type, op, op2); \ + return PCIBIOS_SUCCESSFUL; \ +} + +MACRISC_PCI_OP(read, byte, u8 *, in_8, x) +MACRISC_PCI_OP(read, word, u16 *, in_le16, x) +MACRISC_PCI_OP(read, dword, u32 *, in_le32, x) +MACRISC_PCI_OP(write, byte, u8, out_8, in_8) +MACRISC_PCI_OP(write, word, u16, out_le16, in_le16) +MACRISC_PCI_OP(write, dword, u32, out_le32, in_le32) + +static struct pci_ops macrisc_pci_ops = +{ + macrisc_read_config_byte, + macrisc_read_config_word, + macrisc_read_config_dword, + macrisc_write_config_byte, + macrisc_write_config_word, + macrisc_write_config_dword +}; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + (offset & ~3)); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_le16((volatile unsigned short *)(bp->cfg_data + (offset & 3)), val); - return PCIBIOS_SUCCESSFUL; -} -__pmac -int pmac_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +/* + * Apple "Chaos" PCI controller. + * + * This controller is present on some first generation "PowerSurge" + * machines (8500, 8600, ...). It's a very weird beast and will die + * in flames if we try to probe the config space. + * The long-term solution is to provide a config space "emulation" + * based on what we find in OF device tree + */ + +static int chaos_config_read_byte(struct pci_dev *dev, int offset, u8 *val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (bus == bp->bus_number) { - if (dev_fn < (11 << 3)) - return PCIBIOS_DEVICE_NOT_FOUND; - out_le32(bp->cfg_addr, - (1UL << (dev_fn >> 3)) + ((dev_fn & 7) << 8) - + offset); - } else { - /* See pci_read_config_byte */ - out_le32(bp->cfg_addr, (bus << 16) + (dev_fn << 8) + (offset & ~3) + 1); - } - udelay(2); - out_le32((volatile unsigned int *)bp->cfg_data, val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ - | (((o) & ~3) << 24)) - -int grackle_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) +static int chaos_config_read_word(struct pci_dev *dev, int offset, u16 *val) { - struct bridge_data *bp; - - *val = 0xff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_8(bp->cfg_data + (offset & 3)); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) +static int chaos_config_read_dword(struct pci_dev *dev, int offset, u32 *val) { - struct bridge_data *bp; - - *val = 0xffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_le16((volatile unsigned short *)(bp->cfg_data + (offset&3))); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) +static int chaos_config_write_byte(struct pci_dev *dev, int offset, u8 val) { - struct bridge_data *bp; - - *val = 0xffffffff; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 3) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - *val = in_le32((volatile unsigned int *)bp->cfg_data); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) +static int chaos_config_write_word(struct pci_dev *dev, int offset, u16 val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_8(bp->cfg_data + (offset & 3), val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) +static int chaos_config_write_dword(struct pci_dev *dev, int offset, u32 val) { - struct bridge_data *bp; - - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_le16((volatile unsigned short *)(bp->cfg_data + (offset&3)), val); - return PCIBIOS_SUCCESSFUL; + return PCIBIOS_DEVICE_NOT_FOUND; } -int grackle_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) +static struct pci_ops chaos_pci_ops = { - struct bridge_data *bp; + chaos_config_read_byte, + chaos_config_read_word, + chaos_config_read_dword, + chaos_config_write_byte, + chaos_config_write_word, + chaos_config_write_dword +}; - if (bus > max_bus || (bp = bridges[bus]) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; - if ((offset & 1) != 0) - return PCIBIOS_BAD_REGISTER_NUMBER; - out_be32(bp->cfg_addr, GRACKLE_CFA(bus, dev_fn, offset)); - out_le32((volatile unsigned int *)bp->cfg_data, val); - return PCIBIOS_SUCCESSFUL; -} /* * For a bandit bridge, turn on cache coherency if necessary. - * N.B. we can't use pcibios_*_config_* here because bridges[] - * is not initialized yet. + * N.B. we could clean this up using the hose ops directly. */ -static void __init init_bandit(struct bridge_data *bp) +static void __init init_bandit(struct pci_controller *bp) { unsigned int vendev, magic; int rev; @@ -543,8 +258,8 @@ static void __init init_bandit(struct bridge_data *bp) rev = in_8(bp->cfg_data); if (rev != BANDIT_REVID) printk(KERN_WARNING - "Unknown revision %d for bandit at %p\n", - rev, bp->io_base); + "Unknown revision %d for bandit at %08lx\n", + rev, bp->io_base_phys); } else if (vendev != (BANDIT_DEVID_2 << 16) + APPLE_VENDID) { printk(KERN_WARNING "bandit isn't? (%x)\n", vendev); return; @@ -555,8 +270,8 @@ static void __init init_bandit(struct bridge_data *bp) udelay(2); rev = in_8(bp->cfg_data); if (rev != BANDIT_REVID) - printk(KERN_WARNING "Unknown revision %d for bandit at %p\n", - rev, bp->io_base); + printk(KERN_WARNING "Unknown revision %d for bandit at %08lx\n", + rev, bp->io_base_phys); /* read the word at offset 0x50 */ out_le32(bp->cfg_addr, (1UL << BANDIT_DEVNUM) + BANDIT_MAGIC); @@ -567,16 +282,71 @@ static void __init init_bandit(struct bridge_data *bp) magic |= BANDIT_COHERENT; udelay(2); out_le32((volatile unsigned int *)bp->cfg_data, magic); - printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %p\n", - bp->io_base); + printk(KERN_INFO "Cache coherency enabled for bandit/PSX at %08lx\n", + bp->io_base_phys); +} + + +/* + * Tweak the PCI-PCI bridge chip on the blue & white G3s. + */ +static void __init +init_p2pbridge(void) +{ + struct device_node *p2pbridge; + struct pci_controller* hose; + u8 bus, devfn; + u16 val; + + /* XXX it would be better here to identify the specific + PCI-PCI bridge chip we have. */ + if ((p2pbridge = find_devices("pci-bridge")) == 0 + || p2pbridge->parent == NULL + || strcmp(p2pbridge->parent->name, "pci") != 0) + return; + if (pci_device_from_OF_node(p2pbridge, &bus, &devfn) < 0) { +#ifdef DEBUG + printk("Can't find PCI infos for PCI<->PCI bridge\n"); +#endif + return; + } + /* Warning: At this point, we have not yet renumbered all busses. + * So we must use OF walking to find out hose + */ + hose = pci_find_hose_for_OF_device(p2pbridge); + if (!hose) { +#ifdef DEBUG + printk("Can't find hose for PCI<->PCI bridge\n"); +#endif + return; + } + if (early_read_config_word(hose, bus, devfn, + PCI_BRIDGE_CONTROL, &val) < 0) { + printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); + return; + } + val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; + early_write_config_word(hose, bus, devfn, PCI_BRIDGE_CONTROL, val); } +void __init +pmac_find_bridges(void) +{ + add_bridges(find_devices("bandit")); + add_bridges(find_devices("chaos")); + add_bridges(find_devices("pci")); + init_p2pbridge(); +} + +#define GRACKLE_CFA(b, d, o) (0x80 | ((b) << 8) | ((d) << 16) \ + | (((o) & ~3) << 24)) + #define GRACKLE_PICR1_STG 0x00000040 #define GRACKLE_PICR1_LOOPSNOOP 0x00000010 /* N.B. this is called before bridges is initialized, so we can't use grackle_pcibios_{read,write}_config_dword. */ -static inline void grackle_set_stg(struct bridge_data *bp, int enable) +static inline void grackle_set_stg(struct pci_controller* bp, int enable) { unsigned int val; @@ -586,9 +356,10 @@ static inline void grackle_set_stg(struct bridge_data *bp, int enable) (val & ~GRACKLE_PICR1_STG); out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); out_le32((volatile unsigned int *)bp->cfg_data, val); + (void)in_le32((volatile unsigned int *)bp->cfg_data); } -static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable) +static inline void grackle_set_loop_snoop(struct pci_controller *bp, int enable) { unsigned int val; @@ -598,25 +369,68 @@ static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable) (val & ~GRACKLE_PICR1_LOOPSNOOP); out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8)); out_le32((volatile unsigned int *)bp->cfg_data, val); + (void)in_le32((volatile unsigned int *)bp->cfg_data); } +static void __init +setup_uninorth(struct pci_controller* hose, struct reg_property* addr) +{ + pci_assign_all_busses = 1; + has_uninorth = 1; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + /* is 0x10000 enough for io space ? */ + hose->io_base_virt = (void *)ioremap(addr->address, 0x10000); + + /* XXX This is the bridge with the PCI expansion bus. We route + * legacy IOs to it. + */ + if (addr->address == 0xf2000000) + isa_io_base = (unsigned long)hose->io_base_virt; +} -void __init pmac_find_bridges(void) +static void __init +setup_bandit(struct pci_controller* hose, struct reg_property* addr) { - int bus; - struct bridge_data *bridge; + hose->ops = ¯isc_pci_ops; + hose->cfg_addr = (volatile unsigned int *) + ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = (volatile unsigned char *) + ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); + init_bandit(hose); +} - bridge_list = 0; - max_bus = 0; - add_bridges(find_devices("bandit")); - add_bridges(find_devices("chaos")); - add_bridges(find_devices("pci")); - bridges = (struct bridge_data **) - alloc_bootmem((max_bus + 1) * sizeof(struct bridge_data *)); - memset(bridges, 0, (max_bus + 1) * sizeof(struct bridge_data *)); - for (bridge = bridge_list; bridge != NULL; bridge = bridge->next) - for (bus = bridge->bus_number; bus <= bridge->max_bus; ++bus) - bridges[bus] = bridge; +static void __init +setup_chaos(struct pci_controller* hose, struct reg_property* addr) +{ + /* assume a `chaos' bridge */ + hose->ops = &chaos_pci_ops; + hose->cfg_addr = (volatile unsigned int *) + ioremap(addr->address + 0x800000, 0x1000); + hose->cfg_data = (volatile unsigned char *) + ioremap(addr->address + 0xc00000, 0x1000); + hose->io_base_phys = addr->address; + hose->io_base_virt = (void *) ioremap(addr->address, 0x10000); +} + +void __init +setup_grackle(struct pci_controller *hose, unsigned io_space_size) +{ + setup_indirect_pci(hose, 0xfec00000, 0xfee00000); + hose->io_base_phys = 0xfe000000; + hose->io_base_virt = (void *) ioremap(0xfe000000, io_space_size); + pci_dram_offset = 0; + isa_mem_base = 0xfd000000; + isa_io_base = (unsigned long) hose->io_base_virt; + if (machine_is_compatible("AAPL,PowerBook1998")) + grackle_set_loop_snoop(hose, 1); +#if 0 /* Disabled for now, HW problems ??? */ + grackle_set_stg(hose, 1); +#endif } /* @@ -626,11 +440,12 @@ void __init pmac_find_bridges(void) */ static void __init add_bridges(struct device_node *dev) { - int *bus_range; int len; - struct bridge_data *bp; + struct pci_controller *hose; struct reg_property *addr; - + char* disp_name; + int *bus_range; + for (; dev != NULL; dev = dev->next) { addr = (struct reg_property *) get_property(dev, "reg", &len); if (addr == NULL || len < sizeof(*addr)) { @@ -640,108 +455,52 @@ static void __init add_bridges(struct device_node *dev) } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { - printk(KERN_WARNING "Can't get bus-range for %s\n", - dev->full_name); - continue; - } - if (bus_range[1] == bus_range[0]) - printk(KERN_INFO "PCI bus %d", bus_range[0]); - else - printk(KERN_INFO "PCI buses %d..%d", bus_range[0], - bus_range[1]); - printk(" controlled by %s at %x\n", dev->name, addr->address); - if (device_is_compatible(dev, "uni-north")) { - int i = uninorth_count++; - uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000); - uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000); - uninorth_bridges[i].node = dev; - uninorth_bridges[i].iobase_phys = addr->address; - /* is 0x10000 enough for io space ? */ - uninorth_bridges[i].iobase = (void *)ioremap(addr->address, 0x10000); - /* XXX This is the bridge with the PCI expansion bus. This is also the - * address of the bus that will receive type 1 config accesses and io - * accesses. Appears to be correct for iMac DV and G4 Sawtooth too. - * That means that we cannot do io cycles on the AGP bus nor the internal - * ethernet/fw bus. Fortunately, they appear not to be needed on iMac DV - * and G4 neither. - */ - if (addr->address == 0xf2000000) - uninorth_default = i; - else - continue; + printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n", + dev->full_name); } - bp = (struct bridge_data *) alloc_bootmem(sizeof(*bp)); + hose = pcibios_alloc_controller(); + if (!hose) + continue; + hose->arch_data = dev; + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + + disp_name = NULL; if (device_is_compatible(dev, "uni-north")) { - bp->cfg_addr = 0; - bp->cfg_data = 0; - bp->io_base = uninorth_bridges[uninorth_count-1].iobase; - bp->io_base_phys = uninorth_bridges[uninorth_count-1].iobase_phys; + setup_uninorth(hose, addr); + disp_name = "UniNorth"; } else if (strcmp(dev->name, "pci") == 0) { /* XXX assume this is a mpc106 (grackle) */ - bp->cfg_addr = (volatile unsigned int *) - ioremap(0xfec00000, 0x1000); - bp->cfg_data = (volatile unsigned char *) - ioremap(0xfee00000, 0x1000); - bp->io_base_phys = 0xfe000000; - bp->io_base = (void *) ioremap(0xfe000000, 0x20000); - if (machine_is_compatible("AAPL,PowerBook1998")) - grackle_set_loop_snoop(bp, 1); -#if 0 /* Disabled for now, HW problems ??? */ - grackle_set_stg(bp, 1); -#endif - } else { - /* a `bandit' or `chaos' bridge */ - bp->cfg_addr = (volatile unsigned int *) - ioremap(addr->address + 0x800000, 0x1000); - bp->cfg_data = (volatile unsigned char *) - ioremap(addr->address + 0xc00000, 0x1000); - bp->io_base_phys = addr->address; - bp->io_base = (void *) ioremap(addr->address, 0x10000); + setup_grackle(hose, 0x20000); + disp_name = "Grackle (MPC106)"; + } else if (strcmp(dev->name, "bandit") == 0) { + setup_bandit(hose, addr); + disp_name = "Bandit"; + } else if (strcmp(dev->name, "chaos") == 0) { + setup_chaos(hose, addr); + disp_name = "Chaos"; } + printk(KERN_INFO "Found %s PCI host bridge at 0x%08x. Firmware bus number: %d->%d\n", + disp_name, addr->address, hose->first_busno, hose->last_busno); +#ifdef DEBUG + printk(" ->Hose at 0x%08lx, cfg_addr=0x%08lx,cfg_data=0x%08lx\n", + hose, hose->cfg_addr, hose->cfg_data); +#endif + + /* Setup a default isa_io_base */ if (isa_io_base == 0) - isa_io_base = (unsigned long) bp->io_base; - bp->bus_number = bus_range[0]; - bp->max_bus = bus_range[1]; - bp->next = bridge_list; - bp->node = dev; - bridge_list = bp; - if (bp->max_bus > max_bus) - max_bus = bp->max_bus; - - if (strcmp(dev->name, "bandit") == 0) - init_bandit(bp); - } -} - -/* Recursively searches any node that is of type PCI-PCI bridge. Without - * this, the old code would miss children of P2P bridges and hence not - * fix IRQ's for cards located behind P2P bridges. - * - Ranjit Deshpande, 01/20/99 - */ -void __init -fix_intr(struct device_node *node, struct pci_dev *dev) -{ - unsigned int *reg, *class_code; + isa_io_base = (unsigned long)hose->io_base_virt; - for (; node != 0;node = node->sibling) { - class_code = (unsigned int *) get_property(node, "class-code", 0); - if(class_code && (*class_code >> 8) == PCI_CLASS_BRIDGE_PCI) - fix_intr(node->child, dev); - reg = (unsigned int *) get_property(node, "reg", 0); - if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn) - continue; - /* this is the node, see if it has interrupts */ - if (node->n_intrs > 0) - dev->irq = node->intrs[0].line; - break; + /* Fixup "bus-range" OF property */ + fixup_bus_range(dev); } } -void __init -pmac_pcibios_fixup(void) -{ - struct pci_dev *dev; +static void +pcibios_fixup_OF_interrupts(void) +{ + struct pci_dev* dev; /* * FIXME: This is broken: We should not assign IRQ's to IRQless @@ -757,44 +516,43 @@ pmac_pcibios_fixup(void) * should find the device node and se if it has an * AAPL,interrupts property. */ - struct bridge_data *bp = bridges[dev->bus->number]; unsigned char pin; + struct device_node* node; - if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || - !pin) + if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) || !pin) continue; /* No interrupt generated -> no fixup */ - /* We iterate all instances of uninorth for now */ - if (uninorth_count && dev->bus->number == 0) { - int i; - for (i=0;i<uninorth_count;i++) - fix_intr(uninorth_bridges[i].node->child, dev); - } else - fix_intr(bp->node->child, dev); + node = pci_device_to_OF_node(dev); + if (!node) { + printk("No OF node for device %x:%x\n", dev->bus->number, dev->devfn >> 3); + continue; + } + /* this is the node, see if it has interrupts */ + if (node->n_intrs > 0) + dev->irq = node->intrs[0].line; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); } } void __init -pmac_setup_pci_ptrs(void) +pmac_pcibios_fixup(void) { - struct device_node* np; + /* Fixup interrupts according to OF tree */ + pcibios_fixup_OF_interrupts(); +} - np = find_devices("pci"); - if (np != 0) - { - if (device_is_compatible(np, "uni-north")) - { - /* looks like an Core99 powermac */ - set_config_access_method(uni); - } else - { - /* looks like a G3 powermac */ - set_config_access_method(grackle); - } - } else - { - set_config_access_method(pmac); +/* We don't want to enable USB controllers absent from the OF tree + * (iBook second controller) + */ +int +pmac_pci_enable_device_hook(struct pci_dev *dev, int initial) +{ + if (dev->vendor == PCI_VENDOR_ID_APPLE + && dev->device == PCI_DEVICE_ID_APPLE_KL_USB) { + struct device_node* node; + node = pci_device_to_OF_node(dev); + if (!node) + return -EINVAL; } - - ppc_md.pcibios_fixup = pmac_pcibios_fixup; + return 0; } diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c index efd7674826f3..a9a1777caf41 100644 --- a/arch/ppc/kernel/pmac_pic.c +++ b/arch/ppc/kernel/pmac_pic.c @@ -4,14 +4,15 @@ #include <linux/sched.h> #include <linux/signal.h> #include <linux/pci.h> -#include <linux/openpic.h> #include <asm/init.h> #include <asm/io.h> #include <asm/smp.h> #include <asm/prom.h> #include <asm/pci-bridge.h> + #include "pmac_pic.h" +#include "open_pic.h" /* pmac */struct pmac_irq_hw { unsigned int flag; @@ -30,16 +31,14 @@ static volatile struct pmac_irq_hw *pmac_irq_hw[4] = { static int max_irqs; static int max_real_irqs; -static int has_openpic = 0; +static int pmac_has_openpic; + +spinlock_t pmac_pic_lock = SPIN_LOCK_UNLOCKED; + #define GATWICK_IRQ_POOL_SIZE 10 static struct interrupt_info gatwick_int_pool[GATWICK_IRQ_POOL_SIZE]; -extern int pmac_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val); -extern int pmac_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val); - /* * Mark an irq as "lost". This is only used on the pmac * since it can lose interrupts (see pmac_set_irq_mask). @@ -51,48 +50,11 @@ void __pmac __no_use_set_lost(unsigned long irq_nr) atomic_inc(&ppc_n_lost_interrupts); } -static void pmac_openpic_mask_irq(unsigned int irq_nr) -{ - openpic_disable_irq(irq_nr); -} - -static void pmac_openpic_unmask_irq(unsigned int irq_nr) -{ - openpic_enable_irq(irq_nr); -} - -static void pmac_openpic_ack_irq(unsigned int irq_nr) -{ - if ((irq_desc[irq_nr].status & IRQ_LEVEL) == 0) - openpic_eoi(smp_processor_id()); - openpic_disable_irq(irq_nr); -} - -static void pmac_openpic_end_irq(unsigned int irq_nr) -{ - if ((irq_desc[irq_nr].status & IRQ_LEVEL) != 0) - openpic_eoi(smp_processor_id()); - openpic_enable_irq(irq_nr); -} - -struct hw_interrupt_type pmac_open_pic = { - " OpenPIC ", - NULL, - NULL, - pmac_openpic_unmask_irq, - pmac_openpic_mask_irq, - /* Theorically, the mask&ack should be NULL for OpenPIC. However, doing - * so shows tons of bogus interrupts coming in. - */ - pmac_openpic_ack_irq, - pmac_openpic_end_irq, - NULL -}; - static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; + unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; @@ -100,6 +62,7 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) clear_bit(irq_nr, ppc_cached_irq_mask); if (test_and_clear_bit(irq_nr, ppc_lost_interrupts)) atomic_dec(&ppc_n_lost_interrupts); + spin_lock_irqsave(&pmac_pic_lock, flags); out_le32(&pmac_irq_hw[i]->ack, bit); out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); out_le32(&pmac_irq_hw[i]->ack, bit); @@ -108,16 +71,19 @@ static void __pmac pmac_mask_and_ack_irq(unsigned int irq_nr) interrupts */ mb(); } while(in_le32(&pmac_irq_hw[i]->flag) & bit); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_set_irq_mask(unsigned int irq_nr) { unsigned long bit = 1UL << (irq_nr & 0x1f); int i = irq_nr >> 5; + unsigned long flags; if ((unsigned)irq_nr >= max_irqs) return; + spin_lock_irqsave(&pmac_pic_lock, flags); /* enable unmasked interrupts */ out_le32(&pmac_irq_hw[i]->enable, ppc_cached_irq_mask[i]); @@ -137,6 +103,7 @@ static void __pmac pmac_set_irq_mask(unsigned int irq_nr) && (ld_le32(&pmac_irq_hw[i]->level) & bit) && !(ld_le32(&pmac_irq_hw[i]->flag) & bit)) __set_lost((ulong)irq_nr); + spin_unlock_irqrestore(&pmac_pic_lock, flags); } static void __pmac pmac_mask_irq(unsigned int irq_nr) @@ -152,6 +119,15 @@ static void __pmac pmac_unmask_irq(unsigned int irq_nr) pmac_set_irq_mask(irq_nr); } +static void __pmac pmac_end_irq(unsigned int irq_nr) +{ + if (!(irq_desc[irq_nr].status & (IRQ_DISABLED|IRQ_INPROGRESS))) { + set_bit(irq_nr, ppc_cached_irq_mask); + pmac_set_irq_mask(irq_nr); + } +} + + struct hw_interrupt_type pmac_pic = { " PMAC-PIC ", NULL, @@ -159,7 +135,7 @@ struct hw_interrupt_type pmac_pic = { pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - pmac_unmask_irq, + pmac_end_irq, NULL }; @@ -170,7 +146,7 @@ struct hw_interrupt_type gatwick_pic = { pmac_unmask_irq, pmac_mask_irq, pmac_mask_and_ack_irq, - pmac_unmask_irq, + pmac_end_irq, NULL }; @@ -204,35 +180,22 @@ pmac_get_irq(struct pt_regs *regs) unsigned long bits = 0; #ifdef CONFIG_SMP - void pmac_smp_message_recv(struct pt_regs *); + void psurge_smp_message_recv(struct pt_regs *); - /* IPI's are a hack on the powersurge -- Cort */ - if ( smp_processor_id() != 0 ) - { - pmac_smp_message_recv(regs); + /* IPI's are a hack on the powersurge -- Cort */ + if ( smp_processor_id() != 0 ) { + psurge_smp_message_recv(regs); return -2; /* ignore, already handled */ } #endif /* CONFIG_SMP */ - - if (has_openpic) { - irq = openpic_irq(smp_processor_id()); - if (irq == OPENPIC_VEC_SPURIOUS) - /* We get those when doing polled ADB requests, - * using -2 is a temp hack to disable the printk - */ - irq = -2; /*-1; */ - } - else - { - for (irq = max_real_irqs; (irq -= 32) >= 0; ) { - int i = irq >> 5; - bits = ld_le32(&pmac_irq_hw[i]->flag) - | ppc_lost_interrupts[i]; - if (bits == 0) - continue; - irq += __ilog2(bits); - break; - } + for (irq = max_real_irqs; (irq -= 32) >= 0; ) { + int i = irq >> 5; + bits = ld_le32(&pmac_irq_hw[i]->flag) + | ppc_lost_interrupts[i]; + if (bits == 0) + continue; + irq += __ilog2(bits); + break; } return irq; @@ -336,11 +299,16 @@ static void __init enable_second_ohare(void) addr = (unsigned long) ioremap(irqctrler->addrs[0].address, 0x40); pmac_irq_hw[1] = (volatile struct pmac_irq_hw *)(addr + 0x20); max_irqs = 64; - if (pci_device_loc(irqctrler, &bus, &devfn) == 0) { - pmac_pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - cmd &= ~PCI_COMMAND_IO; - pmac_pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd); + if (pci_device_from_OF_node(irqctrler, &bus, &devfn) == 0) { + struct pci_controller* hose = pci_find_hose_for_OF_device(irqctrler); + if (!hose) + printk(KERN_ERR "Can't find PCI hose for OHare2 !\n"); + else { + early_read_config_word(hose, bus, devfn, PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + cmd &= ~PCI_COMMAND_IO; + early_write_config_word(hose, bus, devfn, PCI_COMMAND, cmd); + } } second_irq = irqctrler->intrs[0].line; @@ -378,20 +346,26 @@ pmac_pic_init(void) printk("PowerMac using OpenPIC irq controller\n"); if (irqctrler->n_addrs > 0) { + int nmi_irq = -1; + unsigned char senses[NR_IRQS]; #ifdef CONFIG_XMON struct device_node* pswitch; -#endif /* CONFIG_XMON */ - OpenPIC = (volatile struct OpenPIC *) - ioremap(irqctrler->addrs[0].address, - irqctrler->addrs[0].size); - for ( i = 0 ; i < NR_IRQS ; i++ ) - irq_desc[i].handler = &pmac_open_pic; - openpic_init(1); - has_openpic = 1; -#ifdef CONFIG_XMON + pswitch = find_devices("programmer-switch"); if (pswitch && pswitch->n_intrs) - request_irq(pswitch->intrs[0].line, xmon_irq, 0, + nmi_irq = pswitch->intrs[0].line; +#endif /* CONFIG_XMON */ + prom_get_irq_senses(senses, 0, NR_IRQS); + OpenPIC_InitSenses = senses; + OpenPIC_NumInitSenses = NR_IRQS; + ppc_md.get_irq = openpic_get_irq; + OpenPIC_Addr = ioremap(irqctrler->addrs[0].address, + irqctrler->addrs[0].size); + openpic_init(1, 0, 0, nmi_irq); + pmac_has_openpic = 1; +#ifdef CONFIG_XMON + if (nmi_irq >= 0) + request_irq(nmi_irq, xmon_irq, 0, "NMI - XMON", 0); #endif /* CONFIG_XMON */ return; diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c index b5bf03abc34e..e7be1114e95a 100644 --- a/arch/ppc/kernel/pmac_setup.c +++ b/arch/ppc/kernel/pmac_setup.c @@ -47,6 +47,7 @@ #include <linux/cuda.h> #include <linux/pmu.h> +#include <asm/processor.h> #include <asm/init.h> #include <asm/prom.h> #include <asm/system.h> @@ -73,7 +74,8 @@ extern unsigned long pmac_get_rtc_time(void); extern int pmac_set_rtc_time(unsigned long nowtime); extern void pmac_read_rtc_time(void); extern void pmac_calibrate_decr(void); -extern void pmac_setup_pci_ptrs(void); +extern void pmac_pcibios_fixup(void); +extern void pmac_find_bridges(void); extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int mackbd_getkeycode(unsigned int scancode); @@ -99,9 +101,7 @@ extern char pckbd_unexpected_up(unsigned char keycode); extern int keyboard_sends_linux_keycodes; extern void pmac_nvram_update(void); -extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical); -extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn); -extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn); +extern int pmac_pci_enable_device_hook(struct pci_dev *dev, int initial); unsigned char drive_info; @@ -119,13 +119,34 @@ extern int pmac_newworld; extern void zs_kgdb_hook(int tty_num); static void ohare_init(void); -static void init_p2pbridge(void); #ifdef CONFIG_BOOTX_TEXT void pmac_progress(char *s, unsigned short hex); #endif sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN; +#ifdef CONFIG_SMP +volatile static long int core99_l2_cache; +void core99_init_l2(void) +{ + int cpu = smp_processor_id(); + + if ( (_get_PVR() >> 16) != 8 && (_get_PVR() >> 16) != 12 ) + return; + + if (cpu == 0){ + core99_l2_cache = _get_L2CR(); + printk("CPU0: L2CR is %lx\n", core99_l2_cache); + } else { + printk("CPU%d: L2CR was %lx\n", cpu, _get_L2CR()); + _set_L2CR(0); + _set_L2CR(core99_l2_cache); + printk("CPU%d: L2CR set to %lx\n", cpu, core99_l2_cache); + } +} +#endif /* CONFIG_SMP */ + + __pmac int pmac_get_cpuinfo(char *buffer) @@ -250,7 +271,7 @@ pmac_setup_arch(void) struct device_node *cpu; int *fp; - /* Set loops_per_sec to a half-way reasonable value, + /* Set loops_per_jiffy to a half-way reasonable value, for use until calibrate_delay gets called. */ cpu = find_type_devices("cpu"); if (cpu != 0) { @@ -263,13 +284,13 @@ pmac_setup_arch(void) case 10: /* mach V (604ev5) */ case 12: /* G4 */ case 20: /* 620 */ - loops_per_sec = *fp; + loops_per_jiffy = *fp / HZ; break; default: /* 601, 603, etc. */ - loops_per_sec = *fp / 2; + loops_per_jiffy = *fp / (2*HZ); } } else - loops_per_sec = 50000000; + loops_per_jiffy = 50000000 / HZ; } /* this area has the CPU identification register @@ -278,8 +299,8 @@ pmac_setup_arch(void) __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); + /* Lookup PCI hosts */ pmac_find_bridges(); - init_p2pbridge(); /* Checks "l2cr-value" property in the registry */ if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) { @@ -303,6 +324,11 @@ pmac_setup_arch(void) ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled"); +#ifdef CONFIG_SMP + /* somewhat of a hack */ + core99_init_l2(); +#endif + #ifdef CONFIG_KGDB zs_kgdb_hook(0); #endif @@ -330,32 +356,6 @@ pmac_setup_arch(void) ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE); } -/* - * Tweak the PCI-PCI bridge chip on the blue & white G3s. - */ -static void __init init_p2pbridge(void) -{ - struct device_node *p2pbridge; - unsigned char bus, devfn; - unsigned short val; - - /* XXX it would be better here to identify the specific - PCI-PCI bridge chip we have. */ - if ((p2pbridge = find_devices("pci-bridge")) == 0 - || p2pbridge->parent == NULL - || strcmp(p2pbridge->parent->name, "pci") != 0) - return; - if (pci_device_loc(p2pbridge, &bus, &devfn) < 0) - return; - if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) { - printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); - return; - } - val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; - ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val); - ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val); -} - static void __init ohare_init(void) { /* @@ -448,7 +448,7 @@ kdev_t __init find_ide_boot(void) void __init find_boot_device(void) { -#ifdef CONFIG_SCSI +#if defined(CONFIG_SCSI) && defined(CONFIG_BLK_DEV_SD) if (boot_host != NULL) { boot_dev = sd_find_target(boot_host, boot_target); if (boot_dev != 0) @@ -493,7 +493,9 @@ pmac_restart(char *cmd) struct adb_request req; #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_NVRAM pmac_nvram_update(); +#endif switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA @@ -509,7 +511,7 @@ pmac_restart(char *cmd) pmu_restart(); break; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } } @@ -520,7 +522,9 @@ pmac_power_off(void) struct adb_request req; #endif /* CONFIG_ADB_CUDA */ +#ifdef CONFIG_NVRAM pmac_nvram_update(); +#endif switch (sys_ctrler) { #ifdef CONFIG_ADB_CUDA @@ -536,7 +540,7 @@ pmac_power_off(void) pmu_shutdown(); break; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } } @@ -566,17 +570,19 @@ pmac_ide_outsw(ide_ioreg_t port, void *buf, int ns) int pmac_ide_default_irq(ide_ioreg_t base) { - return 0; -} - #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) -extern ide_ioreg_t pmac_ide_get_base(int index); + extern int pmac_ide_get_irq(ide_ioreg_t base); + return pmac_ide_get_irq(base); +#else + return 0; #endif +} ide_ioreg_t pmac_ide_default_io_base(int index) { #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) + extern ide_ioreg_t pmac_ide_get_base(int index); return pmac_ide_get_base(index); #else return 0; @@ -586,7 +592,14 @@ pmac_ide_default_io_base(int index) int pmac_ide_check_region(ide_ioreg_t from, unsigned int extent) { - return 0; + /* + * We only do the check_region if `from' looks like a genuine + * I/O port number. If it actually refers to a memory-mapped + * register, it should be OK. + */ + if (from < ~_IO_BASE) + return 0; + return check_region(from, extent); } void @@ -594,24 +607,16 @@ pmac_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) { + if (from < ~_IO_BASE) + request_region(from, extent, name); } void pmac_ide_release_region(ide_ioreg_t from, unsigned int extent) { -} - -/* Convert the shorts/longs in hd_driveid from little to big endian; - * chars are endian independant, of course, but strings need to be flipped. - * (Despite what it says in drivers/block/ide.h, they come up as little - * endian...) - * - * Changes to linux/hdreg.h may require changes here. */ -void -pmac_ide_fix_driveid(struct hd_driveid *id) -{ - ppc_generic_ide_fix_driveid(id); + if (from < ~_IO_BASE) + release_region(from, extent); } #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) @@ -632,8 +637,6 @@ void __init pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { - pmac_setup_pci_ptrs(); - /* isa_io_base gets set in pmac_find_bridges */ isa_mem_base = PMAC_ISA_MEM_BASE; pci_dram_offset = PMAC_PCI_DRAM_OFFSET; @@ -646,8 +649,11 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_cpuinfo = pmac_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = pmac_pic_init; - ppc_md.get_irq = pmac_get_irq; + ppc_md.get_irq = pmac_get_irq; /* Changed later on ... */ ppc_md.init = pmac_init2; + + ppc_md.pcibios_fixup = pmac_pcibios_fixup; + ppc_md.pcibios_enable_device_hook = pmac_pci_enable_device_hook; ppc_md.restart = pmac_restart; ppc_md.power_off = pmac_power_off; @@ -658,12 +664,8 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.get_rtc_time = pmac_get_rtc_time; ppc_md.calibrate_decr = pmac_calibrate_decr; - ppc_md.pci_dev_io_base = pmac_pci_dev_io_base; - ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base; - ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge; - #ifdef CONFIG_VT -#ifdef CONFIG_INPUT_ADBHID +#ifdef CONFIG_INPUT ppc_md.kbd_init_hw = mac_hid_init_hw; ppc_md.kbd_translate = mac_hid_kbd_translate; ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up; @@ -682,35 +684,33 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, } #endif /* CONFIG_MAGIC_SYSRQ */ #elif defined(CONFIG_ADB_KEYBOARD) - ppc_md.kbd_setkeycode = mackbd_setkeycode; - ppc_md.kbd_getkeycode = mackbd_getkeycode; - ppc_md.kbd_translate = mackbd_translate; - ppc_md.kbd_unexpected_up = mackbd_unexpected_up; - ppc_md.kbd_leds = mackbd_leds; - ppc_md.kbd_init_hw = mackbd_init_hw; + ppc_md.kbd_setkeycode = mackbd_setkeycode; + ppc_md.kbd_getkeycode = mackbd_getkeycode; + ppc_md.kbd_translate = mackbd_translate; + ppc_md.kbd_unexpected_up = mackbd_unexpected_up; + ppc_md.kbd_leds = mackbd_leds; + ppc_md.kbd_init_hw = mackbd_init_hw; #ifdef CONFIG_MAGIC_SYSRQ - ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; + ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate; SYSRQ_KEY = 0x69; #endif /* CONFIG_MAGIC_SYSRQ */ #endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */ #endif /* CONFIG_VT */ #if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC) - ppc_ide_md.insw = pmac_ide_insw; - ppc_ide_md.outsw = pmac_ide_outsw; - ppc_ide_md.default_irq = pmac_ide_default_irq; - ppc_ide_md.default_io_base = pmac_ide_default_io_base; - ppc_ide_md.ide_check_region = pmac_ide_check_region; - ppc_ide_md.ide_request_region = pmac_ide_request_region; - ppc_ide_md.ide_release_region = pmac_ide_release_region; - ppc_ide_md.fix_driveid = pmac_ide_fix_driveid; - ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; - - ppc_ide_md.io_base = _IO_BASE; /* actually too early for this :-( */ -#endif + ppc_ide_md.insw = pmac_ide_insw; + ppc_ide_md.outsw = pmac_ide_outsw; + ppc_ide_md.default_irq = pmac_ide_default_irq; + ppc_ide_md.default_io_base = pmac_ide_default_io_base; + ppc_ide_md.ide_check_region = pmac_ide_check_region; + ppc_ide_md.ide_request_region = pmac_ide_request_region; + ppc_ide_md.ide_release_region = pmac_ide_release_region; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = pmac_ide_init_hwif_ports; +#endif /* CONFIG_BLK_DEV_IDE && CONFIG_BLK_DEV_IDE_PMAC */ #ifdef CONFIG_BOOTX_TEXT ppc_md.progress = pmac_progress; -#endif +#endif /* CONFIG_BOOTX_TEXT */ if (ppc_md.progress) ppc_md.progress("pmac_init(): exit", 0); } @@ -727,5 +727,5 @@ pmac_progress(char *s, unsigned short hex) prom_drawstring(s); prom_drawchar('\n'); } -#endif CONFIG_BOOTX_TEXT +#endif /* CONFIG_BOOTX_TEXT */ diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c index 00b6302a76e9..46d067e81a78 100644 --- a/arch/ppc/kernel/pmac_time.c +++ b/arch/ppc/kernel/pmac_time.c @@ -114,7 +114,7 @@ unsigned long pmac_get_rtc_time(void) + (req.reply[3] << 8) + req.reply[4]; return now - RTC_OFFSET; #endif /* CONFIG_ADB_PMU */ - default: + default: ; } return 0; } @@ -135,7 +135,7 @@ int pmac_set_rtc_time(unsigned long nowtime) return 0; while (!req.complete) cuda_poll(); -// if (req.reply_len != 7) + if ((req.reply_len != 3) && (req.reply_len != 7)) printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n", req.reply_len); return 1; diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h index 42b8c9c39469..59c377c4d419 100644 --- a/arch/ppc/kernel/ppc_asm.h +++ b/arch/ppc/kernel/ppc_asm.h @@ -50,7 +50,7 @@ */ #define LVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1) #define STVX(r,a,b) .long (31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1) -#define MFVSCR(r) .long (4<<26)+((r)<<21)+(1540<<1) +#define MFVSCR(r) .long (4<<26)+((r)<<21)+(770<<1) #define MTVSCR(r) .long (4<<26)+((r)<<11)+(802<<1) #define SAVE_VR(n,b,base) li b,THREAD_VR0+(16*(n)); STVX(n,b,base) @@ -66,9 +66,13 @@ #define REST_16VR(n,b,base) REST_8VR(n,b,base); REST_8VR(n+8,b,base) #define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) +#ifdef CONFIG_PPC601_SYNC_FIX #define SYNC \ sync; \ isync +#else +#define SYNC +#endif /* * This instruction is not implemented on the PPC 603 or 601; however, on diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c index 32f99ce0e191..9768f2890203 100644 --- a/arch/ppc/kernel/ppc_htab.c +++ b/arch/ppc/kernel/ppc_htab.c @@ -555,10 +555,7 @@ int proc_dol2crvec(ctl_table *table, int write, struct file *filp, break; buffer += len; left -= len; - _set_L2CR(0); _set_L2CR(val); - while ( _get_L2CR() & 0x1 ) - /* wait for invalidate to finish */; } else { p = buf; diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 827e3754047d..6de2d94fe226 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c @@ -12,6 +12,7 @@ #include <linux/console.h> #include <linux/irq.h> #include <linux/pci.h> +#include <linux/delay.h> #include <asm/page.h> #include <asm/semaphore.h> @@ -40,6 +41,7 @@ #include <asm/backlight.h> #ifdef CONFIG_SMP #include <asm/smplock.h> +#include <asm/smp.h> #endif /* CONFIG_SMP */ #include <asm/time.h> @@ -53,9 +55,10 @@ extern void MachineCheckException(struct pt_regs *regs); extern void AlignmentException(struct pt_regs *regs); extern void ProgramCheckException(struct pt_regs *regs); extern void SingleStepException(struct pt_regs *regs); -extern int sys_sigreturn(struct pt_regs *regs); extern void do_lost_interrupts(unsigned long); extern int do_signal(sigset_t *, struct pt_regs *); +extern int pmac_newworld; +extern int sys_sigreturn(struct pt_regs *regs); long long __ashrdi3(long long, int); long long __ashldi3(long long, int); @@ -98,10 +101,6 @@ EXPORT_SYMBOL(_prep_type); EXPORT_SYMBOL(ucSystemType); #endif #endif -#ifdef CONFIG_PCI -EXPORT_SYMBOL(pci_dev_io_base); -EXPORT_SYMBOL(pci_dev_mem_base); -#endif #if !__INLINE_BITOPS EXPORT_SYMBOL(set_bit); @@ -125,6 +124,7 @@ EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strncmp); +EXPORT_SYMBOL(strcasecmp); /* EXPORT_SYMBOL(csum_partial); already in net/netsyms.c */ EXPORT_SYMBOL(csum_partial_copy_generic); @@ -202,6 +202,10 @@ EXPORT_SYMBOL(_read_lock); EXPORT_SYMBOL(_read_unlock); EXPORT_SYMBOL(_write_lock); EXPORT_SYMBOL(_write_unlock); +EXPORT_SYMBOL(smp_call_function); +EXPORT_SYMBOL(smp_hw_index); +EXPORT_SYMBOL(smp_num_cpus); +EXPORT_SYMBOL(synchronize_irq); #endif #ifndef CONFIG_MACH_SPECIFIC @@ -234,12 +238,14 @@ EXPORT_SYMBOL(pmu_enable_irled); #ifdef CONFIG_PMAC_BACKLIGHT EXPORT_SYMBOL(get_backlight_level); EXPORT_SYMBOL(set_backlight_level); +EXPORT_SYMBOL(set_backlight_enable); +EXPORT_SYMBOL(register_backlight_controller); #endif /* CONFIG_PMAC_BACKLIGHT */ -#if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL_NOVERS(sys_ctrler); #ifndef CONFIG_MACH_SPECIFIC EXPORT_SYMBOL_NOVERS(have_of); #endif /* CONFIG_MACH_SPECIFIC */ +#if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); EXPORT_SYMBOL(find_compatible_devices); @@ -247,18 +253,29 @@ EXPORT_SYMBOL(find_path_device); EXPORT_SYMBOL(find_phandle); EXPORT_SYMBOL(device_is_compatible); EXPORT_SYMBOL(machine_is_compatible); -EXPORT_SYMBOL(find_pci_device_OFnode); EXPORT_SYMBOL(find_all_nodes); EXPORT_SYMBOL(get_property); -EXPORT_SYMBOL(pci_io_base); -EXPORT_SYMBOL(pci_device_loc); +EXPORT_SYMBOL(pci_bus_io_base); +EXPORT_SYMBOL(pci_bus_io_base_phys); +EXPORT_SYMBOL(pci_bus_mem_base_phys); +EXPORT_SYMBOL(pci_device_to_OF_node); +EXPORT_SYMBOL(pci_device_from_OF_node); +EXPORT_SYMBOL(pci_bus_to_hose); +EXPORT_SYMBOL(pci_resource_to_bus); +EXPORT_SYMBOL(pci_phys_to_bus); +EXPORT_SYMBOL(pci_bus_to_phys); +EXPORT_SYMBOL(pmac_newworld); EXPORT_SYMBOL(feature_set); EXPORT_SYMBOL(feature_clear); EXPORT_SYMBOL(feature_test); EXPORT_SYMBOL(feature_set_gmac_power); +EXPORT_SYMBOL(feature_set_gmac_phy_reset); EXPORT_SYMBOL(feature_set_usb_power); EXPORT_SYMBOL(feature_set_firewire_power); #endif /* defined(CONFIG_ALL_PPC) */ +#if defined(CONFIG_BOOTX_TEXT) +EXPORT_SYMBOL(bootx_update_display); +#endif #if defined(CONFIG_SCSI) && defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(note_scsi_host); #endif @@ -286,6 +303,7 @@ EXPORT_SYMBOL(abs); EXPORT_SYMBOL(screen_info); #endif +EXPORT_SYMBOL(__delay); EXPORT_SYMBOL(int_control); EXPORT_SYMBOL(timer_interrupt_intercept); EXPORT_SYMBOL(timer_interrupt); @@ -300,6 +318,10 @@ EXPORT_SYMBOL(console_lock); #ifdef CONFIG_XMON EXPORT_SYMBOL(xmon); #endif +EXPORT_SYMBOL(__up); +EXPORT_SYMBOL(__down); +EXPORT_SYMBOL(__down_interruptible); +EXPORT_SYMBOL(__down_trylock); EXPORT_SYMBOL(down_read_failed); EXPORT_SYMBOL(down_write_failed); @@ -324,6 +346,12 @@ EXPORT_SYMBOL(do_softirq); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); EXPORT_SYMBOL(mmu_context_overflow); +#if !defined(CONFIG_8xx) && !defined(CONFIG_4xx) +extern long *intercept_table; +EXPORT_SYMBOL(intercept_table); +#endif +extern long *ret_from_intercept; +EXPORT_SYMBOL(ret_from_intercept); #ifdef CONFIG_MOL extern ulong mol_interface[]; diff --git a/arch/ppc/kernel/prep_nvram.c b/arch/ppc/kernel/prep_nvram.c index c3dcdea07f05..3d34a853f678 100644 --- a/arch/ppc/kernel/prep_nvram.c +++ b/arch/ppc/kernel/prep_nvram.c @@ -16,19 +16,9 @@ #include <asm/machdep.h> #include <asm/prep_nvram.h> -/* - * Allow for a maximum of 32K of PReP NvRAM data - */ -#define MAX_PREP_NVRAM 0x8000 static char nvramData[MAX_PREP_NVRAM]; static NVRAM_MAP *nvram=(NVRAM_MAP *)&nvramData[0]; -#define PREP_NVRAM_AS0 0x74 -#define PREP_NVRAM_AS1 0x75 -#define PREP_NVRAM_DATA 0x77 - -unsigned char *rs_pcNvRAM; - unsigned char __prep prep_nvram_read_val(int addr) { outb(addr, PREP_NVRAM_AS0); @@ -44,20 +34,6 @@ void __prep prep_nvram_write_val(int addr, outb(val, PREP_NVRAM_DATA); } -/* - * Most Radstone boards have NvRAM memory mapped at offset 8M in ISA space - */ -unsigned char __prep rs_nvram_read_val(int addr) -{ - return rs_pcNvRAM[addr]; -} - -void __prep rs_nvram_write_val(int addr, - unsigned char val) -{ - rs_pcNvRAM[addr]=val; -} - void __init init_prep_nvram(void) { unsigned char *nvp; @@ -65,16 +41,6 @@ void __init init_prep_nvram(void) int nvramSize; /* - * I'm making the assumption that 32k will always cover the - * nvramsize. If this isn't the case please let me know and we can - * map the header, then get the size from the header, then map - * the whole size. -- Cort - */ - if ( _prep_type == _PREP_Radstone ) - rs_pcNvRAM = (unsigned char *)ioremap(_ISA_MEM_BASE+0x00800000, - 32<<10); - request_region(PREP_NVRAM_AS0, 0x8, "PReP NVRAM"); - /* * The following could fail if the NvRAM were corrupt but * we expect the boot firmware to have checked its checksum * before boot diff --git a/arch/ppc/kernel/prep_pci.c b/arch/ppc/kernel/prep_pci.c index fd14fc483f64..633521c4a86d 100644 --- a/arch/ppc/kernel/prep_pci.c +++ b/arch/ppc/kernel/prep_pci.c @@ -11,7 +11,6 @@ #include <linux/pci.h> #include <linux/kernel.h> #include <linux/init.h> -#include <linux/openpic.h> #include <asm/init.h> #include <asm/byteorder.h> @@ -25,6 +24,7 @@ #include <asm/machdep.h> #include "pci.h" +#include "open_pic.h" #define MAX_DEVNR 22 @@ -39,9 +39,6 @@ unsigned char *Motherboard_routes; /* Used for Motorola to store system config register */ static unsigned long *ProcInfo; -extern int chrp_get_irq(struct pt_regs *); -extern void chrp_post_irq(struct pt_regs* regs, int); - /* Tables for known hardware */ /* Motorola PowerStackII - Utah */ @@ -534,128 +531,45 @@ static char Nobis_pci_IRQ_routes[] __prepdata = { #define CFGPTR(dev) (0x80800000 | (1<<(dev>>3)) | ((dev&7)<<8) | offset) #define DEVNO(dev) (dev>>3) -__prep -int -prep_pcibios_read_config_dword (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned int *val) -{ - unsigned long _val; - unsigned long *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFFFFFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned long *)CFGPTR(dev); - _val = le32_to_cpu(*ptr); - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_read_config_word (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned short *val) -{ - unsigned short _val; - unsigned short *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFFFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned short *)CFGPTR(dev); - _val = le16_to_cpu(*ptr); - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_read_config_byte (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned char *val) -{ - unsigned char _val; - unsigned char *ptr; - - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - *val = 0xFF; - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned char *)CFGPTR(dev); - _val = *ptr; - } - *val = _val; - return PCIBIOS_SUCCESSFUL; -} - -__prep -int -prep_pcibios_write_config_dword (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned int val) -{ - unsigned long _val; - unsigned long *ptr; - - _val = le32_to_cpu(val); - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned long *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((type *)(addr), (val)) + +#define cfg_read_bad(val, size) *val = bad_##size; +#define cfg_write_bad(val, size) + +#define bad_byte 0xff +#define bad_word 0xffff +#define bad_dword 0xffffffffU + +#define PREP_PCI_OP(rw, size, type, op) \ +static int __prep \ +prep_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + if ((dev->bus->number != 0) || (DEVNO(dev->devfn) > MAX_DEVNR)) \ + { \ + cfg_##rw##_bad(val, size) \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + cfg_##rw(val, CFGPTR(dev->devfn), type, op); \ + return PCIBIOS_SUCCESSFUL; \ } -__prep -int -prep_pcibios_write_config_word (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned short val) -{ - unsigned short _val; - unsigned short *ptr; - - _val = le16_to_cpu(val); - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned short *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} +PREP_PCI_OP(read, byte, u8 *, in_8) +PREP_PCI_OP(read, word, u16 *, in_le16) +PREP_PCI_OP(read, dword, u32 *, in_le32) +PREP_PCI_OP(write, byte, u8, out_8) +PREP_PCI_OP(write, word, u16, out_le16) +PREP_PCI_OP(write, dword, u32, out_le32) -__prep -int -prep_pcibios_write_config_byte (unsigned char bus, - unsigned char dev, unsigned char offset, unsigned char val) +static struct pci_ops prep_pci_ops = { - unsigned char _val; - unsigned char *ptr; - - _val = val; - if ((bus != 0) || (DEVNO(dev) > MAX_DEVNR)) - { - return PCIBIOS_DEVICE_NOT_FOUND; - } else - { - ptr = (unsigned char *)CFGPTR(dev); - *ptr = _val; - } - return PCIBIOS_SUCCESSFUL; -} + prep_read_config_byte, + prep_read_config_word, + prep_read_config_dword, + prep_write_config_byte, + prep_write_config_word, + prep_write_config_dword +}; #define MOTOROLA_CPUTYPE_REG 0x800 #define MOTOROLA_BASETYPE_REG 0x803 @@ -685,7 +599,8 @@ static u_char mvme2600_openpic_initsenses[] __initdata = { #define MOT_HAWK_PRESENT 0x2 int prep_keybd_present = 1; -int MotMPIC = 0; +int MotMPIC; +int mot_multi; int __init raven_init(void) { @@ -695,18 +610,18 @@ int __init raven_init(void) /* Check to see if the Raven chip exists. */ if ( _prep_type != _PREP_Motorola) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Check to see if this board is a type that might have a Raven. */ if ((inb(MOTOROLA_CPUTYPE_REG) & 0xF0) != 0xE0) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Check the first PCI device to see if it is a Raven. */ - pcibios_read_config_dword(0, 0, PCI_VENDOR_ID, &devid); + early_read_config_dword(0, 0, 0, PCI_VENDOR_ID, &devid); switch (devid & 0xffff0000) { case MPIC_RAVEN_ID: @@ -716,33 +631,37 @@ int __init raven_init(void) MotMPIC = MOT_HAWK_PRESENT; break; default: - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Read the memory base register. */ - pcibios_read_config_dword(0, 0, PCI_BASE_ADDRESS_1, &pci_membase); + early_read_config_dword(0, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase); if (pci_membase == 0) { - OpenPIC = NULL; + OpenPIC_Addr = NULL; return 0; } /* Map the Raven MPIC registers to virtual memory. */ - OpenPIC = (struct OpenPIC *)ioremap(pci_membase+0xC0000000, 0x22000); + OpenPIC_Addr = ioremap(pci_membase+0xC0000000, 0x22000); OpenPIC_InitSenses = mvme2600_openpic_initsenses; OpenPIC_NumInitSenses = sizeof(mvme2600_openpic_initsenses); - ppc_md.get_irq = chrp_get_irq; - ppc_md.post_irq = chrp_post_irq; + ppc_md.get_irq = openpic_get_irq; /* If raven is present on Motorola store the system config register * for later use. */ ProcInfo = (unsigned long *)ioremap(0xfef80400, 4); + /* Indicate to system if this is a multiprocessor board */ + if (!(*ProcInfo & MOT_PROC2_BIT)) { + mot_multi = 1; + } + /* This is a hack. If this is a 2300 or 2400 mot board then there is * no keyboard controller and we have to indicate that. */ @@ -898,72 +817,8 @@ unsigned long __init prep_route_pci_interrupts(void) outb(pl_id|CAROLINA_IRQ_EDGE_MASK_HI, 0x04d1); pl_id=inb(0x04d1); /*printk("Hi mask now %#0x\n", pl_id);*/ - } else if ( _prep_type == _PREP_Radstone ) - { - unsigned char ucElcrM, ucElcrS; - - /* - * Set up edge/level - */ - switch(ucSystemType) - { - case RS_SYS_TYPE_PPC1: - { - if(ucBoardRevMaj<5) - { - ucElcrS=ELCRS_INT15_LVL; - } - else - { - ucElcrS=ELCRS_INT9_LVL | - ELCRS_INT11_LVL | - ELCRS_INT14_LVL | - ELCRS_INT15_LVL; - } - ucElcrM=ELCRM_INT5_LVL | ELCRM_INT7_LVL; - break; - } - - case RS_SYS_TYPE_PPC1a: - { - ucElcrS=ELCRS_INT9_LVL | - ELCRS_INT11_LVL | - ELCRS_INT14_LVL | - ELCRS_INT15_LVL; - ucElcrM=ELCRM_INT5_LVL; - break; - } - - case RS_SYS_TYPE_PPC2: - case RS_SYS_TYPE_PPC2a: - case RS_SYS_TYPE_PPC2ep: - case RS_SYS_TYPE_PPC4: - case RS_SYS_TYPE_PPC4a: - default: - { - ucElcrS=ELCRS_INT9_LVL | - ELCRS_INT10_LVL | - ELCRS_INT11_LVL | - ELCRS_INT14_LVL | - ELCRS_INT15_LVL; - ucElcrM=ELCRM_INT5_LVL | - ELCRM_INT7_LVL; - break; - } - } - - /* - * Write edge/level selection - */ - outb(ucElcrS, ISA8259_S_ELCR); - outb(ucElcrM, ISA8259_M_ELCR); - - /* - * Radstone boards have PCI interrupts all set up - * so leave well alone - */ - return 0; - } else + } + else { printk("No known machine pci routing!\n"); return -1; @@ -987,16 +842,10 @@ prep_pcibios_fixup(void) extern unsigned char *Motherboard_routes; unsigned char i; - if ( _prep_type == _PREP_Radstone ) - { - printk("Radstone boards require no PCI fixups\n"); - return; - } - prep_route_pci_interrupts(); printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name); - if (OpenPIC) { + if (OpenPIC_Addr) { /* PCI interrupts are controlled by the OpenPIC */ pci_for_each_dev(dev) { if (dev->bus->number == 0) { @@ -1018,7 +867,12 @@ prep_pcibios_fixup(void) for ( i = 0 ; i <= 5 ; i++ ) { - if ( dev->resource[i].start > 0x10000000 ) + /* + * Relocate PCI I/O resources if necessary so the + * standard 256MB BAT covers them. + */ + if ( (pci_resource_flags(dev, i) & IORESOURCE_IO) && + (dev->resource[i].start > 0x10000000) ) { printk("Relocating PCI address %lx -> %lx\n", dev->resource[i].start, @@ -1029,6 +883,8 @@ prep_pcibios_fixup(void) pci_write_config_dword(dev, PCI_BASE_ADDRESS_0+(i*0x4), dev->resource[i].start ); + dev->resource[i].end = + (dev->resource[i].end & 0x00FFFFFF) | 0x01000000; } } #if 0 @@ -1043,49 +899,50 @@ prep_pcibios_fixup(void) } } -decl_config_access_method(indirect); - void __init -prep_setup_pci_ptrs(void) +prep_find_bridges(void) { - PPC_DEVICE *hostbridge; - - printk("PReP architecture\n"); - if ( _prep_type == _PREP_Radstone ) - { - pci_config_address = (unsigned *)0x80000cf8; - pci_config_data = (char *)0x80000cfc; - set_config_access_method(indirect); - } - else - { - hostbridge = residual_find_device(PROCESSORDEVICE, NULL, - BridgeController, PCIBridge, -1, 0); - if (hostbridge && - hostbridge->DeviceId.Interface == PCIBridgeIndirect) { - PnP_TAG_PACKET * pkt; - set_config_access_method(indirect); - pkt = PnP_find_large_vendor_packet( + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PREP_ISA_MEM_BASE; + + printk("PReP architecture\n"); + { +#ifdef CONFIG_PREP_RESIDUAL + PPC_DEVICE *hostbridge; + + hostbridge = residual_find_device(PROCESSORDEVICE, NULL, + BridgeController, PCIBridge, -1, 0); + if (hostbridge && + hostbridge->DeviceId.Interface == PCIBridgeIndirect) { + PnP_TAG_PACKET * pkt; + pkt = PnP_find_large_vendor_packet( res->DevicePnPHeap+hostbridge->AllocatedOffset, 3, 0); - if(pkt) + if(pkt) { #define p pkt->L4_Pack.L4_Data.L4_PPCPack - pci_config_address= (unsigned *)ld_le32((unsigned *) p.PPCData); - pci_config_data= (unsigned char *)ld_le32((unsigned *) (p.PPCData+8)); - } + setup_indirect_pci(hose, + ld_le32((unsigned *) (p.PPCData)), + ld_le32((unsigned *) (p.PPCData+8))); + } else { - pci_config_address= (unsigned *) 0x80000cf8; - pci_config_data= (unsigned char *) 0x80000cfc; - } - } + setup_indirect_pci(hose, 0x80000cf8, 0x80000cfc); + } + } else +#endif /* CONFIG_PREP_RESIDUAL */ { - set_config_access_method(prep); - } - - } + hose->ops = &prep_pci_ops; + } + } ppc_md.pcibios_fixup = prep_pcibios_fixup; } diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c index 6e30462aafbb..64ad519cb604 100644 --- a/arch/ppc/kernel/prep_setup.c +++ b/arch/ppc/kernel/prep_setup.c @@ -32,7 +32,6 @@ #include <linux/console.h> #include <linux/timex.h> #include <linux/pci.h> -#include <linux/openpic.h> #include <linux/ide.h> #include <asm/init.h> @@ -48,8 +47,9 @@ #include <asm/prep_nvram.h> #include <asm/raven.h> #include <asm/keyboard.h> - +#include <asm/vga.h> #include <asm/time.h> + #include "local_irq.h" #include "i8259.h" #include "open_pic.h" @@ -84,7 +84,7 @@ extern void pckbd_leds(unsigned char leds); extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; -extern void prep_setup_pci_ptrs(void); +extern void prep_find_bridges(void); extern char saved_command_line[256]; int _prep_type; @@ -101,23 +101,23 @@ unsigned long empty_zero_page[1024]; extern PTE *Hash, *Hash_end; extern unsigned long Hash_size, Hash_mask; extern int probingmem; -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; #ifdef CONFIG_BLK_DEV_RAM extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ extern int rd_image_start; /* starting block # of image */ #endif -#ifdef CONFIG_VGA_CONSOLE -unsigned long vgacon_remap_base; -#endif int __prep prep_get_cpuinfo(char *buffer) { extern char *Motherboard_map_name; - int len, i; - + int len; +#ifdef CONFIG_PREP_RESIDUAL + int i; +#endif + #ifdef CONFIG_SMP #define CD(X) (cpu_data[n].X) #else @@ -190,7 +190,10 @@ prep_get_cpuinfo(char *buffer) } -no_l2: +no_l2: +#ifndef CONFIG_PREP_RESIDUAL + return len; +#else if ( res->ResidualLength == 0 ) return len; @@ -205,8 +208,8 @@ no_l2: res->Memories[i].SIMMSize); } len += sprintf(buffer+len,"\n"); - return len; +#endif } void __init @@ -214,11 +217,16 @@ prep_setup_arch(void) { extern char cmd_line[]; unsigned char reg; +#if 0 /* unused?? */ unsigned char ucMothMemType; unsigned char ucEquipPres1; +#endif /* init to some ~sane value until calibrate_delay() runs */ - loops_per_sec = 50000000; + loops_per_jiffy = 50000000; + + /* Lookup PCI host bridges */ + prep_find_bridges(); /* Set up floppy in PS/2 mode */ outb(0x09, SIO_CONFIG_RA); @@ -247,41 +255,6 @@ prep_setup_arch(void) *(unsigned char *)(0x8000081c) |= 3; ROOT_DEV = to_kdev_t(0x0802); /* sda2 */ break; - case _PREP_Radstone: - ROOT_DEV = to_kdev_t(0x0801); /* sda1 */ - - /* - * Determine system type - */ - ucMothMemType=inb(0x866); - ucEquipPres1=inb(0x80c); - - ucSystemType=((ucMothMemType&0x03)<<1) | - ((ucEquipPres1&0x80)>>7); - ucSystemType^=7; - - /* - * Determine board revision for use by - * rev. specific code - */ - ucBoardRev=inb(0x854); - ucBoardRevMaj=ucBoardRev>>5; - ucBoardRevMin=ucBoardRev&0x1f; - - /* - * Most Radstone boards have memory mapped NvRAM - */ - if((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj<5)) - { - ppc_md.nvram_read_val = prep_nvram_read_val; - ppc_md.nvram_write_val = prep_nvram_write_val; - } - else - { - ppc_md.nvram_read_val = rs_nvram_read_val; - ppc_md.nvram_write_val = rs_nvram_write_val; - } - break; } /* Read in NVRAM data */ @@ -341,12 +314,6 @@ prep_setup_arch(void) #endif /* CONFIG_SOUND_CS4232 */ /*print_residual_device_info();*/ - request_region(0x20,0x20,"pic1"); - request_region(0xa0,0x20,"pic2"); - request_region(0x00,0x20,"dma1"); - request_region(0x40,0x20,"timer"); - request_region(0x80,0x10,"dma page reg"); - request_region(0xc0,0x20,"dma2"); raven_init(); @@ -365,6 +332,7 @@ prep_setup_arch(void) */ void __init prep_res_calibrate_decr(void) { +#ifdef CONFIG_PREP_RESIDUAL unsigned long freq, divisor=4; freq = res->VitalProductData.ProcessorBusHz; @@ -372,6 +340,7 @@ void __init prep_res_calibrate_decr(void) (freq/divisor)/1000000, (freq/divisor)%1000000); tb_ticks_per_jiffy = freq / HZ / divisor; tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +#endif } /* @@ -585,15 +554,16 @@ prep_setup_residual(char *buffer) { int len = 0; - /* PREP's without residual data will give incorrect values here */ len += sprintf(len+buffer, "clock\t\t: "); +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength ) len += sprintf(len+buffer, "%ldMHz\n", (res->VitalProductData.ProcessorHz > 1024) ? res->VitalProductData.ProcessorHz>>20 : res->VitalProductData.ProcessorHz); else +#endif /* CONFIG_PREP_RESIDUAL */ len += sprintf(len+buffer, "???\n"); return len; @@ -640,19 +610,11 @@ prep_init_IRQ(void) { int i; - if (OpenPIC != NULL) { - for ( i = 16 ; i < 36 ; i++ ) - irq_desc[i].handler = &open_pic; - openpic_init(1); - } - - for ( i = 0 ; i < 16 ; i++ ) + if (OpenPIC_Addr != NULL) + openpic_init(1, NUM_8259_INTERRUPTS, 0, -1); + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) irq_desc[i].handler = &i8259_pic; - i8259_init(); -#ifdef CONFIG_SMP - request_irq(openpic_to_irq(OPENPIC_VEC_SPURIOUS), openpic_ipi_action, - 0, "IPI0", 0); -#endif /* CONFIG_SMP */ + i8259_init(); } #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) @@ -708,19 +670,14 @@ prep_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name) { - request_region(from, extent, name); + request_region(from, extent, name); } void __prep prep_ide_release_region(ide_ioreg_t from, unsigned int extent) { - release_region(from, extent); -} - -void __prep -prep_ide_fix_driveid(struct hd_driveid *id) -{ + release_region(from, extent); } void __init @@ -743,17 +700,52 @@ prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl } #endif +unsigned long *MotSave_SmpIar; +unsigned char *MotSave_CpusState[2]; + +void __init +prep_init2(void) +{ +#ifdef CONFIG_NVRAM + request_region(PREP_NVRAM_AS0, 0x8, "nvram"); +#endif + request_region(0x20,0x20,"pic1"); + request_region(0xa0,0x20,"pic2"); + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); +} + void __init prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { +#ifdef CONFIG_PREP_RESIDUAL + RESIDUAL *old_res = (RESIDUAL *)(r3 + KERNELBASE); + /* make a copy of residual data */ if ( r3 ) { memcpy((void *)res,(void *)(r3+KERNELBASE), sizeof(RESIDUAL)); + + /* These need to be saved for the Motorola Prep + * MVME4600 and Dual MTX boards. + */ + MotSave_SmpIar = &old_res->VitalProductData.SmpIar; + MotSave_CpusState[0] = &old_res->Cpus[0].CpuState; + MotSave_CpusState[1] = &old_res->Cpus[1].CpuState; } +#endif + /* Copy cmd_line parameters */ + if ( r6) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + isa_io_base = PREP_ISA_IO_BASE; isa_mem_base = PREP_ISA_MEM_BASE; pci_dram_offset = PREP_PCI_DRAM_OFFSET; @@ -762,29 +754,19 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, DMA_MODE_WRITE = 0x48; /* figure out what kind of prep workstation we are */ +#ifdef CONFIG_PREP_RESIDUAL if ( res->ResidualLength != 0 ) { if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) ) _prep_type = _PREP_IBM; - else if (!strncmp(res->VitalProductData.PrintableModel, - "Radstone",8)) - { - extern char *Motherboard_map_name; - - _prep_type = _PREP_Radstone; - Motherboard_map_name= - res->VitalProductData.PrintableModel; - } - else - _prep_type = _PREP_Motorola; + _prep_type = _PREP_Motorola; } else /* assume motorola if no residual (netboot?) */ +#endif { _prep_type = _PREP_Motorola; } - prep_setup_pci_ptrs(); - ppc_md.setup_arch = prep_setup_arch; ppc_md.setup_residual = prep_setup_residual; ppc_md.get_cpuinfo = prep_get_cpuinfo; @@ -792,40 +774,14 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_md.init_IRQ = prep_init_IRQ; /* this gets changed later on if we have an OpenPIC -- Cort */ ppc_md.get_irq = prep_get_irq; - ppc_md.init = NULL; + ppc_md.init = prep_init2; ppc_md.restart = prep_restart; ppc_md.power_off = prep_power_off; ppc_md.halt = prep_halt; ppc_md.time_init = NULL; - if (_prep_type == _PREP_Radstone) { - /* - * We require a direct restart as port 92 does not work on - * all Radstone boards - */ - ppc_md.restart = prep_direct_restart; - /* - * The RTC device used varies according to board type - */ - if(((ucSystemType==RS_SYS_TYPE_PPC1) && (ucBoardRevMaj>=5)) || - (ucSystemType==RS_SYS_TYPE_PPC1a)) - { - ppc_md.set_rtc_time = mk48t59_set_rtc_time; - ppc_md.get_rtc_time = mk48t59_get_rtc_time; - ppc_md.time_init = mk48t59_init; - } - else - { - ppc_md.set_rtc_time = mc146818_set_rtc_time; - ppc_md.get_rtc_time = mc146818_get_rtc_time; - } - /* - * Determine the decrementer rate from the residual data - */ - ppc_md.calibrate_decr = prep_res_calibrate_decr; - } - else if (_prep_type == _PREP_IBM) { + if (_prep_type == _PREP_IBM) { ppc_md.set_rtc_time = mc146818_set_rtc_time; ppc_md.get_rtc_time = mc146818_get_rtc_time; ppc_md.calibrate_decr = prep_calibrate_decr; @@ -845,7 +801,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5, ppc_ide_md.ide_check_region = prep_ide_check_region; ppc_ide_md.ide_request_region = prep_ide_request_region; ppc_ide_md.ide_release_region = prep_ide_release_region; - ppc_ide_md.fix_driveid = prep_ide_fix_driveid; + ppc_ide_md.fix_driveid = NULL; ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports; #endif ppc_ide_md.io_base = _IO_BASE; diff --git a/arch/ppc/kernel/proc_rtas.c b/arch/ppc/kernel/proc_rtas.c new file mode 100644 index 000000000000..2e81442048b4 --- /dev/null +++ b/arch/ppc/kernel/proc_rtas.c @@ -0,0 +1,784 @@ +/* + * arch/ppc/kernel/proc_rtas.c + * Copyright (C) 2000 Tilmann Bitterberg + * (tilmann@bitterberg.de) + * + * RTAS (Runtime Abstraction Services) stuff + * Intention is to provide a clean user interface + * to use the RTAS. + * + * TODO: + * Split off a header file and maybe move it to a different + * location. Write Documentation on what the /proc/rtas/ entries + * actually do. + */ + +#include <linux/errno.h> +#include <linux/sched.h> +#include <linux/proc_fs.h> +#include <linux/stat.h> +#include <linux/ctype.h> +#include <linux/time.h> +#include <linux/string.h> + +#include <asm/uaccess.h> +#include <asm/bitops.h> +#include <asm/processor.h> +#include <asm/io.h> +#include <asm/prom.h> +#include <asm/machdep.h> /* for ppc_md */ +#include <asm/time.h> + +/* Token for Sensors */ +#define KEY_SWITCH 0x0001 +#define ENCLOSURE_SWITCH 0x0002 +#define THERMAL_SENSOR 0x0003 +#define LID_STATUS 0x0004 +#define POWER_SOURCE 0x0005 +#define BATTERY_VOLTAGE 0x0006 +#define BATTERY_REMAINING 0x0007 +#define BATTERY_PERCENTAGE 0x0008 +#define EPOW_SENSOR 0x0009 +#define BATTERY_CYCLESTATE 0x000a +#define BATTERY_CHARGING 0x000b + +/* IBM specific sensors */ +#define IBM_SURVEILLANCE 0x2328 /* 9000 */ +#define IBM_FANRPM 0x2329 /* 9001 */ +#define IBM_VOLTAGE 0x232a /* 9002 */ +#define IBM_DRCONNECTOR 0x232b /* 9003 */ +#define IBM_POWERSUPPLY 0x232c /* 9004 */ +#define IBM_INTQUEUE 0x232d /* 9005 */ + +/* Status return values */ +#define SENSOR_CRITICAL_HIGH 13 +#define SENSOR_WARNING_HIGH 12 +#define SENSOR_NORMAL 11 +#define SENSOR_WARNING_LOW 10 +#define SENSOR_CRITICAL_LOW 9 +#define SENSOR_SUCCESS 0 +#define SENSOR_HW_ERROR -1 +#define SENSOR_BUSY -2 +#define SENSOR_NOT_EXIST -3 +#define SENSOR_DR_ENTITY -9000 + +/* Location Codes */ +#define LOC_SCSI_DEV_ADDR 'A' +#define LOC_SCSI_DEV_LOC 'B' +#define LOC_CPU 'C' +#define LOC_DISKETTE 'D' +#define LOC_ETHERNET 'E' +#define LOC_FAN 'F' +#define LOC_GRAPHICS 'G' +/* reserved / not used 'H' */ +#define LOC_IO_ADAPTER 'I' +/* reserved / not used 'J' */ +#define LOC_KEYBOARD 'K' +#define LOC_LCD 'L' +#define LOC_MEMORY 'M' +#define LOC_NV_MEMORY 'N' +#define LOC_MOUSE 'O' +#define LOC_PLANAR 'P' +#define LOC_OTHER_IO 'Q' +#define LOC_PARALLEL 'R' +#define LOC_SERIAL 'S' +#define LOC_DEAD_RING 'T' +#define LOC_RACKMOUNTED 'U' /* for _u_nit is rack mounted */ +#define LOC_VOLTAGE 'V' +#define LOC_SWITCH_ADAPTER 'W' +#define LOC_OTHER 'X' +#define LOC_FIRMWARE 'Y' +#define LOC_SCSI 'Z' + +/* Tokens for indicators */ +#define TONE_FREQUENCY 0x0001 /* 0 - 1000 (HZ)*/ +#define TONE_VOLUME 0x0002 /* 0 - 100 (%) */ +#define SYSTEM_POWER_STATE 0x0003 +#define WARNING_LIGHT 0x0004 +#define DISK_ACTIVITY_LIGHT 0x0005 +#define HEX_DISPLAY_UNIT 0x0006 +#define BATTERY_WARNING_TIME 0x0007 +#define CONDITION_CYCLE_REQUEST 0x0008 +#define SURVEILLANCE_INDICATOR 0x2328 /* 9000 */ +#define DR_ACTION 0x2329 /* 9001 */ +#define DR_INDICATOR 0x232a /* 9002 */ +/* 9003 - 9004: Vendor specific */ +#define GLOBAL_INTERRUPT_QUEUE 0x232d /* 9005 */ +/* 9006 - 9999: Vendor specific */ + +/* other */ +#define MAX_SENSORS 17 /* I only know of 17 sensors */ +#define MAX_LINELENGTH 256 +#define SENSOR_PREFIX "ibm,sensor-" +#define cel_to_fahr(x) ((x*9/5)+32) + + +/* Globals */ +static struct proc_dir_entry *proc_rtas; +static struct rtas_sensors sensors; +static struct device_node *rtas; +static unsigned long power_on_time = 0; /* Save the time the user set */ +static char progress_led[MAX_LINELENGTH]; + +static unsigned long rtas_tone_frequency = 1000; +static unsigned long rtas_tone_volume = 0; + +/* ****************STRUCTS******************************************* */ +struct individual_sensor { + unsigned int token; + unsigned int quant; +}; + +struct rtas_sensors { + struct individual_sensor sensor[MAX_SENSORS]; + unsigned int quant; +}; + +/* ****************************************************************** */ +/* Declarations */ +static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, + int count, int *eof, void *data); +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); + +static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, + size_t count, loff_t *ppos); +static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, + size_t count, loff_t *ppos); + +struct file_operations ppc_rtas_poweron_operations = { + read: ppc_rtas_poweron_read, + write: ppc_rtas_poweron_write +}; +struct file_operations ppc_rtas_progress_operations = { + read: ppc_rtas_progress_read, + write: ppc_rtas_progress_write +}; + +struct file_operations ppc_rtas_clock_operations = { + read: ppc_rtas_clock_read, + write: ppc_rtas_clock_write +}; + +struct file_operations ppc_rtas_tone_freq_operations = { + read: ppc_rtas_tone_freq_read, + write: ppc_rtas_tone_freq_write +}; +struct file_operations ppc_rtas_tone_volume_operations = { + read: ppc_rtas_tone_volume_read, + write: ppc_rtas_tone_volume_write +}; + +int ppc_rtas_find_all_sensors (void); +int ppc_rtas_process_sensor(struct individual_sensor s, int state, + int error, char * buf); +char * ppc_rtas_process_error(int error); +int get_location_code(struct individual_sensor s, char * buf); +int check_location_string (char *c, char * buf); +int check_location (char *c, int idx, char * buf); + +/* ****************************************************************** */ +/* MAIN */ +/* ****************************************************************** */ +void proc_rtas_init(void) +{ + struct proc_dir_entry *entry; + + rtas = find_devices("rtas"); + if ((rtas == 0) || (_machine != _MACH_chrp)) { + return; + } + + proc_rtas = proc_mkdir("rtas", 0); + if (proc_rtas == 0) + return; + + /* /proc/rtas entries */ + + entry = create_proc_entry("progress", S_IRUGO|S_IWUSR, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_progress_operations; + + entry = create_proc_entry("clock", S_IRUGO|S_IWUSR, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_clock_operations; + + entry = create_proc_entry("poweron", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_poweron_operations; + + create_proc_read_entry("sensors", S_IRUGO, proc_rtas, + ppc_rtas_sensor_read, NULL); + + entry = create_proc_entry("frequency", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_tone_freq_operations; + + entry = create_proc_entry("volume", S_IWUSR|S_IRUGO, proc_rtas); + if (entry) entry->proc_fops = &ppc_rtas_tone_volume_operations; +} + +/* ****************************************************************** */ +/* POWER-ON-TIME */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_poweron_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct rtc_time tm; + unsigned long nowtime; + char *dest; + int error; + + nowtime = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_poweron_write: Invalid time\n"); + return count; + } + power_on_time = nowtime; /* save the time */ + + to_tm(nowtime, &tm); + + error = call_rtas("set-time-for-power-on", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, 0 /* nano */); + if (error != 0) + printk(KERN_WARNING "error: setting poweron time returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_poweron_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + if (power_on_time == 0) + n = sprintf(buf, "Power on time not set\n"); + else + n = sprintf(buf, "%lu\n", power_on_time); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* PROGRESS */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_progress_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long hex; + + strcpy(progress_led, buf); /* save the string */ + /* Lets see if the user passed hexdigits */ + hex = simple_strtoul(buf, NULL, 10); + + ppc_md.progress ((char *)buf, hex); + return count; + + /* clear the line */ /* ppc_md.progress(" ", 0xffff);*/ +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n = 0; + if (progress_led != NULL) + n = sprintf (buf, "%s\n", progress_led); + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* CLOCK */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_clock_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + struct rtc_time tm; + unsigned long nowtime; + char *dest; + int error; + + nowtime = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_clock_write: Invalid time\n"); + return count; + } + + to_tm(nowtime, &tm); + error = call_rtas("set-time-of-day", 7, 1, NULL, + tm.tm_year, tm.tm_mon, tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, 0); + if (error != 0) + printk(KERN_WARNING "error: setting the clock returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_clock_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + unsigned int year, mon, day, hour, min, sec; + unsigned long *ret = kmalloc(4*8, GFP_KERNEL); + int n, error; + + error = call_rtas("get-time-of-day", 0, 8, ret); + + year = ret[0]; mon = ret[1]; day = ret[2]; + hour = ret[3]; min = ret[4]; sec = ret[5]; + + if (error != 0){ + printk(KERN_WARNING "error: reading the clock returned: %s\n", + ppc_rtas_process_error(error)); + n = sprintf (buf, "0"); + } else { + n = sprintf (buf, "%lu\n", mktime(year, mon, day, hour, min, sec)); + } + kfree(ret); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} + +/* ****************************************************************** */ +/* SENSOR STUFF */ +/* ****************************************************************** */ +static int ppc_rtas_sensor_read(char * buf, char ** start, off_t off, + int count, int *eof, void *data) +{ + int i,j,n; + unsigned long ret; + int state, error; + char buffer[MAX_LINELENGTH*MAX_SENSORS]; /* May not be enough */ + + if (count < 0) + return -EINVAL; + + n = sprintf ( buffer , "RTAS (RunTime Abstraction Services) Sensor Information\n"); + n += sprintf ( buffer+n, "Sensor\t\tValue\t\tCondition\tLocation\n"); + n += sprintf ( buffer+n, "********************************************************\n"); + + if (ppc_rtas_find_all_sensors() != 0) { + n += sprintf ( buffer+n, "\nNo sensors are available\n"); + goto return_string; + } + + for (i=0; i<sensors.quant; i++) { + j = sensors.sensor[i].quant; + /* A sensor may have multiple instances */ + while (j >= 0) { + error = call_rtas("get-sensor-state", 2, 2, &ret, + sensors.sensor[i].token, sensors.sensor[i].quant-j); + state = (int) ret; + n += ppc_rtas_process_sensor(sensors.sensor[i], state, error, buffer+n ); + n += sprintf (buffer+n, "\n"); + j--; + } /* while */ + } /* for */ + +return_string: + if (off >= strlen(buffer)) { + *eof = 1; + return 0; + } + if (n > strlen(buffer) - off) + n = strlen(buffer) - off; + if (n > count) + n = count; + else + *eof = 1; + memcpy(buf, buffer + off, n); + *start = buf; + return n; +} + +/* ****************************************************************** */ + +int ppc_rtas_find_all_sensors (void) +{ + unsigned long *utmp; + int len, i, j; + + utmp = (unsigned long *) get_property(rtas, "rtas-sensors", &len); + if (utmp == NULL) { + printk (KERN_ERR "error: could not get rtas-sensors\n"); + return 1; + } + + sensors.quant = len / 8; /* int + int */ + + for (i=0, j=0; j<sensors.quant; i+=2, j++) { + sensors.sensor[j].token = utmp[i]; + sensors.sensor[j].quant = utmp[i+1]; + } + return 0; +} + +/* ****************************************************************** */ +/* + * Builds a string of what rtas returned + */ +char * ppc_rtas_process_error(int error) +{ + switch (error) { + case SENSOR_CRITICAL_HIGH: + return "(critical high)"; + case SENSOR_WARNING_HIGH: + return "(warning high)"; + case SENSOR_NORMAL: + return "(normal)"; + case SENSOR_WARNING_LOW: + return "(warning low)"; + case SENSOR_CRITICAL_LOW: + return "(critical low)"; + case SENSOR_SUCCESS: + return "(read ok)"; + case SENSOR_HW_ERROR: + return "(hardware error)"; + case SENSOR_BUSY: + return "(busy)"; + case SENSOR_NOT_EXIST: + return "(non existant)"; + case SENSOR_DR_ENTITY: + return "(dr entity removed)"; + default: + return "(UNKNOWN)"; + } +} + +/* ****************************************************************** */ +/* + * Builds a string out of what the sensor said + */ + +int ppc_rtas_process_sensor(struct individual_sensor s, int state, + int error, char * buf) +{ + /* Defined return vales */ + const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t", "Mainenance" }; + const char * enclosure_switch[] = { "Closed", "Open" }; + const char * lid_status[] = { " ", "Open", "Closed" }; + const char * power_source[] = { "AC\t", "Battery", "AC & Battery" }; + const char * battery_remaining[] = { "Very Low", "Low", "Mid", "High" }; + const char * epow_sensor[] = { + "EPOW Reset", "Cooling warning", "Power warning", + "System shutdown", "System halt", "EPOW main enclosure", + "EPOW power off" }; + const char * battery_cyclestate[] = { "None", "In progress", "Requested" }; + const char * battery_charging[] = { "Charging", "Discharching", "No current flow" }; + const char * ibm_drconnector[] = { "Empty", "Present" }; + const char * ibm_intqueue[] = { "Disabled", "Enabled" }; + + int have_strings = 0; + int temperature = 0; + int unknown = 0; + int n = 0; + + /* What kind of sensor do we have here? */ + switch (s.token) { + case KEY_SWITCH: + n += sprintf(buf+n, "Key switch:\t"); + n += sprintf(buf+n, "%s\t", key_switch[state]); + have_strings = 1; + break; + case ENCLOSURE_SWITCH: + n += sprintf(buf+n, "Enclosure switch:\t"); + n += sprintf(buf+n, "%s\t", enclosure_switch[state]); + have_strings = 1; + break; + case THERMAL_SENSOR: + n += sprintf(buf+n, "Temp. (°C/°F):\t"); + temperature = 1; + break; + case LID_STATUS: + n += sprintf(buf+n, "Lid status:\t"); + n += sprintf(buf+n, "%s\t", lid_status[state]); + have_strings = 1; + break; + case POWER_SOURCE: + n += sprintf(buf+n, "Power source:\t"); + n += sprintf(buf+n, "%s\t", power_source[state]); + have_strings = 1; + break; + case BATTERY_VOLTAGE: + n += sprintf(buf+n, "Battery voltage:\t"); + break; + case BATTERY_REMAINING: + n += sprintf(buf+n, "Battery remaining:\t"); + n += sprintf(buf+n, "%s\t", battery_remaining[state]); + have_strings = 1; + break; + case BATTERY_PERCENTAGE: + n += sprintf(buf+n, "Battery percentage:\t"); + break; + case EPOW_SENSOR: + n += sprintf(buf+n, "EPOW Sensor:\t"); + n += sprintf(buf+n, "%s\t", epow_sensor[state]); + have_strings = 1; + break; + case BATTERY_CYCLESTATE: + n += sprintf(buf+n, "Battery cyclestate:\t"); + n += sprintf(buf+n, "%s\t", battery_cyclestate[state]); + have_strings = 1; + break; + case BATTERY_CHARGING: + n += sprintf(buf+n, "Battery Charging:\t"); + n += sprintf(buf+n, "%s\t", battery_charging[state]); + have_strings = 1; + break; + case IBM_SURVEILLANCE: + n += sprintf(buf+n, "Surveillance:\t"); + break; + case IBM_FANRPM: + n += sprintf(buf+n, "Fan (rpm):\t"); + break; + case IBM_VOLTAGE: + n += sprintf(buf+n, "Voltage (mv):\t"); + break; + case IBM_DRCONNECTOR: + n += sprintf(buf+n, "DR connector:\t"); + n += sprintf(buf+n, "%s\t", ibm_drconnector[state]); + have_strings = 1; + break; + case IBM_POWERSUPPLY: + n += sprintf(buf+n, "Powersupply:\t"); + break; + case IBM_INTQUEUE: + n += sprintf(buf+n, "Interrupt queue:\t"); + n += sprintf(buf+n, "%s\t", ibm_intqueue[state]); + have_strings = 1; + break; + default: + n += sprintf(buf+n, "Unkown sensor (type %d), ignoring it\n", + s.token); + unknown = 1; + have_strings = 1; + break; + } + if (have_strings == 0) { + if (temperature) { + n += sprintf(buf+n, "%4d /%4d\t", state, cel_to_fahr(state)); + } else + n += sprintf(buf+n, "%10d\t", state); + } + if (unknown == 0) { + n += sprintf ( buf+n, "%s\t", ppc_rtas_process_error(error)); + n += get_location_code(s, buf+n); + } + return n; +} + +/* ****************************************************************** */ + +int check_location (char *c, int idx, char * buf) +{ + int n = 0; + + switch (*(c+idx)) { + case LOC_PLANAR: + n += sprintf ( buf, "Planar #%c", *(c+idx+1)); + break; + case LOC_CPU: + n += sprintf ( buf, "CPU #%c", *(c+idx+1)); + break; + case LOC_FAN: + n += sprintf ( buf, "Fan #%c", *(c+idx+1)); + break; + case LOC_RACKMOUNTED: + n += sprintf ( buf, "Rack #%c", *(c+idx+1)); + break; + case LOC_VOLTAGE: + n += sprintf ( buf, "Voltage #%c", *(c+idx+1)); + break; + case LOC_LCD: + n += sprintf ( buf, "LCD #%c", *(c+idx+1)); + break; + case '.': + n += sprintf ( buf, "- %c", *(c+idx+1)); + default: + n += sprintf ( buf, "Unknown location"); + break; + } + return n; +} + + +/* ****************************************************************** */ +/* + * Format: + * ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ] + * the '.' may be an abbrevation + */ +int check_location_string (char *c, char *buf) +{ + int n=0,i=0; + + while (c[i]) { + if (isalpha(c[i]) || c[i] == '.') { + n += check_location(c, i, buf+n); + } + else if (c[i] == '/' || c[i] == '-') + n += sprintf(buf+n, " at "); + i++; + } + return n; +} + + +/* ****************************************************************** */ + +int get_location_code(struct individual_sensor s, char * buffer) +{ + char rstr[512], tmp[10], tmp2[10]; + int n=0, i=0, llen, len; + /* char *buf = kmalloc(MAX_LINELENGTH, GFP_KERNEL); */ + char *ret; + + static int pos = 0; /* remember position where buffer was */ + + /* construct the sensor number like 0003 */ + /* fill with zeros */ + n = sprintf(tmp, "%d", s.token); + len = strlen(tmp); + while (strlen(tmp) < 4) + n += sprintf (tmp+n, "0"); + + /* invert the string */ + while (tmp[i]) { + if (i<len) + tmp2[4-len+i] = tmp[i]; + else + tmp2[3-i] = tmp[i]; + i++; + } + tmp2[4] = '\0'; + + sprintf (rstr, SENSOR_PREFIX"%s", tmp2); + + ret = (char *) get_property(rtas, rstr, &llen); + + n=0; + if (ret[0] == '\0') + n += sprintf ( buffer+n, "--- ");/* does not have a location */ + else { + char t[50]; + ret += pos; + + n += check_location_string(ret, buffer + n); + n += sprintf ( buffer+n, " "); + /* see how many characters we have printed */ + sprintf ( t, "%s ", ret); + + pos += strlen(t); + if (pos >= llen) pos=0; + } + return n; +} +/* ****************************************************************** */ +/* INDICATORS - Tone Frequency */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_freq_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long freq; + char *dest; + int error; + freq = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_tone_freq_write: Invalid tone freqency\n"); + return count; + } + if (freq < 0) freq = 0; + rtas_tone_frequency = freq; /* save it for later */ + error = call_rtas("set-indicator", 3, 1, NULL, + TONE_FREQUENCY, 0, freq); + if (error != 0) + printk(KERN_WARNING "error: setting tone frequency returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + n = sprintf(buf, "%lu\n", rtas_tone_frequency); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} +/* ****************************************************************** */ +/* INDICATORS - Tone Volume */ +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_volume_write(struct file * file, const char * buf, + size_t count, loff_t *ppos) +{ + unsigned long volume; + char *dest; + int error; + volume = simple_strtoul(buf, &dest, 10); + if (*dest != '\0' && *dest != '\n') { + printk("ppc_rtas_tone_volume_write: Invalid tone volume\n"); + return count; + } + if (volume < 0) volume = 0; + if (volume > 100) volume = 100; + + rtas_tone_volume = volume; /* save it for later */ + error = call_rtas("set-indicator", 3, 1, NULL, + TONE_VOLUME, 0, volume); + if (error != 0) + printk(KERN_WARNING "error: setting tone volume returned: %s\n", + ppc_rtas_process_error(error)); + return count; +} +/* ****************************************************************** */ +static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, + size_t count, loff_t *ppos) +{ + int n; + n = sprintf(buf, "%lu\n", rtas_tone_volume); + + if (*ppos >= strlen(buf)) + return 0; + if (n > strlen(buf) - *ppos) + n = strlen(buf) - *ppos; + if (n > count) + n = count; + *ppos += n; + return n; +} diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index a200b1c788ee..c4c76adecad1 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -222,16 +222,17 @@ _switch_to(struct task_struct *prev, struct task_struct *new, giveup_fpu(prev); #ifdef CONFIG_ALTIVEC /* - * If the previous thread 1) has some altivec regs it wants saved - * (has bits in vrsave set) and 2) used altivec in the last quantum + * If the previous thread used altivec in the last quantum * (thus changing altivec regs) then save them. + * We used to check the VRSAVE register but not all apps + * set it, so we don't rely on it now (and in fact we need + * to save & restore VSCR even if VRSAVE == 0). -- paulus * * On SMP we always save/restore altivec regs just to avoid the * complexity of changing processors. * -- Cort */ - if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) && - prev->thread.vrsave ) + if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC))) giveup_altivec(prev); #endif /* CONFIG_ALTIVEC */ current_set[smp_processor_id()] = new; @@ -251,13 +252,15 @@ void show_regs(struct pt_regs * regs) { int i; - printk("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx\n", - regs->nip, regs->xer, regs->link, regs,regs->trap); + printk("NIP: %08lX XER: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx\n", + regs->nip, regs->xer, regs->link, regs->gpr[1], regs,regs->trap); printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n", regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0, regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0, regs->msr&MSR_IR ? 1 : 0, regs->msr&MSR_DR ? 1 : 0); + if (regs->trap == 0x300 || regs->trap == 0x600) + printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr); printk("TASK = %p[%d] '%s' ", current, current->pid, current->comm); printk("Last syscall: %ld ", current->thread.last_syscall); @@ -285,7 +288,7 @@ void show_regs(struct pt_regs * regs) printk("\n"); } } -out: +out: ; } void exit_thread(void) diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c index 5494f2f52dfd..f3b39c2225be 100644 --- a/arch/ppc/kernel/prom.c +++ b/arch/ppc/kernel/prom.c @@ -28,10 +28,11 @@ #include <asm/smp.h> #include <asm/bootx.h> #include <asm/system.h> -#include <asm/gemini.h> #include <asm/mmu.h> #include <asm/pgtable.h> #include <asm/bitops.h> +/* for openpic_to_irq */ +#include "open_pic.h" #ifdef CONFIG_FB #include <asm/linux_logo.h> @@ -95,26 +96,28 @@ static interpret_func interpret_root_props; #define FB_MAX 8 #endif char *prom_display_paths[FB_MAX] __initdata = { 0, }; -unsigned int prom_num_displays = 0; -char *of_stdout_device = 0; +unsigned int prom_num_displays __initdata = 0; +char *of_stdout_device __initdata = 0; +ihandle prom_disp_node __initdata = 0; -prom_entry prom = 0; -ihandle prom_chosen = 0, prom_stdout = 0, prom_disp_node = 0; +prom_entry prom __initdata = 0; +ihandle prom_chosen __initdata = 0; +ihandle prom_stdout __initdata = 0; extern char *klimit; -char *bootpath = 0; -char *bootdevice = 0; +char *bootpath; +char *bootdevice; -unsigned int rtas_data = 0; /* physical pointer */ -unsigned int rtas_entry = 0; /* physical pointer */ -unsigned int rtas_size = 0; -unsigned int old_rtas = 0; +unsigned int rtas_data; /* physical pointer */ +unsigned int rtas_entry; /* physical pointer */ +unsigned int rtas_size; +unsigned int old_rtas; /* Set for a newworld machine */ -int use_of_interrupt_tree = 0; -int pmac_newworld = 0; +int use_of_interrupt_tree; +int pmac_newworld; -static struct device_node *allnodes = 0; +static struct device_node *allnodes; #ifdef CONFIG_BOOTX_TEXT @@ -134,13 +137,12 @@ static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb); static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb); static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb); -/* We want those in data, not BSS */ -static long g_loc_X = 0; -static long g_loc_Y = 0; -static long g_max_loc_X = 0; -static long g_max_loc_Y = 0; +static int g_loc_X; +static int g_loc_Y; +static int g_max_loc_X; +static int g_max_loc_Y; -unsigned long disp_BAT[2] = {0, 0}; +unsigned long disp_BAT[2] __initdata = {0, 0}; #define cmapsz (16*256) @@ -173,10 +175,10 @@ extern unsigned long reloc_offset(void); void phys_call_rtas(int, int, int, ...); extern char cmd_line[512]; /* XXX */ -boot_infos_t *boot_infos = 0; /* init it so it's in data segment not bss */ +boot_infos_t *boot_infos; #ifdef CONFIG_BOOTX_TEXT -boot_infos_t *disp_bi = 0; -boot_infos_t fake_bi = {0,}; +boot_infos_t *disp_bi; +boot_infos_t fake_bi; #endif unsigned long dev_tree_size; @@ -195,10 +197,6 @@ unsigned long dev_tree_size; * OF calls should be done within prom_init(), and prom_init() * and all routines called within it must be careful to relocate * references as necessary. - * - * Note that the bss is cleared *after* prom_init runs, so we have - * to make sure that any static or extern variables it accesses - * are put in the data segment. */ #define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) #define PTRUNRELOC(x) ((typeof(x))((unsigned long)(x) - offset)) @@ -618,6 +616,11 @@ prom_init(int r3, int r4, prom_entry pp) char *p, *d; int prom_version = 0; unsigned long phys; + extern char __bss_start, _end; + + /* First zero the BSS -- use memset, some arches don't have + * caches on yet */ + memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); /* Default */ phys = offset + KERNELBASE; @@ -948,34 +951,6 @@ check_display(unsigned long mem) if ((int) call_prom(RELOC("package-to-path"), 3, 1, node, path, 255) < 0) continue; - prom_print(RELOC("opening display ")); - prom_print(path); - ih = call_prom(RELOC("open"), 1, 1, path); - if (ih == 0 || ih == (ihandle) -1) { - prom_print(RELOC("... failed\n")); - continue; - } - prom_print(RELOC("... ok\n")); - - if (RELOC(prom_disp_node) == 0) - RELOC(prom_disp_node) = node; - - /* Setup a useable color table when the appropriate - * method is available. Should update this to set-colors */ - for (i = 0; i < 32; i++) - if (prom_set_color(ih, i, RELOC(default_colors)[i*3], - RELOC(default_colors)[i*3+1], - RELOC(default_colors)[i*3+2]) != 0) - break; - -#ifdef CONFIG_FB - for (i = 0; i < LINUX_LOGO_COLORS; i++) - if (prom_set_color(ih, i + 32, - RELOC(linux_logo_red)[i], - RELOC(linux_logo_green)[i], - RELOC(linux_logo_blue)[i]) != 0) - break; -#endif /* CONFIG_FB */ /* * If this display is the device that OF is using for stdout, @@ -990,9 +965,44 @@ check_display(unsigned long mem) = RELOC(prom_display_paths[i-1]); } RELOC(prom_display_paths[i]) = PTRUNRELOC(path); + if (i == 0) + RELOC(prom_disp_node) = node; if (RELOC(prom_num_displays) >= FB_MAX) break; } + + /* + * Open the first display and set its colormap. + */ + if (RELOC(prom_num_displays) > 0) { + path = PTRRELOC(RELOC(prom_display_paths[0])); + prom_print(RELOC("opening display ")); + prom_print(path); + ih = call_prom(RELOC("open"), 1, 1, path); + if (ih == 0 || ih == (ihandle) -1) { + prom_print(RELOC("... failed\n")); + } else { + prom_print(RELOC("... ok\n")); + + /* Setup a useable color table when the appropriate + * method is available. Should update this to set-colors */ + for (i = 0; i < 32; i++) + if (prom_set_color(ih, i, RELOC(default_colors)[i*3], + RELOC(default_colors)[i*3+1], + RELOC(default_colors)[i*3+2]) != 0) + break; + +#ifdef CONFIG_FB + for (i = 0; i < LINUX_LOGO_COLORS; i++) + if (prom_set_color(ih, i + 32, + RELOC(linux_logo_red)[i], + RELOC(linux_logo_green)[i], + RELOC(linux_logo_blue)[i]) != 0) + break; +#endif /* CONFIG_FB */ + } + } + return ALIGN(mem); } @@ -1277,7 +1287,7 @@ finish_node(struct device_node *np, unsigned long mem_start, if (!strcmp(np->name, "display")) np->name = get_property(np, "compatible", 0); - if (!strcmp(np->name, "device-tree")) + if (np->parent == NULL) ifunc = interpret_root_props; else if (np->type == 0) ifunc = NULL; @@ -1370,7 +1380,7 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start) np->intrs[i].line = *interrupts++; if (cvt_irq) np->intrs[i].line = openpic_to_irq(np->intrs[i].line); - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; if (isize > 1) np->intrs[i].sense = *interrupts++; for (j=2; j<isize; j++) @@ -1540,7 +1550,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, for (i = 0; (ml -= cell_size) >= 0; ++i) { if (imp->addr.a_hi == devfn) { np->intrs[np->n_intrs].line = imp->intr; - np->intrs[np->n_intrs].sense = 0; /* FIXME */ + np->intrs[np->n_intrs].sense = 1; /* FIXME */ ++np->n_intrs; } imp = (struct pci_intr_map *)(((unsigned int)imp) @@ -1561,7 +1571,7 @@ interpret_pci_props(struct device_node *np, unsigned long mem_start, mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1614,7 +1624,7 @@ interpret_dbdma_props(struct device_node *np, unsigned long mem_start, mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1675,7 +1685,7 @@ interpret_macio_props(struct device_node *np, unsigned long mem_start, if (keylargo) np->intrs[i].sense = *ip++; else - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } else { /* CHRP machines */ @@ -1771,7 +1781,7 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { np->intrs[i].line = *ip++; - np->intrs[i].sense = 0; + np->intrs[i].sense = 1; } } @@ -1779,6 +1789,30 @@ interpret_root_props(struct device_node *np, unsigned long mem_start, } /* + * Work out the sense (active-low level / active-high edge) + * of each interrupt from the device tree. + */ +void __init +prom_get_irq_senses(unsigned char *senses, int off, int max) +{ + struct device_node *np; + int i, j; + + /* default to level-triggered */ + memset(senses, 1, max - off); + if (!use_of_interrupt_tree) + return; + + for (np = allnodes; np != 0; np = np->allnext) { + for (j = 0; j < np->n_intrs; j++) { + i = np->intrs[j].line; + if (i >= off && i < max) + senses[i-off] = np->intrs[j].sense; + } + } +} + +/* * Construct and return a list of the device_nodes with a given name. */ __openfirmware @@ -1818,39 +1852,6 @@ find_type_devices(const char *type) return head; } -/* Finds a device node given its PCI bus number, device number - * and function number - */ -__openfirmware -struct device_node * -find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn) -{ - struct device_node* np; - unsigned int *reg; - int l; - - for (np = allnodes; np != 0; np = np->allnext) { - int in_macio = 0; - struct device_node* parent = np->parent; - while(parent) { - char *pname = (char *)get_property(parent, "name", &l); - if (pname && strcmp(pname, "mac-io") == 0) { - in_macio = 1; - break; - } - parent = parent->parent; - } - if (in_macio) - continue; - reg = (unsigned int *) get_property(np, "reg", &l); - if (reg == 0 || l < sizeof(struct reg_property)) - continue; - if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus) - break; - } - return np; -} - /* * Returns all nodes linked together */ @@ -1983,6 +1984,21 @@ get_property(struct device_node *np, const char *name, int *lenp) return 0; } +/* + * Add a property to a node + */ +__openfirmware +void +prom_add_property(struct device_node* np, struct property* prop) +{ + struct property **next = &np->properties; + + prop->next = NULL; + while (*next) + next = &(*next)->next; + *next = prop; +} + #if 0 __openfirmware void diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 6bafa57c128f..58fb87e9c07e 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -12,6 +12,7 @@ #include <linux/delay.h> #include <linux/blk.h> #include <linux/ide.h> +#include <linux/bootmem.h> #include <asm/init.h> #include <asm/residual.h> @@ -71,12 +72,6 @@ extern void apus_init(unsigned long r3, unsigned long r6, unsigned long r7); -extern void gemini_init(unsigned long r3, - unsigned long r4, - unsigned long r5, - unsigned long r6, - unsigned long r7); - #ifdef CONFIG_XMON extern void xmon_map_scc(void); #endif @@ -106,6 +101,10 @@ int have_of = 0; unsigned long SYSRQ_KEY; #endif /* CONFIG_MAGIC_SYSRQ */ +#ifdef CONFIG_VGA_CONSOLE +unsigned long vgacon_remap_base; +#endif + struct machdep_calls ppc_md; /* @@ -377,9 +376,9 @@ int get_cpuinfo(char *buffer) len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min); len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n", - (CD(loops_per_sec)+2500)/500000, - (CD(loops_per_sec)+2500)/5000 % 100); - bogosum += CD(loops_per_sec); + (CD(loops_per_jiffy)+2500)/(500000/HZ), + (CD(loops_per_jiffy)+2500)/(5000/HZ) % 100); + bogosum += CD(loops_per_jiffy); } #ifdef CONFIG_SMP @@ -549,11 +548,6 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, apus_init(r3, r4, r5, r6, r7); break; #endif -#ifdef CONFIG_GEMINI - case _MACH_gemini: - gemini_init(r3, r4, r5, r6, r7); - break; -#endif default: printk("Unknown machine type in identify_machine!\n"); } @@ -673,13 +667,14 @@ __setup("l2cr=", ppc_setup_l2cr); void __init ppc_init(void) { /* clear the progress line */ - if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); + if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); if (ppc_md.init != NULL) { ppc_md.init(); } } +/* Warning, IO base is not yet inited */ void __init setup_arch(char **cmdline_p) { extern int panic_timeout; @@ -688,7 +683,7 @@ void __init setup_arch(char **cmdline_p) extern void do_init_bootmem(void); /* so udelay does something sensible, assume <= 1000 bogomips */ - loops_per_sec = 500000000; + loops_per_jiffy = 500000000 / HZ; #ifdef CONFIG_ALL_PPC feature_init(); @@ -743,10 +738,34 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); +#ifdef CONFIG_PCI + /* We create the "pci-OF-bus-map" property now so it appear in the + * /proc device tree + */ + if (have_of) { + struct property* of_prop; + + of_prop = (struct property*)alloc_bootmem(sizeof(struct property) + 256); + if (of_prop && find_path_device("/")) { + memset(of_prop, -1, sizeof(struct property) + 256); + of_prop->name = "pci-OF-bus-map"; + of_prop->length = 256; + of_prop->value = (unsigned char *)&of_prop[1]; + prom_add_property(find_path_device("/"), of_prop); + } + } +#endif /* CONFIG_PCI */ + paging_init(); sort_exception_table(); } +/* Convert the shorts/longs in hd_driveid from little to big endian; + * chars are endian independant, of course, but strings need to be flipped. + * (Despite what it says in drivers/block/ide.h, they come up as little + * endian...) + * + * Changes to linux/hdreg.h may require changes here. */ void ppc_generic_ide_fix_driveid(struct hd_driveid *id) { int i; diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c index fb7f384440c8..7edf7209d4d0 100644 --- a/arch/ppc/kernel/smp.c +++ b/arch/ppc/kernel/smp.c @@ -1,6 +1,4 @@ /* - * $Id: smp.c,v 1.68 1999/09/17 19:38:05 cort Exp $ - * * Smp support for ppc. * * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great @@ -8,8 +6,11 @@ * * Copyright (C) 1999 Cort Dougan <cort@cs.nmt.edu> * - * Support for PReP (Motorola MTX/MVME) SMP by Troy Benjegerdes - * (troy@microux.com, hozer@drgw.net) + * Support for PReP (Motorola MTX/MVME) and Macintosh G4 SMP + * by Troy Benjegerdes (hozer@drgw.net) + * + * Support for DayStar quad CPU cards + * Copyright (C) XLR8, Inc. 1994-2000 */ #include <linux/config.h> @@ -23,7 +24,6 @@ #define __KERNEL_SYSCALLS__ #include <linux/unistd.h> #include <linux/init.h> -#include <linux/openpic.h> #include <linux/spinlock.h> #include <asm/ptrace.h> @@ -37,47 +37,97 @@ #include <asm/io.h> #include <asm/prom.h> #include <asm/smp.h> -#include <asm/gemini.h> - +#include <asm/residual.h> +#include <asm/feature.h> #include <asm/time.h> + #include "open_pic.h" int smp_threads_ready; volatile int smp_commenced; int smp_num_cpus = 1; +int smp_tb_synchronized; struct cpuinfo_PPC cpu_data[NR_CPUS]; struct klock_info_struct klock_info = { KLOCK_CLEAR, 0 }; -volatile unsigned char active_kernel_processor = NO_PROC_ID; /* Processor holding kernel spinlock */ -volatile unsigned long ipi_count; +atomic_t ipi_recv; +atomic_t ipi_sent; spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; unsigned int prof_multiplier[NR_CPUS]; unsigned int prof_counter[NR_CPUS]; cycles_t cacheflush_time; +static int max_cpus __initdata = NR_CPUS; -/* this has to go in the data section because it is accessed from prom_init */ int smp_hw_index[NR_CPUS]; /* all cpu mappings are 1-1 -- Cort */ volatile unsigned long cpu_callin_map[NR_CPUS]; +#define TB_SYNC_PASSES 4 +volatile unsigned long __initdata tb_sync_flag = 0; +volatile unsigned long __initdata tb_offset = 0; + int start_secondary(void *); extern int cpu_idle(void *unused); -u_int openpic_read(volatile u_int *addr); void smp_call_function_interrupt(void); void smp_message_pass(int target, int msg, unsigned long data, int wait); +extern void __secondary_start_psurge(void); +extern void __secondary_start_psurge2(void); /* Temporary horrible hack */ +extern void __secondary_start_psurge3(void); /* Temporary horrible hack */ + +/* Addresses for powersurge registers */ +#define HAMMERHEAD_BASE 0xf8000000 +#define HHEAD_CONFIG 0x90 +#define HHEAD_SEC_INTR 0xc0 + /* register for interrupting the primary processor on the powersurge */ /* N.B. this is actually the ethernet ROM! */ -#define PSURGE_PRI_INTR 0xf3019000 -/* register for interrupting the secondary processor on the powersurge */ -#define PSURGE_SEC_INTR 0xf80000c0 +#define PSURGE_PRI_INTR 0xf3019000 + /* register for storing the start address for the secondary processor */ -#define PSURGE_START 0xf2800000 +/* N.B. this is the PCI config space address register for the 1st bridge */ +#define PSURGE_START 0xf2800000 + +/* Daystar/XLR8 4-CPU card */ +#define PSURGE_QUAD_REG_ADDR 0xf8800000 + +#define PSURGE_QUAD_IRQ_SET 0 +#define PSURGE_QUAD_IRQ_CLR 1 +#define PSURGE_QUAD_IRQ_PRIMARY 2 +#define PSURGE_QUAD_CKSTOP_CTL 3 +#define PSURGE_QUAD_PRIMARY_ARB 4 +#define PSURGE_QUAD_BOARD_ID 6 +#define PSURGE_QUAD_WHICH_CPU 7 +#define PSURGE_QUAD_CKSTOP_RDBK 8 +#define PSURGE_QUAD_RESET_CTL 11 + +#define PSURGE_QUAD_OUT(r, v) (out_8((u8 *)(quad_base+((r)<<2)+1), (v))) +#define PSURGE_QUAD_IN(r) (in_8((u8 *)(quad_base+((r)<<2)+1)) & 0x0f) +#define PSURGE_QUAD_BIS(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) | (v))) +#define PSURGE_QUAD_BIC(r, v) (PSURGE_QUAD_OUT((r), PSURGE_QUAD_IN(r) & ~(v))) + /* virtual addresses for the above */ -volatile u32 *psurge_pri_intr; -volatile u32 *psurge_sec_intr; -volatile u32 *psurge_start; +static volatile u8 *hhead_base; +static volatile u32 *quad_base; +static volatile u32 *psurge_pri_intr; +static volatile u8 *psurge_sec_intr; +static volatile u32 *psurge_start; + +/* what sort of powersurge board we have */ +static int psurge_type; + +/* values for psurge_type */ +#define PSURGE_DUAL 0 +#define PSURGE_QUAD_OKEE 1 +#define PSURGE_QUAD_COTTON 2 +#define PSURGE_QUAD_ICEGRASS 3 -/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */ +/* l2 cache stuff for dual G4 macs */ +extern void core99_init_l2(void); + +/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. + * + * Make sure this matches openpic_request_IPIs in open_pic.c, or what shows up + * in /proc/interrupts will be wrong!!! --Troy */ #define PPC_MSG_CALL_FUNCTION 0 #define PPC_MSG_RESCHEDULE 1 #define PPC_MSG_INVALIDATE_TLB 2 @@ -85,10 +135,577 @@ volatile u32 *psurge_start; static inline void set_tb(unsigned int upper, unsigned int lower) { + mtspr(SPRN_TBWL, 0); mtspr(SPRN_TBWU, upper); mtspr(SPRN_TBWL, lower); } +/* + * Set and clear IPIs for powersurge. + */ +static inline void psurge_set_ipi(int cpu) +{ + if (cpu == 0) + in_be32(psurge_pri_intr); + else if (psurge_type == PSURGE_DUAL) + out_8(psurge_sec_intr, 0); + else + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_SET, 1 << cpu); +} + +static inline void psurge_clr_ipi(int cpu) +{ + if (cpu > 0) { + if (psurge_type == PSURGE_DUAL) + out_8(psurge_sec_intr, ~0); + else + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, 1 << cpu); + } +} + +/* + * On powersurge (old SMP powermac architecture) we don't have + * separate IPIs for separate messages like openpic does. Instead + * we have a bitmap for each processor, where a 1 bit means that + * the corresponding message is pending for that processor. + * Ideally each cpu's entry would be in a different cache line. + * -- paulus. + */ +static unsigned long psurge_smp_message[NR_CPUS]; + +void psurge_smp_message_recv(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + int msg; + + /* clear interrupt */ + psurge_clr_ipi(cpu); + + if (smp_num_cpus < 2) + return; + + /* make sure there is a message there */ + for (msg = 0; msg < 4; msg++) + if (test_and_clear_bit(msg, &psurge_smp_message[cpu])) + smp_message_recv(msg, regs); +} + +void +psurge_primary_intr(int irq, void *d, struct pt_regs *regs) +{ + psurge_smp_message_recv(regs); +} + +static void +smp_psurge_message_pass(int target, int msg, unsigned long data, int wait) +{ + int i; + + if (smp_num_cpus < 2) + return; + + for (i = 0; i < smp_num_cpus; i++) { + if (target == MSG_ALL + || (target == MSG_ALL_BUT_SELF && i != smp_processor_id()) + || target == i) { + set_bit(msg, &psurge_smp_message[i]); + psurge_set_ipi(i); + } + } +} + +/* + * Determine a quad card presence. We read the board ID register, we + * for the data bus to change to something else, and we read it again. + * It it's stable, then the register probably exist (ugh !) + */ +static int __init psurge_quad_probe(void) +{ + int type; + unsigned int i; + + type = PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID); + if (type < PSURGE_QUAD_OKEE || type > PSURGE_QUAD_ICEGRASS + || type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) + return PSURGE_DUAL; + + /* looks OK, try a slightly more rigorous test */ + /* bogus is not necessarily cacheline-aligned, + though I don't suppose that really matters. -- paulus */ + for (i = 0; i < 100; i++) { + volatile u32 bogus[8]; + bogus[(0+i)%8] = 0x00000000; + bogus[(1+i)%8] = 0x55555555; + bogus[(2+i)%8] = 0xFFFFFFFF; + bogus[(3+i)%8] = 0xAAAAAAAA; + bogus[(4+i)%8] = 0x33333333; + bogus[(5+i)%8] = 0xCCCCCCCC; + bogus[(6+i)%8] = 0xCCCCCCCC; + bogus[(7+i)%8] = 0x33333333; + wmb(); + asm volatile("dcbf 0,%0" : : "r" (bogus) : "memory"); + mb(); + if (type != PSURGE_QUAD_IN(PSURGE_QUAD_BOARD_ID)) + return PSURGE_DUAL; + } + return type; +} + +static void __init psurge_quad_init(void) +{ + int procbits; + + if (ppc_md.progress) ppc_md.progress("psurge_quad_init", 0x351); + procbits = ~PSURGE_QUAD_IN(PSURGE_QUAD_WHICH_CPU); + if (psurge_type == PSURGE_QUAD_ICEGRASS) + PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); + else + PSURGE_QUAD_BIC(PSURGE_QUAD_CKSTOP_CTL, procbits); + mdelay(33); + out_8(psurge_sec_intr, ~0); + PSURGE_QUAD_OUT(PSURGE_QUAD_IRQ_CLR, procbits); + PSURGE_QUAD_BIS(PSURGE_QUAD_RESET_CTL, procbits); + if (psurge_type != PSURGE_QUAD_ICEGRASS) + PSURGE_QUAD_BIS(PSURGE_QUAD_CKSTOP_CTL, procbits); + PSURGE_QUAD_BIC(PSURGE_QUAD_PRIMARY_ARB, procbits); + mdelay(33); + PSURGE_QUAD_BIC(PSURGE_QUAD_RESET_CTL, procbits); + mdelay(33); + PSURGE_QUAD_BIS(PSURGE_QUAD_PRIMARY_ARB, procbits); + mdelay(33); +} + +static int __init smp_psurge_probe(void) +{ + int i, ncpus; + + /* We don't do SMP on the PPC601 -- paulus */ + if ((_get_PVR() >> 16) == 1) + return 1; + + /* + * The powersurge cpu board can be used in the generation + * of powermacs that have a socket for an upgradeable cpu card, + * including the 7500, 8500, 9500, 9600. + * The device tree doesn't tell you if you have 2 cpus because + * OF doesn't know anything about the 2nd processor. + * Instead we look for magic bits in magic registers, + * in the hammerhead memory controller in the case of the + * dual-cpu powersurge board. -- paulus. + */ + if (find_devices("hammerhead") == NULL) + return 1; + + hhead_base = ioremap(HAMMERHEAD_BASE, 0x800); + quad_base = ioremap(PSURGE_QUAD_REG_ADDR, 1024); + psurge_sec_intr = hhead_base + HHEAD_SEC_INTR; + + psurge_type = psurge_quad_probe(); + if (psurge_type != PSURGE_DUAL) { + psurge_quad_init(); + /* I believe we could "count" CPUs by counting 1 bits + * in procbits on a quad board. For now, we assume 4, + * non-present CPUs will just be seen as "stuck". + * (hope they are the higher-numbered ones -- paulus) + */ + ncpus = 4; + } else { + iounmap((void *) quad_base); + if ((in_8(hhead_base + HHEAD_CONFIG) & 0x02) == 0) { + /* not a dual-cpu card */ + iounmap((void *) hhead_base); + return 1; + } + ncpus = 2; + } + + psurge_start = ioremap(PSURGE_START, 4); + psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); + + /* this is not actually strictly necessary -- paulus. */ + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + + if (ppc_md.progress) ppc_md.progress("smp_psurge_probe - done", 0x352); + + return ncpus; +} + +static void __init smp_psurge_kick_cpu(int nr) +{ + void (*start)(void) = __secondary_start_psurge; + + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu", 0x353); + + /* setup entry point of secondary processor */ + switch (nr) { + case 2: + start = __secondary_start_psurge2; + break; + case 3: + start = __secondary_start_psurge3; + break; + } + + out_be32(psurge_start, __pa(start)); + mb(); + + psurge_set_ipi(nr); + udelay(10); + psurge_clr_ipi(nr); + + if (ppc_md.progress) ppc_md.progress("smp_psurge_kick_cpu - done", 0x354); +} + +/* + * With the dual-cpu powersurge board, the decrementers and timebases + * of both cpus are frozen after the secondary cpu is started up, + * until we give the secondary cpu another interrupt. This routine + * uses this to get the timebases synchronized. + * -- paulus. + */ +static void __init psurge_dual_sync_tb(int cpu_nr) +{ + static volatile int sec_tb_reset = 0; + int t; + + set_dec(tb_ticks_per_jiffy); + set_tb(0, 0); + last_jiffy_stamp(cpu_nr) = 0; + + if (cpu_nr > 0) { + mb(); + sec_tb_reset = 1; + return; + } + + /* wait for the secondary to have reset its TB before proceeding */ + for (t = 10000000; t > 0 && !sec_tb_reset; --t) + ; + + /* now interrupt the secondary, starting both TBs */ + psurge_set_ipi(1); + + smp_tb_synchronized = 1; +} + +static void +smp_psurge_setup_cpu(int cpu_nr) +{ + + if (cpu_nr == 0) { + if (smp_num_cpus < 2) + return; + /* reset the entry point so if we get another intr we won't + * try to startup again */ + out_be32(psurge_start, 0x100); + if (request_irq(30, psurge_primary_intr, 0, "primary IPI", 0)) + printk(KERN_ERR "Couldn't get primary IPI interrupt"); + } + + if (psurge_type == PSURGE_DUAL) + psurge_dual_sync_tb(cpu_nr); +} + + +static void +smp_openpic_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* make sure we're sending something that translates to an IPI */ + if ( msg > 0x3 ){ + printk("SMP %d: smp_message_pass: unknown msg %d\n", + smp_processor_id(), msg); + return; + } + switch ( target ) + { + case MSG_ALL: + openpic_cause_IPI(msg, 0xffffffff); + break; + case MSG_ALL_BUT_SELF: + openpic_cause_IPI(msg, + 0xffffffff & ~(1 << smp_hw_index[smp_processor_id()])); + + break; + default: + openpic_cause_IPI(msg, smp_hw_index[1<<target]); + break; + } +} + +static int +smp_core99_probe(void) +{ + struct device_node *cpus; + int *pp; + int i, ncpus = 1; + + if (ppc_md.progress) ppc_md.progress("smp_core99_probe", 0x345); +#if 0 /* Paulus method.. doesn't seem to work on earlier dual G4's??*/ + cpus = find_devices("cpus"); + if (cpus != 0) { + pp = (int *) get_property(cpus, "#cpus", NULL); + if (pp != NULL) + ncpus = *pp; + } +#else /* My original method -- Troy <hozer@drgw.net> */ + + cpus = find_type_devices("cpu"); + if (cpus){ + for ( ncpus = 1; cpus->next; cpus = cpus->next ){ + ncpus++; + } + } +#endif + printk("smp_core99_probe: OF reports %d cpus\n", ncpus); + if (ncpus > 1) { + openpic_request_IPIs(); + for (i = 1; i < ncpus; ++i) + smp_hw_index[i] = i; + } + + return ncpus; +} + +static void +smp_core99_kick_cpu(int nr) +{ + unsigned long save_int; + unsigned long flags; + volatile unsigned long *vector + = ((volatile unsigned long *)(KERNELBASE+0x500)); + + if (nr != 1) + return; + if (ppc_md.progress) ppc_md.progress("smp_core99_kick_cpu", 0x346); + + local_irq_save(flags); + local_irq_disable(); + + /* Save EE vector */ + save_int = *vector; + + /* Setup fake EE vector that does + * b __secondary_start_psurge - KERNELBASE + */ + *vector = 0x48000002 + + ((unsigned long)__secondary_start_psurge - KERNELBASE); + + /* flush data cache and inval instruction cache */ + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + /* Put some life in our friend */ + feature_core99_kick_cpu1(); + + /* FIXME: We wait a bit for the CPU to take the exception, I should + * instead wait for the entry code to set something for me. Well, + * ideally, all that crap will be done in prom.c and the CPU left + * in a RAM-based wait loop like CHRP. + */ + mdelay(1); + + /* Restore our exception vector */ + *vector = save_int; + flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); + + local_irq_restore(flags); + if (ppc_md.progress) ppc_md.progress("smp_core99_probe done", 0x347); +} + +static void +smp_core99_setup_cpu(int cpu_nr) +{ + /* Setup openpic */ + do_openpic_setup_cpu(); + + /* Setup L2 */ + if (cpu_nr != 0) + core99_init_l2(); + else + if (ppc_md.progress) ppc_md.progress("core99_setup_cpu 0 done", 0x349); +} + +static int +smp_chrp_probe(void) +{ + extern unsigned long smp_chrp_cpu_nr; + + if (smp_chrp_cpu_nr > 1) + openpic_request_IPIs(); + + return smp_chrp_cpu_nr; +} + +static void +smp_chrp_kick_cpu(int nr) +{ + *(unsigned long *)KERNELBASE = nr; + asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); +} + +static void +smp_chrp_setup_cpu(int cpu_nr) +{ + static atomic_t ready = ATOMIC_INIT(1); + static volatile int frozen = 0; + + if (cpu_nr == 0) { + /* wait for all the others */ + while (atomic_read(&ready) < smp_num_cpus) + barrier(); + atomic_set(&ready, 1); + /* freeze the timebase */ + call_rtas("freeze-time-base", 0, 1, NULL); + mb(); + frozen = 1; + /* XXX assumes this is not a 601 */ + set_tb(0, 0); + last_jiffy_stamp(0) = 0; + while (atomic_read(&ready) < smp_num_cpus) + barrier(); + /* thaw the timebase again */ + call_rtas("thaw-time-base", 0, 1, NULL); + mb(); + frozen = 0; + smp_tb_synchronized = 1; + } else { + atomic_inc(&ready); + while (!frozen) + barrier(); + set_tb(0, 0); + last_jiffy_stamp(0) = 0; + mb(); + atomic_inc(&ready); + while (frozen) + barrier(); + } + + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +#ifdef CONFIG_POWER4 +static void +smp_xics_message_pass(int target, int msg, unsigned long data, int wait) +{ + /* for now, only do reschedule messages + since we only have one IPI */ + if (msg != PPC_MSG_RESCHEDULE) + return; + for (i = 0; i < smp_num_cpus; ++i) { + if (target == MSG_ALL || target == i + || (target == MSG_ALL_BUT_SELF + && i != smp_processor_id())) + xics_cause_IPI(i); + } +} + +static int +smp_xics_probe(void) +{ + return smp_chrp_cpu_nr; +} + +static void +smp_xics_setup_cpu(int cpu_nr) +{ + if (cpu_nr > 0) + xics_setup_cpu(); +} +#endif /* CONFIG_POWER4 */ + +static int +smp_prep_probe(void) +{ + extern int mot_multi; + + if (mot_multi) { + openpic_request_IPIs(); + smp_hw_index[1] = 1; + return 2; + } + + return 1; +} + +static void +smp_prep_kick_cpu(int nr) +{ + extern unsigned long *MotSave_SmpIar; + extern unsigned char *MotSave_CpusState[2]; + + *MotSave_SmpIar = (unsigned long)__secondary_start_psurge - KERNELBASE; + *MotSave_CpusState[1] = CPU_GOOD; + printk("CPU1 reset, waiting\n"); +} + +static void +smp_prep_setup_cpu(int cpu_nr) +{ + if (OpenPIC_Addr) + do_openpic_setup_cpu(); +} + +static struct smp_ops_t { + void (*message_pass)(int target, int msg, unsigned long data, int wait); + int (*probe)(void); + void (*kick_cpu)(int nr); + void (*setup_cpu)(int nr); + +} *smp_ops; + +#define smp_message_pass(t,m,d,w) \ + do { if (smp_ops) \ + atomic_inc(&ipi_sent); \ + smp_ops->message_pass((t),(m),(d),(w)); \ + } while(0) + + +/* PowerSurge-style Macs */ +static struct smp_ops_t psurge_smp_ops = { + smp_psurge_message_pass, + smp_psurge_probe, + smp_psurge_kick_cpu, + smp_psurge_setup_cpu, +}; + +/* Core99 Macs (dual G4s) */ +static struct smp_ops_t core99_smp_ops = { + smp_openpic_message_pass, + smp_core99_probe, + smp_core99_kick_cpu, + smp_core99_setup_cpu, +}; + +/* CHRP with openpic */ +static struct smp_ops_t chrp_smp_ops = { + smp_openpic_message_pass, + smp_chrp_probe, + smp_chrp_kick_cpu, + smp_chrp_setup_cpu, +}; + +#ifdef CONFIG_POWER4 +/* CHRP with new XICS interrupt controller */ +static struct smp_ops_t xics_smp_ops = { + smp_xics_message_pass, + smp_xics_probe, + smp_chrp_kick_cpu, + smp_xics_setup_cpu, +}; +#endif /* CONFIG_POWER4 */ + +/* PReP (MTX) */ +static struct smp_ops_t prep_smp_ops = { + smp_openpic_message_pass, + smp_prep_probe, + smp_prep_kick_cpu, + smp_prep_setup_cpu, +}; + +/* + * Common functions + */ void smp_local_timer_interrupt(struct pt_regs * regs) { int cpu = smp_processor_id(); @@ -101,7 +718,7 @@ void smp_local_timer_interrupt(struct pt_regs * regs) void smp_message_recv(int msg, struct pt_regs *regs) { - ipi_count++; + atomic_inc(&ipi_recv); switch( msg ) { case PPC_MSG_CALL_FUNCTION: @@ -126,47 +743,6 @@ void smp_message_recv(int msg, struct pt_regs *regs) } /* - * As it is now, if we're sending two message at the same time - * we have race conditions on Pmac. The PowerSurge doesn't easily - * allow us to send IPI messages so we put the messages in - * smp_message[]. - * - * This is because don't have several IPI's on the PowerSurge even though - * we do on the chrp. It would be nice to use actual IPI's such as with - * openpic rather than this. - * -- Cort - */ -int pmac_smp_message[NR_CPUS]; -void pmac_smp_message_recv(struct pt_regs *regs) -{ - int cpu = smp_processor_id(); - int msg; - - /* clear interrupt */ - if (cpu == 1) - out_be32(psurge_sec_intr, ~0); - - if (smp_num_cpus < 2) - return; - - /* make sure there is a message there */ - msg = pmac_smp_message[cpu]; - if (msg == 0) - return; - - /* reset message */ - pmac_smp_message[cpu] = 0; - - smp_message_recv(msg - 1, regs); -} - -void -pmac_primary_intr(int irq, void *d, struct pt_regs *regs) -{ - pmac_smp_message_recv(regs); -} - -/* * 750's don't broadcast tlb invalidates so * we have to emulate that behavior. * -- Cort @@ -220,7 +796,7 @@ void smp_send_stop(void) */ static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; -static volatile struct call_data_struct { +static struct call_data_struct { void (*func) (void *info); void *info; atomic_t started; @@ -317,87 +893,9 @@ void smp_call_function_interrupt(void) atomic_inc(&call_data->finished); } -void smp_message_pass(int target, int msg, unsigned long data, int wait) -{ - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) ) - return; - - switch (_machine) { - case _MACH_Pmac: - /* - * IPI's on the Pmac are a hack but without reasonable - * IPI hardware SMP on Pmac is a hack. - * - * We assume here that the msg is not -1. If it is, - * the recipient won't know the message was destined - * for it. -- Cort - */ - if (smp_processor_id() == 0) { - /* primary cpu */ - if (target == 1 || target == MSG_ALL_BUT_SELF - || target == MSG_ALL) { - pmac_smp_message[1] = msg + 1; - /* interrupt secondary processor */ - out_be32(psurge_sec_intr, ~0); - out_be32(psurge_sec_intr, 0); - } - } else { - /* secondary cpu */ - if (target == 0 || target == MSG_ALL_BUT_SELF - || target == MSG_ALL) { - pmac_smp_message[0] = msg + 1; - /* interrupt primary processor */ - in_be32(psurge_pri_intr); - } - } - if (target == smp_processor_id() || target == MSG_ALL) { - /* sending a message to ourself */ - /* XXX maybe we shouldn't do this if ints are off */ - smp_message_recv(msg, NULL); - } - break; - case _MACH_chrp: - case _MACH_prep: - case _MACH_gemini: -#ifndef CONFIG_POWER4 - /* make sure we're sending something that translates to an IPI */ - if ( msg > 0x3 ) - break; - switch ( target ) - { - case MSG_ALL: - openpic_cause_IPI(smp_processor_id(), msg, 0xffffffff); - break; - case MSG_ALL_BUT_SELF: - openpic_cause_IPI(smp_processor_id(), msg, - 0xffffffff & ~(1 << smp_processor_id())); - break; - default: - openpic_cause_IPI(smp_processor_id(), msg, 1<<target); - break; - } -#else /* CONFIG_POWER4 */ - /* for now, only do reschedule messages - since we only have one IPI */ - if (msg != PPC_MSG_RESCHEDULE) - break; - for (i = 0; i < smp_num_cpus; ++i) { - if (target == MSG_ALL || target == i - || (target == MSG_ALL_BUT_SELF - && i != smp_processor_id())) - xics_cause_IPI(i); - } -#endif /* CONFIG_POWER4 */ - break; - } -} - void __init smp_boot_cpus(void) { extern struct task_struct *current_set[NR_CPUS]; - extern unsigned long smp_chrp_cpu_nr; - extern void __secondary_start_psurge(void); - extern void __secondary_start_chrp(void); int i, cpu_nr; struct task_struct *p; unsigned long a; @@ -411,7 +909,6 @@ void __init smp_boot_cpus(void) * cpu 0, the master -- Cort */ cpu_callin_map[0] = 1; - active_kernel_processor = 0; current->processor = 0; init_idle(); @@ -427,41 +924,40 @@ void __init smp_boot_cpus(void) */ cacheflush_time = 5 * 1024; - if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_gemini)) ) - { - printk("SMP not supported on this machine.\n"); - return; - } - - switch ( _machine ) - { + /* To be later replaced by some arch-specific routine */ + switch(_machine) { case _MACH_Pmac: - /* assume powersurge board - 2 processors -- Cort */ - cpu_nr = 2; - psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4); - psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4); - psurge_start = ioremap(PSURGE_START, 4); + /* Check for Core99 */ + if (find_devices("uni-n")) + smp_ops = &core99_smp_ops; + else + smp_ops = &psurge_smp_ops; break; case _MACH_chrp: - if (OpenPIC) - for ( i = 0; i < 4 ; i++ ) - openpic_enable_IPI(i); - cpu_nr = smp_chrp_cpu_nr; +#ifndef CONFIG_POWER4 + smp_ops = &chrp_smp_ops; +#else + smp_ops = &xics_smp_ops; +#endif /* CONFIG_POWER4 */ break; - case _MACH_gemini: - for ( i = 0; i < 4 ; i++ ) - openpic_enable_IPI(i); - cpu_nr = (readb(GEMINI_CPUSTAT) & GEMINI_CPU_COUNT_MASK)>>2; - cpu_nr = (cpu_nr == 0) ? 4 : cpu_nr; + case _MACH_prep: + smp_ops = &prep_smp_ops; break; + default: + printk("SMP not supported on this machine.\n"); + return; } + + /* Probe arch for CPUs */ + cpu_nr = smp_ops->probe(); /* * only check for cpus we know exist. We keep the callin map * with cpus at the bottom -- Cort */ - for ( i = 1 ; i < cpu_nr; i++ ) - { + if (cpu_nr > max_cpus) + cpu_nr = max_cpus; + for (i = 1; i < cpu_nr; i++) { int c; struct pt_regs regs; @@ -487,25 +983,7 @@ void __init smp_boot_cpus(void) asm volatile("sync"); /* wake up cpus */ - switch ( _machine ) - { - case _MACH_Pmac: - /* setup entry point of secondary processor */ - out_be32(psurge_start, __pa(__secondary_start_psurge)); - /* interrupt secondary to begin executing code */ - out_be32(psurge_sec_intr, ~0); - udelay(1); - out_be32(psurge_sec_intr, 0); - break; - case _MACH_chrp: - *(unsigned long *)KERNELBASE = i; - asm volatile("dcbf 0,%0"::"r"(KERNELBASE):"memory"); - break; - case _MACH_gemini: - openpic_init_processor( 1<<i ); - openpic_init_processor( 0 ); - break; - } + smp_ops->kick_cpu(i); /* * wait to see if the cpu made a callin (is actually up). @@ -517,40 +995,108 @@ void __init smp_boot_cpus(void) if ( cpu_callin_map[i] ) { + char buf[32]; + sprintf(buf, "found cpu %d", i); + if (ppc_md.progress) ppc_md.progress(buf, 0x350+i); printk("Processor %d found.\n", i); smp_num_cpus++; } else { + char buf[32]; + sprintf(buf, "didn't find cpu %d", i); + if (ppc_md.progress) ppc_md.progress(buf, 0x360+i); printk("Processor %d is stuck.\n", i); } } - if (OpenPIC && (_machine & (_MACH_gemini|_MACH_chrp|_MACH_prep))) - do_openpic_setup_cpu(); + /* Setup CPU 0 last (important) */ + smp_ops->setup_cpu(0); +} - if ( _machine == _MACH_Pmac ) - { - /* reset the entry point so if we get another intr we won't - * try to startup again */ - out_be32(psurge_start, 0x100); - if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0)) - printk(KERN_ERR "Couldn't get primary IPI interrupt"); - /* - * The decrementers of both cpus are frozen at this point - * until we give the secondary cpu another interrupt. - * We set them both to decrementer_count and then send - * the interrupt. This should get the decrementers - * synchronized. - * -- paulus. - */ - set_dec(tb_ticks_per_jiffy); - if ((_get_PVR() >> 16) != 1) { - set_tb(0, 0); /* set timebase if not 601 */ - last_jiffy_stamp(0) = 0; +void __init smp_software_tb_sync(int cpu) +{ +#define PASSES 4 /* 4 passes.. */ + int pass; + int i, j; + + /* stop - start will be the number of timebase ticks it takes for cpu0 + * to send a message to all others and the first reponse to show up. + * + * ASSUMPTION: this time is similiar for all cpus + * ASSUMPTION: the time to send a one-way message is ping/2 + */ + register unsigned long start = 0; + register unsigned long stop = 0; + register unsigned long temp = 0; + + if (smp_num_cpus < 2) { + smp_tb_synchronized = 1; + return; + } + + /* This code need fixing on >2 CPUs --BenH/paulus */ + if (smp_num_cpus > 2) { + smp_tb_synchronized = 0; + return; + } + + set_tb(0, 0); + + /* multiple passes to get in l1 cache.. */ + for (pass = 2; pass < 2+PASSES; pass++){ + if (cpu == 0){ + mb(); + for (i = j = 1; i < smp_num_cpus; i++, j++){ + /* skip stuck cpus */ + while (!cpu_callin_map[j]) + ++j; + while (cpu_callin_map[j] != pass) + barrier(); + } + mb(); + tb_sync_flag = pass; + start = get_tbl(); /* start timing */ + while (tb_sync_flag) + mb(); + stop = get_tbl(); /* end timing */ + /* theoretically, the divisor should be 2, but + * I get better results on my dual mtx. someone + * please report results on other smp machines.. + */ + tb_offset = (stop-start)/4; + mb(); + tb_sync_flag = pass; + udelay(10); + mb(); + tb_sync_flag = 0; + mb(); + set_tb(0,0); + mb(); + } else { + cpu_callin_map[cpu] = pass; + mb(); + while (!tb_sync_flag) + mb(); /* wait for cpu0 */ + mb(); + tb_sync_flag = 0; /* send response for timing */ + mb(); + while (!tb_sync_flag) + mb(); + temp = tb_offset; /* make sure offset is loaded */ + while (tb_sync_flag) + mb(); + set_tb(0,temp); /* now, set the timebase */ + mb(); } - out_be32(psurge_sec_intr, ~0); - udelay(1); - out_be32(psurge_sec_intr, 0); } + if (cpu == 0) { + smp_tb_synchronized = 1; + printk("smp_software_tb_sync: %d passes, final offset: %ld\n", + PASSES, tb_offset); + } + /* so time.c doesn't get confused */ + set_dec(tb_ticks_per_jiffy); + last_jiffy_stamp(cpu) = 0; + cpu_callin_map[cpu] = 1; } void __init smp_commence(void) @@ -558,8 +1104,48 @@ void __init smp_commence(void) /* * Lets the callin's below out of their loop. */ + if (ppc_md.progress) ppc_md.progress("smp_commence", 0x370); wmb(); smp_commenced = 1; + /* if the smp_ops->setup_cpu function has not already synched the + * timebases with a nicer hardware-based method, do so now + * + * I am open to suggestions for improvements to this method + * -- Troy <hozer@drgw.net> + * + * NOTE: if you are debugging, set smp_tb_synchronized for now + * since if this code runs pretty early and needs all cpus that + * reported in in smp_callin_map to be working + * + * NOTE2: this code doesn't seem to work on > 2 cpus. -- paulus + */ + if (!smp_tb_synchronized) { + unsigned long flags; + __save_and_cli(flags); + smp_software_tb_sync(0); + __restore_flags(flags); + } +} + +void __init smp_callin(void) +{ + int cpu = current->processor; + + smp_store_cpu_info(cpu); + set_dec(tb_ticks_per_jiffy); + cpu_callin_map[cpu] = 1; + + smp_ops->setup_cpu(cpu); + + init_idle(); + + while(!smp_commenced) + barrier(); + /* see smp_commence for more info */ + if (!smp_tb_synchronized){ + smp_software_tb_sync(cpu); + } + __sti(); } /* intel needs this */ @@ -576,37 +1162,6 @@ int __init start_secondary(void *unused) return cpu_idle(NULL); } -void __init smp_callin(void) -{ - smp_store_cpu_info(current->processor); - set_dec(tb_ticks_per_jiffy); - if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) { - set_tb(0, 0); /* set timebase if not 601 */ - last_jiffy_stamp(current->processor) = 0; - } - init_idle(); - cpu_callin_map[current->processor] = 1; - -#ifndef CONFIG_POWER4 - /* - * Each processor has to do this and this is the best - * place to stick it for now. - * -- Cort - */ - if (OpenPIC && _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep)) - do_openpic_setup_cpu(); -#else - xics_setup_cpu(); -#endif /* CONFIG_POWER4 */ -#ifdef CONFIG_GEMINI - if ( _machine == _MACH_gemini ) - gemini_init_l2(); -#endif - while(!smp_commenced) - barrier(); - __sti(); -} - void __init smp_setup(char *str, int *ints) { } @@ -621,6 +1176,14 @@ void __init smp_store_cpu_info(int id) struct cpuinfo_PPC *c = &cpu_data[id]; /* assume bogomips are same for everything */ - c->loops_per_sec = loops_per_sec; + c->loops_per_jiffy = loops_per_jiffy; c->pvr = _get_PVR(); } + +static int __init maxcpus(char *str) +{ + get_option(&str, &max_cpus); + return 1; +} + +__setup("maxcpus=", maxcpus); diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c index f71c8cbbf811..5b36cedcc156 100644 --- a/arch/ppc/kernel/time.c +++ b/arch/ppc/kernel/time.c @@ -67,7 +67,12 @@ #include <asm/time.h> -void smp_local_timer_interrupt(struct pt_regs *); +#ifdef CONFIG_SMP +extern void smp_local_timer_interrupt(struct pt_regs *); +extern int smp_tb_synchronized; +#endif /* CONFIG_SMP */ + +extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz); /* keep track of when we need to update the rtc */ time_t last_rtc_update; @@ -97,6 +102,36 @@ static inline int tb_delta(unsigned *jiffy_stamp) { return delta; } +extern unsigned long prof_cpu_mask; +extern unsigned int * prof_buffer; +extern unsigned long prof_len; +extern unsigned long prof_shift; +extern char _stext; + +static inline void ppc_do_profile (unsigned long nip) +{ + if (!prof_buffer) + return; + + /* + * Only measure the CPUs specified by /proc/irq/prof_cpu_mask. + * (default is all CPUs.) + */ + if (!((1<<smp_processor_id()) & prof_cpu_mask)) + return; + + nip -= (unsigned long) &_stext; + nip >>= prof_shift; + /* + * Don't ignore out-of-bounds EIP values silently, + * put them into the last histogram slot, so if + * present, they will show up as a sharp peak. + */ + if (nip > prof_len-1) + nip = prof_len-1; + atomic_inc((atomic_t *)&prof_buffer[nip]); +} + /* * timer_interrupt - gets called when the decrementer overflows, * with interrupts disabled. @@ -110,6 +145,9 @@ int timer_interrupt(struct pt_regs * regs) hardirq_enter(cpu); + if (!user_mode(regs)) + ppc_do_profile(instruction_pointer(regs)); + do { jiffy_stamp += tb_ticks_per_jiffy; if (smp_processor_id()) continue; @@ -151,7 +189,7 @@ int timer_interrupt(struct pt_regs * regs) #ifdef CONFIG_SMP smp_local_timer_interrupt(regs); -#endif +#endif /* CONFIG_SMP */ if (ppc_md.heartbeat && !ppc_md.heartbeat_count--) ppc_md.heartbeat(); @@ -176,7 +214,7 @@ void do_gettimeofday(struct timeval *tv) /* As long as timebases are not in sync, gettimeofday can only * have jiffy resolution on SMP. */ - if (_machine != _MACH_Pmac) + if (!smp_tb_synchronized) delta = 0; #endif /* CONFIG_SMP */ lost_ticks = jiffies - wall_jiffies; diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index 3b7473dda3f5..8bd9ebded554 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -65,21 +65,37 @@ int (*debugger_dabr_match)(struct pt_regs *regs); void (*debugger_fault_handler)(struct pt_regs *regs); #endif #endif + /* * Trap & Exception support */ + +spinlock_t oops_lock = SPIN_LOCK_UNLOCKED; + +void die(const char * str, struct pt_regs * fp, long err) +{ + console_verbose(); + spin_lock_irq(&oops_lock); + printk("Oops: %s, sig: %ld\n", str, err); + show_regs(fp); + print_backtrace((unsigned long *)fp->gpr[1]); + spin_unlock_irq(&oops_lock); + /* do_exit() should take care of panic'ing from an interrupt + * context so we don't handle it here + */ + do_exit(err); +} + void _exception(int signr, struct pt_regs *regs) { if (!user_mode(regs)) { - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Exception in kernel pc %lx signal %d",regs->nip,signr); + die("Exception in kernel mode", regs, signr); } force_sig(signr, current); } @@ -98,7 +114,7 @@ MachineCheckException(struct pt_regs *regs) #if defined(CONFIG_8xx) && defined(CONFIG_PCI) /* the qspan pci read routines can cause machine checks -- Cort */ - bad_page_fault(regs, regs->dar); + bad_page_fault(regs, regs->dar, SIGBUS); return; #endif #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) @@ -151,12 +167,10 @@ MachineCheckException(struct pt_regs *regs) default: printk("Unknown values in msr\n"); } - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("machine check"); + die("machine check", regs, SIGBUS); } void @@ -217,13 +231,13 @@ emulate_instruction(struct pt_regs *regs) uint rd; uint retval; - retval = EFAULT; + retval = EINVAL; if (!user_mode(regs)) return retval; if (get_user(instword, (uint *)(regs->nip))) - return retval; + return EFAULT; /* Emulate the mfspr rD, PVR. */ @@ -337,12 +351,10 @@ SoftwareEmulation(struct pt_regs *regs) int errcode; if (!user_mode(regs)) { - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) debugger(regs); #endif - print_backtrace((unsigned long *)regs->gpr[1]); - panic("Kernel Mode Software FPU Emulation"); + die("Kernel Mode Software FPU Emulation", regs, SIGFPE); } #ifdef CONFIG_MATH_EMULATION diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index 1e973940cd27..b6f99174baa6 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -9,6 +9,6 @@ O_TARGET := lib.o obj-y := checksum.o string.o strcase.o -obj-$(CONFIG_SMP) := locks.o +obj-$(CONFIG_SMP) += locks.o include $(TOPDIR)/Rules.make diff --git a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c index 60d8576da857..a5b0a40a872d 100644 --- a/arch/ppc/lib/locks.c +++ b/arch/ppc/lib/locks.c @@ -58,8 +58,9 @@ void _spin_unlock(spinlock_t *lp) { #ifdef DEBUG_LOCKS if ( !lp->lock ) - printk("_spin_unlock(%p): no lock cpu %d %s/%d\n", lp, - smp_processor_id(),current->comm,current->pid); + printk("_spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n", + lp, smp_processor_id(), __builtin_return_address(0), + current->comm, current->pid); if ( lp->owner_cpu != smp_processor_id() ) printk("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n", lp, smp_processor_id(), (int)lp->owner_cpu, diff --git a/arch/ppc/mbxboot/vmlinux.lds b/arch/ppc/mbxboot/vmlinux.lds deleted file mode 100644 index 2bf2c87b3486..000000000000 --- a/arch/ppc/mbxboot/vmlinux.lds +++ /dev/null @@ -1,152 +0,0 @@ -OUTPUT_ARCH(powerpc) -SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } -/* .init : { *(.init) } =0*/ - .plt : { *(.plt) } - .text : - { - *(.text) - *(.fixup) - *(.got1) - } - _etext = .; - PROVIDE (etext = .); - .rodata : - { - *(.rodata) - *(.rodata1) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - - .fixup : { *(.fixup) } - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - . = ALIGN(4096); - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { - *(.data.init); - __vtop_table_begin = .; - *(.vtop_fixup); - __vtop_table_end = .; - __ptov_table_begin = .; - *(.ptov_fixup); - __ptov_table_end = .; - } - . = ALIGN(16); - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { *(.initcall.init) } - __initcall_end = .; - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - __pmac_begin = .; - .text.pmac : { *(.text.pmac) } - .data.pmac : { *(.data.pmac) } - . = ALIGN(4096); - __pmac_end = .; - - . = ALIGN(4096); - __prep_begin = .; - .text.prep : { *(.text.prep) } - .data.prep : { *(.data.prep) } - . = ALIGN(4096); - __prep_end = .; - - . = ALIGN(4096); - __apus_begin = .; - .text.apus : { *(.text.apus) } - .data.apus : { *(.data.apus) } - . = ALIGN(4096); - __apus_end = .; - - . = ALIGN(4096); - __apus_begin = .; - .text.apus : { *(.text.apus) } - .data.apus : { *(.data.apus) } - . = ALIGN(4096); - __apus_end = .; - - . = ALIGN(4096); - __openfirmware_begin = .; - .text.openfirmware : { *(.text.openfirmware) } - .data.openfirmware : { *(.data.openfirmware) } - . = ALIGN(4096); - __openfirmware_end = .; - - __bss_start = .; - .bss : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); - - /* - * For loader only: Put the zImage after everything else - */ - _gzstart = . ; - .gzimage : { *(.gzimage) } - _gzend = . ; - - /* - * For loader only: Put the initrd after zImage - */ - _rdstart = . ; - .rdimage : { *(.rdimage) } - _rdend = . ; - -} diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index b6da2cdfcabd..97bb6dbc1aea 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -48,7 +48,7 @@ unsigned long pte_errors = 0; /* updated by do_page_fault() */ unsigned int probingmem = 0; extern void die_if_kernel(char *, struct pt_regs *, long); -void bad_page_fault(struct pt_regs *, unsigned long); +void bad_page_fault(struct pt_regs *, unsigned long, int sig); void do_page_fault(struct pt_regs *, unsigned long, unsigned long); /* @@ -96,7 +96,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address, #endif /* CONFIG_XMON || CONFIG_KGDB */ if (in_interrupt() || mm == NULL) { - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGSEGV); return; } down(&mm->mmap_sem); @@ -182,7 +182,7 @@ bad_area: return; } - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGSEGV); return; /* @@ -194,7 +194,7 @@ out_of_memory: printk("VM: killing process %s\n", current->comm); if (user_mode(regs)) do_exit(SIGKILL); - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGKILL); return; do_sigbus: @@ -205,7 +205,7 @@ do_sigbus: info.si_addr = (void *)address; force_sig_info (SIGBUS, &info, current); if (!user_mode(regs)) - bad_page_fault(regs, address); + bad_page_fault(regs, address, SIGBUS); } /* @@ -214,8 +214,10 @@ do_sigbus: * in traps.c. */ void -bad_page_fault(struct pt_regs *regs, unsigned long address) +bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) { + extern void die(const char *,struct pt_regs *,long); + unsigned long fixup; /* Are we prepared to handle this fault? */ @@ -225,14 +227,11 @@ bad_page_fault(struct pt_regs *regs, unsigned long address) } /* kernel has accessed a bad area */ - show_regs(regs); #if defined(CONFIG_XMON) || defined(CONFIG_KGDB) if (debugger_kernel_faults) debugger(regs); #endif - print_backtrace( (unsigned long *)regs->gpr[1] ); - panic("kernel access of bad area pc %lx lr %lx address %lX tsk %s/%d", - regs->nip,regs->link,address,current->comm,current->pid); + die("kernel access of bad area", regs, sig); } #ifdef CONFIG_8xx diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index c3d77a67ec22..839b618d0c22 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -34,7 +34,6 @@ #include <linux/vmalloc.h> #include <linux/init.h> #include <linux/delay.h> -#include <linux/openpic.h> #include <linux/bootmem.h> #include <linux/highmem.h> #ifdef CONFIG_BLK_DEV_INITRD @@ -62,7 +61,6 @@ #include <asm/machdep.h> #include <asm/setup.h> #include <asm/amigahw.h> -#include <asm/gemini.h> #include "mem_pieces.h" @@ -70,15 +68,17 @@ #include "4xx_tlb.h" #endif -#define MAX_LOW_MEM (640 << 20) +#define MAX_LOW_MEM (512 << 20) #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10) int prom_trashed; atomic_t next_mmu_context; +rwlock_t context_overflow_lock __cacheline_aligned = RW_LOCK_UNLOCKED; unsigned long *end_of_DRAM; unsigned long total_memory; unsigned long total_lowmem; +unsigned long ram_phys_base; int mem_init_done; int init_bootmem_done; int boot_mapsize; @@ -114,7 +114,6 @@ static void *MMU_get_page(void); unsigned long prep_find_end_of_memory(void); unsigned long pmac_find_end_of_memory(void); unsigned long apus_find_end_of_memory(void); -unsigned long gemini_find_end_of_memory(void); extern unsigned long find_end_of_memory(void); #ifdef CONFIG_8xx unsigned long m8xx_find_end_of_memory(void); @@ -127,14 +126,13 @@ unsigned long m8260_find_end_of_memory(void); #endif /* CONFIG_8260 */ static void mapin_ram(void); void map_page(unsigned long va, unsigned long pa, int flags); -void set_phys_avail(struct mem_pieces *mp); +void set_phys_avail(unsigned long total_ram); extern void die_if_kernel(char *,struct pt_regs *,long); extern char _start[], _end[]; extern char _stext[], etext[]; extern struct task_struct *current_set[NR_CPUS]; -struct mem_pieces phys_mem; char *klimit = _end; struct mem_pieces phys_avail; @@ -199,6 +197,8 @@ int __map_without_bats; /* max amount of RAM to use */ unsigned long __max_memory; +/* max amount of low RAM to map in */ +unsigned long __max_low_memory = MAX_LOW_MEM; void __bad_pte(pmd_t *pmd) { @@ -399,8 +399,8 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) * If the address lies within the first 16 MB, assume it's in ISA * memory space */ - if (p < 16*1024*1024) - p += _ISA_MEM_BASE; + if ( p < 16*1024*1024 ) + p += _ISA_MEM_BASE; /* * Don't allow anybody to remap normal RAM that we're using. @@ -437,7 +437,11 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags) return NULL; v = VMALLOC_VMADDR(area->addr); } else { +#ifndef CONFIG_HIGHMEM if (p >= ioremap_base) +#else + if (p >= ioremap_base && p < PKMAP_BASE) +#endif /* CONFIG_HIGHMEM */ v = p; else v = (ioremap_bot -= size); @@ -491,16 +495,13 @@ unsigned long iopa(unsigned long addr) void map_page(unsigned long va, unsigned long pa, int flags) { - pmd_t *pd, oldpd; + pmd_t *pd; pte_t *pg; /* Use upper 10 bits of VA to index the first level map */ pd = pmd_offset(pgd_offset_k(va), va); - oldpd = *pd; /* Use middle 10 bits of VA to index the second-level map */ pg = pte_alloc(pd, va); - if (pmd_none(oldpd) && mem_init_done) - set_pgdir(va, *(pgd_t *)pd); set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); if (mem_init_done) flush_hash_page(0, va); @@ -532,6 +533,8 @@ local_flush_tlb_all(void) * 0xd0000000 on 64-bit machines. */ flush_hash_segments(0xd, 0xffffff); #else + /* this could cause problems on SMP with nobats -- paulus */ + /* XXX no hash_table_lock? interesting -- paulus */ __clear_user(Hash, Hash_size); _tlbia(); #ifdef CONFIG_SMP @@ -548,6 +551,27 @@ local_flush_tlb_all(void) void local_flush_tlb_mm(struct mm_struct *mm) { + if (mm->context == 0) { + /* don't try to reassign a new context to the kernel */ + /* + * This could cause problems on SMP if we aren't using + * the BATs (e.g. on POWER4 or if the nobats option is used). + * The problem scenario is that one cpu is doing + * flush_hash_page or similar when another cpu clears + * out the HPTEs which map the flush_hash_page text + * and the hash table. hash_page will then deadlock. + * We need some way to have "protected" HPTEs or else + * do all hash-table manipulation with the MMU off. + * -- paulus. + */ +#ifdef CONFIG_PPC64BRIDGE + flush_hash_segments(0xd, 0xf); +#else + flush_hash_segments(0xc, 0xf); +#endif CONFIG_PPC64BRIDGE + _tlbia(); + return; + } mm->context = NO_CONTEXT; if (mm == current->mm) activate_mm(mm, mm); @@ -581,16 +605,18 @@ local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long e { start &= PAGE_MASK; - if (end - start > 20 * PAGE_SIZE) - { - flush_tlb_mm(mm); - return; + if (mm->context != 0) { + if (end > TASK_SIZE) + end = TASK_SIZE; + if (end - start > 20 * PAGE_SIZE) { + flush_tlb_mm(mm); + return; + } } - for (; start < end && start < TASK_SIZE; start += PAGE_SIZE) - { + for (; start < end; start += PAGE_SIZE) flush_hash_page(mm->context, start); - } + #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif @@ -608,23 +634,36 @@ mmu_context_overflow(void) struct task_struct *tsk; printk(KERN_DEBUG "mmu_context_overflow\n"); - read_lock(&tasklist_lock); - for_each_task(tsk) { - if (tsk->mm) - tsk->mm->context = NO_CONTEXT; - } - read_unlock(&tasklist_lock); - flush_hash_segments(0x10, 0xffffff); + /* acquire the write lock for context overflow */ + write_lock (&context_overflow_lock); + /* recheck if overflow still exists */ + if (atomic_read(&next_mmu_context) == LAST_CONTEXT) { + read_lock(&tasklist_lock); + for_each_task(tsk) { + if (tsk->mm) + tsk->mm->context = NO_CONTEXT; + } + read_unlock(&tasklist_lock); + flush_hash_segments(0x10, 0xffffff); #ifdef CONFIG_SMP - smp_send_tlb_invalidate(0); + smp_send_tlb_invalidate(0); #endif - atomic_set(&next_mmu_context, 0); + atomic_set(&next_mmu_context, 0); + } + write_unlock (&context_overflow_lock); /* make sure current always has a context */ - current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); - /* The PGD is only a placeholder. It is only used on - * 8xx processors. - */ - set_context(current->mm->context, current->mm->pgd); + /* need to check to assure current task has an mm */ + /* - idle thread does not have an MM */ + if (current->mm) { + current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); + set_context(current->mm->context, current->mm->pgd); + } +} +#else /* CONFIG_8xx */ +void +mmu_context_overflow(void) +{ + atomic_set(&next_mmu_context, -1); } #endif /* CONFIG_8xx */ @@ -727,22 +766,20 @@ void __init setbat(int index, unsigned long virt, unsigned long phys, static void __init mapin_ram(void) { - int i; unsigned long v, p, s, f; #if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_POWER4) if (!__map_without_bats) { - unsigned long tot, mem_base, bl, done; + unsigned long tot, bl, done; unsigned long max_size = (256<<20); unsigned long align; /* Set up BAT2 and if necessary BAT3 to cover RAM. */ - mem_base = __pa(KERNELBASE); /* Make sure we don't map a block larger than the smallest alignment of the physical address. */ - /* alignment of mem_base */ - align = ~(mem_base-1) & mem_base; + /* alignment of ram_phys_base */ + align = ~(ram_phys_base-1) & ram_phys_base; /* set BAT block size to MIN(max_size, align) */ if (align && align < max_size) max_size = align; @@ -753,7 +790,7 @@ static void __init mapin_ram(void) break; } - setbat(2, KERNELBASE, mem_base, bl, RAM_PAGE); + setbat(2, KERNELBASE, ram_phys_base, bl, RAM_PAGE); done = (unsigned long)bat_addrs[2].limit - KERNELBASE + 1; if ((done < tot) && !bat_addrs[3].limit) { /* use BAT3 to cover a bit more */ @@ -761,41 +798,35 @@ static void __init mapin_ram(void) for (bl = 128<<10; bl < max_size; bl <<= 1) if (bl * 2 > tot) break; - setbat(3, KERNELBASE+done, mem_base+done, bl, + setbat(3, KERNELBASE+done, ram_phys_base+done, bl, RAM_PAGE); } } #endif /* !CONFIG_4xx && !CONFIG_8xx && !CONFIG_POWER4 */ - for (i = 0; i < phys_mem.n_regions; ++i) { - v = (ulong)__va(phys_mem.regions[i].address); - p = phys_mem.regions[i].address; - if (p >= total_lowmem) - break; - for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) { - /* On the MPC8xx, we want the page shared so we - * don't get ASID compares on kernel space. - */ - f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; + v = KERNELBASE; + p = ram_phys_base; + for (s = 0; s < total_lowmem; s += PAGE_SIZE) { + /* On the MPC8xx, we want the page shared so we + * don't get ASID compares on kernel space. + */ + f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) - /* Allows stub to set breakpoints everywhere */ - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + /* Allows stub to set breakpoints everywhere */ + f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #else - if ((char *) v < _stext || (char *) v >= etext) - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + if ((char *) v < _stext || (char *) v >= etext) + f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; #ifndef CONFIG_8xx - else - /* On the powerpc (not 8xx), no user access - forces R/W kernel access */ - f |= _PAGE_USER; + else + /* On the powerpc (not 8xx), no user access + forces R/W kernel access */ + f |= _PAGE_USER; #endif /* CONFIG_8xx */ #endif /* CONFIG_KGDB */ - map_page(v, p, f); - v += PAGE_SIZE; - p += PAGE_SIZE; - if (p >= total_lowmem) - break; - } + map_page(v, p, f); + v += PAGE_SIZE; + p += PAGE_SIZE; } } @@ -922,27 +953,64 @@ MMU_init(void) mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */ mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ } -#else - /* How about ppc_md.md_find_end_of_memory instead of these - * ifdefs? -- Dan. - */ -#ifdef CONFIG_BOOTX_TEXT -extern boot_infos_t *disp_bi; + +#elif defined(CONFIG_8xx) +void __init MMU_init(void) +{ + if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); + + total_memory = total_lowmem = m8xx_find_end_of_memory(); +#ifdef CONFIG_HIGHMEM + if (total_lowmem > MAX_LOW_MEM) { + total_lowmem = MAX_LOW_MEM; + mem_pieces_remove(&phys_avail, total_lowmem, + total_memory - total_lowmem, 0); + } +#endif /* CONFIG_HIGHMEM */ + end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); + + /* Map in all of RAM starting at KERNELBASE */ + mapin_ram(); + + /* Now map in some of the I/O space that is generically needed + * or shared with multiple devices. + * All of this fits into the same 4Mbyte region, so it only + * requires one page table page. + */ + ioremap(IMAP_ADDR, IMAP_SIZE); +#ifdef CONFIG_MBX + ioremap(NVRAM_ADDR, NVRAM_SIZE); + ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + + /* Map some of the PCI/ISA I/O space to get the IDE interface. + */ + ioremap(PCI_ISA_IO_ADDR, 0x4000); + ioremap(PCI_IDE_ADDR, 0x4000); +#endif +#ifdef CONFIG_RPXLITE + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); + ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); +#endif +#ifdef CONFIG_RPXCLASSIC + ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); + ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); #endif + if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); +} + +#else /* not 4xx or 8xx */ void __init MMU_init(void) { if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111); -#ifndef CONFIG_8xx + if (have_of) total_memory = pmac_find_end_of_memory(); #ifdef CONFIG_APUS else if (_machine == _MACH_apus ) total_memory = apus_find_end_of_memory(); #endif -#ifdef CONFIG_GEMINI - else if ( _machine == _MACH_gemini ) - total_memory = gemini_find_end_of_memory(); -#endif /* CONFIG_GEMINI */ #if defined(CONFIG_8260) else total_memory = m8260_find_end_of_memory(); @@ -950,16 +1018,17 @@ void __init MMU_init(void) else /* prep */ total_memory = prep_find_end_of_memory(); #endif - + if (__max_memory && total_memory > __max_memory) + total_memory = __max_memory; total_lowmem = total_memory; -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } + if (total_lowmem > __max_low_memory) { + total_lowmem = __max_low_memory; +#ifndef CONFIG_HIGHMEM + total_memory = total_lowmem; #endif /* CONFIG_HIGHMEM */ + } end_of_DRAM = __va(total_lowmem); + set_phys_avail(total_lowmem); if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300); hash_init(); @@ -991,12 +1060,15 @@ void __init MMU_init(void) ioremap_base = 0xf0000000; break; case _MACH_chrp: - setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); -#ifdef CONFIG_PPC64BRIDGE - setbat(1, 0x80000000, 0xc0000000, 0x10000000, IO_PAGE); -#else - setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); - setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); + /* + * The code below tends to get removed, please don't take it out. + * The F50 needs this mapping and it you take it out I'll track you + * down and slap your hands. If it causes problems please email me. + * -- Cort <cort@fsmlabs.com> + */ +#ifndef CONFIG_POWER3 + setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); #endif break; case _MACH_Pmac: @@ -1008,10 +1080,6 @@ void __init MMU_init(void) /* Map chip and ZorroII memory */ setbat(1, zTwoBase, 0x00000000, 0x01000000, IO_PAGE); break; - case _MACH_gemini: - setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE); - setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); - break; case _MACH_8260: /* Map the IMMR, plus anything else we can cover * in that upper space according to the memory controller @@ -1025,46 +1093,7 @@ void __init MMU_init(void) } ioremap_bot = ioremap_base; #endif /* CONFIG_POWER4 */ -#else /* CONFIG_8xx */ - - total_memory = total_lowmem = m8xx_find_end_of_memory(); -#ifdef CONFIG_HIGHMEM - if (total_lowmem > MAX_LOW_MEM) { - total_lowmem = MAX_LOW_MEM; - mem_pieces_remove(&phys_avail, total_lowmem, - total_memory - total_lowmem, 0); - } -#endif /* CONFIG_HIGHMEM */ - end_of_DRAM = __va(total_lowmem); - - /* Map in all of RAM starting at KERNELBASE */ - mapin_ram(); - - /* Now map in some of the I/O space that is generically needed - * or shared with multiple devices. - * All of this fits into the same 4Mbyte region, so it only - * requires one page table page. - */ - ioremap(IMAP_ADDR, IMAP_SIZE); -#ifdef CONFIG_MBX - ioremap(NVRAM_ADDR, NVRAM_SIZE); - ioremap(MBX_CSR_ADDR, MBX_CSR_SIZE); - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - /* Map some of the PCI/ISA I/O space to get the IDE interface. - */ - ioremap(PCI_ISA_IO_ADDR, 0x4000); - ioremap(PCI_IDE_ADDR, 0x4000); -#endif -#ifdef CONFIG_RPXLITE - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); - ioremap(HIOX_CSR_ADDR, HIOX_CSR_SIZE); -#endif -#ifdef CONFIG_RPXCLASSIC - ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); - ioremap(RPX_CSR_ADDR, RPX_CSR_SIZE); -#endif -#endif /* CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT /* Must be done last, or ppc_md.progress will die */ @@ -1189,7 +1218,8 @@ void __init mem_init(void) #if defined(CONFIG_ALL_PPC) /* mark the RTAS pages as reserved */ if ( rtas_data ) - for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ; + for (addr = (ulong)__va(rtas_data); + addr < PAGE_ALIGN((ulong)__va(rtas_data)+rtas_size) ; addr += PAGE_SIZE) SetPageReserved(virt_to_page(addr)); #endif /* defined(CONFIG_ALL_PPC) */ @@ -1249,7 +1279,7 @@ void __init mem_init(void) unsigned long __init pmac_find_end_of_memory(void) { unsigned long a, total; - unsigned long ram_limit = 0xe0000000 - KERNELBASE; + struct mem_pieces phys_mem; memory_node = find_devices("memory"); if (memory_node == NULL) { @@ -1260,8 +1290,7 @@ unsigned long __init pmac_find_end_of_memory(void) /* * Find out where physical memory is, and check that it * starts at 0 and is contiguous. It seems that RAM is - * always physically contiguous on Power Macintoshes, - * because MacOS can't cope if it isn't. + * always physically contiguous on Power Macintoshes. * * Supporting discontiguous physical memory isn't hard, * it just makes the virtual <-> physical mapping functions @@ -1274,23 +1303,14 @@ unsigned long __init pmac_find_end_of_memory(void) a = phys_mem.regions[0].address; if (a != 0) panic("RAM doesn't start at physical address 0"); - if (__max_memory == 0 || __max_memory > ram_limit) - __max_memory = ram_limit; - if (phys_mem.regions[0].size >= __max_memory) { - phys_mem.regions[0].size = __max_memory; - phys_mem.n_regions = 1; - } total = phys_mem.regions[0].size; - + if (phys_mem.n_regions > 1) { printk("RAM starting at 0x%x is not contiguous\n", phys_mem.regions[1].address); printk("Using RAM from 0 to 0x%lx\n", total-1); - phys_mem.n_regions = 1; } - set_phys_avail(&phys_mem); - return total; } #endif /* CONFIG_ALL_PPC */ @@ -1305,7 +1325,11 @@ unsigned long __init pmac_find_end_of_memory(void) unsigned long __init prep_find_end_of_memory(void) { unsigned long total; +#ifdef CONFIG_PREP_RESIDUAL total = res->TotalMemory; +#else + total = 0; +#endif if (total == 0 ) { @@ -1317,33 +1341,11 @@ unsigned long __init prep_find_end_of_memory(void) total = 0x02000000; printk("Ramsize default to be %ldM\n", total>>20); } - mem_pieces_append(&phys_mem, 0, total); - set_phys_avail(&phys_mem); return (total); } #endif /* defined(CONFIG_ALL_PPC) */ - -#if defined(CONFIG_GEMINI) -unsigned long __init gemini_find_end_of_memory(void) -{ - unsigned long total; - unsigned char reg; - - reg = readb(GEMINI_MEMCFG); - total = ((1<<((reg & 0x7) - 1)) * - (8<<((reg >> 3) & 0x7))); - total *= (1024*1024); - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = total; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].size; -} -#endif /* defined(CONFIG_GEMINI) */ - #ifdef CONFIG_8260 /* * Same hack as 8xx. @@ -1355,12 +1357,7 @@ unsigned long __init m8260_find_end_of_memory(void) binfo = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].size; + return binfo->bi_memsize; } #endif /* CONFIG_8260 */ @@ -1369,6 +1366,7 @@ unsigned long __init m8260_find_end_of_memory(void) unsigned long __init apus_find_end_of_memory(void) { int shadow = 0; + unsigned long total; /* The memory size reported by ADOS excludes the 512KB reserved for PPC exception registers and possibly 512KB @@ -1394,43 +1392,28 @@ unsigned long __init apus_find_end_of_memory(void) memory[0].size = ((size+0x001fffff) & 0xffe00000); } - /* Now register the memory block. */ - mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size); - set_phys_avail(&phys_mem); + total = memory[0].size; /* Remove the memory chunks that are controlled by special Phase5 hardware. */ - { - unsigned long top = memory[0].addr + memory[0].size; - /* Remove the upper 512KB if it contains a shadow of - the ADOS ROM. FIXME: It might be possible to - disable this shadow HW. Check the booter - (ppc_boot.c) */ - if (shadow) - { - top -= HARDWARE_MAPPED_SIZE; - mem_pieces_remove(&phys_avail, top, - HARDWARE_MAPPED_SIZE, 0); - } - - /* Remove the upper 512KB where the PPC exception - vectors are mapped. */ - top -= HARDWARE_MAPPED_SIZE; -#if 0 - /* This would be neat, but it breaks on A3000 machines!? */ - mem_pieces_remove(&phys_avail, top, 16384, 0); -#else - mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0); -#endif + /* Remove the upper 512KB if it contains a shadow of + the ADOS ROM. FIXME: It might be possible to + disable this shadow HW. Check the booter + (ppc_boot.c) */ + if (shadow) + total -= HARDWARE_MAPPED_SIZE; - } + /* Remove the upper 512KB where the PPC exception + vectors are mapped. */ + total -= HARDWARE_MAPPED_SIZE; /* Linux/APUS only handles one block of memory -- the one on the PowerUP board. Other system memory is horrible slow in comparison. The user can use other memory for swapping using the z2ram device. */ - return memory[0].addr + memory[0].size; + ram_phys_base = memory[0].addr; + return total; } #endif /* CONFIG_APUS */ @@ -1440,12 +1423,11 @@ unsigned long __init apus_find_end_of_memory(void) static void __init hash_init(void) { int Hash_bits, mb, mb2; - unsigned int hmask, ramsize, h; + unsigned int hmask, h; extern unsigned int hash_page_patch_A[], hash_page_patch_B[], hash_page_patch_C[], hash_page[]; - ramsize = (ulong)end_of_DRAM - KERNELBASE; #ifdef CONFIG_PPC64BRIDGE /* The hash table has already been allocated and initialized in prom.c */ @@ -1464,7 +1446,7 @@ static void __init hash_init(void) * Allow 64k of hash table for every 16MB of memory, * up to a maximum of 2MB. */ - for (h = 64<<10; h < ramsize / 256 && h < (2<<20); h *= 2) + for (h = 64<<10; h < total_memory / 256 && h < (2<<20); h *= 2) ; Hash_size = h; Hash_mask = (h >> 6) - 1; @@ -1498,8 +1480,8 @@ static void __init hash_init(void) Hash = 0; #endif /* CONFIG_PPC64BRIDGE */ - printk("Total memory = %dMB; using %ldkB for hash table (at %p)\n", - ramsize >> 20, Hash_size >> 10, Hash); + printk("Total memory = %ldMB; using %ldkB for hash table (at %p)\n", + total_memory >> 20, Hash_size >> 10, Hash); if ( Hash_size ) { if ( ppc_md.progress ) ppc_md.progress("hash:patch", 0x345); @@ -1560,12 +1542,7 @@ unsigned long __init m8xx_find_end_of_memory(void) binfo = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = binfo->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return phys_mem.regions[0].address + phys_mem.regions[0].size; + return binfo->bi_memsize; } #endif /* !CONFIG_4xx && !CONFIG_8xx */ @@ -1582,20 +1559,16 @@ oak_find_end_of_memory(void) unsigned long *ret; bd_t *bip = (bd_t *)__res; - phys_mem.regions[0].address = 0; - phys_mem.regions[0].size = bip->bi_memsize; - phys_mem.n_regions = 1; - - set_phys_avail(&phys_mem); - return (phys_mem.regions[0].address + phys_mem.regions[0].size); + return bip->bi_memsize; } #endif /* - * Set phys_avail to phys_mem less the kernel text/data/bss. + * Set phys_avail to the amount of physical memory, + * less the kernel text/data/bss. */ void __init -set_phys_avail(struct mem_pieces *mp) +set_phys_avail(unsigned long total_memory) { unsigned long kstart, ksize; @@ -1604,7 +1577,9 @@ set_phys_avail(struct mem_pieces *mp) * physical memory. */ - phys_avail = *mp; + phys_avail.regions[0].address = 0; + phys_avail.regions[0].size = total_memory; + phys_avail.n_regions = 1; /* * Map out the kernel text/data/bss from the available physical diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c index 499c5b6c8303..611b1e069fe0 100644 --- a/arch/ppc/xmon/start.c +++ b/arch/ppc/xmon/start.c @@ -14,6 +14,10 @@ #include <asm/bootx.h> #include <asm/feature.h> #include <asm/processor.h> +#include <asm/delay.h> +#ifdef CONFIG_SMP +#include <asm/bitops.h> +#endif static volatile unsigned char *sccc, *sccd; unsigned long TXRDY, RXRDY; @@ -22,10 +26,10 @@ extern void prom_drawchar(char); extern void prom_drawstring(const char *str); static int xmon_expect(const char *str, unsigned int timeout); -static int console = 0; -static int use_screen = 1; /* default */ -static int via_modem = 0; -static int xmon_use_sccb = 0; +static int console; +static int use_screen; +static int via_modem = 1; +static int xmon_use_sccb; static struct device_node *macio_node; #define TB_SPEED 25000000 @@ -53,28 +57,32 @@ xmon_map_scc(void) use_screen = 0; - if ( _machine == _MACH_Pmac ) - { + if (_machine == _MACH_Pmac) { struct device_node *np; unsigned long addr; #ifdef CONFIG_BOOTX_TEXT extern boot_infos_t *disp_bi; + /* see if there is a keyboard in the device tree + with a parent of type "adb" */ + for (np = find_devices("keyboard"); np; np = np->next) + if (np->parent && np->parent->type + && strcmp(np->parent->type, "adb") == 0) + break; + /* needs to be hacked if xmon_printk is to be used from within find_via_pmu() */ #ifdef CONFIG_ADB_PMU - if (!via_modem && disp_bi && find_via_pmu()) { - prom_drawstring("xmon uses screen and keyboard\n"); + if (np != NULL && disp_bi && find_via_pmu()) use_screen = 1; - } #endif #ifdef CONFIG_ADB_CUDA - if (!via_modem && disp_bi ) { - prom_drawstring("xmon uses screen and keyboard\n"); + if (np != NULL && disp_bi && find_via_cuda()) use_screen = 1; - } -#endif #endif + if (use_screen) + prom_drawstring("xmon uses screen and keyboard\n"); +#endif /* CONFIG_BOOTX_TEXT */ #ifdef CHRP_ESCC addr = 0xc1013020; @@ -93,15 +101,6 @@ xmon_map_scc(void) sccc = base + (addr & ~PAGE_MASK); sccd = sccc + 0x10; } - else if ( _machine & _MACH_gemini ) - { - /* should already be mapped by the kernel boot */ - sccc = (volatile unsigned char *) 0xffeffb0d; - sccd = (volatile unsigned char *) 0xffeffb08; - TXRDY = 0x20; - RXRDY = 1; - console = 1; - } else { /* should already be mapped by the kernel boot */ @@ -140,12 +139,22 @@ xmon_write(void *handle, void *ptr, int nb) char *p = ptr; int i, c, ct; +#ifdef CONFIG_SMP + static unsigned long xmon_write_lock; + int lock_wait = 1000000; + int locked; + + while ((locked = test_and_set_bit(0, &xmon_write_lock)) != 0) + if (--lock_wait == 0) + break; +#endif + #ifdef CONFIG_BOOTX_TEXT if (use_screen) { /* write it on the screen */ for (i = 0; i < nb; ++i) prom_drawchar(*p++); - return nb; + goto out; } #endif if (!scc_initialized) @@ -166,8 +175,15 @@ xmon_write(void *handle, void *ptr, int nb) } buf_access(); *sccd = c; + eieio(); } - return i; + + out: +#ifdef CONFIG_SMP + if (!locked) + clear_bit(0, &xmon_write_lock); +#endif + return nb; } int xmon_wants_key; diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c index 49c3be834f95..65082d458607 100644 --- a/arch/ppc/xmon/xmon.c +++ b/arch/ppc/xmon/xmon.c @@ -406,6 +406,7 @@ cmds(struct pt_regs *excp) break; case 'M': print_sysmap(); + break; case 'S': super_regs(); break; @@ -795,6 +796,8 @@ print_sysmap(void) extern char *sysmap; if ( sysmap ) printf("System.map: \n%s", sysmap); + else + printf("No System.map\n"); } void diff --git a/arch/sparc/config.in b/arch/sparc/config.in index dbe1d1fb256c..cb27cf77badc 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.106 2000/11/17 04:27:52 davem Exp $ +# $Id: config.in,v 1.107 2001/01/06 00:46:44 davem Exp $ # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. # @@ -29,6 +29,9 @@ define_bool CONFIG_VT_CONSOLE y bool 'Symmetric multi-processing support (does not work on sun4/sun4c)' CONFIG_SMP +# Identify this as a Sparc32 build +define_bool CONFIG_SPARC32 y + # Global things across all Sun machines. define_bool CONFIG_ISA n define_bool CONFIG_EISA n diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index 19c9feba0822..20c0782e7d76 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -22,7 +22,10 @@ CONFIG_KMOD=y CONFIG_VT=y CONFIG_VT_CONSOLE=y # CONFIG_SMP is not set +CONFIG_SPARC32=y # CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_MCA is not set # CONFIG_PCMCIA is not set CONFIG_SBUS=y CONFIG_SBUSCHAR=y @@ -64,6 +67,7 @@ CONFIG_PROM_CONSOLE=y # CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_CYBER2000 is not set CONFIG_FB_SBUS=y CONFIG_FB_CGSIX=y CONFIG_FB_BWTWO=y @@ -111,10 +115,18 @@ CONFIG_SUN_AURORA=m CONFIG_BLK_DEV_FD=y CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_MD=m -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_BLK_DEV_LVM is not set +# CONFIG_LVM_PROC_FS is not set CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=4096 CONFIG_BLK_DEV_INITRD=y @@ -132,10 +144,8 @@ CONFIG_INET=y # CONFIG_IP_MULTICAST is not set # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set -# CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set # CONFIG_INET_ECN is not set # CONFIG_SYN_COOKIES is not set CONFIG_IPV6=m @@ -148,7 +158,6 @@ CONFIG_IPV6=m # CONFIG_IPX=m # CONFIG_IPX_INTERN is not set -# CONFIG_SPX is not set CONFIG_ATALK=m CONFIG_DECNET=m CONFIG_DECNET_SIOCGIFCONF=y @@ -157,6 +166,7 @@ CONFIG_DECNET_SIOCGIFCONF=y # CONFIG_X25 is not set # CONFIG_LAPB is not set # CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set # CONFIG_ECONET is not set # CONFIG_WAN_ROUTER is not set # CONFIG_NET_FASTROUTE is not set @@ -228,6 +238,7 @@ CONFIG_SCSI_FCAL=m CONFIG_NETDEVICES=y CONFIG_DUMMY=m CONFIG_BONDING=m +# CONFIG_TUN is not set CONFIG_PPP=m CONFIG_PPP_ASYNC=m CONFIG_PPP_SYNC_TTY=m @@ -302,6 +313,7 @@ CONFIG_NFSD=m CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m +# CONFIG_SMB_NLS_DEFAULT is not set # CONFIG_NCP_FS is not set # CONFIG_NCPFS_PACKET_SIGNING is not set # CONFIG_NCPFS_IOCTL_LOCKING is not set @@ -309,8 +321,6 @@ CONFIG_SMB_FS=m # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -320,6 +330,7 @@ CONFIG_SMB_FS=m # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y CONFIG_SUN_PARTITION=y +CONFIG_SMB_NLS=y CONFIG_NLS=y # diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c index c9ba85b2704c..9bc82a518243 100644 --- a/arch/sparc/kernel/pcic.c +++ b/arch/sparc/kernel/pcic.c @@ -1,4 +1,4 @@ -/* $Id: pcic.c,v 1.20 2000/12/05 00:56:36 anton Exp $ +/* $Id: pcic.c,v 1.21 2001/01/18 00:23:00 davem Exp $ * pcic.c: Sparc/PCI controller support * * Copyright (C) 1998 V. Roganov and G. Raiko @@ -898,93 +898,6 @@ void pcic_nmi(unsigned int pend, struct pt_regs *regs) regs->npc += 4; } -/* - * XXX Gleb wrote me that he needs this for X server (only). - * Since we successfuly use XF86_FBDev, we do not need these anymore. - * - * Following code added to handle extra PCI-related system calls - */ -asmlinkage int sys_pciconfig_read(unsigned long bus, - unsigned long dfn, - unsigned long off, - unsigned long len, - unsigned char *buf) -{ - unsigned char ubyte; - unsigned short ushort; - unsigned int uint; - int err = 0; - - if(!suser()) - return -EPERM; - - switch(len) { - case 1: - pcibios_read_config_byte(bus, dfn, off, &ubyte); - put_user(ubyte, (unsigned char *)buf); - break; - case 2: - pcibios_read_config_word(bus, dfn, off, &ushort); - put_user(ushort, (unsigned short *)buf); - break; - case 4: - pcibios_read_config_dword(bus, dfn, off, &uint); - put_user(uint, (unsigned int *)buf); - break; - - default: - err = -EINVAL; - break; - }; - - return err; -} - -asmlinkage int sys_pciconfig_write(unsigned long bus, - unsigned long dfn, - unsigned long off, - unsigned long len, - unsigned char *buf) -{ - unsigned char ubyte; - unsigned short ushort; - unsigned int uint; - int err = 0; - - if(!suser()) - return -EPERM; - - switch(len) { - case 1: - err = get_user(ubyte, (unsigned char *)buf); - if(err) - break; - pcibios_write_config_byte(bus, dfn, off, ubyte); - break; - - case 2: - err = get_user(ushort, (unsigned short *)buf); - if(err) - break; - pcibios_write_config_byte(bus, dfn, off, ushort); - break; - - case 4: - err = get_user(uint, (unsigned int *)buf); - if(err) - break; - pcibios_write_config_byte(bus, dfn, off, uint); - break; - - default: - err = -EINVAL; - break; - - }; - - return err; -} - static inline unsigned long get_irqmask(int irq_nr) { return 1 << irq_nr; diff --git a/arch/sparc/kernel/semaphore.c b/arch/sparc/kernel/semaphore.c index c949717b4321..259a0a71beff 100644 --- a/arch/sparc/kernel/semaphore.c +++ b/arch/sparc/kernel/semaphore.c @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.5 2000/12/29 10:35:05 anton Exp $ */ +/* $Id: semaphore.c,v 1.6 2001/01/05 04:40:07 davem Exp $ */ /* sparc32 semaphore implementation, based on i386 version */ diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index d9883654e5f9..235d4b96e185 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.105 2000/12/11 05:24:25 anton Exp $ +/* $Id: sparc_ksyms.c,v 1.106 2001/01/11 15:07:09 davem Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -154,6 +154,7 @@ EXPORT_SYMBOL(__cpu_logical_map); #endif EXPORT_SYMBOL(udelay); +EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); #if CONFIG_SUN_AUXIO EXPORT_SYMBOL(auxio_register); diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c index 9809815920ed..37113ef38d7f 100644 --- a/arch/sparc/kernel/time.c +++ b/arch/sparc/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.57 2000/09/16 07:33:45 davem Exp $ +/* $Id: time.c,v 1.58 2001/01/11 15:07:09 davem Exp $ * linux/arch/sparc/kernel/time.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -44,6 +44,7 @@ extern rwlock_t xtime_lock; enum sparc_clock_type sp_clock_typ; +spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED; unsigned long mstk48t02_regs = 0UL; static struct mostek48t08 *mstk48t08_regs = 0; static int set_rtc_mmss(unsigned long); @@ -158,12 +159,16 @@ static void __init kick_start_clock(void) prom_printf("CLOCK: Clock was stopped. Kick start "); + spin_lock_irq(&mostek_lock); + /* Turn on the kick start bit to start the oscillator. */ regs->creg |= MSTK_CREG_WRITE; regs->sec &= ~MSTK_STOP; regs->hour |= MSTK_KICK_START; regs->creg &= ~MSTK_CREG_WRITE; + spin_unlock_irq(&mostek_lock); + /* Delay to allow the clock oscillator to start. */ sec = MSTK_REG_SEC(regs); for (i = 0; i < 3; i++) { @@ -175,6 +180,8 @@ static void __init kick_start_clock(void) } prom_printf("\n"); + spin_lock_irq(&mostek_lock); + /* Turn off kick start and set a "valid" time and date. */ regs->creg |= MSTK_CREG_WRITE; regs->hour &= ~MSTK_KICK_START; @@ -187,12 +194,17 @@ static void __init kick_start_clock(void) MSTK_SET_REG_YEAR(regs,1996 - MSTK_YEAR_ZERO); regs->creg &= ~MSTK_CREG_WRITE; + spin_unlock_irq(&mostek_lock); + /* Ensure the kick start bit is off. If it isn't, turn it off. */ while (regs->hour & MSTK_KICK_START) { prom_printf("CLOCK: Kick start still on!\n"); + + spin_lock_irq(&mostek_lock); regs->creg |= MSTK_CREG_WRITE; regs->hour &= ~MSTK_KICK_START; regs->creg &= ~MSTK_CREG_WRITE; + spin_unlock_irq(&mostek_lock); } prom_printf("CLOCK: Kick start procedure successful.\n"); @@ -204,10 +216,12 @@ static __inline__ int has_low_battery(void) struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; unsigned char data1, data2; + spin_lock_irq(&mostek_lock); data1 = regs->eeprom[0]; /* Read some data. */ regs->eeprom[0] = ~data1; /* Write back the complement. */ data2 = regs->eeprom[0]; /* Read back the complement. */ regs->eeprom[0] = data1; /* Restore the original value. */ + spin_unlock_irq(&mostek_lock); return (data1 == data2); /* Was the write blocked? */ } @@ -376,6 +390,7 @@ void __init sbus_time_init(void) prom_printf("Something wrong, clock regs not mapped yet.\n"); prom_halt(); } + spin_lock_irq(&mostek_lock); mregs->creg |= MSTK_CREG_READ; sec = MSTK_REG_SEC(mregs); min = MSTK_REG_MIN(mregs); @@ -386,6 +401,7 @@ void __init sbus_time_init(void) xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_usec = 0; mregs->creg &= ~MSTK_CREG_READ; + spin_unlock_irq(&mostek_lock); #ifdef CONFIG_SUN4 } else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) { /* initialise the intersil on sun4 */ @@ -520,6 +536,7 @@ static int set_rtc_mmss(unsigned long nowtime) { int real_seconds, real_minutes, mostek_minutes; struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs; + unsigned long flags; #ifdef CONFIG_SUN4 struct intersil *iregs = intersil_clock; int temp; @@ -557,6 +574,8 @@ static int set_rtc_mmss(unsigned long nowtime) } #endif } + + spin_lock_irqsave(&mostek_lock, flags); /* Read the current RTC minutes. */ regs->creg |= MSTK_CREG_READ; mostek_minutes = MSTK_REG_MIN(regs); @@ -579,8 +598,10 @@ static int set_rtc_mmss(unsigned long nowtime) MSTK_SET_REG_SEC(regs,real_seconds); MSTK_SET_REG_MIN(regs,real_minutes); regs->creg &= ~MSTK_CREG_WRITE; - } else + spin_unlock_irqrestore(&mostek_lock, flags); + return 0; + } else { + spin_unlock_irqrestore(&mostek_lock, flags); return -1; - - return 0; + } } diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 19b05e28ff4e..5c208915be27 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.125 2000/10/10 01:05:53 davem Exp $ +# $Id: config.in,v 1.130 2001/01/18 04:47:44 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # @@ -26,6 +26,9 @@ define_bool CONFIG_VT_CONSOLE y bool 'Symmetric multi-processing support' CONFIG_SMP +# Identify this as a Sparc64 build +define_bool CONFIG_SPARC64 y + # Global things across all Sun machines. define_bool CONFIG_HAVE_DEC_LOCK y define_bool CONFIG_ISA n @@ -70,6 +73,7 @@ dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT if [ "$CONFIG_PCI" = "y" ]; then tristate 'SUNW, envctrl support' CONFIG_ENVCTRL tristate '7-Segment Display support' CONFIG_DISPLAY7SEG + tristate 'CP1XXX Hardware Watchdog support' CONFIG_WATCHDOG_CP1XXX fi endmenu diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 7c2f852b3a37..c777356b3a63 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -20,8 +20,11 @@ CONFIG_KMOD=y CONFIG_VT=y CONFIG_VT_CONSOLE=y # CONFIG_SMP is not set +CONFIG_SPARC64=y CONFIG_HAVE_DEC_LOCK=y # CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_MCA is not set # CONFIG_PCMCIA is not set CONFIG_SBUS=y CONFIG_SBUSCHAR=y @@ -66,6 +69,7 @@ CONFIG_PARPORT_1284=y CONFIG_PRINTER=m CONFIG_ENVCTRL=m CONFIG_DISPLAY7SEG=m +CONFIG_WATCHDOG_CP1XXX=m # # Console drivers @@ -122,9 +126,7 @@ CONFIG_SUN_AURORA=m # Linux/SPARC audio subsystem (EXPERIMENTAL) # CONFIG_SPARCAUDIO=y -# CONFIG_SPARCAUDIO_AMD7930 is not set CONFIG_SPARCAUDIO_CS4231=y -# CONFIG_SPARCAUDIO_DBRI is not set # CONFIG_SPARCAUDIO_DUMMY is not set # @@ -180,7 +182,6 @@ CONFIG_IPV6=m # CONFIG_IPX=m # CONFIG_IPX_INTERN is not set -# CONFIG_SPX is not set CONFIG_ATALK=m CONFIG_DECNET=m CONFIG_DECNET_SIOCGIFCONF=y @@ -470,8 +471,6 @@ CONFIG_LOCKD_V4=y # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set # CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_MOUNT_SUBDIR is not set -# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -481,6 +480,7 @@ CONFIG_LOCKD_V4=y # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y CONFIG_SUN_PARTITION=y +# CONFIG_SMB_NLS is not set CONFIG_NLS=y # diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index 81e11af70dac..67c1ec6d0651 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.104 2001/01/03 09:28:19 anton Exp $ +/* $Id: ioctl32.c,v 1.105 2001/01/18 04:47:44 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -73,6 +73,7 @@ #include <asm/audioio.h> #include <linux/ethtool.h> #include <asm/display7seg.h> +#include <asm/watchdog.h> #include <asm/module.h> #include <linux/soundcard.h> @@ -3600,6 +3601,16 @@ COMPATIBLE_IOCTL(DRM_IOCTL_FINISH) /* elevator */ COMPATIBLE_IOCTL(BLKELVGET) COMPATIBLE_IOCTL(BLKELVSET) +/* Big W */ +/* WIOC_GETSUPPORT not yet implemented -E */ +COMPATIBLE_IOCTL(WDIOC_GETSTATUS) +COMPATIBLE_IOCTL(WDIOC_GETBOOTSTATUS) +COMPATIBLE_IOCTL(WDIOC_GETTEMP) +COMPATIBLE_IOCTL(WDIOC_SETOPTIONS) +COMPATIBLE_IOCTL(WDIOC_KEEPALIVE) +COMPATIBLE_IOCTL(WIOCSTART) +COMPATIBLE_IOCTL(WIOCSTOP) +COMPATIBLE_IOCTL(WIOCGSTAT) /* And these ioctls need translation */ HANDLE_IOCTL(SIOCGIFNAME, dev_ifname32) HANDLE_IOCTL(SIOCGIFCONF, dev_ifconf) diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 2b697dd8726c..009900165d4a 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1,4 +1,4 @@ -/* $Id: pci.c,v 1.20 2000/12/14 22:57:25 davem Exp $ +/* $Id: pci.c,v 1.21 2001/01/10 18:22:59 davem Exp $ * pci.c: UltraSparc PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -78,6 +78,9 @@ volatile int pci_poke_faulted; /* Probe for all PCI controllers in the system. */ extern void sabre_init(int); extern void psycho_init(int); +#if 0 +extern void schizo_init(int); +#endif static struct { char *model_name; @@ -87,6 +90,10 @@ static struct { { "pci108e,a000", sabre_init }, { "SUNW,psycho", psycho_init }, { "pci108e,8000", psycho_init } +#if 0 + { "SUNW,schizo", schizo_init }, + { "pci108e,8001", schizo_init } +#endif }; #define PCI_NUM_CONTROLLER_TYPES (sizeof(pci_controller_table) / \ sizeof(pci_controller_table[0])) diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index d7267880adf2..08d5b8ee331d 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c @@ -1,4 +1,4 @@ -/* $Id: pci_iommu.c,v 1.11 2000/03/10 02:42:15 davem Exp $ +/* $Id: pci_iommu.c,v 1.12 2001/01/11 16:26:45 davem Exp $ * pci_iommu.c: UltraSparc PCI controller IOM/STC support. * * Copyright (C) 1999 David S. Miller (davem@redhat.com) @@ -187,7 +187,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t size, dma_addr_t *dma_ad memset((char *)first_page, 0, PAGE_SIZE << order); pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; spin_lock_irqsave(&iommu->lock, flags); iopte = alloc_consistent_cluster(iommu, size >> PAGE_SHIFT); @@ -241,7 +241,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t size, void *cpu, dma_addr_ npages = PAGE_ALIGN(size) >> PAGE_SHIFT; pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; iopte = iommu->page_table + ((dvma - iommu->page_table_map_base) >> PAGE_SHIFT); @@ -308,7 +308,7 @@ dma_addr_t pci_map_single(struct pci_dev *pdev, void *ptr, size_t sz, int direct unsigned long iopte_protection; pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; strbuf = &pcp->pbm->stc; if (direction == PCI_DMA_NONE) @@ -356,7 +356,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int BUG(); pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; strbuf = &pcp->pbm->stc; npages = PAGE_ALIGN(bus_addr + sz) - (bus_addr & PAGE_MASK); @@ -504,7 +504,7 @@ int pci_map_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, int } pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; strbuf = &pcp->pbm->stc; if (direction == PCI_DMA_NONE) @@ -568,7 +568,7 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, BUG(); pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; strbuf = &pcp->pbm->stc; bus_addr = sglist->dvma_address & PAGE_MASK; @@ -639,7 +639,7 @@ void pci_dma_sync_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, i unsigned long flags, ctx, npages; pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; strbuf = &pcp->pbm->stc; if (!strbuf->strbuf_enabled) @@ -700,7 +700,7 @@ void pci_dma_sync_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelem unsigned long flags, ctx; pcp = pdev->sysdata; - iommu = &pcp->pbm->parent->iommu; + iommu = pcp->pbm->iommu; strbuf = &pcp->pbm->stc; if (!strbuf->strbuf_enabled) @@ -762,7 +762,7 @@ int pci_dma_supported(struct pci_dev *pdev, dma_addr_t device_mask) if (pdev == NULL) { dma_addr_mask = 0xffffffff; } else { - struct pci_iommu *iommu = &pcp->pbm->parent->iommu; + struct pci_iommu *iommu = pcp->pbm->iommu; dma_addr_mask = iommu->dma_addr_mask; } diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c index aff2de594699..fbd7832cdc06 100644 --- a/arch/sparc64/kernel/pci_psycho.c +++ b/arch/sparc64/kernel/pci_psycho.c @@ -1,4 +1,4 @@ -/* $Id: pci_psycho.c,v 1.17 2000/09/21 06:25:14 anton Exp $ +/* $Id: pci_psycho.c,v 1.18 2001/01/11 16:26:45 davem Exp $ * pci_psycho.c: PSYCHO/U2P specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -619,20 +619,21 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, unsigned long afar, enum psycho_error_type type) { + struct pci_iommu *iommu = p->pbm_A.iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; u64 control; int i; - spin_lock_irqsave(&p->iommu.lock, flags); - control = psycho_read(p->iommu.iommu_control); + spin_lock_irqsave(&iommu->lock, flags); + control = psycho_read(iommu->iommu_control); if (control & PSYCHO_IOMMU_CTRL_XLTEERR) { char *type_string; /* Clear the error encountered bit. */ control &= ~PSYCHO_IOMMU_CTRL_XLTEERR; - psycho_write(p->iommu.iommu_control, control); + psycho_write(iommu->iommu_control, control); switch((control & PSYCHO_IOMMU_CTRL_XLTESTAT) >> 25UL) { case 0: @@ -662,7 +663,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, * get as much diagnostic information to the * console as we can. */ - psycho_write(p->iommu.iommu_control, + psycho_write(iommu->iommu_control, control | PSYCHO_IOMMU_CTRL_DENAB); for (i = 0; i < 16; i++) { unsigned long base = p->controller_regs; @@ -678,7 +679,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, } /* Leave diagnostic mode. */ - psycho_write(p->iommu.iommu_control, control); + psycho_write(iommu->iommu_control, control); for (i = 0; i < 16; i++) { unsigned long tag, data; @@ -717,7 +718,7 @@ static void psycho_check_iommu_error(struct pci_controller_info *p, } } __psycho_check_stc_error(p, afsr, afar, type); - spin_unlock_irqrestore(&p->iommu.lock, flags); + spin_unlock_irqrestore(&iommu->lock, flags); } /* Uncorrectable Errors. Cause of the error and the address are @@ -1255,24 +1256,25 @@ static void __init psycho_scan_bus(struct pci_controller_info *p) static void __init psycho_iommu_init(struct pci_controller_info *p) { + struct pci_iommu *iommu = p->pbm_A.iommu; unsigned long tsbbase, i; u64 control; /* Setup initial software IOMMU state. */ - spin_lock_init(&p->iommu.lock); - p->iommu.iommu_cur_ctx = 0; + spin_lock_init(&iommu->lock); + iommu->iommu_cur_ctx = 0; /* Register addresses. */ - p->iommu.iommu_control = p->controller_regs + PSYCHO_IOMMU_CONTROL; - p->iommu.iommu_tsbbase = p->controller_regs + PSYCHO_IOMMU_TSBBASE; - p->iommu.iommu_flush = p->controller_regs + PSYCHO_IOMMU_FLUSH; + iommu->iommu_control = p->controller_regs + PSYCHO_IOMMU_CONTROL; + iommu->iommu_tsbbase = p->controller_regs + PSYCHO_IOMMU_TSBBASE; + iommu->iommu_flush = p->controller_regs + PSYCHO_IOMMU_FLUSH; /* PSYCHO's IOMMU lacks ctx flushing. */ - p->iommu.iommu_ctxflush = 0; + iommu->iommu_ctxflush = 0; /* We use the main control register of PSYCHO as the write * completion register. */ - p->iommu.write_complete_reg = p->controller_regs + PSYCHO_CONTROL; + iommu->write_complete_reg = p->controller_regs + PSYCHO_CONTROL; /* * Invalidate TLB Entries. @@ -1298,19 +1300,19 @@ static void __init psycho_iommu_init(struct pci_controller_info *p) prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n"); prom_halt(); } - p->iommu.page_table = (iopte_t *)tsbbase; - p->iommu.page_table_sz_bits = 17; - p->iommu.page_table_map_base = 0xc0000000; - p->iommu.dma_addr_mask = 0xffffffff; + iommu->page_table = (iopte_t *)tsbbase; + iommu->page_table_sz_bits = 17; + iommu->page_table_map_base = 0xc0000000; + iommu->dma_addr_mask = 0xffffffff; memset((char *)tsbbase, 0, PAGE_SIZE << 7); /* We start with no consistent mappings. */ - p->iommu.lowest_consistent_map = - 1 << (p->iommu.page_table_sz_bits - PBM_LOGCLUSTERS); + iommu->lowest_consistent_map = + 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS); for (i = 0; i < PBM_NCLUSTERS; i++) { - p->iommu.alloc_info[i].flush = 0; - p->iommu.alloc_info[i].next = 0; + iommu->alloc_info[i].flush = 0; + iommu->alloc_info[i].next = 0; } psycho_write(p->controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase)); @@ -1515,6 +1517,7 @@ void __init psycho_init(int node) { struct linux_prom64_registers pr_regs[3]; struct pci_controller_info *p; + struct pci_iommu *iommu; unsigned long flags; u32 upa_portid; int is_pbm_a, err; @@ -1538,6 +1541,13 @@ void __init psycho_init(int node) prom_halt(); } memset(p, 0, sizeof(*p)); + iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + if (!iommu) { + prom_printf("PSYCHO: Fatal memory allocation error.\n"); + prom_halt(); + } + memset(iommu, 0, sizeof(*iommu)); + p->pbm_A.iommu = p->pbm_B.iommu = iommu; spin_lock_irqsave(&pci_controller_lock, flags); p->next = pci_controller_root; diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c index f3a5adbecdce..ec74a3696ea1 100644 --- a/arch/sparc64/kernel/pci_sabre.c +++ b/arch/sparc64/kernel/pci_sabre.c @@ -1,4 +1,4 @@ -/* $Id: pci_sabre.c,v 1.20 2000/06/26 19:40:27 davem Exp $ +/* $Id: pci_sabre.c,v 1.22 2001/01/16 13:03:48 anton Exp $ * pci_sabre.c: Sabre specific PCI controller support. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu) @@ -672,14 +672,15 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, unsigned long afsr, unsigned long afar) { + struct pci_iommu *iommu = p->pbm_A.iommu; unsigned long iommu_tag[16]; unsigned long iommu_data[16]; unsigned long flags; u64 control; int i; - spin_lock_irqsave(&p->iommu.lock, flags); - control = sabre_read(p->iommu.iommu_control); + spin_lock_irqsave(&iommu->lock, flags); + control = sabre_read(iommu->iommu_control); if (control & SABRE_IOMMUCTRL_ERR) { char *type_string; @@ -687,7 +688,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, * NOTE: On Sabre this is write 1 to clear, * which is different from Psycho. */ - sabre_write(p->iommu.iommu_control, control); + sabre_write(iommu->iommu_control, control); switch((control & SABRE_IOMMUCTRL_ERRSTS) >> 25UL) { case 1: type_string = "Invalid Error"; @@ -706,7 +707,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, * entries in the IOTLB. */ control &= ~(SABRE_IOMMUCTRL_ERRSTS | SABRE_IOMMUCTRL_ERR); - sabre_write(p->iommu.iommu_control, + sabre_write(iommu->iommu_control, (control | SABRE_IOMMUCTRL_DENAB)); for (i = 0; i < 16; i++) { unsigned long base = p->controller_regs; @@ -718,7 +719,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, sabre_write(base + SABRE_IOMMU_TAG + (i * 8UL), 0); sabre_write(base + SABRE_IOMMU_DATA + (i * 8UL), 0); } - sabre_write(p->iommu.iommu_control, control); + sabre_write(iommu->iommu_control, control); for (i = 0; i < 16; i++) { unsigned long tag, data; @@ -752,7 +753,7 @@ static void sabre_check_iommu_error(struct pci_controller_info *p, ((data & SABRE_IOMMUDATA_PPN) << PAGE_SHIFT)); } } - spin_unlock_irqrestore(&p->iommu.lock, flags); + spin_unlock_irqrestore(&iommu->lock, flags); } static void sabre_ue_intr(int irq, void *dev_id, struct pt_regs *regs) @@ -1158,20 +1159,21 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, int tsbsize, unsigned long dvma_offset, u32 dma_mask) { + struct pci_iommu *iommu = p->pbm_A.iommu; unsigned long tsbbase, i, order; u64 control; /* Setup initial software IOMMU state. */ - spin_lock_init(&p->iommu.lock); - p->iommu.iommu_cur_ctx = 0; + spin_lock_init(&iommu->lock); + iommu->iommu_cur_ctx = 0; /* Register addresses. */ - p->iommu.iommu_control = p->controller_regs + SABRE_IOMMU_CONTROL; - p->iommu.iommu_tsbbase = p->controller_regs + SABRE_IOMMU_TSBBASE; - p->iommu.iommu_flush = p->controller_regs + SABRE_IOMMU_FLUSH; - p->iommu.write_complete_reg = p->controller_regs + SABRE_WRSYNC; + iommu->iommu_control = p->controller_regs + SABRE_IOMMU_CONTROL; + iommu->iommu_tsbbase = p->controller_regs + SABRE_IOMMU_TSBBASE; + iommu->iommu_flush = p->controller_regs + SABRE_IOMMU_FLUSH; + iommu->write_complete_reg = p->controller_regs + SABRE_WRSYNC; /* Sabre's IOMMU lacks ctx flushing. */ - p->iommu.iommu_ctxflush = 0; + iommu->iommu_ctxflush = 0; /* Invalidate TLB Entries. */ control = sabre_read(p->controller_regs + SABRE_IOMMU_CONTROL); @@ -1192,9 +1194,9 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n"); prom_halt(); } - p->iommu.page_table = (iopte_t *)tsbbase; - p->iommu.page_table_map_base = dvma_offset; - p->iommu.dma_addr_mask = dma_mask; + iommu->page_table = (iopte_t *)tsbbase; + iommu->page_table_map_base = dvma_offset; + iommu->dma_addr_mask = dma_mask; memset((char *)tsbbase, 0, PAGE_SIZE << order); sabre_write(p->controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase)); @@ -1205,11 +1207,11 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, switch(tsbsize) { case 64: control |= SABRE_IOMMU_TSBSZ_64K; - p->iommu.page_table_sz_bits = 16; + iommu->page_table_sz_bits = 16; break; case 128: control |= SABRE_IOMMU_TSBSZ_128K; - p->iommu.page_table_sz_bits = 17; + iommu->page_table_sz_bits = 17; break; default: prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize); @@ -1219,12 +1221,12 @@ static void __init sabre_iommu_init(struct pci_controller_info *p, sabre_write(p->controller_regs + SABRE_IOMMU_CONTROL, control); /* We start with no consistent mappings. */ - p->iommu.lowest_consistent_map = - 1 << (p->iommu.page_table_sz_bits - PBM_LOGCLUSTERS); + iommu->lowest_consistent_map = + 1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS); for (i = 0; i < PBM_NCLUSTERS; i++) { - p->iommu.alloc_info[i].flush = 0; - p->iommu.alloc_info[i].next = 0; + iommu->alloc_info[i].flush = 0; + iommu->alloc_info[i].next = 0; } } @@ -1368,6 +1370,7 @@ void __init sabre_init(int pnode) { struct linux_prom64_registers pr_regs[2]; struct pci_controller_info *p; + struct pci_iommu *iommu; unsigned long flags; int tsbsize, err; u32 busrange[2]; @@ -1380,10 +1383,17 @@ void __init sabre_init(int pnode) prom_printf("SABRE: Error, kmalloc(pci_controller_info) failed.\n"); prom_halt(); } + memset(p, 0, sizeof(*p)); - upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff); + iommu = kmalloc(sizeof(*iommu), GFP_ATOMIC); + if (!iommu) { + prom_printf("SABRE: Error, kmalloc(pci_iommu) failed.\n"); + prom_halt(); + } + memset(iommu, 0, sizeof(*iommu)); + p->pbm_A.iommu = p->pbm_B.iommu = iommu; - memset(p, 0, sizeof(*p)); + upa_portid = prom_getintdefault(pnode, "upa-portid", 0xff); spin_lock_irqsave(&pci_controller_lock, flags); p->next = pci_controller_root; diff --git a/arch/sparc64/kernel/pci_schizo.c b/arch/sparc64/kernel/pci_schizo.c new file mode 100644 index 000000000000..9299c2531b80 --- /dev/null +++ b/arch/sparc64/kernel/pci_schizo.c @@ -0,0 +1,169 @@ +/* $Id: pci_schizo.c,v 1.2 2001/01/12 02:43:30 davem Exp $ + * pci_schizo.c: SCHIZO specific PCI controller support. + * + * Copyright (C) 2001 David S. Miller (davem@redhat.com) + */ + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/pci.h> +#include <linux/init.h> +#include <linux/malloc.h> + +#include <asm/pbm.h> +#include <asm/iommu.h> +#include <asm/irq.h> + +#include "pci_impl.h" + +static int schizo_read_byte(struct pci_dev *dev, int where, u8 *value) +{ + /* IMPLEMENT ME */ +} + +static int schizo_read_word(struct pci_dev *dev, int where, u16 *value) +{ + /* IMPLEMENT ME */ +} + +static int schizo_read_dword(struct pci_dev *dev, int where, u32 *value) +{ + /* IMPLEMENT ME */ +} + +static int schizo_write_byte(struct pci_dev *dev, int where, u8 value) +{ + /* IMPLEMENT ME */ +} + +static int schizo_write_word(struct pci_dev *dev, int where, u16 value) +{ + /* IMPLEMENT ME */ +} + +static int schizo_write_dword(struct pci_dev *dev, int where, u32 value) +{ + /* IMPLEMENT ME */ +} + +static struct pci_ops schizo_ops = { + schizo_read_byte, + schizo_read_word, + schizo_read_dword, + schizo_write_byte, + schizo_write_word, + schizo_write_dword +}; + +static void __init schizo_scan_bus(struct pci_controller_info *p) +{ + /* IMPLEMENT ME */ +} + +static unsigned int __init schizo_irq_build(struct pci_controller_info *p, + struct pci_dev *pdev, + unsigned int ino) +{ + /* IMPLEMENT ME */ +} + +static void __init schizo_base_address_update(struct pci_dev *pdev, int resource) +{ + /* IMPLEMENT ME */ +} + +static void __init schizo_resource_adjust(struct pci_dev *pdev, + struct resource *res, + struct resource *root) +{ + /* IMPLEMENT ME */ +} + +static void schizo_pbm_init(struct pci_controller_info *p, + int prom_node, int is_pbm_a) +{ + /* IMPLEMENT ME */ +} + +void __init schizo_init(int node) +{ + struct linux_prom64_registers pr_regs[3]; + struct pci_controller_info *p; + struct pci_iommu *iommu; + u32 portid; + int is_pbm_a, err; + + portid = prom_getintdefault(node, "portid", 0xff); + + spin_lock_irqsave(&pci_controller_lock, flags); + for(p = pci_controller_root; p; p = p->next) { + if (p->portid == portid) { + spin_unlock_irqrestore(&pci_controller_lock, flags); + is_pbm_a = (p->pbm_A.prom_node == 0); + schizo_pbm_init(p, node, is_pbm_a); + return; + } + } + spin_unlock_irqrestore(&pci_controller_lock, flags); + + p = kmalloc(sizeof(struct pci_controller_info), GFP_ATOMIC); + if (!p) { + prom_printf("SCHIZO: Fatal memory allocation error.\n"); + prom_halt(); + } + memset(p, 0, sizeof(*p)); + + iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + if (!iommu) { + prom_printf("SCHIZO: Fatal memory allocation error.\n"); + prom_halt(); + } + memset(iommu, 0, sizeof(*iommu)); + p->pbm_A.iommu = iommu; + + iommu = kmalloc(sizeof(struct pci_iommu), GFP_ATOMIC); + if (!iommu) { + prom_printf("SCHIZO: Fatal memory allocation error.\n"); + prom_halt(); + } + memset(iommu, 0, sizeof(*iommu)); + p->pbm_B.iommu = iommu; + + spin_lock_irqsave(&pci_controller_lock, flags); + p->next = pci_controller_root; + pci_controller_root = p; + spin_unlock_irqrestore(&pci_controller_lock, flags); + + p->portid = portid; + p->index = pci_num_controllers++; + p->scan_bus = schizo_scan_bus; + p->irq_build = schizo_irq_build; + p->base_address_update = schizo_base_address_update; + p->resource_adjust = schizo_resource_adjust; + p->pci_ops = &schizo_ops; + +pbm_init: + /* Three OBP regs: + * 1) PBM controller regs + * 2) Schizo front-end controller regs (same for both PBMs) + * 3) Unknown... (0x7ffec000000 and 0x7ffee000000 on Excalibur) + */ + err = prom_getproperty(node, "reg", + (char *)&pr_regs[0], + sizeof(pr_regs)); + if (err == 0 || err == -1) { + prom_printf("SCHIZO: Fatal error, no reg property.\n"); + prom_halt(); + } + + /* XXX Read REG base, record in controller/pbm structures. */ + + /* XXX Report controller to console. */ + + /* XXX Setup pci_memspace_mask */ + + /* XXX Init core controller and IOMMU */ + + is_pbm_a = XXX; /* Figure out this test */ + schizo_pbm_init(p, node, is_pbm_a); +} diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index a0311626e131..f35e38a5d53d 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.99 2000/12/09 04:15:24 anton Exp $ +/* $Id: sparc64_ksyms.c,v 1.100 2001/01/11 15:07:09 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -182,6 +182,7 @@ EXPORT_SYMBOL(__flushw_user); EXPORT_SYMBOL(flush_icache_range); EXPORT_SYMBOL(__flush_dcache_page); +EXPORT_SYMBOL(mostek_lock); EXPORT_SYMBOL(mstk48t02_regs); EXPORT_SYMBOL(request_fast_irq); #if CONFIG_SBUS diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index a9d143759e01..58e4704c4015 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -1,4 +1,4 @@ -/* $Id: sys_sunos32.c,v 1.55 2000/11/18 02:10:59 davem Exp $ +/* $Id: sys_sunos32.c,v 1.56 2001/01/04 05:35:48 davem Exp $ * sys_sunos32.c: SunOS binary compatability layer on sparc64. * * Copyright (C) 1995, 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -1047,6 +1047,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) (current->thread.kregs->u_regs[UREG_FP] & 0xffffffffUL); if(get_user(arg5, &sp->xxargs[0])) { rval = -EFAULT; + kfree(kmbuf); break; } set_fs(KERNEL_DS); diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 0264f94189a7..a3340f54ac37 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c @@ -1,4 +1,4 @@ -/* $Id: time.c,v 1.32 2000/09/22 23:02:13 davem Exp $ +/* $Id: time.c,v 1.33 2001/01/11 15:07:09 davem Exp $ * time.c: UltraSparc timer and TOD clock support. * * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) @@ -34,7 +34,9 @@ extern rwlock_t xtime_lock; +spinlock_t mostek_lock = SPIN_LOCK_UNLOCKED; unsigned long mstk48t02_regs = 0UL; + static unsigned long mstk48t08_regs = 0UL; static unsigned long mstk48t59_regs = 0UL; @@ -187,6 +189,8 @@ static void __init kick_start_clock(void) prom_printf("CLOCK: Clock was stopped. Kick start "); + spin_lock_irq(&mostek_lock); + /* Turn on the kick start bit to start the oscillator. */ tmp = mostek_read(regs + MOSTEK_CREG); tmp |= MSTK_CREG_WRITE; @@ -201,6 +205,8 @@ static void __init kick_start_clock(void) tmp &= ~MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); + spin_unlock_irq(&mostek_lock); + /* Delay to allow the clock oscillator to start. */ sec = MSTK_REG_SEC(regs); for (i = 0; i < 3; i++) { @@ -212,6 +218,8 @@ static void __init kick_start_clock(void) } prom_printf("\n"); + spin_lock_irq(&mostek_lock); + /* Turn off kick start and set a "valid" time and date. */ tmp = mostek_read(regs + MOSTEK_CREG); tmp |= MSTK_CREG_WRITE; @@ -230,9 +238,14 @@ static void __init kick_start_clock(void) tmp &= ~MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); + spin_unlock_irq(&mostek_lock); + /* Ensure the kick start bit is off. If it isn't, turn it off. */ while (mostek_read(regs + MOSTEK_HOUR) & MSTK_KICK_START) { prom_printf("CLOCK: Kick start still on!\n"); + + spin_lock_irq(&mostek_lock); + tmp = mostek_read(regs + MOSTEK_CREG); tmp |= MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); @@ -244,6 +257,8 @@ static void __init kick_start_clock(void) tmp = mostek_read(regs + MOSTEK_CREG); tmp &= ~MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); + + spin_unlock_irq(&mostek_lock); } prom_printf("CLOCK: Kick start procedure successful.\n"); @@ -255,11 +270,15 @@ static int __init has_low_battery(void) unsigned long regs = mstk48t02_regs; u8 data1, data2; + spin_lock_irq(&mostek_lock); + data1 = mostek_read(regs + MOSTEK_EEPROM); /* Read some data. */ mostek_write(regs + MOSTEK_EEPROM, ~data1); /* Write back the complement. */ data2 = mostek_read(regs + MOSTEK_EEPROM); /* Read back the complement. */ mostek_write(regs + MOSTEK_EEPROM, data1); /* Restore original value. */ + spin_unlock_irq(&mostek_lock); + return (data1 == data2); /* Was the write blocked? */ } @@ -278,6 +297,8 @@ static void __init set_system_time(void) prom_halt(); } + spin_lock_irq(&mostek_lock); + tmp = mostek_read(mregs + MOSTEK_CREG); tmp |= MSTK_CREG_READ; mostek_write(mregs + MOSTEK_CREG, tmp); @@ -294,6 +315,8 @@ static void __init set_system_time(void) tmp = mostek_read(mregs + MOSTEK_CREG); tmp &= ~MSTK_CREG_READ; mostek_write(mregs + MOSTEK_CREG, tmp); + + spin_unlock_irq(&mostek_lock); } void __init clock_probe(void) @@ -512,6 +535,7 @@ static int set_rtc_mmss(unsigned long nowtime) { int real_seconds, real_minutes, mostek_minutes; unsigned long regs = mstk48t02_regs; + unsigned long flags; u8 tmp; /* @@ -521,6 +545,8 @@ static int set_rtc_mmss(unsigned long nowtime) if (!regs) return -1; + spin_lock_irqsave(&mostek_lock, flags); + /* Read the current RTC minutes. */ tmp = mostek_read(regs + MOSTEK_CREG); tmp |= MSTK_CREG_READ; @@ -555,8 +581,13 @@ static int set_rtc_mmss(unsigned long nowtime) tmp = mostek_read(regs + MOSTEK_CREG); tmp &= ~MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); - } else - return -1; - return 0; + spin_unlock_irqrestore(&mostek_lock, flags); + + return 0; + } else { + spin_unlock_irqrestore(&mostek_lock, flags); + + return -1; + } } diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 307cb08ad724..e1e0745a4752 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -4,7 +4,7 @@ O_TARGET := acpi.o -export-objs := ksyms.o +export-objs := acpi_ksyms.o export ACPI_CFLAGS ACPI_CFLAGS := -D_LINUX @@ -20,18 +20,26 @@ EXTRA_CFLAGS += -I./include EXTRA_CFLAGS += $(ACPI_CFLAGS) +# genksyms only reads $(CFLAGS), it should really read $(EXTRA_CFLAGS) as well. +# Without EXTRA_CFLAGS the gcc pass for genksyms fails, resulting in an empty +# include/linux/modules/acpi_ksyms.ver. Changing genkyms to use EXTRA_CFLAGS +# will hit everything, too risky in 2.4.0-prerelease. Bandaid by tweaking +# CFLAGS only for .ver targets. Review after 2.4.0 release. KAO + +$(MODINCL)/%.ver: CFLAGS := -I./include $(CFLAGS) + acpi-subdirs := common dispatcher events hardware \ interpreter namespace parser resources tables subdir-$(CONFIG_ACPI) += $(acpi-subdirs) obj-$(CONFIG_ACPI) := $(patsubst %,%.o,$(acpi-subdirs)) -obj-$(CONFIG_ACPI) += os.o ksyms.o +obj-$(CONFIG_ACPI) += os.o acpi_ksyms.o ifdef CONFIG_ACPI_KERNEL_CONFIG obj-$(CONFIG_ACPI) += acpiconf.o osconf.o else - obj-$(CONFIG_ACPI) += driver.o cmbatt.o cpu.o ec.o ksyms.o sys.o table.o power.o + obj-$(CONFIG_ACPI) += driver.o cmbatt.o cpu.o ec.o acpi_ksyms.o sys.o table.o power.o endif include $(TOPDIR)/Rules.make diff --git a/drivers/acpi/ksyms.c b/drivers/acpi/acpi_ksyms.c index 13f4fe0e78fc..cb4c5a4b92a5 100644 --- a/drivers/acpi/ksyms.c +++ b/drivers/acpi/acpi_ksyms.c @@ -18,6 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/config.h> #include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> diff --git a/drivers/acpi/cmbatt.c b/drivers/acpi/cmbatt.c index c45aa810c12e..d5dc5977abe9 100644 --- a/drivers/acpi/cmbatt.c +++ b/drivers/acpi/cmbatt.c @@ -113,10 +113,10 @@ acpi_get_battery_status(ACPI_HANDLE handle, struct cmbatt_status *result) obj = (ACPI_OBJECT *) buf.pointer; objs = obj->package.elements; - result->state = objs[0].number.value; - result->present_rate = objs[1].number.value; - result->remaining_capacity = objs[2].number.value; - result->present_voltage = objs[3].number.value; + result->state = objs[0].integer.value; + result->present_rate = objs[1].integer.value; + result->remaining_capacity = objs[2].integer.value; + result->present_voltage = objs[3].integer.value; kfree(buf.pointer); @@ -153,15 +153,15 @@ acpi_get_battery_info(ACPI_HANDLE handle, struct cmbatt_info *result) obj = (ACPI_OBJECT *) buf.pointer; objs = obj->package.elements; - result->power_unit=objs[0].number.value; - result->design_capacity=objs[1].number.value; - result->last_full_capacity=objs[2].number.value; - result->battery_technology=objs[3].number.value; - result->design_voltage=objs[4].number.value; - result->design_capacity_warning=objs[5].number.value; - result->design_capacity_low=objs[6].number.value; - result->battery_capacity_granularity_1=objs[7].number.value; - result->battery_capacity_granularity_2=objs[8].number.value; + result->power_unit=objs[0].integer.value; + result->design_capacity=objs[1].integer.value; + result->last_full_capacity=objs[2].integer.value; + result->battery_technology=objs[3].integer.value; + result->design_voltage=objs[4].integer.value; + result->design_capacity_warning=objs[5].integer.value; + result->design_capacity_low=objs[6].integer.value; + result->battery_capacity_granularity_1=objs[7].integer.value; + result->battery_capacity_granularity_2=objs[8].integer.value; /* BUG: trailing NULL issue */ strncpy(result->model_number, objs[9].string.pointer, MAX_BATT_STRLEN-1); diff --git a/drivers/acpi/common/cmalloc.c b/drivers/acpi/common/cmalloc.c index b7a64e5b6166..880376433130 100644 --- a/drivers/acpi/common/cmalloc.c +++ b/drivers/acpi/common/cmalloc.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmalloc - local memory allocation routines - * $Revision: 79 $ + * $Revision: 83 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -57,8 +57,6 @@ _cm_allocate ( u32 line) { void *address = NULL; - DEBUG_ONLY_MEMBERS (\ - ACPI_STATUS status) /* Check for an inadvertent size of zero bytes */ @@ -107,8 +105,6 @@ _cm_callocate ( u32 line) { void *address = NULL; - DEBUG_ONLY_MEMBERS (\ - ACPI_STATUS status) /* Check for an inadvertent size of zero bytes */ diff --git a/drivers/acpi/common/cmclib.c b/drivers/acpi/common/cmclib.c index 5146b09c56fb..88e92d17fc4d 100644 --- a/drivers/acpi/common/cmclib.c +++ b/drivers/acpi/common/cmclib.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmclib - Local implementation of C library functions - * $Revision: 28 $ + * $Revision: 32 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -347,7 +347,7 @@ acpi_cm_memcpy ( void * acpi_cm_memset ( void *dest, - u32 value, + NATIVE_UINT value, NATIVE_UINT count) { NATIVE_CHAR *new = (NATIVE_CHAR *) dest; @@ -522,6 +522,7 @@ static const u8 _acpi_ctype[257] = { #define IS_LOWER(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_LO)) #define IS_DIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_DI)) #define IS_SPACE(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_SP)) +#define IS_XDIGIT(c) (_acpi_ctype[(unsigned char)(c)] & (_ACPI_XD)) /******************************************************************************* @@ -658,7 +659,7 @@ u32 acpi_cm_strtoul ( const NATIVE_CHAR *string, NATIVE_CHAR **terminator, - u32 base) + NATIVE_UINT base) { u32 converted = 0; u32 index; diff --git a/drivers/acpi/common/cmcopy.c b/drivers/acpi/common/cmcopy.c index 68b7bda0152f..da3851c17828 100644 --- a/drivers/acpi/common/cmcopy.c +++ b/drivers/acpi/common/cmcopy.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmcopy - Internal to external object translation utilities - * $Revision: 61 $ + * $Revision: 62 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -118,9 +118,9 @@ acpi_cm_build_external_simple_object ( break; - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: - external_obj->number.value= internal_obj->number.value; + external_obj->integer.value= internal_obj->integer.value; break; @@ -469,11 +469,11 @@ acpi_cm_build_internal_simple_object ( break; - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: /* * Number is included in the object itself */ - internal_obj->number.value = external_obj->number.value; + internal_obj->integer.value = external_obj->integer.value; break; diff --git a/drivers/acpi/common/cmdebug.c b/drivers/acpi/common/cmdebug.c index a55372d5c489..2d0022ac3aa2 100644 --- a/drivers/acpi/common/cmdebug.c +++ b/drivers/acpi/common/cmdebug.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmdebug - Debug print routines - * $Revision: 61 $ + * $Revision: 64 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -281,7 +281,7 @@ function_value_exit ( u32 line_number, u32 component_id, NATIVE_CHAR *function_name, - NATIVE_UINT value) + ACPI_INTEGER value) { debug_print (module_name, line_number, component_id, TRACE_FUNCTIONS, diff --git a/drivers/acpi/common/cmdelete.c b/drivers/acpi/common/cmdelete.c index a6e74c12f142..b516b691c355 100644 --- a/drivers/acpi/common/cmdelete.c +++ b/drivers/acpi/common/cmdelete.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: cmdelete - object deletion and reference count utilities - * $Revision: 60 $ + * $Revision: 62 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/common/cmeval.c b/drivers/acpi/common/cmeval.c index 29a5cefa6411..653e26a47df7 100644 --- a/drivers/acpi/common/cmeval.c +++ b/drivers/acpi/common/cmeval.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmeval - Object evaluation - * $Revision: 19 $ + * $Revision: 21 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -77,7 +77,7 @@ acpi_cm_evaluate_numeric_object ( /* Is the return object of the correct type? */ - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + if (obj_desc->common.type != ACPI_TYPE_INTEGER) { status = AE_TYPE; } else { @@ -85,7 +85,7 @@ acpi_cm_evaluate_numeric_object ( * Since the structure is a union, setting any field will set all * of the variables in the union */ - *address = obj_desc->number.value; + *address = obj_desc->integer.value; } /* On exit, we must delete the return object */ @@ -142,17 +142,17 @@ acpi_cm_execute_HID ( * a string */ - if ((obj_desc->common.type != ACPI_TYPE_NUMBER) && + if ((obj_desc->common.type != ACPI_TYPE_INTEGER) && (obj_desc->common.type != ACPI_TYPE_STRING)) { status = AE_TYPE; } else { - if (obj_desc->common.type == ACPI_TYPE_NUMBER) { + if (obj_desc->common.type == ACPI_TYPE_INTEGER) { /* Convert the Numeric HID to string */ - acpi_aml_eisa_id_to_string ((u32) obj_desc->number.value, hid->buffer); + acpi_aml_eisa_id_to_string ((u32) obj_desc->integer.value, hid->buffer); } else { @@ -217,17 +217,17 @@ acpi_cm_execute_UID ( * a string */ - if ((obj_desc->common.type != ACPI_TYPE_NUMBER) && + if ((obj_desc->common.type != ACPI_TYPE_INTEGER) && (obj_desc->common.type != ACPI_TYPE_STRING)) { status = AE_TYPE; } else { - if (obj_desc->common.type == ACPI_TYPE_NUMBER) { + if (obj_desc->common.type == ACPI_TYPE_INTEGER) { /* Convert the Numeric UID to string */ - acpi_aml_unsigned_integer_to_string (obj_desc->number.value, uid->buffer); + acpi_aml_unsigned_integer_to_string (obj_desc->integer.value, uid->buffer); } else { @@ -289,14 +289,14 @@ acpi_cm_execute_STA ( /* Is the return object of the correct type? */ - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + if (obj_desc->common.type != ACPI_TYPE_INTEGER) { status = AE_TYPE; } else { /* Extract the status flags */ - *flags = (u32) obj_desc->number.value; + *flags = (u32) obj_desc->integer.value; } /* On exit, we must delete the return object */ diff --git a/drivers/acpi/common/cmglobal.c b/drivers/acpi/common/cmglobal.c index 4b4460f46909..a388907f3532 100644 --- a/drivers/acpi/common/cmglobal.c +++ b/drivers/acpi/common/cmglobal.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmglobal - Global variables for the ACPI subsystem - * $Revision: 112 $ + * $Revision: 116 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -95,7 +95,7 @@ PREDEFINED_NAMES acpi_gbl_pre_defined_names[] = {"_SB_", INTERNAL_TYPE_DEF_ANY}, {"_SI_", INTERNAL_TYPE_DEF_ANY}, {"_TZ_", INTERNAL_TYPE_DEF_ANY}, - {"_REV", ACPI_TYPE_NUMBER, "2"}, + {"_REV", ACPI_TYPE_INTEGER, "2"}, {"_OS_", ACPI_TYPE_STRING, ACPI_OS_NAME}, {"_GL_", ACPI_TYPE_MUTEX, "0"}, @@ -152,6 +152,13 @@ u8 acpi_gbl_ns_properties[] = }; +/* Hex to ASCII conversion table */ + +NATIVE_CHAR acpi_gbl_hex_to_ascii[] = + {'0','1','2','3','4','5','6','7', + '8','9','A','B','C','D','E','F'}; + + /****************************************************************************** * * Table globals diff --git a/drivers/acpi/common/cminit.c b/drivers/acpi/common/cminit.c index e6cfb7655d4b..0952720f1659 100644 --- a/drivers/acpi/common/cminit.c +++ b/drivers/acpi/common/cminit.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cminit - Common ACPI subsystem initialization - * $Revision: 91 $ + * $Revision: 93 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -35,6 +35,9 @@ MODULE_NAME ("cminit") +#define ACPI_OFFSET(d,o) ((u32) &(((d *)0)->o)) +#define ACPI_FADT_OFFSET(o) ACPI_OFFSET (FADT_DESCRIPTOR, o) + /******************************************************************************* * * FUNCTION: Acpi_cm_fadt_register_error @@ -53,12 +56,13 @@ static ACPI_STATUS acpi_cm_fadt_register_error ( NATIVE_CHAR *register_name, - u32 value) + u32 value, + u32 offset) { REPORT_ERROR ( - ("Invalid FADT register value, %s=%X (FADT=%p)\n", - register_name, value, acpi_gbl_FADT)); + ("Invalid FADT value %s=%lX at offset %lX FADT=%p\n", + register_name, value, offset, acpi_gbl_FADT)); return (AE_BAD_VALUE); @@ -91,39 +95,42 @@ acpi_cm_validate_fadt ( if (acpi_gbl_FADT->pm1_evt_len < 4) { status = acpi_cm_fadt_register_error ("PM1_EVT_LEN", - (u32) acpi_gbl_FADT->pm1_evt_len); + (u32) acpi_gbl_FADT->pm1_evt_len, + ACPI_FADT_OFFSET (pm1_evt_len)); } if (!acpi_gbl_FADT->pm1_cnt_len) { - status = acpi_cm_fadt_register_error ("PM1_CNT_LEN", - 0); + status = acpi_cm_fadt_register_error ("PM1_CNT_LEN", 0, + ACPI_FADT_OFFSET (pm1_cnt_len)); } if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_evt_blk.address)) { - status = acpi_cm_fadt_register_error ("PM1a_EVT_BLK", - 0); + status = acpi_cm_fadt_register_error ("X_PM1a_EVT_BLK", 0, + ACPI_FADT_OFFSET (Xpm1a_evt_blk.address)); } if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm1a_cnt_blk.address)) { - status = acpi_cm_fadt_register_error ("PM1a_CNT_BLK", - 0); + status = acpi_cm_fadt_register_error ("X_PM1a_CNT_BLK", 0, + ACPI_FADT_OFFSET (Xpm1a_cnt_blk.address)); } if (!ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm_tmr_blk.address)) { - status = acpi_cm_fadt_register_error ("PM_TMR_BLK", - 0); + status = acpi_cm_fadt_register_error ("X_PM_TMR_BLK", 0, + ACPI_FADT_OFFSET (Xpm_tmr_blk.address)); } if ((ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xpm2_cnt_blk.address) && !acpi_gbl_FADT->pm2_cnt_len)) { status = acpi_cm_fadt_register_error ("PM2_CNT_LEN", - (u32) acpi_gbl_FADT->pm2_cnt_len); + (u32) acpi_gbl_FADT->pm2_cnt_len, + ACPI_FADT_OFFSET (pm2_cnt_len)); } if (acpi_gbl_FADT->pm_tm_len < 4) { status = acpi_cm_fadt_register_error ("PM_TM_LEN", - (u32) acpi_gbl_FADT->pm_tm_len); + (u32) acpi_gbl_FADT->pm_tm_len, + ACPI_FADT_OFFSET (pm_tm_len)); } /* length of GPE blocks must be a multiple of 2 */ @@ -132,15 +139,17 @@ acpi_cm_validate_fadt ( if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe0blk.address) && (acpi_gbl_FADT->gpe0blk_len & 1)) { - status = acpi_cm_fadt_register_error ("GPE0_BLK_LEN", - (u32) acpi_gbl_FADT->gpe0blk_len); + status = acpi_cm_fadt_register_error ("(x)GPE0_BLK_LEN", + (u32) acpi_gbl_FADT->gpe0blk_len, + ACPI_FADT_OFFSET (gpe0blk_len)); } if (ACPI_VALID_ADDRESS (acpi_gbl_FADT->Xgpe1_blk.address) && (acpi_gbl_FADT->gpe1_blk_len & 1)) { - status = acpi_cm_fadt_register_error ("GPE1_BLK_LEN", - (u32) acpi_gbl_FADT->gpe1_blk_len); + status = acpi_cm_fadt_register_error ("(x)GPE1_BLK_LEN", + (u32) acpi_gbl_FADT->gpe1_blk_len, + ACPI_FADT_OFFSET (gpe1_blk_len)); } return (status); diff --git a/drivers/acpi/common/cmobject.c b/drivers/acpi/common/cmobject.c index 95e70fb14b0b..5f73abaafcad 100644 --- a/drivers/acpi/common/cmobject.c +++ b/drivers/acpi/common/cmobject.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmobject - ACPI object create/delete/size/cache routines - * $Revision: 34 $ + * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -434,7 +434,7 @@ acpi_cm_get_simple_object_size ( break; - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: case ACPI_TYPE_PROCESSOR: case ACPI_TYPE_POWER: diff --git a/drivers/acpi/common/cmutils.c b/drivers/acpi/common/cmutils.c index cb3d959c854d..b0ee8b4d9d00 100644 --- a/drivers/acpi/common/cmutils.c +++ b/drivers/acpi/common/cmutils.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: cmutils - common utility procedures - * $Revision: 21 $ + * $Revision: 23 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -647,16 +647,16 @@ acpi_cm_resolve_package_references ( if (sub_object->common.type == INTERNAL_TYPE_REFERENCE) { if (sub_object->reference.op_code == AML_ZERO_OP) { - sub_object->common.type = ACPI_TYPE_NUMBER; - sub_object->number.value = 0; + sub_object->common.type = ACPI_TYPE_INTEGER; + sub_object->integer.value = 0; } else if (sub_object->reference.op_code == AML_ONE_OP) { - sub_object->common.type = ACPI_TYPE_NUMBER; - sub_object->number.value = 1; + sub_object->common.type = ACPI_TYPE_INTEGER; + sub_object->integer.value = 1; } else if (sub_object->reference.op_code == AML_ONES_OP) { - sub_object->common.type = ACPI_TYPE_NUMBER; - sub_object->number.value = ACPI_INTEGER_MAX; + sub_object->common.type = ACPI_TYPE_INTEGER; + sub_object->integer.value = ACPI_INTEGER_MAX; } } } diff --git a/drivers/acpi/common/cmxface.c b/drivers/acpi/common/cmxface.c index fc063850cabb..c968fecfa5fa 100644 --- a/drivers/acpi/common/cmxface.c +++ b/drivers/acpi/common/cmxface.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: cmxface - External interfaces for "global" ACPI functions - * $Revision: 55 $ + * $Revision: 58 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/dispatcher/dsfield.c b/drivers/acpi/dispatcher/dsfield.c index 1ce75dbdb265..897324547ecf 100644 --- a/drivers/acpi/dispatcher/dsfield.c +++ b/drivers/acpi/dispatcher/dsfield.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: dsfield - Dispatcher field routines - * $Revision: 29 $ + * $Revision: 31 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c index d9d73ccea384..4834f47ec4cd 100644 --- a/drivers/acpi/dispatcher/dsmethod.c +++ b/drivers/acpi/dispatcher/dsmethod.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: dsmethod - Parser/Interpreter interface - control method parsing - * $Revision: 53 $ + * $Revision: 56 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/dispatcher/dsmthdat.c b/drivers/acpi/dispatcher/dsmthdat.c index e6913fabf434..24b7386b4c26 100644 --- a/drivers/acpi/dispatcher/dsmthdat.c +++ b/drivers/acpi/dispatcher/dsmthdat.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: dsmthdat - control method arguments and local variables - * $Revision: 36 $ + * $Revision: 38 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/dispatcher/dsobject.c b/drivers/acpi/dispatcher/dsobject.c index 042cc4a8093c..0a6c88b4d5fa 100644 --- a/drivers/acpi/dispatcher/dsobject.c +++ b/drivers/acpi/dispatcher/dsobject.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: dsobject - Dispatcher object management routines - * $Revision: 53 $ + * $Revision: 56 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -241,14 +241,14 @@ acpi_ds_init_object_from_op ( /* We are expecting a number */ - if (arg_desc->common.type != ACPI_TYPE_NUMBER) { + if (arg_desc->common.type != ACPI_TYPE_INTEGER) { acpi_cm_remove_reference (arg_desc); return (AE_TYPE); } /* Get the value, delete the internal object */ - (*obj_desc)->buffer.length = (u32) arg_desc->number.value; + (*obj_desc)->buffer.length = (u32) arg_desc->integer.value; acpi_cm_remove_reference (arg_desc); /* Allocate the buffer */ @@ -304,8 +304,8 @@ acpi_ds_init_object_from_op ( status = acpi_ds_build_internal_object (walk_state, op, obj_desc); break; - case ACPI_TYPE_NUMBER: - (*obj_desc)->number.value = op->value.integer; + case ACPI_TYPE_INTEGER: + (*obj_desc)->integer.value = op->value.integer; break; @@ -411,18 +411,20 @@ acpi_ds_build_internal_simple_obj ( acpi_ns_externalize_name (ACPI_UINT32_MAX, op->value.string, &length, &name); if (name) { - REPORT_WARNING (("Reference %s AML %X not found\n", + REPORT_WARNING (("Reference %s at AML %X not found\n", name, op->aml_offset)); acpi_cm_free (name); } else { - REPORT_WARNING (("Reference %s AML %X not found\n", + REPORT_WARNING (("Reference %s at AML %X not found\n", op->value.string, op->aml_offset)); } *obj_desc_ptr = NULL; } - return (status); + else { + return (status); + } } } diff --git a/drivers/acpi/dispatcher/dsopcode.c b/drivers/acpi/dispatcher/dsopcode.c index 21e15bc2613e..ba06cf4dba4e 100644 --- a/drivers/acpi/dispatcher/dsopcode.c +++ b/drivers/acpi/dispatcher/dsopcode.c @@ -2,12 +2,12 @@ * * Module Name: dsopcode - Dispatcher Op Region support and handling of * "control" opcodes - * $Revision: 28 $ + * $Revision: 30 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -355,7 +355,7 @@ acpi_ds_eval_field_unit_operands ( } - offset = (u32) off_desc->number.value; + offset = (u32) off_desc->integer.value; /* @@ -427,7 +427,7 @@ acpi_ds_eval_field_unit_operands ( /* Offset is in bits, count is in bits */ bit_offset = offset; - bit_count = (u16) cnt_desc->number.value; + bit_count = (u16) cnt_desc->integer.value; break; @@ -586,7 +586,7 @@ acpi_ds_eval_region_operands ( */ operand_desc = walk_state->operands[walk_state->num_operands - 1]; - obj_desc->region.length = (u32) operand_desc->number.value; + obj_desc->region.length = (u32) operand_desc->integer.value; acpi_cm_remove_reference (operand_desc); /* @@ -595,7 +595,7 @@ acpi_ds_eval_region_operands ( */ operand_desc = walk_state->operands[walk_state->num_operands - 2]; - obj_desc->region.address = (ACPI_PHYSICAL_ADDRESS) operand_desc->number.value; + obj_desc->region.address = (ACPI_PHYSICAL_ADDRESS) operand_desc->integer.value; acpi_cm_remove_reference (operand_desc); diff --git a/drivers/acpi/dispatcher/dsutils.c b/drivers/acpi/dispatcher/dsutils.c index 2efa43e5164b..d31464840e4c 100644 --- a/drivers/acpi/dispatcher/dsutils.c +++ b/drivers/acpi/dispatcher/dsutils.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: dsutils - Dispatcher utilities - * $Revision: 50 $ + * $Revision: 52 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -566,7 +566,7 @@ acpi_ds_map_opcode_to_data_type ( case AML_WORD_OP: case AML_DWORD_OP: - data_type = ACPI_TYPE_NUMBER; + data_type = ACPI_TYPE_INTEGER; break; diff --git a/drivers/acpi/dispatcher/dswexec.c b/drivers/acpi/dispatcher/dswexec.c index 1f7e329adb97..6f0a8668c440 100644 --- a/drivers/acpi/dispatcher/dswexec.c +++ b/drivers/acpi/dispatcher/dswexec.c @@ -2,12 +2,12 @@ * * Module Name: dswexec - Dispatcher method execution callbacks; * dispatch to interpreter. - * $Revision: 50 $ + * $Revision: 54 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -46,7 +46,7 @@ * * RETURN: Status * - * DESCRIPTION: + * DESCRIPTION: Get the result of a predicate evaluation * ****************************************************************************/ @@ -93,22 +93,22 @@ acpi_ds_get_predicate_value ( * be a number */ - if (obj_desc->common.type != ACPI_TYPE_NUMBER) { + if (obj_desc->common.type != ACPI_TYPE_INTEGER) { status = AE_AML_OPERAND_TYPE; goto cleanup; } - /* TBD: 64/32-bit */ + /* Truncate the predicate to 32-bits if necessary */ - obj_desc->number.value &= (UINT64) 0x00000000FFFFFFFF; + acpi_aml_truncate_for32bit_table (obj_desc, walk_state); /* * Save the result of the predicate evaluation on * the control stack */ - if (obj_desc->number.value) { + if (obj_desc->integer.value) { walk_state->control_state->common.value = TRUE; } diff --git a/drivers/acpi/dispatcher/dswload.c b/drivers/acpi/dispatcher/dswload.c index b3f1dc06230e..300d02b7f93c 100644 --- a/drivers/acpi/dispatcher/dswload.c +++ b/drivers/acpi/dispatcher/dswload.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: dswload - Dispatcher namespace load callbacks - * $Revision: 24 $ + * $Revision: 26 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/dispatcher/dswscope.c b/drivers/acpi/dispatcher/dswscope.c index 11b6a6cb96dc..332ab4ffd3e9 100644 --- a/drivers/acpi/dispatcher/dswscope.c +++ b/drivers/acpi/dispatcher/dswscope.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: dswscope - Scope stack manipulation - * $Revision: 40 $ + * $Revision: 42 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/dispatcher/dswstate.c b/drivers/acpi/dispatcher/dswstate.c index a15a6f5f7eb2..a436945df886 100644 --- a/drivers/acpi/dispatcher/dswstate.c +++ b/drivers/acpi/dispatcher/dswstate.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: dswstate - Dispatcher parse tree walk management routines - * $Revision: 36 $ + * $Revision: 38 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -37,31 +37,6 @@ /******************************************************************************* * - * FUNCTION: Acpi_ds_result_stack_clear - * - * PARAMETERS: Walk_state - Current Walk state - * - * RETURN: Status - * - * DESCRIPTION: Reset this walk's result stack pointers to zero, thus setting - * the stack to zero. - * - ******************************************************************************/ - -ACPI_STATUS -xxx_acpi_ds_result_stack_clear ( - ACPI_WALK_STATE *walk_state) -{ -/* - Walk_state->Num_results = 0; - Walk_state->Current_result = 0; -*/ - return (AE_OK); -} - - -/******************************************************************************* - * * FUNCTION: Acpi_ds_result_insert * * PARAMETERS: Object - Object to push @@ -135,7 +110,7 @@ acpi_ds_result_remove ( /* Check for a valid result object */ if (!state->results.obj_desc [index]) { - return (AE_AML_NO_OPERAND); + return (AE_AML_NO_RETURN_VALUE); } /* Remove the object */ @@ -179,7 +154,7 @@ acpi_ds_result_pop ( if (!state->results.num_results) { - return (AE_STACK_UNDERFLOW); + return (AE_AML_NO_RETURN_VALUE); } /* Remove top element */ @@ -198,12 +173,12 @@ acpi_ds_result_pop ( } - return (AE_STACK_UNDERFLOW); + return (AE_AML_NO_RETURN_VALUE); } /******************************************************************************* * - * FUNCTION: Acpi_ds_result_pop + * FUNCTION: Acpi_ds_result_pop_from_bottom * * PARAMETERS: Object - Where to return the popped object * Walk_state - Current Walk state @@ -231,7 +206,7 @@ acpi_ds_result_pop_from_bottom ( if (!state->results.num_results) { - return (AE_STACK_UNDERFLOW); + return (AE_AML_NO_RETURN_VALUE); } /* Remove Bottom element */ @@ -250,7 +225,7 @@ acpi_ds_result_pop_from_bottom ( /* Check for a valid result object */ if (!*object) { - return (AE_AML_NO_OPERAND); + return (AE_AML_NO_RETURN_VALUE); } @@ -260,15 +235,14 @@ acpi_ds_result_pop_from_bottom ( /******************************************************************************* * - * FUNCTION: Acpi_ds_result_pop + * FUNCTION: Acpi_ds_result_push * * PARAMETERS: Object - Where to return the popped object * Walk_state - Current Walk state * * RETURN: Status * - * DESCRIPTION: Pop an object off the bottom of this walk's result stack. In - * other words, this is a FIFO. + * DESCRIPTION: Push an object onto the current result stack * ******************************************************************************/ @@ -282,7 +256,7 @@ acpi_ds_result_push ( state = walk_state->results; if (!state) { - return (AE_OK); + return (AE_AML_INTERNAL); } if (state->results.num_results == OBJ_NUM_OPERANDS) { @@ -719,6 +693,7 @@ acpi_ds_create_walk_state ( ACPI_WALK_LIST *walk_list) { ACPI_WALK_STATE *walk_state; + ACPI_STATUS status; acpi_cm_acquire_mutex (ACPI_MTX_CACHES); @@ -736,7 +711,7 @@ acpi_ds_create_walk_state ( acpi_gbl_walk_state_cache_depth--; acpi_cm_release_mutex (ACPI_MTX_CACHES); - } + } else { /* The cache is empty, create a new object */ @@ -762,6 +737,14 @@ acpi_ds_create_walk_state ( acpi_ds_method_data_init (walk_state); #endif + /* Create an initial result stack entry */ + + status = acpi_ds_result_stack_push (walk_state); + if (ACPI_FAILURE (status)) { + return (NULL); + } + + /* Put the new state at the head of the walk list */ acpi_ds_push_walk_state (walk_state, walk_list); diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 8f6f61e36dc1..8bedfac6c59b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -270,25 +270,6 @@ ec_transaction ( return_ACPI_STATUS(status); } -static ACPI_STATUS -ec_space_setup ( - ACPI_HANDLE region_handle, - UINT32 function, - void *handler_context, - void **return_context) -{ - // TODO: What is this function for? - /* - * The ec object is in the handler context and is needed - * when calling the ec_space_handler. - */ - *return_context = handler_context; - - return AE_OK; -} - - - static void ec_query_handler ( @@ -556,10 +537,10 @@ found_ec( buf.length = sizeof(obj); buf.pointer = &obj; if (!ACPI_SUCCESS(acpi_evaluate_object(handle, "_GPE", NULL, &buf)) - || obj.type != ACPI_TYPE_NUMBER) + || obj.type != ACPI_TYPE_INTEGER) return AE_OK; - ec_cxt->gpe_bit = obj.number.value; + ec_cxt->gpe_bit = obj.integer.value; /* determine if we need the Global Lock when accessing */ buf.length = sizeof(obj); @@ -568,12 +549,12 @@ found_ec( status = acpi_evaluate_object(handle, "_GLK", NULL, &buf); if (status == AE_NOT_FOUND) ec_cxt->need_global_lock = 0; - else if (!ACPI_SUCCESS(status) || obj.type != ACPI_TYPE_NUMBER) { + else if (!ACPI_SUCCESS(status) || obj.type != ACPI_TYPE_INTEGER) { DEBUG_PRINT(ACPI_ERROR, ("_GLK failed\n")); return AE_OK; } - ec_cxt->need_global_lock = obj.number.value; + ec_cxt->need_global_lock = obj.integer.value; printk(KERN_INFO "ACPI: found EC @ (0x%02x,0x%02x,gpe %d GL %d)\n", ec_cxt->data_port, ec_cxt->status_port, ec_cxt->gpe_bit, diff --git a/drivers/acpi/events/evevent.c b/drivers/acpi/events/evevent.c index d5ce143a8899..afdd477db6e5 100644 --- a/drivers/acpi/events/evevent.c +++ b/drivers/acpi/events/evevent.c @@ -2,12 +2,12 @@ * * Module Name: evevent - Fixed and General Purpose Acpi_event * handling and dispatch - * $Revision: 32 $ + * $Revision: 33 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c index a52f2dc3ddad..cae4a44b27a2 100644 --- a/drivers/acpi/events/evmisc.c +++ b/drivers/acpi/events/evmisc.c @@ -2,12 +2,12 @@ * * Module Name: evmisc - ACPI device notification handler dispatch * and ACPI Global Lock support - * $Revision: 20 $ + * $Revision: 22 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c index 53cae63925aa..071639a27670 100644 --- a/drivers/acpi/events/evregion.c +++ b/drivers/acpi/events/evregion.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: evregion - ACPI Address_space (Op_region) handler dispatch - * $Revision: 93 $ + * $Revision: 94 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -122,8 +122,8 @@ acpi_ev_execute_reg_method ( u32 function) { ACPI_OPERAND_OBJECT *params[3]; - ACPI_OPERAND_OBJECT space_iD_obj; - ACPI_OPERAND_OBJECT function_obj; + ACPI_OPERAND_OBJECT space_id_desc; + ACPI_OPERAND_OBJECT function_desc; ACPI_STATUS status; @@ -141,24 +141,24 @@ acpi_ev_execute_reg_method ( * Passed as a parameter */ - acpi_cm_init_static_object (&space_iD_obj); - acpi_cm_init_static_object (&function_obj); + acpi_cm_init_static_object (&space_id_desc); + acpi_cm_init_static_object (&function_desc); /* * Method requires two parameters. */ - params [0] = &space_iD_obj; - params [1] = &function_obj; + params [0] = &space_id_desc; + params [1] = &function_desc; params [2] = NULL; /* * Set up the parameter objects */ - space_iD_obj.common.type = ACPI_TYPE_NUMBER; - space_iD_obj.number.value = region_obj->region.space_id; + space_id_desc.common.type = ACPI_TYPE_INTEGER; + space_id_desc.integer.value = region_obj->region.space_id; - function_obj.common.type = ACPI_TYPE_NUMBER; - function_obj.number.value = function; + function_desc.common.type = ACPI_TYPE_INTEGER; + function_desc.integer.value = function; /* * Execute the method, no return value diff --git a/drivers/acpi/events/evrgnini.c b/drivers/acpi/events/evrgnini.c index 92e5f198fac9..eb5e2033e255 100644 --- a/drivers/acpi/events/evrgnini.c +++ b/drivers/acpi/events/evrgnini.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: evrgnini- ACPI Address_space (Op_region) init - * $Revision: 31 $ + * $Revision: 33 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/events/evsci.c b/drivers/acpi/events/evsci.c index 02320e93c34e..369d2f184cf1 100644 --- a/drivers/acpi/events/evsci.c +++ b/drivers/acpi/events/evsci.c @@ -2,12 +2,12 @@ * * Module Name: evsci - System Control Interrupt configuration and * legacy to ACPI mode state transition functions - * $Revision: 67 $ + * $Revision: 69 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/events/evxface.c b/drivers/acpi/events/evxface.c index c3bbad0ffbc2..f0e62934f9fd 100644 --- a/drivers/acpi/events/evxface.c +++ b/drivers/acpi/events/evxface.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: evxface - External interfaces for ACPI events - * $Revision: 97 $ + * $Revision: 101 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -187,26 +187,25 @@ acpi_install_notify_handler ( return (AE_BAD_PARAMETER); } - /* Convert and validate the device handle */ - acpi_cm_acquire_mutex (ACPI_MTX_NAMESPACE); + /* Convert and validate the device handle */ + device_node = acpi_ns_convert_handle_to_entry (device); if (!device_node) { status = AE_BAD_PARAMETER; goto unlock_and_exit; } - /* - * Support for global notify handlers. These handlers are invoked for - * every notifiy of the type specifiec + * Root Object: + * ------------ + * Registering a notify handler on the root object indicates that the + * caller wishes to receive notifications for all objects. Note that + * only one <external> global handler can be regsitered (per notify type). */ - if (device == ACPI_ROOT_OBJECT) { - /* - * Make sure the handler is not already installed. - */ + /* Make sure the handler is not already installed */ if (((handler_type == ACPI_SYSTEM_NOTIFY) && acpi_gbl_sys_notify.handler) || @@ -222,94 +221,89 @@ acpi_install_notify_handler ( acpi_gbl_sys_notify.handler = handler; acpi_gbl_sys_notify.context = context; } - - else { + else /* ACPI_DEVICE_NOTIFY */ { acpi_gbl_drv_notify.node = device_node; acpi_gbl_drv_notify.handler = handler; acpi_gbl_drv_notify.context = context; } - /* Global notify handler installed */ - - goto unlock_and_exit; } - /* - * These are the ONLY objects that can receive ACPI notifications + * Other Objects: + * -------------- + * Caller will only receive notifications specific to the target object. + * Note that only certain object types can receive notifications. */ - - if ((device_node->type != ACPI_TYPE_DEVICE) && - (device_node->type != ACPI_TYPE_PROCESSOR) && - (device_node->type != ACPI_TYPE_POWER) && - (device_node->type != ACPI_TYPE_THERMAL)) - { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - /* Check for an existing internal object */ - - obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node); - if (obj_desc) { + else { /* - * The object exists. - * Make sure the handler is not already installed. + * These are the ONLY objects that can receive ACPI notifications */ - - if (((handler_type == ACPI_SYSTEM_NOTIFY) && - obj_desc->device.sys_handler) || - ((handler_type == ACPI_DEVICE_NOTIFY) && - obj_desc->device.drv_handler)) + if ((device_node->type != ACPI_TYPE_DEVICE) && + (device_node->type != ACPI_TYPE_PROCESSOR) && + (device_node->type != ACPI_TYPE_POWER) && + (device_node->type != ACPI_TYPE_THERMAL)) { - status = AE_EXIST; + status = AE_BAD_PARAMETER; goto unlock_and_exit; } - } - else { - /* Create a new object */ + /* Check for an existing internal object */ - obj_desc = acpi_cm_create_internal_object (device_node->type); - if (!obj_desc) { - status = AE_NO_MEMORY; - goto unlock_and_exit; + obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node); + if (obj_desc) { + + /* Object exists - make sure there's no handler */ + + if (((handler_type == ACPI_SYSTEM_NOTIFY) && + obj_desc->device.sys_handler) || + ((handler_type == ACPI_DEVICE_NOTIFY) && + obj_desc->device.drv_handler)) + { + status = AE_EXIST; + goto unlock_and_exit; + } } - /* Attach new object to the Node */ + else { + /* Create a new object */ - status = acpi_ns_attach_object (device, obj_desc, (u8) device_node->type); + obj_desc = acpi_cm_create_internal_object (device_node->type); + if (!obj_desc) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } - if (ACPI_FAILURE (status)) { - goto unlock_and_exit; - } - } + /* Attach new object to the Node */ + status = acpi_ns_attach_object (device, obj_desc, (u8) device_node->type); - /* - * If we get here, we know that there is no handler installed - * so let's party - */ - notify_obj = acpi_cm_create_internal_object (INTERNAL_TYPE_NOTIFY); - if (!notify_obj) { - status = AE_NO_MEMORY; - goto unlock_and_exit; - } + if (ACPI_FAILURE (status)) { + goto unlock_and_exit; + } + } - notify_obj->notify_handler.node = device_node; - notify_obj->notify_handler.handler = handler; - notify_obj->notify_handler.context = context; + /* Install the handler */ + notify_obj = acpi_cm_create_internal_object (INTERNAL_TYPE_NOTIFY); + if (!notify_obj) { + status = AE_NO_MEMORY; + goto unlock_and_exit; + } - if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->device.sys_handler = notify_obj; - } + notify_obj->notify_handler.node = device_node; + notify_obj->notify_handler.handler = handler; + notify_obj->notify_handler.context = context; - else { - obj_desc->device.drv_handler = notify_obj; - } + if (handler_type == ACPI_SYSTEM_NOTIFY) { + obj_desc->device.sys_handler = notify_obj; + } + else /* ACPI_DEVICE_NOTIFY */ { + obj_desc->device.drv_handler = notify_obj; + } + } unlock_and_exit: acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); @@ -343,7 +337,6 @@ acpi_remove_notify_handler ( ACPI_NAMESPACE_NODE *device_node; ACPI_STATUS status = AE_OK; - /* Parameter validation */ if ((!handler) || @@ -363,63 +356,92 @@ acpi_remove_notify_handler ( } /* - * These are the ONLY objects that can receive ACPI notifications + * Root Object: + * ------------ */ + if (device == ACPI_ROOT_OBJECT) { - if ((device_node->type != ACPI_TYPE_DEVICE) && - (device_node->type != ACPI_TYPE_PROCESSOR) && - (device_node->type != ACPI_TYPE_POWER) && - (device_node->type != ACPI_TYPE_THERMAL)) - { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } - - /* Check for an existing internal object */ + if (((handler_type == ACPI_SYSTEM_NOTIFY) && + !acpi_gbl_sys_notify.handler) || + ((handler_type == ACPI_DEVICE_NOTIFY) && + !acpi_gbl_drv_notify.handler)) + { + status = AE_NOT_EXIST; + goto unlock_and_exit; + } - obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node); - if (!obj_desc) { - status = AE_NOT_EXIST; - goto unlock_and_exit; + if (handler_type == ACPI_SYSTEM_NOTIFY) { + acpi_gbl_sys_notify.node = NULL; + acpi_gbl_sys_notify.handler = NULL; + acpi_gbl_sys_notify.context = NULL; + } + else { + acpi_gbl_drv_notify.node = NULL; + acpi_gbl_drv_notify.handler = NULL; + acpi_gbl_drv_notify.context = NULL; + } } /* - * The object exists. - * - * Make sure the handler is installed. + * Other Objects: + * -------------- */ - - if (handler_type == ACPI_SYSTEM_NOTIFY) { - notify_obj = obj_desc->device.sys_handler; - } else { - notify_obj = obj_desc->device.drv_handler; - } + /* + * These are the ONLY objects that can receive ACPI notifications + */ + if ((device_node->type != ACPI_TYPE_DEVICE) && + (device_node->type != ACPI_TYPE_PROCESSOR) && + (device_node->type != ACPI_TYPE_POWER) && + (device_node->type != ACPI_TYPE_THERMAL)) + { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } - if ((!notify_obj) || - (notify_obj->notify_handler.handler != handler)) - { - status = AE_BAD_PARAMETER; - goto unlock_and_exit; - } + /* Check for an existing internal object */ - /* - * Now we can remove the handler - */ - if (handler_type == ACPI_SYSTEM_NOTIFY) { - obj_desc->device.sys_handler = NULL; - } - else { - obj_desc->device.drv_handler = NULL; + obj_desc = acpi_ns_get_attached_object ((ACPI_HANDLE) device_node); + if (!obj_desc) { + status = AE_NOT_EXIST; + goto unlock_and_exit; + } + + /* Object exists - make sure there's an existing handler */ + + if (handler_type == ACPI_SYSTEM_NOTIFY) { + notify_obj = obj_desc->device.sys_handler; + } + else { + notify_obj = obj_desc->device.drv_handler; + } + + if ((!notify_obj) || + (notify_obj->notify_handler.handler != handler)) + { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + /* Remove the handler */ + + if (handler_type == ACPI_SYSTEM_NOTIFY) { + obj_desc->device.sys_handler = NULL; + } + else { + obj_desc->device.drv_handler = NULL; + } + + acpi_cm_remove_reference (notify_obj); } - acpi_cm_remove_reference (notify_obj); unlock_and_exit: acpi_cm_release_mutex (ACPI_MTX_NAMESPACE); return (status); } + /****************************************************************************** * * FUNCTION: Acpi_install_gpe_handler diff --git a/drivers/acpi/events/evxfevnt.c b/drivers/acpi/events/evxfevnt.c index 5b7652e52bd7..9864301a34f5 100644 --- a/drivers/acpi/events/evxfevnt.c +++ b/drivers/acpi/events/evxfevnt.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: evxfevnt - External Interfaces, ACPI event disable/enable - * $Revision: 26 $ + * $Revision: 28 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/events/evxfregn.c b/drivers/acpi/events/evxfregn.c index 71116cfc8715..e54bbab248dd 100644 --- a/drivers/acpi/events/evxfregn.c +++ b/drivers/acpi/events/evxfregn.c @@ -2,12 +2,12 @@ * * Module Name: evxfregn - External Interfaces, ACPI Operation Regions and * Address Spaces. - * $Revision: 26 $ + * $Revision: 27 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/hardware/hwacpi.c b/drivers/acpi/hardware/hwacpi.c index d2154a1a2646..28e25368541c 100644 --- a/drivers/acpi/hardware/hwacpi.c +++ b/drivers/acpi/hardware/hwacpi.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: hwacpi - ACPI hardware functions - mode and timer - * $Revision: 34 $ + * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/hardware/hwcpu32.c b/drivers/acpi/hardware/hwcpu32.c index fde6d1c07dd3..380db25e3c62 100644 --- a/drivers/acpi/hardware/hwcpu32.c +++ b/drivers/acpi/hardware/hwcpu32.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: hwcpu32.c - CPU support for IA32 (Throttling, Cx_states) - * $Revision: 39 $ + * $Revision: 42 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -707,5 +707,3 @@ acpi_hw_program_duty_cycle ( return; } - - diff --git a/drivers/acpi/hardware/hwgpe.c b/drivers/acpi/hardware/hwgpe.c index 2b413fac803b..b2a621e47523 100644 --- a/drivers/acpi/hardware/hwgpe.c +++ b/drivers/acpi/hardware/hwgpe.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: hwgpe - Low level GPE enable/disable/clear functions - * $Revision: 25 $ + * $Revision: 27 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/hardware/hwregs.c b/drivers/acpi/hardware/hwregs.c index 77b6a1c8c444..cbb98ec78364 100644 --- a/drivers/acpi/hardware/hwregs.c +++ b/drivers/acpi/hardware/hwregs.c @@ -3,12 +3,12 @@ * * Module Name: hwregs - Read/write access functions for the various ACPI * control and status registers. - * $Revision: 86 $ + * $Revision: 87 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -185,9 +185,9 @@ acpi_hw_obtain_sleep_type_register_data ( } else if (((obj_desc->package.elements[0])->common.type != - ACPI_TYPE_NUMBER) || + ACPI_TYPE_INTEGER) || ((obj_desc->package.elements[1])->common.type != - ACPI_TYPE_NUMBER)) + ACPI_TYPE_INTEGER)) { /* Must have two */ @@ -199,9 +199,9 @@ acpi_hw_obtain_sleep_type_register_data ( /* * Valid _Sx_ package size, type, and value */ - *slp_typ_a = (u8) (obj_desc->package.elements[0])->number.value; + *slp_typ_a = (u8) (obj_desc->package.elements[0])->integer.value; - *slp_typ_b = (u8) (obj_desc->package.elements[1])->number.value; + *slp_typ_b = (u8) (obj_desc->package.elements[1])->integer.value; } diff --git a/drivers/acpi/hardware/hwxface.c b/drivers/acpi/hardware/hwxface.c index 156c946e73f8..35194cae38c6 100644 --- a/drivers/acpi/hardware/hwxface.c +++ b/drivers/acpi/hardware/hwxface.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Name: hwxface.c - Hardware access external interfaces - * $Revision: 36 $ + * $Revision: 38 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/accommon.h b/drivers/acpi/include/accommon.h index 37e13b2285e4..b657b6d9eee6 100644 --- a/drivers/acpi/include/accommon.h +++ b/drivers/acpi/include/accommon.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: accommon.h -- prototypes for the common (subsystem-wide) procedures - * $Revision: 82 $ + * $Revision: 86 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -100,6 +100,8 @@ acpi_cm_allocate_owner_id ( * Cm_clib - Local implementations of C library functions */ +#ifndef ACPI_USE_SYSTEM_CLIBRARY + NATIVE_UINT acpi_cm_strlen ( const NATIVE_CHAR *string); @@ -141,7 +143,7 @@ u32 acpi_cm_strtoul ( const NATIVE_CHAR *string, NATIVE_CHAR **terminator, - u32 base); + NATIVE_UINT base); NATIVE_CHAR * acpi_cm_strstr ( @@ -161,7 +163,7 @@ acpi_cm_memcpy ( void * acpi_cm_memset ( void *dest, - u32 value, + NATIVE_UINT value, NATIVE_UINT count); u32 @@ -172,6 +174,7 @@ u32 acpi_cm_to_lower ( u32 c); +#endif /* ACPI_USE_SYSTEM_CLIBRARY */ /* * Cm_copy - Object construction and conversion interfaces @@ -297,7 +300,7 @@ function_value_exit ( u32 line_number, u32 component_id, NATIVE_CHAR *function_name, - NATIVE_UINT value); + ACPI_INTEGER value); void function_ptr_exit ( @@ -596,7 +599,7 @@ acpi_cm_init_static_object ( #define acpi_cm_callocate(a) _cm_callocate(a, _COMPONENT,_THIS_MODULE,__LINE__) #define acpi_cm_free(a) _cm_free(a,_COMPONENT,_THIS_MODULE,__LINE__) -#ifndef ACPI_DEBUG +#ifndef ACPI_DEBUG_TRACK_ALLOCATIONS #define acpi_cm_add_element_to_alloc_list(a,b,c,d,e,f) #define acpi_cm_delete_element_from_alloc_list(a,b,c,d) diff --git a/drivers/acpi/include/acconfig.h b/drivers/acpi/include/acconfig.h index 2b210339b5e7..d5ab95dfb600 100644 --- a/drivers/acpi/include/acconfig.h +++ b/drivers/acpi/include/acconfig.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acconfig.h - Global configuration constants - * $Revision: 48 $ + * $Revision: 51 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -122,6 +122,10 @@ #define MTH_NUM_ARGS 7 #define MTH_MAX_ARG 6 +/* Maximum length of resulting string when converting from a buffer */ + +#define ACPI_MAX_STRING_CONVERSION 200 + /* * Operand Stack (in WALK_STATE), Must be large enough to contain MTH_MAX_ARG */ diff --git a/drivers/acpi/include/acdebug.h b/drivers/acpi/include/acdebug.h index 2bc9e7165420..f1fa7094ef18 100644 --- a/drivers/acpi/include/acdebug.h +++ b/drivers/acpi/include/acdebug.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acdebug.h - ACPI/AML debugger - * $Revision: 37 $ + * $Revision: 39 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acdispat.h b/drivers/acpi/include/acdispat.h index 599e46c365ed..f5d52cc4151f 100644 --- a/drivers/acpi/include/acdispat.h +++ b/drivers/acpi/include/acdispat.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acdispat.h - dispatcher (parser to interpreter interface) - * $Revision: 33 $ + * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acenv.h b/drivers/acpi/include/acenv.h index f867a348f907..9e4e62339ccd 100644 --- a/drivers/acpi/include/acenv.h +++ b/drivers/acpi/include/acenv.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acenv.h - Generation environment specific items - * $Revision: 65 $ + * $Revision: 70 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -28,7 +28,7 @@ /* - * Configuration for ACPI Utilities + * Configuration for ACPI tools and utilities */ #ifdef _ACPI_DUMP_APP @@ -55,6 +55,16 @@ #define ACPI_USE_SYSTEM_CLIBRARY #endif +/* + * Memory allocation tracking. Used only if + * 1) This is the debug version + * 2) This is NOT a 16-bit version of the code (not enough real-mode memory) + */ +#ifdef ACPI_DEBUG +#ifndef _IA16 +#define ACPI_DEBUG_TRACK_ALLOCATIONS +#endif +#endif /* * Environment configuration. The purpose of this file is to interface to the @@ -154,17 +164,17 @@ #define STRUPR(s) strupr((s)) #define STRLEN(s) strlen((s)) #define STRCPY(d,s) strcpy((d), (s)) -#define STRNCPY(d,s,n) strncpy((d), (s), (n)) -#define STRNCMP(d,s,n) strncmp((d), (s), (n)) +#define STRNCPY(d,s,n) strncpy((d), (s), (NATIVE_INT)(n)) +#define STRNCMP(d,s,n) strncmp((d), (s), (NATIVE_INT)(n)) #define STRCMP(d,s) strcmp((d), (s)) #define STRCAT(d,s) strcat((d), (s)) -#define STRNCAT(d,s,n) strncat((d), (s), (n)) -#define STRTOUL(d,s,n) strtoul((d), (s), (n)) -#define MEMCPY(d,s,n) memcpy((d), (s), (n)) -#define MEMSET(d,s,n) memset((d), (s), (n)) +#define STRNCAT(d,s,n) strncat((d), (s), (NATIVE_INT)(n)) +#define STRTOUL(d,s,n) strtoul((d), (s), (NATIVE_INT)(n)) +#define MEMCPY(d,s,n) memcpy((d), (s), (NATIVE_INT)(n)) +#define MEMSET(d,s,n) memset((d), (s), (NATIVE_INT)(n)) #define TOUPPER toupper #define TOLOWER tolower - +#define IS_XDIGIT isxdigit /****************************************************************************** * diff --git a/drivers/acpi/include/acevents.h b/drivers/acpi/include/acevents.h index 3e76370bf5e3..b7d335451583 100644 --- a/drivers/acpi/include/acevents.h +++ b/drivers/acpi/include/acevents.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acevents.h - Event subcomponent prototypes and defines - * $Revision: 62 $ + * $Revision: 63 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acexcep.h b/drivers/acpi/include/acexcep.h index 1629a0934d2a..8fb2675857d2 100644 --- a/drivers/acpi/include/acexcep.h +++ b/drivers/acpi/include/acexcep.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acexcep.h - Exception codes returned by the ACPI subsystem - * $Revision: 37 $ + * $Revision: 41 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -116,8 +116,10 @@ #define AE_AML_NAME_NOT_FOUND (ACPI_STATUS) (0x0010 | AE_CODE_AML) #define AE_AML_INTERNAL (ACPI_STATUS) (0x0011 | AE_CODE_AML) #define AE_AML_INVALID_SPACE_ID (ACPI_STATUS) (0x0012 | AE_CODE_AML) +#define AE_AML_STRING_LIMIT (ACPI_STATUS) (0x0013 | AE_CODE_AML) +#define AE_AML_NO_RETURN_VALUE (ACPI_STATUS) (0x0014 | AE_CODE_AML) -#define AE_CODE_AML_MAX 0x0012 +#define AE_CODE_AML_MAX 0x0014 /* * Internal exceptions used for control @@ -202,6 +204,8 @@ static NATIVE_CHAR *acpi_gbl_exception_names_aml[] = "AE_AML_NAME_NOT_FOUND", "AE_AML_INTERNAL", "AE_AML_INVALID_SPACE_ID", + "AE_AML_STRING_LIMIT", + "AE_AML_NO_RETURN_VALUE", }; static NATIVE_CHAR *acpi_gbl_exception_names_ctrl[] = diff --git a/drivers/acpi/include/acgcc.h b/drivers/acpi/include/acgcc.h index 5992f493d9b8..82b1e5139a99 100644 --- a/drivers/acpi/include/acgcc.h +++ b/drivers/acpi/include/acgcc.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acgcc.h - GCC specific defines, etc. - * $Revision: 2 $ + * $Revision: 4 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acglobal.h b/drivers/acpi/include/acglobal.h index 248f72c9d75b..36444038c253 100644 --- a/drivers/acpi/include/acglobal.h +++ b/drivers/acpi/include/acglobal.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acglobal.h - Declarations for global variables - * $Revision: 92 $ + * $Revision: 96 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -154,7 +154,6 @@ ACPI_EXTERN u8 acpi_gbl_global_lock_set; /* TBD: [Restr ACPI_EXTERN u8 acpi_gbl_step_to_next_call; ACPI_EXTERN u8 acpi_gbl_acpi_hardware_present; - ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_drv_notify; ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_sys_notify; @@ -162,7 +161,8 @@ ACPI_EXTERN ACPI_OBJECT_NOTIFY_HANDLER acpi_gbl_sys_notify; extern u8 acpi_gbl_shutdown; extern u32 acpi_gbl_system_flags; extern u32 acpi_gbl_startup_flags; -extern u8 acpi_gbl_decode_to8bit[]; +extern u8 acpi_gbl_decode_to8bit[8]; +extern NATIVE_CHAR acpi_gbl_hex_to_ascii[]; /***************************************************************************** diff --git a/drivers/acpi/include/achware.h b/drivers/acpi/include/achware.h index 1a206e8d24d7..24b767cc939d 100644 --- a/drivers/acpi/include/achware.h +++ b/drivers/acpi/include/achware.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: achware.h -- hardware specific interfaces - * $Revision: 48 $ + * $Revision: 50 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acinterp.h b/drivers/acpi/include/acinterp.h index c8c967492bcd..ffeb5682f96e 100644 --- a/drivers/acpi/include/acinterp.h +++ b/drivers/acpi/include/acinterp.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acinterp.h - Interpreter subcomponent prototypes and defines - * $Revision: 86 $ + * $Revision: 89 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -70,9 +70,28 @@ acpi_aml_execute_method ( /* - * amfield - ACPI AML (p-code) execution - field manipulation + * amconvrt - object conversion */ +ACPI_STATUS +acpi_aml_convert_to_integer ( + ACPI_OPERAND_OBJECT **obj_desc, + ACPI_WALK_STATE *walk_state); + +ACPI_STATUS +acpi_aml_convert_to_buffer ( + ACPI_OPERAND_OBJECT **obj_desc, + ACPI_WALK_STATE *walk_state); + +ACPI_STATUS +acpi_aml_convert_to_string ( + ACPI_OPERAND_OBJECT **obj_desc, + ACPI_WALK_STATE *walk_state); + + +/* + * amfield - ACPI AML (p-code) execution - field manipulation + */ ACPI_STATUS acpi_aml_read_field ( diff --git a/drivers/acpi/include/aclinux.h b/drivers/acpi/include/aclinux.h index 673d5f96b34d..77a634234568 100644 --- a/drivers/acpi/include/aclinux.h +++ b/drivers/acpi/include/aclinux.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: aclinux.h - OS specific defines, etc. - * $Revision: 6 $ + * $Revision: 7 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -29,6 +29,7 @@ #define ACPI_OS_NAME "Linux" +#include <linux/config.h> #include <linux/string.h> #include <linux/kernel.h> #include <linux/ctype.h> diff --git a/drivers/acpi/include/aclocal.h b/drivers/acpi/include/aclocal.h index a647026f1573..99da2a422741 100644 --- a/drivers/acpi/include/aclocal.h +++ b/drivers/acpi/include/aclocal.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: aclocal.h - Internal data types used across the ACPI subsystem - * $Revision: 95 $ + * $Revision: 97 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -476,7 +476,9 @@ typedef struct acpi_opcode_info u32 parse_args; /* Grammar/Parse time arguments */ u32 runtime_args; /* Interpret time arguments */ - DEBUG_ONLY_MEMBERS (NATIVE_CHAR *name) /* op name (debug only) */ +#ifdef _OPCODE_NAMES + NATIVE_CHAR *name; /* op name (debug only) */ +#endif } ACPI_OPCODE_INFO; @@ -751,66 +753,66 @@ typedef struct acpi_get_devices_info /* * Control bit definitions */ -#define TMR_STS (PM1_STS | 0x01) -#define BM_STS (PM1_STS | 0x02) -#define GBL_STS (PM1_STS | 0x03) -#define PWRBTN_STS (PM1_STS | 0x04) -#define SLPBTN_STS (PM1_STS | 0x05) -#define RTC_STS (PM1_STS | 0x06) -#define WAK_STS (PM1_STS | 0x07) - -#define TMR_EN (PM1_EN | 0x01) +#define TMR_STS (PM1_STS | 0x01) +#define BM_STS (PM1_STS | 0x02) +#define GBL_STS (PM1_STS | 0x03) +#define PWRBTN_STS (PM1_STS | 0x04) +#define SLPBTN_STS (PM1_STS | 0x05) +#define RTC_STS (PM1_STS | 0x06) +#define WAK_STS (PM1_STS | 0x07) + +#define TMR_EN (PM1_EN | 0x01) /* no BM_EN */ -#define GBL_EN (PM1_EN | 0x03) -#define PWRBTN_EN (PM1_EN | 0x04) -#define SLPBTN_EN (PM1_EN | 0x05) -#define RTC_EN (PM1_EN | 0x06) -#define WAK_EN (PM1_EN | 0x07) +#define GBL_EN (PM1_EN | 0x03) +#define PWRBTN_EN (PM1_EN | 0x04) +#define SLPBTN_EN (PM1_EN | 0x05) +#define RTC_EN (PM1_EN | 0x06) +#define WAK_EN (PM1_EN | 0x07) -#define SCI_EN (PM1_CONTROL | 0x01) -#define BM_RLD (PM1_CONTROL | 0x02) -#define GBL_RLS (PM1_CONTROL | 0x03) -#define SLP_TYPE_A (PM1_CONTROL | 0x04) -#define SLP_TYPE_B (PM1_CONTROL | 0x05) -#define SLP_EN (PM1_CONTROL | 0x06) +#define SCI_EN (PM1_CONTROL | 0x01) +#define BM_RLD (PM1_CONTROL | 0x02) +#define GBL_RLS (PM1_CONTROL | 0x03) +#define SLP_TYPE_A (PM1_CONTROL | 0x04) +#define SLP_TYPE_B (PM1_CONTROL | 0x05) +#define SLP_EN (PM1_CONTROL | 0x06) -#define ARB_DIS (PM2_CONTROL | 0x01) +#define ARB_DIS (PM2_CONTROL | 0x01) -#define TMR_VAL (PM_TIMER | 0x01) +#define TMR_VAL (PM_TIMER | 0x01) -#define GPE0_STS (GPE0_STS_BLOCK | 0x01) -#define GPE0_EN (GPE0_EN_BLOCK | 0x01) +#define GPE0_STS (GPE0_STS_BLOCK | 0x01) +#define GPE0_EN (GPE0_EN_BLOCK | 0x01) -#define GPE1_STS (GPE1_STS_BLOCK | 0x01) -#define GPE1_EN (GPE1_EN_BLOCK | 0x01) +#define GPE1_STS (GPE1_STS_BLOCK | 0x01) +#define GPE1_EN (GPE1_EN_BLOCK | 0x01) -#define TMR_STS_MASK 0x0001 -#define BM_STS_MASK 0x0010 -#define GBL_STS_MASK 0x0020 -#define PWRBTN_STS_MASK 0x0100 -#define SLPBTN_STS_MASK 0x0200 -#define RTC_STS_MASK 0x0400 -#define WAK_STS_MASK 0x8000 +#define TMR_STS_MASK 0x0001 +#define BM_STS_MASK 0x0010 +#define GBL_STS_MASK 0x0020 +#define PWRBTN_STS_MASK 0x0100 +#define SLPBTN_STS_MASK 0x0200 +#define RTC_STS_MASK 0x0400 +#define WAK_STS_MASK 0x8000 -#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK \ - | PWRBTN_STS_MASK | SLPBTN_STS_MASK \ - | RTC_STS_MASK | WAK_STS_MASK) +#define ALL_FIXED_STS_BITS (TMR_STS_MASK | BM_STS_MASK | GBL_STS_MASK \ + | PWRBTN_STS_MASK | SLPBTN_STS_MASK \ + | RTC_STS_MASK | WAK_STS_MASK) -#define TMR_EN_MASK 0x0001 -#define GBL_EN_MASK 0x0020 -#define PWRBTN_EN_MASK 0x0100 -#define SLPBTN_EN_MASK 0x0200 -#define RTC_EN_MASK 0x0400 +#define TMR_EN_MASK 0x0001 +#define GBL_EN_MASK 0x0020 +#define PWRBTN_EN_MASK 0x0100 +#define SLPBTN_EN_MASK 0x0200 +#define RTC_EN_MASK 0x0400 -#define SCI_EN_MASK 0x0001 -#define BM_RLD_MASK 0x0002 -#define GBL_RLS_MASK 0x0004 -#define SLP_TYPE_X_MASK 0x1C00 -#define SLP_EN_MASK 0x2000 +#define SCI_EN_MASK 0x0001 +#define BM_RLD_MASK 0x0002 +#define GBL_RLS_MASK 0x0004 +#define SLP_TYPE_X_MASK 0x1C00 +#define SLP_EN_MASK 0x2000 -#define ARB_DIS_MASK 0x0001 -#define TMR_VAL_MASK 0xFFFFFFFF +#define ARB_DIS_MASK 0x0001 +#define TMR_VAL_MASK 0xFFFFFFFF #define GPE0_STS_MASK #define GPE0_EN_MASK @@ -819,8 +821,8 @@ typedef struct acpi_get_devices_info #define GPE1_EN_MASK -#define ACPI_READ 1 -#define ACPI_WRITE 2 +#define ACPI_READ 1 +#define ACPI_WRITE 2 /* Plug and play */ diff --git a/drivers/acpi/include/acmacros.h b/drivers/acpi/include/acmacros.h index 19cfa05913d7..7bed83ddd3a9 100644 --- a/drivers/acpi/include/acmacros.h +++ b/drivers/acpi/include/acmacros.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acmacros.h - C macros for the entire subsystem. - * $Revision: 59 $ + * $Revision: 62 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -30,6 +30,14 @@ * Data manipulation macros */ +#ifndef LODWORD +#define LODWORD(l) ((u32)(UINT64)(l)) +#endif + +#ifndef HIDWORD +#define HIDWORD(l) ((u32)((((UINT64)(l)) >> 32) & 0xFFFFFFFF)) +#endif + #ifndef LOWORD #define LOWORD(l) ((u16)(NATIVE_UINT)(l)) #endif @@ -64,10 +72,18 @@ #ifdef _IA16 +/* + * For 16-bit addresses, we have to assume that the upper 32 bits + * are zero. + */ #define ACPI_GET_ADDRESS(a) ((a).lo) #define ACPI_STORE_ADDRESS(a,b) {(a).hi=0;(a).lo=(b);} -#define ACPI_VALID_ADDRESS(a) ((a).hi && (a).lo) +#define ACPI_VALID_ADDRESS(a) ((a).hi | (a).lo) + #else +/* + * Full 64-bit address on 32-bit and 64-bit platforms + */ #define ACPI_GET_ADDRESS(a) (a) #define ACPI_STORE_ADDRESS(a,b) ((a)=(b)) #define ACPI_VALID_ADDRESS(a) (a) @@ -335,7 +351,7 @@ */ #define return_VOID {function_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name);return;} #define return_ACPI_STATUS(s) {function_status_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,s);return(s);} -#define return_VALUE(s) {function_value_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(NATIVE_UINT)s);return(s);} +#define return_VALUE(s) {function_value_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(ACPI_INTEGER)s);return(s);} #define return_PTR(s) {function_ptr_exit(_THIS_MODULE,__LINE__,_COMPONENT,_proc_name,(u8 *)s);return(s);} @@ -346,6 +362,8 @@ #define DEBUG_DEFINE(a) a; #define DEBUG_ONLY_MEMBERS(a) a; +#define _OPCODE_NAMES +#define _VERBOSE_STRUCTURES /* Stack and buffer dumping */ @@ -458,9 +476,8 @@ */ #ifdef _IA16 #undef DEBUG_ONLY_MEMBERS +#undef _VERBOSE_STRUCTURES #define DEBUG_ONLY_MEMBERS(a) -#undef OP_INFO_ENTRY -#define OP_INFO_ENTRY(flags,name,Pargs,Iargs) {flags,Pargs,Iargs} #endif diff --git a/drivers/acpi/include/acnamesp.h b/drivers/acpi/include/acnamesp.h index e010a811881d..d6acb8444344 100644 --- a/drivers/acpi/include/acnamesp.h +++ b/drivers/acpi/include/acnamesp.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acnamesp.h - Namespace subcomponent prototypes and defines - * $Revision: 100 $ + * $Revision: 101 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acobject.h b/drivers/acpi/include/acobject.h index c801ff117bd9..9394b470a171 100644 --- a/drivers/acpi/include/acobject.h +++ b/drivers/acpi/include/acobject.h @@ -2,12 +2,12 @@ /****************************************************************************** * * Name: acobject.h - Definition of ACPI_OPERAND_OBJECT (Internal object only) - * $Revision: 75 $ + * $Revision: 78 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -113,10 +113,10 @@ typedef struct /* NUMBER - has value */ ACPI_INTEGER value; -} ACPI_OBJECT_NUMBER; +} ACPI_OBJECT_INTEGER; -typedef struct /* STRING - has length and pointer */ +typedef struct /* STRING - has length and pointer - Null terminated, ASCII characters only */ { ACPI_OBJECT_COMMON_HEADER @@ -126,13 +126,11 @@ typedef struct /* STRING - has length and pointer */ } ACPI_OBJECT_STRING; -typedef struct /* BUFFER - has length, sequence, and pointer */ +typedef struct /* BUFFER - has length and pointer - not null terminated */ { ACPI_OBJECT_COMMON_HEADER u32 length; - u32 sequence; /* Sequential count of buffers created */ - u8 *pointer; /* points to the buffer in allocated space */ } ACPI_OBJECT_BUFFER; @@ -398,7 +396,7 @@ typedef union acpi_operand_obj { ACPI_OBJECT_COMMON common; ACPI_OBJECT_CACHE_LIST cache; - ACPI_OBJECT_NUMBER number; + ACPI_OBJECT_INTEGER integer; ACPI_OBJECT_STRING string; ACPI_OBJECT_BUFFER buffer; ACPI_OBJECT_PACKAGE package; diff --git a/drivers/acpi/include/acoutput.h b/drivers/acpi/include/acoutput.h index 664a5f8a81ab..8e79f788cc96 100644 --- a/drivers/acpi/include/acoutput.h +++ b/drivers/acpi/include/acoutput.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acoutput.h -- debug output - * $Revision: 66 $ + * $Revision: 68 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acparser.h b/drivers/acpi/include/acparser.h index d657749da7c1..9b4bfabeae1d 100644 --- a/drivers/acpi/include/acparser.h +++ b/drivers/acpi/include/acparser.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: acparser.h - AML Parser subcomponent prototypes and defines - * $Revision: 47 $ + * $Revision: 49 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acpi.h b/drivers/acpi/include/acpi.h index 4896c4a7f2f9..344b01a774a4 100644 --- a/drivers/acpi/include/acpi.h +++ b/drivers/acpi/include/acpi.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acpi.h - Master include file, Publics and external data. - * $Revision: 48 $ + * $Revision: 50 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acpiosxf.h b/drivers/acpi/include/acpiosxf.h index 2f9eb4c13097..c2b3ed79edcf 100644 --- a/drivers/acpi/include/acpiosxf.h +++ b/drivers/acpi/include/acpiosxf.h @@ -9,7 +9,7 @@ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acpixf.h b/drivers/acpi/include/acpixf.h index d70fa75a78b7..76c7fe26b800 100644 --- a/drivers/acpi/include/acpixf.h +++ b/drivers/acpi/include/acpixf.h @@ -6,7 +6,7 @@ *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/acresrc.h b/drivers/acpi/include/acresrc.h index 3bb19490dccd..0852367d2290 100644 --- a/drivers/acpi/include/acresrc.h +++ b/drivers/acpi/include/acresrc.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: acresrc.h - Resource Manager function prototypes - * $Revision: 20 $ + * $Revision: 22 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/actables.h b/drivers/acpi/include/actables.h index 4dd724517b9c..be8b5e3b0377 100644 --- a/drivers/acpi/include/actables.h +++ b/drivers/acpi/include/actables.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: actables.h - ACPI table management - * $Revision: 27 $ + * $Revision: 29 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/actbl.h b/drivers/acpi/include/actbl.h index 34631e820509..7a41842d27b1 100644 --- a/drivers/acpi/include/actbl.h +++ b/drivers/acpi/include/actbl.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: actbl.h - Table data structures defined in ACPI specification - * $Revision: 43 $ + * $Revision: 45 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/actbl1.h b/drivers/acpi/include/actbl1.h index 019ba168045b..5c68ca050519 100644 --- a/drivers/acpi/include/actbl1.h +++ b/drivers/acpi/include/actbl1.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: actbl1.h - ACPI 1.0 tables - * $Revision: 15 $ + * $Revision: 17 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/actbl2.h b/drivers/acpi/include/actbl2.h index e3ccf218896a..d36555b3f759 100644 --- a/drivers/acpi/include/actbl2.h +++ b/drivers/acpi/include/actbl2.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: actbl2.h - ACPI Specification Revision 2.0 Tables - * $Revision: 19 $ + * $Revision: 21 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/actbl71.h b/drivers/acpi/include/actbl71.h index 408ec402ef47..095806ccb971 100644 --- a/drivers/acpi/include/actbl71.h +++ b/drivers/acpi/include/actbl71.h @@ -3,12 +3,12 @@ * Name: actbl71.h - IA-64 Extensions to the ACPI Spec Rev. 0.71 * This file includes tables specific to this * specification revision. - * $Revision: 7 $ + * $Revision: 9 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/include/actypes.h b/drivers/acpi/include/actypes.h index dfa28a9d9c6b..06cc0f33124a 100644 --- a/drivers/acpi/include/actypes.h +++ b/drivers/acpi/include/actypes.h @@ -1,12 +1,12 @@ /****************************************************************************** * * Name: actypes.h - Common data types for the entire ACPI subsystem - * $Revision: 159 $ + * $Revision: 162 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -97,7 +97,7 @@ typedef INT16 NATIVE_INT; typedef UINT32 ACPI_TBLPTR; typedef UINT32 ACPI_IO_ADDRESS; -typedef void *ACPI_PHYSICAL_ADDRESS; +typedef char *ACPI_PHYSICAL_ADDRESS; #define ALIGNED_ADDRESS_BOUNDARY 0x00000002 #define _HW_ALIGNMENT_SUPPORT @@ -284,8 +284,37 @@ typedef u32 ACPI_TABLE_TYPE; typedef u32 ACPI_OBJECT_TYPE; typedef u8 OBJECT_TYPE_INTERNAL; +#define ACPI_BTYPE_ANY 0x00000000 +#define ACPI_BTYPE_INTEGER 0x00000001 +#define ACPI_BTYPE_STRING 0x00000002 +#define ACPI_BTYPE_BUFFER 0x00000004 +#define ACPI_BTYPE_PACKAGE 0x00000008 +#define ACPI_BTYPE_FIELD_UNIT 0x00000010 +#define ACPI_BTYPE_DEVICE 0x00000020 +#define ACPI_BTYPE_EVENT 0x00000040 +#define ACPI_BTYPE_METHOD 0x00000080 +#define ACPI_BTYPE_MUTEX 0x00000100 +#define ACPI_BTYPE_REGION 0x00000200 +#define ACPI_BTYPE_POWER 0x00000400 +#define ACPI_BTYPE_PROCESSOR 0x00000800 +#define ACPI_BTYPE_THERMAL 0x00001000 +#define ACPI_BTYPE_BUFFER_FIELD 0x00002000 +#define ACPI_BTYPE_DDB_HANDLE 0x00004000 +#define ACPI_BTYPE_DEBUG_OBJECT 0x00008000 +#define ACPI_BTYPE_REFERENCE 0x00010000 +#define ACPI_BTYPE_RESOURCE 0x00020000 + +#define ACPI_BTYPE_COMPUTE_DATA (ACPI_BTYPE_INTEGER | ACPI_BTYPE_STRING | ACPI_BTYPE_BUFFER) + +#define ACPI_BTYPE_DATA (ACPI_BTYPE_COMPUTE_DATA | ACPI_BTYPE_PACKAGE) +#define ACPI_BTYPE_DATA_REFERENCE (ACPI_BTYPE_DATA | ACPI_BTYPE_REFERENCE | ACPI_BTYPE_DDB_HANDLE) +#define ACPI_BTYPE_DEVICE_OBJECTS (ACPI_BTYPE_DEVICE | ACPI_BTYPE_THERMAL | ACPI_BTYPE_PROCESSOR) +#define ACPI_BTYPE_OBJECTS_AND_REFS 0x00017FFF /* ARG or LOCAL */ +#define ACPI_BTYPE_ALL_OBJECTS 0x00007FFF + + #define ACPI_TYPE_ANY 0 /* 0x00 */ -#define ACPI_TYPE_NUMBER 1 /* 0x01 Byte/Word/Dword/Zero/One/Ones */ +#define ACPI_TYPE_INTEGER 1 /* 0x01 Byte/Word/Dword/Zero/One/Ones */ #define ACPI_TYPE_STRING 2 /* 0x02 */ #define ACPI_TYPE_BUFFER 3 /* 0x03 */ #define ACPI_TYPE_PACKAGE 4 /* 0x04 Byte_const, multiple Data_term/Constant/Super_name */ @@ -432,7 +461,7 @@ typedef union acpi_obj { ACPI_OBJECT_TYPE type; ACPI_INTEGER value; /* The actual number */ - } number; + } integer; struct { diff --git a/drivers/acpi/include/amlcode.h b/drivers/acpi/include/amlcode.h index 9a5cb2c52dc9..707e7535d551 100644 --- a/drivers/acpi/include/amlcode.h +++ b/drivers/acpi/include/amlcode.h @@ -3,12 +3,12 @@ * Name: amlcode.h - Definitions for AML, as included in "definition blocks" * Declarations and definitions contained herein are derived * directly from the ACPI specification. - * $Revision: 42 $ + * $Revision: 46 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -211,27 +211,42 @@ #define ARGP_TERMARG 0x0E #define ARGP_TERMLIST 0x0F #define ARGP_WORDDATA 0x10 +#define ARGP_QWORDDATA 0x11 +#define ARGP_SIMPLENAME 0x12 /* * Resolved argument types for the AML Interpreter * Each field in the Arg_types u32 is 5 bits, allowing for a maximum of 6 arguments. - * There can be up to 31 unique argument types + * There can be up to 31 unique argument types (0 is end-of-arg-list indicator) */ -#define ARGI_ANYTYPE 0x01 -#define ARGI_TARGETREF 0x02 -#define ARGI_REFERENCE 0x03 -#define ARGI_IF 0x04 -#define ARGI_NUMBER 0x05 -#define ARGI_STRING 0x06 -#define ARGI_BUFFER 0x07 -#define ARGI_PACKAGE 0x08 -#define ARGI_DATAOBJECT 0x09 /* Buffer, string, package or reference to a Node - Used only by Size_of operator*/ -#define ARGI_COMPLEXOBJ 0x0A /* Buffer or package */ -#define ARGI_MUTEX 0x0B -#define ARGI_EVENT 0x0C -#define ARGI_REGION 0x0D -#define ARGI_DDBHANDLE 0x0E +/* "Standard" ACPI types are 1-15 (0x0F) */ + +#define ARGI_INTEGER ACPI_TYPE_INTEGER /* 1 */ +#define ARGI_STRING ACPI_TYPE_STRING /* 2 */ +#define ARGI_BUFFER ACPI_TYPE_BUFFER /* 3 */ +#define ARGI_PACKAGE ACPI_TYPE_PACKAGE /* 4 */ +#define ARGI_EVENT ACPI_TYPE_EVENT +#define ARGI_MUTEX ACPI_TYPE_MUTEX +#define ARGI_REGION ACPI_TYPE_REGION +#define ARGI_DDBHANDLE ACPI_TYPE_DDB_HANDLE + +/* Custom types are 0x10 through 0x1F */ + +#define ARGI_IF 0x10 +#define ARGI_ANYOBJECT 0x11 +#define ARGI_ANYTYPE 0x12 +#define ARGI_COMPUTEDATA 0x13 /* Buffer, String, or Integer */ +#define ARGI_DATAOBJECT 0x14 /* Buffer, string, package or reference to a Node - Used only by Size_of operator*/ +#define ARGI_COMPLEXOBJ 0x15 /* Buffer or package */ +#define ARGI_INTEGER_REF 0x16 +#define ARGI_OBJECT_REF 0x17 +#define ARGI_DEVICE_REF 0x18 +#define ARGI_REFERENCE 0x19 +#define ARGI_TARGETREF 0x1A /* Target, subject to implicit conversion */ +#define ARGI_FIXED_TARGET 0x1B /* Target, no implicit conversion */ +#define ARGI_SIMPLE_TARGET 0x1C /* Name, Local, Arg -- no implicit conversion */ +#define ARGI_BUFFERSTRING 0x1D #define ARGI_INVALID_OPCODE 0xFFFFFFFF diff --git a/drivers/acpi/interpreter/amconfig.c b/drivers/acpi/interpreter/amconfig.c index 55e5b05106d8..497f35375c0b 100644 --- a/drivers/acpi/interpreter/amconfig.c +++ b/drivers/acpi/interpreter/amconfig.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: amconfig - Namespace reconfiguration (Load/Unload opcodes) - * $Revision: 26 $ + * $Revision: 29 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -73,7 +73,8 @@ acpi_aml_exec_load_table ( table_header.length = 0; for (i = 0; i < sizeof (ACPI_TABLE_HEADER); i++) { status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ, - i, 8, (u32 *) ((u8 *) &table_header + i)); + (ACPI_PHYSICAL_ADDRESS) i, 8, + (u32 *) ((u8 *) &table_header + i)); if (ACPI_FAILURE (status)) { return (status); } @@ -96,7 +97,8 @@ acpi_aml_exec_load_table ( for (i = 0; i < table_header.length; i++) { status = acpi_ev_address_space_dispatch (rgn_desc, ADDRESS_SPACE_READ, - i, 8, (u32 *) (table_data_ptr + i)); + (ACPI_PHYSICAL_ADDRESS)i, 8, + (u32 *) (table_data_ptr + i)); if (ACPI_FAILURE (status)) { goto cleanup; } diff --git a/drivers/acpi/interpreter/amconvrt.c b/drivers/acpi/interpreter/amconvrt.c new file mode 100644 index 000000000000..3519553e8615 --- /dev/null +++ b/drivers/acpi/interpreter/amconvrt.c @@ -0,0 +1,400 @@ +/****************************************************************************** + * + * Module Name: amconvrt - Object conversion routines + * $Revision: 2 $ + * + *****************************************************************************/ + +/* + * Copyright (C) 2000, 2001 R. Byron Moore + * + * 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. 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 + */ + + +#include "acpi.h" +#include "acparser.h" +#include "acnamesp.h" +#include "acinterp.h" +#include "acevents.h" +#include "amlcode.h" +#include "acdispat.h" + + +#define _COMPONENT INTERPRETER + MODULE_NAME ("amconvrt") + + +/******************************************************************************* + * + * FUNCTION: Acpi_aml_convert_to_integer + * + * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * Walk_state - Current method state + * + * RETURN: Status + * + * DESCRIPTION: Convert an ACPI Object to an integer. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_convert_to_integer ( + ACPI_OPERAND_OBJECT **obj_desc, + ACPI_WALK_STATE *walk_state) +{ + u32 i; + ACPI_OPERAND_OBJECT *ret_desc; + u32 count; + char *pointer; + ACPI_INTEGER result; + u32 integer_size = sizeof (ACPI_INTEGER); + + + switch ((*obj_desc)->common.type) + { + case ACPI_TYPE_INTEGER: + return (AE_OK); + + case ACPI_TYPE_STRING: + pointer = (*obj_desc)->string.pointer; + count = (*obj_desc)->string.length; + break; + + case ACPI_TYPE_BUFFER: + pointer = (char *) (*obj_desc)->buffer.pointer; + count = (*obj_desc)->buffer.length; + break; + + default: + return (AE_TYPE); + } + + /* + * Create a new integer + */ + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + + /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + /* + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper 32-bit field + */ + integer_size = sizeof (u32); + } + + + /* + * Convert the buffer/string to an integer. Note that both buffers and + * strings are treated as raw data - we don't convert ascii to hex for + * strings. + * + * There are two terminating conditions for the loop: + * 1) The size of an integer has been reached, or + * 2) The end of the buffer or string has been reached + */ + result = 0; + + /* Transfer no more than an integer's worth of data */ + + if (count > integer_size) { + count = integer_size; + } + + /* + * String conversion is different than Buffer conversion + */ + switch ((*obj_desc)->common.type) + { + case ACPI_TYPE_STRING: + + /* TBD: Need to use 64-bit STRTOUL */ + + /* + * Convert string to an integer + * String must be hexadecimal as per the ACPI specification + */ + + result = STRTOUL (pointer, NULL, 16); + break; + + + case ACPI_TYPE_BUFFER: + + /* + * Buffer conversion - we simply grab enough raw data from the + * buffer to fill an integer + */ + for (i = 0; i < count; i++) { + /* + * Get next byte and shift it into the Result. + * Little endian is used, meaning that the first byte of the buffer + * is the LSB of the integer + */ + result |= (((ACPI_INTEGER) pointer[i]) << (i * 8)); + } + + break; + } + + /* Save the Result, delete original descriptor, store new descriptor */ + + ret_desc->integer.value = result; + acpi_cm_remove_reference (*obj_desc); + *obj_desc = ret_desc; + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_aml_convert_to_buffer + * + * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * Walk_state - Current method state + * + * RETURN: Status + * + * DESCRIPTION: Convert an ACPI Object to an Buffer + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_convert_to_buffer ( + ACPI_OPERAND_OBJECT **obj_desc, + ACPI_WALK_STATE *walk_state) +{ + ACPI_OPERAND_OBJECT *ret_desc; + u32 i; + u32 integer_size = sizeof (ACPI_INTEGER); + u8 *new_buf; + + + switch ((*obj_desc)->common.type) + { + case ACPI_TYPE_INTEGER: + + /* + * Create a new Buffer + */ + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + /* + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper + * 32-bit field + */ + integer_size = sizeof (u32); + } + + /* Need enough space for one integers */ + + ret_desc->buffer.length = integer_size; + new_buf = acpi_cm_callocate (integer_size); + if (!new_buf) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); + acpi_cm_remove_reference (ret_desc); + return (AE_NO_MEMORY); + } + + /* Copy the integer to the buffer */ + + for (i = 0; i < integer_size; i++) { + new_buf[i] = (u8) ((*obj_desc)->integer.value >> (i * 8)); + } + ret_desc->buffer.pointer = new_buf; + + /* Return the new buffer descriptor */ + + acpi_cm_remove_reference (*obj_desc); + *obj_desc = ret_desc; + break; + + + case ACPI_TYPE_STRING: + break; + + + case ACPI_TYPE_BUFFER: + break; + + + default: + return (AE_TYPE); + break; + } + + return (AE_OK); +} + + +/******************************************************************************* + * + * FUNCTION: Acpi_aml_convert_to_string + * + * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * Walk_state - Current method state + * + * RETURN: Status + * + * DESCRIPTION: Convert an ACPI Object to a string + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_convert_to_string ( + ACPI_OPERAND_OBJECT **obj_desc, + ACPI_WALK_STATE *walk_state) +{ + ACPI_OPERAND_OBJECT *ret_desc; + u32 i; + u32 index; + u32 integer_size = sizeof (ACPI_INTEGER); + u8 *new_buf; + u8 *pointer; + + + switch ((*obj_desc)->common.type) + { + case ACPI_TYPE_INTEGER: + + /* + * Create a new String + */ + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + /* + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper + * 32-bit field + */ + integer_size = sizeof (u32); + } + + /* Need enough space for one ASCII integer plus null terminator */ + + ret_desc->string.length = (integer_size * 2) + 1; + new_buf = acpi_cm_callocate (ret_desc->string.length); + if (!new_buf) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); + acpi_cm_remove_reference (ret_desc); + return (AE_NO_MEMORY); + } + + /* Copy the integer to the buffer */ + + for (i = 0; i < (integer_size * 2); i++) { + new_buf[i] = acpi_gbl_hex_to_ascii [((*obj_desc)->integer.value >> (i * 4)) & 0xF]; + } + + /* Null terminate */ + + new_buf [i] = 0; + ret_desc->buffer.pointer = new_buf; + + /* Return the new buffer descriptor */ + + acpi_cm_remove_reference (*obj_desc); + *obj_desc = ret_desc; + + return (AE_OK); + + + case ACPI_TYPE_BUFFER: + + if (((*obj_desc)->buffer.length * 3) > ACPI_MAX_STRING_CONVERSION) { + return (AE_AML_STRING_LIMIT); + } + + /* + * Create a new String + */ + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + /* Need enough space for one ASCII integer plus null terminator */ + + ret_desc->string.length = (*obj_desc)->buffer.length * 3; + new_buf = acpi_cm_callocate (ret_desc->string.length + 1); + if (!new_buf) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); + acpi_cm_remove_reference (ret_desc); + return (AE_NO_MEMORY); + } + + /* + * Convert each byte of the buffer to two ASCII characters plus a space. + */ + pointer = (*obj_desc)->buffer.pointer; + index = 0; + for (i = 0; i < (*obj_desc)->buffer.length; i++) { + new_buf[index + 0] = acpi_gbl_hex_to_ascii [pointer[i] & 0x0F]; + new_buf[index + 1] = acpi_gbl_hex_to_ascii [(pointer[i] >> 4) & 0x0F]; + new_buf[index + 2] = ' '; + index += 3; + } + + /* Null terminate */ + + new_buf [index] = 0; + ret_desc->buffer.pointer = new_buf; + + /* Return the new buffer descriptor */ + + acpi_cm_remove_reference (*obj_desc); + *obj_desc = ret_desc; + break; + + + case ACPI_TYPE_STRING: + break; + + + default: + return (AE_TYPE); + break; + } + + return (AE_OK); +} + + diff --git a/drivers/acpi/interpreter/amcreate.c b/drivers/acpi/interpreter/amcreate.c index 02d7933e1d37..f19c422ce841 100644 --- a/drivers/acpi/interpreter/amcreate.c +++ b/drivers/acpi/interpreter/amcreate.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: amcreate - Named object creation - * $Revision: 51 $ + * $Revision: 53 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -353,7 +353,7 @@ acpi_aml_exec_create_mutex ( goto cleanup; } - obj_desc->mutex.sync_level = (u8) sync_desc->number.value; + obj_desc->mutex.sync_level = (u8) sync_desc->integer.value; /* Obj_desc was on the stack top, and the name is below it */ diff --git a/drivers/acpi/interpreter/amdyadic.c b/drivers/acpi/interpreter/amdyadic.c index ba67b062aa79..a02173f293f1 100644 --- a/drivers/acpi/interpreter/amdyadic.c +++ b/drivers/acpi/interpreter/amdyadic.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: amdyadic - ACPI AML (p-code) execution for dyadic operators - * $Revision: 68 $ + * $Revision: 71 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -37,7 +37,174 @@ MODULE_NAME ("amdyadic") -/***************************************************************************** +/******************************************************************************* + * + * FUNCTION: Acpi_aml_do_concatenate + * + * PARAMETERS: *Obj_desc - Object to be converted. Must be an + * Integer, Buffer, or String + * + * RETURN: Status + * + * DESCRIPTION: Concatenate two objects OF THE SAME TYPE. + * + ******************************************************************************/ + +ACPI_STATUS +acpi_aml_do_concatenate ( + ACPI_OPERAND_OBJECT *obj_desc, + ACPI_OPERAND_OBJECT *obj_desc2, + ACPI_OPERAND_OBJECT **actual_ret_desc, + ACPI_WALK_STATE *walk_state) +{ + ACPI_STATUS status; + u32 i; + ACPI_INTEGER this_integer; + ACPI_OPERAND_OBJECT *ret_desc; + NATIVE_CHAR *new_buf; + u32 integer_size = sizeof (ACPI_INTEGER); + + + /* + * There are three cases to handle: + * 1) Two Integers concatenated to produce a buffer + * 2) Two Strings concatenated to produce a string + * 3) Two Buffers concatenated to produce a buffer + */ + switch (obj_desc->common.type) + { + case ACPI_TYPE_INTEGER: + + /* Handle both ACPI 1.0 and ACPI 2.0 Integer widths */ + + if (walk_state->method_node->flags & ANOBJ_DATA_WIDTH_32) { + /* + * We are running a method that exists in a 32-bit ACPI table. + * Truncate the value to 32 bits by zeroing out the upper + * 32-bit field + */ + integer_size = sizeof (u32); + } + + /* Result of two integers is a buffer */ + + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + /* Need enough space for two integers */ + + ret_desc->buffer.length = integer_size * 2; + new_buf = acpi_cm_callocate (ret_desc->buffer.length); + if (!new_buf) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); + status = AE_NO_MEMORY; + goto cleanup; + } + + ret_desc->buffer.pointer = (u8 *) new_buf; + + /* Convert the first integer */ + + this_integer = obj_desc->integer.value; + for (i = 0; i < integer_size; i++) { + new_buf[i] = (u8) this_integer; + this_integer >>= 8; + } + + /* Convert the second integer */ + + this_integer = obj_desc2->integer.value; + for (; i < (integer_size * 2); i++) { + new_buf[i] = (u8) this_integer; + this_integer >>= 8; + } + + break; + + + case ACPI_TYPE_STRING: + + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + /* Operand1 is string */ + + new_buf = acpi_cm_allocate (obj_desc->string.length + + obj_desc2->string.length + 1); + if (!new_buf) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Concat_op: String allocation failure\n")); + status = AE_NO_MEMORY; + goto cleanup; + } + + STRCPY (new_buf, obj_desc->string.pointer); + STRCPY (new_buf + obj_desc->string.length, + obj_desc2->string.pointer); + + /* Point the return object to the new string */ + + ret_desc->string.pointer = new_buf; + ret_desc->string.length = obj_desc->string.length += + obj_desc2->string.length; + break; + + + case ACPI_TYPE_BUFFER: + + /* Operand1 is a buffer */ + + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER); + if (!ret_desc) { + return (AE_NO_MEMORY); + } + + new_buf = acpi_cm_allocate (obj_desc->buffer.length + + obj_desc2->buffer.length); + if (!new_buf) { + REPORT_ERROR + (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); + status = AE_NO_MEMORY; + goto cleanup; + } + + MEMCPY (new_buf, obj_desc->buffer.pointer, + obj_desc->buffer.length); + MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer, + obj_desc2->buffer.length); + + /* + * Point the return object to the new buffer + */ + + ret_desc->buffer.pointer = (u8 *) new_buf; + ret_desc->buffer.length = obj_desc->buffer.length + + obj_desc2->buffer.length; + break; + + default: + status = AE_AML_INTERNAL; + ret_desc = NULL; + } + + + *actual_ret_desc = ret_desc; + return (AE_OK); + + +cleanup: + + acpi_cm_remove_reference (ret_desc); + return (status); +} + + +/******************************************************************************* * * FUNCTION: Acpi_aml_exec_dyadic1 * @@ -50,7 +217,7 @@ * * ALLOCATION: Deletes both operands * - ****************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_aml_exec_dyadic1 ( @@ -106,7 +273,7 @@ acpi_aml_exec_dyadic1 ( /* Dispatch the notify to the appropriate handler */ - acpi_ev_notify_dispatch (node, (u32) val_desc->number.value); + acpi_ev_notify_dispatch (node, (u32) val_desc->integer.value); break; default: @@ -135,7 +302,7 @@ cleanup: } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_aml_exec_dyadic2_r * @@ -148,7 +315,7 @@ cleanup: * * ALLOCATION: Deletes one operand descriptor -- other remains on stack * - ****************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_aml_exec_dyadic2_r ( @@ -164,7 +331,6 @@ acpi_aml_exec_dyadic2_r ( ACPI_OPERAND_OBJECT *ret_desc2 = NULL; ACPI_STATUS status = AE_OK; u32 num_operands = 3; - NATIVE_CHAR *new_buf; /* Resolve all operands */ @@ -201,7 +367,7 @@ acpi_aml_exec_dyadic2_r ( case AML_SHIFT_RIGHT_OP: case AML_SUBTRACT_OP: - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -222,8 +388,8 @@ acpi_aml_exec_dyadic2_r ( case AML_ADD_OP: - ret_desc->number.value = obj_desc->number.value + - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value + + obj_desc2->integer.value; break; @@ -231,8 +397,8 @@ acpi_aml_exec_dyadic2_r ( case AML_BIT_AND_OP: - ret_desc->number.value = obj_desc->number.value & - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value & + obj_desc2->integer.value; break; @@ -240,8 +406,8 @@ acpi_aml_exec_dyadic2_r ( case AML_BIT_NAND_OP: - ret_desc->number.value = ~(obj_desc->number.value & - obj_desc2->number.value); + ret_desc->integer.value = ~(obj_desc->integer.value & + obj_desc2->integer.value); break; @@ -249,8 +415,8 @@ acpi_aml_exec_dyadic2_r ( case AML_BIT_OR_OP: - ret_desc->number.value = obj_desc->number.value | - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value | + obj_desc2->integer.value; break; @@ -258,8 +424,8 @@ acpi_aml_exec_dyadic2_r ( case AML_BIT_NOR_OP: - ret_desc->number.value = ~(obj_desc->number.value | - obj_desc2->number.value); + ret_desc->integer.value = ~(obj_desc->integer.value | + obj_desc2->integer.value); break; @@ -267,16 +433,16 @@ acpi_aml_exec_dyadic2_r ( case AML_BIT_XOR_OP: - ret_desc->number.value = obj_desc->number.value ^ - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value ^ + obj_desc2->integer.value; break; - /* Def_divide := Divide_op Dividend Divisor Remainder Quotient */ + /* Def_divide := Divide_op Dividend Divisor Remainder Quotient */ case AML_DIVIDE_OP: - if (!obj_desc2->number.value) { + if (!obj_desc2->integer.value) { REPORT_ERROR (("Aml_exec_dyadic2_r/Divide_op: Divide by zero\n")); @@ -284,7 +450,7 @@ acpi_aml_exec_dyadic2_r ( goto cleanup; } - ret_desc2 = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc2 = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc2) { status = AE_NO_MEMORY; goto cleanup; @@ -292,13 +458,13 @@ acpi_aml_exec_dyadic2_r ( /* Remainder (modulo) */ - ret_desc->number.value = ACPI_MODULO (obj_desc->number.value, - obj_desc2->number.value); + ret_desc->integer.value = ACPI_MODULO (obj_desc->integer.value, + obj_desc2->integer.value); /* Result (what we used to call the quotient) */ - ret_desc2->number.value = ACPI_DIVIDE (obj_desc->number.value, - obj_desc2->number.value); + ret_desc2->integer.value = ACPI_DIVIDE (obj_desc->integer.value, + obj_desc2->integer.value); break; @@ -306,8 +472,8 @@ acpi_aml_exec_dyadic2_r ( case AML_MULTIPLY_OP: - ret_desc->number.value = obj_desc->number.value * - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value * + obj_desc2->integer.value; break; @@ -315,8 +481,8 @@ acpi_aml_exec_dyadic2_r ( case AML_SHIFT_LEFT_OP: - ret_desc->number.value = obj_desc->number.value << - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value << + obj_desc2->integer.value; break; @@ -324,8 +490,8 @@ acpi_aml_exec_dyadic2_r ( case AML_SHIFT_RIGHT_OP: - ret_desc->number.value = obj_desc->number.value >> - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value >> + obj_desc2->integer.value; break; @@ -333,8 +499,8 @@ acpi_aml_exec_dyadic2_r ( case AML_SUBTRACT_OP: - ret_desc->number.value = obj_desc->number.value - - obj_desc2->number.value; + ret_desc->integer.value = obj_desc->integer.value - + obj_desc2->integer.value; break; @@ -342,79 +508,54 @@ acpi_aml_exec_dyadic2_r ( case AML_CONCAT_OP: - if (obj_desc2->common.type != obj_desc->common.type) { - status = AE_AML_OPERAND_TYPE; - goto cleanup; - } - /* Both operands are now known to be the same */ - - if (ACPI_TYPE_STRING == obj_desc->common.type) { - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_STRING); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } + /* + * Convert the second operand if necessary. The first operand + * determines the type of the second operand, (See the Data Types + * section of the ACPI specification.) Both object types are + * guaranteed to be either Integer/String/Buffer by the operand + * resolution mechanism above. + */ - /* Operand1 is string */ + switch (obj_desc->common.type) + { + case ACPI_TYPE_INTEGER: + status = acpi_aml_convert_to_integer (&obj_desc2, walk_state); + break; - new_buf = acpi_cm_allocate (obj_desc->string.length + - obj_desc2->string.length + 1); - if (!new_buf) { - REPORT_ERROR - (("Aml_exec_dyadic2_r/Concat_op: String allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } + case ACPI_TYPE_STRING: + status = acpi_aml_convert_to_string (&obj_desc2, walk_state); + break; - STRCPY (new_buf, obj_desc->string.pointer); - STRCPY (new_buf + obj_desc->string.length, - obj_desc2->string.pointer); + case ACPI_TYPE_BUFFER: + status = acpi_aml_convert_to_buffer (&obj_desc2, walk_state); + break; - /* Point the return object to the new string */ - - ret_desc->string.pointer = new_buf; - ret_desc->string.length = obj_desc->string.length += - obj_desc2->string.length; + default: + status = AE_AML_INTERNAL; } - else { - /* Operand1 is not a string ==> must be a buffer */ - - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_BUFFER); - if (!ret_desc) { - status = AE_NO_MEMORY; - goto cleanup; - } - - new_buf = acpi_cm_allocate (obj_desc->buffer.length + - obj_desc2->buffer.length); - if (!new_buf) { - REPORT_ERROR - (("Aml_exec_dyadic2_r/Concat_op: Buffer allocation failure\n")); - status = AE_NO_MEMORY; - goto cleanup; - } - - MEMCPY (new_buf, obj_desc->buffer.pointer, - obj_desc->buffer.length); - MEMCPY (new_buf + obj_desc->buffer.length, obj_desc2->buffer.pointer, - obj_desc2->buffer.length); + if (ACPI_FAILURE (status)) { + goto cleanup; + } - /* - * Point the return object to the new buffer - */ - ret_desc->buffer.pointer = (u8 *) new_buf; - ret_desc->buffer.length = obj_desc->buffer.length + - obj_desc2->buffer.length; + /* + * Both operands are now known to be the same object type + * (Both are Integer, String, or Buffer), and we can now perform the + * concatenation. + */ + status = acpi_aml_do_concatenate (obj_desc, obj_desc2, &ret_desc, walk_state); + if (ACPI_FAILURE (status)) { + goto cleanup; } break; default: - REPORT_ERROR (("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode %X\n", opcode)); + REPORT_ERROR (("Acpi_aml_exec_dyadic2_r: Unknown dyadic opcode %X\n", + opcode)); status = AE_AML_BAD_OPCODE; goto cleanup; } @@ -474,7 +615,7 @@ cleanup: } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_aml_exec_dyadic2_s * @@ -486,7 +627,7 @@ cleanup: * * ALLOCATION: Deletes one operand descriptor -- other remains on stack * - ****************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_aml_exec_dyadic2_s ( @@ -516,7 +657,7 @@ acpi_aml_exec_dyadic2_s ( /* Create the internal return object */ - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -524,7 +665,7 @@ acpi_aml_exec_dyadic2_s ( /* Default return value is FALSE, operation did not time out */ - ret_desc->number.value = 0; + ret_desc->integer.value = 0; /* Examine the opcode */ @@ -562,7 +703,7 @@ acpi_aml_exec_dyadic2_s ( */ if (status == AE_TIME) { - ret_desc->number.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */ + ret_desc->integer.value = ACPI_INTEGER_MAX; /* TRUE, op timed out */ status = AE_OK; } @@ -591,7 +732,7 @@ cleanup: } -/***************************************************************************** +/******************************************************************************* * * FUNCTION: Acpi_aml_exec_dyadic2 * @@ -605,7 +746,7 @@ cleanup: * ALLOCATION: Deletes one operand descriptor -- other remains on stack * containing result value * - ****************************************************************************/ + ******************************************************************************/ ACPI_STATUS acpi_aml_exec_dyadic2 ( @@ -636,7 +777,7 @@ acpi_aml_exec_dyadic2 ( /* Create the internal return object */ - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -654,8 +795,8 @@ acpi_aml_exec_dyadic2 ( case AML_LAND_OP: - lboolean = (u8) (obj_desc->number.value && - obj_desc2->number.value); + lboolean = (u8) (obj_desc->integer.value && + obj_desc2->integer.value); break; @@ -663,8 +804,8 @@ acpi_aml_exec_dyadic2 ( case AML_LEQUAL_OP: - lboolean = (u8) (obj_desc->number.value == - obj_desc2->number.value); + lboolean = (u8) (obj_desc->integer.value == + obj_desc2->integer.value); break; @@ -672,8 +813,8 @@ acpi_aml_exec_dyadic2 ( case AML_LGREATER_OP: - lboolean = (u8) (obj_desc->number.value > - obj_desc2->number.value); + lboolean = (u8) (obj_desc->integer.value > + obj_desc2->integer.value); break; @@ -681,8 +822,8 @@ acpi_aml_exec_dyadic2 ( case AML_LLESS_OP: - lboolean = (u8) (obj_desc->number.value < - obj_desc2->number.value); + lboolean = (u8) (obj_desc->integer.value < + obj_desc2->integer.value); break; @@ -690,8 +831,8 @@ acpi_aml_exec_dyadic2 ( case AML_LOR_OP: - lboolean = (u8) (obj_desc->number.value || - obj_desc2->number.value); + lboolean = (u8) (obj_desc->integer.value || + obj_desc2->integer.value); break; @@ -707,10 +848,10 @@ acpi_aml_exec_dyadic2 ( /* Set return value to logical TRUE (all ones) or FALSE (zero) */ if (lboolean) { - ret_desc->number.value = ACPI_INTEGER_MAX; + ret_desc->integer.value = ACPI_INTEGER_MAX; } else { - ret_desc->number.value = 0; + ret_desc->integer.value = 0; } diff --git a/drivers/acpi/interpreter/amfield.c b/drivers/acpi/interpreter/amfield.c index 356be14c230b..b722d8107204 100644 --- a/drivers/acpi/interpreter/amfield.c +++ b/drivers/acpi/interpreter/amfield.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: amfield - ACPI AML (p-code) execution - field manipulation - * $Revision: 74 $ + * $Revision: 76 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/interpreter/amfldio.c b/drivers/acpi/interpreter/amfldio.c index ce877c982829..535be8c45fb6 100644 --- a/drivers/acpi/interpreter/amfldio.c +++ b/drivers/acpi/interpreter/amfldio.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: amfldio - Aml Field I/O - * $Revision: 32 $ + * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -132,7 +132,7 @@ acpi_aml_read_field ( u32 this_field_byte_offset; u32 this_field_datum_offset; u32 previous_raw_datum; - u32 this_raw_datum; + u32 this_raw_datum = 0; u32 valid_field_bits; u32 mask; u32 merged_datum = 0; @@ -203,32 +203,46 @@ acpi_aml_read_field ( while (this_field_datum_offset < datum_length) { /* - * Get the next raw datum, it contains bits of the current - * field datum + * If the field is aligned on a byte boundary, we don't want + * to perform a final read, since this would potentially read + * past the end of the region. + * + * TBD: [Investigate] It may make more sense to just split the aligned + * and non-aligned cases since the aligned case is so very simple, */ - - status = acpi_aml_read_field_data (obj_desc, - this_field_byte_offset + byte_granularity, - bit_granularity, &this_raw_datum); - if (ACPI_FAILURE (status)) { - goto cleanup; - } - - /* Before merging the data, make sure the unused bits are clear */ - - switch (byte_granularity) + if ((obj_desc->field.bit_offset != 0) || + ((obj_desc->field.bit_offset == 0) && + (this_field_datum_offset < (datum_length -1)))) { - case 1: - this_raw_datum &= 0x000000FF; - previous_raw_datum &= 0x000000FF; - break; - - case 2: - this_raw_datum &= 0x0000FFFF; - previous_raw_datum &= 0x0000FFFF; - break; + /* + * Get the next raw datum, it contains some or all bits + * of the current field datum + */ + + status = acpi_aml_read_field_data (obj_desc, + this_field_byte_offset + byte_granularity, + bit_granularity, &this_raw_datum); + if (ACPI_FAILURE (status)) { + goto cleanup; + } + + /* Before merging the data, make sure the unused bits are clear */ + + switch (byte_granularity) + { + case 1: + this_raw_datum &= 0x000000FF; + previous_raw_datum &= 0x000000FF; + break; + + case 2: + this_raw_datum &= 0x0000FFFF; + previous_raw_datum &= 0x0000FFFF; + break; + } } + /* * Put together bits of the two raw data to make a complete * field datum diff --git a/drivers/acpi/interpreter/ammisc.c b/drivers/acpi/interpreter/ammisc.c index 907169dfcb9a..3c58daeab32f 100644 --- a/drivers/acpi/interpreter/ammisc.c +++ b/drivers/acpi/interpreter/ammisc.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: ammisc - ACPI AML (p-code) execution - specific opcodes - * $Revision: 71 $ + * $Revision: 73 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -172,7 +172,7 @@ acpi_aml_exec_index ( if (obj_desc->common.type == ACPI_TYPE_PACKAGE) { /* Object to be indexed is a Package */ - if (idx_desc->number.value >= obj_desc->package.count) { + if (idx_desc->integer.value >= obj_desc->package.count) { status = AE_AML_PACKAGE_LIMIT; goto cleanup; } @@ -195,7 +195,7 @@ acpi_aml_exec_index ( * we are after. */ - tmp_desc = obj_desc->package.elements[idx_desc->number.value]; + tmp_desc = obj_desc->package.elements[idx_desc->integer.value]; ret_desc->reference.op_code = AML_INDEX_OP; ret_desc->reference.target_type = tmp_desc->common.type; ret_desc->reference.object = tmp_desc; @@ -210,13 +210,13 @@ acpi_aml_exec_index ( */ ret_desc->reference.op_code = AML_INDEX_OP; ret_desc->reference.target_type = ACPI_TYPE_PACKAGE; - ret_desc->reference.where = &obj_desc->package.elements[idx_desc->number.value]; + ret_desc->reference.where = &obj_desc->package.elements[idx_desc->integer.value]; } else { /* Object to be indexed is a Buffer */ - if (idx_desc->number.value >= obj_desc->buffer.length) { + if (idx_desc->integer.value >= obj_desc->buffer.length) { status = AE_AML_BUFFER_LIMIT; goto cleanup; } @@ -224,7 +224,7 @@ acpi_aml_exec_index ( ret_desc->reference.op_code = AML_INDEX_OP; ret_desc->reference.target_type = ACPI_TYPE_BUFFER_FIELD; ret_desc->reference.object = obj_desc; - ret_desc->reference.offset = (u32) idx_desc->number.value; + ret_desc->reference.offset = (u32) idx_desc->integer.value; status = acpi_aml_exec_store (ret_desc, res_desc, walk_state); } @@ -314,20 +314,20 @@ acpi_aml_exec_match ( /* Validate match comparison sub-opcodes */ - if ((op1_desc->number.value > MAX_MATCH_OPERATOR) || - (op2_desc->number.value > MAX_MATCH_OPERATOR)) + if ((op1_desc->integer.value > MAX_MATCH_OPERATOR) || + (op2_desc->integer.value > MAX_MATCH_OPERATOR)) { status = AE_AML_OPERAND_VALUE; goto cleanup; } - index = (u32) start_desc->number.value; + index = (u32) start_desc->integer.value; if (index >= (u32) pkg_desc->package.count) { status = AE_AML_PACKAGE_LIMIT; goto cleanup; } - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -351,7 +351,7 @@ acpi_aml_exec_match ( * should we examine its value? */ if (!pkg_desc->package.elements[index] || - ACPI_TYPE_NUMBER != pkg_desc->package.elements[index]->common.type) + ACPI_TYPE_INTEGER != pkg_desc->package.elements[index]->common.type) { continue; } @@ -362,7 +362,7 @@ acpi_aml_exec_match ( * "continue" (proceed to next iteration of enclosing * "for" loop) signifies a non-match. */ - switch (op1_desc->number.value) + switch (op1_desc->integer.value) { case MATCH_MTR: /* always true */ @@ -372,8 +372,8 @@ acpi_aml_exec_match ( case MATCH_MEQ: /* true if equal */ - if (pkg_desc->package.elements[index]->number.value - != V1_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + != V1_desc->integer.value) { continue; } @@ -382,8 +382,8 @@ acpi_aml_exec_match ( case MATCH_MLE: /* true if less than or equal */ - if (pkg_desc->package.elements[index]->number.value - > V1_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + > V1_desc->integer.value) { continue; } @@ -392,8 +392,8 @@ acpi_aml_exec_match ( case MATCH_MLT: /* true if less than */ - if (pkg_desc->package.elements[index]->number.value - >= V1_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + >= V1_desc->integer.value) { continue; } @@ -402,8 +402,8 @@ acpi_aml_exec_match ( case MATCH_MGE: /* true if greater than or equal */ - if (pkg_desc->package.elements[index]->number.value - < V1_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + < V1_desc->integer.value) { continue; } @@ -412,8 +412,8 @@ acpi_aml_exec_match ( case MATCH_MGT: /* true if greater than */ - if (pkg_desc->package.elements[index]->number.value - <= V1_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + <= V1_desc->integer.value) { continue; } @@ -426,7 +426,7 @@ acpi_aml_exec_match ( } - switch(op2_desc->number.value) + switch(op2_desc->integer.value) { case MATCH_MTR: @@ -436,8 +436,8 @@ acpi_aml_exec_match ( case MATCH_MEQ: - if (pkg_desc->package.elements[index]->number.value - != V2_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + != V2_desc->integer.value) { continue; } @@ -446,8 +446,8 @@ acpi_aml_exec_match ( case MATCH_MLE: - if (pkg_desc->package.elements[index]->number.value - > V2_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + > V2_desc->integer.value) { continue; } @@ -456,8 +456,8 @@ acpi_aml_exec_match ( case MATCH_MLT: - if (pkg_desc->package.elements[index]->number.value - >= V2_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + >= V2_desc->integer.value) { continue; } @@ -466,8 +466,8 @@ acpi_aml_exec_match ( case MATCH_MGE: - if (pkg_desc->package.elements[index]->number.value - < V2_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + < V2_desc->integer.value) { continue; } @@ -476,8 +476,8 @@ acpi_aml_exec_match ( case MATCH_MGT: - if (pkg_desc->package.elements[index]->number.value - <= V2_desc->number.value) + if (pkg_desc->package.elements[index]->integer.value + <= V2_desc->integer.value) { continue; } @@ -497,7 +497,7 @@ acpi_aml_exec_match ( /* Match_value is the return value */ - ret_desc->number.value = match_value; + ret_desc->integer.value = match_value; cleanup: diff --git a/drivers/acpi/interpreter/ammonad.c b/drivers/acpi/interpreter/ammonad.c index df9671c0674e..ea8834a5c7db 100644 --- a/drivers/acpi/interpreter/ammonad.c +++ b/drivers/acpi/interpreter/ammonad.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: ammonad - ACPI AML (p-code) execution for monadic operators - * $Revision: 88 $ + * $Revision: 89 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -180,7 +180,7 @@ acpi_aml_exec_monadic1 ( case AML_SLEEP_OP: - acpi_aml_system_do_suspend ((u32) obj_desc->number.value); + acpi_aml_system_do_suspend ((u32) obj_desc->integer.value); break; @@ -188,7 +188,7 @@ acpi_aml_exec_monadic1 ( case AML_STALL_OP: - acpi_aml_system_do_stall ((u32) obj_desc->number.value); + acpi_aml_system_do_stall ((u32) obj_desc->integer.value); break; @@ -267,7 +267,7 @@ acpi_aml_exec_monadic2_r ( case AML_TO_BCD_OP: case AML_COND_REF_OF_OP: - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; @@ -283,7 +283,7 @@ acpi_aml_exec_monadic2_r ( case AML_BIT_NOT_OP: - ret_desc->number.value = ~obj_desc->number.value; + ret_desc->integer.value = ~obj_desc->integer.value; break; @@ -291,17 +291,17 @@ acpi_aml_exec_monadic2_r ( case AML_FIND_SET_LEFT_BIT_OP: - ret_desc->number.value = obj_desc->number.value; + ret_desc->integer.value = obj_desc->integer.value; /* * Acpi specification describes Integer type as a little * endian unsigned value, so this boundry condition is valid. */ - for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { - ret_desc->number.value >>= 1; + for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { + ret_desc->integer.value >>= 1; } - ret_desc->number.value = res_val; + ret_desc->integer.value = res_val; break; @@ -309,19 +309,19 @@ acpi_aml_exec_monadic2_r ( case AML_FIND_SET_RIGHT_BIT_OP: - ret_desc->number.value = obj_desc->number.value; + ret_desc->integer.value = obj_desc->integer.value; /* * Acpi specification describes Integer type as a little * endian unsigned value, so this boundry condition is valid. */ - for (res_val = 0; ret_desc->number.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { - ret_desc->number.value <<= 1; + for (res_val = 0; ret_desc->integer.value && res_val < ACPI_INTEGER_BIT_SIZE; ++res_val) { + ret_desc->integer.value <<= 1; } /* Since returns must be 1-based, subtract from 33 (65) */ - ret_desc->number.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val; + ret_desc->integer.value = res_val == 0 ? 0 : (ACPI_INTEGER_BIT_SIZE + 1) - res_val; break; @@ -332,11 +332,11 @@ acpi_aml_exec_monadic2_r ( /* * The 64-bit ACPI integer can hold 16 4-bit BCD integers */ - ret_desc->number.value = 0; + ret_desc->integer.value = 0; for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { /* Get one BCD digit */ - digit = (ACPI_INTEGER) ((obj_desc->number.value >> (i * 4)) & 0xF); + digit = (ACPI_INTEGER) ((obj_desc->integer.value >> (i * 4)) & 0xF); /* Check the range of the digit */ @@ -352,7 +352,7 @@ acpi_aml_exec_monadic2_r ( digit *= 10; } - ret_desc->number.value += digit; + ret_desc->integer.value += digit; } } break; @@ -363,16 +363,16 @@ acpi_aml_exec_monadic2_r ( case AML_TO_BCD_OP: - if (obj_desc->number.value > ACPI_MAX_BCD_VALUE) { + if (obj_desc->integer.value > ACPI_MAX_BCD_VALUE) { status = AE_AML_NUMERIC_OVERFLOW; goto cleanup; } - ret_desc->number.value = 0; + ret_desc->integer.value = 0; for (i = 0; i < ACPI_MAX_BCD_DIGITS; i++) { /* Divide by nth factor of 10 */ - digit = obj_desc->number.value; + digit = obj_desc->integer.value; for (j = 0; j < i; j++) { digit /= 10; } @@ -380,7 +380,7 @@ acpi_aml_exec_monadic2_r ( /* Create the BCD digit */ if (digit > 0) { - ret_desc->number.value += (ACPI_MODULO (digit, 10) << (i * 4)); + ret_desc->integer.value += (ACPI_MODULO (digit, 10) << (i * 4)); } } break; @@ -402,7 +402,7 @@ acpi_aml_exec_monadic2_r ( * return FALSE */ - ret_desc->number.value = 0; + ret_desc->integer.value = 0; /* * Must delete the result descriptor since there is no reference @@ -424,7 +424,7 @@ acpi_aml_exec_monadic2_r ( /* The object exists in the namespace, return TRUE */ - ret_desc->number.value = ACPI_INTEGER_MAX; + ret_desc->integer.value = ACPI_INTEGER_MAX; goto cleanup; break; @@ -579,13 +579,13 @@ acpi_aml_exec_monadic2 ( case AML_LNOT_OP: - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; } - ret_desc->number.value = !obj_desc->number.value; + ret_desc->integer.value = !obj_desc->integer.value; break; @@ -638,10 +638,10 @@ acpi_aml_exec_monadic2 ( /* Do the actual increment or decrement */ if (AML_INCREMENT_OP == opcode) { - ret_desc->number.value++; + ret_desc->integer.value++; } else { - ret_desc->number.value--; + ret_desc->integer.value--; } /* Store the result back in the original descriptor */ @@ -672,7 +672,7 @@ acpi_aml_exec_monadic2 ( /* Constants are of type Number */ - type = ACPI_TYPE_NUMBER; + type = ACPI_TYPE_INTEGER; break; @@ -733,13 +733,13 @@ acpi_aml_exec_monadic2 ( /* Allocate a descriptor to hold the type. */ - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; } - ret_desc->number.value = type; + ret_desc->integer.value = type; break; @@ -793,13 +793,13 @@ acpi_aml_exec_monadic2 ( * object to hold the value */ - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; } - ret_desc->number.value = value; + ret_desc->integer.value = value; break; @@ -910,14 +910,14 @@ acpi_aml_exec_monadic2 ( * sub-buffer of the main buffer, it is only a pointer to a * single element (byte) of the buffer! */ - ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + ret_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!ret_desc) { status = AE_NO_MEMORY; goto cleanup; } tmp_desc = obj_desc->reference.object; - ret_desc->number.value = + ret_desc->integer.value = tmp_desc->buffer.pointer[obj_desc->reference.offset]; /* TBD: [Investigate] (see below) Don't add an additional diff --git a/drivers/acpi/interpreter/amnames.c b/drivers/acpi/interpreter/amnames.c index ea4c26e088f5..07be1a37c7d0 100644 --- a/drivers/acpi/interpreter/amnames.c +++ b/drivers/acpi/interpreter/amnames.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amnames - interpreter/scanner name load/execute - * $Revision: 71 $ + * $Revision: 73 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/interpreter/amprep.c b/drivers/acpi/interpreter/amprep.c index 266cb0105e68..2a56d48268cc 100644 --- a/drivers/acpi/interpreter/amprep.c +++ b/drivers/acpi/interpreter/amprep.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amprep - ACPI AML (p-code) execution - field prep utilities - * $Revision: 72 $ + * $Revision: 73 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/interpreter/amregion.c b/drivers/acpi/interpreter/amregion.c index dfe4fab85928..1a2e7351ddde 100644 --- a/drivers/acpi/interpreter/amregion.c +++ b/drivers/acpi/interpreter/amregion.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amregion - ACPI default Op_region (address space) handlers - * $Revision: 41 $ + * $Revision: 44 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -99,8 +99,8 @@ acpi_aml_system_memory_space_handler ( */ if ((address < mem_info->mapped_physical_address) || - ((address + length) > - (mem_info->mapped_physical_address + mem_info->mapped_length))) + (((ACPI_INTEGER) address + length) > + ((ACPI_INTEGER) mem_info->mapped_physical_address + mem_info->mapped_length))) { /* * The request cannot be resolved by the current memory mapping; @@ -139,7 +139,7 @@ acpi_aml_system_memory_space_handler ( /* TBD: should these pointers go to 64-bit in all cases ? */ logical_addr_ptr = mem_info->mapped_logical_address + - (address - mem_info->mapped_physical_address); + ((ACPI_INTEGER) address - (ACPI_INTEGER) mem_info->mapped_physical_address); /* Perform the memory read or write */ diff --git a/drivers/acpi/interpreter/amresnte.c b/drivers/acpi/interpreter/amresnte.c index 20c6a0b11a8d..0dc67b613de7 100644 --- a/drivers/acpi/interpreter/amresnte.c +++ b/drivers/acpi/interpreter/amresnte.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amresnte - AML Interpreter object resolution - * $Revision: 25 $ + * $Revision: 27 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -55,7 +55,7 @@ * can be either a pointer to an actual internal object or a pointer into the * AML stream itself. These types are currently: * - * ACPI_TYPE_NUMBER + * ACPI_TYPE_INTEGER * ACPI_TYPE_STRING * ACPI_TYPE_BUFFER * ACPI_TYPE_MUTEX @@ -208,14 +208,14 @@ acpi_aml_resolve_node_to_value ( break; - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: /* * The Node has an attached internal object, make sure that it's a * number */ - if (ACPI_TYPE_NUMBER != val_desc->common.type) { + if (ACPI_TYPE_INTEGER != val_desc->common.type) { return (AE_AML_OPERAND_TYPE); } @@ -244,7 +244,7 @@ acpi_aml_resolve_node_to_value ( object_type = ACPI_TYPE_BUFFER; } else { - object_type = ACPI_TYPE_NUMBER; + object_type = ACPI_TYPE_INTEGER; } /* @@ -282,7 +282,7 @@ acpi_aml_resolve_node_to_value ( return (status); } - obj_desc->number.value = temp_val; + obj_desc->integer.value = temp_val; } @@ -330,12 +330,12 @@ acpi_aml_resolve_node_to_value ( /* Create an object for the result */ - obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!obj_desc) { return (AE_NO_MEMORY); } - obj_desc->number.value = temp_val; + obj_desc->integer.value = temp_val; break; @@ -378,12 +378,12 @@ acpi_aml_resolve_node_to_value ( /* Create an object for the result */ - obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!obj_desc) { return (AE_NO_MEMORY); } - obj_desc->number.value = temp_val; + obj_desc->integer.value = temp_val; break; @@ -477,12 +477,12 @@ acpi_aml_resolve_node_to_value ( /* Create object for result */ - obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_NUMBER); + obj_desc = acpi_cm_create_internal_object (ACPI_TYPE_INTEGER); if (!obj_desc) { return (AE_NO_MEMORY); } - obj_desc->number.value = temp_val; + obj_desc->integer.value = temp_val; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/drivers/acpi/interpreter/amresolv.c b/drivers/acpi/interpreter/amresolv.c index 2fa59e9bb424..c63424e10003 100644 --- a/drivers/acpi/interpreter/amresolv.c +++ b/drivers/acpi/interpreter/amresolv.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amresolv - AML Interpreter object resolution - * $Revision: 78 $ + * $Revision: 80 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -118,19 +118,19 @@ acpi_aml_get_field_unit_value ( mask = ACPI_UINT32_MAX; } - result_desc->number.type = (u8) ACPI_TYPE_NUMBER; + result_desc->integer.type = (u8) ACPI_TYPE_INTEGER; /* Get the 32 bit value at the location */ - MOVE_UNALIGNED32_TO_32 (&result_desc->number.value, location); + MOVE_UNALIGNED32_TO_32 (&result_desc->integer.value, location); /* * Shift the 32-bit word containing the field, and mask off the * resulting value */ - result_desc->number.value = - (result_desc->number.value >> field_desc->field_unit.bit_offset) & mask; + result_desc->integer.value = + (result_desc->integer.value >> field_desc->field_unit.bit_offset) & mask; /* Release global lock if we acquired it earlier */ @@ -279,7 +279,7 @@ acpi_aml_resolve_object_to_value ( acpi_cm_remove_reference (stack_desc); *stack_ptr = obj_desc; - if (ACPI_TYPE_NUMBER == obj_desc->common.type) { + if (ACPI_TYPE_INTEGER == obj_desc->common.type) { /* Value is a Number */ } @@ -311,7 +311,7 @@ acpi_aml_resolve_object_to_value ( acpi_cm_remove_reference (stack_desc); *stack_ptr = obj_desc; - if (ACPI_TYPE_NUMBER == obj_desc->common.type) { + if (ACPI_TYPE_INTEGER == obj_desc->common.type) { /* Value is a Number */ } @@ -326,22 +326,22 @@ acpi_aml_resolve_object_to_value ( case AML_ZERO_OP: - stack_desc->common.type = (u8) ACPI_TYPE_NUMBER; - stack_desc->number.value = 0; + stack_desc->common.type = (u8) ACPI_TYPE_INTEGER; + stack_desc->integer.value = 0; break; case AML_ONE_OP: - stack_desc->common.type = (u8) ACPI_TYPE_NUMBER; - stack_desc->number.value = 1; + stack_desc->common.type = (u8) ACPI_TYPE_INTEGER; + stack_desc->integer.value = 1; break; case AML_ONES_OP: - stack_desc->common.type = (u8) ACPI_TYPE_NUMBER; - stack_desc->number.value = ACPI_INTEGER_MAX; + stack_desc->common.type = (u8) ACPI_TYPE_INTEGER; + stack_desc->integer.value = ACPI_INTEGER_MAX; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/drivers/acpi/interpreter/amresop.c b/drivers/acpi/interpreter/amresop.c index 83fda445505b..a837fd66bcb1 100644 --- a/drivers/acpi/interpreter/amresop.c +++ b/drivers/acpi/interpreter/amresop.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amresop - AML Interpreter operand/object resolution - * $Revision: 18 $ + * $Revision: 22 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -214,8 +214,13 @@ acpi_aml_resolve_operands ( switch (this_arg_type) { - case ARGI_REFERENCE: /* Reference */ - case ARGI_TARGETREF: + case ARGI_REFERENCE: /* References */ + case ARGI_INTEGER_REF: + case ARGI_OBJECT_REF: + case ARGI_DEVICE_REF: + case ARGI_TARGETREF: /* TBD: must implement implicit conversion rules before store */ + case ARGI_FIXED_TARGET: /* No implicit conversion before store to target */ + case ARGI_SIMPLE_TARGET: /* Name, Local, or Arg - no implicit conversion */ /* Need an operand of type INTERNAL_TYPE_REFERENCE */ @@ -283,20 +288,6 @@ acpi_aml_resolve_operands ( * For the simple cases, only one type of resolved object * is allowed */ - case ARGI_NUMBER: /* Number */ - - /* Need an operand of type ACPI_TYPE_NUMBER */ - - type_needed = ACPI_TYPE_NUMBER; - break; - - case ARGI_BUFFER: - - /* Need an operand of type ACPI_TYPE_BUFFER */ - - type_needed = ACPI_TYPE_BUFFER; - break; - case ARGI_MUTEX: /* Need an operand of type ACPI_TYPE_MUTEX */ @@ -344,11 +335,69 @@ acpi_aml_resolve_operands ( * The more complex cases allow multiple resolved object types */ + case ARGI_INTEGER: /* Number */ + + /* + * Need an operand of type ACPI_TYPE_INTEGER, + * But we can implicitly convert from a STRING or BUFFER + */ + status = acpi_aml_convert_to_integer (stack_ptr, walk_state); + if (ACPI_FAILURE (status)) { + if (status == AE_TYPE) { + return (AE_AML_OPERAND_TYPE); + } + + return (status); + } + + goto next_operand; + break; + + + case ARGI_BUFFER: + + /* + * Need an operand of type ACPI_TYPE_BUFFER, + * But we can implicitly convert from a STRING or INTEGER + */ + status = acpi_aml_convert_to_buffer (stack_ptr, walk_state); + if (ACPI_FAILURE (status)) { + if (status == AE_TYPE) { + return (AE_AML_OPERAND_TYPE); + } + + return (status); + } + + goto next_operand; + break; + + case ARGI_STRING: - /* Need an operand of type ACPI_TYPE_STRING or ACPI_TYPE_BUFFER */ + /* + * Need an operand of type ACPI_TYPE_STRING, + * But we can implicitly convert from a BUFFER or INTEGER + */ + status = acpi_aml_convert_to_string (stack_ptr, walk_state); + if (ACPI_FAILURE (status)) { + if (status == AE_TYPE) { + return (AE_AML_OPERAND_TYPE); + } + + return (status); + } + + goto next_operand; + break; + + + case ARGI_COMPUTEDATA: + + /* Need an operand of type INTEGER, STRING or BUFFER */ - if ((ACPI_TYPE_STRING != (*stack_ptr)->common.type) && + if ((ACPI_TYPE_INTEGER != (*stack_ptr)->common.type) && + (ACPI_TYPE_STRING != (*stack_ptr)->common.type) && (ACPI_TYPE_BUFFER != (*stack_ptr)->common.type)) { return (AE_AML_OPERAND_TYPE); diff --git a/drivers/acpi/interpreter/amstore.c b/drivers/acpi/interpreter/amstore.c index 8887e0997843..9c780e9ac570 100644 --- a/drivers/acpi/interpreter/amstore.c +++ b/drivers/acpi/interpreter/amstore.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amstore - AML Interpreter object store support - * $Revision: 117 $ + * $Revision: 119 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -260,10 +260,10 @@ acpi_aml_exec_store ( * This loop to assign each of the elements is somewhat * backward because of the Big Endian-ness of IA-64 */ - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: length = 4; for (i = length; i != 0; i--) { - value = (u8)(val_desc->number.value >> (MUL_8 (i - 1))); + value = (u8)(val_desc->integer.value >> (MUL_8 (i - 1))); tmp_desc->buffer.pointer[dest_desc->reference.offset] = value; } break; diff --git a/drivers/acpi/interpreter/amstoren.c b/drivers/acpi/interpreter/amstoren.c index 91b2095c5979..6e3d0c7e0282 100644 --- a/drivers/acpi/interpreter/amstoren.c +++ b/drivers/acpi/interpreter/amstoren.c @@ -3,12 +3,12 @@ * * Module Name: amstoren - AML Interpreter object store support, * Store to Node (namespace object) - * $Revision: 24 $ + * $Revision: 26 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -110,7 +110,7 @@ acpi_aml_store_object_to_node ( case INTERNAL_TYPE_BANK_FIELD: case INTERNAL_TYPE_INDEX_FIELD: case ACPI_TYPE_FIELD_UNIT: - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: /* * These cases all require only number values or values that @@ -119,13 +119,13 @@ acpi_aml_store_object_to_node ( * If value is not a Number, try to resolve it to one. */ - if (val_desc->common.type != ACPI_TYPE_NUMBER) { + if (val_desc->common.type != ACPI_TYPE_INTEGER) { /* * Initially not a number, convert */ status = acpi_aml_resolve_to_value (&val_desc, walk_state); if (ACPI_SUCCESS (status) && - (val_desc->common.type != ACPI_TYPE_NUMBER)) + (val_desc->common.type != ACPI_TYPE_INTEGER)) { /* * Conversion successful but still not a number @@ -147,7 +147,7 @@ acpi_aml_store_object_to_node ( * If value is not a valid type, try to resolve it to one. */ - if ((val_desc->common.type != ACPI_TYPE_NUMBER) && + if ((val_desc->common.type != ACPI_TYPE_INTEGER) && (val_desc->common.type != ACPI_TYPE_BUFFER) && (val_desc->common.type != ACPI_TYPE_STRING)) { @@ -156,7 +156,7 @@ acpi_aml_store_object_to_node ( */ status = acpi_aml_resolve_to_value (&val_desc, walk_state); if (ACPI_SUCCESS (status) && - (val_desc->common.type != ACPI_TYPE_NUMBER) && + (val_desc->common.type != ACPI_TYPE_INTEGER) && (val_desc->common.type != ACPI_TYPE_BUFFER) && (val_desc->common.type != ACPI_TYPE_STRING)) { @@ -269,9 +269,9 @@ acpi_aml_store_object_to_node ( switch (val_desc->common.type) { - case ACPI_TYPE_NUMBER: - buffer = (u8 *) &val_desc->number.value; - length = sizeof (val_desc->number.value); + case ACPI_TYPE_INTEGER: + buffer = (u8 *) &val_desc->integer.value; + length = sizeof (val_desc->integer.value); break; case ACPI_TYPE_BUFFER: @@ -299,9 +299,9 @@ acpi_aml_store_object_to_node ( switch (val_desc->common.type) { - case ACPI_TYPE_NUMBER: - buffer = (u8 *) &val_desc->number.value; - length = sizeof (val_desc->number.value); + case ACPI_TYPE_INTEGER: + buffer = (u8 *) &val_desc->integer.value; + length = sizeof (val_desc->integer.value); break; case ACPI_TYPE_BUFFER: @@ -363,9 +363,9 @@ acpi_aml_store_object_to_node ( switch (val_desc->common.type) { - case ACPI_TYPE_NUMBER: - buffer = (u8 *) &val_desc->number.value; - length = sizeof (val_desc->number.value); + case ACPI_TYPE_INTEGER: + buffer = (u8 *) &val_desc->integer.value; + length = sizeof (val_desc->integer.value); break; case ACPI_TYPE_BUFFER: @@ -422,8 +422,8 @@ acpi_aml_store_object_to_node ( status = acpi_aml_access_named_field (ACPI_WRITE, dest_desc->index_field.data, - &val_desc->number.value, - sizeof (val_desc->number.value)); + &val_desc->integer.value, + sizeof (val_desc->integer.value)); } break; @@ -485,7 +485,7 @@ acpi_aml_store_object_to_node ( * Shift and mask the new value into position, * and or it into the buffer. */ - new_value |= (val_desc->number.value << dest_desc->field_unit.bit_offset) & + new_value |= (val_desc->integer.value << dest_desc->field_unit.bit_offset) & mask; /* Store back the value */ @@ -495,10 +495,10 @@ acpi_aml_store_object_to_node ( break; - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: - dest_desc->number.value = val_desc->number.value; + dest_desc->integer.value = val_desc->integer.value; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/drivers/acpi/interpreter/amstorob.c b/drivers/acpi/interpreter/amstorob.c index f3a098bd2585..f4f26d07f10e 100644 --- a/drivers/acpi/interpreter/amstorob.c +++ b/drivers/acpi/interpreter/amstorob.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amstorob - AML Interpreter object store support, store to object - * $Revision: 18 $ + * $Revision: 20 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -88,7 +88,7 @@ acpi_aml_store_object_to_object ( { /* Type of Name's existing value */ - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: /* * These cases all require only number values or values that @@ -97,13 +97,13 @@ acpi_aml_store_object_to_object ( * If value is not a Number, try to resolve it to one. */ - if (val_desc->common.type != ACPI_TYPE_NUMBER) { + if (val_desc->common.type != ACPI_TYPE_INTEGER) { /* * Initially not a number, convert */ status = acpi_aml_resolve_to_value (&val_desc, walk_state); if (ACPI_SUCCESS (status) && - (val_desc->common.type != ACPI_TYPE_NUMBER)) + (val_desc->common.type != ACPI_TYPE_INTEGER)) { /* * Conversion successful but still not a number @@ -124,7 +124,7 @@ acpi_aml_store_object_to_object ( * If value is not a valid type, try to resolve it to one. */ - if ((val_desc->common.type != ACPI_TYPE_NUMBER) && + if ((val_desc->common.type != ACPI_TYPE_INTEGER) && (val_desc->common.type != ACPI_TYPE_BUFFER) && (val_desc->common.type != ACPI_TYPE_STRING)) { @@ -133,7 +133,7 @@ acpi_aml_store_object_to_object ( */ status = acpi_aml_resolve_to_value (&val_desc, walk_state); if (ACPI_SUCCESS (status) && - (val_desc->common.type != ACPI_TYPE_NUMBER) && + (val_desc->common.type != ACPI_TYPE_INTEGER) && (val_desc->common.type != ACPI_TYPE_BUFFER) && (val_desc->common.type != ACPI_TYPE_STRING)) { @@ -177,9 +177,9 @@ acpi_aml_store_object_to_object ( switch (val_desc->common.type) { - case ACPI_TYPE_NUMBER: - buffer = (u8 *) &val_desc->number.value; - length = sizeof (val_desc->number.value); + case ACPI_TYPE_INTEGER: + buffer = (u8 *) &val_desc->integer.value; + length = sizeof (val_desc->integer.value); break; case ACPI_TYPE_BUFFER: @@ -241,9 +241,9 @@ acpi_aml_store_object_to_object ( switch (val_desc->common.type) { - case ACPI_TYPE_NUMBER: - buffer = (u8 *) &val_desc->number.value; - length = sizeof (val_desc->number.value); + case ACPI_TYPE_INTEGER: + buffer = (u8 *) &val_desc->integer.value; + length = sizeof (val_desc->integer.value); break; case ACPI_TYPE_BUFFER: @@ -291,9 +291,9 @@ acpi_aml_store_object_to_object ( } break; - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: - dest_desc->number.value = val_desc->number.value; + dest_desc->integer.value = val_desc->integer.value; /* Truncate value if we are executing from a 32-bit ACPI table */ diff --git a/drivers/acpi/interpreter/amsystem.c b/drivers/acpi/interpreter/amsystem.c index 9ad72c161523..5e60538afbd2 100644 --- a/drivers/acpi/interpreter/amsystem.c +++ b/drivers/acpi/interpreter/amsystem.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amsystem - Interface to OS services - * $Revision: 52 $ + * $Revision: 54 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -202,7 +202,7 @@ acpi_aml_system_acquire_mutex ( } status = acpi_aml_system_wait_semaphore (obj_desc->mutex.semaphore, - (u32) time_desc->number.value); + (u32) time_desc->integer.value); return (status); } @@ -299,7 +299,7 @@ acpi_aml_system_wait_event ( if (obj_desc) { status = acpi_aml_system_wait_semaphore (obj_desc->event.semaphore, - (u32) time_desc->number.value); + (u32) time_desc->integer.value); } diff --git a/drivers/acpi/interpreter/amutils.c b/drivers/acpi/interpreter/amutils.c index 4e1359888d38..e3456099c00d 100644 --- a/drivers/acpi/interpreter/amutils.c +++ b/drivers/acpi/interpreter/amutils.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amutils - interpreter/scanner utilities - * $Revision: 66 $ + * $Revision: 68 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -46,14 +46,11 @@ typedef struct internal_search_st /* Used to traverse nested packages when copying*/ +/* TBD: This must be removed! */ INTERNAL_PKG_SEARCH_INFO copy_level[MAX_PACKAGE_DEPTH]; -static NATIVE_CHAR hex[] = - {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; - - /******************************************************************************* * * FUNCTION: Acpi_aml_enter_interpreter @@ -156,7 +153,7 @@ acpi_aml_truncate_for32bit_table ( */ if ((!obj_desc) || - (obj_desc->common.type != ACPI_TYPE_NUMBER) || + (obj_desc->common.type != ACPI_TYPE_INTEGER) || (!walk_state->method_node)) { return; @@ -167,7 +164,7 @@ acpi_aml_truncate_for32bit_table ( * We are running a method that exists in a 32-bit ACPI table. * Truncate the value to 32 bits by zeroing out the upper 32-bit field */ - obj_desc->number.value &= (ACPI_INTEGER) ACPI_UINT32_MAX; + obj_desc->integer.value &= (ACPI_INTEGER) ACPI_UINT32_MAX; } } @@ -343,10 +340,10 @@ acpi_aml_eisa_id_to_string ( out_string[0] = (char) ('@' + ((id >> 26) & 0x1f)); out_string[1] = (char) ('@' + ((id >> 21) & 0x1f)); out_string[2] = (char) ('@' + ((id >> 16) & 0x1f)); - out_string[3] = hex[(id >> 12) & 0xf]; - out_string[4] = hex[(id >> 8) & 0xf]; - out_string[5] = hex[(id >> 4) & 0xf]; - out_string[6] = hex[id & 0xf]; + out_string[3] = acpi_gbl_hex_to_ascii[(id >> 12) & 0xf]; + out_string[4] = acpi_gbl_hex_to_ascii[(id >> 8) & 0xf]; + out_string[5] = acpi_gbl_hex_to_ascii[(id >> 4) & 0xf]; + out_string[6] = acpi_gbl_hex_to_ascii[id & 0xf]; out_string[7] = 0; return (AE_OK); diff --git a/drivers/acpi/interpreter/amxface.c b/drivers/acpi/interpreter/amxface.c index fd589d39b445..20cf9820ebc9 100644 --- a/drivers/acpi/interpreter/amxface.c +++ b/drivers/acpi/interpreter/amxface.c @@ -2,12 +2,12 @@ /****************************************************************************** * * Module Name: amxface - External interpreter interfaces - * $Revision: 22 $ + * $Revision: 24 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsaccess.c b/drivers/acpi/namespace/nsaccess.c index 27c02e22af0f..c2e6a71e0105 100644 --- a/drivers/acpi/namespace/nsaccess.c +++ b/drivers/acpi/namespace/nsaccess.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: nsaccess - Top-level functions for accessing ACPI namespace - * $Revision: 117 $ + * $Revision: 119 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -117,9 +117,9 @@ acpi_ns_root_initialize (void) switch (init_val->type) { - case ACPI_TYPE_NUMBER: + case ACPI_TYPE_INTEGER: - obj_desc->number.value = + obj_desc->integer.value = (ACPI_INTEGER) STRTOUL (init_val->val, NULL, 10); break; @@ -239,7 +239,7 @@ acpi_ns_lookup ( ACPI_NAMESPACE_NODE **return_node) { ACPI_STATUS status; - ACPI_NAMESPACE_NODE *prefix_node; + ACPI_NAMESPACE_NODE *prefix_node; ACPI_NAMESPACE_NODE *current_node = NULL; ACPI_NAMESPACE_NODE *scope_to_push = NULL; ACPI_NAMESPACE_NODE *this_node = NULL; @@ -248,8 +248,7 @@ acpi_ns_lookup ( u8 null_name_path = FALSE; OBJECT_TYPE_INTERNAL type_to_check_for; OBJECT_TYPE_INTERNAL this_search_type; - - DEBUG_ONLY_MEMBERS (u32 i) + u32 local_flags = flags & ~NS_ERROR_IF_FOUND; if (!return_node) { @@ -437,6 +436,7 @@ acpi_ns_lookup ( this_search_type = ACPI_TYPE_ANY; if (!num_segments) { this_search_type = type; + local_flags = flags; } /* Pluck one ACPI name from the front of the pathname */ @@ -447,7 +447,7 @@ acpi_ns_lookup ( status = acpi_ns_search_and_enter (simple_name, walk_state, current_node, interpreter_mode, - this_search_type, flags, + this_search_type, local_flags, &this_node); if (ACPI_FAILURE (status)) { diff --git a/drivers/acpi/namespace/nsalloc.c b/drivers/acpi/namespace/nsalloc.c index 9f1d5377e223..5cac5d1111c7 100644 --- a/drivers/acpi/namespace/nsalloc.c +++ b/drivers/acpi/namespace/nsalloc.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: nsalloc - Namespace allocation and deletion utilities - * $Revision: 43 $ + * $Revision: 45 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nseval.c b/drivers/acpi/namespace/nseval.c index fbba7840cf6f..6c040d22e271 100644 --- a/drivers/acpi/namespace/nseval.c +++ b/drivers/acpi/namespace/nseval.c @@ -2,12 +2,12 @@ * * Module Name: nseval - Object evaluation interfaces -- includes control * method lookup and execution. - * $Revision: 79 $ + * $Revision: 81 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsinit.c b/drivers/acpi/namespace/nsinit.c index ddacd7b8caf8..76b535205fe0 100644 --- a/drivers/acpi/namespace/nsinit.c +++ b/drivers/acpi/namespace/nsinit.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: nsinit - namespace initialization - * $Revision: 9 $ + * $Revision: 12 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -239,7 +239,9 @@ acpi_ns_init_one_device ( status = acpi_cm_execute_STA (node, &flags); if (ACPI_FAILURE (status)) { - return (status); + /* Ignore error and move on to next device */ + + return (AE_OK); } info->num_STA++; @@ -260,12 +262,15 @@ acpi_ns_init_one_device ( } else if (ACPI_FAILURE (status)) { - return (status); + /* Ignore error and move on to next device */ + } else { + /* Count of successfull INIs */ + info->num_INI++; } - return (status); + return (AE_OK); } diff --git a/drivers/acpi/namespace/nsload.c b/drivers/acpi/namespace/nsload.c index 28a26376d400..f0eaf273baf4 100644 --- a/drivers/acpi/namespace/nsload.c +++ b/drivers/acpi/namespace/nsload.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: nsload - namespace loading/expanding/contracting procedures - * $Revision: 33 $ + * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsnames.c b/drivers/acpi/namespace/nsnames.c index faf8fe56a241..c2fb4916378d 100644 --- a/drivers/acpi/namespace/nsnames.c +++ b/drivers/acpi/namespace/nsnames.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: nsnames - Name manipulation and search - * $Revision: 51 $ + * $Revision: 53 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsobject.c b/drivers/acpi/namespace/nsobject.c index 6d41b91ce3af..493cb13172d1 100644 --- a/drivers/acpi/namespace/nsobject.c +++ b/drivers/acpi/namespace/nsobject.c @@ -2,12 +2,12 @@ * * Module Name: nsobject - Utilities for objects attached to namespace * table entries - * $Revision: 47 $ + * $Revision: 49 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -205,7 +205,7 @@ acpi_ns_attach_object ( case AML_ZERO_OP: case AML_ONES_OP: case AML_ONE_OP: case AML_BYTE_OP: case AML_WORD_OP: case AML_DWORD_OP: - obj_type = ACPI_TYPE_NUMBER; + obj_type = ACPI_TYPE_INTEGER; break; diff --git a/drivers/acpi/namespace/nssearch.c b/drivers/acpi/namespace/nssearch.c index 001f57d9d153..6a9336c7141b 100644 --- a/drivers/acpi/namespace/nssearch.c +++ b/drivers/acpi/namespace/nssearch.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: nssearch - Namespace search - * $Revision: 62 $ + * $Revision: 63 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsutils.c b/drivers/acpi/namespace/nsutils.c index 593064dbb97e..f795fbba65ab 100644 --- a/drivers/acpi/namespace/nsutils.c +++ b/drivers/acpi/namespace/nsutils.c @@ -2,12 +2,12 @@ * * Module Name: nsutils - Utilities for accessing ACPI namespace, accessing * parents and siblings and Scope manipulation - * $Revision: 74 $ + * $Revision: 76 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nswalk.c b/drivers/acpi/namespace/nswalk.c index 3682266b337f..cf84be326b83 100644 --- a/drivers/acpi/namespace/nswalk.c +++ b/drivers/acpi/namespace/nswalk.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: nswalk - Functions for walking the APCI namespace - * $Revision: 17 $ + * $Revision: 19 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsxfname.c b/drivers/acpi/namespace/nsxfname.c index 2947f7f06eba..957481a6dbc2 100644 --- a/drivers/acpi/namespace/nsxfname.c +++ b/drivers/acpi/namespace/nsxfname.c @@ -2,12 +2,12 @@ * * Module Name: nsxfname - Public interfaces to the ACPI subsystem * ACPI Namespace oriented interfaces - * $Revision: 73 $ + * $Revision: 75 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/namespace/nsxfobj.c b/drivers/acpi/namespace/nsxfobj.c index d4432ee8a51c..742c5da6620a 100644 --- a/drivers/acpi/namespace/nsxfobj.c +++ b/drivers/acpi/namespace/nsxfobj.c @@ -2,12 +2,12 @@ * * Module Name: nsxfobj - Public interfaces to the ACPI subsystem * ACPI Object oriented interfaces - * $Revision: 75 $ + * $Revision: 78 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -695,4 +695,3 @@ acpi_get_devices ( return (status); } - diff --git a/drivers/acpi/os.c b/drivers/acpi/os.c index 7bf86171bb2c..172b6659b2fd 100644 --- a/drivers/acpi/os.c +++ b/drivers/acpi/os.c @@ -24,8 +24,8 @@ #include <linux/mm.h> #include <linux/pci.h> #include <linux/acpi.h> +#include <linux/delay.h> #include <asm/io.h> -#include <asm/delay.h> #include "acpi.h" #include "driver.h" diff --git a/drivers/acpi/parser/psargs.c b/drivers/acpi/parser/psargs.c index 35d623668367..da3ef9b30d29 100644 --- a/drivers/acpi/parser/psargs.c +++ b/drivers/acpi/parser/psargs.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: psargs - Parse AML opcode arguments - * $Revision: 42 $ + * $Revision: 43 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/parser/psopcode.c b/drivers/acpi/parser/psopcode.c index a7f061363b82..90a73f45b7d8 100644 --- a/drivers/acpi/parser/psopcode.c +++ b/drivers/acpi/parser/psopcode.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: psopcode - Parser opcode information table - * $Revision: 24 $ + * $Revision: 27 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -44,7 +44,7 @@ #define _PFX 0x6D #define _UNKNOWN_OPCODE 0x02 /* An example unknown opcode */ -#define MAX_EXTENDED_OPCODE 0x87 +#define MAX_EXTENDED_OPCODE 0x88 #define NUM_EXTENDED_OPCODE MAX_EXTENDED_OPCODE + 1 #define MAX_INTERNAL_OPCODE #define NUM_INTERNAL_OPCODE MAX_INTERNAL_OPCODE + 1 @@ -83,9 +83,11 @@ #define ARGP_WORD_OP ARGP_LIST1 (ARGP_WORDDATA) #define ARGP_DWORD_OP ARGP_LIST1 (ARGP_DWORDDATA) #define ARGP_STRING_OP ARGP_LIST1 (ARGP_CHARLIST) +#define ARGP_QWORD_OP ARGP_LIST1 (ARGP_QWORDDATA) #define ARGP_SCOPE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_TERMLIST) #define ARGP_BUFFER_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_BYTELIST) #define ARGP_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_BYTEDATA, ARGP_DATAOBJLIST) +#define ARGP_VAR_PACKAGE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_BYTEDATA, ARGP_DATAOBJLIST) #define ARGP_METHOD_OP ARGP_LIST4 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_BYTEDATA, ARGP_TERMLIST) #define ARGP_LOCAL0 ARG_NONE #define ARGP_LOCAL1 ARG_NONE @@ -122,6 +124,8 @@ #define ARGP_FIND_SET_LEFT_BIT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) #define ARGP_FIND_SET_RIGHT_BIT_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) #define ARGP_DEREF_OF_OP ARGP_LIST1 (ARGP_TERMARG) +#define ARGP_CONCAT_RES_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) +#define ARGP_MOD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) #define ARGP_NOTIFY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_TERMARG) #define ARGP_SIZE_OF_OP ARGP_LIST1 (ARGP_SUPERNAME) #define ARGP_INDEX_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) @@ -131,12 +135,21 @@ #define ARGP_BYTE_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME) #define ARGP_BIT_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME) #define ARGP_TYPE_OP ARGP_LIST1 (ARGP_SUPERNAME) +#define ARGP_QWORD_FIELD_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME) #define ARGP_LAND_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LOR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LNOT_OP ARGP_LIST1 (ARGP_TERMARG) #define ARGP_LEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LGREATER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LLESS_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) +#define ARGP_TO_BUFFER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) +#define ARGP_TO_DEC_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) +#define ARGP_TO_HEX_STR_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) +#define ARGP_TO_INTEGER_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TARGET) +#define ARGP_TO_STRING_OP ARGP_LIST3 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) +#define ARGP_COPY_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SIMPLENAME) +#define ARGP_MID_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TARGET) +#define ARGP_CONTINUE_OP ARG_NONE #define ARGP_IF_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST) #define ARGP_ELSE_OP ARGP_LIST2 (ARGP_PKGLENGTH, ARGP_TERMLIST) #define ARGP_WHILE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_TERMARG, ARGP_TERMLIST) @@ -149,6 +162,7 @@ #define ARGP_EVENT_OP ARGP_LIST1 (ARGP_NAME) #define ARGP_COND_REF_OF_OP ARGP_LIST2 (ARGP_SUPERNAME, ARGP_SUPERNAME) #define ARGP_CREATE_FIELD_OP ARGP_LIST4 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_NAME) +#define ARGP_LOAD_TABLE_OP ARGP_LIST6 (ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LOAD_OP ARGP_LIST2 (ARGP_NAMESTRING, ARGP_SUPERNAME) #define ARGP_STALL_OP ARGP_LIST1 (ARGP_TERMARG) #define ARGP_SLEEP_OP ARGP_LIST1 (ARGP_TERMARG) @@ -171,6 +185,7 @@ #define ARGP_THERMAL_ZONE_OP ARGP_LIST3 (ARGP_PKGLENGTH, ARGP_NAME, ARGP_OBJLIST) #define ARGP_INDEX_FIELD_OP ARGP_LIST5 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_NAMESTRING,ARGP_BYTEDATA, ARGP_FIELDLIST) #define ARGP_BANK_FIELD_OP ARGP_LIST6 (ARGP_PKGLENGTH, ARGP_NAMESTRING, ARGP_NAMESTRING,ARGP_TERMARG, ARGP_BYTEDATA, ARGP_FIELDLIST) +#define ARGP_DATA_REGION_OP ARGP_LIST4 (ARGP_NAMESTRING, ARGP_TERMARG, ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LNOTEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LLESSEQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) #define ARGP_LGREATEREQUAL_OP ARGP_LIST2 (ARGP_TERMARG, ARGP_TERMARG) @@ -187,7 +202,7 @@ * All AML opcodes and the runtime arguments for each. Used by the AML interpreter Each list is compressed * into a 32-bit number and stored in the master opcode table at the end of this file. * - * (Used by Acpi_aml_prep_operands procedure) + * (Used by Acpi_aml_prep_operands procedure and the ASL Compiler) */ #define ARGI_ZERO_OP ARG_NONE @@ -198,9 +213,11 @@ #define ARGI_WORD_OP ARGI_INVALID_OPCODE #define ARGI_DWORD_OP ARGI_INVALID_OPCODE #define ARGI_STRING_OP ARGI_INVALID_OPCODE +#define ARGI_QWORD_OP ARGI_INVALID_OPCODE #define ARGI_SCOPE_OP ARGI_INVALID_OPCODE #define ARGI_BUFFER_OP ARGI_INVALID_OPCODE #define ARGI_PACKAGE_OP ARGI_INVALID_OPCODE +#define ARGI_VAR_PACKAGE_OP ARGI_INVALID_OPCODE #define ARGI_METHOD_OP ARGI_INVALID_OPCODE #define ARGI_LOCAL0 ARG_NONE #define ARGI_LOCAL1 ARG_NONE @@ -218,40 +235,51 @@ #define ARGI_ARG5 ARG_NONE #define ARGI_ARG6 ARG_NONE #define ARGI_STORE_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_TARGETREF) -#define ARGI_REF_OF_OP ARGI_LIST1 (ARGI_REFERENCE) -#define ARGI_ADD_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_TARGETREF) -#define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_REFERENCE) -#define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_REFERENCE) -#define ARGI_MULTIPLY_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF, ARGI_TARGETREF) -#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_BIT_NAND_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_BIT_OR_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_BIT_XOR_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_BIT_NOT_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_FIND_SET_LEFT_BIT_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF) +#define ARGI_REF_OF_OP ARGI_LIST1 (ARGI_OBJECT_REF) +#define ARGI_ADD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_CONCAT_OP ARGI_LIST3 (ARGI_COMPUTEDATA,ARGI_COMPUTEDATA, ARGI_TARGETREF) +#define ARGI_SUBTRACT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_INCREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF) +#define ARGI_DECREMENT_OP ARGI_LIST1 (ARGI_INTEGER_REF) +#define ARGI_MULTIPLY_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_DIVIDE_OP ARGI_LIST4 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF, ARGI_TARGETREF) +#define ARGI_SHIFT_LEFT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_SHIFT_RIGHT_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_BIT_AND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_BIT_NAND_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_BIT_OR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_BIT_NOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_BIT_XOR_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_BIT_NOT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_FIND_SET_LEFT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_FIND_SET_RIGHT_BIT_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF) #define ARGI_DEREF_OF_OP ARGI_LIST1 (ARGI_REFERENCE) -#define ARGI_NOTIFY_OP ARGI_LIST2 (ARGI_REFERENCE, ARGI_NUMBER) +#define ARGI_CONCAT_RES_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_BUFFER, ARGI_TARGETREF) +#define ARGI_MOD_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_NOTIFY_OP ARGI_LIST2 (ARGI_DEVICE_REF, ARGI_INTEGER) #define ARGI_SIZE_OF_OP ARGI_LIST1 (ARGI_DATAOBJECT) -#define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_DWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_NUMBER, ARGI_REFERENCE) -#define ARGI_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_NUMBER, ARGI_REFERENCE) -#define ARGI_BYTE_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_NUMBER, ARGI_REFERENCE) -#define ARGI_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_NUMBER, ARGI_REFERENCE) +#define ARGI_INDEX_OP ARGI_LIST3 (ARGI_COMPLEXOBJ, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_MATCH_OP ARGI_LIST6 (ARGI_PACKAGE, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_DWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) +#define ARGI_WORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) +#define ARGI_BYTE_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) +#define ARGI_BIT_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) #define ARGI_TYPE_OP ARGI_LIST1 (ARGI_ANYTYPE) -#define ARGI_LAND_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_LOR_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_LNOT_OP ARGI_LIST1 (ARGI_NUMBER) -#define ARGI_LEQUAL_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_LGREATER_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_LLESS_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) +#define ARGI_QWORD_FIELD_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_REFERENCE) +#define ARGI_LAND_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_LOR_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_LNOT_OP ARGI_LIST1 (ARGI_INTEGER) +#define ARGI_LEQUAL_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_LGREATER_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_LLESS_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_TO_BUFFER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) +#define ARGI_TO_DEC_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) +#define ARGI_TO_HEX_STR_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) +#define ARGI_TO_INTEGER_OP ARGI_LIST2 (ARGI_COMPUTEDATA,ARGI_FIXED_TARGET) +#define ARGI_TO_STRING_OP ARGI_LIST3 (ARGI_BUFFER, ARGI_INTEGER, ARGI_FIXED_TARGET) +#define ARGI_COPY_OP ARGI_LIST2 (ARGI_ANYTYPE, ARGI_SIMPLE_TARGET) +#define ARGI_MID_OP ARGI_LIST4 (ARGI_BUFFERSTRING,ARGI_INTEGER, ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_CONTINUE_OP ARGI_INVALID_OPCODE #define ARGI_IF_OP ARGI_INVALID_OPCODE #define ARGI_ELSE_OP ARGI_INVALID_OPCODE #define ARGI_WHILE_OP ARGI_INVALID_OPCODE @@ -262,23 +290,24 @@ #define ARGI_ONES_OP ARG_NONE #define ARGI_MUTEX_OP ARGI_INVALID_OPCODE #define ARGI_EVENT_OP ARGI_INVALID_OPCODE -#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_REFERENCE, ARGI_TARGETREF) -#define ARGI_CREATE_FIELD_OP ARGI_LIST4 (ARGI_BUFFER, ARGI_NUMBER, ARGI_NUMBER, ARGI_REFERENCE) +#define ARGI_COND_REF_OF_OP ARGI_LIST2 (ARGI_OBJECT_REF, ARGI_TARGETREF) +#define ARGI_CREATE_FIELD_OP ARGI_LIST4 (ARGI_BUFFER, ARGI_INTEGER, ARGI_INTEGER, ARGI_REFERENCE) +#define ARGI_LOAD_TABLE_OP ARGI_LIST6 (ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_STRING, ARGI_TARGETREF) #define ARGI_LOAD_OP ARGI_LIST2 (ARGI_REGION, ARGI_TARGETREF) -#define ARGI_STALL_OP ARGI_LIST1 (ARGI_NUMBER) -#define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_NUMBER) -#define ARGI_ACQUIRE_OP ARGI_LIST2 (ARGI_MUTEX, ARGI_NUMBER) +#define ARGI_STALL_OP ARGI_LIST1 (ARGI_INTEGER) +#define ARGI_SLEEP_OP ARGI_LIST1 (ARGI_INTEGER) +#define ARGI_ACQUIRE_OP ARGI_LIST2 (ARGI_MUTEX, ARGI_INTEGER) #define ARGI_SIGNAL_OP ARGI_LIST1 (ARGI_EVENT) -#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_NUMBER) +#define ARGI_WAIT_OP ARGI_LIST2 (ARGI_EVENT, ARGI_INTEGER) #define ARGI_RESET_OP ARGI_LIST1 (ARGI_EVENT) #define ARGI_RELEASE_OP ARGI_LIST1 (ARGI_MUTEX) -#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF) -#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_TARGETREF) +#define ARGI_FROM_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_TARGETREF) +#define ARGI_TO_BCD_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_FIXED_TARGET) #define ARGI_UNLOAD_OP ARGI_LIST1 (ARGI_DDBHANDLE) #define ARGI_REVISION_OP ARG_NONE #define ARGI_DEBUG_OP ARG_NONE -#define ARGI_FATAL_OP ARGI_LIST3 (ARGI_NUMBER, ARGI_NUMBER, ARGI_NUMBER) -#define ARGI_REGION_OP ARGI_LIST2 (ARGI_NUMBER, ARGI_NUMBER) +#define ARGI_FATAL_OP ARGI_LIST3 (ARGI_INTEGER, ARGI_INTEGER, ARGI_INTEGER) +#define ARGI_REGION_OP ARGI_LIST2 (ARGI_INTEGER, ARGI_INTEGER) #define ARGI_DEF_FIELD_OP ARGI_INVALID_OPCODE #define ARGI_DEVICE_OP ARGI_INVALID_OPCODE #define ARGI_PROCESSOR_OP ARGI_INVALID_OPCODE @@ -286,6 +315,7 @@ #define ARGI_THERMAL_ZONE_OP ARGI_INVALID_OPCODE #define ARGI_INDEX_FIELD_OP ARGI_INVALID_OPCODE #define ARGI_BANK_FIELD_OP ARGI_INVALID_OPCODE +#define ARGI_DATA_REGION_OP ARGI_LIST3 (ARGI_STRING, ARGI_STRING, ARGI_STRING) #define ARGI_LNOTEQUAL_OP ARGI_INVALID_OPCODE #define ARGI_LLESSEQUAL_OP ARGI_INVALID_OPCODE #define ARGI_LGREATEREQUAL_OP ARGI_INVALID_OPCODE @@ -307,8 +337,8 @@ static ACPI_OPCODE_INFO aml_op_info[] = { /* Index Opcode Type Class Has Arguments? Name Parser Args Interpreter Args */ -/* 00 */ /* AML_ZERO_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Zero_op", ARGP_ZERO_OP, ARGI_ZERO_OP), -/* 01 */ /* AML_ONE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "One_op", ARGP_ONE_OP, ARGI_ONE_OP), +/* 00 */ /* AML_ZERO_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Zero", ARGP_ZERO_OP, ARGI_ZERO_OP), +/* 01 */ /* AML_ONE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "One", ARGP_ONE_OP, ARGI_ONE_OP), /* 02 */ /* AML_ALIAS_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Alias", ARGP_ALIAS_OP, ARGI_ALIAS_OP), /* 03 */ /* AML_NAME_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Name", ARGP_NAME_OP, ARGI_NAME_OP), /* 04 */ /* AML_BYTE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Byte_const", ARGP_BYTE_OP, ARGI_BYTE_OP), @@ -337,7 +367,7 @@ static ACPI_OPCODE_INFO aml_op_info[] = /* 1_b */ /* AML_STORE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Store", ARGP_STORE_OP, ARGI_STORE_OP), /* 1_c */ /* AML_REF_OF_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Ref_of", ARGP_REF_OF_OP, ARGI_REF_OF_OP), /* 1_d */ /* AML_ADD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Add", ARGP_ADD_OP, ARGI_ADD_OP), -/* 1_e */ /* AML_CONCAT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Concat", ARGP_CONCAT_OP, ARGI_CONCAT_OP), +/* 1_e */ /* AML_CONCAT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Concatenate", ARGP_CONCAT_OP, ARGI_CONCAT_OP), /* 1_f */ /* AML_SUBTRACT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Subtract", ARGP_SUBTRACT_OP, ARGI_SUBTRACT_OP), /* 20 */ /* AML_INCREMENT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Increment", ARGP_INCREMENT_OP, ARGI_INCREMENT_OP), /* 21 */ /* AML_DECREMENT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2| AML_HAS_ARGS, "Decrement", ARGP_DECREMENT_OP, ARGI_DECREMENT_OP), @@ -376,7 +406,7 @@ static ACPI_OPCODE_INFO aml_op_info[] = /* 42 */ /* AML_RETURN_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_HAS_ARGS, "Return", ARGP_RETURN_OP, ARGI_RETURN_OP), /* 43 */ /* AML_BREAK_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_NO_ARGS, "Break", ARGP_BREAK_OP, ARGI_BREAK_OP), /* 44 */ /* AML_BREAK_POINT_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_NO_ARGS, "Break_point", ARGP_BREAK_POINT_OP, ARGI_BREAK_POINT_OP), -/* 45 */ /* AML_ONES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Ones_op", ARGP_ONES_OP, ARGI_ONES_OP), +/* 45 */ /* AML_ONES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONSTANT| AML_NO_ARGS, "Ones", ARGP_ONES_OP, ARGI_ONES_OP), /* Prefixed opcodes (Two-byte opcodes with a prefix op) */ @@ -402,7 +432,7 @@ static ACPI_OPCODE_INFO aml_op_info[] = /* 59 */ /* AML_DEF_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Field", ARGP_DEF_FIELD_OP, ARGI_DEF_FIELD_OP), /* 5_a */ /* AML_DEVICE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Device", ARGP_DEVICE_OP, ARGI_DEVICE_OP), /* 5_b */ /* AML_PROCESSOR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Processor", ARGP_PROCESSOR_OP, ARGI_PROCESSOR_OP), -/* 5_c */ /* AML_POWER_RES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Power_res", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP), +/* 5_c */ /* AML_POWER_RES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Power_resource", ARGP_POWER_RES_OP, ARGI_POWER_RES_OP), /* 5_d */ /* AML_THERMAL_ZONE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Thermal_zone", ARGP_THERMAL_ZONE_OP, ARGI_THERMAL_ZONE_OP), /* 5_e */ /* AML_INDEX_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Index_field", ARGP_INDEX_FIELD_OP, ARGI_INDEX_FIELD_OP), /* 5_f */ /* AML_BANK_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_NAMED_OBJECT| AML_HAS_ARGS, "Bank_field", ARGP_BANK_FIELD_OP, ARGI_BANK_FIELD_OP), @@ -423,6 +453,26 @@ static ACPI_OPCODE_INFO aml_op_info[] = /* 6_b */ /* UNKNOWN OPCODES */ OP_INFO_ENTRY (ACPI_OP_TYPE_UNKNOWN | OPTYPE_BOGUS| AML_HAS_ARGS, "UNKNOWN_OP!", ARG_NONE, ARG_NONE), /* 6_c */ /* ASCII CHARACTERS */ OP_INFO_ENTRY (ACPI_OP_TYPE_ASCII | OPTYPE_BOGUS| AML_HAS_ARGS, "ASCII_ONLY!", ARG_NONE, ARG_NONE), /* 6_d */ /* PREFIX CHARACTERS */ OP_INFO_ENTRY (ACPI_OP_TYPE_PREFIX | OPTYPE_BOGUS| AML_HAS_ARGS, "PREFIX_ONLY!", ARG_NONE, ARG_NONE), + + +/* ACPI 2.0 (new) opcodes */ + +/* 6_e */ /* AML_QWORD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_LITERAL| AML_NO_ARGS, "Qword_const", ARGP_QWORD_OP, ARGI_QWORD_OP), +/* 6_f */ /* AML_VAR_PACKAGE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DATA_TERM| AML_HAS_ARGS, "Var_package", ARGP_VAR_PACKAGE_OP, ARGI_VAR_PACKAGE_OP), +/* 70 */ /* AML_CONCAT_RES_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Concat_res", ARGP_CONCAT_RES_OP, ARGI_CONCAT_RES_OP), +/* 71 */ /* AML_MOD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_DYADIC2_r| AML_HAS_ARGS, "Mod", ARGP_MOD_OP, ARGI_MOD_OP), +/* 72 */ /* AML_QWORD_FIELD_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CREATE_FIELD| AML_HAS_ARGS, "Create_qWord_field", ARGP_QWORD_FIELD_OP, ARGI_QWORD_FIELD_OP), +/* 73 */ /* AML_TO_BUFFER_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "To_buffer", ARGP_TO_BUFFER_OP, ARGI_TO_BUFFER_OP), +/* 74 */ /* AML_TO_DEC_STR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "To_dec_string", ARGP_TO_DEC_STR_OP, ARGI_TO_DEC_STR_OP), +/* 75 */ /* AML_TO_HEX_STR_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "To_hex_string", ARGP_TO_HEX_STR_OP, ARGI_TO_HEX_STR_OP), +/* 76 */ /* AML_TO_INTEGER_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "To_integer", ARGP_TO_INTEGER_OP, ARGI_TO_INTEGER_OP), +/* 77 */ /* AML_TO_STRING_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "To_string", ARGP_TO_STRING_OP, ARGI_TO_STRING_OP), +/* 78 */ /* AML_COPY_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Copy", ARGP_COPY_OP, ARGI_COPY_OP), +/* 79 */ /* AML_MID_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Mid", ARGP_MID_OP, ARGI_MID_OP), +/* 7_a */ /* AML_CONTINUE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_CONTROL| AML_NO_ARGS, "Continue", ARGP_CONTINUE_OP, ARGI_CONTINUE_OP), +/* 7_b */ /* AML_LOAD_TABLE_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Load_table", ARGP_LOAD_TABLE_OP, ARGI_LOAD_TABLE_OP), +/* 7_c */ /* AML_DATA_REGION_OP */ OP_INFO_ENTRY (ACPI_OP_TYPE_OPCODE | OPTYPE_MONADIC2_r| AML_HAS_ARGS, "Data_op_region", ARGP_DATA_REGION_OP, ARGI_DATA_REGION_OP), + }; /* @@ -433,9 +483,10 @@ static ACPI_OPCODE_INFO aml_op_info[] = static u8 aml_short_op_info_index[256] = { /* 0 1 2 3 4 5 6 7 */ +/* 8 9 A B C D E F */ /* 0x00 */ 0x00, 0x01, _UNK, _UNK, _UNK, _UNK, 0x02, _UNK, -/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, _UNK, _UNK, -/* 0x10 */ 0x08, 0x09, 0x0a, _UNK, 0x0b, _UNK, _UNK, _UNK, +/* 0x08 */ 0x03, _UNK, 0x04, 0x05, 0x06, 0x07, 0x6E, _UNK, +/* 0x10 */ 0x08, 0x09, 0x0a, 0x6F, 0x0b, _UNK, _UNK, _UNK, /* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x20 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x28 */ _UNK, _UNK, _UNK, _UNK, _UNK, 0x63, _PFX, _PFX, @@ -449,10 +500,10 @@ static u8 aml_short_op_info_index[256] = /* 0x68 */ 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, _UNK, /* 0x70 */ 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, /* 0x78 */ 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, -/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, _UNK, _UNK, 0x2f, 0x30, -/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, _UNK, -/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, _UNK, _UNK, -/* 0x98 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, +/* 0x80 */ 0x2b, 0x2c, 0x2d, 0x2e, 0x70, 0x71, 0x2f, 0x30, +/* 0x88 */ 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x72, +/* 0x90 */ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x73, 0x74, +/* 0x98 */ 0x75, 0x76, _UNK, _UNK, 0x77, 0x78, 0x79, 0x7A, /* 0xA0 */ 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x60, 0x61, /* 0xA8 */ 0x62, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0xB0 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, @@ -471,10 +522,11 @@ static u8 aml_short_op_info_index[256] = static u8 aml_long_op_info_index[NUM_EXTENDED_OPCODE] = { /* 0 1 2 3 4 5 6 7 */ +/* 8 9 A B C D E F */ /* 0x00 */ _UNK, 0x46, 0x47, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x08 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x10 */ _UNK, _UNK, 0x48, 0x49, _UNK, _UNK, _UNK, _UNK, -/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, +/* 0x18 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, 0x7B, /* 0x20 */ 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, /* 0x28 */ 0x52, 0x53, 0x54, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x30 */ 0x55, 0x56, 0x57, _UNK, _UNK, _UNK, _UNK, _UNK, @@ -488,13 +540,10 @@ static u8 aml_long_op_info_index[NUM_EXTENDED_OPCODE] = /* 0x70 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x78 */ _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, _UNK, /* 0x80 */ 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, +/* 0x88 */ 0x7C, }; -/* 0 1 2 3 4 5 6 7 */ -/* 0x00 */ - - /******************************************************************************* * * FUNCTION: Acpi_ps_get_opcode_info diff --git a/drivers/acpi/parser/psparse.c b/drivers/acpi/parser/psparse.c index 7471efdcbaa7..dc6fcaee8964 100644 --- a/drivers/acpi/parser/psparse.c +++ b/drivers/acpi/parser/psparse.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: psparse - Parser top level AML parse routines - * $Revision: 71 $ + * $Revision: 73 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -537,6 +537,10 @@ acpi_ps_parse_loop ( */ status = acpi_ds_get_predicate_value (walk_state, NULL, TRUE); + if (ACPI_FAILURE (status)) { + return (status); + } + status = acpi_ps_next_parse_state (walk_state, op, status); } diff --git a/drivers/acpi/parser/psscope.c b/drivers/acpi/parser/psscope.c index 2e8926ad159b..37b5d22657eb 100644 --- a/drivers/acpi/parser/psscope.c +++ b/drivers/acpi/parser/psscope.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: psscope - Parser scope stack management routines - * $Revision: 22 $ + * $Revision: 24 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/parser/pstree.c b/drivers/acpi/parser/pstree.c index a22bb646df08..dc2e6d4d7370 100644 --- a/drivers/acpi/parser/pstree.c +++ b/drivers/acpi/parser/pstree.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: pstree - Parser op tree manipulation/traversal/search - * $Revision: 25 $ + * $Revision: 27 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/parser/psutils.c b/drivers/acpi/parser/psutils.c index 3bac4a647012..94518a920c33 100644 --- a/drivers/acpi/parser/psutils.c +++ b/drivers/acpi/parser/psutils.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: psutils - Parser miscellaneous utilities (Parser only) - * $Revision: 30 $ + * $Revision: 32 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/parser/pswalk.c b/drivers/acpi/parser/pswalk.c index 04a75917d6ff..48c11eff370b 100644 --- a/drivers/acpi/parser/pswalk.c +++ b/drivers/acpi/parser/pswalk.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: pswalk - Parser routines to walk parsed op tree(s) - * $Revision: 50 $ + * $Revision: 52 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/parser/psxface.c b/drivers/acpi/parser/psxface.c index a33ace05117f..296ddb1047a1 100644 --- a/drivers/acpi/parser/psxface.c +++ b/drivers/acpi/parser/psxface.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: psxface - Parser external interfaces - * $Revision: 37 $ + * $Revision: 39 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 0422bf94dfd9..d24392895c20 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c @@ -81,12 +81,12 @@ proc_read_ac_adapter_status(char *page, char **start, off_t off, buf.length = sizeof(obj); buf.pointer = &obj; if (!ACPI_SUCCESS(acpi_evaluate_object(ac_handle, "_PSR", NULL, &buf)) - || obj.type != ACPI_TYPE_NUMBER) { + || obj.type != ACPI_TYPE_INTEGER) { p += sprintf(p, "Could not read AC status\n"); goto end; } - if (obj.number.value) + if (obj.integer.value) p += sprintf(p, "on-line\n"); else p += sprintf(p, "off-line\n"); diff --git a/drivers/acpi/resources/rsaddr.c b/drivers/acpi/resources/rsaddr.c index e48666113f97..af91bc59fdca 100644 --- a/drivers/acpi/resources/rsaddr.c +++ b/drivers/acpi/resources/rsaddr.c @@ -4,12 +4,12 @@ * Acpi_rs_address16_stream * Acpi_rs_address32_resource * Acpi_rs_address32_stream - * $Revision: 12 $ + * $Revision: 14 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rscalc.c b/drivers/acpi/resources/rscalc.c index 2874aa3d0594..86ff91be87c5 100644 --- a/drivers/acpi/resources/rscalc.c +++ b/drivers/acpi/resources/rscalc.c @@ -2,12 +2,12 @@ * * Module Name: rscalc - Acpi_rs_calculate_byte_stream_length * Acpi_rs_calculate_list_length - * $Revision: 16 $ + * $Revision: 18 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rscreate.c b/drivers/acpi/resources/rscreate.c index bc95686a7a62..f221a41dc290 100644 --- a/drivers/acpi/resources/rscreate.c +++ b/drivers/acpi/resources/rscreate.c @@ -3,12 +3,12 @@ * Module Name: rscreate - Acpi_rs_create_resource_list * Acpi_rs_create_pci_routing_table * Acpi_rs_create_byte_stream - * $Revision: 22 $ + * $Revision: 24 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -223,9 +223,9 @@ acpi_rs_create_pci_routing_table ( /* * Dereference the Address */ - if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { + if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { user_prt->data.address = - (*sub_object_list)->number.value; + (*sub_object_list)->integer.value; } else { @@ -237,9 +237,9 @@ acpi_rs_create_pci_routing_table ( */ sub_object_list++; - if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { + if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { user_prt->data.pin = - (u32) (*sub_object_list)->number.value; + (u32) (*sub_object_list)->integer.value; } else { @@ -267,7 +267,7 @@ acpi_rs_create_pci_routing_table ( * is NULL, since the entire buffer was zeroed * out, we can leave this alone. */ - if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { + if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { /* * Add to the Length field the length of * the u32 NULL @@ -289,9 +289,9 @@ acpi_rs_create_pci_routing_table ( */ sub_object_list++; - if (ACPI_TYPE_NUMBER == (*sub_object_list)->common.type) { + if (ACPI_TYPE_INTEGER == (*sub_object_list)->common.type) { user_prt->data.source_index = - (u32) (*sub_object_list)->number.value; + (u32) (*sub_object_list)->integer.value; } else { diff --git a/drivers/acpi/resources/rsdump.c b/drivers/acpi/resources/rsdump.c index 073f4ddd4a1b..03d2da6f2150 100644 --- a/drivers/acpi/resources/rsdump.c +++ b/drivers/acpi/resources/rsdump.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: rsdump - Functions do dump out the resource structures. - * $Revision: 13 $ + * $Revision: 15 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rsio.c b/drivers/acpi/resources/rsio.c index 0d6c507c03db..58fcf8cd849b 100644 --- a/drivers/acpi/resources/rsio.c +++ b/drivers/acpi/resources/rsio.c @@ -6,12 +6,12 @@ * Acpi_rs_fixed_io_stream * Acpi_rs_dma_resource * Acpi_rs_dma_stream - * $Revision: 10 $ + * $Revision: 12 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rsirq.c b/drivers/acpi/resources/rsirq.c index 28a3a5045c16..eb47669ada22 100644 --- a/drivers/acpi/resources/rsirq.c +++ b/drivers/acpi/resources/rsirq.c @@ -4,12 +4,12 @@ * Acpi_rs_irq_stream * Acpi_rs_extended_irq_resource * Acpi_rs_extended_irq_stream - * $Revision: 11 $ + * $Revision: 13 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rslist.c b/drivers/acpi/resources/rslist.c index 8e39ddded00a..de47563d0f8e 100644 --- a/drivers/acpi/resources/rslist.c +++ b/drivers/acpi/resources/rslist.c @@ -2,12 +2,12 @@ * * Module Name: rslist - Acpi_rs_byte_stream_to_list * Acpi_list_to_byte_stream - * $Revision: 8 $ + * $Revision: 10 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rsmemory.c b/drivers/acpi/resources/rsmemory.c index 8aa4914f46ca..f9437e60c5cb 100644 --- a/drivers/acpi/resources/rsmemory.c +++ b/drivers/acpi/resources/rsmemory.c @@ -6,12 +6,12 @@ * Acpi_rs_fixed_memory32_resource * Acpi_rs_memory32_range_stream * Acpi_rs_fixed_memory32_stream - * $Revision: 10 $ + * $Revision: 12 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rsmisc.c b/drivers/acpi/resources/rsmisc.c index 01bbb377e32c..be0a1a6a002e 100644 --- a/drivers/acpi/resources/rsmisc.c +++ b/drivers/acpi/resources/rsmisc.c @@ -8,12 +8,12 @@ * Acpi_rs_end_dependent_functions_resource * Acpi_rs_start_dependent_functions_stream * Acpi_rs_end_dependent_functions_stream - * $Revision: 10 $ + * $Revision: 12 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rsutils.c b/drivers/acpi/resources/rsutils.c index 0a3f766680e9..2994bf0d300e 100644 --- a/drivers/acpi/resources/rsutils.c +++ b/drivers/acpi/resources/rsutils.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: rsutils - Utilities for the resource manager - * $Revision: 12 $ + * $Revision: 14 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/resources/rsxface.c b/drivers/acpi/resources/rsxface.c index 8691f8200b33..5c126aaa5f6e 100644 --- a/drivers/acpi/resources/rsxface.c +++ b/drivers/acpi/resources/rsxface.c @@ -1,12 +1,12 @@ /******************************************************************************* * * Module Name: rsxface - Public interfaces to the ACPI subsystem - * $Revision: 8 $ + * $Revision: 10 $ * ******************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/sys.c b/drivers/acpi/sys.c index 13648c255023..09781f97732d 100644 --- a/drivers/acpi/sys.c +++ b/drivers/acpi/sys.c @@ -60,8 +60,8 @@ acpi_enter_sx_async(void *context) arg_list.pointer = &arg; memset(&arg, 0, sizeof(arg)); - arg.type = ACPI_TYPE_NUMBER; - arg.number.value = ctx->state; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = ctx->state; acpi_evaluate_object(NULL, "\\_PTS", &arg_list, NULL); @@ -93,8 +93,8 @@ acpi_enter_sx_async(void *context) arg_list.pointer = &arg; memset(&arg, 0, sizeof(arg)); - arg.type = ACPI_TYPE_NUMBER; - arg.number.value = ctx->state; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = ctx->state; acpi_evaluate_object(NULL, "\\_WAK", &arg_list, NULL); diff --git a/drivers/acpi/tables/tbconvrt.c b/drivers/acpi/tables/tbconvrt.c index 624926d27a55..9984bcadb754 100644 --- a/drivers/acpi/tables/tbconvrt.c +++ b/drivers/acpi/tables/tbconvrt.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: tbconvrt - ACPI Table conversion utilities - * $Revision: 15 $ + * $Revision: 18 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -47,7 +47,7 @@ a.register_bit_width = (u8) MUL_8 (b);\ a.register_bit_offset = 0;\ a.reserved = 0;\ - a.address = (UINT64) c;} + ACPI_STORE_ADDRESS (a.address,c);} /* ACPI V1.0 entries -- address space is always I/O */ @@ -126,8 +126,8 @@ acpi_tb_convert_to_xsdt ( new_table->table_offset_entry[i] = ((RSDT_DESCRIPTOR_REV071 *) table_info->pointer)->table_offset_entry[i]; #else - new_table->table_offset_entry[i] = - ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]; + ACPI_STORE_ADDRESS (new_table->table_offset_entry[i], + ((RSDT_DESCRIPTOR_REV1 *) table_info->pointer)->table_offset_entry[i]); #endif } else { @@ -384,8 +384,8 @@ acpi_tb_convert_table_fadt (void) /* Convert table pointers to 64-bit fields */ - FADT2->Xfirmware_ctrl = (UINT64) FADT1->firmware_ctrl; - FADT2->Xdsdt = (UINT64) FADT1->dsdt; + ACPI_STORE_ADDRESS (FADT2->Xfirmware_ctrl, FADT1->firmware_ctrl); + ACPI_STORE_ADDRESS (FADT2->Xdsdt, FADT1->dsdt); /* System Interrupt Model isn't used in ACPI 2.0*/ /* FADT2->Reserved1 = 0; */ @@ -448,6 +448,7 @@ acpi_tb_convert_table_fadt (void) * Global FADT pointer will point to the common V2.0 FADT */ acpi_gbl_FADT = FADT2; + acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR); /* Free the original table */ @@ -464,8 +465,6 @@ acpi_tb_convert_table_fadt (void) table_desc->length = sizeof (FADT_DESCRIPTOR_REV2); - /* Dump the FADT Header */ - /* Dump the entire FADT */ diff --git a/drivers/acpi/tables/tbget.c b/drivers/acpi/tables/tbget.c index 2cf8eede7781..8e05e2c7df25 100644 --- a/drivers/acpi/tables/tbget.c +++ b/drivers/acpi/tables/tbget.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: tbget - ACPI Table get* routines - * $Revision: 40 $ + * $Revision: 43 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 @@ -243,7 +243,7 @@ acpi_tb_get_all_tables ( /* Get the table via the XSDT */ status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) - acpi_gbl_XSDT->table_offset_entry[index], + ACPI_GET_ADDRESS (acpi_gbl_XSDT->table_offset_entry[index]), table_ptr, &table_info); /* Ignore a table that failed verification */ @@ -326,7 +326,8 @@ acpi_tb_get_all_tables ( * Get the DSDT (We know that the FADT is valid now) */ - status = acpi_tb_get_table (acpi_gbl_FADT->Xdsdt, table_ptr, &table_info); + status = acpi_tb_get_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xdsdt), + table_ptr, &table_info); if (ACPI_FAILURE (status)) { return (status); } @@ -472,13 +473,14 @@ acpi_tb_get_table_rsdt ( /* 0.71 RSDP has 64bit Rsdt address field */ physical_address = ((RSDP_DESCRIPTOR_REV071 *)acpi_gbl_RSDP)->rsdt_physical_address; #else - physical_address = acpi_gbl_RSDP->rsdt_physical_address; + physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->rsdt_physical_address; #endif table_signature = RSDT_SIG; signature_length = sizeof (RSDT_SIG) -1; } else { - physical_address = (ACPI_PHYSICAL_ADDRESS) acpi_gbl_RSDP->xsdt_physical_address; + physical_address = (ACPI_PHYSICAL_ADDRESS) + ACPI_GET_ADDRESS (acpi_gbl_RSDP->xsdt_physical_address); table_signature = XSDT_SIG; signature_length = sizeof (XSDT_SIG) -1; } @@ -586,7 +588,7 @@ acpi_tb_get_table_facs ( else { /* Just map the physical memory to our address space */ - status = acpi_tb_map_acpi_table (acpi_gbl_FADT->Xfirmware_ctrl, + status = acpi_tb_map_acpi_table ((ACPI_PHYSICAL_ADDRESS) ACPI_GET_ADDRESS (acpi_gbl_FADT->Xfirmware_ctrl), &size, &table_ptr); if (ACPI_FAILURE(status)) { return (status); diff --git a/drivers/acpi/tables/tbinstal.c b/drivers/acpi/tables/tbinstal.c index b3926a0e36fd..e753917b79b8 100644 --- a/drivers/acpi/tables/tbinstal.c +++ b/drivers/acpi/tables/tbinstal.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: tbinstal - ACPI table installation and removal - * $Revision: 34 $ + * $Revision: 36 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index baae6fb4c8c4..d89b1508cece 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: tbutils - Table manipulation utilities - * $Revision: 31 $ + * $Revision: 33 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c index ee9eba62a02e..98c99873c65f 100644 --- a/drivers/acpi/tables/tbxface.c +++ b/drivers/acpi/tables/tbxface.c @@ -2,12 +2,12 @@ * * Module Name: tbxface - Public interfaces to the ACPI subsystem * ACPI table oriented interfaces - * $Revision: 32 $ + * $Revision: 34 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c index 4c31f1c37c65..606e8ad10497 100644 --- a/drivers/acpi/tables/tbxfroot.c +++ b/drivers/acpi/tables/tbxfroot.c @@ -1,12 +1,12 @@ /****************************************************************************** * * Module Name: tbxfroot - Find the root ACPI table (RSDT) - * $Revision: 33 $ + * $Revision: 35 $ * *****************************************************************************/ /* - * Copyright (C) 2000 R. Byron Moore + * Copyright (C) 2000, 2001 R. Byron Moore * * 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 diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index 2157f15703ca..5b602f9bac14 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -46,7 +46,7 @@ ifeq ($(CONFIG_ATM_FORE200E_SBA),y) endif endif -obj-$(CONFIG_ATM_FORE200E) += fore200e.o $(FORE200E_FW_OBJS) +obj-$(CONFIG_ATM_FORE200E) += fore_200e.o EXTRA_CFLAGS=-g diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index bf3d90d4b41e..d0aac4c7d15a 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c @@ -1862,13 +1862,9 @@ static int DAC960_MergeRequestsFunction(RequestQueue_T *RequestQueue, DAC960_Controller_T *Controller = (DAC960_Controller_T *) RequestQueue->queuedata; int TotalSegments = Request->nr_segments + NextRequest->nr_segments; - int SameSegment = 0; if (Request->bhtail->b_data + Request->bhtail->b_size == NextRequest->bh->b_data) - { TotalSegments--; - SameSegment = 1; - } if (TotalSegments > MaxSegments || TotalSegments > Controller->DriverScatterGatherLimit) return false; @@ -2831,6 +2827,7 @@ static void DAC960_RequestFunction(RequestQueue_T *RequestQueue) static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader, boolean SuccessfulIO) { + blk_finished_io(BufferHeader->b_size >> 9); BufferHeader->b_end_io(BufferHeader, SuccessfulIO); } diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 35afe2a7f1d3..47937edcc683 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1086,6 +1086,7 @@ static inline void complete_buffers( struct buffer_head *bh, int status) { xbh = bh->b_reqnext; bh->b_reqnext = NULL; + blk_finished_io(bh->b_size >> 9); bh->b_end_io(bh, status); bh = xbh; } diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c index 2f63f7a5bb80..7016cfff4921 100644 --- a/drivers/block/cpqarray.c +++ b/drivers/block/cpqarray.c @@ -376,12 +376,9 @@ static int cpq_merge_requests_fn(request_queue_t *q, struct request *rq, struct request *nxt, int max_segments) { int total_segments = rq->nr_segments + nxt->nr_segments; - int same_segment = 0; - if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data) { + if (rq->bhtail->b_data + rq->bhtail->b_size == nxt->bh->b_data) total_segments--; - same_segment = 1; - } if (total_segments > SG_MAX) return 0; @@ -909,17 +906,12 @@ static void do_ida_request(request_queue_t *q) struct buffer_head *bh; struct request *creq; - if (!q) - BUG(); - if (!h) - BUG(); - - if (q->plugged || list_empty(queue_head)) + if (q->plugged || list_empty(queue_head)) { + start_io(h); return; + } creq = blkdev_entry_next_request(queue_head); - if (creq->rq_status != RQ_ACTIVE) - BUG(); if (creq->nr_segments > SG_MAX) BUG(); @@ -927,6 +919,7 @@ static void do_ida_request(request_queue_t *q) { printk(KERN_WARNING "doreq cmd for %d, %x at %p\n", h->ctlr, creq->rq_dev, creq); + blkdev_dequeue_request(creq); complete_buffers(creq->bh, 0); start_io(h); return; @@ -961,11 +954,12 @@ DBGPX( c->req.sg[seg-1].size += bh->b_size; lastdataend += bh->b_size; } else { + if (seg == SG_MAX) + BUG(); c->req.sg[seg].size = bh->b_size; c->req.sg[seg].addr = (__u32)virt_to_bus(bh->b_data); lastdataend = bh->b_data + bh->b_size; - if (++seg == SG_MAX) - break; + seg++; } bh = bh->b_reqnext; } @@ -978,7 +972,7 @@ DBGPX( printk("Submitting %d sectors in %d segments\n", sect, seg); ); * is now fully setup and there's nothing left. */ if (creq->nr_sectors != sect) { - printk("ida: %ld sectors remain\n", creq->nr_sectors); + printk("ida: %ld != %d sectors\n", creq->nr_sectors, sect); BUG(); } @@ -1037,6 +1031,7 @@ static inline void complete_buffers(struct buffer_head *bh, int ok) xbh = bh->b_reqnext; bh->b_reqnext = NULL; + blk_finished_io(bh->b_size >> 9); bh->b_end_io(bh, ok); bh = xbh; diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index d0685dc18e50..98019ba5d264 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -328,13 +328,9 @@ static int ll_merge_requests_fn(request_queue_t *q, struct request *req, struct request *next, int max_segments) { int total_segments = req->nr_segments + next->nr_segments; - int same_segment; - same_segment = 0; - if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) { + if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) total_segments--; - same_segment = 1; - } if (total_segments > max_segments) return 0; diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h index 566bb339ce9c..101556540df1 100644 --- a/drivers/char/drm/drm.h +++ b/drivers/char/drm/drm.h @@ -374,15 +374,14 @@ typedef struct drm_agp_info { #define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) #define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) #define DRM_IOCTL_R128_RESET DRM_IO( 0x46) -#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t) -#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t) -#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) +#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) +#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t) /* Radeon specific ioctls */ #define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 5a869954b3cd..465fed249e36 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -70,7 +70,6 @@ extern int psaux_init(void); extern void gfx_register(void); #endif extern void streamable_init(void); -extern int rtc_sun_init(void); /* Combines MK48T02 and MK48T08 */ extern int rtc_DP8570A_init(void); extern int rtc_MK48T08_init(void); extern int ds1286_init(void); @@ -259,9 +258,6 @@ int __init misc_init(void) #ifdef CONFIG_BVME6000 rtc_DP8570A_init(); #endif -#if defined(CONFIG_SUN_MOSTEK_RTC) - rtc_sun_init(); -#endif #ifdef CONFIG_SGI_DS1286 ds1286_init(); #endif diff --git a/drivers/isdn/isdn_ppp.c b/drivers/isdn/isdn_ppp.c index 9d4d40a165e3..f1cbb8ab7102 100644 --- a/drivers/isdn/isdn_ppp.c +++ b/drivers/isdn/isdn_ppp.c @@ -2310,8 +2310,7 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc rsparm.data = rsdata; rsparm.maxdlen = IPPP_RESET_MAXDATABYTES; - /* !!!HACK,HACK,HACK!!! 2048 is only assumed */ - skb_out = dev_alloc_skb(2048); + skb_out = dev_alloc_skb(is->mru + PPP_HDRLEN); len = ipc->decompress(stat, skb, skb_out, &rsparm); kfree_skb(skb); if (len <= 0) { @@ -2332,14 +2331,9 @@ static struct sk_buff *isdn_ppp_decompress(struct sk_buff *skb,struct ippp_struc kfree_skb(skb_out); return NULL; } - - if (isdn_ppp_skip_ac(ri, skb) < 0) { - kfree_skb(skb); - return NULL; - } - *proto = isdn_ppp_strip_proto(skb); + *proto = isdn_ppp_strip_proto(skb_out); if (*proto < 0) { - kfree_skb(skb); + kfree_skb(skb_out); return NULL; } return skb_out; diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 7981fe764449..3ad3940a9b5e 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c @@ -714,6 +714,11 @@ static void compute_parity(struct stripe_head *sh, int method) break; } spin_unlock_irq(&conf->device_lock); + if (count>1) { + xor_block(count, bh_ptr); + count = 1; + } + for (i = disks; i--;) if (chosen[i]) { struct buffer_head *bh = sh->bh_cache[i]; diff --git a/drivers/md/xor.c b/drivers/md/xor.c index b9b1cefe9e94..f0b76d4663c2 100644 --- a/drivers/md/xor.c +++ b/drivers/md/xor.c @@ -57,8 +57,7 @@ xor_block(unsigned int count, struct buffer_head **bh_ptr) /* Set of all registered templates. */ static struct xor_block_template *template_list; -/* The -6*32 shift factor colors the cache. */ -#define BENCH_SIZE (PAGE_SIZE-6*32) +#define BENCH_SIZE (PAGE_SIZE) static void do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 7dab437e6796..3ec09be5a737 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c @@ -153,7 +153,7 @@ static int check_crc_flex(unsigned char *cp, int size) /* Find a free channel, and link in this `tty' line. */ static inline struct ax_disp *ax_alloc(void) { - ax25_ctrl_t *axp; + ax25_ctrl_t *axp=NULL; int i; for (i = 0; i < ax25_maxdev; i++) { diff --git a/drivers/net/hamradio/scc.c b/drivers/net/hamradio/scc.c index d65fddc415e0..cc31e9e3011f 100644 --- a/drivers/net/hamradio/scc.c +++ b/drivers/net/hamradio/scc.c @@ -136,7 +136,7 @@ /* ----------------------------------------------------------------------- */ -#undef SCC_LDELAY 1 /* slow it even a bit more down */ +#undef SCC_LDELAY /* slow it even a bit more down */ #undef SCC_DONT_CHECK /* don't look if the SCCs you specified are available */ #define SCC_MAXCHIPS 4 /* number of max. supported chips */ @@ -1776,7 +1776,7 @@ static int scc_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) if (hwcfg.vector_latch) { if (!request_region(Vector_Latch, 1, "scc vector latch")) - printk(KERN_WARNING "z8530drv: warning, cannot reserve vector latch port 0x%x\n, disabled.", hwcfg.vector_latch); + printk(KERN_WARNING "z8530drv: warning, cannot reserve vector latch port 0x%x\n, disabled.", (unsigned int)hwcfg.vector_latch); else Vector_Latch = hwcfg.vector_latch; } diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c index ba9c60250d45..56ca24689517 100644 --- a/drivers/net/myri_sbus.c +++ b/drivers/net/myri_sbus.c @@ -892,6 +892,9 @@ static int __init myri_ether_init(struct net_device *dev, struct sbus_dev *sdev, DET(("myri_ether_init(%p,%p,%d):\n", dev, sdev, num)); dev = init_etherdev(0, sizeof(struct myri_eth)); + if (!dev) + return -ENOMEM; + if (version_printed++ == 0) printk(version); @@ -982,7 +985,7 @@ static int __init myri_ether_init(struct net_device *dev, struct sbus_dev *sdev, mp->reg_size, "MyriCOM Regs"); if (!mp->regs) { printk("MyriCOM: Cannot map MyriCOM registers.\n"); - return -ENODEV; + goto err; } mp->lanai = (unsigned short *) (mp->regs + (256 * 1024)); mp->lanai3 = (unsigned int *) mp->lanai; @@ -1059,7 +1062,7 @@ static int __init myri_ether_init(struct net_device *dev, struct sbus_dev *sdev, if (request_irq(dev->irq, &myri_interrupt, SA_SHIRQ, "MyriCOM Ethernet", (void *) dev)) { printk("MyriCOM: Cannot register interrupt handler.\n"); - return -ENODEV; + goto err; } DET(("ether_setup()\n")); @@ -1083,6 +1086,9 @@ static int __init myri_ether_init(struct net_device *dev, struct sbus_dev *sdev, root_myri_dev = mp; #endif return 0; +err: unregister_netdev(dev); + kfree(dev); + return -ENODEV; } static int __init myri_sbus_match(struct sbus_dev *sdev) diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 8744f6186457..1cdec0a45faf 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c @@ -5,23 +5,24 @@ * PPPoE --- PPP over Ethernet (RFC 2516) * * - * Version: 0.6.4 + * Version: 0.6.5 * * 030700 : Fixed connect logic to allow for disconnect. - * 270700 : Fixed potential SMP problems; we must protect against - * simultaneous invocation of ppp_input + * 270700 : Fixed potential SMP problems; we must protect against + * simultaneous invocation of ppp_input * and ppp_unregister_channel. * 040800 : Respect reference count mechanisms on net-devices. * 200800 : fix kfree(skb) in pppoe_rcv (acme) * Module reference count is decremented in the right spot now, - * guards against sock_put not actually freeing the sk + * guards against sock_put not actually freeing the sk * in pppoe_release. * 051000 : Initialization cleanup. * 111100 : Fix recvmsg. + * 050101 : Fix PADT procesing. * * Author: Michal Ostrowski <mostrows@styx.uwaterloo.ca> * Contributors: - * Arnaldo Carvalho de Melo <acme@conectiva.com.br> + * Arnaldo Carvalho de Melo <acme@xconectiva.com.br> * * License: * This program is free software; you can redistribute it and/or @@ -110,7 +111,7 @@ static int hash_item(unsigned long sid, unsigned char *addr) hash ^= sid >> (i*PPPOE_HASH_BITS); return hash & ( PPPOE_HASH_SIZE - 1 ); -} +} static struct pppox_opt *item_hash_table[PPPOE_HASH_SIZE] = { 0, }; @@ -238,7 +239,7 @@ static int pppoe_device_event(struct notifier_block *this, struct net_device *dev = (struct net_device *) ptr; struct pppox_opt *po = NULL; int hash = 0; - + /* Only look at sockets that are using this specific device. */ switch (event) { case NETDEV_CHANGEMTU: @@ -255,13 +256,13 @@ static int pppoe_device_event(struct notifier_block *this, po = item_hash_table[hash]; ++hash; } - + while (po && hash < PPPOE_HASH_SIZE){ if(po->pppoe_dev == dev){ lock_sock(po->sk); if (po->sk->state & (PPPOX_CONNECTED|PPPOX_BOUND)){ pppox_unbind_sock(po->sk); - + dev_put(po->pppoe_dev); po->pppoe_dev = NULL; @@ -308,7 +309,7 @@ int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb){ if (sk->state & PPPOX_BOUND) { skb_pull(skb, sizeof(struct pppoe_hdr)); - + ppp_input(&po->chan, skb); } else if( sk->state & PPPOX_RELAY ){ @@ -318,7 +319,7 @@ int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb){ !( relay_po->sk->state & PPPOX_CONNECTED ) ){ goto abort; } - + skb_pull(skb, sizeof(struct pppoe_hdr)); if( !__pppoe_xmit( relay_po->sk , skb) ){ goto abort; @@ -369,7 +370,7 @@ static int pppoe_rcv(struct sk_buff *skb, }else{ ret = pppoe_rcv_core(sk, skb); } - + bh_unlock_sock(sk); sock_put(sk); return ret; @@ -466,9 +467,9 @@ static int pppoe_create(struct socket *sock) { int error = 0; struct sock *sk; - + MOD_INC_USE_COUNT; - + sk = sk_alloc(PF_PPPOX, GFP_KERNEL, 1); if (!sk) return -ENOMEM; @@ -528,7 +529,7 @@ int pppoe_release(struct socket *sock) po = sk->protinfo.pppox; if (po->pppoe_pa.sid) delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote); - + if (po->pppoe_dev) dev_put(po->pppoe_dev); @@ -945,7 +946,7 @@ int pppoe_proc_info(char *buffer, char **start, off_t offset, int length) off_t begin = 0; int size; int i; - + len += sprintf(buffer, "Id Address Device\n"); pos = len; @@ -1025,9 +1026,10 @@ int __init pppoe_init(void) int err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto); if (err == 0) { - printk(KERN_INFO "Registered PPPoE v0.6.4\n"); + printk(KERN_INFO "Registered PPPoE v0.6.5\n"); dev_add_pack(&pppoes_ptype); + dev_add_pack(&pppoed_ptype); register_netdevice_notifier(&pppoe_notifier); proc_net_create("pppoe", 0, pppoe_proc_info); } @@ -1038,6 +1040,7 @@ void __exit pppoe_exit(void) { unregister_pppox_proto(PX_PROTO_OE); dev_remove_pack(&pppoes_ptype); + dev_remove_pack(&pppoed_ptype); unregister_netdevice_notifier(&pppoe_notifier); proc_net_remove("pppoe"); } diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c index 3036684f9835..2535485992ad 100644 --- a/drivers/net/sunbmac.c +++ b/drivers/net/sunbmac.c @@ -1,12 +1,9 @@ -/* $Id: sunbmac.c,v 1.21 2000/10/22 16:08:38 davem Exp $ +/* $Id: sunbmac.c,v 1.23 2001/01/20 03:36:40 davem Exp $ * sunbmac.c: Driver for Sparc BigMAC 100baseT ethernet adapters. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) */ -static char *version = - "sunbmac.c:v1.9 11/Sep/99 David S. Miller (davem@redhat.com)\n"; - #include <linux/module.h> #include <linux/kernel.h> @@ -41,6 +38,9 @@ static char *version = #include "sunbmac.h" +static char version[] __initdata = + "sunbmac.c:v1.9 11/Sep/99 David S. Miller (davem@redhat.com)\n"; + #undef DEBUG_PROBE #undef DEBUG_TX #undef DEBUG_IRQ @@ -1051,10 +1051,10 @@ static void bigmac_set_multicast(struct net_device *dev) static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec_sdev) { - static int version_printed = 0; - struct bigmac *bp = 0; + static int version_printed; + struct bigmac *bp; u8 bsizes, bsizes_more; - int i, res = ENOMEM; + int i; /* Get a new device struct for this interface. */ dev = init_etherdev(0, sizeof(struct bigmac)); @@ -1062,6 +1062,9 @@ static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec if (version_printed++ == 0) printk(KERN_INFO "%s", version); + if (!dev) + return -ENOMEM; + /* Report what we have found to the user. */ printk(KERN_INFO "%s: BigMAC 100baseT Ethernet ", dev->name); dev->base_addr = (long) qec_sdev; @@ -1077,9 +1080,6 @@ static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec spin_lock_init(&bp->lock); - /* All further failures we find return this. */ - res = ENODEV; - /* Verify the registers we expect, are actually there. */ if ((bp->bigmac_sdev->num_registers != 3) || (bp->qec_sdev->num_registers != 2)) { @@ -1205,28 +1205,25 @@ static int __init bigmac_ether_init(struct net_device *dev, struct sbus_dev *qec fail_and_cleanup: /* Something went wrong, undo whatever we did so far. */ - if (bp) { - /* Free register mappings if any. */ - if (bp->gregs) - sbus_iounmap(bp->gregs, GLOB_REG_SIZE); - if (bp->creg) - sbus_iounmap(bp->creg, CREG_REG_SIZE); - if (bp->bregs) - sbus_iounmap(bp->bregs, BMAC_REG_SIZE); - if (bp->tregs) - sbus_iounmap(bp->tregs, TCVR_REG_SIZE); - - if (bp->bmac_block) - sbus_free_consistent(bp->bigmac_sdev, - PAGE_SIZE, - bp->bmac_block, - bp->bblock_dvma); - - /* Free the BigMAC softc. */ - kfree(bp); - dev->priv = 0; - } - return res; /* Return error code. */ + /* Free register mappings if any. */ + if (bp->gregs) + sbus_iounmap(bp->gregs, GLOB_REG_SIZE); + if (bp->creg) + sbus_iounmap(bp->creg, CREG_REG_SIZE); + if (bp->bregs) + sbus_iounmap(bp->bregs, BMAC_REG_SIZE); + if (bp->tregs) + sbus_iounmap(bp->tregs, TCVR_REG_SIZE); + + if (bp->bmac_block) + sbus_free_consistent(bp->bigmac_sdev, + PAGE_SIZE, + bp->bmac_block, + bp->bblock_dvma); + + unregister_netdev(dev); + kfree(dev); + return -ENODEV; } /* QEC can be the parent of either QuadEthernet or diff --git a/drivers/net/tulip/ChangeLog b/drivers/net/tulip/ChangeLog index dfac943492b9..bb5b70f019d5 100644 --- a/drivers/net/tulip/ChangeLog +++ b/drivers/net/tulip/ChangeLog @@ -1,7 +1,37 @@ -2000-12-17 Alan Cox <alan@redhat.com> +2001-01-16 Jeff Garzik <jgarzik@mandrakesoft.com> - * merge support for the Davicom's quirks into the main tulip. Patch - by Tobias Ringstrom + * tulip_core.c: static vars no longer explicitly + initialized to zero. + * eeprom.c (tulip_read_eeprom): Make sure to delay between + EE_ENB and EE_ENB|EE_SHIFT_CLK. Merged from becker tulip.c. + +2001-01-05 Peter De Schrijver <p2@mind.be> + + * eeprom.c (tulip_parse_eeprom): Interpret a bit more of 21142 + extended format type 3 info blocks in a tulip SROM. + +2001-01-03 Matti Aarnio <matti.aarnio@zmailer.org> + + * media.c (tulip_select_media): Support media types 5 and 6 + +2001-??-?? ?? + + * tulip_core.c: Add comment about LanMedia needing + a different driver. + Enable workarounds for early PCI chipsets. + Add IA64 csr0 support, update HPPA csr0 support. + +2000-12-17 Alan Cox <alan@redhat.com> + + * eeprom.c, timer.c, tulip.h, tulip_core.c: Merge support + for the Davicom's quirks into the main tulip. + Patch by Tobias Ringstrom + +2000-11-08 Jim Studt <jim@federated.com> + + * eeprom.c (tulip_parse_eeprom): Check array bounds for + medianame[] and block_name[] arrays to avoid oops due + to bad values returned from hardware. 2000-11-02 Jeff Garzik <jgarzik@mandrakesoft.com> diff --git a/drivers/net/tulip/eeprom.c b/drivers/net/tulip/eeprom.c index 49e8bf42e772..f42baefc2ac3 100644 --- a/drivers/net/tulip/eeprom.c +++ b/drivers/net/tulip/eeprom.c @@ -207,8 +207,13 @@ subsequent_board: p += (p[0] & 0x3f) + 1; continue; } else if (p[1] & 1) { + int gpr_len, reset_len; + mtable->has_mii = 1; leaf->media = 11; + gpr_len=p[3]*2; + reset_len=p[4+gpr_len]*2; + new_advertise |= get_u16(&p[7+gpr_len+reset_len]); } else { mtable->has_nonmii = 1; leaf->media = p[2] & 0x0f; @@ -247,9 +252,9 @@ subsequent_board: } printk(KERN_INFO "%s: Index #%d - Media %s (#%d) described " "by a %s (%d) block.\n", - dev->name, i, medianame[leaf->media], leaf->media, - leaf->type >= ARRAY_SIZE(block_name) ? "UNKNOWN" : - block_name[leaf->type], leaf->type); + dev->name, i, medianame[leaf->media & 15], leaf->media, + leaf->type < ARRAY_SIZE(block_name) ? block_name[leaf->type] : "<unknown>", + leaf->type); } if (new_advertise) tp->to_advertise = new_advertise; @@ -278,6 +283,7 @@ int __devinit tulip_read_eeprom(long ioaddr, int location, int addr_len) retval = (retval << 1) | ((inl(ee_addr) & EE_DATA_READ) ? 1 : 0); } outl(EE_ENB, ee_addr); + eeprom_delay(); for (i = 16; i > 0; i--) { outl(EE_ENB | EE_SHIFT_CLK, ee_addr); diff --git a/drivers/net/tulip/media.c b/drivers/net/tulip/media.c index b8203f33a6fd..bc8e7bbbcb6b 100644 --- a/drivers/net/tulip/media.c +++ b/drivers/net/tulip/media.c @@ -148,7 +148,7 @@ void tulip_select_media(struct net_device *dev, int startup) long ioaddr = dev->base_addr; struct tulip_private *tp = (struct tulip_private *)dev->priv; struct mediatable *mtable = tp->mtable; - u32 new_csr6; + u32 new_csr6=0; int i; if (mtable) { @@ -265,7 +265,9 @@ void tulip_select_media(struct net_device *dev, int startup) } case 5: case 6: { u16 setup[5]; - u32 csr13val, csr14val, csr15dir, csr15val; + + new_csr6 = 0; /* FIXME */ + for (i = 0; i < 5; i++) setup[i] = get_u16(&p[i*2 + 1]); diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index 765cd6c7cdde..0517b90af83c 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c @@ -28,7 +28,7 @@ #include <asm/unaligned.h> static char version[] __devinitdata = - "Linux Tulip driver version 0.9.13 (January 2, 2001)\n"; + "Linux Tulip driver version 0.9.13a (January 20, 2001)\n"; /* A few user-configurable values. */ diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index eaba0cd3415f..3f23aec1c1a7 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -45,25 +45,10 @@ #include <linux/lapb.h> #include <linux/init.h> -static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; - -static int lapbeth_rcv(struct sk_buff *, struct net_device *, struct packet_type *); -static int lapbeth_device_event(struct notifier_block *, unsigned long, void *); - -static struct packet_type lapbeth_packet_type = { - 0, /* ntohs(ETH_P_DEC),*/ - 0, /* copy */ - lapbeth_rcv, - NULL, - NULL, -}; - -static struct notifier_block lapbeth_dev_notifier = { - lapbeth_device_event, - 0 -}; - +static char bcast_addr[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; +/* If this number is made larger, check that the temporary string buffer + * in lapbeth_new_device is large enough to store the probe device name.*/ #define MAXLAPBDEV 100 static struct lapbethdev { @@ -72,29 +57,14 @@ static struct lapbethdev { struct net_device *ethdev; /* link to ethernet device */ struct net_device axdev; /* lapbeth device (lapb#) */ struct net_device_stats stats; /* some statistics */ -} *lapbeth_devices = NULL; - +} *lapbeth_devices /* = NULL initially */; /* ------------------------------------------------------------------------ */ - -/* - * Get the ethernet device for a LAPB device - */ -#if 0 -static __inline__ struct net_device *lapbeth_get_ether_dev(struct net_device *dev) -{ - struct lapbethdev *lapbeth; - - lapbeth = (struct lapbethdev *)dev->priv; - - return (lapbeth != NULL) ? lapbeth->ethdev : NULL; -} -#endif /* * Get the LAPB device for the ethernet device */ -static __inline__ struct net_device *lapbeth_get_x25_dev(struct net_device *dev) +static inline struct net_device *lapbeth_get_x25_dev(struct net_device *dev) { struct lapbethdev *lapbeth; @@ -105,7 +75,7 @@ static __inline__ struct net_device *lapbeth_get_x25_dev(struct net_device *dev) return NULL; } -static __inline__ int dev_is_ethdev(struct net_device *dev) +static inline int dev_is_ethdev(struct net_device *dev) { return ( dev->type == ARPHRD_ETHER @@ -122,7 +92,7 @@ static int lapbeth_check_devices(struct net_device *dev) struct lapbethdev *lapbeth, *lapbeth_prev; int result = 0; unsigned long flags; - + save_flags(flags); cli(); @@ -134,7 +104,7 @@ static int lapbeth_check_devices(struct net_device *dev) lapbeth_prev->next = lapbeth->next; else lapbeth_devices = lapbeth->next; - + if (&lapbeth->axdev == dev) result = 1; @@ -145,16 +115,14 @@ static int lapbeth_check_devices(struct net_device *dev) lapbeth_prev = lapbeth; } - + restore_flags(flags); - + return result; } - /* ------------------------------------------------------------------------ */ - /* * Receive a LAPB frame via an ethernet interface. */ @@ -164,7 +132,7 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe struct lapbethdev *lapbeth; skb->sk = NULL; /* Initially we don't know who it's for */ - + dev = lapbeth_get_x25_dev(dev); if (dev == NULL || !netif_running(dev)) { @@ -172,7 +140,7 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe return 0; } - lapbeth = (struct lapbethdev *)dev->priv; + lapbeth = (struct lapbethdev *) dev->priv; lapbeth->stats.rx_packets++; @@ -191,7 +159,7 @@ static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packe static int lapbeth_data_indication(void *token, struct sk_buff *skb) { - struct lapbethdev *lapbeth = (struct lapbethdev *)token; + struct lapbethdev *lapbeth = (struct lapbethdev *) token; unsigned char *ptr; ptr = skb_push(skb, 1); @@ -206,14 +174,12 @@ static int lapbeth_data_indication(void *token, struct sk_buff *skb) } /* - * Send a LAPB frame via an ethernet interface + * Send a LAPB frame via an ethernet interface */ static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) { - struct lapbethdev *lapbeth; + struct lapbethdev *lapbeth = (struct lapbethdev *) dev->priv; int err; - - lapbeth = (struct lapbethdev *)dev->priv; /* * Just to be *really* sure not to send anything if the interface @@ -253,10 +219,10 @@ static int lapbeth_xmit(struct sk_buff *skb, struct net_device *dev) return 0; } - + static void lapbeth_data_transmit(void *token, struct sk_buff *skb) { - struct lapbethdev *lapbeth = (struct lapbethdev *)token; + struct lapbethdev *lapbeth = (struct lapbethdev *) token; unsigned char *ptr; struct net_device *dev; int size; @@ -281,7 +247,7 @@ static void lapbeth_data_transmit(void *token, struct sk_buff *skb) static void lapbeth_connected(void *token, int reason) { - struct lapbethdev *lapbeth = (struct lapbethdev *)token; + struct lapbethdev *lapbeth = (struct lapbethdev *) token; struct sk_buff *skb; unsigned char *ptr; @@ -303,7 +269,7 @@ static void lapbeth_connected(void *token, int reason) static void lapbeth_disconnected(void *token, int reason) { - struct lapbethdev *lapbeth = (struct lapbethdev *)token; + struct lapbethdev *lapbeth = (struct lapbethdev *) token; struct sk_buff *skb; unsigned char *ptr; @@ -328,10 +294,7 @@ static void lapbeth_disconnected(void *token, int reason) */ static struct net_device_stats *lapbeth_get_stats(struct net_device *dev) { - struct lapbethdev *lapbeth; - - lapbeth = (struct lapbethdev *)dev->priv; - + struct lapbethdev *lapbeth = (struct lapbethdev *) dev->priv; return &lapbeth->stats; } @@ -340,18 +303,11 @@ static struct net_device_stats *lapbeth_get_stats(struct net_device *dev) */ static int lapbeth_set_mac_address(struct net_device *dev, void *addr) { - struct sockaddr *sa = (struct sockaddr *)addr; - + struct sockaddr *sa = (struct sockaddr *) addr; memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); - return 0; } -static int lapbeth_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -{ - return -EINVAL; -} - /* * open/close a device */ @@ -363,8 +319,8 @@ static int lapbeth_open(struct net_device *dev) if (lapbeth_check_devices(dev)) return -ENODEV; /* oops, it's gone */ - - lapbeth = (struct lapbethdev *)dev->priv; + + lapbeth = (struct lapbethdev *) dev->priv; lapbeth_callbacks.connect_confirmation = lapbeth_connected; lapbeth_callbacks.connect_indication = lapbeth_connected; @@ -378,31 +334,20 @@ static int lapbeth_open(struct net_device *dev) return -ENODEV; } - MOD_INC_USE_COUNT; netif_start_queue(dev); - return 0; } static int lapbeth_close(struct net_device *dev) { - struct lapbethdev *lapbeth; + struct lapbethdev *lapbeth = (struct lapbethdev *) dev->priv; int err; netif_stop_queue(dev); - - lapbeth = (struct lapbethdev *)dev->priv; if ((err = lapb_unregister(lapbeth)) != LAPB_OK) printk(KERN_ERR "lapbeth: lapb_unregister error - %d\n", err); - MOD_DEC_USE_COUNT; - - return 0; -} - -static int lapbeth_dev_init(struct net_device *dev) -{ return 0; } @@ -414,14 +359,14 @@ static int lapbeth_dev_init(struct net_device *dev) static int lapbeth_new_device(struct net_device *dev) { int k; - unsigned char *buf; + unsigned char buf[14]; struct lapbethdev *lapbeth, *lapbeth2; - + if ((lapbeth = kmalloc(sizeof(struct lapbethdev), GFP_KERNEL)) == NULL) return -ENOMEM; - + memset(lapbeth, 0, sizeof(struct lapbethdev)); - + dev_hold(dev); lapbeth->ethdev = dev; @@ -429,7 +374,7 @@ static int lapbeth_new_device(struct net_device *dev) strncpy(lapbeth->ethname, dev->name, sizeof(lapbeth->ethname)-1); dev = &lapbeth->axdev; - buf = kmalloc(14, GFP_KERNEL); + SET_MODULE_OWNER(dev); for (k = 0; k < MAXLAPBDEV; k++) { struct net_device *odev; @@ -445,10 +390,9 @@ static int lapbeth_new_device(struct net_device *dev) kfree(lapbeth); return -ENODEV; } - + dev->priv = (void *)lapbeth; /* pointer back */ strcpy(dev->name, buf); - dev->init = lapbeth_dev_init; if (register_netdev(dev) != 0) { dev_put(dev); @@ -463,10 +407,6 @@ static int lapbeth_new_device(struct net_device *dev) dev->stop = lapbeth_close; dev->set_mac_address = lapbeth_set_mac_address; dev->get_stats = lapbeth_get_stats; - dev->do_ioctl = lapbeth_ioctl; - - dev->flags = 0; - dev->type = ARPHRD_X25; dev->hard_header_len = 3; dev->mtu = 1000; @@ -480,20 +420,19 @@ static int lapbeth_new_device(struct net_device *dev) for (lapbeth2 = lapbeth_devices; lapbeth2->next != NULL; lapbeth2 = lapbeth2->next); lapbeth2->next = lapbeth; } - + sti(); return 0; } - /* * Handle device status changes. */ -static int lapbeth_device_event(struct notifier_block *this,unsigned long event, void *ptr) +static int lapbeth_device_event(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev = (struct net_device *)ptr; - + struct net_device *dev = (struct net_device *) ptr; + if (!dev_is_ethdev(dev)) return NOTIFY_DONE; @@ -518,23 +457,28 @@ static int lapbeth_device_event(struct notifier_block *this,unsigned long event, return NOTIFY_DONE; } - /* ------------------------------------------------------------------------ */ -/* - * Initialize driver. To be called from af_ax25 if not compiled as a - * module - */ -int lapbeth_init(void) +static struct packet_type lapbeth_packet_type = { + type: __constant_htons(ETH_P_DEC), + func: lapbeth_rcv, +}; + +static struct notifier_block lapbeth_dev_notifier = { + notifier_call: lapbeth_device_event, +}; + +static const char banner[] __initdata = KERN_INFO "LAPB Ethernet driver version 0.01\n"; + +static int __init lapbeth_init_driver(void) { struct net_device *dev; - lapbeth_packet_type.type = htons(ETH_P_DEC); dev_add_pack(&lapbeth_packet_type); register_netdevice_notifier(&lapbeth_dev_notifier); - printk(KERN_INFO "LAPB Ethernet driver version 0.01\n"); + printk(banner); read_lock_bh(&dev_base_lock); for (dev = dev_base; dev != NULL; dev = dev->next) { @@ -548,19 +492,9 @@ int lapbeth_init(void) return 0; } +module_init(lapbeth_init_driver); -#ifdef MODULE -EXPORT_NO_SYMBOLS; - -MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>"); -MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver"); - -int init_module(void) -{ - return lapbeth_init(); -} - -void cleanup_module(void) +static void __exit lapbeth_cleanup_driver(void) { struct lapbethdev *lapbeth; @@ -571,4 +505,10 @@ void cleanup_module(void) for (lapbeth = lapbeth_devices; lapbeth != NULL; lapbeth = lapbeth->next) unregister_netdev(&lapbeth->axdev); } -#endif +module_exit(lapbeth_cleanup_driver); + +EXPORT_NO_SYMBOLS; + +MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>"); +MODULE_DESCRIPTION("The unofficial LAPB over Ethernet driver"); + diff --git a/drivers/net/wan/lmc/lmc.h b/drivers/net/wan/lmc/lmc.h index 91b9e8f00ee1..882e58c1bfd7 100644 --- a/drivers/net/wan/lmc/lmc.h +++ b/drivers/net/wan/lmc/lmc.h @@ -29,4 +29,5 @@ extern lmc_media_t lmc_hssi_media; static void lmcEventLog( u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3 ); #endif -#endif
\ No newline at end of file +#endif + diff --git a/drivers/net/wan/lmc/lmc_media.h b/drivers/net/wan/lmc/lmc_media.h index 7cc6c1650ffc..ddcc00403563 100644 --- a/drivers/net/wan/lmc/lmc_media.h +++ b/drivers/net/wan/lmc/lmc_media.h @@ -61,4 +61,5 @@ lmc_media_t lmc_t1_media = { }; -#endif
\ No newline at end of file +#endif + diff --git a/drivers/net/wan/lmc/lmc_prot.h b/drivers/net/wan/lmc/lmc_prot.h index 859ef0f006a1..f3b1df9e2cdb 100644 --- a/drivers/net/wan/lmc/lmc_prot.h +++ b/drivers/net/wan/lmc/lmc_prot.h @@ -11,4 +11,5 @@ void lmc_proto_close(lmc_softc_t *sc const) unsigned short lmc_proto_type(lmc_softc_t *sc const, struct skbuff *skb) -#endif
\ No newline at end of file +#endif + diff --git a/drivers/net/wan/lmc/lmc_proto.h b/drivers/net/wan/lmc/lmc_proto.h index 6136dfad7516..080a55773349 100644 --- a/drivers/net/wan/lmc/lmc_proto.h +++ b/drivers/net/wan/lmc/lmc_proto.h @@ -12,4 +12,5 @@ unsigned short lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb); void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb); int lmc_skb_rawpackets(char *buf, char **start, off_t offset, int len, int unused); -#endif
\ No newline at end of file +#endif + diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c index ef489b1a687f..1eb66b44e7cd 100644 --- a/drivers/net/wan/sdla.c +++ b/drivers/net/wan/sdla.c @@ -744,7 +744,7 @@ static void sdla_receive(struct net_device *dev) struct buf_entry *pbuf; unsigned long flags; - int i, received, success, addr, buf_base, buf_top; + int i=0, received, success, addr, buf_base, buf_top; short dlci, len, len2, split; flp = dev->priv; diff --git a/drivers/sbus/audio/Config.in b/drivers/sbus/audio/Config.in index a9419f78ce24..40a431f81f62 100644 --- a/drivers/sbus/audio/Config.in +++ b/drivers/sbus/audio/Config.in @@ -8,9 +8,11 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then comment 'Linux/SPARC audio subsystem (EXPERIMENTAL)' tristate 'Audio support (EXPERIMENTAL)' CONFIG_SPARCAUDIO - dep_tristate ' AMD7930 Lowlevel Driver' CONFIG_SPARCAUDIO_AMD7930 $CONFIG_SPARCAUDIO + if [ "$CONFIG_SPARC64" != "y" ]; then + dep_tristate ' AMD7930 Lowlevel Driver' CONFIG_SPARCAUDIO_AMD7930 $CONFIG_SPARCAUDIO + dep_tristate ' DBRI Lowlevel Driver' CONFIG_SPARCAUDIO_DBRI $CONFIG_SPARCAUDIO + fi dep_tristate ' CS4231 Lowlevel Driver' CONFIG_SPARCAUDIO_CS4231 $CONFIG_SPARCAUDIO - dep_tristate ' DBRI Lowlevel Driver' CONFIG_SPARCAUDIO_DBRI $CONFIG_SPARCAUDIO dep_tristate ' Dummy Lowlevel Driver' CONFIG_SPARCAUDIO_DUMMY $CONFIG_SPARCAUDIO endmenu fi diff --git a/drivers/sbus/audio/amd7930.c b/drivers/sbus/audio/amd7930.c index f3f593bce38d..1ddfb5017cb0 100644 --- a/drivers/sbus/audio/amd7930.c +++ b/drivers/sbus/audio/amd7930.c @@ -1,4 +1,4 @@ -/* $Id: amd7930.c,v 1.24 2000/01/22 05:10:27 anton Exp $ +/* $Id: amd7930.c,v 1.25 2001/01/08 04:19:16 davem Exp $ * drivers/sbus/audio/amd7930.c * * Copyright (C) 1996,1997 Thomas K. Dyas (tdyas@eden.rutgers.edu) @@ -107,7 +107,7 @@ static __u8 mulaw2bilinear(__u8 data); static __u8 linear2mulaw(__u16 data); static __u16 mulaw2linear(__u8 data); -#if defined (AMD79C30_ISDN) || defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff +#if defined (AMD79C30_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff #include "../../isdn/hisax/hisax.h" #include "../../isdn/hisax/isdnl1.h" #include "../../isdn/hisax/foreign.h" @@ -1131,7 +1131,7 @@ static int amd7930_ioctl(struct inode * inode, struct file * file, * */ -#if defined (AMD79C30_ISDN) || defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff +#if defined (AMD79C30_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff static int amd7930_get_irqnum(int dev) { struct amd7930_info *info; diff --git a/drivers/sbus/audio/dbri.c b/drivers/sbus/audio/dbri.c index ad0d879b156f..665bb4b31812 100644 --- a/drivers/sbus/audio/dbri.c +++ b/drivers/sbus/audio/dbri.c @@ -1,4 +1,4 @@ -/* $Id: dbri.c,v 1.22 2000/10/27 07:01:38 uzi Exp $ +/* $Id: dbri.c,v 1.23 2001/01/08 04:19:16 davem Exp $ * drivers/sbus/audio/dbri.c * * Copyright (C) 1997 Rudolf Koenig (rfkoenig@immd4.informatik.uni-erlangen.de) @@ -61,7 +61,7 @@ #include <asm/audioio.h> #include "dbri.h" -#if defined(DBRI_ISDN) || defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff +#if defined(DBRI_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff #include "../../isdn/hisax/hisax.h" #include "../../isdn/hisax/isdnl1.h" #include "../../isdn/hisax/foreign.h" @@ -2227,7 +2227,7 @@ void dbri_brecv(int dev, unsigned int chan, recv_on_pipe(dbri, 8+chan, buffer, size, callback, callback_arg); } -#if defined(DBRI_ISDN) || defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff +#if defined(DBRI_ISDN) && defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE > 0x200ff struct foreign_interface dbri_foreign_interface = { dbri_get_irqnum, dbri_get_liu_state, diff --git a/drivers/sbus/char/Makefile b/drivers/sbus/char/Makefile index b3a736db58e6..437f2d28cd85 100644 --- a/drivers/sbus/char/Makefile +++ b/drivers/sbus/char/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_PCI) += su.o pcikbd.o obj-$(CONFIG_SAB82532) += sab82532.o obj-$(CONFIG_ENVCTRL) += envctrl.o obj-$(CONFIG_DISPLAY7SEG) += display7seg.o +obj-$(CONFIG_WATCHDOG_CP1XXX) += cpwatchdog.o obj-$(CONFIG_OBP_FLASH) += flash.o obj-$(CONFIG_SUN_OPENPROMIO) += openprom.o obj-$(CONFIG_SUN_MOSTEK_RTC) += rtc.o diff --git a/drivers/sbus/char/bpp.c b/drivers/sbus/char/bpp.c index c96a141a5a09..2be051503e11 100644 --- a/drivers/sbus/char/bpp.c +++ b/drivers/sbus/char/bpp.c @@ -17,6 +17,7 @@ #include <linux/errno.h> #include <linux/sched.h> #include <linux/smp_lock.h> +#include <linux/spinlock.h> #include <linux/timer.h> #include <linux/ioport.h> #include <linux/major.h> @@ -432,6 +433,7 @@ static int terminate(unsigned minor) return 0; } +static spinlock_t bpp_open_lock = SPIN_LOCK_UNLOCKED; /* * Allow only one process to open the device at a time. @@ -439,13 +441,25 @@ static int terminate(unsigned minor) static int bpp_open(struct inode *inode, struct file *f) { unsigned minor = MINOR(inode->i_rdev); - if (minor >= BPP_NO) return -ENODEV; - if (! instances[minor].present) return -ENODEV; - if (instances[minor].opened) return -EBUSY; - - instances[minor].opened = 1; + int ret; + + spin_lock(&bpp_open_lock); + ret = 0; + if (minor >= BPP_NO) { + ret = -ENODEV; + } else { + if (! instances[minor].present) { + ret = -ENODEV; + } else { + if (instances[minor].opened) + ret = -EBUSY; + else + instances[minor].opened = 1; + } + } + spin_unlock(&bpp_open_lock); - return 0; + return ret; } /* @@ -458,12 +472,14 @@ static int bpp_release(struct inode *inode, struct file *f) { unsigned minor = MINOR(inode->i_rdev); - lock_kernel(); + spin_lock(&bpp_open_lock); instances[minor].opened = 0; if (instances[minor].mode != COMPATIBILITY) - terminate(minor); - unlock_kernel(); + terminate(minor); + + spin_unlock(&bpp_open_lock); + return 0; } diff --git a/drivers/sbus/char/cpwatchdog.c b/drivers/sbus/char/cpwatchdog.c new file mode 100644 index 000000000000..c319b4d33839 --- /dev/null +++ b/drivers/sbus/char/cpwatchdog.c @@ -0,0 +1,838 @@ +/* cpwatchdog.c - driver implementation for hardware watchdog + * timers found on Sun Microsystems CP1400 and CP1500 boards. + * + * This device supports both the generic Linux watchdog + * interface and Solaris-compatible ioctls as best it is + * able. + * + * NOTE: CP1400 systems appear to have a defective intr_mask + * register on the PLD, preventing the disabling of + * timer interrupts. We use a timer to periodically + * reset 'stopped' watchdogs on affected platforms. + * + * TODO: DevFS support (/dev/watchdogs/0 ... /dev/watchdogs/2) + * + * Copyright (c) 2000 Eric Brower (ebrower@usa.net) + */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/version.h> +#include <linux/fs.h> +#include <linux/errno.h> +#include <linux/major.h> +#include <linux/init.h> +#include <linux/miscdevice.h> +#include <linux/sched.h> +#include <linux/interrupt.h> +#include <linux/ioport.h> +#include <linux/timer.h> +#include <asm/irq.h> +#include <asm/ebus.h> +#include <asm/oplib.h> +#include <asm/uaccess.h> + +#include <asm/watchdog.h> + +#define WD_OBPNAME "watchdog" +#define WD_BADMODEL "SUNW,501-5336" +#define WD_BTIMEOUT (jiffies + (HZ * 1000)) +#define WD_BLIMIT 0xFFFF + +#define WD0_DEVNAME "watchdog0" +#define WD1_DEVNAME "watchdog1" +#define WD2_DEVNAME "watchdog2" + +#define WD0_MINOR 212 +#define WD1_MINOR 213 +#define WD2_MINOR 214 + + +/* Internal driver definitions + */ +#define WD0_ID 0 /* Watchdog0 */ +#define WD1_ID 1 /* Watchdog1 */ +#define WD2_ID 2 /* Watchdog2 */ +#define WD_NUMDEVS 3 /* Device contains 3 timers */ + +#define WD_INTR_OFF 0 /* Interrupt disable value */ +#define WD_INTR_ON 1 /* Interrupt enable value */ + +#define WD_STAT_INIT 0x01 /* Watchdog timer is initialized */ +#define WD_STAT_BSTOP 0x02 /* Watchdog timer is brokenstopped */ +#define WD_STAT_SVCD 0x04 /* Watchdog interrupt occurred */ + +/* Register value definitions + */ +#define WD0_INTR_MASK 0x01 /* Watchdog device interrupt masks */ +#define WD1_INTR_MASK 0x02 +#define WD2_INTR_MASK 0x04 + +#define WD_S_RUNNING 0x01 /* Watchdog device status running */ +#define WD_S_EXPIRED 0x02 /* Watchdog device status expired */ + +/* Sun uses Altera PLD EPF8820ATC144-4 + * providing three hardware watchdogs: + * + * 1) RIC - sends an interrupt when triggered + * 2) XIR - asserts XIR_B_RESET when triggered, resets CPU + * 3) POR - asserts POR_B_RESET when triggered, resets CPU, backplane, board + * + *** Timer register block definition (struct wd_timer_regblk) + * + * dcntr and limit registers (halfword access): + * ------------------- + * | 15 | ...| 1 | 0 | + * ------------------- + * |- counter val -| + * ------------------- + * dcntr - Current 16-bit downcounter value. + * When downcounter reaches '0' watchdog expires. + * Reading this register resets downcounter with 'limit' value. + * limit - 16-bit countdown value in 1/10th second increments. + * Writing this register begins countdown with input value. + * Reading from this register does not affect counter. + * NOTES: After watchdog reset, dcntr and limit contain '1' + * + * status register (byte access): + * --------------------------- + * | 7 | ... | 2 | 1 | 0 | + * --------------+------------ + * |- UNUSED -| EXP | RUN | + * --------------------------- + * status- Bit 0 - Watchdog is running + * Bit 1 - Watchdog has expired + * + *** PLD register block definition (struct wd_pld_regblk) + * + * intr_mask register (byte access): + * --------------------------------- + * | 7 | ... | 3 | 2 | 1 | 0 | + * +-------------+------------------ + * |- UNUSED -| WD3 | WD2 | WD1 | + * --------------------------------- + * WD3 - 1 == Interrupt disabled for watchdog 3 + * WD2 - 1 == Interrupt disabled for watchdog 2 + * WD1 - 1 == Interrupt disabled for watchdog 1 + * + * pld_status register (byte access): + * UNKNOWN, MAGICAL MYSTERY REGISTER + * + */ +struct wd_timer_regblk { + volatile __u16 dcntr; /* down counter - hw */ + volatile __u16 dcntr_pad; + volatile __u16 limit; /* limit register - hw */ + volatile __u16 limit_pad; + volatile __u8 status; /* status register - b */ + volatile __u8 status_pad; + volatile __u16 status_pad2; + volatile __u32 pad32; /* yet more padding */ +}; + +struct wd_pld_regblk { + volatile __u8 intr_mask; /* interrupt mask - b */ + volatile __u8 intr_mask_pad; + volatile __u16 intr_mask_pad2; + volatile __u8 status; /* device status - b */ + volatile __u8 status_pad; + volatile __u16 status_pad2; +}; + +struct wd_regblk { + volatile struct wd_timer_regblk wd0_regs; + volatile struct wd_timer_regblk wd1_regs; + volatile struct wd_timer_regblk wd2_regs; + volatile struct wd_pld_regblk pld_regs; +}; + +/* Individual timer structure + */ +struct wd_timer { + __u16 timeout; + __u8 intr_mask; + unsigned char runstatus; + volatile struct wd_timer_regblk* regs; +}; + +/* Device structure + */ +struct wd_device { + int irq; + spinlock_t lock; + unsigned char isbaddoggie; /* defective PLD */ + unsigned char opt_enable; + unsigned char opt_reboot; + unsigned short opt_timeout; + unsigned char initialized; + struct wd_timer watchdog[WD_NUMDEVS]; + volatile struct wd_regblk* regs; +}; + +static struct wd_device wd_dev = { + 0, SPIN_LOCK_UNLOCKED, 0, 0, 0, 0, +}; + +struct timer_list wd_timer; + +static int wd0_timeout = 0; +static int wd1_timeout = 0; +static int wd2_timeout = 0; + +#ifdef MODULE +EXPORT_NO_SYMBOLS; + +MODULE_PARM (wd0_timeout, "i"); +MODULE_PARM_DESC(wd0_timeout, "Default watchdog0 timeout in 1/10secs"); +MODULE_PARM (wd1_timeout, "i"); +MODULE_PARM_DESC(wd1_timeout, "Default watchdog1 timeout in 1/10secs"); +MODULE_PARM (wd2_timeout, "i"); +MODULE_PARM_DESC(wd2_timeout, "Default watchdog2 timeout in 1/10secs"); + +MODULE_AUTHOR + ("Eric Brower <ebrower@usa.net>"); +MODULE_DESCRIPTION + ("Hardware watchdog driver for Sun Microsystems CP1400/1500"); +MODULE_SUPPORTED_DEVICE + ("watchdog"); +#endif /* ifdef MODULE */ + +/* Forward declarations of internal methods + */ +void wd_dumpregs(void); +void wd_interrupt(int irq, void *dev_id, struct pt_regs *regs); +void wd_toggleintr(struct wd_timer* pTimer, int enable); +void wd_pingtimer(struct wd_timer* pTimer); +void wd_starttimer(struct wd_timer* pTimer); +void wd_resetbrokentimer(struct wd_timer* pTimer); +void wd_stoptimer(struct wd_timer* pTimer); +void wd_brokentimer(unsigned long data); +int wd_getstatus(struct wd_timer* pTimer); + +/* PLD expects words to be written in LSB format, + * so we must flip all words prior to writing them to regs + */ +inline unsigned short flip_word(unsigned short word) +{ + return ((word & 0xff) << 8) | ((word >> 8) & 0xff); +} + +#define wd_writew(val, addr) (writew(flip_word(val), addr)) +#define wd_readw(addr) (flip_word(readw(addr))) +#define wd_writeb(val, addr) (writeb(val, addr)) +#define wd_readb(addr) (readb(addr)) + + +/* CP1400s seem to have broken PLD implementations-- + * the interrupt_mask register cannot be written, so + * no timer interrupts can be masked within the PLD. + */ +static inline int wd_isbroken(void) +{ + /* we could test this by read/write/read/restore + * on the interrupt mask register only if OBP + * 'watchdog-enable?' == FALSE, but it seems + * ubiquitous on CP1400s + */ + char val[32]; + prom_getproperty(prom_root_node, "model", val, sizeof(val)); + return((!strcmp(val, WD_BADMODEL)) ? 1 : 0); +} + +/* Retrieve watchdog-enable? option from OBP + * Returns 0 if false, 1 if true + */ +static inline int wd_opt_enable(void) +{ + int opt_node; + + opt_node = prom_getchild(prom_root_node); + opt_node = prom_searchsiblings(opt_node, "options"); + return((-1 == prom_getint(opt_node, "watchdog-enable?")) ? 0 : 1); +} + +/* Retrieve watchdog-reboot? option from OBP + * Returns 0 if false, 1 if true + */ +static inline int wd_opt_reboot(void) +{ + int opt_node; + + opt_node = prom_getchild(prom_root_node); + opt_node = prom_searchsiblings(opt_node, "options"); + return((-1 == prom_getint(opt_node, "watchdog-reboot?")) ? 0 : 1); +} + +/* Retrieve watchdog-timeout option from OBP + * Returns OBP value, or 0 if not located + */ +static inline int wd_opt_timeout(void) +{ + int opt_node; + char value[32]; + char *p = value; + + opt_node = prom_getchild(prom_root_node); + opt_node = prom_searchsiblings(opt_node, "options"); + opt_node = prom_getproperty(opt_node, + "watchdog-timeout", + value, + sizeof(value)); + if(-1 != opt_node) { + /* atoi implementation */ + for(opt_node = 0; /* nop */; p++) { + if(*p >= '0' && *p <= '9') { + opt_node = (10*opt_node)+(*p-'0'); + } + else { + break; + } + } + } + return((-1 == opt_node) ? (0) : (opt_node)); +} + +static int wd_open(struct inode *inode, struct file *f) +{ + switch(MINOR(inode->i_rdev)) + { + case WD0_MINOR: + f->private_data = &wd_dev.watchdog[WD0_ID]; + break; + case WD1_MINOR: + f->private_data = &wd_dev.watchdog[WD1_ID]; + break; + case WD2_MINOR: + f->private_data = &wd_dev.watchdog[WD2_ID]; + break; + default: + return(-ENODEV); + } + + /* Register IRQ on first open of device */ + if(0 == wd_dev.initialized) + { + if (request_irq(wd_dev.irq, + &wd_interrupt, + SA_SHIRQ, + WD_OBPNAME, + (void *)wd_dev.regs)) { + printk("%s: Cannot register IRQ %s\n", + WD_OBPNAME, __irq_itoa(wd_dev.irq)); + return(-EBUSY); + } + wd_dev.initialized = 1; + } + + MOD_INC_USE_COUNT; + return(0); +} + +static int wd_release(struct inode *inode, struct file *file) +{ + MOD_DEC_USE_COUNT; + return 0; +} + +static int wd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) +{ + int setopt = 0; + struct wd_timer* pTimer = (struct wd_timer*)file->private_data; + struct watchdog_info info = { + 0, + 0, + "Altera EPF8820ATC144-4" + }; + + if(NULL == pTimer) { + return(-EINVAL); + } + + switch(cmd) + { + /* Generic Linux IOCTLs */ + case WDIOC_GETSUPPORT: + if(copy_to_user((struct watchdog_info *)arg, + (struct watchdog_info *)&info, + sizeof(struct watchdog_info *))) { + return(-EFAULT); + } + break; + case WDIOC_KEEPALIVE: + wd_pingtimer(pTimer); + break; + case WDIOC_SETOPTIONS: + if(copy_from_user(&setopt, (void*) arg, sizeof(unsigned int))) { + return -EFAULT; + } + if(setopt & WDIOS_DISABLECARD) { + if(wd_dev.opt_enable) { + printk( + "%s: cannot disable watchdog in ENABLED mode\n", + WD_OBPNAME); + return(-EINVAL); + } + wd_stoptimer(pTimer); + } + else if(setopt & WDIOS_ENABLECARD) { + wd_starttimer(pTimer); + } + else { + return(-EINVAL); + } + break; + /* Solaris-compatible IOCTLs */ + case WIOCGSTAT: + setopt = wd_getstatus(pTimer); + if(copy_to_user((void*)arg, &setopt, sizeof(unsigned int))) { + return(-EFAULT); + } + break; + case WIOCSTART: + wd_starttimer(pTimer); + break; + case WIOCSTOP: + if(wd_dev.opt_enable) { + printk("%s: cannot disable watchdog in ENABLED mode\n", + WD_OBPNAME); + return(-EINVAL); + } + wd_stoptimer(pTimer); + break; + default: + return(-EINVAL); + } + return(0); +} + +static ssize_t wd_write( struct file *file, + const char *buf, + size_t count, + loff_t *ppos) +{ + struct wd_timer* pTimer = (struct wd_timer*)file->private_data; + + if(NULL == pTimer) { + return(-EINVAL); + } + + wd_pingtimer(pTimer); + return(count); +} + +static ssize_t wd_read(struct file * file, char * buffer, + size_t count, loff_t *ppos) +{ +#ifdef WD_DEBUG + wd_dumpregs(); + return(0); +#else + return(-EINVAL); +#endif /* ifdef WD_DEBUG */ +} + +void wd_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + /* Only WD0 will interrupt-- others are NMI and we won't + * see them here.... + */ + spin_lock_irq(&wd_dev.lock); + if((unsigned long)wd_dev.regs == (unsigned long)dev_id) + { + wd_stoptimer(&wd_dev.watchdog[WD0_ID]); + wd_dev.watchdog[WD0_ID].runstatus |= WD_STAT_SVCD; + } + spin_unlock_irq(&wd_dev.lock); + return; +} + +static struct file_operations wd_fops = { + owner: THIS_MODULE, + ioctl: wd_ioctl, + open: wd_open, + write: wd_write, + read: wd_read, + release: wd_release, +}; + +static struct miscdevice wd0_miscdev = { WD0_MINOR, WD0_DEVNAME, &wd_fops }; +static struct miscdevice wd1_miscdev = { WD1_MINOR, WD1_DEVNAME, &wd_fops }; +static struct miscdevice wd2_miscdev = { WD2_MINOR, WD2_DEVNAME, &wd_fops }; + +void wd_dumpregs(void) +{ + /* Reading from downcounters initiates watchdog countdown-- + * Example is included below for illustration purposes. + */ + int i; + printk("%s: dumping register values\n", WD_OBPNAME); + for(i = WD0_ID; i < WD_NUMDEVS; ++i) { + /* printk("\t%s%i: dcntr at 0x%lx: 0x%x\n", + * WD_OBPNAME, + * i, + * (unsigned long)(&wd_dev.watchdog[i].regs->dcntr), + * readw(&wd_dev.watchdog[i].regs->dcntr)); + */ + printk("\t%s%i: limit at 0x%lx: 0x%x\n", + WD_OBPNAME, + i, + (unsigned long)(&wd_dev.watchdog[i].regs->limit), + readw(&wd_dev.watchdog[i].regs->limit)); + printk("\t%s%i: status at 0x%lx: 0x%x\n", + WD_OBPNAME, + i, + (unsigned long)(&wd_dev.watchdog[i].regs->status), + readb(&wd_dev.watchdog[i].regs->status)); + printk("\t%s%i: driver status: 0x%x\n", + WD_OBPNAME, + i, + wd_getstatus(&wd_dev.watchdog[i])); + } + printk("\tintr_mask at 0x%lx: 0x%x\n", + (unsigned long)(&wd_dev.regs->pld_regs.intr_mask), + readb(&wd_dev.regs->pld_regs.intr_mask)); + printk("\tpld_status at 0x%lx: 0x%x\n", + (unsigned long)(&wd_dev.regs->pld_regs.status), + readb(&wd_dev.regs->pld_regs.status)); +} + +/* Enable or disable watchdog interrupts + * Because of the CP1400 defect this should only be + * called during initialzation or by wd_[start|stop]timer() + * + * pTimer - pointer to timer device, or NULL to indicate all timers + * enable - non-zero to enable interrupts, zero to disable + */ +void wd_toggleintr(struct wd_timer* pTimer, int enable) +{ + unsigned char curregs = wd_readb(&wd_dev.regs->pld_regs.intr_mask); + unsigned char setregs = + (NULL == pTimer) ? + (WD0_INTR_MASK | WD1_INTR_MASK | WD2_INTR_MASK) : + (pTimer->intr_mask); + + (WD_INTR_ON == enable) ? + (curregs &= ~setregs): + (curregs |= setregs); + + wd_writeb(curregs, &wd_dev.regs->pld_regs.intr_mask); + return; +} + +/* Reset countdown timer with 'limit' value and continue countdown. + * This will not start a stopped timer. + * + * pTimer - pointer to timer device + */ +void wd_pingtimer(struct wd_timer* pTimer) +{ + if(wd_readb(&pTimer->regs->status) & WD_S_RUNNING) { + wd_readb(&pTimer->regs->dcntr); + } +} + +/* Stop a running watchdog timer-- the timer actually keeps + * running, but the interrupt is masked so that no action is + * taken upon expiration. + * + * pTimer - pointer to timer device + */ +void wd_stoptimer(struct wd_timer* pTimer) +{ + if(wd_readb(&pTimer->regs->status) & WD_S_RUNNING) { + wd_toggleintr(pTimer, WD_INTR_OFF); + + if(wd_dev.isbaddoggie) { + pTimer->runstatus |= WD_STAT_BSTOP; + wd_brokentimer((unsigned long)&wd_dev); + } + } +} + +/* Start a watchdog timer with the specified limit value + * If the watchdog is running, it will be restarted with + * the provided limit value. + * + * This function will enable interrupts on the specified + * watchdog. + * + * pTimer - pointer to timer device + * limit - limit (countdown) value in 1/10th seconds + */ +void wd_starttimer(struct wd_timer* pTimer) +{ + if(wd_dev.isbaddoggie) { + pTimer->runstatus &= ~WD_STAT_BSTOP; + } + pTimer->runstatus &= ~WD_STAT_SVCD; + + wd_writew(pTimer->timeout, &pTimer->regs->limit); + wd_toggleintr(pTimer, WD_INTR_ON); +} + +/* Restarts timer with maximum limit value and + * does not unset 'brokenstop' value. + */ +void wd_resetbrokentimer(struct wd_timer* pTimer) +{ + wd_toggleintr(pTimer, WD_INTR_ON); + wd_writew(WD_BLIMIT, &pTimer->regs->limit); +} + +/* Timer device initialization helper. + * Returns 0 on success, other on failure + */ +int wd_inittimer(int whichdog) +{ + struct miscdevice *whichmisc; + volatile struct wd_timer_regblk *whichregs; + char whichident[8]; + int whichmask; + __u16 whichlimit; + + switch(whichdog) + { + case WD0_ID: + whichmisc = &wd0_miscdev; + strcpy(whichident, "RIC"); + whichregs = &wd_dev.regs->wd0_regs; + whichmask = WD0_INTR_MASK; + whichlimit= (0 == wd0_timeout) ? + (wd_dev.opt_timeout): + (wd0_timeout); + break; + case WD1_ID: + whichmisc = &wd1_miscdev; + strcpy(whichident, "XIR"); + whichregs = &wd_dev.regs->wd1_regs; + whichmask = WD1_INTR_MASK; + whichlimit= (0 == wd1_timeout) ? + (wd_dev.opt_timeout): + (wd1_timeout); + break; + case WD2_ID: + whichmisc = &wd2_miscdev; + strcpy(whichident, "POR"); + whichregs = &wd_dev.regs->wd2_regs; + whichmask = WD2_INTR_MASK; + whichlimit= (0 == wd2_timeout) ? + (wd_dev.opt_timeout): + (wd2_timeout); + break; + default: + printk("%s: %s: invalid watchdog id: %i\n", + WD_OBPNAME, __FUNCTION__, whichdog); + return(1); + } + if(0 != misc_register(whichmisc)) + { + return(1); + } + wd_dev.watchdog[whichdog].regs = whichregs; + wd_dev.watchdog[whichdog].timeout = whichlimit; + wd_dev.watchdog[whichdog].intr_mask = whichmask; + wd_dev.watchdog[whichdog].runstatus &= ~WD_STAT_BSTOP; + wd_dev.watchdog[whichdog].runstatus |= WD_STAT_INIT; + + printk("%s%i: %s hardware watchdog [%01i.%i sec] %s\n", + WD_OBPNAME, + whichdog, + whichident, + wd_dev.watchdog[whichdog].timeout / 10, + wd_dev.watchdog[whichdog].timeout % 10, + (0 != wd_dev.opt_enable) ? "in ENABLED mode" : ""); + return(0); +} + +/* Timer method called to reset stopped watchdogs-- + * because of the PLD bug on CP1400, we cannot mask + * interrupts within the PLD so me must continually + * reset the timers ad infinitum. + */ +void wd_brokentimer(unsigned long data) +{ + struct wd_device* pDev = (struct wd_device*)data; + int id, tripped = 0; + + /* kill a running timer instance, in case we + * were called directly instead of by kernel timer + */ + if(timer_pending(&wd_timer)) { + del_timer(&wd_timer); + } + + for(id = WD0_ID; id < WD_NUMDEVS; ++id) { + if(pDev->watchdog[id].runstatus & WD_STAT_BSTOP) { + ++tripped; + wd_resetbrokentimer(&pDev->watchdog[id]); + } + } + + if(tripped) { + /* there is at least one timer brokenstopped-- reschedule */ + wd_timer.expires = WD_BTIMEOUT; + add_timer(&wd_timer); + } +} + +int wd_getstatus(struct wd_timer* pTimer) +{ + unsigned char stat = wd_readb(&pTimer->regs->status); + unsigned char intr = wd_readb(&wd_dev.regs->pld_regs.intr_mask); + unsigned char ret = WD_STOPPED; + + /* determine STOPPED */ + if(0 == stat ) { + return(ret); + } + /* determine EXPIRED vs FREERUN vs RUNNING */ + else if(WD_S_EXPIRED & stat) { + ret = WD_EXPIRED; + } + else if(WD_S_RUNNING & stat) { + if(intr & pTimer->intr_mask) { + ret = WD_FREERUN; + } + else { + /* Fudge WD_EXPIRED status for defective CP1400-- + * IF timer is running + * AND brokenstop is set + * AND an interrupt has been serviced + * we are WD_EXPIRED. + * + * IF timer is running + * AND brokenstop is set + * AND no interrupt has been serviced + * we are WD_FREERUN. + */ + if(wd_dev.isbaddoggie && (pTimer->runstatus & WD_STAT_BSTOP)) { + if(pTimer->runstatus & WD_STAT_SVCD) { + ret = WD_EXPIRED; + } + else { + /* we could as well pretend we are expired */ + ret = WD_FREERUN; + } + } + else { + ret = WD_RUNNING; + } + } + } + + /* determine SERVICED */ + if(pTimer->runstatus & WD_STAT_SVCD) { + ret |= WD_SERVICED; + } + + return(ret); +} + +static int __init wd_init(void) +{ + int id; + struct linux_ebus *ebus = NULL; + struct linux_ebus_device *edev = NULL; + + for_each_ebus(ebus) { + for_each_ebusdev(edev, ebus) { + if (!strcmp(edev->prom_name, WD_OBPNAME)) + goto ebus_done; + } + } + +ebus_done: + if(!edev) { + printk("%s: unable to locate device\n", WD_OBPNAME); + return -ENODEV; + } + + wd_dev.regs = + ioremap(edev->resource[0].start, sizeof(struct wd_regblk)); + + if(NULL == wd_dev.regs) { + printk("%s: unable to map registers\n", WD_OBPNAME); + return(-ENODEV); + } + + /* initialize device structure from OBP parameters */ + wd_dev.irq = edev->irqs[0]; + wd_dev.opt_enable = wd_opt_enable(); + wd_dev.opt_reboot = wd_opt_reboot(); + wd_dev.opt_timeout = wd_opt_timeout(); + wd_dev.isbaddoggie = wd_isbroken(); + + /* disable all interrupts unless watchdog-enabled? == true */ + if(! wd_dev.opt_enable) { + wd_toggleintr(NULL, WD_INTR_OFF); + } + + /* register miscellaneous devices */ + for(id = WD0_ID; id < WD_NUMDEVS; ++id) { + if(0 != wd_inittimer(id)) { + printk("%s%i: unable to initialize\n", WD_OBPNAME, id); + } + } + + /* warn about possible defective PLD */ + if(wd_dev.isbaddoggie) { + init_timer(&wd_timer); + wd_timer.function = wd_brokentimer; + wd_timer.data = (unsigned long)&wd_dev; + wd_timer.expires = WD_BTIMEOUT; + + printk("%s: PLD defect workaround enabled for model %s\n", + WD_OBPNAME, WD_BADMODEL); + } + return(0); +} + +static void __exit wd_cleanup(void) +{ + int id; + + /* if 'watchdog-enable?' == TRUE, timers are not stopped + * when module is unloaded. All brokenstopped timers will + * also now eventually trip. + */ + for(id = WD0_ID; id < WD_NUMDEVS; ++id) { + if(WD_S_RUNNING == wd_readb(&wd_dev.watchdog[id].regs->status)) { + if(wd_dev.opt_enable) { + printk(KERN_WARNING "%s%i: timer not stopped at release\n", + WD_OBPNAME, id); + } + else { + wd_stoptimer(&wd_dev.watchdog[id]); + if(wd_dev.watchdog[id].runstatus & WD_STAT_BSTOP) { + wd_resetbrokentimer(&wd_dev.watchdog[id]); + printk(KERN_WARNING + "%s%i: defect workaround disabled at release, "\ + "timer expires in ~%01i sec\n", + WD_OBPNAME, id, + wd_readw(&wd_dev.watchdog[id].regs->limit) / 10); + } + } + } + } + + if(wd_dev.isbaddoggie && timer_pending(&wd_timer)) { + del_timer(&wd_timer); + } + if(0 != (wd_dev.watchdog[WD0_ID].runstatus & WD_STAT_INIT)) { + misc_deregister(&wd0_miscdev); + } + if(0 != (wd_dev.watchdog[WD1_ID].runstatus & WD_STAT_INIT)) { + misc_deregister(&wd1_miscdev); + } + if(0 != (wd_dev.watchdog[WD2_ID].runstatus & WD_STAT_INIT)) { + misc_deregister(&wd2_miscdev); + } + if(0 != wd_dev.initialized) { + free_irq(wd_dev.irq, (void *)wd_dev.regs); + } + iounmap(wd_dev.regs); +} + +module_init(wd_init); +module_exit(wd_cleanup); diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 71809b59d5f1..c6c927712c93 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -1,4 +1,4 @@ -/* $Id: flash.c,v 1.20 2000/11/08 04:57:49 davem Exp $ +/* $Id: flash.c,v 1.21 2001/01/11 15:29:36 davem Exp $ * flash.c: Allow mmap access to the OBP Flash, for OBP updates. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -14,6 +14,7 @@ #include <linux/poll.h> #include <linux/init.h> #include <linux/smp_lock.h> +#include <linux/spinlock.h> #include <asm/system.h> #include <asm/uaccess.h> @@ -22,6 +23,7 @@ #include <asm/sbus.h> #include <asm/ebus.h> +static spinlock_t flash_lock = SPIN_LOCK_UNLOCKED; static struct { unsigned long read_base; /* Physical read address */ unsigned long write_base; /* Physical write address */ @@ -38,14 +40,14 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) unsigned long addr; unsigned long size; - lock_kernel(); + spin_lock(&flash_lock); if (flash.read_base == flash.write_base) { addr = flash.read_base; size = flash.read_size; } else { if ((vma->vm_flags & VM_READ) && (vma->vm_flags & VM_WRITE)) { - unlock_kernel(); + spin_unlock(&flash_lock); return -EINVAL; } if (vma->vm_flags & VM_READ) { @@ -55,11 +57,11 @@ flash_mmap(struct file *file, struct vm_area_struct *vma) addr = flash.write_base; size = flash.write_size; } else { - unlock_kernel(); + spin_unlock(&flash_lock); return -ENXIO; } } - unlock_kernel(); + spin_unlock(&flash_lock); if ((vma->vm_pgoff << PAGE_SHIFT) > size) return -ENXIO; @@ -127,9 +129,10 @@ flash_open(struct inode *inode, struct file *file) static int flash_release(struct inode *inode, struct file *file) { - lock_kernel(); + spin_lock(&flash_lock); flash.busy = 0; - unlock_kernel(); + spin_unlock(&flash_lock); + return 0; } diff --git a/drivers/sbus/char/jsflash.c b/drivers/sbus/char/jsflash.c index f87850b2cf7d..8faec19dd9d9 100644 --- a/drivers/sbus/char/jsflash.c +++ b/drivers/sbus/char/jsflash.c @@ -505,9 +505,7 @@ static int jsfd_open(struct inode *inode, struct file *file) static int jsf_release(struct inode *inode, struct file *file) { - lock_kernel(); jsf0.busy = 0; - unlock_kernel(); return 0; } diff --git a/drivers/sbus/char/pcikbd.c b/drivers/sbus/char/pcikbd.c index 6ddccf114995..ea37949fad0b 100644 --- a/drivers/sbus/char/pcikbd.c +++ b/drivers/sbus/char/pcikbd.c @@ -1,4 +1,4 @@ -/* $Id: pcikbd.c,v 1.49 2000/07/13 08:06:40 davem Exp $ +/* $Id: pcikbd.c,v 1.50 2001/01/11 15:29:36 davem Exp $ * pcikbd.c: Ultra/AX PC keyboard support. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -746,13 +746,13 @@ static int aux_release(struct inode * inode, struct file * file) { unsigned long flags; - lock_kernel(); aux_fasync(-1, file, 0); - if (--aux_count) - goto out; spin_lock_irqsave(&pcikbd_lock, flags); + if (--aux_count) + goto out; + /* Disable controller ints */ aux_write_cmd(AUX_INTS_OFF); poll_aux_status(); @@ -761,9 +761,8 @@ static int aux_release(struct inode * inode, struct file * file) pcimouse_outb(KBD_CCMD_MOUSE_DISABLE, pcimouse_iobase + KBD_CNTL_REG); poll_aux_status(); - spin_unlock_irqrestore(&pcikbd_lock, flags); out: - unlock_kernel(); + spin_unlock_irqrestore(&pcikbd_lock, flags); return 0; } @@ -780,11 +779,13 @@ static int aux_open(struct inode * inode, struct file * file) if (!aux_present) return -ENODEV; - if (aux_count++) - return 0; - spin_lock_irqsave(&pcikbd_lock, flags); + if (aux_count++) { + spin_unlock_irqrestore(&pcikbd_lock, flags); + return 0; + } + if (!poll_aux_status()) { aux_count--; spin_unlock_irqrestore(&pcikbd_lock, flags); diff --git a/drivers/sbus/char/rtc.c b/drivers/sbus/char/rtc.c index d8454cf25860..6105e42290fc 100644 --- a/drivers/sbus/char/rtc.c +++ b/drivers/sbus/char/rtc.c @@ -1,4 +1,4 @@ -/* $Id: rtc.c,v 1.23 2000/08/29 07:01:55 davem Exp $ +/* $Id: rtc.c,v 1.24 2001/01/11 15:07:09 davem Exp $ * * Linux/SPARC Real Time Clock Driver * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu) @@ -31,11 +31,9 @@ static int rtc_busy = 0; void get_rtc_time(struct rtc_time *t) { unsigned long regs = mstk48t02_regs; - unsigned long flags; u8 tmp; - save_flags(flags); - cli(); + spin_lock_irq(&mostek_lock); tmp = mostek_read(regs + MOSTEK_CREG); tmp |= MSTK_CREG_READ; @@ -52,18 +50,18 @@ void get_rtc_time(struct rtc_time *t) tmp = mostek_read(regs + MOSTEK_CREG); tmp &= ~MSTK_CREG_READ; mostek_write(regs + MOSTEK_CREG, tmp); - restore_flags(flags); + + spin_unlock_irq(&mostek_lock); } /* Set the current date and time inthe real time clock. */ void set_rtc_time(struct rtc_time *t) { unsigned long regs = mstk48t02_regs; - unsigned long flags; u8 tmp; - save_flags(flags); - cli(); + spin_lock_irq(&mostek_lock); + tmp = mostek_read(regs + MOSTEK_CREG); tmp |= MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); @@ -79,7 +77,8 @@ void set_rtc_time(struct rtc_time *t) tmp = mostek_read(regs + MOSTEK_CREG); tmp &= ~MSTK_CREG_WRITE; mostek_write(regs + MOSTEK_CREG, tmp); - restore_flags(flags); + + spin_unlock_irq(&mostek_lock); } static long long rtc_lseek(struct file *file, long long offset, int origin) @@ -121,20 +120,24 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, static int rtc_open(struct inode *inode, struct file *file) { + int ret; + + spin_lock_irq(&mostek_lock); + if (rtc_busy) { + ret = -EBUSY; + } else { + rtc_busy = 1; + ret = 0; + } + spin_unlock_irq(&mostek_lock); - if (rtc_busy) - return -EBUSY; - - rtc_busy = 1; - - return 0; + return ret; } static int rtc_release(struct inode *inode, struct file *file) { - lock_kernel(); rtc_busy = 0; - unlock_kernel(); + return 0; } @@ -150,11 +153,7 @@ static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops }; EXPORT_NO_SYMBOLS; -#ifdef MODULE -int init_module(void) -#else -int __init rtc_sun_init(void) -#endif +static int __init rtc_sun_init(void) { int error; @@ -173,9 +172,10 @@ int __init rtc_sun_init(void) return 0; } -#ifdef MODULE -void cleanup_module(void) +static void __exit rtc_sun_cleanup(void) { misc_deregister(&rtc_dev); } -#endif + +module_init(rtc_sun_init); +module_exit(rtc_sun_cleanup); diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c index f34c12250ecb..467200699c63 100644 --- a/drivers/sbus/char/sunkbd.c +++ b/drivers/sbus/char/sunkbd.c @@ -1521,15 +1521,17 @@ kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg) static int kbd_open (struct inode *i, struct file *f) { + spin_lock_irq(&kbd_queue_lock); kbd_active++; if (kbd_opened) - return 0; + goto out; kbd_opened = fg_console + 1; - spin_lock_irq(&kbd_queue_lock); kbd_head = kbd_tail = 0; + + out: spin_unlock_irq(&kbd_queue_lock); return 0; @@ -1538,7 +1540,7 @@ kbd_open (struct inode *i, struct file *f) static int kbd_close (struct inode *i, struct file *f) { - lock_kernel(); + spin_lock_irq(&kbd_queue_lock); if (!--kbd_active) { if (kbd_redirected) kbd_table [kbd_redirected-1].kbdmode = VC_XLATE; @@ -1546,7 +1548,8 @@ kbd_close (struct inode *i, struct file *f) kbd_opened = 0; kbd_fasync (-1, f, 0); } - unlock_kernel(); + spin_unlock_irq(&kbd_queue_lock); + return 0; } diff --git a/drivers/sbus/char/sunmouse.c b/drivers/sbus/char/sunmouse.c index fd92bc4345c3..8bb45cbdedb9 100644 --- a/drivers/sbus/char/sunmouse.c +++ b/drivers/sbus/char/sunmouse.c @@ -391,11 +391,14 @@ sun_mouse_inbyte(unsigned char byte, int is_break) static int sun_mouse_open(struct inode * inode, struct file * file) { + spin_lock_irq(&sunmouse.lock); if (sunmouse.active++) - return 0; + goto out; sunmouse.delta_x = sunmouse.delta_y = 0; sunmouse.button_state = 0x80; sunmouse.vuid_mode = VUID_NATIVE; +out: + spin_unlock_irq(&sunmouse.lock); return 0; } @@ -412,10 +415,12 @@ static int sun_mouse_fasync (int fd, struct file *filp, int on) static int sun_mouse_close(struct inode *inode, struct file *file) { - lock_kernel(); sun_mouse_fasync (-1, file, 0); + + spin_lock_irq(&sunmouse.lock); sunmouse.active--; - unlock_kernel(); + spin_unlock_irq(&sunmouse.lock); + return 0; } diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c index 73158f351708..a4c0f347ec3f 100644 --- a/drivers/sbus/char/vfc_dev.c +++ b/drivers/sbus/char/vfc_dev.c @@ -22,6 +22,7 @@ #include <linux/sched.h> #include <linux/fs.h> #include <linux/smp_lock.h> +#include <linux/spinlock.h> #include <asm/openprom.h> #include <asm/oplib.h> @@ -181,17 +182,26 @@ struct vfc_dev *vfc_get_dev_ptr(int instance) return vfc_dev_lst[instance]; } +static spinlock_t vfc_dev_lock = SPIN_LOCK_UNLOCKED; + static int vfc_open(struct inode *inode, struct file *file) { struct vfc_dev *dev; + spin_lock(&vfc_dev_lock); dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); - if (dev == NULL) + if (dev == NULL) { + spin_unlock(&vfc_dev_lock); return -ENODEV; - if (dev->busy) + } + if (dev->busy) { + spin_unlock(&vfc_dev_lock); return -EBUSY; + } dev->busy = 1; + spin_unlock(&vfc_dev_lock); + vfc_lock_device(dev); vfc_csr_init(dev); @@ -209,14 +219,14 @@ static int vfc_release(struct inode *inode,struct file *file) { struct vfc_dev *dev; - lock_kernel(); + spin_lock(&vfc_dev_lock); dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); if (!dev || !dev->busy) { - unlock_kernel(); + spin_unlock(&vfc_dev_lock); return -EINVAL; } dev->busy = 0; - unlock_kernel(); + spin_unlock(&vfc_dev_lock); return 0; } @@ -611,12 +621,10 @@ static int vfc_mmap(struct inode *inode, struct file *file, unsigned int map_size, ret, map_offset; struct vfc_dev *dev; - lock_kernel(); dev = vfc_get_dev_ptr(MINOR(inode->i_rdev)); - if(dev == NULL) { - unlock_kernel(); + if(dev == NULL) return -ENODEV; - } + map_size = vma->vm_end - vma->vm_start; if(map_size > sizeof(struct vfc_regs)) map_size = sizeof(struct vfc_regs); @@ -626,7 +634,7 @@ static int vfc_mmap(struct inode *inode, struct file *file, map_offset = (unsigned int) (long)dev->phys_regs; ret = io_remap_page_range(vma->vm_start, map_offset, map_size, vma->vm_page_prot, dev->which_io); - unlock_kernel(); + if(ret) return -EAGAIN; diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index e1228dec184f..d29307433fc4 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -28,10 +28,10 @@ */ /* IMPORTANT NOTE: This file must be included in another file which does - * both of the following things for it to work: - * (1) <include/config.h> _must_ be included before this file - * (2) The macro UNUSUAL_DEV() must be defined before this file is included + * the following thing for it to work: + * The macro UNUSUAL_DEV() must be defined before this file is included */ +#include <linux/config.h> /* If you edit this file, please try to keep it sorted first by VendorID, * then by ProductID. diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index f5f7858db357..aa09b0dd98fc 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c @@ -299,7 +299,7 @@ int hpfs_notify_change(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; int error; - if (attr->ia_valid & ATTR_SIZE && attr->ia_size > inode->i_size) return -EPERM; + if ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) return -EINVAL; if (inode->i_sb->s_hpfs_root == inode->i_ino) return -EINVAL; if ((error = inode_change_ok(inode, attr))) return error; inode_setattr(inode, attr); diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c index a187b119919b..c16d93614d55 100644 --- a/fs/ncpfs/dir.c +++ b/fs/ncpfs/dir.c @@ -871,6 +871,12 @@ int ncp_create_new(struct inode *dir, struct dentry *dentry, int mode, goto out; error = -EACCES; + + if (S_ISREG(mode) && + (server->m.flags & NCP_MOUNT_EXTRAS) && + (mode & S_IXUGO)) + attributes |= aSYSTEM; + result = ncp_open_create_file_or_subdir(server, dir, __name, OC_MODE_CREATE | OC_MODE_OPEN | OC_MODE_REPLACE, attributes, AR_READ | AR_WRITE, &finfo); diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c index 171f0cb515e1..470ea5e96ae3 100644 --- a/fs/ncpfs/sock.c +++ b/fs/ncpfs/sock.c @@ -456,7 +456,10 @@ static int ncp_do_request(struct ncp_server *server, int size, spin_lock_irqsave(¤t->sigmask_lock, flags); old_set = current->blocked; - mask = sigmask(SIGKILL) | sigmask(SIGSTOP); + if (current->flags & PF_EXITING) + mask = 0; + else + mask = sigmask(SIGKILL); if (server->m.flags & NCP_MOUNT_INTR) { /* FIXME: This doesn't seem right at all. So, like, we can't handle SIGINT and get whatever to stop? diff --git a/include/asm-ppc/delay.h b/include/asm-ppc/delay.h index 2116a2f2cdc6..8cc1fde24b4d 100644 --- a/include/asm-ppc/delay.h +++ b/include/asm-ppc/delay.h @@ -2,6 +2,8 @@ #ifndef _PPC_DELAY_H #define _PPC_DELAY_H +#include <asm/param.h> + /* * Copyright 1996, Paul Mackerras. * @@ -11,25 +13,38 @@ * 2 of the License, or (at your option) any later version. */ -extern unsigned long loops_per_sec; +extern unsigned long loops_per_jiffy; -extern __inline__ void __delay(unsigned int loops) -{ - if (loops != 0) - __asm__ __volatile__("mtctr %0; 1: bdnz 1b" : : - "r" (loops) : "ctr"); -} +/* maximum permitted argument to udelay */ +#define __MAX_UDELAY 1000000 -extern __inline__ void udelay(unsigned long usecs) +extern void __delay(unsigned int loops); + +/* N.B. the `secs' parameter here is a fixed-point number with + the binary point to the left of the most-significant bit. */ +extern __inline__ void __const_udelay(unsigned int secs) { - unsigned long loops; + unsigned int loops; - /* compute (usecs * 2^32 / 10^6) * loops_per_sec / 2^32 */ - usecs *= 0x10c6; /* 2^32 / 10^6 */ __asm__("mulhwu %0,%1,%2" : "=r" (loops) : - "r" (usecs), "r" (loops_per_sec)); - __delay(loops); + "r" (secs), "r" (loops_per_jiffy)); + __delay(loops * HZ); } +/* + * note that 4294 == 2^32 / 10^6, multiplying by 4294 converts from + * microseconds to a 32-bit fixed-point number of seconds. + */ +extern __inline__ void __udelay(unsigned int usecs) +{ + __const_udelay(usecs * 4294); +} + +extern void __bad_udelay(void); /* deliberately undefined */ + +#define udelay(n) (__builtin_constant_p(n)? \ + ((n) > __MAX_UDELAY? __bad_udelay(): __const_udelay((n) * 4294u)) : \ + __udelay(n)) + #endif /* defined(_PPC_DELAY_H) */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/dma.h b/include/asm-ppc/dma.h index 735d91d1f645..56f56cd0ad8d 100644 --- a/include/asm-ppc/dma.h +++ b/include/asm-ppc/dma.h @@ -102,13 +102,13 @@ extern unsigned long ISA_DMA_THRESHOLD; /* used in nasty hack for sound - see prep_setup_arch() -- Cort */ extern long ppc_cs4232_dma, ppc_cs4232_dma2; #if defined(CONFIG_CS4232) -#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC) +#if defined(CONFIG_ALL_PPC) #define SND_DMA1 ppc_cs4232_dma #define SND_DMA2 ppc_cs4232_dma2 -#else /* !CONFIG_PREP && !CONFIG_ALL_PPC */ +#else /* !CONFIG_ALL_PPC */ #define SND_DMA1 -1 #define SND_DMA2 -1 -#endif /* !CONFIG_PREP */ +#endif /* CONFIG_ALL_PPC */ #elif defined(CONFIG_MSS) #define SND_DMA1 CONFIG_MSS_DMA #define SND_DMA2 CONFIG_MSS_DMA2 @@ -201,40 +201,8 @@ static __inline__ void release_dma_lock(unsigned long flags) /* enable/disable a specific DMA channel */ static __inline__ void enable_dma(unsigned int dmanr) { - /* - * The Radstone PPC2 and PPC2a boards have inverted DREQ - * lines (active low) so each command needs to be logically - * ORed with 0x40 - */ unsigned char ucDmaCmd=0x00; -#if defined(CONFIG_PREP) || defined(CONFIG_ALL_PPC) - if(_prep_type==_PREP_Radstone) - { - switch(ucSystemType) - { - case RS_SYS_TYPE_PPC2: - case RS_SYS_TYPE_PPC2a: - case RS_SYS_TYPE_PPC2ep: - { - /* - * DREQ lines are active low - */ - ucDmaCmd=0x40; - break; - } - - default: - { - /* - * DREQ lines are active high - */ - break; - } - } - } -#endif /* CONFIG_PREP || CONFIG_ALL_PPC */ - if (dmanr != 4) { dma_outb(0, DMA2_MASK_REG); /* This may not be enabled */ diff --git a/include/asm-ppc/elf.h b/include/asm-ppc/elf.h index 6a0e2e87472e..85124797a769 100644 --- a/include/asm-ppc/elf.h +++ b/include/asm-ppc/elf.h @@ -70,5 +70,24 @@ typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG]; #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) +/* + * We need to put in some extra aux table entries to tell glibc what + * the cache block size is, so it can use the dcbz instruction safely. + */ +#define AT_DCACHEBSIZE 17 +#define AT_ICACHEBSIZE 18 +#define AT_UCACHEBSIZE 19 + +extern int dcache_bsize; +extern int icache_bsize; +extern int ucache_bsize; + +#define DLINFO_EXTRA_ITEMS 3 +#define EXTRA_DLINFO do { \ + NEW_AUX_ENT(0, AT_DCACHEBSIZE, dcache_bsize); \ + NEW_AUX_ENT(1, AT_ICACHEBSIZE, icache_bsize); \ + NEW_AUX_ENT(2, AT_UCACHEBSIZE, ucache_bsize); \ +} while (0) + #endif /* __KERNEL__ */ #endif diff --git a/include/asm-ppc/feature.h b/include/asm-ppc/feature.h index 7a33ea8d320f..9e9f831d5bb7 100644 --- a/include/asm-ppc/feature.h +++ b/include/asm-ppc/feature.h @@ -86,6 +86,8 @@ extern void feature_set_usb_power(struct device_node* device, int power); extern void feature_set_firewire_power(struct device_node* device, int power); +extern void feature_core99_kick_cpu1(void); + /* * Sleep related functions. At term, they should be high-priority notifiers */ diff --git a/include/asm-ppc/gemini.h b/include/asm-ppc/gemini.h deleted file mode 100644 index ebd01c9b6598..000000000000 --- a/include/asm-ppc/gemini.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * include/asm-ppc/gemini.h - * - * - * Onboard registers and descriptions for Synergy Microsystems' - * "Gemini" boards. - * - */ -#ifdef __KERNEL__ -#ifndef __PPC_GEMINI_H -#define __PPC_GEMINI_H - -/* Registers */ - -#define GEMINI_SERIAL_B (0xffeffb00) -#define GEMINI_SERIAL_A (0xffeffb08) -#define GEMINI_USWITCH (0xffeffd00) -#define GEMINI_BREV (0xffeffe00) -#define GEMINI_BECO (0xffeffe08) -#define GEMINI_FEAT (0xffeffe10) -#define GEMINI_BSTAT (0xffeffe18) -#define GEMINI_CPUSTAT (0xffeffe20) -#define GEMINI_L2CFG (0xffeffe30) -#define GEMINI_MEMCFG (0xffeffe38) -#define GEMINI_FLROM (0xffeffe40) -#define GEMINI_P0PCI (0xffeffe48) -#define GEMINI_FLWIN (0xffeffe50) -#define GEMINI_P0INTMASK (0xffeffe60) -#define GEMINI_P0INTAP (0xffeffe68) -#define GEMINI_PCIERR (0xffeffe70) -#define GEMINI_LEDBASE (0xffeffe80) -#define GEMINI_RTC (0xffe9fff8) -#define GEMINI_LEDS 8 -#define GEMINI_SWITCHES 8 - - -/* Flash ROM bit definitions */ -#define GEMINI_FLS_WEN (1<<0) -#define GEMINI_FLS_JMP (1<<6) -#define GEMINI_FLS_BOOT (1<<7) - -/* Memory bit definitions */ -#define GEMINI_MEM_TYPE_MASK 0xc0 -#define GEMINI_MEM_SIZE_MASK 0x38 -#define GEMINI_MEM_BANK_MASK 0x07 - -/* L2 cache bit definitions */ -#define GEMINI_L2_SIZE_MASK 0xc0 -#define GEMINI_L2_RATIO_MASK 0x03 - -/* Timebase register bit definitons */ -#define GEMINI_TIMEB0_EN (1<<0) -#define GEMINI_TIMEB1_EN (1<<1) -#define GEMINI_TIMEB2_EN (1<<2) -#define GEMINI_TIMEB3_EN (1<<3) - -/* CPU status bit definitions */ -#define GEMINI_CPU_ID_MASK 0x03 -#define GEMINI_CPU_COUNT_MASK 0x0c -#define GEMINI_CPU0_HALTED (1<<4) -#define GEMINI_CPU1_HALTED (1<<5) -#define GEMINI_CPU2_HALTED (1<<6) -#define GEMINI_CPU3_HALTED (1<<7) - -/* Board status bit definitions */ -#define GEMINI_BRD_FAIL (1<<0) /* FAIL led is lit */ -#define GEMINI_BRD_BUS_MASK 0x0c /* PowerPC bus speed */ - -/* Board family/feature bit descriptions */ -#define GEMINI_FEAT_HAS_FLASH (1<<0) -#define GEMINI_FEAT_HAS_ETH (1<<1) -#define GEMINI_FEAT_HAS_SCSI (1<<2) -#define GEMINI_FEAT_HAS_P0 (1<<3) -#define GEMINI_FEAT_FAM_MASK 0xf0 - -/* Mod/ECO bit definitions */ -#define GEMINI_ECO_LEVEL_MASK 0x0f -#define GEMINI_MOD_MASK 0xf0 - -/* Type/revision bit definitions */ -#define GEMINI_REV_MASK 0x0f -#define GEMINI_TYPE_MASK 0xf0 - -/* User switch definitions */ -#define GEMINI_SWITCH_VERBOSE 1 /* adds "debug" to boot cmd line */ -#define GEMINI_SWITCH_SINGLE_USER 7 /* boots into "single-user" mode */ - -#define SGS_RTC_CONTROL 0 -#define SGS_RTC_SECONDS 1 -#define SGS_RTC_MINUTES 2 -#define SGS_RTC_HOURS 3 -#define SGS_RTC_DAY 4 -#define SGS_RTC_DAY_OF_MONTH 5 -#define SGS_RTC_MONTH 6 -#define SGS_RTC_YEAR 7 - -#define SGS_RTC_SET 0x80 -#define SGS_RTC_IS_STOPPED 0x80 - -#define GRACKLE_CONFIG_ADDR_ADDR (0xfec00000) -#define GRACKLE_CONFIG_DATA_ADDR (0xfee00000) - -#define GEMINI_BOOT_INIT (0xfff00100) - -#ifndef __ASSEMBLY__ - -static inline void grackle_write( unsigned long addr, unsigned long data ) -{ - __asm__ __volatile__( - " stwbrx %1, 0, %0\n \ - sync\n \ - stwbrx %3, 0, %2\n \ - sync " - : /* no output */ - : "r" (GRACKLE_CONFIG_ADDR_ADDR), "r" (addr), - "r" (GRACKLE_CONFIG_DATA_ADDR), "r" (data)); -} - -static inline unsigned long grackle_read( unsigned long addr ) -{ - unsigned long val; - - __asm__ __volatile__( - " stwbrx %1, 0, %2\n \ - sync\n \ - lwbrx %0, 0, %3\n \ - sync " - : "=r" (val) - : "r" (addr), "r" (GRACKLE_CONFIG_ADDR_ADDR), - "r" (GRACKLE_CONFIG_DATA_ADDR)); - - return val; -} - -static inline void gemini_led_on( int led ) -{ - if (led >= 0 && led < GEMINI_LEDS) - *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 1; -} - -static inline void gemini_led_off(int led) -{ - if (led >= 0 && led < GEMINI_LEDS) - *(unsigned char *)(GEMINI_LEDBASE + (led<<3)) = 0; -} - -static inline int gemini_led_val(int led) -{ - int val = 0; - if (led >= 0 && led < GEMINI_LEDS) - val = *(unsigned char *)(GEMINI_LEDBASE + (led<<3)); - return (val & 0x1); -} - -/* returns processor id from the board */ -static inline int gemini_processor(void) -{ - unsigned char cpu = *(unsigned char *)(GEMINI_CPUSTAT); - return (int) ((cpu == 0) ? 4 : (cpu & GEMINI_CPU_ID_MASK)); -} - - -extern void _gemini_reboot(void); -extern void gemini_prom_init(void); -extern void gemini_init_l2(void); -#endif /* __ASSEMBLY__ */ -#endif -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/gemini_serial.h b/include/asm-ppc/gemini_serial.h deleted file mode 100644 index e4e08467e00d..000000000000 --- a/include/asm-ppc/gemini_serial.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifdef __KERNEL__ -#ifndef __ASMPPC_GEMINI_SERIAL_H -#define __ASMPPC_GEMINI_SERIAL_H - -#include <linux/config.h> -#include <asm/gemini.h> - -#ifdef CONFIG_SERIAL_MANY_PORTS -#define RS_TABLE_SIZE 64 -#else -#define RS_TABLE_SIZE 4 -#endif - -/* Rate for the 24.576 Mhz clock for the onboard serial chip */ -#define BASE_BAUD (24576000 / 16) - -#ifdef CONFIG_SERIAL_DETECT_IRQ -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST|ASYNC_AUTO_IRQ) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_AUTO_IRQ) -#else -#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF|ASYNC_SKIP_TEST) -#define STD_COM4_FLAGS (ASYNC_BOOT_AUTOCONF) -#endif - -#define STD_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, GEMINI_SERIAL_A, 15, STD_COM_FLAGS }, /* ttyS0 */ \ - { 0, BASE_BAUD, GEMINI_SERIAL_B, 14, STD_COM_FLAGS }, /* ttyS1 */ \ - -#ifdef CONFIG_GEMINI_PU32 -#define PU32_SERIAL_PORT_DEFNS \ - { 0, BASE_BAUD, NULL, 0, STD_COM_FLAGS }, -#else -#define PU32_SERIAL_PORT_DEFNS -#endif - -#define SERIAL_PORT_DFNS \ - STD_SERIAL_PORT_DEFNS \ - PU32_SERIAL_PORT_DEFNS - -#endif -#endif /* __KERNEL__ */ diff --git a/include/asm-ppc/hardirq.h b/include/asm-ppc/hardirq.h index 8a270c8c1b96..66aa6abeb544 100644 --- a/include/asm-ppc/hardirq.h +++ b/include/asm-ppc/hardirq.h @@ -47,7 +47,7 @@ typedef struct { #include <asm/atomic.h> extern unsigned char global_irq_holder; -extern unsigned volatile int global_irq_lock; +extern unsigned volatile long global_irq_lock; extern atomic_t global_irq_count; static inline void release_irqlock(int cpu) @@ -66,8 +66,8 @@ static inline void hardirq_enter(int cpu) ++local_irq_count(cpu); atomic_inc(&global_irq_count); while (test_bit(0,&global_irq_lock)) { - if (smp_processor_id() == global_irq_holder) { - printk("uh oh, interrupt while we hold global irq lock!\n"); + if (cpu == global_irq_holder) { + printk("uh oh, interrupt while we hold global irq lock! (CPU %d)\n", cpu); #ifdef CONFIG_XMON xmon(0); #endif diff --git a/include/asm-ppc/hw_irq.h b/include/asm-ppc/hw_irq.h index 7d47901719a5..54e4d711133c 100644 --- a/include/asm-ppc/hw_irq.h +++ b/include/asm-ppc/hw_irq.h @@ -28,17 +28,23 @@ extern void __no_use_set_lost(unsigned long); #define __cli() int_control.int_cli() #define __sti() int_control.int_sti() -#define __save_flags(flags) int_control.int_save_flags(&flags) -#define __restore_flags(flags) int_control.int_restore_flags(flags) +#define __save_flags(flags) int_control.int_save_flags((unsigned long *)&flags) +#define __restore_flags(flags) int_control.int_restore_flags((unsigned long)flags) #define __save_and_cli(flags) ({__save_flags(flags);__cli();}) -#define __set_lost(irq) ({ if ((ulong)int_control.int_set_lost) int_control.int_set_lost(irq); }) +#define __set_lost(irq) ({ if ((unsigned long)int_control.int_set_lost) int_control.int_set_lost(irq); }) extern void do_lost_interrupts(unsigned long); -extern atomic_t ppc_n_lost_interrupts; #define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);}) #define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);}) -#define mask_and_ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);}) +#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);}) + +/* Should we handle this via lost interrupts and IPIs or should we don't care like + * we do now ? --BenH. + */ +struct hw_interrupt_type; +static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) {} + #endif /* _PPC_HW_IRQ_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/ide.h b/include/asm-ppc/ide.h index 179bdec67e27..a9e3baf0d476 100644 --- a/include/asm-ppc/ide.h +++ b/include/asm-ppc/ide.h @@ -37,6 +37,8 @@ extern ide_ioreg_t chrp_idedma_regbase; /* one for both channels */ extern unsigned int chrp_ide_irq; extern void chrp_ide_probe(void); +extern void ppc_generic_ide_fix_driveid(struct hd_driveid *id); + struct ide_machdep_calls { void (*insw)(ide_ioreg_t port, void *buf, int ns); void (*outsw)(ide_ioreg_t port, void *buf, int ns); @@ -90,10 +92,9 @@ static __inline__ int ide_default_irq(ide_ioreg_t base) static __inline__ ide_ioreg_t ide_default_io_base(int index) { - if ( ppc_ide_md.default_io_base ) + if (ppc_ide_md.default_io_base) return ppc_ide_md.default_io_base(index); - else - return -1; + return 0; } static __inline__ void ide_init_hwif_ports(hw_regs_t *hw, @@ -124,10 +125,9 @@ static __inline__ void ide_init_default_hwifs(void) static __inline__ int ide_check_region (ide_ioreg_t from, unsigned int extent) { - if ( ppc_ide_md.ide_check_region ) + if (ppc_ide_md.ide_check_region) return ppc_ide_md.ide_check_region(from, extent); - else - return -1; + return 0; } static __inline__ void ide_request_region (ide_ioreg_t from, unsigned int extent, const char *name) @@ -148,19 +148,6 @@ static __inline__ void ide_fix_driveid (struct hd_driveid *id) ppc_ide_md.fix_driveid(id); } -#if 0 /* inb/outb from io.h is OK now -- paulus */ -#undef inb -#define inb(port) in_8((unsigned char *)((port) + ppc_ide_md.io_base)) -#undef inb_p -#define inb_p(port) inb(port) - -#undef outb -#define outb(val, port) \ - out_8((unsigned char *)((port) + ppc_ide_md.io_base), (val) ) -#undef outb_p -#define outb_p(val, port) outb(val, port) -#endif - typedef union { unsigned all : 8; /* all of the bits together */ struct { diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index 03f9db09a48f..6023635116de 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -222,20 +222,6 @@ extern inline void * bus_to_virt(unsigned long address) } /* - * The PCI bus bridge can translate addresses issued by the processor(s) - * into a different address on the PCI bus. On 32-bit cpus, we assume - * this mapping is 1-1, but on 64-bit systems it often isn't. - */ -#ifndef CONFIG_PPC64BRIDGE -#define phys_to_bus(x) (x) -#define bus_to_phys(x) (x) - -#else -extern unsigned long phys_to_bus(unsigned long pa); -extern unsigned long bus_to_phys(unsigned int ba, int busnr); -#endif /* CONFIG_PPC64BRIDGE */ - -/* * Change virtual addresses to physical addresses and vv, for * addresses in the area where the kernel has the RAM mapped. */ @@ -364,6 +350,13 @@ out: return retval; } +/* Make some pcmcia drivers happy */ +static inline int isa_check_signature(unsigned long io_addr, + const unsigned char *signature, int length) +{ + return 0; +} + /* Nothing to do */ #define dma_cache_inv(_start,_size) do { } while (0) diff --git a/include/asm-ppc/ioctls.h b/include/asm-ppc/ioctls.h index 0f879c163c4c..e700d29fd47e 100644 --- a/include/asm-ppc/ioctls.h +++ b/include/asm-ppc/ioctls.h @@ -9,6 +9,7 @@ #define FIONBIO _IOW('f', 126, int) #define FIONREAD _IOR('f', 127, int) #define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) #define TIOCGETP _IOR('t', 8, struct sgttyb) #define TIOCSETP _IOW('t', 9, struct sgttyb) diff --git a/include/asm-ppc/irq.h b/include/asm-ppc/irq.h index c3ae15763fc9..139dfea0cb8d 100644 --- a/include/asm-ppc/irq.h +++ b/include/asm-ppc/irq.h @@ -4,6 +4,7 @@ #include <linux/config.h> #include <asm/machdep.h> /* ppc_md */ +#include <asm/atomic.h> extern void disable_irq(unsigned int); extern void disable_irq_nosync(unsigned int); @@ -163,9 +164,6 @@ extern irq_node_t *new_irq_node(void); #ifndef CONFIG_8260 #define NUM_8259_INTERRUPTS 16 -#define IRQ_8259_CASCADE 16 -#define openpic_to_irq(n) ((n)+NUM_8259_INTERRUPTS) -#define irq_to_openpic(n) ((n)-NUM_8259_INTERRUPTS) #else /* CONFIG_8260 */ @@ -214,7 +212,10 @@ static __inline__ int irq_cannonicalize(int irq) #endif #define NR_MASK_WORDS ((NR_IRQS + 31) / 32) -extern unsigned int ppc_lost_interrupts[NR_MASK_WORDS]; +/* pendatic: these are long because they are used with set_bit --RR */ +extern unsigned long ppc_cached_irq_mask[NR_MASK_WORDS]; +extern unsigned long ppc_lost_interrupts[NR_MASK_WORDS]; +extern atomic_t ppc_n_lost_interrupts; #endif /* _ASM_IRQ_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/keylargo.h b/include/asm-ppc/keylargo.h index 5408262a1790..02d3d58b2189 100644 --- a/include/asm-ppc/keylargo.h +++ b/include/asm-ppc/keylargo.h @@ -20,10 +20,19 @@ #define KEYLARGO_GPIO_CNT 17 /* Specific GPIO regs */ + #define KL_GPIO_ETH_PHY_RESET (KEYLARGO_GPIO_0+0x10) #define KL_GPIO_ETH_PHY_RESET_ASSERT 0x04 #define KL_GPIO_ETH_PHY_RESET_RELEASE 0x05 #define KL_GPIO_ETH_PHY_RESET_TRISTATE 0x00 + +#define KL_GPIO_KICK_CPU1 (KEYLARGO_GPIO_0+0x0a) +#define KL_GPIO_KICK_CPU1_UP 0x04 +#define KL_GPIO_KICK_CPU1_DOWN 0x38 + +#define KL_GPIO_PMU_MESSAGE_IRQ (KEYLARGO_GPIO_EXTINT_0+0x09) +#define KL_GPIO_PMU_MESSAGE_BIT 0x02 + /* * Bits in feature control register */ diff --git a/include/asm-ppc/linux_logo.h b/include/asm-ppc/linux_logo.h index c35e6db5bb50..d3aa2d267af5 100644 --- a/include/asm-ppc/linux_logo.h +++ b/include/asm-ppc/linux_logo.h @@ -34,9 +34,6 @@ extern unsigned char linux_logo_green[]; extern unsigned char linux_logo_blue[]; extern unsigned char linux_logo[]; extern unsigned char linux_logo_bw[]; -extern unsigned char linux_logo16_red[]; -extern unsigned char linux_logo16_green[]; -extern unsigned char linux_logo16_blue[]; extern unsigned char linux_logo16[]; #endif diff --git a/include/asm-ppc/machdep.h b/include/asm-ppc/machdep.h index 67111965fe2a..ca254d0e7a86 100644 --- a/include/asm-ppc/machdep.h +++ b/include/asm-ppc/machdep.h @@ -10,6 +10,7 @@ struct pt_regs; struct pci_bus; +struct pci_dev; struct machdep_calls { void (*setup_arch)(void); @@ -45,7 +46,7 @@ struct machdep_calls { unsigned char (*nvram_read_val)(int addr); void (*nvram_write_val)(int addr, unsigned char val); -/* Tons of keyboard stuff. */ + /* Tons of keyboard stuff. */ int (*kbd_setkeycode)(unsigned int scancode, unsigned int keycode); int (*kbd_getkeycode)(unsigned int scancode); @@ -59,25 +60,25 @@ struct machdep_calls { unsigned char *ppc_kbd_sysrq_xlate; #endif - /* PCI interfaces */ - int (*pcibios_read_config_byte)(unsigned char bus, - unsigned char dev_fn, unsigned char offset, unsigned char *val); - int (*pcibios_read_config_word)(unsigned char bus, - unsigned char dev_fn, unsigned char offset, unsigned short *val); - int (*pcibios_read_config_dword)(unsigned char bus, - unsigned char dev_fn, unsigned char offset, unsigned int *val); - int (*pcibios_write_config_byte)(unsigned char bus, - unsigned char dev_fn, unsigned char offset, unsigned char val); - int (*pcibios_write_config_word)(unsigned char bus, - unsigned char dev_fn, unsigned char offset, unsigned short val); - int (*pcibios_write_config_dword)(unsigned char bus, - unsigned char dev_fn, unsigned char offset, unsigned int val); + /* + * optional PCI "hooks" + */ + + /* Called after scanning the bus, before allocating + * resources + */ void (*pcibios_fixup)(void); - void (*pcibios_fixup_bus)(struct pci_bus *); - void* (*pci_dev_io_base)(unsigned char bus, unsigned char devfn, int physical); - void* (*pci_dev_mem_base)(unsigned char bus, unsigned char devfn); - int (*pci_dev_root_bridge)(unsigned char bus, unsigned char devfn); + /* Called for each PCI bus in the system + * when it's probed + */ + void (*pcibios_fixup_bus)(struct pci_bus *); + + /* Called when pci_enable_device() is called (initial=0) or + * when a device with no assigned resource is found (initial=1). + * Returns 0 to allow assignement/enabling of the device + */ + int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); /* this is for modules, since _machine can be a define -- Cort */ int ppc_machine; diff --git a/include/asm-ppc/mman.h b/include/asm-ppc/mman.h index 64abf0c58ced..1c0dbe2051d1 100644 --- a/include/asm-ppc/mman.h +++ b/include/asm-ppc/mman.h @@ -13,6 +13,7 @@ #define MAP_ANONYMOUS 0x20 /* don't use a file */ #define MAP_RENAME MAP_ANONYMOUS /* In SunOS terminology */ #define MAP_NORESERVE 0x40 /* don't reserve swap pages */ +#define MAP_LOCKED 0x80 #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 3efe39d00866..976ea6cc9afb 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -6,12 +6,13 @@ #ifndef _PPC_MMU_H_ #define _PPC_MMU_H_ -/* Default "unsigned long" context */ -typedef unsigned long mm_context_t; - #include <linux/config.h> #ifndef __ASSEMBLY__ + +/* Default "unsigned long" context */ +typedef unsigned long mm_context_t; + /* Hardware Page Table Entry */ typedef struct _PTE { #ifdef CONFIG_PPC64BRIDGE diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index fed474d14e92..f8ef4e604bf6 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -56,13 +56,6 @@ extern void mmu_context_overflow(void); */ extern void set_context(int context, void *pgd); -#ifdef CONFIG_8xx -extern inline void mmu_context_overflow(void) -{ - atomic_set(&next_mmu_context, -1); -} -#endif - /* * Get a new mmu context for task tsk if necessary. */ diff --git a/include/asm-ppc/parport.h b/include/asm-ppc/parport.h new file mode 100644 index 000000000000..11f96d3de5b6 --- /dev/null +++ b/include/asm-ppc/parport.h @@ -0,0 +1,18 @@ +/* + * parport.h: platform-specific PC-style parport initialisation + * + * Copyright (C) 1999, 2000 Tim Waugh <tim@cyberelk.demon.co.uk> + * + * This file should only be included by drivers/parport/parport_pc.c. + */ + +#ifndef _ASM_PPC_PARPORT_H +#define _ASM_PPC_PARPORT_H + +static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); +static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) +{ + return parport_pc_find_isa_ports (autoirq, autodma); +} + +#endif /* !(_ASM_PPC_PARPORT_H) */ diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h index 9e5385e512e8..a6c8d89192c0 100644 --- a/include/asm-ppc/pci-bridge.h +++ b/include/asm-ppc/pci-bridge.h @@ -2,49 +2,70 @@ #ifndef _ASM_PCI_BRIDGE_H #define _ASM_PCI_BRIDGE_H -void pmac_find_bridges(void); +struct device_node; +struct pci_controller; /* * pci_io_base returns the memory address at which you can access * the I/O space for PCI bus number `bus' (or NULL on error). - * - * NOTE: This doesn't handle the new Uni-N chip which requires - * per-device io_base. */ -void *pci_io_base(unsigned int bus); - -/* This version handles the new Uni-N host bridge, the iobase is now - * a per-device thing. I also added the memory base so PReP can - * be fixed to return 0xc0000000 (I didn't actually implement it) - * - * pci_dev_io_base() returns either a virtual (ioremap'ed) address or - * a physical address. In-kernel clients will use logical while the - * sys_pciconfig_iobase syscall returns a physical one to userland. +extern void *pci_bus_io_base(unsigned int bus); +extern unsigned long pci_bus_io_base_phys(unsigned int bus); +extern unsigned long pci_bus_mem_base_phys(unsigned int bus); + +/* + * PCI <-> OF matching functions */ -void *pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical); -void *pci_dev_mem_base(unsigned char bus, unsigned char devfn); +extern int pci_device_from_OF_node(struct device_node *node, + u8* bus, u8* devfn); +extern struct device_node* pci_device_to_OF_node(struct pci_dev *); -/* Returns the root-bridge number (Uni-N number) of a device */ -int pci_dev_root_bridge(unsigned char bus, unsigned char devfn); +/* Get the PCI host controller for a bus */ +extern struct pci_controller* pci_bus_to_hose(int bus); + +/* Get the PCI host controller for an OF device */ +extern struct pci_controller* +pci_find_hose_for_OF_device(struct device_node* node); /* - * pci_device_loc returns the bus number and device/function number - * for a device on a PCI bus, given its device_node struct. - * It returns 0 if OK, -1 on error. + * Structure of a PCI controller (host bridge) */ -int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr, - unsigned char *devfn_ptr); +struct pci_controller { + struct pci_controller *next; + struct pci_bus *bus; + void *arch_data; + + int first_busno; + int last_busno; + + void *io_base_virt; + unsigned long io_base_phys; + + /* Some machines (PReP) have a non 1:1 mapping of + * the PCI memory space in the CPU bus space + */ + unsigned long pci_mem_offset; -struct bridge_data { + struct pci_ops *ops; volatile unsigned int *cfg_addr; volatile unsigned char *cfg_data; - void *io_base; /* virtual */ - unsigned long io_base_phys; - int bus_number; - int max_bus; - struct bridge_data *next; - struct device_node *node; + + /* Currently, we limit ourselves to 1 IO range and 3 mem + * ranges since the common pci_bus structure can't handle more + */ + struct resource io_resource; + struct resource mem_resources[3]; + int mem_resource_count; }; +/* These are used for config access before all the PCI probing + has been done. */ +int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 *val); +int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 *val); +int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 *val); +int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn, int where, u8 val); +int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn, int where, u16 val); +int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn, int where, u32 val); + #endif #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/pci.h b/include/asm-ppc/pci.h index 1a661f050cc8..a1cfa7d31dc2 100644 --- a/include/asm-ppc/pci.h +++ b/include/asm-ppc/pci.h @@ -6,13 +6,11 @@ #define IOBASE_BRIDGE_NUMBER 0 #define IOBASE_MEMORY 1 #define IOBASE_IO 2 +#define IOBASE_ISA_IO 3 +#define IOBASE_ISA_MEM 4 -/* Can be used to override the logic in pci_scan_bus for skipping - * already-configured bus numbers - to be used for buggy BIOSes - * or architectures with incomplete PCI setup by the loader. - */ -#define pcibios_assign_all_busses() 0 +extern int pcibios_assign_all_busses(void); #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 @@ -27,6 +25,18 @@ extern inline void pcibios_penalize_isa_irq(int irq) /* We don't do dynamic PCI IRQ allocation */ } +extern unsigned long pci_resource_to_bus(struct pci_dev *pdev, struct resource *res); + +/* + * The PCI bus bridge can translate addresses issued by the processor(s) + * into a different address on the PCI bus. On 32-bit cpus, we assume + * this mapping is 1-1, but on 64-bit systems it often isn't. + * + * Obsolete ! Drivers should now use pci_resource_to_bus + */ +extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr); +extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr); + /* Dynamic DMA Mapping stuff * ++ajoshi */ diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 0f4579cd7ba8..353f5c9bfbe8 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -17,22 +17,22 @@ extern void local_flush_tlb_mm(struct mm_struct *mm); extern void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end); -extern inline void flush_hash_page(unsigned context, unsigned long va) +static inline void flush_hash_page(unsigned context, unsigned long va) { } #elif defined(CONFIG_8xx) #define __tlbia() asm volatile ("tlbia" : : ) -extern inline void local_flush_tlb_all(void) +static inline void local_flush_tlb_all(void) { __tlbia(); } -extern inline void local_flush_tlb_mm(struct mm_struct *mm) +static inline void local_flush_tlb_mm(struct mm_struct *mm) { __tlbia(); } -extern inline void local_flush_tlb_page(struct vm_area_struct *vma, +static inline void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { __tlbia(); } -extern inline void local_flush_tlb_range(struct mm_struct *mm, +static inline void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { __tlbia(); } -extern inline void flush_hash_page(unsigned context, unsigned long va) +static inline void flush_hash_page(unsigned context, unsigned long va) { } #else struct mm_struct; @@ -49,7 +49,7 @@ extern void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, #define flush_tlb_page local_flush_tlb_page #define flush_tlb_range local_flush_tlb_range -extern inline void flush_tlb_pgtables(struct mm_struct *mm, +static inline void flush_tlb_pgtables(struct mm_struct *mm, unsigned long start, unsigned long end) { /* PPC has hw page tables. */ @@ -323,9 +323,9 @@ extern pte_t * __bad_pagetable(void); * setup: the pgd is never bad, and a pmd always exists (as it's folded * into the pgd entry) */ -extern inline int pgd_none(pgd_t pgd) { return 0; } -extern inline int pgd_bad(pgd_t pgd) { return 0; } -extern inline int pgd_present(pgd_t pgd) { return 1; } +static inline int pgd_none(pgd_t pgd) { return 0; } +static inline int pgd_bad(pgd_t pgd) { return 0; } +static inline int pgd_present(pgd_t pgd) { return 1; } #define pgd_clear(xp) do { } while (0) #define pgd_page(pgd) \ @@ -335,45 +335,45 @@ extern inline int pgd_present(pgd_t pgd) { return 1; } * The following only work if pte_present() is true. * Undefined behaviour if not.. */ -extern inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } -extern inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } -extern inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -extern inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } +static inline int pte_read(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +static inline int pte_write(pte_t pte) { return pte_val(pte) & _PAGE_RW; } +static inline int pte_exec(pte_t pte) { return pte_val(pte) & _PAGE_USER; } +static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } +static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -extern inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } -extern inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } +static inline void pte_uncache(pte_t pte) { pte_val(pte) |= _PAGE_NO_CACHE; } +static inline void pte_cache(pte_t pte) { pte_val(pte) &= ~_PAGE_NO_CACHE; } -extern inline pte_t pte_rdprotect(pte_t pte) { +static inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } -extern inline pte_t pte_exprotect(pte_t pte) { +static inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) &= ~_PAGE_USER; return pte; } -extern inline pte_t pte_wrprotect(pte_t pte) { +static inline pte_t pte_wrprotect(pte_t pte) { pte_val(pte) &= ~(_PAGE_RW | _PAGE_HWWRITE); return pte; } -extern inline pte_t pte_mkclean(pte_t pte) { +static inline pte_t pte_mkclean(pte_t pte) { pte_val(pte) &= ~(_PAGE_DIRTY | _PAGE_HWWRITE); return pte; } -extern inline pte_t pte_mkold(pte_t pte) { +static inline pte_t pte_mkold(pte_t pte) { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; } -extern inline pte_t pte_mkread(pte_t pte) { +static inline pte_t pte_mkread(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } -extern inline pte_t pte_mkexec(pte_t pte) { +static inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) |= _PAGE_USER; return pte; } -extern inline pte_t pte_mkwrite(pte_t pte) +static inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_RW; if (pte_val(pte) & _PAGE_DIRTY) pte_val(pte) |= _PAGE_HWWRITE; return pte; } -extern inline pte_t pte_mkdirty(pte_t pte) +static inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= _PAGE_DIRTY; if (pte_val(pte) & _PAGE_RW) pte_val(pte) |= _PAGE_HWWRITE; return pte; } -extern inline pte_t pte_mkyoung(pte_t pte) { +static inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= _PAGE_ACCESSED; return pte; } /* Certain architectures need to do special things when pte's @@ -387,7 +387,7 @@ extern inline pte_t pte_mkyoung(pte_t pte) { * and a page entry and page directory to the page they refer to. */ -extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) +static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { pte_t pte; pte_val(pte) = physpage | pgprot_val(pgprot); @@ -401,12 +401,73 @@ extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) pte; \ }) -extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) +static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } +/* + * Atomic PTE updates. + * + * pte_update clears and sets bit atomically, and returns + * the old pte value. + */ +static inline unsigned long pte_update(pte_t *p, unsigned long clr, + unsigned long set) +{ + unsigned long old, tmp; + + __asm__ __volatile__("\ +1: lwarx %0,0,%3 + andc %1,%0,%4 + or %1,%1,%5 + stwcx. %1,0,%3 + bne- 1b" + : "=&r" (old), "=&r" (tmp), "=m" (*p) + : "r" (p), "r" (clr), "r" (set), "m" (*p) + : "cc" ); + return old; +} + +static inline int ptep_test_and_clear_young(pte_t *ptep) +{ + return (pte_update(ptep, _PAGE_ACCESSED, 0) & _PAGE_ACCESSED) != 0; +} + +static inline int ptep_test_and_clear_dirty(pte_t *ptep) +{ + return (pte_update(ptep, _PAGE_DIRTY | _PAGE_HWWRITE, 0) + & _PAGE_DIRTY) != 0; +} + +static inline pte_t ptep_get_and_clear(pte_t *ptep) +{ + return __pte(pte_update(ptep, ~0UL, 0)); +} + +static inline void ptep_set_wrprotect(pte_t *ptep) +{ + pte_update(ptep, _PAGE_RW | _PAGE_HWWRITE, 0); +} + +static inline void ptep_mkdirty(pte_t *ptep) +{ + /* + * N.B. this doesn't set the _PAGE_HWWRITE bit in the case + * where _PAGE_RW is set and _PAGE_DIRTY was clear. This + * doesn't matter; all it will mean is that if the next call + * to hash_page for this page is for a read, it will put a + * readonly HPTE into the hash table rather than a R/W HPTE. + * A call to hash_page for a write to this page will set + * _PAGE_HWWRITE and put a R/W HPTE into the hash table. + * -- paulus. + */ + pte_update(ptep, 0, _PAGE_DIRTY); +} + +#define pte_same(A,B) (pte_val(A) == pte_val(B)) + #define pmd_page(pmd) (pmd_val(pmd)) /* to find an entry in a kernel page-table-directory */ @@ -417,13 +478,13 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) /* Find an entry in the second-level page table.. */ -extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) +static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { return (pmd_t *) dir; } /* Find an entry in the third-level page table.. */ -extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address) +static inline pte_t * pte_offset(pmd_t * dir, unsigned long address) { return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)); } @@ -486,8 +547,6 @@ extern void kernel_set_cachemode (unsigned long address, unsigned long size, #define io_remap_page_range remap_page_range -#include <asm-generic/pgtable.h> - -#endif __ASSEMBLY__ +#endif /* __ASSEMBLY__ */ #endif /* _PPC_PGTABLE_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/prep_nvram.h b/include/asm-ppc/prep_nvram.h index 82ec215081a4..85694899c2c2 100644 --- a/include/asm-ppc/prep_nvram.h +++ b/include/asm-ppc/prep_nvram.h @@ -21,6 +21,11 @@ #ifndef _PPC_PREP_NVRAM_H #define _PPC_PREP_NVRAM_H +#define MAX_PREP_NVRAM 0x8000 +#define PREP_NVRAM_AS0 0x74 +#define PREP_NVRAM_AS1 0x75 +#define PREP_NVRAM_DATA 0x77 + #define NVSIZE 4096 /* size of NVRAM */ #define OSAREASIZE 512 /* size of OSArea space */ #define CONFSIZE 1024 /* guess at size of Configuration space */ diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 5908d7f32edc..cd87f248e695 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -203,6 +203,12 @@ #define SPRN_IMISS 0x3D4 /* Instruction TLB Miss Register */ #define SPRN_IMMR 0x27E /* Internal Memory Map Register */ #define SPRN_L2CR 0x3F9 /* Level 2 Cache Control Regsiter */ +#define L2CR_PIPE_LATEWR (0x01800000) /* late-write SRAM */ +#define L2CR_L2CTL (0x00100000) /* RAM control */ +#define L2CR_INST_DISABLE (0x00400000) /* disable for insn's */ +#define L2CR_L2I (0x00200000) /* global invalidate */ +#define L2CR_L2E (0x80000000) /* enable */ +#define L2CR_L2WT (0x00080000) /* write-through */ #define SPRN_LR 0x008 /* Link Register */ #define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */ #define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */ @@ -233,14 +239,14 @@ #define SPRN_SRR1 0x01B /* Save/Restore Register 1 */ #define SPRN_SRR2 0x3DE /* Save/Restore Register 2 */ #define SPRN_SRR3 0x3DF /* Save/Restore Register 3 */ -#define SPRN_TBHI 0x3DC /* Time Base High */ -#define SPRN_TBHU 0x3CC /* Time Base High User-mode */ -#define SPRN_TBLO 0x3DD /* Time Base Low */ -#define SPRN_TBLU 0x3CD /* Time Base Low User-mode */ -#define SPRN_TBRL 0x10D /* Time Base Read Lower Register */ -#define SPRN_TBRU 0x10C /* Time Base Read Upper Register */ -#define SPRN_TBWL 0x11D /* Time Base Write Lower Register */ -#define SPRN_TBWU 0x11C /* Time Base Write Upper Register */ +#define SPRN_TBRL 0x10C /* Time Base Read Lower Register (user, R/O) */ +#define SPRN_TBRU 0x10D /* Time Base Read Upper Register (user, R/O) */ +#define SPRN_TBWL 0x11C /* Time Base Lower Register (supervisor, R/W) */ +#define SPRN_TBWU 0x11D /* Time Base Upper Register (supervisor, R/W) */ +#define SPRN_TBHI 0x3DC /* Time Base High (4xx) */ +#define SPRN_TBHU 0x3CC /* Time Base High User-mode (4xx) */ +#define SPRN_TBLO 0x3DD /* Time Base Low (4xx) */ +#define SPRN_TBLU 0x3CD /* Time Base Low User-mode (4xx) */ #define SPRN_TCR 0x3DA /* Timer Control Register */ #define TCR_WP(x) (((x)&0x3)<<30) /* WDT Period */ #define WP_2_17 0 /* 2^17 clocks */ @@ -262,15 +268,17 @@ #define TCR_FIE 0x00800000 /* FIT Interrupt Enable */ #define TCR_ARE 0x00400000 /* Auto Reload Enable */ #define SPRN_THRM1 0x3FC /* Thermal Management Register 1 */ -#define THRM1_TIN (1<<0) -#define THRM1_TIV (1<<1) -#define THRM1_THRES (0x7f<<2) -#define THRM1_TID (1<<29) -#define THRM1_TIE (1<<30) -#define THRM1_V (1<<31) +/* these bits were defined in inverted endian sense originally, ugh, confusing */ +#define THRM1_TIN (1 << 31) +#define THRM1_TIV (1 << 30) +#define THRM1_THRES(x) ((x&0x7f)<<23) +#define THRM3_SITV(x) ((x&0x3fff)<<1) +#define THRM1_TID (1<<2) +#define THRM1_TIE (1<<1) +#define THRM1_V (1<<0) #define SPRN_THRM2 0x3FD /* Thermal Management Register 2 */ #define SPRN_THRM3 0x3FE /* Thermal Management Register 3 */ -#define THRM3_E (1<<31) +#define THRM3_E (1<<0) #define SPRN_TSR 0x3D8 /* Timer Status Register */ #define TSR_ENW 0x80000000 /* Enable Next Watchdog */ #define TSR_WIS 0x40000000 /* WDT Interrupt Status */ @@ -500,8 +508,8 @@ #define _MACH_fads 0x00000020 /* Motorola FADS board */ #define _MACH_rpxlite 0x00000040 /* RPCG RPX-Lite 8xx board */ #define _MACH_bseip 0x00000080 /* Bright Star Engineering ip-Engine */ -#define _MACH_yk 0x00000100 /* Motorola Yellowknife */ -#define _MACH_gemini 0x00000200 /* Synergy Microsystems gemini board */ +#define _MACH_unused0 0x00000100 /* Now free to be used */ +#define _MACH_unused1 0x00000200 /* Now free to be used */ #define _MACH_classic 0x00000400 /* RPCG RPX-Classic 8xx board */ #define _MACH_oak 0x00000800 /* IBM "Oak" 403 eval. board */ #define _MACH_walnut 0x00001000 /* IBM "Walnut" 405GP eval. board */ @@ -509,24 +517,11 @@ #define _MACH_tqm860 0x00004000 /* TQM860/L */ #define _MACH_tqm8xxL 0x00008000 /* TQM8xxL */ - /* see residual.h for these */ #define _PREP_Motorola 0x01 /* motorola prep */ #define _PREP_Firm 0x02 /* firmworks prep */ #define _PREP_IBM 0x00 /* ibm prep */ #define _PREP_Bull 0x03 /* bull prep */ -#define _PREP_Radstone 0x04 /* Radstone Technology PLC prep */ - -/* - * Radstone board types - */ -#define RS_SYS_TYPE_PPC1 0 -#define RS_SYS_TYPE_PPC2 1 -#define RS_SYS_TYPE_PPC1a 2 -#define RS_SYS_TYPE_PPC2a 3 -#define RS_SYS_TYPE_PPC4 4 -#define RS_SYS_TYPE_PPC4a 5 -#define RS_SYS_TYPE_PPC2ep 6 /* these are arbitrary */ #define _CHRP_Motorola 0x04 /* motorola chrp, the cobra */ @@ -715,9 +710,6 @@ void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); #elif defined(CONFIG_APUS) #define _machine _MACH_apus #define have_of 0 -#elif defined(CONFIG_GEMINI) -#define _machine _MACH_gemini -#define have_of 0 #elif defined(CONFIG_8260) #define _machine _MACH_8260 #define have_of 0 diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h index 0c57690eaeee..b80c460b3374 100644 --- a/include/asm-ppc/prom.h +++ b/include/asm-ppc/prom.h @@ -80,14 +80,15 @@ extern struct device_node *find_type_devices(const char *type); extern struct device_node *find_path_device(const char *path); extern struct device_node *find_compatible_devices(const char *type, const char *compat); -extern struct device_node *find_pci_device_OFnode(unsigned char bus, - unsigned char dev_fn); extern struct device_node *find_phandle(phandle); extern struct device_node *find_all_nodes(void); extern int device_is_compatible(struct device_node *device, const char *); extern int machine_is_compatible(const char *compat); extern unsigned char *get_property(struct device_node *node, const char *name, int *lenp); +extern void prom_add_property(struct device_node* np, struct property* prop); +extern void prom_get_irq_senses(unsigned char *, int, int); + extern void print_properties(struct device_node *node); extern int call_rtas(const char *service, int nargs, int nret, unsigned long *outputs, ...); @@ -96,7 +97,8 @@ extern void prom_drawhex(unsigned long v); extern void prom_drawchar(char c); extern void map_bootx_text(void); - +extern void bootx_update_display(unsigned long phys, int width, int height, + int depth, int pitch); #endif /* _PPC_PROM_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/raven.h b/include/asm-ppc/raven.h index ee873ff8232f..e912088b0447 100644 --- a/include/asm-ppc/raven.h +++ b/include/asm-ppc/raven.h @@ -31,5 +31,5 @@ extern struct hw_interrupt_type raven_pic; extern int raven_init(void); -#endif _ASMPPC_RAVEN_H +#endif /* _ASMPPC_RAVEN_H */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/segment.h b/include/asm-ppc/segment.h index 0eef1e5e744d..0f2f7428d437 100644 --- a/include/asm-ppc/segment.h +++ b/include/asm-ppc/segment.h @@ -1,7 +1 @@ -#ifndef __PPC_SEGMENT_H -#define __PPC_SEGMENT_H - -/* Only here because we have some old header files that expect it.. */ - -#endif #include <asm/uaccess.h> diff --git a/include/asm-ppc/serial.h b/include/asm-ppc/serial.h index 60c1a14ff3ac..721476591e5d 100644 --- a/include/asm-ppc/serial.h +++ b/include/asm-ppc/serial.h @@ -5,10 +5,6 @@ #ifdef __KERNEL__ #include <linux/config.h> -#ifdef CONFIG_GEMINI -#include <asm/gemini_serial.h> -#else - /* * This assumes you have a 1.8432 MHz clock for your UART. * @@ -127,5 +123,4 @@ HUB6_SERIAL_PORT_DFNS \ MCA_SERIAL_PORT_DFNS -#endif /* CONFIG_GEMINI */ #endif /* __KERNEL__ */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index 4851e13fd149..6dfc778b94bc 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -15,7 +15,7 @@ #ifndef __ASSEMBLY__ struct cpuinfo_PPC { - unsigned long loops_per_sec; + unsigned long loops_per_jiffy; unsigned long pvr; unsigned long *pgd_cache; unsigned long *pte_cache; diff --git a/include/asm-ppc/smplock.h b/include/asm-ppc/smplock.h index 5fdd5733b47f..4b7ba58e914b 100644 --- a/include/asm-ppc/smplock.h +++ b/include/asm-ppc/smplock.h @@ -39,13 +39,13 @@ do { \ * so we only need to worry about other * CPU's. */ -extern __inline__ void lock_kernel(void) +static __inline__ void lock_kernel(void) { if (!++current->lock_depth) spin_lock(&kernel_flag); } -extern __inline__ void unlock_kernel(void) +static __inline__ void unlock_kernel(void) { if (--current->lock_depth < 0) spin_unlock(&kernel_flag); diff --git a/include/asm-ppc/termios.h b/include/asm-ppc/termios.h index 2a9b8b02512b..22f53ce8b2cd 100644 --- a/include/asm-ppc/termios.h +++ b/include/asm-ppc/termios.h @@ -43,6 +43,7 @@ struct ltchars { #define FIONBIO _IOW('f', 126, int) #define FIONREAD _IOR('f', 127, int) #define TIOCINQ FIONREAD +#define FIOQSIZE _IOR('f', 128, loff_t) #define TIOCGETP _IOR('t', 8, struct sgttyb) #define TIOCSETP _IOW('t', 9, struct sgttyb) diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index 5c432792b381..c0a69ef721fc 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -206,6 +206,10 @@ #define __NR_pciconfig_iobase 200 #define __NR_multiplexer 201 #define __NR_getdents64 202 +#define __NR_pivot_root 203 +#define __NR_fcntl64 204 +#define __NR_madvise 205 +#define __NR_mincore 206 #define __NR(n) #n diff --git a/include/asm-sparc/mostek.h b/include/asm-sparc/mostek.h index c9a10cd864f7..be60a9afa41f 100644 --- a/include/asm-sparc/mostek.h +++ b/include/asm-sparc/mostek.h @@ -1,4 +1,4 @@ -/* $Id: mostek.h,v 1.12 1999/08/31 18:51:41 davem Exp $ +/* $Id: mostek.h,v 1.13 2001/01/11 15:07:09 davem Exp $ * mostek.h: Describes the various Mostek time of day clock registers. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -64,6 +64,7 @@ struct mostek48t02 { volatile unsigned char year; /* Year (0-99) */ }; +extern spinlock_t mostek_lock; extern unsigned long mstk48t02_regs; /* Control register values. */ diff --git a/include/asm-sparc64/mostek.h b/include/asm-sparc64/mostek.h index e153a36cfea1..b000c1586b4d 100644 --- a/include/asm-sparc64/mostek.h +++ b/include/asm-sparc64/mostek.h @@ -1,4 +1,4 @@ -/* $Id: mostek.h,v 1.3 1999/08/30 10:14:50 davem Exp $ +/* $Id: mostek.h,v 1.4 2001/01/11 15:07:09 davem Exp $ * mostek.h: Describes the various Mostek time of day clock registers. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -66,6 +66,7 @@ static __inline__ void mostek_write(unsigned long addr, u8 val) #define MOSTEK_MONTH 0x07feUL #define MOSTEK_YEAR 0x07ffUL +extern spinlock_t mostek_lock; extern unsigned long mstk48t02_regs; /* Control register values. */ diff --git a/include/asm-sparc64/pbm.h b/include/asm-sparc64/pbm.h index c17e9bf23d71..0826267255ac 100644 --- a/include/asm-sparc64/pbm.h +++ b/include/asm-sparc64/pbm.h @@ -1,4 +1,4 @@ -/* $Id: pbm.h,v 1.22 2000/03/25 05:18:30 davem Exp $ +/* $Id: pbm.h,v 1.23 2001/01/11 16:26:45 davem Exp $ * pbm.h: UltraSparc PCI controller software state. * * Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com) @@ -18,11 +18,12 @@ /* The abstraction used here is that there are PCI controllers, * each with one (Sabre) or two (PSYCHO/SCHIZO) PCI bus modules - * underneath. Each PCI controller has a single IOMMU shared - * by the PCI bus modules underneath, and if a streaming buffer + * underneath. Each PCI bus module uses an IOMMU (shared by both + * PBMs of a controller, or per-PBM), and if a streaming buffer * is present, each PCI bus module has it's own. (ie. the IOMMU - * is shared between PBMs, the STC is not) Furthermore, each - * PCI bus module controls it's own autonomous PCI bus. + * might be shared between PBMs, the STC is never shared) + * Furthermore, each PCI bus module controls it's own autonomous + * PCI bus. */ #define PBM_LOGCLUSTERS 3 @@ -150,6 +151,9 @@ struct pci_pbm_info { /* This PBM's streaming buffer. */ struct pci_strbuf stc; + /* IOMMU state, potentially shared by both PBM segments. */ + struct pci_iommu *iommu; + /* Now things for the actual PCI bus probes. */ unsigned int pci_first_busno; unsigned int pci_last_busno; @@ -189,9 +193,6 @@ struct pci_controller_info { unsigned int pci_first_busno; unsigned int pci_last_busno; - /* IOMMU state shared by both PBM segments. */ - struct pci_iommu iommu; - void *starfire_cookie; }; diff --git a/include/asm-sparc64/watchdog.h b/include/asm-sparc64/watchdog.h new file mode 100644 index 000000000000..4d5b03b60e4d --- /dev/null +++ b/include/asm-sparc64/watchdog.h @@ -0,0 +1,31 @@ +/* $Id: watchdog.h,v 1.1 2001/01/18 04:47:44 davem Exp $ + * + * watchdog - Driver interface for the hardware watchdog timers + * present on Sun Microsystems boardsets + * + * Copyright (c) 2000 Eric Brower <ebrower@usa.net> + * + */ + +#ifndef _SPARC64_WATCHDOG_H +#define _SPARC64_WATCHDOG_H + +#include <linux/watchdog.h> + +/* Solaris compatibility ioctls-- + * Ref. <linux/watchdog.h> for standard linux watchdog ioctls + */ +#define WIOCSTART _IO (WATCHDOG_IOCTL_BASE, 10) /* Start Timer */ +#define WIOCSTOP _IO (WATCHDOG_IOCTL_BASE, 11) /* Stop Timer */ +#define WIOCGSTAT _IOR(WATCHDOG_IOCTL_BASE, 12, int)/* Get Timer Status */ + +/* Status flags from WIOCGSTAT ioctl + */ +#define WD_FREERUN 0x01 /* timer is running, interrupts disabled */ +#define WD_EXPIRED 0x02 /* timer has expired */ +#define WD_RUNNING 0x04 /* timer is running, interrupts enabled */ +#define WD_STOPPED 0x08 /* timer has not been started */ +#define WD_SERVICED 0x10 /* timer interrupt was serviced */ + +#endif /* ifndef _SPARC64_WATCHDOG_H */ + diff --git a/include/linux/acpi.h b/include/linux/acpi.h index ff1dcaf45551..38b7a6a982a5 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -28,8 +28,6 @@ #include <linux/wait.h> #endif /* __KERNEL__ */ -u64 acpi_get_rsdp_ptr(void); - /* * System sleep states */ diff --git a/include/linux/dn.h b/include/linux/dn.h index c7448158b152..d98b0c3c7903 100644 --- a/include/linux/dn.h +++ b/include/linux/dn.h @@ -45,7 +45,12 @@ #define DSO_LINKINFO 7 /* Set/Get link information */ #define DSO_STREAM 8 /* Set socket type to stream */ #define DSO_SEQPACKET 9 /* Set socket type to sequenced packet */ -#define DSO_MAX 10 /* Maximum option number */ +#define DSO_MAXWINDOW 11 /* Maximum window size allowed */ +#define DSO_NODELAY 12 /* Turn off nagle */ +#define DSO_CORK 13 /* Wait for more data! */ +#define DSO_SERVICES 14 /* NSP Services field */ +#define DSO_INFO 15 /* NSP Info field */ +#define DSO_MAX 15 /* Maximum option number */ /* LINK States */ @@ -138,5 +143,6 @@ struct dn_addr { #define SIOCGNETADDR _IOR(DECNET_IOCTL_BASE, 0xe1, struct dn_naddr) #define OSIOCSNETADDR _IOW(DECNET_IOCTL_BASE, 0xe0, int) #define OSIOCGNETADDR _IOR(DECNET_IOCTL_BASE, 0xe1, int) +/* #define SIOCATEOR _IOR(DECNET_IOCTL_BASE, 0x01, int) */ #endif /* _LINUX_DN_H */ diff --git a/include/linux/sched.h b/include/linux/sched.h index 4f6645a3d555..d139801f4041 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -563,6 +563,7 @@ extern void FASTCALL(wake_up_process(struct task_struct * tsk)); #define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE, 0) #define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1) #define wake_up_interruptible_sync_nr(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, nr) +asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options, struct rusage * ru); extern int in_group_p(gid_t); extern int in_egroup_p(gid_t); diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index 80feae4c7e40..f24e4de6b9ac 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h @@ -30,7 +30,7 @@ extern struct vt_struct { wait_queue_head_t paste_wait; } *vt_cons[MAX_NR_CONSOLES]; -void (*kd_mksound)(unsigned int hz, unsigned int ticks); +extern void (*kd_mksound)(unsigned int hz, unsigned int ticks); /* console.c */ diff --git a/include/net/dn.h b/include/net/dn.h index 52c6ba44d4b8..c4c598f2f15c 100644 --- a/include/net/dn.h +++ b/include/net/dn.h @@ -9,6 +9,8 @@ typedef unsigned short dn_address; #define dn_ntohs(x) le16_to_cpu((unsigned short)(x)) #define dn_htons(x) cpu_to_le16((unsigned short)(x)) +#define DN_SK(sk) (&sk->protinfo.dn) + struct dn_scp /* Session Control Port */ { unsigned char state; @@ -44,9 +46,23 @@ struct dn_scp /* Session Control Port */ #define DN_SEND 2 #define DN_DONTSEND 1 #define DN_NOCHANGE 0 + unsigned short flowrem_dat; + unsigned short flowrem_oth; + unsigned short flowloc_dat; + unsigned short flowloc_oth; + unsigned char services_rem; + unsigned char services_loc; + unsigned char info_rem; + unsigned char info_loc; + + unsigned short segsize_rem; + unsigned short segsize_loc; + + unsigned char at_eor; + unsigned char nonagle; + unsigned char multi_ireq; unsigned char accept_mode; - unsigned short mss; - unsigned long seg_size; /* Running total of current segment */ + unsigned long seg_total; /* Running total of current segment */ struct optdata_dn conndata_in; struct optdata_dn conndata_out; @@ -80,7 +96,8 @@ struct dn_scp /* Session Control Port */ * multipliers. */ #define NSP_MIN_WINDOW 1 -#define NSP_MAX_WINDOW 512 +#define NSP_MAX_WINDOW (0x07fe) + unsigned long max_window; unsigned long snd_window; #define NSP_INITIAL_SRTT (HZ) unsigned long nsp_srtt; @@ -116,6 +133,7 @@ struct dn_scp /* Session Control Port */ struct timer_list delack_timer; int delack_pending; void (*delack_fxn)(struct sock *sk); + }; /* @@ -128,7 +146,7 @@ struct dn_scp /* Session Control Port */ * segsize : Size of segment * segnum : Number, for data, otherdata and linkservice * xmit_count : Number of times we've transmitted this skb - * stamp : Time stamp of first transmission, used in RTT calculations + * stamp : Time stamp of most recent transmission, used in RTT calculations * iif: Input interface number * * As a general policy, this structure keeps all addresses in network @@ -136,6 +154,7 @@ struct dn_scp /* Session Control Port */ * and src_port are in network order. All else is in host order. * */ +#define DN_SKB_CB(skb) ((struct dn_skb_cb *)(skb)->cb) struct dn_skb_cb { unsigned short dst; unsigned short src; diff --git a/include/net/dn_nsp.h b/include/net/dn_nsp.h index 8b628d2e5341..3948c30a33ca 100644 --- a/include/net/dn_nsp.h +++ b/include/net/dn_nsp.h @@ -24,12 +24,12 @@ extern void dn_nsp_send_disc(struct sock *sk, unsigned char type, unsigned short reason, int gfp); extern void dn_nsp_return_disc(struct sk_buff *skb, unsigned char type, unsigned short reason); -extern void dn_nsp_send_lnk(struct sock *sk, unsigned short flags); +extern void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval); extern void dn_nsp_send_conninit(struct sock *sk, unsigned char flags); extern void dn_nsp_output(struct sock *sk); extern int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum); -extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int oob); +extern void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oob); extern unsigned long dn_nsp_persist(struct sock *sk); extern int dn_nsp_xmit_timeout(struct sock *sk); @@ -120,6 +120,7 @@ struct nsp_conn_init_msg #define NSP_FC_NONE 0x00 /* Flow Control None */ #define NSP_FC_SRC 0x04 /* Seg Req. Count */ #define NSP_FC_SCMC 0x08 /* Sess. Control Mess */ +#define NSP_FC_MASK 0x0c /* FC type mask */ unsigned char info __attribute__((packed)); unsigned short segsize __attribute__((packed)); }; @@ -178,13 +179,13 @@ static __inline__ int before_or_equal(unsigned short seq1, unsigned short seq2) static __inline__ void seq_add(unsigned short *seq, unsigned short off) { - *seq += off; - *seq &= 0x0fff; + (*seq) += off; + (*seq) &= 0x0fff; } static __inline__ int seq_next(unsigned short seq1, unsigned short seq2) { - return (((seq2&0x0fff) - (seq1&0x0fff)) == 1); + return equal(seq1 + 1, seq2); } /* diff --git a/include/net/ipx.h b/include/net/ipx.h index bc023a6624c0..ba788670fd6c 100644 --- a/include/net/ipx.h +++ b/include/net/ipx.h @@ -73,6 +73,14 @@ typedef struct ipx_route { struct ipx_route *ir_next; } ipx_route; +#ifdef __KERNEL__ +struct ipx_cb { + u8 ipx_tctrl; + u32 ipx_dest_net; + u32 ipx_source_net; + int last_hop_index; +}; +#endif #define IPX_MIN_EPHEMERAL_SOCKET 0x4000 #define IPX_MAX_EPHEMERAL_SOCKET 0x7fff diff --git a/include/net/x25.h b/include/net/x25.h index 257618d44983..2e1e884261dd 100644 --- a/include/net/x25.h +++ b/include/net/x25.h @@ -217,6 +217,7 @@ extern void x25_start_t23timer(struct sock *); extern void x25_stop_heartbeat(struct sock *); extern void x25_stop_timer(struct sock *); extern unsigned long x25_display_timer(struct sock *); +extern void x25_check_rbuf(struct sock *); /* sysctl_net_x25.c */ extern void x25_register_sysctl(void); diff --git a/kernel/fork.c b/kernel/fork.c index cee975bdc29c..e578a9644379 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -447,7 +447,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) if (size > __FD_SETSIZE) { newf->max_fdset = 0; write_lock(&newf->file_lock); - error = expand_fdset(newf, size); + error = expand_fdset(newf, size-1); write_unlock(&newf->file_lock); if (error) goto out_release; @@ -466,7 +466,7 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk) read_unlock(&oldf->file_lock); newf->max_fds = 0; write_lock(&newf->file_lock); - error = expand_fd_array(newf, open_files); + error = expand_fd_array(newf, open_files-1); write_unlock(&newf->file_lock); if (error) goto out_release; diff --git a/mm/swap.c b/mm/swap.c index 693773ccd7bf..b1a6640bc5e5 100644 --- a/mm/swap.c +++ b/mm/swap.c @@ -30,8 +30,7 @@ * start background swapping if we fall below freepages.high free * pages, and we begin intensive swapping below freepages.low. * - * Actual initialization is done in mm/page_alloc.c or - * arch/sparc(64)/mm/init.c. + * Actual initialization is done in mm/page_alloc.c */ freepages_t freepages = { 0, /* freepages.min */ diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index c67e3fdd0014..ce5fc6d0dc0b 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -25,6 +25,7 @@ * Jaume Grau - flush caches on AARP_PROBE * Rob Newberry - Added proxy AARP and AARP proc fs, * moved probing from DDP module. + * Arnaldo C. Melo - don't mangle rx packets * */ @@ -58,16 +59,12 @@ #include <linux/init.h> #include <linux/proc_fs.h> - int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; int sysctl_aarp_tick_time = AARP_TICK_TIME; int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT; int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; -/* - * Lists of aarp entries - */ - +/* Lists of aarp entries */ struct aarp_entry { /* These first two are only used for unresolved entries */ unsigned long last_sent; /* Last time we xmitted the aarp request */ @@ -81,22 +78,16 @@ struct aarp_entry { struct aarp_entry *next; /* Next entry in chain */ }; -/* - * Hashed list of resolved, unresolved and proxy entries - */ - +/* Hashed list of resolved, unresolved and proxy entries */ static struct aarp_entry *resolved[AARP_HASH_SIZE]; static struct aarp_entry *unresolved[AARP_HASH_SIZE]; static struct aarp_entry *proxies[AARP_HASH_SIZE]; -static int unresolved_count = 0; +static int unresolved_count; /* One lock protects it all. */ static spinlock_t aarp_lock = SPIN_LOCK_UNLOCKED; -/* - * Used to walk the list and purge/kick entries. - */ - +/* Used to walk the list and purge/kick entries. */ static struct timer_list aarp_timer; /* @@ -108,7 +99,7 @@ static void __aarp_expire(struct aarp_entry *a) { struct sk_buff *skb; - while ((skb=skb_dequeue(&a->packet_queue)) != NULL) + while ((skb = skb_dequeue(&a->packet_queue)) != NULL) kfree_skb(skb); kfree(a); @@ -125,33 +116,29 @@ static void __aarp_send_query(struct aarp_entry *a) static char aarp_eth_multicast[ETH_ALEN] = { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; struct net_device *dev = a->dev; - int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length; + int len = dev->hard_header_len + sizeof(struct elapaarp) + + aarp_dl->header_length; struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - struct elapaarp *eah; struct at_addr *sat = atalk_find_dev_addr(dev); + struct elapaarp *eah; - if (skb == NULL) + if (!skb) return; - if (sat == NULL) { + if (!sat) { kfree_skb(skb); return; } - /* - * Set up the buffer. - */ - + /* Set up the buffer */ skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - eah = (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp)); + eah = (struct elapaarp *)skb_put(skb, + sizeof(struct elapaarp)); skb->protocol = htons(ETH_P_ATALK); skb->nh.raw = skb->h.raw = (void *) eah; skb->dev = dev; - /* - * Set up the ARP. - */ - + /* Set up the ARP */ eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); eah->pa_type = htons(ETH_P_ATALK); eah->hw_len = ETH_ALEN; @@ -170,52 +157,37 @@ static void __aarp_send_query(struct aarp_entry *a) eah->pa_dst_net = a->target_addr.s_net; eah->pa_dst_node= a->target_addr.s_node; - /* - * Add ELAP headers and set target to the AARP multicast. - */ - + /* Add ELAP headers and set target to the AARP multicast */ aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast); - /* - * Send it. - */ - + /* Send it */ dev_queue_xmit(skb); - - /* - * Update the sending count - */ - + /* Update the sending count */ a->xmit_count++; } -/* This runs under aarp_lock and in softint context, so only - * atomic memory allocations can be used. - */ +/* This runs under aarp_lock and in softint context, so only atomic memory + * allocations can be used. */ static void aarp_send_reply(struct net_device *dev, struct at_addr *us, struct at_addr *them, unsigned char *sha) { - int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length; + int len = dev->hard_header_len + sizeof(struct elapaarp) + + aarp_dl->header_length; struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); struct elapaarp *eah; - if (skb == NULL) + if (!skb) return; - /* - * Set up the buffer. - */ - + /* Set up the buffer */ skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - eah = (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp)); + eah = (struct elapaarp *)skb_put(skb, + sizeof(struct elapaarp)); skb->protocol = htons(ETH_P_ATALK); skb->nh.raw = skb->h.raw = (void *) eah; skb->dev = dev; - /* - * Set up the ARP. - */ - + /* Set up the ARP */ eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); eah->pa_type = htons(ETH_P_ATALK); eah->hw_len = ETH_ALEN; @@ -228,7 +200,7 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us, eah->pa_src_net = us->s_net; eah->pa_src_node= us->s_node; - if (sha == NULL) + if (!sha) memset(eah->hw_dst, '\0', ETH_ALEN); else memcpy(eah->hw_dst, sha, ETH_ALEN); @@ -237,47 +209,38 @@ static void aarp_send_reply(struct net_device *dev, struct at_addr *us, eah->pa_dst_net = them->s_net; eah->pa_dst_node= them->s_node; - /* - * Add ELAP headers and set target to the AARP multicast. - */ - + /* Add ELAP headers and set target to the AARP multicast */ aarp_dl->datalink_header(aarp_dl, skb, sha); - - /* - * Send it. - */ + /* Send it */ dev_queue_xmit(skb); } /* - * Send probe frames. Called from aarp_probe_network and aarp_proxy_probe_network. + * Send probe frames. Called from aarp_probe_network and + * aarp_proxy_probe_network. */ void aarp_send_probe(struct net_device *dev, struct at_addr *us) { - int len = dev->hard_header_len + sizeof(struct elapaarp) + aarp_dl->header_length; + int len = dev->hard_header_len + sizeof(struct elapaarp) + + aarp_dl->header_length; struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC); - struct elapaarp *eah; static char aarp_eth_multicast[ETH_ALEN] = { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + struct elapaarp *eah; - if (skb == NULL) + if (!skb) return; - /* - * Set up the buffer. - */ - + /* Set up the buffer */ skb_reserve(skb, dev->hard_header_len + aarp_dl->header_length); - eah = (struct elapaarp *)skb_put(skb, sizeof(struct elapaarp)); + eah = (struct elapaarp *)skb_put(skb, + sizeof(struct elapaarp)); skb->protocol = htons(ETH_P_ATALK); skb->nh.raw = skb->h.raw = (void *) eah; skb->dev = dev; - /* - * Set up the ARP. - */ - + /* Set up the ARP */ eah->hw_type = htons(AARP_HW_TYPE_ETHERNET); eah->pa_type = htons(ETH_P_ATALK); eah->hw_len = ETH_ALEN; @@ -296,15 +259,9 @@ void aarp_send_probe(struct net_device *dev, struct at_addr *us) eah->pa_dst_net = us->s_net; eah->pa_dst_node= us->s_node; - /* - * Add ELAP headers and set target to the AARP multicast. - */ - + /* Add ELAP headers and set target to the AARP multicast */ aarp_dl->datalink_header(aarp_dl, skb, aarp_eth_multicast); - - /* - * Send it. - */ + /* Send it */ dev_queue_xmit(skb); } @@ -318,16 +275,14 @@ static void __aarp_expire_timer(struct aarp_entry **n) { struct aarp_entry *t; - while ((*n) != NULL) { + while (*n) /* Expired ? */ - if(time_after(jiffies, (*n)->expires_at)) { + if (time_after(jiffies, (*n)->expires_at)) { t = *n; *n = (*n)->next; __aarp_expire(t); - } else { + } else n = &((*n)->next); - } - } } /* @@ -340,10 +295,8 @@ static void __aarp_kick(struct aarp_entry **n) { struct aarp_entry *t; - while ((*n) != NULL) { - /* Expired - if this will be the 11th transmit, we delete - * instead. - */ + while (*n) + /* Expired: if this will be the 11th tx, we delete instead. */ if ((*n)->xmit_count >= sysctl_aarp_retransmit_limit) { t = *n; *n = (*n)->next; @@ -352,7 +305,6 @@ static void __aarp_kick(struct aarp_entry **n) __aarp_send_query(*n); n = &((*n)->next); } - } } /* @@ -366,21 +318,16 @@ static void __aarp_expire_device(struct aarp_entry **n, struct net_device *dev) { struct aarp_entry *t; - while ((*n) != NULL) { + while (*n) if ((*n)->dev == dev) { t = *n; *n = (*n)->next; __aarp_expire(t); - } else { + } else n = &((*n)->next); - } - } } -/* - * Handle the timer event - */ - +/* Handle the timer event */ static void aarp_expire_timeout(unsigned long unused) { int ct; @@ -395,17 +342,14 @@ static void aarp_expire_timeout(unsigned long unused) } spin_unlock_bh(&aarp_lock); - mod_timer(&aarp_timer, jiffies + - (unresolved_count ? sysctl_aarp_tick_time: + (unresolved_count ? sysctl_aarp_tick_time : sysctl_aarp_expiry_time)); } -/* - * Network device notifier chain handler. - */ - -static int aarp_device_event(struct notifier_block *this, unsigned long event, void *ptr) +/* Network device notifier chain handler. */ +static int aarp_device_event(struct notifier_block *this, unsigned long event, + void *ptr) { int ct; @@ -432,11 +376,8 @@ static struct aarp_entry *aarp_alloc(void) { struct aarp_entry *a = kmalloc(sizeof(struct aarp_entry), GFP_ATOMIC); - if (a == NULL) - return NULL; - - skb_queue_head_init(&a->packet_queue); - + if (a) + skb_queue_head_init(&a->packet_queue); return a; } @@ -464,10 +405,8 @@ static struct aarp_entry *__aarp_find_entry(struct aarp_entry *list, /* Called from the DDP code, and thus must be exported. */ void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa) { + int hash = sa->s_node % (AARP_HASH_SIZE - 1); struct aarp_entry *a; - int hash; - - hash = sa->s_node % (AARP_HASH_SIZE-1); spin_lock_bh(&aarp_lock); @@ -479,23 +418,15 @@ void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa) } /* This must run under aarp_lock. */ -static struct at_addr *__aarp_proxy_find(struct net_device *dev, struct at_addr *sa) +static struct at_addr *__aarp_proxy_find(struct net_device *dev, + struct at_addr *sa) { - struct at_addr *retval; - struct aarp_entry *a; - int hash; + int hash = sa->s_node % (AARP_HASH_SIZE - 1); + struct aarp_entry *a = __aarp_find_entry(proxies[hash], dev, sa); - hash = sa->s_node % (AARP_HASH_SIZE-1); - - retval = NULL; - a = __aarp_find_entry(proxies[hash], dev, sa); - if (a != NULL) - retval = sa; - - return retval; + return a ? sa : NULL; } - /* * Probe a Phase 1 device or a device that requires its Net:Node to * be set via an ioctl. @@ -506,13 +437,13 @@ void aarp_send_probe_phase1(struct atalk_iface *iface) struct sockaddr_at *sa = (struct sockaddr_at *)&atreq.ifr_addr; sa->sat_addr.s_node = iface->address.s_node; - sa->sat_addr.s_net = ntohs(iface->address.s_net); + sa->sat_addr.s_net = ntohs(iface->address.s_net); /* We pass the Net:Node to the drivers/cards by a Device ioctl. */ if (!(iface->dev->do_ioctl(iface->dev, &atreq, SIOCSIFADDR))) { (void)iface->dev->do_ioctl(iface->dev, &atreq, SIOCGIFADDR); - if ((iface->address.s_net != htons(sa->sat_addr.s_net)) || - (iface->address.s_node != sa->sat_addr.s_node)) + if (iface->address.s_net != htons(sa->sat_addr.s_net) || + iface->address.s_node != sa->sat_addr.s_node) iface->status |= ATIF_PROBE_FAIL; iface->address.s_net = htons(sa->sat_addr.s_net); @@ -523,17 +454,16 @@ void aarp_send_probe_phase1(struct atalk_iface *iface) void aarp_probe_network(struct atalk_iface *atif) { - if(atif->dev->type == ARPHRD_LOCALTLK || atif->dev->type == ARPHRD_PPP) { + if (atif->dev->type == ARPHRD_LOCALTLK || + atif->dev->type == ARPHRD_PPP) aarp_send_probe_phase1(atif); - } else { + else { unsigned int count; for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { aarp_send_probe(atif->dev, &atif->address); - /* - * Defer 1/10th - */ + /* Defer 1/10th */ current->state = TASK_INTERRUPTIBLE; schedule_timeout(HZ/10); @@ -545,9 +475,9 @@ void aarp_probe_network(struct atalk_iface *atif) int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa) { - struct aarp_entry *entry; + int hash, retval = 1; + struct aarp_entry *entry; unsigned int count; - int hash, retval; /* * we don't currently support LocalTalk or PPP for proxy AARP; @@ -564,7 +494,7 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa) * we need this one to hang around even if it's in use */ entry = aarp_alloc(); - if (entry == NULL) + if (!entry) return -ENOMEM; entry->expires_at = -1; @@ -582,56 +512,38 @@ int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa) for (count = 0; count < AARP_RETRANSMIT_LIMIT; count++) { aarp_send_probe(atif->dev, sa); - /* - * Defer 1/10th - */ + /* Defer 1/10th */ current->state = TASK_INTERRUPTIBLE; - spin_unlock_bh(&aarp_lock); - schedule_timeout(HZ/10); - spin_lock_bh(&aarp_lock); if (entry->status & ATIF_PROBE_FAIL) break; } - retval = 1; - if (entry->status & ATIF_PROBE_FAIL) { - /* free the entry */ - entry->expires_at = jiffies - 1; - - /* return network full */ - retval = -EADDRINUSE; - } else { - /* clear the probing flag */ + entry->expires_at = jiffies - 1; /* free the entry */ + retval = -EADDRINUSE; /* return network full */ + } else /* clear the probing flag */ entry->status &= ~ATIF_PROBE; - } spin_unlock_bh(&aarp_lock); - return retval; } - -/* - * Send a DDP frame - */ -int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa, void *hwaddr) +/* Send a DDP frame */ +int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, + struct at_addr *sa, void *hwaddr) { - static char ddp_eth_multicast[ETH_ALEN] = { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; + static char ddp_eth_multicast[ETH_ALEN] = + { 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF }; int hash; struct aarp_entry *a; skb->nh.raw = skb->data; - /* - * Check for LocalTalk first - */ - - + /* Check for LocalTalk first */ if (dev->type == ARPHRD_LOCALTLK) { struct at_addr *at = atalk_find_dev_addr(dev); struct ddpehdr *ddp = (struct ddpehdr *)skb->data; @@ -644,8 +556,8 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa * (zero matches anything) */ - if( ( ddp->deh_snet==0 || at->s_net==ddp->deh_snet) && - ( ddp->deh_dnet==0 || at->s_net==ddp->deh_dnet) ) { + if ((!ddp->deh_snet || at->s_net == ddp->deh_snet) && + (!ddp->deh_dnet || at->s_net == ddp->deh_dnet)) { skb_pull(skb, sizeof(struct ddpehdr) - 4); /* @@ -665,104 +577,58 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa skb->data[0] = sa->s_node; skb->data[1] = at->s_node; skb->data[2] = ft; - - if (skb->sk) - skb->priority = skb->sk->priority; skb->dev = dev; - dev_queue_xmit(skb); - return 1; + goto sendit; } - /* - * On a PPP link we neither compress nor aarp. - */ + /* On a PPP link we neither compress nor aarp. */ if (dev->type == ARPHRD_PPP) { skb->protocol = htons(ETH_P_PPPTALK); - if (skb->sk) - skb->priority = skb->sk->priority; skb->dev = dev; - dev_queue_xmit(skb); - return 1; + goto sendit; } - /* - * Non ELAP we cannot do. - */ - + /* Non ELAP we cannot do. */ if (dev->type != ARPHRD_ETHER) return -1; skb->dev = dev; skb->protocol = htons(ETH_P_ATALK); - hash = sa->s_node % (AARP_HASH_SIZE - 1); - /* - * Do we have a resolved entry ? - */ - + /* Do we have a resolved entry? */ if (sa->s_node == ATADDR_BCAST) { ddp_dl->datalink_header(ddp_dl, skb, ddp_eth_multicast); - - if (skb->sk) - skb->priority = skb->sk->priority; - dev_queue_xmit(skb); - return 1; + goto sendit; } spin_lock_bh(&aarp_lock); - a = __aarp_find_entry(resolved[hash], dev, sa); - if (a != NULL) { - /* - * Return 1 and fill in the address - */ - + if (a) { /* Return 1 and fill in the address */ a->expires_at = jiffies + (sysctl_aarp_expiry_time * 10); ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr); - if(skb->sk) - skb->priority = skb->sk->priority; - dev_queue_xmit(skb); - spin_unlock_bh(&aarp_lock); - return 1; + goto sendit; } - /* - * Do we have an unresolved entry: This is the less common path - */ - + /* Do we have an unresolved entry: This is the less common path */ a = __aarp_find_entry(unresolved[hash], dev, sa); - if (a != NULL) { - /* - * Queue onto the unresolved queue - */ - + if (a) { /* Queue onto the unresolved queue */ skb_queue_tail(&a->packet_queue, skb); - spin_unlock_bh(&aarp_lock); return 0; } - /* - * Allocate a new entry - */ - + /* Allocate a new entry */ a = aarp_alloc(); - if (a == NULL) { - /* - * Whoops slipped... good job it's an unreliable - * protocol 8) - */ + if (!a) { + /* Whoops slipped... good job it's an unreliable protocol 8) */ spin_unlock_bh(&aarp_lock); return -1; } - /* - * Set up the queue - */ - + /* Set up the queue */ skb_queue_tail(&a->packet_queue, skb); a->expires_at = jiffies + sysctl_aarp_resolve_time; a->dev = dev; @@ -772,10 +638,7 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa unresolved[hash] = a; unresolved_count++; - /* - * Send an initial request for the address - */ - + /* Send an initial request for the address */ __aarp_send_query(a); /* @@ -786,18 +649,16 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa if (unresolved_count == 1) mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); - - /* - * Now finally, it is safe to drop the lock. - */ - + /* Now finally, it is safe to drop the lock. */ spin_unlock_bh(&aarp_lock); - /* - * Tell the ddp layer we have taken over for this frame. - */ - + /* Tell the ddp layer we have taken over for this frame. */ return 0; + +sendit: if (skb->sk) + skb->priority = skb->sk->priority; + dev_queue_xmit(skb); + return 1; } /* @@ -806,170 +667,112 @@ int aarp_send_ddp(struct net_device *dev,struct sk_buff *skb, struct at_addr *sa * * Must run under aarp_lock. */ -static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int hash) +static void __aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, + int hash) { struct sk_buff *skb; - while (*list != NULL) { + while (*list) if (*list == a) { unresolved_count--; - *list = a->next; - /* - * Move into the resolved list - */ - + /* Move into the resolved list */ a->next = resolved[hash]; resolved[hash] = a; - /* - * Kick frames off - */ - + /* Kick frames off */ while ((skb = skb_dequeue(&a->packet_queue)) != NULL) { - a->expires_at = jiffies + (sysctl_aarp_expiry_time*10); + a->expires_at = jiffies + + sysctl_aarp_expiry_time * 10; ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr); if (skb->sk) skb->priority = skb->sk->priority; dev_queue_xmit(skb); } - } else { + } else list = &((*list)->next); - } - } } /* * This is called by the SNAP driver whenever we see an AARP SNAP * frame. We currently only support Ethernet. */ -static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) +static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) { - struct elapaarp *ea=(struct elapaarp *)skb->h.raw; + struct elapaarp *ea = (struct elapaarp *)skb->h.raw; + int hash, ret = 0; + __u16 function; struct aarp_entry *a; struct at_addr sa, *ma, da; - int hash; struct atalk_iface *ifa; - /* - * We only do Ethernet SNAP AARP. - */ - - if (dev->type != ARPHRD_ETHER) { - kfree_skb(skb); - return 0; - } - - /* - * Frame size ok ? - */ - - if (!skb_pull(skb, sizeof(*ea))) { - kfree_skb(skb); - return 0; - } - - ea->function = ntohs(ea->function); + /* We only do Ethernet SNAP AARP. */ + if (dev->type != ARPHRD_ETHER) + goto out0; - /* - * Sanity check fields. - */ + /* Frame size ok? */ + if (!skb_pull(skb, sizeof(*ea))) + goto out0; - if (ea->function < AARP_REQUEST || - ea->function > AARP_PROBE || - ea->hw_len != ETH_ALEN || - ea->pa_len != AARP_PA_ALEN || - ea->pa_src_zero != 0 || - ea->pa_dst_zero != 0) { - kfree_skb(skb); - return 0; - } + function = ntohs(ea->function); - /* - * Looks good. - */ + /* Sanity check fields. */ + if (function < AARP_REQUEST || function > AARP_PROBE || + ea->hw_len != ETH_ALEN || ea->pa_len != AARP_PA_ALEN || + ea->pa_src_zero || ea->pa_dst_zero) + goto out0; + /* Looks good. */ hash = ea->pa_src_node % (AARP_HASH_SIZE - 1); - /* - * Build an address. - */ - + /* Build an address. */ sa.s_node = ea->pa_src_node; sa.s_net = ea->pa_src_net; - /* - * Process the packet. - * Check for replies of me. - */ - + /* Process the packet. Check for replies of me. */ ifa = atalk_find_dev(dev); - if (ifa == NULL) { - kfree_skb(skb); - return 1; - } - - if (ifa->status & ATIF_PROBE) { - if (ifa->address.s_node == ea->pa_dst_node && - ifa->address.s_net == ea->pa_dst_net) { - /* - * Fail the probe (in use) - */ - - ifa->status |= ATIF_PROBE_FAIL; - kfree_skb(skb); - return 1; - } + if (!ifa) + goto out1; + + if (ifa->status & ATIF_PROBE && + ifa->address.s_node == ea->pa_dst_node && + ifa->address.s_net == ea->pa_dst_net) { + ifa->status |= ATIF_PROBE_FAIL; /* Fail the probe (in use) */ + goto out1; } - /* - * Check for replies of proxy AARP entries - */ - + /* Check for replies of proxy AARP entries */ da.s_node = ea->pa_dst_node; da.s_net = ea->pa_dst_net; spin_lock_bh(&aarp_lock); - a = __aarp_find_entry(proxies[hash], dev, &da); - if (a != NULL) { - if (a->status & ATIF_PROBE) { - a->status |= ATIF_PROBE_FAIL; - - spin_unlock_bh(&aarp_lock); - - /* - * we do not respond to probe or request packets for - * this address while we are probing this address - */ - kfree_skb(skb); - - return 1; - } + if (a && a->status & ATIF_PROBE) { + a->status |= ATIF_PROBE_FAIL; + /* + * we do not respond to probe or request packets for + * this address while we are probing this address + */ + goto unlock; } - switch (ea->function) { + switch (function) { case AARP_REPLY: - if (unresolved_count == 0) /* Speed up */ + if (!unresolved_count) /* Speed up */ break; - /* - * Find the entry. - */ - - if ((a = __aarp_find_entry(unresolved[hash],dev,&sa)) == NULL || - (dev != a->dev)) + /* Find the entry. */ + a = __aarp_find_entry(unresolved[hash],dev,&sa); + if (!a || dev != a->dev) break; - /* - * We can fill one in - this is good. - */ - + /* We can fill one in - this is good. */ memcpy(a->hwaddr,ea->hw_src,ETH_ALEN); __aarp_resolved(&unresolved[hash],a,hash); - if (unresolved_count == 0) + if (!unresolved_count) mod_timer(&aarp_timer, jiffies + sysctl_aarp_expiry_time); break; @@ -977,49 +780,45 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t case AARP_REQUEST: case AARP_PROBE: /* - * If it is my address set ma to my address and reply. We can treat probe and - * request the same. Probe simply means we shouldn't cache the querying host, - * as in a probe they are proposing an address not using one. + * If it is my address set ma to my address and + * reply. We can treat probe and request the + * same. Probe simply means we shouldn't cache + * the querying host, as in a probe they are + * proposing an address not using one. * - * Support for proxy-AARP added. We check if the address is one - * of our proxies before we toss the packet out. + * Support for proxy-AARP added. We check if the + * address is one of our proxies before we toss + * the packet out. */ sa.s_node = ea->pa_dst_node; sa.s_net = ea->pa_dst_net; - /* - * See if we have a matching proxy. - */ + /* See if we have a matching proxy. */ ma = __aarp_proxy_find(dev, &sa); - if (!ma) { + if (!ma) ma = &ifa->address; - } else { - /* - * We need to make a copy of the entry. - */ + else { /* We need to make a copy of the entry. */ da.s_node = sa.s_node; da.s_net = da.s_net; ma = &da; } - if (ea->function == AARP_PROBE) { + if (function == AARP_PROBE) { /* A probe implies someone trying to get an * address. So as a precaution flush any - * entries we have for this address. - */ + * entries we have for this address. */ struct aarp_entry *a = __aarp_find_entry( - resolved[sa.s_node%(AARP_HASH_SIZE-1)], - skb->dev, - &sa); + resolved[sa.s_node%(AARP_HASH_SIZE-1)], + skb->dev, &sa); /* Make it expire next tick - that avoids us - * getting into a probe/flush/learn/probe/flush/learn - * cycle during probing of a slow to respond host addr. - */ - if (a != NULL) - { + * getting into a probe/flush/learn/probe/ + * flush/learn cycle during probing of a slow + * to respond host addr. */ + if (a) { a->expires_at = jiffies - 1; - mod_timer(&aarp_timer, jiffies + sysctl_aarp_tick_time); + mod_timer(&aarp_timer, jiffies + + sysctl_aarp_tick_time); } } @@ -1032,18 +831,16 @@ static int aarp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_t sa.s_node = ea->pa_src_node; sa.s_net = ea->pa_src_net; - /* - * aarp_my_address has found the address to use for us. - */ - + /* aarp_my_address has found the address to use for us. + */ aarp_send_reply(dev, ma, &sa, ea->hw_src); break; - }; - - spin_unlock_bh(&aarp_lock); + } - kfree_skb(skb); - return 1; +unlock: spin_unlock_bh(&aarp_lock); +out1: ret = 1; +out0: kfree_skb(skb); + return ret; } static struct notifier_block aarp_notifier = { @@ -1054,10 +851,10 @@ static struct notifier_block aarp_notifier = { static char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; - void __init aarp_proto_init(void) { - if ((aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv)) == NULL) + aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); + if (!aarp_dl) printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); init_timer(&aarp_timer); aarp_timer.function = aarp_expire_timeout; @@ -1067,9 +864,7 @@ void __init aarp_proto_init(void) register_netdevice_notifier(&aarp_notifier); } -/* - * Remove the AARP entries associated with a device. - */ +/* Remove the AARP entries associated with a device. */ void aarp_device_down(struct net_device *dev) { int ct; @@ -1085,14 +880,12 @@ void aarp_device_down(struct net_device *dev) spin_unlock_bh(&aarp_lock); } -/* - * Called from proc fs - */ +/* Called from proc fs */ static int aarp_get_info(char *buffer, char **start, off_t offset, int length) { /* we should dump all our AARP entries */ - struct aarp_entry *entry; - int len, ct; + struct aarp_entry *entry; + int len, ct; len = sprintf(buffer, "%-10.10s ""%-10.10s""%-18.18s""%12.12s""%12.12s"" xmit_count status\n", @@ -1171,25 +964,19 @@ static int aarp_get_info(char *buffer, char **start, off_t offset, int length) } spin_unlock_bh(&aarp_lock); - return len; } #ifdef MODULE -/* - * General module cleanup. Called from cleanup_module() in ddp.c. - */ +/* General module cleanup. Called from cleanup_module() in ddp.c. */ void aarp_cleanup_module(void) { del_timer(&aarp_timer); unregister_netdevice_notifier(&aarp_notifier); unregister_snap_client(aarp_snap_id); } - #endif /* MODULE */ - #ifdef CONFIG_PROC_FS - void aarp_register_proc_fs(void) { proc_net_create("aarp", 0, aarp_get_info); @@ -1199,7 +986,5 @@ void aarp_unregister_proc_fs(void) { proc_net_remove("aarp"); } - #endif - #endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index e7784dabd0cb..0e514faae0e2 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -29,15 +29,17 @@ * driver file. (ipddp.c & ipddp.h) * Jay Schulist : Made work as module with * AppleTalk drivers, cleaned it. - * Rob Newberry : Added proxy AARP and AARP proc fs, - * moved probing to AARP module. + * Rob Newberry : Added proxy AARP and AARP + * procfs, moved probing to AARP + * module. * Adrian Sun/ * Michael Zuelsdorff : fix for net.0 packets. don't * allow illegal ether/tokentalk * port assignment. we lose a * valid localtalk port as a * result. - * + * Arnaldo C. de Melo : Cleanup, in preparation for + * shared skb support 8) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -84,19 +86,19 @@ #include <linux/stat.h> #include <linux/init.h> - #ifdef CONFIG_PROC_FS extern void aarp_register_proc_fs(void); extern void aarp_unregister_proc_fs(void); #endif +extern void aarp_cleanup_module(void); + extern void aarp_probe_network(struct atalk_iface *atif); -extern int aarp_proxy_probe_network(struct atalk_iface *atif, struct at_addr *sa); +extern int aarp_proxy_probe_network(struct atalk_iface *atif, + struct at_addr *sa); extern void aarp_proxy_remove(struct net_device *dev, struct at_addr *sa); - #undef APPLETALK_DEBUG - #ifdef APPLETALK_DEBUG #define DPRINT(x) print(x) #else @@ -119,13 +121,14 @@ static struct proto_ops atalk_dgram_ops; * * \**************************************************************************/ -static struct sock *atalk_sockets = NULL; +static struct sock *atalk_sockets; static spinlock_t atalk_sockets_lock = SPIN_LOCK_UNLOCKED; extern inline void atalk_insert_socket(struct sock *sk) { spin_lock_bh(&atalk_sockets_lock); - if ((sk->next = atalk_sockets) != NULL) + sk->next = atalk_sockets; + if (sk->next) atalk_sockets->pprev = &sk->next; atalk_sockets = sk; sk->pprev = &atalk_sockets; @@ -135,7 +138,7 @@ extern inline void atalk_insert_socket(struct sock *sk) extern inline void atalk_remove_socket(struct sock *sk) { spin_lock_bh(&atalk_sockets_lock); - if (sk->pprev != NULL) { + if (sk->pprev) { if (sk->next) sk->next->pprev = sk->pprev; *sk->pprev = sk->next; @@ -144,12 +147,13 @@ extern inline void atalk_remove_socket(struct sock *sk) spin_unlock_bh(&atalk_sockets_lock); } -static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_iface *atif) +static struct sock *atalk_search_socket(struct sockaddr_at *to, + struct atalk_iface *atif) { struct sock *s; spin_lock_bh(&atalk_sockets_lock); - for (s = atalk_sockets; s != NULL; s = s->next) { + for (s = atalk_sockets; s; s = s->next) { if (to->sat_port != s->protinfo.af_at.src_port) continue; @@ -174,7 +178,6 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_ifa } } spin_unlock_bh(&atalk_sockets_lock); - return s; } @@ -185,29 +188,28 @@ static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_ifa * * This entire operation must execute atomically. */ -static struct sock *atalk_find_or_insert_socket(struct sock *sk, struct sockaddr_at *sat) +static struct sock *atalk_find_or_insert_socket(struct sock *sk, + struct sockaddr_at *sat) { struct sock *s; spin_lock_bh(&atalk_sockets_lock); - - for (s = atalk_sockets; s != NULL; s = s->next) { + for (s = atalk_sockets; s; s = s->next) if (s->protinfo.af_at.src_net == sat->sat_addr.s_net && s->protinfo.af_at.src_node == sat->sat_addr.s_node && s->protinfo.af_at.src_port == sat->sat_port) break; - } if (!s) { /* Wheee, it's free, assign and insert. */ - if ((sk->next = atalk_sockets) != NULL) + sk->next = atalk_sockets; + if (sk->next) atalk_sockets->pprev = &sk->next; atalk_sockets = sk; sk->pprev = &atalk_sockets; } spin_unlock_bh(&atalk_sockets_lock); - return s; } @@ -215,9 +217,8 @@ static void atalk_destroy_timer(unsigned long data) { struct sock *sk = (struct sock *) data; - if (atomic_read(&sk->wmem_alloc) == 0 && - atomic_read(&sk->rmem_alloc) == 0 && - sk->dead) { + if (!atomic_read(&sk->wmem_alloc) && + !atomic_read(&sk->rmem_alloc) && sk->dead) { sock_put(sk); MOD_DEC_USE_COUNT; } else { @@ -228,16 +229,11 @@ static void atalk_destroy_timer(unsigned long data) extern inline void atalk_destroy_socket(struct sock *sk) { - struct sk_buff *skb; - atalk_remove_socket(sk); + skb_queue_purge(&sk->receive_queue); - while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) - kfree_skb(skb); - - if (atomic_read(&sk->wmem_alloc) == 0 && - atomic_read(&sk->rmem_alloc) == 0 && - sk->dead) { + if (!atomic_read(&sk->wmem_alloc) && + !atomic_read(&sk->rmem_alloc) && sk->dead) { sock_put(sk); MOD_DEC_USE_COUNT; } else { @@ -249,37 +245,31 @@ extern inline void atalk_destroy_socket(struct sock *sk) } } -/* - * Called from proc fs - */ +/* Called from proc fs */ static int atalk_get_info(char *buffer, char **start, off_t offset, int length) { - struct sock *s; - int len = 0; off_t pos = 0; off_t begin = 0; - - /* - * Output the AppleTalk data for the /proc filesystem. - */ - - len += sprintf(buffer,"Type local_addr remote_addr tx_queue rx_queue st uid\n"); + int len = sprintf(buffer, "Type local_addr remote_addr tx_queue " + "rx_queue st uid\n"); + struct sock *s; + /* Output the AppleTalk data for the /proc filesystem */ spin_lock_bh(&atalk_sockets_lock); - for (s = atalk_sockets; s != NULL; s = s->next) { - len += sprintf(buffer+len,"%02X ", s->type); - len += sprintf(buffer+len,"%04X:%02X:%02X ", + for (s = atalk_sockets; s; s = s->next) { + len += sprintf(buffer + len,"%02X ", s->type); + len += sprintf(buffer + len,"%04X:%02X:%02X ", ntohs(s->protinfo.af_at.src_net), s->protinfo.af_at.src_node, s->protinfo.af_at.src_port); - len += sprintf(buffer+len,"%04X:%02X:%02X ", + len += sprintf(buffer + len,"%04X:%02X:%02X ", ntohs(s->protinfo.af_at.dest_net), s->protinfo.af_at.dest_node, s->protinfo.af_at.dest_port); - len += sprintf(buffer+len,"%08X:%08X ", + len += sprintf(buffer + len,"%08X:%08X ", atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc)); - len += sprintf(buffer+len,"%02X %d\n", s->state, + len += sprintf(buffer + len,"%02X %d\n", s->state, SOCK_INODE(s->socket)->i_uid); /* Are we still dumping unwanted data then discard the record */ @@ -295,8 +285,8 @@ static int atalk_get_info(char *buffer, char **start, off_t offset, int length) spin_unlock_bh(&atalk_sockets_lock); /* The data in question runs from begin to begin+len */ - *start = buffer + (offset - begin); /* Start of wanted data */ - len -= (offset - begin); /* Remove unwanted header data from length */ + *start = buffer + offset - begin; /* Start of wanted data */ + len -= offset - begin; /* Remove unwanted header data from length */ if (len > length) len = length; /* Remove unwanted tail data from length */ @@ -310,18 +300,16 @@ static int atalk_get_info(char *buffer, char **start, off_t offset, int length) \**************************************************************************/ /* Anti-deadlock ordering is router_lock --> iface_lock -DaveM */ -static struct atalk_route *atalk_router_list = NULL; +static struct atalk_route *atalk_router_list; static rwlock_t atalk_router_lock = RW_LOCK_UNLOCKED; -static struct atalk_iface *atalk_iface_list = NULL; +static struct atalk_iface *atalk_iface_list; static spinlock_t atalk_iface_lock = SPIN_LOCK_UNLOCKED; -static struct atalk_route atrtr_default; /* For probing devices or in a routerless network */ - -/* - * AppleTalk interface control - */ +/* For probing devices or in a routerless network */ +static struct atalk_route atrtr_default; +/* AppleTalk interface control */ /* * Drop a device. Doesn't drop any of its routes - that is the caller's * problem. Called when we down the interface or delete the address. @@ -344,12 +332,12 @@ static void atif_drop_device(struct net_device *dev) spin_unlock_bh(&atalk_iface_lock); } -static struct atalk_iface *atif_add_device(struct net_device *dev, struct at_addr *sa) +static struct atalk_iface *atif_add_device(struct net_device *dev, + struct at_addr *sa) { - struct atalk_iface *iface = (struct atalk_iface *) - kmalloc(sizeof(*iface), GFP_KERNEL); + struct atalk_iface *iface = kmalloc(sizeof(*iface), GFP_KERNEL); - if (iface == NULL) + if (!iface) return NULL; iface->dev = dev; @@ -363,51 +351,37 @@ static struct atalk_iface *atif_add_device(struct net_device *dev, struct at_add spin_unlock_bh(&atalk_iface_lock); MOD_INC_USE_COUNT; - return iface; } - -/* - * Perform phase 2 AARP probing on our tentative address. - */ +/* Perform phase 2 AARP probing on our tentative address */ static int atif_probe_device(struct atalk_iface *atif) { - int netrange = ntohs(atif->nets.nr_lastnet) - ntohs(atif->nets.nr_firstnet) + 1; + int netrange = ntohs(atif->nets.nr_lastnet) - + ntohs(atif->nets.nr_firstnet) + 1; int probe_net = ntohs(atif->address.s_net); int probe_node = atif->address.s_node; int netct, nodect; - /* - * Offset the network we start probing with. - */ - + /* Offset the network we start probing with */ if (probe_net == ATADDR_ANYNET) { - if (!netrange) - probe_net = ntohs(atif->nets.nr_firstnet); - else - probe_net = ntohs(atif->nets.nr_firstnet) + (jiffies % netrange); + probe_net = ntohs(atif->nets.nr_firstnet); + if (netrange) + probe_net += jiffies % netrange; } - if (probe_node == ATADDR_ANYNODE) probe_node = jiffies & 0xFF; - /* - * Scan the networks. - */ + /* Scan the networks */ atif->status |= ATIF_PROBE; for (netct = 0; netct <= netrange; netct++) { - /* - * Sweep the available nodes from a given start. - */ - + /* Sweep the available nodes from a given start */ atif->address.s_net = htons(probe_net); for (nodect = 0; nodect < 256; nodect++) { atif->address.s_node = ((nodect+probe_node) & 0xFF); - if (atif->address.s_node > 0 && atif->address.s_node < 254) { - /* - * Probe a proposed address. - */ + if (atif->address.s_node > 0 && + atif->address.s_node < 254) { + /* Probe a proposed address */ aarp_probe_network(atif); if (!(atif->status & ATIF_PROBE_FAIL)) { @@ -427,58 +401,45 @@ static int atif_probe_device(struct atalk_iface *atif) } -/* - * Perform AARP probing for a proxy address - */ -static int atif_proxy_probe_device(struct atalk_iface *atif, struct at_addr* proxy_addr) +/* Perform AARP probing for a proxy address */ +static int atif_proxy_probe_device(struct atalk_iface *atif, + struct at_addr* proxy_addr) { - int netrange = ntohs(atif->nets.nr_lastnet) - ntohs(atif->nets.nr_firstnet) + 1; - int probe_net = ntohs(atif->address.s_net); /* we probe the interface's network */ + int netrange = ntohs(atif->nets.nr_lastnet) - + ntohs(atif->nets.nr_firstnet) + 1; + /* we probe the interface's network */ + int probe_net = ntohs(atif->address.s_net); int probe_node = ATADDR_ANYNODE; /* we'll take anything */ int netct, nodect; - /* - * Offset the network we start probing with. - */ - + /* Offset the network we start probing with */ if (probe_net == ATADDR_ANYNET) { - if (!netrange) - probe_net = ntohs(atif->nets.nr_firstnet); - else - probe_net = ntohs(atif->nets.nr_firstnet) + (jiffies % netrange); + probe_net = ntohs(atif->nets.nr_firstnet); + if (netrange) + probe_net += jiffies % netrange; } if (probe_node == ATADDR_ANYNODE) probe_node = jiffies & 0xFF; - /* - * Scan the networks. - */ - + /* Scan the networks */ for (netct = 0; netct <= netrange; netct++) { - /* - * Sweep the available nodes from a given start. - */ - + /* Sweep the available nodes from a given start */ proxy_addr->s_net = htons(probe_net); for (nodect = 0; nodect < 256; nodect++) { proxy_addr->s_node = ((nodect + probe_node) & 0xFF); - if ((proxy_addr->s_node > 0) && (proxy_addr->s_node < 254)) { - /* - * Tell AARP to probe a proposed address. - */ - int probe_result = aarp_proxy_probe_network(atif, - proxy_addr); - - if (probe_result == 0) - return 0; - - if (probe_result != -EADDRINUSE) - return probe_result; + if (proxy_addr->s_node > 0 && + proxy_addr->s_node < 254) { + /* Tell AARP to probe a proposed address */ + int ret = aarp_proxy_probe_network(atif, + proxy_addr); + + if (ret != -EADDRINUSE) + return ret; } } probe_net++; - if(probe_net > ntohs(atif->nets.nr_lastnet)) + if (probe_net > ntohs(atif->nets.nr_lastnet)) probe_net = ntohs(atif->nets.nr_firstnet); } @@ -489,25 +450,21 @@ static int atif_proxy_probe_device(struct atalk_iface *atif, struct at_addr* pro struct at_addr *atalk_find_dev_addr(struct net_device *dev) { struct atalk_iface *iface = dev->atalk_ptr; - - if(iface) - return &iface->address; - - return NULL; + return iface ? &iface->address : NULL; } static struct at_addr *atalk_find_primary(void) { + struct atalk_iface *fiface = NULL; struct at_addr *retval; struct atalk_iface *iface; - struct atalk_iface *fiface = NULL; /* * Return a point-to-point interface only if * there is no non-ptp interface available. */ spin_lock_bh(&atalk_iface_lock); - for (iface = atalk_iface_list; iface != NULL; iface = iface->next) { + for (iface = atalk_iface_list; iface; iface = iface->next) { if (!fiface && !(iface->dev->flags & IFF_LOOPBACK)) fiface = iface; if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { @@ -516,16 +473,13 @@ static struct at_addr *atalk_find_primary(void) } } - if (fiface) { + if (fiface) retval = &fiface->address; - } else if (atalk_iface_list != NULL) { + else if (atalk_iface_list) retval = &atalk_iface_list->address; - } else { + else retval = NULL; - } -out: - spin_unlock_bh(&atalk_iface_lock); - +out: spin_unlock_bh(&atalk_iface_lock); return retval; } @@ -535,9 +489,9 @@ out: */ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) { - struct atalk_iface *iface=dev->atalk_ptr; + struct atalk_iface *iface = dev->atalk_ptr; - if (iface==NULL || (iface->status & ATIF_PROBE)) + if (!iface || iface->status & ATIF_PROBE) return NULL; if (node == ATADDR_BCAST || @@ -548,15 +502,13 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev) return NULL; } -/* - * Find a match for a specific network:node pair - */ +/* Find a match for a specific network:node pair */ static struct atalk_iface *atalk_find_interface(int net, int node) { struct atalk_iface *iface; spin_lock_bh(&atalk_iface_lock); - for (iface = atalk_iface_list; iface != NULL; iface = iface->next) { + for (iface = atalk_iface_list; iface; iface = iface->next) { if ((node == ATADDR_BCAST || node == ATADDR_ANYNODE || iface->address.s_node == node) && @@ -565,13 +517,12 @@ static struct atalk_iface *atalk_find_interface(int net, int node) break; /* XXXX.0 -- net.0 returns the iface associated with net */ - if ((node == ATADDR_ANYNODE) && (net != ATADDR_ANYNET) && - (ntohs(iface->nets.nr_firstnet) <= ntohs(net)) && - (ntohs(net) <= ntohs(iface->nets.nr_lastnet))) + if (node == ATADDR_ANYNODE && net != ATADDR_ANYNET && + ntohs(iface->nets.nr_firstnet) <= ntohs(net) && + ntohs(net) <= ntohs(iface->nets.nr_lastnet)) break; } spin_unlock_bh(&atalk_iface_lock); - return iface; } @@ -588,11 +539,11 @@ static struct atalk_route *atrtr_find(struct at_addr *target) * host route, because some host routes might overlap * network routes */ - struct atalk_route *r; struct atalk_route *net_route = NULL; + struct atalk_route *r; read_lock_bh(&atalk_router_lock); - for (r = atalk_router_list; r != NULL; r = r->next) { + for (r = atalk_router_list; r; r = r->next) { if (!(r->flags & RTF_UP)) continue; @@ -604,13 +555,12 @@ static struct atalk_route *atrtr_find(struct at_addr *target) */ if (r->target.s_node == target->s_node) goto out; - } else { + } else /* * this route will work if there isn't a * direct host route, so cache it */ net_route = r; - } } } @@ -618,19 +568,13 @@ static struct atalk_route *atrtr_find(struct at_addr *target) * if we found a network route but not a direct host * route, then return it */ - if (net_route != NULL) { + if (net_route) r = net_route; - } else if (atrtr_default.dev) { + else if (atrtr_default.dev) r = &atrtr_default; - } else { - /* - * No route can be found. - */ + else /* No route can be found */ r = NULL; - } - -out: - read_unlock_bh(&atalk_router_lock); +out: read_unlock_bh(&atalk_router_lock); return r; } @@ -642,16 +586,10 @@ out: struct net_device *atrtr_get_dev(struct at_addr *sa) { struct atalk_route *atr = atrtr_find(sa); - - if (atr == NULL) - return NULL; - else - return atr->dev; + return atr ? atr->dev : NULL; } -/* - * Set up a default router. - */ +/* Set up a default router */ static void atrtr_set_default(struct net_device *dev) { atrtr_default.dev = dev; @@ -678,20 +616,16 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint) * operations. */ - /* - * Validate the request - */ + /* Validate the request */ if (ta->sat_family != AF_APPLETALK) return -EINVAL; - if (devhint == NULL && ga->sat_family != AF_APPLETALK) + if (!devhint && ga->sat_family != AF_APPLETALK) return -EINVAL; - /* - * Now walk the routing table and make our decisions. - */ + /* Now walk the routing table and make our decisions */ write_lock_bh(&atalk_router_lock); - for (rt = atalk_router_list; rt != NULL; rt = rt->next) { + for (rt = atalk_router_list; rt; rt = rt->next) { if (r->rt_flags != rt->flags) continue; @@ -703,65 +637,59 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint) } } - if(devhint == NULL) { + if (!devhint) { riface = NULL; spin_lock_bh(&atalk_iface_lock); for (iface = atalk_iface_list; iface; iface = iface->next) { - if (riface == NULL && - ntohs(ga->sat_addr.s_net) >= ntohs(iface->nets.nr_firstnet) && - ntohs(ga->sat_addr.s_net) <= ntohs(iface->nets.nr_lastnet)) + if (!riface && + ntohs(ga->sat_addr.s_net) >= + ntohs(iface->nets.nr_firstnet) && + ntohs(ga->sat_addr.s_net) <= + ntohs(iface->nets.nr_lastnet)) riface = iface; - if (ga->sat_addr.s_net == iface->address.s_net && + if (ga->sat_addr.s_net == iface->address.s_net && ga->sat_addr.s_node == iface->address.s_node) riface = iface; } spin_unlock_bh(&atalk_iface_lock); retval = -ENETUNREACH; - if (riface == NULL) + if (!riface) goto out; devhint = riface->dev; } - if (rt == NULL) { - rt = (struct atalk_route *) - kmalloc(sizeof(struct atalk_route), GFP_ATOMIC); + if (!rt) { + rt = kmalloc(sizeof(struct atalk_route), GFP_ATOMIC); retval = -ENOBUFS; - if (rt == NULL) + if (!rt) goto out; rt->next = atalk_router_list; atalk_router_list = rt; } - /* - * Fill in the routing entry. - */ + /* Fill in the routing entry */ rt->target = ta->sat_addr; rt->dev = devhint; rt->flags = r->rt_flags; rt->gateway = ga->sat_addr; retval = 0; - -out: - write_unlock_bh(&atalk_router_lock); - +out: write_unlock_bh(&atalk_router_lock); return retval; } -/* - * Delete a route. Find it and discard it. - */ +/* Delete a route. Find it and discard it */ static int atrtr_delete(struct at_addr * addr) { struct atalk_route **r = &atalk_router_list; - struct atalk_route *tmp; int retval = 0; + struct atalk_route *tmp; write_lock_bh(&atalk_router_lock); while ((tmp = *r) != NULL) { @@ -775,8 +703,7 @@ static int atrtr_delete(struct at_addr * addr) r = &tmp->next; } retval = -ENOENT; -out: - write_unlock_bh(&atalk_router_lock); +out: write_unlock_bh(&atalk_router_lock); return retval; } @@ -794,9 +721,8 @@ void atrtr_device_down(struct net_device *dev) if (tmp->dev == dev) { *r = tmp->next; kfree(tmp); - } else { + } else r = &tmp->next; - } } write_unlock_bh(&atalk_router_lock); @@ -804,9 +730,7 @@ void atrtr_device_down(struct net_device *dev) atrtr_set_default(NULL); } -/* - * Actually down the interface. - */ +/* Actually down the interface */ static inline void atalk_dev_down(struct net_device *dev) { atrtr_device_down(dev); /* Remove all routes for the device */ @@ -818,27 +742,22 @@ static inline void atalk_dev_down(struct net_device *dev) * A device event has occurred. Watch for devices going down and * delete our use of them (iface and route). */ -static int ddp_device_event(struct notifier_block *this, unsigned long event, void *ptr) +static int ddp_device_event(struct notifier_block *this, unsigned long event, + void *ptr) { - if (event == NETDEV_DOWN) { + if (event == NETDEV_DOWN) /* Discard any use of this */ atalk_dev_down((struct net_device *) ptr); - } return NOTIFY_DONE; } -/* - * ioctl calls. Shouldn't even need touching. - */ - -/* - * Device configuration ioctl calls. - */ +/* ioctl calls. Shouldn't even need touching */ +/* Device configuration ioctl calls */ int atif_ioctl(int cmd, void *arg) { - struct ifreq atreq; static char aarp_mcast[6] = {0x09, 0x00, 0x00, 0xFF, 0xFF, 0xFF}; + struct ifreq atreq; struct netrange *nr; struct sockaddr_at *sa; struct net_device *dev; @@ -846,12 +765,13 @@ int atif_ioctl(int cmd, void *arg) int ct; int limit; struct rtentry rtdef; - int add_route; + int add_route; if (copy_from_user(&atreq, arg, sizeof(atreq))) return -EFAULT; - if ((dev = __dev_get_by_name(atreq.ifr_name)) == NULL) + dev = __dev_get_by_name(atreq.ifr_name); + if (!dev) return -ENODEV; sa = (struct sockaddr_at*) &atreq.ifr_addr; @@ -870,16 +790,19 @@ int atif_ioctl(int cmd, void *arg) return -EPROTONOSUPPORT; nr = (struct netrange *) &sa->sat_zero[0]; - add_route = 1; /* - * if this is a point-to-point iface, and we already have an - * iface for this AppleTalk address, then we should not add a route + * if this is a point-to-point iface, and we already + * have an iface for this AppleTalk address, then we + * should not add a route */ if ((dev->flags & IFF_POINTOPOINT) && - atalk_find_interface(sa->sat_addr.s_net, sa->sat_addr.s_node)) { - printk(KERN_DEBUG "AppleTalk: point-to-point interface added with existing address\n"); + atalk_find_interface(sa->sat_addr.s_net, + sa->sat_addr.s_node)) { + printk(KERN_DEBUG "AppleTalk: point-to-point " + "interface added with " + "existing address\n"); add_route = 0; } @@ -889,13 +812,11 @@ int atif_ioctl(int cmd, void *arg) */ if (dev->type == ARPHRD_ETHER && nr->nr_phase != 2) return -EPROTONOSUPPORT; - if (sa->sat_addr.s_node == ATADDR_BCAST || + if (sa->sat_addr.s_node == ATADDR_BCAST || sa->sat_addr.s_node == 254) return -EINVAL; if (atif) { - /* - * Already setting address. - */ + /* Already setting address */ if (atif->status & ATIF_PROBE) return -EBUSY; @@ -904,7 +825,7 @@ int atif_ioctl(int cmd, void *arg) atrtr_device_down(dev); /* Flush old routes */ } else { atif = atif_add_device(dev, &sa->sat_addr); - if (atif == NULL) + if (!atif) return -ENOMEM; } atif->nets = *nr; @@ -921,10 +842,7 @@ int atif_ioctl(int cmd, void *arg) return -EADDRINUSE; } - /* - * Hey it worked - add the direct routes. - */ - + /* Hey it worked - add the direct routes */ sa = (struct sockaddr_at *) &rtdef.rt_gateway; sa->sat_family = AF_APPLETALK; sa->sat_addr.s_net = atif->address.s_net; @@ -933,13 +851,11 @@ int atif_ioctl(int cmd, void *arg) rtdef.rt_flags = RTF_UP; sa->sat_family = AF_APPLETALK; sa->sat_addr.s_node = ATADDR_ANYNODE; - if ((dev->flags & IFF_LOOPBACK) || - (dev->flags & IFF_POINTOPOINT)) + if (dev->flags & IFF_LOOPBACK || + dev->flags & IFF_POINTOPOINT) rtdef.rt_flags |= RTF_HOST; - /* - * Routerless initial state. - */ + /* Routerless initial state */ if (nr->nr_firstnet == htons(0) && nr->nr_lastnet == htons(0xFFFE)) { sa->sat_addr.s_net = atif->address.s_net; @@ -948,37 +864,35 @@ int atif_ioctl(int cmd, void *arg) } else { limit = ntohs(nr->nr_lastnet); if (limit - ntohs(nr->nr_firstnet) > 4096) { - printk(KERN_WARNING "Too many routes/iface.\n"); + printk(KERN_WARNING "Too many routes/" + "iface.\n"); return -EINVAL; } - if (add_route) { - for(ct = ntohs(nr->nr_firstnet);ct <= limit; ct++) { + if (add_route) + for (ct = ntohs(nr->nr_firstnet); + ct <= limit; ct++) { sa->sat_addr.s_net = htons(ct); atrtr_create(&rtdef, dev); } - } } dev_mc_add(dev, aarp_mcast, 6, 1); return 0; case SIOCGIFADDR: - if (atif == NULL) + if (!atif) return -EADDRNOTAVAIL; - ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_family = - AF_APPLETALK; - ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr = - atif->address; + + sa->sat_family = AF_APPLETALK; + sa->sat_addr = atif->address; break; case SIOCGIFBRDADDR: - if (atif == NULL) + if (!atif) return -EADDRNOTAVAIL; - ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_family = - AF_APPLETALK; - ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_net = - atif->address.s_net; - ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_node = - ATADDR_BCAST; + + sa->sat_family = AF_APPLETALK; + sa->sat_addr.s_net = atif->address.s_net; + sa->sat_addr.s_node = ATADDR_BCAST; break; case SIOCATALKDIFADDR: @@ -995,7 +909,7 @@ int atif_ioctl(int cmd, void *arg) return -EPERM; if (sa->sat_family != AF_APPLETALK) return -EINVAL; - if (atif == NULL) + if (!atif) return -EADDRNOTAVAIL; /* @@ -1007,9 +921,10 @@ int atif_ioctl(int cmd, void *arg) /* * atif points to the current interface on this network; - * we aren't concerned about its current status (at least for now), - * but it has all the settings about the network we're going - * to probe. consequently, it must exist. + * we aren't concerned about its current status (at + * least for now), but it has all the settings about + * the network we're going to probe. Consequently, it + * must exist. */ if (!atif) return -EADDRNOTAVAIL; @@ -1034,10 +949,10 @@ int atif_ioctl(int cmd, void *arg) return -EADDRINUSE; /* - * We now have an address on the local network, and the AARP - * code will defend it for us until we take it down. - * We don't set up any routes right now, because ATCP will - * install them manually via SIOCADDRT. + * We now have an address on the local network, and + * the AARP code will defend it for us until we take it + * down. We don't set up any routes right now, because + * ATCP will install them manually via SIOCADDRT. */ break; @@ -1046,30 +961,22 @@ int atif_ioctl(int cmd, void *arg) return -EPERM; if (sa->sat_family != AF_APPLETALK) return -EINVAL; - if (atif == NULL) + if (!atif) return -EADDRNOTAVAIL; - /* - * give to aarp module to remove proxy entry - */ + /* give to aarp module to remove proxy entry */ aarp_proxy_remove(atif->dev, &(sa->sat_addr)); - return 0; - }; - - if (copy_to_user(arg, &atreq, sizeof(atreq))) - return -EFAULT; + } - return 0; + return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0; } -/* - * Routing ioctl() calls - */ +/* Routing ioctl() calls */ static int atrtr_ioctl(unsigned int cmd, void *arg) { - struct rtentry rt; struct net_device *dev = NULL; + struct rtentry rt; if (copy_from_user(&rt, arg, sizeof(rt))) return -EFAULT; @@ -1078,37 +985,38 @@ static int atrtr_ioctl(unsigned int cmd, void *arg) case SIOCDELRT: if (rt.rt_dst.sa_family != AF_APPLETALK) return -EINVAL; - return atrtr_delete(&((struct sockaddr_at *)&rt.rt_dst)->sat_addr); + return atrtr_delete(&((struct sockaddr_at *) + &rt.rt_dst)->sat_addr); case SIOCADDRT: - /* FIX ME: the name of the device is still in user space, isn't it? */ - if (rt.rt_dev != NULL) { - if ((dev = __dev_get_by_name(rt.rt_dev)) == NULL) + /* FIXME: the name of the device is still in user + * space, isn't it? */ + if (rt.rt_dev) { + dev = __dev_get_by_name(rt.rt_dev); + if (!dev) return -ENODEV; } return atrtr_create(&rt, dev); - - default: - return -EINVAL; - }; + } + return -EINVAL; } /* Called from proc fs - just make it print the ifaces neatly */ - -static int atalk_if_get_info(char *buffer, char **start, off_t offset, int length) +static int atalk_if_get_info(char *buffer, char **start, off_t offset, + int length) { - struct atalk_iface *iface; - int len = 0; off_t pos = 0; off_t begin = 0; - - len += sprintf(buffer,"Interface Address Networks Status\n"); + struct atalk_iface *iface; + int len = sprintf(buffer, "Interface Address " + "Networks Status\n"); spin_lock_bh(&atalk_iface_lock); - for (iface = atalk_iface_list; iface != NULL; iface = iface->next) { + for (iface = atalk_iface_list; iface; iface = iface->next) { len += sprintf(buffer+len,"%-16s %04X:%02X %04X-%04X %d\n", iface->dev->name, ntohs(iface->address.s_net), - iface->address.s_node, ntohs(iface->nets.nr_firstnet), + iface->address.s_node, + ntohs(iface->nets.nr_firstnet), ntohs(iface->nets.nr_lastnet), iface->status); pos = begin + len; if (pos < offset) { @@ -1124,33 +1032,32 @@ static int atalk_if_get_info(char *buffer, char **start, off_t offset, int lengt len -= (offset - begin); if (len > length) len = length; - - return (len); + return len; } /* Called from proc fs - just make it print the routes neatly */ - -static int atalk_rt_get_info(char *buffer, char **start, off_t offset, int length) +static int atalk_rt_get_info(char *buffer, char **start, off_t offset, + int length) { - struct atalk_route *rt; - int len = 0; off_t pos = 0; off_t begin = 0; + int len = sprintf(buffer, "Target Router Flags Dev\n"); + struct atalk_route *rt; - len += sprintf(buffer,"Target Router Flags Dev\n"); if (atrtr_default.dev) { rt = &atrtr_default; - len += sprintf(buffer+len,"Default %04X:%02X %-4d %s\n", + len += sprintf(buffer + len,"Default %04X:%02X %-4d %s\n", ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags, rt->dev->name); } read_lock_bh(&atalk_router_lock); - for (rt = atalk_router_list; rt != NULL; rt = rt->next) { - len += sprintf(buffer+len,"%04X:%02X %04X:%02X %-4d %s\n", + for (rt = atalk_router_list; rt; rt = rt->next) { + len += sprintf(buffer + len, + "%04X:%02X %04X:%02X %-4d %s\n", ntohs(rt->target.s_net), rt->target.s_node, - ntohs(rt->gateway.s_net), rt->gateway.s_node, rt->flags, - rt->dev->name); + ntohs(rt->gateway.s_net), rt->gateway.s_node, + rt->flags, rt->dev->name); pos = begin + len; if (pos < offset) { len = 0; @@ -1165,7 +1072,6 @@ static int atalk_rt_get_info(char *buffer, char **start, off_t offset, int lengt len -= (offset - begin); if (len > length) len = length; - return len; } @@ -1198,11 +1104,8 @@ unsigned short atalk_checksum(struct ddpehdr *ddp, int len) } data++; } - - if (sum) - return htons((unsigned short) sum); - - return 0xFFFF; /* Use 0xFFFF for 0. 0 itself means none */ + /* Use 0xFFFF for 0. 0 itself means none */ + return sum ? htons((unsigned short) sum) : 0xFFFF; } /* @@ -1211,10 +1114,9 @@ unsigned short atalk_checksum(struct ddpehdr *ddp, int len) */ static int atalk_create(struct socket *sock, int protocol) { - struct sock *sk; + struct sock *sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, 1); - sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, 1); - if (sk == NULL) + if (!sk) return -ENOMEM; switch (sock->type) { @@ -1230,36 +1132,32 @@ static int atalk_create(struct socket *sock, int protocol) case SOCK_STREAM: /* - * TO DO: if you want to implement ADSP, here's the place to start + * TODO: if you want to implement ADSP, here's the + * place to start */ /* sock->ops = &atalk_stream_ops; break; */ default: - sk_free((void *) sk); + sk_free(sk); return -ESOCKTNOSUPPORT; - }; + } MOD_INC_USE_COUNT; - sock_init_data(sock, sk); - sk->destruct = NULL; /* Checksums on by default */ sk->zapped = 1; - return 0; } -/* - * Free a socket. No work needed - */ +/* Free a socket. No work needed */ static int atalk_release(struct socket *sock) { - struct sock *sk=sock->sk; + struct sock *sk = sock->sk; - if (sk == NULL) + if (!sk) return 0; if (!sk->dead) @@ -1268,7 +1166,6 @@ static int atalk_release(struct socket *sock) sk->dead = 1; sock->sk = NULL; atalk_destroy_socket(sk); - return 0; } @@ -1289,21 +1186,21 @@ static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat) for (sat->sat_port = ATPORT_RESERVED; sat->sat_port < ATPORT_LAST; sat->sat_port++) { - for (s = atalk_sockets; s != NULL; s = s->next) { + for (s = atalk_sockets; s; s = s->next) { if (s->protinfo.af_at.src_net == sat->sat_addr.s_net && - s->protinfo.af_at.src_node == sat->sat_addr.s_node && + s->protinfo.af_at.src_node == + sat->sat_addr.s_node && s->protinfo.af_at.src_port == sat->sat_port) goto try_next_port; } /* Wheee, it's free, assign and insert. */ - if ((sk->next = atalk_sockets) != NULL) + sk->next = atalk_sockets; + if (sk->next) atalk_sockets->pprev = &sk->next; atalk_sockets = sk; sk->pprev = &atalk_sockets; - sk->protinfo.af_at.src_port = sat->sat_port; - retval = 0; goto out; @@ -1312,61 +1209,53 @@ static int atalk_pick_and_bind_port(struct sock *sk, struct sockaddr_at *sat) } retval = -EBUSY; -out: - spin_unlock_bh(&atalk_sockets_lock); - +out: spin_unlock_bh(&atalk_sockets_lock); return retval; } static int atalk_autobind(struct sock *sk) { - struct at_addr *ap = atalk_find_primary(); struct sockaddr_at sat; int n; + struct at_addr *ap = atalk_find_primary(); - if (ap == NULL || ap->s_net == htons(ATADDR_ANYNET)) + if (!ap || ap->s_net == htons(ATADDR_ANYNET)) return -EADDRNOTAVAIL; sk->protinfo.af_at.src_net = sat.sat_addr.s_net = ap->s_net; sk->protinfo.af_at.src_node = sat.sat_addr.s_node = ap->s_node; - if ((n = atalk_pick_and_bind_port(sk, &sat)) < 0) + n = atalk_pick_and_bind_port(sk, &sat); + if (n < 0) return n; sk->zapped = 0; - return 0; } -/* - * Set the address 'our end' of the connection. - */ +/* Set the address 'our end' of the connection */ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { - struct sock *sk; struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; + struct sock *sk = sock->sk; - sk = sock->sk; - - if(sk->zapped == 0) - return -EINVAL; - - if(addr_len != sizeof(struct sockaddr_at)) + if (!sk->zapped || addr_len != sizeof(struct sockaddr_at)) return -EINVAL; - if(addr->sat_family != AF_APPLETALK) + if (addr->sat_family != AF_APPLETALK) return -EAFNOSUPPORT; - if(addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { + if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { struct at_addr *ap = atalk_find_primary(); - if(ap == NULL) + if (!ap) return -EADDRNOTAVAIL; sk->protinfo.af_at.src_net = addr->sat_addr.s_net = ap->s_net; sk->protinfo.af_at.src_node = addr->sat_addr.s_node= ap->s_node; } else { - if (atalk_find_interface(addr->sat_addr.s_net, addr->sat_addr.s_node) == NULL) + if (!atalk_find_interface(addr->sat_addr.s_net, + addr->sat_addr.s_node)) return -EADDRNOTAVAIL; sk->protinfo.af_at.src_net = addr->sat_addr.s_net; @@ -1381,18 +1270,15 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) } else { sk->protinfo.af_at.src_port = addr->sat_port; - if (atalk_find_or_insert_socket(sk, addr) != NULL) + if (atalk_find_or_insert_socket(sk, addr)) return -EADDRINUSE; } sk->zapped = 0; - return 0; } -/* - * Set the address we talk to. - */ +/* Set the address we talk to */ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags) { @@ -1412,19 +1298,20 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, if (addr->sat_addr.s_node == ATADDR_BCAST && !sk->broadcast) { #if 1 - printk(KERN_WARNING "%s is broken and did not set SO_BROADCAST. It will break when 2.2 is released.\n", + printk(KERN_WARNING "%s is broken and did not set " + "SO_BROADCAST. It will break when 2.2 is " + "released.\n", current->comm); #else return -EACCES; #endif } - if (sk->zapped) { + if (sk->zapped) if (atalk_autobind(sk) < 0) return -EBUSY; - } - if (atrtr_get_dev(&addr->sat_addr) == NULL) + if (!atrtr_get_dev(&addr->sat_addr)) return -ENETUNREACH; sk->protinfo.af_at.dest_port = addr->sat_port; @@ -1433,7 +1320,6 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr, sock->state = SS_CONNECTED; sk->state = TCP_ESTABLISHED; - return 0; } @@ -1446,13 +1332,11 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer) { struct sockaddr_at sat; - struct sock *sk; + struct sock *sk = sock->sk; - sk = sock->sk; - if (sk->zapped) { + if (sk->zapped) if (atalk_autobind(sk) < 0) return -ENOBUFS; - } *uaddr_len = sizeof(struct sockaddr_at); @@ -1471,7 +1355,6 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, sat.sat_family = AF_APPLETALK; memcpy(uaddr, &sat, sizeof(sat)); - return 0; } @@ -1482,20 +1365,19 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr, * extracted. PPP should probably pass frames marked as for this layer. * [ie ARPHRD_ETHERTALK] */ -static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) +static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) { - struct sock *sock; struct ddpehdr *ddp = (void *) skb->h.raw; + struct sock *sock; struct atalk_iface *atif; struct sockaddr_at tosat; int origlen; struct ddpebits ddphv; /* Size check */ - if (skb->len < sizeof(*ddp)) { - kfree_skb(skb); - return 0; - } + if (skb->len < sizeof(*ddp)) + goto freeit; /* * Fix up the length field [Ok this is horrible but otherwise @@ -1506,15 +1388,10 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ * happens to be safe BUT.. (Its safe as user space will not * run until we put it back) */ - *((__u16 *)&ddphv) = ntohs(*((__u16 *)ddp)); - /* - * Trim buffer in case of stray trailing data - */ - + /* Trim buffer in case of stray trailing data */ origlen = skb->len; - skb_trim(skb, min(skb->len, ddphv.deh_len)); /* @@ -1522,32 +1399,26 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ * (Otherwise we'll detonate most spectacularly * in the middle of recvmsg()). */ - if (skb->len < sizeof(*ddp)) { - kfree_skb(skb); - return 0; - } + if (skb->len < sizeof(*ddp)) + goto freeit; /* * Any checksums. Note we don't do htons() on this == is assumed to be * valid for net byte orders all over the networking code... */ - if (ddp->deh_sum && atalk_checksum(ddp, ddphv.deh_len) != ddp->deh_sum) { + if (ddp->deh_sum && + atalk_checksum(ddp, ddphv.deh_len) != ddp->deh_sum) /* Not a valid AppleTalk frame - dustbin time */ - kfree_skb(skb); - return 0; - } + goto freeit; /* Check the packet is aimed at us */ - - if (ddp->deh_dnet == 0) /* Net 0 is 'this network' */ + if (!ddp->deh_dnet) /* Net 0 is 'this network' */ atif = atalk_find_anynet(ddp->deh_dnode, dev); else atif = atalk_find_interface(ddp->deh_dnet, ddp->deh_dnode); - /* - * Not ours, so we route the packet via the correct AppleTalk interface. - */ - if (atif == NULL) { + /* Not ours, so we route the packet via the correct AppleTalk iface */ + if (!atif) { struct atalk_route *rt; struct at_addr ta; @@ -1555,16 +1426,16 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ * Don't route multicast, etc., packets, or packets * sent to "this network" */ - if (skb->pkt_type != PACKET_HOST || ddp->deh_dnet == 0) { - /* - * FIX ME: - * Can it ever happen that a packet is from a PPP iface and needs to be broadcast onto the default network? - */ + if (skb->pkt_type != PACKET_HOST || !ddp->deh_dnet) { + /* FIXME: + * Can it ever happen that a packet is from a PPP + * iface and needs to be broadcast onto the default + * network? */ if (dev->type == ARPHRD_PPP) - printk(KERN_DEBUG "AppleTalk: didn't forward broadcast packet received from PPP iface\n"); - - kfree_skb(skb); - return 0; + printk(KERN_DEBUG "AppleTalk: didn't forward " + "broadcast packet received " + "from PPP iface\n"); + goto freeit; } ta.s_net = ddp->deh_dnet; @@ -1572,10 +1443,8 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ /* Route the packet */ rt = atrtr_find(&ta); - if (rt == NULL || ddphv.deh_hops == DDP_MAXHOPS) { - kfree_skb(skb); - return 0; - } + if (!rt || ddphv.deh_hops == DDP_MAXHOPS) + goto freeit; ddphv.deh_hops++; /* @@ -1606,40 +1475,33 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ * * Note. ddp-> becomes invalid at the realloc. */ - if (skb_headroom(skb) < 22) - { - struct sk_buff *newskb; + if (skb_headroom(skb) < 22) { /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */ - newskb = skb_realloc_headroom(skb, 32); + struct sk_buff *nskb = skb_realloc_headroom(skb, 32); kfree_skb(skb); - if (!newskb) - return 0; - skb = newskb; - } - else + if (!nskb) + goto out; + skb = nskb; + } else skb = skb_unshare(skb, GFP_ATOMIC); /* * If the buffer didn't vanish into the lack of * space bitbucket we can send it. */ - if (skb) { - if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1) - kfree_skb(skb); - } - - return 0; + if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1) + goto freeit; + goto out; } #if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) - /* - * Check if IP-over-DDP - */ + /* Check if IP-over-DDP */ if (skb->data[12] == 22) { - struct net_device *dev; + struct net_device *dev = __dev_get_by_name("ipddp0"); + struct net_device_stats *stats; /* This needs to be able to handle ipddp"N" devices */ - if ((dev = __dev_get_by_name("ipddp0")) == NULL) + if (!dev) return -ENODEV; skb->protocol = htons(ETH_P_IP); @@ -1647,14 +1509,13 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ skb->dev = dev; skb->h.raw = skb->data; - ((struct net_device_stats *)dev->priv)->rx_packets++; - ((struct net_device_stats *)dev->priv)->rx_bytes += skb->len + 13; + stats = dev->priv; + stats->rx_packets++; + stats->rx_bytes += skb->len + 13; netif_rx(skb); /* Send the SKB up to a higher place. */ - - return 0; + goto out; } #endif - /* * Which socket - atalk_search_socket() looks for a *full match* * of the <net,node,port> tuple. @@ -1664,23 +1525,17 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ tosat.sat_port = ddp->deh_dport; sock = atalk_search_socket(&tosat, atif); - - if (sock == NULL) { - /* But not one of our sockets */ - kfree_skb(skb); - return 0; - } + if (!sock) /* But not one of our sockets */ + goto freeit; - /* - * Queue packet (standard) - */ - + /* Queue packet (standard) */ skb->sk = sock; if (sock_queue_rcv_skb(sock, skb) < 0) - kfree_skb(skb); - - return 0; + goto freeit; + goto out; +freeit: kfree_skb(skb); +out: return 0; } /* @@ -1688,21 +1543,18 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ * Caller must provide enough headroom on the packet to pull the short * header and append a long one. */ -static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) +static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, + struct packet_type *pt) { struct ddpehdr *ddp; struct at_addr *ap; - /* - * Expand any short form frames. - */ + /* Expand any short form frames */ if (skb->mac.raw[2] == 1) { - /* - * Find our address. - */ + /* Find our address */ ap = atalk_find_dev_addr(dev); - if (ap == NULL || skb->len < sizeof(struct ddpshdr)) { + if (!ap || skb->len < sizeof(struct ddpshdr)) { kfree_skb(skb); return 0; } @@ -1715,9 +1567,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ skb_push(skb, sizeof(*ddp) - 4); ddp = (struct ddpehdr *)skb->data; - /* - * Now fill in the long header. - */ + /* Now fill in the long header */ /* * These two first. The mac overlays the new source/dest @@ -1737,7 +1587,6 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ ddp->deh_len = skb->len; ddp->deh_hops = DDP_MAXHOPS; /* Non routable, so force a drop if we slip up later */ - /* Mend the byte order */ *((__u16 *)ddp) = htons(*((__u16 *)ddp)); } @@ -1746,19 +1595,20 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_ return atalk_rcv(skb, dev, pt); } -static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) +static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, + struct scm_cookie *scm) { struct sock *sk = sock->sk; struct sockaddr_at *usat = (struct sockaddr_at *)msg->msg_name; + int flags = msg->msg_flags; + int loopback = 0; struct sockaddr_at local_satalk, gsat; struct sk_buff *skb; struct net_device *dev; struct ddpehdr *ddp; int size; struct atalk_route *rt; - int loopback = 0; int err; - int flags = msg->msg_flags; if (flags & ~MSG_DONTWAIT) return -EINVAL; @@ -1767,19 +1617,18 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc return -EMSGSIZE; if (usat) { - if(sk->zapped) { + if (sk->zapped) if (atalk_autobind(sk) < 0) return -EBUSY; - } - if (msg->msg_namelen < sizeof(*usat)) - return -EINVAL; - if (usat->sat_family != AF_APPLETALK) + if (msg->msg_namelen < sizeof(*usat) || + usat->sat_family != AF_APPLETALK) return -EINVAL; /* netatalk doesn't implement this check */ if (usat->sat_addr.s_node == ATADDR_BCAST && !sk->broadcast) { - printk(KERN_INFO "SO_BROADCAST: Fix your netatalk as it will break before 2.2\n"); + printk(KERN_INFO "SO_BROADCAST: Fix your netatalk as " + "it will break before 2.2\n"); #if 0 return -EPERM; #endif @@ -1795,15 +1644,14 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc } /* Build a packet */ - SOCK_DEBUG(sk, "SK %p: Got address.\n", sk); /* For headers */ size = sizeof(struct ddpehdr) + len + ddp_dl->header_length; - if (usat->sat_addr.s_net != 0 || usat->sat_addr.s_node == ATADDR_ANYNODE) { + if (usat->sat_addr.s_net || usat->sat_addr.s_node == ATADDR_ANYNODE) { rt = atrtr_find(&usat->sat_addr); - if (rt == NULL) + if (!rt) return -ENETUNREACH; dev = rt->dev; @@ -1814,24 +1662,23 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc at_hint.s_net = sk->protinfo.af_at.src_net; rt = atrtr_find(&at_hint); - if (rt == NULL) + if (!rt) return -ENETUNREACH; dev = rt->dev; } - SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", sk, size, dev->name); + SOCK_DEBUG(sk, "SK %p: Size needed %d, device %s\n", + sk, size, dev->name); size += dev->hard_header_len; - skb = sock_alloc_send_skb(sk, size, 0, (flags & MSG_DONTWAIT), &err); - if (skb == NULL) + if (!skb) return err; skb->sk = sk; skb_reserve(skb, ddp_dl->header_length); skb_reserve(skb, dev->hard_header_len); - skb->dev = dev; SOCK_DEBUG(sk, "SK %p: Begin build.\n", sk); @@ -1871,28 +1718,30 @@ static int atalk_sendmsg(struct socket *sock, struct msghdr *msg, int len, struc * Loopback broadcast packets to non gateway targets (ie routes * to group we are in) */ - if (ddp->deh_dnode == ATADDR_BCAST) { - if ((!(rt->flags&RTF_GATEWAY)) && (!(dev->flags&IFF_LOOPBACK))) { - struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); - if (skb2) { - loopback = 1; - SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); - if (aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL) == -1) - kfree_skb(skb2); + if (ddp->deh_dnode == ATADDR_BCAST && + !(rt->flags & RTF_GATEWAY) && !(dev->flags & IFF_LOOPBACK)) { + struct sk_buff *skb2 = skb_copy(skb, GFP_KERNEL); + + if (skb2) { + loopback = 1; + SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk); + if (aarp_send_ddp(dev, skb2, + &usat->sat_addr, NULL) == -1) + kfree_skb(skb2); /* else queued/sent above in the aarp queue */ - } } } - if ((dev->flags & IFF_LOOPBACK) || loopback) { + if (dev->flags & IFF_LOOPBACK || loopback) { SOCK_DEBUG(sk, "SK %p: Loop back.\n", sk); /* loop back */ skb_orphan(skb); ddp_dl->datalink_header(ddp_dl, skb, dev->dev_addr); skb->mac.raw = skb->data; - skb->h.raw = skb->data + ddp_dl->header_length + dev->hard_header_len; - skb_pull(skb,dev->hard_header_len); - skb_pull(skb,ddp_dl->header_length); + skb->h.raw = skb->data + ddp_dl->header_length + + dev->hard_header_len; + skb_pull(skb, dev->hard_header_len); + skb_pull(skb, ddp_dl->header_length); atalk_rcv(skb, dev, NULL); } else { SOCK_DEBUG(sk, "SK %p: send out.\n", sk); @@ -1915,15 +1764,15 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size, { struct sock *sk = sock->sk; struct sockaddr_at *sat = (struct sockaddr_at *)msg->msg_name; - struct ddpehdr *ddp = NULL; - struct ddpebits ddphv; + struct ddpehdr *ddp = NULL; int copied = 0; - struct sk_buff *skb; int err = 0; + struct ddpebits ddphv; + struct sk_buff *skb; - skb = skb_recv_datagram(sk, (flags & ~MSG_DONTWAIT), - (flags & MSG_DONTWAIT), &err); - if (skb == NULL) + skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, + flags & MSG_DONTWAIT, &err); + if (!skb) return err; ddp = (struct ddpehdr *)(skb->h.raw); @@ -1943,7 +1792,8 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size, copied = size; msg->msg_flags |= MSG_TRUNC; } - err = skb_copy_datagram_iovec(skb, sizeof(*ddp), msg->msg_iov, copied); + err = skb_copy_datagram_iovec(skb, sizeof(*ddp), + msg->msg_iov, copied); } if (!err) { @@ -1957,7 +1807,6 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size, } skb_free_datagram(sk, skb); /* Free the datagram. */ - return err ? err : copied; } @@ -1967,50 +1816,40 @@ static int atalk_recvmsg(struct socket *sock, struct msghdr *msg, int size, */ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) { - long amount=0; - struct sock *sk=sock->sk; + long amount = 0; + struct sock *sk = sock->sk; - switch(cmd) - { - /* - * Protocol layer - */ + switch (cmd) { + /* Protocol layer */ case TIOCOUTQ: amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); - if(amount < 0) + if (amount < 0) amount = 0; break; - case TIOCINQ: { - struct sk_buff *skb; - /* These two are safe on a single CPU system as only user tasks fiddle here */ - if((skb = skb_peek(&sk->receive_queue)) != NULL) + /* These two are safe on a single CPU system as only + * user tasks fiddle here */ + struct sk_buff *skb = skb_peek(&sk->receive_queue); + + if (skb) amount = skb->len-sizeof(struct ddpehdr); break; } - case SIOCGSTAMP: - if(sk) - { - if(sk->stamp.tv_sec == 0) - return -ENOENT; - return (copy_to_user((void *)arg,&sk->stamp,sizeof(struct timeval)) ? -EFAULT : 0); - } - return (-EINVAL); - - /* - * Routing - */ + if (!sk) + return -EINVAL; + if (!sk->stamp.tv_sec) + return -ENOENT; + return copy_to_user((void *)arg, &sk->stamp, + sizeof(struct timeval)) ? -EFAULT : 0; + /* Routing */ case SIOCADDRT: case SIOCDELRT: - if(!capable(CAP_NET_ADMIN)) + if (!capable(CAP_NET_ADMIN)) return -EPERM; - return (atrtr_ioctl(cmd,(void *)arg)); - - /* - * Interface - */ + return atrtr_ioctl(cmd, (void *)arg); + /* Interface */ case SIOCGIFADDR: case SIOCSIFADDR: case SIOCGIFBRDADDR: @@ -2018,11 +1857,8 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCDIFADDR: case SIOCSARP: /* proxy AARP */ case SIOCDARP: /* proxy AARP */ - return (atif_ioctl(cmd,(void *)arg)); - - /* - * Physical layer ioctl calls - */ + return atif_ioctl(cmd, (void *)arg); + /* Physical layer ioctl calls */ case SIOCSIFLINK: case SIOCGIFHWADDR: case SIOCSIFHWADDR: @@ -2035,8 +1871,7 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCGIFCOUNT: case SIOCGIFINDEX: case SIOCGIFNAME: - return ((dev_ioctl(cmd,(void *) arg))); - + return dev_ioctl(cmd,(void *) arg); case SIOCSIFMETRIC: case SIOCSIFBRDADDR: case SIOCGIFNETMASK: @@ -2045,16 +1880,15 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCSIFMEM: case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: - return (-EINVAL); - + return -EINVAL; default: - return (-EINVAL); + return -EINVAL; } - return (put_user(amount, (int *)arg)); + return put_user(amount, (int *)arg); } -static struct net_proto_family atalk_family_ops= +static struct net_proto_family atalk_family_ops = { PF_APPLETALK, atalk_create @@ -2111,19 +1945,17 @@ struct packet_type ppptalk_packet_type= static char ddp_snap_id[] = {0x08, 0x00, 0x07, 0x80, 0x9B}; -/* - * Export symbols for use by drivers when AppleTalk is a module. - */ +/* Export symbols for use by drivers when AppleTalk is a module */ EXPORT_SYMBOL(aarp_send_ddp); EXPORT_SYMBOL(atrtr_get_dev); EXPORT_SYMBOL(atalk_find_dev_addr); /* Called by proto.c on kernel start up */ - static int __init atalk_init(void) { (void) sock_register(&atalk_family_ops); - if((ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv)) == NULL) + ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); + if (!ddp_dl) printk(KERN_CRIT "Unable to register DDP with SNAP.\n"); ltalk_packet_type.type = htons(ETH_P_LOCALTALK); @@ -2135,19 +1967,16 @@ static int __init atalk_init(void) register_netdevice_notifier(&ddp_notifier); aarp_proto_init(); -#ifdef CONFIG_PROC_FS proc_net_create("appletalk", 0, atalk_get_info); proc_net_create("atalk_route", 0, atalk_rt_get_info); proc_net_create("atalk_iface", 0, atalk_if_get_info); - +#ifdef CONFIG_PROC_FS aarp_register_proc_fs(); #endif /* CONFIG_PROC_FS */ - #ifdef CONFIG_SYSCTL atalk_register_sysctl(); #endif /* CONFIG_SYSCTL */ - - printk(KERN_INFO "NET4: AppleTalk 0.18 for Linux NET4.0\n"); + printk(KERN_INFO "NET4: AppleTalk 0.18a for Linux NET4.0\n"); return 0; } module_init(atalk_init); @@ -2165,32 +1994,24 @@ module_init(atalk_init); * Ergo, before the AppleTalk module can be removed, all AppleTalk * sockets be closed from user space. */ - static void __exit atalk_exit(void) { #ifdef CONFIG_SYSCTL atalk_unregister_sysctl(); #endif /* CONFIG_SYSCTL */ - -#ifdef CONFIG_PROC_FS proc_net_remove("appletalk"); proc_net_remove("atalk_route"); proc_net_remove("atalk_iface"); - +#ifdef CONFIG_PROC_FS aarp_unregister_proc_fs(); #endif /* CONFIG_PROC_FS */ - aarp_cleanup_module(); /* General aarp clean-up. */ - unregister_netdevice_notifier(&ddp_notifier); dev_remove_pack(<alk_packet_type); dev_remove_pack(&ppptalk_packet_type); unregister_snap_client(ddp_snap_id); sock_unregister(PF_APPLETALK); - - return; } module_exit(atalk_exit); #endif /* MODULE */ - #endif /* CONFIG_ATALK || CONFIG_ATALK_MODULE */ diff --git a/net/atm/lec.c b/net/atm/lec.c index 51be9f0779c4..ec0dc2671600 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c @@ -51,6 +51,11 @@ static unsigned char bridge_ula_lec[] = {0x01, 0x80, 0xc2, 0x00, 0x00}; #define DPRINTK(format,args...) #endif +struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br, + unsigned char *addr); +void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); + + #define DUMP_PACKETS 0 /* 0 = None, * 1 = 30 first bytes * 2 = Whole packet @@ -853,8 +858,11 @@ static void __exit lane_module_cleanup(void) if (dev_lec[i] != NULL) { priv = (struct lec_priv *)dev_lec[i]->priv; #if defined(CONFIG_TR) - unregister_trdev(dev_lec[i]); + if (priv->is_trdev) + unregister_trdev(dev_lec[i]); + else #endif + unregister_netdev(dev_lec[i]); kfree(dev_lec[i]); dev_lec[i] = NULL; } diff --git a/net/atm/lec.h b/net/atm/lec.h index f40a37fa3f41..5dd0494e9e07 100644 --- a/net/atm/lec.h +++ b/net/atm/lec.h @@ -16,9 +16,9 @@ #if defined (CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) #include <linux/if_bridge.h> -struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br, +extern struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br, unsigned char *addr); -void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); +extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); #endif /* defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) */ #define LEC_HEADER_LEN 16 diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 940d69be0aa1..8fcfe3fe4a99 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -4,7 +4,7 @@ * Authors: * Lennert Buytenhek <buytenh@gnu.org> * - * $Id: br_private.h,v 1.3 2000/05/05 02:17:17 davem Exp $ + * $Id: br_private.h,v 1.4 2001/01/19 04:51:48 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -112,8 +112,8 @@ struct net_bridge int gc_interval; }; -struct notifier_block br_device_notifier; -unsigned char bridge_ula[6]; +extern struct notifier_block br_device_notifier; +extern unsigned char bridge_ula[6]; /* br.c */ void br_dec_use_count(void); diff --git a/net/core/netfilter.c b/net/core/netfilter.c index f4bb62818a49..b12e1d5ecf15 100644 --- a/net/core/netfilter.c +++ b/net/core/netfilter.c @@ -442,7 +442,6 @@ static void nf_queue(struct sk_buff *skb, } } -/* We have BR_NETPROTO_LOCK here */ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, @@ -452,6 +451,9 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, unsigned int verdict; int ret = 0; + /* We may already have this, but read-locks nest anyway */ + br_read_lock_bh(BR_NETPROTO_LOCK); + #ifdef CONFIG_NETFILTER_DEBUG if (skb->nf_debug & (1 << hook)) { printk("nf_hook: hook %i already set.\n", hook); @@ -479,6 +481,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, break; } + br_read_unlock_bh(BR_NETPROTO_LOCK); return ret; } diff --git a/net/decnet/Makefile b/net/decnet/Makefile index ac7a1a462ec0..11f7c8b08955 100644 --- a/net/decnet/Makefile +++ b/net/decnet/Makefile @@ -11,5 +11,3 @@ obj-y += sysctl_net_decnet.o include $(TOPDIR)/Rules.make -tar: - tar -cvf /dev/f1 . diff --git a/net/decnet/TODO b/net/decnet/TODO index 1607d6d1b04d..c8ea8178dbfe 100644 --- a/net/decnet/TODO +++ b/net/decnet/TODO @@ -43,15 +43,15 @@ Steve's quick list of things that need finishing off: o Hello messages should be generated for each primary address on each interface. - o Add more information into /proc/net/decnet and finalise the format to - allow DECnet support in netstat. - - o Make sure that returned connect messages are generated when they should - be, and that the correct error messages are sent too. - o Add the routing message grabbing netfilter module [written, tested, awaiting merge] o Add perfect socket hashing - an idea suggested by Paul Koning [part written, awaiting debugging and merge] + o Add session control message flow control + + o Add NSP message flow control + + o DECnet sendpages() function + diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c index bc51b636d957..da59ab6ef3d9 100644 --- a/net/decnet/af_decnet.c +++ b/net/decnet/af_decnet.c @@ -35,6 +35,7 @@ * Arnaldo C. Melo: use capable, not suser * Steve Whitehouse: Removed unused code. Fix to use sk->allocation * when required. + * Patrick Caulfield: /proc/net/decnet now has object name/number */ @@ -128,8 +129,6 @@ Version 0.0.6 2.1.110 07-aug-98 Eduardo Marcelo Serrat #include <net/dn_fib.h> #include <net/dn_neigh.h> -#define MAX(a,b) ((a)>(b)?(a):(b)) - static void dn_keepalive(struct sock *sk); /* @@ -141,15 +140,15 @@ unsigned char decnet_ether_address[ETH_ALEN] = { 0xAA, 0x00, 0x04, 0x00, 0x00, 0 static struct proto_ops dn_proto_ops; rwlock_t dn_hash_lock = RW_LOCK_UNLOCKED; -static struct sock *dn_sklist = NULL; -static struct sock *dn_wild_sk = NULL; +static struct sock *dn_sklist; +static struct sock *dn_wild_sk; static int __dn_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen, int flags); static int __dn_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen, int flags); static struct sock **dn_find_list(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->addr.sdn_flags & SDF_WILD) return dn_wild_sk ? NULL : &dn_wild_sk; @@ -159,7 +158,7 @@ static struct sock **dn_find_list(struct sock *sk) static unsigned short port_alloc(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); static unsigned short port = 0x2000; if (port == 0) @@ -177,12 +176,17 @@ static unsigned short port = 0x2000; */ static int dn_hash_sock(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct sock **skp; int rv = -EUSERS; - write_lock_bh(&dn_hash_lock); + if (sk->next) + BUG(); + if (sk->pprev) + BUG(); + write_lock_bh(&dn_hash_lock); + if (!scp->addrloc && !port_alloc(sk)) goto out; @@ -327,7 +331,7 @@ struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr) read_lock(&dn_hash_lock); for(sk = dn_sklist; sk != NULL; sk = sk->next) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (sk->state != TCP_LISTEN) continue; if (scp->addr.sdn_objnum) { @@ -355,13 +359,13 @@ struct sock *dn_sklist_find_listener(struct sockaddr_dn *addr) struct sock *dn_find_by_skb(struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); struct sock *sk; struct dn_scp *scp; read_lock(&dn_hash_lock); for(sk = dn_sklist; sk != NULL; sk = sk->next) { - scp = &sk->protinfo.dn; + scp = DN_SK(sk); if (cb->src != dn_saddr2dn(&scp->peer)) continue; if (cb->dst_port != scp->addrloc) @@ -383,7 +387,7 @@ struct sock *dn_find_by_skb(struct sk_buff *skb) static void dn_destruct(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); skb_queue_purge(&scp->data_xmit_queue); skb_queue_purge(&scp->other_xmit_queue); @@ -394,25 +398,26 @@ static void dn_destruct(struct sock *sk) MOD_DEC_USE_COUNT; } -struct sock *dn_alloc_sock(struct socket *sock, int flags) +struct sock *dn_alloc_sock(struct socket *sock, int gfp) { struct sock *sk; struct dn_scp *scp; - if ((sk = sk_alloc(PF_DECnet, flags, 1)) == NULL) + if ((sk = sk_alloc(PF_DECnet, gfp, 1)) == NULL) goto no_sock; if (sock) { sock->ops = &dn_proto_ops; } sock_init_data(sock,sk); - scp = &sk->protinfo.dn; + scp = DN_SK(sk); sk->backlog_rcv = dn_nsp_backlog_rcv; sk->destruct = dn_destruct; sk->no_check = 1; sk->family = PF_DECnet; sk->protocol = 0; + sk->allocation = gfp; /* Initialization of DECnet Session Control Port */ scp->state = DN_O; /* Open */ @@ -424,13 +429,26 @@ struct sock *dn_alloc_sock(struct socket *sock, int flags) scp->ackrcv_oth = 0; /* Last oth data ack rec*/ scp->flowrem_sw = DN_SEND; scp->flowloc_sw = DN_SEND; + scp->flowrem_dat = 0; + scp->flowrem_oth = 1; + scp->flowloc_dat = 0; + scp->flowloc_oth = 1; + scp->services_rem = 0; + scp->services_loc = 1 | NSP_FC_NONE; + scp->info_rem = 0; + scp->info_loc = 0x03; /* NSP version 4.1 */ + scp->segsize_rem = 230; /* Default: Updated by remote segsize */ + scp->segsize_loc = 1450; /* Best guess for ethernet */ + scp->at_eor = 1; + scp->nonagle = 0; + scp->multi_ireq = 1; scp->accept_mode = ACC_IMMED; scp->addr.sdn_family = AF_DECnet; scp->peer.sdn_family = AF_DECnet; scp->accessdata.acc_accl = 5; memcpy(scp->accessdata.acc_acc, "LINUX", 5); - scp->mss = 1460; + scp->max_window = NSP_MAX_WINDOW; scp->snd_window = NSP_MIN_WINDOW; scp->nsp_srtt = NSP_INITIAL_SRTT; scp->nsp_rttvar = NSP_INITIAL_RTTVAR; @@ -464,7 +482,7 @@ no_sock: */ static void dn_keepalive(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); /* * By checking the other_data transmit queue is empty @@ -472,7 +490,7 @@ static void dn_keepalive(struct sock *sk) * many of these keepalive frames. */ if (skb_queue_len(&scp->other_xmit_queue) == 0) - dn_nsp_send_lnk(sk, DN_NOCHANGE); + dn_nsp_send_link(sk, DN_NOCHANGE, 0); } @@ -485,7 +503,7 @@ static void dn_keepalive(struct sock *sk) */ int dn_destroy_timer(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); scp->persist = dn_nsp_persist(sk); @@ -527,7 +545,7 @@ int dn_destroy_timer(struct sock *sk) static void dn_destroy_sock(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); scp->nsp_rxtshift = 0; /* reset back off */ @@ -674,7 +692,7 @@ dn_release(struct socket *sock) static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr; struct net_device *dev; int rv; @@ -722,11 +740,8 @@ static int dn_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) memcpy(&scp->addr, saddr, addr_len); sk->zapped = 0; - if ((rv = dn_hash_sock(sk)) == 0) - goto out; - - sk->zapped = 1; -out: + if ((rv = dn_hash_sock(sk)) != 0) + sk->zapped = 1; return rv; } @@ -735,7 +750,7 @@ out: static int dn_auto_bind(struct socket *sock) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); sk->zapped = 0; @@ -769,7 +784,7 @@ static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, { struct sockaddr_dn *addr = (struct sockaddr_dn *)uaddr; struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int err = -EISCONN; lock_sock(sk); @@ -788,7 +803,7 @@ static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, } err = -EINVAL; - if (sk->protinfo.dn.state != DN_O) + if (DN_SK(sk)->state != DN_O) goto out; if (addr_len != sizeof(struct sockaddr_dn)) @@ -812,7 +827,7 @@ static int dn_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, sk->state = TCP_SYN_SENT; sock->state = SS_CONNECTING; - sk->protinfo.dn.state = DN_CI; + DN_SK(sk)->state = DN_CI; dn_nsp_send_conninit(sk, NSP_CI); @@ -853,7 +868,7 @@ out: return err; } -static int dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc) +static void dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc) { unsigned char *ptr = skb->data; @@ -870,10 +885,9 @@ static int dn_access_copy(struct sk_buff *skb, struct accessdata_dn *acc) skb_pull(skb, acc->acc_accl + acc->acc_passl + acc->acc_userl + 3); - return 0; } -static int dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) +static void dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) { unsigned char *ptr = skb->data; @@ -882,7 +896,6 @@ static int dn_user_copy(struct sk_buff *skb, struct optdata_dn *opt) memcpy(opt->opt_data, ptr, opt->opt_optl); skb_pull(skb, opt->opt_optl + 1); - return 0; } @@ -910,7 +923,7 @@ static int dn_wait_accept(struct socket *sock, int flags) return -ERESTARTSYS; /* But of course you don't! */ } - if ((sk->protinfo.dn.state != DN_RUN) && (sk->protinfo.dn.state != DN_DRC)) { + if ((DN_SK(sk)->state != DN_RUN) && (DN_SK(sk)->state != DN_DRC)) { sock->state = SS_UNCONNECTED; return sock_error(sk); } @@ -937,7 +950,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) return -EINVAL; } - if (sk->protinfo.dn.state != DN_O) { + if (DN_SK(sk)->state != DN_O) { release_sock(sk); return -EINVAL; } @@ -967,7 +980,7 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) } } while (skb == NULL); - cb = (struct dn_skb_cb *)skb->cb; + cb = DN_SKB_CB(skb); if ((newsk = dn_alloc_sock(newsock, sk->allocation)) == NULL) { release_sock(sk); @@ -980,50 +993,52 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) dst_release(xchg(&newsk->dst_cache, skb->dst)); skb->dst = NULL; - newsk->protinfo.dn.state = DN_CR; - newsk->protinfo.dn.addrrem = cb->src_port; - newsk->protinfo.dn.mss = cb->segsize; - newsk->protinfo.dn.accept_mode = sk->protinfo.dn.accept_mode; + DN_SK(newsk)->state = DN_CR; + DN_SK(newsk)->addrrem = cb->src_port; + DN_SK(newsk)->services_rem = cb->services; + DN_SK(newsk)->info_rem = cb->info; + DN_SK(newsk)->segsize_rem = cb->segsize; + DN_SK(newsk)->accept_mode = DN_SK(sk)->accept_mode; - if (newsk->protinfo.dn.mss < 230) - newsk->protinfo.dn.mss = 230; + if (DN_SK(newsk)->segsize_rem < 230) + DN_SK(newsk)->segsize_rem = 230; newsk->state = TCP_LISTEN; newsk->zapped = 0; - memcpy(&newsk->protinfo.dn.addr, &sk->protinfo.dn.addr, sizeof(struct sockaddr_dn)); + memcpy(&(DN_SK(newsk)->addr), &(DN_SK(sk)->addr), sizeof(struct sockaddr_dn)); /* * If we are listening on a wild socket, we don't want * the newly created socket on the wrong hash queue. */ - newsk->protinfo.dn.addr.sdn_flags &= ~SDF_WILD; + DN_SK(newsk)->addr.sdn_flags &= ~SDF_WILD; - skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &newsk->protinfo.dn.addr, &type)); - skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &newsk->protinfo.dn.peer, &type)); - *(dn_address *)newsk->protinfo.dn.peer.sdn_add.a_addr = cb->src; - *(dn_address *)newsk->protinfo.dn.addr.sdn_add.a_addr = cb->dst; + skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->addr), &type)); + skb_pull(skb, dn_username2sockaddr(skb->data, skb->len, &(DN_SK(newsk)->peer), &type)); + *(dn_address *)(DN_SK(newsk)->peer.sdn_add.a_addr) = cb->src; + *(dn_address *)(DN_SK(newsk)->addr.sdn_add.a_addr) = cb->dst; menuver = *skb->data; skb_pull(skb, 1); if (menuver & DN_MENUVER_ACC) - dn_access_copy(skb, &newsk->protinfo.dn.accessdata); + dn_access_copy(skb, &(DN_SK(newsk)->accessdata)); if (menuver & DN_MENUVER_USR) - dn_user_copy(skb, &newsk->protinfo.dn.conndata_in); + dn_user_copy(skb, &(DN_SK(newsk)->conndata_in)); if (menuver & DN_MENUVER_PRX) - newsk->protinfo.dn.peer.sdn_flags |= SDF_PROXY; + DN_SK(newsk)->peer.sdn_flags |= SDF_PROXY; if (menuver & DN_MENUVER_UIC) - newsk->protinfo.dn.peer.sdn_flags |= SDF_UICPROXY; + DN_SK(newsk)->peer.sdn_flags |= SDF_UICPROXY; kfree_skb(skb); - memcpy(&newsk->protinfo.dn.conndata_out, &sk->protinfo.dn.conndata_out, + memcpy(&(DN_SK(newsk)->conndata_out), &(DN_SK(sk)->conndata_out), sizeof(struct optdata_dn)); - memcpy(&newsk->protinfo.dn.discdata_out, &sk->protinfo.dn.discdata_out, + memcpy(&(DN_SK(newsk)->discdata_out), &(DN_SK(sk)->discdata_out), sizeof(struct optdata_dn)); lock_sock(newsk); @@ -1031,9 +1046,13 @@ static int dn_accept(struct socket *sock, struct socket *newsock, int flags) dn_send_conn_ack(newsk); - if (newsk->protinfo.dn.accept_mode == ACC_IMMED) { - newsk->protinfo.dn.state = DN_CC; - dn_send_conn_conf(newsk, newsk->allocation); + /* + * Here we use sk->allocation since although the conn conf is + * for the newsk, the context is the old socket. + */ + if (DN_SK(newsk)->accept_mode == ACC_IMMED) { + DN_SK(newsk)->state = DN_CC; + dn_send_conn_conf(newsk, sk->allocation); err = dn_wait_accept(newsock, flags); } @@ -1046,7 +1065,7 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len { struct sockaddr_dn *sa = (struct sockaddr_dn *)uaddr; struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); *uaddr_len = sizeof(struct sockaddr_dn); @@ -1070,7 +1089,7 @@ static int dn_getname(struct socket *sock, struct sockaddr *uaddr,int *uaddr_len static unsigned int dn_poll(struct file *file, struct socket *sock, poll_table *wait) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int mask = datagram_poll(file, sock, wait); if (skb_queue_len(&scp->other_receive_queue)) @@ -1082,100 +1101,44 @@ static unsigned int dn_poll(struct file *file, struct socket *sock, poll_table static int dn_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int err = -EOPNOTSUPP; unsigned long amount = 0; struct sk_buff *skb; + int val; -#if 0 - struct dn_naddr dnaddr; -#endif switch(cmd) { case SIOCGIFADDR: case SIOCSIFADDR: return dn_dev_ioctl(cmd, (void *)arg); + case SIOCATMARK: + lock_sock(sk); + val = (skb_queue_len(&scp->other_receive_queue) != 0); + if (scp->state != DN_RUN) + val = -ENOTCONN; + release_sock(sk); + return val; + +#ifdef SIOCATEOR + case SIOCATEOR: + lock_sock(sk); + val = scp->at_eor; + if (scp->state != DN_RUN) + val = -ENOTCONN; + if (sock->type != SOCK_SEQPACKET) + val = -EINVAL; + release_sock(sk); + return val; +#endif /* SIOCATEOR */ + #ifdef CONFIG_DECNET_ROUTER case SIOCADDRT: case SIOCDELRT: return dn_fib_ioctl(sock, cmd, arg); #endif /* CONFIG_DECNET_ROUTER */ -#if 0 - case SIOCSIFADDR: - if (!capable(CAP_NET_ADMIN)) return -EPERM; - - if ((err = copy_from_user(devname, ioarg->devname, 5)) != 0) - break; - if ((err = copy_from_user(addr, ioarg->exec_addr, 6)) != 0) - break; - if ((dev = dev_get(devname)) == NULL) { - err = -ENODEV; - break; - } - if (dev->dn_ptr == NULL) { - err = -ENODEV; - break; - } - - dn_dev_devices_off(); - - decnet_default_device = dev; - memcpy(decnet_ether_address, addr, ETH_ALEN); - decnet_address = dn_htons(dn_eth2dn(decnet_ether_address)); - - dn_dev_devices_on(); - - break; - - case SIOCGIFADDR: - if (decnet_default_device) - strcpy(devname, decnet_default_device->name); - else - memset(devname, 0, 6); - - if ((err = copy_to_user(ioarg->devname, devname, 5)) != 0) - break; - - if ((err = copy_to_user(ioarg->exec_addr, decnet_ether_address, 6)) != 0) - break; - - break; -#endif - -#if 0 - case SIOCSNETADDR: - if (!capable(CAP_NET_ADMIN)) { - err = -EPERM; - break; - } - - if ((err = copy_from_user(&dnaddr, (void *)arg, sizeof(struct dn_naddr))) != 0) - break; - - if (dnaddr.a_len != ETH_ALEN) { - err = -EINVAL; - break; - } - - dn_dev_devices_off(); - - memcpy(decnet_ether_address, dnaddr.a_addr, ETH_ALEN); - decnet_address = dn_htons(dn_eth2dn(decnet_ether_address)); - - dn_dev_devices_on(); - break; - - case SIOCGNETADDR: - dnaddr.a_len = ETH_ALEN; - memcpy(dnaddr.a_addr, decnet_ether_address, ETH_ALEN); - - if ((err = copy_to_user((void *)arg, &dnaddr, sizeof(struct dn_naddr))) != 0) - break; - - break; -#endif case OSIOCSNETADDR: if (!capable(CAP_NET_ADMIN)) { err = -EPERM; @@ -1237,7 +1200,7 @@ static int dn_listen(struct socket *sock, int backlog) if (sk->zapped) goto out; - if ((sk->protinfo.dn.state != DN_O) || (sk->state == TCP_LISTEN)) + if ((DN_SK(sk)->state != DN_O) || (sk->state == TCP_LISTEN)) goto out; sk->max_ack_backlog = backlog; @@ -1255,7 +1218,7 @@ out: static int dn_shutdown(struct socket *sock, int how) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int err = -ENOTCONN; lock_sock(sk); @@ -1300,14 +1263,27 @@ static int dn_setsockopt(struct socket *sock, int level, int optname, char *optv static int __dn_setsockopt(struct socket *sock, int level,int optname, char *optval, int optlen, int flags) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; - struct optdata_dn opt; - struct accessdata_dn acc; + struct dn_scp *scp = DN_SK(sk); + union { + struct optdata_dn opt; + struct accessdata_dn acc; + int mode; + unsigned long win; + int val; + unsigned char services; + unsigned char info; + } u; int err; if (optlen && !optval) return -EINVAL; + if (optlen > sizeof(u)) + return -EINVAL; + + if (copy_from_user(&u, optval, optlen)) + return -EFAULT; + switch(optname) { case DSO_CONDATA: if (sock->state == SS_CONNECTED) @@ -1318,29 +1294,23 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt if (optlen != sizeof(struct optdata_dn)) return -EINVAL; - if (copy_from_user(&opt, optval, optlen)) - return -EFAULT; - - if (opt.opt_optl > 16) + if (u.opt.opt_optl > 16) return -EINVAL; - memcpy(&scp->conndata_out, &opt, sizeof(struct optdata_dn)); + memcpy(&scp->conndata_out, &u.opt, optlen); break; case DSO_DISDATA: - if (sock->state != SS_CONNECTED && sk->protinfo.dn.accept_mode == ACC_IMMED) + if (sock->state != SS_CONNECTED && scp->accept_mode == ACC_IMMED) return -ENOTCONN; if (optlen != sizeof(struct optdata_dn)) return -EINVAL; - if (copy_from_user(&opt, optval, sizeof(struct optdata_dn))) - return -EFAULT; - - if (opt.opt_optl > 16) + if (u.opt.opt_optl > 16) return -EINVAL; - memcpy(&scp->discdata_out, &opt, sizeof(struct optdata_dn)); + memcpy(&scp->discdata_out, &u.opt, optlen); break; case DSO_CONACCESS: @@ -1352,15 +1322,12 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt if (optlen != sizeof(struct accessdata_dn)) return -EINVAL; - if (copy_from_user(&acc, optval, sizeof(struct accessdata_dn))) - return -EFAULT; - - if ((acc.acc_accl > DN_MAXACCL) || - (acc.acc_passl > DN_MAXACCL) || - (acc.acc_userl > DN_MAXACCL)) + if ((u.acc.acc_accl > DN_MAXACCL) || + (u.acc.acc_passl > DN_MAXACCL) || + (u.acc.acc_userl > DN_MAXACCL)) return -EINVAL; - memcpy(&scp->accessdata, &acc, sizeof(struct accessdata_dn)); + memcpy(&scp->accessdata, &u.acc, optlen); break; case DSO_ACCEPTMODE: @@ -1372,16 +1339,10 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt if (optlen != sizeof(int)) return -EINVAL; - { - int mode; - - if (get_user(mode, optval)) - return -EFAULT; - if ((mode != ACC_IMMED) && (mode != ACC_DEFER)) - return -EINVAL; + if ((u.mode != ACC_IMMED) && (u.mode != ACC_DEFER)) + return -EINVAL; - scp->accept_mode = (unsigned char)mode; - } + scp->accept_mode = (unsigned char)u.mode; break; case DSO_CONACCEPT: @@ -1411,8 +1372,55 @@ static int __dn_setsockopt(struct socket *sock, int level,int optname, char *opt case DSO_LINKINFO: case DSO_STREAM: case DSO_SEQPACKET: - return -ENOPROTOOPT; + + case DSO_MAXWINDOW: + if (optlen != sizeof(unsigned long)) + return -EINVAL; + if (u.win > NSP_MAX_WINDOW) + u.win = NSP_MAX_WINDOW; + if (u.win == 0) + return -EINVAL; + scp->max_window = u.win; + if (scp->snd_window > u.win) + scp->snd_window = u.win; + break; + + case DSO_NODELAY: + if (optlen != sizeof(int)) + return -EINVAL; + if (scp->nonagle == 2) + return -EINVAL; + scp->nonagle = (u.val == 0) ? 0 : 1; + /* if (scp->nonagle == 1) { Push pending frames } */ + break; + + case DSO_CORK: + if (optlen != sizeof(int)) + return -EINVAL; + if (scp->nonagle == 1) + return -EINVAL; + scp->nonagle = (u.val == 0) ? 0 : 2; + /* if (scp->nonagle == 0) { Push pending frames } */ + break; + + case DSO_SERVICES: + if (optlen != sizeof(unsigned char)) + return -EINVAL; + if ((u.services & ~NSP_FC_MASK) != 0x01) + return -EINVAL; + if ((u.services & NSP_FC_MASK) == NSP_FC_MASK) + return -EINVAL; + scp->services_loc = u.services; + break; + + case DSO_INFO: + if (optlen != sizeof(unsigned char)) + return -EINVAL; + if (u.info & 0xfc) + return -EINVAL; + scp->info_loc = u.info; + break; } return 0; @@ -1433,44 +1441,40 @@ static int dn_getsockopt(struct socket *sock, int level, int optname, char *optv static int __dn_getsockopt(struct socket *sock, int level,int optname, char *optval,int *optlen, int flags) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct linkinfo_dn link; - int mode = scp->accept_mode; + int r_len = *optlen; + void *r_data = NULL; + int val; switch(optname) { case DSO_CONDATA: - if (*optlen != sizeof(struct optdata_dn)) - return -EINVAL; - - if (copy_to_user(optval, &scp->conndata_in, sizeof(struct optdata_dn))) - return -EFAULT; + if (r_len > sizeof(struct optdata_dn)) + r_len = sizeof(struct optdata_dn); + r_data = &scp->conndata_in; break; case DSO_DISDATA: - if (*optlen != sizeof(struct optdata_dn)) - return -EINVAL; - - if (copy_to_user(optval, &scp->discdata_in, sizeof(struct optdata_dn))) - return -EFAULT; - + if (r_len > sizeof(struct optdata_dn)) + r_len = sizeof(struct optdata_dn); + r_data = &scp->discdata_in; break; case DSO_CONACCESS: - if (*optlen != sizeof(struct accessdata_dn)) - return -EINVAL; - - if (copy_to_user(optval, &scp->accessdata, sizeof(struct accessdata_dn))) - return -EFAULT; + if (r_len > sizeof(struct accessdata_dn)) + r_len = sizeof(struct accessdata_dn); + r_data = &scp->accessdata; break; case DSO_ACCEPTMODE: - if (put_user(mode, optval)) - return -EFAULT; + if (r_len > sizeof(unsigned char)) + r_len = sizeof(unsigned char); + r_data = &scp->accept_mode; break; case DSO_LINKINFO: - if (*optlen != sizeof(struct linkinfo_dn)) - return -EINVAL; + if (r_len > sizeof(struct linkinfo_dn)) + r_len = sizeof(struct linkinfo_dn); switch(sock->state) { case SS_CONNECTING: @@ -1486,10 +1490,8 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt link.idn_linkstate = LL_INACTIVE; } - link.idn_segsize = scp->mss; - - if (copy_to_user(optval, &link, sizeof(struct linkinfo_dn))) - return -EFAULT; + link.idn_segsize = scp->segsize_rem; + r_data = &link; break; default: @@ -1508,6 +1510,45 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt case DSO_CONACCEPT: case DSO_CONREJECT: return -ENOPROTOOPT; + + case DSO_MAXWINDOW: + if (r_len > sizeof(unsigned long)) + r_len = sizeof(unsigned long); + r_data = &scp->max_window; + break; + + case DSO_NODELAY: + if (r_len > sizeof(int)) + r_len = sizeof(int); + val = (scp->nonagle == 1); + r_data = &val; + break; + + case DSO_CORK: + if (r_len > sizeof(int)) + r_len = sizeof(int); + val = (scp->nonagle == 2); + r_data = &val; + break; + + case DSO_SERVICES: + if (r_len > sizeof(unsigned char)) + r_len = sizeof(unsigned char); + r_data = &scp->services_rem; + break; + + case DSO_INFO: + if (r_len > sizeof(unsigned char)) + r_len = sizeof(unsigned char); + r_data = &scp->info_rem; + break; + } + + if (r_data) { + if (copy_to_user(optval, r_data, r_len)) + return -EFAULT; + if (put_user(r_len, optlen)) + return -EFAULT; } return 0; @@ -1520,7 +1561,7 @@ static int __dn_getsockopt(struct socket *sock, int level,int optname, char *opt */ static int dn_wait_run(struct sock *sk, int flags) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int err = 0; switch(scp->state) { @@ -1572,7 +1613,7 @@ static int dn_data_ready(struct sock *sk, struct sk_buff_head *q, int flags, int return skb_queue_len(q) ? 1 : 0; while(skb != (struct sk_buff *)q) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); len += skb->len; if (cb->nsp_flags & 0x40) { @@ -1599,7 +1640,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size, int flags, struct scm_cookie *scm) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct sk_buff_head *queue = &sk->receive_queue; int target = size > 1 ? 1 : 0; int copied = 0; @@ -1681,7 +1722,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size, for(skb = queue->next; skb != (struct sk_buff *)queue; skb = nskb) { int chunk = skb->len; - cb = (struct dn_skb_cb *)skb->cb; + cb = DN_SKB_CB(skb); if ((chunk + copied) > size) chunk = size - copied; @@ -1693,7 +1734,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size, copied += chunk; if (!(flags & MSG_PEEK)) - skb->len -= chunk; + skb_pull(skb, chunk); eor = cb->nsp_flags & 0x40; nskb = skb->next; @@ -1707,7 +1748,7 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size, */ if ((scp->flowloc_sw == DN_DONTSEND) && !dn_congested(sk)) { scp->flowloc_sw = DN_SEND; - dn_nsp_send_lnk(sk, DN_SEND); + dn_nsp_send_link(sk, DN_SEND, 0); } } @@ -1727,9 +1768,14 @@ static int dn_recvmsg(struct socket *sock, struct msghdr *msg, int size, rv = copied; - if (eor && (sk->type == SOCK_SEQPACKET)) - msg->msg_flags |= MSG_EOR; + if (!(flags & (MSG_PEEK|MSG_OOB))) + scp->at_eor = 0; + if (eor && (sk->type == SOCK_SEQPACKET)) { + msg->msg_flags |= MSG_EOR; + if (!(flags & (MSG_PEEK|MSG_OOB))) + scp->at_eor = 1; + } out: if (rv == 0) rv = (flags & MSG_PEEK) ? -sk->err : sock_error(sk); @@ -1745,16 +1791,31 @@ out: } +static inline int dn_queue_too_long(struct dn_scp *scp, struct sk_buff_head *queue, int flags) +{ + unsigned char fctype = scp->services_rem & NSP_FC_MASK; + if (skb_queue_len(queue) >= scp->snd_window) + return 1; + if (fctype != NSP_FC_NONE) { + if (flags & MSG_OOB) { + if (scp->flowrem_oth == 0) + return 1; + } else { + if (scp->flowrem_dat == 0) + return 1; + } + } + return 0; +} + static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, struct scm_cookie *scm) { struct sock *sk = sock->sk; - struct dn_scp *scp = &sk->protinfo.dn; - int mss = scp->mss; - int mtu = 230 - 11; /* maximum value thats always safe */ + struct dn_scp *scp = DN_SK(sk); + int mss; struct sk_buff_head *queue = &scp->data_xmit_queue; int flags = msg->msg_flags; - unsigned short numseg = 0; int err = 0; int sent = 0; int addr_len = msg->msg_namelen; @@ -1765,6 +1826,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, unsigned char *ptr; unsigned short ack; int len; + unsigned char fctype; if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR)) return -EOPNOTSUPP; @@ -1801,16 +1863,19 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, if ((flags & MSG_TRYHARD) && sk->dst_cache) dst_negative_advice(&sk->dst_cache); + mss = scp->segsize_rem; + fctype = scp->services_rem & NSP_FC_MASK; + if (sk->dst_cache && sk->dst_cache->neighbour) { struct dn_neigh *dn = (struct dn_neigh *)sk->dst_cache->neighbour; - if (dn->blksize > 230) - mtu = dn->blksize - 11; + if (dn->blksize < (mss + 11)) + mss = dn->blksize - 11; } /* * The only difference between SEQPACKET & STREAM sockets under DECnet - * AFAIK is that SEQPACKET sockets set the MSG_EOR flag for the last - * session control message segment. + * is that SEQPACKET sockets set the MSG_EOR flag for the last + * session control message segment. */ if (flags & MSG_OOB) { @@ -1822,9 +1887,6 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, } } - if (mss < mtu) - mtu = mss; - scp->persist_fxn = dn_nsp_xmit_timeout; while(sent < size) { @@ -1842,14 +1904,14 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, */ len = size - sent; - if (len > mtu) - len = mtu; + if (len > mss) + len = mss; /* * Wait for queue size to go down below the window * size. */ - if (skb_queue_len(queue) >= scp->snd_window) { + if (dn_queue_too_long(scp, queue, flags)) { if (flags & MSG_DONTWAIT) { err = -EWOULDBLOCK; goto out; @@ -1857,7 +1919,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, SOCK_SLEEP_PRE(sk) - if (skb_queue_len(queue) >= scp->snd_window) + if (dn_queue_too_long(scp, queue, flags)) schedule(); SOCK_SLEEP_POST(sk) @@ -1876,7 +1938,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, if (!skb) continue; - cb = (struct dn_skb_cb *)skb->cb; + cb = DN_SKB_CB(skb); ptr = skb_put(skb, 9); @@ -1886,26 +1948,34 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, } if (flags & MSG_OOB) { - cb->segnum = scp->numoth++; - scp->numoth &= 0x0fff; + cb->segnum = scp->numoth; + seq_add(&scp->numoth, 1); msgflg = 0x30; - ack = scp->ackxmt_oth | 0x8000; + ack = (scp->numoth_rcv & 0x0FFF) | 0x8000; + scp->ackxmt_oth = scp->numoth_rcv; + if (fctype != NSP_FC_NONE) + scp->flowrem_oth--; } else { - cb->segnum = scp->numdat++; - scp->numdat &= 0x0fff; + cb->segnum = scp->numdat; + seq_add(&scp->numdat, 1); msgflg = 0x00; if (sock->type == SOCK_STREAM) msgflg = 0x60; - if (scp->seg_size == 0) + if (scp->seg_total == 0) msgflg |= 0x20; - scp->seg_size += len; + scp->seg_total += len; if (((sent + len) == size) && (flags & MSG_EOR)) { msgflg |= 0x40; - scp->seg_size = 0; + scp->seg_total = 0; + if (fctype == NSP_FC_SCMC) + scp->flowrem_dat--; } - ack = scp->ackxmt_dat | 0x8000; + ack = (scp->numdat_rcv & 0x0FFF) | 0x8000; + scp->ackxmt_dat = scp->numdat_rcv; + if (fctype == NSP_FC_SRC) + scp->flowrem_dat--; } *ptr++ = msgflg; @@ -1918,8 +1988,7 @@ static int dn_sendmsg(struct socket *sock, struct msghdr *msg, int size, *(__u16 *)ptr = dn_htons(cb->segnum); sent += len; - dn_nsp_queue_xmit(sk, skb, flags & MSG_OOB); - numseg++; + dn_nsp_queue_xmit(sk, skb, sk->allocation, flags & MSG_OOB); skb = NULL; scp->persist = dn_nsp_persist(sk); @@ -1955,21 +2024,38 @@ static int dn_device_event(struct notifier_block *this, unsigned long event, } static struct notifier_block dn_dev_notifier = { - dn_device_event, - 0 + notifier_call: dn_device_event, }; extern int dn_route_rcv(struct sk_buff *, struct net_device *, struct packet_type *); -static struct packet_type dn_dix_packet_type = -{ - __constant_htons(ETH_P_DNA_RT), - NULL, /* All devices */ - dn_route_rcv, - (void*)1, - NULL, +static struct packet_type dn_dix_packet_type = { + type: __constant_htons(ETH_P_DNA_RT), + dev: NULL, /* All devices */ + func: dn_route_rcv, + data: (void*)1, }; +#define IS_NOT_PRINTABLE(x) ((x) < 32 || (x) > 126) + +static void dn_printable_object(struct sockaddr_dn *dn, unsigned char *buf) +{ + int i; + + switch (dn->sdn_objnamel) { + case 0: + sprintf(buf, "%d", dn->sdn_objnum); + break; + default: + for (i = 0; i < dn->sdn_objnamel; i++) { + buf[i] = dn->sdn_objname[i]; + if (IS_NOT_PRINTABLE(buf[i])) + buf[i] = '.'; + } + buf[i] = 0; + } +} + static int dn_get_info(char *buffer, char **start, off_t offset, int length) { struct sock *sk; @@ -1979,15 +2065,20 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length) off_t begin = 0; char buf1[DN_ASCBUF_LEN]; char buf2[DN_ASCBUF_LEN]; + char local_object[DN_MAXOBJL+3]; + char remote_object[DN_MAXOBJL+3]; - len += sprintf(buffer + len, "Local Remote\n"); + len += sprintf(buffer + len, "Local Remote\n"); read_lock(&dn_hash_lock); for(sk = dn_sklist; sk != NULL; sk = sk->next) { - scp = &sk->protinfo.dn; + scp = DN_SK(sk); + + dn_printable_object(&scp->addr, local_object); + dn_printable_object(&scp->peer, remote_object); len += sprintf(buffer + len, - "%6s/%04X %04d:%04d %04d:%04d %01d %6s/%04X %04d:%04d %04d:%04d %01d %4s %s\n", + "%6s/%04X %04d:%04d %04d:%04d %01d %-16s %6s/%04X %04d:%04d %04d:%04d %01d %-16s %4s %s\n", dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->addr)), buf1), scp->addrloc, scp->numdat, @@ -1995,6 +2086,7 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length) scp->ackxmt_dat, scp->ackxmt_oth, scp->flowloc_sw, + local_object, dn_addr2asc(dn_ntohs(dn_saddr2dn(&scp->peer)), buf2), scp->addrrem, scp->numdat_rcv, @@ -2002,6 +2094,7 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length) scp->ackrcv_dat, scp->ackrcv_oth, scp->flowrem_sw, + remote_object, dn_state2asc(scp->state), ((scp->accept_mode == ACC_IMMED) ? "IMMED" : "DEFER")); @@ -2026,8 +2119,8 @@ static int dn_get_info(char *buffer, char **start, off_t offset, int length) static struct net_proto_family dn_family_ops = { - AF_DECnet, - dn_create + family: AF_DECnet, + create: dn_create, }; static struct proto_ops dn_proto_ops = { @@ -2067,6 +2160,7 @@ MODULE_PARM(addr, "2i"); MODULE_PARM_DESC(addr, "The DECnet address of this machine: area,node"); #endif +static char banner[] __initdata = KERN_INFO "NET4: DECnet for Linux: V.2.4.0-test12s (C) 1995-2000 Linux DECnet Project Team\n"; static int __init decnet_init(void) { @@ -2085,7 +2179,7 @@ static int __init decnet_init(void) dn_dn2eth(decnet_ether_address, dn_ntohs(decnet_address)); #endif - printk(KERN_INFO "NET4: DECnet for Linux: V.2.4.0-test10s (C) 1995-2000 Linux DECnet Project Team\n"); + printk(banner); sock_register(&dn_family_ops); dev_add_pack(&dn_dix_packet_type); diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index d8f91ac38988..056eaa043b64 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -52,7 +52,7 @@ static unsigned char dn_eco_version[3] = {0x02,0x00,0x00}; extern struct neigh_table dn_neigh_table; -struct net_device *decnet_default_device = NULL; +struct net_device *decnet_default_device; static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); static void dn_dev_delete(struct net_device *dev); @@ -1286,9 +1286,7 @@ void __exit dn_dev_cleanup(void) } #endif /* CONFIG_SYSCTL */ -#ifdef CONFIG_PROC_FS proc_net_remove("decnet_dev"); -#endif /* CONFIG_PROC_FS */ dn_dev_devices_off(); } diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index aff2dc05d8af..f82e2640697f 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c @@ -55,7 +55,7 @@ extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb); #endif /* CONFIG_RTNETLINK */ -static struct dn_fib_info *dn_fib_info_list = NULL; +static struct dn_fib_info *dn_fib_info_list; static rwlock_t dn_fib_info_lock = RW_LOCK_UNLOCKED; int dn_fib_info_cnt; @@ -641,15 +641,11 @@ static int decnet_rt_get_info(char *buffer, char **start, off_t offset, int leng return 0; } - #endif /* CONFIG_PROC_FS */ - void __exit dn_fib_cleanup(void) { -#ifdef CONFIG_PROC_FS proc_net_remove("decnet_route"); -#endif dn_fib_table_cleanup(); dn_fib_rules_cleanup(); diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 00c27cdeca9e..f25f37275ed6 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -18,6 +18,8 @@ * forwarding now stands a good chance of * working. * Steve Whitehouse : Fixed neighbour states (for now anyway). + * Steve Whitehouse : Made error_report functions dummies. This + * is not the right place to return skbs. * */ @@ -52,81 +54,66 @@ static int dn_phase3_output(struct sk_buff *); * For talking to broadcast devices: Ethernet & PPP */ static struct neigh_ops dn_long_ops = { - AF_DECnet, - NULL, - NULL, - dn_long_error_report, - dn_long_output, - dn_long_output, - dev_queue_xmit, - dev_queue_xmit + family: AF_DECnet, + error_report: dn_long_error_report, + output: dn_long_output, + connected_output: dn_long_output, + hh_output: dev_queue_xmit, + queue_xmit: dev_queue_xmit, }; /* * For talking to pointopoint and multidrop devices: DDCMP and X.25 */ static struct neigh_ops dn_short_ops = { - AF_DECnet, - NULL, - NULL, - dn_short_error_report, - dn_short_output, - dn_short_output, - dev_queue_xmit, - dev_queue_xmit + family: AF_DECnet, + error_report: dn_short_error_report, + output: dn_short_output, + connected_output: dn_short_output, + hh_output: dev_queue_xmit, + queue_xmit: dev_queue_xmit, }; /* * For talking to DECnet phase III nodes */ static struct neigh_ops dn_phase3_ops = { - AF_DECnet, - NULL, - NULL, - dn_short_error_report, /* Can use short version here */ - dn_phase3_output, - dn_phase3_output, - dev_queue_xmit, - dev_queue_xmit + family: AF_DECnet, + error_report: dn_short_error_report, /* Can use short version here */ + output: dn_phase3_output, + connected_output: dn_phase3_output, + hh_output: dev_queue_xmit, + queue_xmit: dev_queue_xmit }; struct neigh_table dn_neigh_table = { - NULL, - PF_DECnet, - sizeof(struct dn_neigh), - sizeof(dn_address), - dn_neigh_hash, - dn_neigh_construct, - NULL, /* pconstructor */ - NULL, /* pdestructor */ - NULL, /* proxyredo */ - "dn_neigh_cache", - { - NULL, - NULL, - &dn_neigh_table, - 0, - NULL, - NULL, - 30 * HZ, /* base_reachable_time */ - 1 * HZ, /* retrans_time */ - 60 * HZ, /* gc_staletime */ - 30 * HZ, /* reachable_time */ - 5 * HZ, /* delay_probe_time */ - 3, /* queue_len */ - 0, /* ucast_probes */ - 0, /* app_probes */ - 0, /* mcast_probes */ - 0, /* anycast_delay */ - 0, /* proxy_delay */ - 0, /* proxy_qlen */ - 1 * HZ, /* locktime */ + family: PF_DECnet, + entry_size: sizeof(struct dn_neigh), + key_len: sizeof(dn_address), + hash: dn_neigh_hash, + constructor: dn_neigh_construct, + id: "dn_neigh_cache", + parms: { + tbl: &dn_neigh_table, + entries: 0, + base_reachable_time: 30 * HZ, + retrans_time: 1 * HZ, + gc_staletime: 60 * HZ, + reachable_time: 30 * HZ, + delay_probe_time: 5 * HZ, + queue_len: 3, + ucast_probes: 0, + app_probes: 0, + mcast_probes: 0, + anycast_delay: 0, + proxy_delay: 0, + proxy_qlen: 0, + locktime: 1 * HZ, }, - 30 * HZ, /* gc_interval */ - 128, /* gc_thresh1 */ - 512, /* gc_thresh2 */ - 1024, /* gc_thresh3 */ - + gc_interval: 30 * HZ, + gc_thresh1: 128, + gc_thresh2: 512, + gc_thresh3: 1024, }; static u32 dn_neigh_hash(const void *pkey, const struct net_device *dev) @@ -180,66 +167,15 @@ static int dn_neigh_construct(struct neighbour *neigh) static void dn_long_error_report(struct neighbour *neigh, struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; - unsigned char *ptr; - printk(KERN_DEBUG "dn_long_error_report: called\n"); - - if (!(cb->rt_flags & DN_RT_F_RQR)) { - kfree_skb(skb); - return; - } - - skb_push(skb, skb->data - skb->nh.raw); - ptr = skb->data; - - *(unsigned short *)ptr = dn_htons(skb->len - 2); - ptr += 2; - - if (*ptr & DN_RT_F_PF) { - char padlen = (*ptr & ~DN_RT_F_PF); - ptr += padlen; - } - - *ptr++ |= (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS; - - ptr += 2; - dn_dn2eth(ptr, dn_ntohs(cb->src)); - ptr += 8; - dn_dn2eth(ptr, dn_ntohs(cb->dst)); - ptr += 6; - *ptr = 0; - - skb->dst->neighbour->ops->queue_xmit(skb); + kfree_skb(skb); } static void dn_short_error_report(struct neighbour *neigh, struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; - unsigned char *ptr; - printk(KERN_DEBUG "dn_short_error_report: called\n"); - - if (!(cb->rt_flags & DN_RT_F_RQR)) { - kfree_skb(skb); - return; - } - - skb_push(skb, skb->data - skb->nh.raw); - ptr = skb->data; - - *(unsigned short *)ptr = dn_htons(skb->len - 2); - ptr += 2; - *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS; - - *(dn_address *)ptr = cb->src; - ptr += 2; - *(dn_address *)ptr = cb->dst; - ptr += 2; - *ptr = 0; - - skb->dst->neighbour->ops->queue_xmit(skb); + kfree_skb(skb); } static int dn_neigh_output_packet(struct sk_buff *skb) @@ -266,7 +202,7 @@ static int dn_long_output(struct sk_buff *skb) int headroom = dev->hard_header_len + sizeof(struct dn_long_packet) + 3; unsigned char *data; struct dn_long_packet *lp; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); if (skb_headroom(skb) < headroom) { @@ -312,7 +248,7 @@ static int dn_short_output(struct sk_buff *skb) int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2; struct dn_short_packet *sp; unsigned char *data; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); if (skb_headroom(skb) < headroom) { @@ -355,7 +291,7 @@ static int dn_phase3_output(struct sk_buff *skb) int headroom = dev->hard_header_len + sizeof(struct dn_short_packet) + 2; struct dn_short_packet *sp; unsigned char *data; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); if (skb_headroom(skb) < headroom) { struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); @@ -659,8 +595,6 @@ void __init dn_neigh_init(void) void __exit dn_neigh_cleanup(void) { -#ifdef CONFIG_PROC_FS proc_net_remove("decnet_neigh"); -#endif /* CONFIG_PROC_FS */ neigh_table_clear(&dn_neigh_table); } diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 361729458ada..11a4e82376e7 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c @@ -25,6 +25,9 @@ * Steve Whitehouse: * Patrick Caulfield: Checking conninits for correctness & sending of error * responses. + * Steve Whitehouse: Added backlog congestion level return codes. + * Patrick Caulfield: + * Steve Whitehouse: Added flow control support (outbound) */ /****************************************************************************** @@ -79,7 +82,7 @@ static void dn_log_martian(struct sk_buff *skb, const char *msg) { if (decnet_log_martians && net_ratelimit()) { char *devname = skb->dev ? skb->dev->name : "???"; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); printk(KERN_INFO "DECnet: Martian packet (%s) dev=%s src=0x%04hx dst=0x%04hx srcport=0x%04hx dstport=0x%04hx\n", msg, devname, cb->src, cb->dst, cb->src_port, cb->dst_port); } } @@ -91,7 +94,7 @@ static void dn_log_martian(struct sk_buff *skb, const char *msg) */ static void dn_ack(struct sock *sk, struct sk_buff *skb, unsigned short ack) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); unsigned short type = ((ack >> 12) & 0x0003); int wakeup = 0; @@ -212,7 +215,7 @@ static struct { */ static struct sock *dn_find_listener(struct sk_buff *skb, unsigned short *reason) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); struct nsp_conn_init_msg *msg = (struct nsp_conn_init_msg *)skb->data; struct sockaddr_dn dstaddr; struct sockaddr_dn srcaddr; @@ -331,33 +334,26 @@ static void dn_nsp_conn_init(struct sock *sk, struct sk_buff *skb) static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_skb_cb *cb = DN_SKB_CB(skb); + struct dn_scp *scp = DN_SK(sk); + unsigned char *ptr; - if (skb->len < 3) + if (skb->len < 4) goto out; - cb->services = *skb->data; - cb->info = *(skb->data+1); - skb_pull(skb, 2); - cb->segsize = dn_ntohs(*(__u16 *)skb->data); - skb_pull(skb, 2); - - /* - * FIXME: Check out services and info fields to check that - * we can talk to this kind of node. - */ + ptr = skb->data; + cb->services = *ptr++; + cb->info = *ptr++; + cb->segsize = dn_ntohs(*(__u16 *)ptr); if ((scp->state == DN_CI) || (scp->state == DN_CD)) { scp->persist = 0; scp->addrrem = cb->src_port; sk->state = TCP_ESTABLISHED; scp->state = DN_RUN; - - if (scp->mss > cb->segsize) - scp->mss = cb->segsize; - if (scp->mss < 230) - scp->mss = 230; + scp->services_rem = cb->services; + scp->info_rem = cb->info; + scp->segsize_rem = cb->segsize; if (skb->len > 0) { unsigned char dlen = *skb->data; @@ -366,7 +362,7 @@ static void dn_nsp_conn_conf(struct sock *sk, struct sk_buff *skb) memcpy(scp->conndata_in.opt_data, skb->data + 1, dlen); } } - dn_nsp_send_lnk(sk, DN_NOCHANGE); + dn_nsp_send_link(sk, DN_NOCHANGE, 0); if (!sk->dead) sk->state_change(sk); } @@ -377,7 +373,7 @@ out: static void dn_nsp_conn_ack(struct sock *sk, struct sk_buff *skb) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->state == DN_CI) { scp->state = DN_CD; @@ -389,8 +385,8 @@ static void dn_nsp_conn_ack(struct sock *sk, struct sk_buff *skb) static void dn_nsp_disc_init(struct sock *sk, struct sk_buff *skb) { - struct dn_scp *scp = &sk->protinfo.dn; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_scp *scp = DN_SK(sk); + struct dn_skb_cb *cb = DN_SKB_CB(skb); unsigned short reason; if (skb->len < 2) @@ -448,7 +444,7 @@ out: */ static void dn_nsp_disc_conf(struct sock *sk, struct sk_buff *skb) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); unsigned short reason; if (skb->len != 2) @@ -492,38 +488,65 @@ out: static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_scp *scp = DN_SK(sk); unsigned short segnum; unsigned char lsflags; char fcval; + int wake_up = 0; + char *ptr = skb->data; + unsigned char fctype = scp->services_rem & NSP_FC_MASK; if (skb->len != 4) goto out; - cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data); - skb_pull(skb, 2); - lsflags = *(unsigned char *)skb->data; - skb_pull(skb, 1); - fcval = *(char *)skb->data; + segnum = dn_ntohs(*(__u16 *)ptr); + ptr += 2; + lsflags = *(unsigned char *)ptr++; + fcval = *ptr; - if (lsflags & 0xf0) + /* + * Here we ignore erronous packets which should really + * should cause a connection abort. It is not critical + * for now though. + */ + if (lsflags & 0xf8) goto out; - if (((sk->protinfo.dn.numoth_rcv + 1) & 0x0FFF) == (segnum & 0x0FFF)) { - sk->protinfo.dn.numoth_rcv += 1; - switch(lsflags & 0x03) { - case 0x00: - break; - case 0x01: - sk->protinfo.dn.flowrem_sw = DN_DONTSEND; - break; - case 0x02: - sk->protinfo.dn.flowrem_sw = DN_SEND; + if (seq_next(scp->numoth_rcv, segnum)) { + seq_add(&scp->numoth_rcv, 1); + switch(lsflags & 0x04) { /* FCVAL INT */ + case 0x00: /* Normal Request */ + switch(lsflags & 0x03) { /* FCVAL MOD */ + case 0x00: /* Request count */ + if (fcval < 0) { + unsigned char p_fcval = -fcval; + if ((scp->flowrem_dat > p_fcval) && + (fctype == NSP_FC_SCMC)) { + scp->flowrem_dat -= p_fcval; + } + } else if (fcval > 0) { + scp->flowrem_dat += fcval; + wake_up = 1; + } + break; + case 0x01: /* Stop outgoing data */ + scp->flowrem_sw = DN_DONTSEND; + break; + case 0x02: /* Ok to start again */ + scp->flowrem_sw = DN_SEND; dn_nsp_output(sk); - if (!sk->dead) - sk->state_change(sk); + wake_up = 1; + } + break; + case 0x04: /* Interrupt Request */ + if (fcval > 0) { + scp->flowrem_oth += fcval; + wake_up = 1; + } + break; } - + if (wake_up && !sk->dead) + sk->state_change(sk); } dn_nsp_send_oth_ack(sk); @@ -582,9 +605,9 @@ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); unsigned short segnum; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); int queued = 0; if (skb->len < 2) @@ -593,10 +616,10 @@ static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb) cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data); skb_pull(skb, 2); - if (((sk->protinfo.dn.numoth_rcv + 1) & 0x0fff) == (segnum & 0x0fff)) { + if (seq_next(scp->numoth_rcv, segnum)) { if (dn_queue_skb(sk, skb, SIGURG, &scp->other_receive_queue) == 0) { - sk->protinfo.dn.numoth_rcv++; + seq_add(&scp->numoth_rcv, 1); scp->other_report = 0; queued = 1; } @@ -612,8 +635,8 @@ static void dn_nsp_data(struct sock *sk, struct sk_buff *skb) { int queued = 0; unsigned short segnum; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_skb_cb *cb = DN_SKB_CB(skb); + struct dn_scp *scp = DN_SK(sk); if (skb->len < 2) goto out; @@ -621,17 +644,15 @@ static void dn_nsp_data(struct sock *sk, struct sk_buff *skb) cb->segnum = segnum = dn_ntohs(*(__u16 *)skb->data); skb_pull(skb, 2); - if (((sk->protinfo.dn.numdat_rcv + 1) & 0x0FFF) == - (segnum & 0x0FFF)) { - + if (seq_next(scp->numdat_rcv, segnum)) { if (dn_queue_skb(sk, skb, SIGIO, &sk->receive_queue) == 0) { - sk->protinfo.dn.numdat_rcv++; + seq_add(&scp->numdat_rcv, 1); queued = 1; } if ((scp->flowloc_sw == DN_SEND) && dn_congested(sk)) { scp->flowloc_sw = DN_DONTSEND; - dn_nsp_send_lnk(sk, DN_DONTSEND); + dn_nsp_send_link(sk, DN_DONTSEND, 0); } } @@ -648,7 +669,7 @@ out: */ static void dn_returned_conn_init(struct sock *sk, struct sk_buff *skb) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->state == DN_CI) { scp->state = DN_NC; @@ -660,28 +681,37 @@ static void dn_returned_conn_init(struct sock *sk, struct sk_buff *skb) kfree_skb(skb); } -static void dn_nsp_no_socket(struct sk_buff *skb, unsigned short reason) +static int dn_nsp_no_socket(struct sk_buff *skb, unsigned short reason) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); + int ret = NET_RX_DROP; + + /* Must not reply to returned packets */ + if (cb->rt_flags & DN_RT_F_RTS) + goto out; if ((reason != NSP_REASON_OK) && ((cb->nsp_flags & 0x0c) == 0x08)) { switch(cb->nsp_flags & 0x70) { case 0x10: case 0x60: /* (Retransmitted) Connect Init */ dn_nsp_return_disc(skb, NSP_DISCINIT, reason); + ret = NET_RX_SUCCESS; break; case 0x20: /* Connect Confirm */ dn_nsp_return_disc(skb, NSP_DISCCONF, reason); + ret = NET_RX_SUCCESS; break; } } +out: kfree_skb(skb); + return ret; } static int dn_nsp_rx_packet(struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); struct sock *sk = NULL; unsigned char *ptr = (unsigned char *)skb->data; unsigned short reason = NSP_REASON_NL; @@ -754,14 +784,19 @@ static int dn_nsp_rx_packet(struct sk_buff *skb) sk = dn_find_by_skb(skb); got_it: if (sk != NULL) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int ret; /* Reset backoff */ scp->nsp_rxtshift = 0; bh_lock_sock(sk); - ret = 0; + ret = NET_RX_SUCCESS; + if (decnet_debug_level & 8) + printk(KERN_DEBUG "NSP: 0x%02x 0x%02x 0x%04x 0x%04x %d\n", + (int)cb->rt_flags, (int)cb->nsp_flags, + (int)cb->src_port, (int)cb->dst_port, + (int)sk->lock.users); if (sk->lock.users == 0) ret = dn_nsp_backlog_rcv(sk, skb); else @@ -772,12 +807,11 @@ got_it: return ret; } - dn_nsp_no_socket(skb, reason); - return 1; + return dn_nsp_no_socket(skb, reason); free_out: kfree_skb(skb); - return 0; + return NET_RX_DROP; } int dn_nsp_rx(struct sk_buff *skb) @@ -792,12 +826,12 @@ int dn_nsp_rx(struct sk_buff *skb) */ int dn_nsp_backlog_rcv(struct sock *sk, struct sk_buff *skb) { - struct dn_scp *scp = &sk->protinfo.dn; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_scp *scp = DN_SK(sk); + struct dn_skb_cb *cb = DN_SKB_CB(skb); if (cb->rt_flags & DN_RT_F_RTS) { dn_returned_conn_init(sk, skb); - return 0; + return NET_RX_SUCCESS; } /* @@ -875,6 +909,6 @@ free_out: } } - return 0; + return NET_RX_SUCCESS; } diff --git a/net/decnet/dn_nsp_out.c b/net/decnet/dn_nsp_out.c index 6965cbf42967..5e8482ce08d5 100644 --- a/net/decnet/dn_nsp_out.c +++ b/net/decnet/dn_nsp_out.c @@ -20,6 +20,7 @@ * Steve Whitehouse: New output state machine * Paul Koning: Connect Confirm message fix. * Eduardo Serrat: Fix to stop dn_nsp_do_disc() sending malformed packets. + * Steve Whitehouse: dn_nsp_output() and friends needed a spring clean */ /****************************************************************************** @@ -165,7 +166,7 @@ struct sk_buff *dn_alloc_send_skb(struct sock *sk, int *size, int noblock, int * */ unsigned long dn_nsp_persist(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1; @@ -188,7 +189,7 @@ unsigned long dn_nsp_persist(struct sock *sk) */ static void dn_nsp_rtt(struct sock *sk, long rtt) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); long srtt = (long)scp->nsp_srtt; long rttvar = (long)scp->nsp_rttvar; long delta; @@ -223,65 +224,64 @@ static void dn_nsp_rtt(struct sock *sk, long rtt) /* printk(KERN_DEBUG "srtt=%lu rttvar=%lu\n", scp->nsp_srtt, scp->nsp_rttvar); */ } -/* - * Walk the queues, otherdata/linkservice first. Send as many - * frames as the window allows, increment send counts on all - * skbs which are sent. Reduce the window if we are retransmitting - * frames. +/** + * dn_nsp_clone_and_send - Send a data packet by cloning it + * @skb: The packet to clone and transmit + * @gfp: memory allocation flag + * + * Clone a queued data or other data packet and transmit it. + * + * Returns: The number of times the packet has been sent previously */ -void dn_nsp_output(struct sock *sk) +static inline unsigned dn_nsp_clone_and_send(struct sk_buff *skb, int gfp) { - struct dn_scp *scp = &sk->protinfo.dn; - unsigned long win = scp->snd_window; - struct sk_buff *skb, *skb2, *list; - struct dn_skb_cb *cb; - int reduce_win = 0; + struct dn_skb_cb *cb = DN_SKB_CB(skb); + struct sk_buff *skb2; + int ret = 0; - /* printk(KERN_DEBUG "dn_nsp_output: ping\n"); */ + if ((skb2 = skb_clone(skb, gfp)) != NULL) { + ret = cb->xmit_count; + cb->xmit_count++; + cb->stamp = jiffies; + skb2->sk = skb->sk; + dn_nsp_send(skb2); + } + + return ret; +} + +/** + * dn_nsp_output - Try and send something from socket queues + * @sk: The socket whose queues are to be investigated + * @gfp: The memory allocation flags + * + * Try and send the packet on the end of the data and other data queues. + * Other data gets priority over data, and if we retransmit a packet we + * reduce the window by dividing it in two. + * + */ +void dn_nsp_output(struct sock *sk) +{ + struct dn_scp *scp = DN_SK(sk); + struct sk_buff *skb; + unsigned reduce_win = 0; /* * First we check for otherdata/linkservice messages */ - skb = scp->other_xmit_queue.next; - list = (struct sk_buff *)&scp->other_xmit_queue; - while(win && (skb != list)) { - if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { - cb = (struct dn_skb_cb *)skb; - if (cb->xmit_count > 0) - reduce_win = 1; - else - cb->stamp = jiffies; - cb->xmit_count++; - skb2->sk = sk; - dn_nsp_send(skb2); - } - skb = skb->next; - win--; - } + if ((skb = skb_peek(&scp->other_xmit_queue)) != NULL) + reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC); /* * If we may not send any data, we don't. - * Should this apply to otherdata as well ? - SJW + * If we are still trying to get some other data down the + * channel, we don't try and send any data. */ - if (scp->flowrem_sw != DN_SEND) + if (reduce_win || (scp->flowrem_sw != DN_SEND)) goto recalc_window; - skb = scp->data_xmit_queue.next; - list = (struct sk_buff *)&scp->data_xmit_queue; - while(win && (skb != list)) { - if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { - cb = (struct dn_skb_cb *)skb; - if (cb->xmit_count > 0) - reduce_win = 1; - else - cb->stamp = jiffies; - cb->xmit_count++; - skb2->sk = sk; - dn_nsp_send(skb2); - } - skb = skb->next; - win--; - } + if ((skb = skb_peek(&scp->data_xmit_queue)) != NULL) + reduce_win = dn_nsp_clone_and_send(skb, GFP_ATOMIC); /* * If we've sent any frame more than once, we cut the @@ -290,7 +290,6 @@ void dn_nsp_output(struct sock *sk) */ recalc_window: if (reduce_win) { - /* printk(KERN_DEBUG "Window reduction %ld\n", scp->snd_window); */ scp->snd_window >>= 1; if (scp->snd_window < NSP_MIN_WINDOW) scp->snd_window = NSP_MIN_WINDOW; @@ -299,7 +298,7 @@ recalc_window: int dn_nsp_xmit_timeout(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); dn_nsp_output(sk); @@ -309,14 +308,60 @@ int dn_nsp_xmit_timeout(struct sock *sk) return 0; } -void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int oth) +static inline unsigned char *dn_mk_common_header(struct dn_scp *scp, struct sk_buff *skb, unsigned char msgflag, int len) +{ + unsigned char *ptr = skb_push(skb, len); + + if (len < 5) + BUG(); + + *ptr++ = msgflag; + *((unsigned short *)ptr) = scp->addrrem; + ptr += 2; + *((unsigned short *)ptr) = scp->addrloc; + ptr += 2; + return ptr; +} + +static unsigned short *dn_mk_ack_header(struct sock *sk, struct sk_buff *skb, unsigned char msgflag, int hlen, int other) +{ + struct dn_scp *scp = DN_SK(sk); + unsigned short acknum = scp->numdat_rcv & 0x0FFF; + unsigned short ackcrs = scp->numoth_rcv & 0x0FFF; + unsigned short *ptr; + + if (hlen < 9) + BUG(); + + scp->ackxmt_dat = acknum; + scp->ackxmt_oth = ackcrs; + acknum |= 0x8000; + ackcrs |= 0x8000; + + /* If this is an "other data/ack" message, swap acknum and ackcrs */ + if (other) { + unsigned short tmp = acknum; + acknum = ackcrs; + ackcrs = tmp; + } + + /* Set "cross subchannel" bit in ackcrs */ + ackcrs |= 0x2000; + + ptr = (unsigned short *)dn_mk_common_header(scp, skb, msgflag, hlen); + + *ptr++ = dn_htons(acknum); + *ptr++ = dn_htons(ackcrs); + + return ptr; +} + +void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int gfp, int oth) { - struct dn_scp *scp = &sk->protinfo.dn; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_scp *scp = DN_SK(sk); + struct dn_skb_cb *cb = DN_SKB_CB(skb); unsigned long t = ((scp->nsp_srtt >> 2) + scp->nsp_rttvar) >> 1; - struct sk_buff *skb2; - if (t < HZ) t = HZ; /* * Slow start: If we have been idle for more than * one RTT, then reset window to min size. @@ -336,20 +381,17 @@ void dn_nsp_queue_xmit(struct sock *sk, struct sk_buff *skb, int oth) if (scp->flowrem_sw != DN_SEND) return; - if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) { - cb->stamp = jiffies; - cb->xmit_count++; - skb2->sk = sk; - dn_nsp_send(skb2); - } + dn_nsp_clone_and_send(skb, gfp); } + int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff_head *q, unsigned short acknum) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_skb_cb *cb = DN_SKB_CB(skb); + struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb2, *list, *ack = NULL; int wakeup = 0; + int try_retrans = 0; unsigned long reftime = cb->stamp; unsigned long pkttime; unsigned short xmit_count; @@ -358,7 +400,7 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff skb2 = q->next; list = (struct sk_buff *)q; while(list != skb2) { - struct dn_skb_cb *cb2 = (struct dn_skb_cb *)skb2->cb; + struct dn_skb_cb *cb2 = DN_SKB_CB(skb2); if (before_or_equal(cb2->segnum, acknum)) ack = skb2; @@ -372,27 +414,50 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff /* printk(KERN_DEBUG "check_xmit_queue: %04x, %d\n", acknum, cb2->xmit_count); */ + /* Does _last_ packet acked have xmit_count > 1 */ + try_retrans = 0; + /* Remember to wake up the sending process */ wakeup = 1; + /* Keep various statistics */ pkttime = cb2->stamp; xmit_count = cb2->xmit_count; segnum = cb2->segnum; + /* Remove and drop ack'ed packet */ skb_unlink(ack); kfree_skb(ack); ack = NULL; + + /* + * We don't expect to see acknowledgements for packets we + * haven't sent yet. + */ + if (xmit_count == 0) + BUG(); + /* + * If the packet has only been sent once, we can use it + * to calculate the RTT and also open the window a little + * further. + */ if (xmit_count == 1) { if (equal(segnum, acknum)) dn_nsp_rtt(sk, (long)(pkttime - reftime)); - if (scp->snd_window < NSP_MAX_WINDOW) + if (scp->snd_window < scp->max_window) scp->snd_window++; } + + /* + * Packet has been sent more than once. If this is the last + * packet to be acknowledged then we want to send the next + * packet in the send queue again (assumes the remote host does + * go-back-N error control). + */ + if (xmit_count > 1) + try_retrans = 1; } -#if 0 /* Turned off due to possible interference in socket shutdown */ - if ((skb_queue_len(&scp->data_xmit_queue) == 0) && - (skb_queue_len(&scp->other_xmit_queue) == 0)) - scp->persist = 0; -#endif + if (try_retrans) + dn_nsp_output(sk); return wakeup; } @@ -400,47 +465,31 @@ int dn_nsp_check_xmit_queue(struct sock *sk, struct sk_buff *skb, struct sk_buff void dn_nsp_send_data_ack(struct sock *sk) { struct sk_buff *skb = NULL; - struct nsp_data_ack_msg *msg; - if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL) + if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL) return; - - msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg)); - - msg->msgflg = 0x04; /* data ack message */ - msg->dstaddr = sk->protinfo.dn.addrrem; - msg->srcaddr = sk->protinfo.dn.addrloc; - msg->acknum = dn_htons((sk->protinfo.dn.numdat_rcv & 0x0FFF) | 0x8000); - - sk->protinfo.dn.ackxmt_dat = sk->protinfo.dn.numdat_rcv; + skb_reserve(skb, 9); + dn_mk_ack_header(sk, skb, 0x04, 9, 0); dn_nsp_send(skb); } void dn_nsp_send_oth_ack(struct sock *sk) { struct sk_buff *skb = NULL; - struct nsp_data_ack_msg *msg; - if ((skb = dn_alloc_skb(sk, 200, GFP_ATOMIC)) == NULL) + if ((skb = dn_alloc_skb(sk, 9, GFP_ATOMIC)) == NULL) return; - - msg = (struct nsp_data_ack_msg *)skb_put(skb,sizeof(*msg)); - - msg->msgflg = 0x14; /* oth ack message */ - msg->dstaddr = sk->protinfo.dn.addrrem; - msg->srcaddr = sk->protinfo.dn.addrloc; - msg->acknum = dn_htons((sk->protinfo.dn.numoth_rcv & 0x0FFF) | 0x8000); - - sk->protinfo.dn.ackxmt_oth = sk->protinfo.dn.numoth_rcv; + skb_reserve(skb, 9); + dn_mk_ack_header(sk, skb, 0x14, 9, 1); dn_nsp_send(skb); } void dn_send_conn_ack (struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb = NULL; struct nsp_conn_ack_msg *msg; @@ -456,7 +505,7 @@ void dn_send_conn_ack (struct sock *sk) void dn_nsp_delayed_ack(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->ackxmt_oth != scp->numoth_rcv) dn_nsp_send_oth_ack(sk); @@ -467,7 +516,7 @@ void dn_nsp_delayed_ack(struct sock *sk) static int dn_nsp_retrans_conn_conf(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->state == DN_CC) dn_send_conn_conf(sk, GFP_ATOMIC); @@ -477,7 +526,7 @@ static int dn_nsp_retrans_conn_conf(struct sock *sk) void dn_send_conn_conf(struct sock *sk, int gfp) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb = NULL; struct nsp_conn_init_msg *msg; unsigned char len = scp->conndata_out.opt_optl; @@ -489,9 +538,9 @@ void dn_send_conn_conf(struct sock *sk, int gfp) msg->msgflg = 0x28; msg->dstaddr = scp->addrrem; msg->srcaddr = scp->addrloc; - msg->services = 0x01; - msg->info = 0x03; - msg->segsize = dn_htons(0x05B3); + msg->services = scp->services_loc; + msg->info = scp->info_loc; + msg->segsize = dn_htons(scp->segsize_loc); *skb_put(skb,1) = len; @@ -551,7 +600,7 @@ static __inline__ void dn_nsp_do_disc(struct sock *sk, unsigned char msgflg, void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg, unsigned short reason, int gfp) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); int ddl = 0; if (msgflg == NSP_DISCINIT) @@ -568,7 +617,7 @@ void dn_nsp_send_disc(struct sock *sk, unsigned char msgflg, void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg, unsigned short reason) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); int ddl = 0; int gfp = GFP_ATOMIC; @@ -577,38 +626,35 @@ void dn_nsp_return_disc(struct sk_buff *skb, unsigned char msgflg, } -void dn_nsp_send_lnk(struct sock *sk, unsigned short flgs) +void dn_nsp_send_link(struct sock *sk, unsigned char lsflags, char fcval) { - struct dn_scp *scp = &sk->protinfo.dn; - struct sk_buff *skb = NULL; - struct nsp_data_seg_msg *msg; - struct nsp_data_opt_msg *msg1; - struct dn_skb_cb *cb; + struct dn_scp *scp = DN_SK(sk); + struct sk_buff *skb; + unsigned short *segnum; + unsigned char *ptr; + int gfp = GFP_ATOMIC; - if ((skb = dn_alloc_skb(sk, 80, GFP_ATOMIC)) == NULL) + if ((skb = dn_alloc_skb(sk, 13, gfp)) == NULL) return; - cb = (struct dn_skb_cb *)skb->cb; - msg = (struct nsp_data_seg_msg *)skb_put(skb, sizeof(*msg)); - msg->msgflg = 0x10; /* Link svc message */ - msg->dstaddr = scp->addrrem; - msg->srcaddr = scp->addrloc; + skb_reserve(skb, 13); + segnum = dn_mk_ack_header(sk, skb, 0x10, 13, 1); + *segnum = dn_htons(scp->numoth); + DN_SKB_CB(skb)->segnum = scp->numoth; + seq_add(&scp->numoth, 1); + ptr = (unsigned char *)(segnum + 1); + *ptr++ = lsflags; + *ptr = fcval; - msg1 = (struct nsp_data_opt_msg *)skb_put(skb, sizeof(*msg1)); - msg1->acknum = dn_htons((scp->ackxmt_oth & 0x0FFF) | 0x8000); - msg1->segnum = dn_htons(cb->segnum = (scp->numoth++ & 0x0FFF)); - msg1->lsflgs = flgs; - - dn_nsp_queue_xmit(sk, skb, 1); + dn_nsp_queue_xmit(sk, skb, gfp, 1); scp->persist = dn_nsp_persist(sk); scp->persist_fxn = dn_nsp_xmit_timeout; - } static int dn_nsp_retrans_conninit(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->state == DN_CI) dn_nsp_send_conninit(sk, NSP_RCI); @@ -618,7 +664,7 @@ static int dn_nsp_retrans_conninit(struct sock *sk) void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); struct sk_buff *skb = NULL; struct nsp_conn_init_msg *msg; unsigned char aux; @@ -629,16 +675,16 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg) if ((skb = dn_alloc_skb(sk, 200, (msgflg == NSP_CI) ? sk->allocation : GFP_ATOMIC)) == NULL) return; - cb = (struct dn_skb_cb *)skb->cb; + cb = DN_SKB_CB(skb); msg = (struct nsp_conn_init_msg *)skb_put(skb,sizeof(*msg)); msg->msgflg = msgflg; msg->dstaddr = 0x0000; /* Remote Node will assign it*/ - msg->srcaddr = sk->protinfo.dn.addrloc; - msg->services = 1 | NSP_FC_NONE; /* Requested flow control */ - msg->info = 0x03; /* Version Number */ - msg->segsize = dn_htons(1459); /* Max segment size */ + msg->srcaddr = scp->addrloc; + msg->services = scp->services_loc; /* Requested flow control */ + msg->info = scp->info_loc; /* Version Number */ + msg->segsize = dn_htons(scp->segsize_loc); /* Max segment size */ if (scp->peer.sdn_objnum) type = 0; @@ -674,8 +720,8 @@ void dn_nsp_send_conninit(struct sock *sk, unsigned char msgflg) if (aux > 0) memcpy(skb_put(skb,aux), scp->conndata_out.opt_data, aux); - sk->protinfo.dn.persist = dn_nsp_persist(sk); - sk->protinfo.dn.persist_fxn = dn_nsp_retrans_conninit; + scp->persist = dn_nsp_persist(sk); + scp->persist_fxn = dn_nsp_retrans_conninit; cb->rt_flags = DN_RT_F_RQR; diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 70646fc11d2a..b40c601b68c0 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -33,6 +33,9 @@ * Steve Whitehouse : Real SMP at last :-) Also new netfilter * stuff. Look out raw sockets your days * are numbered! + * Steve Whitehouse : Added return-to-sender functions. Added + * backlog congestion level return codes. + * */ /****************************************************************************** @@ -109,17 +112,16 @@ static struct timer_list dn_rt_flush_timer = { function: dn_run_flush }; int decnet_dst_gc_interval = 2; static struct dst_ops dn_dst_ops = { - PF_DECnet, - __constant_htons(ETH_P_DNA_RT), - 128, - dn_dst_gc, - dn_dst_check, - dn_dst_reroute, - NULL, - dn_dst_negative_advice, - dn_dst_link_failure, - sizeof(struct dn_route), - ATOMIC_INIT(0) + family: PF_DECnet, + protocol: __constant_htons(ETH_P_DNA_RT), + gc_thresh: 128, + gc: dn_dst_gc, + check: dn_dst_check, + reroute: dn_dst_reroute, + negative_advice: dn_dst_negative_advice, + link_failure: dn_dst_link_failure, + entry_size: sizeof(struct dn_route), + entries: ATOMIC_INIT(0), }; static __inline__ unsigned dn_hash(unsigned short src, unsigned short dst) @@ -294,21 +296,131 @@ void dn_rt_cache_flush(int delay) spin_unlock_bh(&dn_rt_flush_lock); } +/** + * dn_return_short - Return a short packet to its sender + * @skb: The packet to return + * + */ +static int dn_return_short(struct sk_buff *skb) +{ + struct dn_skb_cb *cb; + unsigned char *ptr; + dn_address *src; + dn_address *dst; + dn_address tmp; + + /* Add back headers */ + skb_push(skb, skb->data - skb->nh.raw); + + if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL) + return NET_RX_DROP; + + cb = DN_SKB_CB(skb); + /* Skip packet length and point to flags */ + ptr = skb->data + 2; + *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS; + + dst = (dn_address *)ptr; + ptr += 2; + src = (dn_address *)ptr; + ptr += 2; + *ptr = 0; /* Zero hop count */ + + /* Swap source and destination */ + tmp = *src; + *src = *dst; + *dst = tmp; + + skb->pkt_type = PACKET_OUTGOING; + dn_rt_finish_output(skb, NULL); + return NET_RX_SUCCESS; +} + +/** + * dn_return_long - Return a long packet to its sender + * @skb: The long format packet to return + * + */ +static int dn_return_long(struct sk_buff *skb) +{ + struct dn_skb_cb *cb; + unsigned char *ptr; + unsigned char *src_addr, *dst_addr; + unsigned char tmp[ETH_ALEN]; + + /* Add back all headers */ + skb_push(skb, skb->data - skb->nh.raw); + + if ((skb = skb_unshare(skb, GFP_ATOMIC)) == NULL) + return NET_RX_DROP; + cb = DN_SKB_CB(skb); + /* Ignore packet length and point to flags */ + ptr = skb->data + 2; + + /* Skip padding */ + if (*ptr & DN_RT_F_PF) { + char padlen = (*ptr & ~DN_RT_F_PF); + ptr += padlen; + } + + *ptr++ = (cb->rt_flags & ~DN_RT_F_RQR) | DN_RT_F_RTS; + ptr += 2; + dst_addr = ptr; + ptr += 8; + src_addr = ptr; + ptr += 6; + *ptr = 0; /* Zero hop count */ + + /* Swap source and destination */ + memcpy(tmp, src_addr, ETH_ALEN); + memcpy(src_addr, dst_addr, ETH_ALEN); + memcpy(dst_addr, tmp, ETH_ALEN); + + skb->pkt_type = PACKET_OUTGOING; + dn_rt_finish_output(skb, tmp); + return NET_RX_SUCCESS; +} + +/** + * dn_route_rx_packet - Try and find a route for an incoming packet + * @skb: The packet to find a route for + * + * Returns: result of input function if route is found, error code otherwise + */ static int dn_route_rx_packet(struct sk_buff *skb) { + struct dn_skb_cb *cb = DN_SKB_CB(skb); int err; if ((err = dn_route_input(skb)) == 0) return skb->dst->input(skb); + if (decnet_debug_level & 4) { + char *devname = skb->dev ? skb->dev->name : "???"; + struct dn_skb_cb *cb = DN_SKB_CB(skb); + printk(KERN_DEBUG + "DECnet: dn_route_rx_packet: rt_flags=0x%02x dev=%s len=%d src=0x%04hx dst=0x%04hx err=%d type=%d\n", + (int)cb->rt_flags, devname, skb->len, cb->src, cb->dst, + err, skb->pkt_type); + } + + if ((skb->pkt_type == PACKET_HOST) && (cb->rt_flags & DN_RT_F_RQR)) { + switch(cb->rt_flags & DN_RT_PKT_MSK) { + case DN_RT_PKT_SHORT: + return dn_return_short(skb); + case DN_RT_PKT_LONG: + return dn_return_long(skb); + } + } + kfree_skb(skb); - return err; + return NET_RX_DROP; } static int dn_route_rx_long(struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); unsigned char *ptr = skb->data; if (skb->len < 21) /* 20 for long header, 1 for shortest nsp */ @@ -339,14 +451,14 @@ static int dn_route_rx_long(struct sk_buff *skb) drop_it: kfree_skb(skb); - return 0; + return NET_RX_DROP; } static int dn_route_rx_short(struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); unsigned char *ptr = skb->data; if (skb->len < 6) /* 5 for short header + 1 for shortest nsp */ @@ -365,29 +477,33 @@ static int dn_route_rx_short(struct sk_buff *skb) drop_it: kfree_skb(skb); - return 0; + return NET_RX_DROP; } static int dn_route_discard(struct sk_buff *skb) { + /* + * I know we drop the packet here, but thats considered success in + * this case + */ kfree_skb(skb); - return 0; + return NET_RX_SUCCESS; } static int dn_route_ptp_hello(struct sk_buff *skb) { dn_dev_hello(skb); dn_neigh_pointopoint_hello(skb); - return 0; + return NET_RX_SUCCESS; } int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) { struct dn_skb_cb *cb; unsigned char flags = 0; - int padlen = 0; __u16 len = dn_ntohs(*(__u16 *)skb->data); struct dn_dev *dn = (struct dn_dev *)dev->dn_ptr; + unsigned char padlen = 0; if (dn == NULL) goto dump_it; @@ -404,7 +520,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type flags = *skb->data; - cb = (struct dn_skb_cb *)skb->cb; + cb = DN_SKB_CB(skb); cb->stamp = jiffies; cb->iif = dev->ifindex; @@ -448,20 +564,16 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type switch(flags & DN_RT_CNTL_MSK) { case DN_RT_PKT_HELO: - NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello); - goto out; + return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_route_ptp_hello); case DN_RT_PKT_L1RT: case DN_RT_PKT_L2RT: - NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard); - goto out; + return NF_HOOK(PF_DECnet, NF_DN_ROUTE, skb, skb->dev, NULL, dn_route_discard); case DN_RT_PKT_ERTH: - NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello); - goto out; + return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_router_hello); case DN_RT_PKT_EEDH: - NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello); - goto out; + return NF_HOOK(PF_DECnet, NF_DN_HELLO, skb, skb->dev, NULL, dn_neigh_endnode_hello); } } else { if (dn->parms.state != DN_DEV_S_RU) @@ -480,7 +592,7 @@ int dn_route_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type dump_it: kfree_skb(skb); out: - return 0; + return NET_RX_DROP; } static int dn_output(struct sk_buff *skb) @@ -488,7 +600,7 @@ static int dn_output(struct sk_buff *skb) struct dst_entry *dst = skb->dst; struct dn_route *rt = (struct dn_route *)dst; struct net_device *dev = dst->dev; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); struct neighbour *neigh; int err = -EINVAL; @@ -524,7 +636,7 @@ error: #ifdef CONFIG_DECNET_ROUTER static int dn_forward(struct sk_buff *skb) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); struct dst_entry *dst = skb->dst; struct net_device *dev = skb->dev; struct neighbour *neigh; @@ -536,7 +648,7 @@ static int dn_forward(struct sk_buff *skb) /* * Hop count exceeded. */ - err = 0; + err = NET_RX_DROP; if (++cb->hops > 30) goto drop; @@ -573,7 +685,7 @@ drop: static int dn_blackhole(struct sk_buff *skb) { kfree_skb(skb); - return 0; + return NET_RX_DROP; } /* @@ -583,7 +695,7 @@ static int dn_blackhole(struct sk_buff *skb) static int dn_rt_bug(struct sk_buff *skb) { if (net_ratelimit()) { - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); printk(KERN_DEBUG "dn_rt_bug: skb from:%04x to:%04x\n", cb->src, cb->dst); @@ -591,7 +703,7 @@ static int dn_rt_bug(struct sk_buff *skb) kfree_skb(skb); - return -EINVAL; + return NET_RX_BAD; } static int dn_route_output_slow(struct dst_entry **pprt, dn_address dst, dn_address src, int flags) @@ -732,7 +844,7 @@ int dn_route_output(struct dst_entry **pprt, dn_address dst, dn_address src, int static int dn_route_input_slow(struct sk_buff *skb) { struct dn_route *rt = NULL; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); struct net_device *dev = skb->dev; struct dn_dev *dn_db; struct neighbour *neigh = NULL; @@ -880,7 +992,7 @@ add_entry: int dn_route_input(struct sk_buff *skb) { struct dn_route *rt; - struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb; + struct dn_skb_cb *cb = DN_SKB_CB(skb); unsigned hash = dn_hash(cb->src, cb->dst); if (skb->dst) @@ -964,7 +1076,7 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg) if (skb == NULL) return -ENOBUFS; skb->mac.raw = skb->data; - cb = (struct dn_skb_cb *)skb->cb; + cb = DN_SKB_CB(skb); if (rta[RTA_SRC-1]) memcpy(&src, RTA_DATA(rta[RTA_SRC-1]), 2); @@ -1185,8 +1297,6 @@ void __exit dn_route_cleanup(void) del_timer(&dn_route_timer); dn_run_flush(0); -#ifdef CONFIG_PROC_FS proc_net_remove("decnet_cache"); -#endif /* CONFIG_PROC_FS */ } diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index 133591f0b854..32adfecbaeea 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c @@ -57,7 +57,12 @@ struct dn_fib_rule int r_dead; }; -static struct dn_fib_rule default_rule = { NULL, ATOMIC_INIT(2), 0x7fff, DN_DEFAULT_TABLE, RTN_UNICAST }; +static struct dn_fib_rule default_rule = { + r_clntref: ATOMIC_INIT(2), + r_preference: 0x7fff, + r_table: DN_DEFAULT_TABLE, + r_action: RTN_UNICAST +}; static struct dn_fib_rule *dn_fib_rules = &default_rule; static rwlock_t dn_fib_rules_lock = RW_LOCK_UNLOCKED; @@ -291,9 +296,7 @@ static int dn_fib_rules_event(struct notifier_block *this, unsigned long event, static struct notifier_block dn_fib_rules_notifier = { - dn_fib_rules_event, - NULL, - 0 + notifier_call: dn_fib_rules_event, }; #ifdef CONFIG_RTNETLINK diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index ce7a3ac06dc5..bc21acb4b472 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c @@ -78,7 +78,7 @@ static rwlock_t dn_fib_tables_lock = RW_LOCK_UNLOCKED; static struct dn_fib_table *dn_fib_tables[DN_NUM_TABLES + 1]; static kmem_cache_t *dn_hash_kmem; -static int dn_fib_hash_zombies = 0; +static int dn_fib_hash_zombies; static __inline__ dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz) { diff --git a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c index bbba58b028f4..41a4aa6025e2 100644 --- a/net/decnet/dn_timer.c +++ b/net/decnet/dn_timer.c @@ -52,7 +52,7 @@ void dn_stop_slow_timer(struct sock *sk) static void dn_slow_timer(unsigned long arg) { struct sock *sk = (struct sock *)arg; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); sock_hold(sk); bh_lock_sock(sk); @@ -112,7 +112,7 @@ out: static void dn_fast_timer(unsigned long arg) { struct sock *sk = (struct sock *)arg; - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); bh_lock_sock(sk); if (sk->lock.users != 0) { @@ -131,7 +131,7 @@ out: void dn_start_fast_timer(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (!scp->delack_pending) { scp->delack_pending = 1; @@ -145,7 +145,7 @@ void dn_start_fast_timer(struct sock *sk) void dn_stop_fast_timer(struct sock *sk) { - struct dn_scp *scp = &sk->protinfo.dn; + struct dn_scp *scp = DN_SK(sk); if (scp->delack_pending) { scp->delack_pending = 0; diff --git a/net/ipv4/netfilter/Config.in b/net/ipv4/netfilter/Config.in index 406d2ea3d482..5887658fb8d2 100644 --- a/net/ipv4/netfilter/Config.in +++ b/net/ipv4/netfilter/Config.in @@ -37,11 +37,20 @@ if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then fi if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then - dep_tristate ' Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES + dep_tristate ' Full NAT' CONFIG_IP_NF_NAT $CONFIG_IP_NF_IPTABLES $CONFIG_IP_NF_CONNTRACK if [ "$CONFIG_IP_NF_NAT" != "n" ]; then define_bool CONFIG_IP_NF_NAT_NEEDED y dep_tristate ' MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT + # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), + # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh. + if [ "$CONFIG_IP_NF_FTP" = "m" ]; then + define_tristate CONFIG_IP_NF_NAT_FTP m + else + if [ "$CONFIG_IP_NF_FTP" = "y" ]; then + define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT + fi + fi fi fi diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile index 995860767885..c40caa75e48e 100644 --- a/net/ipv4/netfilter/Makefile +++ b/net/ipv4/netfilter/Makefile @@ -35,7 +35,7 @@ obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o # NAT helpers -obj-$(CONFIG_IP_NF_FTP) += ip_nat_ftp.o +obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o # generic IP tables obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 2e4dd82ee0ad..bc7e64c8b28e 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -882,10 +882,15 @@ ip_ct_gather_frags(struct sk_buff *skb) #ifdef CONFIG_NETFILTER_DEBUG unsigned int olddebug = skb->nf_debug; #endif - if (sk) sock_hold(sk); + if (sk) { + sock_hold(sk); + skb_orphan(skb); + } + local_bh_disable(); skb = ip_defrag(skb); - local_bh_enable(); + local_bh_enable(); + if (!skb) { if (sk) sock_put(sk); return skb; diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c index 9c1088e768f3..cc5ffbc4a093 100644 --- a/net/ipv4/netfilter/ipt_REJECT.c +++ b/net/ipv4/netfilter/ipt_REJECT.c @@ -167,27 +167,9 @@ static unsigned int reject(struct sk_buff **pskb, case IPT_ICMP_HOST_PROHIBITED: icmp_send(*pskb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0); break; - case IPT_ICMP_ECHOREPLY: { - struct icmphdr *icmph = (struct icmphdr *) - ((u_int32_t *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl); - unsigned int datalen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4; - - /* Not non-head frags, or truncated */ - if (((ntohs((*pskb)->nh.iph->frag_off) & IP_OFFSET) == 0) - && datalen >= 4) { - /* Usually I don't like cut & pasting code, - but dammit, my party is starting in 45 - mins! --RR */ - struct icmp_bxm icmp_param; - - icmp_param.icmph=*icmph; - icmp_param.icmph.type=ICMP_ECHOREPLY; - icmp_param.data_ptr=(icmph+1); - icmp_param.data_len=datalen; - icmp_reply(&icmp_param, *pskb); - } - } - break; + case IPT_ICMP_ECHOREPLY: + printk("REJECT: ECHOREPLY no longer supported.\n"); + break; case IPT_TCP_RESET: send_reset(*pskb, hooknum == NF_IP_LOCAL_IN); break; diff --git a/net/ipv6/netfilter/Makefile b/net/ipv6/netfilter/Makefile index aec5db879f12..fcc9bc05848b 100644 --- a/net/ipv6/netfilter/Makefile +++ b/net/ipv6/netfilter/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_IP6_NF_MATCH_MARK) += ip6t_mark.o obj-$(CONFIG_IP6_NF_MATCH_MAC) += ip6t_mac.o obj-$(CONFIG_IP6_NF_MATCH_MULTIPORT) += ip6t_multiport.o obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o +obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o obj-$(CONFIG_IP6_NF_TARGET_MARK) += ip6t_MARK.o include $(TOPDIR)/Rules.make diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 57430f29f31d..659bb3a1e909 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -11,7 +11,7 @@ #include <linux/module.h> #include <linux/tcp.h> #include <linux/udp.h> -#include <linux/icmp.h> +#include <linux/icmpv6.h> #include <net/ip.h> #include <asm/uaccess.h> #include <asm/semaphore.h> @@ -1642,7 +1642,7 @@ udp_checkentry(const char *tablename, /* Returns 1 if the type and code is matched by the range, 0 otherwise */ static inline int -icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, +icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, u_int8_t type, u_int8_t code, int invert) { @@ -1651,7 +1651,7 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code, } static int -icmp_match(const struct sk_buff *skb, +icmp6_match(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *matchinfo, @@ -1660,7 +1660,7 @@ icmp_match(const struct sk_buff *skb, u_int16_t datalen, int *hotdrop) { - const struct icmphdr *icmp = hdr; + const struct icmp6hdr *icmp = hdr; const struct ip6t_icmp *icmpinfo = matchinfo; if (offset == 0 && datalen < 2) { @@ -1673,16 +1673,16 @@ icmp_match(const struct sk_buff *skb, /* Must not be a fragment. */ return !offset - && icmp_type_code_match(icmpinfo->type, + && icmp6_type_code_match(icmpinfo->type, icmpinfo->code[0], icmpinfo->code[1], - icmp->type, icmp->code, + icmp->icmp6_type, icmp->icmp6_code, !!(icmpinfo->invflags&IP6T_ICMP_INV)); } /* Called when user tries to insert an entry of this type. */ static int -icmp_checkentry(const char *tablename, +icmp6_checkentry(const char *tablename, const struct ip6t_ip6 *ipv6, void *matchinfo, unsigned int matchsize, @@ -1691,7 +1691,7 @@ icmp_checkentry(const char *tablename, const struct ip6t_icmp *icmpinfo = matchinfo; /* Must specify proto == ICMP, and no unknown invflags */ - return ipv6->proto == IPPROTO_ICMP + return ipv6->proto == IPPROTO_ICMPV6 && !(ipv6->invflags & IP6T_INV_PROTO) && matchsize == IP6T_ALIGN(sizeof(struct ip6t_icmp)) && !(icmpinfo->invflags & ~IP6T_ICMP_INV); @@ -1711,8 +1711,8 @@ static struct ip6t_match tcp_matchstruct = { { NULL, NULL }, "tcp", &tcp_match, &tcp_checkentry, NULL }; static struct ip6t_match udp_matchstruct = { { NULL, NULL }, "udp", &udp_match, &udp_checkentry, NULL }; -static struct ip6t_match icmp_matchstruct -= { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL }; +static struct ip6t_match icmp6_matchstruct += { { NULL, NULL }, "icmp6", &icmp6_match, &icmp6_checkentry, NULL }; #ifdef CONFIG_PROC_FS static inline int print_name(const struct ip6t_table *t, @@ -1761,7 +1761,7 @@ static int __init init(void) list_append(&ip6t_target, &ip6t_error_target); list_append(&ip6t_match, &tcp_matchstruct); list_append(&ip6t_match, &udp_matchstruct); - list_append(&ip6t_match, &icmp_matchstruct); + list_append(&ip6t_match, &icmp6_matchstruct); up(&ip6t_mutex); /* Register setsockopt */ diff --git a/net/ipv6/netfilter/ip6t_MARK.c b/net/ipv6/netfilter/ip6t_MARK.c index dd8bb322691c..08df336e811f 100644 --- a/net/ipv6/netfilter/ip6t_MARK.c +++ b/net/ipv6/netfilter/ip6t_MARK.c @@ -4,8 +4,8 @@ #include <linux/ip.h> #include <net/checksum.h> -#include <linux/netfilter_ipv4/ip_tables.h> -#include <linux/netfilter_ipv4/ipt_MARK.h> +#include <linux/netfilter_ipv6/ip6_tables.h> +#include <linux/netfilter_ipv6/ip6t_MARK.h> static unsigned int target(struct sk_buff **pskb, @@ -15,26 +15,26 @@ target(struct sk_buff **pskb, const void *targinfo, void *userinfo) { - const struct ipt_mark_target_info *markinfo = targinfo; + const struct ip6t_mark_target_info *markinfo = targinfo; if((*pskb)->nfmark != markinfo->mark) { (*pskb)->nfmark = markinfo->mark; (*pskb)->nfcache |= NFC_ALTERED; } - return IPT_CONTINUE; + return IP6T_CONTINUE; } static int checkentry(const char *tablename, - const struct ipt_entry *e, + const struct ip6t_entry *e, void *targinfo, unsigned int targinfosize, unsigned int hook_mask) { - if (targinfosize != IPT_ALIGN(sizeof(struct ipt_mark_target_info))) { + if (targinfosize != IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))) { printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n", targinfosize, - IPT_ALIGN(sizeof(struct ipt_mark_target_info))); + IP6T_ALIGN(sizeof(struct ip6t_mark_target_info))); return 0; } @@ -46,12 +46,13 @@ checkentry(const char *tablename, return 1; } -static struct ipt_target ipt_mark_reg +static struct ip6t_target ip6t_mark_reg = { { NULL, NULL }, "MARK", target, checkentry, NULL, THIS_MODULE }; static int __init init(void) { - if (ipt_register_target(&ipt_mark_reg)) + printk(KERN_DEBUG "registreing ipv6 mark target\n"); + if (ip6t_register_target(&ip6t_mark_reg)) return -EINVAL; return 0; @@ -59,7 +60,7 @@ static int __init init(void) static void __exit fini(void) { - ipt_unregister_target(&ipt_mark_reg); + ip6t_unregister_target(&ip6t_mark_reg); } module_init(init); diff --git a/net/ipv6/netfilter/ip6t_mark.c b/net/ipv6/netfilter/ip6t_mark.c index babe202a4e94..9a78b1ca269f 100644 --- a/net/ipv6/netfilter/ip6t_mark.c +++ b/net/ipv6/netfilter/ip6t_mark.c @@ -2,7 +2,7 @@ #include <linux/module.h> #include <linux/skbuff.h> -#include <linux/netfilter_ipv4/ipt_mark.h> +#include <linux/netfilter_ipv6/ip6t_mark.h> #include <linux/netfilter_ipv6/ip6_tables.h> static int @@ -15,7 +15,7 @@ match(const struct sk_buff *skb, u_int16_t datalen, int *hotdrop) { - const struct ipt_mark_info *info = matchinfo; + const struct ip6t_mark_info *info = matchinfo; return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; } @@ -27,7 +27,7 @@ checkentry(const char *tablename, unsigned int matchsize, unsigned int hook_mask) { - if (matchsize != IP6T_ALIGN(sizeof(struct ipt_mark_info))) + if (matchsize != IP6T_ALIGN(sizeof(struct ip6t_mark_info))) return 0; return 1; diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c new file mode 100644 index 000000000000..612c292c4668 --- /dev/null +++ b/net/ipv6/netfilter/ip6table_mangle.c @@ -0,0 +1,189 @@ +/* + * IPv6 packet mangling table, a port of the IPv4 mangle table to IPv6 + * + * Copyright (C) 2000 by Harald Welte <laforge@gnumonks.org> + */ +#include <linux/module.h> +#include <linux/netfilter_ipv6/ip6_tables.h> + +#define MANGLE_VALID_HOOKS ((1 << NF_IP6_PRE_ROUTING) | (1 << NF_IP6_LOCAL_OUT)) + +#if 1 +#define DEBUGP(x, args...) printk(KERN_DEBUG x, ## args) +#else +#define DEBUGP(x, args...) +#endif + +/* Standard entry. */ +struct ip6t_standard +{ + struct ip6t_entry entry; + struct ip6t_standard_target target; +}; + +struct ip6t_error_target +{ + struct ip6t_entry_target target; + char errorname[IP6T_FUNCTION_MAXNAMELEN]; +}; + +struct ip6t_error +{ + struct ip6t_entry entry; + struct ip6t_error_target target; +}; + +static struct +{ + struct ip6t_replace repl; + struct ip6t_standard entries[2]; + struct ip6t_error term; +} initial_table __initdata += { { "mangle", MANGLE_VALID_HOOKS, 3, + sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error), + { [NF_IP6_PRE_ROUTING] 0, + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) }, + { [NF_IP6_PRE_ROUTING] 0, + [NF_IP6_LOCAL_OUT] sizeof(struct ip6t_standard) }, + 0, NULL, { } }, + { + /* PRE_ROUTING */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_standard), + 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } }, + /* LOCAL_OUT */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_standard), + 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_standard_target)), "" } }, { } }, + -NF_ACCEPT - 1 } } + }, + /* ERROR */ + { { { { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, { { { 0 } } }, "", "", { 0 }, { 0 }, 0, 0, 0 }, + 0, + sizeof(struct ip6t_entry), + sizeof(struct ip6t_error), + 0, { 0, 0 }, { } }, + { { { { IP6T_ALIGN(sizeof(struct ip6t_error_target)), IP6T_ERROR_TARGET } }, + { } }, + "ERROR" + } + } +}; + +static struct ip6t_table packet_mangler += { { NULL, NULL }, "mangle", &initial_table.repl, + MANGLE_VALID_HOOKS, RW_LOCK_UNLOCKED, NULL }; + +/* The work comes in here from netfilter.c. */ +static unsigned int +ip6t_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + return ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL); +} + +static unsigned int +ip6t_local_out_hook(unsigned int hook, + struct sk_buff **pskb, + const struct net_device *in, + const struct net_device *out, + int (*okfn)(struct sk_buff *)) +{ + + unsigned long nfmark; + unsigned int ret; + struct in6_addr saddr, daddr; + u_int8_t hop_limit; + u_int32_t flowlabel; + +#if 0 + /* root is playing with raw sockets. */ + if ((*pskb)->len < sizeof(struct iphdr) + || (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr)) { + if (net_ratelimit()) + printk("ip6t_hook: happy cracking.\n"); + return NF_ACCEPT; + } +#endif + + /* save source/dest address, nfmark, hoplimit, flowlabel, priority, */ + memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr)); + memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr)); + nfmark = (*pskb)->nfmark; + hop_limit = (*pskb)->nh.ipv6h->hop_limit; + + /* flowlabel and prio (includes version, which shouldn't change either */ + flowlabel = (u_int32_t) (*pskb)->nh.ipv6h; + + ret = ip6t_do_table(pskb, hook, in, out, &packet_mangler, NULL); + + if (ret != NF_DROP && ret != NF_STOLEN + && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr)) + || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr)) + || (*pskb)->nfmark != nfmark + || (*pskb)->nh.ipv6h->hop_limit != hop_limit)) { + + /* something which could affect routing has changed */ + + DEBUGP("ip6table_mangle: we'd need to re-route a packet\n"); + } + + return ret; +} + +static struct nf_hook_ops ip6t_ops[] += { { { NULL, NULL }, ip6t_hook, PF_INET6, NF_IP6_PRE_ROUTING, NF_IP6_PRI_MANGLE }, + { { NULL, NULL }, ip6t_local_out_hook, PF_INET6, NF_IP6_LOCAL_OUT, + NF_IP6_PRI_MANGLE } +}; + +static int __init init(void) +{ + int ret; + + /* Register table */ + ret = ip6t_register_table(&packet_mangler); + if (ret < 0) + return ret; + + /* Register hooks */ + ret = nf_register_hook(&ip6t_ops[0]); + if (ret < 0) + goto cleanup_table; + + ret = nf_register_hook(&ip6t_ops[1]); + if (ret < 0) + goto cleanup_hook0; + + return ret; + + cleanup_hook0: + nf_unregister_hook(&ip6t_ops[0]); + cleanup_table: + ip6t_unregister_table(&packet_mangler); + + return ret; +} + +static void __exit fini(void) +{ + unsigned int i; + + for (i = 0; i < sizeof(ip6t_ops)/sizeof(struct nf_hook_ops); i++) + nf_unregister_hook(&ip6t_ops[i]); + + ip6t_unregister_table(&packet_mangler); +} + +module_init(init); +module_exit(fini); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 26cc633483e2..fb73651bf2a3 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -61,6 +61,9 @@ * suggestions and guidance. * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, * November, 2000 + * Revision 043: Shared SKBs, don't mangle packets, some cleanups + * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, + * December, 2000 * * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT * pair. Also, now usage count is managed this way @@ -140,28 +143,23 @@ static ipx_interface *ipx_internal_net; atomic_t ipx_sock_nr; #endif -static int ipxcfg_set_auto_create(char val) +static void ipxcfg_set_auto_create(char val) { - if(ipxcfg_auto_create_interfaces != val) - { - if(val) + if (ipxcfg_auto_create_interfaces != val) { + if (val) MOD_INC_USE_COUNT; else MOD_DEC_USE_COUNT; ipxcfg_auto_create_interfaces = val; } - - return (0); } -static int ipxcfg_set_auto_select(char val) +static void ipxcfg_set_auto_select(char val) { ipxcfg_auto_select_primary = val; - if(val && (ipx_primary_net == NULL)) + if (val && !ipx_primary_net) ipx_primary_net = ipx_interfaces; - - return (0); } static int ipxcfg_get_config_data(ipx_config_data *arg) @@ -171,7 +169,7 @@ static int ipxcfg_get_config_data(ipx_config_data *arg) vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces; vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary; - return (copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0); + return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0; } /**************************************************************************\ @@ -213,22 +211,19 @@ void ipx_remove_socket(struct sock *sk) /* Determine interface with which socket is associated */ intrfc = sk->protinfo.af_ipx.intrfc; - if(intrfc == NULL) + if (!intrfc) return; ipxitf_hold(intrfc); spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; - if(s == sk) - { + if (s == sk) { intrfc->if_sklist = s->next; goto out; } - while(s && s->next) - { - if(s->next == sk) - { + while (s && s->next) { + if (s->next == sk) { s->next = sk->next; goto out; } @@ -264,7 +259,7 @@ static ipx_route * ipxrtr_lookup(__u32); static void ipxitf_clear_primary_net(void) { - if(ipxcfg_auto_select_primary && (ipx_interfaces != NULL)) + if (ipxcfg_auto_select_primary && ipx_interfaces) ipx_primary_net = ipx_interfaces; else ipx_primary_net = NULL; @@ -273,14 +268,14 @@ static void ipxitf_clear_primary_net(void) static ipx_interface *__ipxitf_find_using_phys(struct net_device *dev, unsigned short datalink) { - ipx_interface *i; + ipx_interface *i; - for(i = ipx_interfaces; - i && ((i->if_dev != dev) || (i->if_dlink_type != datalink)); + for (i = ipx_interfaces; + i && (i->if_dev != dev || i->if_dlink_type != datalink); i = i->if_next) ; - return (i); + return i; } static ipx_interface *ipxitf_find_using_phys(struct net_device *dev, @@ -298,12 +293,12 @@ static ipx_interface *ipxitf_find_using_phys(struct net_device *dev, static ipx_interface *ipxitf_find_using_net(__u32 net) { - ipx_interface *i; + ipx_interface *i; spin_lock_bh(&ipx_interfaces_lock); - if(net) - for(i = ipx_interfaces; i && (i->if_netnum != net); - i = i->if_next) + if (net) + for (i = ipx_interfaces; i && i->if_netnum != net; + i = i->if_next) ; else i = ipx_primary_net; @@ -311,7 +306,7 @@ static ipx_interface *ipxitf_find_using_net(__u32 net) ipxitf_hold(i); spin_unlock_bh(&ipx_interfaces_lock); - return (i); + return i; } /* Sockets are bound to a particular IPX interface. */ @@ -324,11 +319,10 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) spin_lock_bh(&intrfc->if_sklist_lock); sk->protinfo.af_ipx.intrfc = intrfc; sk->next = NULL; - if(intrfc->if_sklist == NULL) + if (!intrfc->if_sklist) intrfc->if_sklist = sk; - else - { - for (s = intrfc->if_sklist; s->next != NULL; s = s->next) + else { + for (s = intrfc->if_sklist; s->next; s = s->next) ; s->next = sk; } @@ -337,19 +331,21 @@ static void ipxitf_insert_socket(ipx_interface *intrfc, struct sock *sk) } /* caller must hold intrfc->if_sklist_lock */ -static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, unsigned short port) +static struct sock *__ipxitf_find_socket(ipx_interface *intrfc, + unsigned short port) { struct sock *s; - for(s = intrfc->if_sklist; - (s != NULL) && (s->protinfo.af_ipx.port != port); - s = s->next) + for (s = intrfc->if_sklist; + s && s->protinfo.af_ipx.port != port; + s = s->next) ; return s; } /* caller must hold a reference to intrfc */ -static struct sock *ipxitf_find_socket(ipx_interface *intrfc, unsigned short port) +static struct sock *ipxitf_find_socket(ipx_interface *intrfc, + unsigned short port) { struct sock *s; @@ -359,11 +355,10 @@ static struct sock *ipxitf_find_socket(ipx_interface *intrfc, unsigned short por sock_hold(s); spin_unlock_bh(&intrfc->if_sklist_lock); - return (s); + return s; } #ifdef CONFIG_IPX_INTERN - static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, unsigned char *node, unsigned short port) { @@ -373,19 +368,16 @@ static struct sock *ipxitf_find_internal_socket(ipx_interface *intrfc, spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; - while(s != NULL) - { - if((s->protinfo.af_ipx.port == port) - && (memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0)) - { + while (s) { + if (s->protinfo.af_ipx.port == port && + !memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN)) break; - } s = s->next; } spin_unlock_bh(&intrfc->if_sklist_lock); ipxitf_put(intrfc); - return (s); + return s; } #endif @@ -401,8 +393,7 @@ static void __ipxitf_down(ipx_interface *intrfc) spin_lock_bh(&intrfc->if_sklist_lock); /* error sockets */ - for(s = intrfc->if_sklist; s != NULL; ) - { + for (s = intrfc->if_sklist; s; ) { s->err = ENOLINK; s->error_report(s); s->protinfo.af_ipx.intrfc = NULL; @@ -416,30 +407,27 @@ static void __ipxitf_down(ipx_interface *intrfc) spin_unlock_bh(&intrfc->if_sklist_lock); /* remove this interface from list */ - if(intrfc == ipx_interfaces) + if (intrfc == ipx_interfaces) ipx_interfaces = intrfc->if_next; - else - { - for(i = ipx_interfaces; - (i != NULL) && (i->if_next != intrfc); - i = i->if_next) + else { + for (i = ipx_interfaces; + i && i->if_next != intrfc; + i = i->if_next) ; - if((i != NULL) && (i->if_next == intrfc)) + if (i && i->if_next == intrfc) i->if_next = intrfc->if_next; } /* remove this interface from *special* networks */ - if(intrfc == ipx_primary_net) + if (intrfc == ipx_primary_net) ipxitf_clear_primary_net(); - if(intrfc == ipx_internal_net) + if (intrfc == ipx_internal_net) ipx_internal_net = NULL; if (intrfc->if_dev) dev_put(intrfc->if_dev); kfree(intrfc); MOD_DEC_USE_COUNT; - - return; } static void ipxitf_down(ipx_interface *intrfc) @@ -449,36 +437,31 @@ static void ipxitf_down(ipx_interface *intrfc) spin_unlock_bh(&ipx_interfaces_lock); } -static int ipxitf_device_event(struct notifier_block *notifier, unsigned long event, void *ptr) +static int ipxitf_device_event(struct notifier_block *notifier, + unsigned long event, void *ptr) { struct net_device *dev = ptr; ipx_interface *i, *tmp; - if(event != NETDEV_DOWN) + if (event != NETDEV_DOWN) return NOTIFY_DONE; spin_lock_bh(&ipx_interfaces_lock); - for(i = ipx_interfaces; i != NULL;) - { + for (i = ipx_interfaces; i;) { tmp = i->if_next; - if(i->if_dev == dev) + if (i->if_dev == dev) __ipxitf_put(i); i = tmp; } spin_unlock_bh(&ipx_interfaces_lock); - - return (NOTIFY_DONE); + return NOTIFY_DONE; } -static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) +static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb) { - int retval; - - if((retval = sock_queue_rcv_skb(sock, skb)) < 0) + if (sock_queue_rcv_skb(sock, skb) < 0) kfree_skb(skb); - - return (retval); } /* @@ -500,57 +483,50 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c spin_lock_bh(&intrfc->if_sklist_lock); s = intrfc->if_sklist; - while(s != NULL) - { - if((s->protinfo.af_ipx.port == ipx->ipx_dest.sock) - && (is_broadcast - || (memcmp(ipx->ipx_dest.node, s->protinfo.af_ipx.node, - IPX_NODE_LEN) == 0))) - { + while (s) { + if (s->protinfo.af_ipx.port == ipx->ipx_dest.sock && + (is_broadcast || !memcmp(ipx->ipx_dest.node, + s->protinfo.af_ipx.node, + IPX_NODE_LEN))) { /* We found a socket to which to send */ struct sk_buff *skb1; - if(copy != 0) - { + if (copy) { skb1 = skb_clone(skb, GFP_ATOMIC); ret = -ENOMEM; - if (skb1 == NULL) + if (!skb1) goto out; - } - else - { + } else { skb1 = skb; copy = 1; /* skb may only be used once */ } ipxitf_def_skb_handler(s, skb1); /* On an external interface, one socket can listen */ - if(intrfc != ipx_internal_net) + if (intrfc != ipx_internal_net) break; } s = s->next; } /* skb was solely for us, and we did not make a copy, so free it. */ - if(copy == 0) + if (!copy) kfree_skb(skb); ret = 0; out: spin_unlock_bh(&intrfc->if_sklist_lock); return ret; } - #else - -static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy) +static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, + int copy) { struct ipxhdr *ipx = skb->nh.ipxh; struct sock *sock1 = NULL, *sock2 = NULL; struct sk_buff *skb1 = NULL, *skb2 = NULL; int ret; - if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) - { + if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451) { /* * The packet's target is a NCP connection handler. We want to * hand it to the correct socket directly within the kernel, @@ -562,48 +538,34 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * VERY fast as well. */ int connection = 0; - - if (*((char*)(ipx+1)) == 0x22 && *((char*)(ipx+1)+1) == 0x22) - { - /* - * The packet is a NCP request - */ - connection = ( ((int) *((char*)(ipx+1)+5)) << 8 ) - | (int) *((char*)(ipx+1)+3); - } - else if (*((char*)(ipx+1))== 0x77 && *((char*)(ipx+1)+1) == 0x77) - { - /* - * The packet is a BURST packet - */ - connection = ( ((int) *((char*)(ipx+1)+9)) << 8 ) - | (int) *((char*)(ipx+1)+8); - } - - if (connection) - { - /* - * Now we have to look for a special NCP connection handling - * socket. Only these sockets have ipx_ncp_conn != 0, set - * by SIOCIPXNCPCONN. - */ + u8 *ncphdr = (u8 *)(ipx + 1); + + if (*ncphdr == 0x22 && *(ncphdr + 1) == 0x22) + /* The packet is a NCP request */ + connection = (((int) *(ncphdr + 5)) << 8) | + (int) *(ncphdr+3); + else if (*ncphdr == 0x77 && *(ncphdr + 1) == 0x77) + /* The packet is a BURST packet */ + connection = (((int) *(ncphdr+9)) << 8) | + (int) *(ncphdr+8); + + if (connection) { + /* Now we have to look for a special NCP connection + * handling socket. Only these sockets have + * ipx_ncp_conn != 0, set by SIOCIPXNCPCONN. */ spin_lock_bh(&intrfc->if_sklist_lock); - for (sock1=intrfc->if_sklist; - (sock1 != NULL) && - (sock1->protinfo.af_ipx.ipx_ncp_conn != connection); - sock1=sock1->next); + for (sock1 = intrfc->if_sklist; + sock1 && + sock1->protinfo.af_ipx.ipx_ncp_conn != connection; + sock1 = sock1->next); if (sock1) sock_hold(sock1); spin_unlock_bh(&intrfc->if_sklist_lock); } } - if (sock1 == NULL) - { - /* No special socket found, forward the packet the - * normal way. - */ + if (!sock1) + /* No special socket found, forward the packet the normal way */ sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock); - } /* * We need to check if there is a primary net and if @@ -613,10 +575,8 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * 0x456(Diagnostic). */ - if(ipx_primary_net && (intrfc != ipx_primary_net)) - { - switch(ntohs(ipx->ipx_dest.sock)) - { + if (ipx_primary_net && intrfc != ipx_primary_net) { + switch (ntohs(ipx->ipx_dest.sock)) { case 0x452: case 0x453: case 0x456: @@ -637,11 +597,10 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c /* * If there is nothing to do return. The kfree will cancel any charging. */ - if(sock1 == NULL && sock2 == NULL) - { - if(!copy) + if (!sock1 && !sock2) { + if (!copy) kfree_skb(skb); - return (0); + return 0; } /* @@ -652,30 +611,30 @@ static int ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int c * copies, we do as much as is possible. */ - if(copy) + if (copy) skb1 = skb_clone(skb, GFP_ATOMIC); else skb1 = skb; ret = -ENOMEM; - if(skb1 == NULL) + if (!skb1) goto out; /* Do we need 2 SKBs? */ - if(sock1 && sock2) + if (sock1 && sock2) skb2 = skb_clone(skb1, GFP_ATOMIC); else skb2 = skb1; - if(sock1) - (void) ipxitf_def_skb_handler(sock1, skb1); + if (sock1) + ipxitf_def_skb_handler(sock1, skb1); ret = -ENOMEM; - if(skb2 == NULL) + if (!skb2) goto out; - if(sock2) - (void) ipxitf_def_skb_handler(sock2, skb2); + if (sock2) + ipxitf_def_skb_handler(sock2, skb2); ret = 0; out: if (sock1) @@ -686,7 +645,8 @@ out: if (sock1) } #endif /* CONFIG_IPX_INTERN */ -static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb) +static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, + struct sk_buff *skb) { struct sk_buff *skb2; int in_offset = skb->h.raw - skb->head; @@ -694,21 +654,21 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buf int len; /* Hopefully, most cases */ - if(in_offset >= out_offset) - return (skb); + if (in_offset >= out_offset) + return skb; /* Need new SKB */ len = skb->len + out_offset; skb2 = alloc_skb(len, GFP_ATOMIC); - if(skb2 != NULL) - { + if (skb2) { skb_reserve(skb2, out_offset); skb2->nh.raw = skb2->h.raw = skb_put(skb2,skb->len); memcpy(skb2->h.raw, skb->h.raw, skb->len); + memcpy(skb2->cb, skb->cb, sizeof(skb->cb)); } kfree_skb(skb); - return (skb2); + return skb2; } /* caller must hold a reference to intrfc */ @@ -716,6 +676,7 @@ static struct sk_buff *ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buf static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) { struct ipxhdr *ipx = skb->nh.ipxh; + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; struct net_device *dev = intrfc->if_dev; struct datalink_proto *dl = intrfc->if_dlink; char dest_node[IPX_NODE_LEN]; @@ -727,7 +688,7 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) * packet to avoid unnecessary copies. */ - if((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK)) + if (!dl || !dev || dev->flags & IFF_LOOPBACK) send_to_wire = 0; /* No non looped */ /* @@ -737,30 +698,27 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) * up clones. */ - if(ipx->ipx_dest.net == intrfc->if_netnum) - { + if (cb->ipx_dest_net == intrfc->if_netnum) { /* * To our own node, loop and free the original. * The internal net will receive on all node address. */ - if((intrfc == ipx_internal_net) - || memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0) - { + if (intrfc == ipx_internal_net || + !memcmp(intrfc->if_node, node, IPX_NODE_LEN)) { /* Don't charge sender */ skb_orphan(skb); /* Will charge receiver */ - return (ipxitf_demux_socket(intrfc, skb, 0)); + return ipxitf_demux_socket(intrfc, skb, 0); } /* Broadcast, loop and possibly keep to send on. */ - if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) - { - if(!send_to_wire) + if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) { + if (!send_to_wire) skb_orphan(skb); ipxitf_demux_socket(intrfc, skb, send_to_wire); - if(!send_to_wire) - return (0); + if (!send_to_wire) + return 0; } } @@ -769,36 +727,45 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) * We are still charging the sender. Which is right - the driver * free will handle this fairly. */ - if(ipx->ipx_source.net != intrfc->if_netnum) - { + if (cb->ipx_source_net != intrfc->if_netnum) { /* * Unshare the buffer before modifying the count in * case its a flood or tcpdump */ skb = skb_unshare(skb, GFP_ATOMIC); - if(!skb) - return (0); - if(++(ipx->ipx_tctrl) > ipxcfg_max_hops) + if (!skb) + return 0; + if (++(cb->ipx_tctrl) > ipxcfg_max_hops) send_to_wire = 0; } - if(!send_to_wire) - { + if (!send_to_wire) { kfree_skb(skb); - return (0); + return 0; } /* Determine the appropriate hardware address */ addr_len = dev->addr_len; - if(memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0) + if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) memcpy(dest_node, dev->broadcast, addr_len); else memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len); /* Make any compensation for differing physical/data link size */ skb = ipxitf_adjust_skbuff(intrfc, skb); - if(skb == NULL) - return (0); + if (!skb) + return 0; + + ipx->ipx_tctrl = cb->ipx_tctrl; + ipx->ipx_dest.net = cb->ipx_dest_net; + ipx->ipx_source.net = cb->ipx_source_net; + /* see if we need to include the netnum in the route list */ + if (cb->last_hop_index >= 0) { + u32 *last_hop = (u32 *)(((u8 *) skb->data) + + sizeof(struct ipxhdr) + cb->last_hop_index * + sizeof(u32)); + *last_hop = intrfc->if_netnum; + } /* set up data link and physical headers */ skb->dev = dev; @@ -807,15 +774,14 @@ static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node) /* Send it out */ dev_queue_xmit(skb); - - return (0); + return 0; } static int ipxrtr_add_route(__u32, ipx_interface *, unsigned char *); static int ipxitf_add_local_route(ipx_interface *intrfc) { - return (ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL)); + return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL); } static const char * ipx_frame_name(unsigned short); @@ -824,29 +790,26 @@ static const char * ipx_device_name(ipx_interface *); static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) { struct ipxhdr *ipx = skb->nh.ipxh; - ipx_interface *i; + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; int ret = 0; ipxitf_hold(intrfc); /* See if we should update our network number */ - if(!intrfc->if_netnum /* net number of intrfc not known yet (== 0) */ - && (ipx->ipx_source.net == ipx->ipx_dest.net) /* intra packet */ - && ipx->ipx_source.net) /* source net number of packet != 0 */ - { + if (!intrfc->if_netnum && /* net number of intrfc not known yet */ + cb->ipx_source_net == cb->ipx_dest_net && /* intra packet */ + cb->ipx_source_net) { + ipx_interface *i = ipxitf_find_using_net(cb->ipx_source_net); /* NB: NetWare servers lie about their hop count so we * dropped the test based on it. This is the best way * to determine this is a 0 hop count packet. */ - if((i=ipxitf_find_using_net(ipx->ipx_source.net)) == NULL) - { - intrfc->if_netnum = ipx->ipx_source.net; - (void) ipxitf_add_local_route(intrfc); - } - else - { + if (!i) { + intrfc->if_netnum = cb->ipx_source_net; + ipxitf_add_local_route(intrfc); + } else { printk(KERN_WARNING "IPX: Network number collision %lx\n %s %s and %s %s\n", - (long unsigned int) htonl(ipx->ipx_source.net), + (long unsigned int) htonl(cb->ipx_source_net), ipx_device_name(i), ipx_frame_name(i->if_dlink_type), ipx_device_name(intrfc), @@ -854,75 +817,63 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) ipxitf_put(i); } } + + cb->last_hop_index = -1; - if(ipx->ipx_type == IPX_TYPE_PPROP - && ipx->ipx_tctrl < 8 - && skb->pkt_type != PACKET_OTHERHOST - /* header + 8 network numbers */ - && ntohs(ipx->ipx_pktsize) >= sizeof(struct ipxhdr) + 8 * 4) - { + if (ipx->ipx_type == IPX_TYPE_PPROP && cb->ipx_tctrl < 8 && + skb->pkt_type != PACKET_OTHERHOST && + /* header + 8 network numbers */ + ntohs(ipx->ipx_pktsize) >= sizeof(struct ipxhdr) + 8 * 4) { int i; ipx_interface *ifcs; struct sk_buff *skb2; - __u32 *l; - char *c; - - c = (char *) skb->data; - c += sizeof(struct ipxhdr); - l = (__u32 *) c; - - i = 0; + char *c = ((char *) skb->data) + sizeof(struct ipxhdr); + u32 *l = (u32 *) c; /* Dump packet if already seen this net */ - for( ; i < ipx->ipx_tctrl; i++) - if(*l++ == intrfc->if_netnum) + for (i = 0; i < cb->ipx_tctrl; i++) + if (*l++ == intrfc->if_netnum) break; - if(i == ipx->ipx_tctrl) - { + if (i == cb->ipx_tctrl) { /* < 8 hops && input itfc not in list */ - *l = intrfc->if_netnum; /* insert recvd netnum into list */ - ipx->ipx_tctrl++; + /* insert recvd netnum into list */ + cb->last_hop_index = i; + cb->ipx_tctrl++; /* xmit on all other interfaces... */ spin_lock_bh(&ipx_interfaces_lock); - for(ifcs = ipx_interfaces; ifcs != NULL; ifcs = ifcs->if_next) - { + for (ifcs = ipx_interfaces; ifcs; + ifcs = ifcs->if_next) { /* Except unconfigured interfaces */ - if(ifcs->if_netnum == 0) + if (!ifcs->if_netnum) continue; /* That aren't in the list */ l = (__u32 *) c; - for(i = 0; i <= ipx->ipx_tctrl; i++) - if(ifcs->if_netnum == *l++) + for (i = 0; i <= cb->ipx_tctrl; i++) + if (ifcs->if_netnum == *l++) break; - if(i - 1 == ipx->ipx_tctrl) - { - ipx->ipx_dest.net = ifcs->if_netnum; + if (i - 1 == cb->ipx_tctrl) { + cb->ipx_dest_net = ifcs->if_netnum; skb2=skb_clone(skb, GFP_ATOMIC); if (skb2) ipxrtr_route_skb(skb2); } } spin_unlock_bh(&ipx_interfaces_lock); - - /* Reset network number in packet */ - ipx->ipx_dest.net = intrfc->if_netnum; } } - if(!ipx->ipx_dest.net) - ipx->ipx_dest.net = intrfc->if_netnum; - if(!ipx->ipx_source.net) - ipx->ipx_source.net = intrfc->if_netnum; + if (!cb->ipx_dest_net) + cb->ipx_dest_net = intrfc->if_netnum; + if (!cb->ipx_source_net) + cb->ipx_source_net = intrfc->if_netnum; - if(intrfc->if_netnum != ipx->ipx_dest.net) - { + if (intrfc->if_netnum != cb->ipx_dest_net) { /* We only route point-to-point packets. */ - if(skb->pkt_type == PACKET_HOST) - { + if (skb->pkt_type == PACKET_HOST) { skb=skb_unshare(skb, GFP_ATOMIC); - if(skb) + if (skb) ret = ipxrtr_route_skb(skb); goto out_intrfc; } @@ -931,9 +882,8 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } /* see if we should keep it */ - if((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0) - || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)) - { + if (!memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) || + !memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN)) { ret = ipxitf_demux_socket(intrfc, skb, 0); goto out_intrfc; } @@ -952,20 +902,17 @@ static void ipxitf_insert(ipx_interface *intrfc) intrfc->if_next = NULL; spin_lock_bh(&ipx_interfaces_lock); - if(ipx_interfaces == NULL) + if (!ipx_interfaces) ipx_interfaces = intrfc; - else - { - for(i = ipx_interfaces; i->if_next != NULL; i = i->if_next) + else { + for (i = ipx_interfaces; i->if_next; i = i->if_next) ; i->if_next = intrfc; } spin_unlock_bh(&ipx_interfaces_lock); - if(ipxcfg_auto_select_primary && (ipx_primary_net == NULL)) + if (ipxcfg_auto_select_primary && !ipx_primary_net) ipx_primary_net = intrfc; - - return; } static int ipxitf_create_internal(ipx_interface_definition *idef) @@ -974,21 +921,21 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) int ret; /* Only one primary network allowed */ - if(ipx_primary_net != NULL) - return (-EEXIST); + if (ipx_primary_net) + return -EEXIST; /* Must have a valid network number */ - if(!idef->ipx_network) - return (-EADDRNOTAVAIL); + if (!idef->ipx_network) + return -EADDRNOTAVAIL; intrfc = ipxitf_find_using_net(idef->ipx_network); - if(intrfc != NULL) { + if (intrfc) { ipxitf_put(intrfc); - return (-EADDRINUSE); + return -EADDRINUSE; } - intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if(intrfc == NULL) - return (-EAGAIN); + intrfc = kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + if (!intrfc) + return -EAGAIN; intrfc->if_dev = NULL; intrfc->if_netnum = idef->ipx_network; intrfc->if_dlink_type = 0; @@ -998,8 +945,7 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) intrfc->if_ipx_offset = 0; intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN); - ipx_internal_net = intrfc; - ipx_primary_net = intrfc; + ipx_internal_net = ipx_primary_net = intrfc; spin_lock_init(&intrfc->if_sklist_lock); atomic_set(&intrfc->refcnt, 1); MOD_INC_USE_COUNT; @@ -1013,22 +959,21 @@ static int ipxitf_create_internal(ipx_interface_definition *idef) static int ipx_map_frame_type(unsigned char type) { - switch(type) - { + switch (type) { case IPX_FRAME_ETHERII: - return (htons(ETH_P_IPX)); + return htons(ETH_P_IPX); case IPX_FRAME_8022: - return (htons(ETH_P_802_2)); + return htons(ETH_P_802_2); case IPX_FRAME_SNAP: - return (htons(ETH_P_SNAP)); + return htons(ETH_P_SNAP); case IPX_FRAME_8023: - return (htons(ETH_P_802_3)); + return htons(ETH_P_802_3); } - return (0); + return 0; } static int ipxitf_create(ipx_interface_definition *idef) @@ -1039,29 +984,29 @@ static int ipxitf_create(ipx_interface_definition *idef) ipx_interface *intrfc; int err; - if(idef->ipx_special == IPX_INTERNAL) - return (ipxitf_create_internal(idef)); + if (idef->ipx_special == IPX_INTERNAL) + return ipxitf_create_internal(idef); - if((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL)) - return (-EEXIST); + if (idef->ipx_special == IPX_PRIMARY && ipx_primary_net) + return -EEXIST; intrfc = ipxitf_find_using_net(idef->ipx_network); - if(idef->ipx_network && intrfc != NULL) { + if (idef->ipx_network && intrfc) { ipxitf_put(intrfc); - return (-EADDRINUSE); + return -EADDRINUSE; } if (intrfc) ipxitf_put(intrfc); dev = dev_get_by_name(idef->ipx_device); - if(dev == NULL) - return (-ENODEV); + if (!dev) + return -ENODEV; - switch(idef->ipx_dlink_type) - { + switch (idef->ipx_dlink_type) { case IPX_FRAME_TR_8022: - printk("IPX frame type 802.2TR is obsolete. Use 802.2 instead.\n"); + printk(KERN_WARNING "IPX frame type 802.2TR is " + "obsolete Use 802.2 instead.\n"); /* fall through */ case IPX_FRAME_8022: @@ -1070,14 +1015,14 @@ static int ipxitf_create(ipx_interface_definition *idef) break; case IPX_FRAME_ETHERII: - if (dev->type != ARPHRD_IEEE802) - { + if (dev->type != ARPHRD_IEEE802) { dlink_type = htons(ETH_P_IPX); datalink = pEII_datalink; break; - } - else - printk("IPX frame type EtherII over token-ring is obsolete. Use SNAP instead.\n"); + } else + printk(KERN_WARNING "IPX frame type EtherII " + "over token-ring is obsolete. Use SNAP " + "instead.\n"); /* fall through */ case IPX_FRAME_SNAP: @@ -1096,24 +1041,24 @@ static int ipxitf_create(ipx_interface_definition *idef) } err = -ENETDOWN; - if(!(dev->flags & IFF_UP)) + if (!(dev->flags & IFF_UP)) goto out_dev; /* Check addresses are suitable */ err = -EINVAL; - if(dev->addr_len > IPX_NODE_LEN) + if (dev->addr_len > IPX_NODE_LEN) goto out_dev; err = -EPROTONOSUPPORT; - if(datalink == NULL) + if (!datalink) goto out_dev; - if((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) - { + intrfc = ipxitf_find_using_phys(dev, dlink_type); + if (!intrfc) { /* Ok now create */ - intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); + intrfc = kmalloc(sizeof(ipx_interface), GFP_ATOMIC); err = -EAGAIN; - if(intrfc == NULL) + if (!intrfc) goto out_dev; intrfc->if_dev = dev; intrfc->if_netnum = idef->ipx_network; @@ -1122,17 +1067,16 @@ static int ipxitf_create(ipx_interface_definition *idef) intrfc->if_sklist = NULL; intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET; /* Setup primary if necessary */ - if((idef->ipx_special == IPX_PRIMARY)) + if ((idef->ipx_special == IPX_PRIMARY)) ipx_primary_net = intrfc; intrfc->if_internal = 0; intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length; - if(memcmp(idef->ipx_node, "\000\000\000\000\000\000", IPX_NODE_LEN) == 0) - { + if (!memcmp(idef->ipx_node, "\000\000\000\000\000\000", + IPX_NODE_LEN)) { memset(intrfc->if_node, 0, IPX_NODE_LEN); memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), dev->dev_addr, dev->addr_len); - } - else + } else memcpy(intrfc->if_node, idef->ipx_node, IPX_NODE_LEN); spin_lock_init(&intrfc->if_sklist_lock); atomic_set(&intrfc->refcnt, 1); @@ -1144,7 +1088,7 @@ static int ipxitf_create(ipx_interface_definition *idef) /* If the network number is known, add a route */ err = 0; - if(!intrfc->if_netnum) + if (!intrfc->if_netnum) goto out_intrfc; err = ipxitf_add_local_route(intrfc); @@ -1164,10 +1108,8 @@ static int ipxitf_delete(ipx_interface_definition *idef) int ret = 0; spin_lock_bh(&ipx_interfaces_lock); - if(idef->ipx_special == IPX_INTERNAL) - { - if(ipx_internal_net != NULL) - { + if (idef->ipx_special == IPX_INTERNAL) { + if (ipx_internal_net) { __ipxitf_put(ipx_internal_net); goto out; } @@ -1176,19 +1118,19 @@ static int ipxitf_delete(ipx_interface_definition *idef) } dlink_type = ipx_map_frame_type(idef->ipx_dlink_type); - if(dlink_type == 0) { + if (!dlink_type) { ret = -EPROTONOSUPPORT; goto out; } dev = __dev_get_by_name(idef->ipx_device); - if(dev == NULL) { + if (!dev) { ret = -ENODEV; goto out; } intrfc = __ipxitf_find_using_phys(dev, dlink_type); - if(intrfc != NULL) + if (intrfc) __ipxitf_put(intrfc); else ret = -EINVAL; @@ -1198,13 +1140,12 @@ out: spin_unlock_bh(&ipx_interfaces_lock); } static ipx_interface *ipxitf_auto_create(struct net_device *dev, - unsigned short dlink_type) + unsigned short dlink_type) { struct datalink_proto *datalink = NULL; ipx_interface *intrfc; - switch(htons(dlink_type)) - { + switch (htons(dlink_type)) { case ETH_P_IPX: datalink = pEII_datalink; break; @@ -1222,19 +1163,18 @@ static ipx_interface *ipxitf_auto_create(struct net_device *dev, break; default: - return (NULL); + return NULL; } - if(dev == NULL) - return (NULL); + if (!dev) + return NULL; /* Check addresses are suitable */ - if(dev->addr_len>IPX_NODE_LEN) - return (NULL); + if (dev->addr_len > IPX_NODE_LEN) + return NULL; - intrfc = (ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC); - if(intrfc != NULL) - { + intrfc = kmalloc(sizeof(ipx_interface), GFP_ATOMIC); + if (intrfc) { intrfc->if_dev = dev; intrfc->if_netnum = 0; intrfc->if_dlink_type = dlink_type; @@ -1253,27 +1193,25 @@ static ipx_interface *ipxitf_auto_create(struct net_device *dev, ipxitf_insert(intrfc); } - return (intrfc); + return intrfc; } static int ipxitf_ioctl(unsigned int cmd, void *arg) { struct ifreq ifr; - int err, val; + int err = 0, val; - switch(cmd) - { - case SIOCSIFADDR: - { + switch (cmd) { + case SIOCSIFADDR: { struct sockaddr_ipx *sipx; ipx_interface_definition f; - if(copy_from_user(&ifr, arg, sizeof(ifr))) - return (-EFAULT); + if (copy_from_user(&ifr, arg, sizeof(ifr))) + return -EFAULT; sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; - if(sipx->sipx_family != AF_IPX) - return (-EINVAL); + if (sipx->sipx_family != AF_IPX) + return -EINVAL; f.ipx_network = sipx->sipx_network; memcpy(f.ipx_device,ifr.ifr_name,sizeof(f.ipx_device)); @@ -1281,10 +1219,10 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) f.ipx_dlink_type = sipx->sipx_type; f.ipx_special = sipx->sipx_special; - if(sipx->sipx_action == IPX_DLTITF) - return (ipxitf_delete(&f)); + if (sipx->sipx_action == IPX_DLTITF) + return ipxitf_delete(&f); else - return (ipxitf_create(&f)); + return ipxitf_create(&f); } case SIOCGIFADDR: @@ -1293,50 +1231,46 @@ static int ipxitf_ioctl(unsigned int cmd, void *arg) ipx_interface *ipxif; struct net_device *dev; - if(copy_from_user(&ifr, arg, sizeof(ifr))) - return (-EFAULT); + if (copy_from_user(&ifr, arg, sizeof(ifr))) + return -EFAULT; sipx = (struct sockaddr_ipx *)&ifr.ifr_addr; dev = __dev_get_by_name(ifr.ifr_name); - if(!dev) - return (-ENODEV); + if (!dev) + return -ENODEV; ipxif = ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type)); - if(ipxif == NULL) - return (-EADDRNOTAVAIL); + if (!ipxif) + return -EADDRNOTAVAIL; sipx->sipx_family = AF_IPX; sipx->sipx_network = ipxif->if_netnum; - memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node)); - err = -EFAULT; - if(!copy_to_user(arg, &ifr, sizeof(ifr))) - err = 0; + memcpy(sipx->sipx_node, ipxif->if_node, + sizeof(sipx->sipx_node)); + if (copy_to_user(arg, &ifr, sizeof(ifr))) + err = -EFAULT; ipxitf_put(ipxif); - return (err); + return err; } case SIOCAIPXITFCRT: - { - err = get_user(val, (unsigned char *) arg); - if(err) - return (err); - - return (ipxcfg_set_auto_create(val)); - } + if (get_user(val, (unsigned char *) arg)) + return -EFAULT; + ipxcfg_set_auto_create(val); + break; case SIOCAIPXPRISLT: - { - err = get_user(val, (unsigned char *) arg); - if(err) - return (err); - - return (ipxcfg_set_auto_select(val)); - } + if (get_user(val, (unsigned char *) arg)) + return -EFAULT; + ipxcfg_set_auto_select(val); + break; default: - return (-EINVAL); + return -EINVAL; } + + return 0; } /**************************************************************************\ @@ -1350,11 +1284,11 @@ static ipx_route *ipxrtr_lookup(__u32 net) ipx_route *r; read_lock_bh(&ipx_routes_lock); - for(r = ipx_routes; (r != NULL) && (r->ir_net != net); r = r->ir_next) + for (r = ipx_routes; r && r->ir_net != net; r = r->ir_next) ; read_unlock_bh(&ipx_routes_lock); - return (r); + return r; } /* caller must hold a reference to intrfc */ @@ -1365,34 +1299,30 @@ static int ipxrtr_add_route(__u32 network, ipx_interface *intrfc, unsigned char /* Get a route structure; either existing or create */ rt = ipxrtr_lookup(network); - if(rt == NULL) - { - rt = (ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC); - if(rt == NULL) - return (-EAGAIN); + if (!rt) { + rt = kmalloc(sizeof(ipx_route),GFP_ATOMIC); + if (!rt) + return -EAGAIN; write_lock_bh(&ipx_routes_lock); rt->ir_next = ipx_routes; ipx_routes = rt; write_unlock_bh(&ipx_routes_lock); } - else if(intrfc == ipx_internal_net) - return (-EEXIST); + else if (intrfc == ipx_internal_net) + return -EEXIST; rt->ir_net = network; rt->ir_intrfc = intrfc; - if(node == NULL) - { + if (!node) { memset(rt->ir_router_node, '\0', IPX_NODE_LEN); rt->ir_routed = 0; - } - else - { + } else { memcpy(rt->ir_router_node, node, IPX_NODE_LEN); rt->ir_routed = 1; } - return (0); + return 0; } static void ipxrtr_del_routes(ipx_interface *intrfc) @@ -1400,14 +1330,11 @@ static void ipxrtr_del_routes(ipx_interface *intrfc) ipx_route **r, *tmp; write_lock_bh(&ipx_routes_lock); - for(r = &ipx_routes; (tmp = *r) != NULL;) - { - if(tmp->ir_intrfc == intrfc) - { + for (r = &ipx_routes; (tmp = *r) != NULL;) { + if (tmp->ir_intrfc == intrfc) { *r = tmp->ir_next; kfree(tmp); - } - else + } else r = &(tmp->ir_next); } write_unlock_bh(&ipx_routes_lock); @@ -1420,8 +1347,8 @@ static int ipxrtr_create(ipx_route_definition *rd) /* Find the appropriate interface */ intrfc = ipxitf_find_using_net(rd->ipx_router_network); - if(intrfc == NULL) - return (-ENETUNREACH); + if (!intrfc) + return -ENETUNREACH; ret = ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node); ipxitf_put(intrfc); return ret; @@ -1434,13 +1361,11 @@ static int ipxrtr_delete(long net) int err; write_lock_bh(&ipx_routes_lock); - for(r = &ipx_routes; (tmp = *r) != NULL;) - { - if(tmp->ir_net == net) - { + for (r = &ipx_routes; (tmp = *r) != NULL;) { + if (tmp->ir_net == net) { /* Directly connected; can't lose route */ err = -EPERM; - if(!(tmp->ir_routed)) + if (!tmp->ir_routed) goto out; *r = tmp->ir_next; @@ -1461,45 +1386,38 @@ out: write_unlock_bh(&ipx_routes_lock); */ /* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */ +/* This functions should *not* mess with packet contents */ -static __u16 ipx_set_checksum(struct ipxhdr *packet,int length) +static __u16 ipx_cksum(struct ipxhdr *packet,int length) { /* * NOTE: sum is a net byte order quantity, which optimizes the * loop. This only works on big and little endian machines. (I * don't know of a machine that isn't.) */ - - __u32 sum = 0; - - /* Pointer to second word - We skip the checksum field */ - __u16 *p = (__u16 *)&packet->ipx_pktsize; - - /* Number of complete words */ - __u32 i = length >> 1; - char hops = packet->ipx_tctrl; - - /* Hop count excluded from checksum calc */ - packet->ipx_tctrl = 0; - - /* Loop through all complete words except the checksum field */ - while(--i) + /* start at ipx_dest - We skip the checksum field and start with + * ipx_type before the loop, not considering ipx_tctrl in the calc */ + __u16 *p = (__u16 *)&packet->ipx_dest; + __u32 i = (length >> 1) - 1; /* Number of complete words */ + __u32 sum = packet->ipx_type << sizeof(packet->ipx_tctrl); + + /* Loop through all complete words except the checksum field, + * ipx_type (accounted above) and ipx_tctrl (not used in the cksum) */ + while (--i) sum += *p++; /* Add on the last part word if it exists */ - if(packet->ipx_pktsize & htons(1)) + if (packet->ipx_pktsize & htons(1)) sum += ntohs(0xff00) & *p; - packet->ipx_tctrl = hops; - /* Do final fixup */ sum = (sum & 0xffff) + (sum >> 16); /* It's a pity there's no concept of carry in C */ - if(sum >= 0x10000) + if (sum >= 0x10000) sum++; - return (~sum); + return ~sum; } /* @@ -1510,80 +1428,76 @@ static int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx, stru struct sk_buff *skb; ipx_interface *intrfc; struct ipxhdr *ipx; + struct ipx_cb *cb; int size; int ipx_offset; ipx_route *rt = NULL; int err; /* Find the appropriate interface on which to send packet */ - if(!usipx->sipx_network && (ipx_primary_net != NULL)) - { + if (!usipx->sipx_network && ipx_primary_net) { usipx->sipx_network = ipx_primary_net->if_netnum; intrfc = ipx_primary_net; - } - else - { + } else { rt = ipxrtr_lookup(usipx->sipx_network); - if(rt == NULL) - return (-ENETUNREACH); + if (!rt) + return -ENETUNREACH; intrfc = rt->ir_intrfc; } ipxitf_hold(intrfc); ipx_offset = intrfc->if_ipx_offset; - size = sizeof(struct ipxhdr) + len; - size += ipx_offset; + size = sizeof(struct ipxhdr) + len + ipx_offset; skb = sock_alloc_send_skb(sk, size, 0, noblock, &err); - if(skb == NULL) + if (!skb) goto out; skb_reserve(skb,ipx_offset); skb->sk = sk; + cb = (struct ipx_cb *) skb->cb; /* Fill in IPX header */ ipx = (struct ipxhdr *)skb_put(skb, sizeof(struct ipxhdr)); ipx->ipx_pktsize= htons(len + sizeof(struct ipxhdr)); - ipx->ipx_tctrl = 0; + cb->ipx_tctrl = 0; ipx->ipx_type = usipx->sipx_type; skb->h.raw = (void *)skb->nh.ipxh = ipx; - ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum; + cb->last_hop_index = -1; #ifdef CONFIG_IPX_INTERN + cb->ipx_source_net = sk->protinfo.af_ipx.intrfc->if_netnum; memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); #else - if((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452) - { + err = ntohs(sk->protinfo.af_ipx.port); + if (err == 0x453 || err == 0x452) { /* RIP/SAP special handling for mars_nwe */ - ipx->ipx_source.net = intrfc->if_netnum; + cb->ipx_source_net = intrfc->if_netnum; memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN); - } - else - { - ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum; + } else { + cb->ipx_source_net = sk->protinfo.af_ipx.intrfc->if_netnum; memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); } #endif /* CONFIG_IPX_INTERN */ ipx->ipx_source.sock = sk->protinfo.af_ipx.port; - ipx->ipx_dest.net = usipx->sipx_network; + cb->ipx_dest_net = usipx->sipx_network; memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN); ipx->ipx_dest.sock = usipx->sipx_port; err = memcpy_fromiovec(skb_put(skb,len),iov,len); - if(err) - { + if (err) { kfree_skb(skb); goto out; } /* Apply checksum. Not allowed on 802.3 links. */ - if(sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023) + if (sk->no_check || intrfc->if_dlink_type == IPX_FRAME_8023) ipx->ipx_checksum=0xFFFF; else - ipx->ipx_checksum = ipx_set_checksum(ipx, len + sizeof(struct ipxhdr)); + ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr)); err = ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ? rt->ir_router_node : ipx->ipx_dest.node); @@ -1594,21 +1508,20 @@ out: ipxitf_put(intrfc); int ipxrtr_route_skb(struct sk_buff *skb) { struct ipxhdr *ipx = skb->nh.ipxh; - ipx_route *r; + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; + ipx_route *r = ipxrtr_lookup(cb->ipx_dest_net); - r = ipxrtr_lookup(ipx->ipx_dest.net); - if(r == NULL) /* no known route */ - { + if (!r) { /* no known route */ kfree_skb(skb); - return (0); + return 0; } ipxitf_hold(r->ir_intrfc); - (void)ipxitf_send(r->ir_intrfc, skb, (r->ir_routed) ? + ipxitf_send(r->ir_intrfc, skb, (r->ir_routed) ? r->ir_router_node : ipx->ipx_dest.node); ipxitf_put(r->ir_intrfc); - return (0); + return 0; } /* @@ -1621,23 +1534,22 @@ static int ipxrtr_ioctl(unsigned int cmd, void *arg) int err; err = copy_from_user(&rt,arg,sizeof(rt)); - if(err) - return (-EFAULT); + if (err) + return -EFAULT; sg = (struct sockaddr_ipx *)&rt.rt_gateway; st = (struct sockaddr_ipx *)&rt.rt_dst; - if(!(rt.rt_flags & RTF_GATEWAY)) - return (-EINVAL); /* Direct routes are fixed */ - if(sg->sipx_family != AF_IPX) - return (-EINVAL); - if(st->sipx_family != AF_IPX) - return (-EINVAL); + if (!(rt.rt_flags & RTF_GATEWAY)) + return -EINVAL; /* Direct routes are fixed */ + if (sg->sipx_family != AF_IPX) + return -EINVAL; + if (st->sipx_family != AF_IPX) + return -EINVAL; - switch(cmd) - { + switch (cmd) { case SIOCDELRT: - return (ipxrtr_delete(st->sipx_network)); + return ipxrtr_delete(st->sipx_network); case SIOCADDRT: { @@ -1645,42 +1557,40 @@ static int ipxrtr_ioctl(unsigned int cmd, void *arg) f.ipx_network=st->sipx_network; f.ipx_router_network=sg->sipx_network; memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN); - return (ipxrtr_create(&f)); + return ipxrtr_create(&f); } - - default: - return (-EINVAL); } + + return -EINVAL; } static const char *ipx_frame_name(unsigned short frame) { - switch(ntohs(frame)) - { + switch (ntohs(frame)) { case ETH_P_IPX: - return ("EtherII"); + return "EtherII"; case ETH_P_802_2: - return ("802.2"); + return "802.2"; case ETH_P_SNAP: - return ("SNAP"); + return "SNAP"; case ETH_P_802_3: - return ("802.3"); + return "802.3"; case ETH_P_TR_802_2: - return ("802.2TR"); + return "802.2TR"; default: - return ("None"); + return "None"; } } static const char *ipx_device_name(ipx_interface *intrfc) { - return (intrfc->if_internal ? "Internal" : - (intrfc->if_dev ? intrfc->if_dev->name : "Unknown")); + return intrfc->if_internal ? "Internal" : + intrfc->if_dev ? intrfc->if_dev->name : "Unknown"; } /* Called from proc fs */ @@ -1700,13 +1610,12 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, #endif strcat(buffer+len++, "\n"); spin_lock_bh(&ipx_interfaces_lock); - for(i = ipx_interfaces; i != NULL; i = i->if_next) - { + for (i = ipx_interfaces; i; i = i->if_next) { len += sprintf(buffer+len, "%08lX ", (long unsigned int)ntohl(i->if_netnum)); len += sprintf(buffer+len,"%02X%02X%02X%02X%02X%02X ", i->if_node[0], i->if_node[1], i->if_node[2], i->if_node[3], i->if_node[4], i->if_node[5]); - len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ? + len += sprintf(buffer+len, "%-9s", i == ipx_primary_net ? "Yes" : "No"); len += sprintf(buffer+len, "%-11s", ipx_device_name(i)); len += sprintf(buffer+len, "%-9s", @@ -1718,12 +1627,11 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, /* Are we still dumping unwanted data then discard the record */ pos = begin + len; - if(pos < offset) - { + if (pos < offset) { len = 0; /* Keep dumping into the buffer start */ begin = pos; } - if(pos > offset + length) /* We have dumped enough */ + if (pos > offset + length) /* We have dumped enough */ break; } spin_unlock_bh(&ipx_interfaces_lock); @@ -1731,10 +1639,10 @@ static int ipx_interface_get_info(char *buffer, char **start, off_t offset, /* The data in question runs from begin to begin+len */ *start = buffer + (offset - begin); /* Start of wanted data */ len -= (offset - begin); /* Remove unwanted header data from length */ - if(len > length) + if (len > length) len = length; /* Remove unwanted tail data from length */ - return (len); + return len; } static int ipx_get_info(char *buffer, char **start, off_t offset, int length) @@ -1755,12 +1663,10 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) "State", "Uid"); spin_lock_bh(&ipx_interfaces_lock); - for(i = ipx_interfaces; i != NULL; i = i->if_next) - { + for (i = ipx_interfaces; i; i = i->if_next) { ipxitf_hold(i); spin_lock_bh(&i->if_sklist_lock); - for(s = i->if_sklist; s != NULL; s = s->next) - { + for (s = i->if_sklist; s; s = s->next) { #ifdef CONFIG_IPX_INTERN len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", @@ -1778,10 +1684,9 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) htons(s->protinfo.af_ipx.port)); #endif /* CONFIG_IPX_INTERN */ - if(s->state != TCP_ESTABLISHED) + if (s->state != TCP_ESTABLISHED) len += sprintf(buffer+len, "%-28s", "Not_Connected"); - else - { + else { len += sprintf(buffer+len, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ", (unsigned long) htonl(s->protinfo.af_ipx.dest_addr.net), @@ -1801,13 +1706,12 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) s->state, SOCK_INODE(s->socket)->i_uid); pos = begin + len; - if(pos < offset) - { + if (pos < offset) { len = 0; begin = pos; } - if(pos > offset + length) /* We have dumped enough */ + if (pos > offset + length) /* We have dumped enough */ break; } spin_unlock_bh(&i->if_sklist_lock); @@ -1818,10 +1722,10 @@ static int ipx_get_info(char *buffer, char **start, off_t offset, int length) /* The data in question runs from begin to begin+len */ *start = buffer + (offset-begin); len -= (offset - begin); - if(len > length) + if (len > length) len = length; - return (len); + return len; } static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) @@ -1833,41 +1737,36 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) len += sprintf(buffer,"%-11s%-13s%s\n", "Network", "Router_Net", "Router_Node"); read_lock_bh(&ipx_routes_lock); - for(rt = ipx_routes; rt != NULL; rt = rt->ir_next) - { + for (rt = ipx_routes; rt; rt = rt->ir_next) { len += sprintf(buffer+len,"%08lX ", (long unsigned int) ntohl(rt->ir_net)); - if(rt->ir_routed) - { + if (rt->ir_routed) { len += sprintf(buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n", (long unsigned int) ntohl(rt->ir_intrfc->if_netnum), rt->ir_router_node[0], rt->ir_router_node[1], rt->ir_router_node[2], rt->ir_router_node[3], rt->ir_router_node[4], rt->ir_router_node[5]); - } - else - { + } else { len += sprintf(buffer+len, "%-13s%s\n", "Directly", "Connected"); } pos = begin + len; - if(pos < offset) - { - len = 0; + if (pos < offset) { + len = 0; begin = pos; } - if(pos > offset + length) + if (pos > offset + length) break; } read_unlock_bh(&ipx_routes_lock); *start = buffer + (offset - begin); len -= (offset - begin); - if(len > length) + if (len > length) len = length; - return (len); + return len; } /**************************************************************************\ @@ -1877,89 +1776,80 @@ static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length) * * \**************************************************************************/ -static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen) +static int ipx_setsockopt(struct socket *sock, int level, int optname, + char *optval, int optlen) { - struct sock *sk; - int err, opt; - - sk = sock->sk; + struct sock *sk = sock->sk; + int opt; - if(optlen != sizeof(int)) - return (-EINVAL); + if (optlen != sizeof(int)) + return -EINVAL; - err = get_user(opt, (unsigned int *)optval); - if(err) - return (err); + if (get_user(opt, (unsigned int *)optval)) + return -EFAULT; - switch(level) - { + switch (level) { case SOL_IPX: - switch(optname) - { + switch (optname) { case IPX_TYPE: sk->protinfo.af_ipx.type = opt; - return (0); + return 0; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } break; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } } static int ipx_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { - struct sock *sk; - int val=0; + struct sock *sk = sock->sk; + int val = 0; int len; - sk = sock->sk; - - switch(level) - { + switch (level) { case SOL_IPX: - switch(optname) - { + switch (optname) { case IPX_TYPE: val = sk->protinfo.af_ipx.type; break; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } break; default: - return (-ENOPROTOOPT); + return -ENOPROTOOPT; } - if(get_user(len, optlen)) - return (-EFAULT); + if (get_user(len, optlen)) + return -EFAULT; len = min(len, sizeof(int)); - if(put_user(len, optlen)) - return (-EFAULT); + if (put_user(len, optlen)) + return -EFAULT; - if(copy_to_user(optval, &val, len)) - return (-EFAULT); + if (copy_to_user(optval, &val, len)) + return -EFAULT; - return (0); + return 0; } static int ipx_create(struct socket *sock, int protocol) { struct sock *sk; - switch(sock->type) - { + switch (sock->type) { case SOCK_DGRAM: sk = sk_alloc(PF_IPX, GFP_KERNEL, 1); - if(sk == NULL) - return (-ENOMEM); + if (!sk) + return -ENOMEM; sock->ops = &ipx_dgram_ops; break; @@ -1968,12 +1858,12 @@ static int ipx_create(struct socket *sock, int protocol) * From this point on SPX sockets are handled * by af_spx.c and the methods replaced. */ - if(spx_family_ops) - return (spx_family_ops->create(sock,protocol)); + if (spx_family_ops) + return spx_family_ops->create(sock,protocol); /* Fall through if SPX is not loaded */ case SOCK_STREAM: /* Allow higher levels to piggyback */ default: - return (-ESOCKTNOSUPPORT); + return -ESOCKTNOSUPPORT; } #ifdef IPX_REFCNT_DEBUG atomic_inc(&ipx_sock_nr); @@ -1985,31 +1875,30 @@ static int ipx_create(struct socket *sock, int protocol) sk->no_check = 1; /* Checksum off by default */ MOD_INC_USE_COUNT; - - return (0); + return 0; } static int ipx_release(struct socket *sock) { struct sock *sk = sock->sk; - if(sk == NULL) - return (0); + if (!sk) + return 0; - if(!sk->dead) + if (!sk->dead) sk->state_change(sk); sk->dead = 1; sock->sk = NULL; ipx_destroy_socket(sk); - if(sock->type == SOCK_DGRAM) + if (sock->type == SOCK_DGRAM) MOD_DEC_USE_COUNT; - return (0); + return 0; } -/* caller must hold a referente to intrfc */ +/* caller must hold a reference to intrfc */ static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc) { @@ -2017,91 +1906,80 @@ static unsigned short ipx_first_free_socketnum(ipx_interface *intrfc) spin_lock_bh(&intrfc->if_sklist_lock); - if(socketNum < IPX_MIN_EPHEMERAL_SOCKET) + if (socketNum < IPX_MIN_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; - while(__ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL) - { - if(socketNum > IPX_MAX_EPHEMERAL_SOCKET) + while (__ipxitf_find_socket(intrfc, ntohs(socketNum))) + if (socketNum > IPX_MAX_EPHEMERAL_SOCKET) socketNum = IPX_MIN_EPHEMERAL_SOCKET; else socketNum++; - } spin_unlock_bh(&intrfc->if_sklist_lock); intrfc->if_sknum = socketNum; - return (ntohs(socketNum)); + return ntohs(socketNum); } static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) { - struct sock *sk; + struct sock *sk = sock->sk; ipx_interface *intrfc; struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr; int ret; - sk = sock->sk; - - if(sk->zapped == 0) - return (-EINVAL); + if (!sk->zapped) + return -EINVAL; - if(addr_len != sizeof(struct sockaddr_ipx)) - return (-EINVAL); + if (addr_len != sizeof(struct sockaddr_ipx)) + return -EINVAL; intrfc = ipxitf_find_using_net(addr->sipx_network); - if(intrfc == NULL) - return (-EADDRNOTAVAIL); + if (!intrfc) + return -EADDRNOTAVAIL; - if(addr->sipx_port == 0) - { + if (!addr->sipx_port) { addr->sipx_port = ipx_first_free_socketnum(intrfc); ret = -EINVAL; - if(addr->sipx_port == 0) + if (!addr->sipx_port) goto out; } /* protect IPX system stuff like routing/sap */ ret = -EACCES; - if(ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && !capable(CAP_NET_ADMIN)) + if (ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET && + !capable(CAP_NET_ADMIN)) goto out; sk->protinfo.af_ipx.port = addr->sipx_port; #ifdef CONFIG_IPX_INTERN - if(intrfc == ipx_internal_net) - { + if (intrfc == ipx_internal_net) { /* The source address is to be set explicitly if the * socket is to be bound on the internal network. If a * node number 0 was specified, the default is used. */ ret = -EINVAL; - if(memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN) == 0) + if (!memcmp(addr->sipx_node,ipx_broadcast_node,IPX_NODE_LEN)) goto out; - if(memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0) - { + if (!memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN)) memcpy(sk->protinfo.af_ipx.node, intrfc->if_node, IPX_NODE_LEN); - } else - { - memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN); - } + memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, + IPX_NODE_LEN); ret = -EADDRINUSE; - if(ipxitf_find_internal_socket(intrfc, - sk->protinfo.af_ipx.node, - sk->protinfo.af_ipx.port) != NULL) - { + if (ipxitf_find_internal_socket(intrfc, + sk->protinfo.af_ipx.node, + sk->protinfo.af_ipx.port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); goto out; } - } - else - { + } else { /* Source addresses are easy. It must be our * network:node pair for an interface routed to IPX * with the ipx routing ioctl() @@ -2111,8 +1989,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) IPX_NODE_LEN); ret = -EADDRINUSE; - if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL) - { + if (ipxitf_find_socket(intrfc, addr->sipx_port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); @@ -2126,8 +2003,7 @@ static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) an interface routed to IPX with the ipx routing ioctl() */ ret = -EADDRINUSE; - if(ipxitf_find_socket(intrfc, addr->sipx_port) != NULL) - { + if (ipxitf_find_socket(intrfc, addr->sipx_port)) { SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n", ntohs((int)addr->sipx_port)); goto out; @@ -2153,13 +2029,12 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, sk->state = TCP_CLOSE; sock->state = SS_UNCONNECTED; - if(addr_len != sizeof(*addr)) - return (-EINVAL); + if (addr_len != sizeof(*addr)) + return -EINVAL; addr = (struct sockaddr_ipx *)uaddr; /* put the autobinding in */ - if(sk->protinfo.af_ipx.port == 0) - { + if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; int ret; @@ -2167,7 +2042,7 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if(sk->protinfo.af_ipx.intrfc) + if (sk->protinfo.af_ipx.intrfc) memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,IPX_NODE_LEN); else return -ENETDOWN; /* Someone zonked the iface */ @@ -2175,13 +2050,15 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if(ret != 0) - return (ret); + if (ret) + return ret; } - /* We can either connect to primary network or somewhere we can route to */ - if( !(addr->sipx_network == 0 && ipx_primary_net != NULL) && ipxrtr_lookup(addr->sipx_network) == NULL) - return (-ENETUNREACH); + /* We can either connect to primary network or somewhere + * we can route to */ + if (!(!addr->sipx_network && ipx_primary_net) && + !ipxrtr_lookup(addr->sipx_network)) + return -ENETUNREACH; sk->protinfo.af_ipx.dest_addr.net = addr->sipx_network; sk->protinfo.af_ipx.dest_addr.sock = addr->sipx_port; @@ -2189,41 +2066,34 @@ static int ipx_connect(struct socket *sock, struct sockaddr *uaddr, addr->sipx_node,IPX_NODE_LEN); sk->protinfo.af_ipx.type = addr->sipx_type; - if(sock->type == SOCK_DGRAM ) - { + if (sock->type == SOCK_DGRAM) { sock->state = SS_CONNECTED; sk->state = TCP_ESTABLISHED; } - return (0); + return 0; } static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, - int *uaddr_len, int peer) + int *uaddr_len, int peer) { ipx_address *addr; struct sockaddr_ipx sipx; - struct sock *sk; - - sk = sock->sk; + struct sock *sk = sock->sk; *uaddr_len = sizeof(struct sockaddr_ipx); - if(peer) - { - if(sk->state != TCP_ESTABLISHED) - return (-ENOTCONN); + if (peer) { + if (sk->state != TCP_ESTABLISHED) + return -ENOTCONN; addr = &sk->protinfo.af_ipx.dest_addr; sipx.sipx_network = addr->net; memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN); sipx.sipx_port = addr->sock; - } - else - { - if(sk->protinfo.af_ipx.intrfc != NULL) - { + } else { + if (sk->protinfo.af_ipx.intrfc) { sipx.sipx_network=sk->protinfo.af_ipx.intrfc->if_netnum; #ifdef CONFIG_IPX_INTERN memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN); @@ -2231,9 +2101,7 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, memcpy(sipx.sipx_node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN); #endif /* CONFIG_IPX_INTERN */ - } - else - { + } else { sipx.sipx_network = 0; memset(sipx.sipx_node, '\0', IPX_NODE_LEN); } @@ -2242,10 +2110,10 @@ static int ipx_getname(struct socket *sock, struct sockaddr *uaddr, } sipx.sipx_family = AF_IPX; - sipx.sipx_type = sk->protinfo.af_ipx.type; + sipx.sipx_type = sk->protinfo.af_ipx.type; memcpy(uaddr,&sipx,sizeof(sipx)); - return (0); + return 0; } int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) @@ -2253,97 +2121,96 @@ int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) /* NULL here for pt means the packet was looped back */ ipx_interface *intrfc; struct ipxhdr *ipx; + struct ipx_cb *cb; + u16 ipx_pktsize; int ret; - - ipx = skb->nh.ipxh; - - /* Too small? */ - if(ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr)) - goto drop; - - /* Invalid header */ - if(ntohs(ipx->ipx_pktsize) > skb->len) - goto drop; /* Not ours */ if (skb->pkt_type == PACKET_OTHERHOST) goto drop; + + if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) + goto out; + + ipx = skb->nh.ipxh; + ipx_pktsize = ntohs(ipx->ipx_pktsize); + + /* Too small or invalid header? */ + if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len) + goto drop; - if(ipx->ipx_checksum != IPX_NO_CHECKSUM) - { - if(ipx_set_checksum(ipx, ntohs(ipx->ipx_pktsize)) != ipx->ipx_checksum) - goto drop; - } + if (ipx->ipx_checksum != IPX_NO_CHECKSUM && + ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize)) + goto drop; + + cb = (struct ipx_cb *) skb->cb; + cb->ipx_tctrl = ipx->ipx_tctrl; + cb->ipx_dest_net = ipx->ipx_dest.net; + cb->ipx_source_net = ipx->ipx_source.net; /* Determine what local ipx endpoint this is */ intrfc = ipxitf_find_using_phys(dev, pt->type); - if(intrfc == NULL) - { - if(ipxcfg_auto_create_interfaces - && ntohl(ipx->ipx_dest.net) != 0L) - { + if (!intrfc) { + if (ipxcfg_auto_create_interfaces && + ntohl(cb->ipx_dest_net)) { intrfc = ipxitf_auto_create(dev, pt->type); ipxitf_hold(intrfc); } - if(intrfc == NULL) /* Not one of ours */ + if (!intrfc) /* Not one of ours */ goto drop; } ret = ipxitf_rcv(intrfc, skb); ipxitf_put(intrfc); return ret; -drop: - kfree_skb(skb); - return (0); +drop: kfree_skb(skb); +out: return 0; } static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm) { struct sock *sk = sock->sk; - struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name; + struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name; struct sockaddr_ipx local_sipx; int retval; int flags = msg->msg_flags; /* Socket gets bound below anyway */ -/* if(sk->zapped) - return (-EIO); */ /* Socket not bound */ - if(flags & ~MSG_DONTWAIT) - return (-EINVAL); - - if(usipx) - { - if(sk->protinfo.af_ipx.port == 0) - { +/* if (sk->zapped) + return -EIO; */ /* Socket not bound */ + if (flags & ~MSG_DONTWAIT) + return -EINVAL; + + if (usipx) { + if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; int ret; uaddr.sipx_port = 0; uaddr.sipx_network = 0L; #ifdef CONFIG_IPX_INTERN - if(sk->protinfo.af_ipx.intrfc) - memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc - ->if_node,IPX_NODE_LEN); + if (sk->protinfo.af_ipx.intrfc) + memcpy(uaddr.sipx_node, + sk->protinfo.af_ipx.intrfc->if_node, + IPX_NODE_LEN); else return -ENETDOWN; /* Someone zonked the iface */ #endif ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if(ret != 0) - return (ret); + if (ret) + return ret; } - if(msg->msg_namelen < sizeof(*usipx)) - return (-EINVAL); - if(usipx->sipx_family != AF_IPX) - return (-EINVAL); - } - else - { - if(sk->state != TCP_ESTABLISHED) - return (-ENOTCONN); + if (msg->msg_namelen < sizeof(*usipx)) + return -EINVAL; + if (usipx->sipx_family != AF_IPX) + return -EINVAL; + } else { + if (sk->state != TCP_ESTABLISHED) + return -ENOTCONN; usipx=&local_sipx; usipx->sipx_family = AF_IPX; @@ -2353,11 +2220,12 @@ static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN); } - retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, flags&MSG_DONTWAIT); - if(retval < 0) - return (retval); + retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len, + flags & MSG_DONTWAIT); + if (retval < 0) + return retval; - return (len); + return len; } @@ -2371,8 +2239,7 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, int copied, err; /* put the autobinding in */ - if(sk->protinfo.af_ipx.port == 0) - { + if (!sk->protinfo.af_ipx.port) { struct sockaddr_ipx uaddr; int ret; @@ -2380,7 +2247,7 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, uaddr.sipx_network = 0; #ifdef CONFIG_IPX_INTERN - if(sk->protinfo.af_ipx.intrfc) + if (sk->protinfo.af_ipx.intrfc) memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,IPX_NODE_LEN); else return -ENETDOWN; /* Someone zonked the iface */ @@ -2388,47 +2255,45 @@ static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, ret = ipx_bind(sock, (struct sockaddr *)&uaddr, sizeof(struct sockaddr_ipx)); - if(ret != 0) - return (ret); + if (ret) + return ret; } - if(sk->zapped) - return (-ENOTCONN); + if (sk->zapped) + return -ENOTCONN; skb = skb_recv_datagram(sk,flags&~MSG_DONTWAIT,flags&MSG_DONTWAIT,&err); - if(!skb) + if (!skb) goto out; ipx = skb->nh.ipxh; copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr); - if(copied > size) - { + if (copied > size) { copied=size; msg->msg_flags |= MSG_TRUNC; } err = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov, copied); - if(err) + if (err) goto out_free; sk->stamp = skb->stamp; msg->msg_namelen = sizeof(*sipx); - if(sipx) - { + if (sipx) { + struct ipx_cb *cb = (struct ipx_cb *) skb->cb; sipx->sipx_family = AF_IPX; sipx->sipx_port = ipx->ipx_source.sock; memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN); - sipx->sipx_network = ipx->ipx_source.net; + sipx->sipx_network = cb->ipx_source_net; sipx->sipx_type = ipx->ipx_type; } err = copied; out_free: skb_free_datagram(sk, skb); -out: - return (err); +out: return err; } @@ -2437,40 +2302,39 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) long amount = 0; struct sock *sk = sock->sk; - switch(cmd) - { + switch (cmd) { case TIOCOUTQ: amount = sk->sndbuf - atomic_read(&sk->wmem_alloc); - if(amount < 0) + if (amount < 0) amount = 0; - return (put_user(amount, (int *)arg)); + return put_user(amount, (int *)arg); case TIOCINQ: { - struct sk_buff *skb; + struct sk_buff *skb = skb_peek(&sk->receive_queue); /* These two are safe on a single CPU system as only user tasks fiddle here */ - if((skb = skb_peek(&sk->receive_queue)) != NULL) + if (skb) amount = skb->len - sizeof(struct ipxhdr); - return (put_user(amount, (int *)arg)); + return put_user(amount, (int *)arg); } case SIOCADDRT: case SIOCDELRT: - if(!capable(CAP_NET_ADMIN)) - return (-EPERM); - return (ipxrtr_ioctl(cmd,(void *)arg)); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; + return ipxrtr_ioctl(cmd,(void *)arg); case SIOCSIFADDR: case SIOCAIPXITFCRT: case SIOCAIPXPRISLT: - if(!capable(CAP_NET_ADMIN)) - return (-EPERM); + if (!capable(CAP_NET_ADMIN)) + return -EPERM; case SIOCGIFADDR: - return (ipxitf_ioctl(cmd,(void *)arg)); + return ipxitf_ioctl(cmd,(void *)arg); case SIOCIPXCFGDATA: - return (ipxcfg_get_config_data((void *)arg)); + return ipxcfg_get_config_data((void *)arg); case SIOCIPXNCPCONN: { @@ -2479,24 +2343,24 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) * handed to us in arg. */ if (!capable(CAP_NET_ADMIN)) - return(-EPERM); - return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, (const unsigned short *)(arg)); + return -EPERM; + return get_user(sk->protinfo.af_ipx.ipx_ncp_conn, + (const unsigned short *)(arg)); } case SIOCGSTAMP: { int ret = -EINVAL; - if(sk) - { - if(sk->stamp.tv_sec == 0) - return (-ENOENT); + if (sk) { + if (!sk->stamp.tv_sec) + return -ENOENT; ret = -EFAULT; - if(!copy_to_user((void *)arg, &sk->stamp, + if (!copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval))) ret = 0; } - return (ret); + return ret; } case SIOCGIFDSTADDR: @@ -2505,14 +2369,14 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCSIFBRDADDR: case SIOCGIFNETMASK: case SIOCSIFNETMASK: - return (-EINVAL); + return -EINVAL; default: - return (dev_ioctl(cmd,(void *) arg)); + return dev_ioctl(cmd,(void *) arg); } /*NOT REACHED*/ - return (0); + return 0; } /* @@ -2521,19 +2385,19 @@ static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) int ipx_register_spx(struct proto_ops **p, struct net_proto_family *spx) { - if(spx_family_ops!=NULL) + if (spx_family_ops) return -EBUSY; cli(); MOD_INC_USE_COUNT; - *p=&ipx_dgram_ops; - spx_family_ops=spx; + *p = &ipx_dgram_ops; + spx_family_ops = spx; sti(); return 0; } int ipx_unregister_spx(void) { - spx_family_ops=NULL; + spx_family_ops = NULL; MOD_DEC_USE_COUNT; return 0; } @@ -2576,7 +2440,7 @@ static struct packet_type ipx_8023_packet_type = __constant_htons(ETH_P_802_3), NULL, /* All devices */ ipx_rcv, - NULL, + (void *) 1, /* yap, I understand shared skbs :-) */ NULL, }; @@ -2585,7 +2449,7 @@ static struct packet_type ipx_dix_packet_type = __constant_htons(ETH_P_IPX), NULL, /* All devices */ ipx_rcv, - NULL, + (void *) 1, /* yap, I understand shared skbs :-) */ NULL, }; @@ -2604,12 +2468,9 @@ extern void destroy_8023_client(struct datalink_proto *); static unsigned char ipx_8022_type = 0xE0; static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 }; - - - static int __init ipx_init(void) { - (void) sock_register(&ipx_family_ops); + sock_register(&ipx_family_ops); pEII_datalink = make_EII_client(); dev_add_pack(&ipx_dix_packet_type); @@ -2617,35 +2478,34 @@ static int __init ipx_init(void) p8023_datalink = make_8023_client(); dev_add_pack(&ipx_8023_packet_type); - if((p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv)) == NULL) + p8022_datalink = register_8022_client(ipx_8022_type,ipx_rcv); + if (!p8022_datalink) printk(KERN_CRIT "IPX: Unable to register with 802.2\n"); - if((pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv)) == NULL) + pSNAP_datalink = register_snap_client(ipx_snap_id,ipx_rcv); + if (!pSNAP_datalink) printk(KERN_CRIT "IPX: Unable to register with SNAP\n"); register_netdevice_notifier(&ipx_dev_notifier); - #ifdef CONFIG_PROC_FS proc_net_create("ipx", 0, ipx_get_info); proc_net_create("ipx_interface", 0, ipx_interface_get_info); proc_net_create("ipx_route", 0, ipx_rt_get_info); #endif - - printk(KERN_INFO "NET4: Linux IPX 0.42v4 for NET4.0\n"); + printk(KERN_INFO "NET4: Linux IPX 0.43 for NET4.0\n"); printk(KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n"); printk(KERN_INFO "IPX Portions Copyright (c) 2000 Conectiva, Inc.\n"); return 0; } + module_init(ipx_init); /* Higher layers need this info to prep tx pkts */ int ipx_if_offset(unsigned long ipx_net_number) { - ipx_route *rt = NULL; - - rt = ipxrtr_lookup(ipx_net_number); + ipx_route *rt = ipxrtr_lookup(ipx_net_number); - return (rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH); + return rt ? rt->ir_intrfc->if_ipx_offset : -ENETUNREACH; } /* Export symbols for higher layers */ @@ -2683,24 +2543,22 @@ static void ipx_proto_finito(void) unregister_netdevice_notifier(&ipx_dev_notifier); unregister_snap_client(ipx_snap_id); - pSNAP_datalink = NULL; + pSNAP_datalink = NULL; unregister_8022_client(ipx_8022_type); - p8022_datalink = NULL; + p8022_datalink = NULL; dev_remove_pack(&ipx_8023_packet_type); destroy_8023_client(p8023_datalink); - p8023_datalink = NULL; + p8023_datalink = NULL; dev_remove_pack(&ipx_dix_packet_type); destroy_EII_client(pEII_datalink); - pEII_datalink = NULL; - - (void) sock_unregister(ipx_family_ops.family); + pEII_datalink = NULL; - return; + sock_unregister(ipx_family_ops.family); } + module_exit(ipx_proto_finito); #endif /* MODULE */ - #endif /* CONFIG_IPX || CONFIG_IPX_MODULE */ diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 550519e0b138..43ed8e26b18c 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c @@ -252,7 +252,7 @@ static u32 gen_new_htid(struct tc_u_common *tp_c) do { if (++tp_c->hgenerator == 0x7FF) tp_c->hgenerator = 1; - } while (i>0 && u32_lookup_ht(tp_c, (tp_c->hgenerator|0x800)<<20)); + } while (--i>0 && u32_lookup_ht(tp_c, (tp_c->hgenerator|0x800)<<20)); return i > 0 ? (tp_c->hgenerator|0x800)<<20 : 0; } diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 76f2fc394c36..a66fd2b45761 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c @@ -39,16 +39,22 @@ * x:y y>0 y+1 use entry [y] * ... ... ... * x:indices-1 indices use entry [indices-1] + * ... ... ... + * x:y y+1 use entry [y & (indices-1)] + * ... ... ... + * 0xffff 0x10000 use entry [indices-1] */ +#define NO_DEFAULT_INDEX (1 << 16) + struct dsmark_qdisc_data { struct Qdisc *q; struct tcf_proto *filter_list; __u8 *mask; /* "owns" the array */ __u8 *value; __u16 indices; - __u16 default_index; + __u32 default_index; /* index range is 0...0xffff */ int set_tc_index; }; @@ -217,7 +223,7 @@ static int dsmark_enqueue(struct sk_buff *skb,struct Qdisc *sch) case TC_POLICE_UNSPEC: /* fall through */ default: - if (p->default_index) + if (p->default_index != NO_DEFAULT_INDEX) skb->tc_index = p->default_index; break; }; @@ -325,14 +331,12 @@ int dsmark_init(struct Qdisc *sch,struct rtattr *opt) if (tmp & 1) return -EINVAL; } - p->default_index = 0; + p->default_index = NO_DEFAULT_INDEX; if (tb[TCA_DSMARK_DEFAULT_INDEX-1]) { if (RTA_PAYLOAD(tb[TCA_DSMARK_DEFAULT_INDEX-1]) < sizeof(__u16)) return -EINVAL; p->default_index = *(__u16 *) RTA_DATA(tb[TCA_DSMARK_DEFAULT_INDEX-1]); - if (!p->default_index || p->default_index >= p->indices) - return -EINVAL; } p->set_tc_index = !!tb[TCA_DSMARK_SET_TC_INDEX-1]; p->mask = kmalloc(p->indices*2,GFP_KERNEL); @@ -411,9 +415,11 @@ static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) rta = (struct rtattr *) b; RTA_PUT(skb,TCA_OPTIONS,0,NULL); RTA_PUT(skb,TCA_DSMARK_INDICES,sizeof(__u16),&p->indices); - if (p->default_index) - RTA_PUT(skb,TCA_DSMARK_DEFAULT_INDEX, sizeof(__u16), - &p->default_index); + if (p->default_index != NO_DEFAULT_INDEX) { + __u16 tmp = p->default_index; + + RTA_PUT(skb,TCA_DSMARK_DEFAULT_INDEX, sizeof(__u16), &tmp); + } if (p->set_tc_index) RTA_PUT(skb, TCA_DSMARK_SET_TC_INDEX, 0, NULL); rta->rta_len = skb->tail-b; diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index 4983e898e5db..3a48c3ebf3bd 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c @@ -110,12 +110,9 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) unsigned long qave=0; int i=0; - if (!t->initd) { - DPRINTK("NO GRED Queues setup yet! Enqueued anyway\n"); - if (q->backlog <= q->limit) { - __skb_queue_tail(&sch->q, skb); - return NET_XMIT_DROP; /* @@@@ */ - } + if (!t->initd && skb_queue_len(&sch->q) <= sch->dev->tx_queue_len) { + D2PRINTK("NO GRED Queues setup yet! Enqueued anyway\n"); + goto do_enqueue; } @@ -179,11 +176,12 @@ gred_enqueue(struct sk_buff *skb, struct Qdisc* sch) q->qcount = -1; enqueue: if (q->backlog <= q->limit) { + q->backlog += skb->len; +do_enqueue: __skb_queue_tail(&sch->q, skb); sch->stats.backlog += skb->len; sch->stats.bytes += skb->len; sch->stats.packets++; - q->backlog += skb->len; return 0; } else { q->pdrop++; diff --git a/net/sysctl_net.c b/net/sysctl_net.c index bda8d54d8bc1..61f94839093a 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -26,10 +26,6 @@ extern ctl_table ipx_table[]; extern ctl_table core_table[]; -#ifdef CONFIG_UNIX -extern ctl_table unix_table[]; -#endif - #ifdef CONFIG_NET extern ctl_table ether_table[], e802_table[]; #endif @@ -48,9 +44,6 @@ extern ctl_table econet_table[]; ctl_table net_table[] = { {NET_CORE, "core", NULL, 0, 0555, core_table}, -#ifdef CONFIG_UNIX - {NET_UNIX, "unix", NULL, 0, 0555, unix_table}, -#endif #ifdef CONFIG_NET {NET_802, "802", NULL, 0, 0555, e802_table}, {NET_ETHER, "ethernet", NULL, 0, 0555, ether_table}, diff --git a/net/unix/Makefile b/net/unix/Makefile index 88a2626716c2..9a840afde932 100644 --- a/net/unix/Makefile +++ b/net/unix/Makefile @@ -16,5 +16,3 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_unix.o include $(TOPDIR)/Rules.make -tar: - tar -cvf /dev/f1 . diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e48b8549a35b..121e4d9de05c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -1,5 +1,5 @@ /* - * NET3: Implementation of BSD Unix domain sockets. + * NET4: Implementation of BSD Unix domain sockets. * * Authors: Alan Cox, <alan.cox@linux.org> * @@ -8,7 +8,7 @@ * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * - * Version: $Id: af_unix.c,v 1.108 2000/11/10 04:02:04 davem Exp $ + * Version: $Id: af_unix.c,v 1.109 2001/01/06 00:42:23 davem Exp $ * * Fixes: * Linus Torvalds : Assorted bug cures. @@ -124,13 +124,12 @@ static atomic_t unix_nr_socks = ATOMIC_INIT(0); #define UNIX_ABSTRACT(sk) ((sk)->protinfo.af_unix.addr->hash!=UNIX_HASH_SIZE) /* - SMP locking strategy. - * hash table is protceted with rwlock unix_table_lock - * each socket state is protected by separate rwlock. - + * SMP locking strategy: + * hash table is protected with rwlock unix_table_lock + * each socket state is protected by separate rwlock. */ -extern __inline__ unsigned unix_hash_fold(unsigned hash) +static inline unsigned unix_hash_fold(unsigned hash) { hash ^= hash>>16; hash ^= hash>>8; @@ -139,17 +138,17 @@ extern __inline__ unsigned unix_hash_fold(unsigned hash) #define unix_peer(sk) ((sk)->pair) -extern __inline__ int unix_our_peer(unix_socket *sk, unix_socket *osk) +static inline int unix_our_peer(unix_socket *sk, unix_socket *osk) { return unix_peer(osk) == sk; } -extern __inline__ int unix_may_send(unix_socket *sk, unix_socket *osk) +static inline int unix_may_send(unix_socket *sk, unix_socket *osk) { return (unix_peer(osk) == NULL || unix_our_peer(sk, osk)); } -static __inline__ unix_socket * unix_peer_get(unix_socket *s) +static inline unix_socket * unix_peer_get(unix_socket *s) { unix_socket *peer; @@ -161,7 +160,7 @@ static __inline__ unix_socket * unix_peer_get(unix_socket *s) return peer; } -extern __inline__ void unix_release_addr(struct unix_address *addr) +extern inline void unix_release_addr(struct unix_address *addr) { if (atomic_dec_and_test(&addr->refcnt)) kfree(addr); @@ -231,14 +230,14 @@ static void __unix_insert_socket(unix_socket **list, unix_socket *sk) sock_hold(sk); } -static __inline__ void unix_remove_socket(unix_socket *sk) +static inline void unix_remove_socket(unix_socket *sk) { write_lock(&unix_table_lock); __unix_remove_socket(sk); write_unlock(&unix_table_lock); } -static __inline__ void unix_insert_socket(unix_socket **list, unix_socket *sk) +static inline void unix_insert_socket(unix_socket **list, unix_socket *sk) { write_lock(&unix_table_lock); __unix_insert_socket(list, sk); @@ -258,7 +257,7 @@ static unix_socket *__unix_find_socket_byname(struct sockaddr_un *sunname, return NULL; } -static __inline__ unix_socket * +static inline unix_socket * unix_find_socket_byname(struct sockaddr_un *sunname, int len, int type, unsigned hash) { @@ -291,7 +290,7 @@ static unix_socket *unix_find_socket_byinode(struct inode *i) return s; } -static __inline__ int unix_writable(struct sock *sk) +static inline int unix_writable(struct sock *sk) { return ((atomic_read(&sk->wmem_alloc)<<2) <= sk->sndbuf); } @@ -1823,7 +1822,7 @@ struct proto_ops unix_stream_ops = { struct proto_ops unix_dgram_ops = { family: PF_UNIX, - + release: unix_release, bind: unix_bind, connect: unix_dgram_connect, @@ -1842,20 +1841,25 @@ struct proto_ops unix_dgram_ops = { }; struct net_proto_family unix_family_ops = { - PF_UNIX, - unix_create + family: PF_UNIX, + create: unix_create }; #ifdef CONFIG_SYSCTL extern void unix_sysctl_register(void); extern void unix_sysctl_unregister(void); +#else +static inline unix_sysctl_register() {}; +static inline unix_sysctl_unregister() {}; #endif +static const char banner[] __initdata = KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n"; + static int __init af_unix_init(void) { struct sk_buff *dummy_skb; - - printk(KERN_INFO "NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.\n"); + + printk(banner); if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) { printk(KERN_CRIT "unix_proto_init: panic\n"); @@ -1865,23 +1869,15 @@ static int __init af_unix_init(void) #ifdef CONFIG_PROC_FS create_proc_read_entry("net/unix", 0, 0, unix_read_proc, NULL); #endif - -#ifdef CONFIG_SYSCTL unix_sysctl_register(); -#endif - return 0; } static void __exit af_unix_exit(void) { sock_unregister(PF_UNIX); -#ifdef CONFIG_SYSCTL unix_sysctl_unregister(); -#endif -#ifdef CONFIG_PROC_FS remove_proc_entry("net/unix", 0); -#endif } module_init(af_unix_init); diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c index 885119da3928..928b3f857a4d 100644 --- a/net/unix/sysctl_net_unix.c +++ b/net/unix/sysctl_net_unix.c @@ -1,10 +1,8 @@ /* - * NET3: Sysctl interface to net af_unix subsystem. + * NET4: Sysctl interface to net af_unix subsystem. * * Authors: Mike Shaver. * - * Added /proc/sys/net/unix directory entry (empty =) ). - * * 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 @@ -15,8 +13,6 @@ #include <linux/sysctl.h> #include <linux/config.h> -#ifdef CONFIG_SYSCTL - extern int sysctl_unix_max_dgram_qlen; ctl_table unix_table[] = { @@ -26,20 +22,18 @@ ctl_table unix_table[] = { {0} }; -static struct ctl_table_header * unix_sysctl_header; -static struct ctl_table unix_root_table[]; -static struct ctl_table unix_net_table[]; - -ctl_table unix_root_table[] = { - {CTL_NET, "net", NULL, 0, 0555, unix_net_table}, +static ctl_table unix_net_table[] = { + {NET_UNIX, "unix", NULL, 0, 0555, unix_table}, {0} }; -ctl_table unix_net_table[] = { - {NET_UNIX, "unix", NULL, 0, 0555, unix_table}, +static ctl_table unix_root_table[] = { + {CTL_NET, "net", NULL, 0, 0555, unix_net_table}, {0} }; +static struct ctl_table_header * unix_sysctl_header; + void unix_sysctl_register(void) { unix_sysctl_header = register_sysctl_table(unix_root_table, 0); @@ -50,4 +44,3 @@ void unix_sysctl_unregister(void) unregister_sysctl_table(unix_sysctl_header); } -#endif /* CONFIG_SYSCTL */ diff --git a/net/x25/Makefile b/net/x25/Makefile index 0890eff84b8a..d0082933f1eb 100644 --- a/net/x25/Makefile +++ b/net/x25/Makefile @@ -17,5 +17,3 @@ obj-$(CONFIG_SYSCTL) += sysctl_net_x25.o include $(TOPDIR)/Rules.make -tar: - tar -cvf /dev/f1 . diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index c8f8c3e974a2..a938f3bc1b3c 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -1084,6 +1084,9 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size, int fl msg->msg_namelen = sizeof(struct sockaddr_x25); skb_free_datagram(sk, skb); + lock_sock(sk); + x25_check_rbuf(sk); + release_sock(sk); return copied; } @@ -1258,8 +1261,8 @@ static int x25_get_info(char *buffer, char **start, off_t offset, int length) } struct net_proto_family x25_family_ops = { - AF_X25, - x25_create + family: AF_X25, + create: x25_create, }; static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { @@ -1286,18 +1289,13 @@ static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = { SOCKOPS_WRAP(x25_proto, AF_X25); -static struct packet_type x25_packet_type = -{ - 0, /* MUTTER ntohs(ETH_P_X25),*/ - 0, /* copy */ - x25_lapb_receive_frame, - NULL, - NULL, +static struct packet_type x25_packet_type = { + type: __constant_htons(ETH_P_X25), + func: x25_lapb_receive_frame, }; struct notifier_block x25_dev_notifier = { - x25_device_event, - 0 + notifier_call: x25_device_event, }; void x25_kill_by_neigh(struct x25_neigh *neigh) @@ -1317,7 +1315,6 @@ static int __init x25_init(void) #endif /* MODULE */ sock_register(&x25_family_ops); - x25_packet_type.type = htons(ETH_P_X25); dev_add_pack(&x25_packet_type); register_netdevice_notifier(&x25_dev_notifier); diff --git a/net/x25/x25_dev.c b/net/x25/x25_dev.c index fbc781dcecaf..1abb28358041 100644 --- a/net/x25/x25_dev.c +++ b/net/x25/x25_dev.c @@ -18,7 +18,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -249,8 +248,3 @@ void x25_send_frame(struct sk_buff *skb, struct x25_neigh *neigh) dev_queue_xmit(skb); } - -#endif - - - diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c index ad41d1cde1ce..cdd3f3e53fa3 100644 --- a/net/x25/x25_facilities.c +++ b/net/x25/x25_facilities.c @@ -19,7 +19,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -232,7 +231,3 @@ void x25_limit_facilities(struct x25_facilities *facilities, } } } - -#endif - - diff --git a/net/x25/x25_in.c b/net/x25/x25_in.c index bcb5f1cf49b6..34e6c4190b35 100644 --- a/net/x25/x25_in.c +++ b/net/x25/x25_in.c @@ -23,7 +23,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -369,5 +368,3 @@ int x25_backlog_rcv(struct sock *sk, struct sk_buff *skb) return 0; } - -#endif diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index d6b878371127..1401c90dee89 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c @@ -21,7 +21,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -42,9 +41,10 @@ #include <linux/fcntl.h> #include <linux/mm.h> #include <linux/interrupt.h> +#include <linux/init.h> #include <net/x25.h> -static struct x25_neigh *x25_neigh_list = NULL; +static struct x25_neigh *x25_neigh_list /* = NULL initially */; static void x25_t20timer_expiry(unsigned long); @@ -422,12 +422,11 @@ int x25_subscr_ioctl(unsigned int cmd, void *arg) return 0; } -#ifdef MODULE /* * Release all memory associated with X.25 neighbour structures. */ -void x25_link_free(void) +void __exit x25_link_free(void) { struct x25_neigh *neigh, *x25_neigh = x25_neigh_list; @@ -438,7 +437,3 @@ void x25_link_free(void) x25_remove_neigh(neigh); } } - -#endif - -#endif diff --git a/net/x25/x25_out.c b/net/x25/x25_out.c index b3ce30477097..e7a429bf6b73 100644 --- a/net/x25/x25_out.c +++ b/net/x25/x25_out.c @@ -22,7 +22,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -229,5 +228,3 @@ void x25_enquiry_response(struct sock *sk) x25_stop_timer(sk); } - -#endif diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c index 4cb51300bc19..a4651699ea72 100644 --- a/net/x25/x25_route.c +++ b/net/x25/x25_route.c @@ -17,7 +17,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -42,9 +41,10 @@ #include <linux/mm.h> #include <linux/interrupt.h> #include <linux/notifier.h> +#include <linux/init.h> #include <net/x25.h> -static struct x25_route *x25_route_list = NULL; +static struct x25_route *x25_route_list /* = NULL initially */; /* * Add a new route. @@ -255,12 +255,10 @@ int x25_routes_get_info(char *buffer, char **start, off_t offset, int length) return len; } -#ifdef MODULE - /* * Release all memory associated with X.25 routing structures. */ -void x25_route_free(void) +void __exit x25_route_free(void) { struct x25_route *route, *x25_route = x25_route_list; @@ -271,7 +269,3 @@ void x25_route_free(void) x25_remove_route(route); } } - -#endif - -#endif diff --git a/net/x25/x25_subr.c b/net/x25/x25_subr.c index 25a700af937b..d81f00ba85e0 100644 --- a/net/x25/x25_subr.c +++ b/net/x25/x25_subr.c @@ -20,7 +20,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -351,4 +350,18 @@ void x25_disconnect(struct sock *sk, int reason, unsigned char cause, unsigned c sk->dead = 1; } -#endif +/* + * Clear an own-rx-busy condition and tell the peer about this, provided + * that there is a significant amount of free receive buffer space available. + */ +void x25_check_rbuf(struct sock *sk) +{ + if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) && + (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) { + sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY; + sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING; + sk->protinfo.x25->vl = sk->protinfo.x25->vr; + x25_write_internal(sk, X25_RR); + x25_stop_timer(sk); + } +} diff --git a/net/x25/x25_timer.c b/net/x25/x25_timer.c index 20672419e623..c30ccb626fe6 100644 --- a/net/x25/x25_timer.c +++ b/net/x25/x25_timer.c @@ -19,7 +19,6 @@ */ #include <linux/config.h> -#if defined(CONFIG_X25) || defined(CONFIG_X25_MODULE) #include <linux/errno.h> #include <linux/types.h> #include <linux/socket.h> @@ -121,6 +120,11 @@ static void x25_heartbeat_expiry(unsigned long param) { struct sock *sk = (struct sock *)param; + bh_lock_sock(sk); + if (sk->lock.users) { /* can currently only occur in state 3 */ + goto restart_heartbeat; + } + switch (sk->protinfo.x25->state) { case X25_STATE_0: @@ -128,7 +132,7 @@ static void x25_heartbeat_expiry(unsigned long param) is accepted() it isn't 'dead' so doesn't get removed. */ if (sk->destroy || (sk->state == TCP_LISTEN && sk->dead)) { x25_destroy_socket(sk); - return; + goto unlock; } break; @@ -136,29 +140,21 @@ static void x25_heartbeat_expiry(unsigned long param) /* * Check for the state of the receive buffer. */ - if (atomic_read(&sk->rmem_alloc) < (sk->rcvbuf / 2) && - (sk->protinfo.x25->condition & X25_COND_OWN_RX_BUSY)) { - sk->protinfo.x25->condition &= ~X25_COND_OWN_RX_BUSY; - sk->protinfo.x25->condition &= ~X25_COND_ACK_PENDING; - sk->protinfo.x25->vl = sk->protinfo.x25->vr; - x25_write_internal(sk, X25_RR); - x25_stop_timer(sk); - break; - } + x25_check_rbuf(sk); break; } - + restart_heartbeat: x25_start_heartbeat(sk); + unlock: + bh_unlock_sock(sk); } /* * Timer has expired, it may have been T2, T21, T22, or T23. We can tell * by the state machine state. */ -static void x25_timer_expiry(unsigned long param) +static inline void x25_do_timer_expiry(struct sock * sk) { - struct sock *sk = (struct sock *)param; - switch (sk->protinfo.x25->state) { case X25_STATE_3: /* T2 */ @@ -181,4 +177,17 @@ static void x25_timer_expiry(unsigned long param) } } -#endif +static void x25_timer_expiry(unsigned long param) +{ + struct sock *sk = (struct sock *)param; + + bh_lock_sock(sk); + if (sk->lock.users) { /* can currently only occur in state 3 */ + if (sk->protinfo.x25->state == X25_STATE_3) { + x25_start_t2timer(sk); + } + } else { + x25_do_timer_expiry(sk); + } + bh_unlock_sock(sk); +} |
