diff options
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/devices.c | 25 | ||||
-rw-r--r-- | arch/sparc/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/of_device.c | 207 | ||||
-rw-r--r-- | arch/sparc/kernel/prom.c | 9 | ||||
-rw-r--r-- | arch/sparc/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/smp.c | 96 | ||||
-rw-r--r-- | arch/sparc/kernel/sparc_ksyms.c | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/sun4d_smp.c | 103 | ||||
-rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 18 |
9 files changed, 289 insertions, 174 deletions
diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index adba9dfee35..af90a5f9ab5 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -15,6 +15,7 @@ #include <asm/page.h> #include <asm/oplib.h> +#include <asm/prom.h> #include <asm/smp.h> #include <asm/system.h> #include <asm/cpudata.h> @@ -34,12 +35,6 @@ static int check_cpu_node(int nd, int *cur_inst, int (*compare)(int, int, void *), void *compare_arg, int *prom_node, int *mid) { - char node_str[128]; - - prom_getstring(nd, "device_type", node_str, sizeof(node_str)); - if (strcmp(node_str, "cpu")) - return -ENODEV; - if (!compare(nd, *cur_inst, compare_arg)) { if (prom_node) *prom_node = nd; @@ -59,20 +54,14 @@ static int check_cpu_node(int nd, int *cur_inst, static int __cpu_find_by(int (*compare)(int, int, void *), void *compare_arg, int *prom_node, int *mid) { - int nd, cur_inst, err; + struct device_node *dp; + int cur_inst; - nd = prom_root_node; cur_inst = 0; - - err = check_cpu_node(nd, &cur_inst, compare, compare_arg, - prom_node, mid); - if (!err) - return 0; - - nd = prom_getchild(nd); - while ((nd = prom_getsibling(nd)) != 0) { - err = check_cpu_node(nd, &cur_inst, compare, compare_arg, - prom_node, mid); + for_each_node_by_type(dp, "cpu") { + int err = check_cpu_node(dp->node, &cur_inst, + compare, compare_arg, + prom_node, mid); if (!err) return 0; } diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index cde73327ca9..72f0201051a 100644 --- a/arch/sparc/kernel/irq.c +++ b/arch/sparc/kernel/irq.c @@ -329,7 +329,7 @@ void handler_irq(int irq, struct pt_regs * regs) disable_pil_irq(irq); #ifdef CONFIG_SMP /* Only rotate on lower priority IRQ's (scsi, ethernet, etc.). */ - if(irq < 10) + if((sparc_cpu_model==sun4m) && (irq < 10)) smp4m_irq_rotate(cpu); #endif action = sparc_irq[irq].action; diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index bc956c53037..97bf87e8cdd 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -183,7 +183,7 @@ struct bus_type of_bus_type = { }; EXPORT_SYMBOL(of_bus_type); -static inline u64 of_read_addr(u32 *cell, int size) +static inline u64 of_read_addr(const u32 *cell, int size) { u64 r = 0; while (size--) @@ -209,8 +209,8 @@ struct of_bus { int (*match)(struct device_node *parent); void (*count_cells)(struct device_node *child, int *addrc, int *sizec); - u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna); - int (*translate)(u32 *addr, u64 offset, int na); + int (*map)(u32 *addr, const u32 *range, + int na, int ns, int pna); unsigned int (*get_flags)(u32 *addr); }; @@ -224,27 +224,49 @@ static void of_bus_default_count_cells(struct device_node *dev, get_cells(dev, addrc, sizec); } -static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna) +/* Make sure the least significant 64-bits are in-range. Even + * for 3 or 4 cell values it is a good enough approximation. + */ +static int of_out_of_range(const u32 *addr, const u32 *base, + const u32 *size, int na, int ns) { - u64 cp, s, da; + u64 a = of_read_addr(addr, na); + u64 b = of_read_addr(base, na); - cp = of_read_addr(range, na); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr, na); + if (a < b) + return 1; - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; + b += of_read_addr(size, ns); + if (a >= b) + return 1; + + return 0; } -static int of_bus_default_translate(u32 *addr, u64 offset, int na) +static int of_bus_default_map(u32 *addr, const u32 *range, + int na, int ns, int pna) { - u64 a = of_read_addr(addr, na); - memset(addr, 0, na * 4); - a += offset; - if (na > 1) - addr[na - 2] = a >> 32; - addr[na - 1] = a & 0xffffffffu; + u32 result[OF_MAX_ADDR_CELLS]; + int i; + + if (ns > 2) { + printk("of_device: Cannot handle size cells (%d) > 2.", ns); + return -EINVAL; + } + + if (of_out_of_range(addr, range, range + na + pna, na, ns)) + return -EINVAL; + + /* Start with the parent range base. */ + memcpy(result, range + na, pna * 4); + + /* Add in the child address offset. */ + for (i = 0; i < na; i++) + result[pna - 1 - i] += + (addr[na - 1 - i] - + range[na - 1 - i]); + + memcpy(addr, result, pna * 4); return 0; } @@ -254,14 +276,26 @@ static unsigned int of_bus_default_get_flags(u32 *addr) return IORESOURCE_MEM; } - /* * PCI bus specific translator */ static int of_bus_pci_match(struct device_node *np) { - return !strcmp(np->type, "pci") || !strcmp(np->type, "pciex"); + if (!strcmp(np->type, "pci") || !strcmp(np->type, "pciex")) { + /* Do not do PCI specific frobbing if the + * PCI bridge lacks a ranges property. We + * want to pass it through up to the next + * parent as-is, not with the PCI translate + * method which chops off the top address cell. + */ + if (!of_find_property(np, "ranges", NULL)) + return 0; + + return 1; + } + + return 0; } static void of_bus_pci_count_cells(struct device_node *np, @@ -273,27 +307,32 @@ static void of_bus_pci_count_cells(struct device_node *np, *sizec = 2; } -static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna) +static int of_bus_pci_map(u32 *addr, const u32 *range, + int na, int ns, int pna) { - u64 cp, s, da; + u32 result[OF_MAX_ADDR_CELLS]; + int i; /* Check address type match */ if ((addr[0] ^ range[0]) & 0x03000000) - return OF_BAD_ADDR; + return -EINVAL; - /* Read address values, skipping high cell */ - cp = of_read_addr(range + 1, na - 1); - s = of_read_addr(range + na + pna, ns); - da = of_read_addr(addr + 1, na - 1); + if (of_out_of_range(addr + 1, range + 1, range + na + pna, + na - 1, ns)) + return -EINVAL; - if (da < cp || da >= (cp + s)) - return OF_BAD_ADDR; - return da - cp; -} + /* Start with the parent range base. */ + memcpy(result, range + na, pna * 4); -static int of_bus_pci_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr + 1, offset, na - 1); + /* Add in the child address offset, skipping high cell. */ + for (i = 0; i < na - 1; i++) + result[pna - 1 - i] += + (addr[na - 1 - i] - + range[na - 1 - i]); + + memcpy(addr, result, pna * 4); + + return 0; } static unsigned int of_bus_pci_get_flags(u32 *addr) @@ -332,16 +371,11 @@ static void of_bus_sbus_count_cells(struct device_node *child, *sizec = 1; } -static u64 of_bus_sbus_map(u32 *addr, u32 *range, int na, int ns, int pna) +static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int pna) { return of_bus_default_map(addr, range, na, ns, pna); } -static int of_bus_sbus_translate(u32 *addr, u64 offset, int na) -{ - return of_bus_default_translate(addr, offset, na); -} - static unsigned int of_bus_sbus_get_flags(u32 *addr) { return IORESOURCE_MEM; @@ -360,7 +394,6 @@ static struct of_bus of_busses[] = { .match = of_bus_pci_match, .count_cells = of_bus_pci_count_cells, .map = of_bus_pci_map, - .translate = of_bus_pci_translate, .get_flags = of_bus_pci_get_flags, }, /* SBUS */ @@ -370,7 +403,6 @@ static struct of_bus of_busses[] = { .match = of_bus_sbus_match, .count_cells = of_bus_sbus_count_cells, .map = of_bus_sbus_map, - .translate = of_bus_sbus_translate, .get_flags = of_bus_sbus_get_flags, }, /* Default */ @@ -380,7 +412,6 @@ static struct of_bus of_busses[] = { .match = NULL, .count_cells = of_bus_default_count_cells, .map = of_bus_default_map, - .translate = of_bus_default_translate, .get_flags = of_bus_default_get_flags, }, }; @@ -405,33 +436,34 @@ static int __init build_one_resource(struct device_node *parent, u32 *ranges; unsigned int rlen; int rone; - u64 offset = OF_BAD_ADDR; ranges = of_get_property(parent, "ranges", &rlen); if (ranges == NULL || rlen == 0) { - offset = of_read_addr(addr, na); - memset(addr, 0, pna * 4); - goto finish; + u32 result[OF_MAX_ADDR_CELLS]; + int i; + + memset(result, 0, pna * 4); + for (i = 0; i < na; i++) + result[pna - 1 - i] = + addr[na - 1 - i]; + + memcpy(addr, result, pna * 4); + return 0; } /* Now walk through the ranges */ rlen /= 4; rone = na + pna + ns; for (; rlen >= rone; rlen -= rone, ranges += rone) { - offset = bus->map(addr, ranges, na, ns, pna); - if (offset != OF_BAD_ADDR) - break; + if (!bus->map(addr, ranges, na, ns, pna)) + return 0; } - if (offset == OF_BAD_ADDR) - return 1; - memcpy(addr, ranges + na, 4 * pna); - -finish: - /* Translate it into parent bus space */ - return pbus->translate(addr, offset, pna); + return 1; } +static int of_resource_verbose; + static void __init build_device_resources(struct of_device *op, struct device *parent) { @@ -497,7 +529,8 @@ static void __init build_device_resources(struct of_device *op, pbus = of_match_bus(pp); pbus->count_cells(dp, &pna, &pns); - if (build_one_resource(dp, bus, pbus, addr, dna, dns, pna)) + if (build_one_resource(dp, bus, pbus, addr, + dna, dns, pna)) break; dna = pna; @@ -507,6 +540,12 @@ static void __init build_device_resources(struct of_device *op, build_res: memset(r, 0, sizeof(*r)); + + if (of_resource_verbose) + printk("%s reg[%d] -> %llx\n", + op->node->full_name, index, + result); + if (result != OF_BAD_ADDR) { r->start = result & 0xffffffff; r->end = result + size - 1; @@ -557,14 +596,41 @@ static struct of_device * __init scan_one_device(struct device_node *dp, static int pil_to_sbus[] = { 0, 0, 1, 2, 0, 3, 0, 4, 0, 5, 0, 6, 0, 7, 0, 0, }; - struct device_node *busp = dp->parent; + struct device_node *io_unit, *sbi = dp->parent; struct linux_prom_registers *regs; - int board = of_getintprop_default(busp, "board#", 0); - int slot; + int board, slot; + + while (sbi) { + if (!strcmp(sbi->name, "sbi")) + break; + + sbi = sbi->parent; + } + if (!sbi) + goto build_resources; regs = of_get_property(dp, "reg", NULL); + if (!regs) + goto build_resources; + slot = regs->which_io; + /* If SBI's parent is not io-unit or the io-unit lacks + * a "board#" property, something is very wrong. + */ + if (!sbi->parent || strcmp(sbi->parent->name, "io-unit")) { + printk("%s: Error, parent is not io-unit.\n", + sbi->full_name); + goto build_resources; + } + io_unit = sbi->parent; + board = of_getintprop_default(io_unit, "board#", -1); + if (board == -1) { + printk("%s: Error, lacks board# property.\n", + io_unit->full_name); + goto build_resources; + } + for (i = 0; i < op->num_irqs; i++) { int this_irq = op->irqs[i]; int sbusl = pil_to_sbus[this_irq]; @@ -578,6 +644,7 @@ static struct of_device * __init scan_one_device(struct device_node *dp, } } +build_resources: build_device_resources(op, parent); op->dev.parent = parent; @@ -643,6 +710,18 @@ static int __init of_bus_driver_init(void) postcore_initcall(of_bus_driver_init); +static int __init of_debug(char *str) +{ + int val = 0; + + get_option(&str, &val); + if (val & 1) + of_resource_verbose = 1; + return 1; +} + +__setup("of_debug=", of_debug); + int of_register_driver(struct of_platform_driver *drv, struct bus_type *bus) { /* initialize common driver fields */ @@ -695,9 +774,11 @@ int of_device_register(struct of_device *ofdev) if (rc) return rc; - device_create_file(&ofdev->dev, &dev_attr_devspec); + rc = device_create_file(&ofdev->dev, &dev_attr_devspec); + if (rc) + device_unregister(&ofdev->dev); - return 0; + return rc; } void of_device_unregister(struct of_device *ofdev) diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 4b06dcb00eb..4ca9e5fc97f 100644 --- a/arch/sparc/kernel/prom.c +++ b/arch/sparc/kernel/prom.c @@ -444,6 +444,7 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s static struct property *tmp = NULL; struct property *p; int len; + const char *name; if (tmp) { p = tmp; @@ -456,19 +457,21 @@ static struct property * __init build_one_prop(phandle node, char *prev, char *s p->name = (char *) (p + 1); if (special_name) { + strcpy(p->name, special_name); p->length = special_len; p->value = prom_early_alloc(special_len); memcpy(p->value, special_val, special_len); } else { if (prev == NULL) { - prom_firstprop(node, p->name); + name = prom_firstprop(node, NULL); } else { - prom_nextprop(node, prev, p->name); + name = prom_nextprop(node, prev, NULL); } - if (strlen(p->name) == 0) { + if (strlen(name) == 0) { tmp = p; return NULL; } + strcpy(p->name, name); p->length = prom_getproplen(node, p->name); if (p->length <= 0) { p->length = 0; diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 8606ef4e52e..35488d6c745 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -17,7 +17,7 @@ #include <asm/smp.h> #include <linux/user.h> #include <linux/a.out.h> -#include <linux/tty.h> +#include <linux/screen_info.h> #include <linux/delay.h> #include <linux/fs.h> #include <linux/seq_file.h> diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 6135d4faeee..e311ade1b49 100644 --- a/arch/sparc/kernel/smp.c +++ b/arch/sparc/kernel/smp.c @@ -87,6 +87,7 @@ void __cpuinit smp_store_cpu_info(int id) void __init smp_cpus_done(unsigned int max_cpus) { extern void smp4m_smp_done(void); + extern void smp4d_smp_done(void); unsigned long bogosum = 0; int cpu, num; @@ -100,8 +101,34 @@ void __init smp_cpus_done(unsigned int max_cpus) num, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100); - BUG_ON(sparc_cpu_model != sun4m); - smp4m_smp_done(); + switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; + case sun4m: + smp4m_smp_done(); + break; + case sun4d: + smp4d_smp_done(); + break; + case sun4e: + printk("SUN4E\n"); + BUG(); + break; + case sun4u: + printk("SUN4U\n"); + BUG(); + break; + default: + printk("UNKNOWN!\n"); + BUG(); + break; + }; } void cpu_panic(void) @@ -267,9 +294,9 @@ int setup_profiling_timer(unsigned int multiplier) void __init smp_prepare_cpus(unsigned int max_cpus) { extern void smp4m_boot_cpus(void); + extern void smp4d_boot_cpus(void); int i, cpuid, extra; - BUG_ON(sparc_cpu_model != sun4m); printk("Entering SMP Mode...\n"); extra = 0; @@ -283,7 +310,34 @@ void __init smp_prepare_cpus(unsigned int max_cpus) smp_store_cpu_info(boot_cpu_id); - smp4m_boot_cpus(); + switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; + case sun4m: + smp4m_boot_cpus(); + break; + case sun4d: + smp4d_boot_cpus(); + break; + case sun4e: + printk("SUN4E\n"); + BUG(); + break; + case sun4u: + printk("SUN4U\n"); + BUG(); + break; + default: + printk("UNKNOWN!\n"); + BUG(); + break; + }; } /* Set this up early so that things like the scheduler can init @@ -323,9 +377,37 @@ void __init smp_prepare_boot_cpu(void) int __cpuinit __cpu_up(unsigned int cpu) { extern int smp4m_boot_one_cpu(int); - int ret; - - ret = smp4m_boot_one_cpu(cpu); + extern int smp4d_boot_one_cpu(int); + int ret=0; + + switch(sparc_cpu_model) { + case sun4: + printk("SUN4\n"); + BUG(); + break; + case sun4c: + printk("SUN4C\n"); + BUG(); + break; + case sun4m: + ret = smp4m_boot_one_cpu(cpu); + break; + case sun4d: + ret = smp4d_boot_one_cpu(cpu); + break; + case sun4e: + printk("SUN4E\n"); + BUG(); + break; + case sun4u: + printk("SUN4U\n"); + BUG(); + break; + default: + printk("UNKNOWN!\n"); + BUG(); + break; + }; if (!ret) { cpu_set(cpu, smp_commenced_mask); diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 5fb987fc3d6..4d441a554d3 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -237,7 +237,6 @@ EXPORT_SYMBOL(prom_node_has_property); EXPORT_SYMBOL(prom_setprop); EXPORT_SYMBOL(saved_command_line); EXPORT_SYMBOL(prom_apply_obio_ranges); -EXPORT_SYMBOL(prom_getname); EXPORT_SYMBOL(prom_feval); EXPORT_SYMBOL(prom_getbool); EXPORT_SYMBOL(prom_getstring); diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index b141b7ee671..ba843f6a283 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c @@ -43,15 +43,10 @@ extern ctxd_t *srmmu_ctx_table_phys; extern void calibrate_delay(void); extern volatile int smp_processors_ready; -extern int smp_num_cpus; static int smp_highest_cpu; extern volatile unsigned long cpu_callin_map[NR_CPUS]; extern cpuinfo_sparc cpu_data[NR_CPUS]; extern unsigned char boot_cpu_id; -extern int smp_activated; -extern volatile int __cpu_number_map[NR_CPUS]; -extern volatile int __cpu_logical_map[NR_CPUS]; -extern volatile unsigned long ipi_count; extern volatile int smp_process_available; extern cpumask_t smp_commenced_mask; @@ -144,6 +139,8 @@ void __init smp4d_callin(void) spin_lock_irqsave(&sun4d_imsk_lock, flags); cc_set_imsk(cc_get_imsk() & ~0x4000); /* Allow PIL 14 as well */ spin_unlock_irqrestore(&sun4d_imsk_lock, flags); + cpu_set(cpuid, cpu_online_map); + } extern void init_IRQ(void); @@ -160,51 +157,24 @@ extern unsigned long trapbase_cpu3[]; void __init smp4d_boot_cpus(void) { - int cpucount = 0; - int i, mid; - - printk("Entering SMP Mode...\n"); - if (boot_cpu_id) current_set[0] = NULL; - - local_irq_enable(); - cpus_clear(cpu_present_map); - - /* XXX This whole thing has to go. See sparc64. */ - for (i = 0; !cpu_find_by_instance(i, NULL, &mid); i++) - cpu_set(mid, cpu_present_map); - SMP_PRINTK(("cpu_present_map %08lx\n", cpus_addr(cpu_present_map)[0])); - for(i=0; i < NR_CPUS; i++) - __cpu_number_map[i] = -1; - for(i=0; i < NR_CPUS; i++) - __cpu_logical_map[i] = -1; - __cpu_number_map[boot_cpu_id] = 0; - __cpu_logical_map[0] = boot_cpu_id; - current_thread_info()->cpu = boot_cpu_id; - smp_store_cpu_info(boot_cpu_id); smp_setup_percpu_timer(); local_flush_cache_all(); - if (cpu_find_by_instance(1, NULL, NULL)) - return; /* Not an MP box. */ - SMP_PRINTK(("Iterating over CPUs\n")); - for(i = 0; i < NR_CPUS; i++) { - if(i == boot_cpu_id) - continue; - - if (cpu_isset(i, cpu_present_map)) { +} + +int smp4d_boot_one_cpu(int i) +{ extern unsigned long sun4d_cpu_startup; unsigned long *entry = &sun4d_cpu_startup; struct task_struct *p; int timeout; - int no; + int cpu_node; + cpu_find_by_instance(i, &cpu_node,NULL); /* Cook up an idler for this guy. */ p = fork_idle(i); - cpucount++; current_set[i] = task_thread_info(p); - for (no = 0; !cpu_find_by_instance(no, NULL, &mid) - && mid != i; no++) ; /* * Initialize the contexts table @@ -216,9 +186,9 @@ void __init smp4d_boot_cpus(void) smp_penguin_ctable.reg_size = 0; /* whirrr, whirrr, whirrrrrrrrr... */ - SMP_PRINTK(("Starting CPU %d at %p task %d node %08x\n", i, entry, cpucount, cpu_data(no).prom_node)); + SMP_PRINTK(("Starting CPU %d at %p \n", i, entry)); local_flush_cache_all(); - prom_startcpu(cpu_data(no).prom_node, + prom_startcpu(cpu_node, &smp_penguin_ctable, 0, (char *)entry); SMP_PRINTK(("prom_startcpu returned :)\n")); @@ -230,39 +200,30 @@ void __init smp4d_boot_cpus(void) udelay(200); } - if(cpu_callin_map[i]) { - /* Another "Red Snapper". */ - __cpu_number_map[i] = cpucount; - __cpu_logical_map[cpucount] = i; - } else { - cpucount--; - printk("Processor %d is stuck.\n", i); - } - } - if(!(cpu_callin_map[i])) { - cpu_clear(i, cpu_present_map); - __cpu_number_map[i] = -1; - } + if (!(cpu_callin_map[i])) { + printk("Processor %d is stuck.\n", i); + return -ENODEV; + } local_flush_cache_all(); - if(cpucount == 0) { - printk("Error: only one Processor found.\n"); - cpu_present_map = cpumask_of_cpu(hard_smp4d_processor_id()); - } else { - unsigned long bogosum = 0; - - for_each_present_cpu(i) { - bogosum += cpu_data(i).udelay_val; - smp_highest_cpu = i; + return 0; +} + +void __init smp4d_smp_done(void) +{ + int i, first; + int *prev; + + /* setup cpu list for irq rotation */ + first = 0; + prev = &first; + for (i = 0; i < NR_CPUS; i++) + if (cpu_online(i)) { + *prev = i; + prev = &cpu_data(i).next; } - SMP_PRINTK(("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", cpucount + 1, bogosum/(500000/HZ), (bogosum/(5000/HZ))%100)); - printk("Total of %d Processors activated (%lu.%02lu BogoMIPS).\n", - cpucount + 1, - bogosum/(500000/HZ), - (bogosum/(5000/HZ))%100); - smp_activated = 1; - smp_num_cpus = cpucount + 1; - } + *prev = first; + local_flush_cache_all(); /* Free unneeded trap tables */ ClearPageReserved(virt_to_page(trapbase_cpu1)); @@ -334,7 +295,7 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2, register int i; mask = cpumask_of_cpu(hard_smp4d_processor_id()); - cpus_andnot(mask, cpu_present_map, mask); + cpus_andnot(mask, cpu_online_map, mask); for(i = 0; i <= high; i++) { if (cpu_isset(i, mask)) { ccall_info.processors_in[i] = 0; diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 0cdfc9d294b..a41c8a5c200 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -465,21 +465,21 @@ sys_rt_sigaction(int sig, asmlinkage int sys_getdomainname(char __user *name, int len) { - int nlen; - int err = -EFAULT; + int nlen, err; + if (len < 0 || len > __NEW_UTS_LEN) + return -EINVAL; + down_read(&uts_sem); nlen = strlen(system_utsname.domainname) + 1; - if (nlen < len) len = nlen; - if (len > __NEW_UTS_LEN) - goto done; - if (copy_to_user(name, system_utsname.domainname, len)) - goto done; - err = 0; -done: + + err = -EFAULT; + if (!copy_to_user(name, system_utsname.domainname, len)) + err = 0; + up_read(&uts_sem); return err; } |