From: <jsi...@us...> - 2007-04-10 02:01:17
|
Revision: 2362 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2362&view=rev Author: jsimmons Date: 2007-04-09 19:01:16 -0700 (Mon, 09 Apr 2007) Log Message: ----------- files ported over to 2.6.21. More to go Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/arch/i386/kernel/setup.c branches/ruby-2.6.21/ruby-2.6/arch/x86_64/kernel/setup.c branches/ruby-2.6.21/ruby-2.6/fs/compat_ioctl.c branches/ruby-2.6.21/ruby-2.6/include/linux/console.h branches/ruby-2.6.21/ruby-2.6/include/linux/consolemap.h branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h branches/ruby-2.6.21/ruby-2.6/include/linux/selection.h branches/ruby-2.6.21/ruby-2.6/include/linux/tty.h branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h Modified: branches/ruby-2.6.21/ruby-2.6/arch/i386/kernel/setup.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/arch/i386/kernel/setup.c 2007-04-10 01:57:48 UTC (rev 2361) +++ branches/ruby-2.6.21/ruby-2.6/arch/i386/kernel/setup.c 2007-04-10 02:01:16 UTC (rev 2362) @@ -25,7 +25,8 @@ #include <linux/sched.h> #include <linux/mm.h> -#include <linux/tty.h> +#include <linux/mmzone.h> +#include <linux/screen_info.h> #include <linux/ioport.h> #include <linux/acpi.h> #include <linux/apm_bios.h> @@ -40,16 +41,25 @@ #include <linux/init.h> #include <linux/edd.h> #include <linux/nodemask.h> +#include <linux/kexec.h> +#include <linux/crash_dump.h> +#include <linux/dmi.h> +#include <linux/pfn.h> + #include <video/edid.h> + +#include <asm/apic.h> #include <asm/e820.h> #include <asm/mpspec.h> +#include <asm/mmzone.h> #include <asm/setup.h> #include <asm/arch_hooks.h> #include <asm/sections.h> #include <asm/io_apic.h> #include <asm/ist.h> #include <asm/io.h> -#include "setup_arch_pre.h" +#include <asm/vmi.h> +#include <setup_arch.h> #include <bios_ebda.h> /* This value is set up by the early boot code to point to the value @@ -57,45 +67,31 @@ address, and must not be in the .bss segment! */ unsigned long init_pg_tables_end __initdata = ~0UL; -int disable_pse __initdata = 0; +int disable_pse __devinitdata = 0; /* * Machine setup.. */ +extern struct resource code_resource; +extern struct resource data_resource; -#ifdef CONFIG_EFI -int efi_enabled = 0; -EXPORT_SYMBOL(efi_enabled); -#endif - /* cpu data as detected by the assembly code in head.S */ -struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +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 = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +struct cpuinfo_x86 boot_cpu_data __read_mostly = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; -#ifdef CONFIG_ACPI_INTERPRETER - int acpi_disabled = 0; -#else - int acpi_disabled = 1; -#endif -EXPORT_SYMBOL(acpi_disabled); - -#ifdef CONFIG_ACPI_BOOT -int __initdata acpi_force = 0; -extern acpi_interrupt_flags acpi_sci_flags; -#endif - /* for MCA, but anyone else can use it if they want */ unsigned int machine_id; +#ifdef CONFIG_MCA +EXPORT_SYMBOL(machine_id); +#endif unsigned int machine_submodel_id; unsigned int BIOS_revision; unsigned int mca_pentium_flag; -/* For PCI or other memory-mapped resources */ -unsigned long pci_mem_start = 0x10000000; - /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; @@ -106,19 +102,27 @@ * Setup options */ struct drive_info_struct { char dummy[32]; } drive_info; +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || \ + defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE) +EXPORT_SYMBOL(drive_info); +#endif struct screen_info screen_info; +EXPORT_SYMBOL(screen_info); struct apm_info apm_info; +EXPORT_SYMBOL(apm_info); struct sys_desc_table_struct { unsigned short length; unsigned char table[0]; }; struct edid_info edid_info; +EXPORT_SYMBOL_GPL(edid_info); struct ist_info ist_info; -struct e820map e820; +#if defined(CONFIG_X86_SPEEDSTEP_SMI) || \ + defined(CONFIG_X86_SPEEDSTEP_SMI_MODULE) +EXPORT_SYMBOL(ist_info); +#endif extern void early_cpu_init(void); -extern void dmi_scan_machine(void); -extern void generic_apic_probe(char *); extern int root_mountflags; unsigned long saved_videomode; @@ -127,512 +131,10 @@ #define RAMDISK_PROMPT_FLAG 0x8000 #define RAMDISK_LOAD_FLAG 0x4000 -static char command_line[COMMAND_LINE_SIZE]; +static char __initdata command_line[COMMAND_LINE_SIZE]; unsigned char __initdata boot_params[PARAM_SIZE]; -static struct resource data_resource = { - .name = "Kernel data", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource code_resource = { - .name = "Kernel code", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource adapter_rom_resources[] = { { - .name = "Adapter ROM", - .start = 0xc8000, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}, { - .name = "Adapter ROM", - .start = 0, - .end = 0, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -} }; - -#define ADAPTER_ROM_RESOURCES \ - (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM -}; - -static struct resource video_ram_resource = { - .name = "Video RAM area", - .start = 0xa0000, - .end = 0xbffff, - .flags = IORESOURCE_BUSY | IORESOURCE_MEM -}; - -static struct resource standard_io_resources[] = { { - .name = "dma1", - .start = 0x0000, - .end = 0x001f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic1", - .start = 0x0020, - .end = 0x0021, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer0", - .start = 0x0040, - .end = 0x0043, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "timer1", - .start = 0x0050, - .end = 0x0053, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "keyboard", - .start = 0x0060, - .end = 0x006f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma page reg", - .start = 0x0080, - .end = 0x008f, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "pic2", - .start = 0x00a0, - .end = 0x00a1, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "dma2", - .start = 0x00c0, - .end = 0x00df, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -}, { - .name = "fpu", - .start = 0x00f0, - .end = 0x00ff, - .flags = IORESOURCE_BUSY | IORESOURCE_IO -} }; - -#define STANDARD_IO_RESOURCES \ - (sizeof standard_io_resources / sizeof standard_io_resources[0]) - -#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) - -static int __init romchecksum(unsigned char *rom, unsigned long length) -{ - unsigned char *p, sum = 0; - - for (p = rom; p < rom + length; p++) - sum += *p; - return sum == 0; -} - -static void __init probe_roms(void) -{ - unsigned long start, length, upper; - unsigned char *rom; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* if checksum okay, trust length byte */ - if (length && romchecksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (romchecksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !romchecksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - -static void __init limit_regions(unsigned long long size) -{ - unsigned long long current_addr = 0; - int i; - - if (efi_enabled) { - for (i = 0; i < memmap.nr_map; i++) { - current_addr = memmap.map[i].phys_addr + - (memmap.map[i].num_pages << 12); - if (memmap.map[i].type == EFI_CONVENTIONAL_MEMORY) { - if (current_addr >= size) { - memmap.map[i].num_pages -= - (((current_addr-size) + PAGE_SIZE-1) >> PAGE_SHIFT); - memmap.nr_map = i + 1; - return; - } - } - } - } - for (i = 0; i < e820.nr_map; i++) { - if (e820.map[i].type == E820_RAM) { - current_addr = e820.map[i].addr + e820.map[i].size; - if (current_addr >= size) { - e820.map[i].size -= current_addr-size; - e820.nr_map = i + 1; - return; - } - } - } -} - -static void __init add_memory_region(unsigned long long start, - unsigned long long size, int type) -{ - int x; - - if (!efi_enabled) { - x = e820.nr_map; - - if (x == E820MAX) { - printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); - return; - } - - e820.map[x].addr = start; - e820.map[x].size = size; - e820.map[x].type = type; - e820.nr_map++; - } -} /* add_memory_region */ - -#define E820_DEBUG 1 - -static void __init print_memory_map(char *who) -{ - int i; - - for (i = 0; i < e820.nr_map; i++) { - printk(" %s: %016Lx - %016Lx ", who, - e820.map[i].addr, - e820.map[i].addr + e820.map[i].size); - switch (e820.map[i].type) { - case E820_RAM: printk("(usable)\n"); - break; - case E820_RESERVED: - printk("(reserved)\n"); - break; - case E820_ACPI: - printk("(ACPI data)\n"); - break; - case E820_NVS: - printk("(ACPI NVS)\n"); - break; - default: printk("type %lu\n", e820.map[i].type); - break; - } - } -} - -/* - * Sanitize the BIOS e820 map. - * - * Some e820 responses include overlapping entries. The following - * replaces the original e820 map with a new one, removing overlaps. - * - */ -struct change_member { - struct e820entry *pbios; /* pointer to original bios entry */ - unsigned long long addr; /* address for this change point */ -}; -static struct change_member change_point_list[2*E820MAX] __initdata; -static struct change_member *change_point[2*E820MAX] __initdata; -static struct e820entry *overlap_list[E820MAX] __initdata; -static struct e820entry new_bios[E820MAX] __initdata; - -static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map) -{ - struct change_member *change_tmp; - unsigned long current_type, last_type; - unsigned long long last_addr; - int chgidx, still_changing; - int overlap_entries; - int new_bios_entry; - int old_nr, new_nr, chg_nr; - int i; - - /* - Visually we're performing the following (1,2,3,4 = memory types)... - - Sample memory map (w/overlaps): - ____22__________________ - ______________________4_ - ____1111________________ - _44_____________________ - 11111111________________ - ____________________33__ - ___________44___________ - __________33333_________ - ______________22________ - ___________________2222_ - _________111111111______ - _____________________11_ - _________________4______ - - Sanitized equivalent (no overlap): - 1_______________________ - _44_____________________ - ___1____________________ - ____22__________________ - ______11________________ - _________1______________ - __________3_____________ - ___________44___________ - _____________33_________ - _______________2________ - ________________1_______ - _________________4______ - ___________________2____ - ____________________33__ - ______________________4_ - */ - - /* if there's only one memory region, don't bother */ - if (*pnr_map < 2) - return -1; - - old_nr = *pnr_map; - - /* bail out if we find any unreasonable addresses in bios map */ - for (i=0; i<old_nr; i++) - if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr) - return -1; - - /* create pointers for initial change-point information (for sorting) */ - for (i=0; i < 2*old_nr; i++) - change_point[i] = &change_point_list[i]; - - /* record all known change-points (starting and ending addresses), - omitting those that are for empty memory regions */ - chgidx = 0; - for (i=0; i < old_nr; i++) { - if (biosmap[i].size != 0) { - change_point[chgidx]->addr = biosmap[i].addr; - change_point[chgidx++]->pbios = &biosmap[i]; - change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size; - change_point[chgidx++]->pbios = &biosmap[i]; - } - } - chg_nr = chgidx; /* true number of change-points */ - - /* sort change-point list by memory addresses (low -> high) */ - still_changing = 1; - while (still_changing) { - still_changing = 0; - for (i=1; i < chg_nr; i++) { - /* if <current_addr> > <last_addr>, swap */ - /* or, if current=<start_addr> & last=<end_addr>, swap */ - if ((change_point[i]->addr < change_point[i-1]->addr) || - ((change_point[i]->addr == change_point[i-1]->addr) && - (change_point[i]->addr == change_point[i]->pbios->addr) && - (change_point[i-1]->addr != change_point[i-1]->pbios->addr)) - ) - { - change_tmp = change_point[i]; - change_point[i] = change_point[i-1]; - change_point[i-1] = change_tmp; - still_changing=1; - } - } - } - - /* create a new bios memory map, removing overlaps */ - overlap_entries=0; /* number of entries in the overlap table */ - new_bios_entry=0; /* index for creating new bios map entries */ - last_type = 0; /* start with undefined memory type */ - last_addr = 0; /* start with 0 as last starting address */ - /* loop through change-points, determining affect on the new bios map */ - for (chgidx=0; chgidx < chg_nr; chgidx++) - { - /* keep track of all overlapping bios entries */ - if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr) - { - /* add map entry to overlap list (> 1 entry implies an overlap) */ - overlap_list[overlap_entries++]=change_point[chgidx]->pbios; - } - else - { - /* remove entry from list (order independent, so swap with last) */ - for (i=0; i<overlap_entries; i++) - { - if (overlap_list[i] == change_point[chgidx]->pbios) - overlap_list[i] = overlap_list[overlap_entries-1]; - } - overlap_entries--; - } - /* if there are overlapping entries, decide which "type" to use */ - /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */ - current_type = 0; - for (i=0; i<overlap_entries; i++) - if (overlap_list[i]->type > current_type) - current_type = overlap_list[i]->type; - /* continue building up new bios map based on this information */ - if (current_type != last_type) { - if (last_type != 0) { - new_bios[new_bios_entry].size = - change_point[chgidx]->addr - last_addr; - /* move forward only if the new size was non-zero */ - if (new_bios[new_bios_entry].size != 0) - if (++new_bios_entry >= E820MAX) - break; /* no more space left for new bios entries */ - } - if (current_type != 0) { - new_bios[new_bios_entry].addr = change_point[chgidx]->addr; - new_bios[new_bios_entry].type = current_type; - last_addr=change_point[chgidx]->addr; - } - last_type = current_type; - } - } - new_nr = new_bios_entry; /* retain count for new bios entries */ - - /* copy new bios mapping into original location */ - memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry)); - *pnr_map = new_nr; - - return 0; -} - -/* - * Copy the BIOS e820 map into a safe place. - * - * Sanity-check it while we're at it.. - * - * If we're lucky and live on a modern system, the setup code - * will have given us a memory map that we can use to properly - * set up memory. If we aren't, we'll fake a memory map. - * - * We check to see that the memory map contains at least 2 elements - * before we'll use it, because the detection code in setup.S may - * not be perfect and most every PC known to man has two memory - * regions: one from 0 to 640k, and one from 1mb up. (The IBM - * thinkpad 560x, for example, does not cooperate with the memory - * detection code.) - */ -static int __init copy_e820_map(struct e820entry * biosmap, int nr_map) -{ - /* Only one memory region (or negative)? Ignore it */ - if (nr_map < 2) - return -1; - - do { - unsigned long long start = biosmap->addr; - unsigned long long size = biosmap->size; - unsigned long long end = start + size; - unsigned long type = biosmap->type; - - /* Overflow in 64 bits? Ignore the memory map. */ - if (start > end) - return -1; - - /* - * Some BIOSes claim RAM in the 640k - 1M region. - * Not right. Fix it up. - */ - if (type == E820_RAM) { - if (start < 0x100000ULL && end > 0xA0000ULL) { - if (start < 0xA0000ULL) - add_memory_region(start, 0xA0000ULL-start, type); - if (end <= 0x100000ULL) - continue; - start = 0x100000ULL; - size = end - start; - } - } - add_memory_region(start, size, type); - } while (biosmap++,--nr_map); - return 0; -} - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -656,238 +158,105 @@ } #endif +int __initdata user_defined_memmap = 0; + /* - * Do NOT EVER look at the BIOS memory size location. - * It does not work on many machines. + * "mem=nopentium" disables the 4MB page tables. + * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM + * to <mem>, overriding the bios size. + * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from + * <start> to <start>+<mem>, overriding the bios size. + * + * HPA tells me bootloaders need to parse mem=, so no new + * option should be mem= [also see Documentation/i386/boot.txt] */ -#define LOWMEMSIZE() (0x9f000) - -static void __init parse_cmdline_early (char ** cmdline_p) +static int __init parse_mem(char *arg) { - char c = ' ', *to = command_line, *from = saved_command_line; - int len = 0; - int userdef = 0; + if (!arg) + return -EINVAL; - /* Save unparsed command line copy for /proc/cmdline */ - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - - for (;;) { - if (c != ' ') - goto next_char; - /* - * "mem=nopentium" disables the 4MB page tables. - * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM - * to <mem>, overriding the bios size. - * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from - * <start> to <start>+<mem>, overriding the bios size. - * - * HPA tells me bootloaders need to parse mem=, so no new - * option should be mem= [also see Documentation/i386/boot.txt] + if (strcmp(arg, "nopentium") == 0) { + clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); + disable_pse = 1; + } else { + /* If the user specifies memory size, we + * limit the BIOS-provided memory map to + * that size. exactmap can be used to specify + * the exact map. mem=number can be used to + * trim the existing memory map. */ - if (!memcmp(from, "mem=", 4)) { - if (to != command_line) - to--; - if (!memcmp(from+4, "nopentium", 9)) { - from += 9+4; - clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability); - disable_pse = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. - */ - unsigned long long mem_size; + unsigned long long mem_size; - mem_size = memparse(from+4, &from); - limit_regions(mem_size); - userdef=1; - } - } + mem_size = memparse(arg, &arg); + limit_regions(mem_size); + user_defined_memmap = 1; + } + return 0; +} +early_param("mem", parse_mem); - else if (!memcmp(from, "memmap=", 7)) { - if (to != command_line) - to--; - if (!memcmp(from+7, "exactmap", 8)) { - from += 8+7; - e820.nr_map = 0; - userdef = 1; - } else { - /* If the user specifies memory size, we - * limit the BIOS-provided memory map to - * that size. exactmap can be used to specify - * the exact map. mem=number can be used to - * trim the existing memory map. - */ - unsigned long long start_at, mem_size; - - mem_size = memparse(from+7, &from); - if (*from == '@') { - start_at = memparse(from+1, &from); - add_memory_region(start_at, mem_size, E820_RAM); - } else if (*from == '#') { - start_at = memparse(from+1, &from); - add_memory_region(start_at, mem_size, E820_ACPI); - } else if (*from == '$') { - start_at = memparse(from+1, &from); - add_memory_region(start_at, mem_size, E820_RESERVED); - } else { - limit_regions(mem_size); - userdef=1; - } - } - } +#ifdef CONFIG_PROC_VMCORE +/* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. + */ +static int __init parse_elfcorehdr(char *arg) +{ + if (!arg) + return -EINVAL; - else if (!memcmp(from, "noexec=", 7)) - noexec_setup(from + 7); + elfcorehdr_addr = memparse(arg, &arg); + return 0; +} +early_param("elfcorehdr", parse_elfcorehdr); +#endif /* CONFIG_PROC_VMCORE */ +/* + * highmem=size forces highmem to be exactly 'size' bytes. + * This works even on boxes that have no highmem otherwise. + * This also works to reduce highmem size on bigger boxes. + */ +static int __init parse_highmem(char *arg) +{ + if (!arg) + return -EINVAL; -#ifdef CONFIG_X86_SMP - /* - * If the BIOS enumerates physical processors before logical, - * maxcpus=N at enumeration-time can be used to disable HT. - */ - else if (!memcmp(from, "maxcpus=", 8)) { - extern unsigned int maxcpus; - - maxcpus = simple_strtoul(from + 8, NULL, 0); - } -#endif - -#ifdef CONFIG_ACPI_BOOT - /* "acpi=off" disables both ACPI table parsing and interpreter */ - else if (!memcmp(from, "acpi=off", 8)) { - disable_acpi(); - } - - /* acpi=force to over-ride black-list */ - else if (!memcmp(from, "acpi=force", 10)) { - acpi_force = 1; - acpi_ht = 1; - acpi_disabled = 0; - } - - /* acpi=strict disables out-of-spec workarounds */ - else if (!memcmp(from, "acpi=strict", 11)) { - acpi_strict = 1; - } - - /* Limit ACPI just to boot-time to enable HT */ - else if (!memcmp(from, "acpi=ht", 7)) { - if (!acpi_force) - disable_acpi(); - acpi_ht = 1; - } - - /* "pci=noacpi" disable ACPI IRQ routing and PCI scan */ - else if (!memcmp(from, "pci=noacpi", 10)) { - acpi_disable_pci(); - } - /* "acpi=noirq" disables ACPI interrupt routing */ - else if (!memcmp(from, "acpi=noirq", 10)) { - acpi_noirq_set(); - } - - else if (!memcmp(from, "acpi_sci=edge", 13)) - acpi_sci_flags.trigger = 1; - - else if (!memcmp(from, "acpi_sci=level", 14)) - acpi_sci_flags.trigger = 3; - - else if (!memcmp(from, "acpi_sci=high", 13)) - acpi_sci_flags.polarity = 1; - - else if (!memcmp(from, "acpi_sci=low", 12)) - acpi_sci_flags.polarity = 3; - -#ifdef CONFIG_X86_IO_APIC - else if (!memcmp(from, "acpi_skip_timer_override", 24)) - acpi_skip_timer_override = 1; -#endif - -#ifdef CONFIG_X86_LOCAL_APIC - /* disable IO-APIC */ - else if (!memcmp(from, "noapic", 6)) - disable_ioapic_setup(); -#endif /* CONFIG_X86_LOCAL_APIC */ -#endif /* CONFIG_ACPI_BOOT */ - - /* - * highmem=size forces highmem to be exactly 'size' bytes. - * This works even on boxes that have no highmem otherwise. - * This also works to reduce highmem size on bigger boxes. - */ - else if (!memcmp(from, "highmem=", 8)) - highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT; - - /* - * vmalloc=size forces the vmalloc area to be exactly 'size' - * bytes. This can be used to increase (or decrease) the - * vmalloc area - the default is 128m. - */ - else if (!memcmp(from, "vmalloc=", 8)) - __VMALLOC_RESERVE = memparse(from+8, &from); - - next_char: - c = *(from++); - if (!c) - break; - if (COMMAND_LINE_SIZE <= ++len) - break; - *(to++) = c; - } - *to = '\0'; - *cmdline_p = command_line; - if (userdef) { - printk(KERN_INFO "user-defined physical RAM map:\n"); - print_memory_map("user"); - } + highmem_pages = memparse(arg, &arg) >> PAGE_SHIFT; + return 0; } +early_param("highmem", parse_highmem); /* - * Callback for efi_memory_walk. + * vmalloc=size forces the vmalloc area to be exactly 'size' + * bytes. This can be used to increase (or decrease) the + * vmalloc area - the default is 128m. */ -static int __init -efi_find_max_pfn(unsigned long start, unsigned long end, void *arg) +static int __init parse_vmalloc(char *arg) { - unsigned long *max_pfn = arg, pfn; + if (!arg) + return -EINVAL; - if (start < end) { - pfn = PFN_UP(end -1); - if (pfn > *max_pfn) - *max_pfn = pfn; - } + __VMALLOC_RESERVE = memparse(arg, &arg); return 0; } +early_param("vmalloc", parse_vmalloc); - /* - * Find the highest page frame number we have available + * reservetop=size reserves a hole at the top of the kernel address space which + * a hypervisor can load into later. Needed for dynamically loaded hypervisors, + * so relocating the fixmap can be done before paging initialization. */ -void __init find_max_pfn(void) +static int __init parse_reservetop(char *arg) { - int i; + unsigned long address; - max_pfn = 0; - if (efi_enabled) { - efi_memmap_walk(efi_find_max_pfn, &max_pfn); - return; - } + if (!arg) + return -EINVAL; - for (i = 0; i < e820.nr_map; i++) { - unsigned long start, end; - /* RAM? */ - if (e820.map[i].type != E820_RAM) - continue; - start = PFN_UP(e820.map[i].addr); - end = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - if (start >= end) - continue; - if (end > max_pfn) - max_pfn = end; - } + address = memparse(arg, &arg); + reserve_top_address(address); + return 0; } +early_param("reservetop", parse_reservetop); /* * Determine low and high memory ranges: @@ -949,68 +318,6 @@ } /* - * Free all available memory for boot time allocation. Used - * as a callback function by efi_memory_walk() - */ - -static int __init -free_available_memory(unsigned long start, unsigned long end, void *arg) -{ - /* check max_low_pfn */ - if (start >= ((max_low_pfn + 1) << PAGE_SHIFT)) - return 0; - if (end >= ((max_low_pfn + 1) << PAGE_SHIFT)) - end = (max_low_pfn + 1) << PAGE_SHIFT; - if (start < end) - free_bootmem(start, end - start); - - return 0; -} -/* - * Register fully available low RAM pages with the bootmem allocator. - */ -static void __init register_bootmem_low_pages(unsigned long max_low_pfn) -{ - int i; - - if (efi_enabled) { - efi_memmap_walk(free_available_memory, NULL); - return; - } - for (i = 0; i < e820.nr_map; i++) { - unsigned long curr_pfn, last_pfn, size; - /* - * Reserve usable low memory - */ - if (e820.map[i].type != E820_RAM) - continue; - /* - * We are rounding up the start address of usable memory: - */ - curr_pfn = PFN_UP(e820.map[i].addr); - if (curr_pfn >= max_low_pfn) - continue; - /* - * ... and at the end of the usable range downwards: - */ - last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size); - - if (last_pfn > max_low_pfn) - last_pfn = max_low_pfn; - - /* - * .. finally, did all the rounding and playing - * around just make the area go away? - */ - if (last_pfn <= curr_pfn) - continue; - - size = last_pfn - curr_pfn; - free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size)); - } -} - -/* * workaround for Dell systems that neglect to reserve EBDA */ static void __init reserve_ebda_region(void) @@ -1021,7 +328,7 @@ reserve_bootmem(addr, PAGE_SIZE); } -#ifndef CONFIG_DISCONTIGMEM +#ifndef CONFIG_NEED_MULTIPLE_NODES void __init setup_bootmem_allocator(void); static unsigned long __init setup_memory(void) { @@ -1042,7 +349,15 @@ } printk(KERN_NOTICE "%ldMB HIGHMEM available.\n", pages_to_mb(highend_pfn - highstart_pfn)); + num_physpages = highend_pfn; + high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1; +#else + num_physpages = max_low_pfn; + high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1; #endif +#ifdef CONFIG_FLATMEM + max_mapnr = num_physpages; +#endif printk(KERN_NOTICE "%ldMB LOWMEM available.\n", pages_to_mb(max_low_pfn)); @@ -1053,27 +368,24 @@ void __init zone_sizes_init(void) { - unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; - unsigned int max_dma, low; - - max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; - low = max_low_pfn; - - if (low < max_dma) - zones_size[ZONE_DMA] = low; - else { - zones_size[ZONE_DMA] = max_dma; - zones_size[ZONE_NORMAL] = low - max_dma; + unsigned long max_zone_pfns[MAX_NR_ZONES]; + memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); + max_zone_pfns[ZONE_DMA] = + virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; + max_zone_pfns[ZONE_NORMAL] = max_low_pfn; #ifdef CONFIG_HIGHMEM - zones_size[ZONE_HIGHMEM] = highend_pfn - low; + max_zone_pfns[ZONE_HIGHMEM] = highend_pfn; + add_active_range(0, 0, highend_pfn); +#else + add_active_range(0, 0, max_low_pfn); #endif - } - free_area_init(zones_size); + + free_area_init_nodes(max_zone_pfns); } #else -extern unsigned long setup_memory(void); +extern unsigned long __init setup_memory(void); extern void zone_sizes_init(void); -#endif /* !CONFIG_DISCONTIGMEM */ +#endif /* !CONFIG_NEED_MULTIPLE_NODES */ void __init setup_bootmem_allocator(void) { @@ -1091,8 +403,8 @@ * the (very unlikely) case of us accidentally initializing the * bootmem allocator with an invalid RAM area. */ - reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(min_low_pfn) + - bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY)); + reserve_bootmem(__pa_symbol(_text), (PFN_PHYS(min_low_pfn) + + bootmap_size + PAGE_SIZE-1) - __pa_symbol(_text)); /* * reserve physical page 0 - it's a special BIOS page on many boxes, @@ -1130,13 +442,12 @@ */ find_smp_config(); #endif - + numa_kva_reserve(); #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) { reserve_bootmem(INITRD_START, INITRD_SIZE); - initrd_start = - INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start+INITRD_SIZE; } else { @@ -1148,6 +459,11 @@ } } #endif +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) + reserve_bootmem(crashk_res.start, + crashk_res.end - crashk_res.start + 1); +#endif } /* @@ -1168,215 +484,6 @@ } } -/* - * Request address space for all standard RAM and ROM resources - * and also for regions reported as reserved by the e820. - */ -static void __init -legacy_init_iomem_resources(struct resource *code_resource, struct resource *data_resource) -{ - int i; - - probe_roms(); - for (i = 0; i < e820.nr_map; i++) { - struct resource *res; - if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) - continue; - res = alloc_bootmem_low(sizeof(struct resource)); - switch (e820.map[i].type) { - case E820_RAM: res->name = "System RAM"; break; - case E820_ACPI: res->name = "ACPI Tables"; break; - case E820_NVS: res->name = "ACPI Non-volatile Storage"; break; - default: res->name = "reserved"; - } - res->start = e820.map[i].addr; - res->end = res->start + e820.map[i].size - 1; - res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; - request_resource(&iomem_resource, res); - if (e820.map[i].type == E820_RAM) { - /* - * We don't know which RAM region contains kernel data, - * so we try it repeatedly and let the resource manager - * test it. - */ - request_resource(res, code_resource); - request_resource(res, data_resource); - } - } -} - -/* - * Request address space for all standard resources - */ -static void __init register_memory(void) -{ - unsigned long gapstart, gapsize; - unsigned long long last; - int i; - - if (efi_enabled) - efi_initialize_iomem_resources(&code_resource, &data_resource); - else - legacy_init_iomem_resources(&code_resource, &data_resource); - - /* EFI systems may still have VGA */ - request_resource(&iomem_resource, &video_ram_resource); - - /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < STANDARD_IO_RESOURCES; i++) - request_resource(&ioport_resource, &standard_io_resources[i]); - - /* - * Search for the bigest gap in the low 32 bits of the e820 - * memory space. - */ - last = 0x100000000ull; - gapstart = 0x10000000; - gapsize = 0x400000; - i = e820.nr_map; - while (--i >= 0) { - unsigned long long start = e820.map[i].addr; - unsigned long long end = start + e820.map[i].size; - - /* - * Since "last" is at most 4GB, we know we'll - * fit in 32 bits if this condition is true - */ - if (last > end) { - unsigned long gap = last - end; - - if (gap > gapsize) { - gapsize = gap; - gapstart = end; - } - } - if (start < last) - last = start; - } - - /* - * Start allocating dynamic PCI memory a bit into the gap, - * aligned up to the nearest megabyte. - * - * Question: should we try to pad it up a bit (do something - * like " + (gapsize >> 3)" in there too?). We now have the - * technology. - */ - pci_mem_start = (gapstart + 0xfffff) & ~0xfffff; - - printk("Allocating PCI resources starting at %08lx (gap: %08lx:%08lx)\n", - pci_mem_start, gapstart, gapsize); -} - -/* Use inline assembly to define this because the nops are defined - as inline assembly strings in the include files and we cannot - get them easily into strings. */ -asm("\t.data\nintelnops: " - GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 - GENERIC_NOP7 GENERIC_NOP8); -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); -asm("\t.data\nk7nops: " - K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 - K7_NOP7 K7_NOP8); - -extern unsigned char intelnops[], k8nops[], k7nops[]; -static unsigned char *intel_nops[ASM_NOP_MAX+1] = { - NULL, - intelnops, - intelnops + 1, - intelnops + 1 + 2, - intelnops + 1 + 2 + 3, - intelnops + 1 + 2 + 3 + 4, - intelnops + 1 + 2 + 3 + 4 + 5, - intelnops + 1 + 2 + 3 + 4 + 5 + 6, - intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -static unsigned char *k8_nops[ASM_NOP_MAX+1] = { - NULL, - k8nops, - k8nops + 1, - k8nops + 1 + 2, - k8nops + 1 + 2 + 3, - k8nops + 1 + 2 + 3 + 4, - k8nops + 1 + 2 + 3 + 4 + 5, - k8nops + 1 + 2 + 3 + 4 + 5 + 6, - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -static unsigned char *k7_nops[ASM_NOP_MAX+1] = { - NULL, - k7nops, - k7nops + 1, - k7nops + 1 + 2, - k7nops + 1 + 2 + 3, - k7nops + 1 + 2 + 3 + 4, - k7nops + 1 + 2 + 3 + 4 + 5, - k7nops + 1 + 2 + 3 + 4 + 5 + 6, - k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; -static struct nop { - int cpuid; - unsigned char **noptable; -} noptypes[] = { - { X86_FEATURE_K8, k8_nops }, - { X86_FEATURE_K7, k7_nops }, - { -1, NULL } -}; - -/* Replace instructions with better alternatives for this CPU type. - - This runs before SMP is initialized to avoid SMP problems with - self modifying code. This implies that assymetric systems where - APs have less capabilities than the boot processor are not handled. - In this case boot with "noreplacement". */ -void apply_alternatives(void *start, void *end) -{ - struct alt_instr *a; - int diff, i, k; - unsigned char **noptable = intel_nops; - for (i = 0; noptypes[i].cpuid >= 0; i++) { - if (boot_cpu_has(noptypes[i].cpuid)) { - noptable = noptypes[i].noptable; - break; - } - } - for (a = start; (void *)a < end; a++) { - if (!boot_cpu_has(a->cpuid)) - continue; - BUG_ON(a->replacementlen > a->instrlen); - memcpy(a->instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - memcpy(a->instr + i, noptable[k], k); - } - } -} - -static int no_replacement __initdata = 0; - -void __init alternative_instructions(void) -{ - extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; - if (no_replacement) - return; - apply_alternatives(__alt_instructions, __alt_instructions_end); -} - -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 0; -} - -__setup("noreplacement", noreplacement_setup); - -static char * __init machine_specific_memory_setup(void); - #ifdef CONFIG_MCA static void set_mca_bus(int x) { @@ -1386,6 +493,12 @@ static void set_mca_bus(int x) { } #endif +/* Overridden in paravirt.c if CONFIG_PARAVIRT */ +char * __init __attribute__((weak)) memory_setup(void) +{ + return machine_specific_memory_setup(); +} + /* * Determine if we were loaded by an EFI loader. If so, then we have also been * passed the efi memmap, systab, etc., so we should use these data structures @@ -1438,7 +551,7 @@ efi_init(); else { printk(KERN_INFO "BIOS-provided physical RAM map:\n"); - print_memory_map(machine_specific_memory_setup()); + print_memory_map(memory_setup()); } copy_edd(); @@ -1455,11 +568,27 @@ data_resource.start = virt_to_phys(_etext); data_resource.end = virt_to_phys(_edata)-1; - parse_cmdline_early(cmdline_p); + parse_early_param(); + if (user_defined_memmap) { + printk(KERN_INFO "user-defined physical RAM map:\n"); + print_memory_map("user"); + } + + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); + *cmdline_p = command_line; + max_low_pfn = setup_memory(); +#ifdef CONFIG_VMI /* + * Must be after max_low_pfn is determined, and before kernel + * pagetables are setup. + */ + vmi_init(); +#endif + + /* * NOTE: before this point _nobody_ is allowed to allocate * any memory using the bootmem allocator. Although the * alloctor is now initialised only the first 8Mb of the kernel @@ -1474,54 +603,48 @@ #endif paging_init(); remapped_pgdat_init(); + sparse_init(); zone_sizes_init(); /* * NOTE: at this point the bootmem allocator is fully available. */ -#ifdef CONFIG_EARLY_PRINTK - { - char *s = strstr(*cmdline_p, "earlyprintk="); - if (s) { - extern void setup_early_printk(char *); - - setup_early_printk(s); - printk("early console enabled\n"); - } - } -#endif - - dmi_scan_machine(); #ifdef CONFIG_X86_GENERICARCH - generic_apic_probe(*cmdline_p); + generic_apic_probe(); #endif if (efi_enabled) efi_map_memmap(); -#ifdef CONFIG_ACPI_BOOT +#ifdef CONFIG_ACPI /* * Parse the ACPI tables for possible boot-time SMP configuration. */ acpi_boot_table_init(); - acpi_boot_init(); #endif +#ifdef CONFIG_PCI +#ifdef CONFIG_X86_IO_APIC + check_acpi_pci(); /* Checks more than just ACPI actually */ +#endif +#endif + +#ifdef CONFIG_ACPI + acpi_boot_init(); + +#if defined(CONFIG_SMP) && defined(CONFIG_X86_PC) + if (def_to_bigsmp) + printk(KERN_WARNING "More than 8 CPUs detected and " + "CONFIG_X86_PC cannot handle it.\nUse " + "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); +#endif +#endif #ifdef CONFIG_X86_LOCAL_APIC if (smp_found_config) get_smp_config(); #endif - register_memory(); + e820_register_memory(); } - -#include "setup_arch_post.h" -/* - * Local Variables: - * mode:c - * c-file-style:"k&r" - * c-basic-offset:8 - * End: - */ Modified: branches/ruby-2.6.21/ruby-2.6/arch/x86_64/kernel/setup.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/arch/x86_64/kernel/setup.c 2007-04-10 01:57:48 UTC (rev 2361) +++ branches/ruby-2.6.21/ruby-2.6/arch/x86_64/kernel/setup.c 2007-04-10 02:01:16 UTC (rev 2362) @@ -5,8 +5,6 @@ * * Nov 2001 Dave Jones <da...@su...> * Forked from i386 setup code. - * - * $Id$ */ /* @@ -23,10 +21,9 @@ #include <linux/slab.h> #include <linux/user.h> #include <linux/a.out.h> -#include <linux/tty.h> +#include <linux/screen_info.h> #include <linux/ioport.h> #include <linux/delay.h> -#include <linux/config.h> #include <linux/init.h> #include <linux/initrd.h> #include <linux/highmem.h> @@ -34,11 +31,19 @@ #include <linux/module.h> #include <asm/processor.h> #include <linux/seq_file.h> +#include <linux/crash_dump.h> #include <linux/root_dev.h> #include <linux/pci.h> #include <linux/acpi.h> #include <linux/kallsyms.h> #include <linux/edd.h> +#include <linux/mmzone.h> +#include <linux/kexec.h> +#include <linux/cpufreq.h> +#include <linux/dmi.h> +#include <linux/dma-mapping.h> +#include <linux/ctype.h> + #include <asm/mtrr.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -56,52 +61,45 @@ #include <asm/setup.h> #include <asm/mach_apic.h> #include <asm/numa.h> +#include <asm/sections.h> +#include <asm/dmi.h> /* * Machine setup.. */ -struct cpuinfo_x86 boot_cpu_data; +struct cpuinfo_x86 boot_cpu_data __read_mostly; +EXPORT_SYMBOL(boot_cpu_data); unsigned long mmu_cr4_features; -int acpi_disabled; -EXPORT_SYMBOL(acpi_disabled); -#ifdef CONFIG_ACPI_BOOT -extern int __initdata acpi_ht; -extern acpi_interrupt_flags acpi_sci_flags; -int __initdata acpi_force = 0; -#endif - -int acpi_numa __initdata; - /* Boot loader ID as an integer, for the benefit of proc_dointvec */ int bootloader_type; unsigned long saved_video_mode; -#ifdef CONFIG_SWIOTLB -int swiotlb; -EXPORT_SYMBOL(swiotlb); -#endif +/* + * Early DMI memory + */ +int dmi_alloc_index; +char dmi_alloc_data[DMI_MAX_DATA]; /* * Setup options */ -struct drive_info_struct { char dummy[32]; } drive_info; struct screen_info screen_info; +EXPORT_SYMBOL(screen_info); struct sys_desc_table_struct { unsigned short length; unsigned char table[0]; }; struct edid_info edid_info; -struct e820map e820; +EXPORT_SYMBOL_GPL(edid_info); extern int root_mountflags; -extern char _text, _etext, _edata, _end; -char command_line[COMMAND_LINE_SIZE]; +char __initdata command_line[COMMAND_LINE_SIZE]; struct resource standard_io_resources[] = { { .name = "dma1", .start = 0x00, .end = 0x1f, @@ -124,9 +122,6 @@ .flags = IORESOURCE_BUSY | IORESOURCE_IO } }; -#define STANDARD_IO_RESOURCES \ - (sizeof standard_io_resources / sizeof standard_io_resources[0]) - #define IORESOURCE_RAM (IORESOURCE_BUSY | IORESOURCE_MEM) struct resource data_resource = { @@ -142,320 +137,39 @@ .flags = IORESOURCE_RAM, }; -#define IORESOURCE_ROM (IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM) - -static struct resource system_rom_resource = { - .name = "System ROM", - .start = 0xf0000, - .end = 0xfffff, - .flags = IORESOURCE_ROM, -}; - -static struct resource extension_rom_resource = { - .name = "Extension ROM", - .start = 0xe0000, - .end = 0xeffff, - .flags = IORESOURCE_ROM, -}; - -static struct resource adapter_rom_resources[] = { - { .name = "Adapter ROM", .start = 0xc8000, .end = 0, - .flags = IORESOURCE_ROM }, - { .name = "Adapter ROM", .start = 0, .end = 0, - .flags = IORESOURCE_ROM }, - { .name = "Adapter ROM", .start = 0, .end = 0, - .flags = IORESOURCE_ROM }, - { .name = "Adapter ROM", .start = 0, .end = 0, - .flags = IORESOURCE_ROM }, - { .name = "Adapter ROM", .start = 0, .end = 0, - .flags = IORESOURCE_ROM }, - { .name = "Adapter ROM", .start = 0, .end = 0, - .flags = IORESOURCE_ROM } -}; - -#define ADAPTER_ROM_RESOURCES \ - (sizeof adapter_rom_resources / sizeof adapter_rom_resources[0]) - -static struct resource video_rom_resource = { - .name = "Video ROM", - .start = 0xc0000, - .end = 0xc7fff, - .flags = IORESOURCE_ROM, -}; - -static struct resource video_ram_resource = { - .name = "Video RAM area", - .start = 0xa0000, - .end = 0xbffff, - .flags = IORESOURCE_RAM, -}; - -#define romsignature(x) (*(unsigned short *)(x) == 0xaa55) - -static int __init romchecksum(unsigned char *rom, unsigned long length) +#ifdef CONFIG_PROC_VMCORE +/* elfcorehdr= specifies the location of elf core header + * stored by the crashed kernel. This option will be passed + * by kexec loader to the capture kernel. + */ +static int __init setup_elfcorehdr(char *arg) { - unsigned char *p, sum = 0; - - for (p = rom; p < rom + length; p++) - sum += *p; - return sum == 0; + char *end; + if (!arg) + return -EINVAL; + elfcorehdr_addr = memparse(arg, &end); + return end > arg ? 0 : -EINVAL; } - -static void __init probe_roms(void) -{ - unsigned long start, length, upper; - unsigned char *rom; - int i; - - /* video rom */ - upper = adapter_rom_resources[0].start; - for (start = video_rom_resource.start; start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - video_rom_resource.start = start; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* if checksum okay, trust length byte */ - if (length && romchecksum(rom, length)) - video_rom_resource.end = start + length - 1; - - request_resource(&iomem_resource, &video_rom_resource); - break; - } - - start = (video_rom_resource.end + 1 + 2047) & ~2047UL; - if (start < upper) - start = upper; - - /* system rom */ - request_resource(&iomem_resource, &system_rom_resource); - upper = system_rom_resource.start; - - /* check for extension rom (ignore length byte!) */ - rom = isa_bus_to_virt(extension_rom_resource.start); - if (romsignature(rom)) { - length = extension_rom_resource.end - extension_rom_resource.start + 1; - if (romchecksum(rom, length)) { - request_resource(&iomem_resource, &extension_rom_resource); - upper = extension_rom_resource.start; - } - } - - /* check for adapter roms on 2k boundaries */ - for (i = 0; i < ADAPTER_ROM_RESOURCES && start < upper; start += 2048) { - rom = isa_bus_to_virt(start); - if (!romsignature(rom)) - continue; - - /* 0 < length <= 0x7f * 512, historically */ - length = rom[2] * 512; - - /* but accept any length that fits if checksum okay */ - if (!length || start + length > upper || !romchecksum(rom, length)) - continue; - - adapter_rom_resources[i].start = start; - adapter_rom_resources[i].end = start + length - 1; - request_resource(&iomem_resource, &adapter_rom_resources[i]); - - start = adapter_rom_resources[i++].end & ~2047UL; - } -} - -static __init void parse_cmdline_early (char ** cmdline_p) -{ - char c = ' ', *to = command_line, *from = COMMAND_LINE; - int len = 0; - - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE); - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - - for (;;) { - if (c != ' ') - goto next_char; - -#ifdef CONFIG_SMP - /* - * If the BIOS enumerates physical processors before logical, - * maxcpus=N at enumeration-time can be used to disable HT. - */ - else if (!memcmp(from, "maxcpus=", 8)) { - extern unsigned int maxcpus; - - maxcpus = simple_strtoul(from + 8, NULL, 0); - } +early_param("elfcorehdr", setup_elfcorehdr); #endif -#ifdef CONFIG_ACPI_BOOT - /* "acpi=off" disables both ACPI table parsing and interpreter init */ - if (!memcmp(from, "acpi=off", 8)) - disable_acpi(); - if (!memcmp(from, "acpi=force", 10)) { - /* add later when we do DMI horrors: */ - acpi_force = 1; - acpi_disabled = 0; - } - - /* acpi=ht just means: do ACPI MADT parsing - at bootup, but don't enable the full ACPI interpreter */ - if (!memcmp(from, "acpi=ht", 7)) { - if (!acpi_force) - disable_acpi(); - acpi_ht = 1; - } - else if (!memcmp(from, "pci=noacpi", 10)) - acpi_disable_pci(); - else if (!memcmp(from, "acpi=noirq", 10)) - acpi_noirq_set(); - - else if (!memcmp(from, "acpi_sci=edge", 13)) - acpi_sci_flags.trigger = 1; - else if (!memcmp(from, "acpi_sci=level", 14)) - acpi_sci_flags.trigger = 3; - else if (!memcmp(from, "acpi_sci=high", 13)) - acpi_sci_flags.polarity = 1; - else if (!memcmp(from, "acpi_sci=low", 12)) - acpi_sci_flags.polarity = 3; - - /* acpi=strict disables out-of-spec workarounds */ - else if (!memcmp(from, "acpi=strict", 11)) { - acpi_strict = 1; - } -#ifdef CONFIG_X86_IO_APIC - else if (!memcmp(from, "acpi_skip_timer_override", 24)) - acpi_skip_timer_override = 1; -#endif -#endif - - if (!memcmp(from, "nolapic", 7) || - !memcmp(from, "disableapic", 11)) - disable_apic = 1; - - if (!memcmp(from, "noapic", 6)) - skip_ioapic_setup = 1; - - if (!memcmp(from, "apic", 4)) { - skip_ioapic_setup = 0; - ioapic_force = 1; - } - - if (!memcmp(from, "mem=", 4)) - parse_memopt(from+4, &from); - -#ifdef CONFIG_DISCONTIGMEM - if (!memcmp(from, "numa=", 5)) - numa_setup(from+5); -#endif - -#ifdef CONFIG_GART_IOMMU - if (!memcmp(from,"iommu=",6)) { - iommu_setup(from+6); - } -#endif - - if (!memcmp(from,"oops=panic", 10)) - panic_on_oops = 1; - - if (!memcmp(from, "noexec=", 7)) - nonx_setup(from + 7); - - next_char: - c = *(from++); - if (!c) - break; - if (COMMAND_LINE_SIZE <= ++len) - break; - *(to++) = c; - } - *to = '\0'; - *cmdline_p = command_line; -} - -#ifndef CONFIG_DISCONTIGMEM -static void __init contig_initmem_init(void) +#ifndef CONFIG_NUMA +static void __init +contig_initmem_init(unsigned long start_pfn, unsigned long end_pfn) { - unsigned long bootmap_size, bootmap; - bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; - bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); - if (bootmap == -1L) - panic("Cannot find bootmem map of size %ld\n",bootmap_size); - bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); - e820_bootmem_free(&contig_page_data, 0, end_pfn << PAGE_SHIFT); - reserve_bootmem(bootmap, bootmap_size); + unsigned long bootmap_size, bootmap; + + bootmap_size = bootmem_bootmap_pages(end_pfn)<<PAGE_SHIFT; + bootmap = find_e820_area(0, end_pfn<<PAGE_SHIFT, bootmap_size); + if (bootmap == -1L) + panic("Cannot find bootmem map of size %ld\n",bootmap_size); + bootmap_size = init_bootmem(bootmap >> PAGE_SHIFT, end_pfn); + e820_register_active_regions(0, start_pfn, end_pfn); + free_bootmem_with_active_regions(0, end_pfn); + reserve_bootmem(bootmap, bootmap_size); } #endif -/* Use inline assembly to define this because the nops are defined - as inline assembly strings in the include files and we cannot - get them easily into strings. */ -asm("\t.data\nk8nops: " - K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 - K8_NOP7 K8_NOP8); - -extern unsigned char k8nops[]; -static unsigned char *k8_nops[ASM_NOP_MAX+1] = { - NULL, - k8nops, - k8nops + 1, - k8nops + 1 + 2, - k8nops + 1 + 2 + 3, - k8nops + 1 + 2 + 3 + 4, - k8nops + 1 + 2 + 3 + 4 + 5, - k8nops + 1 + 2 + 3 + 4 + 5 + 6, - k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, -}; - -/* Replace instructions with better alternatives for this CPU type. - - This runs before SMP is initialized to avoid SMP problems with - self modifying code. This implies that assymetric systems where - APs have less capabilities than the boot processor are not handled. - In this case boot with "noreplacement". */ -void apply_alternatives(void *start, void *end) -{ - struct alt_instr *a; - int diff, i, k; - for (a = start; (void *)a < end; a++) { - if (!boot_cpu_has(a->cpuid)) - continue; - - BUG_ON(a->replacementlen > a->instrlen); - __inline_memcpy(a->instr, a->replacement, a->replacementlen); - diff = a->instrlen - a->replacementlen; - - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - __inline_memcpy(a->instr + i, k8_nops[k], k); - } - } -} - -static int no_replacement __initdata = 0; - -void __init alternative_instructions(void) -{ - extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; - if (no_replacement) - return; - apply_alternatives(__alt_instructions, __alt_instructions_end); -} - -static int __init noreplacement_setup(char *s) -{ - no_replacement = 1; - return 0; -} - -__setup("noreplacement", noreplacement_setup); - #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE) struct edd edd; #ifdef CONFIG_EDD_MODULE @@ -480,25 +194,35 @@ #endif #define EBDA_ADDR_POINTER 0x40E -static void __init reserve_ebda_region(void) + +unsigned __initdata ebda_addr; +unsigned __initdata ebda_size; + +static void discover_ebda(void) { - unsigned int addr; - /** + /* * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E */ - addr = *(unsigned short *)phys_to_virt(EBDA_ADDR_POINTER); - addr <<= 4; - if (addr) - reserve_bootmem_generic(addr, PAGE_SIZE); + ebda_addr = *(unsigned short *)EBDA_ADDR_POINTER; + ebda_addr <<= 4; + + ebda_size = *(unsigned short *)(unsigned long)ebda_addr; + + /* Round EBDA up to pages */ + if (ebda_size == 0) + ebda_size = 1; + ebda_size <<= 10; + ebda_size = round_up(ebda_size + (ebda_addr & ~PAGE_MASK), PAGE_SIZE); + if (ebda_size > 64*1024) + ebda_size = 64*1024; } void __init setup_arch(char **cmdline_p) { - unsigned long kernel_end; + printk(KERN_INFO "Command line: %s\n", boot_command_line); ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV); - drive_info = DRIVE_INFO; screen_info = SCREEN_INFO; edid_info = EDID_INFO; saved_video_mode = SAVED_VIDEO_MODE; @@ -524,21 +248,34 @@ data_resource.start = virt_to_phys(&_etext); data_resource.end = virt_to_phys(&_edata)-1; - parse_cmdline_early(cmdline_p); - early_identify_cpu(&boot_cpu_data); + strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); + *cmdline_p = command_line; + + parse_early_param(); + + finish_e820_parsing(); + + e820_register_active_regions(0, 0, -1UL); /* * partially used pages are not usable - thus * we are rounding upwards: */ end_pfn = e820_end_of_ram(); + num_physpages = end_pfn; check_efer(); + discover_ebda(); + init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT)); -#ifdef CONFIG_ACPI_BOOT + dmi_scan_machine(); + + zap_low_mappings(0); + +#ifdef CONFIG_ACPI /* * Initialize the ACPI boot-time table parser (gets the RSDP and SDT). * Call this early for SRAT node setup. @@ -546,6 +283,14 @@ acpi_boot_table_init(); #endif + /* How many end-of-memory variables you have, grandma! */ + max_low_pfn = end_pfn; + max_pfn = end_pfn; + high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1; + + /* Remove active ranges so rediscovery with NUMA-awareness happens */ + remove_all_active_ranges(); + #ifdef CONFIG_ACPI_NUMA /* * Parse SRAT to discover nodes. @@ -553,10 +298,10 @@ acpi_numa_init(); #endif -#ifdef CONFIG_DISCONTIGMEM +#ifdef CONFIG_NUMA numa_initmem_init(0, end_pfn); #else - contig_initmem_init(); + contig_initmem_init(0, end_pfn); #endif /* Reserve direct mapping */ @@ -564,8 +309,8 @@ (table_end - table_start) << PAGE_SHIFT); /* reserve kernel */ - kernel_end = round_up(__pa_symbol(&_end),PAGE_SIZE); - reserve_bootmem_generic(HIGH_MEMORY, kernel_end - HIGH_MEMORY); + reserve_bootmem_generic(__pa_symbol(&_text), + __pa_symbol(&_end) - __pa_symbol(&_text)); /* * reserve physical page 0 - it's a special BIOS page on many boxes, @@ -574,7 +319,13 @@ reserve_bootmem_generic(0, PAGE_SIZE); /* reserve ebda region */ - reserve_ebda_region(); + if (ebda_addr) + reserve_bootmem_generic(ebda_addr, ebda_size); +#ifdef CONFIG_NUMA + /* reserve nodemap region */ + if (nodemap_addr) + reserve_bootmem_generic(nodemap_addr, nodemap_size); +#endif #ifdef CONFIG_SMP /* @@ -594,18 +345,15 @@ */ acpi_reserve_bootmem(); #endif -#ifdef CONFIG_X86_LOCAL_APIC /* * Find and reserve possible boot-time SMP configuration: */ find_smp_config(); -#endif #ifdef CONFIG_BLK_DEV_INITRD if (LOADER_TYPE && INITRD_START) { if (INITRD_START + INITRD_SIZE <= (end_pfn << PAGE_SHIFT)) { reserve_bootmem_generic(INITRD_START, INITRD_SIZE); - initrd_start = - INITRD_START ? INITRD_START + PAGE_OFFSET : 0; + initrd_start = INITRD_START + PAGE_OFFSET; initrd_end = initrd_start+INITRD_SIZE; } else { @@ -617,50 +365,58 @@ } } #endif +#ifdef CONFIG_KEXEC + if (crashk_res.start != crashk_res.end) { + reserve_bootmem_generic(crashk_res.start, + crashk_res.end - crashk_res.start + 1); + } +#endif + paging_init(); - check_ioapic(); +#ifdef CONFIG_PCI + early_quirks(); +#endif -#ifdef CONFIG_ACPI_BOOT /* + * set this early, so we dont allocate cpu0 + * if MADT list doesnt list BSP first + * mpparse.c/MP_processor_info() allocates logical cpu numbers. + */ + cpu_set(0, cpu_present_map); +#ifdef CONFIG_ACPI + /* * Read APIC and some other early information from ACPI tables. */ acpi_boot_init(); #endif -#ifdef CONFIG_X86_LOCAL_APIC + init_cpu_to_node(); + /* * get boot-time SMP configuration: */ if (smp_found_config) get_smp_config(); init_apic_mappings(); -#endif /* - * Request address space for all standard RAM and ROM resources - * and also for regions reported as reserved by the e820. - */ - probe_roms(); + * We trust e820 completely. No explicit ROM probing in memory. + */ e820_reserve_resources(); + e820_mark_nosave_regions(); - request_resource(&iomem_resource, &video_ram_resource); - { unsigned i; /* request I/O space for devices used on all i[345]86 PCs */ - for (i = 0; i < STANDARD_IO_RESOURCES; i++) + for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) request_resource(&ioport_resource, &standard_io_resources[i]); } e820_setup_gap(); - -#ifdef CONFIG_GART_IOMMU - iommu_hole_init(); -#endif } -static int __init get_model_name(struct cpuinfo_x86 *c) +static int __cpuinit get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; @@ -676,7 +432,7 @@ } -static void __init display_cacheinfo(struct cpuinfo_x86 *c) +static void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) { unsigned int n, dummy, eax, ebx, ecx, edx; @@ -710,6 +466,24 @@ } } +#ifdef CONFIG_NUMA +static int nearby_node(int apicid) +{ + int i; + for (i = apicid - 1; i >= 0; i--) { + int node = apicid_to_node[i]; + if (node != NUMA_NO_NODE && node_online(node)) + return node; + } + for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) { + int node = apicid_to_node[i]; + if (node != NUMA_NO_NODE && node_online(node)) + return node; + } + return first_node(node_online_map); /* Shouldn't happen */ +} +#endif + /* * On a AMD dual core setup the lower bits of the APIC id distingush the cores. * Assumes number of cores is a power of two. @@ -717,55 +491,95 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) { #ifdef CONFIG_SMP + unsigned bits; +#ifdef CONFIG_NUMA int cpu = smp_processor_id(); int node = 0; - unsigned bits; - if (c->x86_num_cores == 1) - return; + unsigned apicid = hard_smp_processor_id(); +#endif + unsigned ecx = cpuid_ecx(0x80000008); - bits = 0; - while ((1 << bits) < c->x86_num_cores) - bits++; + c->x86_max_cores = (ecx & 0xff) + ... [truncated message content] |
From: <jsi...@us...> - 2007-04-15 14:13:14
|
Revision: 2376 http://linuxconsole.svn.sourceforge.net/linuxconsole/?rev=2376&view=rev Author: jsimmons Date: 2007-04-15 07:13:12 -0700 (Sun, 15 Apr 2007) Log Message: ----------- Lots of fixes to makeit compile Modified Paths: -------------- branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h Added Paths: ----------- branches/ruby-2.6.21/ruby-2.6/kernel/power/ branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/consolemap.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -412,8 +412,8 @@ static int con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos) { - int i, n; u16 **p1, *p2; + int n; if (!(p1 = p->uni_pgdir[n = unicode >> 11])) { p1 = p->uni_pgdir[n] = kzalloc(32*sizeof(u16 *), GFP_KERNEL); Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/decvte.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -34,12 +34,10 @@ #include <linux/major.h> #include <linux/mm.h> #include <linux/init.h> -#include <linux/devfs_fs_kernel.h> #include <linux/vt_kern.h> #include <linux/vt_buffer.h> #include <linux/selection.h> #include <linux/consolemap.h> -#include <linux/config.h> #include <linux/version.h> #include <asm/io.h> @@ -123,7 +121,7 @@ /* * CARRIAGE RETURN (CR) */ -inline void vte_cr(struct vc_data *vc) +void vte_cr(struct vc_data *vc) { vc->vc_pos -= vc->vc_x << 1; vc->vc_need_wrap = vc->vc_x = 0; @@ -132,7 +130,7 @@ /* * BACK SPACE (BS) */ -inline void vte_bs(struct vc_data *vc) +void vte_bs(struct vc_data *vc) { if (vc->vc_x) { vc->vc_pos -= 2; Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/keyboard.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -43,28 +43,6 @@ static void kbd_disconnect(struct input_handle *handle); extern void ctrl_alt_del(void); - -/* - * Exported functions/variables - */ - -#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) - -/* - * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. - * This seems a good reason to start with NumLock off. On HIL keyboards - * of PARISC machines however there is no NumLock key and everyone expects the keypad - * to be used for numbers. - */ - -#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)) -#define KBD_DEFLEDS (1 << VC_NUMLOCK) -#else -#define KBD_DEFLEDS 0 -#endif - -#define KBD_DEFLOCK 0 - void compute_shiftstate(void); /* @@ -197,7 +175,7 @@ /* * Making beeps and bells. */ -static void kd_nosound(unsigned long private) +void kd_nosound(unsigned long private) { struct input_handle *handle = (struct input_handle *) private; @@ -209,7 +187,7 @@ } } -static void kd_mksound(struct input_handle *handle, unsigned int hz, unsigned int ticks) +void kd_mksound(struct input_handle *handle, unsigned int hz, unsigned int ticks) { struct vt_struct *vt; @@ -245,9 +223,9 @@ if (test_bit(EV_REP, dev->evbit)) { if (rep->delay > 0) - input_inject_event(dev, EV_REP, REP_DELAY, rep->delay); + input_inject_event(handle, EV_REP, REP_DELAY, rep->delay); if (rep->period > 0) - input_inject_event(dev, EV_REP, REP_PERIOD, rep->period); + input_inject_event(handle, EV_REP, REP_PERIOD, rep->period); d = dev->rep[REP_DELAY]; p = dev->rep[REP_PERIOD]; } @@ -265,11 +243,11 @@ if (tty) { tty_insert_flip_char(tty, ch, 0); - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); } } -static void puts_queue(struct vc_data *vc, char *cp) +void puts_queue(struct vc_data *vc, char *cp) { struct tty_struct *tty = vc->vc_tty; @@ -280,7 +258,7 @@ tty_insert_flip_char(tty, *cp, 0); cp++; } - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); } static void applkey(struct vc_data *vc, int key, char mode) @@ -393,7 +371,7 @@ static void fn_enter(struct vc_data *vc) { if (diacr) { - if (kbd->kbdmode == VC_UNICODE) + if (vc->kbd_table.kbdmode == VC_UNICODE) to_utf8(vc, diacr); else if (diacr < 0x100) put_queue(vc, diacr); @@ -508,7 +486,7 @@ if (!tty) return; tty_insert_flip_char(tty, 0, TTY_BREAK); - schedule_work(&tty->flip.work); + tty_schedule_flip(tty); } static void fn_scroll_forw(struct vc_data *vc) @@ -608,7 +586,7 @@ diacr = value; return; } - if (kbd->kbdmode == VC_UNICODE) + if (vc->kbd_table.kbdmode == VC_UNICODE) to_utf8(vc, value); else if (value < 0x100) put_queue(vc, value); @@ -1316,7 +1294,6 @@ break; } } - kbd_start(handle); } else if (test_bit(EV_SND, dev->evbit) && admin_vt && !admin_vt->beeper) { admin_vt->beeper = handle; handle->private = admin_vt; Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/sysrq.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -90,9 +90,8 @@ { if (tty->driver->type == TTY_DRIVER_TYPE_CONSOLE) { struct vc_data *vc = (struct vc_data *) tty->driver_data; - struct work_struct *SAK_work = vc->SAK_work; // Should this be fg_console - - schedule_work(SAK_work); + // Should this be fg_console + schedule_work(&vc->SAK_work); } } static struct sysrq_key_op sysrq_SAK_op = { Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -714,28 +714,6 @@ * Screen blanking */ -static void powerdown_screen(unsigned long private) -{ - /* - * Power down if currently suspended (1 or 2), - * suspend if currently blanked (0), - * else do nothing (i.e. already powered down (3)). - * Called only if powerdown features are allowed. - */ - struct vt_struct *vt = (struct vt_struct *) private; - struct vc_data *vc = vt->fg_console; - - switch (vc->display_fg->blank_mode) { - case VESA_NO_BLANKING: - sw->con_blank(vc, VESA_VSYNC_SUSPEND+1, 0); - break; - case VESA_VSYNC_SUSPEND: - case VESA_HSYNC_SUSPEND: - sw->con_blank(vc, VESA_POWERDOWN+1, 0); - break; - } -} - void do_blank_screen(struct vt_struct *vt, int entering_gfx) { struct vc_data *vc = vt->fg_console; @@ -746,7 +724,7 @@ if (vt->vt_blanked) { if (vt->blank_state == blank_vesa_wait) { vt->blank_state = blank_off; - vc->vc_sw->con_blank(vc, vesa_blank_mode + 1, 0); + vt->vt_sw->con_blank(vc, vt->blank_mode + 1, 0); } return; } @@ -776,7 +754,7 @@ save_screen(vc); /* In case we need to reset origin, blanking hook returns 1 */ - i = sw->con_blank(vc, vesa_off_interval ? 1 : (vesa_blank_mode + 1), 0); + i = sw->con_blank(vc, vt->off_interval ? 1 : (vt->blank_mode + 1), 0); vt->vt_blanked = 1; if (i) set_origin(vc); @@ -884,7 +862,7 @@ */ static void vt_callback(struct work_struct *work) { - struct vt_struct *vt = container_of(work, struct vt_struct, SAK_work); + struct vt_struct *vt = container_of(work, struct vt_struct, vt_work); if (!vt || !vt->want_vc || !vt->want_vc->vc_tty) return; @@ -916,6 +894,26 @@ release_console_sem(); } +void vc_SAK(struct work_struct *work) +{ + struct vc_data *vc = + container_of(work, struct vc_data, SAK_work); + struct tty_struct *tty; + + acquire_console_sem(); + if (vc) { + tty = vc->vc_tty; + /* + * SAK should also work in all raw modes and reset + * them properly. + */ + if (tty) + __do_SAK(tty); + reset_vc(vc); + } + release_console_sem(); +} + int set_console(struct vc_data *vc) { if (!vc || vc->display_fg->vt_dont_switch || @@ -1074,7 +1072,7 @@ module_put(sw->owner); vt->vc_cons[vc->vc_num - vt->first_vc] = NULL; if (vt->kmalloced) - kfree(screenbuf); + kfree(vc->vc_screenbuf); kfree(vc); } return 0; @@ -1223,38 +1221,6 @@ return 0; } -int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines) -{ - int rc; - - acquire_console_sem(); - rc = vc_resize(vc, cols, lines); - release_console_sem(); - return rc; -} - -void vc_SAK(struct work_struct *work) -{ - struct vc *vc_con = - container_of(work, struct vc, SAK_work); - struct tty_struct *tty; - struct vc_data *vc; - - acquire_console_sem(); - vc = vc_con->d; - if (vc) { - tty = vc->vc_tty; - /* - * SAK should also work in all raw modes and reset - * them properly. - */ - if (tty) - __do_SAK(tty); - reset_vc(vc); - } - release_console_sem(); -} - /* * Selection stuff for GPM. */ @@ -1311,7 +1277,7 @@ if (!vc) { printk("vt_write: tty %d not allocated\n", tty->index); release_console_sem(); - return 0; + return n; } release_console_sem(); @@ -1335,7 +1301,9 @@ hide_cursor(vc); while (!tty->stopped && count) { - c = *buf; + int orig = *buf; + + c = orig; buf++; n++; count--; @@ -1348,7 +1316,7 @@ /* Malformed sequences as sequences of replacement glyphs */ rescan_last_byte: if(c > 0x7f) { - if (vc->vc_utf_count > 0) + if (vc->vc_utf_count > 0) { if ((c & 0xc0) == 0x80) { vc->vc_utf_char = (vc->vc_utf_char << 6) | (c & 0x3f); if (--vc->vc_utf_count) { @@ -1356,8 +1324,8 @@ continue; } tc = c = vc->vc_utf_char; - else - goto replacement; + } else + goto replacement_glyph; } else { vc->vc_npar = 0; if ((c & 0xe0) == 0xc0) { @@ -1464,8 +1432,6 @@ FLUSH console_conditional_schedule(); release_console_sem(); - -out: return n; #undef FLUSH } @@ -1854,7 +1820,7 @@ list_add_tail(&vt->node, &vt_list); init_MUTEX(&vt->lock); vt->vt_num = current_vt; - vt->display_desc = (char *)display_desc; + vt->desc = (char *)display_desc; vt->vt_dont_switch = 0; vt->scrollback_delta = 0; vt->vt_blanked = 0; @@ -1866,7 +1832,7 @@ vt->timer.function = blank_screen_t; mod_timer(&vt->timer, jiffies + vt->blank_interval); vt->keyboard = NULL; - INIT_WORK(&vt->vt_work, vt_callback, vt); + INIT_WORK(&vt->vt_work, vt_callback); if (!admin_vt) { admin_vt = vt; @@ -1884,7 +1850,7 @@ current_vc += vc_count; current_vt += 1; if (vt->kmalloced) { - vt_create_sysfs_dev_files(vt); + vt_init_device(vt); #ifdef CONFIG_PROC_FS vt_proc_attach(vt); #endif @@ -2011,7 +1977,7 @@ module_put(owner); return -ENODEV; } - vt->display_desc = (char *)desc; + vt->desc = (char *)desc; vt->vt_sw = csw; /* Set the VC states to the new default mode */ @@ -2025,7 +1991,7 @@ vc->vc_origin = (unsigned long) vc->vc_screenbuf; vc->vc_visible_origin = vc->vc_origin; vc->vc_scr_end = vc->vc_origin + vc->vc_screenbuf_size; - vc->vc_pos = vc->vc_origin + vc->vc_size_rows * vc->vc_y + 2 * vc->vc_x; + vc->vc_pos = vc->vc_origin + vc->vc_size_row * vc->vc_y + 2 * vc->vc_x; INIT_WORK(&vc->SAK_work, vc_SAK); visual_init(vc, 0); set_origin(vc); @@ -2063,7 +2029,7 @@ EXPORT_SYMBOL(vc_lock_resize); EXPORT_SYMBOL(console_blank_hook); EXPORT_SYMBOL(vt_list); -EXPORT_SYMBOL(take_over_console); +EXPORT_SYMBOL(bind_vt_driver); EXPORT_SYMBOL(update_region); EXPORT_SYMBOL(update_screen); EXPORT_SYMBOL(vt_map_display); Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_proc.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -6,8 +6,6 @@ * Aivils Stoss <> */ -#include <linux/config.h> - #ifdef CONFIG_PROC_FS #include <linux/types.h> #include <linux/kernel.h> @@ -53,7 +51,7 @@ if(!vt) return 0; - len = sprintf(page, "%s\n", vt->display_desc ? vt->display_desc : ""); + len = sprintf(page, "%s\n", vt->desc ? vt->desc : ""); return generic_read(page, start, off, count, eof, len); } @@ -103,7 +101,7 @@ } handle->private = vt; printk("keyboard: [%s] bound to [%s] vc:%d-%d\n", - handle->dev->name, vt->display_desc, vt->first_vc + 1, + handle->dev->name, vt->desc, vt->first_vc + 1, vt->first_vc + vt->vc_count); } return count; Modified: branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/char/vt_sysfs.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -26,7 +26,7 @@ } static ssize_t show_keyboard(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) + char *buf) { struct vt_struct *vt = dev_get_drvdata(dev); struct input_handle *handle = vt->keyboard; @@ -45,7 +45,7 @@ if (bind) vt_bind(vt); else - vt_unbind(con); + vt_unbind(vt); return count; } @@ -74,41 +74,42 @@ __ATTR(name, S_IRUGO, show_name, NULL), }; -static int vt_init_device(struct vt_struct *vt) +int vt_init_device(struct vt_struct *vt) { int err = 0; - vt->dev = device_create(vt_class, NULL, MKDEV(0, vt->count), - "vtcon%i", vt->count); + vt->dev = device_create(vt_class, NULL, MKDEV(0, vt->vc_count), + "vtcon%i", vt->vc_count); if (IS_ERR(vt->dev)) { vt->flag &= ~CON_DRIVER_FLAG_ATTR; vt->dev = NULL; - error = -EINVAL; + err = -EINVAL; } else { dev_set_drvdata(vt->dev, vt); - fb_info->flag |= CON_DRIVER_FLAG_ATTR; + vt->flag |= CON_DRIVER_FLAG_ATTR; } return err; } -static void vt_deinit_device(struct vt_struct *vt) +void vt_deinit_device(struct vt_struct *vt) { vt->flag &= ~CON_DRIVER_FLAG_ATTR; dev_set_drvdata(vt->dev, NULL); - device_destroy(vt_class, MKDEV(0, vt->count)); + device_destroy(vt_class, MKDEV(0, vt->vc_count)); } -void __init vt_sysfs_init(void) +int __init vt_sysfs_init(void) { /* we have only one boot time console - admin_vt*/ vt_class = class_create(THIS_MODULE, "vt"); if (IS_ERR(vt_class)) { printk(KERN_WARNING "Unable to create vt console class; " - "errno = %ld\n", PTR_ERR(vtconsole_class)); + "errno = %ld\n", PTR_ERR(vt_class)); vt_class = NULL; } else { - vt_class->dev_attrs = vt_device_attrs + vt_class->dev_attrs = vt_device_attrs; } + return 0; } -postcore_initcall(vtconsole_class_init); +postcore_initcall(vt_sysfs_init); Modified: branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/video/console/dummycon.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -32,10 +32,9 @@ #define MAX_DUMB_CONSOLES 16 -static const char *dummycon_startup(void) -static unsigned long dumb_num = 0; -static struct vt_struct dummy_vt; static struct vc_data default_mode; +static struct vt_struct dummy_vt; +static unsigned long dumb_num; static const char *dummycon_startup(struct vt_struct *vt, int init) { @@ -45,11 +44,6 @@ return "dummy device"; } -static const char *dummycon_startup(void) -{ - return "dummy device"; -} - static void dummycon_init(struct vc_data *vc, int init) { vc->vc_can_do_color = 1; @@ -82,7 +76,7 @@ .con_putc = DUMMY, .con_putcs = DUMMY, .con_cursor = DUMMY, - .con_scroll = DUMMY, + .con_scroll_region =DUMMY, .con_bmove = DUMMY, .con_switch = DUMMY, .con_blank = DUMMY, @@ -91,7 +85,7 @@ .con_font_default = DUMMY, .con_font_copy = DUMMY, .con_set_palette = DUMMY, - .con_scrolldelta = DUMMY, + .con_scroll = DUMMY, }; int __init dumbcon_init(void) @@ -99,7 +93,7 @@ const char *display_desc = NULL; memset(&dummy_vt, 0, sizeof(struct vt_struct)); - dummy_vt.vt_kmalloced = 0; + dummy_vt.kmalloced = 0; dummy_vt.vt_sw = &dummy_con; display_desc = vt_map_display(&dummy_vt, 1, MAX_NR_USER_CONSOLES); if (!display_desc) return -ENODEV; @@ -120,7 +114,7 @@ if (!vt) return -ENOMEM; memset(vt, 0, sizeof(struct vt_struct)); - vt->vt_kmalloced = 1; + vt->kmalloced = 1; vt->vt_sw = &dummy_con; display_desc = vt_map_display(vt, 1, MIN_NR_CONSOLES); if (!display_desc) { Modified: branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/drivers/video/console/vgacon.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -719,8 +719,6 @@ spin_lock_irqsave(&vga_lock, flags); - vgacon_xres = width * VGA_FONTWIDTH; - vgacon_yres = height * c->vc_font.height; if (vga_video_type >= VIDEO_TYPE_VGAC) { outb_p(VGA_CRTC_MAX_SCAN, vga_video_port_reg); max_scan = inb_p(vga_video_port_val); @@ -774,20 +772,23 @@ static int vgacon_switch(struct vc_data *c) { + int y = c->vc_rows * c->vc_font.height; + int x = c->vc_cols = 8; + /* We can only copy out the size of the video buffer here, * otherwise we get into VGA BIOS. We can only copy out * the size of the video buffer here, otherwise we get * into VGA BIOS */ if (!vga_is_gfx) { + struct winsize *ws = &c->vc_tty->winsize; + scr_memcpyw((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size > vga_vram_size ? vga_vram_size : c->vc_screenbuf_size); - if ((vgacon_xres != x || vgacon_yres != y) && - (!(vga_video_num_columns % 2) && - vga_video_num_columns <= ORIG_VIDEO_COLS && - vga_video_num_lines <= rows)) + if ((ws->ws_xpixel != x || ws->ws_ypixel != y) && + (!(c->vc_cols % 2) && c->vc_cols <= ORIG_VIDEO_COLS)) vgacon_doresize(c, c->vc_cols, c->vc_rows); } @@ -1242,17 +1243,17 @@ #endif -static int vgacon_resize(struct vc_data *c, unsigned int width, +static int vgacon_resize(struct vc_data *vc, unsigned int width, unsigned int height) { if (width % 2 || width > ORIG_VIDEO_COLS || - height > (ORIG_VIDEO_LINES * vga_default_font_height)/ - c->vc_font.height) + height > (ORIG_VIDEO_LINES * vc->vc_font.height)/ + vc->vc_font.height) /* let svgatextmode tinker with video timings */ return 0; if (IS_VISIBLE && !vga_is_gfx) /* who knows */ - vgacon_doresize(c, width, height); + vgacon_doresize(vc, width, height); return 0; } @@ -1367,7 +1368,7 @@ const char *display_desc = NULL; memset(&vga_vt, 0, sizeof(struct vt_struct)); - vga_vt.vt_kmalloced = 0; + vga_vt.kmalloced = 0; vga_vt.vt_sw = &vga_con; display_desc = vt_map_display(&vga_vt, 1, MAX_NR_USER_CONSOLES); if (!display_desc) return -ENODEV; Modified: branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h =================================================================== --- branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/include/linux/kbd_kern.h 2007-04-15 14:13:12 UTC (rev 2376) @@ -7,6 +7,27 @@ #include <linux/keyboard.h> #include <linux/input.h> +/* + * Exported functions/variables + */ + +#define KBD_DEFMODE ((1 << VC_REPEAT) | (1 << VC_META)) + +/* + * Some laptops take the 789uiojklm,. keys as number pad when NumLock is on. + * This seems a good reason to start with NumLock off. On HIL keyboards + * of PARISC machines however there is no NumLock key and everyone expects the keypad + * to be used for numbers. + */ + +#if defined(CONFIG_PARISC) && (defined(CONFIG_KEYBOARD_HIL) || defined(CONFIG_KEYBOARD_HIL_OLD)) +#define KBD_DEFLEDS (1 << VC_NUMLOCK) +#else +#define KBD_DEFLEDS 0 +#endif + +#define KBD_DEFLOCK 0 + extern struct tasklet_struct keyboard_tasklet; extern int shift_state; Modified: branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h =================================================================== --- branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h 2007-04-15 01:06:27 UTC (rev 2375) +++ branches/ruby-2.6.21/ruby-2.6/include/linux/vt_kern.h 2007-04-15 14:13:12 UTC (rev 2376) @@ -11,9 +11,10 @@ #include <linux/kbd_kern.h> #include <linux/device.h> -#define MIN_NR_CONSOLES 1 /* must be at least 1 */ -#define MAX_NR_CONSOLES 63 /* serial lines start at 64 */ -#define MAX_NR_USER_CONSOLES 16 /* number of VCs per VT */ +/* VT driver state */ +#define CON_DRIVER_FLAG_MODULE 1 +#define CON_DRIVER_FLAG_INIT 2 +#define CON_DRIVER_FLAG_ATTR 4 /* scroll */ #define SM_UP (1) @@ -117,7 +118,7 @@ struct tty_struct *vc_tty; /* TTY we are attached to */ /* data for manual vt switching */ struct vt_mode vt_mode; - int vt_pid; + struct pid *vt_pid; int vt_newvt; /* mode flags */ unsigned int vc_charset:1; /* Character set G0 / G1 */ @@ -192,6 +193,8 @@ unsigned char vc_saved_G2; unsigned char vc_saved_G3; unsigned char vc_saved_GS; + + struct work_struct SAK_work; // Does it really belong here ? }; struct consw { @@ -229,6 +232,7 @@ struct vc_data *want_vc; /* VC we want to switch to */ int scrollback_delta; int cursor_original; + int flag; char kmalloced; /* Did we use kmalloced ? */ char vt_dont_switch; /* VC switching flag */ char vt_blanked; /* Is this display blanked */ @@ -261,8 +265,8 @@ struct proc_dir_entry *procdir; unsigned char vt_ledstate; unsigned char vt_ledioctl; - char *display_desc; - struct class_device dev; /* Generic device interface */ + char *desc; + struct device *dev; /* Generic device interface */ }; extern struct list_head vt_list; @@ -272,9 +276,9 @@ /* universal VT emulation functions */ void vte_ris(struct vc_data *vc, int do_clear); -inline void vte_cr(struct vc_data *vc); +void vte_cr(struct vc_data *vc); void vte_lf(struct vc_data *vc); -inline void vte_bs(struct vc_data *vc); +void vte_bs(struct vc_data *vc); void vte_ed(struct vc_data *vc, int vpar); void vte_decsc(struct vc_data *vc); void terminal_emulation(struct tty_struct *tty, int c); @@ -296,16 +300,16 @@ void vt_map_input(struct vt_struct *vt); struct vc_data *find_vc(int currcons); struct vc_data *vc_allocate(unsigned int console); -inline int set_console(struct vc_data *vc); +int set_console(struct vc_data *vc); int vc_resize(struct vc_data *vc, unsigned int lines, unsigned int cols); int vc_lock_resize(struct vc_data *vc, unsigned int cols, unsigned int lines); -int vc_disallocate(struct vc_data *vc); +int vc_deallocate(struct vc_data *vc); void reset_vc(struct vc_data *vc); void add_softcursor(struct vc_data *vc); void set_cursor(struct vc_data *vc); void hide_cursor(struct vc_data *vc); void gotoxy(struct vc_data *vc, int new_x, int new_y); -inline void gotoxay(struct vc_data *vc, int new_x, int new_y); +void gotoxay(struct vc_data *vc, int new_x, int new_y); void reset_palette(struct vc_data *vc); void set_palette(struct vc_data *vc); void scroll_up(struct vc_data *vc, int); @@ -319,7 +323,7 @@ void insert_line(struct vc_data *vc, unsigned int nr); void delete_line(struct vc_data *vc, unsigned int nr); void set_origin(struct vc_data *vc); -inline void clear_region(struct vc_data *vc, int x, int y, int width, int height); +void clear_region(struct vc_data *vc, int x, int y, int width, int height); void do_update_region(struct vc_data *vc, unsigned long start, int count); void update_region(struct vc_data *vc, unsigned long start, int count); void update_screen(struct vc_data *vc); @@ -357,13 +361,16 @@ void con_protect_unimap(struct vc_data *vc, int rdonly); int con_copy_unimap(struct vc_data *dst, struct vc_data *src); +/* keyboard.c */ +void puts_queue(struct vc_data *vc, char *cp); + /* vt_ioctl.c */ void complete_change_console(struct vc_data *new_vc, struct vc_data *old_vc); void change_console(struct vc_data *new_vc, struct vc_data *old_vc); /* vt_sysfs.c*/ -int __init vt_create_sysfs_dev_files (struct vt_struct *vt); -void __init vt_sysfs_init(void); +int __init vt_init_device(struct vt_struct *vt); +int __init vt_sysfs_init(void); /* vt_proc.c */ #ifdef CONFIG_PROC_FS extern int vt_proc_attach(struct vt_struct *vt); Added: branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile =================================================================== --- branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile (rev 0) +++ branches/ruby-2.6.21/ruby-2.6/kernel/power/Makefile 2007-04-15 14:13:12 UTC (rev 2376) @@ -0,0 +1,10 @@ + +ifeq ($(CONFIG_PM_DEBUG),y) +EXTRA_CFLAGS += -DDEBUG +endif + +obj-y := main.o process.o +obj-$(CONFIG_PM_LEGACY) += pm.o +obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o disk.o snapshot.o swap.o user.o + +obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o Added: branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c (rev 0) +++ branches/ruby-2.6.21/ruby-2.6/kernel/power/disk.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -0,0 +1,461 @@ +/* + * kernel/power/disk.c - Suspend-to-disk support. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * Copyright (c) 2004 Pavel Machek <pa...@su...> + * + * This file is released under the GPLv2. + * + */ + +#include <linux/suspend.h> +#include <linux/syscalls.h> +#include <linux/reboot.h> +#include <linux/string.h> +#include <linux/device.h> +#include <linux/delay.h> +#include <linux/fs.h> +#include <linux/mount.h> +#include <linux/pm.h> +#include <linux/console.h> +#include <linux/cpu.h> +#include <linux/freezer.h> + +#include "power.h" + + +static int noresume = 0; +char resume_file[256] = CONFIG_PM_STD_PARTITION; +dev_t swsusp_resume_device; +sector_t swsusp_resume_block; + +/** + * platform_prepare - prepare the machine for hibernation using the + * platform driver if so configured and return an error code if it fails + */ + +static inline int platform_prepare(void) +{ + int error = 0; + + if (pm_disk_mode == PM_DISK_PLATFORM) { + if (pm_ops && pm_ops->prepare) + error = pm_ops->prepare(PM_SUSPEND_DISK); + } + return error; +} + +/** + * power_down - Shut machine down for hibernate. + * @mode: Suspend-to-disk mode + * + * Use the platform driver, if configured so, and return gracefully if it + * fails. + * Otherwise, try to power off and reboot. If they fail, halt the machine, + * there ain't no turning back. + */ + +static void power_down(suspend_disk_method_t mode) +{ + switch(mode) { + case PM_DISK_PLATFORM: + if (pm_ops && pm_ops->enter) { + kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK); + pm_ops->enter(PM_SUSPEND_DISK); + break; + } + case PM_DISK_SHUTDOWN: + kernel_power_off(); + break; + case PM_DISK_REBOOT: + kernel_restart(NULL); + break; + } + kernel_halt(); + /* Valid image is on the disk, if we continue we risk serious data corruption + after resume. */ + printk(KERN_CRIT "Please power me down manually\n"); + while(1); +} + +static inline void platform_finish(void) +{ + if (pm_disk_mode == PM_DISK_PLATFORM) { + if (pm_ops && pm_ops->finish) + pm_ops->finish(PM_SUSPEND_DISK); + } +} + +static void unprepare_processes(void) +{ + thaw_processes(); +} + +static int prepare_processes(void) +{ + int error = 0; + + if (freeze_processes()) { + error = -EBUSY; + unprepare_processes(); + } + return error; +} + +/** + * pm_suspend_disk - The granpappy of hibernation power management. + * + * If we're going through the firmware, then get it over with quickly. + * + * If not, then call swsusp to do its thing, then figure out how + * to power down the system. + */ + +int pm_suspend_disk(void) +{ + int error; + + error = prepare_processes(); + if (error) + return error; + + if (pm_disk_mode == PM_DISK_TESTPROC) { + printk("swsusp debug: Waiting for 5 seconds.\n"); + mdelay(5000); + goto Thaw; + } + /* Free memory before shutting down devices. */ + error = swsusp_shrink_memory(); + if (error) + goto Thaw; + + error = platform_prepare(); + if (error) + goto Thaw; + + error = device_suspend(PMSG_FREEZE); + if (error) { + printk(KERN_ERR "PM: Some devices failed to suspend\n"); + goto Resume_devices; + } + error = disable_nonboot_cpus(); + if (error) + goto Enable_cpus; + + if (pm_disk_mode == PM_DISK_TEST) { + printk("swsusp debug: Waiting for 5 seconds.\n"); + mdelay(5000); + goto Enable_cpus; + } + + pr_debug("PM: snapshotting memory.\n"); + in_suspend = 1; + error = swsusp_suspend(); + if (error) + goto Enable_cpus; + + if (in_suspend) { + enable_nonboot_cpus(); + platform_finish(); + device_resume(); + resume_console(); + pr_debug("PM: writing image.\n"); + error = swsusp_write(); + if (!error) + power_down(pm_disk_mode); + else { + swsusp_free(); + goto Thaw; + } + } else { + pr_debug("PM: Image restored successfully.\n"); + } + + swsusp_free(); + Enable_cpus: + enable_nonboot_cpus(); + Resume_devices: + platform_finish(); + device_resume(); + resume_console(); + Thaw: + unprepare_processes(); + return error; +} + + +/** + * software_resume - Resume from a saved image. + * + * Called as a late_initcall (so all devices are discovered and + * initialized), we call swsusp to see if we have a saved image or not. + * If so, we quiesce devices, the restore the saved image. We will + * return above (in pm_suspend_disk() ) if everything goes well. + * Otherwise, we fail gracefully and return to the normally + * scheduled program. + * + */ + +static int software_resume(void) +{ + int error; + + mutex_lock(&pm_mutex); + if (!swsusp_resume_device) { + if (!strlen(resume_file)) { + mutex_unlock(&pm_mutex); + return -ENOENT; + } + swsusp_resume_device = name_to_dev_t(resume_file); + pr_debug("swsusp: Resume From Partition %s\n", resume_file); + } else { + pr_debug("swsusp: Resume From Partition %d:%d\n", + MAJOR(swsusp_resume_device), MINOR(swsusp_resume_device)); + } + + if (noresume) { + /** + * FIXME: If noresume is specified, we need to find the partition + * and reset it back to normal swap space. + */ + mutex_unlock(&pm_mutex); + return 0; + } + + pr_debug("PM: Checking swsusp image.\n"); + + error = swsusp_check(); + if (error) + goto Done; + + pr_debug("PM: Preparing processes for restore.\n"); + + error = prepare_processes(); + if (error) { + swsusp_close(); + goto Done; + } + + pr_debug("PM: Reading swsusp image.\n"); + + error = swsusp_read(); + if (error) { + swsusp_free(); + goto Thaw; + } + + pr_debug("PM: Preparing devices for restore.\n"); + + error = device_suspend(PMSG_PRETHAW); + if (error) + goto Free; + + error = disable_nonboot_cpus(); + if (!error) + swsusp_resume(); + + enable_nonboot_cpus(); + Free: + swsusp_free(); + device_resume(); + resume_console(); + Thaw: + printk(KERN_ERR "PM: Restore failed, recovering.\n"); + unprepare_processes(); + Done: + /* For success case, the suspend path will release the lock */ + mutex_unlock(&pm_mutex); + pr_debug("PM: Resume from disk failed.\n"); + return 0; +} + +late_initcall(software_resume); + + +static const char * const pm_disk_modes[] = { + [PM_DISK_FIRMWARE] = "firmware", + [PM_DISK_PLATFORM] = "platform", + [PM_DISK_SHUTDOWN] = "shutdown", + [PM_DISK_REBOOT] = "reboot", + [PM_DISK_TEST] = "test", + [PM_DISK_TESTPROC] = "testproc", +}; + +/** + * disk - Control suspend-to-disk mode + * + * Suspend-to-disk can be handled in several ways. The greatest + * distinction is who writes memory to disk - the firmware or the OS. + * If the firmware does it, we assume that it also handles suspending + * the system. + * If the OS does it, then we have three options for putting the system + * to sleep - using the platform driver (e.g. ACPI or other PM registers), + * powering off the system or rebooting the system (for testing). + * + * The system will support either 'firmware' or 'platform', and that is + * known a priori (and encoded in pm_ops). But, the user may choose + * 'shutdown' or 'reboot' as alternatives. + * + * show() will display what the mode is currently set to. + * store() will accept one of + * + * 'firmware' + * 'platform' + * 'shutdown' + * 'reboot' + * + * It will only change to 'firmware' or 'platform' if the system + * supports it (as determined from pm_ops->pm_disk_mode). + */ + +static ssize_t disk_show(struct subsystem * subsys, char * buf) +{ + return sprintf(buf, "%s\n", pm_disk_modes[pm_disk_mode]); +} + + +static ssize_t disk_store(struct subsystem * s, const char * buf, size_t n) +{ + int error = 0; + int i; + int len; + char *p; + suspend_disk_method_t mode = 0; + + p = memchr(buf, '\n', n); + len = p ? p - buf : n; + + mutex_lock(&pm_mutex); + for (i = PM_DISK_FIRMWARE; i < PM_DISK_MAX; i++) { + if (!strncmp(buf, pm_disk_modes[i], len)) { + mode = i; + break; + } + } + if (mode) { + if (mode == PM_DISK_SHUTDOWN || mode == PM_DISK_REBOOT || + mode == PM_DISK_TEST || mode == PM_DISK_TESTPROC) { + pm_disk_mode = mode; + } else { + if (pm_ops && pm_ops->enter && + (mode == pm_ops->pm_disk_mode)) + pm_disk_mode = mode; + else + error = -EINVAL; + } + } else { + error = -EINVAL; + } + + pr_debug("PM: suspend-to-disk mode set to '%s'\n", + pm_disk_modes[mode]); + mutex_unlock(&pm_mutex); + return error ? error : n; +} + +power_attr(disk); + +static ssize_t resume_show(struct subsystem * subsys, char *buf) +{ + return sprintf(buf,"%d:%d\n", MAJOR(swsusp_resume_device), + MINOR(swsusp_resume_device)); +} + +static ssize_t resume_store(struct subsystem *subsys, const char *buf, size_t n) +{ + unsigned int maj, min; + dev_t res; + int ret = -EINVAL; + + if (sscanf(buf, "%u:%u", &maj, &min) != 2) + goto out; + + res = MKDEV(maj,min); + if (maj != MAJOR(res) || min != MINOR(res)) + goto out; + + mutex_lock(&pm_mutex); + swsusp_resume_device = res; + mutex_unlock(&pm_mutex); + printk("Attempting manual resume\n"); + noresume = 0; + software_resume(); + ret = n; + out: + return ret; +} + +power_attr(resume); + +static ssize_t image_size_show(struct subsystem * subsys, char *buf) +{ + return sprintf(buf, "%lu\n", image_size); +} + +static ssize_t image_size_store(struct subsystem * subsys, const char * buf, size_t n) +{ + unsigned long size; + + if (sscanf(buf, "%lu", &size) == 1) { + image_size = size; + return n; + } + + return -EINVAL; +} + +power_attr(image_size); + +static struct attribute * g[] = { + &disk_attr.attr, + &resume_attr.attr, + &image_size_attr.attr, + NULL, +}; + + +static struct attribute_group attr_group = { + .attrs = g, +}; + + +static int __init pm_disk_init(void) +{ + return sysfs_create_group(&power_subsys.kset.kobj,&attr_group); +} + +core_initcall(pm_disk_init); + + +static int __init resume_setup(char *str) +{ + if (noresume) + return 1; + + strncpy( resume_file, str, 255 ); + return 1; +} + +static int __init resume_offset_setup(char *str) +{ + unsigned long long offset; + + if (noresume) + return 1; + + if (sscanf(str, "%llu", &offset) == 1) + swsusp_resume_block = offset; + + return 1; +} + +static int __init noresume_setup(char *str) +{ + noresume = 1; + return 1; +} + +__setup("noresume", noresume_setup); +__setup("resume_offset=", resume_offset_setup); +__setup("resume=", resume_setup); Added: branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c =================================================================== --- branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c (rev 0) +++ branches/ruby-2.6.21/ruby-2.6/kernel/power/main.c 2007-04-15 14:13:12 UTC (rev 2376) @@ -0,0 +1,338 @@ +/* + * kernel/power/main.c - PM subsystem core functionality. + * + * Copyright (c) 2003 Patrick Mochel + * Copyright (c) 2003 Open Source Development Lab + * + * This file is released under the GPLv2 + * + */ + +#include <linux/module.h> +#include <linux/suspend.h> +#include <linux/kobject.h> +#include <linux/string.h> +#include <linux/delay.h> +#include <linux/errno.h> +#include <linux/init.h> +#include <linux/pm.h> +#include <linux/console.h> +#include <linux/cpu.h> +#include <linux/resume-trace.h> +#include <linux/freezer.h> +#include <linux/vmstat.h> + +#include "power.h" + +/*This is just an arbitrary number */ +#define FREE_PAGE_NUMBER (100) + +DEFINE_MUTEX(pm_mutex); + +struct pm_ops *pm_ops; +suspend_disk_method_t pm_disk_mode = PM_DISK_PLATFORM; + +/** + * pm_set_ops - Set the global power method table. + * @ops: Pointer to ops structure. + */ + +void pm_set_ops(struct pm_ops * ops) +{ + mutex_lock(&pm_mutex); + pm_ops = ops; + mutex_unlock(&pm_mutex); +} + +static inline void pm_finish(suspend_state_t state) +{ + if (pm_ops->finish) + pm_ops->finish(state); +} + +/** + * suspend_prepare - Do prep work before entering low-power state. + * @state: State we're entering. + * + * This is common code that is called for each state that we're + * entering. Allocate a console, stop all processes, then make sure + * the platform can enter the requested state. + */ + +static int suspend_prepare(suspend_state_t state) +{ + int error; + unsigned int free_pages; + + if (!pm_ops || !pm_ops->enter) + return -EPERM; + + if (freeze_processes()) { + error = -EAGAIN; + goto Thaw; + } + + if ((free_pages = global_page_state(NR_FREE_PAGES)) + < FREE_PAGE_NUMBER) { + pr_debug("PM: free some memory\n"); + shrink_all_memory(FREE_PAGE_NUMBER - free_pages); + if (nr_free_pages() < FREE_PAGE_NUMBER) { + error = -ENOMEM; + printk(KERN_ERR "PM: No enough memory\n"); + goto Thaw; + } + } + + if (pm_ops->prepare) { + if ((error = pm_ops->prepare(state))) + goto Thaw; + } + + error = device_suspend(PMSG_SUSPEND); + if (error) { + printk(KERN_ERR "Some devices failed to suspend\n"); + goto Resume_devices; + } + error = disable_nonboot_cpus(); + if (!error) + return 0; + + enable_nonboot_cpus(); + Resume_devices: + pm_finish(state); + device_resume(); + resume_console(); + Thaw: + thaw_processes(); + return error; +} + + +int suspend_enter(suspend_state_t state) +{ + int error = 0; + unsigned long flags; + + local_irq_save(flags); + + if ((error = device_power_down(PMSG_SUSPEND))) { + printk(KERN_ERR "Some devices failed to power down\n"); + goto Done; + } + error = pm_ops->enter(state); + device_power_up(); + Done: + local_irq_restore(flags); + return error; +} + + +/** + * suspend_finish - Do final work before exiting suspend sequence. + * @state: State we're coming out of. + * + * Call platform code to clean up, restart processes, and free the + * console that we've allocated. This is not called for suspend-to-disk. + */ + +static void suspend_finish(suspend_state_t state) +{ + enable_nonboot_cpus(); + pm_finish(state); + device_resume(); + resume_console(); + thaw_processes(); +} + + + + +static const char * const pm_states[PM_SUSPEND_MAX] = { + [PM_SUSPEND_STANDBY] = "standby", + [PM_SUSPEND_MEM] = "mem", +#ifdef CONFIG_SOFTWARE_SUSPEND + [PM_SUSPEND_DISK] = "disk", +#endif +}; + +static inline int valid_state(suspend_state_t state) +{ + /* Suspend-to-disk does not really need low-level support. + * It can work with reboot if needed. */ + if (state == PM_SUSPEND_DISK) + return 1; + + /* all other states need lowlevel support and need to be + * valid to the lowlevel implementation, no valid callback + * implies that all are valid. */ + if (!pm_ops || (pm_ops->valid && !pm_ops->valid(state))) + return 0; + return 1; +} + + +/** + * enter_state - Do common work of entering low-power state. + * @state: pm_state structure for state we're entering. + * + * Make sure we're the only ones trying to enter a sleep state. Fail + * if someone has beat us to it, since we don't want anything weird to + * happen when we wake up. + * Then, do the setup for suspend, enter the state, and cleaup (after + * we've woken up). + */ + +static int enter_state(suspend_state_t state) +{ + int error; + + if (!valid_state(state)) + return -ENODEV; + if (!mutex_trylock(&pm_mutex)) + return -EBUSY; + + if (state == PM_SUSPEND_DISK) { + error = pm_suspend_disk(); + goto Unlock; + } + + pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); + if ((error = suspend_prepare(state))) + goto Unlock; + + pr_debug("PM: Entering %s sleep\n", pm_states[state]); + error = suspend_enter(state); + + pr_debug("PM: Finishing wakeup.\n"); + suspend_finish(state); + Unlock: + mutex_unlock(&pm_mutex); + return error; +} + +/* + * This is main interface to the outside world. It needs to be + * called from process context. + */ +int software_suspend(void) +{ + return enter_state(PM_SUSPEND_DISK); +} + + +/** + * pm_suspend - Externally visible function for suspending system. + * @state: Enumarted value of state to enter. + * + * Determine whether or not value is within range, get state + * structure, and enter (above). + */ + +int pm_suspend(suspend_state_t state) +{ + if (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX) + return enter_state(state); + return -EINVAL; +} + +EXPORT_SYMBOL(pm_suspend); + +decl_subsys(power,NULL,NULL); + + +/** + * state - control system power state. + * + * show() returns what states are supported, which is hard-coded to + * 'standby' (Power-On Suspend), 'mem' (Suspend-to-RAM), and + * 'disk' (Suspend-to-Disk). + * + * store() accepts one of those strings, translates it into the + * proper enumerated value, and initiates a suspend transition. + */ + +static ssize_t state_show(struct subsystem * subsys, char * buf) +{ + int i; + char * s = buf; + + for (i = 0; i < PM_SUSPEND_MAX; i++) { + if (pm_states[i] && valid_state(i)) + s += sprintf(s,"%s ", pm_states[i]); + } + s += sprintf(s,"\n"); + return (s - buf); +} + +static ssize_t state_store(struct subsystem * subsys, const char * buf, size_t n) +{ + suspend_state_t state = PM_SUSPEND_STANDBY; + const char * const *s; + char *p; + int error; + int len; + + p = memchr(buf, '\n', n); + len = p ? p - buf : n; + + for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) { + if (*s && !strncmp(buf, *s, len)) + break; + } + if (state < PM_SUSPEND_MAX && *s) + error = enter_state(state); + else + error = -EINVAL; + return error ? error : n; +} + +power_attr(state); + +#ifdef CONFIG_PM_TRACE +int pm_trace_enabled; + +static ssize_t pm_trace_show(struct subsystem * subsys, char * buf) +{ + return sprintf(buf, "%d\n", pm_trace_enabled); +} + +static ssize_t +pm_trace_store(struct subsystem * subsys, const char * buf, size_t n) +{ + int val; + + if (sscanf(buf, "%d", &val) == 1) { + pm_trace_enabled = !!val; + return n; + } + return -EINVAL; +} + +power_attr(pm_trace); + +static struct attribute * g[] = { + &state_attr.attr, + &pm_trace_attr.attr, + NULL, +}; +#else +static struct attribute * g[] = { + &state_attr.attr, + NULL, +}; +#endif /* CONFIG_PM_TRACE */ + +static struct attribute_group attr_group = { + .attrs = g, +}; + + +static int __init pm_init(void) +{ + int error = subsystem_register(&power_subsys); + if (!error) + error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group); + return error; +} + +core_initcall(pm_init); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |