diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/Kconfig 110-ppc64_update/arch/ppc64/Kconfig --- 107-kgdb_gdb6_patches/arch/ppc64/Kconfig Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/Kconfig Mon Feb 9 10:06:05 2004 @@ -251,54 +251,10 @@ config CMDLINE endmenu -source "drivers/base/Kconfig" - -source "drivers/mtd/Kconfig" - -source "drivers/parport/Kconfig" - -source "drivers/pnp/Kconfig" - -source "drivers/block/Kconfig" - -source "drivers/ide/Kconfig" - -source "drivers/scsi/Kconfig" - -source "drivers/md/Kconfig" - -source "drivers/message/fusion/Kconfig" - -source "drivers/ieee1394/Kconfig" - -source "drivers/message/i2o/Kconfig" - -source "net/Kconfig" - -source "drivers/isdn/Kconfig" - -source "drivers/telephony/Kconfig" - -# -# input before char - char/joystick depends on it. As does USB. -# -source "drivers/input/Kconfig" - -source "drivers/char/Kconfig" - -source "drivers/i2c/Kconfig" - -source "drivers/media/Kconfig" +source "drivers/Kconfig" source "fs/Kconfig" -source "drivers/video/Kconfig" - -source "sound/Kconfig" - -source "drivers/usb/Kconfig" - - menu "iSeries device drivers" depends on PPC_ISERIES @@ -401,6 +357,13 @@ config DEBUG_INFO debugging info resulting in a larger kernel image. Say Y here only if you plan to use gdb to debug the kernel. If you don't debug the kernel, you can say N. + +config DEBUG_SPINLOCK_SLEEP + bool "Sleep-inside-spinlock checking" + depends on DEBUG_KERNEL + help + If you say Y here, various routines which may sleep will become very + noisy if they are called with a spinlock held. endmenu diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/Makefile 110-ppc64_update/arch/ppc64/kernel/Makefile --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/Makefile Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/Makefile Mon Feb 9 10:06:05 2004 @@ -39,6 +39,6 @@ obj-$(CONFIG_PPC_RTAS) += rtas-proc.o obj-$(CONFIG_SCANLOG) += scanlog.o obj-$(CONFIG_VIOPATH) += viopath.o obj-$(CONFIG_LPARCFG) += lparcfg.o - +obj-$(CONFIG_HVC_CONSOLE) += hvconsole.o CFLAGS_ioctl32.o += -Ifs/ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/head.S 110-ppc64_update/arch/ppc64/kernel/head.S --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/head.S Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/head.S Mon Feb 9 10:06:05 2004 @@ -52,7 +52,7 @@ /* * hcall interface to pSeries LPAR */ -#define HSC .long 0x44000022 +#define HVSC .long 0x44000022 #define H_SET_ASR 0x30 /* @@ -1743,7 +1743,7 @@ _GLOBAL(__secondary_start) cmpwi r3,0x34 /* Pulsar */ bne 98f 97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ - HSC /* Invoking hcall */ + HVSC /* Invoking hcall */ b 99f 98: /* !(rpa hypervisor) || !(star) */ mtasr r4 /* set the stab location */ @@ -1912,7 +1912,7 @@ _STATIC(start_here_pSeries) cmpwi r3,0x34 /* Pulsar */ bne 98f 97: li r3,H_SET_ASR /* hcall = H_SET_ASR */ - HSC /* Invoking hcall */ + HVSC /* Invoking hcall */ b 99f 98: /* !(rpa hypervisor) || !(star) */ mtasr r4 /* set the stab location */ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/hvconsole.c 110-ppc64_update/arch/ppc64/kernel/hvconsole.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/hvconsole.c Wed Dec 31 16:00:00 1969 +++ 110-ppc64_update/arch/ppc64/kernel/hvconsole.c Mon Feb 9 10:06:05 2004 @@ -0,0 +1,88 @@ +/* + * hvconsole.c + * Copyright (C) 2004 Hollis Blanchard, IBM Corporation + * + * LPAR console support. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include + +int hvc_get_chars(int index, char *buf, int count) +{ + unsigned long got; + + if (plpar_hcall(H_GET_TERM_CHAR, index, 0, 0, 0, &got, + (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) { + /* + * Work around a HV bug where it gives us a null + * after every \r. -- paulus + */ + if (got > 0) { + int i; + for (i = 1; i < got; ++i) { + if (buf[i] == 0 && buf[i-1] == '\r') { + --got; + if (i < got) + memmove(&buf[i], &buf[i+1], + got - i); + } + } + } + return got; + } + return 0; +} + +int hvc_put_chars(int index, const char *buf, int count) +{ + unsigned long *lbuf = (unsigned long *) buf; + long ret; + + ret = plpar_hcall_norets(H_PUT_TERM_CHAR, index, count, lbuf[0], + lbuf[1]); + if (ret == H_Success) + return count; + if (ret == H_Busy) + return 0; + return -1; +} + +/* return the number of client vterms present */ +/* XXX this requires an interface change to handle multiple discontiguous + * vterms */ +int hvc_count(int *start_termno) +{ + struct device_node *vty; + int num_found = 0; + + /* consider only the first vty node. + * we should _always_ be able to find one. */ + vty = of_find_node_by_name(NULL, "vty"); + if (vty && device_is_compatible(vty, "hvterm1")) { + u32 *termno = (u32 *)get_property(vty, "reg", 0); + + if (termno && start_termno) + *start_termno = *termno; + num_found = 1; + of_node_put(vty); + } + + return num_found; +} diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/iSeries_htab.c 110-ppc64_update/arch/ppc64/kernel/iSeries_htab.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/iSeries_htab.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/iSeries_htab.c Mon Feb 9 10:06:05 2004 @@ -109,6 +109,12 @@ static long iSeries_hpte_remove(unsigned return -1; } +/* + * The HyperVisor expects the "flags" argument in this form: + * bits 0..59 : reserved + * bit 60 : N + * bits 61..63 : PP2,PP1,PP0 + */ static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp, unsigned long va, int large, int local) { @@ -117,7 +123,7 @@ static long iSeries_hpte_updatepp(unsign HvCallHpt_get(&hpte, slot); if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) { - HvCallHpt_setPp(slot, newpp); + HvCallHpt_setPp(slot, (newpp & 0x3) | ((newpp & 0x4) << 1)); return 0; } return -1; diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/idle.c 110-ppc64_update/arch/ppc64/kernel/idle.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/idle.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/idle.c Mon Feb 9 10:06:05 2004 @@ -161,7 +161,7 @@ int dedicated_idle(void) struct paca_struct *lpaca = get_paca(), *ppaca; unsigned long start_snooze; - ppaca = &paca[(lpaca->xPacaIndex) ^ 1]; + ppaca = &paca[smp_processor_id() ^ 1]; while (1) { /* Indicate to the HV that we are idle. Now would be diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/lparcfg.c 110-ppc64_update/arch/ppc64/kernel/lparcfg.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/lparcfg.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/lparcfg.c Mon Feb 9 10:06:05 2004 @@ -331,7 +331,7 @@ static int lparcfg_data(unsigned char *b if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { system_potential_processors = get_splpar_potential_characteristics(); n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, - "system_active_processors=%d\n", + "system_active_processors=%ld\n", (h_resource >> 2*8) & 0xffff); n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, "system_potential_processors=%d\n", @@ -373,16 +373,16 @@ static int lparcfg_data(unsigned char *b if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) { n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, - "pool=%d\n", (h_aggregation >> 0*8)&0xffff); + "pool=%ld\n", (h_aggregation >> 0*8)&0xffff); n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, - "pool_capacity=%d\n", (h_resource >> 3*8) &0xffff); + "pool_capacity=%ld\n", (h_resource >> 3*8) &0xffff); n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, - "group=%d\n", (h_aggregation >> 2*8)&0xffff); + "group=%ld\n", (h_aggregation >> 2*8)&0xffff); n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, - "capped=%d\n", (h_resource >> 6*8)&0x40); + "capped=%ld\n", (h_resource >> 6*8)&0x40); n += snprintf(buf+n, LPARCFG_BUFF_SIZE - n, "capacity_weight=%d\n", (int)(h_resource>>5*8)&0xFF); diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/pSeries_hvCall.S 110-ppc64_update/arch/ppc64/kernel/pSeries_hvCall.S --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/pSeries_hvCall.S Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/pSeries_hvCall.S Mon Feb 9 10:06:05 2004 @@ -22,7 +22,7 @@ /* * hcall interface to pSeries LPAR */ -#define HSC .long 0x44000022 +#define HVSC .long 0x44000022 /* long plpar_hcall(unsigned long opcode, R3 unsigned long arg1, R4 @@ -44,7 +44,7 @@ _GLOBAL(plpar_hcall) std r9,-16(r1) std r10,-24(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ ld r10,-8(r1) /* Fetch r4-r7 ret args. */ std r4,0(r10) @@ -63,7 +63,7 @@ _GLOBAL(plpar_hcall) _GLOBAL(plpar_hcall_norets) mfcr r0 std r0,-8(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ ld r0,-8(r1) mtcrf 0xff,r0 blr /* return r3 = status */ @@ -94,7 +94,7 @@ _GLOBAL(plpar_hcall_8arg_2ret) std r12,-8(r1) /* Save out ptr */ - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ ld r10,-8(r1) /* Fetch r4 ret arg */ std r4,0(r10) @@ -126,7 +126,7 @@ _GLOBAL(plpar_hcall_4out) std r10,16(r1) std r14,8(r1) - HSC /* invoke the hypervisor */ + HVSC /* invoke the hypervisor */ ld r14,32(r1) /* Fetch r4-r7 ret args. */ std r4,0(r14) diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/pSeries_lpar.c 110-ppc64_update/arch/ppc64/kernel/pSeries_lpar.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/pSeries_lpar.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/pSeries_lpar.c Mon Feb 9 10:06:05 2004 @@ -313,69 +313,6 @@ void pSeriesLP_init_early(void) } } -int hvc_get_chars(int index, char *buf, int count) -{ - unsigned long got; - - if (plpar_hcall(H_GET_TERM_CHAR, index, 0, 0, 0, &got, - (unsigned long *)buf, (unsigned long *)buf+1) == H_Success) { - /* - * Work around a HV bug where it gives us a null - * after every \r. -- paulus - */ - if (got > 0) { - int i; - for (i = 1; i < got; ++i) { - if (buf[i] == 0 && buf[i-1] == '\r') { - --got; - if (i < got) - memmove(&buf[i], &buf[i+1], - got - i); - } - } - } - return got; - } - return 0; -} - -int hvc_put_chars(int index, const char *buf, int count) -{ - unsigned long *lbuf = (unsigned long *) buf; - long ret; - - ret = plpar_hcall_norets(H_PUT_TERM_CHAR, index, count, lbuf[0], - lbuf[1]); - if (ret == H_Success) - return count; - if (ret == H_Busy) - return 0; - return -1; -} - -/* return the number of client vterms present */ -/* XXX this requires an interface change to handle multiple discontiguous - * vterms */ -int hvc_count(int *start_termno) -{ - struct device_node *vty; - int num_found = 0; - - /* consider only the first vty node. - * we should _always_ be able to find one. */ - vty = of_find_node_by_name(NULL, "vty"); - if (vty && device_is_compatible(vty, "hvterm1")) { - u32 *termno = (u32 *)get_property(vty, "reg", 0); - - if (termno && start_termno) - *start_termno = *termno; - num_found = 1; - of_node_put(vty); - } - - return num_found; -} - long pSeries_lpar_hpte_insert(unsigned long hpte_group, unsigned long va, unsigned long prpn, int secondary, unsigned long hpteflags, diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/proc_ppc64.c 110-ppc64_update/arch/ppc64/kernel/proc_ppc64.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/proc_ppc64.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/proc_ppc64.c Mon Feb 9 10:06:05 2004 @@ -268,12 +268,10 @@ out: static int do_remove_node(char *buf) { struct device_node *node; - int rv = 0; + int rv = -ENODEV; if ((node = of_find_node_by_path(buf))) - of_remove_node(node); - else - rv = -ENODEV; + rv = of_remove_node(node); of_node_put(node); return rv; diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/prom.c 110-ppc64_update/arch/ppc64/kernel/prom.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/prom.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/prom.c Mon Feb 9 10:06:05 2004 @@ -2507,29 +2507,48 @@ int of_add_node(const char *path, struct /* * Remove an OF device node from the system. + * Caller should have already "gotten" np. */ int of_remove_node(struct device_node *np) { struct device_node *parent, *child; parent = of_get_parent(np); - child = of_get_next_child(np, NULL); - if (child && !child->child && !child->sibling) { - /* For now, we will allow removal of a - * node with one and only one child, so - * that we can support removing a slot with - * an IOA in it. More general support for - * subtree removal to be implemented later, if - * necessary. - */ - of_remove_node(child); - } - else if (child) { - of_node_put(child); - of_node_put(parent); + + if (!parent) return -EINVAL; + + /* Make sure we are not recursively removing + * more than one level of nodes. We need to + * allow this so we can remove a slot containing + * an IOA. + */ + for (child = of_get_next_child(np, NULL); + child != NULL; + child = of_get_next_child(np, child)) { + struct device_node *grandchild; + + if ((grandchild = of_get_next_child(child, NULL))) { + /* Too deep */ + of_node_put(grandchild); + of_node_put(child); + return -EBUSY; + } + } + + /* Now that we're reasonably sure that we won't + * overflow our stack, remove any children of np. + */ + for (child = of_get_next_child(np, NULL); + child != NULL; + child = of_get_next_child(np, child)) { + int rc; + + if ((rc = of_remove_node(child))) { + of_node_put(child); + return rc; + } } - of_node_put(child); write_lock(&devtree_lock); OF_MARK_STALE(np); @@ -2545,8 +2564,8 @@ int of_remove_node(struct device_node *n prev->allnext = np->allnext; } - if (np->parent->child == np) - np->parent->child = np->sibling; + if (parent->child == np) + parent->child = np->sibling; else { struct device_node *prevsib; for (prevsib = np->parent->child; diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/rtas-proc.c 110-ppc64_update/arch/ppc64/kernel/rtas-proc.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/rtas-proc.c Wed Feb 4 23:03:17 2004 +++ 110-ppc64_update/arch/ppc64/kernel/rtas-proc.c Mon Feb 9 10:06:05 2004 @@ -285,13 +285,13 @@ static ssize_t ppc_rtas_poweron_read(str size_t count, loff_t *ppos) { char stkbuf[40]; /* its small, its on stack */ - int n; + int n, sn; if (power_on_time == 0) n = snprintf(stkbuf, 40, "Power on time not set\n"); else n = snprintf(stkbuf, 40, "%lu\n", power_on_time); - int sn = strlen (stkbuf) +1; + sn = strlen (stkbuf) +1; if (*ppos >= sn) return 0; if (n > sn - *ppos) @@ -331,18 +331,19 @@ static ssize_t ppc_rtas_progress_write(s static ssize_t ppc_rtas_progress_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n = 0; + int sn, n = 0; + char *tmpbuf; if (progress_led == NULL) return 0; - char * tmpbuf = kmalloc (MAX_LINELENGTH, GFP_KERNEL); + tmpbuf = kmalloc (MAX_LINELENGTH, GFP_KERNEL); if (!tmpbuf) { printk(KERN_ERR "error: kmalloc failed\n"); return -ENOMEM; } n = sprintf (tmpbuf, "%s\n", progress_led); - int sn = strlen (tmpbuf) +1; + sn = strlen (tmpbuf) +1; if (*ppos >= sn) { kfree (tmpbuf); return 0; @@ -398,15 +399,14 @@ static ssize_t ppc_rtas_clock_read(struc { unsigned int year, mon, day, hour, min, sec; unsigned long *ret = kmalloc(4*8, GFP_KERNEL); - int n, error; + int n, sn, error; + char stkbuf[40]; /* its small, its on stack */ error = rtas_call(rtas_token("get-time-of-day"), 0, 8, ret); year = ret[0]; mon = ret[1]; day = ret[2]; hour = ret[3]; min = ret[4]; sec = ret[5]; - char stkbuf[40]; /* its small, its on stack */ - if (error != 0){ printk(KERN_WARNING "error: reading the clock returned: %s\n", ppc_rtas_process_error(error)); @@ -416,7 +416,7 @@ static ssize_t ppc_rtas_clock_read(struc } kfree(ret); - int sn = strlen (stkbuf) +1; + sn = strlen (stkbuf) +1; if (*ppos >= sn) return 0; if (n > sn - *ppos) @@ -860,11 +860,12 @@ static ssize_t ppc_rtas_tone_freq_write( static ssize_t ppc_rtas_tone_freq_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n; + int n, sn; char stkbuf[40]; /* its small, its on stack */ + n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_frequency); - int sn = strlen (stkbuf) +1; + sn = strlen (stkbuf) +1; if (*ppos >= sn) return 0; if (n > sn - *ppos) @@ -913,11 +914,12 @@ static ssize_t ppc_rtas_tone_volume_writ static ssize_t ppc_rtas_tone_volume_read(struct file * file, char * buf, size_t count, loff_t *ppos) { - int n; + int n, sn; char stkbuf[40]; /* its small, its on stack */ + n = snprintf(stkbuf, 40, "%lu\n", rtas_tone_volume); - int sn = strlen (stkbuf) +1; + sn = strlen (stkbuf) +1; if (*ppos >= sn) return 0; if (n > sn - *ppos) diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/setup.c 110-ppc64_update/arch/ppc64/kernel/setup.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/setup.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/kernel/setup.c Mon Feb 9 10:06:05 2004 @@ -283,6 +283,10 @@ EXPORT_SYMBOL(machine_halt); unsigned long ppc_proc_freq; unsigned long ppc_tb_freq; +#ifdef CONFIG_SMP +DEFINE_PER_CPU(unsigned int, pvr); +#endif + static int show_cpuinfo(struct seq_file *m, void *v) { unsigned long cpu_id = (unsigned long)v - 1; @@ -302,7 +306,7 @@ static int show_cpuinfo(struct seq_file return 0; #ifdef CONFIG_SMP - pvr = paca[cpu_id].pvr; + pvr = per_cpu(pvr, cpu_id); #else pvr = _get_PVR(); #endif diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/smp.c 110-ppc64_update/arch/ppc64/kernel/smp.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/smp.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/kernel/smp.c Mon Feb 9 10:06:05 2004 @@ -575,9 +575,11 @@ extern struct gettimeofday_struct do_gto struct thread_info *current_set[NR_CPUS]; +DECLARE_PER_CPU(unsigned int, pvr); + static void __devinit smp_store_cpu_info(int id) { - paca[id].pvr = _get_PVR(); + per_cpu(pvr, id) = _get_PVR(); } void __init smp_prepare_cpus(unsigned int max_cpus) diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/time.c 110-ppc64_update/arch/ppc64/kernel/time.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/time.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/kernel/time.c Mon Feb 9 10:06:05 2004 @@ -267,7 +267,7 @@ int timer_interrupt(struct pt_regs * reg int next_dec; unsigned long cur_tb; struct paca_struct *lpaca = get_paca(); - unsigned long cpu = lpaca->xPacaIndex; + unsigned long cpu = smp_processor_id(); irq_enter(); diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/kernel/vio.c 110-ppc64_update/arch/ppc64/kernel/vio.c --- 107-kgdb_gdb6_patches/arch/ppc64/kernel/vio.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/kernel/vio.c Mon Feb 9 10:06:05 2004 @@ -4,6 +4,7 @@ * Copyright (c) 2003 IBM Corp. * Dave Engebretsen engebret@us.ibm.com * Santiago Leon santil@us.ibm.com + * Hollis Blanchard * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -16,14 +17,16 @@ #include #include #include +#include +#include #include #include #include #include #include #include -#include -#include "open_pic.h" /* temporary, until we merge large irq support */ + +#define DBGENTER() pr_debug("%s entered\n", __FUNCTION__) extern struct TceTable *build_tce_table(struct TceTable *tbl); @@ -32,83 +35,74 @@ extern dma_addr_t get_tces(struct TceTab extern void tce_free(struct TceTable *tbl, dma_addr_t dma_addr, unsigned order, unsigned num_pages); +static int vio_num_address_cells; +static struct vio_dev *vio_bus_device; /* fake "parent" device */ -static struct vio_bus vio_bus; -static LIST_HEAD(registered_vio_drivers); -int vio_num_address_cells; -EXPORT_SYMBOL(vio_num_address_cells); - -/* TODO: - * really fit into driver model (see include/linux/device.h) - * locking around list accesses - */ +/* convert from struct device to struct vio_dev and pass to driver. + * dev->driver has already been set by generic code because vio_bus_match + * succeeded. */ +static int vio_bus_probe(struct device *dev) +{ + struct vio_dev *viodev = to_vio_dev(dev); + struct vio_driver *viodrv = to_vio_driver(dev->driver); + const struct vio_device_id *id; + int error = -ENODEV; + + DBGENTER(); + + if (!viodrv->probe) + return error; + + id = vio_match_device(viodrv->id_table, viodev); + if (id) { + error = viodrv->probe(viodev, id); + } + + return error; +} + +/* convert from struct device to struct vio_dev and pass to driver. */ +static int vio_bus_remove(struct device *dev) +{ + struct vio_dev *viodev = to_vio_dev(dev); + struct vio_driver *viodrv = to_vio_driver(dev->driver); + + DBGENTER(); + + if (viodrv->remove) { + return viodrv->remove(viodev); + } + + /* driver can't remove */ + return 1; +} /** * vio_register_driver: - Register a new vio driver * @drv: The vio_driver structure to be registered. - * - * Adds the driver structure to the list of registered drivers - * Returns the number of vio devices which were claimed by the driver - * during registration. The driver remains registered even if the - * return value is zero. */ -int vio_register_driver(struct vio_driver *drv) +int vio_register_driver(struct vio_driver *viodrv) { - int count = 0; - struct vio_dev *dev; - - printk(KERN_DEBUG "%s: driver %s/%s registering\n", __FUNCTION__, - drv->id_table[0].type, drv->id_table[0].type); - - /* find matching devices not already claimed by other drivers and pass - * them to probe() */ - list_for_each_entry(dev, &vio_bus.devices, devices_list) { - const struct vio_device_id* id; - - if (dev->driver) - continue; /* this device is already owned */ - - id = vio_match_device(drv->id_table, dev); - if (drv && id) { - if (0 == drv->probe(dev, id)) { - printk(KERN_DEBUG " took device %p\n", dev); - dev->driver = drv; - count++; - } - } - } + printk(KERN_DEBUG "%s: driver %s registering\n", __FUNCTION__, + viodrv->name); - list_add_tail(&drv->node, ®istered_vio_drivers); + /* fill in 'struct driver' fields */ + viodrv->driver.name = viodrv->name; + viodrv->driver.bus = &vio_bus_type; + viodrv->driver.probe = vio_bus_probe; + viodrv->driver.remove = vio_bus_remove; - return count; + return driver_register(&viodrv->driver); } EXPORT_SYMBOL(vio_register_driver); /** * vio_unregister_driver - Remove registration of vio driver. * @driver: The vio_driver struct to be removed form registration - * - * Searches for devices that are assigned to the driver and calls - * driver->remove() for each one. Removes the driver from the list - * of registered drivers. Returns the number of devices that were - * assigned to that driver. */ -int vio_unregister_driver(struct vio_driver *driver) +void vio_unregister_driver(struct vio_driver *viodrv) { - struct vio_dev *dev; - int devices_found = 0; - - list_for_each_entry(dev, &vio_bus.devices, devices_list) { - if (dev->driver == driver) { - driver->remove(dev); - dev->driver = NULL; - devices_found++; - } - } - - list_del(&driver->node); - - return devices_found; + driver_unregister(&viodrv->driver); } EXPORT_SYMBOL(vio_unregister_driver); @@ -121,9 +115,11 @@ EXPORT_SYMBOL(vio_unregister_driver); * system is in its list of supported devices. Returns the matching * vio_device_id structure or NULL if there is no match. */ -const struct vio_device_id * -vio_match_device(const struct vio_device_id *ids, const struct vio_dev *dev) +const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, + const struct vio_dev *dev) { + DBGENTER(); + while (ids->type) { if ((strncmp(dev->archdata->type, ids->type, strlen(ids->type)) == 0) && device_is_compatible((struct device_node*)dev->archdata, ids->compat)) @@ -136,18 +132,33 @@ vio_match_device(const struct vio_device /** * vio_bus_init: - Initialize the virtual IO bus */ -int __init -vio_bus_init(void) +static int __init vio_bus_init(void) { - struct device_node *node_vroot, *node_vdev; + struct device_node *node_vroot, *of_node; + int err; - INIT_LIST_HEAD(&vio_bus.devices); + err = bus_register(&vio_bus_type); + if (err) { + printk(KERN_ERR "failed to register VIO bus\n"); + return err; + } + + /* the fake parent of all vio devices, just to give us a nice directory */ + vio_bus_device = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); + if (!vio_bus_device) { + return 1; + } + memset(vio_bus_device, 0, sizeof(struct vio_dev)); + strcpy(vio_bus_device->dev.bus_id, "vdevice"); + + err = device_register(&vio_bus_device->dev); + if (err) { + printk(KERN_WARNING "%s: device_register returned %i\n", __FUNCTION__, + err); + kfree(vio_bus_device); + return err; + } - /* - * Create device node entries for each virtual device - * identified in the device tree. - * Functionally takes the place of pci_scan_bus - */ node_vroot = find_devices("vdevice"); if ((node_vroot == NULL) || (node_vroot->child == NULL)) { printk(KERN_INFO "VIO: missing or empty /vdevice node; no virtual IO" @@ -157,12 +168,16 @@ vio_bus_init(void) vio_num_address_cells = prom_n_addr_cells(node_vroot->child); - for (node_vdev = node_vroot->child; - node_vdev != NULL; - node_vdev = node_vdev->sibling) { - printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, node_vdev); + /* + * Create struct vio_devices for each virtual device in the device tree. + * Drivers will associate with them later. + */ + for (of_node = node_vroot->child; + of_node != NULL; + of_node = of_node->sibling) { + printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node); - vio_register_device(node_vdev); + vio_register_device(of_node); } return 0; @@ -171,98 +186,91 @@ vio_bus_init(void) __initcall(vio_bus_init); -/** - * vio_probe_device - attach dev to appropriate driver - * @dev: device to find a driver for - * - * Walks the list of registered VIO drivers looking for one to take this - * device. - * - * Returns a pointer to the matched driver or NULL if driver is not - * found. - */ -struct vio_driver * __devinit vio_probe_device(struct vio_dev* dev) +/* vio_dev refcount hit 0 */ +static void __devinit vio_dev_release(struct device *dev) { - struct vio_driver *driver; - - list_for_each_entry(driver, ®istered_vio_drivers, node) { - const struct vio_device_id* id; + struct vio_dev *viodev = to_vio_dev(dev); - id = vio_match_device(driver->id_table, dev); - if (id && (0 < driver->probe(dev, id))) { - printk(KERN_DEBUG "%s: driver %s/%s took device %p\n", - __FUNCTION__, id->type, id->compat, dev); - dev->driver = driver; - return driver; - } - } + DBGENTER(); - printk(KERN_DEBUG "%s: device %p found no driver\n", __FUNCTION__, dev); - return NULL; + /* XXX free TCE table */ + of_node_put(viodev->archdata); + kfree(viodev); } /** * vio_register_device: - Register a new vio device. - * @archdata: The OF node for this device. + * @of_node: The OF node for this device. * * Creates and initializes a vio_dev structure from the data in - * node_vdev (archdata) and adds it to the list of virtual devices. + * of_node (archdata) and adds it to the list of virtual devices. * Returns a pointer to the created vio_dev or NULL if node has * NULL device_type or compatible fields. */ -struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev) +struct vio_dev * __devinit vio_register_device(struct device_node *of_node) { - struct vio_dev *dev; + struct vio_dev *viodev; unsigned int *unit_address; unsigned int *irq_p; - /* guarantee all vio_devs have 'device_type' field*/ - if ((NULL == node_vdev->type)) { + DBGENTER(); + + /* we need the 'device_type' property, in order to match with drivers */ + if ((NULL == of_node->type)) { printk(KERN_WARNING "%s: node %s missing 'device_type'\n", __FUNCTION__, - node_vdev->name ? node_vdev->name : ""); + of_node->name ? of_node->name : ""); return NULL; } - unit_address = (unsigned int *)get_property(node_vdev, "reg", NULL); + unit_address = (unsigned int *)get_property(of_node, "reg", NULL); if (!unit_address) { printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__, - node_vdev->name ? node_vdev->name : ""); + of_node->name ? of_node->name : ""); return NULL; } /* allocate a vio_dev for this node */ - dev = kmalloc(sizeof(*dev), GFP_KERNEL); - if (!dev) + viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); + if (!viodev) { return NULL; - memset(dev, 0, sizeof(*dev)); - - dev->archdata = (void*)of_node_get(node_vdev); - dev->bus = &vio_bus; - dev->unit_address = *unit_address; - dev->tce_table = vio_build_tce_table(dev); - - irq_p = (unsigned int *) get_property(node_vdev, "interrupts", 0); - if(irq_p) { - dev->irq = openpic_to_irq(virt_irq_create_mapping(*irq_p)); - } else { - dev->irq = (unsigned int) -1; } + memset(viodev, 0, sizeof(struct vio_dev)); - list_add_tail(&dev->devices_list, &vio_bus.devices); - - vio_probe_device(dev); /* finally, assign it to a driver */ + viodev->archdata = (void *)of_node_get(of_node); + viodev->unit_address = *unit_address; + viodev->tce_table = vio_build_tce_table(viodev); + + viodev->irq = (unsigned int) -1; + irq_p = (unsigned int *)get_property(of_node, "interrupts", 0); + if (irq_p) { + viodev->irq = irq_offset_up(*irq_p); + } + + /* init generic 'struct device' fields: */ + viodev->dev.parent = &vio_bus_device->dev; + viodev->dev.bus = &vio_bus_type; + snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s@%lx", + of_node->name, viodev->unit_address); + viodev->dev.release = vio_dev_release; + + /* register with generic device framework */ + if (device_register(&viodev->dev)) { + printk(KERN_ERR "%s: failed to register device %s\n", __FUNCTION__, + viodev->dev.bus_id); + /* XXX free TCE table */ + kfree(viodev); + return NULL; + } - return dev; + return viodev; } EXPORT_SYMBOL(vio_register_device); -int __devinit vio_unregister_device(struct vio_dev *dev) +void __devinit vio_unregister_device(struct vio_dev *viodev) { - list_del(&dev->devices_list); - of_node_put(dev->archdata); - - return 0; + DBGENTER(); + device_unregister(&viodev->dev); } EXPORT_SYMBOL(vio_unregister_device); @@ -531,6 +539,30 @@ void vio_free_consistent(struct vio_dev } } EXPORT_SYMBOL(vio_free_consistent); + +static int vio_bus_match(struct device *dev, struct device_driver *drv) +{ + const struct vio_dev *vio_dev = to_vio_dev(dev); + struct vio_driver *vio_drv = to_vio_driver(drv); + const struct vio_device_id *ids = vio_drv->id_table; + const struct vio_device_id *found_id; + + DBGENTER(); + + if (!ids) + return 0; + + found_id = vio_match_device(ids, vio_dev); + if (found_id) + return 1; + + return 0; +} + +struct bus_type vio_bus_type = { + .name = "vio", + .match = vio_bus_match, +}; EXPORT_SYMBOL(plpar_hcall_norets); EXPORT_SYMBOL(plpar_hcall_8arg_2ret); diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/mm/numa.c 110-ppc64_update/arch/ppc64/mm/numa.c --- 107-kgdb_gdb6_patches/arch/ppc64/mm/numa.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/mm/numa.c Mon Feb 9 10:06:05 2004 @@ -273,8 +273,8 @@ void __init do_init_bootmem(void) physbase = start_paddr; } - if (size > end_paddr - start_paddr) - size = end_paddr - start_paddr; + if (size > end_paddr - physbase) + size = end_paddr - physbase; dbg("free_bootmem %lx %lx\n", physbase, size); free_bootmem_node(NODE_DATA(nid), physbase, @@ -294,8 +294,8 @@ void __init do_init_bootmem(void) physbase = start_paddr; } - if (size > end_paddr - start_paddr) - size = end_paddr - start_paddr; + if (size > end_paddr - physbase) + size = end_paddr - physbase; dbg("reserve_bootmem %lx %lx\n", physbase, size); diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/xmon/start.c 110-ppc64_update/arch/ppc64/xmon/start.c --- 107-kgdb_gdb6_patches/arch/ppc64/xmon/start.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/xmon/start.c Mon Feb 9 10:06:05 2004 @@ -41,7 +41,7 @@ static void sysrq_handle_xmon(int key, s static struct sysrq_key_op sysrq_xmon_op = { .handler = sysrq_handle_xmon, - .help_msg = "xmon", + .help_msg = "Xmon", .action_msg = "Entering xmon\n", }; diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/arch/ppc64/xmon/xmon.c 110-ppc64_update/arch/ppc64/xmon/xmon.c --- 107-kgdb_gdb6_patches/arch/ppc64/xmon/xmon.c Wed Feb 4 23:03:18 2004 +++ 110-ppc64_update/arch/ppc64/xmon/xmon.c Mon Feb 9 10:06:05 2004 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -37,7 +38,7 @@ #define skipbl xmon_skipbl #ifdef CONFIG_SMP -volatile unsigned long cpus_in_xmon = 0; +volatile cpumask_t cpus_in_xmon = CPU_MASK_NONE; static unsigned long got_xmon = 0; static volatile int take_xmon = -1; static volatile int leaving_xmon = 0; @@ -288,17 +289,18 @@ xmon(struct pt_regs *excp) leaving_xmon = 0; /* possible race condition here if a CPU is held up and gets * here while we are exiting */ - if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon)) { + if (cpu_test_and_set(smp_processor_id(), cpus_in_xmon)) { /* xmon probably caused an exception itself */ printf("We are already in xmon\n"); for (;;) - ; + cpu_relax(); } while (test_and_set_bit(0, &got_xmon)) { if (take_xmon == smp_processor_id()) { take_xmon = -1; break; } + cpu_relax(); } /* * XXX: breakpoints are removed while any cpu is in xmon @@ -325,7 +327,7 @@ xmon(struct pt_regs *excp) leaving_xmon = 1; if (cmd != 's') clear_bit(0, &got_xmon); - clear_bit(smp_processor_id(), &cpus_in_xmon); + cpu_clear(smp_processor_id(), cpus_in_xmon); #endif /* CONFIG_SMP */ set_msrd(msr); /* restore interrupt enable */ } @@ -602,6 +604,7 @@ cmds(struct pt_regs *excp) printf(" (type ? for help)\n"); break; } + cpu_relax(); } } @@ -638,7 +641,7 @@ static void cpu_cmd(void) /* print cpus waiting or in xmon */ printf("cpus stopped:"); for (cpu = 0; cpu < NR_CPUS; ++cpu) { - if (test_bit(cpu, &cpus_in_xmon)) { + if (cpu_isset(cpu, cpus_in_xmon)) { printf(" %x", cpu); if (cpu == smp_processor_id()) printf("*", cpu); @@ -664,6 +667,7 @@ static void cpu_cmd(void) take_xmon = -1; break; } + cpu_relax(); } } #endif /* CONFIG_SMP */ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/drivers/char/hvc_console.c 110-ppc64_update/drivers/char/hvc_console.c --- 107-kgdb_gdb6_patches/drivers/char/hvc_console.c Mon Nov 17 18:28:44 2003 +++ 110-ppc64_update/drivers/char/hvc_console.c Mon Feb 9 10:06:06 2004 @@ -29,6 +29,7 @@ #include #include #include +#include extern int hvc_count(int *); extern int hvc_get_chars(int index, char *buf, int count); @@ -223,10 +224,10 @@ static void hvc_poll(int index) spin_unlock_irqrestore(&hp->lock, flags); } -#if defined (CONFIG_XMON) -extern unsigned long cpus_in_xmon; +#if defined(CONFIG_XMON) && defined(CONFIG_SMP) +extern cpumask_t cpus_in_xmon; #else -unsigned long cpus_in_xmon=0; +static const cpumask_t cpus_in_xmon = CPU_MASK_NONE; #endif @@ -237,7 +238,7 @@ int khvcd(void *unused) daemonize("khvcd"); for (;;) { - if (!cpus_in_xmon) { + if (cpus_empty(cpus_in_xmon)) { for (i = 0; i < MAX_NR_HVC_CONSOLES; ++i) hvc_poll(i); } @@ -268,8 +269,9 @@ int __init hvc_init(void) return -ENOMEM; hvc_driver->owner = THIS_MODULE; + hvc_driver->devfs_name = "hvc/"; hvc_driver->driver_name = "hvc"; - hvc_driver->name = "hvc/"; + hvc_driver->name = "hvc"; hvc_driver->major = HVC_MAJOR; hvc_driver->minor_start = HVC_MINOR; hvc_driver->type = TTY_DRIVER_TYPE_SYSTEM; diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/hardirq.h 110-ppc64_update/include/asm-ppc64/hardirq.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/hardirq.h Mon Nov 17 18:29:43 2003 +++ 110-ppc64_update/include/asm-ppc64/hardirq.h Mon Feb 9 10:06:06 2004 @@ -80,7 +80,7 @@ typedef struct { #define irq_enter() (preempt_count() += HARDIRQ_OFFSET) -#ifdef CONFIG_PREEMPT +#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP) # define in_atomic() ((preempt_count() & ~PREEMPT_ACTIVE) != kernel_locked()) # define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1) #else diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/hvcall.h 110-ppc64_update/include/asm-ppc64/hvcall.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/hvcall.h Wed Feb 4 23:03:35 2004 +++ 110-ppc64_update/include/asm-ppc64/hvcall.h Mon Feb 9 10:06:06 2004 @@ -102,6 +102,8 @@ long plpar_hcall(unsigned long opcode, unsigned long *out2, unsigned long *out3); +#define HVSC ".long 0x44000022\n" + /* Same as plpar_hcall but for those opcodes that return no values * other than status. Slightly more efficient. */ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/hvconsole.h 110-ppc64_update/include/asm-ppc64/hvconsole.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/hvconsole.h Wed Dec 31 16:00:00 1969 +++ 110-ppc64_update/include/asm-ppc64/hvconsole.h Mon Feb 9 10:06:06 2004 @@ -0,0 +1,30 @@ +/* + * hvconsole.h + * Copyright (C) 2004 Ryan S Arnold, IBM Corporation + * + * LPAR console support. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _PPC64_HVCONSOLE_H +#define _PPC64_HVCONSOLE_H + +extern int hvc_get_chars(int index, char *buf, int count); +extern int hvc_put_chars(int index, const char *buf, int count); +extern int hvc_count(int *start_termno); + +#endif /* _PPC64_HVCONSOLE_H */ + diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/iSeries/vio.h 110-ppc64_update/include/asm-ppc64/iSeries/vio.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/iSeries/vio.h Wed Feb 4 23:03:35 2004 +++ 110-ppc64_update/include/asm-ppc64/iSeries/vio.h Mon Feb 9 10:06:06 2004 @@ -49,7 +49,7 @@ * in. We use a table to route these, and this defines * the maximum number of distinct subtypes */ -#define VIO_MAX_SUBTYPES 7 +#define VIO_MAX_SUBTYPES 8 /* Each subtype can register a handler to process their events. * The handler must have this interface. @@ -103,7 +103,8 @@ enum viosubtypes { viomajorsubtype_chario = 0x0300, viomajorsubtype_config = 0x0400, viomajorsubtype_cdio = 0x0500, - viomajorsubtype_tape = 0x0600 + viomajorsubtype_tape = 0x0600, + viomajorsubtype_scsi = 0x0700 }; diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/paca.h 110-ppc64_update/include/asm-ppc64/paca.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/paca.h Wed Feb 4 23:03:35 2004 +++ 110-ppc64_update/include/asm-ppc64/paca.h Mon Feb 9 10:06:06 2004 @@ -64,14 +64,13 @@ struct paca_struct { u16 xHwProcNum; /* Physical processor number 0x1A */ u32 default_decr; /* Default decrementer value 0x1c */ u64 xKsave; /* Saved Kernel stack addr or zero 0x20 */ - u64 pvr; /* Processor version register 0x28 */ struct ItLpQueue *lpQueuePtr; /* LpQueue handled by this processor 0x30 */ u64 xTOC; /* Kernel TOC address 0x38 */ STAB xStab_data; /* Segment table information 0x40,0x48,0x50 */ u8 *exception_sp; /* 0x58 */ u8 xProcEnabled; /* 0x59 */ u8 prof_enabled; /* 1=iSeries profiling enabled 0x60 */ - u8 resv1[30]; /* 0x61-0x7F */ + u8 resv1[38]; /* 0x61-0x7F */ /*===================================================================================== * CACHE_LINE_2 0x0080 - 0x00FF diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/pci.h 110-ppc64_update/include/asm-ppc64/pci.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/pci.h Wed Feb 4 23:03:35 2004 +++ 110-ppc64_update/include/asm-ppc64/pci.h Mon Feb 9 10:06:06 2004 @@ -19,6 +19,12 @@ #define PCIBIOS_MIN_IO 0x1000 #define PCIBIOS_MIN_MEM 0x10000000 +#ifdef CONFIG_PPC_ISERIES +#define pcibios_scan_all_fns(a, b) 0 +#else +extern int pcibios_scan_all_fns(struct pci_bus *bus, int devfn); +#endif + static inline void pcibios_set_master(struct pci_dev *dev) { /* No special bus mastering setup handling */ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/asm-ppc64/vio.h 110-ppc64_update/include/asm-ppc64/vio.h --- 107-kgdb_gdb6_patches/include/asm-ppc64/vio.h Wed Feb 4 23:03:35 2004 +++ 110-ppc64_update/include/asm-ppc64/vio.h Mon Feb 9 10:06:06 2004 @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -40,11 +41,11 @@ struct vio_device_id; struct TceTable; int vio_register_driver(struct vio_driver *drv); -int vio_unregister_driver(struct vio_driver *drv); +void vio_unregister_driver(struct vio_driver *drv); const struct vio_device_id * vio_match_device(const struct vio_device_id *ids, const struct vio_dev *dev); struct vio_dev * __devinit vio_register_device(struct device_node *node_vdev); -int __devinit vio_unregister_device(struct vio_dev *dev); +void __devinit vio_unregister_device(struct vio_dev *dev); const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length); int vio_get_irq(struct vio_dev *dev); struct TceTable * vio_build_tce_table(struct vio_dev *dev); @@ -64,11 +65,11 @@ void *vio_alloc_consistent(struct vio_de void vio_free_consistent(struct vio_dev *dev, size_t size, void *vaddr, dma_addr_t dma_handle); +extern struct bus_type vio_bus_type; + struct vio_device_id { char *type; char *compat; -/* I don't think we need this - unsigned long driver_data; */ /* Data private to the driver */ }; struct vio_driver { @@ -76,55 +77,33 @@ struct vio_driver { char *name; const struct vio_device_id *id_table; /* NULL if wants all devices */ int (*probe) (struct vio_dev *dev, const struct vio_device_id *id); /* New device inserted */ - void (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ + int (*remove) (struct vio_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ unsigned long driver_data; + + struct device_driver driver; }; -struct vio_bus; +static inline struct vio_driver *to_vio_driver(struct device_driver *drv) +{ + return container_of(drv, struct vio_driver, driver); +} + /* * The vio_dev structure is used to describe virtual I/O devices. */ struct vio_dev { - struct list_head devices_list; /* node in list of all vio devices */ - struct device_node *archdata; /* Open Firmware node */ - struct vio_bus *bus; /* bus this device is on */ - struct vio_driver *driver; /* owning driver */ + struct device_node *archdata; /* Open Firmware node */ void *driver_data; /* data private to the driver */ unsigned long unit_address; - - struct TceTable *tce_table; /* vio_map_* uses this */ + struct TceTable *tce_table; /* vio_map_* uses this */ unsigned int irq; - struct proc_dir_entry *procent; /* device entry in /proc/bus/vio */ -}; -struct vio_bus { - struct list_head devices; /* list of virtual devices */ + struct device dev; }; - -static inline int vio_module_init(struct vio_driver *drv) +static inline struct vio_dev *to_vio_dev(struct device *dev) { - int rc = vio_register_driver (drv); - - if (rc > 0) - return 0; - - /* iff CONFIG_HOTPLUG and built into kernel, we should - * leave the driver around for future hotplug events. - * For the module case, a hotplug daemon of some sort - * should load a module in response to an insert event. */ -#if defined(CONFIG_HOTPLUG) && !defined(MODULE) - if (rc == 0) - return 0; -#else - if (rc == 0) - rc = -ENODEV; -#endif - - /* if we get here, we need to clean up vio driver instance - * and return some sort of error */ - - return rc; + return container_of(dev, struct vio_dev, dev); } #endif /* _PHYP_H */ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/include/linux/preempt.h 110-ppc64_update/include/linux/preempt.h --- 107-kgdb_gdb6_patches/include/linux/preempt.h Mon Dec 8 09:55:53 2003 +++ 110-ppc64_update/include/linux/preempt.h Mon Feb 9 10:06:06 2004 @@ -24,6 +24,17 @@ do { \ extern void preempt_schedule(void); +#define preempt_check_resched() \ +do { \ + if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ + preempt_schedule(); \ +} while (0) +#else +#define preempt_check_resched() do { } while (0) +#endif + +#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP) + #define preempt_disable() \ do { \ inc_preempt_count(); \ @@ -34,12 +45,6 @@ do { \ do { \ barrier(); \ dec_preempt_count(); \ -} while (0) - -#define preempt_check_resched() \ -do { \ - if (unlikely(test_thread_flag(TIF_NEED_RESCHED))) \ - preempt_schedule(); \ } while (0) #define preempt_enable() \ diff -aurpN -X /home/fletch/.diff.exclude 107-kgdb_gdb6_patches/kernel/sched.c 110-ppc64_update/kernel/sched.c --- 107-kgdb_gdb6_patches/kernel/sched.c Mon Feb 9 09:04:07 2004 +++ 110-ppc64_update/kernel/sched.c Mon Feb 9 10:06:06 2004 @@ -728,7 +728,7 @@ void sched_fork(task_t *p) INIT_LIST_HEAD(&p->run_list); p->array = NULL; spin_lock_init(&p->switch_lock); -#ifdef CONFIG_PREEMPT +#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP) /* * During context-switch we hold precisely one spinlock, which * schedule_tail drops. (in the common case it's this_rq()->lock, @@ -2666,7 +2666,7 @@ void __init init_idle(task_t *idle, int local_irq_restore(flags); /* Set the preempt count _outside_ the spinlocks! */ -#ifdef CONFIG_PREEMPT +#if defined(CONFIG_PREEMPT) || defined(CONFIG_DEBUG_SPINLOCK_SLEEP) idle->thread_info->preempt_count = (idle->lock_depth >= 0); #else idle->thread_info->preempt_count = 0;