From 2a9bc71e9a1a099e1aab745f1755a3c15a745ad8 Mon Sep 17 00:00:00 2001 From: Tony Zelenoff Date: Fri, 13 Apr 2012 06:09:53 +0000 Subject: atl1: do not process interrupts in cycle in handler As the rx/tx handled inside napi handler, the cycle is not needed now, because only the rx/tx need such kind of processing. Signed-off-by: Tony Zelenoff Signed-off-by: David S. Miller --- scripts/mod/file2alias.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'scripts') diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8e730ccc3f2..44ddaa542db 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -1100,6 +1100,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections) return; + /* We're looking for an object */ + if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) + return; + /* All our symbols are of form __mod_XXX_device_table. */ name = strstr(symname, "__mod_"); if (!name) -- cgit v1.2.3-70-g09d2 From a79f248b9b309ebb5f34ca6a8fd1eb9e18db5720 Mon Sep 17 00:00:00 2001 From: David Daney Date: Thu, 19 Apr 2012 14:59:55 -0700 Subject: scripts: Add sortextable to sort the kernel's exception table. Using this build-time sort saves time booting as we don't have to burn cycles sorting the exception table. Signed-off-by: David Daney Link: http://lkml.kernel.org/r/1334872799-14589-2-git-send-email-ddaney.cavm@gmail.com Signed-off-by: H. Peter Anvin --- scripts/.gitignore | 1 + scripts/Makefile | 1 + scripts/sortextable.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++++++ scripts/sortextable.h | 168 +++++++++++++++++++++++++++++++ 4 files changed, 441 insertions(+) create mode 100644 scripts/sortextable.c create mode 100644 scripts/sortextable.h (limited to 'scripts') diff --git a/scripts/.gitignore b/scripts/.gitignore index 105b21f0818..65f362d931b 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -9,3 +9,4 @@ unifdef ihex2fw recordmcount docproc +sortextable diff --git a/scripts/Makefile b/scripts/Makefile index df7678febf2..43e19b9fc64 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -13,6 +13,7 @@ hostprogs-$(CONFIG_LOGO) += pnmtologo hostprogs-$(CONFIG_VT) += conmakehash hostprogs-$(CONFIG_IKCONFIG) += bin2c hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount +hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable always := $(hostprogs-y) $(hostprogs-m) diff --git a/scripts/sortextable.c b/scripts/sortextable.c new file mode 100644 index 00000000000..f51f1d43da6 --- /dev/null +++ b/scripts/sortextable.c @@ -0,0 +1,271 @@ +/* + * sortextable.c: Sort the kernel's exception table + * + * Copyright 2011 Cavium, Inc. + * + * Based on code taken from recortmcount.c which is: + * + * Copyright 2009 John F. Reiser . All rights reserved. + * Licensed under the GNU General Public License, version 2 (GPLv2). + * + * Restructured to fit Linux format, as well as other updates: + * Copyright 2010 Steven Rostedt , Red Hat Inc. + */ + +/* + * Strategy: alter the vmlinux file in-place. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int fd_map; /* File descriptor for file being modified. */ +static int mmap_failed; /* Boolean flag. */ +static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ +static struct stat sb; /* Remember .st_size, etc. */ +static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ + +/* setjmp() return values */ +enum { + SJ_SETJMP = 0, /* hardwired first return */ + SJ_FAIL, + SJ_SUCCEED +}; + +/* Per-file resource cleanup when multiple files. */ +static void +cleanup(void) +{ + if (!mmap_failed) + munmap(ehdr_curr, sb.st_size); + close(fd_map); +} + +static void __attribute__((noreturn)) +fail_file(void) +{ + cleanup(); + longjmp(jmpenv, SJ_FAIL); +} + +static void __attribute__((noreturn)) +succeed_file(void) +{ + cleanup(); + longjmp(jmpenv, SJ_SUCCEED); +} + + +/* + * Get the whole file as a programming convenience in order to avoid + * malloc+lseek+read+free of many pieces. If successful, then mmap + * avoids copying unused pieces; else just read the whole file. + * Open for both read and write. + */ +static void *mmap_file(char const *fname) +{ + void *addr; + + fd_map = open(fname, O_RDWR); + if (fd_map < 0 || fstat(fd_map, &sb) < 0) { + perror(fname); + fail_file(); + } + if (!S_ISREG(sb.st_mode)) { + fprintf(stderr, "not a regular file: %s\n", fname); + fail_file(); + } + addr = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, MAP_SHARED, + fd_map, 0); + if (addr == MAP_FAILED) { + mmap_failed = 1; + fprintf(stderr, "Could not mmap file: %s\n", fname); + fail_file(); + } + return addr; +} + +/* w8rev, w8nat, ...: Handle endianness. */ + +static uint64_t w8rev(uint64_t const x) +{ + return ((0xff & (x >> (0 * 8))) << (7 * 8)) + | ((0xff & (x >> (1 * 8))) << (6 * 8)) + | ((0xff & (x >> (2 * 8))) << (5 * 8)) + | ((0xff & (x >> (3 * 8))) << (4 * 8)) + | ((0xff & (x >> (4 * 8))) << (3 * 8)) + | ((0xff & (x >> (5 * 8))) << (2 * 8)) + | ((0xff & (x >> (6 * 8))) << (1 * 8)) + | ((0xff & (x >> (7 * 8))) << (0 * 8)); +} + +static uint32_t w4rev(uint32_t const x) +{ + return ((0xff & (x >> (0 * 8))) << (3 * 8)) + | ((0xff & (x >> (1 * 8))) << (2 * 8)) + | ((0xff & (x >> (2 * 8))) << (1 * 8)) + | ((0xff & (x >> (3 * 8))) << (0 * 8)); +} + +static uint32_t w2rev(uint16_t const x) +{ + return ((0xff & (x >> (0 * 8))) << (1 * 8)) + | ((0xff & (x >> (1 * 8))) << (0 * 8)); +} + +static uint64_t w8nat(uint64_t const x) +{ + return x; +} + +static uint32_t w4nat(uint32_t const x) +{ + return x; +} + +static uint32_t w2nat(uint16_t const x) +{ + return x; +} + +static uint64_t (*w8)(uint64_t); +static uint32_t (*w)(uint32_t); +static uint32_t (*w2)(uint16_t); + + +/* 32 bit and 64 bit are very similar */ +#include "sortextable.h" +#define SORTEXTABLE_64 +#include "sortextable.h" + + +static void +do_file(char const *const fname) +{ + Elf32_Ehdr *const ehdr = mmap_file(fname); + + ehdr_curr = ehdr; + w = w4nat; + w2 = w2nat; + w8 = w8nat; + switch (ehdr->e_ident[EI_DATA]) { + static unsigned int const endian = 1; + default: + fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", + ehdr->e_ident[EI_DATA], fname); + fail_file(); + break; + case ELFDATA2LSB: + if (*(unsigned char const *)&endian != 1) { + /* main() is big endian, file.o is little endian. */ + w = w4rev; + w2 = w2rev; + w8 = w8rev; + } + break; + case ELFDATA2MSB: + if (*(unsigned char const *)&endian != 0) { + /* main() is little endian, file.o is big endian. */ + w = w4rev; + w2 = w2rev; + w8 = w8rev; + } + break; + } /* end switch */ + if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 + || w2(ehdr->e_type) != ET_EXEC + || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { + fprintf(stderr, "unrecognized ET_EXEC file %s\n", fname); + fail_file(); + } + + switch (w2(ehdr->e_machine)) { + default: + fprintf(stderr, "unrecognized e_machine %d %s\n", + w2(ehdr->e_machine), fname); + fail_file(); + break; + case EM_386: + case EM_MIPS: + case EM_X86_64: + break; + } /* end switch */ + + switch (ehdr->e_ident[EI_CLASS]) { + default: + fprintf(stderr, "unrecognized ELF class %d %s\n", + ehdr->e_ident[EI_CLASS], fname); + fail_file(); + break; + case ELFCLASS32: + if (w2(ehdr->e_ehsize) != sizeof(Elf32_Ehdr) + || w2(ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { + fprintf(stderr, + "unrecognized ET_EXEC file: %s\n", fname); + fail_file(); + } + do32(ehdr, fname); + break; + case ELFCLASS64: { + Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; + if (w2(ghdr->e_ehsize) != sizeof(Elf64_Ehdr) + || w2(ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { + fprintf(stderr, + "unrecognized ET_EXEC file: %s\n", fname); + fail_file(); + } + do64(ghdr, fname); + break; + } + } /* end switch */ + + cleanup(); +} + +int +main(int argc, char *argv[]) +{ + int n_error = 0; /* gcc-4.3.0 false positive complaint */ + int i; + + if (argc < 2) { + fprintf(stderr, "usage: sortextable vmlinux...\n"); + return 0; + } + + /* Process each file in turn, allowing deep failure. */ + for (i = 1; i < argc; i++) { + char *file = argv[i]; + int const sjval = setjmp(jmpenv); + + switch (sjval) { + default: + fprintf(stderr, "internal error: %s\n", file); + exit(1); + break; + case SJ_SETJMP: /* normal sequence */ + /* Avoid problems if early cleanup() */ + fd_map = -1; + ehdr_curr = NULL; + mmap_failed = 1; + do_file(file); + break; + case SJ_FAIL: /* error in do_file or below */ + ++n_error; + break; + case SJ_SUCCEED: /* premature success */ + /* do nothing */ + break; + } /* end switch */ + } + return !!n_error; +} diff --git a/scripts/sortextable.h b/scripts/sortextable.h new file mode 100644 index 00000000000..bb6aaf16600 --- /dev/null +++ b/scripts/sortextable.h @@ -0,0 +1,168 @@ +/* + * sortextable.h + * + * Copyright 2011 Cavium, Inc. + * + * Some of this code was taken out of recordmcount.h written by: + * + * Copyright 2009 John F. Reiser . All rights reserved. + * Copyright 2010 Steven Rostedt , Red Hat Inc. + * + * + * Licensed under the GNU General Public License, version 2 (GPLv2). + */ + +#undef extable_ent_size +#undef compare_extable +#undef do_func +#undef Elf_Addr +#undef Elf_Ehdr +#undef Elf_Shdr +#undef Elf_Rel +#undef Elf_Rela +#undef Elf_Sym +#undef ELF_R_SYM +#undef Elf_r_sym +#undef ELF_R_INFO +#undef Elf_r_info +#undef ELF_ST_BIND +#undef ELF_ST_TYPE +#undef fn_ELF_R_SYM +#undef fn_ELF_R_INFO +#undef uint_t +#undef _w + +#ifdef SORTEXTABLE_64 +# define extable_ent_size 16 +# define compare_extable compare_extable_64 +# define do_func do64 +# define Elf_Addr Elf64_Addr +# define Elf_Ehdr Elf64_Ehdr +# define Elf_Shdr Elf64_Shdr +# define Elf_Rel Elf64_Rel +# define Elf_Rela Elf64_Rela +# define Elf_Sym Elf64_Sym +# define ELF_R_SYM ELF64_R_SYM +# define Elf_r_sym Elf64_r_sym +# define ELF_R_INFO ELF64_R_INFO +# define Elf_r_info Elf64_r_info +# define ELF_ST_BIND ELF64_ST_BIND +# define ELF_ST_TYPE ELF64_ST_TYPE +# define fn_ELF_R_SYM fn_ELF64_R_SYM +# define fn_ELF_R_INFO fn_ELF64_R_INFO +# define uint_t uint64_t +# define _w w8 +#else +# define extable_ent_size 8 +# define compare_extable compare_extable_32 +# define do_func do32 +# define Elf_Addr Elf32_Addr +# define Elf_Ehdr Elf32_Ehdr +# define Elf_Shdr Elf32_Shdr +# define Elf_Rel Elf32_Rel +# define Elf_Rela Elf32_Rela +# define Elf_Sym Elf32_Sym +# define ELF_R_SYM ELF32_R_SYM +# define Elf_r_sym Elf32_r_sym +# define ELF_R_INFO ELF32_R_INFO +# define Elf_r_info Elf32_r_info +# define ELF_ST_BIND ELF32_ST_BIND +# define ELF_ST_TYPE ELF32_ST_TYPE +# define fn_ELF_R_SYM fn_ELF32_R_SYM +# define fn_ELF_R_INFO fn_ELF32_R_INFO +# define uint_t uint32_t +# define _w w +#endif + +static int compare_extable(const void *a, const void *b) +{ + const uint_t *aa = a; + const uint_t *bb = b; + + if (_w(*aa) < _w(*bb)) + return -1; + if (_w(*aa) > _w(*bb)) + return 1; + return 0; +} + +static void +do_func(Elf_Ehdr *const ehdr, char const *const fname) +{ + Elf_Shdr *shdr; + Elf_Shdr *shstrtab_sec; + Elf_Shdr *strtab_sec = NULL; + Elf_Shdr *symtab_sec = NULL; + Elf_Shdr *extab_sec = NULL; + Elf_Sym *sym; + Elf_Sym *sort_needed_sym; + Elf_Shdr *sort_needed_sec; + uint32_t *sort_done_location; + const char *secstrtab; + const char *strtab; + int i; + int idx; + + shdr = (Elf_Shdr *)((void *)ehdr + _w(ehdr->e_shoff)); + shstrtab_sec = shdr + w2(ehdr->e_shstrndx); + secstrtab = (const char *)ehdr + _w(shstrtab_sec->sh_offset); + for (i = 0; i < w2(ehdr->e_shnum); i++) { + idx = w(shdr[i].sh_name); + if (strcmp(secstrtab + idx, "__ex_table") == 0) + extab_sec = shdr + i; + if (strcmp(secstrtab + idx, ".symtab") == 0) + symtab_sec = shdr + i; + if (strcmp(secstrtab + idx, ".strtab") == 0) + strtab_sec = shdr + i; + } + if (strtab_sec == NULL) { + fprintf(stderr, "no .strtab in file: %s\n", fname); + fail_file(); + } + if (symtab_sec == NULL) { + fprintf(stderr, "no .symtab in file: %s\n", fname); + fail_file(); + } + if (extab_sec == NULL) { + fprintf(stderr, "no __ex_table in file: %s\n", fname); + fail_file(); + } + strtab = (const char *)ehdr + _w(strtab_sec->sh_offset); + + /* Sort the table in place */ + qsort((void *)ehdr + _w(extab_sec->sh_offset), + (_w(extab_sec->sh_size) / extable_ent_size), + extable_ent_size, compare_extable); + + /* find main_extable_sort_needed */ + sort_needed_sym = NULL; + for (i = 0; i < _w(symtab_sec->sh_size) / sizeof(Elf_Sym); i++) { + sym = (void *)ehdr + _w(symtab_sec->sh_offset); + sym += i; + if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) + continue; + idx = w(sym->st_name); + if (strcmp(strtab + idx, "main_extable_sort_needed") == 0) { + sort_needed_sym = sym; + break; + } + } + if (sort_needed_sym == NULL) { + fprintf(stderr, + "no main_extable_sort_needed symbol in file: %s\n", + fname); + fail_file(); + } + sort_needed_sec = &shdr[w2(sort_needed_sym->st_shndx)]; + sort_done_location = (void *)ehdr + + _w(sort_needed_sec->sh_offset) + + _w(sort_needed_sym->st_value) - + _w(sort_needed_sec->sh_addr); + + printf("sort done marker at %lx\n", + (unsigned long) (_w(sort_needed_sec->sh_offset) + + _w(sort_needed_sym->st_value) - + _w(sort_needed_sec->sh_addr))); + /* We sorted it, clear the flag. */ + *sort_done_location = 0; +} -- cgit v1.2.3-70-g09d2 From d59a16836d917548cf41eda3369936684d527f5f Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 24 Apr 2012 11:23:14 -0700 Subject: scripts/sortextable: Handle relative entries, and other cleanups x86 is now using relative rather than absolute addresses in its exception table, so we add a sorter for these. If there are relocations on the __ex_table section, they are redundant and probably incorrect after the sort, so they are zeroed out leaving them valid and consistent. Also use the unaligned safe accessors from tools/{be,le}_byteshift.h Signed-off-by: David Daney Link: http://lkml.kernel.org/r/1335291795-26693-2-git-send-email-ddaney.cavm@gmail.com Signed-off-by: H. Peter Anvin --- scripts/Makefile | 2 + scripts/sortextable.c | 171 ++++++++++++++++++++++++++++++++------------------ scripts/sortextable.h | 79 ++++++++++++++--------- 3 files changed, 164 insertions(+), 88 deletions(-) (limited to 'scripts') diff --git a/scripts/Makefile b/scripts/Makefile index 43e19b9fc64..9eace52c64d 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -15,6 +15,8 @@ hostprogs-$(CONFIG_IKCONFIG) += bin2c hostprogs-$(BUILD_C_RECORDMCOUNT) += recordmcount hostprogs-$(CONFIG_BUILDTIME_EXTABLE_SORT) += sortextable +HOSTCFLAGS_sortextable.o = -I$(srctree)/tools/include + always := $(hostprogs-y) $(hostprogs-m) # The following hostprogs-y programs are only build on demand diff --git a/scripts/sortextable.c b/scripts/sortextable.c index f51f1d43da6..1ca9ceb95eb 100644 --- a/scripts/sortextable.c +++ b/scripts/sortextable.c @@ -1,7 +1,7 @@ /* * sortextable.c: Sort the kernel's exception table * - * Copyright 2011 Cavium, Inc. + * Copyright 2011 - 2012 Cavium, Inc. * * Based on code taken from recortmcount.c which is: * @@ -28,6 +28,9 @@ #include #include +#include +#include + static int fd_map; /* File descriptor for file being modified. */ static int mmap_failed; /* Boolean flag. */ static void *ehdr_curr; /* current ElfXX_Ehdr * for resource cleanup */ @@ -94,109 +97,157 @@ static void *mmap_file(char const *fname) return addr; } -/* w8rev, w8nat, ...: Handle endianness. */ - -static uint64_t w8rev(uint64_t const x) +static uint64_t r8be(const uint64_t *x) { - return ((0xff & (x >> (0 * 8))) << (7 * 8)) - | ((0xff & (x >> (1 * 8))) << (6 * 8)) - | ((0xff & (x >> (2 * 8))) << (5 * 8)) - | ((0xff & (x >> (3 * 8))) << (4 * 8)) - | ((0xff & (x >> (4 * 8))) << (3 * 8)) - | ((0xff & (x >> (5 * 8))) << (2 * 8)) - | ((0xff & (x >> (6 * 8))) << (1 * 8)) - | ((0xff & (x >> (7 * 8))) << (0 * 8)); + return get_unaligned_be64(x); } - -static uint32_t w4rev(uint32_t const x) +static uint32_t rbe(const uint32_t *x) { - return ((0xff & (x >> (0 * 8))) << (3 * 8)) - | ((0xff & (x >> (1 * 8))) << (2 * 8)) - | ((0xff & (x >> (2 * 8))) << (1 * 8)) - | ((0xff & (x >> (3 * 8))) << (0 * 8)); + return get_unaligned_be32(x); } - -static uint32_t w2rev(uint16_t const x) +static uint16_t r2be(const uint16_t *x) { - return ((0xff & (x >> (0 * 8))) << (1 * 8)) - | ((0xff & (x >> (1 * 8))) << (0 * 8)); + return get_unaligned_be16(x); } - -static uint64_t w8nat(uint64_t const x) +static uint64_t r8le(const uint64_t *x) { - return x; + return get_unaligned_le64(x); } - -static uint32_t w4nat(uint32_t const x) +static uint32_t rle(const uint32_t *x) +{ + return get_unaligned_le32(x); +} +static uint16_t r2le(const uint16_t *x) { - return x; + return get_unaligned_le16(x); } -static uint32_t w2nat(uint16_t const x) +static void w8be(uint64_t val, uint64_t *x) +{ + put_unaligned_be64(val, x); +} +static void wbe(uint32_t val, uint32_t *x) +{ + put_unaligned_be32(val, x); +} +static void w2be(uint16_t val, uint16_t *x) +{ + put_unaligned_be16(val, x); +} +static void w8le(uint64_t val, uint64_t *x) +{ + put_unaligned_le64(val, x); +} +static void wle(uint32_t val, uint32_t *x) +{ + put_unaligned_le32(val, x); +} +static void w2le(uint16_t val, uint16_t *x) { - return x; + put_unaligned_le16(val, x); } -static uint64_t (*w8)(uint64_t); -static uint32_t (*w)(uint32_t); -static uint32_t (*w2)(uint16_t); +static uint64_t (*r8)(const uint64_t *); +static uint32_t (*r)(const uint32_t *); +static uint16_t (*r2)(const uint16_t *); +static void (*w8)(uint64_t, uint64_t *); +static void (*w)(uint32_t, uint32_t *); +static void (*w2)(uint16_t, uint16_t *); +typedef void (*table_sort_t)(char *, int); /* 32 bit and 64 bit are very similar */ #include "sortextable.h" #define SORTEXTABLE_64 #include "sortextable.h" +static int compare_x86_table(const void *a, const void *b) +{ + int32_t av = (int32_t)r(a); + int32_t bv = (int32_t)r(b); + + if (av < bv) + return -1; + if (av > bv) + return 1; + return 0; +} + +static void sort_x86_table(char *extab_image, int image_size) +{ + int i; + + /* + * Do the same thing the runtime sort does, first normalize to + * being relative to the start of the section. + */ + i = 0; + while (i < image_size) { + uint32_t *loc = (uint32_t *)(extab_image + i); + w(r(loc) + i, loc); + i += 4; + } + + qsort(extab_image, image_size / 8, 8, compare_x86_table); + + /* Now denormalize. */ + i = 0; + while (i < image_size) { + uint32_t *loc = (uint32_t *)(extab_image + i); + w(r(loc) - i, loc); + i += 4; + } +} static void do_file(char const *const fname) { - Elf32_Ehdr *const ehdr = mmap_file(fname); + table_sort_t custom_sort; + Elf32_Ehdr *ehdr = mmap_file(fname); ehdr_curr = ehdr; - w = w4nat; - w2 = w2nat; - w8 = w8nat; switch (ehdr->e_ident[EI_DATA]) { - static unsigned int const endian = 1; default: fprintf(stderr, "unrecognized ELF data encoding %d: %s\n", ehdr->e_ident[EI_DATA], fname); fail_file(); break; case ELFDATA2LSB: - if (*(unsigned char const *)&endian != 1) { - /* main() is big endian, file.o is little endian. */ - w = w4rev; - w2 = w2rev; - w8 = w8rev; - } + r = rle; + r2 = r2le; + r8 = r8le; + w = wle; + w2 = w2le; + w8 = w8le; break; case ELFDATA2MSB: - if (*(unsigned char const *)&endian != 0) { - /* main() is little endian, file.o is big endian. */ - w = w4rev; - w2 = w2rev; - w8 = w8rev; - } + r = rbe; + r2 = r2be; + r8 = r8be; + w = wbe; + w2 = w2be; + w8 = w8be; break; } /* end switch */ if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 - || w2(ehdr->e_type) != ET_EXEC + || r2(&ehdr->e_type) != ET_EXEC || ehdr->e_ident[EI_VERSION] != EV_CURRENT) { fprintf(stderr, "unrecognized ET_EXEC file %s\n", fname); fail_file(); } - switch (w2(ehdr->e_machine)) { + custom_sort = NULL; + switch (r2(&ehdr->e_machine)) { default: fprintf(stderr, "unrecognized e_machine %d %s\n", - w2(ehdr->e_machine), fname); + r2(&ehdr->e_machine), fname); fail_file(); break; case EM_386: - case EM_MIPS: case EM_X86_64: + custom_sort = sort_x86_table; + break; + case EM_MIPS: break; } /* end switch */ @@ -207,23 +258,23 @@ do_file(char const *const fname) fail_file(); break; case ELFCLASS32: - if (w2(ehdr->e_ehsize) != sizeof(Elf32_Ehdr) - || w2(ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { + if (r2(&ehdr->e_ehsize) != sizeof(Elf32_Ehdr) + || r2(&ehdr->e_shentsize) != sizeof(Elf32_Shdr)) { fprintf(stderr, "unrecognized ET_EXEC file: %s\n", fname); fail_file(); } - do32(ehdr, fname); + do32(ehdr, fname, custom_sort); break; case ELFCLASS64: { Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr; - if (w2(ghdr->e_ehsize) != sizeof(Elf64_Ehdr) - || w2(ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { + if (r2(&ghdr->e_ehsize) != sizeof(Elf64_Ehdr) + || r2(&ghdr->e_shentsize) != sizeof(Elf64_Shdr)) { fprintf(stderr, "unrecognized ET_EXEC file: %s\n", fname); fail_file(); } - do64(ghdr, fname); + do64(ghdr, fname, custom_sort); break; } } /* end switch */ diff --git a/scripts/sortextable.h b/scripts/sortextable.h index bb6aaf16600..e4fd45b7e45 100644 --- a/scripts/sortextable.h +++ b/scripts/sortextable.h @@ -1,7 +1,7 @@ /* * sortextable.h * - * Copyright 2011 Cavium, Inc. + * Copyright 2011 - 2012 Cavium, Inc. * * Some of this code was taken out of recordmcount.h written by: * @@ -30,6 +30,7 @@ #undef fn_ELF_R_SYM #undef fn_ELF_R_INFO #undef uint_t +#undef _r #undef _w #ifdef SORTEXTABLE_64 @@ -51,6 +52,7 @@ # define fn_ELF_R_SYM fn_ELF64_R_SYM # define fn_ELF_R_INFO fn_ELF64_R_INFO # define uint_t uint64_t +# define _r r8 # define _w w8 #else # define extable_ent_size 8 @@ -71,23 +73,24 @@ # define fn_ELF_R_SYM fn_ELF32_R_SYM # define fn_ELF_R_INFO fn_ELF32_R_INFO # define uint_t uint32_t +# define _r r # define _w w #endif static int compare_extable(const void *a, const void *b) { - const uint_t *aa = a; - const uint_t *bb = b; + Elf_Addr av = _r(a); + Elf_Addr bv = _r(b); - if (_w(*aa) < _w(*bb)) + if (av < bv) return -1; - if (_w(*aa) > _w(*bb)) + if (av > bv) return 1; return 0; } static void -do_func(Elf_Ehdr *const ehdr, char const *const fname) +do_func(Elf_Ehdr *ehdr, char const *const fname, table_sort_t custom_sort) { Elf_Shdr *shdr; Elf_Shdr *shstrtab_sec; @@ -97,19 +100,31 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname) Elf_Sym *sym; Elf_Sym *sort_needed_sym; Elf_Shdr *sort_needed_sec; + Elf_Rel *relocs = NULL; + int relocs_size; uint32_t *sort_done_location; const char *secstrtab; const char *strtab; + char *extab_image; + int extab_index = 0; int i; int idx; - shdr = (Elf_Shdr *)((void *)ehdr + _w(ehdr->e_shoff)); - shstrtab_sec = shdr + w2(ehdr->e_shstrndx); - secstrtab = (const char *)ehdr + _w(shstrtab_sec->sh_offset); - for (i = 0; i < w2(ehdr->e_shnum); i++) { - idx = w(shdr[i].sh_name); - if (strcmp(secstrtab + idx, "__ex_table") == 0) + shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff)); + shstrtab_sec = shdr + r2(&ehdr->e_shstrndx); + secstrtab = (const char *)ehdr + _r(&shstrtab_sec->sh_offset); + for (i = 0; i < r2(&ehdr->e_shnum); i++) { + idx = r(&shdr[i].sh_name); + if (strcmp(secstrtab + idx, "__ex_table") == 0) { extab_sec = shdr + i; + extab_index = i; + } + if ((r(&shdr[i].sh_type) == SHT_REL || + r(&shdr[i].sh_type) == SHT_RELA) && + r(&shdr[i].sh_info) == extab_index) { + relocs = (void *)ehdr + _r(&shdr[i].sh_offset); + relocs_size = _r(&shdr[i].sh_size); + } if (strcmp(secstrtab + idx, ".symtab") == 0) symtab_sec = shdr + i; if (strcmp(secstrtab + idx, ".strtab") == 0) @@ -127,21 +142,29 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname) fprintf(stderr, "no __ex_table in file: %s\n", fname); fail_file(); } - strtab = (const char *)ehdr + _w(strtab_sec->sh_offset); + strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset); - /* Sort the table in place */ - qsort((void *)ehdr + _w(extab_sec->sh_offset), - (_w(extab_sec->sh_size) / extable_ent_size), - extable_ent_size, compare_extable); + extab_image = (void *)ehdr + _r(&extab_sec->sh_offset); + + if (custom_sort) { + custom_sort(extab_image, _r(&extab_sec->sh_size)); + } else { + int num_entries = _r(&extab_sec->sh_size) / extable_ent_size; + qsort(extab_image, num_entries, + extable_ent_size, compare_extable); + } + /* If there were relocations, we no longer need them. */ + if (relocs) + memset(relocs, 0, relocs_size); /* find main_extable_sort_needed */ sort_needed_sym = NULL; - for (i = 0; i < _w(symtab_sec->sh_size) / sizeof(Elf_Sym); i++) { - sym = (void *)ehdr + _w(symtab_sec->sh_offset); + for (i = 0; i < _r(&symtab_sec->sh_size) / sizeof(Elf_Sym); i++) { + sym = (void *)ehdr + _r(&symtab_sec->sh_offset); sym += i; if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) continue; - idx = w(sym->st_name); + idx = r(&sym->st_name); if (strcmp(strtab + idx, "main_extable_sort_needed") == 0) { sort_needed_sym = sym; break; @@ -153,16 +176,16 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname) fname); fail_file(); } - sort_needed_sec = &shdr[w2(sort_needed_sym->st_shndx)]; + sort_needed_sec = &shdr[r2(&sort_needed_sym->st_shndx)]; sort_done_location = (void *)ehdr + - _w(sort_needed_sec->sh_offset) + - _w(sort_needed_sym->st_value) - - _w(sort_needed_sec->sh_addr); + _r(&sort_needed_sec->sh_offset) + + _r(&sort_needed_sym->st_value) - + _r(&sort_needed_sec->sh_addr); +#if 1 printf("sort done marker at %lx\n", - (unsigned long) (_w(sort_needed_sec->sh_offset) + - _w(sort_needed_sym->st_value) - - _w(sort_needed_sec->sh_addr))); + (unsigned long)((char *)sort_done_location - (char *)ehdr)); +#endif /* We sorted it, clear the flag. */ - *sort_done_location = 0; + w(0, sort_done_location); } -- cgit v1.2.3-70-g09d2 From 4d53b8012f1f01ddb3f24db2031b042bb4cbd0d0 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 23 Apr 2012 12:07:02 +0200 Subject: HID: Add device group to modalias HID devices are only partially presented to userland. Hotplugged devices emit events containing a modalias based on the basic bus, vendor and product entities. However, in practise a hid device can depend on details such as a single usb interface or a particular item in a report descriptor. This patch adds a device group to the hid device id, and broadcasts it using uevent and the device modalias. The module alias generation is modified to match. As a consequence, a device with a non-zero group will be processed by the corresponding group driver instead of by the generic hid driver. Signed-off-by: Henrik Rydberg Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 24 ++++++++++++++++++++++-- include/linux/hid.h | 1 + include/linux/mod_devicetable.h | 3 ++- scripts/mod/file2alias.c | 2 ++ 4 files changed, 27 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 9ed4ff37dc2..cfcb69eb17d 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1222,6 +1222,7 @@ static bool hid_match_one_id(struct hid_device *hdev, const struct hid_device_id *id) { return id->bus == hdev->bus && + (id->group == HID_GROUP_ANY || id->group == hdev->group) && (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && (id->product == HID_ANY_ID || id->product == hdev->product); } @@ -1694,6 +1695,7 @@ static ssize_t store_new_id(struct device_driver *drv, const char *buf, return -ENOMEM; dynid->id.bus = bus; + dynid->id.group = HID_GROUP_ANY; dynid->id.vendor = vendor; dynid->id.product = product; dynid->id.driver_data = driver_data; @@ -1817,6 +1819,23 @@ static int hid_device_remove(struct device *dev) return 0; } +static ssize_t modalias_show(struct device *dev, struct device_attribute *a, + char *buf) +{ + struct hid_device *hdev = container_of(dev, struct hid_device, dev); + int len; + + len = snprintf(buf, PAGE_SIZE, "hid:b%04Xg%04Xv%08Xp%08X\n", + hdev->bus, hdev->group, hdev->vendor, hdev->product); + + return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; +} + +static struct device_attribute hid_dev_attrs[] = { + __ATTR_RO(modalias), + __ATTR_NULL, +}; + static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) { struct hid_device *hdev = container_of(dev, struct hid_device, dev); @@ -1834,8 +1853,8 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) if (add_uevent_var(env, "HID_UNIQ=%s", hdev->uniq)) return -ENOMEM; - if (add_uevent_var(env, "MODALIAS=hid:b%04Xv%08Xp%08X", - hdev->bus, hdev->vendor, hdev->product)) + if (add_uevent_var(env, "MODALIAS=hid:b%04Xg%04Xv%08Xp%08X", + hdev->bus, hdev->group, hdev->vendor, hdev->product)) return -ENOMEM; return 0; @@ -1843,6 +1862,7 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) static struct bus_type hid_bus_type = { .name = "hid", + .dev_attrs = hid_dev_attrs, .match = hid_bus_match, .probe = hid_device_probe, .remove = hid_device_remove, diff --git a/include/linux/hid.h b/include/linux/hid.h index d8e7cc7f894..a0e27ddb887 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -476,6 +476,7 @@ struct hid_device { /* device report descriptor */ unsigned maxcollection; /* Number of parsed collections */ unsigned maxapplication; /* Number of applications */ __u16 bus; /* BUS ID */ + __u16 group; /* Report group */ __u32 vendor; /* Vendor ID */ __u32 product; /* Product ID */ __u32 version; /* HID version */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 501da4cb8a6..55ed0b0dc61 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -132,10 +132,11 @@ struct usb_device_id { #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 #define HID_ANY_ID (~0) +#define HID_GROUP_ANY 0x0000 struct hid_device_id { __u16 bus; - __u16 pad1; + __u16 group; __u32 vendor; __u32 product; kernel_ulong_t driver_data diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 8e730ccc3f2..fe967cee737 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -336,10 +336,12 @@ static int do_hid_entry(const char *filename, struct hid_device_id *id, char *alias) { id->bus = TO_NATIVE(id->bus); + id->group = TO_NATIVE(id->group); id->vendor = TO_NATIVE(id->vendor); id->product = TO_NATIVE(id->product); sprintf(alias, "hid:b%04X", id->bus); + ADD(alias, "g", id->group != HID_GROUP_ANY, id->group); ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor); ADD(alias, "p", id->product != HID_ANY_ID, id->product); -- cgit v1.2.3-70-g09d2 From 7431fb767d896b7f0048039f2e17707ea057d35a Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Mon, 23 Apr 2012 12:07:04 +0200 Subject: HID: Allow bus wildcard matching Most HID drivers do not need to know what bus driver is in use. A generic group driver can drive any hid device, and the device list should not need to be duplicated for each new bus. This patch adds wildcard matching to the HID bus, simplifying device list handling for group drivers. Signed-off-by: Henrik Rydberg Acked-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 2 +- include/linux/mod_devicetable.h | 1 + scripts/mod/file2alias.c | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index f932cd533d4..20daee56d32 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1273,7 +1273,7 @@ EXPORT_SYMBOL_GPL(hid_input_report); static bool hid_match_one_id(struct hid_device *hdev, const struct hid_device_id *id) { - return id->bus == hdev->bus && + return (id->bus == HID_BUS_ANY || id->bus == hdev->bus) && (id->group == HID_GROUP_ANY || id->group == hdev->group) && (id->vendor == HID_ANY_ID || id->vendor == hdev->vendor) && (id->product == HID_ANY_ID || id->product == hdev->product); diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 55ed0b0dc61..5db93821f9c 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -132,6 +132,7 @@ struct usb_device_id { #define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 #define HID_ANY_ID (~0) +#define HID_BUS_ANY 0xffff #define HID_GROUP_ANY 0x0000 struct hid_device_id { diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index fe967cee737..056de3104e7 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c @@ -340,7 +340,8 @@ static int do_hid_entry(const char *filename, id->vendor = TO_NATIVE(id->vendor); id->product = TO_NATIVE(id->product); - sprintf(alias, "hid:b%04X", id->bus); + sprintf(alias, "hid:"); + ADD(alias, "b", id->bus != HID_BUS_ANY, id->bus); ADD(alias, "g", id->group != HID_GROUP_ANY, id->group); ADD(alias, "v", id->vendor != HID_ANY_ID, id->vendor); ADD(alias, "p", id->product != HID_ANY_ID, id->product); -- cgit v1.2.3-70-g09d2 From 5efe241eac80bb534fed0a965684c2d7527af5bf Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Thu, 26 Apr 2012 01:51:32 -0700 Subject: kconfig: Add error handling to KCONFIG_ALLCONFIG - Only try to read the file specified if KCONFIG_ALL_CONFIG is set to something other than the empty string or "1". - Don't use stat to check the name passed to conf_read_simple so that zconf_fopen can find the file in the current directory or in SRCTREE removing a extremely source of confusing failure, where KCONFIG_ALL_CONFIG was not interpreted with respect to the directory make was called in. - If conf_read_simple fails complain clearly and stop processing. Allowing the simple debugging of typos. - Clearly document the behavior so it is clear to users which values are treated as flags and which values are treated as filenames. Signed-off-by: Eric W. Biederman Signed-off-by: Michal Marek --- Documentation/kbuild/kconfig.txt | 18 +++++++++--------- scripts/kconfig/conf.c | 20 ++++++++++++++------ 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'scripts') diff --git a/Documentation/kbuild/kconfig.txt b/Documentation/kbuild/kconfig.txt index 9d5f2a90dca..a09f1a6a830 100644 --- a/Documentation/kbuild/kconfig.txt +++ b/Documentation/kbuild/kconfig.txt @@ -53,15 +53,15 @@ KCONFIG_ALLCONFIG -------------------------------------------------- (partially based on lkml email from/by Rob Landley, re: miniconfig) -------------------------------------------------- -The allyesconfig/allmodconfig/allnoconfig/randconfig variants can -also use the environment variable KCONFIG_ALLCONFIG as a flag or a -filename that contains config symbols that the user requires to be -set to a specific value. If KCONFIG_ALLCONFIG is used without a -filename, "make *config" checks for a file named -"all{yes/mod/no/def/random}.config" (corresponding to the *config command -that was used) for symbol values that are to be forced. If this file -is not found, it checks for a file named "all.config" to contain forced -values. +The allyesconfig/allmodconfig/allnoconfig/randconfig variants can also +use the environment variable KCONFIG_ALLCONFIG as a flag or a filename +that contains config symbols that the user requires to be set to a +specific value. If KCONFIG_ALLCONFIG is used without a filename where +KCONFIG_ALLCONFIG == "" or KCONFIG_ALLCONFIG == "1", "make *config" +checks for a file named "all{yes/mod/no/def/random}.config" +(corresponding to the *config command that was used) for symbol values +that are to be forced. If this file is not found, it checks for a +file named "all.config" to contain forced values. This enables you to create "miniature" config (miniconfig) or custom config files containing just the config symbols that you are interested diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index f208f900ed3..0fdda916930 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -574,8 +574,13 @@ int main(int ac, char **av) case alldefconfig: case randconfig: name = getenv("KCONFIG_ALLCONFIG"); - if (name && !stat(name, &tmpstat)) { - conf_read_simple(name, S_DEF_USER); + if (name && (strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { + if (conf_read_simple(name, S_DEF_USER)) { + fprintf(stderr, + _("*** Can't read seed configuration \"%s\"!\n"), + name); + exit(1); + } break; } switch (input_mode) { @@ -586,10 +591,13 @@ int main(int ac, char **av) case randconfig: name = "allrandom.config"; break; default: break; } - if (!stat(name, &tmpstat)) - conf_read_simple(name, S_DEF_USER); - else if (!stat("all.config", &tmpstat)) - conf_read_simple("all.config", S_DEF_USER); + if (conf_read_simple(name, S_DEF_USER) && + conf_read_simple("all.config", S_DEF_USER)) { + fprintf(stderr, + _("*** KCONFIG_ALLCONFIG set, but no \"%s\" or \"all.config\" file found\n"), + name); + exit(1); + } break; default: break; -- cgit v1.2.3-70-g09d2 From 1f2bfbd00e466ff3489b2ca5cc75b1cccd14c123 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Sat, 5 May 2012 10:18:41 +0200 Subject: kbuild: link of vmlinux moved to a script Move the final link of vmlinux to a script to improve readability and maintainability of the code. The Makefile fragments used to link vmlinux has over the years seen far too many changes and the logic had become hard to follow. As the process by nature is serialized there was nothing gained including this in the Makefile. "um" has special link requirments - and the only way to handle this was to hard-code the linking of "um" in the script. This was better than trying to modularize it only for the benefit of "um" anyway. The shell script has been improved after input from: Arnaud Lacombe Nick Bowler Signed-off-by: Sam Ravnborg Cc: Arnaud Lacombe Cc: Nick Bowler Cc: Richard Weinberger Signed-off-by: Michal Marek --- Makefile | 215 +++--------------------------------------------- arch/um/Makefile | 11 +-- scripts/link-vmlinux.sh | 211 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+), 212 deletions(-) create mode 100644 scripts/link-vmlinux.sh (limited to 'scripts') diff --git a/Makefile b/Makefile index 7ea0c07779b..a7cf6a11c4d 100644 --- a/Makefile +++ b/Makefile @@ -337,7 +337,6 @@ AWK = awk GENKSYMS = scripts/genksyms/genksyms INSTALLKERNEL := installkernel DEPMOD = /sbin/depmod -KALLSYMS = scripts/kallsyms PERL = perl CHECK = sparse @@ -723,191 +722,21 @@ libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y)) libs-y := $(libs-y1) $(libs-y2) -# externally visible symbols +# Externally visible symbols (used by link-vmlinux.sh) export KBUILD_VMLINUX_INIT := $(head-y) $(init-y) export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y) export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds +export LDFLAGS_vmlinux -# Build vmlinux -# --------------------------------------------------------------------------- -# vmlinux is built from the objects selected by $(vmlinux-init) and -# $(vmlinux-main). Most are built-in.o files from top-level directories -# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. -# Ordering when linking is important, and $(vmlinux-init) must be first. -# -# vmlinux -# ^ -# | -# +-< $(vmlinux-init) -# | +--< init/version.o + more -# | -# +--< $(vmlinux-main) -# | +--< driver/built-in.o mm/built-in.o + more -# | -# +-< kallsyms.o (see description in CONFIG_KALLSYMS section) -# -# vmlinux version (uname -v) cannot be updated during normal -# descending-into-subdirs phase since we do not yet know if we need to -# update vmlinux. -# Therefore this step is delayed until just before final link of vmlinux - -# except in the kallsyms case where it is done just before adding the -# symbols to the kernel. -# -# System.map is generated to document addresses of all kernel symbols - -vmlinux-init := $(head-y) $(init-y) -vmlinux-main := $(core-y) $(libs-y) $(drivers-y) $(net-y) -vmlinux-all := $(vmlinux-init) $(vmlinux-main) -vmlinux-lds := arch/$(SRCARCH)/kernel/vmlinux.lds - -# Rule to link vmlinux - also used during CONFIG_KALLSYMS -# May be overridden by arch/$(ARCH)/Makefile -quiet_cmd_vmlinux__ ?= LD $@ - cmd_vmlinux__ ?= $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) -o $@ \ - -T $(vmlinux-lds) $(vmlinux-init) \ - --start-group $(vmlinux-main) --end-group \ - $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o FORCE ,$^) - -# Generate new vmlinux version -quiet_cmd_vmlinux_version = GEN .version - cmd_vmlinux_version = set -e; \ - if [ ! -r .version ]; then \ - rm -f .version; \ - echo 1 >.version; \ - else \ - mv .version .old_version; \ - expr 0$$(cat .old_version) + 1 >.version; \ - fi; \ - $(MAKE) $(build)=init - -# Generate System.map -quiet_cmd_sysmap = SYSMAP - cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap - -# Link of vmlinux -# If CONFIG_KALLSYMS is set .version is already updated -# Generate System.map and verify that the content is consistent -# Use + in front of the vmlinux_version rule to silent warning with make -j2 -# First command is ':' to allow us to use + in front of the rule -define rule_vmlinux__ - : - $(if $(CONFIG_KALLSYMS),,+$(call cmd,vmlinux_version)) - - $(call cmd,vmlinux__) - $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd - - $(Q)$(if $($(quiet)cmd_sysmap), \ - echo ' $($(quiet)cmd_sysmap) System.map' &&) \ - $(cmd_sysmap) $@ System.map; \ - if [ $$? -ne 0 ]; then \ - rm -f $@; \ - /bin/false; \ - fi; - $(verify_kallsyms) -endef - - -ifdef CONFIG_KALLSYMS -# Generate section listing all symbols and add it into vmlinux $(kallsyms.o) -# It's a three stage process: -# o .tmp_vmlinux1 has all symbols and sections, but __kallsyms is -# empty -# Running kallsyms on that gives us .tmp_kallsyms1.o with -# the right size - vmlinux version (uname -v) is updated during this step -# o .tmp_vmlinux2 now has a __kallsyms section of the right size, -# but due to the added section, some addresses have shifted. -# From here, we generate a correct .tmp_kallsyms2.o -# o The correct .tmp_kallsyms2.o is linked into the final vmlinux. -# o Verify that the System.map from vmlinux matches the map from -# .tmp_vmlinux2, just in case we did not generate kallsyms correctly. -# o If 'make KALLSYMS_EXTRA_PASS=1" was used, do an extra pass using -# .tmp_vmlinux3 and .tmp_kallsyms3.o. This is only meant as a -# temporary bypass to allow the kernel to be built while the -# maintainers work out what went wrong with kallsyms. - -last_kallsyms := 2 - -ifdef KALLSYMS_EXTRA_PASS -ifneq ($(KALLSYMS_EXTRA_PASS),0) -last_kallsyms := 3 -endif -endif - -kallsyms.o := .tmp_kallsyms$(last_kallsyms).o - -define verify_kallsyms - $(Q)$(if $($(quiet)cmd_sysmap), \ - echo ' $($(quiet)cmd_sysmap) .tmp_System.map' &&) \ - $(cmd_sysmap) .tmp_vmlinux$(last_kallsyms) .tmp_System.map - $(Q)cmp -s System.map .tmp_System.map || \ - (echo Inconsistent kallsyms data; \ - echo This is a bug - please report about it; \ - echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround; \ - rm .tmp_kallsyms* ; /bin/false ) -endef - -# Update vmlinux version before link -# Use + in front of this rule to silent warning about make -j1 -# First command is ':' to allow us to use + in front of this rule -cmd_ksym_ld = $(cmd_vmlinux__) -define rule_ksym_ld - : - +$(call cmd,vmlinux_version) - $(call cmd,vmlinux__) - $(Q)echo 'cmd_$@ := $(cmd_vmlinux__)' > $(@D)/.$(@F).cmd -endef - -# Generate .S file with all kernel symbols -quiet_cmd_kallsyms = KSYM $@ - cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \ - $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@ - -.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE - $(call if_changed_dep,as_o_S) +vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) -.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS) - $(call cmd,kallsyms) +# Final link of vmlinux + cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) +quiet_cmd_link-vmlinux = LINK $@ -# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version -.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE - $(call if_changed_rule,ksym_ld) - -.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE - $(call if_changed,vmlinux__) - -.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE - $(call if_changed,vmlinux__) - -# Needs to visit scripts/ before $(KALLSYMS) can be used. -$(KALLSYMS): scripts ; - -# Generate some data for debugging strange kallsyms problems -debug_kallsyms: .tmp_map$(last_kallsyms) - -.tmp_map%: .tmp_vmlinux% FORCE - ($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@ - -.tmp_map3: .tmp_map2 - -.tmp_map2: .tmp_map1 - -endif # ifdef CONFIG_KALLSYMS - -# Do modpost on a prelinked vmlinux. The finally linked vmlinux has -# relevant sections renamed as per the linker script. -quiet_cmd_vmlinux-modpost = LD $@ - cmd_vmlinux-modpost = $(LD) $(LDFLAGS) -r -o $@ \ - $(vmlinux-init) --start-group $(vmlinux-main) --end-group \ - $(filter-out $(vmlinux-init) $(vmlinux-main) FORCE ,$^) -define rule_vmlinux-modpost - : - +$(call cmd,vmlinux-modpost) - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@ - $(Q)echo 'cmd_$@ := $(cmd_vmlinux-modpost)' > $(dot-target).cmd -endef - -# vmlinux image - including updated kernel symbols -vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o $(kallsyms.o) FORCE +# Include targets which we want to +# execute if the rest of the kernel build went well. +vmlinux: scripts/link-vmlinux.sh $(vmlinux-deps) FORCE ifdef CONFIG_HEADERS_CHECK $(Q)$(MAKE) -f $(srctree)/Makefile headers_check endif @@ -917,22 +746,11 @@ endif ifdef CONFIG_BUILD_DOCSRC $(Q)$(MAKE) $(build)=Documentation endif - $(call vmlinux-modpost) - $(call if_changed_rule,vmlinux__) - $(Q)rm -f .old_version - -# build vmlinux.o first to catch section mismatch errors early -ifdef CONFIG_KALLSYMS -.tmp_vmlinux1: vmlinux.o -endif - -modpost-init := $(filter-out init/built-in.o, $(vmlinux-init)) -vmlinux.o: $(modpost-init) $(vmlinux-main) FORCE - $(call if_changed_rule,vmlinux-modpost) + +$(call if_changed,link-vmlinux) # The actual objects are generated when descending, # make sure no implicit rule kicks in -$(sort $(vmlinux-init) $(vmlinux-main)) $(vmlinux-lds): $(vmlinux-dirs) ; +$(sort $(vmlinux-deps)): $(vmlinux-dirs) ; # Handle descending into subdirectories listed in $(vmlinux-dirs) # Preset locale variables to speed up the build process. Limit locale @@ -1156,8 +974,6 @@ endif # CONFIG_MODULES # Directories & files removed with 'make clean' CLEAN_DIRS += $(MODVERDIR) -CLEAN_FILES += vmlinux System.map \ - .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated \ @@ -1403,6 +1219,7 @@ scripts: ; endif # KBUILD_EXTMOD clean: $(clean-dirs) + $(Q)$(CONFIG_SHELL) $(srctree)/scripts/link-vmlinux.sh clean $(call cmd,rmdirs) $(call cmd,rmfiles) @find $(if $(KBUILD_EXTMOD), $(KBUILD_EXTMOD), .) $(RCS_FIND_IGNORE) \ @@ -1536,14 +1353,6 @@ quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) cmd_crmodverdir = $(Q)mkdir -p $(MODVERDIR) \ $(if $(KBUILD_MODULES),; rm -f $(MODVERDIR)/*) -a_flags = -Wp,-MD,$(depfile) $(KBUILD_AFLAGS) $(AFLAGS_KERNEL) \ - $(KBUILD_AFLAGS_KERNEL) \ - $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(KBUILD_CPPFLAGS) \ - $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o) - -quiet_cmd_as_o_S = AS $@ -cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $< - # read all saved command lines targets := $(wildcard $(sort $(targets))) diff --git a/arch/um/Makefile b/arch/um/Makefile index 55c0661e2b5..097091059aa 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -121,15 +121,8 @@ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt)) -CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) -define cmd_vmlinux__ - $(CC) $(CFLAGS_vmlinux) -o $@ \ - -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ - -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ - -lutil \ - $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \ - FORCE ,$^) ; rm -f linux -endef +# Used by link-vmlinux.sh which has special support for um link +export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh new file mode 100644 index 00000000000..26c5b658c2d --- /dev/null +++ b/scripts/link-vmlinux.sh @@ -0,0 +1,211 @@ +#!/bin/sh +# +# link vmlinux +# +# vmlinux is linked from the objects selected by $(KBUILD_VMLINUX_INIT) and +# $(KBUILD_VMLINUX_MAIN). Most are built-in.o files from top-level directories +# in the kernel tree, others are specified in arch/$(ARCH)/Makefile. +# Ordering when linking is important, and $(KBUILD_VMLINUX_INIT) must be first. +# +# vmlinux +# ^ +# | +# +-< $(KBUILD_VMLINUX_INIT) +# | +--< init/version.o + more +# | +# +--< $(KBUILD_VMLINUX_MAIN) +# | +--< drivers/built-in.o mm/built-in.o + more +# | +# +-< ${kallsymso} (see description in KALLSYMS section) +# +# vmlinux version (uname -v) cannot be updated during normal +# descending-into-subdirs phase since we do not yet know if we need to +# update vmlinux. +# Therefore this step is delayed until just before final link of vmlinux. +# +# System.map is generated to document addresses of all kernel symbols + +# Error out on error +set -e + +# Nice output in kbuild format +# Will be supressed by "make -s" +info() +{ + if [ "${quiet}" != "silent_" ]; then + printf " %-7s %s\n" ${1} ${2} + fi +} + +# Link of vmlinux.o used for section mismatch analysis +# ${1} output file +modpost_link() +{ + ${LD} ${LDFLAGS} -r -o ${1} ${KBUILD_VMLINUX_INIT} \ + --start-group ${KBUILD_VMLINUX_MAIN} --end-group +} + +# Link of vmlinux +# ${1} - optional extra .o files +# ${2} - output file +vmlinux_link() +{ + local lds="${objtree}/${KBUILD_LDS}" + + if [ "${SRCARCH}" != "um" ]; then + ${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ + -T ${lds} ${KBUILD_VMLINUX_INIT} \ + --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1} + else + ${CC} ${CFLAGS_vmlinux} -o ${2} \ + -Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \ + -Wl,--start-group \ + ${KBUILD_VMLINUX_MAIN} \ + -Wl,--end-group \ + -lutil ${1} + rm -f linux + fi +} + + +# Create ${2} .o file with all symbols from the ${1} object file +kallsyms() +{ + info KSYM ${2} + local kallsymopt; + + if [ -n "${CONFIG_KALLSYMS_ALL}" ]; then + kallsymopt=--all-symbols + fi + + local aflags="${KBUILD_AFLAGS} ${NOSTDINC_FLAGS} \ + ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" + + ${NM} -n ${1} | \ + scripts/kallsyms ${kallsymopt} | \ + ${CC} ${aflags} -c -o ${2} -x assembler-with-cpp - +} + +# Create map file with all symbols from ${1} +# See mksymap for additional details +mksysmap() +{ + ${CONFIG_SHELL} "${srctree}/scripts/mksysmap" ${1} ${2} +} + +# Delete output files in case of error +trap cleanup SIGHUP SIGINT SIGQUIT SIGTERM ERR +cleanup() +{ + rm -f .old_version + rm -f .tmp_System.map + rm -f .tmp_kallsyms* + rm -f .tmp_version + rm -f .tmp_vmlinux* + rm -f System.map + rm -f vmlinux + rm -f vmlinux.o +} + +# +# +# Use "make V=1" to debug this script +case "${KBUILD_VERBOSE}" in +*1*) + set -x + ;; +esac + +if [ "$1" = "clean" ]; then + cleanup + exit 0 +fi + +# We need access to CONFIG_ symbols +. ./.config + +#link vmlinux.o +info LD vmlinux.o +modpost_link vmlinux.o + +# modpost vmlinux.o to check for section mismatches +${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o + +# Update version +info GEN .version +if [ ! -r .version ]; then + rm -f .version; + echo 1 >.version; +else + mv .version .old_version; + expr 0$(cat .old_version) + 1 >.version; +fi; + +# final build of init/ +${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init + +kallsymso="" +kallsyms_vmlinux="" +if [ -n "${CONFIG_KALLSYMS}" ]; then + + # kallsyms support + # Generate section listing all symbols and add it into vmlinux + # It's a three step process: + # 1) Link .tmp_vmlinux1 so it has all symbols and sections, + # but __kallsyms is empty. + # Running kallsyms on that gives us .tmp_kallsyms1.o with + # the right size + # 2) Link .tmp_vmlinux2 so it now has a __kallsyms section of + # the right size, but due to the added section, some + # addresses have shifted. + # From here, we generate a correct .tmp_kallsyms2.o + # 2a) We may use an extra pass as this has been necessary to + # woraround some alignment related bugs. + # KALLSYMS_EXTRA_PASS=1 is used to trigger this. + # 3) The correct ${kallsymso} is linked into the final vmlinux. + # + # a) Verify that the System.map from vmlinux matches the map from + # ${kallsymso}. + + kallsymso=.tmp_kallsyms2.o + kallsyms_vmlinux=.tmp_vmlinux2 + + # step 1 + vmlinux_link "" .tmp_vmlinux1 + kallsyms .tmp_vmlinux1 .tmp_kallsyms1.o + + # step 2 + vmlinux_link .tmp_kallsyms1.o .tmp_vmlinux2 + kallsyms .tmp_vmlinux2 .tmp_kallsyms2.o + + # step 2a + if [ -n "${KALLSYMS_EXTRA_PASS}" ]; then + kallsymso=.tmp_kallsyms3.o + kallsyms_vmlinux=.tmp_vmlinux3 + + vmlinux_link .tmp_kallsyms2.o .tmp_vmlinux3 + + kallsyms .tmp_vmlinux3 .tmp_kallsyms3.o + fi +fi + +info LD vmlinux +vmlinux_link "${kallsymso}" vmlinux + +info SYSMAP System.map +mksysmap vmlinux System.map + +# step a (see comment above) +if [ -n "${CONFIG_KALLSYMS}" ]; then + mksysmap ${kallsyms_vmlinux} .tmp_System.map + + if ! cmp -s System.map .tmp_System.map; then + echo Inconsistent kallsyms data + echo echo Try "make KALLSYMS_EXTRA_PASS=1" as a workaround + cleanup + exit 1 + fi +fi + +# We made a new kernel - delete old version file +rm -f .old_version -- cgit v1.2.3-70-g09d2 From 9f420bf0f4a74e404b73b42b7fc3c85c20c64ea7 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Mon, 7 May 2012 05:37:45 -0700 Subject: kbuild: all{no,yes,mod,def,rand}config only read files when instructed to. Prevent subtle surprises to both people working on the kconfig code and people using make allnoconfig allyesconfig allmoconfig and randconfig by only attempting to read a config file if KCONFIG_ALLCONFIG is set. Common sense suggests attempting to read the extra config files does not make sense unless requested. The documentation says the code won't attempt to read the extra config files unless requested. Current usage does not appear to include people depending on the code reading the config files without the variable being set So do the simple thing and stop reading config files when passed all{no,yes,mod,def,rand}config unless KCONFIG_ALLCONFIG environment variable is set. Signed-off-by: Eric W. Biederman Reported-by: Stephen Rothwell Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 0fdda916930..0dc4a2c779b 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -574,7 +574,9 @@ int main(int ac, char **av) case alldefconfig: case randconfig: name = getenv("KCONFIG_ALLCONFIG"); - if (name && (strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { + if (!name) + break; + if ((strcmp(name, "") != 0) && (strcmp(name, "1") != 0)) { if (conf_read_simple(name, S_DEF_USER)) { fprintf(stderr, _("*** Can't read seed configuration \"%s\"!\n"), -- cgit v1.2.3-70-g09d2 From 00e6c28c6808c0ef6a3f25bb420d037fbb724d84 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 8 May 2012 19:53:46 +0200 Subject: kbuild: fix ia64 link ia64 build failed like this: CC init/version.o LD init/built-in.o KSYM .tmp_kallsyms1.o ld: .tmp_kallsyms1.o: linking constant-gp files with non-constant-gp files ld: failed to merge target specific data of file .tmp_kallsyms1.o make: *** [vmlinux] Error 1 This was introduced when link of vmlinux was migrated to a script. Add missing option to as to fix this. Reported-by: Tony Luck Tested-by: Tony Luck Signed-off-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/link-vmlinux.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'scripts') diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 26c5b658c2d..1f4c27bd5d2 100644 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -78,8 +78,8 @@ kallsyms() kallsymopt=--all-symbols fi - local aflags="${KBUILD_AFLAGS} ${NOSTDINC_FLAGS} \ - ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" + local aflags="${KBUILD_AFLAGS} ${KBUILD_AFLAGS_KERNEL} \ + ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS}" ${NM} -n ${1} | \ scripts/kallsyms ${kallsymopt} | \ -- cgit v1.2.3-70-g09d2 From d6686da814c884e341d3bd8aa54947c91cb678be Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Mon, 9 Apr 2012 14:49:10 +0200 Subject: scripts/config: properly report and set string options Currently, scripts/config removes the leading double-quote from string options, but leaves the trailing double-quote. Also, double-quotes in a string are escaped, but scripts/config does not unescape those when printing Finally, scripts/config does not escape double-quotes when setting string options. Eg. the current behavior: $ grep -E '^CONFIG_FOO=' .config CONFIG_FOO="Bar \"Buz\" Meh" $ ./scripts/config -s FOO Bar \"Buz\" Meh" $ ./scripts/config --set-str FOO 'Alpha "Bravo" Charlie' $ grep -E '^CONFIG_FOO=' .config CONFIG_FOO="Alpha "Bravo" Charlie" Fix those three, giving this new behavior: $ grep -E '^CONFIG_FOO=' .config CONFIG_FOO="Bar \"Buz\" Meh" $ ./scripts/config -s FOO Bar "Buz" Meh $ ./scripts/config --set-str FOO 'Alpha "Bravo" Charlie' $ grep -E '^CONFIG_FOO=' .config CONFIG_FOO="Alpha \"Bravo\" Charlie" Signed-off-by: "Yann E. MORIN" Acked-by: Andi Kleen Signed-off-by: Michal Marek --- scripts/config | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/config b/scripts/config index a7c7c4b8e95..ed6653ef970 100755 --- a/scripts/config +++ b/scripts/config @@ -107,7 +107,8 @@ while [ "$1" != "" ] ; do ;; --set-str) - set_var "CONFIG_$ARG" "CONFIG_$ARG=\"$1\"" + # sed swallows one level of escaping, so we need double-escaping + set_var "CONFIG_$ARG" "CONFIG_$ARG=\"${1//\"/\\\\\"}\"" shift ;; @@ -124,9 +125,11 @@ while [ "$1" != "" ] ; do if [ $? != 0 ] ; then echo undef else - V="${V/CONFIG_$ARG=/}" - V="${V/\"/}" - echo "$V" + V="${V/#CONFIG_$ARG=/}" + V="${V/#\"/}" + V="${V/%\"/}" + V="${V/\\\"/\"}" + echo "${V}" fi fi ;; -- cgit v1.2.3-70-g09d2 From bb8187d35f820671d6dd76700d77a6b55f95e2c5 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Thu, 17 May 2012 19:06:13 -0400 Subject: MCA: delete all remaining traces of microchannel bus support. Hardware with MCA bus is limited to 386 and 486 class machines that are now 20+ years old and typically with less than 32MB of memory. A quick search on the internet, and you see that even the MCA hobbyist/enthusiast community has lost interest in the early 2000 era and never really even moved ahead from the 2.4 kernels to the 2.6 series. This deletes anything remaining related to CONFIG_MCA from core kernel code and from the x86 architecture. There is no point in carrying this any further into the future. One complication to watch for is inadvertently scooping up stuff relating to machine check, since there is overlap in the TLA name space (e.g. arch/x86/boot/mca.c). Cc: Thomas Gleixner Cc: James Bottomley Cc: x86@kernel.org Acked-by: Ingo Molnar Acked-by: H. Peter Anvin Signed-off-by: Paul Gortmaker --- Documentation/00-INDEX | 2 - Documentation/DocBook/Makefile | 2 +- Documentation/DocBook/kernel-api.tmpl | 13 - Documentation/DocBook/mcabook.tmpl | 107 -------- Documentation/devices.txt | 8 +- Documentation/eisa.txt | 2 +- Documentation/kernel-parameters.txt | 1 - Documentation/mca.txt | 313 ---------------------- MAINTAINERS | 13 - arch/frv/include/asm/processor.h | 1 - arch/x86/Kconfig | 10 - arch/x86/include/asm/mca.h | 43 --- arch/x86/include/asm/mca_dma.h | 201 -------------- arch/x86/include/asm/mpspec.h | 2 +- arch/x86/include/asm/mpspec_def.h | 3 +- arch/x86/kernel/Makefile | 1 - arch/x86/kernel/acpi/boot.c | 2 +- arch/x86/kernel/apic/io_apic.c | 17 +- arch/x86/kernel/mca_32.c | 476 ---------------------------------- arch/x86/kernel/mpparse.c | 11 +- arch/x86/kernel/nmi.c | 12 - arch/x86/kernel/setup.c | 8 - arch/x86/kernel/time.c | 6 - arch/x86/kernel/traps.c | 4 - drivers/Makefile | 1 - drivers/mca/Kconfig | 14 - drivers/mca/Makefile | 7 - drivers/mca/mca-bus.c | 169 ------------ drivers/mca/mca-device.c | 218 ---------------- drivers/mca/mca-driver.c | 63 ----- drivers/mca/mca-legacy.c | 329 ----------------------- drivers/mca/mca-proc.c | 249 ------------------ drivers/message/i2o/i2o_proc.c | 13 - include/linux/i2o-dev.h | 2 +- include/linux/mca-legacy.h | 66 ----- include/linux/mca.h | 148 ----------- scripts/kconfig/mconf.c | 2 +- scripts/kconfig/nconf.c | 2 +- 38 files changed, 15 insertions(+), 2526 deletions(-) delete mode 100644 Documentation/DocBook/mcabook.tmpl delete mode 100644 Documentation/mca.txt delete mode 100644 arch/x86/include/asm/mca.h delete mode 100644 arch/x86/include/asm/mca_dma.h delete mode 100644 arch/x86/kernel/mca_32.c delete mode 100644 drivers/mca/Kconfig delete mode 100644 drivers/mca/Makefile delete mode 100644 drivers/mca/mca-bus.c delete mode 100644 drivers/mca/mca-device.c delete mode 100644 drivers/mca/mca-driver.c delete mode 100644 drivers/mca/mca-legacy.c delete mode 100644 drivers/mca/mca-proc.c delete mode 100644 include/linux/mca-legacy.h delete mode 100644 include/linux/mca.h (limited to 'scripts') diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 2214f123a97..49c051380da 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX @@ -218,8 +218,6 @@ m68k/ - directory with info about Linux on Motorola 68k architecture. magic-number.txt - list of magic numbers used to mark/protect kernel data structures. -mca.txt - - info on supporting Micro Channel Architecture (e.g. PS/2) systems. md.txt - info on boot arguments for the multiple devices driver. memory-barriers.txt diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile index 66725a3d30d..bc3d9f8c0a9 100644 --- a/Documentation/DocBook/Makefile +++ b/Documentation/DocBook/Makefile @@ -6,7 +6,7 @@ # To add a new book the only step required is to add the book to the # list of DOCBOOKS. -DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \ +DOCBOOKS := z8530book.xml device-drivers.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ writing_usb_driver.xml networking.xml \ kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \ diff --git a/Documentation/DocBook/kernel-api.tmpl b/Documentation/DocBook/kernel-api.tmpl index 7160652a873..00687ee9d36 100644 --- a/Documentation/DocBook/kernel-api.tmpl +++ b/Documentation/DocBook/kernel-api.tmpl @@ -212,19 +212,6 @@ X!Edrivers/pci/hotplug.c PCI Hotplug Support Library !Edrivers/pci/hotplug/pci_hotplug_core.c - MCA Architecture - MCA Device Functions - - Refer to the file arch/x86/kernel/mca_32.c for more information. - - - - MCA Bus DMA -!Iarch/x86/include/asm/mca_dma.h - - diff --git a/Documentation/DocBook/mcabook.tmpl b/Documentation/DocBook/mcabook.tmpl deleted file mode 100644 index 467ccac6ec5..00000000000 --- a/Documentation/DocBook/mcabook.tmpl +++ /dev/null @@ -1,107 +0,0 @@ - - - - - - MCA Driver Programming Interface - - - - Alan - Cox - -
- alan@lxorguk.ukuu.org.uk -
-
-
- - David - Weinehall - - - Chris - Beauregard - -
- - - 2000 - Alan Cox - David Weinehall - Chris Beauregard - - - - - This documentation 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 - - - - For more details see the file COPYING in the source - distribution of Linux. - - -
- - - - - Introduction - - The MCA bus functions provide a generalised interface to find MCA - bus cards, to claim them for a driver, and to read and manipulate POS - registers without being aware of the motherboard internals or - certain deep magic specific to onboard devices. - - - The basic interface to the MCA bus devices is the slot. Each slot - is numbered and virtual slot numbers are assigned to the internal - devices. Using a pci_dev as other busses do does not really make - sense in the MCA context as the MCA bus resources require card - specific interpretation. - - - Finally the MCA bus functions provide a parallel set of DMA - functions mimicing the ISA bus DMA functions as closely as possible, - although also supporting the additional DMA functionality on the - MCA bus controllers. - - - - Known Bugs And Assumptions - - None. - - - - - Public Functions Provided -!Edrivers/mca/mca-legacy.c - - - - DMA Functions Provided -!Iarch/x86/include/asm/mca_dma.h - - -
diff --git a/Documentation/devices.txt b/Documentation/devices.txt index 00383186d8f..c162be1c323 100644 --- a/Documentation/devices.txt +++ b/Documentation/devices.txt @@ -846,13 +846,7 @@ Your cooperation is appreciated. ... 31 = /dev/tap15 16th Ethertap device - 36 block MCA ESDI hard disk - 0 = /dev/eda First ESDI disk whole disk - 64 = /dev/edb Second ESDI disk whole disk - ... - - Partitions are handled in the same way as IDE disks - (see major number 3). + 36 block OBSOLETE (was MCA ESDI hard disk) 37 char IDE tape 0 = /dev/ht0 First IDE tape diff --git a/Documentation/eisa.txt b/Documentation/eisa.txt index 38cf0c7b559..a55e4910924 100644 --- a/Documentation/eisa.txt +++ b/Documentation/eisa.txt @@ -179,7 +179,7 @@ CONFIG_ALPHA_JENSEN or CONFIG_EISA_VLB_PRIMING are set. Converting an EISA driver to the new API mostly involves *deleting* code (since probing is now in the core EISA code). Unfortunately, most -drivers share their probing routine between ISA, MCA and EISA. Special +drivers share their probing routine between ISA, and EISA. Special care must be taken when ripping out the EISA code, so other busses won't suffer from these surgical strikes... diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c1601e5a8b7..38cad53620c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -70,7 +70,6 @@ parameter is applicable: M68k M68k architecture is enabled. These options have more detailed description inside of Documentation/m68k/kernel-options.txt. - MCA MCA bus support is enabled. MDA MDA console support is enabled. MIPS MIPS architecture is enabled. MOUSE Appropriate mouse support is enabled. diff --git a/Documentation/mca.txt b/Documentation/mca.txt deleted file mode 100644 index dfd130c2207..00000000000 --- a/Documentation/mca.txt +++ /dev/null @@ -1,313 +0,0 @@ -i386 Micro Channel Architecture Support -======================================= - -MCA support is enabled using the CONFIG_MCA define. A machine with a MCA -bus will have the kernel variable MCA_bus set, assuming the BIOS feature -bits are set properly (see arch/i386/boot/setup.S for information on -how this detection is done). - -Adapter Detection -================= - -The ideal MCA adapter detection is done through the use of the -Programmable Option Select registers. Generic functions for doing -this have been added in include/linux/mca.h and arch/x86/kernel/mca_32.c. -Everything needed to detect adapters and read (and write) configuration -information is there. A number of MCA-specific drivers already use -this. The typical probe code looks like the following: - - #include - - unsigned char pos2, pos3, pos4, pos5; - struct net_device* dev; - int slot; - - if( MCA_bus ) { - slot = mca_find_adapter( ADAPTER_ID, 0 ); - if( slot == MCA_NOTFOUND ) { - return -ENODEV; - } - /* optional - see below */ - mca_set_adapter_name( slot, "adapter name & description" ); - mca_set_adapter_procfn( slot, dev_getinfo, dev ); - - /* read the POS registers. Most devices only use 2 and 3 */ - pos2 = mca_read_stored_pos( slot, 2 ); - pos3 = mca_read_stored_pos( slot, 3 ); - pos4 = mca_read_stored_pos( slot, 4 ); - pos5 = mca_read_stored_pos( slot, 5 ); - } else { - return -ENODEV; - } - - /* extract configuration from pos[2345] and set everything up */ - -Loadable modules should modify this to test that the specified IRQ and -IO ports (plus whatever other stuff) match. See 3c523.c for example -code (actually, smc-mca.c has a slightly more complex example that can -handle a list of adapter ids). - -Keep in mind that devices should never directly access the POS registers -(via inb(), outb(), etc). While it's generally safe, there is a small -potential for blowing up hardware when it's done at the wrong time. -Furthermore, accessing a POS register disables a device temporarily. -This is usually okay during startup, but do _you_ want to rely on it? -During initial configuration, mca_init() reads all the POS registers -into memory. mca_read_stored_pos() accesses that data. mca_read_pos() -and mca_write_pos() are also available for (safer) direct POS access, -but their use is _highly_ discouraged. mca_write_pos() is particularly -dangerous, as it is possible for adapters to be put in inconsistent -states (i.e. sharing IO address, etc) and may result in crashes, toasted -hardware, and blindness. - -User level drivers (such as the AGX X server) can use /proc/mca/pos to -find adapters (see below). - -Some MCA adapters can also be detected via the usual ISA-style device -probing (many SCSI adapters, for example). This sort of thing is highly -discouraged. Perfectly good information is available telling you what's -there, so there's no excuse for messing with random IO ports. However, -we MCA people still appreciate any ISA-style driver that will work with -our hardware. You take what you can get... - -Level-Triggered Interrupts -========================== - -Because MCA uses level-triggered interrupts, a few problems arise with -what might best be described as the ISA mindset and its effects on -drivers. These sorts of problems are expected to become less common as -more people use shared IRQs on PCI machines. - -In general, an interrupt must be acknowledged not only at the ICU (which -is done automagically by the kernel), but at the device level. In -particular, IRQ 0 must be reset after a timer interrupt (now done in -arch/x86/kernel/time.c) or the first timer interrupt hangs the system. -There were also problems with the 1.3.x floppy drivers, but that seems -to have been fixed. - -IRQs are also shareable, and most MCA-specific devices should be coded -with shared IRQs in mind. - -/proc/mca -========= - -/proc/mca is a directory containing various files for adapters and -other stuff. - - /proc/mca/pos Straight listing of POS registers - /proc/mca/slot[1-8] Information on adapter in specific slot - /proc/mca/video Same for integrated video - /proc/mca/scsi Same for integrated SCSI - /proc/mca/machine Machine information - -See Appendix A for a sample. - -Device drivers can easily add their own information function for -specific slots (including integrated ones) via the -mca_set_adapter_procfn() call. Drivers that support this are ESDI, IBM -SCSI, and 3c523. If a device is also a module, make sure that the proc -function is removed in the module cleanup. This will require storing -the slot information in a private structure somewhere. See the 3c523 -driver for details. - -Your typical proc function will look something like this: - - static int - dev_getinfo( char* buf, int slot, void* d ) { - struct net_device* dev = (struct net_device*) d; - int len = 0; - - len += sprintf( buf+len, "Device: %s\n", dev->name ); - len += sprintf( buf+len, "IRQ: %d\n", dev->irq ); - len += sprintf( buf+len, "IO Port: %#lx-%#lx\n", ... ); - ... - - return len; - } - -Some of the standard MCA information will already be printed, so don't -bother repeating it. Don't try putting in more than 3K of information. - -Enable this function with: - mca_set_adapter_procfn( slot, dev_getinfo, dev ); - -Disable it with: - mca_set_adapter_procfn( slot, NULL, NULL ); - -It is also recommended that, even if you don't write a proc function, to -set the name of the adapter (i.e. "PS/2 ESDI Controller") via -mca_set_adapter_name( int slot, char* name ). - -MCA Device Drivers -================== - -Currently, there are a number of MCA-specific device drivers. - -1) PS/2 SCSI - drivers/scsi/ibmmca.c - drivers/scsi/ibmmca.h - The driver for the IBM SCSI subsystem. Includes both integrated - controllers and adapter cards. May require command-line arg - "ibmmcascsi=io_port" to force detection of an adapter. If you have a - machine with a front-panel display (i.e. model 95), you can use - "ibmmcascsi=display" to enable a drive activity indicator. - -2) 3c523 - drivers/net/3c523.c - drivers/net/3c523.h - 3Com 3c523 Etherlink/MC ethernet driver. - -3) SMC Ultra/MCA and IBM Adapter/A - drivers/net/smc-mca.c - drivers/net/smc-mca.h - Driver for the MCA version of the SMC Ultra and various other - OEM'ed and work-alike cards (Elite, Adapter/A, etc). - -4) NE/2 - driver/net/ne2.c - driver/net/ne2.h - The NE/2 is the MCA version of the NE2000. This may not work - with clones that have a different adapter id than the original - NE/2. - -5) Future Domain MCS-600/700, OEM'd IBM Fast SCSI Adapter/A and - Reply Sound Blaster/SCSI (SCSI part) - Better support for these cards than the driver for ISA. - Supports multiple cards with IRQ sharing. - -Also added boot time option of scsi-probe, which can do reordering of -SCSI host adapters. This will direct the kernel on the order which -SCSI adapter should be detected. Example: - scsi-probe=ibmmca,fd_mcs,adaptec1542,buslogic - -The serial drivers were modified to support the extended IO port range -of the typical MCA system (also #ifdef CONFIG_MCA). - -The following devices work with existing drivers: -1) Token-ring -2) Future Domain SCSI (MCS-600, MCS-700, not MCS-350, OEM'ed IBM SCSI) -3) Adaptec 1640 SCSI (using the aha1542 driver) -4) Bustek/Buslogic SCSI (various) -5) Probably all Arcnet cards. -6) Some, possibly all, MCA IDE controllers. -7) 3Com 3c529 (MCA version of 3c509) (patched) - -8) Intel EtherExpressMC (patched version) - You need to have CONFIG_MCA defined to have EtherExpressMC support. -9) Reply Sound Blaster/SCSI (SB part) (patched version) - -Bugs & Other Weirdness -====================== - -NMIs tend to occur with MCA machines because of various hardware -weirdness, bus timeouts, and many other non-critical things. Some basic -code to handle them (inspired by the NetBSD MCA code) has been added to -detect the guilty device, but it's pretty incomplete. If NMIs are a -persistent problem (on some model 70 or 80s, they occur every couple -shell commands), the CONFIG_IGNORE_NMI flag will take care of that. - -Various Pentium machines have had serious problems with the FPU test in -bugs.h. Basically, the machine hangs after the HLT test. This occurs, -as far as we know, on the Pentium-equipped 85s, 95s, and some PC Servers. -The PCI/MCA PC 750s are fine as far as I can tell. The ``mca-pentium'' -boot-prompt flag will disable the FPU bug check if this is a problem -with your machine. - -The model 80 has a raft of problems that are just too weird and unique -to get into here. Some people have no trouble while others have nothing -but problems. I'd suspect some problems are related to the age of the -average 80 and accompanying hardware deterioration, although others -are definitely design problems with the hardware. Among the problems -include SCSI controller problems, ESDI controller problems, and serious -screw-ups in the floppy controller. Oh, and the parallel port is also -pretty flaky. There were about 5 or 6 different model 80 motherboards -produced to fix various obscure problems. As far as I know, it's pretty -much impossible to tell which bugs a particular model 80 has (other than -triggering them, that is). - -Drivers are required for some MCA memory adapters. If you're suddenly -short a few megs of RAM, this might be the reason. The (I think) Enhanced -Memory Adapter commonly found on the model 70 is one. There's a very -alpha driver floating around, but it's pretty ugly (disassembled from -the DOS driver, actually). See the MCA Linux web page (URL below) -for more current memory info. - -The Thinkpad 700 and 720 will work, but various components are either -non-functional, flaky, or we don't know anything about them. The -graphics controller is supposed to be some WD, but we can't get things -working properly. The PCMCIA slots don't seem to work. Ditto for APM. -The serial ports work, but detection seems to be flaky. - -Credits -======= -A whole pile of people have contributed to the MCA code. I'd include -their names here, but I don't have a list handy. Check the MCA Linux -home page (URL below) for a perpetually out-of-date list. - -===================================================================== -MCA Linux Home Page: http://www.dgmicro.com/mca/ - -Christophe Beauregard -chrisb@truespectra.com -cpbeaure@calum.csclub.uwaterloo.ca - -===================================================================== -Appendix A: Sample /proc/mca - -This is from my model 8595. Slot 1 contains the standard IBM SCSI -adapter, slot 3 is an Adaptec AHA-1640, slot 5 is a XGA-1 video adapter, -and slot 7 is the 3c523 Etherlink/MC. - -/proc/mca/machine: -Model Id: 0xf8 -Submodel Id: 0x14 -BIOS Revision: 0x5 - -/proc/mca/pos: -Slot 1: ff 8e f1 fc a0 ff ff ff IBM SCSI Adapter w/Cache -Slot 2: ff ff ff ff ff ff ff ff -Slot 3: 1f 0f 81 3b bf b6 ff ff -Slot 4: ff ff ff ff ff ff ff ff -Slot 5: db 8f 1d 5e fd c0 00 00 -Slot 6: ff ff ff ff ff ff ff ff -Slot 7: 42 60 ff 08 ff ff ff ff 3Com 3c523 Etherlink/MC -Slot 8: ff ff ff ff ff ff ff ff -Video : ff ff ff ff ff ff ff ff -SCSI : ff ff ff ff ff ff ff ff - -/proc/mca/slot1: -Slot: 1 -Adapter Name: IBM SCSI Adapter w/Cache -Id: 8eff -Enabled: Yes -POS: ff 8e f1 fc a0 ff ff ff -Subsystem PUN: 7 -Detected at boot: Yes - -/proc/mca/slot3: -Slot: 3 -Adapter Name: Unknown -Id: 0f1f -Enabled: Yes -POS: 1f 0f 81 3b bf b6 ff ff - -/proc/mca/slot5: -Slot: 5 -Adapter Name: Unknown -Id: 8fdb -Enabled: Yes -POS: db 8f 1d 5e fd c0 00 00 - -/proc/mca/slot7: -Slot: 7 -Adapter Name: 3Com 3c523 Etherlink/MC -Id: 6042 -Enabled: Yes -POS: 42 60 ff 08 ff ff ff ff -Revision: 0xe -IRQ: 9 -IO Address: 0x3300-0x3308 -Memory: 0xd8000-0xdbfff -Transceiver: External -Device: eth0 -Hardware Address: 02 60 8c 45 c4 2a diff --git a/MAINTAINERS b/MAINTAINERS index 490dd6e640a..9fa728b53d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3316,12 +3316,6 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux.git S: Maintained F: arch/ia64/ -IBM MCA SCSI SUBSYSTEM DRIVER -M: Michael Lang -W: http://www.uni-mainz.de/~langm000/linux.html -S: Maintained -F: drivers/scsi/ibmmca.c - IBM Power Linux RAID adapter M: Brian King S: Supported @@ -4418,13 +4412,6 @@ T: git git://git.monstr.eu/linux-2.6-microblaze.git S: Supported F: arch/microblaze/ -MICROCHANNEL ARCHITECTURE (MCA) -M: James Bottomley -S: Maintained -F: Documentation/mca.txt -F: drivers/mca/ -F: include/linux/mca* - MICROTEK X6 SCANNER M: Oliver Neukum S: Maintained diff --git a/arch/frv/include/asm/processor.h b/arch/frv/include/asm/processor.h index 81c2e271d62..4a53811cd4c 100644 --- a/arch/frv/include/asm/processor.h +++ b/arch/frv/include/asm/processor.h @@ -54,7 +54,6 @@ extern struct cpuinfo_frv __nongprelbss boot_cpu_data; * Bus types */ #define EISA_bus 0 -#define MCA_bus 0 struct thread_struct { struct pt_regs *frame; /* [GR28] exception frame ptr for this thread */ diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c9866b0b77d..9137057152c 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2023,16 +2023,6 @@ config EISA source "drivers/eisa/Kconfig" -config MCA - bool "MCA support" - ---help--- - MicroChannel Architecture is found in some IBM PS/2 machines and - laptops. It is a bus system similar to PCI or ISA. See - (and especially the web page given - there) before attempting to build an MCA bus kernel. - -source "drivers/mca/Kconfig" - config SCx200 tristate "NatSemi SCx200 support" ---help--- diff --git a/arch/x86/include/asm/mca.h b/arch/x86/include/asm/mca.h deleted file mode 100644 index eedbb6cc1ef..00000000000 --- a/arch/x86/include/asm/mca.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* Platform specific MCA defines */ -#ifndef _ASM_X86_MCA_H -#define _ASM_X86_MCA_H - -/* Maximal number of MCA slots - actually, some machines have less, but - * they all have sufficient number of POS registers to cover 8. - */ -#define MCA_MAX_SLOT_NR 8 - -/* Most machines have only one MCA bus. The only multiple bus machines - * I know have at most two */ -#define MAX_MCA_BUSSES 2 - -#define MCA_PRIMARY_BUS 0 -#define MCA_SECONDARY_BUS 1 - -/* Dummy slot numbers on primary MCA for integrated functions */ -#define MCA_INTEGSCSI (MCA_MAX_SLOT_NR) -#define MCA_INTEGVIDEO (MCA_MAX_SLOT_NR+1) -#define MCA_MOTHERBOARD (MCA_MAX_SLOT_NR+2) - -/* Dummy POS values for integrated functions */ -#define MCA_DUMMY_POS_START 0x10000 -#define MCA_INTEGSCSI_POS (MCA_DUMMY_POS_START+1) -#define MCA_INTEGVIDEO_POS (MCA_DUMMY_POS_START+2) -#define MCA_MOTHERBOARD_POS (MCA_DUMMY_POS_START+3) - -/* MCA registers */ - -#define MCA_MOTHERBOARD_SETUP_REG 0x94 -#define MCA_ADAPTER_SETUP_REG 0x96 -#define MCA_POS_REG(n) (0x100+(n)) - -#define MCA_ENABLED 0x01 /* POS 2, set if adapter enabled */ - -/* Max number of adapters, including both slots and various integrated - * things. - */ -#define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3) - -#endif /* _ASM_X86_MCA_H */ diff --git a/arch/x86/include/asm/mca_dma.h b/arch/x86/include/asm/mca_dma.h deleted file mode 100644 index 45271aef82d..00000000000 --- a/arch/x86/include/asm/mca_dma.h +++ /dev/null @@ -1,201 +0,0 @@ -#ifndef _ASM_X86_MCA_DMA_H -#define _ASM_X86_MCA_DMA_H - -#include -#include - -/* - * Microchannel specific DMA stuff. DMA on an MCA machine is fairly similar to - * standard PC dma, but it certainly has its quirks. DMA register addresses - * are in a different place and there are some added functions. Most of this - * should be pretty obvious on inspection. Note that the user must divide - * count by 2 when using 16-bit dma; that is not handled by these functions. - * - * Ramen Noodles are yummy. - * - * 1998 Tymm Twillman - */ - -/* - * Registers that are used by the DMA controller; FN is the function register - * (tell the controller what to do) and EXE is the execution register (how - * to do it) - */ - -#define MCA_DMA_REG_FN 0x18 -#define MCA_DMA_REG_EXE 0x1A - -/* - * Functions that the DMA controller can do - */ - -#define MCA_DMA_FN_SET_IO 0x00 -#define MCA_DMA_FN_SET_ADDR 0x20 -#define MCA_DMA_FN_GET_ADDR 0x30 -#define MCA_DMA_FN_SET_COUNT 0x40 -#define MCA_DMA_FN_GET_COUNT 0x50 -#define MCA_DMA_FN_GET_STATUS 0x60 -#define MCA_DMA_FN_SET_MODE 0x70 -#define MCA_DMA_FN_SET_ARBUS 0x80 -#define MCA_DMA_FN_MASK 0x90 -#define MCA_DMA_FN_RESET_MASK 0xA0 -#define MCA_DMA_FN_MASTER_CLEAR 0xD0 - -/* - * Modes (used by setting MCA_DMA_FN_MODE in the function register) - * - * Note that the MODE_READ is read from memory (write to device), and - * MODE_WRITE is vice-versa. - */ - -#define MCA_DMA_MODE_XFER 0x04 /* read by default */ -#define MCA_DMA_MODE_READ 0x04 /* same as XFER */ -#define MCA_DMA_MODE_WRITE 0x08 /* OR with MODE_XFER to use */ -#define MCA_DMA_MODE_IO 0x01 /* DMA from IO register */ -#define MCA_DMA_MODE_16 0x40 /* 16 bit xfers */ - - -/** - * mca_enable_dma - channel to enable DMA on - * @dmanr: DMA channel - * - * Enable the MCA bus DMA on a channel. This can be called from - * IRQ context. - */ - -static inline void mca_enable_dma(unsigned int dmanr) -{ - outb(MCA_DMA_FN_RESET_MASK | dmanr, MCA_DMA_REG_FN); -} - -/** - * mca_disble_dma - channel to disable DMA on - * @dmanr: DMA channel - * - * Enable the MCA bus DMA on a channel. This can be called from - * IRQ context. - */ - -static inline void mca_disable_dma(unsigned int dmanr) -{ - outb(MCA_DMA_FN_MASK | dmanr, MCA_DMA_REG_FN); -} - -/** - * mca_set_dma_addr - load a 24bit DMA address - * @dmanr: DMA channel - * @a: 24bit bus address - * - * Load the address register in the DMA controller. This has a 24bit - * limitation (16Mb). - */ - -static inline void mca_set_dma_addr(unsigned int dmanr, unsigned int a) -{ - outb(MCA_DMA_FN_SET_ADDR | dmanr, MCA_DMA_REG_FN); - outb(a & 0xff, MCA_DMA_REG_EXE); - outb((a >> 8) & 0xff, MCA_DMA_REG_EXE); - outb((a >> 16) & 0xff, MCA_DMA_REG_EXE); -} - -/** - * mca_get_dma_addr - load a 24bit DMA address - * @dmanr: DMA channel - * - * Read the address register in the DMA controller. This has a 24bit - * limitation (16Mb). The return is a bus address. - */ - -static inline unsigned int mca_get_dma_addr(unsigned int dmanr) -{ - unsigned int addr; - - outb(MCA_DMA_FN_GET_ADDR | dmanr, MCA_DMA_REG_FN); - addr = inb(MCA_DMA_REG_EXE); - addr |= inb(MCA_DMA_REG_EXE) << 8; - addr |= inb(MCA_DMA_REG_EXE) << 16; - - return addr; -} - -/** - * mca_set_dma_count - load a 16bit transfer count - * @dmanr: DMA channel - * @count: count - * - * Set the DMA count for this channel. This can be up to 64Kbytes. - * Setting a count of zero will not do what you expect. - */ - -static inline void mca_set_dma_count(unsigned int dmanr, unsigned int count) -{ - count--; /* transfers one more than count -- correct for this */ - - outb(MCA_DMA_FN_SET_COUNT | dmanr, MCA_DMA_REG_FN); - outb(count & 0xff, MCA_DMA_REG_EXE); - outb((count >> 8) & 0xff, MCA_DMA_REG_EXE); -} - -/** - * mca_get_dma_residue - get the remaining bytes to transfer - * @dmanr: DMA channel - * - * This function returns the number of bytes left to transfer - * on this DMA channel. - */ - -static inline unsigned int mca_get_dma_residue(unsigned int dmanr) -{ - unsigned short count; - - outb(MCA_DMA_FN_GET_COUNT | dmanr, MCA_DMA_REG_FN); - count = 1 + inb(MCA_DMA_REG_EXE); - count += inb(MCA_DMA_REG_EXE) << 8; - - return count; -} - -/** - * mca_set_dma_io - set the port for an I/O transfer - * @dmanr: DMA channel - * @io_addr: an I/O port number - * - * Unlike the ISA bus DMA controllers the DMA on MCA bus can transfer - * with an I/O port target. - */ - -static inline void mca_set_dma_io(unsigned int dmanr, unsigned int io_addr) -{ - /* - * DMA from a port address -- set the io address - */ - - outb(MCA_DMA_FN_SET_IO | dmanr, MCA_DMA_REG_FN); - outb(io_addr & 0xff, MCA_DMA_REG_EXE); - outb((io_addr >> 8) & 0xff, MCA_DMA_REG_EXE); -} - -/** - * mca_set_dma_mode - set the DMA mode - * @dmanr: DMA channel - * @mode: mode to set - * - * The DMA controller supports several modes. The mode values you can - * set are- - * - * %MCA_DMA_MODE_READ when reading from the DMA device. - * - * %MCA_DMA_MODE_WRITE to writing to the DMA device. - * - * %MCA_DMA_MODE_IO to do DMA to or from an I/O port. - * - * %MCA_DMA_MODE_16 to do 16bit transfers. - */ - -static inline void mca_set_dma_mode(unsigned int dmanr, unsigned int mode) -{ - outb(MCA_DMA_FN_SET_MODE | dmanr, MCA_DMA_REG_FN); - outb(mode, MCA_DMA_REG_EXE); -} - -#endif /* _ASM_X86_MCA_DMA_H */ diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h index 9c7d95f6174..3e2f42a4b87 100644 --- a/arch/x86/include/asm/mpspec.h +++ b/arch/x86/include/asm/mpspec.h @@ -40,7 +40,7 @@ extern int quad_local_to_mp_bus_id [NR_CPUS/4][4]; #endif /* CONFIG_X86_64 */ -#if defined(CONFIG_MCA) || defined(CONFIG_EISA) +#ifdef CONFIG_EISA extern int mp_bus_id_to_type[MAX_MP_BUSSES]; #endif diff --git a/arch/x86/include/asm/mpspec_def.h b/arch/x86/include/asm/mpspec_def.h index c0a955a9a08..b31f8c09827 100644 --- a/arch/x86/include/asm/mpspec_def.h +++ b/arch/x86/include/asm/mpspec_def.h @@ -84,7 +84,7 @@ struct mpc_bus { #define BUSTYPE_EISA "EISA" #define BUSTYPE_ISA "ISA" #define BUSTYPE_INTERN "INTERN" /* Internal BUS */ -#define BUSTYPE_MCA "MCA" +#define BUSTYPE_MCA "MCA" /* Obsolete */ #define BUSTYPE_VL "VL" /* Local bus */ #define BUSTYPE_PCI "PCI" #define BUSTYPE_PCMCIA "PCMCIA" @@ -169,6 +169,5 @@ enum mp_bustype { MP_BUS_ISA = 1, MP_BUS_EISA, MP_BUS_PCI, - MP_BUS_MCA, }; #endif /* _ASM_X86_MPSPEC_DEF_H */ diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 532d2e090e6..7d156994720 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -49,7 +49,6 @@ obj-y += cpu/ obj-y += acpi/ obj-y += reboot.o obj-$(CONFIG_X86_32) += reboot_32.o -obj-$(CONFIG_MCA) += mca_32.o obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_PCI) += early-quirks.o diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index a415b1f4436..f564b189de1 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -990,7 +990,7 @@ void __init mp_config_acpi_legacy_irqs(void) int i; struct mpc_intsrc mp_irq; -#if defined (CONFIG_MCA) || defined (CONFIG_EISA) +#ifdef CONFIG_EISA /* * Fabricate the legacy ISA bus (bus #31). */ diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index e88300d8e80..675e9045a3c 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c @@ -142,7 +142,7 @@ int mp_irq_entries; /* GSI interrupts */ static int nr_irqs_gsi = NR_IRQS_LEGACY; -#if defined (CONFIG_MCA) || defined (CONFIG_EISA) +#ifdef CONFIG_EISA int mp_bus_id_to_type[MAX_MP_BUSSES]; #endif @@ -875,7 +875,7 @@ static int __init find_isa_irq_apic(int irq, int type) return -1; } -#if defined(CONFIG_EISA) || defined(CONFIG_MCA) +#ifdef CONFIG_EISA /* * EISA Edge/Level control register, ELCR */ @@ -912,12 +912,6 @@ static int EISA_ELCR(unsigned int irq) #define default_PCI_trigger(idx) (1) #define default_PCI_polarity(idx) (1) -/* MCA interrupts are always polarity zero level triggered, - * when listed as conforming in the MP table. */ - -#define default_MCA_trigger(idx) (1) -#define default_MCA_polarity(idx) default_ISA_polarity(idx) - static int irq_polarity(int idx) { int bus = mp_irqs[idx].srcbus; @@ -975,7 +969,7 @@ static int irq_trigger(int idx) trigger = default_ISA_trigger(idx); else trigger = default_PCI_trigger(idx); -#if defined(CONFIG_EISA) || defined(CONFIG_MCA) +#ifdef CONFIG_EISA switch (mp_bus_id_to_type[bus]) { case MP_BUS_ISA: /* ISA pin */ { @@ -992,11 +986,6 @@ static int irq_trigger(int idx) /* set before the switch */ break; } - case MP_BUS_MCA: /* MCA pin */ - { - trigger = default_MCA_trigger(idx); - break; - } default: { printk(KERN_WARNING "broken BIOS!!\n"); diff --git a/arch/x86/kernel/mca_32.c b/arch/x86/kernel/mca_32.c deleted file mode 100644 index 7eb1e2b9782..00000000000 --- a/arch/x86/kernel/mca_32.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Written by Martin Kolinek, February 1996 - * - * Changes: - * - * Chris Beauregard July 28th, 1996 - * - Fixed up integrated SCSI detection - * - * Chris Beauregard August 3rd, 1996 - * - Made mca_info local - * - Made integrated registers accessible through standard function calls - * - Added name field - * - More sanity checking - * - * Chris Beauregard August 9th, 1996 - * - Rewrote /proc/mca - * - * Chris Beauregard January 7th, 1997 - * - Added basic NMI-processing - * - Added more information to mca_info structure - * - * David Weinehall October 12th, 1998 - * - Made a lot of cleaning up in the source - * - Added use of save_flags / restore_flags - * - Added the 'driver_loaded' flag in MCA_adapter - * - Added an alternative implemention of ZP Gu's mca_find_unused_adapter - * - * David Weinehall March 24th, 1999 - * - Fixed the output of 'Driver Installed' in /proc/mca/pos - * - Made the Integrated Video & SCSI show up even if they have id 0000 - * - * Alexander Viro November 9th, 1999 - * - Switched to regular procfs methods - * - * Alfred Arnold & David Weinehall August 23rd, 2000 - * - Added support for Planar POS-registers - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static unsigned char which_scsi; - -int MCA_bus; -EXPORT_SYMBOL(MCA_bus); - -/* - * Motherboard register spinlock. Untested on SMP at the moment, but - * are there any MCA SMP boxes? - * - * Yes - Alan - */ -static DEFINE_SPINLOCK(mca_lock); - -/* Build the status info for the adapter */ - -static void mca_configure_adapter_status(struct mca_device *mca_dev) -{ - mca_dev->status = MCA_ADAPTER_NONE; - - mca_dev->pos_id = mca_dev->pos[0] - + (mca_dev->pos[1] << 8); - - if (!mca_dev->pos_id && mca_dev->slot < MCA_MAX_SLOT_NR) { - - /* - * id = 0x0000 usually indicates hardware failure, - * however, ZP Gu (zpg@castle.net> reports that his 9556 - * has 0x0000 as id and everything still works. There - * also seem to be an adapter with id = 0x0000; the - * NCR Parallel Bus Memory Card. Until this is confirmed, - * however, this code will stay. - */ - - mca_dev->status = MCA_ADAPTER_ERROR; - - return; - } else if (mca_dev->pos_id != 0xffff) { - - /* - * 0xffff usually indicates that there's no adapter, - * however, some integrated adapters may have 0xffff as - * their id and still be valid. Examples are on-board - * VGA of the 55sx, the integrated SCSI of the 56 & 57, - * and possibly also the 95 ULTIMEDIA. - */ - - mca_dev->status = MCA_ADAPTER_NORMAL; - } - - if ((mca_dev->pos_id == 0xffff || - mca_dev->pos_id == 0x0000) && mca_dev->slot >= MCA_MAX_SLOT_NR) { - int j; - - for (j = 2; j < 8; j++) { - if (mca_dev->pos[j] != 0xff) { - mca_dev->status = MCA_ADAPTER_NORMAL; - break; - } - } - } - - if (!(mca_dev->pos[2] & MCA_ENABLED)) { - - /* enabled bit is in POS 2 */ - - mca_dev->status = MCA_ADAPTER_DISABLED; - } -} /* mca_configure_adapter_status */ - -/*--------------------------------------------------------------------*/ - -static struct resource mca_standard_resources[] = { - { .start = 0x60, .end = 0x60, .name = "system control port B (MCA)" }, - { .start = 0x90, .end = 0x90, .name = "arbitration (MCA)" }, - { .start = 0x91, .end = 0x91, .name = "card Select Feedback (MCA)" }, - { .start = 0x92, .end = 0x92, .name = "system Control port A (MCA)" }, - { .start = 0x94, .end = 0x94, .name = "system board setup (MCA)" }, - { .start = 0x96, .end = 0x97, .name = "POS (MCA)" }, - { .start = 0x100, .end = 0x107, .name = "POS (MCA)" } -}; - -#define MCA_STANDARD_RESOURCES ARRAY_SIZE(mca_standard_resources) - -/* - * mca_read_and_store_pos - read the POS registers into a memory buffer - * @pos: a char pointer to 8 bytes, contains the POS register value on - * successful return - * - * Returns 1 if a card actually exists (i.e. the pos isn't - * all 0xff) or 0 otherwise - */ -static int mca_read_and_store_pos(unsigned char *pos) -{ - int j; - int found = 0; - - for (j = 0; j < 8; j++) { - pos[j] = inb_p(MCA_POS_REG(j)); - if (pos[j] != 0xff) { - /* 0xff all across means no device. 0x00 means - * something's broken, but a device is - * probably there. However, if you get 0x00 - * from a motherboard register it won't matter - * what we find. For the record, on the - * 57SLC, the integrated SCSI adapter has - * 0xffff for the adapter ID, but nonzero for - * other registers. */ - - found = 1; - } - } - return found; -} - -static unsigned char mca_pc_read_pos(struct mca_device *mca_dev, int reg) -{ - unsigned char byte; - unsigned long flags; - - if (reg < 0 || reg >= 8) - return 0; - - spin_lock_irqsave(&mca_lock, flags); - if (mca_dev->pos_register) { - /* Disable adapter setup, enable motherboard setup */ - - outb_p(0, MCA_ADAPTER_SETUP_REG); - outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); - - byte = inb_p(MCA_POS_REG(reg)); - outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - } else { - - /* Make sure motherboard setup is off */ - - outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - - /* Read the appropriate register */ - - outb_p(0x8|(mca_dev->slot & 0xf), MCA_ADAPTER_SETUP_REG); - byte = inb_p(MCA_POS_REG(reg)); - outb_p(0, MCA_ADAPTER_SETUP_REG); - } - spin_unlock_irqrestore(&mca_lock, flags); - - mca_dev->pos[reg] = byte; - - return byte; -} - -static void mca_pc_write_pos(struct mca_device *mca_dev, int reg, - unsigned char byte) -{ - unsigned long flags; - - if (reg < 0 || reg >= 8) - return; - - spin_lock_irqsave(&mca_lock, flags); - - /* Make sure motherboard setup is off */ - - outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - - /* Read in the appropriate register */ - - outb_p(0x8|(mca_dev->slot&0xf), MCA_ADAPTER_SETUP_REG); - outb_p(byte, MCA_POS_REG(reg)); - outb_p(0, MCA_ADAPTER_SETUP_REG); - - spin_unlock_irqrestore(&mca_lock, flags); - - /* Update the global register list, while we have the byte */ - - mca_dev->pos[reg] = byte; - -} - -/* for the primary MCA bus, we have identity transforms */ -static int mca_dummy_transform_irq(struct mca_device *mca_dev, int irq) -{ - return irq; -} - -static int mca_dummy_transform_ioport(struct mca_device *mca_dev, int port) -{ - return port; -} - -static void *mca_dummy_transform_memory(struct mca_device *mca_dev, void *mem) -{ - return mem; -} - - -static int __init mca_init(void) -{ - unsigned int i, j; - struct mca_device *mca_dev; - unsigned char pos[8]; - short mca_builtin_scsi_ports[] = {0xf7, 0xfd, 0x00}; - struct mca_bus *bus; - - /* - * WARNING: Be careful when making changes here. Putting an adapter - * and the motherboard simultaneously into setup mode may result in - * damage to chips (according to The Indispensable PC Hardware Book - * by Hans-Peter Messmer). Also, we disable system interrupts (so - * that we are not disturbed in the middle of this). - */ - - /* Make sure the MCA bus is present */ - - if (mca_system_init()) { - printk(KERN_ERR "MCA bus system initialisation failed\n"); - return -ENODEV; - } - - if (!MCA_bus) - return -ENODEV; - - printk(KERN_INFO "Micro Channel bus detected.\n"); - - /* All MCA systems have at least a primary bus */ - bus = mca_attach_bus(MCA_PRIMARY_BUS); - if (!bus) - goto out_nomem; - bus->default_dma_mask = 0xffffffffLL; - bus->f.mca_write_pos = mca_pc_write_pos; - bus->f.mca_read_pos = mca_pc_read_pos; - bus->f.mca_transform_irq = mca_dummy_transform_irq; - bus->f.mca_transform_ioport = mca_dummy_transform_ioport; - bus->f.mca_transform_memory = mca_dummy_transform_memory; - - /* get the motherboard device */ - mca_dev = kzalloc(sizeof(struct mca_device), GFP_KERNEL); - if (unlikely(!mca_dev)) - goto out_nomem; - - /* - * We do not expect many MCA interrupts during initialization, - * but let us be safe: - */ - spin_lock_irq(&mca_lock); - - /* Make sure adapter setup is off */ - - outb_p(0, MCA_ADAPTER_SETUP_REG); - - /* Read motherboard POS registers */ - - mca_dev->pos_register = 0x7f; - outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); - mca_dev->name[0] = 0; - mca_read_and_store_pos(mca_dev->pos); - mca_configure_adapter_status(mca_dev); - /* fake POS and slot for a motherboard */ - mca_dev->pos_id = MCA_MOTHERBOARD_POS; - mca_dev->slot = MCA_MOTHERBOARD; - mca_register_device(MCA_PRIMARY_BUS, mca_dev); - - mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); - if (unlikely(!mca_dev)) - goto out_unlock_nomem; - - /* Put motherboard into video setup mode, read integrated video - * POS registers, and turn motherboard setup off. - */ - - mca_dev->pos_register = 0xdf; - outb_p(mca_dev->pos_register, MCA_MOTHERBOARD_SETUP_REG); - mca_dev->name[0] = 0; - mca_read_and_store_pos(mca_dev->pos); - mca_configure_adapter_status(mca_dev); - /* fake POS and slot for the integrated video */ - mca_dev->pos_id = MCA_INTEGVIDEO_POS; - mca_dev->slot = MCA_INTEGVIDEO; - mca_register_device(MCA_PRIMARY_BUS, mca_dev); - - /* - * Put motherboard into scsi setup mode, read integrated scsi - * POS registers, and turn motherboard setup off. - * - * It seems there are two possible SCSI registers. Martin says that - * for the 56,57, 0xf7 is the one, but fails on the 76. - * Alfredo (apena@vnet.ibm.com) says - * 0xfd works on his machine. We'll try both of them. I figure it's - * a good bet that only one could be valid at a time. This could - * screw up though if one is used for something else on the other - * machine. - */ - - for (i = 0; (which_scsi = mca_builtin_scsi_ports[i]) != 0; i++) { - outb_p(which_scsi, MCA_MOTHERBOARD_SETUP_REG); - if (mca_read_and_store_pos(pos)) - break; - } - if (which_scsi) { - /* found a scsi card */ - mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); - if (unlikely(!mca_dev)) - goto out_unlock_nomem; - - for (j = 0; j < 8; j++) - mca_dev->pos[j] = pos[j]; - - mca_configure_adapter_status(mca_dev); - /* fake POS and slot for integrated SCSI controller */ - mca_dev->pos_id = MCA_INTEGSCSI_POS; - mca_dev->slot = MCA_INTEGSCSI; - mca_dev->pos_register = which_scsi; - mca_register_device(MCA_PRIMARY_BUS, mca_dev); - } - - /* Turn off motherboard setup */ - - outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG); - - /* - * Now loop over MCA slots: put each adapter into setup mode, and - * read its POS registers. Then put adapter setup off. - */ - - for (i = 0; i < MCA_MAX_SLOT_NR; i++) { - outb_p(0x8|(i&0xf), MCA_ADAPTER_SETUP_REG); - if (!mca_read_and_store_pos(pos)) - continue; - - mca_dev = kzalloc(sizeof(struct mca_device), GFP_ATOMIC); - if (unlikely(!mca_dev)) - goto out_unlock_nomem; - - for (j = 0; j < 8; j++) - mca_dev->pos[j] = pos[j]; - - mca_dev->driver_loaded = 0; - mca_dev->slot = i; - mca_dev->pos_register = 0; - mca_configure_adapter_status(mca_dev); - mca_register_device(MCA_PRIMARY_BUS, mca_dev); - } - outb_p(0, MCA_ADAPTER_SETUP_REG); - - /* Enable interrupts and return memory start */ - spin_unlock_irq(&mca_lock); - - for (i = 0; i < MCA_STANDARD_RESOURCES; i++) - request_resource(&ioport_resource, mca_standard_resources + i); - - mca_do_proc_init(); - - return 0; - - out_unlock_nomem: - spin_unlock_irq(&mca_lock); - out_nomem: - printk(KERN_EMERG "Failed memory allocation in MCA setup!\n"); - return -ENOMEM; -} - -subsys_initcall(mca_init); - -/*--------------------------------------------------------------------*/ - -static __kprobes void -mca_handle_nmi_device(struct mca_device *mca_dev, int check_flag) -{ - int slot = mca_dev->slot; - - if (slot == MCA_INTEGSCSI) { - printk(KERN_CRIT "NMI: caused by MCA integrated SCSI adapter (%s)\n", - mca_dev->name); - } else if (slot == MCA_INTEGVIDEO) { - printk(KERN_CRIT "NMI: caused by MCA integrated video adapter (%s)\n", - mca_dev->name); - } else if (slot == MCA_MOTHERBOARD) { - printk(KERN_CRIT "NMI: caused by motherboard (%s)\n", - mca_dev->name); - } - - /* More info available in POS 6 and 7? */ - - if (check_flag) { - unsigned char pos6, pos7; - - pos6 = mca_device_read_pos(mca_dev, 6); - pos7 = mca_device_read_pos(mca_dev, 7); - - printk(KERN_CRIT "NMI: POS 6 = 0x%x, POS 7 = 0x%x\n", pos6, pos7); - } - -} /* mca_handle_nmi_slot */ - -/*--------------------------------------------------------------------*/ - -static int __kprobes mca_handle_nmi_callback(struct device *dev, void *data) -{ - struct mca_device *mca_dev = to_mca_device(dev); - unsigned char pos5; - - pos5 = mca_device_read_pos(mca_dev, 5); - - if (!(pos5 & 0x80)) { - /* - * Bit 7 of POS 5 is reset when this adapter has a hardware - * error. Bit 7 it reset if there's error information - * available in POS 6 and 7. - */ - mca_handle_nmi_device(mca_dev, !(pos5 & 0x40)); - return 1; - } - return 0; -} - -void __kprobes mca_handle_nmi(void) -{ - /* - * First try - scan the various adapters and see if a specific - * adapter was responsible for the error. - */ - bus_for_each_dev(&mca_bus_type, NULL, NULL, mca_handle_nmi_callback); -} diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c index ca470e4c92d..b02d4dd6b8a 100644 --- a/arch/x86/kernel/mpparse.c +++ b/arch/x86/kernel/mpparse.c @@ -97,7 +97,7 @@ static void __init MP_bus_info(struct mpc_bus *m) set_bit(m->busid, mp_bus_not_pci); if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA) - 1) == 0) { -#if defined(CONFIG_EISA) || defined(CONFIG_MCA) +#ifdef CONFIG_EISA mp_bus_id_to_type[m->busid] = MP_BUS_ISA; #endif } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) { @@ -105,12 +105,10 @@ static void __init MP_bus_info(struct mpc_bus *m) x86_init.mpparse.mpc_oem_pci_bus(m); clear_bit(m->busid, mp_bus_not_pci); -#if defined(CONFIG_EISA) || defined(CONFIG_MCA) +#ifdef CONFIG_EISA mp_bus_id_to_type[m->busid] = MP_BUS_PCI; } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA) - 1) == 0) { mp_bus_id_to_type[m->busid] = MP_BUS_EISA; - } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA) - 1) == 0) { - mp_bus_id_to_type[m->busid] = MP_BUS_MCA; #endif } else printk(KERN_WARNING "Unknown bustype %s - ignoring\n", str); @@ -368,9 +366,6 @@ static void __init construct_ioapic_table(int mpc_default_type) case 3: memcpy(bus.bustype, "EISA ", 6); break; - case 4: - case 7: - memcpy(bus.bustype, "MCA ", 6); } MP_bus_info(&bus); if (mpc_default_type > 4) { @@ -623,7 +618,7 @@ void __init default_find_smp_config(void) return; /* * If it is an SMP machine we should know now, unless the - * configuration is in an EISA/MCA bus machine with an + * configuration is in an EISA bus machine with an * extended bios data area. * * there is a real-mode segmented pointer pointing to the diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c index 47acaf31916..7b3fdfdabf9 100644 --- a/arch/x86/kernel/nmi.c +++ b/arch/x86/kernel/nmi.c @@ -19,8 +19,6 @@ #include #include -#include - #if defined(CONFIG_EDAC) #include #endif @@ -282,16 +280,6 @@ unknown_nmi_error(unsigned char reason, struct pt_regs *regs) __this_cpu_add(nmi_stats.unknown, 1); -#ifdef CONFIG_MCA - /* - * Might actually be able to figure out what the guilty party - * is: - */ - if (MCA_bus) { - mca_handle_nmi(); - return; - } -#endif pr_emerg("Uhhuh. NMI received for unknown reason %02x on CPU %d.\n", reason, smp_processor_id()); diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 1a290156205..879166402bf 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -179,12 +178,6 @@ struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1}; /* common cpu data for all cpus */ struct cpuinfo_x86 boot_cpu_data __read_mostly = {0, 0, 0, 0, -1, 1, 0, 0, -1}; EXPORT_SYMBOL(boot_cpu_data); -static void set_mca_bus(int x) -{ -#ifdef CONFIG_MCA - MCA_bus = x; -#endif -} unsigned int def_to_bigsmp; @@ -717,7 +710,6 @@ void __init setup_arch(char **cmdline_p) apm_info.bios = boot_params.apm_bios_info; ist_info = boot_params.ist_info; if (boot_params.sys_desc_table.length != 0) { - set_mca_bus(boot_params.sys_desc_table.table[3] & 0x2); machine_id = boot_params.sys_desc_table.table[0]; machine_submodel_id = boot_params.sys_desc_table.table[1]; BIOS_revision = boot_params.sys_desc_table.table[2]; diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c index c6eba2b4267..24d3c91e981 100644 --- a/arch/x86/kernel/time.c +++ b/arch/x86/kernel/time.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include @@ -58,11 +57,6 @@ EXPORT_SYMBOL(profile_pc); static irqreturn_t timer_interrupt(int irq, void *dev_id) { global_clock_event->event_handler(global_clock_event); - - /* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */ - if (MCA_bus) - outb_p(inb_p(0x61)| 0x80, 0x61); - return IRQ_HANDLED; } diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index ff9281f1602..4754f510b36 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c @@ -37,10 +37,6 @@ #include #endif -#ifdef CONFIG_MCA -#include -#endif - #if defined(CONFIG_EDAC) #include #endif diff --git a/drivers/Makefile b/drivers/Makefile index 95952c82bf1..f9b82f2c7c4 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -92,7 +92,6 @@ obj-$(CONFIG_BT) += bluetooth/ obj-$(CONFIG_ACCESSIBILITY) += accessibility/ obj-$(CONFIG_ISDN) += isdn/ obj-$(CONFIG_EDAC) += edac/ -obj-$(CONFIG_MCA) += mca/ obj-$(CONFIG_EISA) += eisa/ obj-y += lguest/ obj-$(CONFIG_CPU_FREQ) += cpufreq/ diff --git a/drivers/mca/Kconfig b/drivers/mca/Kconfig deleted file mode 100644 index a7a0220ab4b..00000000000 --- a/drivers/mca/Kconfig +++ /dev/null @@ -1,14 +0,0 @@ -config MCA_LEGACY - bool "Legacy MCA API Support" - depends on MCA - help - This compiles in support for the old slot based MCA API. If you - have an unconverted MCA driver, you will need to say Y here. It - is safe to say Y anyway. - -config MCA_PROC_FS - bool "Support for the mca entry in /proc" - depends on MCA_LEGACY && PROC_FS - help - If you want the old style /proc/mca directory in addition to the - new style sysfs say Y here. diff --git a/drivers/mca/Makefile b/drivers/mca/Makefile deleted file mode 100644 index 0794b122520..00000000000 --- a/drivers/mca/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -# Makefile for the Linux MCA bus support - -obj-y := mca-bus.o mca-device.o mca-driver.o - -obj-$(CONFIG_MCA_PROC_FS) += mca-proc.o -obj-$(CONFIG_MCA_LEGACY) += mca-legacy.o - diff --git a/drivers/mca/mca-bus.c b/drivers/mca/mca-bus.c deleted file mode 100644 index ada5ebbaa25..00000000000 --- a/drivers/mca/mca-bus.c +++ /dev/null @@ -1,169 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* - * MCA bus support functions for sysfs. - * - * (C) 2002 James Bottomley - * -**----------------------------------------------------------------------------- -** -** 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., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- - */ - -#include -#include -#include -#include -#include -#include - -/* Very few machines have more than one MCA bus. However, there are - * those that do (Voyager 35xx/5xxx), so we do it this way for future - * expansion. None that I know have more than 2 */ -static struct mca_bus *mca_root_busses[MAX_MCA_BUSSES]; - -#define MCA_DEVINFO(i,s) { .pos = i, .name = s } - -struct mca_device_info { - short pos_id; /* the 2 byte pos id for this card */ - char name[50]; -}; - -static int mca_bus_match (struct device *dev, struct device_driver *drv) -{ - struct mca_device *mca_dev = to_mca_device (dev); - struct mca_driver *mca_drv = to_mca_driver (drv); - const unsigned short *mca_ids = mca_drv->id_table; - int i = 0; - - if (mca_ids) { - for(i = 0; mca_ids[i]; i++) { - if (mca_ids[i] == mca_dev->pos_id) { - mca_dev->index = i; - return 1; - } - } - } - /* If the integrated id is present, treat it as though it were an - * additional id in the id_table (it can't be because by definition, - * integrated id's overflow a short */ - if (mca_drv->integrated_id && mca_dev->pos_id == - mca_drv->integrated_id) { - mca_dev->index = i; - return 1; - } - return 0; -} - -struct bus_type mca_bus_type = { - .name = "MCA", - .match = mca_bus_match, -}; -EXPORT_SYMBOL (mca_bus_type); - -static ssize_t mca_show_pos_id(struct device *dev, struct device_attribute *attr, char *buf) -{ - /* four digits, \n and trailing \0 */ - struct mca_device *mca_dev = to_mca_device(dev); - int len; - - if(mca_dev->pos_id < MCA_DUMMY_POS_START) - len = sprintf(buf, "%04x\n", mca_dev->pos_id); - else - len = sprintf(buf, "none\n"); - return len; -} -static ssize_t mca_show_pos(struct device *dev, struct device_attribute *attr, char *buf) -{ - /* enough for 8 two byte hex chars plus space and new line */ - int j, len=0; - struct mca_device *mca_dev = to_mca_device(dev); - - for(j=0; j<8; j++) - len += sprintf(buf+len, "%02x ", mca_dev->pos[j]); - /* change last trailing space to new line */ - buf[len-1] = '\n'; - return len; -} - -static DEVICE_ATTR(id, S_IRUGO, mca_show_pos_id, NULL); -static DEVICE_ATTR(pos, S_IRUGO, mca_show_pos, NULL); - -int __init mca_register_device(int bus, struct mca_device *mca_dev) -{ - struct mca_bus *mca_bus = mca_root_busses[bus]; - int rc; - - mca_dev->dev.parent = &mca_bus->dev; - mca_dev->dev.bus = &mca_bus_type; - dev_set_name(&mca_dev->dev, "%02d:%02X", bus, mca_dev->slot); - mca_dev->dma_mask = mca_bus->default_dma_mask; - mca_dev->dev.dma_mask = &mca_dev->dma_mask; - mca_dev->dev.coherent_dma_mask = mca_dev->dma_mask; - - rc = device_register(&mca_dev->dev); - if (rc) - goto err_out; - - rc = device_create_file(&mca_dev->dev, &dev_attr_id); - if (rc) goto err_out_devreg; - rc = device_create_file(&mca_dev->dev, &dev_attr_pos); - if (rc) goto err_out_id; - - return 1; - -err_out_id: - device_remove_file(&mca_dev->dev, &dev_attr_id); -err_out_devreg: - device_unregister(&mca_dev->dev); -err_out: - return 0; -} - -/* */ -struct mca_bus * __devinit mca_attach_bus(int bus) -{ - struct mca_bus *mca_bus; - - if (unlikely(mca_root_busses[bus] != NULL)) { - /* This should never happen, but just in case */ - printk(KERN_EMERG "MCA tried to add already existing bus %d\n", - bus); - dump_stack(); - return NULL; - } - - mca_bus = kzalloc(sizeof(struct mca_bus), GFP_KERNEL); - if (!mca_bus) - return NULL; - - dev_set_name(&mca_bus->dev, "mca%d", bus); - sprintf(mca_bus->name,"Host %s MCA Bridge", bus ? "Secondary" : "Primary"); - if (device_register(&mca_bus->dev)) { - kfree(mca_bus); - return NULL; - } - - mca_root_busses[bus] = mca_bus; - - return mca_bus; -} - -int __init mca_system_init (void) -{ - return bus_register(&mca_bus_type); -} diff --git a/drivers/mca/mca-device.c b/drivers/mca/mca-device.c deleted file mode 100644 index e7adf89fae4..00000000000 --- a/drivers/mca/mca-device.c +++ /dev/null @@ -1,218 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* - * MCA device support functions - * - * These functions support the ongoing device access API. - * - * (C) 2002 James Bottomley - * -**----------------------------------------------------------------------------- -** -** 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., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- - */ - -#include -#include -#include -#include - -/** - * mca_device_read_stored_pos - read POS register from stored data - * @mca_dev: device to read from - * @reg: register to read from - * - * Fetch a POS value that was stored at boot time by the kernel - * when it scanned the MCA space. The register value is returned. - * Missing or invalid registers report 0. - */ -unsigned char mca_device_read_stored_pos(struct mca_device *mca_dev, int reg) -{ - if(reg < 0 || reg >= 8) - return 0; - - return mca_dev->pos[reg]; -} -EXPORT_SYMBOL(mca_device_read_stored_pos); - -/** - * mca_device_read_pos - read POS register from card - * @mca_dev: device to read from - * @reg: register to read from - * - * Fetch a POS value directly from the hardware to obtain the - * current value. This is much slower than - * mca_device_read_stored_pos and may not be invoked from - * interrupt context. It handles the deep magic required for - * onboard devices transparently. - */ -unsigned char mca_device_read_pos(struct mca_device *mca_dev, int reg) -{ - struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent); - - return mca_bus->f.mca_read_pos(mca_dev, reg); - - return mca_dev->pos[reg]; -} -EXPORT_SYMBOL(mca_device_read_pos); - - -/** - * mca_device_write_pos - read POS register from card - * @mca_dev: device to write pos register to - * @reg: register to write to - * @byte: byte to write to the POS registers - * - * Store a POS value directly to the hardware. You should not - * normally need to use this function and should have a very good - * knowledge of MCA bus before you do so. Doing this wrongly can - * damage the hardware. - * - * This function may not be used from interrupt context. - * - */ -void mca_device_write_pos(struct mca_device *mca_dev, int reg, - unsigned char byte) -{ - struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent); - - mca_bus->f.mca_write_pos(mca_dev, reg, byte); -} -EXPORT_SYMBOL(mca_device_write_pos); - -/** - * mca_device_transform_irq - transform the ADF obtained IRQ - * @mca_device: device whose irq needs transforming - * @irq: input irq from ADF - * - * MCA Adapter Definition Files (ADF) contain irq, ioport, memory - * etc. definitions. In systems with more than one bus, these need - * to be transformed through bus mapping functions to get the real - * system global quantities. - * - * This function transforms the interrupt number and returns the - * transformed system global interrupt - */ -int mca_device_transform_irq(struct mca_device *mca_dev, int irq) -{ - struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent); - - return mca_bus->f.mca_transform_irq(mca_dev, irq); -} -EXPORT_SYMBOL(mca_device_transform_irq); - -/** - * mca_device_transform_ioport - transform the ADF obtained I/O port - * @mca_device: device whose port needs transforming - * @ioport: input I/O port from ADF - * - * MCA Adapter Definition Files (ADF) contain irq, ioport, memory - * etc. definitions. In systems with more than one bus, these need - * to be transformed through bus mapping functions to get the real - * system global quantities. - * - * This function transforms the I/O port number and returns the - * transformed system global port number. - * - * This transformation can be assumed to be linear for port ranges. - */ -int mca_device_transform_ioport(struct mca_device *mca_dev, int port) -{ - struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent); - - return mca_bus->f.mca_transform_ioport(mca_dev, port); -} -EXPORT_SYMBOL(mca_device_transform_ioport); - -/** - * mca_device_transform_memory - transform the ADF obtained memory - * @mca_device: device whose memory region needs transforming - * @mem: memory region start from ADF - * - * MCA Adapter Definition Files (ADF) contain irq, ioport, memory - * etc. definitions. In systems with more than one bus, these need - * to be transformed through bus mapping functions to get the real - * system global quantities. - * - * This function transforms the memory region start and returns the - * transformed system global memory region (physical). - * - * This transformation can be assumed to be linear for region ranges. - */ -void *mca_device_transform_memory(struct mca_device *mca_dev, void *mem) -{ - struct mca_bus *mca_bus = to_mca_bus(mca_dev->dev.parent); - - return mca_bus->f.mca_transform_memory(mca_dev, mem); -} -EXPORT_SYMBOL(mca_device_transform_memory); - - -/** - * mca_device_claimed - check if claimed by driver - * @mca_dev: device to check - * - * Returns 1 if the slot has been claimed by a driver - */ - -int mca_device_claimed(struct mca_device *mca_dev) -{ - return mca_dev->driver_loaded; -} -EXPORT_SYMBOL(mca_device_claimed); - -/** - * mca_device_set_claim - set the claim value of the driver - * @mca_dev: device to set value for - * @val: claim value to set (1 claimed, 0 unclaimed) - */ -void mca_device_set_claim(struct mca_device *mca_dev, int val) -{ - mca_dev->driver_loaded = val; -} -EXPORT_SYMBOL(mca_device_set_claim); - -/** - * mca_device_status - get the status of the device - * @mca_device: device to get - * - * returns an enumeration of the device status: - * - * MCA_ADAPTER_NORMAL adapter is OK. - * MCA_ADAPTER_NONE no adapter at device (should never happen). - * MCA_ADAPTER_DISABLED adapter is disabled. - * MCA_ADAPTER_ERROR adapter cannot be initialised. - */ -enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev) -{ - return mca_dev->status; -} -EXPORT_SYMBOL(mca_device_status); - -/** - * mca_device_set_name - set the name of the device - * @mca_device: device to set the name of - * @name: name to set - */ -void mca_device_set_name(struct mca_device *mca_dev, const char *name) -{ - if(!mca_dev) - return; - - strlcpy(mca_dev->name, name, sizeof(mca_dev->name)); -} -EXPORT_SYMBOL(mca_device_set_name); diff --git a/drivers/mca/mca-driver.c b/drivers/mca/mca-driver.c deleted file mode 100644 index 32cd39bcc71..00000000000 --- a/drivers/mca/mca-driver.c +++ /dev/null @@ -1,63 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* - * MCA driver support functions for sysfs. - * - * (C) 2002 James Bottomley - * -**----------------------------------------------------------------------------- -** -** 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., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- - */ - -#include -#include -#include - -int mca_register_driver(struct mca_driver *mca_drv) -{ - int r; - - if (MCA_bus) { - mca_drv->driver.bus = &mca_bus_type; - if ((r = driver_register(&mca_drv->driver)) < 0) - return r; - mca_drv->integrated_id = 0; - } - - return 0; -} -EXPORT_SYMBOL(mca_register_driver); - -int mca_register_driver_integrated(struct mca_driver *mca_driver, - int integrated_id) -{ - int r = mca_register_driver(mca_driver); - - if (!r) - mca_driver->integrated_id = integrated_id; - - return r; -} -EXPORT_SYMBOL(mca_register_driver_integrated); - -void mca_unregister_driver(struct mca_driver *mca_drv) -{ - if (MCA_bus) - driver_unregister(&mca_drv->driver); -} -EXPORT_SYMBOL(mca_unregister_driver); diff --git a/drivers/mca/mca-legacy.c b/drivers/mca/mca-legacy.c deleted file mode 100644 index 494f0c2001f..00000000000 --- a/drivers/mca/mca-legacy.c +++ /dev/null @@ -1,329 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* - * MCA bus support functions for legacy (2.4) API. - * - * Legacy API means the API that operates in terms of MCA slot number - * - * (C) 2002 James Bottomley - * -**----------------------------------------------------------------------------- -** -** 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., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- - */ - -#include -#include -#include -#include - -/* NOTE: This structure is stack allocated */ -struct mca_find_adapter_info { - int id; - int slot; - struct mca_device *mca_dev; -}; - -/* The purpose of this iterator is to loop over all the devices and - * find the one with the smallest slot number that's just greater than - * or equal to the required slot with a matching id */ -static int mca_find_adapter_callback(struct device *dev, void *data) -{ - struct mca_find_adapter_info *info = data; - struct mca_device *mca_dev = to_mca_device(dev); - - if(mca_dev->pos_id != info->id) - return 0; - - if(mca_dev->slot < info->slot) - return 0; - - if(!info->mca_dev || info->mca_dev->slot >= mca_dev->slot) - info->mca_dev = mca_dev; - - return 0; -} - -/** - * mca_find_adapter - scan for adapters - * @id: MCA identification to search for - * @start: starting slot - * - * Search the MCA configuration for adapters matching the 16bit - * ID given. The first time it should be called with start as zero - * and then further calls made passing the return value of the - * previous call until %MCA_NOTFOUND is returned. - * - * Disabled adapters are not reported. - */ - -int mca_find_adapter(int id, int start) -{ - struct mca_find_adapter_info info; - - if(id == 0xffff) - return MCA_NOTFOUND; - - info.slot = start; - info.id = id; - info.mca_dev = NULL; - - for(;;) { - bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_adapter_callback); - - if(info.mca_dev == NULL) - return MCA_NOTFOUND; - - if(info.mca_dev->status != MCA_ADAPTER_DISABLED) - break; - - /* OK, found adapter but it was disabled. Go around - * again, excluding the slot we just found */ - - info.slot = info.mca_dev->slot + 1; - info.mca_dev = NULL; - } - - return info.mca_dev->slot; -} -EXPORT_SYMBOL(mca_find_adapter); - -/*--------------------------------------------------------------------*/ - -/** - * mca_find_unused_adapter - scan for unused adapters - * @id: MCA identification to search for - * @start: starting slot - * - * Search the MCA configuration for adapters matching the 16bit - * ID given. The first time it should be called with start as zero - * and then further calls made passing the return value of the - * previous call until %MCA_NOTFOUND is returned. - * - * Adapters that have been claimed by drivers and those that - * are disabled are not reported. This function thus allows a driver - * to scan for further cards when some may already be driven. - */ - -int mca_find_unused_adapter(int id, int start) -{ - struct mca_find_adapter_info info = { 0 }; - - if (!MCA_bus || id == 0xffff) - return MCA_NOTFOUND; - - info.slot = start; - info.id = id; - info.mca_dev = NULL; - - for(;;) { - bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_adapter_callback); - - if(info.mca_dev == NULL) - return MCA_NOTFOUND; - - if(info.mca_dev->status != MCA_ADAPTER_DISABLED - && !info.mca_dev->driver_loaded) - break; - - /* OK, found adapter but it was disabled or already in - * use. Go around again, excluding the slot we just - * found */ - - info.slot = info.mca_dev->slot + 1; - info.mca_dev = NULL; - } - - return info.mca_dev->slot; -} -EXPORT_SYMBOL(mca_find_unused_adapter); - -/* NOTE: stack allocated structure */ -struct mca_find_device_by_slot_info { - int slot; - struct mca_device *mca_dev; -}; - -static int mca_find_device_by_slot_callback(struct device *dev, void *data) -{ - struct mca_find_device_by_slot_info *info = data; - struct mca_device *mca_dev = to_mca_device(dev); - - if(mca_dev->slot == info->slot) - info->mca_dev = mca_dev; - - return 0; -} - -struct mca_device *mca_find_device_by_slot(int slot) -{ - struct mca_find_device_by_slot_info info; - - info.slot = slot; - info.mca_dev = NULL; - - bus_for_each_dev(&mca_bus_type, NULL, &info, mca_find_device_by_slot_callback); - - return info.mca_dev; -} - -/** - * mca_read_stored_pos - read POS register from boot data - * @slot: slot number to read from - * @reg: register to read from - * - * Fetch a POS value that was stored at boot time by the kernel - * when it scanned the MCA space. The register value is returned. - * Missing or invalid registers report 0. - */ -unsigned char mca_read_stored_pos(int slot, int reg) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - return 0; - - return mca_device_read_stored_pos(mca_dev, reg); -} -EXPORT_SYMBOL(mca_read_stored_pos); - - -/** - * mca_read_pos - read POS register from card - * @slot: slot number to read from - * @reg: register to read from - * - * Fetch a POS value directly from the hardware to obtain the - * current value. This is much slower than mca_read_stored_pos and - * may not be invoked from interrupt context. It handles the - * deep magic required for onboard devices transparently. - */ - -unsigned char mca_read_pos(int slot, int reg) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - return 0; - - return mca_device_read_pos(mca_dev, reg); -} -EXPORT_SYMBOL(mca_read_pos); - - -/** - * mca_write_pos - read POS register from card - * @slot: slot number to read from - * @reg: register to read from - * @byte: byte to write to the POS registers - * - * Store a POS value directly from the hardware. You should not - * normally need to use this function and should have a very good - * knowledge of MCA bus before you do so. Doing this wrongly can - * damage the hardware. - * - * This function may not be used from interrupt context. - * - * Note that this a technically a Bad Thing, as IBM tech stuff says - * you should only set POS values through their utilities. - * However, some devices such as the 3c523 recommend that you write - * back some data to make sure the configuration is consistent. - * I'd say that IBM is right, but I like my drivers to work. - * - * This function can't do checks to see if multiple devices end up - * with the same resources, so you might see magic smoke if someone - * screws up. - */ - -void mca_write_pos(int slot, int reg, unsigned char byte) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - return; - - mca_device_write_pos(mca_dev, reg, byte); -} -EXPORT_SYMBOL(mca_write_pos); - -/** - * mca_set_adapter_name - Set the description of the card - * @slot: slot to name - * @name: text string for the namen - * - * This function sets the name reported via /proc for this - * adapter slot. This is for user information only. Setting a - * name deletes any previous name. - */ - -void mca_set_adapter_name(int slot, char* name) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - return; - - mca_device_set_name(mca_dev, name); -} -EXPORT_SYMBOL(mca_set_adapter_name); - -/** - * mca_mark_as_used - claim an MCA device - * @slot: slot to claim - * FIXME: should we make this threadsafe - * - * Claim an MCA slot for a device driver. If the - * slot is already taken the function returns 1, - * if it is not taken it is claimed and 0 is - * returned. - */ - -int mca_mark_as_used(int slot) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - /* FIXME: this is actually a severe error */ - return 1; - - if(mca_device_claimed(mca_dev)) - return 1; - - mca_device_set_claim(mca_dev, 1); - - return 0; -} -EXPORT_SYMBOL(mca_mark_as_used); - -/** - * mca_mark_as_unused - release an MCA device - * @slot: slot to claim - * - * Release the slot for other drives to use. - */ - -void mca_mark_as_unused(int slot) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - return; - - mca_device_set_claim(mca_dev, 0); -} -EXPORT_SYMBOL(mca_mark_as_unused); - diff --git a/drivers/mca/mca-proc.c b/drivers/mca/mca-proc.c deleted file mode 100644 index 81ea0d377bf..00000000000 --- a/drivers/mca/mca-proc.c +++ /dev/null @@ -1,249 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* - * MCA bus support functions for the proc fs. - * - * NOTE: this code *requires* the legacy MCA api. - * - * Legacy API means the API that operates in terms of MCA slot number - * - * (C) 2002 James Bottomley - * -**----------------------------------------------------------------------------- -** -** 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., 675 Mass Ave, Cambridge, MA 02139, USA. -** -**----------------------------------------------------------------------------- - */ -#include -#include -#include -#include - -static int get_mca_info_helper(struct mca_device *mca_dev, char *page, int len) -{ - int j; - - for(j=0; j<8; j++) - len += sprintf(page+len, "%02x ", - mca_dev ? mca_dev->pos[j] : 0xff); - len += sprintf(page+len, " %s\n", mca_dev ? mca_dev->name : ""); - return len; -} - -static int get_mca_info(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - int i, len = 0; - - if(MCA_bus) { - struct mca_device *mca_dev; - /* Format POS registers of eight MCA slots */ - - for(i=0; icount) len = count; - if (len<0) len = 0; - return len; -} - -/*--------------------------------------------------------------------*/ - -static int mca_default_procfn(char* buf, struct mca_device *mca_dev) -{ - int len = 0, i; - int slot = mca_dev->slot; - - /* Print out the basic information */ - - if(slot < MCA_MAX_SLOT_NR) { - len += sprintf(buf+len, "Slot: %d\n", slot+1); - } else if(slot == MCA_INTEGSCSI) { - len += sprintf(buf+len, "Integrated SCSI Adapter\n"); - } else if(slot == MCA_INTEGVIDEO) { - len += sprintf(buf+len, "Integrated Video Adapter\n"); - } else if(slot == MCA_MOTHERBOARD) { - len += sprintf(buf+len, "Motherboard\n"); - } - if (mca_dev->name[0]) { - - /* Drivers might register a name without /proc handler... */ - - len += sprintf(buf+len, "Adapter Name: %s\n", - mca_dev->name); - } else { - len += sprintf(buf+len, "Adapter Name: Unknown\n"); - } - len += sprintf(buf+len, "Id: %02x%02x\n", - mca_dev->pos[1], mca_dev->pos[0]); - len += sprintf(buf+len, "Enabled: %s\nPOS: ", - mca_device_status(mca_dev) == MCA_ADAPTER_NORMAL ? - "Yes" : "No"); - for(i=0; i<8; i++) { - len += sprintf(buf+len, "%02x ", mca_dev->pos[i]); - } - len += sprintf(buf+len, "\nDriver Installed: %s", - mca_device_claimed(mca_dev) ? "Yes" : "No"); - buf[len++] = '\n'; - buf[len] = 0; - - return len; -} /* mca_default_procfn() */ - -static int get_mca_machine_info(char* page, char **start, off_t off, - int count, int *eof, void *data) -{ - int len = 0; - - len += sprintf(page+len, "Model Id: 0x%x\n", machine_id); - len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id); - len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision); - - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} - -static int mca_read_proc(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ - struct mca_device *mca_dev = (struct mca_device *)data; - int len = 0; - - /* Get the standard info */ - - len = mca_default_procfn(page, mca_dev); - - /* Do any device-specific processing, if there is any */ - - if(mca_dev->procfn) { - len += mca_dev->procfn(page+len, mca_dev->slot, - mca_dev->proc_dev); - } - if (len <= off+count) *eof = 1; - *start = page + off; - len -= off; - if (len>count) len = count; - if (len<0) len = 0; - return len; -} /* mca_read_proc() */ - -/*--------------------------------------------------------------------*/ - -void __init mca_do_proc_init(void) -{ - int i; - struct proc_dir_entry *proc_mca; - struct proc_dir_entry* node = NULL; - struct mca_device *mca_dev; - - proc_mca = proc_mkdir("mca", NULL); - create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL); - create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL); - - /* Initialize /proc/mca entries for existing adapters */ - - for(i = 0; i < MCA_NUMADAPTERS; i++) { - enum MCA_AdapterStatus status; - mca_dev = mca_find_device_by_slot(i); - if(!mca_dev) - continue; - - mca_dev->procfn = NULL; - - if(i < MCA_MAX_SLOT_NR) sprintf(mca_dev->procname,"slot%d", i+1); - else if(i == MCA_INTEGVIDEO) sprintf(mca_dev->procname,"video"); - else if(i == MCA_INTEGSCSI) sprintf(mca_dev->procname,"scsi"); - else if(i == MCA_MOTHERBOARD) sprintf(mca_dev->procname,"planar"); - - status = mca_device_status(mca_dev); - if (status != MCA_ADAPTER_NORMAL && - status != MCA_ADAPTER_DISABLED) - continue; - - node = create_proc_read_entry(mca_dev->procname, 0, proc_mca, - mca_read_proc, (void *)mca_dev); - - if(node == NULL) { - printk("Failed to allocate memory for MCA proc-entries!"); - return; - } - } - -} /* mca_do_proc_init() */ - -/** - * mca_set_adapter_procfn - Set the /proc callback - * @slot: slot to configure - * @procfn: callback function to call for /proc - * @dev: device information passed to the callback - * - * This sets up an information callback for /proc/mca/slot?. The - * function is called with the buffer, slot, and device pointer (or - * some equally informative context information, or nothing, if you - * prefer), and is expected to put useful information into the - * buffer. The adapter name, ID, and POS registers get printed - * before this is called though, so don't do it again. - * - * This should be called with a %NULL @procfn when a module - * unregisters, thus preventing kernel crashes and other such - * nastiness. - */ - -void mca_set_adapter_procfn(int slot, MCA_ProcFn procfn, void* proc_dev) -{ - struct mca_device *mca_dev = mca_find_device_by_slot(slot); - - if(!mca_dev) - return; - - mca_dev->procfn = procfn; - mca_dev->proc_dev = proc_dev; -} -EXPORT_SYMBOL(mca_set_adapter_procfn); diff --git a/drivers/message/i2o/i2o_proc.c b/drivers/message/i2o/i2o_proc.c index 6d115c7208a..506c36f6e1d 100644 --- a/drivers/message/i2o/i2o_proc.c +++ b/drivers/message/i2o/i2o_proc.c @@ -283,7 +283,6 @@ static char *bus_strings[] = { "Local Bus", "ISA", "EISA", - "MCA", "PCI", "PCMCIA", "NUBUS", @@ -351,18 +350,6 @@ static int i2o_seq_show_hrt(struct seq_file *seq, void *v) EisaSlotNumber); break; - case I2O_BUS_MCA: - seq_printf(seq, " IOBase: %0#6x,", - hrt->hrt_entry[i].bus.mca_bus. - McaBaseIOPort); - seq_printf(seq, " MemoryBase: %0#10x,", - hrt->hrt_entry[i].bus.mca_bus. - McaBaseMemoryAddress); - seq_printf(seq, " Slot: %0#4x,", - hrt->hrt_entry[i].bus.mca_bus. - McaSlotNumber); - break; - case I2O_BUS_PCI: seq_printf(seq, " Bus: %0#4x", hrt->hrt_entry[i].bus.pci_bus. diff --git a/include/linux/i2o-dev.h b/include/linux/i2o-dev.h index a0b23dd4523..a8093bfec3a 100644 --- a/include/linux/i2o-dev.h +++ b/include/linux/i2o-dev.h @@ -124,7 +124,7 @@ typedef struct i2o_sg_io_hdr { #define I2O_BUS_LOCAL 0 #define I2O_BUS_ISA 1 #define I2O_BUS_EISA 2 -#define I2O_BUS_MCA 3 +/* was I2O_BUS_MCA 3 */ #define I2O_BUS_PCI 4 #define I2O_BUS_PCMCIA 5 #define I2O_BUS_NUBUS 6 diff --git a/include/linux/mca-legacy.h b/include/linux/mca-legacy.h deleted file mode 100644 index 7a3aea84590..00000000000 --- a/include/linux/mca-legacy.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- mode: c; c-basic-offset: 8 -*- */ - -/* This is the function prototypes for the old legacy MCA interface - * - * Please move your driver to the new sysfs based one instead */ - -#ifndef _LINUX_MCA_LEGACY_H -#define _LINUX_MCA_LEGACY_H - -#include - -#warning "MCA legacy - please move your driver to the new sysfs api" - -/* MCA_NOTFOUND is an error condition. The other two indicate - * motherboard POS registers contain the adapter. They might be - * returned by the mca_find_adapter() function, and can be used as - * arguments to mca_read_stored_pos(). I'm not going to allow direct - * access to the motherboard registers until we run across an adapter - * that requires it. We don't know enough about them to know if it's - * safe. - * - * See Documentation/mca.txt or one of the existing drivers for - * more information. - */ -#define MCA_NOTFOUND (-1) - - - -/* Returns the slot of the first enabled adapter matching id. User can - * specify a starting slot beyond zero, to deal with detecting multiple - * devices. Returns MCA_NOTFOUND if id not found. Also checks the - * integrated adapters. - */ -extern int mca_find_adapter(int id, int start); -extern int mca_find_unused_adapter(int id, int start); - -extern int mca_mark_as_used(int slot); -extern void mca_mark_as_unused(int slot); - -/* gets a byte out of POS register (stored in memory) */ -extern unsigned char mca_read_stored_pos(int slot, int reg); - -/* This can be expanded later. Right now, it gives us a way of - * getting meaningful information into the MCA_info structure, - * so we can have a more interesting /proc/mca. - */ -extern void mca_set_adapter_name(int slot, char* name); - -/* These routines actually mess with the hardware POS registers. They - * temporarily disable the device (and interrupts), so make sure you know - * what you're doing if you use them. Furthermore, writing to a POS may - * result in two devices trying to share a resource, which in turn can - * result in multiple devices sharing memory spaces, IRQs, or even trashing - * hardware. YOU HAVE BEEN WARNED. - * - * You can only access slots with this. Motherboard registers are off - * limits. - */ - -/* read a byte from the specified POS register. */ -extern unsigned char mca_read_pos(int slot, int reg); - -/* write a byte to the specified POS register. */ -extern void mca_write_pos(int slot, int reg, unsigned char byte); - -#endif diff --git a/include/linux/mca.h b/include/linux/mca.h deleted file mode 100644 index 37972704617..00000000000 --- a/include/linux/mca.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Header for Microchannel Architecture Bus - * Written by Martin Kolinek, February 1996 - */ - -#ifndef _LINUX_MCA_H -#define _LINUX_MCA_H - -#include - -#ifdef CONFIG_MCA -#include - -extern int MCA_bus; -#else -#define MCA_bus 0 -#endif - -/* This sets up an information callback for /proc/mca/slot?. The - * function is called with the buffer, slot, and device pointer (or - * some equally informative context information, or nothing, if you - * prefer), and is expected to put useful information into the - * buffer. The adapter name, id, and POS registers get printed - * before this is called though, so don't do it again. - * - * This should be called with a NULL procfn when a module - * unregisters, thus preventing kernel crashes and other such - * nastiness. - */ -typedef int (*MCA_ProcFn)(char* buf, int slot, void* dev); - -/* Should only be called by the NMI interrupt handler, this will do some - * fancy stuff to figure out what might have generated a NMI. - */ -extern void mca_handle_nmi(void); - -enum MCA_AdapterStatus { - MCA_ADAPTER_NORMAL = 0, - MCA_ADAPTER_NONE = 1, - MCA_ADAPTER_DISABLED = 2, - MCA_ADAPTER_ERROR = 3 -}; - -struct mca_device { - u64 dma_mask; - int pos_id; - int slot; - - /* index into id_table, set by the bus match routine */ - int index; - - /* is there a driver installed? 0 - No, 1 - Yes */ - int driver_loaded; - /* POS registers */ - unsigned char pos[8]; - /* if a pseudo adapter of the motherboard, this is the motherboard - * register value to use for setup cycles */ - short pos_register; - - enum MCA_AdapterStatus status; -#ifdef CONFIG_MCA_PROC_FS - /* name of the proc/mca file */ - char procname[8]; - /* /proc info callback */ - MCA_ProcFn procfn; - /* device/context info for proc callback */ - void *proc_dev; -#endif - struct device dev; - char name[32]; -}; -#define to_mca_device(mdev) container_of(mdev, struct mca_device, dev) - -struct mca_bus_accessor_functions { - unsigned char (*mca_read_pos)(struct mca_device *, int reg); - void (*mca_write_pos)(struct mca_device *, int reg, - unsigned char byte); - int (*mca_transform_irq)(struct mca_device *, int irq); - int (*mca_transform_ioport)(struct mca_device *, - int region); - void * (*mca_transform_memory)(struct mca_device *, - void *memory); -}; - -struct mca_bus { - u64 default_dma_mask; - int number; - struct mca_bus_accessor_functions f; - struct device dev; - char name[32]; -}; -#define to_mca_bus(mdev) container_of(mdev, struct mca_bus, dev) - -struct mca_driver { - const short *id_table; - void *driver_data; - int integrated_id; - struct device_driver driver; -}; -#define to_mca_driver(mdriver) container_of(mdriver, struct mca_driver, driver) - -/* Ongoing supported API functions */ -extern struct mca_device *mca_find_device_by_slot(int slot); -extern int mca_system_init(void); -extern struct mca_bus *mca_attach_bus(int); - -extern unsigned char mca_device_read_stored_pos(struct mca_device *mca_dev, - int reg); -extern unsigned char mca_device_read_pos(struct mca_device *mca_dev, int reg); -extern void mca_device_write_pos(struct mca_device *mca_dev, int reg, - unsigned char byte); -extern int mca_device_transform_irq(struct mca_device *mca_dev, int irq); -extern int mca_device_transform_ioport(struct mca_device *mca_dev, int port); -extern void *mca_device_transform_memory(struct mca_device *mca_dev, - void *mem); -extern int mca_device_claimed(struct mca_device *mca_dev); -extern void mca_device_set_claim(struct mca_device *mca_dev, int val); -extern void mca_device_set_name(struct mca_device *mca_dev, const char *name); -static inline char *mca_device_get_name(struct mca_device *mca_dev) -{ - return mca_dev ? mca_dev->name : NULL; -} - -extern enum MCA_AdapterStatus mca_device_status(struct mca_device *mca_dev); - -extern struct bus_type mca_bus_type; - -extern int mca_register_driver(struct mca_driver *drv); -extern int mca_register_driver_integrated(struct mca_driver *, int); -extern void mca_unregister_driver(struct mca_driver *drv); - -/* WARNING: only called by the boot time device setup */ -extern int mca_register_device(int bus, struct mca_device *mca_dev); - -#ifdef CONFIG_MCA_PROC_FS -extern void mca_do_proc_init(void); -extern void mca_set_adapter_procfn(int slot, MCA_ProcFn, void* dev); -#else -static inline void mca_do_proc_init(void) -{ -} - -static inline void mca_set_adapter_procfn(int slot, MCA_ProcFn fn, void* dev) -{ -} -#endif - -#endif /* _LINUX_MCA_H */ diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 2c6286c0bc1..f606738d421 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c @@ -240,7 +240,7 @@ search_help[] = N_( "Defined at drivers/pci/Kconfig:47\n" "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" "Location:\n" - " -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" + " -> Bus options (PCI, PCMCIA, EISA, ISA)\n" " -> PCI support (PCI [=y])\n" " -> PCI access mode ( [=y])\n" "Selects: LIBCRC32\n" diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 73070cb0b6d..8c0eb65978c 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -223,7 +223,7 @@ search_help[] = N_( "Defined at drivers/pci/Kconfig:47\n" "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n" "Location:\n" -" -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n" +" -> Bus options (PCI, PCMCIA, EISA, ISA)\n" " -> PCI support (PCI [ = y])\n" " -> PCI access mode ( [ = y])\n" "Selects: LIBCRC32\n" -- cgit v1.2.3-70-g09d2 From eb3d5cc67a525df5115c1dc1c0ff8a111bda70e4 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 23 May 2012 22:28:49 +0930 Subject: modpost: Stop grab_file() from leaking filedescriptors if fstat() fails In case the open() call succeeds but the subsequent fstat() call fails, then we'll return without close()'ing the filedescriptor. Signed-off-by: Jesper Juhl Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index c4e7d1510f9..ea0eaca597b 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -337,17 +337,20 @@ static void sym_update_crc(const char *name, struct module *mod, void *grab_file(const char *filename, unsigned long *size) { struct stat st; - void *map; + void *map = MAP_FAILED; int fd; fd = open(filename, O_RDONLY); - if (fd < 0 || fstat(fd, &st) != 0) + if (fd < 0) return NULL; + if (fstat(fd, &st)) + goto failed; *size = st.st_size; map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); - close(fd); +failed: + close(fd); if (map == MAP_FAILED) return NULL; return map; -- cgit v1.2.3-70-g09d2 From 3c7ec94d2c4a67d9663a080aa5080134308261c4 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 25 Apr 2012 11:10:15 -0700 Subject: modpost: use proper kernel style for autogenerated files If the kernel build process is creating files automatically, the least it can do is create them in a properly formatted manner. Sure, it's a minor issue, but being consistent is nice. Cc: Rusty Russell Cc: Alessio Igor Bogani Cc: Tony Lindgren Cc: Ben Hutchings Cc: Russell King Signed-off-by: Greg Kroah-Hartman Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'scripts') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index ea0eaca597b..0f84bb38eb0 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1853,14 +1853,14 @@ static void add_header(struct buffer *b, struct module *mod) buf_printf(b, "\n"); buf_printf(b, "struct module __this_module\n"); buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); - buf_printf(b, " .name = KBUILD_MODNAME,\n"); + buf_printf(b, "\t.name = KBUILD_MODNAME,\n"); if (mod->has_init) - buf_printf(b, " .init = init_module,\n"); + buf_printf(b, "\t.init = init_module,\n"); if (mod->has_cleanup) buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n" - " .exit = cleanup_module,\n" + "\t.exit = cleanup_module,\n" "#endif\n"); - buf_printf(b, " .arch = MODULE_ARCH_INIT,\n"); + buf_printf(b, "\t.arch = MODULE_ARCH_INIT,\n"); buf_printf(b, "};\n"); } -- cgit v1.2.3-70-g09d2 From 4619c2b8304a0751d9ec2ba89e11f387977c8cb4 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Apr 2012 20:14:58 +0200 Subject: scripts/coccinelle: address test is always true Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/ifaddr.cocci | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 scripts/coccinelle/misc/ifaddr.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/ifaddr.cocci b/scripts/coccinelle/misc/ifaddr.cocci new file mode 100644 index 00000000000..3e4089a7700 --- /dev/null +++ b/scripts/coccinelle/misc/ifaddr.cocci @@ -0,0 +1,35 @@ +/// the address of a variable or field is non-zero is likely always to bo +/// non-zero +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report +virtual context + +@r@ +expression x; +statement S1,S2; +position p; +@@ + +*if@p (&x) + S1 else S2 + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("test of a variable/field address",p) + +@script:python depends on report@ +p << r.p; +@@ + +msg = "ERROR: test of a variable/field address" +coccilib.report.print_report(p[0],msg) -- cgit v1.2.3-70-g09d2 From 2cbd08253a011bd9db9a51f15a974df3a779224b Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Sat, 21 Apr 2012 20:23:48 +0200 Subject: scripts/coccinelle: sizeof of pointer Signed-off-by: Julia Lawall Signed-off-by: Michal Marek --- scripts/coccinelle/misc/noderef.cocci | 65 +++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 scripts/coccinelle/misc/noderef.cocci (limited to 'scripts') diff --git a/scripts/coccinelle/misc/noderef.cocci b/scripts/coccinelle/misc/noderef.cocci new file mode 100644 index 00000000000..c1707214e60 --- /dev/null +++ b/scripts/coccinelle/misc/noderef.cocci @@ -0,0 +1,65 @@ +/// sizeof when applied to a pointer typed expression gives the size of +/// the pointer +/// +// Confidence: High +// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2. +// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2. +// URL: http://coccinelle.lip6.fr/ +// Comments: +// Options: -no_includes -include_headers + +virtual org +virtual report +virtual context +virtual patch + +@depends on patch@ +expression *x; +expression f; +type T; +@@ + +( +x = <+... sizeof( +- x ++ *x + ) ...+> +| +f(...,(T)(x),...,sizeof( +- x ++ *x + ),...) +| +f(...,sizeof(x),...,(T)( +- x ++ *x + ),...) +) + +@r depends on !patch@ +expression *x; +expression f; +position p; +type T; +@@ + +( +*x = <+... sizeof@p(x) ...+> +| +*f(...,(T)(x),...,sizeof@p(x),...) +| +*f(...,sizeof@p(x),...,(T)(x),...) +) + +@script:python depends on org@ +p << r.p; +@@ + +cocci.print_main("application of sizeof to pointer",p) + +@script:python depends on report@ +p << r.p; +@@ + +msg = "ERROR: application of sizeof to pointer" +coccilib.report.print_report(p[0],msg) -- cgit v1.2.3-70-g09d2 From 19a4b988955bc1d838a55c89d3d927f3d788a7dd Mon Sep 17 00:00:00 2001 From: Lekensteyn Date: Fri, 18 May 2012 10:22:43 +0200 Subject: builddeb: include autogenerated header files After 303395ac3bf3e2cb488435537d416bc840438fcb, some headers are autogenerated. Include these autogenerated headers (mainly unistd_32_ia32.h) in out-of-tree builds to allow DKMS modules to be built succesfully. Signed-off-by: Peter Lekensteyn Signed-off-by: Michal Marek --- scripts/package/builddeb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts') diff --git a/scripts/package/builddeb b/scripts/package/builddeb index eee5f8ed249..c95fdda5841 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -245,7 +245,7 @@ fi # Build header package (cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles") (cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles") -(cd $objtree; find .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles") +(cd $objtree; find arch/$SRCARCH/include .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles") destdir=$kernel_headers_dir/usr/src/linux-headers-$version mkdir -p "$destdir" (cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -) -- cgit v1.2.3-70-g09d2 From 9a4cad4e25b91f48494f13fce3d25ea44bec7472 Mon Sep 17 00:00:00 2001 From: Eric Nelson Date: Thu, 31 May 2012 16:26:09 -0700 Subject: checkpatch: check for whitespace before semicolon at EOL Requires --strict option during invocation: ~/linux$ scripts/checkpatch --strict foo.patch This tests for a bad habits of mine like this: return 0 ; Note that it does allow a special case of a bare semicolon for empty loops: while (foo()) ; Signed-off-by: Eric Nelson Cc: Andy Whitcroft Cc: Joe Perches Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index faea0ec612b..2262e1f57fa 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2448,6 +2448,13 @@ sub process { "space prohibited between function name and open parenthesis '('\n" . $herecurr); } } + +# check for whitespace before a non-naked semicolon + if ($line =~ /^\+.*\S\s+;/) { + CHK("SPACING", + "space prohibited before semicolon\n" . $herecurr); + } + # Check operator spacing. if (!($line=~/\#\s*include/)) { my $ops = qr{ -- cgit v1.2.3-70-g09d2 From 243f3803cf2a3665092c5fd6f924f453694681a6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 31 May 2012 16:26:09 -0700 Subject: checkpatch: suggest pr_ over printk(KERN_ Suggest the shorter pr_ instead of printk(KERN_. Prefer to use pr_ over bare printks. Prefer to use pr_warn over pr_warning. Signed-off-by: Joe Perches Cc: Andy Whitcroft Cc: Theodore Ts'o Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- scripts/checkpatch.pl | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'scripts') diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 2262e1f57fa..e5bd60ff48e 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -2382,6 +2382,19 @@ sub process { } } + if ($line =~ /\bprintk\s*\(\s*KERN_([A-Z]+)/) { + my $orig = $1; + my $level = lc($orig); + $level = "warn" if ($level eq "warning"); + WARN("PREFER_PR_LEVEL", + "Prefer pr_$level(... to printk(KERN_$1, ...\n" . $herecurr); + } + + if ($line =~ /\bpr_warning\s*\(/) { + WARN("PREFER_PR_LEVEL", + "Prefer pr_warn(... to pr_warning(...\n" . $herecurr); + } + # function brace can't be on same line, except for #defines of do while, # or if closed on same line if (($line=~/$Type\s*$Ident\(.*\).*\s{/) and -- cgit v1.2.3-70-g09d2