## Automatically generated incremental diff ## From: linux-2.4.23-bk13 ## To: linux-2.4.23-bk14 ## Robot: $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $ diff -urN linux-2.4.23-bk13/Makefile linux-2.4.23-bk14/Makefile --- linux-2.4.23-bk13/Makefile 2003-12-19 02:52:50.000000000 -0800 +++ linux-2.4.23-bk14/Makefile 2003-12-19 02:52:53.000000000 -0800 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 23 -EXTRAVERSION = -bk13 +EXTRAVERSION = -bk14 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/chrp_setup.c linux-2.4.23-bk14/arch/ppc64/kernel/chrp_setup.c --- linux-2.4.23-bk13/arch/ppc64/kernel/chrp_setup.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/chrp_setup.c 2003-12-19 02:52:56.000000000 -0800 @@ -82,6 +82,7 @@ extern void pckbd_init_hw(void); extern unsigned char pckbd_sysrq_xlate[128]; extern void openpic_init_IRQ(void); +extern void openpic_init_irq_desc(irq_desc_t *); extern void init_ras_IRQ(void); extern void find_and_init_phbs(void); @@ -264,10 +265,12 @@ ppc_md.setup_residual = NULL; ppc_md.get_cpuinfo = chrp_get_cpuinfo; if(naca->interrupt_controller == IC_OPEN_PIC) { - ppc_md.init_IRQ = openpic_init_IRQ; + ppc_md.init_IRQ = openpic_init_IRQ; + ppc_md.init_irq_desc = openpic_init_irq_desc; ppc_md.get_irq = openpic_get_irq; } else { ppc_md.init_IRQ = xics_init_IRQ; + ppc_md.init_irq_desc = xics_init_irq_desc; ppc_md.get_irq = xics_get_irq; } ppc_md.init_ras_IRQ = init_ras_IRQ; diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/htab.c linux-2.4.23-bk14/arch/ppc64/kernel/htab.c --- linux-2.4.23-bk13/arch/ppc64/kernel/htab.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/htab.c 2003-12-19 02:52:56.000000000 -0800 @@ -1179,7 +1179,7 @@ "mr 5, %3\n" "mr 6, %4\n" "mr 7, %5\n" - HSC + HVSC "mr %0, 3\n" "mr %1, 4\n" : "=r" (lpar_rc), "=r" (slot) @@ -1200,7 +1200,7 @@ "mr 5, %3\n" "mr 6, %4\n" "mr 7, %5\n" - HSC + HVSC "mr %0, 3\n" "mr %1, 4\n" : "=r" (lpar_rc), "=r" (slot) diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/i8259.c linux-2.4.23-bk14/arch/ppc64/kernel/i8259.c --- linux-2.4.23-bk13/arch/ppc64/kernel/i8259.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/i8259.c 2003-12-19 02:52:56.000000000 -0800 @@ -123,7 +123,8 @@ static void i8259_end_irq(unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irqdesc(irq)->status & (IRQ_DISABLED|IRQ_INPROGRESS)) && + irqdesc(irq)->action) i8259_unmask_irq(irq); } diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/iSeries_irq.c linux-2.4.23-bk14/arch/ppc64/kernel/iSeries_irq.c --- linux-2.4.23-bk13/arch/ppc64/kernel/iSeries_irq.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/iSeries_irq.c 2003-12-19 02:52:56.000000000 -0800 @@ -70,15 +70,24 @@ void iSeries_init_irqMap(int irq); +void iSeries_init_irq_desc(irq_desc_t *desc) +{ + if (!desc->handler) + desc->handler = &iSeries_IRQ_handler; +} + /* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ void __init iSeries_init_IRQ(void) { int i; + irq_desc_t *desc; + for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = &iSeries_IRQ_handler; - irq_desc[i].status = 0; - irq_desc[i].status |= IRQ_DISABLED; - irq_desc[i].depth = 1; + desc = real_irqdesc(i); + desc->handler = &iSeries_IRQ_handler; + desc->status = 0; + desc->status |= IRQ_DISABLED; + desc->depth = 1; iSeries_init_irqMap(i); } /* Register PCI event handler and open an event path */ @@ -117,6 +126,7 @@ u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId; struct iSeries_irqEntry* newEntry; unsigned long flags; + irq_desc_t *desc = irqdesc(irq); if (irq < 0 || irq >= NR_IRQS) { return -1; @@ -132,7 +142,7 @@ * done during buswalk, but it should not hurt anything except a * little performance to be smp safe. *******************************************************************/ - spin_lock_irqsave(&irq_desc[irq].lock, flags); + spin_lock_irqsave(&desc->lock, flags); if (iSeries_irqMap[irq].valid) { /* Push the new element onto the irq stack */ @@ -147,7 +157,7 @@ kfree(newEntry); rc = -1; } - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); return rc; } @@ -179,10 +189,11 @@ int irq; unsigned long flags; for (irq=0; irq < NR_IRQS; irq++) { - spin_lock_irqsave(&irq_desc[irq].lock, flags); - irq_desc[irq].handler->startup(irq); - spin_unlock_irqrestore(&irq_desc[irq].lock, flags); - } + irq_desc_t *desc = irqdesc(irq); + spin_lock_irqsave(&desc->lock, flags); + desc->handler->startup(irq); + spin_unlock_irqrestore(&desc->lock, flags); + } } /* this is not called anywhere currently */ diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/iSeries_setup.c linux-2.4.23-bk14/arch/ppc64/kernel/iSeries_setup.c --- linux-2.4.23-bk13/arch/ppc64/kernel/iSeries_setup.c 2003-11-28 10:26:19.000000000 -0800 +++ linux-2.4.23-bk14/arch/ppc64/kernel/iSeries_setup.c 2003-12-19 02:52:56.000000000 -0800 @@ -63,6 +63,7 @@ extern void iSeries_pcibios_init(void); extern void iSeries_pcibios_fixup(void); extern void iSeries_pcibios_fixup_bus(int); +extern void iSeries_init_irq_desc(irq_desc_t *desc); /* Global Variables */ @@ -307,6 +308,7 @@ ppc_md.get_cpuinfo = iSeries_get_cpuinfo; ppc_md.irq_cannonicalize = NULL; ppc_md.init_IRQ = iSeries_init_IRQ; + ppc_md.init_irq_desc = iSeries_init_irq_desc; ppc_md.init_ras_IRQ = NULL; ppc_md.get_irq = iSeries_get_irq; ppc_md.init = NULL; diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/irq.c linux-2.4.23-bk14/arch/ppc64/kernel/irq.c --- linux-2.4.23-bk13/arch/ppc64/kernel/irq.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.23-bk14/arch/ppc64/kernel/irq.c 2003-12-19 02:52:56.000000000 -0800 @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -56,8 +57,47 @@ #include #include -#include "local_irq.h" +/* + * Because the name space for interrupts is so large on ppc64 systems we + * avoid declaring a single array of "NR_IRQ" interrupts and instead build + * a three level tree leading to the irq_desc_t (similar to page tables). + * + * Currently we cover 24-bit irq values: + * 10-bits: the "base" dir (2-pages) + * 9-bits: the "middle" dir (1-page) + * 5-bits: the "bottom" page (1-page) holding 128byte irq_desc's. + * + * We pack a hw_irq_stat struct directly after the irq_desc in the otherwise + * wasted space of the cacheline. + * + * MAX_IRQS is the max this implementation will support. + * It is much larger than NR_IRQS which is bogus on this arch and often used + * to declare arrays. + * + * Note that all "undefined" mid table and bottom table pointers will point + * to dummy tables. Therefore, we don't need to check for NULL on spurious + * interrupts. + */ + +#define IRQ_BASE_INDEX_SIZE 10 +#define IRQ_MID_INDEX_SIZE 9 +#define IRQ_BOT_DESC_SIZE 5 + +#define IRQ_BASE_PTRS (1 << IRQ_BASE_INDEX_SIZE) +#define IRQ_MID_PTRS (1 << IRQ_MID_INDEX_SIZE) +#define IRQ_BOT_DESCS (1 << IRQ_BOT_DESC_SIZE) + +#define IRQ_BASE_IDX_SHIFT (IRQ_MID_INDEX_SIZE + IRQ_BOT_DESC_SIZE) +#define IRQ_MID_IDX_SHIFT (IRQ_BOT_DESC_SIZE) +#define IRQ_MID_IDX_MASK ((1 << IRQ_MID_INDEX_SIZE) - 1) +#define IRQ_BOT_IDX_MASK ((1 << IRQ_BOT_DESC_SIZE) - 1) + +irq_desc_t **irq_desc_base_dir[IRQ_BASE_PTRS] __page_aligned = {0}; +irq_desc_t **irq_desc_mid_null; +irq_desc_t *irq_desc_bot_null; + +unsigned int _next_irq(unsigned int irq); atomic_t ipi_recv; atomic_t ipi_sent; void enable_irq(unsigned int irq_nr); @@ -72,9 +112,10 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { 0, NULL, NULL, 0, SPIN_LOCK_UNLOCKED}}; - + +static irq_desc_t *add_irq_desc(unsigned int irq); + int ppc_spurious_interrupts = 0; -struct irqaction *ppc_irq_action[NR_IRQS]; unsigned long lpEvent_count = 0; #ifdef CONFIG_XMON extern void xmon(struct pt_regs *regs); @@ -93,16 +134,200 @@ extern void (*debugger_fault_handler)(struct pt_regs *regs); #endif -/* nasty hack for shared irq's since we need to do kmalloc calls but - * can't very early in the boot when we need to do a request irq. - * this needs to be removed. - * -- Cort - */ #define IRQ_KMALLOC_ENTRIES 16 static int cache_bitmask = 0; static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES]; extern int mem_init_done; +/* The hw_irq_stat struct is stored directly after the irq_desc_t + * in the same cacheline. We need to use care to make sure we don't + * overrun the size of the cacheline. + * + * Currently sizeof(irq_desc_t) is 40 bytes or less and this hw_irq_stat + * fills the rest of the cache line. + */ +struct hw_irq_stat { + unsigned long irqs; /* statistic per irq */ + unsigned long *per_cpu_stats; + struct proc_dir_entry *irq_dir, *smp_affinity; + unsigned long irq_affinity; /* ToDo: cpu bitmask */ +}; + +static inline struct hw_irq_stat *get_irq_stat(irq_desc_t *desc) +{ + /* WARNING: this assumes lock is the last field! */ + return (struct hw_irq_stat *)(&desc->lock+1); +} + +static inline unsigned long *get_irq_per_cpu(struct hw_irq_stat *hw) +{ + return hw->per_cpu_stats; +} + +static inline irq_desc_t **get_irq_mid_table(unsigned int irq) +{ + /* Assume irq < MAX_IRQS so we won't index off the end. */ + return irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT]; +} + +static inline irq_desc_t *get_irq_bot_table(unsigned int irq, + irq_desc_t **mid_ptr) +{ + return mid_ptr[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK]; +} + +/* This should be inline. */ +void *_irqdesc(unsigned int irq) +{ + irq_desc_t **mid_table, *bot_table, *desc; + + mid_table = get_irq_mid_table(irq); + bot_table = get_irq_bot_table(irq, mid_table); + + desc = bot_table + (irq & IRQ_BOT_IDX_MASK); + return desc; +} + +/* + * This is used by the for_each_irq(i) macro to iterate quickly over + * all interrupts. It optimizes by skipping over ptrs to the null tables + * when possible, but it may produce false positives. + */ +unsigned int _next_irq(unsigned int irq) +{ + irq_desc_t **mid_table, *bot_table; + + irq++; + /* Easy case first...staying on the current bot_table. */ + if (irq & IRQ_BOT_IDX_MASK) + return irq; + + /* Now skip empty mid tables */ + while (irq < MAX_IRQS && + (mid_table = get_irq_mid_table(irq)) == irq_desc_mid_null) { + /* index to the next base index (i.e. the next mid table) */ + irq = (irq & ~(IRQ_BASE_IDX_SHIFT-1)) + IRQ_BASE_IDX_SHIFT; + } + /* And skip empty bot tables */ + while (irq < MAX_IRQS && + (bot_table = get_irq_bot_table(irq, mid_table)) == irq_desc_bot_null) { + /* index to the next mid index (i.e. the next bot table) */ + irq = (irq & ~(IRQ_MID_IDX_SHIFT-1)) + IRQ_MID_IDX_SHIFT; + } + return irq; +} + + +/* Same as irqdesc(irq) except it will "fault in" a real desc as needed + * rather than return the null entry. + * This is used by code that is actually defining the irq. + * + * NULL may be returned on memory allocation failure. In general, init code + * doesn't look for this, but setup_irq does. In this failure case the desc + * is left pointing at the null pages so callers of irqdesc() should + * always return something. + */ +void *_real_irqdesc(unsigned int irq) +{ + irq_desc_t *desc = irqdesc(irq); + if (((unsigned long)desc & PAGE_MASK) == + (unsigned long)irq_desc_bot_null) { + desc = add_irq_desc(irq); + } + return desc; +} + +/* Allocate an irq middle page and init entries to null page. */ +static irq_desc_t **alloc_irq_mid_page(void) +{ + irq_desc_t **m, **ent; + + if (mem_init_done) + m = (irq_desc_t **)__get_free_page(GFP_KERNEL); + else + m = (irq_desc_t **)alloc_bootmem_pages(PAGE_SIZE); + if (m) { + for (ent = m; ent < m + IRQ_MID_PTRS; ent++) { + *ent = irq_desc_bot_null; + } + } + return m; +} + +/* Allocate an irq bottom page and init the entries. */ +static irq_desc_t *alloc_irq_bot_page(void) +{ + irq_desc_t *b, *ent; + if (mem_init_done) + b = (irq_desc_t *)get_zeroed_page(GFP_KERNEL); + else + b = (irq_desc_t *)alloc_bootmem_pages(PAGE_SIZE); + if (b) { + for (ent = b; ent < b + IRQ_BOT_DESCS; ent++) { + ent->lock = SPIN_LOCK_UNLOCKED; + } + } + return b; +} + +/* + * The universe of interrupt numbers ranges from 0 to 2^24. + * Use a sparsely populated tree to map from the irq to the handler. + * Top level is 2 contiguous pages, covering the 10 most significant + * bits. Mid level is 1 page, covering 9 bits. Last page covering + * 5 bits is the irq_desc, each of which is 128B. + */ +static void irq_desc_init(void) { + irq_desc_t ***entry_p; + + /* + * Now initialize the tables to point though the NULL tables for + * the default case of no interrupt handler (spurious). + */ + irq_desc_bot_null = alloc_irq_bot_page(); + irq_desc_mid_null = alloc_irq_mid_page(); + if (!irq_desc_bot_null || !irq_desc_mid_null) + panic("irq_desc_init: could not allocate pages\n"); + for(entry_p = irq_desc_base_dir; + entry_p < irq_desc_base_dir + IRQ_BASE_PTRS; + entry_p++) { + *entry_p = irq_desc_mid_null; + } +} + +/* + * Add a new irq desc for the given irq if needed. + * This breaks any ptr to the "null" middle or "bottom" irq desc page. + * Note that we don't ever coalesce pages as the interrupts are released. + * This isn't worth the effort. We add the cpu stats info when the + * interrupt is actually requested. + * + * May return NULL if memory could not be allocated. + */ +static irq_desc_t *add_irq_desc(unsigned int irq) +{ + irq_desc_t **mid_table_p, *bot_table_p; + + mid_table_p = get_irq_mid_table(irq); + if(mid_table_p == irq_desc_mid_null) { + /* No mid table for this IRQ - create it */ + mid_table_p = alloc_irq_mid_page(); + if (!mid_table_p) return NULL; + irq_desc_base_dir[irq >> IRQ_BASE_IDX_SHIFT] = mid_table_p; + } + + bot_table_p = (irq_desc_t *)(*(mid_table_p + ((irq >> 5) & 0x1ff))); + + if(bot_table_p == irq_desc_bot_null) { + /* No bot table for this IRQ - create it */ + bot_table_p = alloc_irq_bot_page(); + if (!bot_table_p) return NULL; + mid_table_p[(irq >> IRQ_MID_IDX_SHIFT) & IRQ_MID_IDX_MASK] = bot_table_p; + } + + return bot_table_p + (irq & IRQ_BOT_IDX_MASK); +} + void *irq_kmalloc(size_t size, int pri) { unsigned int i; @@ -127,13 +352,44 @@ kfree(ptr); } +void allocate_per_cpu_stats(struct hw_irq_stat *hwstat) +{ + unsigned long *p; + + if (mem_init_done) { + p = (unsigned long *)kmalloc(sizeof(long)*NR_CPUS, GFP_KERNEL); + if (p) memset(p, 0, sizeof(long)*NR_CPUS); + } else + p = (unsigned long *)alloc_bootmem(sizeof(long)*NR_CPUS); + hwstat->per_cpu_stats = p; +} + int setup_irq(unsigned int irq, struct irqaction * new) { int shared = 0; unsigned long flags; struct irqaction *old, **p; - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = real_irqdesc(irq); + struct hw_irq_stat *hwstat; + + if (!desc) + return -ENOMEM; + + ppc_md.init_irq_desc(desc); + + hwstat = get_irq_stat(desc); + +#ifdef CONFIG_IRQ_ALL_CPUS + hwstat->irq_affinity = ~0; +#else + hwstat->irq_affinity = 0; +#endif + + /* Now is the time to add per-cpu kstat data to the desc + * since it appears we are actually going to use the irq. + */ + allocate_per_cpu_stats(hwstat); /* * Some drivers like serial.c use request_irq() heavily, @@ -189,11 +445,10 @@ static int do_free_irq(int irq, void* dev_id) { - irq_desc_t *desc; + irq_desc_t *desc = irqdesc(irq); struct irqaction **p; unsigned long flags; - desc = irq_desc + irq; spin_lock_irqsave(&desc->lock,flags); p = &desc->action; for (;;) { @@ -233,8 +488,9 @@ struct irqaction *action; int retval; - if (irq >= NR_IRQS) + if (irq >= MAX_IRQS) return -EINVAL; + if (!handler) /* We could implement really free_irq() instead of that... */ return do_free_irq(irq, dev_id); @@ -285,7 +541,7 @@ void disable_irq_nosync(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -317,7 +573,7 @@ if (!local_irq_count(smp_processor_id())) { do { barrier(); - } while (irq_desc[irq].status & IRQ_INPROGRESS); + } while (irqdesc(irq)->status & IRQ_INPROGRESS); } } @@ -333,7 +589,7 @@ void enable_irq(unsigned int irq) { - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -357,82 +613,57 @@ spin_unlock_irqrestore(&desc->lock, flags); } -/* one would think this function has one foot in the grave */ +/* This function as implemented was a potential source of data + * corruption. I pulled it for now, until it can be properly + * implemented. DRENG + */ int get_irq_list(char *buf) { - int i, len = 0, j; - struct irqaction * action; - - len += sprintf(buf+len, " "); - for (j=0; jhandler ) - continue; - len += sprintf(buf+len, "%3d: ", i); -#ifdef CONFIG_SMP - for (j = 0; j < smp_num_cpus; j++) - len += sprintf(buf+len, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); -#else - len += sprintf(buf+len, "%10u ", kstat_irqs(i)); -#endif /* CONFIG_SMP */ -if ( irq_desc[i].handler ) -len += sprintf(buf+len, " %s ", irq_desc[i].handler->typename ); -else -len += sprintf(buf+len, " None "); -len += sprintf(buf+len, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); -len += sprintf(buf+len, " %s",action->name); -for (action=action->next; action; action = action->next) { -len += sprintf(buf+len, ", %s", action->name); -} -len += sprintf(buf+len, "\n"); + return(0); } -#ifdef CONFIG_SMP -/* should this be per processor send/receive? */ -len += sprintf(buf+len, "IPI (recv/sent): %10u/%u\n", -atomic_read(&ipi_recv), atomic_read(&ipi_sent)); -#endif -len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts); -return len; -} - - int show_interrupts(struct seq_file *p, void *v) { int i, j; struct irqaction * action; + irq_desc_t *desc; + struct hw_irq_stat *hwstat; + unsigned long *per_cpus; + unsigned long flags; seq_printf(p, " "); for (j=0; jlock, flags); + action = desc->action; + if (!action || !action->handler) - continue; - seq_printf(p, "%3d: ", i); -#ifdef CONFIG_SMP + goto skip; + seq_printf(p, "%3d: ", i); + hwstat = get_irq_stat(desc); + per_cpus = get_irq_per_cpu(hwstat); + if (per_cpus) { for (j = 0; j < smp_num_cpus; j++) - seq_printf(p, "%10u ", - kstat.irqs[cpu_logical_map(j)][i]); -#else - seq_printf(p, "%10u ", kstat_irqs(i)); -#endif /* CONFIG_SMP */ - if (irq_desc[i].handler) - seq_printf(p, " %s ", irq_desc[i].handler->typename ); + seq_printf(p, "%10lu ", per_cpus[j]); + } else { + seq_printf(p, "%10lu ", hwstat->irqs); + } + + if (irqdesc(i)->handler) + seq_printf(p, " %s ", irqdesc(i)->handler->typename ); else seq_printf(p, " None "); - seq_printf(p, "%s", (irq_desc[i].status & IRQ_LEVEL) ? "Level " : "Edge "); + seq_printf(p, "%s", (irqdesc(i)->status & IRQ_LEVEL) ? "Level " : "Edge "); seq_printf(p, " %s",action->name); for (action=action->next; action; action = action->next) seq_printf(p, ", %s", action->name); seq_putc(p, '\n'); +skip: + spin_unlock_irqrestore(&desc->lock, flags); } #ifdef CONFIG_SMP /* should this be per processor send/receive? */ @@ -470,9 +701,24 @@ int status; struct irqaction *action; int cpu = smp_processor_id(); - irq_desc_t *desc = irq_desc + irq; + irq_desc_t *desc = irqdesc(irq); + struct hw_irq_stat *hwstat; + unsigned long *per_cpus; + + /* Statistics. */ + hwstat = get_irq_stat(desc); /* same cache line as desc */ + hwstat->irqs++; + per_cpus = get_irq_per_cpu(hwstat); /* same cache line for < 8 cpus */ + if (per_cpus) + per_cpus[cpu]++; + if(irq < NR_IRQS) { kstat.irqs[cpu][irq]++; + } else { + kstat.irqs[cpu][NR_IRQS-1]++; + } + + spin_lock(&desc->lock); ack_irq(irq); /* @@ -544,11 +790,11 @@ * The ->end() handler has to deal with interrupts which got * disabled while the handler was running. */ - if (irq_desc[irq].handler) { - if (irq_desc[irq].handler->end) - irq_desc[irq].handler->end(irq); - else if (irq_desc[irq].handler->enable) - irq_desc[irq].handler->enable(irq); + if (desc->handler) { + if (desc->handler->end) + desc->handler->end(irq); + else if (desc->handler->enable) + desc->handler->enable(irq); } spin_unlock(&desc->lock); } @@ -638,7 +884,10 @@ return; else once++; - + + /* Initialize the irq tree */ + irq_desc_init(); + ppc_md.init_IRQ(); if(ppc_md.init_ras_IRQ) ppc_md.init_ras_IRQ(); } @@ -794,6 +1043,7 @@ #endif /* CONFIG_SMP */ static struct proc_dir_entry * root_irq_dir; +#if 0 static struct proc_dir_entry * irq_dir [NR_IRQS]; static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; @@ -802,15 +1052,19 @@ #else /* CONFIG_IRQ_ALL_CPUS */ unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0x00000000}; #endif /* CONFIG_IRQ_ALL_CPUS */ +#endif #define HEX_DIGITS 8 static int irq_affinity_read_proc (char *page, char **start, off_t off, int count, int *eof, void *data) { + irq_desc_t *desc = irqdesc((long)data); + struct hw_irq_stat *hwstat = get_irq_stat(desc); + if (count < HEX_DIGITS+1) return -EINVAL; - return sprintf (page, "%08x\n", irq_affinity[(int)(long)data]); + return sprintf(page, "%16lx\n", hwstat->irq_affinity); } static unsigned int parse_hex_value (const char *buffer, @@ -853,10 +1107,13 @@ static int irq_affinity_write_proc (struct file *file, const char *buffer, unsigned long count, void *data) { - int irq = (int)(long) data, full_count = count, err; + unsigned int irq = (long)data; + irq_desc_t *desc = irqdesc(irq); + struct hw_irq_stat *hwstat = get_irq_stat(desc); + int full_count = count, err; unsigned long new_value; - if (!irq_desc[irq].handler->set_affinity) + if (!desc->handler->set_affinity) return -EIO; err = parse_hex_value(buffer, count, &new_value); @@ -871,10 +1128,8 @@ if (!(new_value & cpu_online_map)) return -EINVAL; #endif - - irq_affinity[irq] = new_value; - irq_desc[irq].handler->set_affinity(irq, new_value); - + hwstat->irq_affinity = new_value; + desc->handler->set_affinity(irq, new_value); return full_count; } @@ -923,25 +1178,39 @@ { struct proc_dir_entry *entry; char name [MAX_NAMELEN]; + irq_desc_t *desc; + struct hw_irq_stat *hwstat; - if (!root_irq_dir || (irq_desc[irq].handler == NULL)) + desc = real_irqdesc(irq); + if (!root_irq_dir || !desc || !desc->handler) + return; + hwstat = get_irq_stat(desc); + if (hwstat->irq_dir) return; memset(name, 0, MAX_NAMELEN); sprintf(name, "%d", irq); /* create /proc/irq/1234 */ - irq_dir[irq] = proc_mkdir(name, root_irq_dir); + hwstat->irq_dir = proc_mkdir(name, root_irq_dir); + if(hwstat->irq_dir == NULL) { + printk(KERN_ERR "register_irq_proc: proc_mkdir failed.\n"); + return; + } /* create /proc/irq/1234/smp_affinity */ - entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); + entry = create_proc_entry("smp_affinity", 0600, hwstat->irq_dir); - entry->nlink = 1; - entry->data = (void *)(long)irq; - entry->read_proc = irq_affinity_read_proc; - entry->write_proc = irq_affinity_write_proc; + if(entry) { + entry->nlink = 1; + entry->data = (void *)(long)irq; + entry->read_proc = irq_affinity_read_proc; + entry->write_proc = irq_affinity_write_proc; + } else { + printk(KERN_ERR "register_irq_proc: create_proc_entry failed.\n"); + } - smp_affinity_entry[irq] = entry; + hwstat->smp_affinity = entry; } unsigned long prof_cpu_mask = -1; @@ -953,20 +1222,27 @@ /* create /proc/irq */ root_irq_dir = proc_mkdir("irq", 0); + if(root_irq_dir == NULL) { + printk(KERN_ERR "init_irq_proc: proc_mkdir failed.\n"); + } /* create /proc/irq/prof_cpu_mask */ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); - entry->nlink = 1; - entry->data = (void *)&prof_cpu_mask; - entry->read_proc = prof_cpu_mask_read_proc; - entry->write_proc = prof_cpu_mask_write_proc; + if(entry) { + entry->nlink = 1; + entry->data = (void *)&prof_cpu_mask; + entry->read_proc = prof_cpu_mask_read_proc; + entry->write_proc = prof_cpu_mask_write_proc; + } else { + printk(KERN_ERR "init_irq_proc: create_proc_entry failed.\n"); + } /* * Create entries for all existing IRQs. */ - for (i = 0; i < NR_IRQS; i++) { - if (irq_desc[i].handler == NULL) + for_each_irq(i) { + if (irqdesc(i)->handler == NULL) continue; register_irq_proc(i); } diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/open_pic.c linux-2.4.23-bk14/arch/ppc64/kernel/open_pic.c --- linux-2.4.23-bk13/arch/ppc64/kernel/open_pic.c 2002-11-28 15:53:11.000000000 -0800 +++ linux-2.4.23-bk14/arch/ppc64/kernel/open_pic.c 2003-12-19 02:52:56.000000000 -0800 @@ -20,7 +20,7 @@ #include #include #include - +#include #include #include "local_irq.h" @@ -131,13 +131,23 @@ #define GET_ISU(source) ISU[(source) >> 4][(source) & 0xf] +void +openpic_init_irq_desc(irq_desc_t *desc) +{ + /* Don't mess with the handler if already set. + * This leaves the setup of isa/ipi handlers undisturbed. + */ + if (!desc->handler) + desc->handler = &open_pic; +} + void __init openpic_init_IRQ(void) { struct device_node *np; int i; unsigned int *addrp; unsigned char* chrp_int_ack_special = 0; - unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS]; + unsigned char init_senses[NR_IRQS - NUM_ISA_INTERRUPTS]; int nmi_irq = -1; #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON) struct device_node *kbd; @@ -152,13 +162,13 @@ __ioremap(addrp[prom_n_addr_cells(np)-1], 1, _PAGE_NO_CACHE); /* hydra still sets OpenPIC_InitSenses to a static set of values */ if (OpenPIC_InitSenses == NULL) { - prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS); - OpenPIC_InitSenses = init_senses; - OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS; - } - openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq); - for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) - irq_desc[i].handler = &i8259_pic; + prom_get_irq_senses(init_senses, NUM_ISA_INTERRUPTS, NR_IRQS); + OpenPIC_InitSenses = init_senses; + OpenPIC_NumInitSenses = NR_IRQS - NUM_ISA_INTERRUPTS; + } + openpic_init(1, NUM_ISA_INTERRUPTS, chrp_int_ack_special, nmi_irq); + for ( i = 0 ; i < NUM_ISA_INTERRUPTS ; i++ ) + real_irqdesc(i)->handler = &i8259_pic; i8259_init(); } @@ -343,8 +353,8 @@ /* Disabled, Priority 10..13 */ openpic_initipi(i, 10+i, openpic_vec_ipi+i); /* IPIs are per-CPU */ - irq_desc[openpic_vec_ipi+i].status |= IRQ_PER_CPU; - irq_desc[openpic_vec_ipi+i].handler = &open_pic_ipi; + real_irqdesc(openpic_vec_ipi+i)->status |= IRQ_PER_CPU; + real_irqdesc(openpic_vec_ipi+i)->handler = &open_pic_ipi; } #endif @@ -369,7 +379,7 @@ pri = (i == programmer_switch_irq)? 9: 8; sense = (i < OpenPIC_NumInitSenses)? OpenPIC_InitSenses[i]: 1; if (sense) - irq_desc[i+offset].status = IRQ_LEVEL; + real_irqdesc(i+offset)->status = IRQ_LEVEL; /* Enabled, Priority 8 or 9 */ openpic_initirq(i, pri, i+offset, !sense, sense); @@ -377,10 +387,6 @@ openpic_mapirq(i, 1<status & IRQ_LEVEL) != 0) openpic_eoi(); } diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/open_pic.h linux-2.4.23-bk14/arch/ppc64/kernel/open_pic.h --- linux-2.4.23-bk13/arch/ppc64/kernel/open_pic.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/open_pic.h 2003-12-19 02:52:56.000000000 -0800 @@ -37,9 +37,4 @@ extern void openpic_setup_ISU(int isu_num, unsigned long addr); extern void openpic_cause_IPI(u_int ipi, u_int cpumask); -extern inline int openpic_to_irq(int irq) -{ - return irq += NUM_8259_INTERRUPTS; -} -/*extern int open_pic_irq_offset;*/ #endif /* _PPC64_KERNEL_OPEN_PIC_H */ diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/pSeries_hvCall.S linux-2.4.23-bk14/arch/ppc64/kernel/pSeries_hvCall.S --- linux-2.4.23-bk13/arch/ppc64/kernel/pSeries_hvCall.S 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/pSeries_hvCall.S 2003-12-19 02:52:56.000000000 -0800 @@ -23,7 +23,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 @@ -45,7 +45,7 @@ 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) @@ -60,11 +60,85 @@ blr /* return r3 = status */ +/* long plpar_hcall_4out(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long *out1, (r4) R8 + unsigned long *out2, (r5) R9 + unsigned long *out3, (r6) R10 + unsigned long *out4); (r7) 112(R1). From Parameter save area. + */ +_GLOBAL(plpar_hcall_4out) + mfcr r0 + std r0,-8(r1) + ld r14,112(r1) + stdu r1,-48(r1) + + std r8,32(r1) /* Save out ptrs. */ + std r9,24(r1) + std r10,16(r1) + std r14,8(r1) + + HVSC /* invoke the hypervisor */ + + ld r14,32(r1) /* Fetch r4-r7 ret args. */ + std r4,0(r14) + ld r14,24(r1) + std r5,0(r14) + ld r14,16(r1) + std r6,0(r14) + ld r14,8(r1) + std r7,0(r14) + + ld r1,0(r1) + ld r0,-8(r1) + mtcrf 0xff,r0 + blr /* return r3 = status */ + + /* Simple interface with no output values (other than status) */ _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 */ + + +/* long plpar_hcall_8arg_2ret(unsigned long opcode, R3 + unsigned long arg1, R4 + unsigned long arg2, R5 + unsigned long arg3, R6 + unsigned long arg4, R7 + unsigned long arg5, R8 + unsigned long arg6, R9 + unsigned long arg7, R10 + unsigned long arg8, 112(R1) + unsigned long *out1); 120(R1) + + */ + + .text +_GLOBAL(plpar_hcall_8arg_2ret) + mfcr r0 + + ld r11, 112(r1) /* put arg8 and out1 in R11 and R12 */ + ld r12, 120(r1) + + std r0,-8(r1) + stdu r1,-32(r1) + + std r12,-8(r1) /* Save out ptr */ + + HVSC /* invoke the hypervisor */ + + ld r10,-8(r1) /* Fetch r4 ret arg */ + std r4,0(r10) + + ld r1,0(r1) ld r0,-8(r1) mtcrf 0xff,r0 blr /* return r3 = status */ diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/pSeries_pci.c linux-2.4.23-bk14/arch/ppc64/kernel/pSeries_pci.c --- linux-2.4.23-bk13/arch/ppc64/kernel/pSeries_pci.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/pSeries_pci.c 2003-12-19 02:52:56.000000000 -0800 @@ -703,10 +703,6 @@ pci_read_irq_line(dev); PPCDBGCALL(PPCDBG_PHBINIT, dumpPci_Dev(dev) ); } - - if (naca->interrupt_controller == IC_PPC_XIC) { - xics_isa_init(); - } } /*********************************************************************** diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/prom.c linux-2.4.23-bk14/arch/ppc64/kernel/prom.c --- linux-2.4.23-bk13/arch/ppc64/kernel/prom.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/prom.c 2003-12-19 02:52:56.000000000 -0800 @@ -182,11 +182,6 @@ struct device_node *allnodes = 0; -#define UNDEFINED_IRQ 0xffff -unsigned short real_irq_to_virt_map[NR_HW_IRQS]; -unsigned short virt_irq_to_real_map[NR_IRQS]; -int last_virt_irq = 2; /* index of last virt_irq. Skip through IPI */ - static unsigned long call_prom(const char *service, int nargs, int nret, ...); static void prom_exit(void); static unsigned long copy_device_tree(unsigned long); @@ -1697,46 +1692,6 @@ return DOUBLEWORD_ALIGN(mem); } -void -virt_irq_init(void) -{ - int i; - for (i = 0; i < NR_IRQS; i++) - virt_irq_to_real_map[i] = UNDEFINED_IRQ; - for (i = 0; i < NR_HW_IRQS; i++) - real_irq_to_virt_map[i] = UNDEFINED_IRQ; -} - -/* Create a mapping for a real_irq if it doesn't already exist. - * Return the virtual irq as a convenience. - */ -unsigned long -virt_irq_create_mapping(unsigned long real_irq) -{ - unsigned long virq; - if (naca->interrupt_controller == IC_OPEN_PIC) - return real_irq; /* no mapping for openpic (for now) */ - virq = real_irq_to_virt(real_irq); - if (virq == UNDEFINED_IRQ) { - /* Assign a virtual IRQ number */ - if (real_irq < NR_IRQS && virt_irq_to_real(real_irq) == UNDEFINED_IRQ) { - /* A 1-1 mapping will work. */ - virq = real_irq; - } else { - while (last_virt_irq < NR_IRQS && - virt_irq_to_real(++last_virt_irq) != UNDEFINED_IRQ) - /* skip irq's in use */; - if (last_virt_irq >= NR_IRQS) - panic("Too many IRQs are required on this system. NR_IRQS=%d\n", NR_IRQS); - virq = last_virt_irq; - } - virt_irq_to_real_map[virq] = real_irq; - real_irq_to_virt_map[real_irq] = virq; - } - return virq; -} - - static int __init prom_next_node(phandle *nodep) { @@ -1866,8 +1821,6 @@ { unsigned long mem = klimit; - virt_irq_init(); - mem = finish_node(allnodes, mem, NULL, 0, 0); dev_tree_size = mem - (unsigned long) allnodes; @@ -1972,7 +1925,7 @@ np->n_intrs = ipsize / isize; mem_start += np->n_intrs * sizeof(struct interrupt_info); for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = openpic_to_irq(virt_irq_create_mapping(*interrupts++)); + np->intrs[i].line = irq_offset_up(*interrupts++); np->intrs[i].sense = 1; if (isize > 1) np->intrs[i].sense = *interrupts++; diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/ras.c linux-2.4.23-bk14/arch/ppc64/kernel/ras.c --- linux-2.4.23-bk13/arch/ppc64/kernel/ras.c 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/ras.c 2003-12-19 02:52:56.000000000 -0800 @@ -73,7 +73,7 @@ (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { - request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, + request_irq(irq_offset_up(*(ireg)), &ras_error_interrupt, 0, "RAS_ERROR", NULL); ireg++; @@ -84,7 +84,7 @@ (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { - request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, + request_irq(irq_offset_up(*(ireg)), &ras_epow_interrupt, 0, "RAS_EPOW", NULL); ireg++; diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/xics.c linux-2.4.23-bk14/arch/ppc64/kernel/xics.c --- linux-2.4.23-bk13/arch/ppc64/kernel/xics.c 2003-08-25 04:44:40.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/xics.c 2003-12-19 02:52:56.000000000 -0800 @@ -51,7 +51,6 @@ }; #define XICS_IPI 2 -#define XICS_IRQ_OFFSET 0x10 #define XICS_IRQ_SPURIOUS 0 /* Want a priority other than 0. Various HW issues require this. */ @@ -136,17 +135,14 @@ void -xics_enable_irq( - u_int virq - ) +xics_enable_irq(u_int virq) { u_int irq; unsigned long status; long call_status; unsigned int interrupt_server = default_server; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); + irq = irq_offset_down(virq); if (irq == XICS_IPI) return; @@ -175,18 +171,14 @@ } void -xics_disable_irq( - u_int virq - ) +xics_disable_irq(u_int virq) { u_int irq; unsigned long status; long call_status; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); - call_status = rtas_call(ibm_int_off, 1, 1, (unsigned long*)&status, - irq); + irq = irq_offset_down(virq); + call_status = rtas_call(ibm_int_off, 1, 1, NULL, irq); if( call_status != 0 ) { printk("xics_disable_irq: irq=%x: rtas_call failed, retn=%lx\n", irq, call_status); @@ -195,16 +187,12 @@ } void -xics_end_irq( - u_int irq - ) +xics_end_irq(u_int irq) { int cpu = smp_processor_id(); - ops->cppr_info(cpu, 0); /* actually the value overwritten by ack */ - iosync(); - ops->xirr_info_set(cpu, ((0xff<<24) | (virt_irq_to_real(irq-XICS_IRQ_OFFSET)))); iosync(); + ops->xirr_info_set(cpu, (0xff<<24) | irq_offset_down(irq)); } void @@ -212,7 +200,7 @@ { int cpu = smp_processor_id(); - if( irq < XICS_IRQ_OFFSET ) { + if (irq < irq_offset_value()) { i8259_pic.ack(irq); iosync(); ops->xirr_info_set(cpu, ((0xff<<24) | xics_irq_8259_cascade_real)); @@ -239,13 +227,13 @@ irq = i8259_irq(cpu); if(irq == -1) { /* Spurious cascaded interrupt. Still must ack xics */ - xics_end_irq(XICS_IRQ_OFFSET + xics_irq_8259_cascade); + xics_end_irq(irq_offset_up(xics_irq_8259_cascade)); irq = -1; } } else if( vec == XICS_IRQ_SPURIOUS ) { irq = -1; } else { - irq = real_irq_to_virt(vec) + XICS_IRQ_OFFSET; + irq = irq_offset_up(vec); } return irq; } @@ -290,6 +278,15 @@ } #endif /* CONFIG_SMP */ +void xics_init_irq_desc(irq_desc_t *desc) +{ + /* Don't mess with the handler if already set. + * This leaves the setup of isa handlers undisturbed. + */ + if (!desc->handler) + desc->handler = &xics_pic; +} + void xics_init_IRQ( void ) { @@ -373,7 +370,7 @@ while (1); } xics_irq_8259_cascade_real = *ireg; - xics_irq_8259_cascade = virt_irq_create_mapping(xics_irq_8259_cascade_real); + xics_irq_8259_cascade = xics_irq_8259_cascade_real; } if (systemcfg->platform == PLATFORM_PSERIES) { @@ -398,36 +395,24 @@ xics_8259_pic.enable = i8259_pic.enable; xics_8259_pic.disable = i8259_pic.disable; for (i = 0; i < 16; ++i) - irq_desc[i].handler = &xics_8259_pic; - for (; i < NR_IRQS; ++i) - irq_desc[i].handler = &xics_pic; + real_irqdesc(i)->handler = &xics_8259_pic; ops->cppr_info(0, 0xff); iosync(); if (xics_irq_8259_cascade != -1) { - if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) + if (request_irq(irq_offset_up(xics_irq_8259_cascade), + no_action, 0, "8259 cascade", 0)) printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); i8259_init(); } #ifdef CONFIG_SMP - real_irq_to_virt_map[XICS_IPI] = virt_irq_to_real_map[XICS_IPI] = XICS_IPI; - request_irq(XICS_IPI + XICS_IRQ_OFFSET, xics_ipi_action, 0, "IPI", 0); - irq_desc[XICS_IPI+XICS_IRQ_OFFSET].status |= IRQ_PER_CPU; + request_irq(irq_offset_up(XICS_IPI), xics_ipi_action, 0, "IPI", 0); + real_irqdesc(irq_offset_up(XICS_IPI))->status |= IRQ_PER_CPU; #endif ppc64_boot_msg(0x21, "XICS Done"); } -void xics_isa_init(void) -{ - return; - if (request_irq(xics_irq_8259_cascade + XICS_IRQ_OFFSET, no_action, - 0, "8259 cascade", 0)) - printk(KERN_ERR "xics_init_IRQ: couldn't get 8259 cascade\n"); - i8259_init(); -} - /* * Find first logical cpu and return its physical cpu number */ @@ -445,21 +430,19 @@ return default_distrib_server; } -void xics_set_affinity(unsigned int virq, unsigned long cpumask) +void xics_set_affinity(unsigned int irq, unsigned long cpumask) { - irq_desc_t *desc = irq_desc + virq; - unsigned int irq; + irq_desc_t *desc = irqdesc(irq); unsigned long flags; long status; unsigned long xics_status[2]; u32 newmask; - virq -= XICS_IRQ_OFFSET; - irq = virt_irq_to_real(virq); + irq = irq_offset_down(irq); if (irq == XICS_IPI) return; - spin_lock_irqsave(&desc->lock, flags); + spin_lock_irqsave(&desc->lock, flags); status = rtas_call(ibm_get_xive, 1, 3, (void *)&xics_status, irq); @@ -485,5 +468,5 @@ } out: - spin_unlock_irqrestore(&desc->lock, flags); + spin_unlock_irqrestore(&desc->lock, flags); } diff -urN linux-2.4.23-bk13/arch/ppc64/kernel/xics.h linux-2.4.23-bk14/arch/ppc64/kernel/xics.h --- linux-2.4.23-bk13/arch/ppc64/kernel/xics.h 2002-08-02 17:39:43.000000000 -0700 +++ linux-2.4.23-bk14/arch/ppc64/kernel/xics.h 2003-12-19 02:52:56.000000000 -0800 @@ -18,7 +18,7 @@ extern struct hw_interrupt_type xics_8259_pic; void xics_init_IRQ(void); +void xics_init_irq_desc(irq_desc_t *); int xics_get_irq(struct pt_regs *); -void xics_isa_init(void); #endif /* _PPC_KERNEL_XICS_H */ diff -urN linux-2.4.23-bk13/drivers/char/drm/drmP.h linux-2.4.23-bk14/drivers/char/drm/drmP.h --- linux-2.4.23-bk13/drivers/char/drm/drmP.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/drmP.h 2003-12-19 02:52:56.000000000 -0800 @@ -328,16 +328,16 @@ if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; } /* Mapping helper macros */ -#define DRM_IOREMAP(map) \ - (map)->handle = DRM(ioremap)( (map)->offset, (map)->size ) +#define DRM_IOREMAP(map, dev) \ + (map)->handle = DRM(ioremap)((map)->offset, (map)->size, (dev) ) -#define DRM_IOREMAP_NOCACHE(map) \ - (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size) +#define DRM_IOREMAP_NOCACHE(map, dev) \ + (map)->handle = DRM(ioremap_nocache)((map)->offset, (map)->size, (dev) ) -#define DRM_IOREMAPFREE(map) \ +#define DRM_IOREMAPFREE(map, dev) \ do { \ if ( (map)->handle && (map)->size ) \ - DRM(ioremapfree)( (map)->handle, (map)->size ); \ + DRM(ioremapfree)( (map)->handle, (map)->size, (dev) ); \ } while (0) #define DRM_FIND_MAP(_map, _o) \ @@ -789,9 +789,9 @@ extern unsigned long DRM(alloc_pages)(int order, int area); extern void DRM(free_pages)(unsigned long address, int order, int area); -extern void *DRM(ioremap)(unsigned long offset, unsigned long size); -extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size); -extern void DRM(ioremapfree)(void *pt, unsigned long size); +extern void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev); #if __REALLY_HAVE_AGP extern agp_memory *DRM(alloc_agp)(int pages, u32 type); diff -urN linux-2.4.23-bk13/drivers/char/drm/drm_bufs.h linux-2.4.23-bk14/drivers/char/drm/drm_bufs.h --- linux-2.4.23-bk13/drivers/char/drm/drm_bufs.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/drm_bufs.h 2003-12-19 02:52:56.000000000 -0800 @@ -123,7 +123,7 @@ MTRR_TYPE_WRCOMB, 1 ); } #endif - map->handle = DRM(ioremap)( map->offset, map->size ); + map->handle = DRM(ioremap)( map->offset, map->size, dev ); break; case _DRM_SHM: @@ -245,7 +245,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); diff -urN linux-2.4.23-bk13/drivers/char/drm/drm_drv.h linux-2.4.23-bk14/drivers/char/drm/drm_drv.h --- linux-2.4.23-bk13/drivers/char/drm/drm_drv.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/drm_drv.h 2003-12-19 02:52:56.000000000 -0800 @@ -443,7 +443,7 @@ DRM_DEBUG( "mtrr_del=%d\n", retcode ); } #endif - DRM(ioremapfree)( map->handle, map->size ); + DRM(ioremapfree)( map->handle, map->size, dev ); break; case _DRM_SHM: vfree(map->handle); diff -urN linux-2.4.23-bk13/drivers/char/drm/drm_memory.h linux-2.4.23-bk14/drivers/char/drm/drm_memory.h --- linux-2.4.23-bk13/drivers/char/drm/drm_memory.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/drm_memory.h 2003-12-19 02:52:56.000000000 -0800 @@ -290,7 +290,7 @@ } } -void *DRM(ioremap)(unsigned long offset, unsigned long size) +void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -313,7 +313,7 @@ return pt; } -void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size) +void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -336,7 +336,7 @@ return pt; } -void DRM(ioremapfree)(void *pt, unsigned long size) +void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; diff -urN linux-2.4.23-bk13/drivers/char/drm/drm_vm.h linux-2.4.23-bk14/drivers/char/drm/drm_vm.h --- linux-2.4.23-bk13/drivers/char/drm/drm_vm.h 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/drm_vm.h 2003-12-19 02:52:56.000000000 -0800 @@ -206,7 +206,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - DRM(ioremapfree)(map->handle, map->size); + DRM(ioremapfree)(map->handle, map->size, dev); break; case _DRM_SHM: vfree(map->handle); diff -urN linux-2.4.23-bk13/drivers/char/drm/gamma_dma.c linux-2.4.23-bk14/drivers/char/drm/gamma_dma.c --- linux-2.4.23-bk13/drivers/char/drm/gamma_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/gamma_dma.c 2003-12-19 02:52:56.000000000 -0800 @@ -638,7 +638,7 @@ } else { DRM_FIND_MAP( dev_priv->buffers, init->buffers_offset ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->buffers, dev ); buf = dma->buflist[GLINT_DRI_BUF_COUNT]; pgt = buf->address; @@ -668,7 +668,7 @@ if ( dev->dev_private ) { drm_gamma_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); DRM(free)( dev->dev_private, sizeof(drm_gamma_private_t), DRM_MEM_DRIVER ); diff -urN linux-2.4.23-bk13/drivers/char/drm/i810_dma.c linux-2.4.23-bk14/drivers/char/drm/i810_dma.c --- linux-2.4.23-bk13/drivers/char/drm/i810_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/i810_dma.c 2003-12-19 02:52:56.000000000 -0800 @@ -276,7 +276,7 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { pci_free_consistent(dev->pdev, PAGE_SIZE, @@ -292,7 +292,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -362,7 +362,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -415,7 +415,7 @@ dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; diff -urN linux-2.4.23-bk13/drivers/char/drm/i830_dma.c linux-2.4.23-bk14/drivers/char/drm/i830_dma.c --- linux-2.4.23-bk13/drivers/char/drm/i830_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/i830_dma.c 2003-12-19 02:52:56.000000000 -0800 @@ -252,7 +252,7 @@ if(dev_priv->ring.virtual_start) { DRM(ioremapfree)((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { pci_free_consistent(dev->pdev, PAGE_SIZE, @@ -277,7 +277,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i830_buf_priv_t *buf_priv = buf->dev_private; - DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total); + DRM(ioremapfree)(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -353,7 +353,7 @@ *buf_priv->in_use = I830_BUF_FREE; buf_priv->kernel_virtual = DRM(ioremap)(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -407,7 +407,7 @@ dev_priv->ring.virtual_start = DRM(ioremap)(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); if (dev_priv->ring.virtual_start == NULL) { dev->dev_private = (void *) dev_priv; diff -urN linux-2.4.23-bk13/drivers/char/drm/mga_dma.c linux-2.4.23-bk14/drivers/char/drm/mga_dma.c --- linux-2.4.23-bk13/drivers/char/drm/mga_dma.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/mga_dma.c 2003-12-19 02:52:56.000000000 -0800 @@ -556,9 +556,9 @@ (drm_mga_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DRM_IOREMAP( dev_priv->warp ); - DRM_IOREMAP( dev_priv->primary ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->warp, dev ); + DRM_IOREMAP( dev_priv->primary, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->warp->handle || !dev_priv->primary->handle || @@ -644,9 +644,9 @@ if ( dev->dev_private ) { drm_mga_private_t *dev_priv = dev->dev_private; - DRM_IOREMAPFREE( dev_priv->warp ); - DRM_IOREMAPFREE( dev_priv->primary ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->warp, dev ); + DRM_IOREMAPFREE( dev_priv->primary, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); if ( dev_priv->head != NULL ) { mga_freelist_cleanup( dev ); diff -urN linux-2.4.23-bk13/drivers/char/drm/r128_cce.c linux-2.4.23-bk14/drivers/char/drm/r128_cce.c --- linux-2.4.23-bk13/drivers/char/drm/r128_cce.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/r128_cce.c 2003-12-19 02:52:56.000000000 -0800 @@ -542,9 +542,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cce_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cce_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cce_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -618,9 +618,9 @@ #if __REALLY_HAVE_SG if ( !dev_priv->is_pci ) { #endif - DRM_IOREMAPFREE( dev_priv->cce_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cce_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); #if __REALLY_HAVE_SG } else { if (!DRM(ati_pcigart_cleanup)( dev, diff -urN linux-2.4.23-bk13/drivers/char/drm/radeon_cp.c linux-2.4.23-bk14/drivers/char/drm/radeon_cp.c --- linux-2.4.23-bk13/drivers/char/drm/radeon_cp.c 2003-11-28 10:26:20.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm/radeon_cp.c 2003-12-19 02:52:56.000000000 -0800 @@ -1145,9 +1145,9 @@ init->sarea_priv_offset); if ( !dev_priv->is_pci ) { - DRM_IOREMAP( dev_priv->cp_ring ); - DRM_IOREMAP( dev_priv->ring_rptr ); - DRM_IOREMAP( dev_priv->buffers ); + DRM_IOREMAP( dev_priv->cp_ring, dev ); + DRM_IOREMAP( dev_priv->ring_rptr, dev ); + DRM_IOREMAP( dev_priv->buffers, dev ); if(!dev_priv->cp_ring->handle || !dev_priv->ring_rptr->handle || !dev_priv->buffers->handle) { @@ -1266,9 +1266,9 @@ drm_radeon_private_t *dev_priv = dev->dev_private; if ( !dev_priv->is_pci ) { - DRM_IOREMAPFREE( dev_priv->cp_ring ); - DRM_IOREMAPFREE( dev_priv->ring_rptr ); - DRM_IOREMAPFREE( dev_priv->buffers ); + DRM_IOREMAPFREE( dev_priv->cp_ring, dev ); + DRM_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DRM_IOREMAPFREE( dev_priv->buffers, dev ); } else { #if __REALLY_HAVE_SG if (!DRM(ati_pcigart_cleanup)( dev, diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/bufs.c linux-2.4.23-bk14/drivers/char/drm-4.0/bufs.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/bufs.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/bufs.c 2003-12-19 02:52:56.000000000 -0800 @@ -87,7 +87,7 @@ MTRR_TYPE_WRCOMB, 1); } #endif - map->handle = drm_ioremap(map->offset, map->size); + map->handle = drm_ioremap(map->offset, map->size, dev); break; diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/drmP.h linux-2.4.23-bk14/drivers/char/drm-4.0/drmP.h --- linux-2.4.23-bk13/drivers/char/drm-4.0/drmP.h 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/drmP.h 2003-12-19 02:52:56.000000000 -0800 @@ -679,8 +679,8 @@ extern unsigned long drm_alloc_pages(int order, int area); extern void drm_free_pages(unsigned long address, int order, int area); -extern void *drm_ioremap(unsigned long offset, unsigned long size); -extern void drm_ioremapfree(void *pt, unsigned long size); +extern void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev); +extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev); #if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) extern agp_memory *drm_alloc_agp(int pages, u32 type); diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/ffb_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/ffb_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/ffb_drv.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/ffb_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -158,7 +158,7 @@ switch (map->type) { case _DRM_REGISTERS: case _DRM_FRAME_BUFFER: - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/gamma_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/gamma_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/gamma_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/gamma_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -258,7 +258,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/i810_dma.c linux-2.4.23-bk14/drivers/char/drm-4.0/i810_dma.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/i810_dma.c 2003-06-13 07:51:32.000000000 -0700 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/i810_dma.c 2003-12-19 02:52:56.000000000 -0800 @@ -305,7 +305,7 @@ if(dev_priv->ring.virtual_start) { drm_ioremapfree((void *) dev_priv->ring.virtual_start, - dev_priv->ring.Size); + dev_priv->ring.Size, dev); } if(dev_priv->hw_status_page != 0UL) { i810_free_page(dev, dev_priv->hw_status_page); @@ -319,7 +319,7 @@ for (i = 0; i < dma->buf_count; i++) { drm_buf_t *buf = dma->buflist[ i ]; drm_i810_buf_priv_t *buf_priv = buf->dev_private; - drm_ioremapfree(buf_priv->kernel_virtual, buf->total); + drm_ioremapfree(buf_priv->kernel_virtual, buf->total, dev); } } return 0; @@ -393,7 +393,7 @@ *buf_priv->in_use = I810_BUF_FREE; buf_priv->kernel_virtual = drm_ioremap(buf->bus_address, - buf->total); + buf->total, dev); } return 0; } @@ -430,7 +430,7 @@ dev_priv->ring.virtual_start = drm_ioremap(dev->agp->base + init->ring_start, - init->ring_size); + init->ring_size, dev); dev_priv->ring.tail_mask = dev_priv->ring.Size - 1; diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/i810_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/i810_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/i810_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/i810_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -286,7 +286,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/memory.c linux-2.4.23-bk14/drivers/char/drm-4.0/memory.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/memory.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/memory.c 2003-12-19 02:52:56.000000000 -0800 @@ -296,7 +296,7 @@ } } -void *drm_ioremap(unsigned long offset, unsigned long size) +void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev) { void *pt; @@ -319,7 +319,7 @@ return pt; } -void drm_ioremapfree(void *pt, unsigned long size) +void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev) { int alloc_count; int free_count; diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/mga_dma.c linux-2.4.23-bk14/drivers/char/drm-4.0/mga_dma.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/mga_dma.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/mga_dma.c 2003-12-19 02:52:56.000000000 -0800 @@ -308,7 +308,7 @@ temp = ((temp + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE; dev_priv->ioremap = drm_ioremap(dev->agp->base + offset, - temp); + temp, dev); if(dev_priv->ioremap == NULL) { DRM_ERROR("Ioremap failed\n"); return -ENOMEM; @@ -635,7 +635,7 @@ dev_priv->primary_size + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; - drm_ioremapfree((void *) dev_priv->ioremap, temp); + drm_ioremapfree((void *) dev_priv->ioremap, temp, dev); } if(dev_priv->status_page != NULL) { iounmap(dev_priv->status_page); diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/mga_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/mga_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/mga_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/mga_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -286,7 +286,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/r128_cce.c linux-2.4.23-bk14/drivers/char/drm-4.0/r128_cce.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/r128_cce.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/r128_cce.c 2003-12-19 02:52:56.000000000 -0800 @@ -86,12 +86,12 @@ }; -#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_REMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d)) -#define DO_REMAPFREE(_m) \ +#define DO_REMAPFREE(_m, _d) \ do { \ if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ + drm_ioremapfree((_m)->handle, (_m)->size, (_d)); \ } while (0) #define DO_FIND_MAP(_m, _o) \ @@ -481,12 +481,12 @@ (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_REMAP( dev_priv->cce_ring ); - DO_REMAP( dev_priv->ring_rptr ); - DO_REMAP( dev_priv->buffers ); + DO_REMAP( dev_priv->cce_ring, dev ); + DO_REMAP( dev_priv->ring_rptr, dev ); + DO_REMAP( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAP( dev_priv->agp_textures ); + DO_REMAP( dev_priv->agp_textures, dev ); } #endif @@ -521,12 +521,12 @@ if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; - DO_REMAPFREE( dev_priv->cce_ring ); - DO_REMAPFREE( dev_priv->ring_rptr ); - DO_REMAPFREE( dev_priv->buffers ); + DO_REMAPFREE( dev_priv->cce_ring, dev ); + DO_REMAPFREE( dev_priv->ring_rptr, dev ); + DO_REMAPFREE( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAPFREE( dev_priv->agp_textures ); + DO_REMAPFREE( dev_priv->agp_textures, dev ); } #endif diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/r128_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/r128_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/r128_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/r128_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -296,7 +296,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/radeon_cp.c linux-2.4.23-bk14/drivers/char/drm-4.0/radeon_cp.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/radeon_cp.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/radeon_cp.c 2003-12-19 02:52:56.000000000 -0800 @@ -300,12 +300,12 @@ }; -#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_IOREMAP(_m, _d) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size, (_d)) -#define DO_IOREMAPFREE(_m) \ +#define DO_IOREMAPFREE(_m, _d) \ do { \ if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ + drm_ioremapfree((_m)->handle, (_m)->size, (_d));\ } while (0) #define DO_FIND_MAP(_m, _o) \ @@ -757,12 +757,12 @@ (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_IOREMAP( dev_priv->cp_ring ); - DO_IOREMAP( dev_priv->ring_rptr ); - DO_IOREMAP( dev_priv->buffers ); + DO_IOREMAP( dev_priv->cp_ring, dev ); + DO_IOREMAP( dev_priv->ring_rptr, dev ); + DO_IOREMAP( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAP( dev_priv->agp_textures ); + DO_IOREMAP( dev_priv->agp_textures, dev ); } #endif @@ -828,12 +828,12 @@ if ( dev->dev_private ) { drm_radeon_private_t *dev_priv = dev->dev_private; - DO_IOREMAPFREE( dev_priv->cp_ring ); - DO_IOREMAPFREE( dev_priv->ring_rptr ); - DO_IOREMAPFREE( dev_priv->buffers ); + DO_IOREMAPFREE( dev_priv->cp_ring, dev ); + DO_IOREMAPFREE( dev_priv->ring_rptr, dev ); + DO_IOREMAPFREE( dev_priv->buffers, dev ); #if 0 if ( !dev_priv->is_pci ) { - DO_IOREMAPFREE( dev_priv->agp_textures ); + DO_IOREMAPFREE( dev_priv->agp_textures, dev ); } #endif diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/radeon_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/radeon_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/radeon_drv.c 2002-02-25 11:37:57.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/radeon_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -294,7 +294,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.23-bk13/drivers/char/drm-4.0/tdfx_drv.c linux-2.4.23-bk14/drivers/char/drm-4.0/tdfx_drv.c --- linux-2.4.23-bk13/drivers/char/drm-4.0/tdfx_drv.c 2002-11-28 15:53:12.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/drm-4.0/tdfx_drv.c 2003-12-19 02:52:56.000000000 -0800 @@ -264,7 +264,7 @@ DRM_DEBUG("mtrr_del = %d\n", retcode); } #endif - drm_ioremapfree(map->handle, map->size); + drm_ioremapfree(map->handle, map->size, dev); break; case _DRM_SHM: drm_free_pages((unsigned long)map->handle, diff -urN linux-2.4.23-bk13/drivers/char/efirtc.c linux-2.4.23-bk14/drivers/char/efirtc.c --- linux-2.4.23-bk13/drivers/char/efirtc.c 2003-12-19 02:52:50.000000000 -0800 +++ linux-2.4.23-bk14/drivers/char/efirtc.c 2003-12-19 02:52:56.000000000 -0800 @@ -118,7 +118,7 @@ static void convert_from_efi_time(efi_time_t *eft, struct rtc_time *wtime) { - memset(&wtime, 0, sizeof(struct rtc_time)); + memset(wtime, 0, sizeof(struct rtc_time)); wtime->tm_sec = eft->second; wtime->tm_min = eft->minute; wtime->tm_hour = eft->hour; diff -urN linux-2.4.23-bk13/drivers/input/keybdev.c linux-2.4.23-bk14/drivers/input/keybdev.c --- linux-2.4.23-bk13/drivers/input/keybdev.c 2003-08-25 04:44:42.000000000 -0700 +++ linux-2.4.23-bk14/drivers/input/keybdev.c 2003-12-19 02:52:57.000000000 -0800 @@ -154,16 +154,18 @@ static struct input_handler keybdev_handler; +static unsigned int ledstate = 0xff; + void keybdev_ledfunc(unsigned int led) { struct input_handle *handle; - for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { + ledstate = led; + for (handle = keybdev_handler.handle; handle; handle = handle->hnext) { input_event(handle->dev, EV_LED, LED_SCROLLL, !!(led & 0x01)); input_event(handle->dev, EV_LED, LED_NUML, !!(led & 0x02)); input_event(handle->dev, EV_LED, LED_CAPSL, !!(led & 0x04)); - } } @@ -202,7 +204,12 @@ input_open_device(handle); // printk(KERN_INFO "keybdev.c: Adding keyboard: input%d\n", dev->number); - kbd_refresh_leds(); + + if (ledstate != 0xff) { + input_event(dev, EV_LED, LED_SCROLLL, !!(ledstate & 0x01)); + input_event(dev, EV_LED, LED_NUML, !!(ledstate & 0x02)); + input_event(dev, EV_LED, LED_CAPSL, !!(ledstate & 0x04)); + } return handle; } diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_aops.c linux-2.4.23-bk14/fs/xfs/linux/xfs_aops.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_aops.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_aops.c 2003-12-19 02:52:58.000000000 -0800 @@ -361,6 +361,7 @@ unsigned long p_offset, int block_bits, xfs_iomap_t *iomapp, + int startio, int all_bh) { struct buffer_head *bh = curr; @@ -436,7 +437,7 @@ break; nblocks += bs; atomic_add(bs, &pb->pb_io_remaining); - convert_page(inode, page, iomapp, pb, 1, all_bh); + convert_page(inode, page, iomapp, pb, startio, all_bh); } if (tindex == tlast && @@ -446,7 +447,7 @@ if (page) { nblocks += bs; atomic_add(bs, &pb->pb_io_remaining); - convert_page(inode, page, iomapp, pb, 1, all_bh); + convert_page(inode, page, iomapp, pb, startio, all_bh); } } } @@ -546,7 +547,7 @@ if (buffer_unwritten(bh) && !bh->b_end_io) { ASSERT(tmp->iomap_flags & IOMAP_UNWRITTEN); map_unwritten(inode, page, head, bh, - offset, bbits, tmp, all_bh); + offset, bbits, tmp, startio, all_bh); } else if (! (buffer_unwritten(bh) && buffer_locked(bh))) { map_buffer_at_offset(page, bh, offset, bbits, tmp); if (buffer_unwritten(bh)) { @@ -678,8 +679,8 @@ if (!bh->b_end_io) { err = map_unwritten(inode, page, head, bh, p_offset, - inode->i_blkbits, - iomp, unmapped); + inode->i_blkbits, iomp, + startio, unmapped); if (err) { goto error; } @@ -796,7 +797,7 @@ STATIC int linvfs_get_block_core( struct inode *inode, - sector_t iblock, + long iblock, struct buffer_head *bh_result, int create, int direct, @@ -879,7 +880,7 @@ int linvfs_get_block( struct inode *inode, - sector_t iblock, + long iblock, struct buffer_head *bh_result, int create) { @@ -890,7 +891,7 @@ STATIC int linvfs_get_block_sync( struct inode *inode, - sector_t iblock, + long iblock, struct buffer_head *bh_result, int create) { @@ -901,7 +902,7 @@ STATIC int linvfs_get_block_direct( struct inode *inode, - sector_t iblock, + long iblock, struct buffer_head *bh_result, int create) { @@ -909,10 +910,10 @@ create, 1, BMAPI_WRITE|BMAPI_DIRECT); } -STATIC sector_t +STATIC int linvfs_bmap( struct address_space *mapping, - sector_t block) + long block) { struct inode *inode = (struct inode *)mapping->host; vnode_t *vp = LINVFS_GET_VP(inode); @@ -1116,7 +1117,7 @@ int rw, struct inode *inode, struct kiobuf *iobuf, - sector_t blocknr, + unsigned long blocknr, int blocksize) { struct page **maplist; @@ -1138,7 +1139,7 @@ page_offset = iobuf->offset; map_flags = (rw ? BMAPI_WRITE : BMAPI_READ) | BMAPI_DIRECT; - pb_flags = (rw ? PBF_WRITE : PBF_READ) | PBF_FORCEIO; + pb_flags = (rw ? PBF_WRITE : PBF_READ) | PBF_FORCEIO | PBF_DIRECTIO; while (length) { error = map_blocks(inode, offset, length, &iomap, map_flags); if (error) @@ -1224,21 +1225,6 @@ } -/* since the address_space_operations are not consitent with the type used - * for block indexes we must cast the functions into what is expected.. - * thus the following 2 lines. - * If running on a kernel with LBD support and hence bmap and direct_IO - * correctly defined with sector_t params. use the second set of typedefs - * or casts from the address space_operations - * RMC - */ - -#ifndef HAVE_SECTOR_T -typedef int (bmap_proc)(struct address_space *, long); -typedef int (direct_IO_proc)(int, struct inode *, struct kiobuf *, - unsigned long, int); -#endif - struct address_space_operations linvfs_aops = { .readpage = linvfs_readpage, .writepage = linvfs_writepage, @@ -1246,11 +1232,6 @@ .releasepage = linvfs_release_page, .prepare_write = linvfs_prepare_write, .commit_write = generic_commit_write, -#ifndef HAVE_SECTOR_T - .bmap = (bmap_proc *)linvfs_bmap, - .direct_IO = (direct_IO_proc *)linvfs_direct_IO, -#else .bmap = linvfs_bmap, .direct_IO = linvfs_direct_IO, -#endif }; diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_file.c linux-2.4.23-bk14/fs/xfs/linux/xfs_file.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_file.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_file.c 2003-12-19 02:52:58.000000000 -0800 @@ -58,14 +58,6 @@ static struct vm_operations_struct linvfs_file_vm_ops; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) -#define do_down_read(x) down_read(x) -#define do_up_read(x) up_read(x) -#else -#define do_down_read(x) -#define do_up_read(x) -#endif - STATIC inline ssize_t __linvfs_read( struct file *file, @@ -80,9 +72,9 @@ if (unlikely(file->f_flags & O_DIRECT)) { ioflags |= IO_ISDIRECT; - do_down_read(&inode->i_alloc_sem); + down_read(&inode->i_alloc_sem); VOP_READ(vp, file, buf, size, offset, ioflags, NULL, error); - do_up_read(&inode->i_alloc_sem); + up_read(&inode->i_alloc_sem); } else { VOP_READ(vp, file, buf, size, offset, ioflags, NULL, error); } @@ -144,10 +136,10 @@ */ if (unlikely(file->f_flags & O_DIRECT)) { ioflags |= IO_ISDIRECT; - do_down_read(&inode->i_alloc_sem); + down_read(&inode->i_alloc_sem); VOP_WRITE(vp, file, buf, count, &pos, ioflags, NULL, error); *ppos = pos; - do_up_read(&inode->i_alloc_sem); + up_read(&inode->i_alloc_sem); } else { down(&inode->i_sem); VOP_WRITE(vp, file, buf, count, &pos, ioflags, NULL, error); diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_globals.c linux-2.4.23-bk14/fs/xfs/linux/xfs_globals.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_globals.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_globals.c 2003-12-19 02:52:58.000000000 -0800 @@ -102,10 +102,8 @@ xfs_param_t xfs_params = { /* MIN DFLT MAX */ -#ifdef HAVE_REFCACHE .refcache_size = { 0, 128, XFS_REFCACHE_SIZE_MAX }, .refcache_purge = { 0, 32, XFS_REFCACHE_SIZE_MAX }, -#endif .restrict_chown = { 0, 1, 1 }, .sgid_inherit = { 0, 0, 1 }, .symlink_mode = { 0, 0, 1 }, diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_iops.c linux-2.4.23-bk14/fs/xfs/linux/xfs_iops.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_iops.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_iops.c 2003-12-19 02:52:58.000000000 -0800 @@ -110,7 +110,7 @@ vattr_t va; vnode_t *vp = NULL, *dvp = LINVFS_GET_VP(dir); xfs_acl_t *default_acl = NULL; - xattr_exists_t test_default_acl = _ACL_DEFAULT_EXISTS; + attrexists_t test_default_acl = _ACL_DEFAULT_EXISTS; int error; if (test_default_acl && test_default_acl(dvp)) { @@ -543,61 +543,6 @@ block_truncate_page(inode->i_mapping, inode->i_size, linvfs_get_block); } - - -/* - * Extended attributes interfaces - */ - -#define SYSTEM_NAME "system." /* VFS shared names/values */ -#define ROOT_NAME "trusted." /* root's own names/values */ -#define USER_NAME "user." /* user's own names/values */ -STATIC xattr_namespace_t xfs_namespace_array[] = { - { .name= SYSTEM_NAME, .namelen= sizeof(SYSTEM_NAME)-1,.exists= NULL }, - { .name= ROOT_NAME, .namelen= sizeof(ROOT_NAME)-1, .exists= NULL }, - { .name= USER_NAME, .namelen= sizeof(USER_NAME)-1, .exists= NULL }, - { .name= NULL } -}; -xattr_namespace_t *xfs_namespaces = &xfs_namespace_array[0]; - -#define POSIXACL_ACCESS "posix_acl_access" -#define POSIXACL_ACCESS_SIZE (sizeof(POSIXACL_ACCESS)-1) -#define POSIXACL_DEFAULT "posix_acl_default" -#define POSIXACL_DEFAULT_SIZE (sizeof(POSIXACL_DEFAULT)-1) -#define POSIXCAP "posix_capabilities" -#define POSIXCAP_SIZE (sizeof(POSIXCAP)-1) -#define POSIXMAC "posix_mac" -#define POSIXMAC_SIZE (sizeof(POSIXMAC)-1) -STATIC xattr_namespace_t sys_namespace_array[] = { - { .name= POSIXACL_ACCESS, - .namelen= POSIXACL_ACCESS_SIZE, .exists= _ACL_ACCESS_EXISTS }, - { .name= POSIXACL_DEFAULT, - .namelen= POSIXACL_DEFAULT_SIZE, .exists= _ACL_DEFAULT_EXISTS }, - { .name= POSIXCAP, - .namelen= POSIXCAP_SIZE, .exists= _CAP_EXISTS }, - { .name= POSIXMAC, - .namelen= POSIXMAC_SIZE, .exists= _MAC_EXISTS }, - { .name= NULL } -}; - -/* - * Some checks to prevent people abusing EAs to get over quota: - * - Don't allow modifying user EAs on devices/symlinks; - * - Don't allow modifying user EAs if sticky bit set; - */ -STATIC int -capable_user_xattr( - struct inode *inode) -{ - if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && - !capable(CAP_SYS_ADMIN)) - return 0; - if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && - (current->fsuid != inode->i_uid) && !capable(CAP_FOWNER)) - return 0; - return 1; -} - STATIC int linvfs_setxattr( struct dentry *dentry, @@ -606,59 +551,27 @@ size_t size, int flags) { - struct inode *inode = dentry->d_inode; - vnode_t *vp = LINVFS_GET_VP(inode); - char *p = (char *)name; + vnode_t *vp = LINVFS_GET_VP(dentry->d_inode); + char *attr = (char *)name; + attrnames_t *namesp; int xflags = 0; int error; - if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name, - xfs_namespaces[SYSTEM_NAMES].namelen) == 0) { - error = -EINVAL; - if (flags & XATTR_CREATE) - return error; - error = -EOPNOTSUPP; - p += xfs_namespaces[SYSTEM_NAMES].namelen; - if (strcmp(p, POSIXACL_ACCESS) == 0) - error = xfs_acl_vset(vp, (void *) data, size, - _ACL_TYPE_ACCESS); - else if (strcmp(p, POSIXACL_DEFAULT) == 0) - error = xfs_acl_vset(vp, (void *) data, size, - _ACL_TYPE_DEFAULT); - else if (strcmp(p, POSIXCAP) == 0) - error = xfs_cap_vset(vp, (void *) data, size); - if (!error) - error = vn_revalidate(vp); + namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT); + if (!namesp) + return -EOPNOTSUPP; + attr += namesp->attr_namelen; + error = namesp->attr_capable(vp, NULL); + if (error) return error; - } - - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; /* Convert Linux syscall to XFS internal ATTR flags */ if (flags & XATTR_CREATE) xflags |= ATTR_CREATE; if (flags & XATTR_REPLACE) xflags |= ATTR_REPLACE; - - if (strncmp(name, xfs_namespaces[ROOT_NAMES].name, - xfs_namespaces[ROOT_NAMES].namelen) == 0) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - xflags |= ATTR_ROOT; - p += xfs_namespaces[ROOT_NAMES].namelen; - VOP_ATTR_SET(vp, p, (void *) data, size, xflags, NULL, error); - return -error; - } - if (strncmp(name, xfs_namespaces[USER_NAMES].name, - xfs_namespaces[USER_NAMES].namelen) == 0) { - if (!capable_user_xattr(inode)) - return -EPERM; - p += xfs_namespaces[USER_NAMES].namelen; - VOP_ATTR_SET(vp, p, (void *) data, size, xflags, NULL, error); - return -error; - } - return -EOPNOTSUPP; + xflags |= namesp->attr_flag; + return namesp->attr_set(vp, attr, (void *)data, size, xflags); } STATIC ssize_t @@ -668,96 +581,47 @@ void *data, size_t size) { - struct inode *inode = dentry->d_inode; - vnode_t *vp = LINVFS_GET_VP(inode); - char *p = (char *)name; + vnode_t *vp = LINVFS_GET_VP(dentry->d_inode); + char *attr = (char *)name; + attrnames_t *namesp; int xflags = 0; ssize_t error; - if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name, - xfs_namespaces[SYSTEM_NAMES].namelen) == 0) { - error = -EOPNOTSUPP; - p += xfs_namespaces[SYSTEM_NAMES].namelen; - if (strcmp(p, POSIXACL_ACCESS) == 0) - error = xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); - else if (strcmp(p, POSIXACL_DEFAULT) == 0) - error = xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); - else if (strcmp(p, POSIXCAP) == 0) - error = xfs_cap_vget(vp, data, size); + namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT); + if (!namesp) + return -EOPNOTSUPP; + attr += namesp->attr_namelen; + error = namesp->attr_capable(vp, NULL); + if (error) return error; - } /* Convert Linux syscall to XFS internal ATTR flags */ if (!size) { xflags |= ATTR_KERNOVAL; data = NULL; } - - if (strncmp(name, xfs_namespaces[ROOT_NAMES].name, - xfs_namespaces[ROOT_NAMES].namelen) == 0) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - xflags |= ATTR_ROOT; - p += xfs_namespaces[ROOT_NAMES].namelen; - VOP_ATTR_GET(vp, p, data, (int *)&size, xflags, NULL, error); - if (!error) - error = -size; - return -error; - } - if (strncmp(name, xfs_namespaces[USER_NAMES].name, - xfs_namespaces[USER_NAMES].namelen) == 0) { - p += xfs_namespaces[USER_NAMES].namelen; - if (!capable_user_xattr(inode)) - return -EPERM; - VOP_ATTR_GET(vp, p, data, (int *)&size, xflags, NULL, error); - if (!error) - error = -size; - return -error; - } - return -EOPNOTSUPP; + xflags |= namesp->attr_flag; + return namesp->attr_get(vp, attr, (void *)data, size, xflags); } - STATIC ssize_t linvfs_listxattr( struct dentry *dentry, char *data, size_t size) { - attrlist_cursor_kern_t cursor; - xattr_namespace_t *sys; vnode_t *vp = LINVFS_GET_VP(dentry->d_inode); - char *k = data; - int xflags = ATTR_KERNAMELS; - int result = 0; - ssize_t error; + int error, xflags = ATTR_KERNAMELS; + ssize_t result; if (!size) xflags |= ATTR_KERNOVAL; if (capable(CAP_SYS_ADMIN)) xflags |= ATTR_KERNFULLS; - memset(&cursor, 0, sizeof(cursor)); - VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); - if (error > 0) - return -error; - result += -error; - - k += result; /* advance start of our buffer */ - for (sys = &sys_namespace_array[0]; sys->name != NULL; sys++) { - if (sys->exists == NULL || !sys->exists(vp)) - continue; - result += xfs_namespaces[SYSTEM_NAMES].namelen; - result += sys->namelen + 1; - if (size) { - if (result > size) - return -ERANGE; - strcpy(k, xfs_namespaces[SYSTEM_NAMES].name); - k += xfs_namespaces[SYSTEM_NAMES].namelen; - strcpy(k, sys->name); - k += sys->namelen + 1; - } - } + error = attr_generic_list(vp, data, size, xflags, &result); + if (error < 0) + return error; return result; } @@ -766,51 +630,25 @@ struct dentry *dentry, const char *name) { - struct inode *inode = dentry->d_inode; - vnode_t *vp = LINVFS_GET_VP(inode); - char *p = (char *)name; + vnode_t *vp = LINVFS_GET_VP(dentry->d_inode); + char *attr = (char *)name; + attrnames_t *namesp; int xflags = 0; int error; - if (strncmp(name, xfs_namespaces[SYSTEM_NAMES].name, - xfs_namespaces[SYSTEM_NAMES].namelen) == 0) { - error = -EOPNOTSUPP; - p += xfs_namespaces[SYSTEM_NAMES].namelen; - if (strcmp(p, POSIXACL_ACCESS) == 0) - error = xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); - else if (strcmp(p, POSIXACL_DEFAULT) == 0) - error = xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); - else if (strcmp(p, POSIXCAP) == 0) - error = xfs_cap_vremove(vp); + namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT); + if (!namesp) + return -EOPNOTSUPP; + attr += namesp->attr_namelen; + error = namesp->attr_capable(vp, NULL); + if (error) return error; - } - - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - return -EPERM; - - if (strncmp(name, xfs_namespaces[ROOT_NAMES].name, - xfs_namespaces[ROOT_NAMES].namelen) == 0) { - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - xflags |= ATTR_ROOT; - p += xfs_namespaces[ROOT_NAMES].namelen; - VOP_ATTR_REMOVE(vp, p, xflags, NULL, error); - return -error; - } - if (strncmp(name, xfs_namespaces[USER_NAMES].name, - xfs_namespaces[USER_NAMES].namelen) == 0) { - p += xfs_namespaces[USER_NAMES].namelen; - if (!capable_user_xattr(inode)) - return -EPERM; - VOP_ATTR_REMOVE(vp, p, xflags, NULL, error); - return -error; - } - return -EOPNOTSUPP; + xflags |= namesp->attr_flag; + return namesp->attr_remove(vp, attr, xflags); } -struct inode_operations linvfs_file_inode_operations = -{ +struct inode_operations linvfs_file_inode_operations = { .permission = linvfs_permission, .truncate = linvfs_truncate, .revalidate = linvfs_revalidate, @@ -821,8 +659,7 @@ .removexattr = linvfs_removexattr, }; -struct inode_operations linvfs_dir_inode_operations = -{ +struct inode_operations linvfs_dir_inode_operations = { .create = linvfs_create, .lookup = linvfs_lookup, .link = linvfs_link, @@ -841,8 +678,7 @@ .removexattr = linvfs_removexattr, }; -struct inode_operations linvfs_symlink_inode_operations = -{ +struct inode_operations linvfs_symlink_inode_operations = { .readlink = linvfs_readlink, .follow_link = linvfs_follow_link, .permission = linvfs_permission, diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_iops.h linux-2.4.23-bk14/fs/xfs/linux/xfs_iops.h --- linux-2.4.23-bk13/fs/xfs/linux/xfs_iops.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_iops.h 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -32,30 +32,6 @@ #ifndef __XFS_IOPS_H__ #define __XFS_IOPS_H__ -/* - * Extended system attributes. - * So far only POSIX ACLs are supported, but this will need to - * grow in time (capabilities, mandatory access control, etc). - */ -#define XFS_SYSTEM_NAMESPACE SYSTEM_POSIXACL - -/* - * Define a table of the namespaces XFS supports - */ -typedef int (*xattr_exists_t)(vnode_t *); - -typedef struct xattr_namespace { - char *name; - unsigned int namelen; - xattr_exists_t exists; -} xattr_namespace_t; - -#define SYSTEM_NAMES 0 -#define ROOT_NAMES 1 -#define USER_NAMES 2 -extern struct xattr_namespace *xfs_namespaces; - - extern struct inode_operations linvfs_file_inode_operations; extern struct inode_operations linvfs_dir_inode_operations; extern struct inode_operations linvfs_symlink_inode_operations; @@ -66,7 +42,7 @@ extern struct address_space_operations linvfs_aops; -extern int linvfs_get_block(struct inode *, sector_t, struct buffer_head *, int); +extern int linvfs_get_block(struct inode *, long, struct buffer_head *, int); extern void linvfs_unwritten_done(struct buffer_head *, int); extern int xfs_ioctl(struct bhv_desc *, struct inode *, struct file *, diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_linux.h linux-2.4.23-bk14/fs/xfs/linux/xfs_linux.h --- linux-2.4.23-bk13/fs/xfs/linux/xfs_linux.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_linux.h 2003-12-19 02:52:58.000000000 -0800 @@ -32,6 +32,34 @@ #ifndef __XFS_LINUX__ #define __XFS_LINUX__ +#include +#include + +/* + * Some types are conditional depending on the target system. + * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits. + * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well + * as requiring XFS_BIG_BLKNOS to be set. + */ +#define XFS_BIG_BLKNOS 0 +#define XFS_BIG_INUMS 0 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -55,10 +83,6 @@ #include #include -#ifndef HAVE_SECTOR_T -typedef long sector_t; /* offset- or number- of disk blocks */ -#endif - #include #include #include @@ -97,10 +121,7 @@ { bh->b_end_io = linvfs_unwritten_done; } - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,17) BUFFER_FNS(Unwritten, unwritten) -#endif #define xfs_refcache_size xfs_params.refcache_size.val #define xfs_refcache_purge_count xfs_params.refcache_purge.val @@ -220,18 +241,30 @@ #define howmany(x, y) (((x)+((y)-1))/(y)) #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) -/* dump_stack() showed up in 2.4.20, show_stack is arch-specific */ +/* + * Juggle IRIX device numbers - still used in ondisk structures + */ +#define XFS_DEV_BITSMAJOR 14 +#define XFS_DEV_BITSMINOR 18 +#define XFS_DEV_MAXMAJ 0x1ff +#define XFS_DEV_MAXMIN 0x3ffff +#define XFS_DEV_MAJOR(dev) ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \ + & XFS_DEV_MAXMAJ)) +#define XFS_DEV_MINOR(dev) ((int)((dev)&XFS_DEV_MAXMIN)) +#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<= KERNEL_VERSION(2,4,20) dump_stack(); -#else -# if defined(CONFIG_X86) || defined(CONFIG_X86_64) - show_stack(0); -# endif -#endif } + /* Move the kernel do_div definition off to one side */ #if defined __i386__ diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_lrw.c linux-2.4.23-bk14/fs/xfs/linux/xfs_lrw.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_lrw.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_lrw.c 2003-12-19 02:52:58.000000000 -0800 @@ -321,16 +321,12 @@ } } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) if (unlikely(ioflags & IO_ISDIRECT)) { ret = do_generic_direct_read(file, buf, size, offset); UPDATE_ATIME(file->f_dentry->d_inode); } else { ret = generic_file_read(file, buf, size, offset); } -#else - ret = generic_file_read(file, buf, size, offset); -#endif if (!(ioflags & IO_ISLOCKED)) xfs_iunlock(ip, XFS_IOLOCK_SHARED); @@ -713,7 +709,6 @@ } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) if ((ssize_t) size < 0) { ret = -EINVAL; goto error; @@ -735,13 +730,6 @@ io, buf, size, *offset, ioflags); ret = do_generic_file_write(file, buf, size, offset); } -#else -retry: - if (ioflags & IO_ISDIRECT) { - xfs_inval_cached_pages(vp, io, *offset, 1, 1); - } - ret = generic_file_write_nolock(file, buf, size, offset); -#endif if (unlikely(ioflags & IO_INVIS)) { /* generic_file_write updates the mtime/ctime but we need @@ -770,9 +758,7 @@ goto retry; } -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) error: -#endif if (ret <= 0) { if (iolock) xfs_rwunlock(bdp, locktype); diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_super.c linux-2.4.23-bk14/fs/xfs/linux/xfs_super.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_super.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_super.c 2003-12-19 02:52:58.000000000 -0800 @@ -116,13 +116,7 @@ */ #if BITS_PER_LONG == 32 -# if defined(CONFIG_LBD) - ASSERT(sizeof(sector_t) == 8); - pagefactor = PAGE_CACHE_SIZE; - bitshift = BITS_PER_LONG; -# else pagefactor = PAGE_CACHE_SIZE >> (PAGE_CACHE_SHIFT - blockshift); -# endif #endif return (((__uint64_t)pagefactor) << bitshift) - 1; diff -urN linux-2.4.23-bk13/fs/xfs/linux/xfs_sysctl.c linux-2.4.23-bk14/fs/xfs/linux/xfs_sysctl.c --- linux-2.4.23-bk13/fs/xfs/linux/xfs_sysctl.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/linux/xfs_sysctl.c 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2001-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -41,7 +41,6 @@ /* Custom proc handlers */ -#ifdef HAVE_REFCACHE STATIC int xfs_refcache_resize_proc_handler( ctl_table *ctl, @@ -66,7 +65,6 @@ return ret; } -#endif #ifdef CONFIG_PROC_FS STATIC int @@ -96,8 +94,6 @@ #endif /* CONFIG_PROC_FS */ STATIC ctl_table xfs_table[] = { - -#ifdef HAVE_REFCACHE {XFS_REFCACHE_SIZE, "refcache_size", &xfs_params.refcache_size.val, sizeof(int), 0644, NULL, &xfs_refcache_resize_proc_handler, &sysctl_intvec, NULL, @@ -108,7 +104,6 @@ sizeof(int), 0644, NULL, &proc_dointvec_minmax, &sysctl_intvec, NULL, &xfs_params.refcache_purge.min, &xfs_params.refcache_size.val}, -#endif {XFS_RESTRICT_CHOWN, "restrict_chown", &xfs_params.restrict_chown.val, sizeof(int), 0644, NULL, &proc_dointvec_minmax, diff -urN linux-2.4.23-bk13/fs/xfs/pagebuf/page_buf.c linux-2.4.23-bk14/fs/xfs/pagebuf/page_buf.c --- linux-2.4.23-bk13/fs/xfs/pagebuf/page_buf.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/pagebuf/page_buf.c 2003-12-19 02:52:58.000000000 -0800 @@ -417,9 +417,6 @@ page_cache_release(page); } } - - if (pb->pb_pages != pb->pb_page_array) - kfree(pb->pb_pages); } /* @@ -458,20 +455,17 @@ if (pb->pb_flags & _PBF_MEM_ALLOCATED) { if (pb->pb_pages) { /* release the pages in the address list */ - if (pb->pb_pages[0] && - PageSlab(pb->pb_pages[0])) { - /* - * This came from the slab - * allocator free it as such - */ + if ((pb->pb_pages[0]) && + (pb->pb_flags & _PBF_MEM_SLAB)) { kfree(pb->pb_addr); } else { _pagebuf_freepages(pb); } - + if (pb->pb_pages != pb->pb_page_array) + kfree(pb->pb_pages); pb->pb_pages = NULL; } - pb->pb_flags &= ~_PBF_MEM_ALLOCATED; + pb->pb_flags &= ~(_PBF_MEM_ALLOCATED|_PBF_MEM_SLAB); } } @@ -847,7 +841,8 @@ _PBF_LOCKABLE | \ _PBF_ALL_PAGES_MAPPED | \ _PBF_ADDR_ALLOCATED | \ - _PBF_MEM_ALLOCATED; + _PBF_MEM_ALLOCATED | \ + _PBF_MEM_SLAB; PB_TRACE(pb, "got_lock", 0); PB_STATS_INC(pb_get_locked); return (pb); @@ -927,6 +922,7 @@ PB_STATS_INC(pb_get_read); pagebuf_iostart(pb, flags); } else if (flags & PBF_ASYNC) { + PB_TRACE(pb, "get_read_async", (unsigned long)flags); /* * Read ahead call which is already satisfied, * drop the buffer @@ -936,12 +932,13 @@ pagebuf_rele(pb); return NULL; } else { + PB_TRACE(pb, "get_read_done", (unsigned long)flags); /* We do not want read in the flags */ pb->pb_flags &= ~PBF_READ; } + } else { + PB_TRACE(pb, "get_write", (unsigned long)flags); } - - PB_TRACE(pb, "get_done", (unsigned long)flags); return (pb); } @@ -1067,8 +1064,8 @@ page_buf_t *pb; size_t tlen = 0; - if (len > 0x20000) - return(NULL); + if (unlikely(len > 0x20000)) + return NULL; pb = pagebuf_allocate(flags); if (!pb) @@ -1095,7 +1092,7 @@ return NULL; } /* otherwise pagebuf_free just ignores it */ - pb->pb_flags |= _PBF_MEM_ALLOCATED; + pb->pb_flags |= (_PBF_MEM_ALLOCATED | _PBF_MEM_SLAB); PB_CLEAR_OWNER(pb); up(&pb->pb_sema); /* Return unlocked pagebuf */ diff -urN linux-2.4.23-bk13/fs/xfs/pagebuf/page_buf.h linux-2.4.23-bk14/fs/xfs/pagebuf/page_buf.h --- linux-2.4.23-bk13/fs/xfs/pagebuf/page_buf.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/pagebuf/page_buf.h 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -93,12 +93,14 @@ _PBF_PRIVATE_BH = (1 << 17), /* do not use public buffer heads */ _PBF_ALL_PAGES_MAPPED = (1 << 18), /* all pages in range mapped */ _PBF_ADDR_ALLOCATED = (1 << 19), /* pb_addr space was allocated */ - _PBF_MEM_ALLOCATED = (1 << 20), /* pb_mem+underlying pages alloc'd */ + _PBF_MEM_ALLOCATED = (1 << 20), /* underlying pages are allocated */ + _PBF_MEM_SLAB = (1 << 21), /* underlying pages are slab allocated */ - PBF_FORCEIO = (1 << 21), - PBF_FLUSH = (1 << 22), /* flush disk write cache */ - PBF_READ_AHEAD = (1 << 23), - PBF_RUN_QUEUES = (1 << 24), /* run block device task queue */ + PBF_FORCEIO = (1 << 22), /* ignore any cache state */ + PBF_FLUSH = (1 << 23), /* flush disk write cache */ + PBF_READ_AHEAD = (1 << 24), /* asynchronous read-ahead */ + PBF_RUN_QUEUES = (1 << 25), /* run block device task queue */ + PBF_DIRECTIO = (1 << 26), /* used for a direct IO mapping */ } page_buf_flags_t; @@ -338,6 +340,7 @@ # define pagebuf_trace(pb, id, ptr, ra) do { } while (0) #endif +#define pagebuf_target_name(target) bdevname((target)->pbr_kdev) /* * Kernel version compatibility macros diff -urN linux-2.4.23-bk13/fs/xfs/quota/xfs_dquot.c linux-2.4.23-bk14/fs/xfs/quota/xfs_dquot.c --- linux-2.4.23-bk13/fs/xfs/quota/xfs_dquot.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/quota/xfs_dquot.c 2003-12-19 02:52:58.000000000 -0800 @@ -1508,7 +1508,7 @@ */ ASSERT(XFS_DQ_IS_ON_FREELIST(dqp)); - dqp->q_mount = NULL;; + dqp->q_mount = NULL; dqp->q_hash = NULL; dqp->dq_flags = XFS_DQ_INACTIVE; memset(&dqp->q_core, 0, sizeof(dqp->q_core)); diff -urN linux-2.4.23-bk13/fs/xfs/support/uuid.c linux-2.4.23-bk14/fs/xfs/support/uuid.c --- linux-2.4.23-bk13/fs/xfs/support/uuid.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/support/uuid.c 2003-12-19 02:52:58.000000000 -0800 @@ -30,9 +30,7 @@ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ */ -#include -#include -#include +#include #include "time.h" #include "uuid.h" #include "kmem.h" diff -urN linux-2.4.23-bk13/fs/xfs/xfs.h linux-2.4.23-bk14/fs/xfs/xfs.h --- linux-2.4.23-bk13/fs/xfs/xfs.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs.h 2003-12-19 02:52:58.000000000 -0800 @@ -32,25 +32,6 @@ #ifndef __XFS_H__ #define __XFS_H__ -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - #include #include diff -urN linux-2.4.23-bk13/fs/xfs/xfs_acl.h linux-2.4.23-bk14/fs/xfs/xfs_acl.h --- linux-2.4.23-bk13/fs/xfs/xfs_acl.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_acl.h 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2001-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -102,6 +102,8 @@ #define xfs_acl_vset(v,p,sz,t) (-EOPNOTSUPP) #define xfs_acl_vget(v,p,sz,t) (-EOPNOTSUPP) #define xfs_acl_vremove(v,t) (-EOPNOTSUPP) +#define xfs_acl_vhasacl_access(v) (0) +#define xfs_acl_vhasacl_default(v) (0) #define _ACL_DECL(a) ((void)0) #define _ACL_ALLOC(a) (1) /* successfully allocate nothing */ #define _ACL_FREE(a) ((void)0) diff -urN linux-2.4.23-bk13/fs/xfs/xfs_attr.c linux-2.4.23-bk14/fs/xfs/xfs_attr.c --- linux-2.4.23-bk13/fs/xfs/xfs_attr.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_attr.c 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -63,6 +63,7 @@ #include "xfs_quota.h" #include "xfs_rw.h" #include "xfs_trans_space.h" +#include "xfs_acl.h" /* * xfs_attr.c @@ -2357,3 +2358,307 @@ (void *)a14, (void *)a15); } #endif /* XFS_ATTR_TRACE */ + + +/*======================================================================== + * System (pseudo) namespace attribute interface routines. + *========================================================================*/ + +STATIC int +posix_acl_access_set( + vnode_t *vp, char *name, void *data, size_t size, int xflags) +{ + return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS); +} + +STATIC int +posix_acl_access_remove( + struct vnode *vp, char *name, int xflags) +{ + return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS); +} + +STATIC int +posix_acl_access_get( + vnode_t *vp, char *name, void *data, size_t size, int xflags) +{ + return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS); +} + +STATIC int +posix_acl_access_exists( + vnode_t *vp) +{ + return xfs_acl_vhasacl_access(vp); +} + +STATIC int +posix_acl_default_set( + vnode_t *vp, char *name, void *data, size_t size, int xflags) +{ + return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT); +} + +STATIC int +posix_acl_default_get( + vnode_t *vp, char *name, void *data, size_t size, int xflags) +{ + return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT); +} + +STATIC int +posix_acl_default_remove( + struct vnode *vp, char *name, int xflags) +{ + return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT); +} + +STATIC int +posix_acl_default_exists( + vnode_t *vp) +{ + return xfs_acl_vhasacl_default(vp); +} + +struct attrnames posix_acl_access = { + .attr_name = "posix_acl_access", + .attr_namelen = sizeof("posix_acl_access") - 1, + .attr_get = posix_acl_access_get, + .attr_set = posix_acl_access_set, + .attr_remove = posix_acl_access_remove, + .attr_exists = posix_acl_access_exists, +}; + +struct attrnames posix_acl_default = { + .attr_name = "posix_acl_default", + .attr_namelen = sizeof("posix_acl_default") - 1, + .attr_get = posix_acl_default_get, + .attr_set = posix_acl_default_set, + .attr_remove = posix_acl_default_remove, + .attr_exists = posix_acl_default_exists, +}; + +struct attrnames *attr_system_names[] = + { &posix_acl_access, &posix_acl_default }; + + +/*======================================================================== + * Namespace-prefix-style attribute name interface routines. + *========================================================================*/ + +STATIC int +attr_generic_set( + struct vnode *vp, char *name, void *data, size_t size, int xflags) +{ + int error; + + VOP_ATTR_SET(vp, name, data, size, xflags, NULL, error); + return -error; +} + +STATIC int +attr_generic_get( + struct vnode *vp, char *name, void *data, size_t size, int xflags) +{ + int error, asize = size; + + VOP_ATTR_GET(vp, name, data, &asize, xflags, NULL, error); + if (!error) + return asize; + return -error; +} + +STATIC int +attr_generic_remove( + struct vnode *vp, char *name, int xflags) +{ + int error; + + VOP_ATTR_REMOVE(vp, name, xflags, NULL, error); + return -error; +} + +STATIC int +attr_generic_listadd( + attrnames_t *prefix, + attrnames_t *namesp, + void *data, + size_t size, + ssize_t *result) +{ + char *p = data + *result; + + *result += prefix->attr_namelen; + *result += namesp->attr_namelen + 1; + if (!size) + return 0; + if (*result > size) + return -ERANGE; + strcpy(p, prefix->attr_name); + p += prefix->attr_namelen; + strcpy(p, namesp->attr_name); + p += namesp->attr_namelen + 1; + return 0; +} + +STATIC int +attr_system_list( + struct vnode *vp, + void *data, + size_t size, + ssize_t *result) +{ + attrnames_t *namesp; + int i, error = 0; + + for (i = 0; i < ATTR_SYSCOUNT; i++) { + namesp = attr_system_names[i]; + if (!namesp->attr_exists || !namesp->attr_exists(vp)) + continue; + error = attr_generic_listadd(&attr_system, namesp, + data, size, result); + if (error) + break; + } + return error; +} + +int +attr_generic_list( + struct vnode *vp, void *data, size_t size, int xflags, ssize_t *result) +{ + attrlist_cursor_kern_t cursor = { 0 }; + int error; + + VOP_ATTR_LIST(vp, data, size, xflags, &cursor, NULL, error); + if (error > 0) + return -error; + *result = -error; + return attr_system_list(vp, data, size, result); +} + +attrnames_t * +attr_lookup_namespace( + char *name, + struct attrnames **names, + int nnames) +{ + int i; + + for (i = 0; i < nnames; i++) + if (!strncmp(name, names[i]->attr_name, names[i]->attr_namelen)) + return names[i]; + return NULL; +} + +/* + * Some checks to prevent people abusing EAs to get over quota: + * - Don't allow modifying user EAs on devices/symlinks; + * - Don't allow modifying user EAs if sticky bit set; + */ +STATIC int +attr_user_capable( + struct vnode *vp, + cred_t *cred) +{ + struct inode *inode = LINVFS_GET_IP(vp); + + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + return -EPERM; + if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) && + !capable(CAP_SYS_ADMIN)) + return -EPERM; + if (S_ISDIR(inode->i_mode) && (inode->i_mode & S_ISVTX) && + (current_fsuid(cred) != inode->i_uid) && !capable(CAP_FOWNER)) + return -EPERM; + return 0; +} + +STATIC int +attr_trusted_capable( + struct vnode *vp, + cred_t *cred) +{ + struct inode *inode = LINVFS_GET_IP(vp); + + if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) + return -EPERM; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + return 0; +} + +STATIC int +attr_system_set( + struct vnode *vp, char *name, void *data, size_t size, int xflags) +{ + attrnames_t *namesp; + int error; + + if (xflags & ATTR_CREATE) + return -EINVAL; + + namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT); + if (!namesp) + return -EOPNOTSUPP; + error = namesp->attr_set(vp, name, data, size, xflags); + if (!error) + error = vn_revalidate(vp); + return error; +} + +STATIC int +attr_system_get( + struct vnode *vp, char *name, void *data, size_t size, int xflags) +{ + attrnames_t *namesp; + + namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT); + if (!namesp) + return -EOPNOTSUPP; + return namesp->attr_get(vp, name, data, size, xflags); +} + +STATIC int +attr_system_remove( + struct vnode *vp, char *name, int xflags) +{ + attrnames_t *namesp; + + namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT); + if (!namesp) + return -EOPNOTSUPP; + return namesp->attr_remove(vp, name, xflags); +} + +struct attrnames attr_system = { + .attr_name = "system.", + .attr_namelen = sizeof("system.") - 1, + .attr_flag = ATTR_SYSTEM, + .attr_get = attr_system_get, + .attr_set = attr_system_set, + .attr_remove = attr_system_remove, + .attr_capable = (attrcapable_t)fs_noerr, +}; + +struct attrnames attr_trusted = { + .attr_name = "trusted.", + .attr_namelen = sizeof("trusted.") - 1, + .attr_flag = ATTR_ROOT, + .attr_get = attr_generic_get, + .attr_set = attr_generic_set, + .attr_remove = attr_generic_remove, + .attr_capable = attr_trusted_capable, +}; + +struct attrnames attr_user = { + .attr_name = "user.", + .attr_namelen = sizeof("user.") - 1, + .attr_get = attr_generic_get, + .attr_set = attr_generic_set, + .attr_remove = attr_generic_remove, + .attr_capable = attr_user_capable, +}; + +struct attrnames *attr_namespaces[] = + { &attr_system, &attr_trusted, &attr_user }; diff -urN linux-2.4.23-bk13/fs/xfs/xfs_attr.h linux-2.4.23-bk14/fs/xfs/xfs_attr.h --- linux-2.4.23-bk13/fs/xfs/xfs_attr.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_attr.h 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -49,9 +49,46 @@ * External interfaces *========================================================================*/ -#define ATTR_ROOT 0x0002 /* use attrs in root namespace, not user */ +struct cred; +struct vnode; + +typedef int (*attrset_t)(struct vnode *, char *, void *, size_t, int); +typedef int (*attrget_t)(struct vnode *, char *, void *, size_t, int); +typedef int (*attrremove_t)(struct vnode *, char *, int); +typedef int (*attrexists_t)(struct vnode *); +typedef int (*attrcapable_t)(struct vnode *, struct cred *); + +typedef struct attrnames { + char * attr_name; + unsigned int attr_namelen; + unsigned int attr_flag; + attrget_t attr_get; + attrset_t attr_set; + attrremove_t attr_remove; + attrexists_t attr_exists; + attrcapable_t attr_capable; +} attrnames_t; + +#define ATTR_NAMECOUNT 3 +extern struct attrnames attr_user; +extern struct attrnames attr_system; +extern struct attrnames attr_trusted; +extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT]; + +#define ATTR_SYSCOUNT 2 +extern struct attrnames posix_acl_access; +extern struct attrnames posix_acl_default; +extern struct attrnames *attr_system_names[ATTR_SYSCOUNT]; + +extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int); +extern int attr_generic_list(struct vnode *, void *, size_t, int, ssize_t *); + +#define ATTR_DONTFOLLOW 0x0001 /* -- unused, from IRIX -- */ +#define ATTR_ROOT 0x0002 /* use attrs in root (trusted) namespace */ +#define ATTR_TRUST 0x0004 /* -- unused, from IRIX -- */ #define ATTR_CREATE 0x0010 /* pure create: fail if attr already exists */ #define ATTR_REPLACE 0x0020 /* pure set: fail if attr does not exist */ +#define ATTR_SYSTEM 0x0100 /* use attrs in system (pseudo) namespace */ #define ATTR_KERNOTIME 0x1000 /* [kernel] don't update inode timestamps */ #define ATTR_KERNOVAL 0x2000 /* [kernel] get attr size only, not value */ #define ATTR_KERNAMELS 0x4000 /* [kernel] list attr names (simple list) */ @@ -126,11 +163,8 @@ * Function prototypes for the kernel. *========================================================================*/ -struct cred; -struct vnode; struct xfs_inode; struct attrlist_cursor_kern; -struct xfs_ext_attr; struct xfs_da_args; /* diff -urN linux-2.4.23-bk13/fs/xfs/xfs_attr_leaf.c linux-2.4.23-bk14/fs/xfs/xfs_attr_leaf.c --- linux-2.4.23-bk13/fs/xfs/xfs_attr_leaf.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_attr_leaf.c 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -444,8 +444,10 @@ < context->bufsize) { for (i = 0, sfe = &sf->list[0]; i < INT_GET(sf->hdr.count, ARCH_CONVERT); i++) { - int ns = (sfe->flags & XFS_ATTR_ROOT)? - ROOT_NAMES : USER_NAMES; + attrnames_t *namesp; + + namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : + &attr_user; if (((context->flags & ATTR_ROOT) != 0) != ((sfe->flags & XFS_ATTR_ROOT) != 0) && !(context->flags & ATTR_KERNFULLS)) { @@ -454,11 +456,11 @@ } if (context->flags & ATTR_KERNOVAL) { ASSERT(context->flags & ATTR_KERNAMELS); - context->count += xfs_namespaces[ns].namelen + + context->count += namesp->attr_namelen + INT_GET(sfe->namelen, ARCH_CONVERT) + 1; } else { - if (xfs_attr_put_listent(context, ns, + if (xfs_attr_put_listent(context, namesp, (char *)sfe->nameval, (int)sfe->namelen, (int)INT_GET(sfe->valuelen, @@ -544,18 +546,22 @@ * Loop putting entries into the user buffer. */ for ( ; i < nsbuf; i++, sbp++) { - int ns = (sbp->flags & XFS_ATTR_ROOT)? ROOT_NAMES:USER_NAMES; + attrnames_t *namesp; + + namesp = (sfe->flags & XFS_ATTR_ROOT) ? &attr_trusted : + &attr_user; + if (cursor->hashval != INT_GET(sbp->hash, ARCH_CONVERT)) { cursor->hashval = INT_GET(sbp->hash, ARCH_CONVERT); cursor->offset = 0; } if (context->flags & ATTR_KERNOVAL) { ASSERT(context->flags & ATTR_KERNAMELS); - context->count += xfs_namespaces[ns].namelen - + sbp->namelen + 1; + context->count += namesp->attr_namelen + + sbp->namelen + 1; } else { - if (xfs_attr_put_listent(context, ns, + if (xfs_attr_put_listent(context, namesp, sbp->name, sbp->namelen, INT_GET(sbp->valuelen, ARCH_CONVERT))) break; @@ -2270,7 +2276,7 @@ retval = 0; for ( ; (i < INT_GET(leaf->hdr.count, ARCH_CONVERT)) && (retval == 0); entry++, i++) { - int ns = (entry->flags & XFS_ATTR_ROOT)? ROOT_NAMES:USER_NAMES; + attrnames_t *namesp; if (INT_GET(entry->hashval, ARCH_CONVERT) != cursor->hashval) { cursor->hashval = INT_GET(entry->hashval, ARCH_CONVERT); @@ -2284,14 +2290,17 @@ !(context->flags & ATTR_KERNFULLS)) continue; /* skip non-matching entries */ + namesp = (entry->flags & XFS_ATTR_ROOT) ? &attr_trusted : + &attr_user; + if (entry->flags & XFS_ATTR_LOCAL) { name_loc = XFS_ATTR_LEAF_NAME_LOCAL(leaf, i); if (context->flags & ATTR_KERNOVAL) { ASSERT(context->flags & ATTR_KERNAMELS); - context->count += xfs_namespaces[ns].namelen - + (int)name_loc->namelen + 1; + context->count += namesp->attr_namelen + + (int)name_loc->namelen + 1; } else { - retval = xfs_attr_put_listent(context, ns, + retval = xfs_attr_put_listent(context, namesp, (char *)name_loc->nameval, (int)name_loc->namelen, (int)INT_GET(name_loc->valuelen, @@ -2301,10 +2310,10 @@ name_rmt = XFS_ATTR_LEAF_NAME_REMOTE(leaf, i); if (context->flags & ATTR_KERNOVAL) { ASSERT(context->flags & ATTR_KERNAMELS); - context->count += xfs_namespaces[ns].namelen - + (int)name_rmt->namelen + 1; + context->count += namesp->attr_namelen + + (int)name_rmt->namelen + 1; } else { - retval = xfs_attr_put_listent(context, ns, + retval = xfs_attr_put_listent(context, namesp, (char *)name_rmt->name, (int)name_rmt->namelen, (int)INT_GET(name_rmt->valuelen, @@ -2333,7 +2342,7 @@ /*ARGSUSED*/ int xfs_attr_put_listent(xfs_attr_list_context_t *context, - int ns, char *name, int namelen, int valuelen) + attrnames_t *namesp, char *name, int namelen, int valuelen) { attrlist_ent_t *aep; int arraytop; @@ -2341,23 +2350,21 @@ ASSERT(!(context->flags & ATTR_KERNOVAL)); if (context->flags & ATTR_KERNAMELS) { char *offset; - xattr_namespace_t *nsp; ASSERT(context->count >= 0); - nsp = &xfs_namespaces[ns]; - arraytop = context->count + nsp->namelen + namelen+1; + arraytop = context->count + namesp->attr_namelen + namelen + 1; if (arraytop > context->firstu) { context->count = -1; /* insufficient space */ return(1); } offset = (char *)context->alist + context->count; - strncpy(offset, nsp->name, nsp->namelen); /* namespace */ - offset += nsp->namelen; + strncpy(offset, namesp->attr_name, namesp->attr_namelen); + offset += namesp->attr_namelen; strncpy(offset, name, namelen); /* real name */ offset += namelen; *offset = '\0'; - context->count += nsp->namelen + namelen + 1; + context->count += namesp->attr_namelen + namelen + 1; return(0); } diff -urN linux-2.4.23-bk13/fs/xfs/xfs_attr_leaf.h linux-2.4.23-bk14/fs/xfs/xfs_attr_leaf.h --- linux-2.4.23-bk13/fs/xfs/xfs_attr_leaf.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_attr_leaf.h 2003-12-19 02:52:58.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2002 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (c) 2000, 2002-2003 Silicon Graphics, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as @@ -44,6 +44,7 @@ struct attrlist; struct attrlist_cursor_kern; +struct attrnames; struct xfs_dabuf; struct xfs_da_args; struct xfs_da_state; @@ -128,7 +129,7 @@ * on the system call, they are "or"ed together for various operations. */ #define XFS_ATTR_LOCAL_BIT 0 /* attr is stored locally */ -#define XFS_ATTR_ROOT_BIT 1 /* limit access to attr to userid 0 */ +#define XFS_ATTR_ROOT_BIT 1 /* limit access to trusted attrs */ #define XFS_ATTR_INCOMPLETE_BIT 7 /* attr in middle of create/delete */ #define XFS_ATTR_LOCAL (1 << XFS_ATTR_LOCAL_BIT) #define XFS_ATTR_ROOT (1 << XFS_ATTR_ROOT_BIT) @@ -299,7 +300,8 @@ int *local); int xfs_attr_leaf_entsize(struct xfs_attr_leafblock *leaf, int index); int xfs_attr_put_listent(struct xfs_attr_list_context *context, - int ns, char *name, int namelen, int valuelen); + struct attrnames *, char *name, int namelen, + int valuelen); int xfs_attr_rolltrans(struct xfs_trans **transp, struct xfs_inode *dp); #endif /* __XFS_ATTR_LEAF_H__ */ diff -urN linux-2.4.23-bk13/fs/xfs/xfs_buf.h linux-2.4.23-bk14/fs/xfs/xfs_buf.h --- linux-2.4.23-bk13/fs/xfs/xfs_buf.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_buf.h 2003-12-19 02:52:58.000000000 -0800 @@ -181,7 +181,7 @@ #define XFS_BUF_SET_VTYPE(bp, type) #define XFS_BUF_SET_REF(bp, ref) -#define XFS_BUF_ISPINNED(bp) pagebuf_ispin(bp) +#define XFS_BUF_ISPINNED(bp) pagebuf_ispin(bp) #define XFS_BUF_VALUSEMA(bp) pagebuf_lock_value(bp) #define XFS_BUF_CPSEMA(bp) (pagebuf_cond_lock(bp) == 0) @@ -191,16 +191,10 @@ /* setup the buffer target from a buftarg structure */ #define XFS_BUF_SET_TARGET(bp, target) \ - (bp)->pb_target = (target) - + (bp)->pb_target = (target) #define XFS_BUF_TARGET(bp) ((bp)->pb_target) - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#define XFS_BUFTARG_NAME(target) bdevname((target)->pbr_kdev) -#else -#define XFS_BUFTARG_NAME(target) \ - ({ char __b[BDEVNAME_SIZE]; bdevname((target)->pbr_bdev, __b); __b; }) -#endif +#define XFS_BUFTARG_NAME(target) \ + pagebuf_target_name(target) #define XFS_BUF_SET_VTYPE_REF(bp, type, ref) #define XFS_BUF_SET_VTYPE(bp, type) diff -urN linux-2.4.23-bk13/fs/xfs/xfs_log.c linux-2.4.23-bk14/fs/xfs/xfs_log.c --- linux-2.4.23-bk13/fs/xfs/xfs_log.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_log.c 2003-12-19 02:52:58.000000000 -0800 @@ -1056,7 +1056,7 @@ if (xfs_physmem <= btoc(128*1024*1024)) { log->l_iclog_bufs = XLOG_MIN_ICLOGS; } else if (xfs_physmem <= btoc(400*1024*1024)) { - log->l_iclog_bufs = XLOG_MED_ICLOGS;; + log->l_iclog_bufs = XLOG_MED_ICLOGS; } else { /* 256K with 32K bufs */ log->l_iclog_bufs = XLOG_MAX_ICLOGS; diff -urN linux-2.4.23-bk13/fs/xfs/xfs_rename.c linux-2.4.23-bk14/fs/xfs/xfs_rename.c --- linux-2.4.23-bk13/fs/xfs/xfs_rename.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_rename.c 2003-12-19 02:52:58.000000000 -0800 @@ -485,7 +485,7 @@ error = xfs_droplink(tp, target_ip); if (error) { rename_which_error_return = __LINE__; - goto abort_return;; + goto abort_return; } target_ip_dropped = 1; diff -urN linux-2.4.23-bk13/fs/xfs/xfs_trans.c linux-2.4.23-bk14/fs/xfs/xfs_trans.c --- linux-2.4.23-bk13/fs/xfs/xfs_trans.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_trans.c 2003-12-19 02:52:58.000000000 -0800 @@ -142,9 +142,9 @@ uint type) { xfs_trans_t *tp; + ASSERT(xfs_trans_zone != NULL); tp = kmem_zone_zalloc(xfs_trans_zone, KM_SLEEP); - tp->t_dqinfo = NULL; /* * Initialize the transaction structure. diff -urN linux-2.4.23-bk13/fs/xfs/xfs_types.h linux-2.4.23-bk14/fs/xfs/xfs_types.h --- linux-2.4.23-bk13/fs/xfs/xfs_types.h 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfs_types.h 2003-12-19 02:52:58.000000000 -0800 @@ -75,24 +75,6 @@ #error BITS_PER_LONG must be 32 or 64 #endif -/* - * Some types are conditional depending on the target system. - * XFS_BIG_BLKNOS needs block layer disk addresses to be 64 bits. - * XFS_BIG_INUMS needs the VFS inode number to be 64 bits, as well - * as requiring XFS_BIG_BLKNOS to be set. - */ -#if defined(CONFIG_LBD) || (defined(HAVE_SECTOR_T) && (BITS_PER_LONG == 64)) -# define XFS_BIG_BLKNOS 1 -# if BITS_PER_LONG == 64 -# define XFS_BIG_INUMS 1 -# else -# define XFS_BIG_INUMS 0 -# endif -#else -# define XFS_BIG_BLKNOS 0 -# define XFS_BIG_INUMS 0 -#endif - #endif /* __KERNEL__ */ typedef __uint32_t xfs_agblock_t; /* blockno in alloc. group */ @@ -197,20 +179,4 @@ XFS_BTNUM_MAX } xfs_btnum_t; - -/* - * Juggle IRIX device numbers - still used in ondisk structures - */ -#define XFS_DEV_BITSMAJOR 14 -#define XFS_DEV_BITSMINOR 18 -#define XFS_DEV_MAXMAJ 0x1ff -#define XFS_DEV_MAXMIN 0x3ffff -#define XFS_DEV_MAJOR(dev) ((int)(((unsigned)(dev)>>XFS_DEV_BITSMINOR) \ - & XFS_DEV_MAXMAJ)) -#define XFS_DEV_MINOR(dev) ((int)((dev)&XFS_DEV_MAXMIN)) -#define XFS_MKDEV(major,minor) ((xfs_dev_t)(((major)<m_inoadd) #endif - statp->f_files = - min_t(sector_t, statp->f_files, mp->m_maxicount); + statp->f_files = min_t(typeof(statp->f_files), + statp->f_files, + mp->m_maxicount); statp->f_ffree = statp->f_files - (sbp->sb_icount - sbp->sb_ifree); XFS_SB_UNLOCK(mp, s); @@ -1782,10 +1783,14 @@ char *str; } xfs_info[] = { /* the few simple ones we can get from the mount struct */ + { XFS_MOUNT_WSYNC, "," MNTOPT_WSYNC }, + { XFS_MOUNT_INO64, "," MNTOPT_INO64 }, { XFS_MOUNT_NOALIGN, "," MNTOPT_NOALIGN }, + { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, { XFS_MOUNT_NORECOVERY, "," MNTOPT_NORECOVERY }, { XFS_MOUNT_OSYNCISOSYNC, "," MNTOPT_OSYNCISOSYNC }, - { XFS_MOUNT_NOUUID, "," MNTOPT_NOUUID }, + { XFS_MOUNT_NOLOGFLUSH, "," MNTOPT_NOLOGFLUSH }, + { XFS_MOUNT_IDELETE, "," MNTOPT_NOIKEEP }, { 0, NULL } }; struct proc_xfs_info *xfs_infop; @@ -1821,6 +1826,9 @@ seq_printf(m, "," MNTOPT_SWIDTH "=%d", (int)XFS_FSB_TO_BB(mp, mp->m_swidth)); + if (!(mp->m_flags & XFS_MOUNT_32BITINOOPT)) + seq_printf(m, "," MNTOPT_64BITINODE); + return 0; } diff -urN linux-2.4.23-bk13/fs/xfs/xfsidbg.c linux-2.4.23-bk14/fs/xfs/xfsidbg.c --- linux-2.4.23-bk13/fs/xfs/xfsidbg.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/fs/xfs/xfsidbg.c 2003-12-19 02:52:58.000000000 -0800 @@ -3177,13 +3177,13 @@ static char *attr_arg_flags[] = { "DONTFOLLOW", /* 0x0001 */ "ROOT", /* 0x0002 */ - "?", /* 0x0004 */ - "REPLACE", /* 0x0008 */ + "TRUSTED", /* 0x0004 */ + "?", /* 0x0008 */ "CREATE", /* 0x0010 */ - "?", /* 0x0020 */ + "REPLACE", /* 0x0020 */ "?", /* 0x0040 */ "?", /* 0x0080 */ - "?", /* 0x0100 */ + "SYSTEM", /* 0x0100 */ "?", /* 0x0200 */ "?", /* 0x0400 */ "?", /* 0x0800 */ diff -urN linux-2.4.23-bk13/include/asm-ppc64/hvcall.h linux-2.4.23-bk14/include/asm-ppc64/hvcall.h --- linux-2.4.23-bk13/include/asm-ppc64/hvcall.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.23-bk14/include/asm-ppc64/hvcall.h 2003-12-19 02:52:58.000000000 -0800 @@ -59,7 +59,7 @@ #define H_XIRR 0x74 #define H_PERFMON 0x7c -#define HSC ".long 0x44000022\n" +#define HVSC ".long 0x44000022\n" #define H_ENTER_r3 "li 3, 0x08\n" /* plpar_hcall() -- Generic call interface using above opcodes @@ -84,3 +84,34 @@ */ long plpar_hcall_norets(unsigned long opcode, ...); +/* + * Special hcall interface for ibmveth support. + * Takes 8 input parms. Returns a rc and stores the + * R4 return value in *out1. + */ +long plpar_hcall_8arg_2ret(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long arg5, + unsigned long arg6, + unsigned long arg7, + unsigned long arg8, + unsigned long *out1); + + +/* plpar_hcall_4out() + * + * same as plpar_hcall except with 4 output arguments. + * + */ +long plpar_hcall_4out(unsigned long opcode, + unsigned long arg1, + unsigned long arg2, + unsigned long arg3, + unsigned long arg4, + unsigned long *out1, + unsigned long *out2, + unsigned long *out3, + unsigned long *out4); diff -urN linux-2.4.23-bk13/include/asm-ppc64/hw_irq.h linux-2.4.23-bk14/include/asm-ppc64/hw_irq.h --- linux-2.4.23-bk13/include/asm-ppc64/hw_irq.h 2003-06-13 07:51:38.000000000 -0700 +++ linux-2.4.23-bk14/include/asm-ppc64/hw_irq.h 2003-12-19 02:52:58.000000000 -0800 @@ -71,9 +71,21 @@ #endif /* CONFIG_PPC_ISERIES */ -#define mask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->disable) irq_desc[irq].handler->disable(irq);}) -#define unmask_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->enable) irq_desc[irq].handler->enable(irq);}) -#define ack_irq(irq) ({if (irq_desc[irq].handler && irq_desc[irq].handler->ack) irq_desc[irq].handler->ack(irq);}) +#define mask_irq(irq) ({ \ + irq_desc_t *desc = irqdesc(irq); \ + if (desc->handler && desc->handler->disable) \ + desc->handler->disable(irq); \ +}) +#define unmask_irq(irq) ({ \ + irq_desc_t *desc = irqdesc(irq); \ + if (desc->handler && desc->handler->enable) \ + desc->handler->enable(irq); \ +}) +#define ack_irq(irq) ({ \ + irq_desc_t *desc = irqdesc(irq); \ + if (desc->handler && desc->handler->ack) \ + desc->handler->ack(irq); \ +}) /* Should we handle this via lost interrupts and IPIs or should we don't care like * we do now ? --BenH. diff -urN linux-2.4.23-bk13/include/asm-ppc64/irq.h linux-2.4.23-bk14/include/asm-ppc64/irq.h --- linux-2.4.23-bk13/include/asm-ppc64/irq.h 2002-08-02 17:39:45.000000000 -0700 +++ linux-2.4.23-bk14/include/asm-ppc64/irq.h 2003-12-19 02:52:58.000000000 -0800 @@ -15,31 +15,22 @@ extern void disable_irq_nosync(unsigned int); extern void enable_irq(unsigned int); -/* - * this is the maximum number of virtual irqs we will use. - */ -#define NR_IRQS 512 +/* Need to keep at 256 (minimum) for iSeries */ +#define NR_IRQS 256 -#define NUM_8259_INTERRUPTS 16 +#define MAX_IRQS (1<<24) -/* Interrupt numbers are virtual in case they are sparsely - * distributed by the hardware. - */ -#define NR_HW_IRQS 8192 -extern unsigned short real_irq_to_virt_map[NR_HW_IRQS]; -extern unsigned short virt_irq_to_real_map[NR_IRQS]; -/* Create a mapping for a real_irq if it doesn't already exist. - * Return the virtual irq as a convenience. - */ -unsigned long virt_irq_create_mapping(unsigned long real_irq); +extern unsigned int _next_irq(unsigned int irq); -/* These funcs map irqs between real and virtual */ -static inline unsigned long real_irq_to_virt(unsigned long real_irq) { - return real_irq_to_virt_map[real_irq]; -} -static inline unsigned long virt_irq_to_real(unsigned long virt_irq) { - return virt_irq_to_real_map[virt_irq]; -} +/* Define a way to iterate across irqs fairly efficiently. */ +#define for_each_irq(i) \ + for ((i) = 0; (i) < MAX_IRQS; (i) = _next_irq(i)) + + +extern void *_irqdesc(unsigned int irq); +extern void *_real_irqdesc(unsigned int irq); +#define irqdesc(irq) ((irq_desc_t *)_irqdesc(irq)) +#define real_irqdesc(irq) ((irq_desc_t *)_real_irqdesc(irq)) /* * This gets called from serial.c, which is now used on @@ -51,5 +42,34 @@ return irq; } +/* + * Because many systems have two overlapping names spaces for + * interrupts (ISA and XICS for example), and the ISA interrupts + * have historically not been easy to renumber, we allow ISA + * interrupts to take values 0 - 15, and shift up the remaining + * interrupts by 0x10. + * + * This would be nice to remove at some point as it adds confusion + * and adds a nasty end case if any platform native interrupts have + * values within 0x10 of the end of that namespace. + */ + +#define NUM_ISA_INTERRUPTS 0x10 + +extern inline int irq_offset_up(int irq) +{ + return(irq + NUM_ISA_INTERRUPTS); +} + +extern inline int irq_offset_down(int irq) +{ + return(irq - NUM_ISA_INTERRUPTS); +} + +extern inline int irq_offset_value(void) +{ + return NUM_ISA_INTERRUPTS; +} + #endif /* _ASM_IRQ_H */ #endif /* __KERNEL__ */ diff -urN linux-2.4.23-bk13/include/asm-ppc64/machdep.h linux-2.4.23-bk14/include/asm-ppc64/machdep.h --- linux-2.4.23-bk13/include/asm-ppc64/machdep.h 2002-11-28 15:53:15.000000000 -0800 +++ linux-2.4.23-bk14/include/asm-ppc64/machdep.h 2003-12-19 02:52:58.000000000 -0800 @@ -10,6 +10,8 @@ */ #include +#include +#include struct pt_regs; struct pci_bus; @@ -62,6 +64,7 @@ unsigned int (*irq_cannonicalize)(unsigned int irq); void (*init_IRQ)(void); void (*init_ras_IRQ)(void); + void (*init_irq_desc)(irq_desc_t *desc); int (*get_irq)(struct pt_regs *); /* A general init function, called by ppc_init in init/main.c. diff -urN linux-2.4.23-bk13/mm/page_alloc.c linux-2.4.23-bk14/mm/page_alloc.c --- linux-2.4.23-bk13/mm/page_alloc.c 2003-12-19 02:52:51.000000000 -0800 +++ linux-2.4.23-bk14/mm/page_alloc.c 2003-12-19 02:52:58.000000000 -0800 @@ -378,7 +378,7 @@ /* here we're in the low on memory slow path */ - if (((current->flags & PF_MEMALLOC) && + if ((current->flags & PF_MEMALLOC) && (!in_interrupt() || (current->flags & PF_MEMDIE))) { zone = zonelist->zones; for (;;) {