From dc8f5d21dd6bdd94e5c5bf9bbcc616d00f0cc839 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 18 Jul 2006 13:44:57 +0200 Subject: [S390] .align 4096 statements in head.S SLES9 binutils don't like .align 4096 statements in head.S. Work around this by using .org statements. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/head31.S | 4 ++-- arch/s390/kernel/head64.S | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S index d00de17b3778..a4dc61f3285e 100644 --- a/arch/s390/kernel/head31.S +++ b/arch/s390/kernel/head31.S @@ -273,7 +273,7 @@ startup_continue: .Lbss_end: .long _end .Lparmaddr: .long PARMAREA .Lsccbaddr: .long .Lsccb - .align 4096 + .org 0x12000 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -290,7 +290,7 @@ startup_continue: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .align 4096 + .org 0x13000 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S index 47744fcca930..9d80c5b1ef95 100644 --- a/arch/s390/kernel/head64.S +++ b/arch/s390/kernel/head64.S @@ -268,7 +268,7 @@ startup_continue: .Lparmaddr: .quad PARMAREA - .align 4096 + .org 0x12000 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -285,7 +285,7 @@ startup_continue: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .align 4096 + .org 0x13000 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 -- cgit v1.2.2 From d7cf0d57ef9e07cf0f65c58c19a8e7c4a9db72b5 Mon Sep 17 00:00:00 2001 From: Heiko Carstens Date: Tue, 18 Jul 2006 13:46:58 +0200 Subject: [S390] sysfs_create_xxx return values. Take return values of sysfs_create_group & friends into account. Signed-off-by: Heiko Carstens Signed-off-by: Martin Schwidefsky --- arch/s390/kernel/setup.c | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'arch') diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 1ca34f54ea8a..c902f059c7aa 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c @@ -877,31 +877,57 @@ static struct bin_attribute ipl_scp_data_attr = { static decl_subsys(ipl, NULL, NULL); +static int ipl_register_fcp_files(void) +{ + int rc; + + rc = sysfs_create_group(&ipl_subsys.kset.kobj, + &ipl_fcp_attr_group); + if (rc) + goto out; + rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj, + &ipl_parameter_attr); + if (rc) + goto out_ipl_parm; + rc = sysfs_create_bin_file(&ipl_subsys.kset.kobj, + &ipl_scp_data_attr); + if (!rc) + goto out; + + sysfs_remove_bin_file(&ipl_subsys.kset.kobj, &ipl_parameter_attr); + +out_ipl_parm: + sysfs_remove_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); +out: + return rc; +} + static int __init ipl_device_sysfs_register(void) { int rc; rc = firmware_register(&ipl_subsys); if (rc) - return rc; + goto out; switch (get_ipl_type()) { case ipl_type_ccw: - sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_ccw_attr_group); + rc = sysfs_create_group(&ipl_subsys.kset.kobj, + &ipl_ccw_attr_group); break; case ipl_type_fcp: - sysfs_create_group(&ipl_subsys.kset.kobj, &ipl_fcp_attr_group); - sysfs_create_bin_file(&ipl_subsys.kset.kobj, - &ipl_parameter_attr); - sysfs_create_bin_file(&ipl_subsys.kset.kobj, - &ipl_scp_data_attr); + rc = ipl_register_fcp_files(); break; default: - sysfs_create_group(&ipl_subsys.kset.kobj, - &ipl_unknown_attr_group); + rc = sysfs_create_group(&ipl_subsys.kset.kobj, + &ipl_unknown_attr_group); break; } - return 0; + + if (rc) + firmware_unregister(&ipl_subsys); +out: + return rc; } __initcall(ipl_device_sysfs_register); -- cgit v1.2.2 From 46ba6d7d8b0486e9d565729880ddfb2b84d3af31 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 16 Jul 2006 22:10:44 -0700 Subject: [SPARC64]: Fix more of_device layer IRQ bugs, and correct PROMREG_MAX. Sabre and Psycho PCI controllers can have partial interrupt-map properties, meaning that on-board devices don't match up to any entries. Instead, they are fully specified from the beginning and we should pass them directly to the IRQ translator as-is. Also, fill in the necessary translator slots for the "graphics" and "expansion UPA" interrupts on Sabre, Psycho, and SYSIO SBUS. Increase PROMREG_MAX to 24, as seen on SUNW,ffb devices. Finally, prevent accidentally writing past the end of the of_device struct resource[] and irqs[] arrays. Spit out a log message when we ignore some entries because there are too many of them. Signed-off-by: David S. Miller --- arch/sparc64/kernel/of_device.c | 34 ++++++++++++++++++++++++++++++++-- arch/sparc64/kernel/prom.c | 12 ++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c index 7064cee290ae..238bbf6de07d 100644 --- a/arch/sparc64/kernel/of_device.c +++ b/arch/sparc64/kernel/of_device.c @@ -542,9 +542,17 @@ static void __init build_device_resources(struct of_device *op, /* Convert to num-cells. */ num_reg /= 4; - /* Conver to num-entries. */ + /* Convert to num-entries. */ num_reg /= na + ns; + /* Prevent overruning the op->resources[] array. */ + if (num_reg > PROMREG_MAX) { + printk(KERN_WARNING "%s: Too many regs (%d), " + "limiting to %d.\n", + op->node->full_name, num_reg, PROMREG_MAX); + num_reg = PROMREG_MAX; + } + for (index = 0; index < num_reg; index++) { struct resource *r = &op->resource[index]; u32 addr[OF_MAX_ADDR_CELLS]; @@ -650,8 +658,22 @@ apply_interrupt_map(struct device_node *dp, struct device_node *pp, next: imap += (na + 3); } - if (i == imlen) + if (i == imlen) { + /* Psycho and Sabre PCI controllers can have 'interrupt-map' + * properties that do not include the on-board device + * interrupts. Instead, the device's 'interrupts' property + * is already a fully specified INO value. + * + * Handle this by deciding that, if we didn't get a + * match in the parent's 'interrupt-map', and the + * parent is an IRQ translater, then use the parent as + * our IRQ controller. + */ + if (pp->irq_trans) + return pp; + return NULL; + } *irq_p = irq; cp = of_find_node_by_phandle(handle); @@ -803,6 +825,14 @@ static struct of_device * __init scan_one_device(struct device_node *dp, op->num_irqs = 0; } + /* Prevent overruning the op->irqs[] array. */ + if (op->num_irqs > PROMINTR_MAX) { + printk(KERN_WARNING "%s: Too many irqs (%d), " + "limiting to %d.\n", + dp->full_name, op->num_irqs, PROMINTR_MAX); + op->num_irqs = PROMINTR_MAX; + } + build_device_resources(op, parent); for (i = 0; i < op->num_irqs; i++) op->irqs[i] = build_one_device_irq(op, parent, op->irqs[i]); diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index c86007a2aa3f..5cc5ab63293f 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -344,10 +344,12 @@ static unsigned long __psycho_onboard_imap_off[] = { /*0x2f*/ PSYCHO_IMAP_CE, /*0x30*/ PSYCHO_IMAP_A_ERR, /*0x31*/ PSYCHO_IMAP_B_ERR, -/*0x32*/ PSYCHO_IMAP_PMGMT +/*0x32*/ PSYCHO_IMAP_PMGMT, +/*0x33*/ PSYCHO_IMAP_GFX, +/*0x34*/ PSYCHO_IMAP_EUPA, }; #define PSYCHO_ONBOARD_IRQ_BASE 0x20 -#define PSYCHO_ONBOARD_IRQ_LAST 0x32 +#define PSYCHO_ONBOARD_IRQ_LAST 0x34 #define psycho_onboard_imap_offset(__ino) \ __psycho_onboard_imap_off[(__ino) - PSYCHO_ONBOARD_IRQ_BASE] @@ -529,6 +531,10 @@ static unsigned long __sabre_onboard_imap_off[] = { /*0x2e*/ SABRE_IMAP_UE, /*0x2f*/ SABRE_IMAP_CE, /*0x30*/ SABRE_IMAP_PCIERR, +/*0x31*/ 0 /* reserved */, +/*0x32*/ 0 /* reserved */, +/*0x33*/ SABRE_IMAP_GFX, +/*0x34*/ SABRE_IMAP_EUPA, }; #define SABRE_ONBOARD_IRQ_BASE 0x20 #define SABRE_ONBOARD_IRQ_LAST 0x30 @@ -895,6 +901,8 @@ static unsigned long sysio_irq_offsets[] = { SYSIO_IMAP_CE, SYSIO_IMAP_SBERR, SYSIO_IMAP_PMGMT, + SYSIO_IMAP_GFX, + SYSIO_IMAP_EUPA, }; #undef bogon -- cgit v1.2.2 From 06ffd7956e4790d824b4b5575b56def8448ec6d4 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 16 Jul 2006 22:19:40 -0700 Subject: [SPARC]: Kill prom_getname, unused and not implemented properly. The m68k port's sun3 asm/oplib.h had a stray reference too, so I killed that off as well. Signed-off-by: David S. Miller --- arch/sparc/kernel/sparc_ksyms.c | 1 - arch/sparc/prom/tree.c | 18 -------- arch/sparc64/kernel/sparc64_ksyms.c | 1 - arch/sparc64/prom/tree.c | 85 ------------------------------------- 4 files changed, 105 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 5fb987fc3d63..4d441a554d35 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/prom/tree.c b/arch/sparc/prom/tree.c index 2bf03ee8cde5..5ec246573a98 100644 --- a/arch/sparc/prom/tree.c +++ b/arch/sparc/prom/tree.c @@ -205,24 +205,6 @@ int prom_searchsiblings(int node_start, char *nodename) return 0; } -/* Gets name in the form prom v2+ uses it (name@x,yyyyy or name (if no reg)) */ -int prom_getname (int node, char *buffer, int len) -{ - int i; - struct linux_prom_registers reg[PROMREG_MAX]; - - i = prom_getproperty (node, "name", buffer, len); - if (i <= 0) return -1; - buffer [i] = 0; - len -= i; - i = prom_getproperty (node, "reg", (char *)reg, sizeof (reg)); - if (i <= 0) return 0; - if (len < 11) return -1; - buffer = strchr (buffer, 0); - sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr); - return 0; -} - /* Interal version of nextprop that does not alter return values. */ char * __prom_nextprop(int node, char * oprop) { diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 237524d87cab..beffc82a1e85 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -254,7 +254,6 @@ EXPORT_SYMBOL(prom_getproperty); EXPORT_SYMBOL(prom_node_has_property); EXPORT_SYMBOL(prom_setprop); EXPORT_SYMBOL(saved_command_line); -EXPORT_SYMBOL(prom_getname); EXPORT_SYMBOL(prom_finddevice); EXPORT_SYMBOL(prom_feval); EXPORT_SYMBOL(prom_getbool); diff --git a/arch/sparc64/prom/tree.c b/arch/sparc64/prom/tree.c index 49075abd7cbc..500f05e2cfcb 100644 --- a/arch/sparc64/prom/tree.c +++ b/arch/sparc64/prom/tree.c @@ -193,91 +193,6 @@ prom_searchsiblings(int node_start, const char *nodename) return 0; } -/* Gets name in the {name@x,yyyyy|name (if no reg)} form */ -int -prom_getname (int node, char *buffer, int len) -{ - int i, sbus = 0; - int pci = 0, ebus = 0, ide = 0; - struct linux_prom_registers *reg; - struct linux_prom64_registers reg64[PROMREG_MAX]; - - for (sbus = prom_getparent (node); sbus; sbus = prom_getparent (sbus)) { - i = prom_getproperty (sbus, "name", buffer, len); - if (i > 0) { - buffer [i] = 0; - if (!strcmp (buffer, "sbus")) - goto getit; - } - } - if ((pci = prom_getparent (node))) { - i = prom_getproperty (pci, "name", buffer, len); - if (i > 0) { - buffer [i] = 0; - if (!strcmp (buffer, "pci")) - goto getit; - } - pci = 0; - } - if ((ebus = prom_getparent (node))) { - i = prom_getproperty (ebus, "name", buffer, len); - if (i > 0) { - buffer[i] = 0; - if (!strcmp (buffer, "ebus")) - goto getit; - } - ebus = 0; - } - if ((ide = prom_getparent (node))) { - i = prom_getproperty (ide, "name", buffer, len); - if (i > 0) { - buffer [i] = 0; - if (!strcmp (buffer, "ide")) - goto getit; - } - ide = 0; - } -getit: - i = prom_getproperty (node, "name", buffer, len); - if (i <= 0) { - buffer [0] = 0; - return -1; - } - buffer [i] = 0; - len -= i; - i = prom_getproperty (node, "reg", (char *)reg64, sizeof (reg64)); - if (i <= 0) return 0; - if (len < 16) return -1; - buffer = strchr (buffer, 0); - if (sbus) { - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x,%x", reg[0].which_io, (uint)reg[0].phys_addr); - } else if (pci) { - int dev, fn; - reg = (struct linux_prom_registers *)reg64; - fn = (reg[0].which_io >> 8) & 0x07; - dev = (reg[0].which_io >> 11) & 0x1f; - if (fn) - sprintf (buffer, "@%x,%x", dev, fn); - else - sprintf (buffer, "@%x", dev); - } else if (ebus) { - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr); - } else if (ide) { - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x,%x", reg[0].which_io, reg[0].phys_addr); - } else if (i == 4) { /* Happens on 8042's children on Ultra/PCI. */ - reg = (struct linux_prom_registers *)reg64; - sprintf (buffer, "@%x", reg[0].which_io); - } else { - sprintf (buffer, "@%x,%x", - (unsigned int)(reg64[0].phys_addr >> 36), - (unsigned int)(reg64[0].phys_addr)); - } - return 0; -} - /* Return the first property type for node 'node'. * buffer should be at least 32B in length */ -- cgit v1.2.2 From f7785a64d117951e4c2bf9418d8c1dd59fe53b36 Mon Sep 17 00:00:00 2001 From: Bob Breuer Date: Mon, 17 Jul 2006 17:05:56 -0700 Subject: [SPARC]: Fix property name acquisition in prom.c On sparc32 the prom_{first,next}prop() interfaces work a little differently. The buffer argument is ignored on sparc32 and the firmware just returns a raw pointer to the property name. Signed-off-by: David S. Miller --- arch/sparc/kernel/prom.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/prom.c b/arch/sparc/kernel/prom.c index 4b06dcb00ebd..4ca9e5fc97f4 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; -- cgit v1.2.2 From 9d7ab1f4d56dffcddc1177b3cd55b6da6620e1e1 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 17 Jul 2006 21:39:09 -0700 Subject: [SPARC]: Fix initialization of sun4d SBUS interrupts. 1) Explicitly traverse to the root looking for the "sbi". 2) Grab the "board#" property from the sbi's parent and verify that this parent is an "io-unit" node. 3) Skip IRQ initialization when device lacks "reg" property. Signed-off-by: David S. Miller --- arch/sparc/kernel/of_device.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c index 5a2faad5d043..97bf87e8cdde 100644 --- a/arch/sparc/kernel/of_device.c +++ b/arch/sparc/kernel/of_device.c @@ -596,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]; @@ -617,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; -- cgit v1.2.2 From 2f72ba43581890d003427053ebe4dfaa14e5f4b0 Mon Sep 17 00:00:00 2001 From: Raymond Burns Date: Mon, 17 Jul 2006 21:40:27 -0700 Subject: [SPARC]: Initialize iounit spinlock in iounit_init(). Signed-off-by: David S. Miller --- arch/sparc/mm/io-unit.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 42c1c700c0a7..2bb1309003dd 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -64,6 +64,7 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus) sbus->iommu = (struct iommu_struct *)iounit; iounit->page_table = xpt; + spin_lock_init(&iounit->lock); for (xptend = iounit->page_table + (16 * PAGE_SIZE) / sizeof(iopte_t); xpt < xptend;) -- cgit v1.2.2 From c2d3bffebc2cb651ed33abae2434f85cd503a498 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 17 Jul 2006 21:49:58 -0700 Subject: [SPARC]: Simplify and correct __cpu_find_by() By using for_each_node_by_type(). Also, correct a spurioud test in check_cpu_node() on sparc64. It is only called with nodes that have device_type "cpu". Signed-off-by: David S. Miller --- arch/sparc/kernel/devices.c | 25 +++++++------------------ arch/sparc64/kernel/devices.c | 3 --- 2 files changed, 7 insertions(+), 21 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/devices.c b/arch/sparc/kernel/devices.c index adba9dfee35e..af90a5f9ab57 100644 --- a/arch/sparc/kernel/devices.c +++ b/arch/sparc/kernel/devices.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -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/sparc64/kernel/devices.c b/arch/sparc64/kernel/devices.c index f8ef2f2b9b37..ec10f7edcf86 100644 --- a/arch/sparc64/kernel/devices.c +++ b/arch/sparc64/kernel/devices.c @@ -66,9 +66,6 @@ static int check_cpu_node(struct device_node *dp, int *cur_inst, void *compare_arg, struct device_node **dev_node, int *mid) { - if (strcmp(dp->type, "cpu")) - return -ENODEV; - if (!compare(dp, *cur_inst, compare_arg)) { if (dev_node) *dev_node = dp; -- cgit v1.2.2 From 198c167c5424d30d4f6687aed6e54ef71036f8e9 Mon Sep 17 00:00:00 2001 From: Raymond Burns Date: Mon, 17 Jul 2006 21:50:55 -0700 Subject: [SPARC]: Do not call sun4m_irq_rotate on sun4d. Signed-off-by: David S. Miller --- arch/sparc/kernel/irq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c index cde73327ca96..72f0201051a0 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; -- cgit v1.2.2 From 8b3c848cc89e62904e6d9c8f9fed13d5c225572d Mon Sep 17 00:00:00 2001 From: Raymond Burns Date: Mon, 17 Jul 2006 21:57:09 -0700 Subject: [SPARC]: Get sun4d SMP building again. Signed-off-by: David S. Miller --- arch/sparc/kernel/smp.c | 96 ++++++++++++++++++++++++++++++++++++--- arch/sparc/kernel/sun4d_smp.c | 103 +++++++++++++----------------------------- 2 files changed, 121 insertions(+), 78 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c index 6135d4faeeeb..e311ade1b490 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/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index b141b7ee6717..ba843f6a2832 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; -- cgit v1.2.2 From 8310a32c15c76623bbe2425d38688a9d5b3e50a9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 21 Jul 2006 14:12:39 -0700 Subject: [SPARC]: Fix length parameter verification in sys_getdomainname(). Found by scrashme. Signed-off-by: David S. Miller --- arch/sparc/kernel/sys_sparc.c | 18 +++++++++--------- arch/sparc64/kernel/sys_sparc.c | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) (limited to 'arch') diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index 0cdfc9d294b4..a41c8a5c2007 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; } diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c index 51c056df528e..054d0abdb7ee 100644 --- a/arch/sparc64/kernel/sys_sparc.c +++ b/arch/sparc64/kernel/sys_sparc.c @@ -701,21 +701,21 @@ extern void check_pending(int signum); asmlinkage long 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; } -- cgit v1.2.2 From efab4cbe99f9b73d208ad9e5ec9388524005e095 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 21 Jul 2006 14:19:45 -0700 Subject: [SPARC64]: Update defconfig. Signed-off-by: David S. Miller --- arch/sparc64/defconfig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index 38353621069e..43d9229fca07 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.18-rc1 -# Wed Jul 12 14:00:58 2006 +# Linux kernel version: 2.6.18-rc2 +# Fri Jul 21 14:19:24 2006 # CONFIG_SPARC=y CONFIG_SPARC64=y @@ -36,6 +36,7 @@ CONFIG_SWAP=y CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y # CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set @@ -1120,7 +1121,7 @@ CONFIG_USB_HIDDEV=y # CONFIG_USB_LEGOTOWER is not set # CONFIG_USB_LCD is not set # CONFIG_USB_LED is not set -# CONFIG_USB_CY7C63 is not set +# CONFIG_USB_CYPRESS_CY7C63 is not set # CONFIG_USB_CYTHERM is not set # CONFIG_USB_PHIDGETKIT is not set # CONFIG_USB_PHIDGETSERVO is not set @@ -1279,7 +1280,6 @@ CONFIG_RAMFS=y # CONFIG_NFSD is not set # CONFIG_SMB_FS is not set # CONFIG_CIFS is not set -# CONFIG_CIFS_DEBUG2 is not set # CONFIG_NCP_FS is not set # CONFIG_CODA_FS is not set # CONFIG_AFS_FS is not set -- cgit v1.2.2