[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 1/2][PV-on-HVM] Enable Front-end drivers for 2.4 kernels



[PATCH 1/2][PV-on-HVM] Enable Front-end drivers for 2.4 kernels

This patch enables front end drivers to build under Linux 2.4 (RHEL3-U8)

Signed-off-by: Paul Burkacki <pburkacki@xxxxxxxxxxxxxxx>
Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>


diffstat xen-RHEL3U8-port.patch
b/unmodified_drivers/linux-2.6/balloon/K24build                   |   10
b/unmodified_drivers/linux-2.6/blkfront/K24build                  |    6
b/unmodified_drivers/linux-2.6/compat-include/linux/cpumask.h     |   17
b/unmodified_drivers/linux-2.6/compat-include/linux/device.h      |   13
b/unmodified_drivers/linux-2.6/compat-include/linux/err.h         |    9
b/unmodified_drivers/linux-2.6/compat-include/linux/kthread.h     |    7
b/unmodified_drivers/linux-2.6/compat-include/linux/preempt.h     |    7
b/unmodified_drivers/linux-2.6/compat-include/linux/seqlock.h     |    8
b/unmodified_drivers/linux-2.6/netfront/K24build                  |    8
b/unmodified_drivers/linux-2.6/platform-pci/K24build              |   29
unmodified_drivers/linux-2.6/Makefile                             |   17
unmodified_drivers/linux-2.6/balloon/Makefile                     |    7
unmodified_drivers/linux-2.6/blkfront/Makefile                    |    7
unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h | 384 ++++++++
unmodified_drivers/linux-2.6/mkbuildtree                          |   16
unmodified_drivers/linux-2.6/netfront/Makefile                    |    7
unmodified_drivers/linux-2.6/overrides.mk                         |    7
unmodified_drivers/linux-2.6/platform-pci/Makefile                |    7
unmodified_drivers/linux-2.6/platform-pci/evtchn.c                |    4
unmodified_drivers/linux-2.6/platform-pci/platform-compat.c | 453 +++++++++-
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c          |    6
unmodified_drivers/linux-2.6/platform-pci/xen_support.c           |    4
22 files changed, 1007 insertions(+), 26 deletions(-)

[PATCH 1/2][PV-on-HVM] Enable Front-end drivers for 2.4 kernels

This patch enables front end drivers to build under Linux 2.4 (RHEL3-U8)

Signed-off-by: Paul Burkacki <pburkacki@xxxxxxxxxxxxxxx>
Signed-off-by: Ben Guthro <bguthro@xxxxxxxxxxxxxxx>

diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/Makefile
--- a/unmodified_drivers/linux-2.6/Makefile     Mon Dec 17 15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/Makefile     Mon Dec 17 15:54:42 2007 -0500
@@ -1,6 +1,15 @@ include $(M)/overrides.mk
 include $(M)/overrides.mk
 
-obj-m += platform-pci/
-obj-m += balloon/
-obj-m += blkfront/
-obj-m += netfront/
+ifeq ($(VERSION).$(PATCHLEVEL),2.6)
+       obj-m += platform-pci/
+       obj-m += balloon/
+       obj-m += blkfront/
+       obj-m += netfront/
+endif
+
+ifeq ($(VERSION).$(PATCHLEVEL),2.4)
+       mod-subdirs := platform-pci balloon blkfront netfront
+       subdir-y := platform-pci balloon blkfront netfront
+
+       include $(TOPDIR)/Rules.make
+endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/balloon/K24build
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/balloon/K24build     Mon Dec 17 15:54:42 
2007 -0500
@@ -0,0 +1,10 @@
+EXTRA_CFLAGS += -I$(M)/platform-pci
+
+O_TARGET := xen-balloon.o
+
+export-objs := balloon.o
+
+obj-y := balloon.o
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/balloon/Makefile
--- a/unmodified_drivers/linux-2.6/balloon/Makefile     Mon Dec 17 15:54:42 
2007 -0500
+++ b/unmodified_drivers/linux-2.6/balloon/Makefile     Mon Dec 17 15:54:42 
2007 -0500
@@ -1,3 +1,8 @@ ifneq ($(KERNELRELEASE),)
-ifneq ($(KERNELRELEASE),)
+ifeq ($(VERSION).$(PATCHLEVEL),2.6)
 include $(src)/Kbuild
 endif
+
+ifeq ($(VERSION).$(PATCHLEVEL),2.4)
+include $(M)/overrides.mk
+include K24build
+endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/blkfront/K24build
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/blkfront/K24build    Mon Dec 17 15:54:42 
2007 -0500
@@ -0,0 +1,6 @@
+O_TARGET := xen-vbd.o
+
+obj-y := blkfront.o vbd.o
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/blkfront/Makefile
--- a/unmodified_drivers/linux-2.6/blkfront/Makefile    Mon Dec 17 15:54:42 
2007 -0500
+++ b/unmodified_drivers/linux-2.6/blkfront/Makefile    Mon Dec 17 15:54:42 
2007 -0500
@@ -1,3 +1,8 @@ ifneq ($(KERNELRELEASE),)
-ifneq ($(KERNELRELEASE),)
+ifeq ($(VERSION).$(PATCHLEVEL),2.6)
 include $(src)/Kbuild
 endif
+
+ifeq ($(VERSION).$(PATCHLEVEL),2.4)
+include $(M)/overrides.mk
+include K24build
+endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/compat-include/linux/cpumask.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/cpumask.h       Mon Dec 
17 15:54:42 2007 -0500
@@ -0,0 +1,17 @@
+/*
+ * Dummy cpumask.h header for pre 2.6.x kernels.
+ */
+#ifndef __LINUX_CPUMASK_H
+#define __LINUX_CPUMASK_H
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#error "This version of Linux should not need this version of linux/cpumask.h."
+#endif
+
+#include <linux/kernel.h>
+
+#include <xen/kerncompat.h>
+
+#endif /* __LINUX_CPUMASK__H */
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/compat-include/linux/device.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/device.h        Mon Dec 
17 15:54:42 2007 -0500
@@ -0,0 +1,13 @@
+/*
+ * Dummy device.h header for pre 2.6.x kernels.
+ */
+#ifndef _DEVICE_H_
+#define _DEVICE_H_
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#error "This version of Linux should not need this version of linux/device.h."
+#endif
+
+#include <xen/kerncompat.h>
+
+#endif /* _DEVICE_H_ */
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/compat-include/linux/err.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/err.h   Mon Dec 17 
15:54:42 2007 -0500
@@ -0,0 +1,9 @@
+/*
+ * Dummy err.h header for pre 2.6.x kernels.
+ */
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#error "This version of Linux should not need this version of linux/err.h."
+#endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/compat-include/linux/kthread.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/kthread.h       Mon Dec 
17 15:54:42 2007 -0500
@@ -0,0 +1,7 @@
+/*
+ * Dummy kthread.h header for pre 2.6.x kernels.
+ */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#error "This version of Linux should not need this version of linux/kthread.h."
+#endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/compat-include/linux/preempt.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/preempt.h       Mon Dec 
17 15:54:42 2007 -0500
@@ -0,0 +1,7 @@
+/*
+ * Dummy preempt.h header for pre 2.6.x kernels.
+ */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#error "This version of Linux should not need this version of linux/preempt.h."
+#endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/compat-include/linux/seqlock.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/compat-include/linux/seqlock.h       Mon Dec 
17 13:59:05 2007 -0500
@@ -0,0 +1,8 @@
+#ifndef _LINUX_SEQLOCK_H
+#define _LINUX_SEQLOCK_H
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#error "This version of Linux should not need compat linux/seqlock.h"
+#endif
+
+#endif
diff -r 6349a4bceff8 
unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h
--- a/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Mon Dec 
17 15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/compat-include/xen/platform-compat.h Mon Dec 
17 15:54:42 2007 -0500
@@ -58,10 +58,25 @@
 #define blocking_notifier_call_chain(chain,val,v) 
notifier_call_chain(chain,val,v)
 #endif
 
+/*
+ * Under kernel 2.4, set_page_count() resides in mm_inline.h, not in mm.h.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#include <linux/mm_inline.h>
+
+#if defined(_LINUX_MM_INLINE_H) && defined set_page_count
+#define init_page_count(page) set_page_count(page, 1)
+#endif
+
+#else
+
 #if defined(_LINUX_MM_H) && defined set_page_count
 #define init_page_count(page) set_page_count(page, 1)
 #endif
 
+#endif
+
 #if defined(__LINUX_GFP_H) && !defined __GFP_NOMEMALLOC
 #define __GFP_NOMEMALLOC 0
 #endif
@@ -86,7 +101,11 @@ void *kzalloc(size_t size, int flags);
 void *kzalloc(size_t size, int flags);
 #endif
 
-#if defined(_LINUX_BLKDEV_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
+/*
+ * Ensure that the following definition of end_that_request_last() is not used
+ * under kernel 2.4.  We provide a compatibility macro for this API below.
+ */
+#if defined(_LINUX_BLKDEV_H) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)) 
&& (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)))
 #define end_that_request_last(req, uptodate) end_that_request_last(req)
 #endif
 
@@ -97,10 +116,6 @@ void *kzalloc(size_t size, int flags);
 #if defined(_LINUX_KERNEL_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
 extern char *kasprintf(gfp_t gfp, const char *fmt, ...)
        __attribute__ ((format (printf, 2, 3)));
-#endif
-
-#if defined(_LINUX_SYSRQ_H) && LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)
-#define handle_sysrq(x,y,z) handle_sysrq(x,y)
 #endif
 
 #if defined(_PAGE_PRESENT) && !defined(_PAGE_NX)
@@ -140,7 +155,7 @@ extern char *kasprintf(gfp_t gfp, const 
 #define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
 #endif
 
-#if defined(_LINUX_INTERRUPT_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
+#if defined(_LINUX_INTERRUPT_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) 
&& LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 /**
  *   RHEL4-U5 pulled back this feature into the older kernel 
  *   Since it is a typedef, and not a macro - detect this kernel via
@@ -155,4 +170,359 @@ typedef irqreturn_t (*irq_handler_t)(int
 #define setup_xen_features xen_setup_features
 #endif
 
-#endif
+/*
+ * Map struct kvec into a struct iovec under kernel 2.4.
+ */
+#if defined(__LINUX_UIO_H) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define kvec iovec
+#endif
+
+/*
+ * Translate work queues into task queues for kernel 2.4.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define work_struct tq_struct
+#define schedule_work schedule_task
+#define schedule_delayed_work(func, delay)    schedule_task(func)
+#define flush_scheduled_work    flush_scheduled_tasks
+
+#ifdef INIT_WORK
+#undef INIT_WORK
+#endif
+#define INIT_WORK    INIT_TQUEUE
+
+#ifdef DECLARE_WORK
+#undef DECLARE_WORK
+#endif
+#define DECLARE_WORK(n, f, d)    struct work_struct n = {    \
+    .list = { &(n).list, &(n).list },                        \
+    .sync = 0,                                               \
+    .routine = (f),                                          \
+    .data = (d)                                              \
+}
+
+#endif
+
+#if defined(MODULE) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define subsys_initcall module_init
+#endif
+
+/*
+ * Hide differences which exist in thread APIs between kernel 2.4 and kernel 
2.6.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define kthread_should_stop()    0
+
+#define kthread_run(threadfn, data, namefmt, ...)                              
      \
+({                                                                             
      \
+    struct task_struct *__task;                                                
      \
+    long __pid;                                                                
      \
+                                                                               
      \
+    __pid = kernel_thread((threadfn), (data), CLONE_KERNEL);                   
      \
+                                                                               
      \
+    if (__pid < 0)                                                             
      \
+        __task = NULL;                                                         
      \
+    else {                                                                     
      \
+        read_lock(&tasklist_lock);                                             
      \
+        __task = find_task_by_pid(__pid);                                      
      \
+        read_unlock(&tasklist_lock);                                           
      \
+                                                                               
      \
+        snprintf(__task->comm, sizeof(__task->comm) - 1, (namefmt), ## 
__VA_ARGS__); \
+                                                                               
      \
+        spin_lock_irq(&__task->sighand->siglock);                              
      \
+        sigfillset(&__task->blocked);                                          
      \
+        flush_signals(__task);                                                 
      \
+        spin_unlock_irq(&__task->sighand->siglock);                            
      \
+    }                                                                          
      \
+                                                                               
      \
+    __task;                                                                    
      \
+})
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define might_sleep()    do {} while (0)
+#endif
+
+/*
+ * Provide structures, prototypes and other primitives required by the generic
+ * device model code implemented for kernel 2.4.  This is the stripped down
+ * version of generic device model subsystem implemented in kernel 2.6.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#include <asm/atomic.h>
+#include <linux/list.h>
+
+#define BUS_ID_SIZE    20
+
+struct device;
+struct device_driver;
+
+struct bus_type {
+    char *name;
+    int  (*match)(struct device *dev, struct device_driver *drv);
+
+    struct list_head node;               /* node in the list of buses        */
+    struct list_head drivers;            /* drivers registered with this bus */
+    struct list_head devices;            /* devices on this bus              */
+};
+
+struct device {
+    struct device *parent;               /* parent or root device */
+    char bus_id[64];                     /* device's id on the owning bus */
+    atomic_t refcount;
+    struct bus_type *bus;
+    struct device_driver *driver;
+    void *driver_data;
+    void (*release)(struct device *dev);
+
+    struct list_head node;               /* node in a bus's device list */
+    struct list_head *bus_node;          /* owning bus node */
+};
+
+struct device_driver {
+    char *name;
+    struct bus_type *bus;
+    int (*probe)(struct device *dev);
+    int (*remove)(struct device *dev);
+    void (*shutdown)(struct device *dev);
+
+    struct list_head node;               /* node in a bus's driver list */
+    struct list_head *bus_node;          /* owning bus node */
+};
+
+struct attribute {
+    char *name;
+    struct module *owner;
+    mode_t mode;
+};
+
+struct device_attribute {
+    struct attribute attr;
+    ssize_t (*show)(struct device *dev, char *buf);
+    ssize_t (*store)(struct device *dev, const char *buf, size_t count);
+};
+
+int driver_register(struct device_driver *);
+void driver_unregister(struct device_driver *);
+
+struct device * get_device(struct device *);
+void put_device(struct device *);
+int device_register(struct device *);
+void device_unregister(struct device *);
+
+int bus_for_each_dev(struct bus_type *, struct device *, void *, int 
(*fn)(struct device *, void *));
+int bus_find_device(struct bus_type *, struct device *);
+int bus_register(struct bus_type *);
+void bus_unregister(struct bus_type *);
+int device_create_file(struct device *, struct device_attribute *);
+void device_remove_file(struct device *, struct device_attribute *);
+
+#define __ATTR(_name,_mode,_show,_store) { \
+    .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE 
}, \
+    .show   = _show,                                        \
+    .store  = _store,                                       \
+}
+
+#define DEVICE_ATTR(_name,_mode,_show,_store) \
+struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store)
+
+#define dev_printk(level, dev, format, arg...)  \
+        printk(level "%s %s: " format , (dev)->driver ? (dev)->driver->name : 
"" , (dev)->bus_id , ## arg)
+
+#define dev_err(dev, format, arg...)            \
+        dev_printk(KERN_ERR , dev , format , ## arg)
+
+#endif
+
+
+/*
+ * Provide a 2.4 version of cpumask_of_cpu().
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+typedef unsigned long cpumask_t;
+/*typedef struct { DECLARE_BITMAP(bits, NR_CPUS); } cpumask_t;*/
+#define cpumask_of_cpu(x)             (1 << cpu_logical_map(x))
+
+#endif
+
+/*
+ * Hide miscellaneous differences which exist between kernel 2.4 and 2.6.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#define __GFP_NOWARN        0
+#define __GFP_NOFAIL        0
+#define __GFP_NORETRY       0
+#define __GFP_NOMEMALLOC    0
+
+#define __user
+
+typedef void irqreturn_t;
+typedef irqreturn_t (*irq_handler_t)(int, void *, struct pt_regs *);
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+
+#define preempt_enable()      do { } while(0)
+#define preempt_disable()     do { } while(0)
+
+#ifdef CONFIG_SMP
+#define num_online_cpus()     smp_num_cpus
+#else
+#define num_online_cpus()     1
+#endif
+
+#include <linux/pci.h>
+
+static inline int pci_domain_nr(struct pci_bus *bus) { return 0; }
+
+static inline void wrmsrl(unsigned long msr, unsigned long long val)
+{
+    unsigned long lo, hi;
+    lo = (unsigned long) val;
+    hi = val >> 32;
+    wrmsr (msr, lo, hi);
+}
+
+#define strlcpy    strncpy
+#define strcspn    strspn
+
+void * kzalloc(size_t size, int flags);
+
+#endif
+
+/*
+ * Provide 2.4 versions of macros, functions and other definitions required
+ * by the netfront driver.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#include <linux/netdevice.h>
+
+#define NETDEV_ALIGN            32
+#define NETDEV_ALIGN_CONST      (NETDEV_ALIGN - 1)
+
+static inline void *netdev_priv(struct net_device *dev)
+{
+    return (char *) dev + ((sizeof(struct net_device) + NETDEV_ALIGN_CONST) &
+                            ~NETDEV_ALIGN_CONST);
+}
+
+#define offset_in_page(p)  ((unsigned long)(p) & ~PAGE_MASK)
+
+static inline unsigned int jiffies_to_msecs(const unsigned long j)
+{
+#if HZ <= 1000 && !(1000 % HZ)
+    return (1000 / HZ) * j;
+#elif HZ > 1000 && !(HZ % 1000)
+    return (j + (HZ / 1000) - 1)/(HZ / 1000);
+#else
+    return (j * 1000) / HZ;
+#endif
+}
+
+static inline unsigned long msecs_to_jiffies(const unsigned int m)
+{
+    if (m > jiffies_to_msecs(MAX_JIFFY_OFFSET))
+        return MAX_JIFFY_OFFSET;
+#if HZ <= 1000 && !(1000 % HZ)
+    return (m + (1000 / HZ) - 1) / (1000 / HZ);
+#elif HZ > 1000 && !(HZ % 1000)
+    return m * (HZ / 1000);
+#else
+    return (m * HZ + 999) / 1000;
+#endif
+}
+
+#endif
+
+/*
+ * Provide a 2.4 version of the MODULE_ALIAS() macro.
+ */
+#if !defined(MODULE_ALIAS) && LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#ifdef MODULE
+#define ___module_cat(a,b)    __mod_ ## a ## b
+#define __module_cat(a,b)    ___module_cat(a,b)
+#define __MODULE_INFO(tag, name, info)                                    \
+static const char __module_cat(name,__LINE__)[]                           \
+  __attribute__((section(".modinfo"),unused)) = __stringify(tag) "=" info
+#define MODULE_ALIAS(_alias)    __MODULE_INFO(alias, alias, _alias)
+#endif
+
+#endif
+
+/*
+ * Provide various definitions required by the blkfront driver under kernel 
2.4.
+ * Compatibility versions of rq_for_each_bio() and bio_for_each_segment() refer
+ * to struct bio and struct bio_vec but use struct buffer_head.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+
+#include <linux/blk.h>
+
+#define SCSI_DISK8_MAJOR     126
+#define GENHD_FL_CD          8
+#define GENHD_FL_VIRT_PARTNS 4
+
+#define blkif_io_lock io_request_lock
+
+#define blk_start_queue
+#define blk_stop_queue
+
+typedef unsigned long sector_t;
+
+#define sector_div(n, b) \
+do {                     \
+    int _res;            \
+    _res = (n) % (b);    \
+    (n) /= (b);          \
+    _res;                \
+} while (0)
+
+
+#define bio buffer_head
+struct bio_vec {
+    struct page *bv_page;
+    unsigned int bv_len;
+    unsigned int bv_offset;
+};
+
+#define rq_for_each_bio(_bio, rq)                                   \
+    if ((rq)->bh)                                                  \
+        for ((_bio) = (rq)->bh; (_bio); (_bio) = (_bio)->b_reqnext)
+
+#define bio_for_each_segment(_biovec, _bio, i)                                 
                               \
+    struct bio_vec _bv;                                                        
                               \
+    (_biovec) = &_bv;                                                          
                               \
+    for ((i) = 0, _bv.bv_page = (_bio)->b_page, _bv.bv_offset = 
bh_offset(_bio), _bv.bv_len = (_bio)->b_size; \
+         (i) < 1;                                                              
                               \
+         (i)++)
+
+static inline struct request * elv_next_request(request_queue_t *rq)
+{
+    if (rq->plugged || list_empty(&rq->queue_head))
+        return NULL;
+
+    return (blkdev_entry_next_request(&rq->queue_head));
+}
+
+static inline void blk_requeue_request(struct request_queue *rq, struct 
request *r)
+{
+    list_add(&r->queue, &rq->queue_head);
+}
+
+#define put_disk(gd)
+
+#endif
+
+/*
+ * Block barriers are not supported under kernel 2.4.
+ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#define blk_barrier_rq(req)    0
+#endif
+
+#endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/mkbuildtree
--- a/unmodified_drivers/linux-2.6/mkbuildtree  Mon Dec 17 15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/mkbuildtree  Mon Dec 17 15:54:42 2007 -0500
@@ -35,6 +35,22 @@ ln -sf ${XL}/drivers/xen/core/features.c
 ln -sf ${XL}/drivers/xen/core/features.c platform-pci
 ln -sf ${XL}/drivers/xen/core/xen_proc.c xenbus
 ln -sf ${XL}/drivers/xen/core/reboot.c platform-pci
+
+# The export-objs target for the 2.4 build of platform-pci requires that 
sources
+# listed in that target appear in the same tree in which the module is being
+# built.  That is, references which use relative paths to get to xenbus_*.c
+# (i.e. xenbus/xenbus_xs.c, etc.) do not work under kernel 2.4.  To keep things
+# clean, we are setting up symbolic links from platform-pci to all files needed
+# from under xenbus.  This includes xenbus_xs.c, xenbus_probe.c, 
xenbus_client.c,
+# xen_proc.c, xenbus_comms.c and xenbus_dev.c
+if [ "$2" = "RHEL3-U8-32" ] ; then
+    ln -sf ${XL}/drivers/xen/xenbus/xenbus_xs.c platform-pci
+    ln -sf ${XL}/drivers/xen/xenbus/xenbus_probe.c platform-pci
+    ln -sf ${XL}/drivers/xen/xenbus/xenbus_client.c platform-pci
+    ln -sf ${XL}/drivers/xen/core/xen_proc.c platform-pci
+    ln -sf ${XL}/drivers/xen/xenbus/xenbus_comms.c platform-pci
+    ln -sf ${XL}/drivers/xen/xenbus/xenbus_dev.c platform-pci
+fi
 
 mkdir -p include/asm include/xen
 
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/netfront/K24build
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/netfront/K24build    Mon Dec 17 15:54:42 
2007 -0500
@@ -0,0 +1,8 @@
+O_TARGET := xen-vnif.o
+
+export-objs := netfront.o accel.o
+
+obj-y := netfront.o accel.o
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/netfront/Makefile
--- a/unmodified_drivers/linux-2.6/netfront/Makefile    Mon Dec 17 15:54:42 
2007 -0500
+++ b/unmodified_drivers/linux-2.6/netfront/Makefile    Mon Dec 17 15:54:42 
2007 -0500
@@ -1,3 +1,8 @@ ifneq ($(KERNELRELEASE),)
-ifneq ($(KERNELRELEASE),)
+ifeq ($(VERSION).$(PATCHLEVEL),2.6)
 include $(src)/Kbuild
 endif
+
+ifeq ($(VERSION).$(PATCHLEVEL),2.4)
+include $(M)/overrides.mk
+include K24build
+endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/overrides.mk
--- a/unmodified_drivers/linux-2.6/overrides.mk Mon Dec 17 15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/overrides.mk Mon Dec 17 15:54:42 2007 -0500
@@ -11,4 +11,9 @@ ifeq ($(ARCH),ia64)
   EXTRA_CFLAGS += -DCONFIG_VMX_GUEST
 endif
 
-EXTRA_CFLAGS += -include $(objtree)/include/linux/autoconf.h
+ifeq ($(VERSION).$(PATCHLEVEL),2.4)
+srctree := $(TOPDIR)
+export srctree
+endif
+
+EXTRA_CFLAGS += -include $(srctree)/include/linux/autoconf.h
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/platform-pci/K24build
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/unmodified_drivers/linux-2.6/platform-pci/K24build        Mon Dec 17 
15:54:42 2007 -0500
@@ -0,0 +1,29 @@
+include $(M)/overrides.mk
+
+O_TARGET := xen-platform-pci.o
+
+EXTRA_CFLAGS += -I$(M)/platform-pci -I$(M)/xenbus
+
+export-objs := evtchn.o platform-pci.o gnttab.o xen_support.o
+export-objs += features.o platform-compat.o xenbus_xs.o xenbus_probe.o
+export-objs += xenbus_client.o xen_proc.o
+
+obj-y := evtchn.o platform-pci.o gnttab.o xen_support.o
+obj-y += features.o platform-compat.o
+obj-y += reboot.o machine_reboot.o
+
+obj-y += xenbus_comms.o
+obj-y += xenbus_xs.o
+obj-y += xenbus_probe.o
+obj-y += xenbus_dev.o
+obj-y += xenbus_client.o
+obj-y += xen_proc.o
+
+# Can we do better ?
+ifeq ($(ARCH),ia64)
+  obj-y += xcom_mini.o xencomm.o
+endif
+
+obj-m := $(O_TARGET)
+
+include $(TOPDIR)/Rules.make
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/platform-pci/Makefile
--- a/unmodified_drivers/linux-2.6/platform-pci/Makefile        Mon Dec 17 
15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/platform-pci/Makefile        Mon Dec 17 
15:54:42 2007 -0500
@@ -1,3 +1,8 @@ ifneq ($(KERNELRELEASE),)
-ifneq ($(KERNELRELEASE),)
+ifeq ($(VERSION).$(PATCHLEVEL),2.6)
 include $(src)/Kbuild
 endif
+
+ifeq ($(VERSION).$(PATCHLEVEL),2.4)
+include $(M)/overrides.mk
+include K24build
+endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/platform-pci/evtchn.c
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c        Mon Dec 17 
15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c        Mon Dec 17 
15:54:42 2007 -0500
@@ -36,9 +36,7 @@
 #include <xen/features.h>
 #include "platform-pci.h"
 
-#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-#include <xen/platform-compat.h>
-#endif
+#include <xen/kerncompat.h>
 
 void *shared_info_area;
 
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/platform-pci/platform-compat.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c       Mon Dec 
17 15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c       Mon Dec 
17 15:54:42 2007 -0500
@@ -5,7 +5,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 
-#include <xen/platform-compat.h>
+#include <xen/kerncompat.h>
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,7)
 static int system_state = 1;
@@ -141,3 +141,454 @@ char *kasprintf(gfp_t gfp, const char *f
 }
 EXPORT_SYMBOL(kasprintf);
 #endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+/*
+ * Generic device model subsystem does not exist under kernel 2.4.  In order to
+ * allow front end drivers to compile under kernel 2.4, the following code
+ * implements those generic device model APIs which are called in front end
+ * drivers.  Specifically, implemented APIs are: driver_register(),
+ * driver_unregister(), get_device(), put_device(), device_register(),
+ * device_unregister(), bus_for_each_dev(), bus_register(), bus_unregister(),
+ * device_create_file and device_remove_file().  The last two functions are
+ * stubs only.  The one function implemented here which is not a member of
+ * the formal generic device model API is bus_find_device().  This is a local
+ * helper function.  Otherwise, all APIs implemented here have formal 
equivalents
+ * under kernel 2.6.  In the formal implementation of the generic device model
+ * under kernel 2.6, all equivalent APIs are defined in linux/device.h.
+ */
+
+static LIST_HEAD(bus_list);
+
+/*
+ * driver_register()
+ *
+ * Find the bus which this driver wants to be associated with.  For now, bus 
drivers
+ * are not handled because only device drivers are registered.  Once the new 
driver
+ * is registered, walk the list of devices registered with the bus to allow
+ * the driver to assume ownership of devices it can handle.
+ *
+ * A device driver is identified by:
+ * 1. having a drv->bus member which points to an already registered bus
+ *
+ * NOTE: this routine does not pay attention to device's refcount value.
+ *
+ * Arguments:
+ * drv - driver to be registered
+ *
+ * Returns:
+ * 0 - success
+ * 1 - failure
+ */
+int driver_register(struct device_driver *drv)
+{
+       struct list_head *entry;
+       struct bus_type *bus;
+       struct device *dev;
+
+       /* Find a matching bus. */
+       list_for_each(entry, &bus_list) {
+               bus = list_entry(entry, struct bus_type, node);
+
+               if (drv->bus == bus)
+                       /* We found a matching bus. */
+                       break;
+       }
+
+       if (entry == &bus_list) {
+               pr_debug("%s: no matching bus found for driver %p.\n", 
__FUNCTION__,
+                               drv->name == NULL ? "unknown" : drv->name);
+               return 1;
+       }
+
+       /*
+       * OK, we found a match.  Put this driver on bus's driver list and 
initialize
+       * relevant fields in the driver structure.
+       */
+       list_add_tail(&drv->node, &bus->drivers);
+       drv->bus_node = entry;
+
+       /*
+       * Walk the list of devices registered with this bus to allow the new 
driver
+       * to claim ownership of devices it can handle.
+       */
+       list_for_each(entry, &bus->devices) {
+               dev = list_entry(entry, struct device, node);
+
+               /* Skip over the root device and devices which are already 
claimed. */
+               if (!dev->parent || dev->driver)
+                       continue;
+
+               if (bus->match && bus->match(dev, drv)) {
+                       dev->driver = drv;
+
+                       if (drv->probe && drv->probe(dev) == 0)
+                               continue;
+                       else
+                               dev->driver = NULL;
+               }
+       }
+
+       pr_debug("%s: driver %s registered with bus %s.\n", __FUNCTION__,
+                       drv->name == NULL ? "unknown" : drv->name, bus->name);
+
+       return 0;
+}
+
+/*
+ * driver_unregister()
+ *
+ * Find the bus which this driver is associated with and unlink it.  That is:
+ * 1. remove it from bus's driver list
+ * 2. find all devices registered with this bus and remove references to this
+ *     driver
+ *
+ * NOTE: this routine does not pay attention to device's refcount value.
+ *
+ * Arguments:
+ * drv - driver to be unregistered
+ *
+ * Returns:
+ * nothing
+ */
+void driver_unregister(struct device_driver *drv)
+{
+       struct list_head *entry;
+       struct bus_type *bus;
+       struct device *dev;
+
+       /* Find a matching bus. */
+       list_for_each(entry, &bus_list) {
+               bus = list_entry(entry, struct bus_type, node);
+
+               if (drv->bus == bus)
+                       /* We found a matching bus. */
+                       break;
+       }
+
+       if (entry == &bus_list) {
+               pr_debug("%s: no matching bus found for driver %p.\n", 
__FUNCTION__,
+                               drv->name == NULL ? "unknown" : drv->name);
+               return;
+       }
+
+       /* OK, we found a match.  Remove this driver from bus's driver list. */
+       list_del(&drv->node);
+       drv->bus_node = NULL;
+
+       /*
+       * Walk the list of devices registered with this bus and disassociate 
them
+       * with this driver.
+       */
+       list_for_each(entry, &bus->devices) {
+               dev = list_entry(entry, struct device, node);
+
+               /* Skip over the root device. */
+               if (!dev->parent)
+                       continue;
+
+               if (dev->driver == drv) {
+                       if (drv->remove)
+                               drv->remove(dev);
+
+                       dev->driver = NULL;
+               }
+       }
+
+       pr_debug("%s: driver %s unregistered on bus %s.\n", __FUNCTION__,
+                       drv->name == NULL ? "unknown" : drv->name, bus->name);
+
+       return;
+}
+
+struct device * get_device(struct device *dev)
+{
+       atomic_inc(&dev->refcount);
+
+       return dev;
+}
+
+void put_device(struct device *dev)
+{
+       atomic_dec(&dev->refcount);
+
+       return;
+}
+
+/*
+ * device_register()
+ *
+ * Find the bus which this device wants to be associated with and add it to 
this
+ * bus's device list.  Once the new device is registered, walk the list of 
registered
+ * drivers and probe each to allow one to accept ownership of the new device.
+ *
+ * The bus device, that is to say, the one which is always registered along 
with
+ * the bus, is identified by:
+ * 1. having a dev->bus member which is NULL
+ * 2. having a dev->bus_id member which is equal to the bus->name memeber of
+ *     the corresponding bus
+ *
+ * A device which defines something other than a bus is, in turn, identified 
by:
+ * 1. having a dev->bus member which points to an already registered bus.
+ * 2. having a dev->parent member which points to the same bus's device (i.e.
+ *     bus->dev).
+ *
+ * NOTE: this routine does not pay attention to device's refcount value.
+ *
+ * Arguments:
+ * dev - device to be registered
+ *
+ * Returns:
+ * 0 - success
+ * 1 - failure
+ */
+int device_register(struct device *dev)
+{
+       struct list_head *entry;
+       struct bus_type *bus;
+       struct device_driver *drv;
+
+       /* Locate matching bus. */
+       list_for_each(entry, &bus_list) {
+               bus = list_entry(entry, struct bus_type, node);
+
+               if (dev->bus == NULL && (dev->bus_id != NULL && 
strcmp(dev->bus_id, bus->name) == 0))
+                       /* This is a root device and we found a bus for it. */
+                       break;
+
+               if (dev->bus == bus && bus_find_device(bus, dev->parent))
+                       /* This is a non root device and we found a bus for it. 
*/
+                       break;
+       }
+
+       if (entry == &bus_list) {
+               pr_debug("%s: no matching bus found for device %s.\n", 
__FUNCTION__,
+                               dev->bus_id == NULL ? "unknown" : dev->bus_id);
+               return 1;
+       }
+
+       /*
+       * OK, we found a match.  Put this device on bus's device list and 
initialize
+       * relevant fields in the device structure.
+       */
+       list_add_tail(&dev->node, &bus->devices);
+       dev->bus_node = entry;
+
+       /*
+       * Walk the list of drivers registered with this bus to allow the new 
device
+       * to be claimed by one of the drivers.
+       */
+       list_for_each(entry, &bus->drivers) {
+               drv = list_entry(entry, struct device_driver, node);
+
+               if (bus->match && bus->match(dev, drv)) {
+                       dev->driver = drv;
+
+                       if (drv->probe && drv->probe(dev) == 0)
+                               /* Only one driver gets to own this device. */
+                               break;
+                       else
+                               /* Try for another driver. */
+                               dev->driver = NULL;
+               }
+       }
+
+       pr_debug("%s: device %s registered with bus %s.\n", __FUNCTION__,
+                       dev->bus_id == NULL ? "unknown" : dev->bus_id, 
bus->name);
+
+       return 0;
+}
+
+/*
+ * device_unregister()
+ *
+ * Find the bus which this device is associated with and remove it from this 
bus's
+ * device list.  If this device is owned by a driver, call the drivers's remove
+ * handler.  Note that this routine assumes that the root device is never 
unregistered.
+ *
+ * Arguments:
+ * dev - device to be unregistered
+ *
+ * Returns:
+ * nothing
+ */
+void device_unregister(struct device *dev)
+{
+       struct list_head *entry;
+       struct bus_type *bus;
+       struct device_driver *drv;
+
+       /* Locate matching bus. */
+       list_for_each(entry, &bus_list) {
+               bus = list_entry(entry, struct bus_type, node);
+
+               if (dev->bus == bus)
+                       break;
+       }
+
+       if (entry == &bus_list) {
+               pr_debug("%s: no matching bus found for device %s.\n", 
__FUNCTION__,
+                               dev->bus_id == NULL ? "unknown" : dev->bus_id);
+               return;
+       }
+
+       /* Found the matching bus, remove the device. */
+       list_del(&dev->node);
+       dev->bus_node = NULL;
+
+       /* Walk the list of drivers on this bus and make this device disappear. 
*/
+       list_for_each(entry, &bus->drivers) {
+               drv = list_entry(entry, struct device_driver, node);
+
+               if (dev->driver == drv && drv->remove) {
+                       drv->remove(dev);
+
+                       /* Only one driver owns this device. */
+                       break;
+               }
+       }
+
+       pr_debug("%s: device %s unregistered on bus %s.\n", __FUNCTION__,
+                       dev->bus_id == NULL ? "unknown" : dev->bus_id, 
bus->name);
+
+       return;
+}
+
+/*
+ * bus_for_each_dev()
+ *
+ * Execute "fn" for every device on "bus" starting with device "dev" (if it is 
not
+ * NULL) and pass to it data pointed to by "data".
+ *
+ * Arguments:
+ * bus - bus to be searched
+ * dev - device at which to start the search (if not NULL)
+ * data - data to be passed to fn
+ * fn - function to call for every device on the bus.  When this function 
returns
+ *      0, this means we should keep calling.  If it returns 1, we should stop.
+ *
+ * Returns:
+ * 0 - success
+ * 1 - failure
+ */
+int bus_for_each_dev(struct bus_type *bus, struct device *dev, void *data, int 
(*fn)(struct device *, void *))
+{
+       struct list_head *entry;
+       struct device *device;
+       int error;
+
+       /* Find the correct bus. */
+       list_for_each(entry, &bus_list) {
+               if (bus == list_entry(entry, struct bus_type, node))
+                       break;
+       }
+
+       if (entry == &bus_list) {
+               pr_debug("%s: bus %s is not registered.\n", __FUNCTION__,
+                               bus->name == NULL ? "unknown" : bus->name);
+               return 1;
+       }
+
+       /* We found the correct bus.  Now, find the starting device. */
+       if (dev && bus_find_device(bus, dev))
+               entry = &dev->node;
+       else
+               entry = NULL;
+
+       /* Finally, call fn for every device except the root device. */
+       list_for_each(entry, &bus->devices) {
+               device = list_entry(entry, struct device, node);
+
+               if (!device->parent)
+                       continue;
+
+               if ((error=(fn)(device, data)) != 0)
+               return error;
+       }
+
+       return 0;
+}
+
+int bus_find_device(struct bus_type *bus, struct device *device)
+{
+       struct list_head *device_node;
+
+       list_for_each(device_node, &bus->devices) {
+               if (device == list_entry(device_node, struct device, node))
+                       return 1;
+       }
+
+       return 0;
+}
+
+/*
+ * bus_register()
+ *
+ * Register a bus on our local bus list.
+ *
+ * Arguments:
+ * bus - bus to be registered
+ *
+ * Returns:
+ * 0 - success
+ */
+int bus_register(struct bus_type *bus)
+{
+       /* Initialize this bus's driver and device list. */
+       INIT_LIST_HEAD(&bus->drivers);
+       INIT_LIST_HEAD(&bus->devices);
+
+       /* Put the bus into our local bus list. */
+       list_add_tail(&bus->node, &bus_list);
+
+       pr_debug("%s: bus %s registered.\n", __FUNCTION__, bus->name == NULL ? 
"unknown" : bus->name);
+
+       return 0;
+}
+
+/*
+ * bus_unregister()
+ *
+ * Unregister a bus from our local bus list.
+ *
+ * Arguments:
+ * bus - bus to be unregistered
+ *
+ * Returns:
+ * nothing
+ */
+void bus_unregister(struct bus_type *bus)
+{
+       struct list_head *entry;
+       struct bus_type *_bus;
+
+       /* Find a matching bus. */
+       list_for_each(entry, &bus_list) {
+               _bus = list_entry(entry, struct bus_type, node);
+
+               if (_bus == bus)
+                       /* We found a matching bus. */
+                       break;
+       }
+
+       if (entry == &bus_list) {
+               pr_debug("%s: no matching bus found for bus %s.\n", 
__FUNCTION__,
+                               bus->name == NULL ? "unknown" : bus->name);
+       }
+
+       /* OK, we found a match.  Remove this bus from the bus list. */
+       list_del(&bus->node);
+
+       pr_debug("%s: bus %s unregistered.\n", __FUNCTION__, bus->name == NULL 
? "unknown" : bus->name);
+}
+
+int device_create_file(struct device *dev, struct device_attribute *attr)
+{
+       return 0;
+}
+
+void device_remove_file(struct device *dev, struct device_attribute *attr)
+{
+}
+
+#endif
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Mon Dec 17 
15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c  Mon Dec 17 
15:54:42 2007 -0500
@@ -30,6 +30,7 @@
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
+#include <linux/kthread.h>
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/irq.h>
@@ -40,15 +41,14 @@
 #include <xen/interface/hvm/params.h>
 #include <xen/features.h>
 #include <xen/evtchn.h>
+#include <xen/xen_proc.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
+#include <xen/kerncompat.h>
 
 #define DRV_NAME    "xen-platform-pci"
 #define DRV_VERSION "0.10"
diff -r 6349a4bceff8 unmodified_drivers/linux-2.6/platform-pci/xen_support.c
--- a/unmodified_drivers/linux-2.6/platform-pci/xen_support.c   Mon Dec 17 
15:54:42 2007 -0500
+++ b/unmodified_drivers/linux-2.6/platform-pci/xen_support.c   Mon Dec 17 
15:54:42 2007 -0500
@@ -26,9 +26,7 @@
 #include <asm/hypervisor.h>
 #include "platform-pci.h"
 
-#ifdef HAVE_XEN_PLATFORM_COMPAT_H
-#include <xen/platform-compat.h>
-#endif
+#include <xen/kerncompat.h>
 
 #if defined (__ia64__)
 unsigned long __hypercall(unsigned long a1, unsigned long a2,
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.