diff options
Diffstat (limited to 'unmodified_drivers/linux-2.6/platform-pci')
6 files changed, 200 insertions, 25 deletions
diff --git a/unmodified_drivers/linux-2.6/platform-pci/Kbuild b/unmodified_drivers/linux-2.6/platform-pci/Kbuild index a4c1961a8a..a44e50e94c 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/Kbuild +++ b/unmodified_drivers/linux-2.6/platform-pci/Kbuild @@ -4,4 +4,9 @@ obj-m := xen-platform-pci.o EXTRA_CFLAGS += -I$(M)/platform-pci -xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o +xen-platform-pci-objs := evtchn.o platform-pci.o gnttab.o xen_support.o features.o platform-compat.o + +# Can we do better ? +ifeq ($(ARCH),ia64) + xen-platform-pci-objs += xcom_mini.o xencomm.o +endif diff --git a/unmodified_drivers/linux-2.6/platform-pci/Makefile b/unmodified_drivers/linux-2.6/platform-pci/Makefile new file mode 100644 index 0000000000..64e7acd194 --- /dev/null +++ b/unmodified_drivers/linux-2.6/platform-pci/Makefile @@ -0,0 +1,3 @@ +ifneq ($(KERNELRELEASE),) +include $(src)/Kbuild +endif diff --git a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c index a38c50c1c4..e328cf9663 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c +++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c @@ -36,6 +36,10 @@ #include <xen/features.h> #include "platform-pci.h" +#ifdef HAVE_XEN_PLATFORM_COMPAT_H +#include <xen/platform-compat.h> +#endif + void *shared_info_area; #define MAX_EVTCHN 256 @@ -128,7 +132,7 @@ EXPORT_SYMBOL(notify_remote_via_irq); irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - unsigned int l1i, l2i, port; + unsigned int l1i, port; int cpu = smp_processor_id(); irqreturn_t(*handler) (int, void *, struct pt_regs *); shared_info_t *s = shared_info_area; @@ -136,38 +140,28 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) unsigned long l1, l2; v->evtchn_upcall_pending = 0; - /* NB. No need for a barrier here -- XCHG is a barrier - * on x86. */ + /* NB. No need for a barrier here -- XCHG is a barrier on x86. */ l1 = xchg(&v->evtchn_pending_sel, 0); - while (l1 != 0) - { + while (l1 != 0) { l1i = __ffs(l1); l1 &= ~(1 << l1i); - - l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]; - while (l2 != 0) - { - l2i = __ffs(l2); - - port = (l1i * BITS_PER_LONG) + l2i; + while ((l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i])) { + port = (l1i * BITS_PER_LONG) + __ffs(l2); synch_clear_bit(port, &s->evtchn_pending[0]); if ((handler = evtchns[port].handler) != NULL) - { handler(port, evtchns[port].dev_id, regs); - } else - { - printk(KERN_WARNING "unexpected event channel upcall on port %d!\n", port); - } - l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]; + printk(KERN_WARNING "unexpected event channel " + "upcall on port %d!\n", port); } } + return IRQ_HANDLED; } void force_evtchn_callback(void) { - evtchn_interrupt(0, NULL, NULL); + (void)HYPERVISOR_xen_version(0, NULL); } EXPORT_SYMBOL(force_evtchn_callback); diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c new file mode 100644 index 0000000000..5a0bb9bce8 --- /dev/null +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c @@ -0,0 +1,139 @@ +#include <linux/config.h> +#include <linux/version.h> + +#include <linux/mm.h> +#include <linux/module.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <xen/platform-compat.h> + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7) +static int system_state = 1; +EXPORT_SYMBOL(system_state); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) +size_t strcspn(const char *s, const char *reject) +{ + const char *p; + const char *r; + size_t count = 0; + + for (p = s; *p != '\0'; ++p) { + for (r = reject; *r != '\0'; ++r) { + if (*p == *r) + return count; + } + ++count; + } + + return count; +} +EXPORT_SYMBOL(strcspn); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +/* + * Map a vmalloc()-space virtual address to the physical page frame number. + */ +unsigned long vmalloc_to_pfn(void * vmalloc_addr) +{ + return page_to_pfn(vmalloc_to_page(vmalloc_addr)); +} +EXPORT_SYMBOL(vmalloc_to_pfn); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11) +unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout) +{ + might_sleep(); + + spin_lock_irq(&x->wait.lock); + if (!x->done) { + DECLARE_WAITQUEUE(wait, current); + + wait.flags |= WQ_FLAG_EXCLUSIVE; + __add_wait_queue_tail(&x->wait, &wait); + do { + __set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock_irq(&x->wait.lock); + timeout = schedule_timeout(timeout); + spin_lock_irq(&x->wait.lock); + if (!timeout) { + __remove_wait_queue(&x->wait, &wait); + goto out; + } + } while (!x->done); + __remove_wait_queue(&x->wait, &wait); + } + x->done--; +out: + spin_unlock_irq(&x->wait.lock); + return timeout; +} +EXPORT_SYMBOL(wait_for_completion_timeout); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,12) +/* + fake do_exit using complete_and_exit + */ +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10) +asmlinkage NORET_TYPE void do_exit(long code) +#else +fastcall NORET_TYPE void do_exit(long code) +#endif +{ + complete_and_exit(NULL, code); +} +EXPORT_SYMBOL_GPL(do_exit); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) +signed long schedule_timeout_interruptible(signed long timeout) +{ + __set_current_state(TASK_INTERRUPTIBLE); + return schedule_timeout(timeout); +} +EXPORT_SYMBOL(schedule_timeout_interruptible); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) +/** + * kzalloc - allocate memory. The memory is set to zero. + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + */ +void *kzalloc(size_t size, int flags) +{ + void *ret = kmalloc(size, flags); + if (ret) + memset(ret, 0, size); + return ret; +} +EXPORT_SYMBOL(kzalloc); +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +/* Simplified asprintf. */ +char *kasprintf(gfp_t gfp, const char *fmt, ...) +{ + va_list ap; + unsigned int len; + char *p, dummy[1]; + + va_start(ap, fmt); + len = vsnprintf(dummy, 0, fmt, ap); + va_end(ap); + + p = kmalloc(len + 1, gfp); + if (!p) + return NULL; + va_start(ap, fmt); + vsprintf(p, fmt, ap); + va_end(ap); + return p; +} +EXPORT_SYMBOL(kasprintf); +#endif diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c index 2bb4dbd5b4..3a2453a25c 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c @@ -33,11 +33,19 @@ #include <asm/irq.h> #include <asm/uaccess.h> #include <asm/hypervisor.h> +#include <asm/pgtable.h> #include <xen/interface/memory.h> #include <xen/features.h> +#ifdef __ia64__ +#include <asm/xen/xencomm.h> +#endif #include "platform-pci.h" +#ifdef HAVE_XEN_PLATFORM_COMPAT_H +#include <xen/platform-compat.h> +#endif + #define DRV_NAME "xen-platform-pci" #define DRV_VERSION "0.10" #define DRV_RELDATE "03/03/2005" @@ -59,6 +67,10 @@ static int __init init_xen_info(void) struct xen_add_to_physmap xatp; extern void *shared_info_area; +#ifdef __ia64__ + xencomm_init(); +#endif + setup_xen_features(); shared_info_frame = alloc_xen_mmio(PAGE_SIZE) >> PAGE_SHIFT; @@ -167,10 +179,24 @@ static int get_hypercall_stubs(void) #define get_hypercall_stubs() (0) #endif +static int get_callback_irq(struct pci_dev *pdev) +{ +#ifdef __ia64__ + int irq; + for (irq = 0; irq < 16; irq++) { + if (isa_irq_to_vector(irq) == pdev->irq) + return irq; + } + return 0; +#else /* !__ia64__ */ + return pdev->irq; +#endif +} + static int __devinit platform_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent) { - int i, ret; + int i, ret, callback_irq; long ioaddr, iolen; long mmio_addr, mmio_len; @@ -184,7 +210,9 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, mmio_addr = pci_resource_start(pdev, 1); mmio_len = pci_resource_len(pdev, 1); - if (mmio_addr == 0 || ioaddr == 0) { + callback_irq = get_callback_irq(pdev); + + if (mmio_addr == 0 || ioaddr == 0 || callback_irq == 0) { printk(KERN_WARNING DRV_NAME ":no resources found\n"); return -ENOENT; } @@ -219,7 +247,7 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, goto out; } - if ((ret = set_callback_irq(pdev->irq))) + if ((ret = set_callback_irq(callback_irq))) goto out; out: @@ -231,11 +259,13 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, return ret; } -#define XEN_PLATFORM_VENDOR_ID 0xfffd -#define XEN_PLATFORM_DEVICE_ID 0x0101 +#define XEN_PLATFORM_VENDOR_ID 0x5853 +#define XEN_PLATFORM_DEVICE_ID 0x0001 static struct pci_device_id platform_pci_tbl[] __devinitdata = { {XEN_PLATFORM_VENDOR_ID, XEN_PLATFORM_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + /* Continue to recognise the old ID for now */ + {0xfffd, 0x0101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,} }; diff --git a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c index b1a903b1c7..423d2f2e24 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c +++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c @@ -26,6 +26,10 @@ #include <asm/hypervisor.h> #include "platform-pci.h" +#ifdef HAVE_XEN_PLATFORM_COMPAT_H +#include <xen/platform-compat.h> +#endif + void xen_machphys_update(unsigned long mfn, unsigned long pfn) { BUG(); |