ia64/xen-unstable

changeset 11185:879918dbe77f

[HVM] Linux driver for the xen platform pseudo-PCI device.
Signed-off-by: Steven Smith <ssmith@xensource.com>
author kfraser@localhost.localdomain
date Thu Aug 17 16:08:01 2006 +0100 (2006-08-17)
parents b9af81884b99
children b2f077bbca89
files unmodified_drivers/linux-2.6/Makefile unmodified_drivers/linux-2.6/mkbuildtree unmodified_drivers/linux-2.6/overrides.mk unmodified_drivers/linux-2.6/platform-pci/Kbuild unmodified_drivers/linux-2.6/platform-pci/evtchn.c unmodified_drivers/linux-2.6/platform-pci/platform-pci.c unmodified_drivers/linux-2.6/platform-pci/platform-pci.h unmodified_drivers/linux-2.6/platform-pci/xen_support.c
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/unmodified_drivers/linux-2.6/Makefile	Thu Aug 17 16:08:01 2006 +0100
     1.3 @@ -0,0 +1,3 @@
     1.4 +include $(M)/overrides.mk
     1.5 +
     1.6 +obj-m += platform-pci/
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/unmodified_drivers/linux-2.6/mkbuildtree	Thu Aug 17 16:08:01 2006 +0100
     2.3 @@ -0,0 +1,41 @@
     2.4 +#! /bin/sh
     2.5 +
     2.6 +C=$PWD
     2.7 +
     2.8 +XEN=$C/../../xen
     2.9 +XL=$C/../../linux-2.6-xen-sparse
    2.10 +
    2.11 +ln -sf ${XL}/drivers/xen/core/features.c platform-pci
    2.12 +
    2.13 +mkdir -p include
    2.14 +mkdir -p include/xen
    2.15 +mkdir -p include/public
    2.16 +mkdir -p include/asm
    2.17 +
    2.18 +lndir -silent ${XL}/include/xen include/xen
    2.19 +ln -sf ${XEN}/include/public include/xen/interface
    2.20 +
    2.21 +# Need to be quite careful here: we don't want the files we link in to
    2.22 +# risk overriding the native Linux ones (in particular, system.h must
    2.23 +# be native and not xenolinux).
    2.24 +uname=`uname -m`
    2.25 +case "$uname"
    2.26 +in
    2.27 +"x86_64")
    2.28 +	ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypervisor.h include/asm
    2.29 +	ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/hypercall.h include/asm
    2.30 +	ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/synch_bitops.h include/asm
    2.31 +	ln -sf ${XL}/include/asm-x86_64/mach-xen/asm/maddr.h include/asm
    2.32 +	ln -sf ${XL}/include/asm-i386 include/asm-i386
    2.33 +	;;
    2.34 +i[34567]86)
    2.35 +	ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypervisor.h include/asm
    2.36 +	ln -sf ${XL}/include/asm-i386/mach-xen/asm/hypercall.h include/asm
    2.37 +	ln -sf ${XL}/include/asm-i386/mach-xen/asm/synch_bitops.h include/asm
    2.38 +	ln -sf ${XL}/include/asm-i386/mach-xen/asm/maddr.h include/asm
    2.39 +	;;
    2.40 +*)
    2.41 +	echo unknown architecture $uname
    2.42 +	exit 1
    2.43 +	;;
    2.44 +esac
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/unmodified_drivers/linux-2.6/overrides.mk	Thu Aug 17 16:08:01 2006 +0100
     3.3 @@ -0,0 +1,12 @@
     3.4 +# Hack: we need to use the config which was used to build the kernel,
     3.5 +# except that that won't have the right headers etc., so duplicate
     3.6 +# some of the mach-xen infrastructure in here.
     3.7 +#
     3.8 +# (i.e. we need the native config for things like -mregparm, but
     3.9 +# a Xen kernel to find the right headers)
    3.10 +EXTRA_CFLAGS += -DCONFIG_VMX -DCONFIG_VMX_GUEST -DCONFIG_X86_XEN
    3.11 +EXTRA_CFLAGS += -DCONFIG_XEN_SHADOW_MODE -DCONFIG_XEN_SHADOW_TRANSLATE
    3.12 +EXTRA_CFLAGS += -DCONFIG_XEN_BLKDEV_GRANT -DXEN_EVTCHN_MASK_OPS
    3.13 +EXTRA_CFLAGS += -DCONFIG_XEN_NETDEV_GRANT_RX -DCONFIG_XEN_NETDEV_GRANT_TX
    3.14 +EXTRA_CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030202
    3.15 +EXTRA_CFLAGS += -I$(M)/include
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/Kbuild	Thu Aug 17 16:08:01 2006 +0100
     4.3 @@ -0,0 +1,7 @@
     4.4 +include $(M)/overrides.mk
     4.5 +
     4.6 +obj-m := xen-platform-pci.o
     4.7 +
     4.8 +EXTRA_CFLAGS += -I$(M)/platform-pci
     4.9 +
    4.10 +xen-platform-pci-objs := evtchn.o platform-pci.o xen_support.o features.o
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c	Thu Aug 17 16:08:01 2006 +0100
     5.3 @@ -0,0 +1,173 @@
     5.4 +/******************************************************************************
     5.5 + * evtchn.c
     5.6 + *
     5.7 + * A simplified event channel for para-drivers in unmodified linux
     5.8 + *
     5.9 + * Copyright (c) 2002-2005, K A Fraser
    5.10 + * Copyright (c) 2005, <xiaofeng.ling@intel.com>
    5.11 + *
    5.12 + * This file may be distributed separately from the Linux kernel, or
    5.13 + * incorporated into other software packages, subject to the following license:
    5.14 + *
    5.15 + * Permission is hereby granted, free of charge, to any person obtaining a copy
    5.16 + * of this source file (the "Software"), to deal in the Software without
    5.17 + * restriction, including without limitation the rights to use, copy, modify,
    5.18 + * merge, publish, distribute, sublicense, and/or sell copies of the Software,
    5.19 + * and to permit persons to whom the Software is furnished to do so, subject to
    5.20 + * the following conditions:
    5.21 + *
    5.22 + * The above copyright notice and this permission notice shall be included in
    5.23 + * all copies or substantial portions of the Software.
    5.24 + *
    5.25 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    5.26 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    5.27 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    5.28 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    5.29 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    5.30 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
    5.31 + * IN THE SOFTWARE.
    5.32 + */
    5.33 +
    5.34 +#include <linux/config.h>
    5.35 +#include <linux/module.h>
    5.36 +#include <linux/kernel.h>
    5.37 +#include <xen/evtchn.h>
    5.38 +#include <xen/interface/hvm/ioreq.h>
    5.39 +#include <xen/features.h>
    5.40 +#include "platform-pci.h"
    5.41 +
    5.42 +void *shared_info_area;
    5.43 +
    5.44 +#define MAX_EVTCHN 256
    5.45 +static struct
    5.46 +{
    5.47 +	irqreturn_t(*handler) (int, void *, struct pt_regs *);
    5.48 +	void *dev_id;
    5.49 +} evtchns[MAX_EVTCHN];
    5.50 +
    5.51 +void mask_evtchn(int port)
    5.52 +{
    5.53 +	shared_info_t *s = shared_info_area;
    5.54 +	synch_set_bit(port, &s->evtchn_mask[0]);
    5.55 +}
    5.56 +EXPORT_SYMBOL(mask_evtchn);
    5.57 +
    5.58 +void unmask_evtchn(int port)
    5.59 +{
    5.60 +	unsigned int cpu;
    5.61 +	shared_info_t *s = shared_info_area;
    5.62 +	vcpu_info_t *vcpu_info;
    5.63 +
    5.64 +	preempt_disable();
    5.65 +	cpu = smp_processor_id();
    5.66 +	vcpu_info = &s->vcpu_info[cpu];
    5.67 +
    5.68 +	/* Slow path (hypercall) if this is a non-local port.  We only
    5.69 +	   ever bind event channels to vcpu 0 in HVM guests. */
    5.70 +	if (unlikely(cpu != 0)) {
    5.71 +		evtchn_unmask_t op = { .port = port };
    5.72 +		(void)HYPERVISOR_event_channel_op(EVTCHNOP_unmask,
    5.73 +						  &op);
    5.74 +		preempt_enable();
    5.75 +		return;
    5.76 +	}
    5.77 +
    5.78 +	synch_clear_bit(port, &s->evtchn_mask[0]);
    5.79 +
    5.80 +	/*
    5.81 +	 * The following is basically the equivalent of
    5.82 +	 * 'hw_resend_irq'. Just like a real IO-APIC we 'lose the
    5.83 +	 * interrupt edge' if the channel is masked.
    5.84 +	 */
    5.85 +	if (synch_test_bit(port, &s->evtchn_pending[0]) &&
    5.86 +	    !synch_test_and_set_bit(port / BITS_PER_LONG,
    5.87 +				    &vcpu_info->evtchn_pending_sel)) {
    5.88 +		vcpu_info->evtchn_upcall_pending = 1;
    5.89 +		if (!vcpu_info->evtchn_upcall_mask)
    5.90 +			force_evtchn_callback();
    5.91 +	}
    5.92 +	preempt_enable();
    5.93 +}
    5.94 +EXPORT_SYMBOL(unmask_evtchn);
    5.95 +
    5.96 +int
    5.97 +bind_evtchn_to_irqhandler(unsigned int evtchn,
    5.98 +			  irqreturn_t(*handler) (int, void *,
    5.99 +						 struct pt_regs *),
   5.100 +			  unsigned long irqflags, const char *devname,
   5.101 +			  void *dev_id)
   5.102 +{
   5.103 +	if (evtchn >= MAX_EVTCHN)
   5.104 +		return -EINVAL;
   5.105 +	evtchns[evtchn].handler = handler;
   5.106 +	evtchns[evtchn].dev_id = dev_id;
   5.107 +	unmask_evtchn(evtchn);
   5.108 +	return evtchn;
   5.109 +}
   5.110 +
   5.111 +EXPORT_SYMBOL(bind_evtchn_to_irqhandler);
   5.112 +
   5.113 +void unbind_from_irqhandler(unsigned int evtchn, void *dev_id)
   5.114 +{
   5.115 +	if (evtchn >= MAX_EVTCHN)
   5.116 +		return;
   5.117 +
   5.118 +	mask_evtchn(evtchn);
   5.119 +	evtchns[evtchn].handler = NULL;
   5.120 +}
   5.121 +
   5.122 +EXPORT_SYMBOL(unbind_from_irqhandler);
   5.123 +
   5.124 +void notify_remote_via_irq(int irq)
   5.125 +{
   5.126 +	int evtchn = irq;
   5.127 +	notify_remote_via_evtchn(evtchn);
   5.128 +}
   5.129 +
   5.130 +EXPORT_SYMBOL(notify_remote_via_irq);
   5.131 +
   5.132 +irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs)
   5.133 +{
   5.134 +	unsigned int l1i, l2i, port;
   5.135 +	int cpu = smp_processor_id();
   5.136 +	irqreturn_t(*handler) (int, void *, struct pt_regs *);
   5.137 +	shared_info_t *s = shared_info_area;
   5.138 +	vcpu_info_t *v = &s->vcpu_info[cpu];
   5.139 +	unsigned long l1, l2;
   5.140 +
   5.141 +	v->evtchn_upcall_pending = 0;
   5.142 +	/* NB. No need for a barrier here -- XCHG is a barrier
   5.143 +	 * on x86. */
   5.144 +	l1 = xchg(&v->evtchn_pending_sel, 0);
   5.145 +	while (l1 != 0)
   5.146 +	{
   5.147 +		l1i = __ffs(l1);
   5.148 +		l1 &= ~(1 << l1i);
   5.149 +
   5.150 +		l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
   5.151 +		while (l2 != 0)
   5.152 +		{
   5.153 +			l2i = __ffs(l2);
   5.154 +
   5.155 +			port = (l1i * BITS_PER_LONG) + l2i;
   5.156 +			synch_clear_bit(port, &s->evtchn_pending[0]);
   5.157 +			if ((handler = evtchns[port].handler) != NULL)
   5.158 +			{
   5.159 +				handler(port, evtchns[port].dev_id,
   5.160 +					regs);
   5.161 +			}
   5.162 +			else
   5.163 +			{
   5.164 +				printk(KERN_WARNING "unexpected event channel upcall on port %d!\n", port);
   5.165 +			}
   5.166 +			l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i];
   5.167 +		}
   5.168 +	}
   5.169 +	return IRQ_HANDLED;
   5.170 +}
   5.171 +
   5.172 +void force_evtchn_callback(void)
   5.173 +{
   5.174 +	evtchn_interrupt(0, NULL, NULL);
   5.175 +}
   5.176 +EXPORT_SYMBOL(force_evtchn_callback);
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c	Thu Aug 17 16:08:01 2006 +0100
     6.3 @@ -0,0 +1,268 @@
     6.4 +/******************************************************************************
     6.5 + * evtchn-pci.c
     6.6 + * xen event channel fake PCI device driver
     6.7 + * Copyright (C) 2005, Intel Corporation.
     6.8 + *
     6.9 + * This program is free software; you can redistribute it and/or modify it
    6.10 + * under the terms and conditions of the GNU General Public License,
    6.11 + * version 2, as published by the Free Software Foundation.
    6.12 + *
    6.13 + * This program is distributed in the hope it will be useful, but WITHOUT
    6.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    6.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    6.16 + * more details.
    6.17 + *
    6.18 + * You should have received a copy of the GNU General Public License along with
    6.19 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    6.20 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    6.21 + *
    6.22 + */
    6.23 +#include <linux/module.h>
    6.24 +#include <linux/kernel.h>
    6.25 +#include <linux/sched.h>
    6.26 +#include <linux/errno.h>
    6.27 +#include <linux/pci.h>
    6.28 +#include <linux/init.h>
    6.29 +#include <linux/version.h>
    6.30 +#include <linux/interrupt.h>
    6.31 +#include <asm/system.h>
    6.32 +#include <asm/io.h>
    6.33 +#include <asm/irq.h>
    6.34 +#include <asm/uaccess.h>
    6.35 +#include <asm/hypervisor.h>
    6.36 +#include <xen/interface/memory.h>
    6.37 +#include <xen/features.h>
    6.38 +
    6.39 +#include "platform-pci.h"
    6.40 +
    6.41 +#define DRV_NAME    "xen-platform-pci"
    6.42 +#define DRV_VERSION "0.10"
    6.43 +#define DRV_RELDATE "03/03/2005"
    6.44 +
    6.45 +char hypercall_page[PAGE_SIZE];
    6.46 +EXPORT_SYMBOL(hypercall_page);
    6.47 +
    6.48 +// Used to be xiaofeng.ling@intel.com
    6.49 +MODULE_AUTHOR("ssmith@xensource.com");
    6.50 +MODULE_DESCRIPTION("Xen platform PCI device");
    6.51 +MODULE_LICENSE("GPL");
    6.52 +
    6.53 +
    6.54 +unsigned long *phys_to_machine_mapping;
    6.55 +EXPORT_SYMBOL(phys_to_machine_mapping);
    6.56 +
    6.57 +static int __init init_xen_info(void)
    6.58 +{
    6.59 +	unsigned long shared_info_frame;
    6.60 +	struct xen_add_to_physmap xatp;
    6.61 +	extern void *shared_info_area;
    6.62 +
    6.63 +	setup_xen_features();
    6.64 +
    6.65 +	shared_info_frame = alloc_xen_mmio(PAGE_SIZE) >> PAGE_SHIFT;
    6.66 +	xatp.domid = DOMID_SELF;
    6.67 +	xatp.idx = 0;
    6.68 +	xatp.space = XENMAPSPACE_shared_info;
    6.69 +	xatp.gpfn = shared_info_frame;
    6.70 +	BUG_ON(HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp));
    6.71 +	shared_info_area =
    6.72 +		ioremap(shared_info_frame << PAGE_SHIFT, PAGE_SIZE);
    6.73 +
    6.74 +	if (!shared_info_area)
    6.75 +		panic("can't map shared info\n");
    6.76 +
    6.77 +	phys_to_machine_mapping = NULL;
    6.78 +
    6.79 +	return 0;
    6.80 +}
    6.81 +
    6.82 +static void __devexit platform_pci_remove(struct pci_dev *pdev)
    6.83 +{
    6.84 +	long ioaddr, iolen;
    6.85 +	long mmio_addr, mmio_len;
    6.86 +
    6.87 +	ioaddr = pci_resource_start(pdev, 0);
    6.88 +	iolen = pci_resource_len(pdev, 0);
    6.89 +	mmio_addr = pci_resource_start(pdev, 1);
    6.90 +	mmio_len = pci_resource_len(pdev, 1);
    6.91 +
    6.92 +	release_region(ioaddr, iolen);
    6.93 +	release_mem_region(mmio_addr, mmio_len);
    6.94 +
    6.95 +	pci_set_drvdata(pdev, NULL);
    6.96 +	free_irq(pdev->irq, pdev);
    6.97 +}
    6.98 +
    6.99 +static unsigned long platform_mmio;
   6.100 +static unsigned long platform_mmio_alloc;
   6.101 +static unsigned long platform_mmiolen;
   6.102 +
   6.103 +unsigned long alloc_xen_mmio(unsigned long len)
   6.104 +{
   6.105 +	unsigned long addr;
   6.106 +
   6.107 +	addr = 0;
   6.108 +	if (platform_mmio_alloc + len <= platform_mmiolen)
   6.109 +	{
   6.110 +		addr = platform_mmio + platform_mmio_alloc;
   6.111 +		platform_mmio_alloc += len;
   6.112 +	} else {
   6.113 +		panic("ran out of xen mmio space");
   6.114 +	}
   6.115 +	return addr;
   6.116 +}
   6.117 +
   6.118 +/* Lifted from hvmloader.c */
   6.119 +static int get_hypercall_page(void)
   6.120 +{
   6.121 +	void *tmp_hypercall_page;
   6.122 +	uint32_t eax, ebx, ecx, edx;
   6.123 +	char signature[13];
   6.124 +
   6.125 +	cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
   6.126 +	*(uint32_t*)(signature + 0) = ebx;
   6.127 +	*(uint32_t*)(signature + 4) = ecx;
   6.128 +	*(uint32_t*)(signature + 8) = edx;
   6.129 +	signature[12] = 0;
   6.130 +
   6.131 +	if (strcmp("XenVMMXenVMM", signature) || eax < 0x40000002) {
   6.132 +		printk(KERN_WARNING
   6.133 +		       "Detected Xen platform device but not Xen VMM? (sig %s, eax %x)\n",
   6.134 +		       signature, eax);
   6.135 +		return -EINVAL;
   6.136 +	}
   6.137 +
   6.138 +	cpuid(0x40000001, &eax, &ebx, &ecx, &edx);
   6.139 +
   6.140 +	printk(KERN_INFO "Xen version %d.%d.\n", eax >> 16, eax & 0xffff);
   6.141 +
   6.142 +	cpuid(0x40000002, &eax, &ebx, &ecx, &edx);
   6.143 +
   6.144 +	if (eax != 1) {
   6.145 +		printk(KERN_WARNING
   6.146 +		       "This Xen version uses a %d page hypercall area,"
   6.147 +		       "but these modules only support 1 page.\n",
   6.148 +		       eax);
   6.149 +		return -EINVAL;
   6.150 +	}
   6.151 +
   6.152 +	tmp_hypercall_page = (void *)__get_free_page(GFP_KERNEL);
   6.153 +	if (!tmp_hypercall_page)
   6.154 +		return -ENOMEM;
   6.155 +	memset(tmp_hypercall_page, 0xcc, PAGE_SIZE);
   6.156 +	if (wrmsr_safe(ebx, virt_to_phys(tmp_hypercall_page), 0))
   6.157 +		panic("Can't do wrmsr; not running on Xen?\n");
   6.158 +	memcpy(hypercall_page, tmp_hypercall_page, PAGE_SIZE);
   6.159 +	free_page((unsigned long)tmp_hypercall_page);
   6.160 +
   6.161 +	return 0;
   6.162 +}
   6.163 +
   6.164 +static int __devinit platform_pci_init(struct pci_dev *pdev,
   6.165 +				       const struct pci_device_id *ent)
   6.166 +{
   6.167 +	int i, ret;
   6.168 +	long ioaddr, iolen;
   6.169 +	long mmio_addr, mmio_len;
   6.170 +
   6.171 +	i = pci_enable_device(pdev);
   6.172 +	if (i)
   6.173 +		return i;
   6.174 +
   6.175 +	ioaddr = pci_resource_start(pdev, 0);
   6.176 +	iolen = pci_resource_len(pdev, 0);
   6.177 +
   6.178 +	mmio_addr = pci_resource_start(pdev, 1);
   6.179 +	mmio_len = pci_resource_len(pdev, 1);
   6.180 +
   6.181 +	if (mmio_addr == 0 || ioaddr == 0) {
   6.182 +		printk(KERN_WARNING DRV_NAME ":no resources found\n");
   6.183 +		return -ENOENT;
   6.184 +	}
   6.185 +
   6.186 +	if (request_mem_region(mmio_addr, mmio_len, DRV_NAME) == NULL)
   6.187 +	{
   6.188 +		printk(KERN_ERR ":MEM I/O resource 0x%lx @ 0x%lx busy\n",
   6.189 +		       mmio_addr, mmio_len);
   6.190 +		return -EBUSY;
   6.191 +	}
   6.192 +
   6.193 +	if (request_region(ioaddr, iolen, DRV_NAME) == NULL)
   6.194 +	{
   6.195 +		printk(KERN_ERR DRV_NAME ":I/O resource 0x%lx @ 0x%lx busy\n",
   6.196 +		       iolen, ioaddr);
   6.197 +		release_mem_region(mmio_addr, mmio_len);
   6.198 +		return -EBUSY;
   6.199 +	}
   6.200 +
   6.201 +	platform_mmio = mmio_addr;
   6.202 +	platform_mmiolen = mmio_len;
   6.203 +
   6.204 +	ret = get_hypercall_page();
   6.205 +	if (ret < 0)
   6.206 +		goto out;
   6.207 +
   6.208 +	
   6.209 +	if ((ret = init_xen_info()))
   6.210 +		goto out;
   6.211 +
   6.212 +	if ((ret = request_irq(pdev->irq, evtchn_interrupt, SA_SHIRQ,
   6.213 +			       "xen-platform-pci", pdev))) {
   6.214 +		goto out;
   6.215 +	}
   6.216 +
   6.217 +	if ((ret = set_callback_irq(pdev->irq)))
   6.218 +		goto out;
   6.219 +
   6.220 + out:
   6.221 +	if (ret) {
   6.222 +		release_mem_region(mmio_addr, mmio_len);
   6.223 +		release_region(ioaddr, iolen);
   6.224 +	}
   6.225 +
   6.226 +	return ret;
   6.227 +}
   6.228 +
   6.229 +#define XEN_PLATFORM_VENDOR_ID 0xfffd
   6.230 +#define XEN_PLATFORM_DEVICE_ID 0x0101
   6.231 +static struct pci_device_id platform_pci_tbl[] __devinitdata = {
   6.232 +	{XEN_PLATFORM_VENDOR_ID, XEN_PLATFORM_DEVICE_ID,
   6.233 +	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
   6.234 +	{0,}
   6.235 +};
   6.236 +
   6.237 +MODULE_DEVICE_TABLE(pci, platform_pci_tbl);
   6.238 +
   6.239 +static struct pci_driver platform_driver = {
   6.240 +	name:     DRV_NAME,
   6.241 +	probe:    platform_pci_init,
   6.242 +	remove:   __devexit_p(platform_pci_remove),
   6.243 +	id_table: platform_pci_tbl,
   6.244 +};
   6.245 +
   6.246 +static int pci_device_registered;
   6.247 +
   6.248 +static int __init platform_pci_module_init(void)
   6.249 +{
   6.250 +	int rc;
   6.251 +
   6.252 +	rc = pci_module_init(&platform_driver);
   6.253 +	if (rc)
   6.254 +		printk(KERN_INFO DRV_NAME ":No platform pci device model found\n");
   6.255 +	else
   6.256 +		pci_device_registered = 1;
   6.257 +
   6.258 +	return rc;
   6.259 +}
   6.260 +
   6.261 +static void __exit platform_pci_module_cleanup(void)
   6.262 +{
   6.263 +	printk(KERN_INFO DRV_NAME ":Do platform module cleanup\n");
   6.264 +	/* disable hypervisor for callback irq */
   6.265 +	set_callback_irq(0);
   6.266 +	if (pci_device_registered)
   6.267 +		pci_unregister_driver(&platform_driver);
   6.268 +}
   6.269 +
   6.270 +module_init(platform_pci_module_init);
   6.271 +module_exit(platform_pci_module_cleanup);
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h	Thu Aug 17 16:08:01 2006 +0100
     7.3 @@ -0,0 +1,43 @@
     7.4 +/******************************************************************************
     7.5 + * evtchn-pci.h
     7.6 + * module driver support in unmodified Linux
     7.7 + * Copyright (C) 2004, Intel Corporation. <xiaofeng.ling@intel.com>
     7.8 + *
     7.9 + * This program is free software; you can redistribute it and/or modify it
    7.10 + * under the terms and conditions of the GNU General Public License,
    7.11 + * version 2, as published by the Free Software Foundation.
    7.12 + *
    7.13 + * This program is distributed in the hope it will be useful, but WITHOUT
    7.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    7.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    7.16 + * more details.
    7.17 + *
    7.18 + * You should have received a copy of the GNU General Public License along with
    7.19 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    7.20 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    7.21 + *
    7.22 + */
    7.23 +
    7.24 +#ifndef __XEN_SUPPORT_H
    7.25 +#define __XEN_SUPPORT_H
    7.26 +#include <linux/version.h>
    7.27 +#include <linux/interrupt.h>
    7.28 +#include <xen/interface/hvm/params.h>
    7.29 +
    7.30 +static inline int set_callback_irq(int irq)
    7.31 +{
    7.32 +	struct xen_hvm_param a;
    7.33 +
    7.34 +	a.domid = DOMID_SELF;
    7.35 +	a.index = HVM_PARAM_CALLBACK_IRQ;
    7.36 +	a.value = irq;
    7.37 +	return HYPERVISOR_hvm_op(HVMOP_set_param, &a);
    7.38 +}
    7.39 +
    7.40 +unsigned long alloc_xen_mmio(unsigned long len);
    7.41 +
    7.42 +void setup_xen_features(void);
    7.43 +
    7.44 +irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs);
    7.45 +
    7.46 +#endif
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c	Thu Aug 17 16:08:01 2006 +0100
     8.3 @@ -0,0 +1,39 @@
     8.4 +/******************************************************************************
     8.5 + * support.c
     8.6 + * Xen module support functions.
     8.7 + * Copyright (C) 2004, Intel Corporation.
     8.8 + *
     8.9 + * This program is free software; you can redistribute it and/or modify it
    8.10 + * under the terms and conditions of the GNU General Public License,
    8.11 + * version 2, as published by the Free Software Foundation.
    8.12 + *
    8.13 + * This program is distributed in the hope it will be useful, but WITHOUT
    8.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    8.15 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
    8.16 + * more details.
    8.17 + *
    8.18 + * You should have received a copy of the GNU General Public License along with
    8.19 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    8.20 + * Place - Suite 330, Boston, MA 02111-1307 USA.
    8.21 + *
    8.22 + */
    8.23 +
    8.24 +#include <linux/module.h>
    8.25 +#include <linux/init.h>
    8.26 +#include <linux/mm.h>
    8.27 +#include <xen/evtchn.h>
    8.28 +#include <xen/interface/xen.h>
    8.29 +#include <asm/hypervisor.h>
    8.30 +#include "platform-pci.h"
    8.31 +
    8.32 +EXPORT_SYMBOL(xen_machphys_update);
    8.33 +void xen_machphys_update(unsigned long mfn, unsigned long pfn)
    8.34 +{
    8.35 +	BUG();
    8.36 +}
    8.37 +
    8.38 +void balloon_update_driver_allowance(long delta)
    8.39 +{
    8.40 +}
    8.41 +
    8.42 +EXPORT_SYMBOL(balloon_update_driver_allowance);