summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/2.6.22/20077_xen-isa-dma.patch1')
-rw-r--r--trunk/2.6.22/20077_xen-isa-dma.patch1543
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))
+