Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorLinus Torvalds <torvalds@g5.osdl.org>
Fri, 21 Jul 2006 23:44:45 +0000 (16:44 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 21 Jul 2006 23:44:45 +0000 (16:44 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: (21 commits)
  [TIPC]: Removing useless casts
  [IPV4]: Fix nexthop realm dumping for multipath routes
  [DUMMY]: Avoid an oops when dummy_init_one() failed
  [IFB] After ifb_init_one() failed, i is increased. Decrease
  [NET]: Fix reversed error test in netif_tx_trylock
  [MAINTAINERS]: Mark LAPB as Oprhan.
  [NET]: Conversions from kmalloc+memset to k(z|c)alloc.
  [NET]: sun happymeal, little pci cleanup
  [IrDA]: Use alloc_skb() in IrDA TX path
  [I/OAT]: Remove pci_module_init() from Intel I/OAT DMA engine
  [I/OAT]: net/core/user_dma.c should #include <net/netdma.h>
  [SCTP]: ADDIP: Don't use an address as source until it is ASCONF-ACKed
  [SCTP]: Set chunk->data_accepted only if we are going to accept it.
  [SCTP]: Verify all the paths to a peer via heartbeat before using them.
  [SCTP]: Unhash the endpoint in sctp_endpoint_free().
  [SCTP]: Check for NULL arg to sctp_bucket_destroy().
  [PKT_SCHED] netem: Fix slab corruption with netem (2nd try)
  [WAN]: Converted synclink drivers to use netif_carrier_*()
  [WAN]: Cosmetic changes to N2 and C101 drivers
  [WAN]: Added missing netif_dormant_off() to generic HDLC
  ...

24 files changed:
arch/sparc/kernel/devices.c
arch/sparc/kernel/irq.c
arch/sparc/kernel/of_device.c
arch/sparc/kernel/prom.c
arch/sparc/kernel/smp.c
arch/sparc/kernel/sparc_ksyms.c
arch/sparc/kernel/sun4d_smp.c
arch/sparc/kernel/sys_sparc.c
arch/sparc/mm/io-unit.c
arch/sparc/prom/tree.c
arch/sparc64/defconfig
arch/sparc64/kernel/devices.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/prom.c
arch/sparc64/kernel/sparc64_ksyms.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/prom/tree.c
drivers/sbus/sbus.c
drivers/serial/sunsab.c
drivers/serial/sunzilog.c
include/asm-m68k/oplib.h
include/asm-sparc/oplib.h
include/asm-sparc64/openprom.h
include/asm-sparc64/oplib.h

index adba9dfee35e0954326829c3a9c7f7a3318a2268..af90a5f9ab5751a6ee19161221b198c55f9ae8b8 100644 (file)
@@ -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;
        }
index cde73327ca962b906cee82d0b40c6d1c09f63ecb..72f0201051a0bd9fa0cff67c8a3792e5dbf3795c 100644 (file)
@@ -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;
index 5a2faad5d043eb2f4f2fcdb3a8ebf80f484a96fc..97bf87e8cdde56853b86dda4677569be491dff9f 100644 (file)
@@ -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;
index 4b06dcb00ebde6212caafa0ff47989f86ce57f7e..4ca9e5fc97f4d504c12b1dabbfd8ad2bbcf06dde 100644 (file)
@@ -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;
index 6135d4faeeeb62f76abd49ba23b812b38a86f686..e311ade1b490adad0b3188f694ca96d345e82ac6 100644 (file)
@@ -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);
index 5fb987fc3d63ac4e4aad336ac562ae78fd9e7b32..4d441a554d35406da94a99ff9ac20bd3e035986c 100644 (file)
@@ -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);
index b141b7ee6717751751743587cd9072f68390ffc4..ba843f6a28325eeb0189b05af903ac453c5d2631 100644 (file)
@@ -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;
index 0cdfc9d294b45a777b20ec249ed79094862b650f..a41c8a5c20070847a037a8b73ef4e7bcda0a53b4 100644 (file)
@@ -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;
 }
index 42c1c700c0a70b3c7ca86a13c90b22bf0e84fb5f..2bb1309003dd9e6ba316fdf87df308f2bceb34b5 100644 (file)
@@ -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;)
index 2bf03ee8cde5d10b70c55258631d592e5c92aab4..5ec246573a98ee8d8399323b13227c7aac48241f 100644 (file)
@@ -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)
 {
index 38353621069e03ee9f3dfe02ad7ee8a675d637dd..43d9229fca07b39d9a37914b95d5308a05abab81 100644 (file)
@@ -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
index f8ef2f2b9b375a62375b0237a366a3193c4d2ba2..ec10f7edcf868713891e1d1e5f0d1b3ee38df00c 100644 (file)
@@ -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;
index 7064cee290ae15d78b8888429660fc9caba9d399..238bbf6de07d1603b5ab7e225442ef1eabab2177 100644 (file)
@@ -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]);
index c86007a2aa3f251493606edb38a37edea7298b0d..5cc5ab63293fa912188053b8d7a9a360e60fd3e5 100644 (file)
@@ -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
index 237524d87cab9149fe920ef501e6ac4b7f77fbb3..beffc82a1e85a632a27f4b0095c2005b60e478d2 100644 (file)
@@ -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);
index 51c056df528eb2f1f7a1687bfc8a4e172fa2952a..054d0abdb7eef49ad2db9f0a8eea114029dc7a94 100644 (file)
@@ -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;
 }
index 49075abd7cbc2d08394f47df7e71e906ff976fed..500f05e2cfcb655af8ba1deeb0ae224192b560b9 100644 (file)
@@ -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
  */
index 16b59773c0bb9b66828b2887d4d4aa9f4af080fb..935952ef88f19d04127a560a2b2942d5a54c9c56 100644 (file)
@@ -233,7 +233,7 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus)
        sbus->ofdev.node = dp;
        sbus->ofdev.dev.parent = NULL;
        sbus->ofdev.dev.bus = &sbus_bus_type;
-       strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name);
+       sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus);
 
        if (of_device_register(&sbus->ofdev) != 0)
                printk(KERN_DEBUG "sbus: device registration error for %s!\n",
index 979497f108c8678511dd44a7112664d3a8f817d0..dc673e1b6fd9fa1c022abfaea375cc6d8237765c 100644 (file)
@@ -1047,12 +1047,13 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id *
        up = &sunsab_ports[inst * 2];
 
        err = sunsab_init_one(&up[0], op,
-                             sizeof(union sab82532_async_regs),
+                             0,
                              (inst * 2) + 0);
        if (err)
                return err;
 
-       err = sunsab_init_one(&up[1], op, 0,
+       err = sunsab_init_one(&up[1], op,
+                             sizeof(union sab82532_async_regs),
                              (inst * 2) + 1);
        if (err) {
                of_iounmap(up[0].port.membase,
@@ -1117,7 +1118,7 @@ static int __init sunsab_init(void)
        int err;
 
        num_channels = 0;
-       for_each_node_by_name(dp, "su")
+       for_each_node_by_name(dp, "se")
                num_channels += 2;
        for_each_node_by_name(dp, "serial") {
                if (of_device_is_compatible(dp, "sab82532"))
index a1456d9352cba115bb7471ba5a43aacc9c75f0e8..47bc3d57e019e225f533d0a30e7b8bdf8fa71fc2 100644 (file)
@@ -68,9 +68,6 @@ static int num_sunzilog;
 #define NUM_SUNZILOG   num_sunzilog
 #define NUM_CHANNELS   (NUM_SUNZILOG * 2)
 
-#define KEYBOARD_LINE 0x2
-#define MOUSE_LINE    0x3
-
 #define ZS_CLOCK               4915200 /* Zilog input clock rate. */
 #define ZS_CLOCK_DIVISOR       16      /* Divisor this driver uses. */
 
@@ -1225,12 +1222,10 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
 {
        int baud, brg;
 
-       if (channel == KEYBOARD_LINE) {
-               up->flags |= SUNZILOG_FLAG_CONS_KEYB;
+       if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
                up->cflag = B1200 | CS8 | CLOCAL | CREAD;
                baud = 1200;
        } else {
-               up->flags |= SUNZILOG_FLAG_CONS_MOUSE;
                up->cflag = B4800 | CS8 | CLOCAL | CREAD;
                baud = 4800;
        }
@@ -1243,14 +1238,14 @@ static void __init sunzilog_init_kbdms(struct uart_sunzilog_port *up, int channe
 }
 
 #ifdef CONFIG_SERIO
-static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int channel)
+static void __init sunzilog_register_serio(struct uart_sunzilog_port *up)
 {
        struct serio *serio = &up->serio;
 
        serio->port_data = up;
 
        serio->id.type = SERIO_RS232;
-       if (channel == KEYBOARD_LINE) {
+       if (up->flags & SUNZILOG_FLAG_CONS_KEYB) {
                serio->id.proto = SERIO_SUNKBD;
                strlcpy(serio->name, "zskbd", sizeof(serio->name));
        } else {
@@ -1259,7 +1254,8 @@ static void __init sunzilog_register_serio(struct uart_sunzilog_port *up, int ch
                strlcpy(serio->name, "zsms", sizeof(serio->name));
        }
        strlcpy(serio->phys,
-               (channel == KEYBOARD_LINE ? "zs/serio0" : "zs/serio1"),
+               ((up->flags & SUNZILOG_FLAG_CONS_KEYB) ?
+                "zs/serio0" : "zs/serio1"),
                sizeof(serio->phys));
 
        serio->write = sunzilog_serio_write;
@@ -1286,8 +1282,8 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
                (void) read_zsreg(channel, R0);
        }
 
-       if (up->port.line == KEYBOARD_LINE ||
-           up->port.line == MOUSE_LINE) {
+       if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
+                        SUNZILOG_FLAG_CONS_MOUSE)) {
                sunzilog_init_kbdms(up, up->port.line);
                up->curregs[R9] |= (NV | MIE);
                write_zsreg(channel, R9, up->curregs[R9]);
@@ -1313,37 +1309,26 @@ static void __init sunzilog_init_hw(struct uart_sunzilog_port *up)
        spin_unlock_irqrestore(&up->port.lock, flags);
 
 #ifdef CONFIG_SERIO
-       if (up->port.line == KEYBOARD_LINE || up->port.line == MOUSE_LINE)
-               sunzilog_register_serio(up, up->port.line);
+       if (up->flags & (SUNZILOG_FLAG_CONS_KEYB |
+                        SUNZILOG_FLAG_CONS_MOUSE))
+               sunzilog_register_serio(up);
 #endif
 }
 
-static int __devinit zs_get_instance(struct device_node *dp)
-{
-       int ret;
-
-       ret = of_getintprop_default(dp, "slave", -1);
-       if (ret != -1)
-               return ret;
-
-       if (of_find_property(dp, "keyboard", NULL))
-               ret = 1;
-       else
-               ret = 0;
-
-       return ret;
-}
-
 static int zilog_irq = -1;
 
-static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *match)
+static int __devinit zs_probe(struct of_device *op, const struct of_device_id *match)
 {
-       struct of_device *op = to_of_device(&dev->dev);
+       static int inst;
        struct uart_sunzilog_port *up;
        struct zilog_layout __iomem *rp;
-       int inst = zs_get_instance(dev->node);
+       int keyboard_mouse;
        int err;
 
+       keyboard_mouse = 0;
+       if (of_find_property(op->node, "keyboard", NULL))
+               keyboard_mouse = 1;
+
        sunzilog_chip_regs[inst] = of_ioremap(&op->resource[0], 0,
                                              sizeof(struct zilog_layout),
                                              "zs");
@@ -1352,16 +1337,8 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
 
        rp = sunzilog_chip_regs[inst];
 
-       if (zilog_irq == -1) {
+       if (zilog_irq == -1)
                zilog_irq = op->irqs[0];
-               err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
-                                 "zs", sunzilog_irq_chain);
-               if (err) {
-                       of_iounmap(rp, sizeof(struct zilog_layout));
-
-                       return err;
-               }
-       }
 
        up = &sunzilog_port_table[inst * 2];
 
@@ -1378,7 +1355,7 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
        up[0].port.line = (inst * 2) + 0;
        up[0].port.dev = &op->dev;
        up[0].flags |= SUNZILOG_FLAG_IS_CHANNEL_A;
-       if (inst == 1)
+       if (keyboard_mouse)
                up[0].flags |= SUNZILOG_FLAG_CONS_KEYB;
        sunzilog_init_hw(&up[0]);
 
@@ -1395,11 +1372,11 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
        up[1].port.line = (inst * 2) + 1;
        up[1].port.dev = &op->dev;
        up[1].flags |= 0;
-       if (inst == 1)
+       if (keyboard_mouse)
                up[1].flags |= SUNZILOG_FLAG_CONS_MOUSE;
        sunzilog_init_hw(&up[1]);
 
-       if (inst != 1) {
+       if (!keyboard_mouse) {
                err = uart_add_one_port(&sunzilog_reg, &up[0].port);
                if (err) {
                        of_iounmap(rp, sizeof(struct zilog_layout));
@@ -1411,9 +1388,18 @@ static int __devinit zs_probe(struct of_device *dev, const struct of_device_id *
                        of_iounmap(rp, sizeof(struct zilog_layout));
                        return err;
                }
+       } else {
+               printk(KERN_INFO "%s: Keyboard at MMIO %lx (irq = %d) "
+                      "is a zs\n",
+                      op->dev.bus_id, up[0].port.mapbase, op->irqs[0]);
+               printk(KERN_INFO "%s: Mouse at MMIO %lx (irq = %d) "
+                      "is a zs\n",
+                      op->dev.bus_id, up[1].port.mapbase, op->irqs[0]);
        }
 
-       dev_set_drvdata(&dev->dev, &up[0]);
+       dev_set_drvdata(&op->dev, &up[0]);
+
+       inst++;
 
        return 0;
 }
@@ -1462,36 +1448,65 @@ static struct of_platform_driver zs_driver = {
 static int __init sunzilog_init(void)
 {
        struct device_node *dp;
-       int err;
+       int err, uart_count;
+       int num_keybms;
 
        NUM_SUNZILOG = 0;
-       for_each_node_by_name(dp, "zs")
+       num_keybms = 0;
+       for_each_node_by_name(dp, "zs") {
                NUM_SUNZILOG++;
+               if (of_find_property(dp, "keyboard", NULL))
+                       num_keybms++;
+       }
 
+       uart_count = 0;
        if (NUM_SUNZILOG) {
                int uart_count;
 
                err = sunzilog_alloc_tables();
                if (err)
-                       return err;
+                       goto out;
 
-               /* Subtract 1 for keyboard, 1 for mouse.  */
-               uart_count = (NUM_SUNZILOG * 2) - 2;
+               uart_count = (NUM_SUNZILOG * 2) - (2 * num_keybms);
 
                sunzilog_reg.nr = uart_count;
                sunzilog_reg.minor = sunserial_current_minor;
                err = uart_register_driver(&sunzilog_reg);
-               if (err) {
-                       sunzilog_free_tables();
-                       return err;
-               }
+               if (err)
+                       goto out_free_tables;
+
                sunzilog_reg.tty_driver->name_base = sunzilog_reg.minor - 64;
                sunzilog_reg.cons = SUNZILOG_CONSOLE();
 
                sunserial_current_minor += uart_count;
        }
 
-       return of_register_driver(&zs_driver, &of_bus_type);
+       err = of_register_driver(&zs_driver, &of_bus_type);
+       if (err)
+               goto out_unregister_uart;
+
+       if (zilog_irq != -1) {
+               err = request_irq(zilog_irq, sunzilog_interrupt, IRQF_SHARED,
+                                 "zs", sunzilog_irq_chain);
+               if (err)
+                       goto out_unregister_driver;
+       }
+
+out:
+       return err;
+
+out_unregister_driver:
+       of_unregister_driver(&zs_driver);
+
+out_unregister_uart:
+       if (NUM_SUNZILOG) {
+               uart_unregister_driver(&sunzilog_reg);
+               sunzilog_reg.cons = NULL;
+       }
+
+out_free_tables:
+       sunzilog_free_tables();
+       goto out;
 }
 
 static void __exit sunzilog_exit(void)
index c3594f473ef731ad249e460c0bd01d13c51b96e5..06caa2d084519dac6caa1702ce073a2331948f91 100644 (file)
@@ -244,11 +244,6 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
 /* Does the passed node have the given "name"? YES=1 NO=0 */
 extern int prom_nodematch(int thisnode, char *name);
 
-/* Puts in buffer a prom name in the form name@x,y or name (x for which_io
- * and y for first regs phys address
- */
-extern int prom_getname(int node, char *buf, int buflen);
-
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
index f283f8aaf6a95eb230f0c675441ac35d8e57daef..91691e52c058340047fef1eb08f4cb43b49376ee 100644 (file)
@@ -267,11 +267,6 @@ extern void prom_getstring(int node, char *prop, char *buf, int bufsize);
 /* Does the passed node have the given "name"? YES=1 NO=0 */
 extern int prom_nodematch(int thisnode, char *name);
 
-/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
- * and y for first regs phys address
- */
-extern int prom_getname(int node, char *buf, int buflen);
-
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */
index b4959d2b0d991712cc4114644804d17a9152061f..e01b80559c93f164c8ec056aa624bffae6104038 100644 (file)
@@ -175,7 +175,7 @@ struct linux_nodeops {
 };
 
 /* More fun PROM structures for device probing. */
-#define PROMREG_MAX     16
+#define PROMREG_MAX     24
 #define PROMVADDR_MAX   16
 #define PROMINTR_MAX    15
 
index a68b0bb05958d4bd8c29b7fdee9a8784b6802723..6a0da3b1695c0c913f484bf88d90bf7378c9594a 100644 (file)
@@ -287,11 +287,6 @@ extern void prom_getstring(int node, const char *prop, char *buf, int bufsize);
 /* Does the passed node have the given "name"? YES=1 NO=0 */
 extern int prom_nodematch(int thisnode, const char *name);
 
-/* Puts in buffer a prom name in the form name@x,y or name (x for which_io 
- * and y for first regs phys address
- */
-extern int prom_getname(int node, char *buf, int buflen);
-
 /* Search all siblings starting at the passed node for "name" matching
  * the given string.  Returns the node on success, zero on failure.
  */