From a4aa2e867c5d696c0f249ad8d63d0d983b4ffaf9 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 2 Oct 2007 16:17:17 -0700 Subject: [PATCH 1/6] [SPARC64]: Don't use in/local regs for ldx/stx data in N1 memcpy. It doesn't matter for use in 64-bit objects, but when used in 32-bit environments the top 32-bits of the local and in registers will get chopped off on the next register window spill/restore which leads to difficult to track down and subtle bugs. Signed-off-by: David S. Miller --- arch/sparc64/lib/NGmemcpy.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/sparc64/lib/NGmemcpy.S b/arch/sparc64/lib/NGmemcpy.S index 605cb3f0990..96a14caf696 100644 --- a/arch/sparc64/lib/NGmemcpy.S +++ b/arch/sparc64/lib/NGmemcpy.S @@ -321,11 +321,11 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ andn %i2, 0xf, %i4 and %i2, 0xf, %i2 1: subcc %i4, 0x10, %i4 - EX_LD(LOAD(ldx, %i1, %i5)) + EX_LD(LOAD(ldx, %i1, %o4)) add %i1, 0x08, %i1 EX_LD(LOAD(ldx, %i1, %g1)) sub %i1, 0x08, %i1 - EX_ST(STORE(stx, %i5, %i1 + %i3)) + EX_ST(STORE(stx, %o4, %i1 + %i3)) add %i1, 0x8, %i1 EX_ST(STORE(stx, %g1, %i1 + %i3)) bgu,pt %XCC, 1b @@ -334,8 +334,8 @@ FUNC_NAME: /* %i0=dst, %i1=src, %i2=len */ be,pt %XCC, 1f nop sub %i2, 0x8, %i2 - EX_LD(LOAD(ldx, %i1, %i5)) - EX_ST(STORE(stx, %i5, %i1 + %i3)) + EX_LD(LOAD(ldx, %i1, %o4)) + EX_ST(STORE(stx, %o4, %i1 + %i3)) add %i1, 0x8, %i1 1: andcc %i2, 0x4, %g0 be,pt %XCC, 1f From 07607c5492f836923c2ab9eb1cd1d39be7dace49 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 3 Oct 2007 21:08:11 -0700 Subject: [PATCH 2/6] [SPARC64]: Fix domain-services port probing. We should only use ports underneath "domain-services", other DS ports in the MDESC aren't for us to use. Signed-off-by: David S. Miller --- arch/sparc64/kernel/vio.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c index 1550ac5673d..830dc88c19c 100644 --- a/arch/sparc64/kernel/vio.c +++ b/arch/sparc64/kernel/vio.c @@ -342,8 +342,33 @@ static struct mdesc_notifier_client vio_device_notifier = { .node_name = "virtual-device-port", }; +/* We are only interested in domain service ports under the + * "domain-services" node. On control nodes there is another port + * under "openboot" that we should not mess with as aparently that is + * reserved exclusively for OBP use. + */ +static void vio_add_ds(struct mdesc_handle *hp, u64 node) +{ + int found; + u64 a; + + found = 0; + mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) { + u64 target = mdesc_arc_target(hp, a); + const char *name = mdesc_node_name(hp, target); + + if (!strcmp(name, "domain-services")) { + found = 1; + break; + } + } + + if (found) + (void) vio_create_one(hp, node, &root_vdev->dev); +} + static struct mdesc_notifier_client vio_ds_notifier = { - .add = vio_add, + .add = vio_add_ds, .remove = vio_remove, .node_name = "domain-services-port", }; From e2fd58d06f79b10cad22240a6e6fb1c1108aa0ee Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 3 Oct 2007 21:23:40 -0700 Subject: [PATCH 3/6] [SPARC64]: VIO device addition log message level is too high. There is no reason this should be KERN_ERR, KERN_INFO is just fine. Signed-off-by: David S. Miller --- arch/sparc64/kernel/vio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c index 830dc88c19c..0c1ee619d81 100644 --- a/arch/sparc64/kernel/vio.c +++ b/arch/sparc64/kernel/vio.c @@ -292,7 +292,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp, } vdev->dp = dp; - printk(KERN_ERR "VIO: Adding device %s\n", vdev->dev.bus_id); + printk(KERN_INFO "VIO: Adding device %s\n", vdev->dev.bus_id); err = device_register(&vdev->dev); if (err) { From 27097ef9ff219c81a023911c7b0d5e7bc2419177 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 3 Oct 2007 21:37:57 -0700 Subject: [PATCH 4/6] [SPARC64]: Temporary workaround for PCI-E slot on T1000. The PCI-E slot on T1000 connects directly to the Fire PCI chip with no intervening bridges visible in the OBP tree. Unfortunately the bus numbering of the device in that slot is different (2) from the PCI host controller (0), and thus the pci_bus_{read,write}_config_*() calls don't work out. Complicating things further the Fire PCI controller has no config space it responds to either. For now treat this case specially so that devices in the slot work. Longer term we need to perhaps cons up a dummy bridge between the Fire and the PCI-E slot so that the bus hierarchy is complete inside of the kernel and thus the bus numbering all works out right. Signed-off-by: David S. Miller --- arch/sparc64/kernel/pci_common.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/sparc64/kernel/pci_common.c b/arch/sparc64/kernel/pci_common.c index 2f61c4b1259..c76bfbb7da0 100644 --- a/arch/sparc64/kernel/pci_common.c +++ b/arch/sparc64/kernel/pci_common.c @@ -264,7 +264,7 @@ static int sun4v_read_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; - if (bus_dev == pbm->pci_bus && devfn == 0x00) + if (!bus && devfn == 0x00) return pci_host_bridge_read_pci_cfg(bus_dev, devfn, where, size, value); if (config_out_of_range(pbm, bus, devfn, where)) { @@ -300,7 +300,7 @@ static int sun4v_write_pci_cfg(struct pci_bus *bus_dev, unsigned int devfn, unsigned int func = PCI_FUNC(devfn); unsigned long ret; - if (bus_dev == pbm->pci_bus && devfn == 0x00) + if (!bus && devfn == 0x00) return pci_host_bridge_write_pci_cfg(bus_dev, devfn, where, size, value); if (config_out_of_range(pbm, bus, devfn, where)) { From 1177bf9704a4e4e127b961950d75ca6c94fb419b Mon Sep 17 00:00:00 2001 From: Akinobu Mita Date: Thu, 4 Oct 2007 14:55:59 -0700 Subject: [PATCH 5/6] [SPARC64]: check fork_idle() error Check the return value of fork_idle() to catch error. Signed-off-by: Akinobu Mita Signed-off-by: David S. Miller --- arch/sparc64/kernel/smp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index b84c49e3697..c73b7a48b03 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -353,6 +353,8 @@ static int __devinit smp_boot_one_cpu(unsigned int cpu) int timeout, ret; p = fork_idle(cpu); + if (IS_ERR(p)) + return PTR_ERR(p); callin_flag = 0; cpu_new_thread = task_thread_info(p); From b2b27757b6f0e88e30f10c431c763523dd7858ca Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 4 Oct 2007 15:03:35 -0700 Subject: [PATCH 6/6] [SPARC64]: Fix 'niu' complex IRQ probing. They should be computed the same as how we compute them under 'virtual-devices'. Signed-off-by: David S. Miller --- arch/sparc64/kernel/prom.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/sparc64/kernel/prom.c b/arch/sparc64/kernel/prom.c index 0614dff63d7..a246e962e5a 100644 --- a/arch/sparc64/kernel/prom.c +++ b/arch/sparc64/kernel/prom.c @@ -1046,7 +1046,8 @@ static void __init irq_trans_init(struct device_node *dp) if (!strcmp(dp->name, "fhc") && !strcmp(dp->parent->name, "central")) return central_irq_trans_init(dp); - if (!strcmp(dp->name, "virtual-devices")) + if (!strcmp(dp->name, "virtual-devices") || + !strcmp(dp->name, "niu")) return sun4v_vdev_irq_trans_init(dp); }