diff options
Diffstat (limited to 'trunk/2.6.22/20077_xen-isa-dma.patch1')
-rw-r--r-- | trunk/2.6.22/20077_xen-isa-dma.patch1 | 543 |
1 files changed, 543 insertions, 0 deletions
diff --git a/trunk/2.6.22/20077_xen-isa-dma.patch1 b/trunk/2.6.22/20077_xen-isa-dma.patch1 new file mode 100644 index 0000000..3e80ec7 --- /dev/null +++ b/trunk/2.6.22/20077_xen-isa-dma.patch1 @@ -0,0 +1,543 @@ +From: jbeulich@novell.com +Subject: Suppress all use of ISA DMA on Xen. +Patch-mainline: obsolete (non-Xen parts 2.6.23-rc4-mm1) + +The kernel's ISA DMA API is just not fitting virtualization requirements. + +Index: head-2007-09-03/arch/i386/kernel/setup-xen.c +=================================================================== +--- head-2007-09-03.orig/arch/i386/kernel/setup-xen.c 2007-09-03 09:53:47.000000000 +0200 ++++ head-2007-09-03/arch/i386/kernel/setup-xen.c 2007-09-03 10:02:35.000000000 +0200 +@@ -758,6 +758,11 @@ void __init setup_arch(char **cmdline_p) + virt_to_mfn(pfn_to_mfn_frame_list_list); + } + ++ /* Mark all ISA DMA channels in-use - using them wouldn't work. */ ++ for (i = 0; i < MAX_DMA_CHANNELS; ++i) ++ if (i != 4 && request_dma(i, "xen") != 0) ++ BUG(); ++ + /* + * NOTE: at this point the bootmem allocator is fully available. + */ +Index: head-2007-09-03/arch/x86_64/kernel/Makefile +=================================================================== +--- head-2007-09-03.orig/arch/x86_64/kernel/Makefile 2007-09-03 10:01:35.000000000 +0200 ++++ head-2007-09-03/arch/x86_64/kernel/Makefile 2007-09-03 10:03:00.000000000 +0200 +@@ -69,7 +69,7 @@ pci-dma-y += ../../i386/kernel/pci-dma + microcode-$(subst m,y,$(CONFIG_MICROCODE)) := ../../i386/kernel/microcode-xen.o + quirks-y := ../../i386/kernel/quirks-xen.o + +-n-obj-xen := early-quirks.o genapic_flat.o i8237.o i8259.o perfctr-watchdog.o \ ++n-obj-xen := early-quirks.o genapic_flat.o i8259.o perfctr-watchdog.o \ + reboot.o smpboot.o trampoline.o tsc.o tsc_sync.o + + include $(srctree)/scripts/Makefile.xen +Index: head-2007-09-03/arch/x86_64/kernel/setup-xen.c +=================================================================== +--- head-2007-09-03.orig/arch/x86_64/kernel/setup-xen.c 2007-09-03 09:53:50.000000000 +0200 ++++ head-2007-09-03/arch/x86_64/kernel/setup-xen.c 2007-09-03 10:02:35.000000000 +0200 +@@ -534,6 +534,10 @@ void __init setup_arch(char **cmdline_p) + virt_to_mfn(pfn_to_mfn_frame_list_list); + } + ++ /* Mark all ISA DMA channels in-use - using them wouldn't work. */ ++ for (i = 0; i < MAX_DMA_CHANNELS; ++i) ++ if (i != 4 && request_dma(i, "xen") != 0) ++ BUG(); + } + + #ifdef CONFIG_ACPI +Index: head-2007-09-03/drivers/block/floppy.c +=================================================================== +--- head-2007-09-03.orig/drivers/block/floppy.c 2007-07-09 01:32:17.000000000 +0200 ++++ head-2007-09-03/drivers/block/floppy.c 2007-09-03 10:02:35.000000000 +0200 +@@ -4397,11 +4397,15 @@ static int floppy_grab_irq_and_dma(void) + if (fd_request_dma()) { + DPRINT("Unable to grab DMA%d for the floppy driver\n", + FLOPPY_DMA); +- fd_free_irq(); +- spin_lock_irqsave(&floppy_usage_lock, flags); +- usage_count--; +- spin_unlock_irqrestore(&floppy_usage_lock, flags); +- return -1; ++ if (can_use_virtual_dma & 2) ++ use_virtual_dma = can_use_virtual_dma = 1; ++ if (!(can_use_virtual_dma & 1)) { ++ fd_free_irq(); ++ spin_lock_irqsave(&floppy_usage_lock, flags); ++ usage_count--; ++ spin_unlock_irqrestore(&floppy_usage_lock, flags); ++ return -1; ++ } + } + + for (fdc = 0; fdc < N_FDC; fdc++) { +Index: head-2007-09-03/drivers/pnp/manager.c +=================================================================== +--- head-2007-09-03.orig/drivers/pnp/manager.c 2007-04-26 05:08:32.000000000 +0200 ++++ head-2007-09-03/drivers/pnp/manager.c 2007-09-03 10:02:35.000000000 +0200 +@@ -168,7 +168,7 @@ static int pnp_assign_irq(struct pnp_dev + return 0; + } + +-static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) ++static void pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) + { + resource_size_t *start, *end; + unsigned long *flags; +@@ -179,18 +179,14 @@ static int pnp_assign_dma(struct pnp_dev + 1, 3, 5, 6, 7, 0, 2, 4 + }; + +- if (!dev || !rule) +- return -EINVAL; +- + if (idx >= PNP_MAX_DMA) { + pnp_err("More than 2 dmas is incompatible with pnp specifications."); +- /* pretend we were successful so at least the manager won't try again */ +- return 1; ++ return; + } + + /* check if this resource has been manually set, if so skip */ + if (!(dev->res.dma_resource[idx].flags & IORESOURCE_AUTO)) +- return 1; ++ return; + + start = &dev->res.dma_resource[idx].start; + end = &dev->res.dma_resource[idx].end; +@@ -200,19 +196,17 @@ static int pnp_assign_dma(struct pnp_dev + *flags |= rule->flags | IORESOURCE_DMA; + *flags &= ~IORESOURCE_UNSET; + +- if (!rule->map) { +- *flags |= IORESOURCE_DISABLED; +- return 1; /* skip disabled resource requests */ +- } +- + for (i = 0; i < 8; i++) { + if(rule->map & (1<<xtab[i])) { + *start = *end = xtab[i]; + if(pnp_check_dma(dev, idx)) +- return 1; ++ return; + } + } +- return 0; ++#ifdef MAX_DMA_CHANNELS ++ *start = *end = MAX_DMA_CHANNELS; ++#endif ++ *flags |= IORESOURCE_UNSET | IORESOURCE_DISABLED; + } + + /** +@@ -331,8 +325,7 @@ static int pnp_assign_resources(struct p + irq = irq->next; + } + while (dma) { +- if (!pnp_assign_dma(dev, dma, ndma)) +- goto fail; ++ pnp_assign_dma(dev, dma, ndma); + ndma++; + dma = dma->next; + } +@@ -367,8 +360,7 @@ static int pnp_assign_resources(struct p + irq = irq->next; + } + while (dma) { +- if (!pnp_assign_dma(dev, dma, ndma)) +- goto fail; ++ pnp_assign_dma(dev, dma, ndma); + ndma++; + dma = dma->next; + } +Index: head-2007-09-03/include/asm-i386/mach-xen/asm/floppy.h +=================================================================== +--- head-2007-09-03.orig/include/asm-i386/mach-xen/asm/floppy.h 2007-09-03 09:53:00.000000000 +0200 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,147 +0,0 @@ +-/* +- * Architecture specific parts of the Floppy driver +- * +- * This file is subject to the terms and conditions of the GNU General Public +- * License. See the file "COPYING" in the main directory of this archive +- * for more details. +- * +- * Copyright (C) 1995 +- * +- * Modifications for Xen are Copyright (c) 2004, Keir Fraser. +- */ +-#ifndef __ASM_XEN_I386_FLOPPY_H +-#define __ASM_XEN_I386_FLOPPY_H +- +-#include <linux/vmalloc.h> +- +-/* XEN: Hit DMA paths on the head. This trick from asm-m68k/floppy.h. */ +-#include <asm/dma.h> +-#undef MAX_DMA_ADDRESS +-#define MAX_DMA_ADDRESS 0 +-#define CROSS_64KB(a,s) (0) +- +-#define fd_inb(port) inb_p(port) +-#define fd_outb(value,port) outb_p(value,port) +- +-#define fd_request_dma() (0) +-#define fd_free_dma() ((void)0) +-#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +-#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +-#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) +-#define fd_get_dma_residue() (virtual_dma_count + virtual_dma_residue) +-#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io) +-/* +- * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from +- * softirq context via motor_off_callback. A generic bug we happen to trigger. +- */ +-#define fd_dma_mem_alloc(size) __get_free_pages(GFP_KERNEL, get_order(size)) +-#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size)) +- +-static int virtual_dma_count; +-static int virtual_dma_residue; +-static char *virtual_dma_addr; +-static int virtual_dma_mode; +-static int doing_pdma; +- +-static irqreturn_t floppy_hardint(int irq, void *dev_id) +-{ +- register unsigned char st; +- register int lcount; +- register char *lptr; +- +- if (!doing_pdma) +- return floppy_interrupt(irq, dev_id); +- +- st = 1; +- for(lcount=virtual_dma_count, lptr=virtual_dma_addr; +- lcount; lcount--, lptr++) { +- st=inb(virtual_dma_port+4) & 0xa0 ; +- if(st != 0xa0) +- break; +- if(virtual_dma_mode) +- outb_p(*lptr, virtual_dma_port+5); +- else +- *lptr = inb_p(virtual_dma_port+5); +- } +- virtual_dma_count = lcount; +- virtual_dma_addr = lptr; +- st = inb(virtual_dma_port+4); +- +- if(st == 0x20) +- return IRQ_HANDLED; +- if(!(st & 0x20)) { +- virtual_dma_residue += virtual_dma_count; +- virtual_dma_count=0; +- doing_pdma = 0; +- floppy_interrupt(irq, dev_id); +- return IRQ_HANDLED; +- } +- return IRQ_HANDLED; +-} +- +-static void fd_disable_dma(void) +-{ +- doing_pdma = 0; +- virtual_dma_residue += virtual_dma_count; +- virtual_dma_count=0; +-} +- +-static int fd_request_irq(void) +-{ +- return request_irq(FLOPPY_IRQ, floppy_hardint, +- IRQF_DISABLED, "floppy", NULL); +-} +- +-static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) +-{ +- doing_pdma = 1; +- virtual_dma_port = io; +- virtual_dma_mode = (mode == DMA_MODE_WRITE); +- virtual_dma_addr = addr; +- virtual_dma_count = size; +- virtual_dma_residue = 0; +- return 0; +-} +- +-/* XEN: This trick to force 'virtual DMA' is from include/asm-m68k/floppy.h. */ +-#define FDC1 xen_floppy_init() +-static int FDC2 = -1; +- +-static int xen_floppy_init(void) +-{ +- use_virtual_dma = 1; +- can_use_virtual_dma = 1; +- return 0x3f0; +-} +- +-/* +- * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock +- * is needed to prevent corrupted CMOS RAM in case "insmod floppy" +- * coincides with another rtc CMOS user. Paul G. +- */ +-#define FLOPPY0_TYPE ({ \ +- unsigned long flags; \ +- unsigned char val; \ +- spin_lock_irqsave(&rtc_lock, flags); \ +- val = (CMOS_READ(0x10) >> 4) & 15; \ +- spin_unlock_irqrestore(&rtc_lock, flags); \ +- val; \ +-}) +- +-#define FLOPPY1_TYPE ({ \ +- unsigned long flags; \ +- unsigned char val; \ +- spin_lock_irqsave(&rtc_lock, flags); \ +- val = CMOS_READ(0x10) & 15; \ +- spin_unlock_irqrestore(&rtc_lock, flags); \ +- val; \ +-}) +- +-#define N_FDC 2 +-#define N_DRIVE 8 +- +-#define FLOPPY_MOTOR_MASK 0xf0 +- +-#define EXTRA_FLOPPY_PARAMS +- +-#endif /* __ASM_XEN_I386_FLOPPY_H */ +Index: head-2007-09-03/include/asm-i386/mach-xen/asm/io.h +=================================================================== +--- head-2007-09-03.orig/include/asm-i386/mach-xen/asm/io.h 2007-09-03 09:53:30.000000000 +0200 ++++ head-2007-09-03/include/asm-i386/mach-xen/asm/io.h 2007-09-03 10:02:35.000000000 +0200 +@@ -152,7 +152,7 @@ extern void bt_iounmap(void *addr, unsig + /* + * ISA I/O bus memory addresses are 1:1 with the physical address. + */ +-#define isa_virt_to_bus(_x) isa_virt_to_bus_is_UNSUPPORTED->x ++#define isa_virt_to_bus(_x) ({ BUG(); virt_to_bus(_x); }) + #define isa_page_to_bus(_x) isa_page_to_bus_is_UNSUPPORTED->x + #define isa_bus_to_virt(_x) (void *)(__fix_to_virt(FIX_ISAMAP_BEGIN) + (_x)) + +Index: head-2007-09-03/include/asm-x86_64/mach-xen/asm/floppy.h +=================================================================== +--- head-2007-09-03.orig/include/asm-x86_64/mach-xen/asm/floppy.h 2007-09-03 09:53:00.000000000 +0200 ++++ /dev/null 1970-01-01 00:00:00.000000000 +0000 +@@ -1,206 +0,0 @@ +-/* +- * Architecture specific parts of the Floppy driver +- * +- * This file is subject to the terms and conditions of the GNU General Public +- * License. See the file "COPYING" in the main directory of this archive +- * for more details. +- * +- * Copyright (C) 1995 +- * +- * Modifications for Xen are Copyright (c) 2004, Keir Fraser. +- */ +-#ifndef __ASM_XEN_X86_64_FLOPPY_H +-#define __ASM_XEN_X86_64_FLOPPY_H +- +-#include <linux/vmalloc.h> +- +-/* +- * The DMA channel used by the floppy controller cannot access data at +- * addresses >= 16MB +- * +- * Went back to the 1MB limit, as some people had problems with the floppy +- * driver otherwise. It doesn't matter much for performance anyway, as most +- * floppy accesses go through the track buffer. +- */ +-#define _CROSS_64KB(a,s,vdma) \ +-(!(vdma) && ((unsigned long)(a)/K_64 != ((unsigned long)(a) + (s) - 1) / K_64)) +- +-/* XEN: Hit DMA paths on the head. This trick from asm-m68k/floppy.h. */ +-#include <asm/dma.h> +-#undef MAX_DMA_ADDRESS +-#define MAX_DMA_ADDRESS 0 +-#define CROSS_64KB(a,s) (0) +- +-#define fd_inb(port) inb_p(port) +-#define fd_outb(value,port) outb_p(value,port) +- +-#define fd_request_dma() (0) +-#define fd_free_dma() ((void)0) +-#define fd_enable_irq() enable_irq(FLOPPY_IRQ) +-#define fd_disable_irq() disable_irq(FLOPPY_IRQ) +-#define fd_free_irq() free_irq(FLOPPY_IRQ, NULL) +-#define fd_get_dma_residue() vdma_get_dma_residue(FLOPPY_DMA) +-/* +- * Do not use vmalloc/vfree: floppy_release_irq_and_dma() gets called from +- * softirq context via motor_off_callback. A generic bug we happen to trigger. +- */ +-#define fd_dma_mem_alloc(size) __get_free_pages(GFP_KERNEL|__GFP_NORETRY, get_order(size)) +-#define fd_dma_mem_free(addr, size) free_pages(addr, get_order(size)) +-#define fd_dma_setup(addr, size, mode, io) vdma_dma_setup(addr, size, mode, io) +- +-static int virtual_dma_count; +-static int virtual_dma_residue; +-static char *virtual_dma_addr; +-static int virtual_dma_mode; +-static int doing_pdma; +- +-static irqreturn_t floppy_hardint(int irq, void *dev_id) +-{ +- register unsigned char st; +- +-#undef TRACE_FLPY_INT +- +-#ifdef TRACE_FLPY_INT +- static int calls=0; +- static int bytes=0; +- static int dma_wait=0; +-#endif +- if (!doing_pdma) +- return floppy_interrupt(irq, dev_id); +- +-#ifdef TRACE_FLPY_INT +- if(!calls) +- bytes = virtual_dma_count; +-#endif +- +- { +- register int lcount; +- register char *lptr; +- +- st = 1; +- for(lcount=virtual_dma_count, lptr=virtual_dma_addr; +- lcount; lcount--, lptr++) { +- st=inb(virtual_dma_port+4) & 0xa0 ; +- if(st != 0xa0) +- break; +- if(virtual_dma_mode) +- outb_p(*lptr, virtual_dma_port+5); +- else +- *lptr = inb_p(virtual_dma_port+5); +- } +- virtual_dma_count = lcount; +- virtual_dma_addr = lptr; +- st = inb(virtual_dma_port+4); +- } +- +-#ifdef TRACE_FLPY_INT +- calls++; +-#endif +- if(st == 0x20) +- return IRQ_HANDLED; +- if(!(st & 0x20)) { +- virtual_dma_residue += virtual_dma_count; +- virtual_dma_count=0; +-#ifdef TRACE_FLPY_INT +- printk("count=%x, residue=%x calls=%d bytes=%d dma_wait=%d\n", +- virtual_dma_count, virtual_dma_residue, calls, bytes, +- dma_wait); +- calls = 0; +- dma_wait=0; +-#endif +- doing_pdma = 0; +- floppy_interrupt(irq, dev_id); +- return IRQ_HANDLED; +- } +-#ifdef TRACE_FLPY_INT +- if(!virtual_dma_count) +- dma_wait++; +-#endif +- return IRQ_HANDLED; +-} +- +-static void fd_disable_dma(void) +-{ +- doing_pdma = 0; +- virtual_dma_residue += virtual_dma_count; +- virtual_dma_count=0; +-} +- +-static int vdma_get_dma_residue(unsigned int dummy) +-{ +- return virtual_dma_count + virtual_dma_residue; +-} +- +- +-static int fd_request_irq(void) +-{ +- return request_irq(FLOPPY_IRQ, floppy_hardint, +- IRQF_DISABLED, "floppy", NULL); +-} +- +-#if 0 +-static unsigned long vdma_mem_alloc(unsigned long size) +-{ +- return (unsigned long) vmalloc(size); +- +-} +- +-static void vdma_mem_free(unsigned long addr, unsigned long size) +-{ +- vfree((void *)addr); +-} +-#endif +- +-static int vdma_dma_setup(char *addr, unsigned long size, int mode, int io) +-{ +- doing_pdma = 1; +- virtual_dma_port = io; +- virtual_dma_mode = (mode == DMA_MODE_WRITE); +- virtual_dma_addr = addr; +- virtual_dma_count = size; +- virtual_dma_residue = 0; +- return 0; +-} +- +-/* XEN: This trick to force 'virtual DMA' is from include/asm-m68k/floppy.h. */ +-#define FDC1 xen_floppy_init() +-static int FDC2 = -1; +- +-static int xen_floppy_init(void) +-{ +- use_virtual_dma = 1; +- can_use_virtual_dma = 1; +- return 0x3f0; +-} +- +-/* +- * Floppy types are stored in the rtc's CMOS RAM and so rtc_lock +- * is needed to prevent corrupted CMOS RAM in case "insmod floppy" +- * coincides with another rtc CMOS user. Paul G. +- */ +-#define FLOPPY0_TYPE ({ \ +- unsigned long flags; \ +- unsigned char val; \ +- spin_lock_irqsave(&rtc_lock, flags); \ +- val = (CMOS_READ(0x10) >> 4) & 15; \ +- spin_unlock_irqrestore(&rtc_lock, flags); \ +- val; \ +-}) +- +-#define FLOPPY1_TYPE ({ \ +- unsigned long flags; \ +- unsigned char val; \ +- spin_lock_irqsave(&rtc_lock, flags); \ +- val = CMOS_READ(0x10) & 15; \ +- spin_unlock_irqrestore(&rtc_lock, flags); \ +- val; \ +-}) +- +-#define N_FDC 2 +-#define N_DRIVE 8 +- +-#define FLOPPY_MOTOR_MASK 0xf0 +- +-#define EXTRA_FLOPPY_PARAMS +- +-#endif /* __ASM_XEN_X86_64_FLOPPY_H */ +Index: head-2007-09-03/include/asm-x86_64/mach-xen/asm/io.h +=================================================================== +--- head-2007-09-03.orig/include/asm-x86_64/mach-xen/asm/io.h 2007-09-03 09:53:19.000000000 +0200 ++++ head-2007-09-03/include/asm-x86_64/mach-xen/asm/io.h 2007-09-03 10:02:35.000000000 +0200 +@@ -167,7 +167,7 @@ extern void iounmap(volatile void __iome + * ISA I/O bus memory addresses are 1:1 with the physical address. + */ + +-#define isa_virt_to_bus(_x) isa_virt_to_bus_is_UNSUPPORTED->x ++#define isa_virt_to_bus(_x) ({ BUG(); virt_to_bus(_x); }) + #define isa_page_to_bus(_x) isa_page_to_bus_is_UNSUPPORTED->x + #define isa_bus_to_virt(_x) (void *)(__fix_to_virt(FIX_ISAMAP_BEGIN) + (_x)) + |